rhash-1.4.6/ 0000775 0000000 0000000 00000000000 15010731530 011322 5 ustar root root rhash-1.4.6/file_set.h 0000664 0000000 0000000 00000002221 14703622112 013265 0 ustar root root /* file_set.h - functions to manipulate a set of files with its message digests */
#ifndef FILE_SET_H
#define FILE_SET_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* Filepath with its string-hash (for fast search).
*/
typedef struct file_set_item
{
unsigned hash;
char* filepath;
char* search_filepath; /* for case-insensitive comparison */
} file_set_item;
/* array to store filenames from a parsed hash file */
struct vector_t;
typedef struct vector_t file_set;
#define file_set_new() rsh_vector_new((void(*)(void*))file_set_item_free) /* allocate new file set */
#define file_set_free(set) rsh_vector_free(set) /* free memory */
#define file_set_get(set, index) ((file_set_item*)((set)->array[index])) /* get i-th element */
#define file_set_add(set, item) rsh_vector_add_ptr(set, item) /* add a file_set_item to file_set */
void file_set_item_free(file_set_item* item);
void file_set_add_name(file_set* set, const char* filename);
void file_set_sort(file_set* set);
void file_set_sort_by_path(file_set* set);
int file_set_exist(file_set* set, const char* filename);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FILE_SET_H */
rhash-1.4.6/calc_sums.h 0000664 0000000 0000000 00000004432 15010476501 013453 0 ustar root root /* calc_sums.h */
#ifndef CALC_SUMS_H
#define CALC_SUMS_H
#include "common_func.h"
#include "file.h"
#include "hash_check.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Hash function identifiers and bit masks */
#define bit64_to_hash_id(bit64) ((unsigned)RHASH_EXTENDED_BIT ^ get_ctz64(bit64))
#define hash_id_to_bit64(hash_id) ((hash_id) & RHASH_EXTENDED_BIT ? \
(uint64_t)1 << (unsigned)((hash_id) & ~RHASH_EXTENDED_BIT): (uint64_t)(hash_id))
#define hash_id_to_extended(hash_id) ((hash_id) & RHASH_EXTENDED_BIT ? hash_id : \
(unsigned)RHASH_EXTENDED_BIT ^ get_ctz(hash_id))
int hash_mask_to_hash_ids(uint64_t hash_mask, unsigned max_count,
unsigned* hash_ids, unsigned* out_count);
int set_openssl_enabled_hash_mask(uint64_t hash_mask);
uint64_t get_openssl_supported_hash_mask(void);
uint64_t get_all_supported_hash_mask(void);
/* Hash function calculation */
/**
* Information about a file to calculate/verify message digests for.
*/
struct file_info {
uint64_t size; /* the size of the hashed file */
uint64_t msg_offset; /* rctx->msg_size before hashing this file */
uint64_t time; /* file processing time in milliseconds */
file_t* file; /* the file being processed */
struct rhash_context* rctx; /* state of hash algorithms */
struct hash_parser* hp; /* parsed line of a hash file */
uint64_t hash_mask; /* mask of ids of calculated hash functions */
int processing_result; /* -1/-2 for i/o error, 0 on success, 1 on a hash mismatch */
};
int calc_sums(struct file_info* info);
int calculate_and_print_sums(FILE* out, file_t* out_file, file_t* file);
int find_embedded_crc32(file_t* file, unsigned* crc32);
int rename_file_by_embeding_crc32(struct file_info* info);
int save_torrent_to(file_t* torrent_file, struct rhash_context* rctx);
/* Benchmarking */
/** Benchmarking flag: measure the CPU "clocks per byte" speed */
#define BENCHMARK_CPB 1
/** Benchmarking flag: print benchmark result in tab-delimited format */
#define BENCHMARK_RAW 2
/**
* Benchmark hash functions.
*
* @param hash_mask bit mask for hash functions to benchmark
* @param flags benchmark flags, can contain BENCHMARK_CPB, BENCHMARK_RAW
*/
void run_benchmark(uint64_t hash_mask, unsigned flags);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* CALC_SUMS_H */
rhash-1.4.6/output.h 0000664 0000000 0000000 00000004342 14703622112 013041 0 ustar root root /* output.h */
#ifndef OUTPUT_H
#define OUTPUT_H
#include
#include
#ifdef __cplusplus
extern "C" {
#endif
struct file_info;
struct file_t;
/**
* A 'method' to output percents.
*/
struct percents_output_info_t
{
int (*init)(struct file_info* info);
void (*update)(struct file_info* info, uint64_t offset);
int (*finish)(struct file_info* info, int process_res);
const char* name;
};
/* pointer to the selected percents output method */
extern struct percents_output_info_t* percents_output;
#define init_percents(info) percents_output->init(info)
#define update_percents(info, offset) percents_output->update(info, offset)
#define finish_percents(info, process_res) percents_output->finish(info, process_res)
/* initialization of percents output method */
void setup_output(void);
void setup_percents(void);
enum FileOutputFlags {
OutDefaultFlags = 0x0,
OutForceUtf8 = 0x1,
OutCountSymbols = 0x2,
OutBaseName = 0x4,
OutDirName = 0x8,
OutEscape = 0x10,
OutEscapePrefixed = 0x20,
};
int fprintf_file_t(FILE* out, const char* format, struct file_t* file, unsigned output_flags);
int fprint_urlencoded(FILE* out, const char* str, int upper_case);
void log_msg(const char* format, ...);
void log_msg_file_t(const char* format, struct file_t* file);
void die(const char* format, ...);
#define log_warning log_error
#define log_warning_msg_file_t log_error_msg_file_t
void log_error(const char* format, ...);
void log_error_file_t(struct file_t* file);
void log_error_msg_file_t(const char* format, struct file_t* file);
void fatal_error_impl(const char* file, int line, const char* format, ...);
#define RSH_REQUIRE_IMPL(condition, file, line, ...) \
while(!(condition)) { \
fatal_error_impl(file, line, __VA_ARGS__); \
}
#define RSH_REQUIRE(condition, ...) \
RSH_REQUIRE_IMPL(condition, __FILE__, __LINE__, __VA_ARGS__)
void report_interrupted(void);
int print_verifying_header(struct file_t* file);
int print_verifying_footer(void);
int print_check_stats(void);
int print_verbose_algorithms(FILE* out, uint64_t hash_mask);
void print_time_stats(uint64_t time, uint64_t size, int total);
void print_file_time_stats(struct file_info* info);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* OUTPUT_H */
rhash-1.4.6/Makefile 0000664 0000000 0000000 00000030334 15010476501 012771 0 ustar root root
include config.mak
HEADERS = calc_sums.h hash_print.h common_func.h hash_update.h file.h file_mask.h file_set.h find_file.h hash_check.h output.h parse_cmdline.h rhash_main.h win_utils.h platform.h version.h
SOURCES = calc_sums.c hash_print.c common_func.c hash_update.c file.c file_mask.c file_set.c find_file.c hash_check.c output.c parse_cmdline.c rhash_main.c win_utils.c
OBJECTS = $(SOURCES:.c=.o)
WIN_DIST_FILES = dist/MD5.bat dist/magnet.bat dist/rhashrc.sample
OTHER_FILES = configure Makefile ChangeLog INSTALL.md COPYING README.md \
build/vc-2010/rhash.vcxproj dist/rhash.spec.in dist/rhash.1.in dist/rhash.1.win.sed \
docs/CONTRIBUTING.md docs/LIBRHASH.md librhash/Doxyfile po/rhash.pot \
tests/test_rhash.sh tests/test1K.data
LIBRHASH_FILES = librhash/algorithms.c librhash/algorithms.h \
librhash/byte_order.c librhash/byte_order.h librhash/plug_openssl.c librhash/plug_openssl.h \
librhash/rhash.c librhash/rhash.h librhash/rhash_torrent.c librhash/rhash_torrent.h \
librhash/aich.c librhash/aich.h librhash/blake2b.c librhash/blake2b.h \
librhash/blake2s.c librhash/blake2s.h librhash/blake3.c librhash/blake3.h \
librhash/crc32.c librhash/crc32.h \
librhash/ed2k.c librhash/ed2k.h librhash/edonr.c librhash/edonr.h \
librhash/gost12.c librhash/gost12.h librhash/gost94.c librhash/gost94.h \
librhash/has160.c librhash/has160.h librhash/hex.c librhash/hex.h librhash/md4.c \
librhash/md4.h librhash/md5.c librhash/md5.h librhash/ripemd-160.c librhash/ripemd-160.h \
librhash/sha1.c librhash/sha1.h librhash/sha3.c librhash/sha3.h \
librhash/sha256.c librhash/sha256.h librhash/sha512.c librhash/sha512.h \
librhash/sha_ni.c librhash/sha_ni.h librhash/snefru.c librhash/snefru.h \
librhash/tiger.c librhash/tiger.h librhash/tiger_sbox.c \
librhash/torrent.h librhash/torrent.c librhash/tth.c librhash/tth.h \
librhash/whirlpool.c librhash/whirlpool.h librhash/whirlpool_sbox.c \
librhash/test_lib.c librhash/test_lib.h librhash/test_utils.c librhash/test_utils.h \
librhash/ustd.h librhash/util.c librhash/util.h librhash/Makefile
I18N_FILES = po/ca.po po/de.po po/en_AU.po po/es.po po/fr.po po/gl.po po/it.po po/pt_BR.po po/ro.po po/ru.po po/uk.po
ALL_FILES = $(SOURCES) $(HEADERS) $(LIBRHASH_FILES) $(OTHER_FILES) $(WIN_DIST_FILES) $(I18N_FILES)
SPECFILE = dist/rhash.spec
LIBRHASH_PC = dist/librhash.pc
RPMTOP = rpms
RPMDIRS = SOURCES SPECS BUILD SRPMS RPMS
RHASH_NAME = rhash
RHASH_BINARY = rhash$(EXEC_EXT)
INSTALL_PROGRAM = $(INSTALL) -m 755
INSTALL_DATA = $(INSTALL) -m 644
all: $(BUILD_TARGETS)
build: $(RHASH_BINARY)
lib-shared: $(LIBRHASH_SHARED)
lib-static: $(LIBRHASH_STATIC)
install: build-install-binary install-data install-symlinks $(EXTRA_INSTALL)
install-data: install-man install-conf
uninstall: uninstall-binary uninstall-data uninstall-symlinks uninstall-lib uninstall-gmo uninstall-pkg-config
config.mak:
echo "Run the ./configure script first" && false
# creating archives
WIN_SUFFIX = win32
PACKAGE_NAME = $(RHASH_NAME)-$(VERSION)
ARCHIVE_TARGZ = $(PACKAGE_NAME)-src.tar.gz
ARCHIVE_TARGZ_CORE = $(RHASH_NAME)-core-$(VERSION)-src.tar.gz
ARCHIVE_TARGZ_BINDINGS = $(RHASH_NAME)-bindings-$(VERSION)-src.tar.gz
ARCHIVE_TARGZ_DEB = $(RHASH_NAME)_$(VERSION).orig.tar.gz
ARCHIVE_XZ = $(PACKAGE_NAME)-src.tar.xz
ARCHIVE_ZIP = $(PACKAGE_NAME)-$(WIN_SUFFIX).zip
WIN_ZIP_DIR = RHash-$(VERSION)-$(WIN_SUFFIX)
dist: tgz
win-dist: zip
zip: $(ARCHIVE_ZIP)
dgz: check $(ARCHIVE_TARGZ_DEB)
build-install-binary: $(BUILD_TARGETS)
+$(MAKE) install-binary
mkdir-bin:
$(INSTALL) -d $(BINDIR)
# install binary without (re-)compilation
install-binary: mkdir-bin
$(INSTALL_PROGRAM) $(RHASH_BINARY) $(BINDIR)/$(RHASH_BINARY)
install-man:
$(INSTALL) -d $(MANDIR)/man1
$(INSTALL_DATA) dist/rhash.1 $(MANDIR)/man1/rhash.1
install-conf:
$(INSTALL) -d $(SYSCONFDIR)
tr -d \\r < dist/rhashrc.sample > rc.tmp && $(INSTALL_DATA) rc.tmp $(SYSCONFDIR)/rhashrc
rm -f rc.tmp
# dependencies should be properly set, otherwise 'make -j' can fail
install-symlinks: mkdir-bin install-man install-binary
cd $(BINDIR) && for f in $(SYMLINKS); do $(LN_S) $(RHASH_BINARY) $$f$(EXEC_EXT); done
cd $(MANDIR)/man1 && for f in $(SYMLINKS); do $(LN_S) rhash.1 $$f.1; done
install-pkg-config:
$(INSTALL) -d $(PKGCONFIGDIR)
$(INSTALL_DATA) $(LIBRHASH_PC) $(PKGCONFIGDIR)/
uninstall-binary:
rm -f $(BINDIR)/$(RHASH_BINARY)
uninstall-data:
rm -f $(MANDIR)/man1/rhash.1
uninstall-symlinks:
for f in $(SYMLINKS); do rm -f $(BINDIR)/$$f$(EXEC_EXT) $(MANDIR)/man1/$$f.1; done
uninstall-pkg-config:
rm -f $(PKGCONFIGDIR)/librhash.pc
uninstall-lib:
+cd librhash && $(MAKE) uninstall-lib
install-lib-static: $(LIBRHASH_STATIC) install-lib-headers
+cd librhash && $(MAKE) install-lib-static
install-lib-shared: $(LIBRHASH_SHARED)
+cd librhash && $(MAKE) install-lib-shared
install-lib-headers:
+cd librhash && $(MAKE) install-lib-headers
install-lib-so-link:
+cd librhash && $(MAKE) install-so-link
$(LIBRHASH_SHARED): $(LIBRHASH_FILES)
+cd librhash && $(MAKE) lib-shared
$(LIBRHASH_STATIC): $(LIBRHASH_FILES)
+cd librhash && $(MAKE) lib-static
test-lib: test-lib-$(LIBRHASH_TYPE)
test-lib-static: $(LIBRHASH_STATIC)
+cd librhash && $(MAKE) test-static
test-lib-shared: $(LIBRHASH_SHARED)
+cd librhash && $(MAKE) test-shared
test-libs: $(LIBRHASH_STATIC) $(LIBRHASH_SHARED)
+cd librhash && $(MAKE) test-static test-shared
test-full: $(RHASH_BINARY)
/bin/sh tests/test_rhash.sh $(TEST_OPTIONS) --full ./$(RHASH_BINARY)
test: $(RHASH_BINARY)
/bin/sh tests/test_rhash.sh $(TEST_OPTIONS) ./$(RHASH_BINARY)
print-info: lib-$(LIBRHASH_TYPE)
+cd librhash && $(MAKE) print-info
# check that source tree is consistent
check:
grep -q '\* === Version $(VERSION) ===' ChangeLog
grep -q '^#define VERSION "$(VERSION)"' version.h
test ! -f bindings/version.properties || grep -q '^version=$(VERSION)$$' bindings/version.properties
$(RHASH_BINARY): $(OBJECTS) $(LIBRHASH_PATH)
$(CC) $(OBJECTS) $(LIBRHASH_PATH) $(LDFLAGS) -o $@
# NOTE: dependences were generated by 'gcc -Ilibrhash -MM *.c'
# we are using plain old makefile style to support BSD make
calc_sums.o: calc_sums.c calc_sums.h common_func.h file.h hash_check.h \
file_set.h hash_print.h output.h parse_cmdline.h platform.h rhash_main.h \
win_utils.h librhash/rhash.h librhash/rhash_torrent.h
$(CC) -c $(CFLAGS) $< -o $@
common_func.o: common_func.c common_func.h output.h parse_cmdline.h \
version.h win_utils.h
$(CC) -c $(CFLAGS) $< -o $@
file.o: file.c file.h common_func.h parse_cmdline.h platform.h \
win_utils.h
$(CC) -c $(CFLAGS) $< -o $@
file_mask.o: file_mask.c file_mask.h common_func.h file.h
$(CC) -c $(CFLAGS) $< -o $@
file_set.o: file_set.c file_set.h common_func.h hash_print.h output.h \
parse_cmdline.h rhash_main.h file.h librhash/rhash.h
$(CC) -c $(CFLAGS) $< -o $@
find_file.o: find_file.c find_file.h common_func.h file.h output.h \
parse_cmdline.h platform.h win_utils.h
$(CC) -c $(CFLAGS) $< -o $@
hash_check.o: hash_check.c hash_check.h file.h file_set.h calc_sums.h \
common_func.h hash_print.h output.h parse_cmdline.h rhash_main.h \
librhash/rhash.h
$(CC) -c $(CFLAGS) $< -o $@
hash_print.o: hash_print.c hash_print.h calc_sums.h common_func.h file.h \
hash_check.h file_set.h output.h parse_cmdline.h rhash_main.h \
win_utils.h librhash/rhash.h
$(CC) -c $(CFLAGS) $< -o $@
hash_update.o: hash_update.c hash_update.h calc_sums.h common_func.h \
file.h hash_check.h file_set.h file_mask.h hash_print.h output.h \
parse_cmdline.h rhash_main.h win_utils.h
$(CC) -c $(CFLAGS) $< -o $@
output.o: output.c output.h calc_sums.h common_func.h file.h hash_check.h \
file_set.h parse_cmdline.h platform.h rhash_main.h win_utils.h \
librhash/rhash.h
$(CC) -c $(CFLAGS) $< -o $@
parse_cmdline.o: parse_cmdline.c parse_cmdline.h calc_sums.h \
common_func.h file.h hash_check.h file_set.h file_mask.h find_file.h \
hash_print.h output.h rhash_main.h win_utils.h librhash/rhash.h
$(CC) -c $(CFLAGS) $(CONFCFLAGS) $< -o $@
rhash_main.o: rhash_main.c rhash_main.h file.h calc_sums.h common_func.h \
hash_check.h file_set.h file_mask.h find_file.h hash_print.h \
hash_update.h output.h parse_cmdline.h win_utils.h librhash/rhash.h
$(CC) -c $(CFLAGS) $(LOCALECFLAGS) $< -o $@
win_utils.o: win_utils.c win_utils.h common_func.h file.h parse_cmdline.h
$(CC) -c $(CFLAGS) $< -o $@
dist/rhash.1.win.html: dist/rhash.1 dist/rhash.1.win.sed
sed -f dist/rhash.1.win.sed dist/rhash.1 | rman -fHTML -roff | \
sed -e '/ dist/rhash.1.win.html
# verify the result
grep -q "utf8" dist/rhash.1.win.html
grep -q "APPDATA" dist/rhash.1.win.html
dist/rhash.1.html: dist/rhash.1
-rman --version 2>/dev/null && (rman -fHTML -roff dist/rhash.1 | sed -e '/ $@)
dist/rhash.1.txt: dist/rhash.1
-groff --version 2>/dev/null && (groff -t -e -mandoc -Tascii dist/rhash.1 | sed -e 's/.\[[0-9]*m//g' > $@)
permissions:
find . build dist docs librhash po tests -maxdepth 1 -type f -exec chmod -x '{}' \;
chmod +x configure tests/test_rhash.sh
copy-dist: $(ALL_FILES) permissions
rm -rf $(PACKAGE_NAME)
mkdir $(PACKAGE_NAME)
cp -rl --parents $(ALL_FILES) $(PACKAGE_NAME)/
tgz-core: check
+$(MAKE) copy-dist PACKAGE_NAME=$(PACKAGE_NAME)-core
tar czf $(ARCHIVE_TARGZ_CORE) --owner=root --group=root $(PACKAGE_NAME)-core/
rm -rf $(PACKAGE_NAME)-core
tgz-bindings:
+cd bindings && $(MAKE) gzip ARCHIVE_GZIP=../$(ARCHIVE_TARGZ_BINDINGS)
tgz: check clean-bindings
+$(MAKE) copy-dist
+cd bindings && $(MAKE) copy-dist COPYDIR=../$(PACKAGE_NAME)/bindings
tar czf $(ARCHIVE_TARGZ) --owner=root:0 --group=root:0 $(PACKAGE_NAME)/
rm -rf $(PACKAGE_NAME)
xz: check clean-bindings
+$(MAKE) copy-dist
+cd bindings && $(MAKE) copy-dist COPYDIR=../$(PACKAGE_NAME)/bindings
tar cJf $(ARCHIVE_XZ) --owner=root:0 --group=root:0 $(PACKAGE_NAME)/
rm -rf $(PACKAGE_NAME)
win-dir: $(WIN_DIST_FILES) dist/rhash.1.win.html
test -s dist/rhash.1.win.html && test -x $(RHASH_BINARY)
-rm -rf $(WIN_ZIP_DIR)
mkdir $(WIN_ZIP_DIR)
cp $(RHASH_BINARY) ChangeLog $(WIN_DIST_FILES) $(WIN_ZIP_DIR)/
cp dist/rhash.1.win.html $(WIN_ZIP_DIR)/rhash-doc.html
$(ARCHIVE_ZIP): $(WIN_DIST_FILES) dist/rhash.1.win.html
+$(MAKE) win-dir
zip -9r $(ARCHIVE_ZIP) $(WIN_ZIP_DIR)
rm -rf $(WIN_ZIP_DIR)
$(ARCHIVE_TARGZ_DEB) : $(ALL_FILES)
+$(MAKE) tgz
mv -f $(ARCHIVE_TARGZ) $(ARCHIVE_TARGZ_DEB)
# rpm packaging
$(SPECFILE): $(SPECFILE).in config.mak
sed -e 's/@VERSION@/$(VERSION)/' $(SPECFILE).in > $(SPECFILE)
rpm: tgz
-for i in $(RPMDIRS); do mkdir -p $(RPMTOP)/$$i; done
cp -f $(ARCHIVE_TARGZ) $(RPMTOP)/SOURCES
rpmbuild -ba --clean --define "_topdir `pwd`/$(RPMTOP)" $(SPECFILE)
mv -f `find $(RPMTOP) -name "*rhash*-$(VERSION)*.rpm"` .
rm -rf $(RPMTOP)
clean-bindings:
+cd bindings && $(MAKE) clean
clean-local:
rm -f *.o $(RHASH_BINARY)
rm -f po/*.gmo po/*.po~ po/compile-gmo.tag
distclean: clean-local
rm -f config.log config.mak dist/rhash.1 $(SPECFILE) $(LIBRHASH_PC)
+cd librhash && $(MAKE) distclean
clean: clean-local
+cd librhash && $(MAKE) clean
update-po:
xgettext *.c -k_ -cTRANSLATORS -o po/rhash.pot \
--msgid-bugs-address='Aleksey ' --package-name='RHash'
for f in $(I18N_FILES); do \
msgmerge -U $$f po/rhash.pot; \
done
po/compile-gmo.tag: $(I18N_FILES)
for f in $(I18N_FILES); do \
g=`basename $$f .po`; \
msgfmt -o po/$$g.gmo $$f; \
done
touch $@
compile-gmo: po/compile-gmo.tag
install-gmo: compile-gmo
for f in $(I18N_FILES); do \
l=`basename $$f .po`; \
$(INSTALL) -d $(LOCALEDIR)/$$l/LC_MESSAGES; \
$(INSTALL_DATA) po/$$l.gmo $(LOCALEDIR)/$$l/LC_MESSAGES/rhash.mo; \
done
uninstall-gmo:
for f in $(I18N_FILES); do \
rm -f $(LOCALEDIR)/`basename $$f .po`/LC_MESSAGES/rhash.mo; \
done
.PHONY: all build lib-shared lib-static clean clean-bindings distclean clean-local \
test test-shared test-static test-full test-lib test-libs test-lib-shared test-lib-static \
install build-install-binary install-binary install-lib-shared install-lib-static \
install-lib-headers install-lib-so-link install-conf install-data install-gmo install-man \
install-symlinks install-pkg-config uninstall-gmo uninstall-pkg-config \
uninstall uninstall-binary uninstall-data uninstall-lib uninstall-symlinks \
print-info check copy-dist update-po compile-gmo mkdir-bin permissions \
dgz dist tgz tgz-bindings tgz-core rpm win-dist win-dir xz zip
rhash-1.4.6/README.md 0000664 0000000 0000000 00000003350 14703622112 012605 0 ustar root root # RHash
RHash (Recursive Hasher) is a console utility for calculation and
verification of magnet links and various message digests, including CRC32, CRC32C,
MD4, MD5, SHA1, SHA256, SHA512, SHA3, AICH, ED2K, DC++ TTH, BitTorrent BTIH,
Tiger, GOST R 34.11-94, GOST R 34.11-2012, RIPEMD-160, HAS-160, EDON-R, and
Whirlpool.
Message digests are used to ensure and verify integrity of large volumes of
data for a long-term storing or transferring.
### Program features:
* Ability to process directories recursively.
* Output in a predefined (SFV, BSD-like) or a user-defined format.
* Calculation of Magnet links.
* Updating hash files (adding message digests of files missing in the hash file).
* Calculates several message digests in one pass.
* Portability: the program works the same on Linux, Unix, macOS or Windows.
## Installation
```shell
./configure && make install
```
For more complicated cases of installation see the [INSTALL.md] file.
## Documentation
* RHash [ChangeLog]
* [The LibRHash Library] documentation
## Links
* Project Home Page: http://rhash.sourceforge.net/
* Official Releases: https://github.com/rhash/RHash/releases/
* Binary Windows Releases: https://sf.net/projects/rhash/files/rhash/
* The table of the supported by RHash [hash functions](http://sf.net/p/rhash/wiki/HashFunctions/)
* ECRYPT [The Hash Function Zoo](http://ehash.iaik.tugraz.at/wiki/The_Hash_Function_Zoo)
* ECRYPT [Benchmarking of hash functions](https://bench.cr.yp.to/results-hash.html)
## Contribution
Please read the [Contribution guidelines](docs/CONTRIBUTING.md) document.
## License
The code is distributed under [BSD Zero Clause License](COPYING).
[INSTALL.md]: INSTALL.md
[The LibRHash Library]: docs/LIBRHASH.md
[ChangeLog]: ChangeLog
rhash-1.4.6/COPYING 0000664 0000000 0000000 00000001340 14703622112 012356 0 ustar root root
BSD Zero Clause License
Copyright (c) 2005, Aleksey Kravchenko
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
rhash-1.4.6/parse_cmdline.c 0000664 0000000 0000000 00000125522 15010476501 014306 0 ustar root root /* parse_cmdline.c - parsing of command line options */
#include "parse_cmdline.h"
#include "calc_sums.h"
#include "file_mask.h"
#include "find_file.h"
#include "hash_print.h"
#include "output.h"
#include "rhash_main.h"
#include "win_utils.h"
#include "librhash/rhash.h"
#include
#include
#include
#include
#include
#include
#include
#ifdef _WIN32
# include /* for CommandLineToArgvW(), GetCommandLineW(), ... */
#endif
typedef struct options_t options_t;
struct options_t conf_opt; /* config file parsed options */
struct options_t opt; /* command line options */
static const char* get_full_program_version(void)
{
static char version_buffer[64];
sprintf(version_buffer, "%s v%s\n", PROGRAM_NAME, get_version_string());
assert(strlen(version_buffer) < sizeof(version_buffer));
return version_buffer;
}
static void on_verbose(options_t* o)
{
if (o->verbose < 2)
o->verbose++;
}
static void print_version(void)
{
rsh_fprintf(rhash_data.out, "%s", get_full_program_version());
rsh_exit(0);
}
static void print_help_line(const char* option, const char* format, ...)
{
va_list args;
va_start(args, format);
rsh_fprintf(rhash_data.out, "%s", option);
rsh_vfprintf(rhash_data.out, format, args);
va_end(args);
}
/**
* Print program help.
*/
static void print_help(void)
{
const char* checksum_format;
const char* digest_format;
assert(rhash_data.out != NULL);
/* print program version and usage */
rsh_fprintf(rhash_data.out, _("%s\n"
"Usage: %s [OPTION...] [FILE | -]...\n"
" %s --printf= [FILE | -]...\n\n"), get_full_program_version(), CMD_FILENAME, CMD_FILENAME);
rsh_fprintf(rhash_data.out, _("Options:\n"));
print_help_line(" -V, --version ", _("Print program version and exit.\n"));
print_help_line(" -h, --help ", _("Print this help screen.\n"));
/* TRANSLATORS: help screen line template for CRC32 and CRC32C */
checksum_format = _("Calculate %s checksum.\n");
/* TRANSLATORS: help screen line template for MD5, SHA1, e.t.c.\n" */
digest_format = _("Calculate %s message digest.\n");
print_help_line(" -C, --crc32 ", checksum_format, "CRC32");
print_help_line(" --crc32c ", checksum_format, "CRC32C");
print_help_line(" --md4 ", digest_format, "MD4");
print_help_line(" -M, --md5 ", digest_format, "MD5");
print_help_line(" -H, --sha1 ", digest_format, "SHA1");
print_help_line(" --sha224, --sha256, --sha384, --sha512 ", digest_format, "SHA2");
print_help_line(" --sha3-224, --sha3-256, --sha3-384, --sha3-512 ", digest_format, "SHA3");
print_help_line(" --blake2s, --blake2b ", digest_format, "BLAKE2S/BLAKE2B");
print_help_line(" --blake3 ", digest_format, "BLAKE3");
print_help_line(" -T, --tth ", digest_format, "TTH");
print_help_line(" --btih ", digest_format, "BitTorrent InfoHash");
print_help_line(" -A, --aich ", digest_format, "AICH");
print_help_line(" -E, --ed2k ", digest_format, "eDonkey");
print_help_line(" -L, --ed2k-link ", _("Calculate and print eDonkey link.\n"));
print_help_line(" --tiger ", digest_format, "Tiger");
print_help_line(" -G, --gost12-256 ", digest_format, _("GOST R 34.11-2012, 256 bit"));
print_help_line(" --gost12-512 ", digest_format, _("GOST R 34.11-2012, 512 bit"));
/* TRANSLATORS: This hash function name should be translated to Russian only */
print_help_line(" --gost94 ", digest_format, _("GOST R 34.11-94"));
/* TRANSLATORS: This hash function name should be translated to Russian only */
print_help_line(" --gost94-cryptopro ", digest_format, _("GOST R 34.11-94 CryptoPro"));
print_help_line(" --ripemd160 ", digest_format, "RIPEMD-160");
print_help_line(" --has160 ", digest_format, "HAS-160");
print_help_line(" --edonr256, --edonr512 ", digest_format, "EDON-R 256/512");
print_help_line(" --snefru128, --snefru256 ", digest_format, "SNEFRU-128/256");
print_help_line(" -a, --all ", _("Calculate all supported hash functions.\n"));
print_help_line(" -c, --check ", _("Check hash files specified by command line.\n"));
print_help_line(" -u, --update= ", _("Update the specified hash file.\n"));
print_help_line(" --missing= ", _("List files from hash file that are missing or inaccessible.\n"));
print_help_line(" --unverified= ", _("List command-line files missing from given hash file.\n"));
print_help_line(" -e, --embed-crc ", _("Rename files by inserting crc32 sum into name.\n"));
print_help_line(" -k, --check-embedded ", _("Verify files by crc32 sum embedded in their names.\n"));
print_help_line(" --list-hashes ", _("List the names of supported hash functions, one per line.\n"));
print_help_line(" -B, --benchmark ", _("Benchmark selected algorithm.\n"));
print_help_line(" -v, --verbose ", _("Be verbose.\n"));
print_help_line(" --brief ", _("Use brief form of hash file verification report.\n"));
print_help_line(" -r, --recursive ", _("Process directories recursively.\n"));
print_help_line(" --file-list= ", _("Process a list of files.\n"));
print_help_line(" -m, --message= ", _("Process the text message.\n"));
print_help_line(" --skip-ok ", _("Don't print OK messages for successfully verified files.\n"));
print_help_line(" --ignore-missing ", _("Ignore missing files, while verifying a hash file.\n"));
print_help_line(" -i, --ignore-case ", _("Ignore case of filenames when updating hash files.\n"));
print_help_line(" -P, --percents ", _("Show percents, while calculating or verifying message digests.\n"));
print_help_line(" --speed ", _("Output per-file and total processing speed.\n"));
print_help_line(" --max-depth= ", _("Descend at most levels of directories.\n"));
if (rhash_is_openssl_supported())
print_help_line(" --openssl= ", _("Specify hash functions to be calculated using OpenSSL.\n"));
print_help_line(" -o, --output= ", _("File to output calculation or checking results.\n"));
print_help_line(" -l, --log= ", _("File to log errors and verbose information.\n"));
print_help_line(" --sfv ", _("Print message digests, using SFV format (default).\n"));
print_help_line(" --bsd ", _("Print message digests, using BSD-like format.\n"));
print_help_line(" --simple ", _("Print message digests, using simple format.\n"));
print_help_line(" --one-hash ", _("Print one message digest per line without file information.\n"));
print_help_line(" --hex ", _("Print message digests in hexadecimal format.\n"));
print_help_line(" --base32 ", _("Print message digests in Base32 format.\n"));
print_help_line(" -b, --base64 ", _("Print message digests in Base64 format.\n"));
print_help_line(" -g, --magnet ", _("Print message digests as magnet links.\n"));
print_help_line(" --torrent ", _("Create torrent files.\n"));
#ifdef _WIN32
print_help_line(" --utf8 ", _("Use UTF-8 encoding for output (Windows only).\n"));
print_help_line(" --win ", _("Use Windows codepage for output (Windows only).\n"));
print_help_line(" --dos ", _("Use DOS codepage for output (Windows only).\n"));
#endif
print_help_line(" --template= ", _("Load a printf-like template from the \n"));
print_help_line(" -p, --printf= ", _("Format and print message digests.\n"));
print_help_line(" ", _("See the RHash manual for details.\n"));
rsh_exit(0);
}
/**
* Print the names of all supported hash algorithms to the console.
*/
static void list_hashes(void)
{
uint64_t hash_mask = get_all_supported_hash_mask();
while (hash_mask) {
uint64_t bit64 = hash_mask & -hash_mask;
const char* hash_name = rhash_get_name(bit64_to_hash_id(bit64));
if (hash_name)
rsh_fprintf(rhash_data.out, "%s\n", hash_name);
hash_mask ^= bit64;
}
rsh_exit(0);
}
/**
* Add a hash function to the list of calulated ones.
* If RHASH_ALL_HASHES is passed as hash_id, then all
* hash functions will be calculated.
*
* @param o pointer to the options structure to update
* @param hash_id hash function identifier
*/
static void add_hash_id(options_t* o, unsigned hash_id)
{
if (hash_id == RHASH_ALL_HASHES)
o->hash_mask = get_all_supported_hash_mask();
else
o->hash_mask |= hash_id_to_bit64(hash_id);
}
/**
* Process a mode option, requiring a hash file.
*
* @param o pointer to the options structure to update
* @param path the path of the hash file
* @param mode the mode bit-flag
*/
static void hash_file_mode(options_t* o, tstr_t path, unsigned mode)
{
if (o->search_data) {
o->update_file = path;
o->mode |= mode;
}
}
/**
* Add a special file.
*
* @param o pointer to the options structure to update
* @param path the path of the file
* @param type the type of the option
*/
static void add_special_file(options_t* o, tstr_t path, unsigned file_mode)
{
if (o->search_data) {
file_search_add_file(o->search_data, path, file_mode);
opt.has_files = 1;
}
}
enum file_suffix_type {
MASK_ACCEPT,
MASK_EXCLUDE,
MASK_CRC_ACCEPT
};
/**
* Process --accept, --exclude and --crc-accept options.
*
* @param o pointer to the options structure to update
* @param accept_string comma delimited string to parse
* @param type the type of the option
*/
static void add_file_suffix(options_t* o, char* accept_string, unsigned type)
{
file_mask_array** ptr = (type == MASK_ACCEPT ? &o->files_accept :
type == MASK_EXCLUDE ? &o->files_exclude : &o->crc_accept);
if (!*ptr) *ptr = file_mask_new();
file_mask_add_list(*ptr, accept_string);
}
/**
* Process --bt_announce option.
*
* @param o pointer to the options structure
* @param announce_url the url to parse
* @param unused a tottaly unused parameter
*/
static void bt_announce(options_t* o, char* announce_url, unsigned unused)
{
(void)unused;
/* skip empty string */
if (!announce_url || !announce_url[0]) return;
if (!o->bt_announce) o->bt_announce = rsh_vector_new_simple();
rsh_vector_add_ptr(o->bt_announce, rsh_strdup(announce_url));
}
/**
* Process an --openssl option.
*
* @param o pointer to the options structure to update
* @param openssl_hashes comma delimited string with names of hash functions
* @param type ignored
*/
static void openssl_flags(options_t* o, char* openssl_hashes, unsigned type)
{
uint64_t openssl_supported_hash_mask = get_openssl_supported_hash_mask();
char* cur;
char* next;
(void)type;
if (!rhash_is_openssl_supported())
{
log_warning(_("compiled without openssl support\n"));
return;
}
/* set the openssl_mask */
for (cur = openssl_hashes; cur && *cur; cur = next) {
print_hash_info* info;
size_t length;
next = strchr(cur, ',');
length = (next != NULL ? (size_t)(next++ - cur) : strlen(cur));
if (length == 0)
continue;
for (info = hash_info_table; info->hash_id; info++) {
uint64_t hash_bit64 = hash_id_to_bit64(info->hash_id);
if ((hash_bit64 & openssl_supported_hash_mask) == 0)
continue;
if (memcmp(cur, info->short_name, length) == 0 &&
info->short_name[length] == '\0') {
o->openssl_mask |= hash_bit64;
break;
}
}
if (!info->hash_id) {
cur[length] = '\0'; /* terminate wrong hash function name */
log_warning(_("openssl option doesn't support '%s' hash function\n"), cur);
}
}
/* mark hash mask as valid to handle disabling openssl by --openssl="" */
o->openssl_mask |= OPENSSL_MASK_VALID_BIT;
}
/**
* Process --video option.
*
* @param o pointer to the options structure to update
*/
static void accept_video(options_t* o)
{
add_file_suffix(o, ".avi,.ogm,.mkv,.mp4,.mpeg,.mpg,.asf,.rm,.wmv,.vob", MASK_ACCEPT);
}
/**
* Say nya! Keep secret! =)
*/
static void nya(void)
{
rsh_fprintf(rhash_data.out, " /\\__/\\\n (^ _ ^.) %s\n (_uu__)\n",
/* TRANSLATORS: Keep it secret ;) */
_("Purrr..."));
rsh_exit(0);
}
/**
* Process on --max-depth option.
*
* @param o pointer to the processed option
* @param number the string containing the max-depth number
* @param param unused parameter
*/
static void set_max_depth(options_t* o, char* number, unsigned param)
{
(void)param;
if (strspn(number, "0123456789") < strlen(number)) {
die(_("max-depth parameter is not a number: %s\n"), number);
}
o->find_max_depth = atoi(number);
}
/**
* Set the length of a BitTorrent file piece.
*
* @param o pointer to the processed option
* @param number string containing the piece length number
* @param param unused parameter
*/
static void set_bt_piece_length(options_t* o, char* number, unsigned param)
{
(void)param;
if (strspn(number, "0123456789") < strlen(number)) {
die(_("bt-piece-length parameter is not a number: %s\n"), number);
}
o->bt_piece_length = (size_t)atoi(number);
}
/**
* Set the path separator to use when printing paths
*
* @param o pointer to the processed option
* @param sep file separator, can be only '/' or '\'
* @param param unused parameter
*/
static void set_path_separator(options_t* o, char* sep, unsigned param)
{
(void)param;
if ((*sep == '/' || *sep == '\\') && sep[1] == 0) {
o->path_separator = *sep;
#if defined(_WIN32)
/* MSYS environment changes '/' in command line to HOME, see http://www.mingw.org/wiki/FAQ */
} else if (getenv("MSYSTEM") || getenv("TERM")) {
log_warning(_("wrong path-separator, use '//' instead of '/' on MSYS\n"));
o->path_separator = '/';
#endif
} else {
die(_("path-separator is neither '/' nor '\\': %s\n"), sep);
}
}
/**
* Function pointer to store an option handler.
*/
typedef void(*opt_handler_t)(void);
/**
* Information about a command line option.
*/
typedef struct cmdline_opt_t
{
unsigned short type; /* how to process the option, see option_type_t below */
char short1, short2; /* short option names */
char* long_name; /* long option name */
opt_handler_t handler; /* option handler */
void* ptr; /* auxiliary pointer, e.g. to an opt field */
unsigned param; /* optional integer parameter */
} cmdline_opt_t;
enum option_type_t
{
F_NEED_PARAM = 16, /* flag: option needs a parameter */
F_OUTPUT_OPT = 32, /* flag: option changes program output */
F_UFLG = 1, /* set a bit flag in a uint32_t field */
F_UENC = F_UFLG | F_OUTPUT_OPT, /* an encoding changing option */
F_CSTR = 2 | F_NEED_PARAM, /* store parameter as a C string */
F_TSTR = 3 | F_NEED_PARAM, /* store parameter as a tstr_t */
F_TOUT = 4 | F_NEED_PARAM | F_OUTPUT_OPT,
F_VFNC = 5, /* just call a function */
F_PFNC = 6 | F_NEED_PARAM, /* process option parameter by calling a handler */
F_TFNC = 7 | F_NEED_PARAM, /* process option parameter by calling a handler */
F_UFNC = 8 | F_NEED_PARAM, /* pass UTF-8 encoded parameter to the handler */
F_PRNT = 9, /* print a constant C-string and exit */
};
#define is_param_required(option_type) ((option_type) & F_NEED_PARAM)
#define is_output_modifier(option_type) ((option_type) & F_OUTPUT_OPT)
/* supported program options */
cmdline_opt_t cmdline_opt[] =
{
/* program modes */
{ F_UFLG, 'c', 0, "check", 0, &opt.mode, MODE_CHECK },
{ F_UFLG, 'k', 0, "check-embedded", 0, &opt.mode, MODE_CHECK_EMBEDDED },
{ F_TFNC, 'u', 0, "update", (opt_handler_t)hash_file_mode, 0, MODE_UPDATE },
{ F_TFNC, 0, 0, "missing", (opt_handler_t)hash_file_mode, 0, MODE_MISSING },
{ F_TFNC, 0, 0, "unverified", (opt_handler_t)hash_file_mode, 0, MODE_UNVERIFIED },
{ F_UFLG, 'B', 0, "benchmark", 0, &opt.mode, MODE_BENCHMARK },
{ F_UFLG, 0, 0, "torrent", 0, &opt.mode, MODE_TORRENT },
{ F_VFNC, 0, 0, "list-hashes", (opt_handler_t)list_hashes, 0, 0 },
{ F_VFNC, 'h', 0, "help", (opt_handler_t)print_help, 0, 0 },
{ F_VFNC, 'V', 0, "version", (opt_handler_t)print_version, 0, 0 },
{ F_VFNC, 'v', 0, "verbose", (opt_handler_t)on_verbose, 0, 0 },
/* hash functions options */
{ F_VFNC, 'a', 0, "all", (opt_handler_t)add_hash_id, 0, RHASH_ALL_HASHES },
{ F_VFNC, 'C', 0, "crc32", (opt_handler_t)add_hash_id, 0, RHASH_CRC32 },
{ F_VFNC, 0, 0, "crc32c", (opt_handler_t)add_hash_id, 0, RHASH_CRC32C },
{ F_VFNC, 0, 0, "md4", (opt_handler_t)add_hash_id, 0, RHASH_MD4 },
{ F_VFNC, 'M', 0, "md5", (opt_handler_t)add_hash_id, 0, RHASH_MD5 },
{ F_VFNC, 'H', 0, "sha1", (opt_handler_t)add_hash_id, 0, RHASH_SHA1 },
{ F_VFNC, 0, 0, "sha224", (opt_handler_t)add_hash_id, 0, RHASH_SHA224 },
{ F_VFNC, 0, 0, "sha256", (opt_handler_t)add_hash_id, 0, RHASH_SHA256 },
{ F_VFNC, 0, 0, "sha384", (opt_handler_t)add_hash_id, 0, RHASH_SHA384 },
{ F_VFNC, 0, 0, "sha512", (opt_handler_t)add_hash_id, 0, RHASH_SHA512 },
{ F_VFNC, 0, 0, "sha3-224", (opt_handler_t)add_hash_id, 0, RHASH_SHA3_224 },
{ F_VFNC, 0, 0, "sha3-256", (opt_handler_t)add_hash_id, 0, RHASH_SHA3_256 },
{ F_VFNC, 0, 0, "sha3-384", (opt_handler_t)add_hash_id, 0, RHASH_SHA3_384 },
{ F_VFNC, 0, 0, "sha3-512", (opt_handler_t)add_hash_id, 0, RHASH_SHA3_512 },
{ F_VFNC, 0, 0, "tiger", (opt_handler_t)add_hash_id, 0, RHASH_TIGER },
{ F_VFNC, 'T', 0, "tth", (opt_handler_t)add_hash_id, 0, RHASH_TTH },
{ F_VFNC, 0, 0, "btih", (opt_handler_t)add_hash_id, 0, RHASH_BTIH },
{ F_VFNC, 'E', 0, "ed2k", (opt_handler_t)add_hash_id, 0, RHASH_ED2K },
{ F_VFNC, 'A', 0, "aich", (opt_handler_t)add_hash_id, 0, RHASH_AICH },
{ F_VFNC, 'G', 0, "gost12-256", (opt_handler_t)add_hash_id, 0, RHASH_GOST12_256 },
{ F_VFNC, 0, 0, "gost12-512", (opt_handler_t)add_hash_id, 0, RHASH_GOST12_512 },
{ F_VFNC, 0, 0, "gost94", (opt_handler_t)add_hash_id, 0, RHASH_GOST94 },
{ F_VFNC, 0, 0, "gost94-cryptopro", (opt_handler_t)add_hash_id, 0, RHASH_GOST94_CRYPTOPRO },
/* legacy: the following two gost options are left for compatibility */
{ F_VFNC, 0, 0, "gost", (opt_handler_t)add_hash_id, 0, RHASH_GOST94 },
{ F_VFNC, 0, 0, "gost-cryptopro", (opt_handler_t)add_hash_id, 0, RHASH_GOST94_CRYPTOPRO },
{ F_VFNC, 'W', 0, "whirlpool", (opt_handler_t)add_hash_id, 0, RHASH_WHIRLPOOL },
{ F_VFNC, 0, 0, "ripemd160", (opt_handler_t)add_hash_id, 0, RHASH_RIPEMD160 },
{ F_VFNC, 0, 0, "has160", (opt_handler_t)add_hash_id, 0, RHASH_HAS160 },
{ F_VFNC, 0, 0, "snefru128", (opt_handler_t)add_hash_id, 0, RHASH_SNEFRU128 },
{ F_VFNC, 0, 0, "snefru256", (opt_handler_t)add_hash_id, 0, RHASH_SNEFRU256 },
{ F_VFNC, 0, 0, "edonr256", (opt_handler_t)add_hash_id, 0, RHASH_EDONR256 },
{ F_VFNC, 0, 0, "edonr512", (opt_handler_t)add_hash_id, 0, RHASH_EDONR512 },
{ F_VFNC, 0, 0, "blake2s", (opt_handler_t)add_hash_id, 0, RHASH_BLAKE2S },
{ F_VFNC, 0, 0, "blake2b", (opt_handler_t)add_hash_id, 0, RHASH_BLAKE2B },
{ F_VFNC, 0, 0, "blake3", (opt_handler_t)add_hash_id, 0, RHASH_BLAKE3 },
/* output formats */
{ F_UFLG, 0, 0, "sfv", 0, &opt.fmt, FMT_SFV },
{ F_UFLG, 0, 0, "bsd", 0, &opt.fmt, FMT_BSD },
{ F_UFLG, 0, 0, "simple", 0, &opt.fmt, FMT_SIMPLE },
{ F_UFLG, 0, 0, "one-hash", 0, &opt.fmt, FMT_ONE_HASH },
{ F_UFLG, 'L', 0, "ed2k-link", 0, &opt.fmt, FMT_ED2K_LINK },
{ F_UFLG, 'g', 0, "magnet", 0, &opt.fmt, FMT_MAGNET },
{ F_UFLG, 0, 0, "uppercase", 0, &opt.flags, OPT_UPPERCASE },
{ F_UFLG, 0, 0, "lowercase", 0, &opt.flags, OPT_LOWERCASE },
{ F_TSTR, 0, 0, "template", 0, &opt.template_file, 0 },
{ F_CSTR, 'p', 0, "printf", 0, &opt.printf_str, 0 },
/* other options */
{ F_UFLG, 'r', 'R', "recursive", 0, &opt.flags, OPT_RECURSIVE },
{ F_TFNC, 'm', 0, "message", (opt_handler_t)add_special_file, 0, FileIsData },
{ F_TFNC, 0, 0, "file-list", (opt_handler_t)add_special_file, 0, FileIsList },
{ F_UFLG, 0, 0, "follow", 0, &opt.flags, OPT_FOLLOW },
{ F_UFLG, 0, 0, "brief", 0, &opt.flags, OPT_BRIEF },
{ F_UFLG, 0, 0, "gost-reverse", 0, &opt.flags, OPT_GOST_REVERSE },
{ F_UFLG, 0, 0, "skip-ok", 0, &opt.flags, OPT_SKIP_OK },
{ F_UFLG, 0, 0, "ignore-missing", 0, &opt.flags, OPT_IGNORE_MISSING },
{ F_UFLG, 'i', 0, "ignore-case", 0, &opt.flags, OPT_IGNORE_CASE },
{ F_UENC, 'P', 0, "percents", 0, &opt.flags, OPT_PERCENTS },
{ F_UFLG, 0, 0, "speed", 0, &opt.flags, OPT_SPEED },
{ F_UFLG, 'e', 0, "embed-crc", 0, &opt.flags, OPT_EMBED_CRC },
{ F_CSTR, 0, 0, "embed-crc-delimiter", 0, &opt.embed_crc_delimiter, 0 },
{ F_PFNC, 0, 0, "path-separator", (opt_handler_t)set_path_separator, 0, 0 },
{ F_TOUT, 'o', 0, "output", 0, &opt.output, 0 },
{ F_TOUT, 'l', 0, "log", 0, &opt.log, 0 },
{ F_PFNC, 'q', 0, "accept", (opt_handler_t)add_file_suffix, 0, MASK_ACCEPT },
{ F_PFNC, 't', 0, "crc-accept", (opt_handler_t)add_file_suffix, 0, MASK_CRC_ACCEPT },
{ F_PFNC, 0, 0, "exclude", (opt_handler_t)add_file_suffix, 0, MASK_EXCLUDE },
{ F_VFNC, 0, 0, "video", (opt_handler_t)accept_video, 0, 0 },
{ F_VFNC, 0, 0, "nya", (opt_handler_t)nya, 0, 0 },
{ F_PFNC, 0, 0, "max-depth", (opt_handler_t)set_max_depth, 0, 0 },
{ F_UFLG, 0, 0, "bt-private", 0, &opt.flags, OPT_BT_PRIVATE },
{ F_UFLG, 0, 0, "bt-transmission", 0, &opt.flags, OPT_BT_TRANSMISSION },
{ F_PFNC, 0, 0, "bt-piece-length", (opt_handler_t)set_bt_piece_length, 0, 0 },
{ F_UFNC, 0, 0, "bt-announce", (opt_handler_t)bt_announce, 0, 0 },
{ F_TSTR, 0, 0, "bt-batch", 0, &opt.bt_batch_file, 0 },
{ F_UFLG, 0, 0, "benchmark-raw", 0, &opt.flags, OPT_BENCH_RAW },
{ F_UFLG, 0, 0, "no-detect-by-ext", 0, &opt.flags, OPT_NO_DETECT_BY_EXT },
{ F_UFLG, 0, 0, "no-path-escaping", 0, &opt.flags, OPT_NO_PATH_ESCAPING },
{ F_UFLG, 0, 0, "hex", 0, &opt.flags, OPT_HEX },
{ F_UFLG, 0, 0, "base32", 0, &opt.flags, OPT_BASE32 },
{ F_UFLG, 'b', 0, "base64", 0, &opt.flags, OPT_BASE64 },
{ F_PFNC, 0, 0, "openssl", (opt_handler_t)openssl_flags, 0, 0 },
/* for compatibility */
{ F_PFNC, 0, 0, "maxdepth", (opt_handler_t)set_max_depth, 0, 0 },
#ifdef _WIN32 /* code pages (windows only) */
{ F_UENC, 0, 0, "utf8", 0, &opt.flags, OPT_UTF8 },
{ F_UENC, 0, 0, "win", 0, &opt.flags, OPT_ENC_WIN },
{ F_UENC, 0, 0, "dos", 0, &opt.flags, OPT_ENC_DOS },
/* legacy: the following two options are left for compatibility */
{ F_UENC, 0, 0, "ansi", 0, &opt.flags, OPT_ENC_WIN },
{ F_UENC, 0, 0, "oem", 0, &opt.flags, OPT_ENC_DOS },
#endif
{ 0,0,0,0,0,0,0 }
};
cmdline_opt_t cmdline_file = { F_TFNC, 0, 0, "FILE", (opt_handler_t)add_special_file, 0, 0 };
/**
* Log an error about unknown option and exit the program.
*
* @param option_name the name of the unknown option encountered
*/
static void fail_on_unknow_option(const char* option_name)
{
die(_("unknown option: %s\n"), (option_name ? option_name : "?"));
}
/* structure to store command line option information */
typedef struct parsed_option_t
{
cmdline_opt_t* o;
const char* name; /* the parsed option name */
char buf[4];
void* parameter; /* option argument, if required */
} parsed_option_t;
/**
* Process given command line option
*
* @param opts the structure to store results of option processing
* @param option option to process
*/
static void apply_option(options_t* opts, parsed_option_t* option)
{
cmdline_opt_t* o = option->o;
unsigned short option_type = o->type;
char* value = NULL;
/* check if option requires a parameter */
if (is_param_required(option_type)) {
if (!option->parameter) {
die(_("argument is required for option %s\n"), option->name);
}
#ifdef _WIN32
if (option_type == F_TOUT || option_type == F_TFNC || option_type == F_TSTR) {
/* leave the value in UTF-16 */
value = (char*)rsh_wcsdup((wchar_t*)option->parameter);
}
else if (option_type == F_UFNC) {
/* convert from UTF-16 to UTF-8 */
value = convert_wcs_to_str((wchar_t*)option->parameter, ConvertToUtf8 | ConvertExact);
} else {
/* convert from UTF-16 */
value = convert_wcs_to_str((wchar_t*)option->parameter, ConvertToPrimaryEncoding);
}
rsh_vector_add_ptr(opt.mem, value);
#else
value = (char*)option->parameter;
#endif
}
/* process option, choosing the method by type */
switch (option_type) {
case F_UFLG:
case F_UENC:
*(unsigned*)((char*)opts + ((char*)o->ptr - (char*)&opt)) |= o->param;
break;
case F_CSTR:
case F_TSTR:
case F_TOUT:
/* save the option parameter */
*(char**)((char*)opts + ((char*)o->ptr - (char*)&opt)) = value;
break;
case F_PFNC:
case F_TFNC:
case F_UFNC:
/* call option parameter handler */
( (void(*)(options_t*, char*, unsigned))o->handler )(opts, value, o->param);
break;
case F_VFNC:
( (void(*)(options_t*, unsigned))o->handler )(opts, o->param); /* call option handler */
break;
case F_PRNT:
log_msg("%s", (char*)o->ptr);
rsh_exit(0);
break;
default:
assert(0); /* impossible option type */
}
}
#ifdef _WIN32
# define rsh_tgetenv(name) _wgetenv(name)
#else
# define rsh_tgetenv(name) getenv(name)
#endif
#define COUNTOF(array) (sizeof(array) / sizeof(*array))
enum ConfigLookupFlags
{
ConfFlagNeedSplit = 8,
ConfFlagNoVars = 16
};
/**
* Check if a config file, specified by path subparts, is a regular file.
* On success the resulting path is stored as rhash_data.config_file.
*
* @param path_parts subparts of the path
* @param flags check flags
* @return 1 if the file is regular, 0 otherwise
*/
static int try_config(ctpath_t path_parts[], unsigned flags)
{
const size_t parts_count = flags & 3;
tpath_t allocated = NULL;
ctpath_t path = NULL;
size_t i;
for (i = 0; i < parts_count; i++) {
ctpath_t sub_path = path_parts[i];
if (sub_path[0] == RSH_T('$') && !(flags & ConfFlagNoVars)) {
sub_path = rsh_tgetenv(sub_path + 1);
if (!sub_path || !sub_path[0]) {
free(allocated);
return 0;
}
#ifndef _WIN32
/* check if the variable should be splitted */
if (flags == (2 | ConfFlagNeedSplit) && i == 0) {
tpath_t next;
ctpath_t parts[2];
parts[1] = path_parts[1];
sub_path = allocated = rsh_strdup(sub_path);
do {
next = strchr(sub_path, ':');
if (next)
*(next++) = '\0';
if (sub_path[0]) {
parts[0] = sub_path;
if (try_config(parts, COUNTOF(parts) | ConfFlagNoVars)) {
free(allocated);
return 1;
}
}
sub_path = next;
} while (sub_path);
free(allocated);
return 0;
}
#endif
}
if (path) {
tpath_t old_allocated = allocated;
path = allocated = make_tpath(path, sub_path);
free(old_allocated);
} else {
path = sub_path;
}
}
assert(!rhash_data.config_file.real_path);
{
unsigned init_flags = FileInitRunFstat | (!allocated ? FileInitReusePath : 0);
int res = file_init(&rhash_data.config_file, path, init_flags);
free(allocated);
if (res == 0 && FILE_ISREG(&rhash_data.config_file))
return 1;
file_cleanup(&rhash_data.config_file);
return 0;
}
}
/**
* Search for config file.
*
* @return 1 if config file is found, 0 otherwise
*/
static int find_conf_file(void)
{
#ifndef SYSCONFDIR
# define SYSCONFDIR "/etc"
#endif
#ifndef _WIN32
/* Linux/Unix part */
static ctpath_t xdg_conf_home[2] = { "$XDG_CONFIG_HOME", "rhash/rhashrc" };
static ctpath_t xdg_conf_default[2] = { "$HOME", ".config/rhash/rhashrc" };
static ctpath_t xdg_conf_dirs[2] = { "$XDG_CONFIG_DIRS", "rhash/rhashrc" };
static ctpath_t home_conf[2] = { "$HOME", ".rhashrc" };
static ctpath_t sysconf_dir[1] = { SYSCONFDIR "/rhashrc" };
return (try_config(xdg_conf_home, COUNTOF(xdg_conf_home)) ||
try_config(xdg_conf_default, COUNTOF(xdg_conf_default)) ||
try_config(xdg_conf_dirs, COUNTOF(xdg_conf_dirs) | ConfFlagNeedSplit) ||
try_config(home_conf, COUNTOF(home_conf)) ||
try_config(sysconf_dir, COUNTOF(sysconf_dir)));
#else /* _WIN32 */
static ctpath_t app_data[2] = { L"$APPDATA", L"RHash\\rhashrc" };
static ctpath_t home_conf[3] = { L"$HOMEDRIVE", L"$HOMEPATH", L"rhashrc" };
if (try_config(app_data, COUNTOF(app_data)) || try_config(home_conf, COUNTOF(home_conf))) {
return 1;
} else {
tpath_t prog_dir[2];
prog_dir[0] = get_program_dir();
prog_dir[1] = L"rhashrc";
return try_config((ctpath_t*)prog_dir, COUNTOF(prog_dir));
}
#endif /* _WIN32 */
}
/**
* Parse config file of the program.
*
* @return 0 on success, -1 on fail
*/
static int read_config(void)
{
#define LINE_BUF_SIZE 2048
char buf[LINE_BUF_SIZE];
FILE* fd;
parsed_option_t option;
unsigned line_number = 0;
int res;
/* initialize conf_opt */
memset(&conf_opt, 0, sizeof(opt));
conf_opt.find_max_depth = -1;
if (!find_conf_file()) return 0;
assert(!!rhash_data.config_file.real_path);
assert(FILE_ISREG(&rhash_data.config_file));
fd = file_fopen(&rhash_data.config_file, FOpenRead);
if (!fd) return -1;
while (fgets(buf, LINE_BUF_SIZE, fd)) {
size_t index;
cmdline_opt_t* t;
char* line = str_trim(buf);
char* name;
char* value;
line_number++;
if (*line == 0 || IS_COMMENT(*line))
continue;
/* search for '=' */
index = strcspn(line, "=");
if (line[index] == 0) {
log_warning(_("%s:%u: can't parse line \"%s\"\n"),
file_get_print_path(&rhash_data.config_file, FPathUtf8 | FPathNotNull),
line_number, line);
continue;
}
line[index] = 0;
name = str_trim(line);
for (t = cmdline_opt; t->type; t++) {
if (strcmp(name, t->long_name) == 0) {
break;
}
}
if (!t->type) {
log_warning(_("%s:%u: unknown option \"%s\"\n"),
file_get_print_path(&rhash_data.config_file, FPathUtf8 | FPathNotNull),
line_number, line);
continue;
}
value = str_trim(line + index + 1);
/* process a long option */
if (is_param_required(t->type)) {
rsh_vector_add_ptr(opt.mem, (value = rsh_strdup(value)));;
} else {
/* possible boolean values for a config file variable */
static const char* strings[] = { "on", "yes", "true", 0 };
const char** cmp;
for (cmp = strings; *cmp && strcmp(value, *cmp); cmp++);
if (*cmp == 0) continue;
}
option.name = name;
option.parameter = value;
option.o = t;
apply_option(&conf_opt, &option);
}
res = fclose(fd);
#ifdef _WIN32
if ( (opt.flags & OPT_ENCODING) == 0 )
opt.flags |= (conf_opt.flags & OPT_ENCODING);
#endif
return (res == 0 ? 0 : -1);
}
/**
* Find long option info, by it's name and retrieve its parameter if required.
* Error is reported for unknown options.
*
* @param option structure to receive the parsed option info
* @param parg pointer to a command line argument
*/
static void parse_long_option(parsed_option_t* option, rsh_tchar*** parg)
{
size_t length;
rsh_tchar* eq_sign;
cmdline_opt_t* t;
char* name;
#ifdef _WIN32
rsh_tchar* wname = **parg; /* "--" */
int fail = 0;
assert((**parg)[0] == L'-' && (**parg)[1] == L'-');
/* search for the '=' sign */
length = ((eq_sign = wcschr(wname, L'=')) ? (size_t)(eq_sign - wname) : wcslen(wname));
option->name = name = (char*)rsh_malloc(length + 1);
rsh_vector_add_ptr(opt.mem, name);
if (length < 30) {
size_t i = 0;
for (; i < length; i++) {
if (((unsigned)wname[i]) <= 128) name[i] = (char)wname[i];
else {
fail = 1;
break;
}
}
name[i] = '\0';
name += 2; /* skip "--" */
length -= 2;
} else fail = 1;
if (fail)
fail_on_unknow_option(convert_wcs_to_str(**parg, ConvertToUtf8));
#else
option->name = **parg;
name = **parg + 2; /* skip "--" */
length = ((eq_sign = strchr(name, '=')) ? (size_t)(eq_sign - name) : strlen(name));
name[length] = '\0';
#endif
/* search for the option by its name */
for (t = cmdline_opt; t->type && (strncmp(name, t->long_name, length) != 0 ||
strlen(t->long_name) != length); t++) {
}
if (!t->type) {
fail_on_unknow_option(option->name); /* report error and exit */
}
option->o = t; /* store the option found */
if (is_param_required(t->type)) {
/* store parameter without a code page conversion */
option->parameter = (eq_sign ? eq_sign + 1 : *(++(*parg)));
}
}
/**
* Parsed program command line.
*/
struct parsed_cmd_line_t
{
blocks_vector_t options; /* array of parsed options */
int argc;
char** argv;
#ifdef _WIN32
rsh_tchar** warg; /* program arguments in Unicode */
#endif
};
/**
* Allocate parsed option.
*
* @param cmd_line the command line to store the parsed option into
* @return allocated parsed option
*/
static parsed_option_t* new_option(struct parsed_cmd_line_t* cmd_line)
{
rsh_blocks_vector_add_empty(&cmd_line->options, 16, sizeof(parsed_option_t));
return rsh_blocks_vector_get_item(&cmd_line->options, cmd_line->options.size - 1, 16, parsed_option_t);
}
/**
* Parse command line arguments.
*
* @param cmd_line structure to store parsed options data
*/
static void parse_cmdline_options(struct parsed_cmd_line_t* cmd_line)
{
int argc;
int b_opt_end = 0;
rsh_tchar** parg;
rsh_tchar** end_arg;
parsed_option_t* next_opt;
#ifdef _WIN32
parg = cmd_line->warg = CommandLineToArgvW(GetCommandLineW(), &argc);
RSH_REQUIRE(parg && argc >= 1, "CommandLineToArgvW failed\n");
#else
argc = cmd_line->argc;
parg = cmd_line->argv;
#endif
/* allocate array for files */
end_arg = parg + argc;
/* loop by program arguments */
for (parg++; parg < end_arg; parg++) {
/* if argument is not an option */
if ((*parg)[0] != RSH_T('-') || (*parg)[1] == 0 || b_opt_end) {
/* it's a file, note that '-' is interpreted as stdin */
next_opt = new_option(cmd_line);
next_opt->name = "";
next_opt->o = &cmdline_file;
next_opt->parameter = *parg;
} else if ((*parg)[1] == L'-' && (*parg)[2] == 0) {
b_opt_end = 1; /* string "--" means end of options */
continue;
} else if ((*parg)[1] == RSH_T('-')) {
next_opt = new_option(cmd_line);
parse_long_option(next_opt, &parg);
/* process encoding and -o/-l options early */
if (is_output_modifier(next_opt->o->type)) {
apply_option(&opt, next_opt);
}
} else if ((*parg)[1] != 0) {
/* found '-' */
rsh_tchar* ptr;
/* parse short options. A string of several characters is interpreted
* as separate short options */
for (ptr = *parg + 1; *ptr; ptr++) {
cmdline_opt_t* t;
char ch = (char)*ptr;
#ifdef _WIN32
if (((unsigned)*ptr) >= 128) {
ptr[1] = 0;
fail_on_unknow_option(convert_wcs_to_str(ptr, ConvertToUtf8));
}
#endif
next_opt = new_option(cmd_line);
next_opt->buf[0] = '-', next_opt->buf[1] = ch, next_opt->buf[2] = '\0';
next_opt->name = next_opt->buf;
next_opt->parameter = NULL;
/* search for the short option */
for (t = cmdline_opt; t->type && ch != t->short1 && ch != t->short2; t++);
if (!t->type) fail_on_unknow_option(next_opt->buf);
next_opt->o = t;
if (is_param_required(t->type)) {
next_opt->parameter = (ptr[1] ? ptr + 1 : *(++parg));
if (!next_opt->parameter) {
/* note: need to check for parameter here, for early -o/-l options processing */
die(_("argument is required for option %s\n"), next_opt->name);
}
}
/* process encoding and -o/-l options early */
if (is_output_modifier(t->type)) {
apply_option(&opt, next_opt);
}
if (next_opt->parameter) break; /* a parameter ends the short options string */
}
}
} /* for */
}
/**
* Apply all parsed command line options: set binary flags, store strings,
* and do complex options handling by calling callbacks.
*
* @param cmd_line the parsed options information
*/
static void apply_cmdline_options(struct parsed_cmd_line_t* cmd_line)
{
size_t count = cmd_line->options.size;
size_t i;
for (i = 0; i < count; i++) {
parsed_option_t* o = (parsed_option_t*)rsh_blocks_vector_get_ptr(
&cmd_line->options, i, 16, sizeof(parsed_option_t));
/* process the option, if it was not applied early */
if (!is_output_modifier(o->o->type)) {
apply_option(&opt, o);
}
}
/* if no formatting options were specified at the command line */
if (!opt.printf_str && !opt.template_file && !opt.hash_mask && !opt.fmt) {
/* copy the format from config */
opt.printf_str = conf_opt.printf_str;
opt.template_file = conf_opt.template_file;
}
opt.fmt |= (opt.printf_str ? FMT_PRINTF : 0) | (opt.template_file ? FMT_FILE_TEMPLATE : 0);
if (!(opt.fmt & FMT_PRINTF_MASK)) {
if (!opt.fmt) opt.fmt = conf_opt.fmt;
if (!opt.hash_mask) opt.hash_mask = conf_opt.hash_mask;
}
if (!opt.mode && !opt.update_file) {
opt.mode = conf_opt.mode;
opt.update_file = conf_opt.update_file;
}
if (!(opt.flags & OPT_FMT_MODIFIERS))
opt.flags |= conf_opt.flags & OPT_FMT_MODIFIERS;
opt.flags |= conf_opt.flags & ~OPT_FMT_MODIFIERS; /* copy the rest of options */
if (!opt.verbose)
opt.verbose = conf_opt.verbose;
if (opt.files_accept == 0) {
opt.files_accept = conf_opt.files_accept;
conf_opt.files_accept = 0;
}
if (opt.files_exclude == 0) {
opt.files_exclude = conf_opt.files_exclude;
conf_opt.files_exclude = 0;
}
if (opt.crc_accept == 0) {
opt.crc_accept = conf_opt.crc_accept;
conf_opt.crc_accept = 0;
}
if (opt.bt_announce == 0) {
opt.bt_announce = conf_opt.bt_announce;
conf_opt.bt_announce = 0;
}
if (opt.embed_crc_delimiter == 0) opt.embed_crc_delimiter = conf_opt.embed_crc_delimiter;
if (!opt.path_separator) opt.path_separator = conf_opt.path_separator;
if (opt.flags & OPT_EMBED_CRC) add_hash_id(&opt, RHASH_CRC32);
if (!opt.openssl_mask) opt.openssl_mask = conf_opt.openssl_mask;
if (opt.find_max_depth < 0) opt.find_max_depth = conf_opt.find_max_depth;
if (!(opt.flags & OPT_RECURSIVE)) opt.find_max_depth = 0;
opt.search_data->max_depth = opt.find_max_depth;
/* set defaults */
if (opt.embed_crc_delimiter == 0) opt.embed_crc_delimiter = " ";
}
/**
* Try to detect hash functions options from program name.
*
* @param progName the program name
*/
static void set_default_hash_mask(const char* progName)
{
const char* p;
char* buf;
/* do nothing if hash functions are already selected by command line or config */
if (opt.hash_mask != 0)
return;
/* remove directory name from the path */
p = strrchr(progName, '/');
if (p) progName = p + 1;
#ifdef _WIN32
p = strrchr(progName, '\\');
if (p) progName = p + 1;
#endif
/* convert the progName to lowercase */
buf = str_tolower(progName);
if (strstr(buf, "sfv") && opt.fmt == 0) opt.fmt = FMT_SFV;
if (strstr(buf, "bsd") && opt.fmt == 0) opt.fmt = FMT_BSD;
if (strstr(buf, "magnet") && opt.fmt == 0) opt.fmt = FMT_MAGNET;
if (strstr(buf, "ed2k-link") && opt.fmt == 0) opt.fmt |= FMT_ED2K_LINK;
if (strstr(buf, "one") && opt.fmt == 0) opt.fmt = FMT_ONE_HASH;
if (strstr(buf, "crc32c")) add_hash_id(&opt, RHASH_CRC32C);
else if (strstr(buf, "crc32")) add_hash_id(&opt, RHASH_CRC32);
if (strstr(buf, "md4")) add_hash_id(&opt, RHASH_MD4);
if (strstr(buf, "md5")) add_hash_id(&opt, RHASH_MD5);
if (strstr(buf, "sha1")) add_hash_id(&opt, RHASH_SHA1);
if (strstr(buf, "sha256")) add_hash_id(&opt, RHASH_SHA256);
if (strstr(buf, "sha512")) add_hash_id(&opt, RHASH_SHA512);
if (strstr(buf, "sha224")) add_hash_id(&opt, RHASH_SHA224);
if (strstr(buf, "sha384")) add_hash_id(&opt, RHASH_SHA384);
if (strstr(buf, "sha3-256")) add_hash_id(&opt, RHASH_SHA3_256);
if (strstr(buf, "sha3-512")) add_hash_id(&opt, RHASH_SHA3_512);
if (strstr(buf, "sha3-224")) add_hash_id(&opt, RHASH_SHA3_224);
if (strstr(buf, "sha3-384")) add_hash_id(&opt, RHASH_SHA3_384);
if (strstr(buf, "tiger")) add_hash_id(&opt, RHASH_TIGER);
if (strstr(buf, "tth")) add_hash_id(&opt, RHASH_TTH);
if (strstr(buf, "btih")) add_hash_id(&opt, RHASH_BTIH);
if (strstr(buf, "aich")) add_hash_id(&opt, RHASH_AICH);
if (strstr(buf, "gost12-256")) add_hash_id(&opt, RHASH_GOST12_256);
if (strstr(buf, "gost12-512")) add_hash_id(&opt, RHASH_GOST12_512);
if (strstr(buf, "gost94-cryptopro")) add_hash_id(&opt, RHASH_GOST94_CRYPTOPRO);
else if (strstr(buf, "gost94")) add_hash_id(&opt, RHASH_GOST94);
if (strstr(buf, "has160")) add_hash_id(&opt, RHASH_HAS160);
if (strstr(buf, "ripemd160") || strstr(buf, "rmd160")) add_hash_id(&opt, RHASH_RIPEMD160);
if (strstr(buf, "whirlpool")) add_hash_id(&opt, RHASH_WHIRLPOOL);
if (strstr(buf, "edonr256")) add_hash_id(&opt, RHASH_EDONR256);
if (strstr(buf, "edonr512")) add_hash_id(&opt, RHASH_EDONR512);
if (strstr(buf, "blake2s")) add_hash_id(&opt, RHASH_BLAKE2S);
if (strstr(buf, "blake2b")) add_hash_id(&opt, RHASH_BLAKE2B);
if (strstr(buf, "blake3")) add_hash_id(&opt, RHASH_BLAKE3);
if (strstr(buf, "snefru256")) add_hash_id(&opt, RHASH_SNEFRU128);
if (strstr(buf, "snefru128")) add_hash_id(&opt, RHASH_SNEFRU256);
else if (strstr(buf, "ed2k")) add_hash_id(&opt, RHASH_ED2K);
if (!opt.hash_mask && opt.fmt == FMT_MAGNET) {
add_hash_id(&opt, RHASH_TTH);
add_hash_id(&opt, RHASH_ED2K);
add_hash_id(&opt, RHASH_AICH);
}
free(buf);
}
/**
* Destroy a parsed options object.
*
* @param o pointer to the options object to destroy
*/
void options_destroy(struct options_t* o)
{
file_mask_free(o->files_accept);
file_mask_free(o->files_exclude);
file_mask_free(o->crc_accept);
rsh_vector_free(o->bt_announce);
rsh_vector_free(o->mem);
file_search_data_free(o->search_data);
}
enum {
ChkMode,
ChkFmt
};
/**
* Ensure that the specified bit_mask has only one bit set.
* Report error and exit the program on fail.
*
* @param what what to check
* @param bit_mask the bit_mask to check
*/
static void check_compatibility(int what, unsigned bit_mask)
{
if ((bit_mask & (bit_mask - 1)) == 0)
return;
die(what == ChkMode ?
_("incompatible program modes\n") :
_("incompatible formatting options\n"));
}
/**
* Check that options do not conflict with each other.
* Also make some final options processing steps.
*/
static void make_final_options_checks(void)
{
if (opt.verbose && !!rhash_data.config_file.real_path) {
/* note that the first log_msg call shall be made after setup_output() */
log_msg_file_t(_("Config file: %s\n"), &rhash_data.config_file);
}
if (opt.bt_batch_file)
opt.mode |= MODE_TORRENT;
else if (!opt.mode)
opt.mode = MODE_DEFAULT;
if (IS_MODE(MODE_TORRENT))
add_hash_id(&opt, RHASH_BTIH);
/* check options compatibility for program mode and output format */
if (opt.mode & ~(MODE_CHECK | MODE_UPDATE))
check_compatibility(ChkMode, opt.mode);
check_compatibility(ChkFmt, opt.fmt);
check_compatibility(ChkFmt, (opt.flags & OPT_FMT_MODIFIERS) | (opt.fmt & FMT_PRINTF_MASK));
if (!opt.crc_accept)
opt.crc_accept = file_mask_new_from_list(".sfv");
}
static struct parsed_cmd_line_t cmd_line;
static void cmd_line_destroy(void)
{
rsh_blocks_vector_destroy(&cmd_line.options);
#ifdef _WIN32
LocalFree(cmd_line.warg);
#endif
}
/**
* Parse command line options.
*
* @param argv program arguments
*/
void read_options(int argc, char* argv[])
{
opt.mem = rsh_vector_new_simple();
opt.search_data = file_search_data_new();
opt.find_max_depth = -1;
/* initialize cmd_line */
memset(&cmd_line, 0, sizeof(cmd_line));
rsh_blocks_vector_init(&cmd_line.options);
cmd_line.argv = argv;
cmd_line.argc = argc;
rsh_install_exit_handler(cmd_line_destroy);
/* parse command line and apply encoding options */
parse_cmdline_options(&cmd_line);
read_config();
errno = 0;
/* setup the program output */
IF_WINDOWS(setup_console());
setup_output();
apply_cmdline_options(&cmd_line); /* process the rest of command line options */
options_destroy(&conf_opt);
/* options were processed, so we don't need them any more */
rsh_remove_exit_handler();
cmd_line_destroy();
make_final_options_checks();
set_default_hash_mask(argv[0]); /* detect default hash functions from program name */
}
rhash-1.4.6/find_file.c 0000664 0000000 0000000 00000032672 15010476501 013423 0 ustar root root /* find_file.c - functions for recursive scan of directories. */
#include "find_file.h"
#include "output.h"
#include "parse_cmdline.h"
#include "platform.h"
#include "win_utils.h"
#include
#include
#include
#include
#include
#ifdef _WIN32
# define WIN32_LEAN_AND_MEAN
# include
#else
# include /* opendir/readdir */
#endif
#define IS_DASH_TSTR(s) ((s)[0] == RSH_T('-') && (s)[1] == RSH_T('\0'))
#define IS_CURRENT_OR_PARENT_DIR(s) ((s)[0]=='.' && (!(s)[1] || ((s)[1] == '.' && !(s)[2])))
#define IS_CURRENT_OR_PARENT_DIRW(s) ((s)[0]==L'.' && (!(s)[1] || ((s)[1] == L'.' && !(s)[2])))
#define RF_BLOCK_SIZE 256
#define add_root_file(data, file) rsh_blocks_vector_add(&(data)->root_files, (file), RF_BLOCK_SIZE, sizeof(file_t))
#define get_root_file(data, index) rsh_blocks_vector_get_item(&(data)->root_files, (index), RF_BLOCK_SIZE, file_t)
static int dir_scan(file_t* start_dir, file_search_data* data);
/**
* Allocate and initialize file search context.
* The allocated context must be freed by file_search_data_free.
*
* @return pointer to the allocated file search context
*/
file_search_data* file_search_data_new(void)
{
file_search_data* data = (file_search_data*)rsh_malloc(sizeof(file_search_data));
memset(data, 0, sizeof(file_search_data));
rsh_blocks_vector_init(&data->root_files);
data->max_depth = -1;
return data;
}
/**
* Add a special file, like stdin or data message, to file search context.
*
* @param context file search context
* @param path file path
* @param file_mode bitmask consisting of FileIsStdin and FileIsData bits
*/
static void file_search_add_special_file(file_search_data* context, unsigned file_mode, tstr_t str)
{
file_t file;
char* filename = (file_mode & FileIsStdin ? "(stdin)" : "(message)");
char* ext_data = 0;
if (file_mode & FileIsData)
{
#ifdef _WIN32
ext_data = convert_wcs_to_str(str, ConvertToUtf8 | ConvertExact);
/* we assume that this conversion always succeeds and the following condition is never met */
if (!ext_data)
return;
#else
ext_data = rsh_strdup(str);
#endif
}
file_init_by_print_path(&file, NULL, filename, file_mode);
if (file_mode & FileIsData)
{
file.data = ext_data;
file.size = strlen(ext_data);
}
add_root_file(context, &file);
}
/**
* Add a file to the file search context for later processing.
*
* @param data file search context
* @param path file path
* @param file_mode bitmask consisting of FileIsList and FileIsData bits
*/
void file_search_add_file(file_search_data* data, tstr_t path, unsigned file_mode)
{
#ifdef _WIN32
size_t length, index;
wchar_t* p;
#endif
file_t file;
file_mode &= (FileIsList | FileIsData);
assert((file_mode & (file_mode - 1)) == 0);
file_mode |= FileIsRoot; /* mark the file as obtained from the command line */
if ((file_mode & FileIsData) != 0)
{
file_search_add_special_file(data, file_mode, path);
return;
}
if (IS_DASH_TSTR(path))
{
file_search_add_special_file(data, (file_mode | FileIsStdin), NULL);
return;
}
#ifdef _WIN32
/* remove trailing path separators, except a separator preceded by ':' */
p = wcschr(path, L'\0') - 1;
for (; p > path && IS_PATH_SEPARATOR_W(*p) && p[-1] != L':'; p--)
*p = 0;
length = p - path + 1;
index = wcscspn(path, L"*?");
if (index < length && wcscspn(path + index, L"/\\") >= (length - index))
{
/* a wildcard is found without a directory separator after it */
wchar_t* parent;
WIN32_FIND_DATAW d;
HANDLE handle;
/* Expand the wildcard, found in the provided file path, and store the results into
* data->root_files. If the wildcard is not found then error is reported.
* NB, only wildcards in the basename (the last filename) of the path are expanded. */
/* find a directory separator before the file name */
for (; index > 0 && !IS_PATH_SEPARATOR(path[index]); index--);
parent = (IS_PATH_SEPARATOR(path[index]) ? path : 0);
handle = FindFirstFileW(path, &d);
if (INVALID_HANDLE_VALUE != handle)
{
do
{
int res;
tpath_t filepath;
if (IS_CURRENT_OR_PARENT_DIRW(d.cFileName))
continue;
/* skip directories unless we are in recursive mode */
if (data->max_depth == 0 && (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
continue;
filepath = make_wpath(parent, index + 1, d.cFileName);
if (!filepath)
continue;
res = file_init(&file, filepath, file_mode | FileInitUpdatePrintPathSlashes | FileInitRunFstat);
free(filepath);
/* convert file name */
if (res == 0 && !(opt.flags & OPT_UTF8) && !file_get_print_path(&file, FPathPrimaryEncoding))
res = -1;
/* quietly skip unconvertible file names and nonexistent files */
if (res < 0) {
data->errors_count++;
file_cleanup(&file);
continue;
}
add_root_file(data, &file);
}
while (FindNextFileW(handle, &d));
FindClose(handle);
}
else
{
/* report error on the specified wildcard */
file_init(&file, path, FileInitReusePath);
set_errno_from_last_file_error();
log_error_file_t(&file);
file_cleanup(&file);
data->errors_count++;
}
}
else
{
if (file_init(&file, path, file_mode | FileInitRunFstat) < 0) {
log_error_file_t(&file);
file_cleanup(&file);
data->errors_count++;
return;
}
if (!(opt.flags & OPT_UTF8) && !file_get_print_path(&file, FPathPrimaryEncoding)) {
log_error_msg_file_t(_("can't convert the file path to local encoding: %s\n"), &file);
file_cleanup(&file);
data->errors_count++;
return;
}
/* mark the file as obtained from the command line */
add_root_file(data, &file);
}
#else
/* init the file and test for its existence */
if (file_init(&file, path, file_mode | FileInitUseRealPathAsIs | FileInitRunLstat) < 0)
{
log_error_file_t(&file);
file_cleanup(&file);
data->errors_count++;
return;
}
add_root_file(data, &file);
#endif /* _WIN32 */
}
/**
* Free memory allocated by file search context.
*
* @param data pointer to the file search context
*/
void file_search_data_free(file_search_data* data)
{
if (data)
{
size_t i;
/* clean the memory allocated by file_t elements */
for (i = 0; i < data->root_files.size; i++)
{
file_t* file = get_root_file(data, i);
file_cleanup(file);
}
rsh_blocks_vector_destroy(&data->root_files);
free(data);
}
}
/**
* Search and process files, using file search context.
*
* @param data file search context
*/
void scan_files(file_search_data* data)
{
size_t i;
size_t count = data->root_files.size;
int skip_symlinked_dirs = (data->options & FIND_FOLLOW_SYMLINKS ? 0 : FUseLstat);
for (i = 0; i < count && !(data->options & FIND_CANCEL); i++)
{
file_t* file = get_root_file(data, i);
assert(!!(file->mode & FileIsRoot));
/* check if file is a directory */
if (FILE_ISLIST(file))
{
file_list_t list;
if (file_list_open(&list, file) < 0)
{
log_error_file_t(file);
continue;
}
while (file_list_read(&list))
{
data->callback(&list.current_file, data->callback_data);
}
file_list_close(&list);
}
else if (FILE_ISDIR(file))
{
/* silently skip symlinks to directories if required */
if (skip_symlinked_dirs && FILE_ISLNK(file))
continue;
if (data->max_depth != 0)
{
dir_scan(file, data);
}
else if ((data->options & FIND_LOG_ERRORS) != 0)
{
errno = EISDIR;
log_error_file_t(file);
}
}
else
{
/* process a regular file or a dash '-' path */
data->callback(file, data->callback_data);
}
}
}
/**
* An entry of a list containing content of a directory.
*/
typedef struct dir_entry
{
struct dir_entry* next;
tstr_t filename;
unsigned type; /* a directory, symlink, etc. */
} dir_entry;
/**
* Allocate and initialize a dir_entry. These entries form a linked list.
*
* @param next pointer to the list entry, before which the allocated one is inserted
* @param filename a filename to store in the dir_entry
* @param type type of the dir_entry
* @return allocated dir_entry
*/
static dir_entry* dir_entry_new(dir_entry* next, tstr_t filename, unsigned type)
{
dir_entry* e = (dir_entry*)malloc(sizeof(dir_entry));
if (!e)
return NULL;
if (filename)
{
e->filename = rsh_tstrdup(filename);
if (!e->filename)
{
free(e);
return NULL;
}
}
else
{
e->filename = NULL;
}
e->next = next;
e->type = type;
return e;
}
/**
* Allocate and insert a dir_entry with given filename and type in the list.
*
* @param at the position, before which the allocated entry will be inserted
* @param filename file name
* @param type file type
* @return pointer to the inserted dir_entry
*/
static dir_entry* dir_entry_insert(dir_entry** at, tstr_t filename, unsigned type)
{
dir_entry* e = dir_entry_new(*at, filename, type);
if (e)
*at = e;
return e;
}
/**
* Free the first entry of the list of dir_entry elements.
*
* @param p pointer to the list
*/
static void dir_entry_drop_head(dir_entry** p)
{
dir_entry* e = *p;
*p = e->next;
free(e->filename);
free(e);
}
/**
* Directory iterator.
*/
typedef struct dir_iterator
{
int count;
tpath_t dir_path;
} dir_iterator;
#define MAX_DIRS_DEPTH 64
/**
* Walk directory tree and call given callback function to process each file/directory.
*
* @param start_dir path to the directory to walk recursively
* @param data the options specifying how to walk the directory tree
* @return 0 on success, -1 on error
*/
static int dir_scan(file_t* start_dir, file_search_data* data)
{
dir_entry* dirs_stack = NULL; /* root of the dir_list */
dir_iterator* it;
int level = 0;
int max_depth = data->max_depth;
int options = data->options;
int fstat_bit = (data->options & FIND_FOLLOW_SYMLINKS ? FileInitRunFstat : FileInitRunLstat);
file_t file;
if (max_depth < 0 || max_depth >= MAX_DIRS_DEPTH)
max_depth = MAX_DIRS_DEPTH - 1;
/* skip the directory if max_depth == 0 */
if (!max_depth)
return 0;
if (!FILE_ISDIR(start_dir))
{
errno = ENOTDIR;
return -1;
}
/* check if we should descend into the root directory */
if ((options & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS)) == 0)
{
if (!data->callback(start_dir, data->callback_data))
return 0;
}
/* allocate array of counters of directory elements */
it = (dir_iterator*)malloc((MAX_DIRS_DEPTH + 1) * sizeof(dir_iterator));
if (!it)
return -1;
/* push dummy counter for the root element */
it[0].count = 1;
it[0].dir_path = 0;
memset(&file, 0, sizeof(file));
while (!(data->options & FIND_CANCEL))
{
dir_entry** insert_at;
tpath_t dir_path;
DIR* dp;
struct dirent* de;
/* go down from the tree */
while (--it[level].count < 0)
{
/* do not need this dir_path anymore */
free(it[level].dir_path);
if (--level < 0)
{
/* walked the whole tree */
assert(dirs_stack == NULL);
free(it);
return 0;
}
}
assert(level >= 0 && it[level].count >= 0);
/* take a filename from dirs_stack and construct the next path */
if (level)
{
assert(dirs_stack != NULL);
dir_path = make_tpath(it[level].dir_path, dirs_stack->filename);
dir_entry_drop_head(&dirs_stack);
}
else
{
/* the first cycle: start from a root directory */
dir_path = rsh_tstrdup(start_dir->real_path);
}
if (!dir_path)
continue;
/* fill the next level of directories */
level++;
assert(level < MAX_DIRS_DEPTH);
it[level].count = 0;
it[level].dir_path = dir_path;
if ((options & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS)) == FIND_WALK_DEPTH_FIRST)
{
int res = file_init(&file, dir_path, FileIsDir | fstat_bit);
/* check if we should skip the directory */
if (res < 0 || !data->callback(&file, data->callback_data))
{
if (res < 0 && (options & FIND_LOG_ERRORS)) {
log_error_file_t(&file);
data->errors_count++;
}
file_cleanup(&file);
continue;
}
}
file_cleanup(&file);
/* step into directory */
dp = rsh_topendir(dir_path);
if (!dp)
continue;
insert_at = &dirs_stack;
while ((de = readdir(dp)) != NULL)
{
int res;
tpath_t filepath;
/* skip the "." and ".." directories */
if (IS_CURRENT_OR_PARENT_DIR(de->d_name))
continue;
filepath = make_tpath(dir_path, dirent_get_tname(de));
if (!filepath)
continue;
#ifdef _WIN32
# define slashes_bits (FileInitUpdatePrintPathSlashes)
#else
# define slashes_bits (FileInitUpdatePrintPathSlashes | FileInitUseRealPathAsIs)
#endif
res = file_init(&file, filepath, fstat_bit | slashes_bits);
free(filepath);
if (res >= 0)
{
/* process the file or directory */
if (FILE_ISDIR(&file) && (options & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS)))
{
res = ((options & FIND_FOLLOW_SYMLINKS) || !FILE_ISLNK(&file));
}
else if (FILE_ISREG(&file))
{
/* handle file by callback function */
res = data->callback(&file, data->callback_data);
}
/* check if file is a directory and we need to walk it, */
/* but don't go deeper than max_depth */
if (FILE_ISDIR(&file) && res && level < max_depth &&
((options & FIND_FOLLOW_SYMLINKS) || !FILE_ISLNK(&file)))
{
/* add the directory name to the dirs_stack */
if (dir_entry_insert(insert_at, dirent_get_tname(de), file.mode))
{
/* the directory name was successfully inserted */
insert_at = &((*insert_at)->next);
it[level].count++;
}
}
}
else if (options & FIND_LOG_ERRORS)
{
/* report error only if FIND_LOG_ERRORS option is set */
log_error_file_t(&file);
data->errors_count++;
}
file_cleanup(&file);
}
closedir(dp);
}
while (dirs_stack)
{
dir_entry_drop_head(&dirs_stack);
}
while (level)
{
free(it[level--].dir_path);
}
free(it);
return 0;
}
rhash-1.4.6/hash_check.c 0000664 0000000 0000000 00000140436 15010476501 013562 0 ustar root root /* hash_check.c - functions to parse and verify a hash file contianing message digests */
#include "hash_check.h"
#include "calc_sums.h"
#include "common_func.h"
#include "hash_print.h"
#include "output.h"
#include "parse_cmdline.h"
#include "rhash_main.h"
#include "librhash/rhash.h"
#include
#include /* isspace */
#include
#include
#include
/* size of the buffer to receive a hash file line */
#define LINE_BUFFER_SIZE 4096
/* message digest conversion macros and functions */
#define HEX_TO_DIGIT(c) ((c) <= '9' ? (c) & 0xF : ((c) - 'a' + 10) & 0xF)
#define BASE32_TO_DIGIT(c) ((c) < 'A' ? (c) - '2' + 26 : ((c) & ~0x20) - 'A')
#define BASE32_LENGTH(bits) (((bits) + 4) / 5)
#define BASE64_LENGTH(bits) (((bits) + 5) / 6)
#define BASE32_BIT_SIZE(length) (((length) * 5) & ~7)
#define BASE64_BIT_SIZE(length) (((length) * 6) & ~7)
/* pack a character sequence into a single unsigned integer */
#define THREEC2U(c1, c2, c3) (((unsigned)(c1) << 16) | \
((unsigned)(c2) << 8) | (unsigned)(c3))
#define FOURC2U(c1, c2, c3, c4) (((unsigned)(c1) << 24) | \
((unsigned)(c2) << 16) | ((unsigned)(c3) << 8) | (unsigned)(c4))
/**
* Convert a hexadecimal string to a string of bytes.
*
* @param str string to parse
* @param bin result
* @param len string length
*/
void rhash_hex_to_byte(const char* str, unsigned char* bin, int len)
{
/* parse the highest hexadecimal digit */
if ((len & 1) != 0) {
*(bin++) = HEX_TO_DIGIT(*(str++));
len--;
}
/* parse the rest - an even-sized hexadecimal string */
for (; len >= 2; len -= 2, str += 2) {
*(bin++) = (HEX_TO_DIGIT(str[0]) << 4) | HEX_TO_DIGIT(str[1]);
}
}
/**
* Decode an URL-encoded string into the specified buffer.
*
* @param buffer buffer to decode string into
* @param buffer_size buffer size
* @param src URL-encoded string
* @param src_length length of the string to decode
* @return length of the decoded string
*/
static size_t urldecode(char* buffer, size_t buffer_size, const char* src, size_t src_length)
{
char* dst = buffer;
char* dst_back = dst + buffer_size - 1;
const char* src_end = src + src_length;
assert(src_length < buffer_size);
for (; src < src_end && dst < dst_back; dst++) {
*dst = *(src++); /* copy non-escaped characters */
if (*dst == '%') {
if (*src == '%') {
src++; /* interpret '%%' as single '%' */
} else if (IS_HEX(*src)) {
/* decode character from the % form */
int ch = HEX_TO_DIGIT(*src);
src++;
if (IS_HEX(*src)) {
ch = (ch << 4) | HEX_TO_DIGIT(*src);
src++;
}
*dst = (char)ch;
}
}
}
assert(dst <= dst_back);
*dst = '\0'; /* terminate decoded string */
return (dst - buffer);
}
/**
* Decode a string with escaped characters into the specified buffer.
*
* @param buffer buffer to decode string into
* @param buffer_size buffer size
* @param src string with escaped characters
* @param src_length length of the source string
* @return length of the decoded string
*/
static size_t unescape_characters(char* buffer, size_t buffer_size, const char* src, size_t src_length)
{
char* dst = buffer;
char* dst_back = dst + buffer_size - 1;
const char* src_end = src + src_length;
assert(src_length < buffer_size);
for (; src < src_end && dst < dst_back; dst++) {
*dst = *(src++); /* copy non-escaped characters */
if (*dst == '\\') {
if (*src == 'r')
*dst = '\r';
else if (*src == 'n')
*dst = '\n';
else if (*src != '\\')
continue;
src++;
}
}
assert(dst <= dst_back);
*dst = '\0'; /* terminate decoded string */
return (dst - buffer);
}
/**
* Encode a hash function digest size into a small number in [0,...,7].
* The digest size must be in the set { 4, 16, 20, 24, 28, 32, 48, 64 }.
*
* @param digest_size digest size (aka hash length) in bytes
* @return code for digest size on success, 32 on error
*/
static int code_digest_size(int digest_size)
{
static int size_codes[17] = {
-1, 0,-1, -1, 1, 2, 3, 4, 5, -1,
-1, -1, 6, -1, -1, -1, 7
};
return (digest_size <= 64 ? size_codes[digest_size / 4] : -1);
}
/**
* Compute a bit mask for hash functions that have a specified length
* (in bytes) of their message digest.
*
* @param digest_size length (in bytes) of a binary message digest
* @return bit mask for found hash functions, 0 on fail
*/
static uint64_t hash_bitmask_by_digest_size(int digest_size)
{
static uint64_t hash_masks[10] = { 0,0,0,0,0,0,0,0,0,0 };
int code;
if (hash_masks[9] == 0) {
unsigned hash_ids[64];
size_t count = rhash_get_all_algorithms(64, hash_ids);
size_t i;
RSH_REQUIRE(count != RHASH_ERROR, "failed to get all hash ids\n");
for (i = 0; i < count; i++) {
code = code_digest_size(rhash_get_digest_size(hash_ids[i]));
assert(0 <= code && code <= 7);
if (code >= 0)
hash_masks[code] |= hash_id_to_bit64(hash_ids[i]);
}
hash_masks[9] = 1;
}
code = code_digest_size(digest_size);
return (code >= 0 ? hash_masks[code] : 0);
}
/**
* Bit flags corresponding to possible formats of a message digest.
*/
enum FmtBitFlags {
FmtHex = 1,
FmtBase32LoweCase = 2,
FmtBase32UpperCase = 4,
FmtBase64 = 8,
FmtBase32 = (FmtBase32LoweCase | FmtBase32UpperCase),
FmtAll = (FmtHex | FmtBase32 | FmtBase64)
};
/**
* Test if a character is a hexadecimal/base32 digit.
*
* @param c the character to test
* @return a combination of Fmt* bits
*/
static int test_hash_char(char c)
{
static unsigned char char_bits[80] = {
8, 0, 0, 0, 8, 9, 9, 15, 15, 15, 15, 15, 15, 9, 9, 0, 0, 0, 0, 0,
0, 0, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
12, 12, 12, 12, 12, 12, 12, 12, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10
};
c -= '+';
return ((unsigned)c <= 80 ? char_bits[(unsigned)c] : 0);
}
/**
* Detect if given string contains a hexadecimal or base32 hash.
*
* @param ptr the pointer to start scanning from
* @param end pointer to scan to
* @param p_len pointer to a number to store length of detected message digest
* @return type of detected hash as combination of Fmt* flags
*/
static int detect_hash_type(char** ptr, char* end, int* p_len)
{
char* p = *ptr;
size_t len = 0;
size_t eq_num = 0;
int char_type = 0;
int next_type = FmtAll;
if (p < end) {
/* search forward (but no more then 129 symbols) */
if ((end - p) >= 129) end = p + 129;
for (; p <= end && (next_type &= test_hash_char(*p)); len++, p++)
char_type = next_type;
if ((char_type & FmtBase64) && *p == '=')
{
char_type = FmtBase64;
for (; *p == '=' && p <= end; eq_num++, p++);
}
} else {
/* search backward (but no more then 129 symbols) */
if ((p - end) >= 129) end = p - 129;
for (; p > end && p[-1] == '='; eq_num++, p--)
char_type = FmtBase64;
for (; p > end && (next_type &= test_hash_char(p[-1])); len++, p--)
char_type = next_type;
}
if ((char_type & FmtBase64) != 0)
{
size_t hash_len = (len * 6) & ~7;
if (eq_num > 3 || ((len + eq_num) & 3) || len != (hash_len + 5) / 6)
char_type &= ~FmtBase64;
}
*ptr = p;
*p_len = (int)len;
return char_type;
}
/**
* Check if a message digest of the specified bit length is supported by the program.
*
* @param length the bit length of a binary message digest value
* @return 1 if a message digest of the specified bit length is supported, 0 otherwise
*/
static int is_acceptable_bit_length(int length)
{
if ((length & 31) == 0 && length <= 512)
{
int pow = get_ctz(length >> 5);
int code = ((length >> (pow + 6)) << 3) | pow;
return (code < 32 && ((1 << code) & 0x101061d));
}
return 0;
}
/**
* Test the given substring to be a hexadecimal or base32
* message digest of one of the supported hash functions.
*
* @param ptr the pointer to start scanning from
* @param end pointer to scan to
* @param p_len pointer to a number to store length of detected message digest
* @return possible type of detected hash as algorithm RHASH id
*/
static unsigned char test_hash_string(char** ptr, char* end, int* p_len)
{
int len = 0;
int char_type = detect_hash_type(ptr, end, &len);
unsigned char hash_type = 0;
if ((char_type & FmtHex) && is_acceptable_bit_length(len * 4))
hash_type |= FmtHex;
if ((char_type & FmtBase32) && is_acceptable_bit_length(BASE32_BIT_SIZE(len)))
hash_type |= FmtBase32;
if ((char_type & FmtBase64) && is_acceptable_bit_length(BASE64_BIT_SIZE(len)))
hash_type |= FmtBase64;
if (hash_type != 0)
*p_len = len;
return hash_type;
}
enum HashNameMatchModes {
ExactMatch,
PrefixMatch
};
/**
* Detect a hash-function id by its BSD name.
*
* @param name an uppercase string, a possible name of a hash-function
* @param length length of the name string
* @param match_mode whether the name parameter must match the name of a
* known hash algorithm exactly, or trailing chars are
* allowed.
* @return id of hash function if found, zero otherwise
*/
static unsigned bsd_hash_name_to_id(const char* name, size_t length, enum HashNameMatchModes match_mode)
{
#define code2mask_size (19 * 2)
static unsigned code2mask[code2mask_size] = {
FOURC2U('A', 'I', 'C', 'H'), RHASH_AICH,
FOURC2U('B', 'T', 'I', 'H'), RHASH_BTIH,
FOURC2U('C', 'R', 'C', '3'), (RHASH_CRC32 | RHASH_CRC32C),
FOURC2U('E', 'D', '2', 'K'), RHASH_ED2K,
FOURC2U('E', 'D', 'O', 'N'), (RHASH_EDONR256 | RHASH_EDONR512),
FOURC2U('G', 'O', 'S', 'T'),
(RHASH_GOST12_256 | RHASH_GOST12_512 | RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO),
FOURC2U('H', 'A', 'S', '1'), RHASH_HAS160,
FOURC2U('M', 'D', '4', 0), RHASH_MD4,
FOURC2U('M', 'D', '5', 0), RHASH_MD5,
FOURC2U('R', 'I', 'P', 'E'), RHASH_RIPEMD160,
FOURC2U('S', 'H', 'A', '1'), RHASH_SHA1,
FOURC2U('S', 'H', 'A', '2'), (RHASH_SHA224 | RHASH_SHA256),
FOURC2U('S', 'H', 'A', '3'),
(RHASH_SHA384 | RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512),
FOURC2U('S', 'H', 'A', '5'), RHASH_SHA512,
FOURC2U('S', 'N', 'E', 'F'), (RHASH_SNEFRU128 | RHASH_SNEFRU256),
FOURC2U('T', 'I', 'G', 'E'), RHASH_TIGER,
FOURC2U('T', 'T', 'H', 0), RHASH_TTH,
FOURC2U('W', 'H', 'I', 'R'), RHASH_WHIRLPOOL
};
unsigned code, i, hash_mask, hash_id;
char fourth_char;
if (length < 3) return 0;
fourth_char = (name[3] != '-' ? name[3] : name[4]);
code = FOURC2U(name[0], name[1], name[2], fourth_char);
/* quick fix to detect "RMD160" as RIPEMD160 */
if (code == FOURC2U('R', 'M', 'D', '1'))
return (length == 6 && name[4] == '6' && name[5] == '0' ? RHASH_RIPEMD160 : 0);
if (code == FOURC2U('B', 'L', 'A', 'K')) {
if (length == 6 && name[4] == 'E' && name[5] == '3')
return RHASH_BLAKE3;
hash_mask = RHASH_BLAKE2S | RHASH_BLAKE2B;
} else {
for (i = 0; code2mask[i] != code; i += 2)
if (i >= (code2mask_size - 2)) return 0;
hash_mask = code2mask[i + 1];
}
i = get_ctz(hash_mask);
if (length <= 4)
{
assert((hash_mask & (hash_mask - 1)) == 0);
return (length == strlen(hash_info_table[i].name) ? hash_mask : 0);
}
/* look for the hash_id in the hash_mask */
for (hash_id = 1 << i; hash_id && hash_id <= hash_mask; i++, hash_id <<= 1)
{
const char* a;
const char* b;
if ((hash_id & hash_mask) == 0)
continue;
assert(length > 4);
assert(strlen(hash_info_table[i].name) >= 4);
/* check the name tail, starting from &name[3] to detect names like "SHA-1" or "SHA256" */
for (a = hash_info_table[i].name + 3, b = name + 3; *a; a++, b++)
{
if (*a == *b)
continue;
else if (*a == '-')
b--;
else if (*b == '-')
a--;
else
break;
}
if (!*a && (match_mode == PrefixMatch || !*b))
return hash_id;
}
return 0;
}
/**
* Detect ASCII-7 white spaces (0x09=\t, 0x0a=\n, 0x0b=\v, 0x0c=\f, 0x0d=\r, 0x20=' ').
* Note that standard C function isspace() is locale specific and
* detects Unicode spaces, like U+00A0.
*
* @param ch character to check
* @return non-zero if ch is space, zero otherwise
*/
static int rhash_isspace(char ch)
{
unsigned code = (unsigned)(ch - 9);
return (code < 0x18 && ((1u << code) & 0x80001f));
}
/**
* Extended hash parser data.
*/
struct hash_parser_ext {
struct hash_parser hp;
file_t* hash_file;
file_t parent_dir;
FILE* fd;
uint64_t expected_hash_mask;
unsigned is_sfv;
unsigned line_number;
char buffer[LINE_BUFFER_SIZE];
};
/**
* Information about found token.
*/
struct hash_token
{
char* begin; /* start of the buffer to parse */
char* end; /* end of the buffer to parse */
file_t* p_parsed_path;
struct hash_parser_ext* parser;
struct hash_value* p_hashes;
unsigned expected_hash_id;
int hash_type;
};
/**
* Bit-flags for the fstat_path_token().
*/
enum FstatPathBitFlags {
PathUrlDecode = 1,
PathUnescape = 2
};
static int fstat_path_token(struct hash_token* token, char* path, size_t path_length, int is_url);
/**
* Bit-flags for the match_hash_tokens().
*/
enum MhtOptionsBitFlags {
MhtFstatPath = 1,
MhtAllowOneHash = 2,
MhtAllowEscapedPath = 4
};
/**
* Constants returned by match_hash_tokens() and some other functions.
*/
enum MhtResults {
ResFailed = 0,
ResAllMatched = 1,
ResPathNotExists = 2,
ResOneHashDetected = 3
};
/**
* Parse the buffer pointed by token->begin, into tokens specified by format string.
* The format string can contain the following special characters:
* '\1' - BSD hash function name, '\2' - any hash, '\3' - specified hash,
* '\4' - an URL-encoded file name, '\5' - a file size,
* '\6' - a required space or line end.
* A space ' ' means 0 or more space characters.
* '$' - parse the rest of the buffer and the format string backward.
* Other (non-special) symbols mean themselves.
* The function updates token->begin and token->end pointers on success.
*
* @param token the structure to store parsed tokens info
* @param format the format string
* @param bit_flags MhtFstatPath flag to run fstat on parsed path,
* MhtAllowOneHash to allow line containing one message digest without a file path
* @return one of the MhtResults constants
*/
static int match_hash_tokens(struct hash_token* token, const char* format, unsigned bit_flags)
{
int backward = 0;
char buf[20];
const char* fend = strchr(format, '\0');
char* begin = token->begin;
char* end = token->end;
char* url_path = 0;
size_t url_length = 0;
struct hash_parser* hp = &token->parser->hp;
struct hash_value hv;
int unsaved_hashval = 0;
int unescape_flag = 0;
memset(&hv, 0, sizeof(hv));
if ((bit_flags & MhtAllowEscapedPath) && (opt.flags & OPT_NO_PATH_ESCAPING) == 0 &&
begin[0] == '\\' && !(begin[1] == '\\' && begin[2] == '?' && begin[3] == '\\')) {
begin++;
unescape_flag = PathUnescape;
}
while (format < fend) {
const char* search_str;
int len = 0;
uint64_t file_size;
if (backward) {
for (; fend[-1] >= '-' && format < fend; fend--, len++);
if (len == 0)
fend--;
search_str = fend;
} else {
search_str = format;
for (; *format >= '-' && format < fend; format++, len++);
if (len == 0)
format++;
}
if (len > 0) {
if ((end - begin) < len)
return ResFailed;
if (0 != memcmp(search_str, (backward ? end - len : begin), len))
return ResFailed;
if (backward)
end -= len;
else
begin += len;
continue;
}
assert(len == 0);
/* find substring specified by single character */
switch (*search_str) {
case '\1': /* parse BSD hash function name */
/* the name should contain alphanumeric or '-' symbols, but */
/* actually the loop shall stop at characters [:& \(\t] */
for (; (begin[len] <= '9' ? begin[len] >= '0' || begin[len] == '-' : begin[len] >= 'A'); len++) {
if (len >= 20)
return ResFailed; /* limit name length */
buf[len] = toupper(begin[len]);
}
buf[len] = '\0';
token->expected_hash_id = bsd_hash_name_to_id(buf, (size_t)len, ExactMatch);
if (!token->expected_hash_id)
return ResFailed;
token->hash_type = FmtAll;
begin += len;
break;
case '\2':
case '\3':
if (backward) {
/* trim right */
for (; begin < end && rhash_isspace(end[-1]); end--, len++);
if (begin == end)
return ResFailed;
hv.format = test_hash_string(&end, begin, &len);
hv.offset = (unsigned short)(end - hp->line_begin);
} else {
/* trim left */
for (; rhash_isspace(*begin) && begin < end; begin++, len++);
if (begin == end)
return ResFailed;
hv.offset = (unsigned short)(begin - hp->line_begin);
hv.format = test_hash_string(&begin, end, &len) & token->hash_type;
}
if (!hv.format)
return ResFailed;
if (*search_str == '\3') {
/* verify message digest type */
int bit_length = rhash_get_digest_size(token->expected_hash_id) * 8;
hv.format &= token->hash_type;
if ((len * 4) != bit_length)
hv.format &= ~FmtHex;
if (len != BASE32_LENGTH(bit_length))
hv.format &= ~FmtBase32;
if (len != BASE64_LENGTH(bit_length))
hv.format &= ~FmtBase64;
if (!hv.format)
return ResFailed;
hv.hash_mask = hash_id_to_bit64(token->expected_hash_id);
} else hv.hash_mask = 0;
hv.length = (unsigned char)len;
unsaved_hashval = 1;
break;
case '\4': /* get URL-encoded name */
url_path = begin;
url_length = strcspn(begin, "?&|");
if (url_length == 0)
return ResFailed; /* empty name */
begin += url_length;
break;
case '\5': /* retrieve file size */
assert(!backward);
file_size = 0L;
for (; '0' <= *begin && *begin <= '9'; begin++, len++) {
file_size = file_size * 10 + (*begin - '0');
}
if (len == 0)
return ResFailed;
else {
hp->file_size = file_size;
hp->bit_flags |= HpHasFileSize;
}
break;
case '\6':
case ' ':
if (backward) {
char* low_limit = (begin < end && *search_str == '\6' ? end - 1 : begin);
for (; low_limit < end && rhash_isspace(end[-1]); end--, len++);
} else {
char* hi_limit = (begin < end && *search_str == '\6' ? begin + 1 : end);
for (; begin < hi_limit && rhash_isspace(*begin); begin++, len++);
}
/* check if space is mandatory */
if (*search_str == '\6' && len == 0) {
/* for '\6' verify (len > 0 || (MhtAllowOneHash is set && begin == end)) */
if (!(bit_flags & MhtAllowOneHash) || begin < end)
return ResFailed;
}
break;
case '$':
backward = 1; /* switch to parsing string backward */
break;
default:
if ((backward ? *(--end) : *(begin++)) != *search_str)
return ResFailed;
}
}
if (unsaved_hashval && hp->hashes_num < HP_MAX_HASHES) {
token->p_hashes[hp->hashes_num++] = hv;
}
if (!backward) {
/* eat zero or one leading space */
if (begin < end && rhash_isspace(*begin))
begin++;
}
/* the rest is stored as a file path */
token->begin = begin;
token->end = end;
if ((bit_flags & MhtAllowOneHash) != 0 && hp->hashes_num == 1 && begin == end)
{
/* a single hash without a file path was detected */
struct hash_parser_ext* const parser = token->parser;
file_t* parsed_path = &parser->hp.parsed_path;
if (file_modify_path(parsed_path, parser->hash_file, NULL, FModifyRemoveExtension) < 0)
return ResFailed;
if ((bit_flags & MhtFstatPath) != 0 && file_stat(parsed_path, 0) < 0)
hp->parsed_path_errno = errno;
return ResOneHashDetected;
}
if ((bit_flags & MhtFstatPath) != 0) {
int fstat_res;
if (url_path != 0) {
fstat_res = fstat_path_token(token, url_path, url_length, PathUrlDecode);
} else {
size_t path_length;
if (begin[0] == '*' && unescape_flag == 0)
begin++;
path_length = end - begin;
fstat_res = fstat_path_token(token, begin, path_length, unescape_flag);
}
if (fstat_res < 0)
return ResPathNotExists;
}
return ResAllMatched;
}
/**
* Fstat given file path. Optionally prepend it, if needed, by parent directory.
* Depending on bit_flags, the path is url-decoded or decoded using escape sequences.
* Fstat result is stored into token->p_parsed_path.
*
* @param token current tokens parsing context
* @param str pointer to the path start
* @param str_length length of the path
* @param bit_flags PathUrlDecode or PathUnescape to decode path
* @return 0 on success, -1 on fstat fail
*/
static int fstat_path_token(struct hash_token* token, char* str, size_t str_length, int bit_flags)
{
static char buffer[LINE_BUFFER_SIZE];
file_t* parent_dir = &token->parser->parent_dir;
unsigned init_flags = (FILE_IS_IN_UTF8(token->parser->hash_file) ?
FileInitRunFstat | FileInitUtf8PrintPath : FileInitRunFstat);
char* path = (bit_flags == 0 ? str : buffer);
size_t path_length = (bit_flags == 0 ? str_length : (bit_flags & PathUrlDecode ?
urldecode(buffer, LINE_BUFFER_SIZE, str, str_length) :
unescape_characters(buffer, LINE_BUFFER_SIZE, str, str_length)));
int res;
int is_absolute = IS_PATH_SEPARATOR(path[0]);
char saved_char = path[path_length];
path[path_length] = '\0';
IF_WINDOWS(is_absolute = is_absolute || (path[0] && path[1] == ':'));
if (is_absolute || !parent_dir->real_path)
parent_dir = NULL;
if ((bit_flags & PathUnescape) != 0)
init_flags |= FileInitUseRealPathAsIs;
res = file_init_by_print_path(token->p_parsed_path, parent_dir, path, init_flags);
if (res < 0 && token->p_parsed_path == &token->parser->hp.parsed_path)
token->parser->hp.parsed_path_errno = errno;
path[path_length] = saved_char;
return res;
}
/**
* Cleanup token context and fill hash_mask of the parser.
*
* @param token token parsing context
* @return ResPathNotExists if path has not been found, ResAllMatched otherwise
*/
static int finalize_parsed_data(struct hash_token* token)
{
int i;
struct hash_parser* const parser = &token->parser->hp;
if (token->p_parsed_path != &parser->parsed_path) {
file_cleanup(&parser->parsed_path);
parser->parsed_path = *token->p_parsed_path;
}
if (FILE_ISBAD(&parser->parsed_path) || !parser->parsed_path.real_path)
return ResPathNotExists;
if (token->p_hashes != parser->hashes) {
assert(parser->hashes_num == 1);
parser->hashes[0] = token->p_hashes[0];
}
/* post-process parsed message digests */
for (i = 0; i < parser->hashes_num; i++) {
struct hash_value* hv = &parser->hashes[i];
char* hash_str = parser->line_begin + hv->offset;
hash_str[hv->length] = '\0'; /* terminate the message digest */
if (hv->hash_mask == 0) {
/* calculate bit-mask of hash function */
uint64_t hash_mask = 0;
if (hv->format & FmtHex) {
hash_mask |= hash_bitmask_by_digest_size(hv->length >> 1);
}
if (hv->format & FmtBase32) {
assert(((hv->length * 5 / 8) & 3) == 0);
hash_mask |= hash_bitmask_by_digest_size(BASE32_BIT_SIZE(hv->length) / 8);
}
if (hv->format & FmtBase64) {
hash_mask |= hash_bitmask_by_digest_size(BASE64_BIT_SIZE(hv->length) / 8);
}
assert(hash_mask != 0);
if ((hash_mask & token->parser->expected_hash_mask) != 0)
hash_mask &= token->parser->expected_hash_mask;
hv->hash_mask = hash_mask;
}
parser->hash_mask |= hv->hash_mask;
}
return ResAllMatched;
}
/**
* Parse the rest of magnet link.
*
* @param token tokens parsing context
* @return ResAllMatched on success, ResFailed on a bad magnet link
*/
static int parse_magnet_url(struct hash_token* token)
{
char* url_path = 0;
size_t url_length;
/* loop by magnet link parameters */
while (1) {
char* next = strchr(token->begin, '&');
char* param_end = (next ? next++ : token->end);
char* hf_end;
if ((token->begin += 3) < param_end) {
switch (THREEC2U(token->begin[-3], token->begin[-2], token->begin[-1])) {
case THREEC2U('d', 'n', '='): /* URL-encoded file path */
url_path = token->begin;
url_length = param_end - token->begin;
break;
case THREEC2U('x', 'l', '='): /* file size */
if (!match_hash_tokens(token, "\5", 0))
return ResFailed;
if (token->begin != param_end)
return ResFailed;
break;
case THREEC2U('x', 't', '='): /* a file hash */
{
uint64_t hash_mask;
/* find last ':' character (hash name can be complex like tree:tiger) */
for (hf_end = param_end - 1; *hf_end != ':' && hf_end > token->begin; hf_end--);
/* test for the "urn:" string */
if ((token->begin += 4) >= hf_end)
return ResFailed;
if (FOURC2U(token->begin[-4], token->begin[-3], token->begin[-2], token->begin[-1]) !=
FOURC2U('u', 'r', 'n', ':'))
return ResFailed;
/* find hash by its magnet link specific URN name */
for (hash_mask = get_all_supported_hash_mask(); hash_mask; hash_mask &= hash_mask - 1) {
uint64_t bit64 = hash_mask & -hash_mask;
unsigned hash_id = bit64_to_hash_id(bit64);
const char* urn = rhash_get_magnet_name(hash_id);
size_t len = hf_end - token->begin;
if (strncmp(token->begin, urn, len) == 0 && urn[len] == '\0') {
token->expected_hash_id = hash_id;
break;
}
}
if (!hash_mask) {
if (opt.verbose) {
*hf_end = '\0';
log_warning(_("unknown hash in magnet link: %s\n"), token->begin);
}
return ResFailed;
}
token->begin = hf_end + 1;
token->hash_type = (FmtHex | FmtBase32);
if (!match_hash_tokens(token, "\3", 0))
return ResFailed;
if (token->begin != param_end)
return ResFailed;
break;
}
/* note: this switch () skips all unknown parameters */
}
}
if (next)
token->begin = next;
else
break;
}
if (!url_path || token->parser->hp.hashes_num == 0)
return ResFailed;
fstat_path_token(token, url_path, url_length, PathUrlDecode);
return finalize_parsed_data(token);
}
/**
* Parse the rest of ed2k link.
*
* @param token the structure to store parsed tokens info
* @return ResAllMatched on success, ResFailed on a bad ed2k link
*/
static int parse_ed2k_link(struct hash_token* token)
{
token->expected_hash_id = RHASH_ED2K;
token->hash_type = FmtHex;
if (!match_hash_tokens(token, "\4|\5|\3|", MhtFstatPath))
return ResFailed;
/* try to parse optional AICH hash */
token->expected_hash_id = RHASH_AICH;
token->hash_type = (FmtHex | FmtBase32); /* AICH is usually base32-encoded*/
match_hash_tokens(token, "h=\3|", 0);
return finalize_parsed_data(token);
}
/**
* Parse a line of a hash-file. This function accepts five formats.
*
* magnet links
* EDonkey/EMule ed2k links
* BSD format: HASH_FUNCTION ( filepath ) = FILE_HASH
* filepath FILE_HASH1 FILE_HASH2...
* FILE_HASH1 FILE_HASH2... filepath
*
* For a magnet/ed2k links file size is also parsed.
*
* @param parser structure to store parsed message digests, file path and file size
* @param check_eol boolean flag meaning that '\n' at the end of the line is required
* @return non-zero on success (ResAllMatched, ResOneHashDetected, ResPathNotExists),
* ResFailed if couldn't parse the line
*/
static int parse_hash_file_line(struct hash_parser_ext* parser, int check_eol)
{
struct hash_token token;
char* const line_start = parser->hp.line_begin;
char* token_start = line_start;
char* line_end = strchr(line_start, '\0');
int res;
assert(line_start[0] != '\0');
/* return if EOL not found at the end of the line */
if (line_end[-1] != '\n' && check_eol)
return ResFailed;
/* remove trailing CR and LF */
while ((line_end[-1] == '\n' || line_end[-1] == '\r') && line_end > line_start)
*(--line_end) = 0;
/* skip white spaces at the start of the line */
while (rhash_isspace(*token_start))
token_start++;
memset(&token, 0, sizeof(token));
token.begin = token_start;
token.end = line_end;
token.parser = parser;
token.p_parsed_path = &parser->hp.parsed_path;
token.p_hashes = parser->hp.hashes;
memset(&parser->hp, 0, sizeof(parser->hp));
parser->hp.line_begin = line_start;
parser->hp.file_size = (uint64_t)-1;
/* check for a minimum acceptable message digest length */
if ((token_start + 8) > line_end)
return ResFailed;
if (strncmp(token.begin, "ed2k://|file|", 13) == 0) {
token.begin += 13;
return parse_ed2k_link(&token);
}
if (strncmp(token.begin, "magnet:?", 8) == 0) {
token.begin += 8;
return parse_magnet_url(&token);
}
/* check for BSD-formatted line has been processed */
res = match_hash_tokens(&token, "\1 ($) = \3", MhtFstatPath | MhtAllowEscapedPath);
if (res != ResFailed)
return finalize_parsed_data(&token);
token.hash_type = FmtAll;
token.begin = line_start;
{
const unsigned is_sfv_format = parser->is_sfv;
unsigned valid_direction = 0;
unsigned state;
unsigned token_flags = (MhtFstatPath | MhtAllowEscapedPath | MhtAllowOneHash);
struct file_t secondary_path;
struct hash_token secondary_token;
struct hash_token *cur_token = &token;
struct hash_value secondary_hash[1];
memset(&secondary_path, 0, sizeof(secondary_path));
memcpy(&secondary_token, &token, sizeof(token));
secondary_token.p_hashes = secondary_hash;
/* parse one hash from each line end */
for (state = 0; state < 2; state++)
{
const unsigned is_backward = (state ^ is_sfv_format);
const char* token_format = (is_backward ? "$\6\2" : "\2\6");
int res = match_hash_tokens(cur_token, token_format, token_flags);
if (res == ResAllMatched || res == ResOneHashDetected)
{
return finalize_parsed_data(cur_token);
}
else if (res == ResPathNotExists)
{
assert(parser->hp.hashes_num == 1);
valid_direction |= (1 << state); /* mark the current parsing direction as valid */
if (token.p_parsed_path == &parser->hp.parsed_path)
token.p_parsed_path = secondary_token.p_parsed_path = &secondary_path;
cur_token = &secondary_token;
parser->hp.hashes_num = 0;
}
token_flags &= ~MhtAllowOneHash;
}
token_flags = MhtFstatPath;
/* parse the rest of hashes */
for (state = 0; state < 2; state++)
{
if ((valid_direction & (1 << state)) != 0)
{
const unsigned is_backward = (state ^ is_sfv_format);
const char* token_format = (is_backward ? "$\6\2" : "\2\6");
/* restore parsing state and a parsed hash */
parser->hp.hashes_num = 1;
if (state == 1 && valid_direction == 3)
{
token.begin = secondary_token.begin;
token.end = secondary_token.end;
token.p_hashes[0] = secondary_token.p_hashes[0];
}
/* allow FmtBase64 only if the first hash can be interpreted only as Base64-encoded */
token.hash_type = (token.hash_type & ~FmtBase64) |
(token.p_hashes[0].format == FmtBase64 ? FmtBase64 : 0);
for (;;)
{
int res = match_hash_tokens(&token, token_format, token_flags);
assert(res != ResOneHashDetected);
if (res == ResAllMatched)
return finalize_parsed_data(&token);
else if (res == ResFailed)
break;
}
}
}
file_cleanup(&secondary_path);
if (token.p_parsed_path != &parser->hp.parsed_path)
return ResPathNotExists;
}
return ResFailed; /* could not parse line */
}
/**
* Bit-flags for the hash.
*/
enum CompareHashBitFlags {
CompareHashCaseSensitive = 1,
CompareHashReversed = 2
};
/**
* Compare two message digests. For base64 encoding, the case-sensitive comparasion is done.
* For hexadecimal or base32 encodings, the case-insensitive match occurs.
* For the GOST94 hash, the additional reversed case-insensitive match is done.
*
* @param calculated_hash the calculated message digest, for the hex/base32 the value must be in upper case
* @param expected a message digest from a hash file to match against
* @param length length of the message digests
* @param comparision_mode 0, CompareHashCaseSensitive or CompareHashReversed comparision mode
* @return 1 if message digests match, 0 otherwise
*/
static int is_hash_string_equal(const char* calculated_hash, const char* expected, size_t length, int comparision_mode)
{
if (comparision_mode == CompareHashCaseSensitive)
return (memcmp(calculated_hash, expected, length) == 0);
{
/* case-insensitive comparision of a hexadecimal or a base32 hash */
size_t i = 0;
for (; i < length && (calculated_hash[i] == (expected[i] >= 'a' ? expected[i] & ~0x20 : expected[i])); i++);
if (i == length)
return 1;
}
if (comparision_mode == CompareHashReversed) {
/* case-insensitive comparision of reversed gost hash */
size_t i = 0, last = length - 1;
for (; i < length && (calculated_hash[last - (i ^ 1)] == (expected[i] >= 'a' ? expected[i] & ~0x20 : expected[i])); i++);
return (i == length);
}
return 0;
}
/**
* Obtain CRC32 from rhash context. The function assumes that
* context contains CRC32 and makes no checks for this.
*
* @param rhash context
* @return crc32 checksum
*/
unsigned get_crc32(struct rhash_context* ctx)
{
unsigned char c[4];
rhash_print((char*)c, ctx, RHASH_CRC32, RHPR_RAW);
return ((unsigned)c[0] << 24) | ((unsigned)c[1] << 16) |
((unsigned)c[2] << 8) | (unsigned)c[3];
}
/**
* Verify calculated message digests against original values.
* Also verify the file size and embedded CRC32 if present.
* The HP_WRONG_* bits are set in the parser->flags field on fail.
*
* @param parser 'original' parsed message digests, to verify against
* @param ctx the rhash context containing calculated message digests
* @return 1 on successfull verification, 0 on message digests mismatch
*/
static int do_hash_sums_match(struct hash_parser* parser, struct rhash_context* ctx)
{
uint64_t hash_mask = parser->hash_mask;
uint64_t unverified_mask;
unsigned printed;
char hex[132], base32[104], base64[88];
int j;
static const uint64_t gost94_hash_mask =
hash_id_to_bit64(RHASH_GOST94) | hash_id_to_bit64(RHASH_GOST94_CRYPTOPRO);
/* verify file size, if present */
if ((parser->bit_flags & HpHasFileSize) != 0 && parser->file_size != ctx->msg_size)
parser->bit_flags |= HpWrongFileSize;
/* verify embedded CRC32 checksum, if present */
if ((parser->bit_flags & HpHasEmbeddedCrc32) != 0 && get_crc32(ctx) != parser->embedded_crc32)
parser->bit_flags |= HpWrongEmbeddedCrc32;
/* return if nothing else to verify */
if (parser->hashes_num == 0)
return !HP_FAILED(parser->bit_flags);
unverified_mask = ((uint64_t)1 << parser->hashes_num) - 1;
while(hash_mask && unverified_mask) {
uint64_t bit64 = hash_mask & -hash_mask;
unsigned hash_id = bit64_to_hash_id(bit64);
if ((parser->hash_mask & bit64) == 0)
continue;
printed = 0;
for (j = 0; j < parser->hashes_num; j++) {
struct hash_value* hv = &parser->hashes[j];
char* calculated_hash;
char* expected_hash;
int bit_length;
int comparision_mode;
/* skip already verified message digests and message digests of different size */
if (!(unverified_mask & ((uint64_t)1 << j)) || !(hv->hash_mask & bit64))
continue;
comparision_mode = 0;
bit_length = rhash_get_digest_size(hash_id) * 8;
if ((hv->length * 4) == bit_length) {
assert(hv->format & FmtHex);
assert(hv->length <= 128);
/* print hexadecimal value, if not printed yet */
if ((printed & FmtHex) == 0) {
rhash_print(hex, ctx, hash_id, RHPR_HEX | RHPR_UPPERCASE);
printed |= FmtHex;
}
calculated_hash = hex;
if ((bit64 & gost94_hash_mask) != 0)
comparision_mode = CompareHashReversed;
} else if (hv->length == BASE32_LENGTH(bit_length)) {
assert(hv->format & FmtBase32);
assert(hv->length <= 103);
/* print base32 value, if not printed yet */
if ((printed & FmtBase32) == 0) {
rhash_print(base32, ctx, hash_id, RHPR_BASE32 | RHPR_UPPERCASE);
printed |= FmtBase32;
}
calculated_hash = base32;
} else {
assert(hv->format & FmtBase64);
assert(hv->length == BASE64_LENGTH(bit_length));
assert(hv->length <= 86);
/* print base32 value, if not printed yet */
if ((printed & FmtBase64) == 0) {
rhash_print(base64, ctx, hash_id, RHPR_BASE64);
printed |= FmtBase64;
}
calculated_hash = base64;
comparision_mode = CompareHashCaseSensitive;
}
expected_hash = parser->line_begin + hv->offset;
if (!is_hash_string_equal(calculated_hash, expected_hash, hv->length, comparision_mode))
continue;
unverified_mask &= ~((uint64_t)1 << j); /* mark the j-th message digest as verified */
parser->found_hash_ids |= bit64;
/* end the loop if all message digests were successfully verified */
if (unverified_mask == 0)
break;
}
hash_mask ^= bit64;
}
parser->wrong_hashes = unverified_mask;
if (unverified_mask != 0)
parser->bit_flags |= HpWrongHashes;
return !HP_FAILED(parser->bit_flags);
}
/**
* Verify message digests of the file.
* In a case of fail, the error will be logged.
*
* @param file the file, which hashes are verified
* @param hp parsed hash file line
* @return 0 on success, 1 on message digests mismatch,
* -1/-2 on input/output error
*/
static int verify_hashes(file_t* file, struct hash_parser* hp)
{
struct file_info info;
timedelta_t timer;
int res = 0;
if (FILE_ISBAD(file) && (opt.flags & OPT_IGNORE_MISSING) != 0)
return -1;
memset(&info, 0, sizeof(info));
info.file = file;
info.hash_mask = hp->hash_mask;
info.hp = hp;
print_verbose_algorithms(rhash_data.log, info.hash_mask);
/* initialize percents output */
if (init_percents(&info) < 0) {
log_error_file_t(&rhash_data.out_file);
return -2;
}
rsh_timer_start(&timer);
if (FILE_ISBAD(info.file)) {
/* restore errno */
errno = hp->parsed_path_errno;
res = -1;
} else {
res = calc_sums(&info);
}
if (res < 0) {
/* report file error */
int output_res = finish_percents(&info, -1);
return (output_res < 0 ? -2 : -1);
}
info.time = rsh_timer_stop(&timer);
if (rhash_data.stop_flags) {
report_interrupted();
return 0;
}
if ((opt.flags & OPT_EMBED_CRC) &&
find_embedded_crc32(info.file, &hp->embedded_crc32)) {
hp->bit_flags |= HpHasEmbeddedCrc32;
assert(hp->hash_mask & RHASH_CRC32);
}
if (!do_hash_sums_match(hp, info.rctx))
res = 1;
if (finish_percents(&info, res) < 0)
res = -2;
if ((opt.flags & OPT_SPEED) && info.hash_mask != 0)
print_file_time_stats(&info);
return res;
}
/**
* Verify the file against the CRC32 checksum embedded into its filename.
*
* @param file the file to verify
* @return 0 on success, -1 on input error, -2 on results output error
*/
int check_embedded_crc32(file_t* file)
{
int res = 0;
unsigned crc32;
struct hash_parser hp;
if (find_embedded_crc32(file, &crc32)) {
/* initialize file_info structure */
memset(&hp, 0, sizeof(hp));
hp.hash_mask = RHASH_CRC32;
hp.bit_flags = HpHasEmbeddedCrc32;
hp.embedded_crc32 = crc32;
res = verify_hashes(file, &hp);
if (res >= -1 && fflush(rhash_data.out) < 0) {
log_error_file_t(&rhash_data.out_file);
res = -2;
} else if (!rhash_data.stop_flags) {
if (res == 0)
rhash_data.ok++;
else if (res == -1 && errno == ENOENT)
rhash_data.miss++;
rhash_data.processed++;
}
} else {
/* TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv */
log_warning_msg_file_t(_("file name doesn't contain a CRC32: %s\n"), file);
return -1;
}
return res;
}
/**
* Structure to store file extension and its length.
*/
struct file_ext {
size_t length;
char buffer[20];
};
/**
* Extract file extension from given file.
*
* @param fe buffer to recieve file extension
* @param file the file to process
* @return 1 on success, 0 on fail
*/
static int extract_uppercase_file_ext(struct file_ext* fe, file_t* file)
{
size_t length;
char* buffer;
const char* basename = file_get_print_path(file, FPathUtf8 | FPathBaseName);
const char* ext;
if (!basename)
return 0;
ext = strrchr(basename, '.');
if (!ext)
/* If there is no extension, then consider the whole filename
* as extension, so callers can do the right thing when
* encountering a file called e.g. "SHA256". */
ext = basename;
else
ext++;
buffer = fe->buffer;
for (length = 0; '-' <= ext[length] && ext[length] <= 'z'; length++) {
if (length >= sizeof(fe->buffer))
return 0; /* limit hash name length */
buffer[length] = toupper(ext[length]);
}
if (ext[length] != '\0')
return 0;
buffer[length] = '\0';
fe->length = length;
return 1;
}
/**
* Detect SFV format and hash functions by the hash file extension.
*
* @param hash_file the file, which extension is checked
* @param parser the parser to store hash_mask and sfv flag into
*/
static void set_flags_by_hash_file_extension(file_t* hash_file, struct hash_parser_ext* parser)
{
struct file_ext ext;
uint64_t hash_mask;
int is_sfv;
if (HAS_OPTION(OPT_NO_DETECT_BY_EXT) || !extract_uppercase_file_ext(&ext, hash_file))
return;
hash_mask = (opt.hash_mask ? opt.hash_mask :
hash_id_to_bit64(bsd_hash_name_to_id(ext.buffer, ext.length, PrefixMatch)));
is_sfv = (ext.length == 3 && memcmp(ext.buffer, "SFV", 3) == 0);
if (parser != NULL) {
parser->expected_hash_mask = hash_mask;
parser->is_sfv = is_sfv;
}
if (IS_MODE(MODE_UPDATE | MODE_MISSING | MODE_UNVERIFIED)) {
opt.hash_mask = hash_mask;
if (!opt.fmt)
rhash_data.is_sfv = is_sfv;
}
}
/**
* Close and cleanup hash parser.
*
* @param parser the hash parser to close
* @return 0 on success, -1 on fail with error code stored in errno
*/
static int hash_parser_close(struct hash_parser* hp)
{
struct hash_parser_ext* parser = (struct hash_parser_ext*)hp;
int res = 0;
if (!parser)
return 0;
file_cleanup(&parser->parent_dir);
file_cleanup(&parser->hp.parsed_path);
if (parser->fd != stdin)
res = fclose(parser->fd);
free(parser);
return res;
}
/**
* Open a hash file and create a hash_parser for it.
*
* @param hash_file the hash file to open
* @param chdir true if function should emulate chdir to the parent directory of the hash file
* @return created hash_parser on success, NULL on fail with error code stored in errno
*/
static struct hash_parser* hash_parser_open(file_t* hash_file, int chdir)
{
FILE* fd;
struct hash_parser_ext* parser;
/* open file or prepare file descriptor */
if (FILE_ISSTDIN(hash_file))
fd = stdin;
else if ( !(fd = file_fopen(hash_file, FOpenRead | FOpenBin) ))
return NULL;
/* allocate and initialize parser */
parser = (struct hash_parser_ext*)rsh_malloc(sizeof(struct hash_parser_ext));
memset(parser, 0, sizeof(struct hash_parser_ext));
parser->hash_file = hash_file;
parser->fd = fd;
parser->expected_hash_mask = opt.hash_mask;
parser->is_sfv = rhash_data.is_sfv;
/* extract the parent directory of the hash file, if required */
if (chdir)
file_modify_path(&parser->parent_dir, hash_file, NULL, FModifyGetParentDir);
if ((opt.flags & OPT_NO_DETECT_BY_EXT) == 0)
set_flags_by_hash_file_extension(hash_file, parser);
return &parser->hp;
}
/**
* Constants returned by hash_parser_process_line() function.
*/
enum ProcessLineResults {
ResReadError = -1,
ResStopParsing = 0,
ResSkipLine = 1,
ResParsedLine = 2,
ResFailedToParse = 3
};
/**
* Parse one line of the openned hash file.
*
* @param hp parser processing the hash file
* @return one of the ProcessLineResults constants
*/
static int hash_parser_process_line(struct hash_parser* hp)
{
struct hash_parser_ext* parser = (struct hash_parser_ext*)hp;
char *line = parser->buffer;
if (!fgets(parser->buffer, sizeof(parser->buffer), parser->fd)) {
if (ferror(parser->fd)) {
log_error_file_t(parser->hash_file);
return ResReadError;
}
return ResStopParsing;
}
parser->line_number++;
if (parser->line_number > 1)
file_cleanup(&hp->parsed_path);
/* skip unicode BOM, if found */
if (STARTS_WITH_UTF8_BOM(line)) {
line += 3;
if (parser->line_number == 1)
parser->hash_file->mode |= FileContentIsUtf8;
}
if (is_binary_string(line)) {
const char* message = (IS_MODE(MODE_UPDATE) ?
/* TRANSLATORS: it's printed, when a non-text hash file is encountered in --update mode */
_("skipping binary file") :
_("file is binary"));
log_msg("%s:%u: %s\n",
file_get_print_path(parser->hash_file, FPathPrimaryEncoding | FPathNotNull),
parser->line_number, message);
hp->bit_flags |= HpIsBinaryFile;
return ResReadError;
}
/* silently skip comments and empty lines */
if (*line == '\0' || *line == '\r' || *line == '\n' || IS_COMMENT(*line))
return ResSkipLine;
hp->line_begin = line;
if (!parse_hash_file_line(parser, !feof(parser->fd))) {
log_msg(_("%s:%u: can't parse line \"%s\"\n"),
file_get_print_path(parser->hash_file, FPathPrimaryEncoding | FPathNotNull),
parser->line_number, parser->hp.line_begin);
return ResFailedToParse;
}
errno = 0;
return ResParsedLine;
}
/**
* Parse content of the openned hash file.
*
* @param parser hash parser, controlling parsing process
* @param files pointer to the vector to load parsed file paths into
* @return HashFileBits bit mask on success, -1 on input error, -2 on results output error
*/
static int hash_parser_process_file(struct hash_parser *parser, file_set* files)
{
timedelta_t timer;
uint64_t time;
int parsing_res;
int result = (HashFileExist | HashFileIsEmpty);
if (IS_MODE(MODE_CHECK) && print_verifying_header(((struct hash_parser_ext*)parser)->hash_file) < 0) {
log_error_file_t(&rhash_data.out_file);
return -2;
}
rsh_timer_start(&timer);
/* initialize statistics */
rhash_data.processed = rhash_data.ok = rhash_data.miss = 0;
rhash_data.total_size = 0;
while ((parsing_res = hash_parser_process_line(parser)) > ResStopParsing) {
result &= ~HashFileIsEmpty;
/* skip comments and empty lines */
if (parsing_res == ResSkipLine)
continue;
if (parsing_res == ResFailedToParse) {
result |= HashFileHasUnparsedLines;
} else {
if (files)
{
/* put UTF8-encoded file path into the file set */
const char* path = file_get_print_path(&parser->parsed_path,
FPathUtf8 | FileInitUpdatePrintPathToForwardSlashes);
if (path)
file_set_add_name(files, path);
}
if (IS_MODE(MODE_CHECK)) {
/* verify message digests of the file */
int res = verify_hashes(&parser->parsed_path, parser);
if (res >= -1 && fflush(rhash_data.out) < 0) {
log_error_file_t(&rhash_data.out_file);
return -2;
}
if (rhash_data.stop_flags || res <= -2) {
return res; /* stop on fatal error */
}
/* update statistics */
if (res == 0)
rhash_data.ok++;
else
{
if (FILE_ISBAD(&parser->parsed_path) && (opt.flags & OPT_IGNORE_MISSING) != 0)
continue;
if (res == -1 && errno == ENOENT)
{
result |= HashFileHasMissedFiles;
rhash_data.miss++;
}
else
result |= HashFileHasWrongHashes;
}
} else if (IS_MODE(MODE_MISSING)) {
if (FILE_ISBAD(&parser->parsed_path)) {
/* print the missing file */
if (fprintf_file_t(rhash_data.out, "%s\n", &parser->parsed_path, OutEscapePrefixed) < 0) {
log_error_file_t(&rhash_data.out_file);
return -2;
}
result |= HashFileHasMissedFiles;
rhash_data.miss++;
}
else
rhash_data.ok++;
}
}
rhash_data.processed++;
}
if (parsing_res == ResReadError)
return -1;
time = rsh_timer_stop(&timer);
if (IS_MODE(MODE_CHECK | MODE_MISSING)) {
/* check for a hash file errors */
if (result >= 0 && (result & (HashFileHasWrongHashes | HashFileHasMissedFiles | HashFileHasUnparsedLines)) != 0)
rhash_data.non_fatal_error = 1;
}
if (IS_MODE(MODE_CHECK)) {
if (result >= -1 && (print_verifying_footer() < 0 || print_check_stats() < 0)) {
log_error_file_t(&rhash_data.out_file);
result = -2;
}
if (HAS_OPTION(OPT_SPEED) && !IS_MODE(MODE_UPDATE) && rhash_data.processed > 1)
print_time_stats(time, rhash_data.total_size, 1);
}
return result;
}
/**
* Open the given hash file and process its content.
*
* @param hash_file the hash file to process
* @param files pointer to the vector to load parsed file paths into
* @param chdir true if function should emulate chdir to the parent directory of the hash file
* @return HashFileBits bit mask on success, -1 on input error, -2 on results output error
*/
static int process_hash_file(file_t* hash_file, file_set* files, int chdir)
{
int result;
struct hash_parser *parser = hash_parser_open(hash_file, chdir);
if (!parser) {
/* in the update mode, a non-existent hash file will be created later */
if (IS_MODE(MODE_UPDATE) && errno == ENOENT) {
set_flags_by_hash_file_extension(hash_file, 0);
return HashFileIsEmpty;
}
log_error_file_t(hash_file);
return -1;
}
result = hash_parser_process_file(parser, files);
if (result >= 0 && (hash_file->mode & FileContentIsUtf8) != 0)
result |= HashFileHasBom;
hash_parser_close(parser);
return result;
}
/**
* Verify message digests of the files listed in the given hash file.
* Lines beginning with ';' and '#' are ignored.
* In a case of fail, obtained error will be logged.
*
* @param hash_file the hash file, containing message digests to verify
* @param chdir true if function should emulate chdir to directory of filepath before checking it
* @return HashFileBits bit mask on success, -1 on input error, -2 on results output error
*/
int check_hash_file(file_t* hash_file, int chdir)
{
return process_hash_file(hash_file, 0, chdir);
}
/**
* Load a set of files from the specified hash file.
* In a case of fail, errors will be logged.
*
* @param hash_file the hash file, containing message digests to load
* @param files pointer to the vector to load parsed file paths into
* @return HashFileBits bit mask on success, -1 on input error, -2 on results output error
*/
int load_updated_hash_file(file_t* hash_file, file_set* files)
{
return process_hash_file(hash_file, files, 0);
}
rhash-1.4.6/librhash/ 0000755 0000000 0000000 00000000000 15010731530 013114 5 ustar root root rhash-1.4.6/librhash/sha256.h 0000664 0000000 0000000 00000001550 14703622112 014303 0 ustar root root /* sha.h sha256 and sha224 hash functions */
#ifndef SHA256_H
#define SHA256_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sha256_block_size 64
#define sha256_hash_size 32
#define sha224_hash_size 28
/* algorithm context */
typedef struct sha256_ctx
{
unsigned message[16]; /* 512-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
unsigned hash[8]; /* 256-bit algorithm internal hashing state */
unsigned digest_length; /* length of the algorithm digest in bytes */
} sha256_ctx;
void rhash_sha224_init(sha256_ctx* ctx);
void rhash_sha256_init(sha256_ctx* ctx);
void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* data, size_t length);
void rhash_sha256_final(sha256_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* SHA256_H */
rhash-1.4.6/librhash/snefru.h 0000664 0000000 0000000 00000002107 14703622112 014574 0 ustar root root /* snefru.h */
#ifndef SNEFRU_H
#define SNEFRU_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Snefru-128 processses message by blocks of 48 bytes, */
/* and Snefru-256 uses blocks of 32 bytes */
/* here we declare the maximal block size */
#define snefru_block_size 48
#define snefru128_hash_length 16
#define snefru256_hash_length 32
/* algorithm context */
typedef struct snefru_ctx
{
unsigned hash[8]; /* algorithm 512-bit hashing state */
unsigned char buffer[48]; /* 384-bit message block */
uint64_t length; /* processed message length */
unsigned index; /* index in the buffer of the last byte stored */
unsigned digest_length; /* length of the algorithm digest in bytes */
} snefru_ctx;
/* hash functions */
void rhash_snefru128_init(snefru_ctx* ctx);
void rhash_snefru256_init(snefru_ctx* ctx);
void rhash_snefru_update(snefru_ctx* ctx, const unsigned char* data, size_t size);
void rhash_snefru_final(snefru_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* SNEFRU_H */
rhash-1.4.6/librhash/plug_openssl.h 0000664 0000000 0000000 00000002157 14703622112 016011 0 ustar root root /* plug_openssl.h - plug-in openssl algorithms */
#ifndef RHASH_PLUG_OPENSSL_H
#define RHASH_PLUG_OPENSSL_H
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
#include "algorithms.h"
#ifdef __cplusplus
extern "C" {
#endif
int rhash_plug_openssl(void); /* load openssl algorithms */
unsigned rhash_get_openssl_supported_hash_mask(void);
unsigned rhash_get_openssl_available_hash_mask(void);
unsigned rhash_get_openssl_enabled_hash_mask(void);
void rhash_set_openssl_enabled_hash_mask(unsigned mask);
extern rhash_hash_info rhash_openssl_hash_info[9];
#define rhash_ossl_sha1_init() (rhash_openssl_hash_info[2].init)
#define rhash_ossl_sha1_update() (rhash_openssl_hash_info[2].update)
#define rhash_ossl_sha1_final() (rhash_openssl_hash_info[2].final)
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#else
# define rhash_get_openssl_supported_hash_mask() (0)
# define rhash_get_openssl_available_hash_mask() (0)
# define rhash_get_openssl_enabled_hash_mask() (0)
# define rhash_set_openssl_enabled_hash_mask(mask) {}
#endif /* defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) */
#endif /* RHASH_PLUG_OPENSSL_H */
rhash-1.4.6/librhash/blake3.h 0000664 0000000 0000000 00000001752 15010476501 014441 0 ustar root root /* blake3.h */
#ifndef RHASH_BLAKE3_H
#define RHASH_BLAKE3_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define blake3_block_size 64
#define blake3_hash_size 32
typedef struct blake3_ctx {
uint32_t message[16]; /* current input bytes */
uint64_t length; /* processed data length */
uint32_t stack_depth;
uint32_t final_flags;
union {
uint32_t stack[54 * 8]; /* chain value stack */
struct {
uint32_t root_message[16];
uint32_t hash[16];
} root;
};
} blake3_ctx;
void rhash_blake3_init(blake3_ctx *);
void rhash_blake3_update(blake3_ctx *, const unsigned char* msg, size_t);
void rhash_blake3_final(blake3_ctx *ctx, unsigned char* result);
#if !defined(NO_IMPORT_EXPORT)
size_t rhash_blake3_export(const blake3_ctx* ctx, void* out, size_t size);
size_t rhash_blake3_import(blake3_ctx* ctx, const void* in, size_t size);
#endif /* !defined(NO_IMPORT_EXPORT) */
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_BLAKE3_H */
rhash-1.4.6/librhash/blake3.c 0000664 0000000 0000000 00000026477 15010476501 014447 0 ustar root root #include "blake3.h"
#include "byte_order.h"
#include
#include
#include
const size_t words_per_stack_entry = 8;
const size_t blake3_chunk_size = 1024;
/**
* The initial value (IV) of BLAKE3 is the same as SHA-256 IV.
* This IV is set to the initial chaining value of BLAKE3,
* when no key is used. The first four words IV[0..3] are also
* used by the compression function as the local initial state.
*/
static const uint32_t blake3_IV[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
};
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_blake3_init(struct blake3_ctx *ctx)
{
#if defined(NO_IMPORT_EXPORT)
ctx->length = 0;
ctx->stack_depth = 0;
ctx->final_flags = 0;
#else
const size_t zero_size = offsetof(blake3_ctx, root) + sizeof(ctx->root);
memset(ctx, 0, zero_size);
#endif
memcpy(ctx->stack, blake3_IV, sizeof(blake3_IV));
}
/* Compression Function Flags */
#define CHUNK_START 0x01u
#define CHUNK_END 0x02u
#define PARENT 0x04u
#define ROOT 0x08u
/**
* Array of 7 permutations applied during Rounds 0-6 of
* the BLAKE3 compression function.
*
* Round 0 uses identity permutation and Round 1 uses the
* following base permutation of the 16 indices (0 to 15):
* {2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8}
*
* Subsequent permutations (Rounds 2-6) are derived by applying
* the base permutation iteratively.
*/
static const uint8_t permutations[7][16] = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, /* Round 0 (identity) */
{2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8}, /* Round 1 */
{3, 4, 10, 12, 13, 2, 7, 14, 6, 5, 9, 0, 11, 15, 8, 1}, /* Round 2 */
{10, 7, 12, 9, 14, 3, 13, 15, 4, 0, 11, 2, 5, 8, 1, 6}, /* Round 3 */
{12, 13, 9, 11, 15, 10, 14, 8, 7, 2, 5, 3, 0, 1, 6, 4}, /* Round 4 */
{9, 14, 11, 5, 8, 12, 15, 1, 13, 3, 0, 10, 2, 6, 4, 7}, /* Round 5 */
{11, 15, 5, 0, 1, 9, 8, 6, 14, 10, 2, 12, 3, 4, 7, 13}, /* Round 6 */
};
/**
* Quarter-Round Function G, which processes four 32-bit words
* of the internal state `v[0..15]` at a time.
* A full round of shuffling in BLAKE3 consists of several such
* `G` operations applied to different parts of the state.
*
* The `G` function mixes two input words from the message array `msg[]`
* into four words of the working array `v[0..15]`. The parameters
* `round` and `i` are used to index the appropriate words from `msg[]`.
*
* @param round the current round index.
* @param i the index used to select words from `msg[]`.
* @param a, b, c, d the four words from `v[]` to be processed.
*/
#define G(round, i, a, b, c, d) \
a = a + b + msg[permutations[round][i * 2]]; \
d = ROTR32(d ^ a, 16); \
c = c + d; \
b = ROTR32(b ^ c, 12); \
a = a + b + msg[permutations[round][i * 2 + 1]]; \
d = ROTR32(d ^ a, 8); \
c = c + d; \
b = ROTR32(b ^ c, 7);
#define ROUND(round) \
G(round, 0, v[0], v[4], v[8], v[12]); \
G(round, 1, v[1], v[5], v[9], v[13]); \
G(round, 2, v[2], v[6], v[10], v[14]); \
G(round, 3, v[3], v[7], v[11], v[15]); \
G(round, 4, v[0], v[5], v[10], v[15]); \
G(round, 5, v[1], v[6], v[11], v[12]); \
G(round, 6, v[2], v[7], v[8], v[13]); \
G(round, 7, v[3], v[4], v[9], v[14]);
/**
* BLAKE3 compression function is used to process chunks,
* compute parent nodes within its tree structure,
* and generate output bytes from the root node.
*
* @param output compression result
* @param msg message block to be processed
* @param hash hash chaining value
* @param counter 64-bit counter
* @param length the number of application data bytes in the msg block,
* must be at least 1 and at most 64. It is equal to
* 64 minus the number of padding bytes, which are set to 0x00.
* @param flags bit flags used to compress the current block
*/
static void compress(uint32_t *output,
const uint32_t msg[16], const uint32_t hash[8],
uint64_t counter, uint32_t length, uint32_t flags)
{
uint32_t v[16] = {
hash[0], hash[1], hash[2], hash[3],
hash[4], hash[5], hash[6], hash[7],
blake3_IV[0], blake3_IV[1], blake3_IV[2], blake3_IV[3],
(uint32_t)counter, (uint32_t)(counter >> 32), length, flags,
};
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
if (flags & ROOT) {
output[8] = v[8] ^ hash[0];
output[9] = v[9] ^ hash[1];
output[10] = v[10] ^ hash[2];
output[11] = v[11] ^ hash[3];
output[12] = v[12] ^ hash[4];
output[13] = v[13] ^ hash[5];
output[14] = v[14] ^ hash[6];
output[15] = v[15] ^ hash[7];
}
output[0] = v[0] ^ v[8];
output[1] = v[1] ^ v[9];
output[2] = v[2] ^ v[10];
output[3] = v[3] ^ v[11];
output[4] = v[4] ^ v[12];
output[5] = v[5] ^ v[13];
output[6] = v[6] ^ v[14];
output[7] = v[7] ^ v[15];
}
/* Process a block of 64 bytes */
static void process_block(struct blake3_ctx *ctx, const uint32_t msg[16])
{
uint32_t *cur_hash = ctx->stack + ctx->stack_depth * words_per_stack_entry;
uint64_t tail_index = ctx->length - 1;
uint64_t chunk_index = tail_index >> 10;
uint32_t block_index_bits = (uint32_t)tail_index & 0x3c0;
uint32_t flags = 0;
switch (block_index_bits) {
case 0:
flags = CHUNK_START; /* the first block of a chunk */
break;
case 15 << 6:
flags = CHUNK_END; /* the last block of a chunk */
break;
}
compress(cur_hash, msg, cur_hash, chunk_index, blake3_block_size, flags);
if ((flags & CHUNK_END) != 0) {
/* process Merkle tree */
uint64_t path = chunk_index + 1;
for (; (path & 1) == 0; path >>= 1) {
cur_hash -= words_per_stack_entry;
compress(cur_hash, cur_hash, blake3_IV, 0, blake3_block_size, PARENT);
}
cur_hash += words_per_stack_entry;
memcpy(cur_hash, blake3_IV, sizeof(blake3_IV));
}
ctx->stack_depth = (uint32_t)((cur_hash - ctx->stack) / words_per_stack_entry);
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_blake3_update(blake3_ctx *ctx, const unsigned char* msg, size_t size)
{
unsigned index = ctx->length ? (((unsigned)ctx->length - 1) & 63) + 1 : 0;
/* fill partial block */
if (index) {
size_t left = blake3_block_size - index;
if (size < left)
left = size;
le32_copy(ctx->message, index, msg, left);
ctx->length += left;
size -= left;
if (!size)
return;
/* process partial block */
process_block(ctx, ctx->message);
msg += left;
}
while (size > blake3_block_size) {
uint32_t* aligned_message_block;
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
/* the most common case is processing a 32-bit aligned message
on a little-endian CPU without copying it */
aligned_message_block = (uint32_t*)msg;
} else {
le32_copy(ctx->message, 0, msg, blake3_block_size);
aligned_message_block = ctx->message;
}
ctx->length += blake3_block_size;
process_block(ctx, aligned_message_block);
msg += blake3_block_size;
size -= blake3_block_size;
}
if (size) {
/* save leftovers */
le32_copy(ctx->message, 0, msg, size);
ctx->length += size;
}
}
/**
* Process the last block.
*
* @param ctx the algorithm context containing current hashing state
*/
static void process_last_block(blake3_ctx *ctx)
{
uint64_t tail_index = ctx->length ? ctx->length - 1 : 0;
uint32_t index = ctx->length ? ((uint32_t)tail_index & 63) + 1 : 0;
uint32_t flags = tail_index & 0x3c0 ? CHUNK_END : CHUNK_START | CHUNK_END;
uint32_t *message;
uint32_t *cur_hash = ctx->stack + ctx->stack_depth * words_per_stack_entry;
/* pad the last block with zeros */
le32_memset(ctx->message, index, 0, blake3_block_size - index);
if (ctx->stack_depth == 0) {
/* use the padded message to get root hash */
message = ctx->message;
} else {
/* compress the last chunk */
uint64_t chunk_index = tail_index >> 10;
compress(cur_hash, ctx->message, cur_hash, chunk_index, index, flags);
/* calculate the top parent hash of the tree */
flags = PARENT;
while ((cur_hash -= words_per_stack_entry) != ctx->stack)
compress(cur_hash, cur_hash, blake3_IV, 0, blake3_block_size, flags);
index = blake3_block_size;
ctx->stack_depth = 0;
message = ctx->root.root_message;
cur_hash = (uint32_t *)blake3_IV;
}
flags |= ROOT;
ctx->final_flags = flags;
compress(ctx->root.hash, message, cur_hash, 0, index, flags);
}
/**
* Store calculated 256-bit hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result buffer to receive the calculated hash or NULL
*/
void rhash_blake3_final(blake3_ctx *ctx, unsigned char* result)
{
if (!ctx->final_flags)
process_last_block(ctx);
if (result)
le32_copy(result, 0, ctx->root.hash, blake3_hash_size);
}
#if !defined(NO_IMPORT_EXPORT)
/**
* Load a 32-bit unsigned integer from memory in memory order.
* Performs no bounds checking - caller must ensure memory is accessible.
*
* @param data pointer to the memory region containing the 32-bit value.
* Must have at least 4 bytes of readable memory.
* @return the 32-bit value constructed from the memory bytes according
* to system endianness.
*/
static uint32_t load_uint32(const uint8_t *data)
{
#if IS_LITTLE_ENDIAN
return (uint32_t)data[0] | (uint32_t)data[1] << 8 |
(uint32_t)data[2] << 16 | (uint32_t)data[3] << 24;
#else
return (uint32_t)data[3] | (uint32_t)data[2] << 8 |
(uint32_t)data[1] << 16 | (uint32_t)data[0] << 24;
#endif
}
/**
* Calculate the minimum stack size in bytes based on the stack depth,
* ensuring the stack contains blake3_ctx.root structure.
* The size calculation accounts for:
* - Each stack entry being 8 uint32_t values (32 bytes)
* - A minimum stack size of 32 uint32_t values (128 bytes)
*
* @param stack_depth the desired depth of the stack (number of entries)
* @return size_t the calculated stack size in bytes
*/
static size_t get_stack_size(uint32_t stack_depth)
{
const size_t bytes_per_entry = sizeof(uint32_t) * words_per_stack_entry;
const size_t min_stack_bytes = sizeof(uint32_t) * 32;
size_t size = stack_depth * bytes_per_entry;
return size < min_stack_bytes ? min_stack_bytes : size;
}
/**
* Export tth context to a memory region, or calculate the
* size required for context export.
*
* @param ctx the algorithm context containing current hashing state
* @param out pointer to the memory region or NULL
* @param size size of memory region
* @return the size of the exported data on success, 0 on fail.
*/
size_t rhash_blake3_export(const blake3_ctx* ctx, void* out, size_t size)
{
size_t export_size = offsetof(blake3_ctx, stack) + get_stack_size(ctx->stack_depth);
if (out != NULL) {
if (size < export_size)
return 0;
memcpy(out, ctx, export_size);
}
return export_size;
}
/**
* Import tth context from a memory region.
*
* @param ctx pointer to the algorithm context
* @param in pointer to the data to import
* @param size size of data to import
* @return the size of the imported data on success, 0 on fail.
*/
size_t rhash_blake3_import(blake3_ctx* ctx, const void* in, size_t size)
{
uint32_t stack_depth = load_uint32(
(const uint8_t*)in + offsetof(blake3_ctx, stack_depth));
size_t import_size =
offsetof(blake3_ctx, stack) + get_stack_size(stack_depth);
if (size < import_size)
return 0;
memcpy(ctx, in, import_size);
assert(ctx->stack_depth == stack_depth);
return import_size;
}
#endif /* !defined(NO_IMPORT_EXPORT) */
rhash-1.4.6/librhash/whirlpool.c 0000664 0000000 0000000 00000014576 14703622112 015321 0 ustar root root /* whirlpool.c - an implementation of the Whirlpool Hash Function.
*
* Copyright (c) 2009, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Documentation:
* P. S. L. M. Barreto, V. Rijmen, ``The Whirlpool hashing function,''
* NESSIE submission, 2000 (tweaked version, 2001)
*
* The algorithm is named after the Whirlpool Galaxy in Canes Venatici.
*/
#include
#include "byte_order.h"
#include "whirlpool.h"
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_whirlpool_init(struct whirlpool_ctx* ctx)
{
ctx->length = 0;
memset(ctx->hash, 0, sizeof(ctx->hash));
}
/* Algorithm S-Box */
extern uint64_t rhash_whirlpool_sbox[8][256];
#define WHIRLPOOL_OP(src, shift) ( \
rhash_whirlpool_sbox[0][(int)(src[ shift & 7] >> 56) ] ^ \
rhash_whirlpool_sbox[1][(int)(src[(shift + 7) & 7] >> 48) & 0xff] ^ \
rhash_whirlpool_sbox[2][(int)(src[(shift + 6) & 7] >> 40) & 0xff] ^ \
rhash_whirlpool_sbox[3][(int)(src[(shift + 5) & 7] >> 32) & 0xff] ^ \
rhash_whirlpool_sbox[4][(int)(src[(shift + 4) & 7] >> 24) & 0xff] ^ \
rhash_whirlpool_sbox[5][(int)(src[(shift + 3) & 7] >> 16) & 0xff] ^ \
rhash_whirlpool_sbox[6][(int)(src[(shift + 2) & 7] >> 8) & 0xff] ^ \
rhash_whirlpool_sbox[7][(int)(src[(shift + 1) & 7] ) & 0xff])
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_whirlpool_process_block(uint64_t* hash, uint64_t* p_block)
{
int i; /* loop counter */
uint64_t K[2][8]; /* key */
uint64_t state[2][8]; /* state */
/* alternating binary flags */
unsigned int m = 0;
/* the number of rounds of the internal dedicated block cipher */
const int number_of_rounds = 10;
/* array used in the rounds */
static const uint64_t rc[10] = {
I64(0x1823c6e887b8014f),
I64(0x36a6d2f5796f9152),
I64(0x60bc9b8ea30c7b35),
I64(0x1de0d7c22e4bfe57),
I64(0x157737e59ff04ada),
I64(0x58c9290ab1a06b85),
I64(0xbd5d10f4cb3e0567),
I64(0xe427418ba77d95d8),
I64(0xfbee7c66dd17479e),
I64(0xca2dbf07ad5a8333)
};
/* map the message buffer to a block */
for (i = 0; i < 8; i++) {
/* store K^0 and xor it with the intermediate hash state */
K[0][i] = hash[i];
state[0][i] = be2me_64(p_block[i]) ^ hash[i];
hash[i] = state[0][i];
}
/* iterate over algorithm rounds */
for (i = 0; i < number_of_rounds; i++)
{
/* compute K^i from K^{i-1} */
K[m ^ 1][0] = WHIRLPOOL_OP(K[m], 0) ^ rc[i];
K[m ^ 1][1] = WHIRLPOOL_OP(K[m], 1);
K[m ^ 1][2] = WHIRLPOOL_OP(K[m], 2);
K[m ^ 1][3] = WHIRLPOOL_OP(K[m], 3);
K[m ^ 1][4] = WHIRLPOOL_OP(K[m], 4);
K[m ^ 1][5] = WHIRLPOOL_OP(K[m], 5);
K[m ^ 1][6] = WHIRLPOOL_OP(K[m], 6);
K[m ^ 1][7] = WHIRLPOOL_OP(K[m], 7);
/* apply the i-th round transformation */
state[m ^ 1][0] = WHIRLPOOL_OP(state[m], 0) ^ K[m ^ 1][0];
state[m ^ 1][1] = WHIRLPOOL_OP(state[m], 1) ^ K[m ^ 1][1];
state[m ^ 1][2] = WHIRLPOOL_OP(state[m], 2) ^ K[m ^ 1][2];
state[m ^ 1][3] = WHIRLPOOL_OP(state[m], 3) ^ K[m ^ 1][3];
state[m ^ 1][4] = WHIRLPOOL_OP(state[m], 4) ^ K[m ^ 1][4];
state[m ^ 1][5] = WHIRLPOOL_OP(state[m], 5) ^ K[m ^ 1][5];
state[m ^ 1][6] = WHIRLPOOL_OP(state[m], 6) ^ K[m ^ 1][6];
state[m ^ 1][7] = WHIRLPOOL_OP(state[m], 7) ^ K[m ^ 1][7];
m = m ^ 1;
}
/* apply the Miyaguchi-Preneel compression function */
hash[0] ^= state[0][0];
hash[1] ^= state[0][1];
hash[2] ^= state[0][2];
hash[3] ^= state[0][3];
hash[4] ^= state[0][4];
hash[5] ^= state[0][5];
hash[6] ^= state[0][6];
hash[7] ^= state[0][7];
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_whirlpool_update(whirlpool_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
unsigned left;
ctx->length += size;
/* fill partial block */
if (index) {
left = whirlpool_block_size - index;
memcpy(ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_whirlpool_process_block(ctx->hash, (uint64_t*)ctx->message);
msg += left;
size -= left;
}
while (size >= whirlpool_block_size) {
uint64_t* aligned_message_block;
if (IS_ALIGNED_64(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (uint64_t*)msg;
} else {
memcpy(ctx->message, msg, whirlpool_block_size);
aligned_message_block = (uint64_t*)ctx->message;
}
rhash_whirlpool_process_block(ctx->hash, aligned_message_block);
msg += whirlpool_block_size;
size -= whirlpool_block_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_whirlpool_final(whirlpool_ctx* ctx, unsigned char* result)
{
unsigned index = (unsigned)ctx->length & 63;
uint64_t* msg64 = (uint64_t*)ctx->message;
/* pad message and run for last block */
ctx->message[index++] = 0x80;
/* if no room left in the message to store 256-bit message length */
if (index > 32) {
/* then pad the rest with zeros and process it */
while (index < 64) {
ctx->message[index++] = 0;
}
rhash_whirlpool_process_block(ctx->hash, msg64);
index = 0;
}
/* due to optimization actually only 64-bit of message length are stored */
while (index < 56) {
ctx->message[index++] = 0;
}
msg64[7] = be2me_64(ctx->length << 3);
rhash_whirlpool_process_block(ctx->hash, msg64);
/* save result hash */
be64_copy(result, 0, ctx->hash, 64);
}
rhash-1.4.6/librhash/whirlpool_sbox.c 0000664 0000000 0000000 00000150110 14703622112 016335 0 ustar root root /* whirlpool_sbox.c - S-Box for the Whirlpool hash function
*
* Copyright (c) 2009, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "byte_order.h"
uint64_t rhash_whirlpool_sbox[8][256] = {
{
/* C0 vectors */
I64(0x18186018c07830d8), I64(0x23238c2305af4626), I64(0xc6c63fc67ef991b8), I64(0xe8e887e8136fcdfb),
I64(0x878726874ca113cb), I64(0xb8b8dab8a9626d11), I64(0x0101040108050209), I64(0x4f4f214f426e9e0d),
I64(0x3636d836adee6c9b), I64(0xa6a6a2a6590451ff), I64(0xd2d26fd2debdb90c), I64(0xf5f5f3f5fb06f70e),
I64(0x7979f979ef80f296), I64(0x6f6fa16f5fcede30), I64(0x91917e91fcef3f6d), I64(0x52525552aa07a4f8),
I64(0x60609d6027fdc047), I64(0xbcbccabc89766535), I64(0x9b9b569baccd2b37), I64(0x8e8e028e048c018a),
I64(0xa3a3b6a371155bd2), I64(0x0c0c300c603c186c), I64(0x7b7bf17bff8af684), I64(0x3535d435b5e16a80),
I64(0x1d1d741de8693af5), I64(0xe0e0a7e05347ddb3), I64(0xd7d77bd7f6acb321), I64(0xc2c22fc25eed999c),
I64(0x2e2eb82e6d965c43), I64(0x4b4b314b627a9629), I64(0xfefedffea321e15d), I64(0x575741578216aed5),
I64(0x15155415a8412abd), I64(0x7777c1779fb6eee8), I64(0x3737dc37a5eb6e92), I64(0xe5e5b3e57b56d79e),
I64(0x9f9f469f8cd92313), I64(0xf0f0e7f0d317fd23), I64(0x4a4a354a6a7f9420), I64(0xdada4fda9e95a944),
I64(0x58587d58fa25b0a2), I64(0xc9c903c906ca8fcf), I64(0x2929a429558d527c), I64(0x0a0a280a5022145a),
I64(0xb1b1feb1e14f7f50), I64(0xa0a0baa0691a5dc9), I64(0x6b6bb16b7fdad614), I64(0x85852e855cab17d9),
I64(0xbdbdcebd8173673c), I64(0x5d5d695dd234ba8f), I64(0x1010401080502090), I64(0xf4f4f7f4f303f507),
I64(0xcbcb0bcb16c08bdd), I64(0x3e3ef83eedc67cd3), I64(0x0505140528110a2d), I64(0x676781671fe6ce78),
I64(0xe4e4b7e47353d597), I64(0x27279c2725bb4e02), I64(0x4141194132588273), I64(0x8b8b168b2c9d0ba7),
I64(0xa7a7a6a7510153f6), I64(0x7d7de97dcf94fab2), I64(0x95956e95dcfb3749), I64(0xd8d847d88e9fad56),
I64(0xfbfbcbfb8b30eb70), I64(0xeeee9fee2371c1cd), I64(0x7c7ced7cc791f8bb), I64(0x6666856617e3cc71),
I64(0xdddd53dda68ea77b), I64(0x17175c17b84b2eaf), I64(0x4747014702468e45), I64(0x9e9e429e84dc211a),
I64(0xcaca0fca1ec589d4), I64(0x2d2db42d75995a58), I64(0xbfbfc6bf9179632e), I64(0x07071c07381b0e3f),
I64(0xadad8ead012347ac), I64(0x5a5a755aea2fb4b0), I64(0x838336836cb51bef), I64(0x3333cc3385ff66b6),
I64(0x636391633ff2c65c), I64(0x02020802100a0412), I64(0xaaaa92aa39384993), I64(0x7171d971afa8e2de),
I64(0xc8c807c80ecf8dc6), I64(0x19196419c87d32d1), I64(0x494939497270923b), I64(0xd9d943d9869aaf5f),
I64(0xf2f2eff2c31df931), I64(0xe3e3abe34b48dba8), I64(0x5b5b715be22ab6b9), I64(0x88881a8834920dbc),
I64(0x9a9a529aa4c8293e), I64(0x262698262dbe4c0b), I64(0x3232c8328dfa64bf), I64(0xb0b0fab0e94a7d59),
I64(0xe9e983e91b6acff2), I64(0x0f0f3c0f78331e77), I64(0xd5d573d5e6a6b733), I64(0x80803a8074ba1df4),
I64(0xbebec2be997c6127), I64(0xcdcd13cd26de87eb), I64(0x3434d034bde46889), I64(0x48483d487a759032),
I64(0xffffdbffab24e354), I64(0x7a7af57af78ff48d), I64(0x90907a90f4ea3d64), I64(0x5f5f615fc23ebe9d),
I64(0x202080201da0403d), I64(0x6868bd6867d5d00f), I64(0x1a1a681ad07234ca), I64(0xaeae82ae192c41b7),
I64(0xb4b4eab4c95e757d), I64(0x54544d549a19a8ce), I64(0x93937693ece53b7f), I64(0x222288220daa442f),
I64(0x64648d6407e9c863), I64(0xf1f1e3f1db12ff2a), I64(0x7373d173bfa2e6cc), I64(0x12124812905a2482),
I64(0x40401d403a5d807a), I64(0x0808200840281048), I64(0xc3c32bc356e89b95), I64(0xecec97ec337bc5df),
I64(0xdbdb4bdb9690ab4d), I64(0xa1a1bea1611f5fc0), I64(0x8d8d0e8d1c830791), I64(0x3d3df43df5c97ac8),
I64(0x97976697ccf1335b), I64(0x0000000000000000), I64(0xcfcf1bcf36d483f9), I64(0x2b2bac2b4587566e),
I64(0x7676c57697b3ece1), I64(0x8282328264b019e6), I64(0xd6d67fd6fea9b128), I64(0x1b1b6c1bd87736c3),
I64(0xb5b5eeb5c15b7774), I64(0xafaf86af112943be), I64(0x6a6ab56a77dfd41d), I64(0x50505d50ba0da0ea),
I64(0x45450945124c8a57), I64(0xf3f3ebf3cb18fb38), I64(0x3030c0309df060ad), I64(0xefef9bef2b74c3c4),
I64(0x3f3ffc3fe5c37eda), I64(0x55554955921caac7), I64(0xa2a2b2a2791059db), I64(0xeaea8fea0365c9e9),
I64(0x656589650fecca6a), I64(0xbabad2bab9686903), I64(0x2f2fbc2f65935e4a), I64(0xc0c027c04ee79d8e),
I64(0xdede5fdebe81a160), I64(0x1c1c701ce06c38fc), I64(0xfdfdd3fdbb2ee746), I64(0x4d4d294d52649a1f),
I64(0x92927292e4e03976), I64(0x7575c9758fbceafa), I64(0x06061806301e0c36), I64(0x8a8a128a249809ae),
I64(0xb2b2f2b2f940794b), I64(0xe6e6bfe66359d185), I64(0x0e0e380e70361c7e), I64(0x1f1f7c1ff8633ee7),
I64(0x6262956237f7c455), I64(0xd4d477d4eea3b53a), I64(0xa8a89aa829324d81), I64(0x96966296c4f43152),
I64(0xf9f9c3f99b3aef62), I64(0xc5c533c566f697a3), I64(0x2525942535b14a10), I64(0x59597959f220b2ab),
I64(0x84842a8454ae15d0), I64(0x7272d572b7a7e4c5), I64(0x3939e439d5dd72ec), I64(0x4c4c2d4c5a619816),
I64(0x5e5e655eca3bbc94), I64(0x7878fd78e785f09f), I64(0x3838e038ddd870e5), I64(0x8c8c0a8c14860598),
I64(0xd1d163d1c6b2bf17), I64(0xa5a5aea5410b57e4), I64(0xe2e2afe2434dd9a1), I64(0x616199612ff8c24e),
I64(0xb3b3f6b3f1457b42), I64(0x2121842115a54234), I64(0x9c9c4a9c94d62508), I64(0x1e1e781ef0663cee),
I64(0x4343114322528661), I64(0xc7c73bc776fc93b1), I64(0xfcfcd7fcb32be54f), I64(0x0404100420140824),
I64(0x51515951b208a2e3), I64(0x99995e99bcc72f25), I64(0x6d6da96d4fc4da22), I64(0x0d0d340d68391a65),
I64(0xfafacffa8335e979), I64(0xdfdf5bdfb684a369), I64(0x7e7ee57ed79bfca9), I64(0x242490243db44819),
I64(0x3b3bec3bc5d776fe), I64(0xabab96ab313d4b9a), I64(0xcece1fce3ed181f0), I64(0x1111441188552299),
I64(0x8f8f068f0c890383), I64(0x4e4e254e4a6b9c04), I64(0xb7b7e6b7d1517366), I64(0xebeb8beb0b60cbe0),
I64(0x3c3cf03cfdcc78c1), I64(0x81813e817cbf1ffd), I64(0x94946a94d4fe3540), I64(0xf7f7fbf7eb0cf31c),
I64(0xb9b9deb9a1676f18), I64(0x13134c13985f268b), I64(0x2c2cb02c7d9c5851), I64(0xd3d36bd3d6b8bb05),
I64(0xe7e7bbe76b5cd38c), I64(0x6e6ea56e57cbdc39), I64(0xc4c437c46ef395aa), I64(0x03030c03180f061b),
I64(0x565645568a13acdc), I64(0x44440d441a49885e), I64(0x7f7fe17fdf9efea0), I64(0xa9a99ea921374f88),
I64(0x2a2aa82a4d825467), I64(0xbbbbd6bbb16d6b0a), I64(0xc1c123c146e29f87), I64(0x53535153a202a6f1),
I64(0xdcdc57dcae8ba572), I64(0x0b0b2c0b58271653), I64(0x9d9d4e9d9cd32701), I64(0x6c6cad6c47c1d82b),
I64(0x3131c43195f562a4), I64(0x7474cd7487b9e8f3), I64(0xf6f6fff6e309f115), I64(0x464605460a438c4c),
I64(0xacac8aac092645a5), I64(0x89891e893c970fb5), I64(0x14145014a04428b4), I64(0xe1e1a3e15b42dfba),
I64(0x16165816b04e2ca6), I64(0x3a3ae83acdd274f7), I64(0x6969b9696fd0d206), I64(0x09092409482d1241),
I64(0x7070dd70a7ade0d7), I64(0xb6b6e2b6d954716f), I64(0xd0d067d0ceb7bd1e), I64(0xeded93ed3b7ec7d6),
I64(0xcccc17cc2edb85e2), I64(0x424215422a578468), I64(0x98985a98b4c22d2c), I64(0xa4a4aaa4490e55ed),
I64(0x2828a0285d885075), I64(0x5c5c6d5cda31b886), I64(0xf8f8c7f8933fed6b), I64(0x8686228644a411c2),
}, {
/* C1 vectors */
I64(0xd818186018c07830), I64(0x2623238c2305af46), I64(0xb8c6c63fc67ef991), I64(0xfbe8e887e8136fcd),
I64(0xcb878726874ca113), I64(0x11b8b8dab8a9626d), I64(0x0901010401080502), I64(0x0d4f4f214f426e9e),
I64(0x9b3636d836adee6c), I64(0xffa6a6a2a6590451), I64(0x0cd2d26fd2debdb9), I64(0x0ef5f5f3f5fb06f7),
I64(0x967979f979ef80f2), I64(0x306f6fa16f5fcede), I64(0x6d91917e91fcef3f), I64(0xf852525552aa07a4),
I64(0x4760609d6027fdc0), I64(0x35bcbccabc897665), I64(0x379b9b569baccd2b), I64(0x8a8e8e028e048c01),
I64(0xd2a3a3b6a371155b), I64(0x6c0c0c300c603c18), I64(0x847b7bf17bff8af6), I64(0x803535d435b5e16a),
I64(0xf51d1d741de8693a), I64(0xb3e0e0a7e05347dd), I64(0x21d7d77bd7f6acb3), I64(0x9cc2c22fc25eed99),
I64(0x432e2eb82e6d965c), I64(0x294b4b314b627a96), I64(0x5dfefedffea321e1), I64(0xd5575741578216ae),
I64(0xbd15155415a8412a), I64(0xe87777c1779fb6ee), I64(0x923737dc37a5eb6e), I64(0x9ee5e5b3e57b56d7),
I64(0x139f9f469f8cd923), I64(0x23f0f0e7f0d317fd), I64(0x204a4a354a6a7f94), I64(0x44dada4fda9e95a9),
I64(0xa258587d58fa25b0), I64(0xcfc9c903c906ca8f), I64(0x7c2929a429558d52), I64(0x5a0a0a280a502214),
I64(0x50b1b1feb1e14f7f), I64(0xc9a0a0baa0691a5d), I64(0x146b6bb16b7fdad6), I64(0xd985852e855cab17),
I64(0x3cbdbdcebd817367), I64(0x8f5d5d695dd234ba), I64(0x9010104010805020), I64(0x07f4f4f7f4f303f5),
I64(0xddcbcb0bcb16c08b), I64(0xd33e3ef83eedc67c), I64(0x2d0505140528110a), I64(0x78676781671fe6ce),
I64(0x97e4e4b7e47353d5), I64(0x0227279c2725bb4e), I64(0x7341411941325882), I64(0xa78b8b168b2c9d0b),
I64(0xf6a7a7a6a7510153), I64(0xb27d7de97dcf94fa), I64(0x4995956e95dcfb37), I64(0x56d8d847d88e9fad),
I64(0x70fbfbcbfb8b30eb), I64(0xcdeeee9fee2371c1), I64(0xbb7c7ced7cc791f8), I64(0x716666856617e3cc),
I64(0x7bdddd53dda68ea7), I64(0xaf17175c17b84b2e), I64(0x454747014702468e), I64(0x1a9e9e429e84dc21),
I64(0xd4caca0fca1ec589), I64(0x582d2db42d75995a), I64(0x2ebfbfc6bf917963), I64(0x3f07071c07381b0e),
I64(0xacadad8ead012347), I64(0xb05a5a755aea2fb4), I64(0xef838336836cb51b), I64(0xb63333cc3385ff66),
I64(0x5c636391633ff2c6), I64(0x1202020802100a04), I64(0x93aaaa92aa393849), I64(0xde7171d971afa8e2),
I64(0xc6c8c807c80ecf8d), I64(0xd119196419c87d32), I64(0x3b49493949727092), I64(0x5fd9d943d9869aaf),
I64(0x31f2f2eff2c31df9), I64(0xa8e3e3abe34b48db), I64(0xb95b5b715be22ab6), I64(0xbc88881a8834920d),
I64(0x3e9a9a529aa4c829), I64(0x0b262698262dbe4c), I64(0xbf3232c8328dfa64), I64(0x59b0b0fab0e94a7d),
I64(0xf2e9e983e91b6acf), I64(0x770f0f3c0f78331e), I64(0x33d5d573d5e6a6b7), I64(0xf480803a8074ba1d),
I64(0x27bebec2be997c61), I64(0xebcdcd13cd26de87), I64(0x893434d034bde468), I64(0x3248483d487a7590),
I64(0x54ffffdbffab24e3), I64(0x8d7a7af57af78ff4), I64(0x6490907a90f4ea3d), I64(0x9d5f5f615fc23ebe),
I64(0x3d202080201da040), I64(0x0f6868bd6867d5d0), I64(0xca1a1a681ad07234), I64(0xb7aeae82ae192c41),
I64(0x7db4b4eab4c95e75), I64(0xce54544d549a19a8), I64(0x7f93937693ece53b), I64(0x2f222288220daa44),
I64(0x6364648d6407e9c8), I64(0x2af1f1e3f1db12ff), I64(0xcc7373d173bfa2e6), I64(0x8212124812905a24),
I64(0x7a40401d403a5d80), I64(0x4808082008402810), I64(0x95c3c32bc356e89b), I64(0xdfecec97ec337bc5),
I64(0x4ddbdb4bdb9690ab), I64(0xc0a1a1bea1611f5f), I64(0x918d8d0e8d1c8307), I64(0xc83d3df43df5c97a),
I64(0x5b97976697ccf133), I64(0x0000000000000000), I64(0xf9cfcf1bcf36d483), I64(0x6e2b2bac2b458756),
I64(0xe17676c57697b3ec), I64(0xe68282328264b019), I64(0x28d6d67fd6fea9b1), I64(0xc31b1b6c1bd87736),
I64(0x74b5b5eeb5c15b77), I64(0xbeafaf86af112943), I64(0x1d6a6ab56a77dfd4), I64(0xea50505d50ba0da0),
I64(0x5745450945124c8a), I64(0x38f3f3ebf3cb18fb), I64(0xad3030c0309df060), I64(0xc4efef9bef2b74c3),
I64(0xda3f3ffc3fe5c37e), I64(0xc755554955921caa), I64(0xdba2a2b2a2791059), I64(0xe9eaea8fea0365c9),
I64(0x6a656589650fecca), I64(0x03babad2bab96869), I64(0x4a2f2fbc2f65935e), I64(0x8ec0c027c04ee79d),
I64(0x60dede5fdebe81a1), I64(0xfc1c1c701ce06c38), I64(0x46fdfdd3fdbb2ee7), I64(0x1f4d4d294d52649a),
I64(0x7692927292e4e039), I64(0xfa7575c9758fbcea), I64(0x3606061806301e0c), I64(0xae8a8a128a249809),
I64(0x4bb2b2f2b2f94079), I64(0x85e6e6bfe66359d1), I64(0x7e0e0e380e70361c), I64(0xe71f1f7c1ff8633e),
I64(0x556262956237f7c4), I64(0x3ad4d477d4eea3b5), I64(0x81a8a89aa829324d), I64(0x5296966296c4f431),
I64(0x62f9f9c3f99b3aef), I64(0xa3c5c533c566f697), I64(0x102525942535b14a), I64(0xab59597959f220b2),
I64(0xd084842a8454ae15), I64(0xc57272d572b7a7e4), I64(0xec3939e439d5dd72), I64(0x164c4c2d4c5a6198),
I64(0x945e5e655eca3bbc), I64(0x9f7878fd78e785f0), I64(0xe53838e038ddd870), I64(0x988c8c0a8c148605),
I64(0x17d1d163d1c6b2bf), I64(0xe4a5a5aea5410b57), I64(0xa1e2e2afe2434dd9), I64(0x4e616199612ff8c2),
I64(0x42b3b3f6b3f1457b), I64(0x342121842115a542), I64(0x089c9c4a9c94d625), I64(0xee1e1e781ef0663c),
I64(0x6143431143225286), I64(0xb1c7c73bc776fc93), I64(0x4ffcfcd7fcb32be5), I64(0x2404041004201408),
I64(0xe351515951b208a2), I64(0x2599995e99bcc72f), I64(0x226d6da96d4fc4da), I64(0x650d0d340d68391a),
I64(0x79fafacffa8335e9), I64(0x69dfdf5bdfb684a3), I64(0xa97e7ee57ed79bfc), I64(0x19242490243db448),
I64(0xfe3b3bec3bc5d776), I64(0x9aabab96ab313d4b), I64(0xf0cece1fce3ed181), I64(0x9911114411885522),
I64(0x838f8f068f0c8903), I64(0x044e4e254e4a6b9c), I64(0x66b7b7e6b7d15173), I64(0xe0ebeb8beb0b60cb),
I64(0xc13c3cf03cfdcc78), I64(0xfd81813e817cbf1f), I64(0x4094946a94d4fe35), I64(0x1cf7f7fbf7eb0cf3),
I64(0x18b9b9deb9a1676f), I64(0x8b13134c13985f26), I64(0x512c2cb02c7d9c58), I64(0x05d3d36bd3d6b8bb),
I64(0x8ce7e7bbe76b5cd3), I64(0x396e6ea56e57cbdc), I64(0xaac4c437c46ef395), I64(0x1b03030c03180f06),
I64(0xdc565645568a13ac), I64(0x5e44440d441a4988), I64(0xa07f7fe17fdf9efe), I64(0x88a9a99ea921374f),
I64(0x672a2aa82a4d8254), I64(0x0abbbbd6bbb16d6b), I64(0x87c1c123c146e29f), I64(0xf153535153a202a6),
I64(0x72dcdc57dcae8ba5), I64(0x530b0b2c0b582716), I64(0x019d9d4e9d9cd327), I64(0x2b6c6cad6c47c1d8),
I64(0xa43131c43195f562), I64(0xf37474cd7487b9e8), I64(0x15f6f6fff6e309f1), I64(0x4c464605460a438c),
I64(0xa5acac8aac092645), I64(0xb589891e893c970f), I64(0xb414145014a04428), I64(0xbae1e1a3e15b42df),
I64(0xa616165816b04e2c), I64(0xf73a3ae83acdd274), I64(0x066969b9696fd0d2), I64(0x4109092409482d12),
I64(0xd77070dd70a7ade0), I64(0x6fb6b6e2b6d95471), I64(0x1ed0d067d0ceb7bd), I64(0xd6eded93ed3b7ec7),
I64(0xe2cccc17cc2edb85), I64(0x68424215422a5784), I64(0x2c98985a98b4c22d), I64(0xeda4a4aaa4490e55),
I64(0x752828a0285d8850), I64(0x865c5c6d5cda31b8), I64(0x6bf8f8c7f8933fed), I64(0xc28686228644a411),
}, {
/* C2 vectors */
I64(0x30d818186018c078), I64(0x462623238c2305af), I64(0x91b8c6c63fc67ef9), I64(0xcdfbe8e887e8136f),
I64(0x13cb878726874ca1), I64(0x6d11b8b8dab8a962), I64(0x0209010104010805), I64(0x9e0d4f4f214f426e),
I64(0x6c9b3636d836adee), I64(0x51ffa6a6a2a65904), I64(0xb90cd2d26fd2debd), I64(0xf70ef5f5f3f5fb06),
I64(0xf2967979f979ef80), I64(0xde306f6fa16f5fce), I64(0x3f6d91917e91fcef), I64(0xa4f852525552aa07),
I64(0xc04760609d6027fd), I64(0x6535bcbccabc8976), I64(0x2b379b9b569baccd), I64(0x018a8e8e028e048c),
I64(0x5bd2a3a3b6a37115), I64(0x186c0c0c300c603c), I64(0xf6847b7bf17bff8a), I64(0x6a803535d435b5e1),
I64(0x3af51d1d741de869), I64(0xddb3e0e0a7e05347), I64(0xb321d7d77bd7f6ac), I64(0x999cc2c22fc25eed),
I64(0x5c432e2eb82e6d96), I64(0x96294b4b314b627a), I64(0xe15dfefedffea321), I64(0xaed5575741578216),
I64(0x2abd15155415a841), I64(0xeee87777c1779fb6), I64(0x6e923737dc37a5eb), I64(0xd79ee5e5b3e57b56),
I64(0x23139f9f469f8cd9), I64(0xfd23f0f0e7f0d317), I64(0x94204a4a354a6a7f), I64(0xa944dada4fda9e95),
I64(0xb0a258587d58fa25), I64(0x8fcfc9c903c906ca), I64(0x527c2929a429558d), I64(0x145a0a0a280a5022),
I64(0x7f50b1b1feb1e14f), I64(0x5dc9a0a0baa0691a), I64(0xd6146b6bb16b7fda), I64(0x17d985852e855cab),
I64(0x673cbdbdcebd8173), I64(0xba8f5d5d695dd234), I64(0x2090101040108050), I64(0xf507f4f4f7f4f303),
I64(0x8bddcbcb0bcb16c0), I64(0x7cd33e3ef83eedc6), I64(0x0a2d050514052811), I64(0xce78676781671fe6),
I64(0xd597e4e4b7e47353), I64(0x4e0227279c2725bb), I64(0x8273414119413258), I64(0x0ba78b8b168b2c9d),
I64(0x53f6a7a7a6a75101), I64(0xfab27d7de97dcf94), I64(0x374995956e95dcfb), I64(0xad56d8d847d88e9f),
I64(0xeb70fbfbcbfb8b30), I64(0xc1cdeeee9fee2371), I64(0xf8bb7c7ced7cc791), I64(0xcc716666856617e3),
I64(0xa77bdddd53dda68e), I64(0x2eaf17175c17b84b), I64(0x8e45474701470246), I64(0x211a9e9e429e84dc),
I64(0x89d4caca0fca1ec5), I64(0x5a582d2db42d7599), I64(0x632ebfbfc6bf9179), I64(0x0e3f07071c07381b),
I64(0x47acadad8ead0123), I64(0xb4b05a5a755aea2f), I64(0x1bef838336836cb5), I64(0x66b63333cc3385ff),
I64(0xc65c636391633ff2), I64(0x041202020802100a), I64(0x4993aaaa92aa3938), I64(0xe2de7171d971afa8),
I64(0x8dc6c8c807c80ecf), I64(0x32d119196419c87d), I64(0x923b494939497270), I64(0xaf5fd9d943d9869a),
I64(0xf931f2f2eff2c31d), I64(0xdba8e3e3abe34b48), I64(0xb6b95b5b715be22a), I64(0x0dbc88881a883492),
I64(0x293e9a9a529aa4c8), I64(0x4c0b262698262dbe), I64(0x64bf3232c8328dfa), I64(0x7d59b0b0fab0e94a),
I64(0xcff2e9e983e91b6a), I64(0x1e770f0f3c0f7833), I64(0xb733d5d573d5e6a6), I64(0x1df480803a8074ba),
I64(0x6127bebec2be997c), I64(0x87ebcdcd13cd26de), I64(0x68893434d034bde4), I64(0x903248483d487a75),
I64(0xe354ffffdbffab24), I64(0xf48d7a7af57af78f), I64(0x3d6490907a90f4ea), I64(0xbe9d5f5f615fc23e),
I64(0x403d202080201da0), I64(0xd00f6868bd6867d5), I64(0x34ca1a1a681ad072), I64(0x41b7aeae82ae192c),
I64(0x757db4b4eab4c95e), I64(0xa8ce54544d549a19), I64(0x3b7f93937693ece5), I64(0x442f222288220daa),
I64(0xc86364648d6407e9), I64(0xff2af1f1e3f1db12), I64(0xe6cc7373d173bfa2), I64(0x248212124812905a),
I64(0x807a40401d403a5d), I64(0x1048080820084028), I64(0x9b95c3c32bc356e8), I64(0xc5dfecec97ec337b),
I64(0xab4ddbdb4bdb9690), I64(0x5fc0a1a1bea1611f), I64(0x07918d8d0e8d1c83), I64(0x7ac83d3df43df5c9),
I64(0x335b97976697ccf1), I64(0x0000000000000000), I64(0x83f9cfcf1bcf36d4), I64(0x566e2b2bac2b4587),
I64(0xece17676c57697b3), I64(0x19e68282328264b0), I64(0xb128d6d67fd6fea9), I64(0x36c31b1b6c1bd877),
I64(0x7774b5b5eeb5c15b), I64(0x43beafaf86af1129), I64(0xd41d6a6ab56a77df), I64(0xa0ea50505d50ba0d),
I64(0x8a5745450945124c), I64(0xfb38f3f3ebf3cb18), I64(0x60ad3030c0309df0), I64(0xc3c4efef9bef2b74),
I64(0x7eda3f3ffc3fe5c3), I64(0xaac755554955921c), I64(0x59dba2a2b2a27910), I64(0xc9e9eaea8fea0365),
I64(0xca6a656589650fec), I64(0x6903babad2bab968), I64(0x5e4a2f2fbc2f6593), I64(0x9d8ec0c027c04ee7),
I64(0xa160dede5fdebe81), I64(0x38fc1c1c701ce06c), I64(0xe746fdfdd3fdbb2e), I64(0x9a1f4d4d294d5264),
I64(0x397692927292e4e0), I64(0xeafa7575c9758fbc), I64(0x0c3606061806301e), I64(0x09ae8a8a128a2498),
I64(0x794bb2b2f2b2f940), I64(0xd185e6e6bfe66359), I64(0x1c7e0e0e380e7036), I64(0x3ee71f1f7c1ff863),
I64(0xc4556262956237f7), I64(0xb53ad4d477d4eea3), I64(0x4d81a8a89aa82932), I64(0x315296966296c4f4),
I64(0xef62f9f9c3f99b3a), I64(0x97a3c5c533c566f6), I64(0x4a102525942535b1), I64(0xb2ab59597959f220),
I64(0x15d084842a8454ae), I64(0xe4c57272d572b7a7), I64(0x72ec3939e439d5dd), I64(0x98164c4c2d4c5a61),
I64(0xbc945e5e655eca3b), I64(0xf09f7878fd78e785), I64(0x70e53838e038ddd8), I64(0x05988c8c0a8c1486),
I64(0xbf17d1d163d1c6b2), I64(0x57e4a5a5aea5410b), I64(0xd9a1e2e2afe2434d), I64(0xc24e616199612ff8),
I64(0x7b42b3b3f6b3f145), I64(0x42342121842115a5), I64(0x25089c9c4a9c94d6), I64(0x3cee1e1e781ef066),
I64(0x8661434311432252), I64(0x93b1c7c73bc776fc), I64(0xe54ffcfcd7fcb32b), I64(0x0824040410042014),
I64(0xa2e351515951b208), I64(0x2f2599995e99bcc7), I64(0xda226d6da96d4fc4), I64(0x1a650d0d340d6839),
I64(0xe979fafacffa8335), I64(0xa369dfdf5bdfb684), I64(0xfca97e7ee57ed79b), I64(0x4819242490243db4),
I64(0x76fe3b3bec3bc5d7), I64(0x4b9aabab96ab313d), I64(0x81f0cece1fce3ed1), I64(0x2299111144118855),
I64(0x03838f8f068f0c89), I64(0x9c044e4e254e4a6b), I64(0x7366b7b7e6b7d151), I64(0xcbe0ebeb8beb0b60),
I64(0x78c13c3cf03cfdcc), I64(0x1ffd81813e817cbf), I64(0x354094946a94d4fe), I64(0xf31cf7f7fbf7eb0c),
I64(0x6f18b9b9deb9a167), I64(0x268b13134c13985f), I64(0x58512c2cb02c7d9c), I64(0xbb05d3d36bd3d6b8),
I64(0xd38ce7e7bbe76b5c), I64(0xdc396e6ea56e57cb), I64(0x95aac4c437c46ef3), I64(0x061b03030c03180f),
I64(0xacdc565645568a13), I64(0x885e44440d441a49), I64(0xfea07f7fe17fdf9e), I64(0x4f88a9a99ea92137),
I64(0x54672a2aa82a4d82), I64(0x6b0abbbbd6bbb16d), I64(0x9f87c1c123c146e2), I64(0xa6f153535153a202),
I64(0xa572dcdc57dcae8b), I64(0x16530b0b2c0b5827), I64(0x27019d9d4e9d9cd3), I64(0xd82b6c6cad6c47c1),
I64(0x62a43131c43195f5), I64(0xe8f37474cd7487b9), I64(0xf115f6f6fff6e309), I64(0x8c4c464605460a43),
I64(0x45a5acac8aac0926), I64(0x0fb589891e893c97), I64(0x28b414145014a044), I64(0xdfbae1e1a3e15b42),
I64(0x2ca616165816b04e), I64(0x74f73a3ae83acdd2), I64(0xd2066969b9696fd0), I64(0x124109092409482d),
I64(0xe0d77070dd70a7ad), I64(0x716fb6b6e2b6d954), I64(0xbd1ed0d067d0ceb7), I64(0xc7d6eded93ed3b7e),
I64(0x85e2cccc17cc2edb), I64(0x8468424215422a57), I64(0x2d2c98985a98b4c2), I64(0x55eda4a4aaa4490e),
I64(0x50752828a0285d88), I64(0xb8865c5c6d5cda31), I64(0xed6bf8f8c7f8933f), I64(0x11c28686228644a4),
}, {
/* C3 vectors */
I64(0x7830d818186018c0), I64(0xaf462623238c2305), I64(0xf991b8c6c63fc67e), I64(0x6fcdfbe8e887e813),
I64(0xa113cb878726874c), I64(0x626d11b8b8dab8a9), I64(0x0502090101040108), I64(0x6e9e0d4f4f214f42),
I64(0xee6c9b3636d836ad), I64(0x0451ffa6a6a2a659), I64(0xbdb90cd2d26fd2de), I64(0x06f70ef5f5f3f5fb),
I64(0x80f2967979f979ef), I64(0xcede306f6fa16f5f), I64(0xef3f6d91917e91fc), I64(0x07a4f852525552aa),
I64(0xfdc04760609d6027), I64(0x766535bcbccabc89), I64(0xcd2b379b9b569bac), I64(0x8c018a8e8e028e04),
I64(0x155bd2a3a3b6a371), I64(0x3c186c0c0c300c60), I64(0x8af6847b7bf17bff), I64(0xe16a803535d435b5),
I64(0x693af51d1d741de8), I64(0x47ddb3e0e0a7e053), I64(0xacb321d7d77bd7f6), I64(0xed999cc2c22fc25e),
I64(0x965c432e2eb82e6d), I64(0x7a96294b4b314b62), I64(0x21e15dfefedffea3), I64(0x16aed55757415782),
I64(0x412abd15155415a8), I64(0xb6eee87777c1779f), I64(0xeb6e923737dc37a5), I64(0x56d79ee5e5b3e57b),
I64(0xd923139f9f469f8c), I64(0x17fd23f0f0e7f0d3), I64(0x7f94204a4a354a6a), I64(0x95a944dada4fda9e),
I64(0x25b0a258587d58fa), I64(0xca8fcfc9c903c906), I64(0x8d527c2929a42955), I64(0x22145a0a0a280a50),
I64(0x4f7f50b1b1feb1e1), I64(0x1a5dc9a0a0baa069), I64(0xdad6146b6bb16b7f), I64(0xab17d985852e855c),
I64(0x73673cbdbdcebd81), I64(0x34ba8f5d5d695dd2), I64(0x5020901010401080), I64(0x03f507f4f4f7f4f3),
I64(0xc08bddcbcb0bcb16), I64(0xc67cd33e3ef83eed), I64(0x110a2d0505140528), I64(0xe6ce78676781671f),
I64(0x53d597e4e4b7e473), I64(0xbb4e0227279c2725), I64(0x5882734141194132), I64(0x9d0ba78b8b168b2c),
I64(0x0153f6a7a7a6a751), I64(0x94fab27d7de97dcf), I64(0xfb374995956e95dc), I64(0x9fad56d8d847d88e),
I64(0x30eb70fbfbcbfb8b), I64(0x71c1cdeeee9fee23), I64(0x91f8bb7c7ced7cc7), I64(0xe3cc716666856617),
I64(0x8ea77bdddd53dda6), I64(0x4b2eaf17175c17b8), I64(0x468e454747014702), I64(0xdc211a9e9e429e84),
I64(0xc589d4caca0fca1e), I64(0x995a582d2db42d75), I64(0x79632ebfbfc6bf91), I64(0x1b0e3f07071c0738),
I64(0x2347acadad8ead01), I64(0x2fb4b05a5a755aea), I64(0xb51bef838336836c), I64(0xff66b63333cc3385),
I64(0xf2c65c636391633f), I64(0x0a04120202080210), I64(0x384993aaaa92aa39), I64(0xa8e2de7171d971af),
I64(0xcf8dc6c8c807c80e), I64(0x7d32d119196419c8), I64(0x70923b4949394972), I64(0x9aaf5fd9d943d986),
I64(0x1df931f2f2eff2c3), I64(0x48dba8e3e3abe34b), I64(0x2ab6b95b5b715be2), I64(0x920dbc88881a8834),
I64(0xc8293e9a9a529aa4), I64(0xbe4c0b262698262d), I64(0xfa64bf3232c8328d), I64(0x4a7d59b0b0fab0e9),
I64(0x6acff2e9e983e91b), I64(0x331e770f0f3c0f78), I64(0xa6b733d5d573d5e6), I64(0xba1df480803a8074),
I64(0x7c6127bebec2be99), I64(0xde87ebcdcd13cd26), I64(0xe468893434d034bd), I64(0x75903248483d487a),
I64(0x24e354ffffdbffab), I64(0x8ff48d7a7af57af7), I64(0xea3d6490907a90f4), I64(0x3ebe9d5f5f615fc2),
I64(0xa0403d202080201d), I64(0xd5d00f6868bd6867), I64(0x7234ca1a1a681ad0), I64(0x2c41b7aeae82ae19),
I64(0x5e757db4b4eab4c9), I64(0x19a8ce54544d549a), I64(0xe53b7f93937693ec), I64(0xaa442f222288220d),
I64(0xe9c86364648d6407), I64(0x12ff2af1f1e3f1db), I64(0xa2e6cc7373d173bf), I64(0x5a24821212481290),
I64(0x5d807a40401d403a), I64(0x2810480808200840), I64(0xe89b95c3c32bc356), I64(0x7bc5dfecec97ec33),
I64(0x90ab4ddbdb4bdb96), I64(0x1f5fc0a1a1bea161), I64(0x8307918d8d0e8d1c), I64(0xc97ac83d3df43df5),
I64(0xf1335b97976697cc), I64(0x0000000000000000), I64(0xd483f9cfcf1bcf36), I64(0x87566e2b2bac2b45),
I64(0xb3ece17676c57697), I64(0xb019e68282328264), I64(0xa9b128d6d67fd6fe), I64(0x7736c31b1b6c1bd8),
I64(0x5b7774b5b5eeb5c1), I64(0x2943beafaf86af11), I64(0xdfd41d6a6ab56a77), I64(0x0da0ea50505d50ba),
I64(0x4c8a574545094512), I64(0x18fb38f3f3ebf3cb), I64(0xf060ad3030c0309d), I64(0x74c3c4efef9bef2b),
I64(0xc37eda3f3ffc3fe5), I64(0x1caac75555495592), I64(0x1059dba2a2b2a279), I64(0x65c9e9eaea8fea03),
I64(0xecca6a656589650f), I64(0x686903babad2bab9), I64(0x935e4a2f2fbc2f65), I64(0xe79d8ec0c027c04e),
I64(0x81a160dede5fdebe), I64(0x6c38fc1c1c701ce0), I64(0x2ee746fdfdd3fdbb), I64(0x649a1f4d4d294d52),
I64(0xe0397692927292e4), I64(0xbceafa7575c9758f), I64(0x1e0c360606180630), I64(0x9809ae8a8a128a24),
I64(0x40794bb2b2f2b2f9), I64(0x59d185e6e6bfe663), I64(0x361c7e0e0e380e70), I64(0x633ee71f1f7c1ff8),
I64(0xf7c4556262956237), I64(0xa3b53ad4d477d4ee), I64(0x324d81a8a89aa829), I64(0xf4315296966296c4),
I64(0x3aef62f9f9c3f99b), I64(0xf697a3c5c533c566), I64(0xb14a102525942535), I64(0x20b2ab59597959f2),
I64(0xae15d084842a8454), I64(0xa7e4c57272d572b7), I64(0xdd72ec3939e439d5), I64(0x6198164c4c2d4c5a),
I64(0x3bbc945e5e655eca), I64(0x85f09f7878fd78e7), I64(0xd870e53838e038dd), I64(0x8605988c8c0a8c14),
I64(0xb2bf17d1d163d1c6), I64(0x0b57e4a5a5aea541), I64(0x4dd9a1e2e2afe243), I64(0xf8c24e616199612f),
I64(0x457b42b3b3f6b3f1), I64(0xa542342121842115), I64(0xd625089c9c4a9c94), I64(0x663cee1e1e781ef0),
I64(0x5286614343114322), I64(0xfc93b1c7c73bc776), I64(0x2be54ffcfcd7fcb3), I64(0x1408240404100420),
I64(0x08a2e351515951b2), I64(0xc72f2599995e99bc), I64(0xc4da226d6da96d4f), I64(0x391a650d0d340d68),
I64(0x35e979fafacffa83), I64(0x84a369dfdf5bdfb6), I64(0x9bfca97e7ee57ed7), I64(0xb44819242490243d),
I64(0xd776fe3b3bec3bc5), I64(0x3d4b9aabab96ab31), I64(0xd181f0cece1fce3e), I64(0x5522991111441188),
I64(0x8903838f8f068f0c), I64(0x6b9c044e4e254e4a), I64(0x517366b7b7e6b7d1), I64(0x60cbe0ebeb8beb0b),
I64(0xcc78c13c3cf03cfd), I64(0xbf1ffd81813e817c), I64(0xfe354094946a94d4), I64(0x0cf31cf7f7fbf7eb),
I64(0x676f18b9b9deb9a1), I64(0x5f268b13134c1398), I64(0x9c58512c2cb02c7d), I64(0xb8bb05d3d36bd3d6),
I64(0x5cd38ce7e7bbe76b), I64(0xcbdc396e6ea56e57), I64(0xf395aac4c437c46e), I64(0x0f061b03030c0318),
I64(0x13acdc565645568a), I64(0x49885e44440d441a), I64(0x9efea07f7fe17fdf), I64(0x374f88a9a99ea921),
I64(0x8254672a2aa82a4d), I64(0x6d6b0abbbbd6bbb1), I64(0xe29f87c1c123c146), I64(0x02a6f153535153a2),
I64(0x8ba572dcdc57dcae), I64(0x2716530b0b2c0b58), I64(0xd327019d9d4e9d9c), I64(0xc1d82b6c6cad6c47),
I64(0xf562a43131c43195), I64(0xb9e8f37474cd7487), I64(0x09f115f6f6fff6e3), I64(0x438c4c464605460a),
I64(0x2645a5acac8aac09), I64(0x970fb589891e893c), I64(0x4428b414145014a0), I64(0x42dfbae1e1a3e15b),
I64(0x4e2ca616165816b0), I64(0xd274f73a3ae83acd), I64(0xd0d2066969b9696f), I64(0x2d12410909240948),
I64(0xade0d77070dd70a7), I64(0x54716fb6b6e2b6d9), I64(0xb7bd1ed0d067d0ce), I64(0x7ec7d6eded93ed3b),
I64(0xdb85e2cccc17cc2e), I64(0x578468424215422a), I64(0xc22d2c98985a98b4), I64(0x0e55eda4a4aaa449),
I64(0x8850752828a0285d), I64(0x31b8865c5c6d5cda), I64(0x3fed6bf8f8c7f893), I64(0xa411c28686228644),
}, {
/* C4 vectors */
I64(0xc07830d818186018), I64(0x05af462623238c23), I64(0x7ef991b8c6c63fc6), I64(0x136fcdfbe8e887e8),
I64(0x4ca113cb87872687), I64(0xa9626d11b8b8dab8), I64(0x0805020901010401), I64(0x426e9e0d4f4f214f),
I64(0xadee6c9b3636d836), I64(0x590451ffa6a6a2a6), I64(0xdebdb90cd2d26fd2), I64(0xfb06f70ef5f5f3f5),
I64(0xef80f2967979f979), I64(0x5fcede306f6fa16f), I64(0xfcef3f6d91917e91), I64(0xaa07a4f852525552),
I64(0x27fdc04760609d60), I64(0x89766535bcbccabc), I64(0xaccd2b379b9b569b), I64(0x048c018a8e8e028e),
I64(0x71155bd2a3a3b6a3), I64(0x603c186c0c0c300c), I64(0xff8af6847b7bf17b), I64(0xb5e16a803535d435),
I64(0xe8693af51d1d741d), I64(0x5347ddb3e0e0a7e0), I64(0xf6acb321d7d77bd7), I64(0x5eed999cc2c22fc2),
I64(0x6d965c432e2eb82e), I64(0x627a96294b4b314b), I64(0xa321e15dfefedffe), I64(0x8216aed557574157),
I64(0xa8412abd15155415), I64(0x9fb6eee87777c177), I64(0xa5eb6e923737dc37), I64(0x7b56d79ee5e5b3e5),
I64(0x8cd923139f9f469f), I64(0xd317fd23f0f0e7f0), I64(0x6a7f94204a4a354a), I64(0x9e95a944dada4fda),
I64(0xfa25b0a258587d58), I64(0x06ca8fcfc9c903c9), I64(0x558d527c2929a429), I64(0x5022145a0a0a280a),
I64(0xe14f7f50b1b1feb1), I64(0x691a5dc9a0a0baa0), I64(0x7fdad6146b6bb16b), I64(0x5cab17d985852e85),
I64(0x8173673cbdbdcebd), I64(0xd234ba8f5d5d695d), I64(0x8050209010104010), I64(0xf303f507f4f4f7f4),
I64(0x16c08bddcbcb0bcb), I64(0xedc67cd33e3ef83e), I64(0x28110a2d05051405), I64(0x1fe6ce7867678167),
I64(0x7353d597e4e4b7e4), I64(0x25bb4e0227279c27), I64(0x3258827341411941), I64(0x2c9d0ba78b8b168b),
I64(0x510153f6a7a7a6a7), I64(0xcf94fab27d7de97d), I64(0xdcfb374995956e95), I64(0x8e9fad56d8d847d8),
I64(0x8b30eb70fbfbcbfb), I64(0x2371c1cdeeee9fee), I64(0xc791f8bb7c7ced7c), I64(0x17e3cc7166668566),
I64(0xa68ea77bdddd53dd), I64(0xb84b2eaf17175c17), I64(0x02468e4547470147), I64(0x84dc211a9e9e429e),
I64(0x1ec589d4caca0fca), I64(0x75995a582d2db42d), I64(0x9179632ebfbfc6bf), I64(0x381b0e3f07071c07),
I64(0x012347acadad8ead), I64(0xea2fb4b05a5a755a), I64(0x6cb51bef83833683), I64(0x85ff66b63333cc33),
I64(0x3ff2c65c63639163), I64(0x100a041202020802), I64(0x39384993aaaa92aa), I64(0xafa8e2de7171d971),
I64(0x0ecf8dc6c8c807c8), I64(0xc87d32d119196419), I64(0x7270923b49493949), I64(0x869aaf5fd9d943d9),
I64(0xc31df931f2f2eff2), I64(0x4b48dba8e3e3abe3), I64(0xe22ab6b95b5b715b), I64(0x34920dbc88881a88),
I64(0xa4c8293e9a9a529a), I64(0x2dbe4c0b26269826), I64(0x8dfa64bf3232c832), I64(0xe94a7d59b0b0fab0),
I64(0x1b6acff2e9e983e9), I64(0x78331e770f0f3c0f), I64(0xe6a6b733d5d573d5), I64(0x74ba1df480803a80),
I64(0x997c6127bebec2be), I64(0x26de87ebcdcd13cd), I64(0xbde468893434d034), I64(0x7a75903248483d48),
I64(0xab24e354ffffdbff), I64(0xf78ff48d7a7af57a), I64(0xf4ea3d6490907a90), I64(0xc23ebe9d5f5f615f),
I64(0x1da0403d20208020), I64(0x67d5d00f6868bd68), I64(0xd07234ca1a1a681a), I64(0x192c41b7aeae82ae),
I64(0xc95e757db4b4eab4), I64(0x9a19a8ce54544d54), I64(0xece53b7f93937693), I64(0x0daa442f22228822),
I64(0x07e9c86364648d64), I64(0xdb12ff2af1f1e3f1), I64(0xbfa2e6cc7373d173), I64(0x905a248212124812),
I64(0x3a5d807a40401d40), I64(0x4028104808082008), I64(0x56e89b95c3c32bc3), I64(0x337bc5dfecec97ec),
I64(0x9690ab4ddbdb4bdb), I64(0x611f5fc0a1a1bea1), I64(0x1c8307918d8d0e8d), I64(0xf5c97ac83d3df43d),
I64(0xccf1335b97976697), I64(0x0000000000000000), I64(0x36d483f9cfcf1bcf), I64(0x4587566e2b2bac2b),
I64(0x97b3ece17676c576), I64(0x64b019e682823282), I64(0xfea9b128d6d67fd6), I64(0xd87736c31b1b6c1b),
I64(0xc15b7774b5b5eeb5), I64(0x112943beafaf86af), I64(0x77dfd41d6a6ab56a), I64(0xba0da0ea50505d50),
I64(0x124c8a5745450945), I64(0xcb18fb38f3f3ebf3), I64(0x9df060ad3030c030), I64(0x2b74c3c4efef9bef),
I64(0xe5c37eda3f3ffc3f), I64(0x921caac755554955), I64(0x791059dba2a2b2a2), I64(0x0365c9e9eaea8fea),
I64(0x0fecca6a65658965), I64(0xb9686903babad2ba), I64(0x65935e4a2f2fbc2f), I64(0x4ee79d8ec0c027c0),
I64(0xbe81a160dede5fde), I64(0xe06c38fc1c1c701c), I64(0xbb2ee746fdfdd3fd), I64(0x52649a1f4d4d294d),
I64(0xe4e0397692927292), I64(0x8fbceafa7575c975), I64(0x301e0c3606061806), I64(0x249809ae8a8a128a),
I64(0xf940794bb2b2f2b2), I64(0x6359d185e6e6bfe6), I64(0x70361c7e0e0e380e), I64(0xf8633ee71f1f7c1f),
I64(0x37f7c45562629562), I64(0xeea3b53ad4d477d4), I64(0x29324d81a8a89aa8), I64(0xc4f4315296966296),
I64(0x9b3aef62f9f9c3f9), I64(0x66f697a3c5c533c5), I64(0x35b14a1025259425), I64(0xf220b2ab59597959),
I64(0x54ae15d084842a84), I64(0xb7a7e4c57272d572), I64(0xd5dd72ec3939e439), I64(0x5a6198164c4c2d4c),
I64(0xca3bbc945e5e655e), I64(0xe785f09f7878fd78), I64(0xddd870e53838e038), I64(0x148605988c8c0a8c),
I64(0xc6b2bf17d1d163d1), I64(0x410b57e4a5a5aea5), I64(0x434dd9a1e2e2afe2), I64(0x2ff8c24e61619961),
I64(0xf1457b42b3b3f6b3), I64(0x15a5423421218421), I64(0x94d625089c9c4a9c), I64(0xf0663cee1e1e781e),
I64(0x2252866143431143), I64(0x76fc93b1c7c73bc7), I64(0xb32be54ffcfcd7fc), I64(0x2014082404041004),
I64(0xb208a2e351515951), I64(0xbcc72f2599995e99), I64(0x4fc4da226d6da96d), I64(0x68391a650d0d340d),
I64(0x8335e979fafacffa), I64(0xb684a369dfdf5bdf), I64(0xd79bfca97e7ee57e), I64(0x3db4481924249024),
I64(0xc5d776fe3b3bec3b), I64(0x313d4b9aabab96ab), I64(0x3ed181f0cece1fce), I64(0x8855229911114411),
I64(0x0c8903838f8f068f), I64(0x4a6b9c044e4e254e), I64(0xd1517366b7b7e6b7), I64(0x0b60cbe0ebeb8beb),
I64(0xfdcc78c13c3cf03c), I64(0x7cbf1ffd81813e81), I64(0xd4fe354094946a94), I64(0xeb0cf31cf7f7fbf7),
I64(0xa1676f18b9b9deb9), I64(0x985f268b13134c13), I64(0x7d9c58512c2cb02c), I64(0xd6b8bb05d3d36bd3),
I64(0x6b5cd38ce7e7bbe7), I64(0x57cbdc396e6ea56e), I64(0x6ef395aac4c437c4), I64(0x180f061b03030c03),
I64(0x8a13acdc56564556), I64(0x1a49885e44440d44), I64(0xdf9efea07f7fe17f), I64(0x21374f88a9a99ea9),
I64(0x4d8254672a2aa82a), I64(0xb16d6b0abbbbd6bb), I64(0x46e29f87c1c123c1), I64(0xa202a6f153535153),
I64(0xae8ba572dcdc57dc), I64(0x582716530b0b2c0b), I64(0x9cd327019d9d4e9d), I64(0x47c1d82b6c6cad6c),
I64(0x95f562a43131c431), I64(0x87b9e8f37474cd74), I64(0xe309f115f6f6fff6), I64(0x0a438c4c46460546),
I64(0x092645a5acac8aac), I64(0x3c970fb589891e89), I64(0xa04428b414145014), I64(0x5b42dfbae1e1a3e1),
I64(0xb04e2ca616165816), I64(0xcdd274f73a3ae83a), I64(0x6fd0d2066969b969), I64(0x482d124109092409),
I64(0xa7ade0d77070dd70), I64(0xd954716fb6b6e2b6), I64(0xceb7bd1ed0d067d0), I64(0x3b7ec7d6eded93ed),
I64(0x2edb85e2cccc17cc), I64(0x2a57846842421542), I64(0xb4c22d2c98985a98), I64(0x490e55eda4a4aaa4),
I64(0x5d8850752828a028), I64(0xda31b8865c5c6d5c), I64(0x933fed6bf8f8c7f8), I64(0x44a411c286862286),
}, {
/* C5 vectors */
I64(0x18c07830d8181860), I64(0x2305af462623238c), I64(0xc67ef991b8c6c63f), I64(0xe8136fcdfbe8e887),
I64(0x874ca113cb878726), I64(0xb8a9626d11b8b8da), I64(0x0108050209010104), I64(0x4f426e9e0d4f4f21),
I64(0x36adee6c9b3636d8), I64(0xa6590451ffa6a6a2), I64(0xd2debdb90cd2d26f), I64(0xf5fb06f70ef5f5f3),
I64(0x79ef80f2967979f9), I64(0x6f5fcede306f6fa1), I64(0x91fcef3f6d91917e), I64(0x52aa07a4f8525255),
I64(0x6027fdc04760609d), I64(0xbc89766535bcbcca), I64(0x9baccd2b379b9b56), I64(0x8e048c018a8e8e02),
I64(0xa371155bd2a3a3b6), I64(0x0c603c186c0c0c30), I64(0x7bff8af6847b7bf1), I64(0x35b5e16a803535d4),
I64(0x1de8693af51d1d74), I64(0xe05347ddb3e0e0a7), I64(0xd7f6acb321d7d77b), I64(0xc25eed999cc2c22f),
I64(0x2e6d965c432e2eb8), I64(0x4b627a96294b4b31), I64(0xfea321e15dfefedf), I64(0x578216aed5575741),
I64(0x15a8412abd151554), I64(0x779fb6eee87777c1), I64(0x37a5eb6e923737dc), I64(0xe57b56d79ee5e5b3),
I64(0x9f8cd923139f9f46), I64(0xf0d317fd23f0f0e7), I64(0x4a6a7f94204a4a35), I64(0xda9e95a944dada4f),
I64(0x58fa25b0a258587d), I64(0xc906ca8fcfc9c903), I64(0x29558d527c2929a4), I64(0x0a5022145a0a0a28),
I64(0xb1e14f7f50b1b1fe), I64(0xa0691a5dc9a0a0ba), I64(0x6b7fdad6146b6bb1), I64(0x855cab17d985852e),
I64(0xbd8173673cbdbdce), I64(0x5dd234ba8f5d5d69), I64(0x1080502090101040), I64(0xf4f303f507f4f4f7),
I64(0xcb16c08bddcbcb0b), I64(0x3eedc67cd33e3ef8), I64(0x0528110a2d050514), I64(0x671fe6ce78676781),
I64(0xe47353d597e4e4b7), I64(0x2725bb4e0227279c), I64(0x4132588273414119), I64(0x8b2c9d0ba78b8b16),
I64(0xa7510153f6a7a7a6), I64(0x7dcf94fab27d7de9), I64(0x95dcfb374995956e), I64(0xd88e9fad56d8d847),
I64(0xfb8b30eb70fbfbcb), I64(0xee2371c1cdeeee9f), I64(0x7cc791f8bb7c7ced), I64(0x6617e3cc71666685),
I64(0xdda68ea77bdddd53), I64(0x17b84b2eaf17175c), I64(0x4702468e45474701), I64(0x9e84dc211a9e9e42),
I64(0xca1ec589d4caca0f), I64(0x2d75995a582d2db4), I64(0xbf9179632ebfbfc6), I64(0x07381b0e3f07071c),
I64(0xad012347acadad8e), I64(0x5aea2fb4b05a5a75), I64(0x836cb51bef838336), I64(0x3385ff66b63333cc),
I64(0x633ff2c65c636391), I64(0x02100a0412020208), I64(0xaa39384993aaaa92), I64(0x71afa8e2de7171d9),
I64(0xc80ecf8dc6c8c807), I64(0x19c87d32d1191964), I64(0x497270923b494939), I64(0xd9869aaf5fd9d943),
I64(0xf2c31df931f2f2ef), I64(0xe34b48dba8e3e3ab), I64(0x5be22ab6b95b5b71), I64(0x8834920dbc88881a),
I64(0x9aa4c8293e9a9a52), I64(0x262dbe4c0b262698), I64(0x328dfa64bf3232c8), I64(0xb0e94a7d59b0b0fa),
I64(0xe91b6acff2e9e983), I64(0x0f78331e770f0f3c), I64(0xd5e6a6b733d5d573), I64(0x8074ba1df480803a),
I64(0xbe997c6127bebec2), I64(0xcd26de87ebcdcd13), I64(0x34bde468893434d0), I64(0x487a75903248483d),
I64(0xffab24e354ffffdb), I64(0x7af78ff48d7a7af5), I64(0x90f4ea3d6490907a), I64(0x5fc23ebe9d5f5f61),
I64(0x201da0403d202080), I64(0x6867d5d00f6868bd), I64(0x1ad07234ca1a1a68), I64(0xae192c41b7aeae82),
I64(0xb4c95e757db4b4ea), I64(0x549a19a8ce54544d), I64(0x93ece53b7f939376), I64(0x220daa442f222288),
I64(0x6407e9c86364648d), I64(0xf1db12ff2af1f1e3), I64(0x73bfa2e6cc7373d1), I64(0x12905a2482121248),
I64(0x403a5d807a40401d), I64(0x0840281048080820), I64(0xc356e89b95c3c32b), I64(0xec337bc5dfecec97),
I64(0xdb9690ab4ddbdb4b), I64(0xa1611f5fc0a1a1be), I64(0x8d1c8307918d8d0e), I64(0x3df5c97ac83d3df4),
I64(0x97ccf1335b979766), I64(0x0000000000000000), I64(0xcf36d483f9cfcf1b), I64(0x2b4587566e2b2bac),
I64(0x7697b3ece17676c5), I64(0x8264b019e6828232), I64(0xd6fea9b128d6d67f), I64(0x1bd87736c31b1b6c),
I64(0xb5c15b7774b5b5ee), I64(0xaf112943beafaf86), I64(0x6a77dfd41d6a6ab5), I64(0x50ba0da0ea50505d),
I64(0x45124c8a57454509), I64(0xf3cb18fb38f3f3eb), I64(0x309df060ad3030c0), I64(0xef2b74c3c4efef9b),
I64(0x3fe5c37eda3f3ffc), I64(0x55921caac7555549), I64(0xa2791059dba2a2b2), I64(0xea0365c9e9eaea8f),
I64(0x650fecca6a656589), I64(0xbab9686903babad2), I64(0x2f65935e4a2f2fbc), I64(0xc04ee79d8ec0c027),
I64(0xdebe81a160dede5f), I64(0x1ce06c38fc1c1c70), I64(0xfdbb2ee746fdfdd3), I64(0x4d52649a1f4d4d29),
I64(0x92e4e03976929272), I64(0x758fbceafa7575c9), I64(0x06301e0c36060618), I64(0x8a249809ae8a8a12),
I64(0xb2f940794bb2b2f2), I64(0xe66359d185e6e6bf), I64(0x0e70361c7e0e0e38), I64(0x1ff8633ee71f1f7c),
I64(0x6237f7c455626295), I64(0xd4eea3b53ad4d477), I64(0xa829324d81a8a89a), I64(0x96c4f43152969662),
I64(0xf99b3aef62f9f9c3), I64(0xc566f697a3c5c533), I64(0x2535b14a10252594), I64(0x59f220b2ab595979),
I64(0x8454ae15d084842a), I64(0x72b7a7e4c57272d5), I64(0x39d5dd72ec3939e4), I64(0x4c5a6198164c4c2d),
I64(0x5eca3bbc945e5e65), I64(0x78e785f09f7878fd), I64(0x38ddd870e53838e0), I64(0x8c148605988c8c0a),
I64(0xd1c6b2bf17d1d163), I64(0xa5410b57e4a5a5ae), I64(0xe2434dd9a1e2e2af), I64(0x612ff8c24e616199),
I64(0xb3f1457b42b3b3f6), I64(0x2115a54234212184), I64(0x9c94d625089c9c4a), I64(0x1ef0663cee1e1e78),
I64(0x4322528661434311), I64(0xc776fc93b1c7c73b), I64(0xfcb32be54ffcfcd7), I64(0x0420140824040410),
I64(0x51b208a2e3515159), I64(0x99bcc72f2599995e), I64(0x6d4fc4da226d6da9), I64(0x0d68391a650d0d34),
I64(0xfa8335e979fafacf), I64(0xdfb684a369dfdf5b), I64(0x7ed79bfca97e7ee5), I64(0x243db44819242490),
I64(0x3bc5d776fe3b3bec), I64(0xab313d4b9aabab96), I64(0xce3ed181f0cece1f), I64(0x1188552299111144),
I64(0x8f0c8903838f8f06), I64(0x4e4a6b9c044e4e25), I64(0xb7d1517366b7b7e6), I64(0xeb0b60cbe0ebeb8b),
I64(0x3cfdcc78c13c3cf0), I64(0x817cbf1ffd81813e), I64(0x94d4fe354094946a), I64(0xf7eb0cf31cf7f7fb),
I64(0xb9a1676f18b9b9de), I64(0x13985f268b13134c), I64(0x2c7d9c58512c2cb0), I64(0xd3d6b8bb05d3d36b),
I64(0xe76b5cd38ce7e7bb), I64(0x6e57cbdc396e6ea5), I64(0xc46ef395aac4c437), I64(0x03180f061b03030c),
I64(0x568a13acdc565645), I64(0x441a49885e44440d), I64(0x7fdf9efea07f7fe1), I64(0xa921374f88a9a99e),
I64(0x2a4d8254672a2aa8), I64(0xbbb16d6b0abbbbd6), I64(0xc146e29f87c1c123), I64(0x53a202a6f1535351),
I64(0xdcae8ba572dcdc57), I64(0x0b582716530b0b2c), I64(0x9d9cd327019d9d4e), I64(0x6c47c1d82b6c6cad),
I64(0x3195f562a43131c4), I64(0x7487b9e8f37474cd), I64(0xf6e309f115f6f6ff), I64(0x460a438c4c464605),
I64(0xac092645a5acac8a), I64(0x893c970fb589891e), I64(0x14a04428b4141450), I64(0xe15b42dfbae1e1a3),
I64(0x16b04e2ca6161658), I64(0x3acdd274f73a3ae8), I64(0x696fd0d2066969b9), I64(0x09482d1241090924),
I64(0x70a7ade0d77070dd), I64(0xb6d954716fb6b6e2), I64(0xd0ceb7bd1ed0d067), I64(0xed3b7ec7d6eded93),
I64(0xcc2edb85e2cccc17), I64(0x422a578468424215), I64(0x98b4c22d2c98985a), I64(0xa4490e55eda4a4aa),
I64(0x285d8850752828a0), I64(0x5cda31b8865c5c6d), I64(0xf8933fed6bf8f8c7), I64(0x8644a411c2868622),
}, {
/* C6 vectors */
I64(0x6018c07830d81818), I64(0x8c2305af46262323), I64(0x3fc67ef991b8c6c6), I64(0x87e8136fcdfbe8e8),
I64(0x26874ca113cb8787), I64(0xdab8a9626d11b8b8), I64(0x0401080502090101), I64(0x214f426e9e0d4f4f),
I64(0xd836adee6c9b3636), I64(0xa2a6590451ffa6a6), I64(0x6fd2debdb90cd2d2), I64(0xf3f5fb06f70ef5f5),
I64(0xf979ef80f2967979), I64(0xa16f5fcede306f6f), I64(0x7e91fcef3f6d9191), I64(0x5552aa07a4f85252),
I64(0x9d6027fdc0476060), I64(0xcabc89766535bcbc), I64(0x569baccd2b379b9b), I64(0x028e048c018a8e8e),
I64(0xb6a371155bd2a3a3), I64(0x300c603c186c0c0c), I64(0xf17bff8af6847b7b), I64(0xd435b5e16a803535),
I64(0x741de8693af51d1d), I64(0xa7e05347ddb3e0e0), I64(0x7bd7f6acb321d7d7), I64(0x2fc25eed999cc2c2),
I64(0xb82e6d965c432e2e), I64(0x314b627a96294b4b), I64(0xdffea321e15dfefe), I64(0x41578216aed55757),
I64(0x5415a8412abd1515), I64(0xc1779fb6eee87777), I64(0xdc37a5eb6e923737), I64(0xb3e57b56d79ee5e5),
I64(0x469f8cd923139f9f), I64(0xe7f0d317fd23f0f0), I64(0x354a6a7f94204a4a), I64(0x4fda9e95a944dada),
I64(0x7d58fa25b0a25858), I64(0x03c906ca8fcfc9c9), I64(0xa429558d527c2929), I64(0x280a5022145a0a0a),
I64(0xfeb1e14f7f50b1b1), I64(0xbaa0691a5dc9a0a0), I64(0xb16b7fdad6146b6b), I64(0x2e855cab17d98585),
I64(0xcebd8173673cbdbd), I64(0x695dd234ba8f5d5d), I64(0x4010805020901010), I64(0xf7f4f303f507f4f4),
I64(0x0bcb16c08bddcbcb), I64(0xf83eedc67cd33e3e), I64(0x140528110a2d0505), I64(0x81671fe6ce786767),
I64(0xb7e47353d597e4e4), I64(0x9c2725bb4e022727), I64(0x1941325882734141), I64(0x168b2c9d0ba78b8b),
I64(0xa6a7510153f6a7a7), I64(0xe97dcf94fab27d7d), I64(0x6e95dcfb37499595), I64(0x47d88e9fad56d8d8),
I64(0xcbfb8b30eb70fbfb), I64(0x9fee2371c1cdeeee), I64(0xed7cc791f8bb7c7c), I64(0x856617e3cc716666),
I64(0x53dda68ea77bdddd), I64(0x5c17b84b2eaf1717), I64(0x014702468e454747), I64(0x429e84dc211a9e9e),
I64(0x0fca1ec589d4caca), I64(0xb42d75995a582d2d), I64(0xc6bf9179632ebfbf), I64(0x1c07381b0e3f0707),
I64(0x8ead012347acadad), I64(0x755aea2fb4b05a5a), I64(0x36836cb51bef8383), I64(0xcc3385ff66b63333),
I64(0x91633ff2c65c6363), I64(0x0802100a04120202), I64(0x92aa39384993aaaa), I64(0xd971afa8e2de7171),
I64(0x07c80ecf8dc6c8c8), I64(0x6419c87d32d11919), I64(0x39497270923b4949), I64(0x43d9869aaf5fd9d9),
I64(0xeff2c31df931f2f2), I64(0xabe34b48dba8e3e3), I64(0x715be22ab6b95b5b), I64(0x1a8834920dbc8888),
I64(0x529aa4c8293e9a9a), I64(0x98262dbe4c0b2626), I64(0xc8328dfa64bf3232), I64(0xfab0e94a7d59b0b0),
I64(0x83e91b6acff2e9e9), I64(0x3c0f78331e770f0f), I64(0x73d5e6a6b733d5d5), I64(0x3a8074ba1df48080),
I64(0xc2be997c6127bebe), I64(0x13cd26de87ebcdcd), I64(0xd034bde468893434), I64(0x3d487a7590324848),
I64(0xdbffab24e354ffff), I64(0xf57af78ff48d7a7a), I64(0x7a90f4ea3d649090), I64(0x615fc23ebe9d5f5f),
I64(0x80201da0403d2020), I64(0xbd6867d5d00f6868), I64(0x681ad07234ca1a1a), I64(0x82ae192c41b7aeae),
I64(0xeab4c95e757db4b4), I64(0x4d549a19a8ce5454), I64(0x7693ece53b7f9393), I64(0x88220daa442f2222),
I64(0x8d6407e9c8636464), I64(0xe3f1db12ff2af1f1), I64(0xd173bfa2e6cc7373), I64(0x4812905a24821212),
I64(0x1d403a5d807a4040), I64(0x2008402810480808), I64(0x2bc356e89b95c3c3), I64(0x97ec337bc5dfecec),
I64(0x4bdb9690ab4ddbdb), I64(0xbea1611f5fc0a1a1), I64(0x0e8d1c8307918d8d), I64(0xf43df5c97ac83d3d),
I64(0x6697ccf1335b9797), I64(0x0000000000000000), I64(0x1bcf36d483f9cfcf), I64(0xac2b4587566e2b2b),
I64(0xc57697b3ece17676), I64(0x328264b019e68282), I64(0x7fd6fea9b128d6d6), I64(0x6c1bd87736c31b1b),
I64(0xeeb5c15b7774b5b5), I64(0x86af112943beafaf), I64(0xb56a77dfd41d6a6a), I64(0x5d50ba0da0ea5050),
I64(0x0945124c8a574545), I64(0xebf3cb18fb38f3f3), I64(0xc0309df060ad3030), I64(0x9bef2b74c3c4efef),
I64(0xfc3fe5c37eda3f3f), I64(0x4955921caac75555), I64(0xb2a2791059dba2a2), I64(0x8fea0365c9e9eaea),
I64(0x89650fecca6a6565), I64(0xd2bab9686903baba), I64(0xbc2f65935e4a2f2f), I64(0x27c04ee79d8ec0c0),
I64(0x5fdebe81a160dede), I64(0x701ce06c38fc1c1c), I64(0xd3fdbb2ee746fdfd), I64(0x294d52649a1f4d4d),
I64(0x7292e4e039769292), I64(0xc9758fbceafa7575), I64(0x1806301e0c360606), I64(0x128a249809ae8a8a),
I64(0xf2b2f940794bb2b2), I64(0xbfe66359d185e6e6), I64(0x380e70361c7e0e0e), I64(0x7c1ff8633ee71f1f),
I64(0x956237f7c4556262), I64(0x77d4eea3b53ad4d4), I64(0x9aa829324d81a8a8), I64(0x6296c4f431529696),
I64(0xc3f99b3aef62f9f9), I64(0x33c566f697a3c5c5), I64(0x942535b14a102525), I64(0x7959f220b2ab5959),
I64(0x2a8454ae15d08484), I64(0xd572b7a7e4c57272), I64(0xe439d5dd72ec3939), I64(0x2d4c5a6198164c4c),
I64(0x655eca3bbc945e5e), I64(0xfd78e785f09f7878), I64(0xe038ddd870e53838), I64(0x0a8c148605988c8c),
I64(0x63d1c6b2bf17d1d1), I64(0xaea5410b57e4a5a5), I64(0xafe2434dd9a1e2e2), I64(0x99612ff8c24e6161),
I64(0xf6b3f1457b42b3b3), I64(0x842115a542342121), I64(0x4a9c94d625089c9c), I64(0x781ef0663cee1e1e),
I64(0x1143225286614343), I64(0x3bc776fc93b1c7c7), I64(0xd7fcb32be54ffcfc), I64(0x1004201408240404),
I64(0x5951b208a2e35151), I64(0x5e99bcc72f259999), I64(0xa96d4fc4da226d6d), I64(0x340d68391a650d0d),
I64(0xcffa8335e979fafa), I64(0x5bdfb684a369dfdf), I64(0xe57ed79bfca97e7e), I64(0x90243db448192424),
I64(0xec3bc5d776fe3b3b), I64(0x96ab313d4b9aabab), I64(0x1fce3ed181f0cece), I64(0x4411885522991111),
I64(0x068f0c8903838f8f), I64(0x254e4a6b9c044e4e), I64(0xe6b7d1517366b7b7), I64(0x8beb0b60cbe0ebeb),
I64(0xf03cfdcc78c13c3c), I64(0x3e817cbf1ffd8181), I64(0x6a94d4fe35409494), I64(0xfbf7eb0cf31cf7f7),
I64(0xdeb9a1676f18b9b9), I64(0x4c13985f268b1313), I64(0xb02c7d9c58512c2c), I64(0x6bd3d6b8bb05d3d3),
I64(0xbbe76b5cd38ce7e7), I64(0xa56e57cbdc396e6e), I64(0x37c46ef395aac4c4), I64(0x0c03180f061b0303),
I64(0x45568a13acdc5656), I64(0x0d441a49885e4444), I64(0xe17fdf9efea07f7f), I64(0x9ea921374f88a9a9),
I64(0xa82a4d8254672a2a), I64(0xd6bbb16d6b0abbbb), I64(0x23c146e29f87c1c1), I64(0x5153a202a6f15353),
I64(0x57dcae8ba572dcdc), I64(0x2c0b582716530b0b), I64(0x4e9d9cd327019d9d), I64(0xad6c47c1d82b6c6c),
I64(0xc43195f562a43131), I64(0xcd7487b9e8f37474), I64(0xfff6e309f115f6f6), I64(0x05460a438c4c4646),
I64(0x8aac092645a5acac), I64(0x1e893c970fb58989), I64(0x5014a04428b41414), I64(0xa3e15b42dfbae1e1),
I64(0x5816b04e2ca61616), I64(0xe83acdd274f73a3a), I64(0xb9696fd0d2066969), I64(0x2409482d12410909),
I64(0xdd70a7ade0d77070), I64(0xe2b6d954716fb6b6), I64(0x67d0ceb7bd1ed0d0), I64(0x93ed3b7ec7d6eded),
I64(0x17cc2edb85e2cccc), I64(0x15422a5784684242), I64(0x5a98b4c22d2c9898), I64(0xaaa4490e55eda4a4),
I64(0xa0285d8850752828), I64(0x6d5cda31b8865c5c), I64(0xc7f8933fed6bf8f8), I64(0x228644a411c28686),
}, {
/* C7 vectors */
I64(0x186018c07830d818), I64(0x238c2305af462623), I64(0xc63fc67ef991b8c6), I64(0xe887e8136fcdfbe8),
I64(0x8726874ca113cb87), I64(0xb8dab8a9626d11b8), I64(0x0104010805020901), I64(0x4f214f426e9e0d4f),
I64(0x36d836adee6c9b36), I64(0xa6a2a6590451ffa6), I64(0xd26fd2debdb90cd2), I64(0xf5f3f5fb06f70ef5),
I64(0x79f979ef80f29679), I64(0x6fa16f5fcede306f), I64(0x917e91fcef3f6d91), I64(0x525552aa07a4f852),
I64(0x609d6027fdc04760), I64(0xbccabc89766535bc), I64(0x9b569baccd2b379b), I64(0x8e028e048c018a8e),
I64(0xa3b6a371155bd2a3), I64(0x0c300c603c186c0c), I64(0x7bf17bff8af6847b), I64(0x35d435b5e16a8035),
I64(0x1d741de8693af51d), I64(0xe0a7e05347ddb3e0), I64(0xd77bd7f6acb321d7), I64(0xc22fc25eed999cc2),
I64(0x2eb82e6d965c432e), I64(0x4b314b627a96294b), I64(0xfedffea321e15dfe), I64(0x5741578216aed557),
I64(0x155415a8412abd15), I64(0x77c1779fb6eee877), I64(0x37dc37a5eb6e9237), I64(0xe5b3e57b56d79ee5),
I64(0x9f469f8cd923139f), I64(0xf0e7f0d317fd23f0), I64(0x4a354a6a7f94204a), I64(0xda4fda9e95a944da),
I64(0x587d58fa25b0a258), I64(0xc903c906ca8fcfc9), I64(0x29a429558d527c29), I64(0x0a280a5022145a0a),
I64(0xb1feb1e14f7f50b1), I64(0xa0baa0691a5dc9a0), I64(0x6bb16b7fdad6146b), I64(0x852e855cab17d985),
I64(0xbdcebd8173673cbd), I64(0x5d695dd234ba8f5d), I64(0x1040108050209010), I64(0xf4f7f4f303f507f4),
I64(0xcb0bcb16c08bddcb), I64(0x3ef83eedc67cd33e), I64(0x05140528110a2d05), I64(0x6781671fe6ce7867),
I64(0xe4b7e47353d597e4), I64(0x279c2725bb4e0227), I64(0x4119413258827341), I64(0x8b168b2c9d0ba78b),
I64(0xa7a6a7510153f6a7), I64(0x7de97dcf94fab27d), I64(0x956e95dcfb374995), I64(0xd847d88e9fad56d8),
I64(0xfbcbfb8b30eb70fb), I64(0xee9fee2371c1cdee), I64(0x7ced7cc791f8bb7c), I64(0x66856617e3cc7166),
I64(0xdd53dda68ea77bdd), I64(0x175c17b84b2eaf17), I64(0x47014702468e4547), I64(0x9e429e84dc211a9e),
I64(0xca0fca1ec589d4ca), I64(0x2db42d75995a582d), I64(0xbfc6bf9179632ebf), I64(0x071c07381b0e3f07),
I64(0xad8ead012347acad), I64(0x5a755aea2fb4b05a), I64(0x8336836cb51bef83), I64(0x33cc3385ff66b633),
I64(0x6391633ff2c65c63), I64(0x020802100a041202), I64(0xaa92aa39384993aa), I64(0x71d971afa8e2de71),
I64(0xc807c80ecf8dc6c8), I64(0x196419c87d32d119), I64(0x4939497270923b49), I64(0xd943d9869aaf5fd9),
I64(0xf2eff2c31df931f2), I64(0xe3abe34b48dba8e3), I64(0x5b715be22ab6b95b), I64(0x881a8834920dbc88),
I64(0x9a529aa4c8293e9a), I64(0x2698262dbe4c0b26), I64(0x32c8328dfa64bf32), I64(0xb0fab0e94a7d59b0),
I64(0xe983e91b6acff2e9), I64(0x0f3c0f78331e770f), I64(0xd573d5e6a6b733d5), I64(0x803a8074ba1df480),
I64(0xbec2be997c6127be), I64(0xcd13cd26de87ebcd), I64(0x34d034bde4688934), I64(0x483d487a75903248),
I64(0xffdbffab24e354ff), I64(0x7af57af78ff48d7a), I64(0x907a90f4ea3d6490), I64(0x5f615fc23ebe9d5f),
I64(0x2080201da0403d20), I64(0x68bd6867d5d00f68), I64(0x1a681ad07234ca1a), I64(0xae82ae192c41b7ae),
I64(0xb4eab4c95e757db4), I64(0x544d549a19a8ce54), I64(0x937693ece53b7f93), I64(0x2288220daa442f22),
I64(0x648d6407e9c86364), I64(0xf1e3f1db12ff2af1), I64(0x73d173bfa2e6cc73), I64(0x124812905a248212),
I64(0x401d403a5d807a40), I64(0x0820084028104808), I64(0xc32bc356e89b95c3), I64(0xec97ec337bc5dfec),
I64(0xdb4bdb9690ab4ddb), I64(0xa1bea1611f5fc0a1), I64(0x8d0e8d1c8307918d), I64(0x3df43df5c97ac83d),
I64(0x976697ccf1335b97), I64(0x0000000000000000), I64(0xcf1bcf36d483f9cf), I64(0x2bac2b4587566e2b),
I64(0x76c57697b3ece176), I64(0x82328264b019e682), I64(0xd67fd6fea9b128d6), I64(0x1b6c1bd87736c31b),
I64(0xb5eeb5c15b7774b5), I64(0xaf86af112943beaf), I64(0x6ab56a77dfd41d6a), I64(0x505d50ba0da0ea50),
I64(0x450945124c8a5745), I64(0xf3ebf3cb18fb38f3), I64(0x30c0309df060ad30), I64(0xef9bef2b74c3c4ef),
I64(0x3ffc3fe5c37eda3f), I64(0x554955921caac755), I64(0xa2b2a2791059dba2), I64(0xea8fea0365c9e9ea),
I64(0x6589650fecca6a65), I64(0xbad2bab9686903ba), I64(0x2fbc2f65935e4a2f), I64(0xc027c04ee79d8ec0),
I64(0xde5fdebe81a160de), I64(0x1c701ce06c38fc1c), I64(0xfdd3fdbb2ee746fd), I64(0x4d294d52649a1f4d),
I64(0x927292e4e0397692), I64(0x75c9758fbceafa75), I64(0x061806301e0c3606), I64(0x8a128a249809ae8a),
I64(0xb2f2b2f940794bb2), I64(0xe6bfe66359d185e6), I64(0x0e380e70361c7e0e), I64(0x1f7c1ff8633ee71f),
I64(0x62956237f7c45562), I64(0xd477d4eea3b53ad4), I64(0xa89aa829324d81a8), I64(0x966296c4f4315296),
I64(0xf9c3f99b3aef62f9), I64(0xc533c566f697a3c5), I64(0x25942535b14a1025), I64(0x597959f220b2ab59),
I64(0x842a8454ae15d084), I64(0x72d572b7a7e4c572), I64(0x39e439d5dd72ec39), I64(0x4c2d4c5a6198164c),
I64(0x5e655eca3bbc945e), I64(0x78fd78e785f09f78), I64(0x38e038ddd870e538), I64(0x8c0a8c148605988c),
I64(0xd163d1c6b2bf17d1), I64(0xa5aea5410b57e4a5), I64(0xe2afe2434dd9a1e2), I64(0x6199612ff8c24e61),
I64(0xb3f6b3f1457b42b3), I64(0x21842115a5423421), I64(0x9c4a9c94d625089c), I64(0x1e781ef0663cee1e),
I64(0x4311432252866143), I64(0xc73bc776fc93b1c7), I64(0xfcd7fcb32be54ffc), I64(0x0410042014082404),
I64(0x515951b208a2e351), I64(0x995e99bcc72f2599), I64(0x6da96d4fc4da226d), I64(0x0d340d68391a650d),
I64(0xfacffa8335e979fa), I64(0xdf5bdfb684a369df), I64(0x7ee57ed79bfca97e), I64(0x2490243db4481924),
I64(0x3bec3bc5d776fe3b), I64(0xab96ab313d4b9aab), I64(0xce1fce3ed181f0ce), I64(0x1144118855229911),
I64(0x8f068f0c8903838f), I64(0x4e254e4a6b9c044e), I64(0xb7e6b7d1517366b7), I64(0xeb8beb0b60cbe0eb),
I64(0x3cf03cfdcc78c13c), I64(0x813e817cbf1ffd81), I64(0x946a94d4fe354094), I64(0xf7fbf7eb0cf31cf7),
I64(0xb9deb9a1676f18b9), I64(0x134c13985f268b13), I64(0x2cb02c7d9c58512c), I64(0xd36bd3d6b8bb05d3),
I64(0xe7bbe76b5cd38ce7), I64(0x6ea56e57cbdc396e), I64(0xc437c46ef395aac4), I64(0x030c03180f061b03),
I64(0x5645568a13acdc56), I64(0x440d441a49885e44), I64(0x7fe17fdf9efea07f), I64(0xa99ea921374f88a9),
I64(0x2aa82a4d8254672a), I64(0xbbd6bbb16d6b0abb), I64(0xc123c146e29f87c1), I64(0x535153a202a6f153),
I64(0xdc57dcae8ba572dc), I64(0x0b2c0b582716530b), I64(0x9d4e9d9cd327019d), I64(0x6cad6c47c1d82b6c),
I64(0x31c43195f562a431), I64(0x74cd7487b9e8f374), I64(0xf6fff6e309f115f6), I64(0x4605460a438c4c46),
I64(0xac8aac092645a5ac), I64(0x891e893c970fb589), I64(0x145014a04428b414), I64(0xe1a3e15b42dfbae1),
I64(0x165816b04e2ca616), I64(0x3ae83acdd274f73a), I64(0x69b9696fd0d20669), I64(0x092409482d124109),
I64(0x70dd70a7ade0d770), I64(0xb6e2b6d954716fb6), I64(0xd067d0ceb7bd1ed0), I64(0xed93ed3b7ec7d6ed),
I64(0xcc17cc2edb85e2cc), I64(0x4215422a57846842), I64(0x985a98b4c22d2c98), I64(0xa4aaa4490e55eda4),
I64(0x28a0285d88507528), I64(0x5c6d5cda31b8865c), I64(0xf8c7f8933fed6bf8), I64(0x86228644a411c286),
}
};
/* end of whirlpool_sbox array */
rhash-1.4.6/librhash/crc32.h 0000664 0000000 0000000 00000000646 14703622112 014214 0 ustar root root /* crc32.h */
#ifndef CRC32_H
#define CRC32_H
#ifdef __cplusplus
extern "C" {
#endif
/* hash functions */
#ifndef DISABLE_CRC32
unsigned rhash_get_crc32(unsigned crcinit, const unsigned char* msg, size_t size);
#endif
#ifndef DISABLE_CRC32C
unsigned rhash_get_crc32c(unsigned crcinit, const unsigned char* msg, size_t size);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* CRC32_H */
rhash-1.4.6/librhash/rhash.c 0000664 0000000 0000000 00000103765 15010520055 014401 0 ustar root root /* rhash.c - implementation of LibRHash library calls
*
* Copyright (c) 2008, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* modifier for Windows DLL */
#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS)
# define RHASH_API __declspec(dllexport)
#endif
/* macros for large file support, must be defined before any include file */
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#define _FILE_OFFSET_BITS 64
#include "rhash.h"
#include "algorithms.h"
#include "byte_order.h"
#include "hex.h"
#include "plug_openssl.h"
#include "torrent.h"
#include "util.h"
#include
#include
#include
#include
#include
#if defined(_WIN32)
# include
#endif
#define STATE_ACTIVE 0xb01dbabe
#define STATE_STOPPED 0xdeadbeef
#define STATE_DELETED 0xdecea5ed
#define IS_BAD_STATE(s) ((s) != STATE_ACTIVE && (s) != STATE_STOPPED)
#define RCTX_AUTO_FINAL 0x1
#define RCTX_FINALIZED 0x2
#define RCTX_FINALIZED_MASK (RCTX_AUTO_FINAL | RCTX_FINALIZED)
#define RHPR_FORMAT (RHPR_RAW | RHPR_HEX | RHPR_BASE32 | RHPR_BASE64)
#define RHPR_MODIFIER (RHPR_UPPERCASE | RHPR_URLENCODE | RHPR_REVERSE)
#define IS_VALID_EXTENDED_HASH_ID(id) (GET_EXTENDED_HASH_ID_INDEX(id) < RHASH_HASH_COUNT)
#define HAS_ZERO_OR_ONE_BIT(id) (((id) & ((id) - 1)) == 0)
#define IS_VALID_HASH_MASK(bitmask) ((bitmask) != 0 && ((bitmask) & ~RHASH_LOW_HASHES_MASK) == 0)
#define IS_VALID_HASH_ID(id) (IS_EXTENDED_HASH_ID(id) ? IS_VALID_EXTENDED_HASH_ID(id) : \
IS_VALID_HASH_MASK(id) && HAS_ZERO_OR_ONE_BIT(id))
#define EXTENDED_HASH_ID_FROM_BIT64(bit) ((unsigned)RHASH_EXTENDED_BIT ^ rhash_ctz64(bit))
/* each hash function context must be aligned to DEFAULT_ALIGNMENT bytes */
#define GET_CTX_ALIGNED(size) ALIGN_SIZE_BY((size), DEFAULT_ALIGNMENT)
#define GET_EXPORT_ALIGNED(size) ALIGN_SIZE_BY((size), 8)
RHASH_API void rhash_library_init(void)
{
rhash_init_algorithms();
#ifdef USE_OPENSSL
rhash_plug_openssl();
#endif
}
RHASH_API int rhash_count(void)
{
return rhash_info_size;
}
/* LOW-LEVEL LIBRHASH INTERFACE */
/**
* Allocate and initialize RHash context for calculating a single or multiple hash functions.
* The context after usage must be freed by calling rhash_free().
*
* @param count the size of the hash_ids array, the count must be greater than zero
* @param hash_ids array of identifiers of hash functions. Each element must
* be an identifier of one hash function
* @param need_init initialize context for each hash function
* @return initialized rhash context, NULL on fail with error code stored in errno
*/
static rhash_context_ext* rhash_alloc_multi(size_t count, const unsigned hash_ids[], int need_init)
{
rhash_context_ext* rctx = NULL; /* allocated rhash context */
const size_t header_size = GET_CTX_ALIGNED(sizeof(rhash_context_ext) + sizeof(rhash_vector_item) * count);
size_t ctx_size_sum = 0; /* size of hash contexts to store in rctx */
size_t i;
char* phash_ctx;
uint64_t hash_bitmask = 0;
if (count < 1) {
errno = EINVAL;
return NULL;
}
if (count == 1 && hash_ids[0] == RHASH_ALL_HASHES)
hash_ids = rhash_get_all_hash_ids(hash_ids[0], &count);
for (i = 0; i < count; i++) {
const rhash_hash_info* info = rhash_hash_info_by_id(hash_ids[i]);
if (!info) {
errno = EINVAL;
return NULL;
}
assert(IS_EXTENDED_HASH_ID(info->info->hash_id));
assert(IS_VALID_EXTENDED_HASH_ID(info->info->hash_id));
hash_bitmask |= I64(1) << GET_EXTENDED_HASH_ID_INDEX(info->info->hash_id);
/* align context sizes and sum up */
ctx_size_sum += GET_CTX_ALIGNED(info->context_size);
}
/* allocate rhash context with enough memory to store contexts of all selected hash functions */
rctx = (rhash_context_ext*)rhash_aligned_alloc(DEFAULT_ALIGNMENT, header_size + ctx_size_sum);
if (rctx == NULL)
return NULL;
/* initialize common fields of the rhash context */
memset(rctx, 0, header_size);
rctx->rc.hash_mask = hash_bitmask;
rctx->flags = RCTX_AUTO_FINAL; /* turn on auto-final by default */
rctx->state = STATE_ACTIVE;
rctx->hash_vector_size = (unsigned)count;
/* calculate aligned pointer >= (&rctx->vector[count]) */
phash_ctx = (char*)rctx + header_size;
assert(phash_ctx >= (char*)&rctx->vector[count]);
assert(phash_ctx < ((char*)&rctx->vector[count] + DEFAULT_ALIGNMENT));
for (i = 0; i < count; i++) {
const rhash_hash_info* info = rhash_hash_info_by_id(hash_ids[i]);
assert(info != NULL);
assert(info->context_size > 0);
assert(info->init != NULL);
assert(IS_PTR_ALIGNED_BY(phash_ctx, DEFAULT_ALIGNMENT)); /* hash context is aligned */
rctx->vector[i].hash_info = info;
rctx->vector[i].context = phash_ctx;
/* BTIH initialization is a bit complicated, so store the context pointer for later usage */
if (info->info->hash_id == EXTENDED_BTIH)
rctx->bt_ctx = phash_ctx;
phash_ctx += GET_CTX_ALIGNED(info->context_size);
/* initialize the i-th hash context */
if (need_init)
info->init(rctx->vector[i].context);
}
return rctx;
}
RHASH_API rhash rhash_init_multi(size_t count, const unsigned hash_ids[])
{
rhash_context_ext* ectx = rhash_alloc_multi(count, hash_ids, 1);
return &ectx->rc; /* return initialized rhash context */
}
RHASH_API rhash rhash_init(unsigned hash_id)
{
if (hash_id == RHASH_ALL_HASHES || hash_id == RHASH_LOW_HASHES_MASK) {
size_t count;
const unsigned* hash_ids = rhash_get_all_hash_ids(hash_id, &count);
return rhash_init_multi(count, hash_ids);
}
if (!IS_EXTENDED_HASH_ID(hash_id) && !IS_VALID_HASH_MASK(hash_id)) {
errno = EINVAL;
return NULL;
}
if (IS_EXTENDED_HASH_ID(hash_id) || HAS_ZERO_OR_ONE_BIT(hash_id)) {
return rhash_init_multi(1, &hash_id);
} else {
/* handle the deprecated case, when hash_id is a bitwise union of several hash function identifiers */
size_t count;
unsigned hash_ids[32];
unsigned id = hash_id & -hash_id; /* get the trailing bit */
for (count = 0; id <= hash_id; id = id << 1) {
assert(id != 0);
if (hash_id & id)
hash_ids[count++] = id;
}
assert(count > 1);
return rhash_init_multi(count, hash_ids);
}
}
void rhash_free(rhash ctx)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
unsigned i;
if (ctx == 0) return;
ectx->state = STATE_DELETED; /* mark memory block as being removed */
/* clean the hash functions, which require additional clean up */
for (i = 0; i < ectx->hash_vector_size; i++) {
const struct rhash_hash_info* info = ectx->vector[i].hash_info;
if (info->cleanup != 0) {
info->cleanup(ectx->vector[i].context);
}
}
rhash_aligned_free(ectx);
}
RHASH_API void rhash_reset(rhash ctx)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
unsigned i;
assert(ectx->hash_vector_size > 0);
assert(ectx->hash_vector_size <= RHASH_HASH_COUNT);
/* re-initialize every hash in a loop */
for (i = 0; i < ectx->hash_vector_size; i++) {
const struct rhash_hash_info* info = ectx->vector[i].hash_info;
if (info->cleanup != 0) {
info->cleanup(ectx->vector[i].context);
}
assert(info->init != NULL);
info->init(ectx->vector[i].context);
}
ectx->flags &= ~RCTX_FINALIZED; /* clear finalized state */
ectx->state = STATE_ACTIVE; /* re-activate the structure */
ctx->msg_size = 0;
}
RHASH_API int rhash_update(rhash ctx, const void* message, size_t length)
{
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
unsigned i;
assert(ectx->hash_vector_size <= RHASH_HASH_COUNT);
if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */
ctx->msg_size += length;
/* call update method for every algorithm */
for (i = 0; i < ectx->hash_vector_size; i++) {
const struct rhash_hash_info* info = ectx->vector[i].hash_info;
assert(info->update != 0);
info->update(ectx->vector[i].context, message, length);
}
return 0; /* no error processing at the moment */
}
RHASH_API int rhash_final(rhash ctx, unsigned char* first_result)
{
unsigned i = 0;
unsigned char buffer[130];
unsigned char* out = (first_result ? first_result : buffer);
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
assert(ectx->hash_vector_size <= RHASH_HASH_COUNT);
/* skip final call if already finalized and auto-final is on */
if ((ectx->flags & RCTX_FINALIZED_MASK) ==
(RCTX_AUTO_FINAL | RCTX_FINALIZED)) return 0;
/* call final method for every algorithm */
for (i = 0; i < ectx->hash_vector_size; i++) {
const struct rhash_hash_info* info = ectx->vector[i].hash_info;
assert(info->final != 0);
assert(info->info->digest_size < sizeof(buffer));
info->final(ectx->vector[i].context, out);
out = buffer;
}
ectx->flags |= RCTX_FINALIZED;
return 0; /* no error processing at the moment */
}
/**
* Header block for rhash context import/export.
*/
typedef struct export_header
{
uint32_t state;
uint16_t hash_vector_size;
uint16_t flags;
uint64_t msg_size;
} export_header;
/**
* Process export error. Returns 0 and set errno to EINVAL.
*
* @return NULL
*/
static size_t export_error_einval(void)
{
errno = EINVAL;
return 0;
}
/**
* Process import error. Returns NULL and set errno to EINVAL.
*
* @return NULL
*/
static rhash import_error_einval(void)
{
errno = EINVAL;
return NULL;
}
RHASH_API size_t rhash_export(rhash ctx, void* out, size_t size)
{
#if !defined(NO_IMPORT_EXPORT)
size_t export_size;
size_t i;
rhash_context_ext* const ectx = (rhash_context_ext*)ctx;
export_header* header = (export_header*)out;
unsigned* hash_ids = NULL;
if (!ctx || (out && size < sizeof(export_header)) || IS_BAD_STATE(ectx->state))
return export_error_einval();
export_size = sizeof(export_header) + sizeof(unsigned) * ectx->hash_vector_size;
if (out != NULL) {
memset(out, 0, size);
header->state = ectx->state;
header->hash_vector_size = (uint16_t)(ectx->hash_vector_size);
header->flags = (uint16_t)(ectx->flags);
header->msg_size = ctx->msg_size;
hash_ids = (unsigned*)(void*)(header + 1);
}
for (i = 0; i < ectx->hash_vector_size; i++) {
void* src_context = ectx->vector[i].context;
const struct rhash_hash_info* hash_info = ectx->vector[i].hash_info;
unsigned is_special = (hash_info->info->flags & F_SPCEXP);
size_t item_size;
if (out != NULL) {
if (size <= export_size)
return export_error_einval();
hash_ids[i] = hash_info->info->hash_id;
if (is_special) {
char* dst_item;
size_t left_size;
export_size = GET_EXPORT_ALIGNED(export_size);
dst_item = (char*)out + export_size;
left_size = size - export_size;
item_size = rhash_export_alg(hash_info->info->hash_id,
src_context, dst_item, left_size);
if (!item_size)
return export_error_einval();
} else {
char* dst_item = (char*)out + export_size;
item_size = hash_info->context_size;
if (size < (export_size + item_size))
return export_error_einval();
memcpy(dst_item, src_context, item_size);
}
} else {
if (is_special) {
export_size = GET_EXPORT_ALIGNED(export_size);
item_size = rhash_export_alg(
hash_info->info->hash_id, src_context, NULL, 0);
} else
item_size = hash_info->context_size;
}
export_size += item_size;
}
if (export_size < size)
return export_error_einval();
return export_size;
#else
return export_error_einval();
#endif /* !defined(NO_IMPORT_EXPORT) */
}
RHASH_API rhash rhash_import(const void* in, size_t size)
{
#if !defined(NO_IMPORT_EXPORT)
const export_header* header = (const export_header*)in;
size_t i;
size_t imported_size;
const unsigned* hash_ids;
const char* src_item;
rhash_context_ext* ectx;
if (!header || IS_BAD_STATE(header->state) || size < sizeof(export_header))
return import_error_einval();
imported_size = sizeof(export_header) + sizeof(unsigned) * header->hash_vector_size;
if (!header->hash_vector_size || size < imported_size)
return import_error_einval();
hash_ids = (const unsigned*)(const void*)(header + 1);
ectx = (rhash_context_ext*)rhash_alloc_multi(header->hash_vector_size, hash_ids, 0);
if (!ectx)
return NULL; /* errno must be set by the previous function */
ectx->state = header->state;
ectx->hash_vector_size = header->hash_vector_size;
ectx->flags = header->flags;
ectx->rc.msg_size = header->msg_size;
for (i = 0; i < ectx->hash_vector_size; i++) {
void* dst_context = ectx->vector[i].context;
const struct rhash_hash_info* hash_info = ectx->vector[i].hash_info;
unsigned is_special = (hash_info->info->flags & F_SPCEXP);
size_t item_size;
if (is_special) {
size_t left_size;
imported_size = GET_EXPORT_ALIGNED(imported_size);
src_item = (const char*)in + imported_size;
left_size = size - imported_size;
assert(size >= imported_size);
item_size = rhash_import_alg(hash_ids[i], dst_context, src_item, left_size);
imported_size += item_size;
if (!item_size || size < imported_size) {
ectx->hash_vector_size = (unsigned)i + 1; /* clean only initialized contextes */
rhash_free(&ectx->rc);
return import_error_einval();
}
} else {
src_item = (const char*)in + imported_size;
item_size = hash_info->context_size;
imported_size += item_size;
if (size < imported_size) {
ectx->hash_vector_size = (unsigned)i + 1;
rhash_free(&ectx->rc);
return import_error_einval();
}
memcpy(dst_context, src_item, item_size);
}
}
return &ectx->rc;
#else
return import_error_einval();
#endif /* !defined(NO_IMPORT_EXPORT) */
}
/**
* Validate and convert hash_id to EXTENDED_HASH_ID.
*
* @param hash_id id of one hash algorithm
* @return hash_id in its extended form if it is valid, 0 otherwise
*/
static unsigned convert_to_extended_hash_id(unsigned hash_id)
{
if (IS_EXTENDED_HASH_ID(hash_id))
{
if (IS_VALID_EXTENDED_HASH_ID(hash_id))
return hash_id;
}
else if (IS_VALID_HASH_MASK(hash_id) && HAS_ZERO_OR_ONE_BIT(hash_id))
{
return RHASH_EXTENDED_BIT ^ (rhash_ctz(hash_id));
}
return 0; /* invalid hash_id detected */
}
/**
* Find rhash_vector_item by the given hash_id in rhash context.
* The context must include the hash algorithm corresponding to the hash_id.
*
* @param ectx extended rhash context
* @param hash_id id of hash algorithm, or zero for the first hash algorithm in the rhash context
* @return item of the rhash context if the hash algorithm has been found, NULL otherwise
*/
static rhash_vector_item* rhash_get_info(rhash_context_ext* ectx, unsigned hash_id)
{
assert(ectx);
assert(ectx->hash_vector_size > 0 && ectx->hash_vector_size <= RHASH_HASH_COUNT);
if (hash_id == 0) {
return &ectx->vector[0]; /* get the first hash */
} else {
unsigned i;
hash_id = convert_to_extended_hash_id(hash_id);
if (!hash_id)
return NULL;
for (i = 0; i < ectx->hash_vector_size; i++) {
rhash_vector_item* item = &ectx->vector[i];
assert(item->hash_info != NULL);
assert(item->hash_info->info != NULL);
if (item->hash_info->info->hash_id == hash_id)
return item;
}
}
return NULL; /* hash_id not found */
}
/**
* Store message digest from the given rhash context item.
*
* @param item rhash context item, containing a message digest
* @param result buffer to put the message digest into
*/
static void rhash_put_digest(rhash_vector_item* item, unsigned char* result)
{
const struct rhash_hash_info* info = item->hash_info;
unsigned char* digest = ((unsigned char*)item->context + info->digest_diff);
if (info->info->flags & F_SWAP32) {
assert((info->info->digest_size & 3) == 0);
/* NB: the next call is correct only for multiple of 4 byte size */
rhash_swap_copy_str_to_u32(result, 0, digest, info->info->digest_size);
} else if (info->info->flags & F_SWAP64) {
rhash_swap_copy_u64_to_str(result, digest, info->info->digest_size);
} else {
memcpy(result, digest, info->info->digest_size);
}
}
RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data)
{
((rhash_context_ext*)ctx)->callback = callback;
((rhash_context_ext*)ctx)->callback_data = callback_data;
}
/* HIGH-LEVEL LIBRHASH INTERFACE */
RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result)
{
rhash ctx;
ctx = rhash_init(hash_id);
if (ctx == NULL) return -1;
rhash_update(ctx, message, length);
rhash_final(ctx, result);
rhash_free(ctx);
return 0;
}
/**
* Universal file I/O context for buffered file reading.
*/
struct file_update_context {
union {
FILE* file_fd; /* Standard C file stream pointer (for fopen/fread) */
int int_fd; /* POSIX file descriptor (for open/read) */
};
unsigned char* buffer; /* Data buffer for read operations */
size_t buffer_size; /* Size of the data buffer */
};
#if defined(_WIN32)
/* For Windows define ssize_t, which is Posix, but not in standard C */
# define ssize_t intptr_t
# define READ_SIZE_TYPE unsigned
#else
# define READ_SIZE_TYPE size_t
#endif
/**
* Read data from a C file stream into the context buffer using fread().
*
* @param fctx file context containing a file descriptor and buffer
* @param data_size number of bytes to read
* @return number of bytes read on success, -1 on fail with error code stored in errno
*/
static ssize_t read_file_fd_impl(struct file_update_context *fctx, size_t data_size)
{
size_t read_size;
if (feof(fctx->file_fd))
return 0;
assert(data_size <= fctx->buffer_size);
read_size = fread(fctx->buffer, 1, data_size, fctx->file_fd);
return (ferror(fctx->file_fd) ? -1 : (ssize_t)read_size);
}
/**
* Read data from a POSIX file descriptor into the context buffer using read().
*
* @param fctx file context containing a file descriptor and buffer
* @param data_size number of bytes to read
* @return number of bytes read on success, -1 on fail with error code stored in errno
*/
static ssize_t read_int_fd_impl(struct file_update_context *fctx, size_t data_size)
{
assert(data_size <= fctx->buffer_size);
return read(fctx->int_fd, fctx->buffer, (READ_SIZE_TYPE)data_size);
}
/**
* File read operation callback signature.
*
* @param fctx file context with configured buffer and file handle
* @param data_size requested read size
* @return bytes read (0 = EOF), or -1 on error (must set errno)
*/
typedef ssize_t (*read_file_func)(struct file_update_context *fctx, size_t data_size);
/**
* Internal implementation for hashing file/stream data.
* Used by rhash_update_fd() and rhash_file_update().
*
* @param ectx extended rhash context (must be initialized)
* @param fctx configured file context (buffer must be pre-allocated)
* @param read_func callback for reading data
* @param data_size maximum bytes to hash (RHASH_MAX_FILE_SIZE for entire file)
* @return 0 on success, -1 on fail with error code stored in errno
*/
static int rhash_file_update_impl(
struct rhash_context_ext* const ectx,
struct file_update_context* const fctx,
read_file_func read_func,
unsigned long long data_size)
{
const size_t buffer_size = 256 * 1024;
size_t read_size = buffer_size;
ssize_t length = 0;
if (ectx == NULL) {
errno = EINVAL;
return -1;
}
if (ectx->state != STATE_ACTIVE)
return 0; /* do nothing if canceled */
fctx->buffer_size = buffer_size;
fctx->buffer = (unsigned char*)rhash_aligned_alloc(DEFAULT_ALIGNMENT, buffer_size);
if (!fctx->buffer) {
return -1; /* errno is set to ENOMEM according to UNIX 98 */
}
while (data_size > (size_t)length) {
data_size -= (size_t)length;
if (data_size < read_size)
read_size = (size_t)data_size;
length = read_func(fctx, read_size);
if (length <= 0 || ectx->state != STATE_ACTIVE)
break;
rhash_update(&ectx->rc, fctx->buffer, (size_t)length);
if (ectx->callback) {
((rhash_callback_t)ectx->callback)(ectx->callback_data, ectx->rc.msg_size);
}
}
rhash_aligned_free(fctx->buffer);
return (length < 0 ? -1 : 0);
}
RHASH_API int rhash_update_fd(rhash ctx, int fd, unsigned long long data_size)
{
struct file_update_context fctx;
memset(&fctx, 0, sizeof(fctx));
fctx.int_fd = fd;
return rhash_file_update_impl((rhash_context_ext*)ctx,
&fctx, read_int_fd_impl, data_size);
}
RHASH_API int rhash_file_update(rhash ctx, FILE* fd)
{
struct file_update_context fctx;
memset(&fctx, 0, sizeof(fctx));
fctx.file_fd = fd;
return rhash_file_update_impl((rhash_context_ext*)ctx,
&fctx, read_file_fd_impl, RHASH_MAX_FILE_SIZE);
}
#ifdef _WIN32
# define FOPEN_MODE "rbS"
#else
# define FOPEN_MODE "rb"
#endif
RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result)
{
FILE* fd;
rhash ctx;
int res;
ctx = rhash_init(hash_id);
if (!ctx) {
return -1;
}
fd = fopen(filepath, FOPEN_MODE);
if (!fd) {
rhash_free(ctx);
return -1;
}
res = rhash_file_update(ctx, fd); /* hash the file */
fclose(fd);
if (res >= 0)
rhash_final(ctx, result);
rhash_free(ctx);
return res;
}
#ifdef _WIN32 /* windows only function */
#include
RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result)
{
FILE* fd;
rhash ctx;
int res;
ctx = rhash_init(hash_id);
if (!ctx) {
return -1;
}
fd = _wfsopen(filepath, L"rbS", _SH_DENYWR);
if (!fd) {
rhash_free(ctx);
return -1;
}
res = rhash_file_update(ctx, fd); /* hash the file */
fclose(fd);
if (res >= 0)
rhash_final(ctx, result);
rhash_free(ctx);
return res;
}
#endif
/* RHash information functions */
RHASH_API int rhash_is_base32(unsigned hash_id)
{
/* fast method is just to test a bit-mask */
return ((hash_id & (RHASH_TTH | RHASH_AICH)) != 0);
}
/**
* Returns information about a hash function by its hash_id.
*
* @param hash_id the id of hash algorithm
* @return pointer to the rhash_info structure containing the information
*/
static const rhash_info* rhash_info_by_id(unsigned hash_id)
{
const rhash_hash_info* hash_info = rhash_hash_info_by_id(hash_id);
return (hash_info ? hash_info->info : NULL);
}
RHASH_API int rhash_get_digest_size(unsigned hash_id)
{
const rhash_info* info = rhash_info_by_id(hash_id);
return (info ? (int)info->digest_size : -1);
}
RHASH_API int rhash_get_hash_length(unsigned hash_id)
{
const rhash_info* info = rhash_info_by_id(hash_id);
return (int)(info ? (info->flags & F_BS32 ?
BASE32_LENGTH(info->digest_size) : info->digest_size * 2) : 0);
}
RHASH_API const char* rhash_get_name(unsigned hash_id)
{
const rhash_info* info = rhash_info_by_id(hash_id);
return (info ? info->name : NULL);
}
RHASH_API const char* rhash_get_magnet_name(unsigned hash_id)
{
const rhash_info* info = rhash_info_by_id(hash_id);
return (info ? info->magnet_name : NULL);
}
static size_t rhash_get_magnet_url_size(const char* filepath,
rhash_context_ext* ectx, uint64_t hash_mask, int flags)
{
size_t size = 0; /* count terminating '\0' */
/* RHPR_NO_MAGNET, RHPR_FILESIZE */
if ((flags & RHPR_NO_MAGNET) == 0) {
size += 8;
}
if ((flags & RHPR_FILESIZE) != 0) {
uint64_t num = ectx->rc.msg_size;
size += 4;
if (num == 0) size++;
else {
for (; num; num /= 10, size++);
}
}
if (filepath) {
size += 4 + rhash_urlencode(NULL, filepath, strlen(filepath), 0);
}
if (!hash_mask) {
return size;
}
/* loop through hash values */
for (; hash_mask; hash_mask = hash_mask & (hash_mask - 1)) {
uint64_t bit = hash_mask & -(int)hash_mask;
unsigned hash_id = EXTENDED_HASH_ID_FROM_BIT64(bit);
const char* name = rhash_get_magnet_name(hash_id);
if (!name)
continue;
size += (7 + 2) + strlen(name);
size += rhash_print(NULL, &ectx->rc, hash_id,
(bit & RHASH_SHA1 ? RHPR_BASE32 : 0));
}
return size;
}
static size_t rhash_print_magnet_impl(char* output, size_t out_size, const char* filepath,
rhash_context_ext* const ectx, int flags, uint64_t hash_mask)
{
int i;
const char* begin = output;
hash_mask &= ectx->rc.hash_mask;
if (output == NULL) {
return rhash_get_magnet_url_size(filepath, ectx, hash_mask, flags);
}
if (out_size != RHASH_ERROR) {
size_t prefix_size = rhash_get_magnet_url_size(filepath, ectx, 0, flags);
if (out_size < prefix_size) {
errno = ENOMEM;
return 0;
}
out_size -= prefix_size;
}
/* RHPR_NO_MAGNET, RHPR_FILESIZE */
if ((flags & RHPR_NO_MAGNET) == 0) {
strcpy(output, "magnet:?");
output += 8;
}
if ((flags & RHPR_FILESIZE) != 0) {
strcpy(output, "xl=");
output += 3;
output += rhash_sprintI64(output, ectx->rc.msg_size);
*(output++) = '&';
}
flags &= RHPR_UPPERCASE;
if (filepath) {
strcpy(output, "dn=");
output += 3;
output += rhash_urlencode(output, filepath, strlen(filepath), flags);
*(output++) = '&';
}
for (i = 0; i <= 1; i++) {
static const uint64_t print_first = (RHASH_ED2K | RHASH_AICH);
uint64_t hash = (!i ? hash_mask & print_first : hash_mask & ~print_first);
/* loop through hash values */
for (; hash; hash = hash & (hash - 1)) {
uint64_t bit = hash & -(int)hash;
unsigned hash_id = EXTENDED_HASH_ID_FROM_BIT64(bit);
const char* magnet_name = rhash_get_magnet_name(hash_id);
size_t name_length;
if (!magnet_name)
continue; /* silently skip unsupported hash_id */
name_length = strlen(magnet_name);
if (out_size != RHASH_ERROR) {
size_t hash_part_size = (7 + 2) + name_length +
rhash_print(NULL, &ectx->rc, hash_id,
(bit & RHASH_SHA1 ? RHPR_BASE32 : 0));
if (out_size < hash_part_size) {
errno = ENOMEM;
return 0;
}
out_size -= hash_part_size;
}
strcpy(output, "xt=urn:");
output += 7;
strcpy(output, magnet_name);
output += name_length;
*(output++) = ':';
output += rhash_print(output, &ectx->rc, hash_id,
(bit & RHASH_SHA1 ? flags | RHPR_BASE32 : flags));
*(output++) = '&';
}
}
output[-1] = '\0'; /* terminate the line */
return (output - begin);
}
RHASH_API size_t rhash_print_magnet_multi(char* output, size_t out_size, const char* filepath,
rhash context, int flags, size_t count, const unsigned hash_ids[])
{
uint64_t hash_mask = 0;
if (!context) {
errno = EINVAL;
return 0;
}
if (count == 0 || (count == 1 && hash_ids[0] == RHASH_ALL_HASHES)) {
hash_mask = RHASH_LOW_HASHES_MASK;
} else {
size_t i;
for (i = 0; i < count; i++) {
unsigned hash_id = hash_ids[i];
if (!IS_VALID_HASH_ID(hash_id)) {
errno = EINVAL;
return 0;
}
if (IS_EXTENDED_HASH_ID(hash_id))
hash_mask |= I64(1) << GET_EXTENDED_HASH_ID_INDEX(hash_id);
else
hash_mask |= hash_id;
}
}
return rhash_print_magnet_impl(output, out_size, filepath,
(rhash_context_ext*)context, flags, hash_mask);
}
RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
rhash context, unsigned hash_mask, int flags)
{
if (hash_mask == RHASH_ALL_HASHES)
hash_mask = RHASH_LOW_HASHES_MASK;
if (!context || IS_EXTENDED_HASH_ID(hash_mask) || !hash_mask) {
errno = EINVAL;
return 0;
}
return rhash_print_magnet_impl(output, RHASH_ERROR, filepath,
(rhash_context_ext*)context, flags, (uint64_t)hash_mask);
}
/* HASH SUM OUTPUT INTERFACE */
size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags)
{
size_t result_length;
int upper_case = (flags & RHPR_UPPERCASE);
int format = (flags & ~RHPR_MODIFIER);
switch (format) {
case RHPR_HEX:
result_length = size * 2;
rhash_byte_to_hex(output, bytes, size, upper_case);
break;
case RHPR_BASE32:
result_length = BASE32_LENGTH(size);
rhash_byte_to_base32(output, bytes, size, upper_case);
break;
case RHPR_BASE64:
result_length = rhash_base64_url_encoded_helper(output, bytes, size, (flags & RHPR_URLENCODE), upper_case);
break;
default:
if (flags & RHPR_URLENCODE) {
result_length = rhash_urlencode(output, (char*)bytes, size, upper_case);
} else {
memcpy(output, bytes, size);
result_length = size;
}
break;
}
return result_length;
}
RHASH_API size_t rhash_print(char* output, rhash context, unsigned hash_id, int flags)
{
rhash_context_ext* ectx = (rhash_context_ext*)context;
rhash_vector_item* item = rhash_get_info(ectx, hash_id);
const rhash_info* info;
unsigned char digest[80];
size_t digest_size;
if (!item || !item->hash_info || !item->hash_info->info) return 0;
info = item->hash_info->info;
digest_size = info->digest_size;
assert(digest_size <= 64);
flags &= (RHPR_FORMAT | RHPR_MODIFIER);
if ((flags & RHPR_FORMAT) == 0) {
/* use default format if not specified by flags */
flags |= (info->flags & RHASH_INFO_BASE32 ? RHPR_BASE32 : RHPR_HEX);
}
if (output == NULL) {
size_t multiplier = (flags & RHPR_URLENCODE ? 3 : 1);
switch (flags & RHPR_FORMAT) {
case RHPR_HEX:
return (digest_size * 2);
case RHPR_BASE32:
return BASE32_LENGTH(digest_size);
case RHPR_BASE64:
return BASE64_LENGTH(digest_size) * multiplier;
default:
return digest_size * multiplier;
}
}
/* finalize context if not yet finalized and auto-final is on */
if ((ectx->flags & RCTX_FINALIZED_MASK) == RCTX_AUTO_FINAL) {
rhash_final(context, NULL);
}
rhash_put_digest(item, digest);
if ((flags & ~RHPR_UPPERCASE) == (RHPR_REVERSE | RHPR_HEX)) {
/* reverse the digest */
unsigned char* p = digest;
unsigned char* r = digest + digest_size - 1;
char tmp;
for (; p < r; p++, r--) {
tmp = *p;
*p = *r;
*r = tmp;
}
}
return rhash_print_bytes(output, digest, digest_size, flags);
}
#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS)
# define WIN32_LEAN_AND_MEAN
# include
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved);
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
(void)hModule;
(void)reserved;
switch (reason) {
case DLL_PROCESS_ATTACH:
rhash_library_init();
break;
case DLL_PROCESS_DETACH:
/*rhash_library_free();*/
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
#endif
/* Helper macro */
#define ENSURE_THAT(condition) while(!(condition)) { return RHASH_ERROR; }
static rhash_uptr_t rhash_get_algorithms_impl(const rhash_context_ext* ctx, size_t count, unsigned* data)
{
size_t i;
if (count != 0 && data != 0) {
ENSURE_THAT(ctx->hash_vector_size <= count);
for (i = 0; i < ctx->hash_vector_size; i++)
data[i] = ctx->vector[i].hash_info->info->hash_id;
}
return ctx->hash_vector_size;
}
static size_t hash_bitmask_to_array(unsigned bitmask, size_t count, unsigned* data)
{
unsigned bits_count;
bitmask &= ((unsigned)RHASH_EXTENDED_BIT - 1);
bits_count = rhash_popcount(bitmask);
if (count > 0 && data != 0) {
size_t index = 0;
ENSURE_THAT(bits_count <= count);
for (unsigned bit = 1; bit <= bitmask; bit = bit << 1) {
if ((bitmask & bit) != 0)
data[index++] = bit;
}
ENSURE_THAT(bits_count == index);
}
return bits_count;
}
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
static unsigned ids_array_to_hash_bitmask(size_t count, unsigned* data)
{
unsigned bitmask = 0;
size_t i;
for (i = 0; i < count; i++) {
if (!IS_EXTENDED_HASH_ID(data[i]))
bitmask |= data[i];
else if (data[i] == RHASH_ALL_HASHES)
bitmask |= RHASH_LOW_HASHES_MASK;
else
bitmask |= 1 << GET_EXTENDED_HASH_ID_INDEX(data[i]);
}
return bitmask;
}
#endif
RHASH_API size_t rhash_ctrl(rhash context, int cmd, size_t size, void* data)
{
/* cast to extented rhash context */
rhash_context_ext* const ctx = (rhash_context_ext*)context;
switch (cmd) {
case RMSG_GET_CONTEXT:
{
unsigned i;
unsigned hash_id = convert_to_extended_hash_id((unsigned)size);
ENSURE_THAT(hash_id);
ENSURE_THAT(data);
for (i = 0; i < ctx->hash_vector_size; i++) {
const struct rhash_hash_info* info = ctx->vector[i].hash_info;
if (info->info->hash_id == hash_id) {
*(void**)data = ctx->vector[i].context;
return 0;
}
}
return RHASH_ERROR;
}
case RMSG_CANCEL:
/* mark rhash context as canceled, in a multithreaded program */
atomic_compare_and_swap(&ctx->state, STATE_ACTIVE, STATE_STOPPED);
break;
case RMSG_IS_CANCELED:
return (ctx->state == STATE_STOPPED);
case RMSG_GET_FINALIZED:
return ((ctx->flags & RCTX_FINALIZED) != 0);
case RMSG_SET_AUTOFINAL:
ctx->flags &= ~RCTX_AUTO_FINAL;
if (size)
ctx->flags |= RCTX_AUTO_FINAL;
break;
case RMSG_HAS_CPU_FEATURE:
return (size_t)has_cpu_feature((unsigned)size);
case RMSG_GET_ALL_ALGORITHMS:
if (data && size) {
const unsigned* hash_ids;
ENSURE_THAT(size >= RHASH_HASH_COUNT);
hash_ids = rhash_get_all_hash_ids(RHASH_ALL_HASHES, &size);
memcpy(data, hash_ids, size * sizeof(*hash_ids));
}
return RHASH_HASH_COUNT;
case RMSG_GET_CTX_ALGORITHMS:
ENSURE_THAT(ctx);
return rhash_get_algorithms_impl(ctx, size, (unsigned*)data);
case RMSG_GET_OPENSSL_SUPPORTED:
return hash_bitmask_to_array(
rhash_get_openssl_supported_hash_mask(), size, (unsigned*)data);
case RMSG_GET_OPENSSL_AVAILABLE:
return hash_bitmask_to_array(
rhash_get_openssl_available_hash_mask(), size, (unsigned*)data);
case RMSG_GET_OPENSSL_ENABLED:
return hash_bitmask_to_array(
rhash_get_openssl_enabled_hash_mask(), size, (unsigned*)data);
case RMSG_SET_OPENSSL_ENABLED:
ENSURE_THAT(data || !size);
rhash_set_openssl_enabled_hash_mask(ids_array_to_hash_bitmask(size, (unsigned*)data));
break;
case RMSG_GET_LIBRHASH_VERSION:
return RHASH_XVERSION;
default:
return RHASH_ERROR; /* unknown message */
}
return 0;
}
/* Convert a rhash_uptr_t to a void* pointer. */
#define UPTR2PVOID(u) ((void*)((u) + 0))
/* Deprecated function to control rhash, use rhash_ctrl() instead */
RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata)
{
rhash ctx = (rhash)dst;
(void)rdata;
switch (msg_id) {
case RMSG_CANCEL:
case RMSG_IS_CANCELED:
case RMSG_GET_FINALIZED:
case RMSG_SET_AUTOFINAL:
case RMSG_GET_LIBRHASH_VERSION:
return rhash_ctrl(ctx, msg_id, (unsigned)ldata, UPTR2PVOID(rdata));
/* Legacy messages, which operate openssl hash masks directly */
#ifdef USE_OPENSSL
case RMSG_SET_OPENSSL_MASK:
rhash_set_openssl_enabled_hash_mask((unsigned)ldata);
break;
case RMSG_GET_OPENSSL_MASK:
return rhash_get_openssl_enabled_hash_mask();
#endif
case RMSG_GET_OPENSSL_SUPPORTED_MASK:
return rhash_get_openssl_supported_hash_mask();
case RMSG_GET_OPENSSL_AVAILABLE_MASK:
return rhash_get_openssl_available_hash_mask();
default:
return RHASH_ERROR; /* unknown message */
}
return 0;
}
rhash-1.4.6/librhash/Makefile 0000664 0000000 0000000 00000016620 15010476501 014567 0 ustar root root # Makefile for LibRHash
include config.mak
HEADERS = algorithms.h byte_order.h plug_openssl.h rhash.h rhash_torrent.h aich.h blake2b.h blake2s.h blake3.h crc32.h ed2k.h edonr.h hex.h md4.h md5.h sha1.h sha_ni.h sha256.h sha512.h sha3.h ripemd-160.h gost12.h gost94.h has160.h snefru.h tiger.h tth.h torrent.h ustd.h util.h whirlpool.h
SOURCES = algorithms.c byte_order.c plug_openssl.c rhash.c rhash_torrent.c aich.c blake2b.c blake2s.c blake3.c crc32.c ed2k.c edonr.c hex.c md4.c md5.c sha1.c sha_ni.c sha256.c sha512.c sha3.c ripemd-160.c gost12.c gost94.c has160.c snefru.c tiger.c tiger_sbox.c tth.c torrent.c util.c whirlpool.c whirlpool_sbox.c
OBJECTS = $(SOURCES:.c=.o)
LIB_HEADERS = rhash.h rhash_torrent.h
TEST_STATIC = test_static$(EXEC_EXT)
TEST_SHARED = test_shared$(EXEC_EXT)
INSTALL_DATA = $(INSTALL) -m 644
INSTALL_SHARED = $(INSTALL) -m $(SHARED_LIB_MODE)
all: $(BUILD_TARGETS)
lib-static: $(LIBRHASH_STATIC)
lib-shared: $(LIBRHASH_SHARED)
libs-all: lib-static lib-shared
uninstall-lib: uninstall-lib-shared uninstall-lib-static uninstall-so-link
config.mak:
echo "Run the ./configure script first" && false
install-lib-static: $(LIBRHASH_STATIC)
$(INSTALL) -d $(LIBDIR)
$(INSTALL_DATA) $(LIBRHASH_STATIC) $(LIBDIR)/
install-lib-shared: $(LIBRHASH_SHARED) $(EXTRA_INSTALL_LIBSHARED)
$(INSTALL) -d $(SO_DIR)
$(INSTALL_SHARED) $(LIBRHASH_SHARED) $(SO_DIR)/
test "x$(LIBRHASH_SO_MAJ)" = "x$(LIBRHASH_SHARED)" || ( \
rm -f $(LIBDIR)/$(LIBRHASH_SO_MAJ) && \
ln -s $(LIBRHASH_SHARED) $(LIBDIR)/$(LIBRHASH_SO_MAJ) )
install-implib:
$(INSTALL) -d $(LIBDIR)
$(INSTALL_DATA) $(LIBRHASH_IMPLIB) $(LIBDIR)/
install-so-link:
$(INSTALL) -d $(LIBDIR)
rm -f $(LIBDIR)/$(LIBRHASH_SOLINK)
ln -s $(LIBRHASH_SO_MAJ) $(LIBDIR)/$(LIBRHASH_SOLINK)
uninstall-lib-static: uninstall-lib-headers
rm -f $(LIBDIR)/$(LIBRHASH_STATIC)
uninstall-lib-shared: $(EXTRA_UNINSTALL_LIBSHARED)
rm -f $(SO_DIR)/$(LIBRHASH_SHARED) $(SO_DIR)/$(LIBRHASH_SO_MAJ)
uninstall-implib:
rm -f $(LIBDIR)/$(LIBRHASH_IMPLIB)
uninstall-so-link:
rm -f $(LIBDIR)/$(LIBRHASH_SOLINK)
install-lib-headers:
$(INSTALL) -d $(INCDIR)
$(INSTALL_DATA) $(LIB_HEADERS) $(INCDIR)/
uninstall-lib-headers:
for f in $(LIB_HEADERS); do rm -f "$(INCDIR)/$$f"; done
# not using GNU make extensions for compatibility with Unix/*BSD make
#%.o: %.c
# $(CC) -c $(CFLAGS) $< -o $@
# NOTE: dependences were generated by 'gcc -MM -DUSE_OPENSSL *.c'
# we are using plain old makefile style to support BSD make
aich.o: aich.c aich.h algorithms.h rhash.h byte_order.h ustd.h sha1.h \
util.h
$(CC) -c $(CFLAGS) $< -o $@
algorithms.o: algorithms.c algorithms.h rhash.h byte_order.h ustd.h \
util.h aich.h sha1.h blake2b.h blake2s.h blake3.h crc32.h ed2k.h md4.h \
edonr.h gost12.h gost94.h has160.h md5.h ripemd-160.h snefru.h sha_ni.h \
sha256.h sha512.h sha3.h tiger.h torrent.h tth.h whirlpool.h \
plug_openssl.h
$(CC) -c $(CFLAGS) $< -o $@
blake2b.o: blake2b.c blake2b.h ustd.h byte_order.h
$(CC) -c $(CFLAGS) $< -o $@
blake2s.o: blake2s.c blake2s.h ustd.h byte_order.h
$(CC) -c $(CFLAGS) $< -o $@
blake3.o: blake3.c blake3.h ustd.h byte_order.h
$(CC) -c $(CFLAGS) $< -o $@
byte_order.o: byte_order.c byte_order.h ustd.h
$(CC) -c $(CFLAGS) $< -o $@
crc32.o: crc32.c byte_order.h ustd.h crc32.h
$(CC) -c $(CFLAGS) $< -o $@
ed2k.o: ed2k.c ed2k.h md4.h ustd.h
$(CC) -c $(CFLAGS) $< -o $@
edonr.o: edonr.c byte_order.h ustd.h edonr.h
$(CC) -c $(CFLAGS) $< -o $@
gost12.o: gost12.c gost12.h ustd.h byte_order.h
$(CC) -c $(CFLAGS) $< -o $@
gost94.o: gost94.c gost94.h ustd.h byte_order.h
$(CC) -c $(CFLAGS) $< -o $@
has160.o: has160.c byte_order.h ustd.h has160.h
$(CC) -c $(CFLAGS) $< -o $@
hex.o: hex.c hex.h ustd.h util.h
$(CC) -c $(CFLAGS) $< -o $@
md4.o: md4.c byte_order.h ustd.h md4.h
$(CC) -c $(CFLAGS) $< -o $@
md5.o: md5.c byte_order.h ustd.h md5.h
$(CC) -c $(CFLAGS) $< -o $@
plug_openssl.o: plug_openssl.c util.h plug_openssl.h algorithms.h rhash.h \
byte_order.h ustd.h
$(CC) -c $(CFLAGS) $< -o $@
rhash.o: rhash.c rhash.h algorithms.h byte_order.h ustd.h hex.h \
plug_openssl.h torrent.h sha1.h util.h
$(CC) -c $(CFLAGS) $(VERSION_CFLAGS) $< -o $@
rhash_torrent.o: rhash_torrent.c rhash_torrent.h algorithms.h rhash.h \
byte_order.h ustd.h torrent.h sha1.h
$(CC) -c $(CFLAGS) $< -o $@
ripemd-160.o: ripemd-160.c byte_order.h ustd.h ripemd-160.h
$(CC) -c $(CFLAGS) $< -o $@
sha1.o: sha1.c byte_order.h ustd.h sha1.h
$(CC) -c $(CFLAGS) $< -o $@
sha_ni.o: sha_ni.c sha_ni.h sha1.h ustd.h sha256.h byte_order.h
$(CC) -c $(CFLAGS) $< -o $@
sha256.o: sha256.c byte_order.h ustd.h sha256.h
$(CC) -c $(CFLAGS) $< -o $@
sha3.o: sha3.c byte_order.h ustd.h sha3.h
$(CC) -c $(CFLAGS) $< -o $@
sha512.o: sha512.c byte_order.h ustd.h sha512.h
$(CC) -c $(CFLAGS) $< -o $@
snefru.o: snefru.c byte_order.h ustd.h snefru.h
$(CC) -c $(CFLAGS) $< -o $@
test_lib.o: test_lib.c byte_order.h ustd.h rhash_torrent.h test_utils.h \
rhash.h test_lib.h util.h
$(CC) -c $(CFLAGS) $< -o $@
test_utils.o: test_utils.c test_utils.h byte_order.h ustd.h rhash.h
$(CC) -c $(CFLAGS) $< -o $@
tiger.o: tiger.c byte_order.h ustd.h tiger.h
$(CC) -c $(CFLAGS) $< -o $@
tiger_sbox.o: tiger_sbox.c byte_order.h ustd.h
$(CC) -c $(CFLAGS) $< -o $@
torrent.o: torrent.c torrent.h algorithms.h rhash.h byte_order.h ustd.h \
sha1.h hex.h util.h
$(CC) -c $(CFLAGS) $< -o $@
tth.o: tth.c tth.h ustd.h tiger.h byte_order.h
$(CC) -c $(CFLAGS) $< -o $@
util.o: util.c util.h
$(CC) -c $(CFLAGS) $< -o $@
whirlpool.o: whirlpool.c byte_order.h ustd.h whirlpool.h
$(CC) -c $(CFLAGS) $< -o $@
whirlpool_sbox.o: whirlpool_sbox.c byte_order.h ustd.h
$(CC) -c $(CFLAGS) $< -o $@
# build shared library
$(EXPORTS_FILE): $(LIB_HEADERS)
sed -ne '1s/.*/{ global:/p; s/^RHASH_API.* \(rhash_[a-z0-9_]*\)(.*/ \1;/p; $$s/.*/local: *; };/p' \
$(LIB_HEADERS) | grep -v "$(EXPORTS_SKIP)" > $@
$(LIBRHASH_SOLINK):
test "x$(LIBRHASH_SO_MAJ)" = "x$(LIBRHASH_SHARED)" || ( \
rm -f $(LIBRHASH_SO_MAJ) && \
ln -s $(LIBRHASH_SHARED) $(LIBRHASH_SO_MAJ) )
rm -f $(LIBRHASH_SOLINK)
ln -s $(LIBRHASH_SO_MAJ) $(LIBRHASH_SOLINK)
$(LIBRHASH_SHARED): $(SOURCES) $(EXPORTS_TARGET) $(SOLINK_TARGET)
$(CC) $(SHARED_CFLAGS) $(VERSION_CFLAGS) $(SOURCES) $(SHARED_LDFLAGS) -o $@
# build static library
$(LIBRHASH_STATIC): $(OBJECTS)
rm -f $@
$(AR) -cqs $@ $(OBJECTS)
# test targets
$(TEST_SHARED): $(LIBRHASH_SHARED) test_lib.o test_utils.o
$(CC) $(CFLAGS) test_lib.o test_utils.o $(LIBRHASH_SHARED) $(LDFLAGS) -o $@
$(TEST_STATIC): $(LIBRHASH_STATIC) test_lib.o test_utils.o
$(CC) $(CFLAGS) test_lib.o test_utils.o $(LIBRHASH_STATIC) $(BIN_STATIC_LDFLAGS) -o $@
test: $(TEST_TARGETS)
test-static: $(TEST_STATIC)
./$(TEST_STATIC)
test-shared: $(TEST_SHARED)
LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(TEST_SHARED)
print-info: print-info-$(BUILD_TYPE)
print-info-static: $(TEST_STATIC)
./$(TEST_STATIC) --info
print-info-shared: $(TEST_SHARED)
LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(TEST_SHARED) --info
distclean: clean
rm -f config.mak
clean:
rm -f *.o $(LIBRHASH_STATIC) $(LIBRHASH_SHARED) $(TEST_STATIC) $(TEST_SHARED) $(RM_FILES)
.PHONY: all clean distclean install-lib-headers install-lib-shared install-lib-static \
install-so-link libs-all lib-shared lib-static test test-shared test-static \
print-info print-info-static print-info-shared uninstall-lib-headers \
uninstall-lib uninstall-lib-shared uninstall-lib-static uninstall-so-link \
install-implib uninstall-implib
rhash-1.4.6/librhash/edonr.h 0000664 0000000 0000000 00000002707 14703622112 014407 0 ustar root root /* edonr.h EDON-R 224/256/384/512 hash functions */
#ifndef EDONR_H
#define EDONR_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define edonr224_hash_size 28
#define edonr256_hash_size 32
#define edonr256_block_size 64
#define edonr384_hash_size 48
#define edonr512_hash_size 64
#define edonr512_block_size 128
struct edonr256_data {
unsigned message[16]; /* 512-bit buffer for leftovers */
unsigned hash[16]; /* 512-bit algorithm internal hashing state */
};
struct edonr512_data {
uint64_t message[16]; /* 1024-bit buffer for leftovers */
uint64_t hash[16]; /* 1024-bit algorithm internal hashing state */
};
/* algorithm context */
typedef struct edonr_ctx
{
union {
struct edonr256_data data256;
struct edonr512_data data512;
} u;
uint64_t length; /* number of processed bytes */
unsigned digest_length; /* length of the algorithm digest in bytes */
} edonr_ctx;
void rhash_edonr224_init(edonr_ctx* ctx);
void rhash_edonr256_init(edonr_ctx* ctx);
void rhash_edonr256_update(edonr_ctx* ctx, const unsigned char* data, size_t length);
void rhash_edonr256_final(edonr_ctx* ctx, unsigned char* result);
void rhash_edonr384_init(edonr_ctx* ctx);
void rhash_edonr512_init(edonr_ctx* ctx);
void rhash_edonr512_update(edonr_ctx* ctx, const unsigned char* data, size_t length);
void rhash_edonr512_final(edonr_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* EDONR_H */
rhash-1.4.6/librhash/sha512.h 0000664 0000000 0000000 00000001552 14703622112 014300 0 ustar root root /* sha.h sha512 and sha384 hash functions */
#ifndef SHA512_H
#define SHA512_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sha512_block_size 128
#define sha512_hash_size 64
#define sha384_hash_size 48
/* algorithm context */
typedef struct sha512_ctx
{
uint64_t message[16]; /* 1024-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
uint64_t hash[8]; /* 512-bit algorithm internal hashing state */
unsigned digest_length; /* length of the algorithm digest in bytes */
} sha512_ctx;
void rhash_sha384_init(sha512_ctx* ctx);
void rhash_sha512_init(sha512_ctx* ctx);
void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* data, size_t length);
void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* SHA512_H */
rhash-1.4.6/librhash/util.c 0000664 0000000 0000000 00000003546 14703622112 014252 0 ustar root root /* util.c - memory functions.
*
* Copyright (c) 2020, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "util.h"
#if defined(HAS_POSIX_ALIGNED_ALLOC)
#include
void* rhash_px_aalloc(size_t alignment, size_t size)
{
void* ptr;
if ((errno = posix_memalign(&ptr, alignment, size)) != 0)
return NULL;
return ptr;
}
#elif defined(HAS_GENERIC_ALIGNED_ALLOC)
#include
#include
void* rhash_aligned_alloc(size_t alignment, size_t size)
{
unsigned char* block = (unsigned char*)malloc(size + alignment);
assert((alignment & (alignment - 1)) == 0);
assert(alignment >= sizeof(void*));
if (block) {
const size_t alignment_mask = (alignment - 1);
unsigned char* basement = block + sizeof(void*);
size_t offset = ((unsigned char*)0 - basement) & alignment_mask;
void** result = (void**)(basement + offset);
assert((((unsigned char*)result - (unsigned char*)0) % alignment) == 0);
result[-1] = block; /* store original pointer */
return result;
}
return NULL;
}
void rhash_aligned_free(void* ptr)
{
void** pfree = (void**)ptr;
if (ptr)
free(pfree[-1]);
}
#else
typedef int dummy_declaration_required_by_strict_iso_c;
#endif /* HAS_POSIX_ALIGNED_ALLOC / HAS_GENERIC_ALIGNED_ALLOC */
rhash-1.4.6/librhash/sha_ni.h 0000664 0000000 0000000 00000001567 15010476501 014545 0 ustar root root /* sha_ni.h */
#ifndef SHA_NI_H
#define SHA_NI_H
#if defined(RHASH_SSE4_SHANI) && !defined(RHASH_DISABLE_SHANI)
# if defined(__GNUC__)
# define RHASH_GCC_SHANI
/* SHA extensions are supported by Visual Studio >= 2015 */
# elif (_MSC_VER >= 1900)
# define RHASH_MSVC_SHANI
# else
# define RHASH_DISABLE_SHANI
# endif
#endif
#if defined(RHASH_SSE4_SHANI) && !defined(RHASH_DISABLE_SHANI)
#include "sha1.h"
#include "sha256.h"
#ifdef __cplusplus
extern "C" {
#endif
void rhash_sha1_ni_update(sha1_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_sha1_ni_final(sha1_ctx* ctx, unsigned char* result);
void rhash_sha256_ni_update(sha256_ctx* ctx, const unsigned char* data, size_t length);
void rhash_sha256_ni_final(sha256_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_SSE4_SHANI */
#endif /* SHA_NI_H */
rhash-1.4.6/librhash/sha256.c 0000664 0000000 0000000 00000021007 14703622112 014275 0 ustar root root /* sha256.c - an implementation of SHA-256/224 hash functions
* based on FIPS 180-3 (Federal Information Processing Standart).
*
* Copyright (c) 2010, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include "byte_order.h"
#include "sha256.h"
/* SHA-224 and SHA-256 constants for 64 rounds. These words represent
* the first 32 bits of the fractional parts of the cube
* roots of the first 64 prime numbers. */
static const unsigned rhash_k256[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
/* The SHA256/224 functions defined by FIPS 180-3, 4.1.2 */
/* Optimized version of Ch(x,y,z)=((x & y) | (~x & z)) */
#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
/* Optimized version of Maj(x,y,z)=((x & y) ^ (x & z) ^ (y & z)) */
#define Maj(x,y,z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
#define Sigma0(x) (ROTR32((x), 2) ^ ROTR32((x), 13) ^ ROTR32((x), 22))
#define Sigma1(x) (ROTR32((x), 6) ^ ROTR32((x), 11) ^ ROTR32((x), 25))
#define sigma0(x) (ROTR32((x), 7) ^ ROTR32((x), 18) ^ ((x) >> 3))
#define sigma1(x) (ROTR32((x),17) ^ ROTR32((x), 19) ^ ((x) >> 10))
/* Recalculate element n-th of circular buffer W using formula
* W[n] = sigma1(W[n - 2]) + W[n - 7] + sigma0(W[n - 15]) + W[n - 16]; */
#define RECALCULATE_W(W,n) (W[n] += \
(sigma1(W[(n - 2) & 15]) + W[(n - 7) & 15] + sigma0(W[(n - 15) & 15])))
#define ROUND(a,b,c,d,e,f,g,h,k,data) { \
unsigned T1 = h + Sigma1(e) + Ch(e,f,g) + k + (data); \
d += T1, h = T1 + Sigma0(a) + Maj(a,b,c); }
#define ROUND_1_16(a,b,c,d,e,f,g,h,n) \
ROUND(a,b,c,d,e,f,g,h, rhash_k256[n], W[n] = be2me_32(block[n]))
#define ROUND_17_64(a,b,c,d,e,f,g,h,n) \
ROUND(a,b,c,d,e,f,g,h, k[n], RECALCULATE_W(W, n))
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha256_init(sha256_ctx* ctx)
{
/* Initial values. These words were obtained by taking the first 32
* bits of the fractional parts of the square roots of the first
* eight prime numbers. */
static const unsigned SHA256_H0[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
memset(ctx->message, 0, sizeof(ctx->message));
ctx->length = 0;
ctx->digest_length = sha256_hash_size;
/* initialize algorithm state */
memcpy(ctx->hash, SHA256_H0, sizeof(ctx->hash));
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha224_init(struct sha256_ctx* ctx)
{
/* Initial values from FIPS 180-3. These words were obtained by taking
* bits from 33th to 64th of the fractional parts of the square
* roots of ninth through sixteenth prime numbers. */
static const unsigned SHA224_H0[8] = {
0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4
};
memset(ctx->message, 0, sizeof(ctx->message));
ctx->length = 0;
ctx->digest_length = sha224_hash_size;
memcpy(ctx->hash, SHA224_H0, sizeof(ctx->hash));
}
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_sha256_process_block(unsigned hash[8], unsigned block[16])
{
unsigned A, B, C, D, E, F, G, H;
unsigned W[16];
const unsigned* k;
int i;
A = hash[0], B = hash[1], C = hash[2], D = hash[3];
E = hash[4], F = hash[5], G = hash[6], H = hash[7];
/* Compute SHA using alternate Method: FIPS 180-3 6.1.3 */
ROUND_1_16(A, B, C, D, E, F, G, H, 0);
ROUND_1_16(H, A, B, C, D, E, F, G, 1);
ROUND_1_16(G, H, A, B, C, D, E, F, 2);
ROUND_1_16(F, G, H, A, B, C, D, E, 3);
ROUND_1_16(E, F, G, H, A, B, C, D, 4);
ROUND_1_16(D, E, F, G, H, A, B, C, 5);
ROUND_1_16(C, D, E, F, G, H, A, B, 6);
ROUND_1_16(B, C, D, E, F, G, H, A, 7);
ROUND_1_16(A, B, C, D, E, F, G, H, 8);
ROUND_1_16(H, A, B, C, D, E, F, G, 9);
ROUND_1_16(G, H, A, B, C, D, E, F, 10);
ROUND_1_16(F, G, H, A, B, C, D, E, 11);
ROUND_1_16(E, F, G, H, A, B, C, D, 12);
ROUND_1_16(D, E, F, G, H, A, B, C, 13);
ROUND_1_16(C, D, E, F, G, H, A, B, 14);
ROUND_1_16(B, C, D, E, F, G, H, A, 15);
for (i = 16, k = &rhash_k256[16]; i < 64; i += 16, k += 16) {
ROUND_17_64(A, B, C, D, E, F, G, H, 0);
ROUND_17_64(H, A, B, C, D, E, F, G, 1);
ROUND_17_64(G, H, A, B, C, D, E, F, 2);
ROUND_17_64(F, G, H, A, B, C, D, E, 3);
ROUND_17_64(E, F, G, H, A, B, C, D, 4);
ROUND_17_64(D, E, F, G, H, A, B, C, 5);
ROUND_17_64(C, D, E, F, G, H, A, B, 6);
ROUND_17_64(B, C, D, E, F, G, H, A, 7);
ROUND_17_64(A, B, C, D, E, F, G, H, 8);
ROUND_17_64(H, A, B, C, D, E, F, G, 9);
ROUND_17_64(G, H, A, B, C, D, E, F, 10);
ROUND_17_64(F, G, H, A, B, C, D, E, 11);
ROUND_17_64(E, F, G, H, A, B, C, D, 12);
ROUND_17_64(D, E, F, G, H, A, B, C, 13);
ROUND_17_64(C, D, E, F, G, H, A, B, 14);
ROUND_17_64(B, C, D, E, F, G, H, A, 15);
}
hash[0] += A, hash[1] += B, hash[2] += C, hash[3] += D;
hash[4] += E, hash[5] += F, hash[6] += G, hash[7] += H;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha256_update(sha256_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
size_t left = sha256_block_size - index;
memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_sha256_process_block(ctx->hash, (unsigned*)ctx->message);
msg += left;
size -= left;
}
while (size >= sha256_block_size) {
unsigned* aligned_message_block;
if (IS_ALIGNED_32(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (unsigned*)msg;
} else {
memcpy(ctx->message, msg, sha256_block_size);
aligned_message_block = (unsigned*)ctx->message;
}
rhash_sha256_process_block(ctx->hash, aligned_message_block);
msg += sha256_block_size;
size -= sha256_block_size;
}
if (size) {
memcpy(ctx->message, msg, size); /* save leftovers */
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha256_final(sha256_ctx* ctx, unsigned char* result)
{
size_t index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
/* pad message and run for last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= le2me_32(~(0xFFFFFFFFu << shift));
ctx->message[index++] ^= le2me_32(0x80u << shift);
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
ctx->message[index++] = 0;
}
rhash_sha256_process_block(ctx->hash, ctx->message);
index = 0;
}
while (index < 14) {
ctx->message[index++] = 0;
}
ctx->message[14] = be2me_32( (unsigned)(ctx->length >> 29) );
ctx->message[15] = be2me_32( (unsigned)(ctx->length << 3) );
rhash_sha256_process_block(ctx->hash, ctx->message);
if (result) be32_copy(result, 0, ctx->hash, ctx->digest_length);
}
rhash-1.4.6/librhash/ed2k.h 0000664 0000000 0000000 00000001212 14703622112 014113 0 ustar root root /* ed2k.h */
#ifndef ED2K_H
#define ED2K_H
#include "md4.h"
#ifdef __cplusplus
extern "C" {
#endif
/* algorithm context */
typedef struct ed2k_ctx
{
md4_ctx md4_context_inner; /* md4 context to hash file blocks */
md4_ctx md4_context; /* md4 context to hash block hashes */
int not_emule; /* flag: 0 for emule ed2k algorithm */
} ed2k_ctx;
/* hash functions */
void rhash_ed2k_init(ed2k_ctx* ctx);
void rhash_ed2k_update(ed2k_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_ed2k_final(ed2k_ctx* ctx, unsigned char result[16]);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* ED2K_H */
rhash-1.4.6/librhash/sha_ni.c 0000664 0000000 0000000 00000051006 15010476501 014531 0 ustar root root /* sha1_ni.c - SHA1 implementation using Intel SHA extensions
* Written and place in public domain by Jeffrey Walton
* Based on code from Intel, and by Sean Gulley for the miTLS project.
*
* Copyright (c) 2025, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "sha_ni.h"
#if defined(RHASH_SSE4_SHANI) && !defined(RHASH_DISABLE_SHANI)
# include "byte_order.h"
# include
# if defined(RHASH_GCC_SHANI)
# include
# elif defined(RHASH_MSVC_SHANI)
# include
# define WIN32_LEAN_AND_MEAN
# include
# else
# error "Unsupported platform"
# endif /* RHASH_GCC_SHANI */
/**
* The core transformation. Process a 512-bit block.
* The function has been taken from RFC 3174 with little changes.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_sha1_ni_process_block(unsigned* state, const uint8_t* block, size_t length)
{
__m128i ABCD, ABCD_SAVE, E0, E0_SAVE, E1;
__m128i MSG0, MSG1, MSG2, MSG3;
const __m128i MASK = _mm_set_epi64x(0x0001020304050607ULL, 0x08090a0b0c0d0e0fULL);
/* Load initial values */
ABCD = _mm_loadu_si128((const __m128i*)state);
E0 = _mm_set_epi32(state[4], 0, 0, 0);
ABCD = _mm_shuffle_epi32(ABCD, 0x1B);
while (length >= sha1_block_size)
{
/* Save current state */
ABCD_SAVE = ABCD;
E0_SAVE = E0;
/* Rounds 0-3 */
MSG0 = _mm_loadu_si128((const __m128i*)(block + 0));
MSG0 = _mm_shuffle_epi8(MSG0, MASK);
E0 = _mm_add_epi32(E0, MSG0);
E1 = ABCD;
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
/* Rounds 4-7 */
MSG1 = _mm_loadu_si128((const __m128i*)(block + 16));
MSG1 = _mm_shuffle_epi8(MSG1, MASK);
E1 = _mm_sha1nexte_epu32(E1, MSG1);
E0 = ABCD;
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0);
MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
/* Rounds 8-11 */
MSG2 = _mm_loadu_si128((const __m128i*)(block + 32));
MSG2 = _mm_shuffle_epi8(MSG2, MASK);
E0 = _mm_sha1nexte_epu32(E0, MSG2);
E1 = ABCD;
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
MSG0 = _mm_xor_si128(MSG0, MSG2);
/* Rounds 12-15 */
MSG3 = _mm_loadu_si128((const __m128i*)(block + 48));
MSG3 = _mm_shuffle_epi8(MSG3, MASK);
E1 = _mm_sha1nexte_epu32(E1, MSG3);
E0 = ABCD;
MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0);
MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
MSG1 = _mm_xor_si128(MSG1, MSG3);
/* Rounds 16-19 */
E0 = _mm_sha1nexte_epu32(E0, MSG0);
E1 = ABCD;
MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
MSG2 = _mm_xor_si128(MSG2, MSG0);
/* Rounds 20-23 */
E1 = _mm_sha1nexte_epu32(E1, MSG1);
E0 = ABCD;
MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
MSG3 = _mm_xor_si128(MSG3, MSG1);
/* Rounds 24-27 */
E0 = _mm_sha1nexte_epu32(E0, MSG2);
E1 = ABCD;
MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1);
MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
MSG0 = _mm_xor_si128(MSG0, MSG2);
/* Rounds 28-31 */
E1 = _mm_sha1nexte_epu32(E1, MSG3);
E0 = ABCD;
MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
MSG1 = _mm_xor_si128(MSG1, MSG3);
/* Rounds 32-35 */
E0 = _mm_sha1nexte_epu32(E0, MSG0);
E1 = ABCD;
MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1);
MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
MSG2 = _mm_xor_si128(MSG2, MSG0);
/* Rounds 36-39 */
E1 = _mm_sha1nexte_epu32(E1, MSG1);
E0 = ABCD;
MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
MSG3 = _mm_xor_si128(MSG3, MSG1);
/* Rounds 40-43 */
E0 = _mm_sha1nexte_epu32(E0, MSG2);
E1 = ABCD;
MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
MSG0 = _mm_xor_si128(MSG0, MSG2);
/* Rounds 44-47 */
E1 = _mm_sha1nexte_epu32(E1, MSG3);
E0 = ABCD;
MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2);
MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
MSG1 = _mm_xor_si128(MSG1, MSG3);
/* Rounds 48-51 */
E0 = _mm_sha1nexte_epu32(E0, MSG0);
E1 = ABCD;
MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
MSG2 = _mm_xor_si128(MSG2, MSG0);
/* Rounds 52-55 */
E1 = _mm_sha1nexte_epu32(E1, MSG1);
E0 = ABCD;
MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2);
MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
MSG3 = _mm_xor_si128(MSG3, MSG1);
/* Rounds 56-59 */
E0 = _mm_sha1nexte_epu32(E0, MSG2);
E1 = ABCD;
MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
MSG0 = _mm_xor_si128(MSG0, MSG2);
/* Rounds 60-63 */
E1 = _mm_sha1nexte_epu32(E1, MSG3);
E0 = ABCD;
MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
MSG1 = _mm_xor_si128(MSG1, MSG3);
/* Rounds 64-67 */
E0 = _mm_sha1nexte_epu32(E0, MSG0);
E1 = ABCD;
MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3);
MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
MSG2 = _mm_xor_si128(MSG2, MSG0);
/* Rounds 68-71 */
E1 = _mm_sha1nexte_epu32(E1, MSG1);
E0 = ABCD;
MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
MSG3 = _mm_xor_si128(MSG3, MSG1);
/* Rounds 72-75 */
E0 = _mm_sha1nexte_epu32(E0, MSG2);
E1 = ABCD;
MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3);
/* Rounds 76-79 */
E1 = _mm_sha1nexte_epu32(E1, MSG3);
E0 = ABCD;
ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
/* Combine state */
E0 = _mm_sha1nexte_epu32(E0, E0_SAVE);
ABCD = _mm_add_epi32(ABCD, ABCD_SAVE);
block += sha1_block_size;
length -= sha1_block_size;
}
/* Save state */
ABCD = _mm_shuffle_epi32(ABCD, 0x1B);
_mm_storeu_si128((__m128i*) state, ABCD);
state[4] = _mm_extract_epi32(E0, 3);
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha1_ni_update(sha1_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
unsigned left = sha1_block_size - index;
memcpy(ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_sha1_ni_process_block(ctx->hash, (uint8_t*)ctx->message, sha1_block_size);
msg += left;
size -= left;
}
if (size >= sha1_block_size) {
size_t blocks_size = size & ~63;
rhash_sha1_ni_process_block(ctx->hash, (uint8_t*)msg, blocks_size);
msg += blocks_size;
size -= blocks_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha1_ni_final(sha1_ctx* ctx, unsigned char* result)
{
unsigned index = (unsigned)ctx->length & 63;
unsigned* msg32 = (unsigned*)ctx->message;
/* pad message and run for last block */
ctx->message[index++] = 0x80;
while ((index & 3) != 0) {
ctx->message[index++] = 0;
}
index >>= 2;
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
msg32[index++] = 0;
}
rhash_sha1_ni_process_block(ctx->hash, (uint8_t*)msg32, sha1_block_size);
index = 0;
}
while (index < 14) {
msg32[index++] = 0;
}
msg32[14] = be2me_32( (unsigned)(ctx->length >> 29) );
msg32[15] = be2me_32( (unsigned)(ctx->length << 3) );
rhash_sha1_ni_process_block(ctx->hash, (uint8_t*)msg32, sha1_block_size);
if (result) be32_copy(result, 0, &ctx->hash, sha1_hash_size);
}
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_sha256_ni_process_block(unsigned* state, const uint8_t* block, size_t length)
{
__m128i STATE0, STATE1;
__m128i MSG, TMP;
__m128i MSG0, MSG1, MSG2, MSG3;
__m128i ABEF_SAVE, CDGH_SAVE;
const __m128i MASK = _mm_set_epi64x(0x0c0d0e0f08090a0bULL, 0x0405060700010203ULL);
/* Load initial values */
TMP = _mm_loadu_si128((const __m128i*) &state[0]);
STATE1 = _mm_loadu_si128((const __m128i*) &state[4]);
TMP = _mm_shuffle_epi32(TMP, 0xB1); /* CDAB */
STATE1 = _mm_shuffle_epi32(STATE1, 0x1B); /* EFGH */
STATE0 = _mm_alignr_epi8(TMP, STATE1, 8); /* ABEF */
STATE1 = _mm_blend_epi16(STATE1, TMP, 0xF0); /* CDGH */
while (length >= sha256_block_size)
{
/* Save current state */
ABEF_SAVE = STATE0;
CDGH_SAVE = STATE1;
/* Rounds 0-3 */
MSG = _mm_loadu_si128((const __m128i*) (block+0));
MSG0 = _mm_shuffle_epi8(MSG, MASK);
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0xE9B5DBA5B5C0FBCFULL, 0x71374491428A2F98ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
/* Rounds 4-7 */
MSG1 = _mm_loadu_si128((const __m128i*) (block+16));
MSG1 = _mm_shuffle_epi8(MSG1, MASK);
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0xAB1C5ED5923F82A4ULL, 0x59F111F13956C25BULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG0 = _mm_sha256msg1_epu32(MSG0, MSG1);
/* Rounds 8-11 */
MSG2 = _mm_loadu_si128((const __m128i*) (block+32));
MSG2 = _mm_shuffle_epi8(MSG2, MASK);
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0x550C7DC3243185BEULL, 0x12835B01D807AA98ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG1 = _mm_sha256msg1_epu32(MSG1, MSG2);
/* Rounds 12-15 */
MSG3 = _mm_loadu_si128((const __m128i*) (block+48));
MSG3 = _mm_shuffle_epi8(MSG3, MASK);
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0xC19BF1749BDC06A7ULL, 0x80DEB1FE72BE5D74ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG3, MSG2, 4);
MSG0 = _mm_add_epi32(MSG0, TMP);
MSG0 = _mm_sha256msg2_epu32(MSG0, MSG3);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG2 = _mm_sha256msg1_epu32(MSG2, MSG3);
/* Rounds 16-19 */
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0x240CA1CC0FC19DC6ULL, 0xEFBE4786E49B69C1ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG0, MSG3, 4);
MSG1 = _mm_add_epi32(MSG1, TMP);
MSG1 = _mm_sha256msg2_epu32(MSG1, MSG0);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG3 = _mm_sha256msg1_epu32(MSG3, MSG0);
/* Rounds 20-23 */
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0x76F988DA5CB0A9DCULL, 0x4A7484AA2DE92C6FULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG1, MSG0, 4);
MSG2 = _mm_add_epi32(MSG2, TMP);
MSG2 = _mm_sha256msg2_epu32(MSG2, MSG1);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG0 = _mm_sha256msg1_epu32(MSG0, MSG1);
/* Rounds 24-27 */
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0xBF597FC7B00327C8ULL, 0xA831C66D983E5152ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG2, MSG1, 4);
MSG3 = _mm_add_epi32(MSG3, TMP);
MSG3 = _mm_sha256msg2_epu32(MSG3, MSG2);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG1 = _mm_sha256msg1_epu32(MSG1, MSG2);
/* Rounds 28-31 */
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0x1429296706CA6351ULL, 0xD5A79147C6E00BF3ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG3, MSG2, 4);
MSG0 = _mm_add_epi32(MSG0, TMP);
MSG0 = _mm_sha256msg2_epu32(MSG0, MSG3);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG2 = _mm_sha256msg1_epu32(MSG2, MSG3);
/* Rounds 32-35 */
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0x53380D134D2C6DFCULL, 0x2E1B213827B70A85ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG0, MSG3, 4);
MSG1 = _mm_add_epi32(MSG1, TMP);
MSG1 = _mm_sha256msg2_epu32(MSG1, MSG0);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG3 = _mm_sha256msg1_epu32(MSG3, MSG0);
/* Rounds 36-39 */
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0x92722C8581C2C92EULL, 0x766A0ABB650A7354ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG1, MSG0, 4);
MSG2 = _mm_add_epi32(MSG2, TMP);
MSG2 = _mm_sha256msg2_epu32(MSG2, MSG1);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG0 = _mm_sha256msg1_epu32(MSG0, MSG1);
/* Rounds 40-43 */
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0xC76C51A3C24B8B70ULL, 0xA81A664BA2BFE8A1ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG2, MSG1, 4);
MSG3 = _mm_add_epi32(MSG3, TMP);
MSG3 = _mm_sha256msg2_epu32(MSG3, MSG2);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG1 = _mm_sha256msg1_epu32(MSG1, MSG2);
/* Rounds 44-47 */
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0x106AA070F40E3585ULL, 0xD6990624D192E819ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG3, MSG2, 4);
MSG0 = _mm_add_epi32(MSG0, TMP);
MSG0 = _mm_sha256msg2_epu32(MSG0, MSG3);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG2 = _mm_sha256msg1_epu32(MSG2, MSG3);
/* Rounds 48-51 */
MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0x34B0BCB52748774CULL, 0x1E376C0819A4C116ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG0, MSG3, 4);
MSG1 = _mm_add_epi32(MSG1, TMP);
MSG1 = _mm_sha256msg2_epu32(MSG1, MSG0);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
MSG3 = _mm_sha256msg1_epu32(MSG3, MSG0);
/* Rounds 52-55 */
MSG = _mm_add_epi32(MSG1, _mm_set_epi64x(0x682E6FF35B9CCA4FULL, 0x4ED8AA4A391C0CB3ULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG1, MSG0, 4);
MSG2 = _mm_add_epi32(MSG2, TMP);
MSG2 = _mm_sha256msg2_epu32(MSG2, MSG1);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
/* Rounds 56-59 */
MSG = _mm_add_epi32(MSG2, _mm_set_epi64x(0x8CC7020884C87814ULL, 0x78A5636F748F82EEULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
TMP = _mm_alignr_epi8(MSG2, MSG1, 4);
MSG3 = _mm_add_epi32(MSG3, TMP);
MSG3 = _mm_sha256msg2_epu32(MSG3, MSG2);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
/* Rounds 60-63 */
MSG = _mm_add_epi32(MSG3, _mm_set_epi64x(0xC67178F2BEF9A3F7ULL, 0xA4506CEB90BEFFFAULL));
STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
MSG = _mm_shuffle_epi32(MSG, 0x0E);
STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
/* Combine state */
STATE0 = _mm_add_epi32(STATE0, ABEF_SAVE);
STATE1 = _mm_add_epi32(STATE1, CDGH_SAVE);
block += sha256_block_size;
length -= sha256_block_size;
}
TMP = _mm_shuffle_epi32(STATE0, 0x1B); /* FEBA */
STATE1 = _mm_shuffle_epi32(STATE1, 0xB1); /* DCHG */
STATE0 = _mm_blend_epi16(TMP, STATE1, 0xF0); /* DCBA */
STATE1 = _mm_alignr_epi8(STATE1, TMP, 8); /* ABEF */
/* Save state */
_mm_storeu_si128((__m128i*) &state[0], STATE0);
_mm_storeu_si128((__m128i*) &state[4], STATE1);
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha256_ni_update(sha256_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
size_t left = sha256_block_size - index;
memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_sha256_ni_process_block(ctx->hash, (uint8_t*)ctx->message, sha256_block_size);
msg += left;
size -= left;
}
if (size >= sha256_block_size) {
size_t blocks_size = size & ~63;
rhash_sha256_ni_process_block(ctx->hash, (uint8_t*)msg, blocks_size);
msg += blocks_size;
size -= blocks_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha256_ni_final(sha256_ctx* ctx, unsigned char* result)
{
size_t index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
/* pad message and run for last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= le2me_32(~(0xFFFFFFFFu << shift));
ctx->message[index++] ^= le2me_32(0x80u << shift);
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
ctx->message[index++] = 0;
}
rhash_sha256_ni_process_block(ctx->hash, (uint8_t*)ctx->message, sha256_block_size);
index = 0;
}
while (index < 14) {
ctx->message[index++] = 0;
}
ctx->message[14] = be2me_32( (unsigned)(ctx->length >> 29) );
ctx->message[15] = be2me_32( (unsigned)(ctx->length << 3) );
rhash_sha256_ni_process_block(ctx->hash, (uint8_t*)ctx->message, sha256_block_size);
if (result) be32_copy(result, 0, ctx->hash, ctx->digest_length);
}
#else
typedef int dummy_declaration_required_by_strict_iso_c;
#endif /* defined(RHASH_SSE4_SHANI) && !defined(RHASH_DISABLE_SHANI) */
rhash-1.4.6/librhash/torrent.c 0000664 0000000 0000000 00000062666 15010476501 015003 0 ustar root root /* torrent.c - create BitTorrent files and calculate BitTorrent InfoHash (BTIH).
*
* Copyright (c) 2010, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "torrent.h"
#include "hex.h"
#include "util.h"
#include
#include
#include
#include
#include /* time() */
#ifdef USE_OPENSSL
#define SHA1_INIT(ctx) ((pinit_t)ctx->sha1_methods.init)(&ctx->sha1_context)
#define SHA1_UPDATE(ctx, msg, size) ((pupdate_t)ctx->sha1_methods.update)(&ctx->sha1_context, (msg), (size))
#define SHA1_FINAL(ctx, result) ((pfinal_t)ctx->sha1_methods.final)(&ctx->sha1_context, (result))
#else
#define SHA1_INIT(ctx) rhash_sha1_init(&ctx->sha1_context)
#define SHA1_UPDATE(ctx, msg, size) rhash_sha1_update(&ctx->sha1_context, (msg), (size))
#define SHA1_FINAL(ctx, result) rhash_sha1_final(&ctx->sha1_context, (result))
#endif
#define BT_MIN_PIECE_LENGTH 16384
/** size of a SHA1 hash in bytes */
#define BT_HASH_SIZE 20
/** number of SHA1 hashes to store together in one block */
#define BT_BLOCK_SIZE 256
#define BT_BLOCK_SIZE_IN_BYTES (BT_BLOCK_SIZE * BT_HASH_SIZE)
/**
* Initialize torrent context before calculating hash.
*
* @param ctx context to initialize
*/
void bt_init(torrent_ctx* ctx)
{
memset(ctx, 0, sizeof(torrent_ctx));
ctx->piece_length = BT_MIN_PIECE_LENGTH;
assert(BT_MIN_PIECE_LENGTH == bt_default_piece_length(0, 0));
#ifdef USE_OPENSSL
/* get the methods of the selected SHA1 algorithm */
assert(rhash_info_table[3].info->hash_id == EXTENDED_SHA1);
assert(rhash_info_table[3].context_size <= (sizeof(sha1_ctx) + sizeof(unsigned long)));
rhash_load_sha1_methods(&ctx->sha1_methods, METHODS_SELECTED);
#endif
SHA1_INIT(ctx);
}
/**
* Free memory allocated by properties of torrent_vect structure.
*
* @param vect vector to clean
*/
static void bt_vector_clean(torrent_vect* vect)
{
size_t i;
for (i = 0; i < vect->size; i++) {
free(vect->array[i]);
}
free(vect->array);
}
/**
* Clean up torrent context by freeing all dynamically
* allocated memory.
*
* @param ctx torrent algorithm context
*/
void bt_cleanup(torrent_ctx* ctx)
{
assert(ctx != NULL);
/* destroy arrays */
bt_vector_clean(&ctx->hash_blocks);
bt_vector_clean(&ctx->files);
bt_vector_clean(&ctx->announce);
free(ctx->program_name);
free(ctx->content.str);
ctx->program_name = 0;
ctx->content.str = 0;
}
static void bt_generate_torrent(torrent_ctx* ctx);
/**
* Add an item to vector.
*
* @param vect vector to add item to
* @param item the item to add
* @return non-zero on success, zero on fail
*/
static int bt_vector_add_ptr(torrent_vect* vect, void* item)
{
/* check if vector contains enough space for the next item */
if (vect->size >= vect->allocated) {
size_t size = (vect->allocated == 0 ? 128 : vect->allocated * 2);
void* new_array = realloc(vect->array, size * sizeof(void*));
if (new_array == NULL) return 0; /* failed: no memory */
vect->array = (void**)new_array;
vect->allocated = size;
}
/* add new item to the vector */
vect->array[vect->size] = item;
vect->size++;
return 1;
}
/**
* Store a SHA1 hash of a processed file piece.
*
* @param ctx torrent algorithm context
* @return non-zero on success, zero on fail
*/
static int bt_store_piece_sha1(torrent_ctx* ctx)
{
unsigned char* block;
unsigned char* hash;
if ((ctx->piece_count % BT_BLOCK_SIZE) == 0) {
block = (unsigned char*)malloc(BT_BLOCK_SIZE_IN_BYTES);
if (!block)
return 0;
if (!bt_vector_add_ptr(&ctx->hash_blocks, block)) {
free(block);
return 0;
}
} else {
block = (unsigned char*)(ctx->hash_blocks.array[ctx->piece_count / BT_BLOCK_SIZE]);
}
hash = &block[BT_HASH_SIZE * (ctx->piece_count % BT_BLOCK_SIZE)];
SHA1_FINAL(ctx, hash); /* write the hash */
ctx->piece_count++;
return 1;
}
/**
* A filepath and filesize information.
*/
typedef struct bt_file_info
{
uint64_t size;
char path[];
} bt_file_info;
/**
* Add a file info into the batch of files of given torrent.
*
* @param ctx torrent algorithm context
* @param path file path
* @param filesize file size
* @return non-zero on success, zero on fail
*/
int bt_add_file(torrent_ctx* ctx, const char* path, uint64_t filesize)
{
size_t len = strlen(path);
bt_file_info* info = (bt_file_info*)malloc(sizeof(uint64_t) + len + 1);
if (info == NULL) {
ctx->error = 1;
return 0;
}
info->size = filesize;
memcpy(info->path, path, len + 1);
if (!bt_vector_add_ptr(&ctx->files, info)) {
free(info);
return 0;
}
/* recalculate piece length (but only if hashing not started yet) */
if (ctx->piece_count == 0 && ctx->index == 0) {
/* note: in case of batch of files should use a total batch size */
ctx->piece_length = bt_default_piece_length(filesize, ctx->options & BT_OPT_TRANSMISSION);
}
return 1;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void bt_update(torrent_ctx* ctx, const void* msg, size_t size)
{
const unsigned char* pmsg = (const unsigned char*)msg;
size_t rest = (size_t)(ctx->piece_length - ctx->index);
assert(ctx->index < ctx->piece_length);
while (size > 0) {
size_t left = (size < rest ? size : rest);
SHA1_UPDATE(ctx, pmsg, left);
if (size < rest) {
ctx->index += left;
break;
}
bt_store_piece_sha1(ctx);
SHA1_INIT(ctx);
ctx->index = 0;
pmsg += rest;
size -= rest;
rest = ctx->piece_length;
}
}
/**
* Finalize hashing and optionally store calculated hash into the given array.
* If the result parameter is NULL, the hash is not stored, but it is
* accessible by bt_get_btih().
*
* @param ctx the algorithm context containing current hashing state
* @param result pointer to the array store message hash into
*/
void bt_final(torrent_ctx* ctx, unsigned char result[20])
{
if (ctx->index > 0) {
bt_store_piece_sha1(ctx); /* flush buffered data */
}
bt_generate_torrent(ctx);
if (result) memcpy(result, ctx->btih, btih_hash_size);
}
/* BitTorrent functions */
/**
* Grow, if needed, the torrent_str buffer to ensure it contains
* at least (length + 1) characters.
*
* @param ctx the torrent algorithm context
* @param length length of the string, the allocated buffer must contain
* @return 1 on success, 0 on error
*/
static int bt_str_ensure_length(torrent_ctx* ctx, size_t length)
{
char* new_str;
if (ctx->error)
return 0;
if (length >= ctx->content.allocated) {
length++; /* allocate one character more */
if (length < 64) length = 64;
else length = (length + 255) & ~255;
new_str = (char*)realloc(ctx->content.str, length);
if (new_str == NULL) {
ctx->error = 1;
ctx->content.allocated = 0;
return 0;
}
ctx->content.str = new_str;
ctx->content.allocated = length;
}
return 1;
}
/**
* Append a null-terminated string to the string string buffer.
*
* @param ctx the torrent algorithm context
* @param text the null-terminated string to append
*/
static void bt_str_append(torrent_ctx* ctx, const char* text)
{
size_t length = strlen(text);
if (!bt_str_ensure_length(ctx, ctx->content.length + length + 1))
return;
assert(ctx->content.str != 0);
memcpy(ctx->content.str + ctx->content.length, text, length + 1);
ctx->content.length += length;
}
/**
* B-encode given integer.
*
* @param ctx the torrent algorithm context
* @param name B-encoded string to prepend the number or NULL
* @param number the integer to output
*/
static void bt_bencode_int(torrent_ctx* ctx, const char* name, uint64_t number)
{
char* p;
if (name)
bt_str_append(ctx, name);
/* add up to 20 digits and 2 letters */
if (!bt_str_ensure_length(ctx, ctx->content.length + 22))
return;
p = ctx->content.str + ctx->content.length;
*(p++) = 'i';
p += rhash_sprintI64(p, number);
*(p++) = 'e';
*p = '\0'; /* terminate string with \0 */
ctx->content.length = (p - ctx->content.str);
}
/**
* B-encode a string.
*
* @param ctx the torrent algorithm context
* @param name B-encoded string to prepend or NULL
* @param str the string to encode
*/
static void bt_bencode_str(torrent_ctx* ctx, const char* name, const char* str)
{
const size_t string_length = strlen(str);
int number_length;
char* p;
if (name)
bt_str_append(ctx, name);
if (!bt_str_ensure_length(ctx, ctx->content.length + string_length + 21))
return;
p = ctx->content.str + ctx->content.length;
p += (number_length = rhash_sprintI64(p, string_length));
ctx->content.length += string_length + number_length + 1;
*(p++) = ':';
memcpy(p, str, string_length + 1); /* copy with trailing '\0' */
}
/**
* B-encode array of SHA1 hashes of file pieces.
*
* @param ctx pointer to the torrent structure containing SHA1 hashes
*/
static void bt_bencode_pieces(torrent_ctx* ctx)
{
const size_t pieces_length = ctx->piece_count * BT_HASH_SIZE;
size_t bytes_left, i;
int number_length;
char* p;
if (!bt_str_ensure_length(ctx, ctx->content.length + pieces_length + 21))
return;
p = ctx->content.str + ctx->content.length;
p += (number_length = rhash_sprintI64(p, pieces_length));
ctx->content.length += pieces_length + number_length + 1;
*(p++) = ':';
p[pieces_length] = '\0'; /* terminate with \0 just in case */
for (bytes_left = pieces_length, i = 0; bytes_left > 0; i++)
{
size_t size = (bytes_left < BT_BLOCK_SIZE_IN_BYTES ? bytes_left : BT_BLOCK_SIZE_IN_BYTES);
memcpy(p, ctx->hash_blocks.array[i], size);
bytes_left -= size;
p += size;
}
}
/**
* Calculate default torrent piece length, using uTorrent algorithm.
* Algorithm:
* piece_length = 16K for total_size < 16M,
* piece_length = 8M for total_size >= 4G,
* piece_length = top_bit(total_size) / 512 otherwise.
*
* @param total_size total torrent batch size
* @return piece length used by torrent file
*/
static size_t utorr_piece_length(uint64_t total_size)
{
size_t size = (size_t)(total_size >> 9) | 16384;
size_t hi_bit;
for (hi_bit = 8388608; hi_bit > size; hi_bit >>= 1);
return hi_bit;
}
#define MB I64(1048576)
/**
* Calculate default torrent piece length, using transmission algorithm.
* Algorithm:
* piece_length = (size >= 2G ? 2M : size >= 1G ? 1M :
* size >= 512M ? 512K : size >= 350M ? 256K :
* size >= 150M ? 128K : size >= 50M ? 64K : 32K);
*
* @param total_size total torrent batch size
* @return piece length used by torrent file
*/
static size_t transmission_piece_length(uint64_t total_size)
{
static const uint64_t sizes[6] = { 50 * MB, 150 * MB, 350 * MB, 512 * MB, 1024 * MB, 2048 * MB };
int i;
for (i = 0; i < 6 && total_size >= sizes[i]; i++);
return (32 * 1024) << i;
}
size_t bt_default_piece_length(uint64_t total_size, int transmission)
{
return (transmission ?
transmission_piece_length(total_size) : utorr_piece_length(total_size));
}
/* get file basename */
static const char* bt_get_basename(const char* path)
{
const char* p = strchr(path, '\0') - 1;
for (; p >= path && *p != '/' && *p != '\\'; p--);
return (p + 1);
}
/* extract batchname from the path, modifies the path buffer */
static const char* get_batch_name(char* path)
{
char* p = (char*)bt_get_basename(path) - 1;
for (; p > path && (*p == '/' || *p == '\\'); p--) *p = 0;
if (p <= path) return "BATCH_DIR";
return bt_get_basename(path);
}
/* write file size and path */
static void bt_file_info_append(torrent_ctx* ctx, const char* length_name,
const char* path_name, bt_file_info* info)
{
bt_bencode_int(ctx, length_name, info->size);
/* store the file basename */
bt_bencode_str(ctx, path_name, bt_get_basename(info->path));
}
/**
* Generate torrent file content
* @see http://wiki.theory.org/BitTorrentSpecification
*
* @param ctx the torrent algorithm context
*/
static void bt_generate_torrent(torrent_ctx* ctx)
{
uint64_t total_size = 0;
size_t info_start_pos;
assert(ctx->content.str == NULL);
if (ctx->piece_length == 0) {
if (ctx->files.size == 1) {
total_size = ((bt_file_info*)ctx->files.array[0])->size;
}
ctx->piece_length = bt_default_piece_length(total_size, ctx->options & BT_OPT_TRANSMISSION);
}
if ((ctx->options & BT_OPT_INFOHASH_ONLY) == 0) {
/* write the torrent header */
bt_str_append(ctx, "d");
if (ctx->announce.array && ctx->announce.size > 0) {
bt_bencode_str(ctx, "8:announce", ctx->announce.array[0]);
/* if more than one announce url */
if (ctx->announce.size > 1) {
/* add the announce-list key-value pair */
size_t i;
bt_str_append(ctx, "13:announce-listll");
for (i = 0; i < ctx->announce.size; i++) {
if (i > 0) {
bt_str_append(ctx, "el");
}
bt_bencode_str(ctx, 0, ctx->announce.array[i]);
}
bt_str_append(ctx, "ee");
}
}
if (ctx->program_name) {
bt_bencode_str(ctx, "10:created by", ctx->program_name);
}
bt_bencode_int(ctx, "13:creation date", (uint64_t)time(NULL));
bt_str_append(ctx, "8:encoding5:UTF-8");
}
/* write the essential for BTIH part of the torrent file */
bt_str_append(ctx, "4:infod"); /* start the info dictionary */
info_start_pos = ctx->content.length - 1;
if (ctx->files.size > 1) {
size_t i;
/* process batch torrent */
bt_str_append(ctx, "5:filesl"); /* start list of files */
/* write length and path for each file in the batch */
for (i = 0; i < ctx->files.size; i++) {
bt_file_info_append(ctx, "d6:length", "4:pathl",
(bt_file_info*)ctx->files.array[i]);
bt_str_append(ctx, "ee");
}
/* note: get_batch_name modifies path, so should be called here */
bt_bencode_str(ctx, "e4:name", get_batch_name(
((bt_file_info*)ctx->files.array[0])->path));
}
else if (ctx->files.size > 0) {
/* write size and basename of the first file */
/* in the non-batch mode other files are ignored */
bt_file_info_append(ctx, "6:length", "4:name",
(bt_file_info*)ctx->files.array[0]);
}
bt_bencode_int(ctx, "12:piece length", ctx->piece_length);
bt_str_append(ctx, "6:pieces");
bt_bencode_pieces(ctx);
if (ctx->options & BT_OPT_PRIVATE) {
bt_str_append(ctx, "7:privatei1e");
} else if (ctx->options & BT_OPT_TRANSMISSION) {
bt_str_append(ctx, "7:privatei0e");
}
bt_str_append(ctx, "ee");
/* calculate BTIH */
SHA1_INIT(ctx);
if (ctx->content.str) {
SHA1_UPDATE(ctx, (unsigned char*)ctx->content.str + info_start_pos,
ctx->content.length - info_start_pos - 1);
}
SHA1_FINAL(ctx, ctx->btih);
}
/* Getters/Setters */
/**
* Get BTIH (BitTorrent Info Hash) value.
*
* @param ctx the torrent algorithm context
* @return the 20-bytes long BTIH value
*/
unsigned char* bt_get_btih(torrent_ctx* ctx)
{
return ctx->btih;
}
/**
* Set the torrent algorithm options.
*
* @param ctx the torrent algorithm context
* @param options the options to set
*/
void bt_set_options(torrent_ctx* ctx, unsigned options)
{
ctx->options = options;
}
#if defined(__STRICT_ANSI__)
/* define strdup for gcc -ansi */
static char* bt_strdup(const char* str)
{
size_t len = strlen(str);
char* res = (char*)malloc(len + 1);
if (res) memcpy(res, str, len + 1);
return res;
}
#define strdup bt_strdup
#endif /* __STRICT_ANSI__ */
/**
* Set optional name of the program generating the torrent
* for storing into torrent file.
*
* @param ctx the torrent algorithm context
* @param name the program name
* @return non-zero on success, zero on error
*/
int bt_set_program_name(torrent_ctx* ctx, const char* name)
{
ctx->program_name = strdup(name);
return (ctx->program_name != NULL);
}
/**
* Set length of a file piece.
*
* @param ctx the torrent algorithm context
* @param piece_length the piece length in bytes
*/
void bt_set_piece_length(torrent_ctx* ctx, size_t piece_length)
{
ctx->piece_length = piece_length;
}
/**
* Set length of a file piece by the total batch size.
*
* @param ctx the torrent algorithm context
* @param total_size total batch size
*/
void bt_set_total_batch_size(torrent_ctx* ctx, uint64_t total_size)
{
ctx->piece_length = bt_default_piece_length(total_size, ctx->options & BT_OPT_TRANSMISSION);
}
/**
* Add a tracker announce-URL to the torrent file.
*
* @param ctx the torrent algorithm context
* @param announce_url the announce URL of the tracker
* @return non-zero on success, zero on error
*/
int bt_add_announce(torrent_ctx* ctx, const char* announce_url)
{
char* url_copy;
if (!announce_url || announce_url[0] == '\0') return 0;
url_copy = strdup(announce_url);
if (!url_copy) return 0;
if (bt_vector_add_ptr(&ctx->announce, url_copy))
return 1;
free(url_copy);
return 0;
}
/**
* Get the content of generated torrent file.
*
* @param ctx the torrent algorithm context
* @param pstr pointer to pointer receiving the buffer with file content
* @return length of the torrent file content
*/
size_t bt_get_text(torrent_ctx* ctx, char** pstr)
{
assert(ctx->content.str);
*pstr = ctx->content.str;
return ctx->content.length;
}
#if !defined(NO_IMPORT_EXPORT)
# define EXPORT_ALIGNER 7
# define GET_EXPORT_ALIGNED(size) (((size) + EXPORT_ALIGNER) & ~EXPORT_ALIGNER)
# define GET_EXPORT_PADDING(size) (-(size) & EXPORT_ALIGNER)
# define GET_EXPORT_STR_LEN(length) GET_EXPORT_ALIGNED((length) + 1)
# define GET_EXPORT_SIZED_STR_LEN(length) GET_EXPORT_STR_LEN((length) + sizeof(size_t))
# define IS_EXPORT_ALIGNED(size) (((size) & EXPORT_ALIGNER) == 0)
# define BT_CTX_OSSL_FLAG 0x10
static void bt_export_str(char* out, const char* str, size_t length)
{
assert(!!out);
*(size_t*)(out) = length;
out += sizeof(size_t);
memcpy(out, str, length + 1);
}
typedef struct bt_export_header {
size_t torrent_ctx_size;
size_t files_size;
size_t announce_size;
size_t program_name_length;
size_t content_length;
} bt_export_header;
/**
* Export algorithm context to a memory region, or calculate the
* size required for context export.
*
* @param ctx the algorithm context containing current hashing state
* @param out pointer to the memory region or NULL
* @param size size of memory region
* @return the size of the exported data on success, 0 on fail.
*/
size_t bt_export(const torrent_ctx* ctx, void* out, size_t size)
{
const size_t head_size = sizeof(bt_export_header);
const size_t ctx_head_size = offsetof(torrent_ctx, hash_blocks);
const size_t hashes_size = ctx->piece_count * BT_HASH_SIZE;
size_t exported_size = head_size + ctx_head_size + hashes_size;
const size_t padding_size = GET_EXPORT_PADDING(exported_size);
const size_t program_name_length = (ctx->program_name ? strlen(ctx->program_name) : 0);
char* out_ptr = (char*)out;
size_t i;
assert((exported_size + padding_size) == GET_EXPORT_ALIGNED(exported_size));
if (out_ptr) {
bt_export_header* header = (bt_export_header*)out_ptr;
size_t hash_data_left = hashes_size;
if (size < exported_size)
return 0;
header->torrent_ctx_size = sizeof(torrent_ctx);
header->files_size = ctx->files.size;
header->announce_size = ctx->announce.size;
header->program_name_length = program_name_length;
header->content_length = ctx->content.length;
out_ptr += head_size;
memcpy(out_ptr, ctx, ctx_head_size);
out_ptr += ctx_head_size;
for (i = 0; i < ctx->hash_blocks.size && hash_data_left; i++) {
size_t left = (hash_data_left < BT_BLOCK_SIZE_IN_BYTES ? hash_data_left : BT_BLOCK_SIZE_IN_BYTES);
memcpy(out_ptr, ctx->hash_blocks.array[i], left);
out_ptr += left;
hash_data_left -= left;
}
out_ptr += padding_size;
}
exported_size += padding_size;
assert(IS_EXPORT_ALIGNED(exported_size));
for (i = 0; i < ctx->files.size; i++) {
bt_file_info* info = (bt_file_info*)(ctx->files.array[i]);
size_t length = strlen(info->path);
const size_t aligned_length = GET_EXPORT_SIZED_STR_LEN(length);
if (!length)
continue;
exported_size += sizeof(uint64_t) + aligned_length;
if (out_ptr) {
if (size < exported_size)
return 0;
*(uint64_t*)out_ptr = info->size;
out_ptr += sizeof(uint64_t);
bt_export_str(out_ptr, info->path, length);
out_ptr += aligned_length;
}
}
assert(IS_EXPORT_ALIGNED(exported_size));
for (i = 0; i < ctx->announce.size; i++) {
size_t length = strlen(ctx->announce.array[i]);
const size_t aligned_length = GET_EXPORT_SIZED_STR_LEN(length);
if (!length)
continue;
exported_size += aligned_length;
if (out_ptr) {
if (size < exported_size)
return 0;
bt_export_str(out_ptr, ctx->announce.array[i], length);
out_ptr += aligned_length;
}
}
assert(IS_EXPORT_ALIGNED(exported_size));
if (program_name_length > 0) {
const size_t aligned_length = GET_EXPORT_STR_LEN(program_name_length);
exported_size += aligned_length;
if (out_ptr) {
if (size < exported_size)
return 0;
strcpy(out_ptr, ctx->program_name);
out_ptr += aligned_length;
}
assert(IS_EXPORT_ALIGNED(exported_size));
}
if (ctx->content.length > 0) {
const size_t aligned_length = GET_EXPORT_STR_LEN(ctx->content.length);
exported_size += aligned_length;
if (out_ptr) {
if (size < exported_size)
return 0;
assert(ctx->content.str != NULL);
memcpy(out_ptr, ctx->content.str, ctx->content.length + 1);
out_ptr += aligned_length;
}
assert(IS_EXPORT_ALIGNED(exported_size));
}
assert(!out || (size_t)(out_ptr - (char*)out) == exported_size);
#if defined(USE_OPENSSL)
if (out_ptr && ARE_OPENSSL_METHODS(ctx->sha1_methods)) {
size_t* error_ptr = (size_t*)((char*)out + head_size + offsetof(torrent_ctx, error));
*error_ptr |= BT_CTX_OSSL_FLAG;
RHASH_ASSERT(sizeof(*error_ptr) == sizeof(ctx->error));
}
#endif
return exported_size;
}
/**
* Import algorithm context from a memory region.
*
* @param ctx pointer to the algorithm context
* @param in pointer to the data to import
* @param size size of data to import
* @return the size of the imported data on success, 0 on fail.
*/
size_t bt_import(torrent_ctx* ctx, const void* in, size_t size)
{
const size_t head_size = sizeof(bt_export_header);
const size_t ctx_head_size = offsetof(torrent_ctx, hash_blocks);
size_t imported_size = head_size + ctx_head_size;
const char* in_ptr = (const char*)in;
size_t padding_size;
size_t hash_data_left;
size_t length;
size_t i;
const bt_export_header* header = (const bt_export_header*)in_ptr;
if (size < imported_size)
return 0;
if (header->torrent_ctx_size != sizeof(torrent_ctx))
return 0;
in_ptr += sizeof(bt_export_header);
memset(ctx, 0, sizeof(torrent_ctx));
memcpy(ctx, in_ptr, ctx_head_size);
in_ptr += ctx_head_size;
hash_data_left = ctx->piece_count * BT_HASH_SIZE;
imported_size += hash_data_left;
padding_size = GET_EXPORT_PADDING(imported_size);
imported_size += padding_size;
assert(IS_EXPORT_ALIGNED(imported_size));
if (size < imported_size)
return 0;
while (hash_data_left) {
size_t left = (hash_data_left < BT_BLOCK_SIZE_IN_BYTES ? hash_data_left : BT_BLOCK_SIZE_IN_BYTES);
unsigned char* block = (unsigned char*)malloc(BT_BLOCK_SIZE_IN_BYTES);
if (!block)
return 0;
if (!bt_vector_add_ptr(&ctx->hash_blocks, block)) {
free(block);
return 0;
}
memcpy(block, in_ptr, left);
in_ptr += left;
hash_data_left -= left;
}
in_ptr += padding_size;
assert((size_t)(in_ptr - (char*)in) == imported_size);
assert(IS_EXPORT_ALIGNED(imported_size));
for (i = 0; i < header->files_size; i++) {
uint64_t filesize;
imported_size += sizeof(uint64_t);
if (size < (imported_size + sizeof(size_t)))
return 0;
filesize = *(uint64_t*)in_ptr;
in_ptr += sizeof(uint64_t);
length = *(size_t*)in_ptr;
imported_size += GET_EXPORT_SIZED_STR_LEN(length);
if (!length || size < imported_size)
return 0;
if (!bt_add_file(ctx, in_ptr + sizeof(size_t), filesize))
return 0;
in_ptr += GET_EXPORT_SIZED_STR_LEN(length);
}
assert((size_t)(in_ptr - (char*)in) == imported_size);
assert(IS_EXPORT_ALIGNED(imported_size));
for (i = 0; i < header->announce_size; i++) {
if (size < (imported_size + sizeof(size_t)))
return 0;
length = *(size_t*)in_ptr;
imported_size += GET_EXPORT_SIZED_STR_LEN(length);
if (!length || size < imported_size)
return 0;
if (!bt_add_announce(ctx, in_ptr + sizeof(size_t)))
return 0;
in_ptr += GET_EXPORT_SIZED_STR_LEN(length);
}
assert((size_t)(in_ptr - (char*)in) == imported_size);
assert(IS_EXPORT_ALIGNED(imported_size));
length = header->program_name_length;
if (length) {
imported_size += GET_EXPORT_STR_LEN(length);
if (size < imported_size)
return 0;
if (!bt_set_program_name(ctx, in_ptr))
return 0;
in_ptr += GET_EXPORT_STR_LEN(length);
assert((size_t)(in_ptr - (char*)in) == imported_size);
assert(IS_EXPORT_ALIGNED(imported_size));
}
#if defined(USE_OPENSSL)
/* must restore ctx->error flag before calling bt_str_ensure_length() */
if ((ctx->error & BT_CTX_OSSL_FLAG) != 0) {
ctx->error &= ~BT_CTX_OSSL_FLAG;
rhash_load_sha1_methods(&ctx->sha1_methods, METHODS_OPENSSL);
} else {
rhash_load_sha1_methods(&ctx->sha1_methods, METHODS_RHASH);
}
#endif
length = header->content_length;
if (length) {
imported_size += GET_EXPORT_STR_LEN(length);
if (size < imported_size)
return 0;
if (!bt_str_ensure_length(ctx, length))
return 0;
memcpy(ctx->content.str, in_ptr, length);
in_ptr += GET_EXPORT_STR_LEN(length);
assert((size_t)(in_ptr - (char*)in) == imported_size);
assert(IS_EXPORT_ALIGNED(imported_size));
}
return imported_size;
}
#endif /* !defined(NO_IMPORT_EXPORT) */
rhash-1.4.6/librhash/tth.c 0000664 0000000 0000000 00000012154 15010476501 014070 0 ustar root root /* tth.c - calculate TTH (Tiger Tree Hash) function.
*
* Copyright (c) 2007, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "tth.h"
#include "byte_order.h"
#include
#include
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_tth_init(tth_ctx* ctx)
{
rhash_tiger_init(&ctx->tiger);
ctx->tiger.message[ ctx->tiger.length++ ] = 0x00;
ctx->block_count = 0;
}
/**
* The core transformation.
*
* @param ctx algorithm state
*/
static void rhash_tth_process_block(tth_ctx* ctx)
{
uint64_t it;
unsigned pos = 0;
unsigned char msg[24];
for (it = 1; it & ctx->block_count; it <<= 1) {
rhash_tiger_final(&ctx->tiger, msg);
rhash_tiger_init(&ctx->tiger);
ctx->tiger.message[ctx->tiger.length++] = 0x01;
rhash_tiger_update(&ctx->tiger, (unsigned char*)(ctx->stack + pos), 24);
/* note: we can cut this step, if the previous rhash_tiger_final saves directly to ctx->tiger.message+25; */
rhash_tiger_update(&ctx->tiger, msg, 24);
pos += 3;
}
rhash_tiger_final(&ctx->tiger, (unsigned char*)(ctx->stack + pos));
ctx->block_count++;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_tth_update(tth_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t rest = 1025 - (size_t)ctx->tiger.length;
for (;;) {
if (size < rest) rest = size;
rhash_tiger_update(&ctx->tiger, msg, rest);
msg += rest;
size -= rest;
if (ctx->tiger.length < 1025) {
return;
}
/* process block hash */
rhash_tth_process_block(ctx);
/* init block hash */
rhash_tiger_init(&ctx->tiger);
ctx->tiger.message[ ctx->tiger.length++ ] = 0x00;
rest = 1024;
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_tth_final(tth_ctx* ctx, unsigned char result[24])
{
uint64_t it = 1;
unsigned pos = 0;
unsigned char msg[24];
const unsigned char* last_message;
/* process the bytes left in the context buffer */
if (ctx->tiger.length > 1 || ctx->block_count == 0) {
rhash_tth_process_block(ctx);
}
for (; it < ctx->block_count && (it & ctx->block_count) == 0; it <<= 1) pos += 3;
last_message = (unsigned char*)(ctx->stack + pos);
for (it <<= 1; it <= ctx->block_count; it <<= 1) {
/* merge TTH sums in the tree */
pos += 3;
if (it & ctx->block_count) {
rhash_tiger_init(&ctx->tiger);
ctx->tiger.message[ ctx->tiger.length++ ] = 0x01;
rhash_tiger_update(&ctx->tiger, (unsigned char*)(ctx->stack + pos), 24);
rhash_tiger_update(&ctx->tiger, last_message, 24);
rhash_tiger_final(&ctx->tiger, msg);
last_message = msg;
}
}
/* save result hash */
memcpy(ctx->tiger.hash, last_message, tiger_hash_length);
if (result) memcpy(result, last_message, tiger_hash_length);
}
#if !defined(NO_IMPORT_EXPORT)
static size_t tth_get_stack_size(uint64_t block_count)
{
size_t stack_size = 0;
for (; block_count; block_count >>= 1)
stack_size += 24;
return stack_size;
}
/**
* Export tth context to a memory region, or calculate the
* size required for context export.
*
* @param ctx the algorithm context containing current hashing state
* @param out pointer to the memory region or NULL
* @param size size of memory region
* @return the size of the exported data on success, 0 on fail.
*/
size_t rhash_tth_export(const tth_ctx* ctx, void* out, size_t size)
{
size_t export_size = offsetof(tth_ctx, stack) +
tth_get_stack_size(ctx->block_count);
if (out != NULL) {
if (size < export_size)
return 0;
memcpy(out, ctx, export_size);
}
return export_size;
}
/**
* Import tth context from a memory region.
*
* @param ctx pointer to the algorithm context
* @param in pointer to the data to import
* @param size size of data to import
* @return the size of the imported data on success, 0 on fail.
*/
size_t rhash_tth_import(tth_ctx* ctx, const void* in, size_t size)
{
const size_t head_size = offsetof(tth_ctx, stack);
size_t stack_size;
if (size < head_size)
return 0;
memset(ctx, 0, sizeof(tth_ctx));
memcpy(ctx, in, head_size);
stack_size = tth_get_stack_size(ctx->block_count);
if (size < (head_size + stack_size))
return 0;
memcpy(ctx->stack, (const char*)in + head_size, stack_size);
return head_size + stack_size;
}
#endif /* !defined(NO_IMPORT_EXPORT) */
rhash-1.4.6/librhash/tiger_sbox.c 0000664 0000000 0000000 00000066654 14703622112 015453 0 ustar root root /* tiger_sbox.c - S-Box for Tiger hash function
*
* Copyright (c) 2007, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "byte_order.h"
/* Four S-boxes used for table lookups by Tiger hash function. 8Kb in total. */
uint64_t rhash_tiger_sboxes[4][256] = {
{
I64(0x02AAB17CF7E90C5E), I64(0xAC424B03E243A8EC),
I64(0x72CD5BE30DD5FCD3), I64(0x6D019B93F6F97F3A),
I64(0xCD9978FFD21F9193), I64(0x7573A1C9708029E2),
I64(0xB164326B922A83C3), I64(0x46883EEE04915870),
I64(0xEAACE3057103ECE6), I64(0xC54169B808A3535C),
I64(0x4CE754918DDEC47C), I64(0x0AA2F4DFDC0DF40C),
I64(0x10B76F18A74DBEFA), I64(0xC6CCB6235AD1AB6A),
I64(0x13726121572FE2FF), I64(0x1A488C6F199D921E),
I64(0x4BC9F9F4DA0007CA), I64(0x26F5E6F6E85241C7),
I64(0x859079DBEA5947B6), I64(0x4F1885C5C99E8C92),
I64(0xD78E761EA96F864B), I64(0x8E36428C52B5C17D),
I64(0x69CF6827373063C1), I64(0xB607C93D9BB4C56E),
I64(0x7D820E760E76B5EA), I64(0x645C9CC6F07FDC42),
I64(0xBF38A078243342E0), I64(0x5F6B343C9D2E7D04),
I64(0xF2C28AEB600B0EC6), I64(0x6C0ED85F7254BCAC),
I64(0x71592281A4DB4FE5), I64(0x1967FA69CE0FED9F),
I64(0xFD5293F8B96545DB), I64(0xC879E9D7F2A7600B),
I64(0x860248920193194E), I64(0xA4F9533B2D9CC0B3),
I64(0x9053836C15957613), I64(0xDB6DCF8AFC357BF1),
I64(0x18BEEA7A7A370F57), I64(0x037117CA50B99066),
I64(0x6AB30A9774424A35), I64(0xF4E92F02E325249B),
I64(0x7739DB07061CCAE1), I64(0xD8F3B49CECA42A05),
I64(0xBD56BE3F51382F73), I64(0x45FAED5843B0BB28),
I64(0x1C813D5C11BF1F83), I64(0x8AF0E4B6D75FA169),
I64(0x33EE18A487AD9999), I64(0x3C26E8EAB1C94410),
I64(0xB510102BC0A822F9), I64(0x141EEF310CE6123B),
I64(0xFC65B90059DDB154), I64(0xE0158640C5E0E607),
I64(0x884E079826C3A3CF), I64(0x930D0D9523C535FD),
I64(0x35638D754E9A2B00), I64(0x4085FCCF40469DD5),
I64(0xC4B17AD28BE23A4C), I64(0xCAB2F0FC6A3E6A2E),
I64(0x2860971A6B943FCD), I64(0x3DDE6EE212E30446),
I64(0x6222F32AE01765AE), I64(0x5D550BB5478308FE),
I64(0xA9EFA98DA0EDA22A), I64(0xC351A71686C40DA7),
I64(0x1105586D9C867C84), I64(0xDCFFEE85FDA22853),
I64(0xCCFBD0262C5EEF76), I64(0xBAF294CB8990D201),
I64(0xE69464F52AFAD975), I64(0x94B013AFDF133E14),
I64(0x06A7D1A32823C958), I64(0x6F95FE5130F61119),
I64(0xD92AB34E462C06C0), I64(0xED7BDE33887C71D2),
I64(0x79746D6E6518393E), I64(0x5BA419385D713329),
I64(0x7C1BA6B948A97564), I64(0x31987C197BFDAC67),
I64(0xDE6C23C44B053D02), I64(0x581C49FED002D64D),
I64(0xDD474D6338261571), I64(0xAA4546C3E473D062),
I64(0x928FCE349455F860), I64(0x48161BBACAAB94D9),
I64(0x63912430770E6F68), I64(0x6EC8A5E602C6641C),
I64(0x87282515337DDD2B), I64(0x2CDA6B42034B701B),
I64(0xB03D37C181CB096D), I64(0xE108438266C71C6F),
I64(0x2B3180C7EB51B255), I64(0xDF92B82F96C08BBC),
I64(0x5C68C8C0A632F3BA), I64(0x5504CC861C3D0556),
I64(0xABBFA4E55FB26B8F), I64(0x41848B0AB3BACEB4),
I64(0xB334A273AA445D32), I64(0xBCA696F0A85AD881),
I64(0x24F6EC65B528D56C), I64(0x0CE1512E90F4524A),
I64(0x4E9DD79D5506D35A), I64(0x258905FAC6CE9779),
I64(0x2019295B3E109B33), I64(0xF8A9478B73A054CC),
I64(0x2924F2F934417EB0), I64(0x3993357D536D1BC4),
I64(0x38A81AC21DB6FF8B), I64(0x47C4FBF17D6016BF),
I64(0x1E0FAADD7667E3F5), I64(0x7ABCFF62938BEB96),
I64(0xA78DAD948FC179C9), I64(0x8F1F98B72911E50D),
I64(0x61E48EAE27121A91), I64(0x4D62F7AD31859808),
I64(0xECEBA345EF5CEAEB), I64(0xF5CEB25EBC9684CE),
I64(0xF633E20CB7F76221), I64(0xA32CDF06AB8293E4),
I64(0x985A202CA5EE2CA4), I64(0xCF0B8447CC8A8FB1),
I64(0x9F765244979859A3), I64(0xA8D516B1A1240017),
I64(0x0BD7BA3EBB5DC726), I64(0xE54BCA55B86ADB39),
I64(0x1D7A3AFD6C478063), I64(0x519EC608E7669EDD),
I64(0x0E5715A2D149AA23), I64(0x177D4571848FF194),
I64(0xEEB55F3241014C22), I64(0x0F5E5CA13A6E2EC2),
I64(0x8029927B75F5C361), I64(0xAD139FABC3D6E436),
I64(0x0D5DF1A94CCF402F), I64(0x3E8BD948BEA5DFC8),
I64(0xA5A0D357BD3FF77E), I64(0xA2D12E251F74F645),
I64(0x66FD9E525E81A082), I64(0x2E0C90CE7F687A49),
I64(0xC2E8BCBEBA973BC5), I64(0x000001BCE509745F),
I64(0x423777BBE6DAB3D6), I64(0xD1661C7EAEF06EB5),
I64(0xA1781F354DAACFD8), I64(0x2D11284A2B16AFFC),
I64(0xF1FC4F67FA891D1F), I64(0x73ECC25DCB920ADA),
I64(0xAE610C22C2A12651), I64(0x96E0A810D356B78A),
I64(0x5A9A381F2FE7870F), I64(0xD5AD62EDE94E5530),
I64(0xD225E5E8368D1427), I64(0x65977B70C7AF4631),
I64(0x99F889B2DE39D74F), I64(0x233F30BF54E1D143),
I64(0x9A9675D3D9A63C97), I64(0x5470554FF334F9A8),
I64(0x166ACB744A4F5688), I64(0x70C74CAAB2E4AEAD),
I64(0xF0D091646F294D12), I64(0x57B82A89684031D1),
I64(0xEFD95A5A61BE0B6B), I64(0x2FBD12E969F2F29A),
I64(0x9BD37013FEFF9FE8), I64(0x3F9B0404D6085A06),
I64(0x4940C1F3166CFE15), I64(0x09542C4DCDF3DEFB),
I64(0xB4C5218385CD5CE3), I64(0xC935B7DC4462A641),
I64(0x3417F8A68ED3B63F), I64(0xB80959295B215B40),
I64(0xF99CDAEF3B8C8572), I64(0x018C0614F8FCB95D),
I64(0x1B14ACCD1A3ACDF3), I64(0x84D471F200BB732D),
I64(0xC1A3110E95E8DA16), I64(0x430A7220BF1A82B8),
I64(0xB77E090D39DF210E), I64(0x5EF4BD9F3CD05E9D),
I64(0x9D4FF6DA7E57A444), I64(0xDA1D60E183D4A5F8),
I64(0xB287C38417998E47), I64(0xFE3EDC121BB31886),
I64(0xC7FE3CCC980CCBEF), I64(0xE46FB590189BFD03),
I64(0x3732FD469A4C57DC), I64(0x7EF700A07CF1AD65),
I64(0x59C64468A31D8859), I64(0x762FB0B4D45B61F6),
I64(0x155BAED099047718), I64(0x68755E4C3D50BAA6),
I64(0xE9214E7F22D8B4DF), I64(0x2ADDBF532EAC95F4),
I64(0x32AE3909B4BD0109), I64(0x834DF537B08E3450),
I64(0xFA209DA84220728D), I64(0x9E691D9B9EFE23F7),
I64(0x0446D288C4AE8D7F), I64(0x7B4CC524E169785B),
I64(0x21D87F0135CA1385), I64(0xCEBB400F137B8AA5),
I64(0x272E2B66580796BE), I64(0x3612264125C2B0DE),
I64(0x057702BDAD1EFBB2), I64(0xD4BABB8EACF84BE9),
I64(0x91583139641BC67B), I64(0x8BDC2DE08036E024),
I64(0x603C8156F49F68ED), I64(0xF7D236F7DBEF5111),
I64(0x9727C4598AD21E80), I64(0xA08A0896670A5FD7),
I64(0xCB4A8F4309EBA9CB), I64(0x81AF564B0F7036A1),
I64(0xC0B99AA778199ABD), I64(0x959F1EC83FC8E952),
I64(0x8C505077794A81B9), I64(0x3ACAAF8F056338F0),
I64(0x07B43F50627A6778), I64(0x4A44AB49F5ECCC77),
I64(0x3BC3D6E4B679EE98), I64(0x9CC0D4D1CF14108C),
I64(0x4406C00B206BC8A0), I64(0x82A18854C8D72D89),
I64(0x67E366B35C3C432C), I64(0xB923DD61102B37F2),
I64(0x56AB2779D884271D), I64(0xBE83E1B0FF1525AF),
I64(0xFB7C65D4217E49A9), I64(0x6BDBE0E76D48E7D4),
I64(0x08DF828745D9179E), I64(0x22EA6A9ADD53BD34),
I64(0xE36E141C5622200A), I64(0x7F805D1B8CB750EE),
I64(0xAFE5C7A59F58E837), I64(0xE27F996A4FB1C23C),
I64(0xD3867DFB0775F0D0), I64(0xD0E673DE6E88891A),
I64(0x123AEB9EAFB86C25), I64(0x30F1D5D5C145B895),
I64(0xBB434A2DEE7269E7), I64(0x78CB67ECF931FA38),
I64(0xF33B0372323BBF9C), I64(0x52D66336FB279C74),
I64(0x505F33AC0AFB4EAA), I64(0xE8A5CD99A2CCE187),
I64(0x534974801E2D30BB), I64(0x8D2D5711D5876D90),
I64(0x1F1A412891BC038E), I64(0xD6E2E71D82E56648),
I64(0x74036C3A497732B7), I64(0x89B67ED96361F5AB),
I64(0xFFED95D8F1EA02A2), I64(0xE72B3BD61464D43D),
I64(0xA6300F170BDC4820), I64(0xEBC18760ED78A77A)
}, {
I64(0xE6A6BE5A05A12138), I64(0xB5A122A5B4F87C98),
I64(0x563C6089140B6990), I64(0x4C46CB2E391F5DD5),
I64(0xD932ADDBC9B79434), I64(0x08EA70E42015AFF5),
I64(0xD765A6673E478CF1), I64(0xC4FB757EAB278D99),
I64(0xDF11C6862D6E0692), I64(0xDDEB84F10D7F3B16),
I64(0x6F2EF604A665EA04), I64(0x4A8E0F0FF0E0DFB3),
I64(0xA5EDEEF83DBCBA51), I64(0xFC4F0A2A0EA4371E),
I64(0xE83E1DA85CB38429), I64(0xDC8FF882BA1B1CE2),
I64(0xCD45505E8353E80D), I64(0x18D19A00D4DB0717),
I64(0x34A0CFEDA5F38101), I64(0x0BE77E518887CAF2),
I64(0x1E341438B3C45136), I64(0xE05797F49089CCF9),
I64(0xFFD23F9DF2591D14), I64(0x543DDA228595C5CD),
I64(0x661F81FD99052A33), I64(0x8736E641DB0F7B76),
I64(0x15227725418E5307), I64(0xE25F7F46162EB2FA),
I64(0x48A8B2126C13D9FE), I64(0xAFDC541792E76EEA),
I64(0x03D912BFC6D1898F), I64(0x31B1AAFA1B83F51B),
I64(0xF1AC2796E42AB7D9), I64(0x40A3A7D7FCD2EBAC),
I64(0x1056136D0AFBBCC5), I64(0x7889E1DD9A6D0C85),
I64(0xD33525782A7974AA), I64(0xA7E25D09078AC09B),
I64(0xBD4138B3EAC6EDD0), I64(0x920ABFBE71EB9E70),
I64(0xA2A5D0F54FC2625C), I64(0xC054E36B0B1290A3),
I64(0xF6DD59FF62FE932B), I64(0x3537354511A8AC7D),
I64(0xCA845E9172FADCD4), I64(0x84F82B60329D20DC),
I64(0x79C62CE1CD672F18), I64(0x8B09A2ADD124642C),
I64(0xD0C1E96A19D9E726), I64(0x5A786A9B4BA9500C),
I64(0x0E020336634C43F3), I64(0xC17B474AEB66D822),
I64(0x6A731AE3EC9BAAC2), I64(0x8226667AE0840258),
I64(0x67D4567691CAECA5), I64(0x1D94155C4875ADB5),
I64(0x6D00FD985B813FDF), I64(0x51286EFCB774CD06),
I64(0x5E8834471FA744AF), I64(0xF72CA0AEE761AE2E),
I64(0xBE40E4CDAEE8E09A), I64(0xE9970BBB5118F665),
I64(0x726E4BEB33DF1964), I64(0x703B000729199762),
I64(0x4631D816F5EF30A7), I64(0xB880B5B51504A6BE),
I64(0x641793C37ED84B6C), I64(0x7B21ED77F6E97D96),
I64(0x776306312EF96B73), I64(0xAE528948E86FF3F4),
I64(0x53DBD7F286A3F8F8), I64(0x16CADCE74CFC1063),
I64(0x005C19BDFA52C6DD), I64(0x68868F5D64D46AD3),
I64(0x3A9D512CCF1E186A), I64(0x367E62C2385660AE),
I64(0xE359E7EA77DCB1D7), I64(0x526C0773749ABE6E),
I64(0x735AE5F9D09F734B), I64(0x493FC7CC8A558BA8),
I64(0xB0B9C1533041AB45), I64(0x321958BA470A59BD),
I64(0x852DB00B5F46C393), I64(0x91209B2BD336B0E5),
I64(0x6E604F7D659EF19F), I64(0xB99A8AE2782CCB24),
I64(0xCCF52AB6C814C4C7), I64(0x4727D9AFBE11727B),
I64(0x7E950D0C0121B34D), I64(0x756F435670AD471F),
I64(0xF5ADD442615A6849), I64(0x4E87E09980B9957A),
I64(0x2ACFA1DF50AEE355), I64(0xD898263AFD2FD556),
I64(0xC8F4924DD80C8FD6), I64(0xCF99CA3D754A173A),
I64(0xFE477BACAF91BF3C), I64(0xED5371F6D690C12D),
I64(0x831A5C285E687094), I64(0xC5D3C90A3708A0A4),
I64(0x0F7F903717D06580), I64(0x19F9BB13B8FDF27F),
I64(0xB1BD6F1B4D502843), I64(0x1C761BA38FFF4012),
I64(0x0D1530C4E2E21F3B), I64(0x8943CE69A7372C8A),
I64(0xE5184E11FEB5CE66), I64(0x618BDB80BD736621),
I64(0x7D29BAD68B574D0B), I64(0x81BB613E25E6FE5B),
I64(0x071C9C10BC07913F), I64(0xC7BEEB7909AC2D97),
I64(0xC3E58D353BC5D757), I64(0xEB017892F38F61E8),
I64(0xD4EFFB9C9B1CC21A), I64(0x99727D26F494F7AB),
I64(0xA3E063A2956B3E03), I64(0x9D4A8B9A4AA09C30),
I64(0x3F6AB7D500090FB4), I64(0x9CC0F2A057268AC0),
I64(0x3DEE9D2DEDBF42D1), I64(0x330F49C87960A972),
I64(0xC6B2720287421B41), I64(0x0AC59EC07C00369C),
I64(0xEF4EAC49CB353425), I64(0xF450244EEF0129D8),
I64(0x8ACC46E5CAF4DEB6), I64(0x2FFEAB63989263F7),
I64(0x8F7CB9FE5D7A4578), I64(0x5BD8F7644E634635),
I64(0x427A7315BF2DC900), I64(0x17D0C4AA2125261C),
I64(0x3992486C93518E50), I64(0xB4CBFEE0A2D7D4C3),
I64(0x7C75D6202C5DDD8D), I64(0xDBC295D8E35B6C61),
I64(0x60B369D302032B19), I64(0xCE42685FDCE44132),
I64(0x06F3DDB9DDF65610), I64(0x8EA4D21DB5E148F0),
I64(0x20B0FCE62FCD496F), I64(0x2C1B912358B0EE31),
I64(0xB28317B818F5A308), I64(0xA89C1E189CA6D2CF),
I64(0x0C6B18576AAADBC8), I64(0xB65DEAA91299FAE3),
I64(0xFB2B794B7F1027E7), I64(0x04E4317F443B5BEB),
I64(0x4B852D325939D0A6), I64(0xD5AE6BEEFB207FFC),
I64(0x309682B281C7D374), I64(0xBAE309A194C3B475),
I64(0x8CC3F97B13B49F05), I64(0x98A9422FF8293967),
I64(0x244B16B01076FF7C), I64(0xF8BF571C663D67EE),
I64(0x1F0D6758EEE30DA1), I64(0xC9B611D97ADEB9B7),
I64(0xB7AFD5887B6C57A2), I64(0x6290AE846B984FE1),
I64(0x94DF4CDEACC1A5FD), I64(0x058A5BD1C5483AFF),
I64(0x63166CC142BA3C37), I64(0x8DB8526EB2F76F40),
I64(0xE10880036F0D6D4E), I64(0x9E0523C9971D311D),
I64(0x45EC2824CC7CD691), I64(0x575B8359E62382C9),
I64(0xFA9E400DC4889995), I64(0xD1823ECB45721568),
I64(0xDAFD983B8206082F), I64(0xAA7D29082386A8CB),
I64(0x269FCD4403B87588), I64(0x1B91F5F728BDD1E0),
I64(0xE4669F39040201F6), I64(0x7A1D7C218CF04ADE),
I64(0x65623C29D79CE5CE), I64(0x2368449096C00BB1),
I64(0xAB9BF1879DA503BA), I64(0xBC23ECB1A458058E),
I64(0x9A58DF01BB401ECC), I64(0xA070E868A85F143D),
I64(0x4FF188307DF2239E), I64(0x14D565B41A641183),
I64(0xEE13337452701602), I64(0x950E3DCF3F285E09),
I64(0x59930254B9C80953), I64(0x3BF299408930DA6D),
I64(0xA955943F53691387), I64(0xA15EDECAA9CB8784),
I64(0x29142127352BE9A0), I64(0x76F0371FFF4E7AFB),
I64(0x0239F450274F2228), I64(0xBB073AF01D5E868B),
I64(0xBFC80571C10E96C1), I64(0xD267088568222E23),
I64(0x9671A3D48E80B5B0), I64(0x55B5D38AE193BB81),
I64(0x693AE2D0A18B04B8), I64(0x5C48B4ECADD5335F),
I64(0xFD743B194916A1CA), I64(0x2577018134BE98C4),
I64(0xE77987E83C54A4AD), I64(0x28E11014DA33E1B9),
I64(0x270CC59E226AA213), I64(0x71495F756D1A5F60),
I64(0x9BE853FB60AFEF77), I64(0xADC786A7F7443DBF),
I64(0x0904456173B29A82), I64(0x58BC7A66C232BD5E),
I64(0xF306558C673AC8B2), I64(0x41F639C6B6C9772A),
I64(0x216DEFE99FDA35DA), I64(0x11640CC71C7BE615),
I64(0x93C43694565C5527), I64(0xEA038E6246777839),
I64(0xF9ABF3CE5A3E2469), I64(0x741E768D0FD312D2),
I64(0x0144B883CED652C6), I64(0xC20B5A5BA33F8552),
I64(0x1AE69633C3435A9D), I64(0x97A28CA4088CFDEC),
I64(0x8824A43C1E96F420), I64(0x37612FA66EEEA746),
I64(0x6B4CB165F9CF0E5A), I64(0x43AA1C06A0ABFB4A),
I64(0x7F4DC26FF162796B), I64(0x6CBACC8E54ED9B0F),
I64(0xA6B7FFEFD2BB253E), I64(0x2E25BC95B0A29D4F),
I64(0x86D6A58BDEF1388C), I64(0xDED74AC576B6F054),
I64(0x8030BDBC2B45805D), I64(0x3C81AF70E94D9289),
I64(0x3EFF6DDA9E3100DB), I64(0xB38DC39FDFCC8847),
I64(0x123885528D17B87E), I64(0xF2DA0ED240B1B642),
I64(0x44CEFADCD54BF9A9), I64(0x1312200E433C7EE6),
I64(0x9FFCC84F3A78C748), I64(0xF0CD1F72248576BB),
I64(0xEC6974053638CFE4), I64(0x2BA7B67C0CEC4E4C),
I64(0xAC2F4DF3E5CE32ED), I64(0xCB33D14326EA4C11),
I64(0xA4E9044CC77E58BC), I64(0x5F513293D934FCEF),
I64(0x5DC9645506E55444), I64(0x50DE418F317DE40A),
I64(0x388CB31A69DDE259), I64(0x2DB4A83455820A86),
I64(0x9010A91E84711AE9), I64(0x4DF7F0B7B1498371),
I64(0xD62A2EABC0977179), I64(0x22FAC097AA8D5C0E)
}, {
I64(0xF49FCC2FF1DAF39B), I64(0x487FD5C66FF29281),
I64(0xE8A30667FCDCA83F), I64(0x2C9B4BE3D2FCCE63),
I64(0xDA3FF74B93FBBBC2), I64(0x2FA165D2FE70BA66),
I64(0xA103E279970E93D4), I64(0xBECDEC77B0E45E71),
I64(0xCFB41E723985E497), I64(0xB70AAA025EF75017),
I64(0xD42309F03840B8E0), I64(0x8EFC1AD035898579),
I64(0x96C6920BE2B2ABC5), I64(0x66AF4163375A9172),
I64(0x2174ABDCCA7127FB), I64(0xB33CCEA64A72FF41),
I64(0xF04A4933083066A5), I64(0x8D970ACDD7289AF5),
I64(0x8F96E8E031C8C25E), I64(0xF3FEC02276875D47),
I64(0xEC7BF310056190DD), I64(0xF5ADB0AEBB0F1491),
I64(0x9B50F8850FD58892), I64(0x4975488358B74DE8),
I64(0xA3354FF691531C61), I64(0x0702BBE481D2C6EE),
I64(0x89FB24057DEDED98), I64(0xAC3075138596E902),
I64(0x1D2D3580172772ED), I64(0xEB738FC28E6BC30D),
I64(0x5854EF8F63044326), I64(0x9E5C52325ADD3BBE),
I64(0x90AA53CF325C4623), I64(0xC1D24D51349DD067),
I64(0x2051CFEEA69EA624), I64(0x13220F0A862E7E4F),
I64(0xCE39399404E04864), I64(0xD9C42CA47086FCB7),
I64(0x685AD2238A03E7CC), I64(0x066484B2AB2FF1DB),
I64(0xFE9D5D70EFBF79EC), I64(0x5B13B9DD9C481854),
I64(0x15F0D475ED1509AD), I64(0x0BEBCD060EC79851),
I64(0xD58C6791183AB7F8), I64(0xD1187C5052F3EEE4),
I64(0xC95D1192E54E82FF), I64(0x86EEA14CB9AC6CA2),
I64(0x3485BEB153677D5D), I64(0xDD191D781F8C492A),
I64(0xF60866BAA784EBF9), I64(0x518F643BA2D08C74),
I64(0x8852E956E1087C22), I64(0xA768CB8DC410AE8D),
I64(0x38047726BFEC8E1A), I64(0xA67738B4CD3B45AA),
I64(0xAD16691CEC0DDE19), I64(0xC6D4319380462E07),
I64(0xC5A5876D0BA61938), I64(0x16B9FA1FA58FD840),
I64(0x188AB1173CA74F18), I64(0xABDA2F98C99C021F),
I64(0x3E0580AB134AE816), I64(0x5F3B05B773645ABB),
I64(0x2501A2BE5575F2F6), I64(0x1B2F74004E7E8BA9),
I64(0x1CD7580371E8D953), I64(0x7F6ED89562764E30),
I64(0xB15926FF596F003D), I64(0x9F65293DA8C5D6B9),
I64(0x6ECEF04DD690F84C), I64(0x4782275FFF33AF88),
I64(0xE41433083F820801), I64(0xFD0DFE409A1AF9B5),
I64(0x4325A3342CDB396B), I64(0x8AE77E62B301B252),
I64(0xC36F9E9F6655615A), I64(0x85455A2D92D32C09),
I64(0xF2C7DEA949477485), I64(0x63CFB4C133A39EBA),
I64(0x83B040CC6EBC5462), I64(0x3B9454C8FDB326B0),
I64(0x56F56A9E87FFD78C), I64(0x2DC2940D99F42BC6),
I64(0x98F7DF096B096E2D), I64(0x19A6E01E3AD852BF),
I64(0x42A99CCBDBD4B40B), I64(0xA59998AF45E9C559),
I64(0x366295E807D93186), I64(0x6B48181BFAA1F773),
I64(0x1FEC57E2157A0A1D), I64(0x4667446AF6201AD5),
I64(0xE615EBCACFB0F075), I64(0xB8F31F4F68290778),
I64(0x22713ED6CE22D11E), I64(0x3057C1A72EC3C93B),
I64(0xCB46ACC37C3F1F2F), I64(0xDBB893FD02AAF50E),
I64(0x331FD92E600B9FCF), I64(0xA498F96148EA3AD6),
I64(0xA8D8426E8B6A83EA), I64(0xA089B274B7735CDC),
I64(0x87F6B3731E524A11), I64(0x118808E5CBC96749),
I64(0x9906E4C7B19BD394), I64(0xAFED7F7E9B24A20C),
I64(0x6509EADEEB3644A7), I64(0x6C1EF1D3E8EF0EDE),
I64(0xB9C97D43E9798FB4), I64(0xA2F2D784740C28A3),
I64(0x7B8496476197566F), I64(0x7A5BE3E6B65F069D),
I64(0xF96330ED78BE6F10), I64(0xEEE60DE77A076A15),
I64(0x2B4BEE4AA08B9BD0), I64(0x6A56A63EC7B8894E),
I64(0x02121359BA34FEF4), I64(0x4CBF99F8283703FC),
I64(0x398071350CAF30C8), I64(0xD0A77A89F017687A),
I64(0xF1C1A9EB9E423569), I64(0x8C7976282DEE8199),
I64(0x5D1737A5DD1F7ABD), I64(0x4F53433C09A9FA80),
I64(0xFA8B0C53DF7CA1D9), I64(0x3FD9DCBC886CCB77),
I64(0xC040917CA91B4720), I64(0x7DD00142F9D1DCDF),
I64(0x8476FC1D4F387B58), I64(0x23F8E7C5F3316503),
I64(0x032A2244E7E37339), I64(0x5C87A5D750F5A74B),
I64(0x082B4CC43698992E), I64(0xDF917BECB858F63C),
I64(0x3270B8FC5BF86DDA), I64(0x10AE72BB29B5DD76),
I64(0x576AC94E7700362B), I64(0x1AD112DAC61EFB8F),
I64(0x691BC30EC5FAA427), I64(0xFF246311CC327143),
I64(0x3142368E30E53206), I64(0x71380E31E02CA396),
I64(0x958D5C960AAD76F1), I64(0xF8D6F430C16DA536),
I64(0xC8FFD13F1BE7E1D2), I64(0x7578AE66004DDBE1),
I64(0x05833F01067BE646), I64(0xBB34B5AD3BFE586D),
I64(0x095F34C9A12B97F0), I64(0x247AB64525D60CA8),
I64(0xDCDBC6F3017477D1), I64(0x4A2E14D4DECAD24D),
I64(0xBDB5E6D9BE0A1EEB), I64(0x2A7E70F7794301AB),
I64(0xDEF42D8A270540FD), I64(0x01078EC0A34C22C1),
I64(0xE5DE511AF4C16387), I64(0x7EBB3A52BD9A330A),
I64(0x77697857AA7D6435), I64(0x004E831603AE4C32),
I64(0xE7A21020AD78E312), I64(0x9D41A70C6AB420F2),
I64(0x28E06C18EA1141E6), I64(0xD2B28CBD984F6B28),
I64(0x26B75F6C446E9D83), I64(0xBA47568C4D418D7F),
I64(0xD80BADBFE6183D8E), I64(0x0E206D7F5F166044),
I64(0xE258A43911CBCA3E), I64(0x723A1746B21DC0BC),
I64(0xC7CAA854F5D7CDD3), I64(0x7CAC32883D261D9C),
I64(0x7690C26423BA942C), I64(0x17E55524478042B8),
I64(0xE0BE477656A2389F), I64(0x4D289B5E67AB2DA0),
I64(0x44862B9C8FBBFD31), I64(0xB47CC8049D141365),
I64(0x822C1B362B91C793), I64(0x4EB14655FB13DFD8),
I64(0x1ECBBA0714E2A97B), I64(0x6143459D5CDE5F14),
I64(0x53A8FBF1D5F0AC89), I64(0x97EA04D81C5E5B00),
I64(0x622181A8D4FDB3F3), I64(0xE9BCD341572A1208),
I64(0x1411258643CCE58A), I64(0x9144C5FEA4C6E0A4),
I64(0x0D33D06565CF620F), I64(0x54A48D489F219CA1),
I64(0xC43E5EAC6D63C821), I64(0xA9728B3A72770DAF),
I64(0xD7934E7B20DF87EF), I64(0xE35503B61A3E86E5),
I64(0xCAE321FBC819D504), I64(0x129A50B3AC60BFA6),
I64(0xCD5E68EA7E9FB6C3), I64(0xB01C90199483B1C7),
I64(0x3DE93CD5C295376C), I64(0xAED52EDF2AB9AD13),
I64(0x2E60F512C0A07884), I64(0xBC3D86A3E36210C9),
I64(0x35269D9B163951CE), I64(0x0C7D6E2AD0CDB5FA),
I64(0x59E86297D87F5733), I64(0x298EF221898DB0E7),
I64(0x55000029D1A5AA7E), I64(0x8BC08AE1B5061B45),
I64(0xC2C31C2B6C92703A), I64(0x94CC596BAF25EF42),
I64(0x0A1D73DB22540456), I64(0x04B6A0F9D9C4179A),
I64(0xEFFDAFA2AE3D3C60), I64(0xF7C8075BB49496C4),
I64(0x9CC5C7141D1CD4E3), I64(0x78BD1638218E5534),
I64(0xB2F11568F850246A), I64(0xEDFABCFA9502BC29),
I64(0x796CE5F2DA23051B), I64(0xAAE128B0DC93537C),
I64(0x3A493DA0EE4B29AE), I64(0xB5DF6B2C416895D7),
I64(0xFCABBD25122D7F37), I64(0x70810B58105DC4B1),
I64(0xE10FDD37F7882A90), I64(0x524DCAB5518A3F5C),
I64(0x3C9E85878451255B), I64(0x4029828119BD34E2),
I64(0x74A05B6F5D3CECCB), I64(0xB610021542E13ECA),
I64(0x0FF979D12F59E2AC), I64(0x6037DA27E4F9CC50),
I64(0x5E92975A0DF1847D), I64(0xD66DE190D3E623FE),
I64(0x5032D6B87B568048), I64(0x9A36B7CE8235216E),
I64(0x80272A7A24F64B4A), I64(0x93EFED8B8C6916F7),
I64(0x37DDBFF44CCE1555), I64(0x4B95DB5D4B99BD25),
I64(0x92D3FDA169812FC0), I64(0xFB1A4A9A90660BB6),
I64(0x730C196946A4B9B2), I64(0x81E289AA7F49DA68),
I64(0x64669A0F83B1A05F), I64(0x27B3FF7D9644F48B),
I64(0xCC6B615C8DB675B3), I64(0x674F20B9BCEBBE95),
I64(0x6F31238275655982), I64(0x5AE488713E45CF05),
I64(0xBF619F9954C21157), I64(0xEABAC46040A8EAE9),
I64(0x454C6FE9F2C0C1CD), I64(0x419CF6496412691C),
I64(0xD3DC3BEF265B0F70), I64(0x6D0E60F5C3578A9E)
}, {
I64(0x5B0E608526323C55), I64(0x1A46C1A9FA1B59F5),
I64(0xA9E245A17C4C8FFA), I64(0x65CA5159DB2955D7),
I64(0x05DB0A76CE35AFC2), I64(0x81EAC77EA9113D45),
I64(0x528EF88AB6AC0A0D), I64(0xA09EA253597BE3FF),
I64(0x430DDFB3AC48CD56), I64(0xC4B3A67AF45CE46F),
I64(0x4ECECFD8FBE2D05E), I64(0x3EF56F10B39935F0),
I64(0x0B22D6829CD619C6), I64(0x17FD460A74DF2069),
I64(0x6CF8CC8E8510ED40), I64(0xD6C824BF3A6ECAA7),
I64(0x61243D581A817049), I64(0x048BACB6BBC163A2),
I64(0xD9A38AC27D44CC32), I64(0x7FDDFF5BAAF410AB),
I64(0xAD6D495AA804824B), I64(0xE1A6A74F2D8C9F94),
I64(0xD4F7851235DEE8E3), I64(0xFD4B7F886540D893),
I64(0x247C20042AA4BFDA), I64(0x096EA1C517D1327C),
I64(0xD56966B4361A6685), I64(0x277DA5C31221057D),
I64(0x94D59893A43ACFF7), I64(0x64F0C51CCDC02281),
I64(0x3D33BCC4FF6189DB), I64(0xE005CB184CE66AF1),
I64(0xFF5CCD1D1DB99BEA), I64(0xB0B854A7FE42980F),
I64(0x7BD46A6A718D4B9F), I64(0xD10FA8CC22A5FD8C),
I64(0xD31484952BE4BD31), I64(0xC7FA975FCB243847),
I64(0x4886ED1E5846C407), I64(0x28CDDB791EB70B04),
I64(0xC2B00BE2F573417F), I64(0x5C9590452180F877),
I64(0x7A6BDDFFF370EB00), I64(0xCE509E38D6D9D6A4),
I64(0xEBEB0F00647FA702), I64(0x1DCC06CF76606F06),
I64(0xE4D9F28BA286FF0A), I64(0xD85A305DC918C262),
I64(0x475B1D8732225F54), I64(0x2D4FB51668CCB5FE),
I64(0xA679B9D9D72BBA20), I64(0x53841C0D912D43A5),
I64(0x3B7EAA48BF12A4E8), I64(0x781E0E47F22F1DDF),
I64(0xEFF20CE60AB50973), I64(0x20D261D19DFFB742),
I64(0x16A12B03062A2E39), I64(0x1960EB2239650495),
I64(0x251C16FED50EB8B8), I64(0x9AC0C330F826016E),
I64(0xED152665953E7671), I64(0x02D63194A6369570),
I64(0x5074F08394B1C987), I64(0x70BA598C90B25CE1),
I64(0x794A15810B9742F6), I64(0x0D5925E9FCAF8C6C),
I64(0x3067716CD868744E), I64(0x910AB077E8D7731B),
I64(0x6A61BBDB5AC42F61), I64(0x93513EFBF0851567),
I64(0xF494724B9E83E9D5), I64(0xE887E1985C09648D),
I64(0x34B1D3C675370CFD), I64(0xDC35E433BC0D255D),
I64(0xD0AAB84234131BE0), I64(0x08042A50B48B7EAF),
I64(0x9997C4EE44A3AB35), I64(0x829A7B49201799D0),
I64(0x263B8307B7C54441), I64(0x752F95F4FD6A6CA6),
I64(0x927217402C08C6E5), I64(0x2A8AB754A795D9EE),
I64(0xA442F7552F72943D), I64(0x2C31334E19781208),
I64(0x4FA98D7CEAEE6291), I64(0x55C3862F665DB309),
I64(0xBD0610175D53B1F3), I64(0x46FE6CB840413F27),
I64(0x3FE03792DF0CFA59), I64(0xCFE700372EB85E8F),
I64(0xA7BE29E7ADBCE118), I64(0xE544EE5CDE8431DD),
I64(0x8A781B1B41F1873E), I64(0xA5C94C78A0D2F0E7),
I64(0x39412E2877B60728), I64(0xA1265EF3AFC9A62C),
I64(0xBCC2770C6A2506C5), I64(0x3AB66DD5DCE1CE12),
I64(0xE65499D04A675B37), I64(0x7D8F523481BFD216),
I64(0x0F6F64FCEC15F389), I64(0x74EFBE618B5B13C8),
I64(0xACDC82B714273E1D), I64(0xDD40BFE003199D17),
I64(0x37E99257E7E061F8), I64(0xFA52626904775AAA),
I64(0x8BBBF63A463D56F9), I64(0xF0013F1543A26E64),
I64(0xA8307E9F879EC898), I64(0xCC4C27A4150177CC),
I64(0x1B432F2CCA1D3348), I64(0xDE1D1F8F9F6FA013),
I64(0x606602A047A7DDD6), I64(0xD237AB64CC1CB2C7),
I64(0x9B938E7225FCD1D3), I64(0xEC4E03708E0FF476),
I64(0xFEB2FBDA3D03C12D), I64(0xAE0BCED2EE43889A),
I64(0x22CB8923EBFB4F43), I64(0x69360D013CF7396D),
I64(0x855E3602D2D4E022), I64(0x073805BAD01F784C),
I64(0x33E17A133852F546), I64(0xDF4874058AC7B638),
I64(0xBA92B29C678AA14A), I64(0x0CE89FC76CFAADCD),
I64(0x5F9D4E0908339E34), I64(0xF1AFE9291F5923B9),
I64(0x6E3480F60F4A265F), I64(0xEEBF3A2AB29B841C),
I64(0xE21938A88F91B4AD), I64(0x57DFEFF845C6D3C3),
I64(0x2F006B0BF62CAAF2), I64(0x62F479EF6F75EE78),
I64(0x11A55AD41C8916A9), I64(0xF229D29084FED453),
I64(0x42F1C27B16B000E6), I64(0x2B1F76749823C074),
I64(0x4B76ECA3C2745360), I64(0x8C98F463B91691BD),
I64(0x14BCC93CF1ADE66A), I64(0x8885213E6D458397),
I64(0x8E177DF0274D4711), I64(0xB49B73B5503F2951),
I64(0x10168168C3F96B6B), I64(0x0E3D963B63CAB0AE),
I64(0x8DFC4B5655A1DB14), I64(0xF789F1356E14DE5C),
I64(0x683E68AF4E51DAC1), I64(0xC9A84F9D8D4B0FD9),
I64(0x3691E03F52A0F9D1), I64(0x5ED86E46E1878E80),
I64(0x3C711A0E99D07150), I64(0x5A0865B20C4E9310),
I64(0x56FBFC1FE4F0682E), I64(0xEA8D5DE3105EDF9B),
I64(0x71ABFDB12379187A), I64(0x2EB99DE1BEE77B9C),
I64(0x21ECC0EA33CF4523), I64(0x59A4D7521805C7A1),
I64(0x3896F5EB56AE7C72), I64(0xAA638F3DB18F75DC),
I64(0x9F39358DABE9808E), I64(0xB7DEFA91C00B72AC),
I64(0x6B5541FD62492D92), I64(0x6DC6DEE8F92E4D5B),
I64(0x353F57ABC4BEEA7E), I64(0x735769D6DA5690CE),
I64(0x0A234AA642391484), I64(0xF6F9508028F80D9D),
I64(0xB8E319A27AB3F215), I64(0x31AD9C1151341A4D),
I64(0x773C22A57BEF5805), I64(0x45C7561A07968633),
I64(0xF913DA9E249DBE36), I64(0xDA652D9B78A64C68),
I64(0x4C27A97F3BC334EF), I64(0x76621220E66B17F4),
I64(0x967743899ACD7D0B), I64(0xF3EE5BCAE0ED6782),
I64(0x409F753600C879FC), I64(0x06D09A39B5926DB6),
I64(0x6F83AEB0317AC588), I64(0x01E6CA4A86381F21),
I64(0x66FF3462D19F3025), I64(0x72207C24DDFD3BFB),
I64(0x4AF6B6D3E2ECE2EB), I64(0x9C994DBEC7EA08DE),
I64(0x49ACE597B09A8BC4), I64(0xB38C4766CF0797BA),
I64(0x131B9373C57C2A75), I64(0xB1822CCE61931E58),
I64(0x9D7555B909BA1C0C), I64(0x127FAFDD937D11D2),
I64(0x29DA3BADC66D92E4), I64(0xA2C1D57154C2ECBC),
I64(0x58C5134D82F6FE24), I64(0x1C3AE3515B62274F),
I64(0xE907C82E01CB8126), I64(0xF8ED091913E37FCB),
I64(0x3249D8F9C80046C9), I64(0x80CF9BEDE388FB63),
I64(0x1881539A116CF19E), I64(0x5103F3F76BD52457),
I64(0x15B7E6F5AE47F7A8), I64(0xDBD7C6DED47E9CCF),
I64(0x44E55C410228BB1A), I64(0xB647D4255EDB4E99),
I64(0x5D11882BB8AAFC30), I64(0xF5098BBB29D3212A),
I64(0x8FB5EA14E90296B3), I64(0x677B942157DD025A),
I64(0xFB58E7C0A390ACB5), I64(0x89D3674C83BD4A01),
I64(0x9E2DA4DF4BF3B93B), I64(0xFCC41E328CAB4829),
I64(0x03F38C96BA582C52), I64(0xCAD1BDBD7FD85DB2),
I64(0xBBB442C16082AE83), I64(0xB95FE86BA5DA9AB0),
I64(0xB22E04673771A93F), I64(0x845358C9493152D8),
I64(0xBE2A488697B4541E), I64(0x95A2DC2DD38E6966),
I64(0xC02C11AC923C852B), I64(0x2388B1990DF2A87B),
I64(0x7C8008FA1B4F37BE), I64(0x1F70D0C84D54E503),
I64(0x5490ADEC7ECE57D4), I64(0x002B3C27D9063A3A),
I64(0x7EAEA3848030A2BF), I64(0xC602326DED2003C0),
I64(0x83A7287D69A94086), I64(0xC57A5FCB30F57A8A),
I64(0xB56844E479EBE779), I64(0xA373B40F05DCBCE9),
I64(0xD71A786E88570EE2), I64(0x879CBACDBDE8F6A0),
I64(0x976AD1BCC164A32F), I64(0xAB21E25E9666D78B),
I64(0x901063AAE5E5C33C), I64(0x9818B34448698D90),
I64(0xE36487AE3E1E8ABB), I64(0xAFBDF931893BDCB4),
I64(0x6345A0DC5FBBD519), I64(0x8628FE269B9465CA),
I64(0x1E5D01603F9C51EC), I64(0x4DE44006A15049B7),
I64(0xBF6C70E5F776CBB1), I64(0x411218F2EF552BED),
I64(0xCB0C0708705A36A3), I64(0xE74D14754F986044),
I64(0xCD56D9430EA8280E), I64(0xC12591D7535F5065),
I64(0xC83223F1720AEF96), I64(0xC3A0396F7363A51F)
}
};
rhash-1.4.6/librhash/gost94.c 0000664 0000000 0000000 00000116153 14703622112 014425 0 ustar root root /* gost94.c - an implementation of the GOST R 34.11-94 hash function,
* the deprecated Russian cryptographic standard.
* See also RFC 4357.
*
* Copyright (c) 2009, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "gost94.h"
#include
#include "byte_order.h"
#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__clang__) && !defined(RHASH_NO_ASM)
# define USE_GCC_ASM_IA32
#elif defined(__GNUC__) && defined(CPU_X64) && !defined(RHASH_NO_ASM)
# define USE_GCC_ASM_X64
#endif
extern unsigned rhash_gost94_sbox[4][256];
extern unsigned rhash_gost94_sbox_cryptpro[4][256];
/**
* Initialize algorithm context before calculating hash
* with test parameters set.
*
* @param ctx context to initialize
*/
void rhash_gost94_init(gost94_ctx* ctx)
{
memset(ctx, 0, sizeof(gost94_ctx));
}
/**
* Initialize GOST algorithm context with CryptoPro parameter set.
*
* @param ctx context to initialize
*/
void rhash_gost94_cryptopro_init(gost94_ctx* ctx)
{
rhash_gost94_init(ctx);
ctx->cryptpro = 1;
}
/*
* A macro that performs a full encryption round of GOST 28147-89.
* Temporary variables tmp assumed and variables r and l for left and right
* blocks.
*/
#ifndef USE_GCC_ASM_IA32
# define GOST94_ENCRYPT_ROUND(key1, key2, sbox) \
tmp = (key1) + r; \
l ^= (sbox)[tmp & 0xff] ^ ((sbox) + 256)[(tmp >> 8) & 0xff] ^ \
((sbox) + 512)[(tmp >> 16) & 0xff] ^ ((sbox) + 768)[tmp >> 24]; \
tmp = (key2) + l; \
r ^= (sbox)[tmp & 0xff] ^ ((sbox) + 256)[(tmp >> 8) & 0xff] ^ \
((sbox) + 512)[(tmp >> 16) & 0xff] ^ ((sbox) + 768)[tmp >> 24];
/* encrypt a block with the given key */
# define GOST94_ENCRYPT(result, i, key, hash, sbox) \
r = hash[i], l = hash[i + 1]; \
GOST94_ENCRYPT_ROUND(key[0], key[1], sbox) \
GOST94_ENCRYPT_ROUND(key[2], key[3], sbox) \
GOST94_ENCRYPT_ROUND(key[4], key[5], sbox) \
GOST94_ENCRYPT_ROUND(key[6], key[7], sbox) \
GOST94_ENCRYPT_ROUND(key[0], key[1], sbox) \
GOST94_ENCRYPT_ROUND(key[2], key[3], sbox) \
GOST94_ENCRYPT_ROUND(key[4], key[5], sbox) \
GOST94_ENCRYPT_ROUND(key[6], key[7], sbox) \
GOST94_ENCRYPT_ROUND(key[0], key[1], sbox) \
GOST94_ENCRYPT_ROUND(key[2], key[3], sbox) \
GOST94_ENCRYPT_ROUND(key[4], key[5], sbox) \
GOST94_ENCRYPT_ROUND(key[6], key[7], sbox) \
GOST94_ENCRYPT_ROUND(key[7], key[6], sbox) \
GOST94_ENCRYPT_ROUND(key[5], key[4], sbox) \
GOST94_ENCRYPT_ROUND(key[3], key[2], sbox) \
GOST94_ENCRYPT_ROUND(key[1], key[0], sbox) \
result[i] = l, result[i + 1] = r;
#else /* USE_GCC_ASM_IA32 */
/* a faster x86 version of GOST94_ENCRYPT() */
/* it supposes edi=r, esi=l, edx=sbox ; */
# define ENC_ROUND_ASMx86(key, reg1, reg2) \
"movl %" #key ", %%eax\n\t" \
"addl %%" #reg1 ", %%eax\n\t" \
"movzx %%al, %%ebx\n\t" \
"movzx %%ah, %%ecx\n\t" \
"xorl (%%edx, %%ebx, 4), %%" #reg2 "\n\t" \
"xorl 1024(%%edx, %%ecx, 4), %%" #reg2 "\n\t" \
"shrl $16, %%eax\n\t" \
"movzx %%al, %%ebx\n\t" \
"shrl $8, %%eax\n\t" \
"xorl 2048(%%edx, %%ebx, 4), %%" #reg2 "\n\t" \
"xorl 3072(%%edx, %%eax, 4), %%" #reg2 "\n\t"
# define ENC_ASM(key1, key2) ENC_ROUND_ASMx86(key1, edi, esi) ENC_ROUND_ASMx86(key2, esi, edi)
# define GOST94_ENCRYPT_GCC_ASM_X86() \
ENC_ASM( 5, 6) ENC_ASM( 7, 8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
ENC_ASM( 5, 6) ENC_ASM( 7, 8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
ENC_ASM( 5, 6) ENC_ASM( 7, 8) ENC_ASM( 9, 10) ENC_ASM(11, 12) \
ENC_ASM(12, 11) ENC_ASM(10, 9) ENC_ASM( 8, 7) ENC_ASM( 6, 5)
#endif /* USE_GCC_ASM_IA32 */
/**
* The core transformation. Process a 512-bit block.
*
* @param hash intermediate message hash
* @param block the message block to process
*/
static void rhash_gost94_block_compress(gost94_ctx* ctx, const unsigned* block)
{
unsigned i;
unsigned key[8], u[8], v[8], w[8], s[8];
unsigned* sbox = (ctx->cryptpro ? (unsigned*)rhash_gost94_sbox_cryptpro : (unsigned*)rhash_gost94_sbox);
/* u := hash, v := <256-bit message block> */
memcpy(u, ctx->hash, sizeof(u));
memcpy(v, block, sizeof(v));
/* w := u xor v */
w[0] = u[0] ^ v[0], w[1] = u[1] ^ v[1];
w[2] = u[2] ^ v[2], w[3] = u[3] ^ v[3];
w[4] = u[4] ^ v[4], w[5] = u[5] ^ v[5];
w[6] = u[6] ^ v[6], w[7] = u[7] ^ v[7];
/* calculate keys, encrypt hash and store result to the s[] array */
for (i = 0;; i += 2) {
/* key generation: key_i := P(w) */
key[0] = (w[0] & 0x000000ff) | ((w[2] & 0x000000ff) << 8) | ((w[4] & 0x000000ff) << 16) | ((w[6] & 0x000000ff) << 24);
key[1] = ((w[0] & 0x0000ff00) >> 8) | (w[2] & 0x0000ff00) | ((w[4] & 0x0000ff00) << 8) | ((w[6] & 0x0000ff00) << 16);
key[2] = ((w[0] & 0x00ff0000) >> 16) | ((w[2] & 0x00ff0000) >> 8) | (w[4] & 0x00ff0000) | ((w[6] & 0x00ff0000) << 8);
key[3] = ((w[0] & 0xff000000) >> 24) | ((w[2] & 0xff000000) >> 16) | ((w[4] & 0xff000000) >> 8) | (w[6] & 0xff000000);
key[4] = (w[1] & 0x000000ff) | ((w[3] & 0x000000ff) << 8) | ((w[5] & 0x000000ff) << 16) | ((w[7] & 0x000000ff) << 24);
key[5] = ((w[1] & 0x0000ff00) >> 8) | (w[3] & 0x0000ff00) | ((w[5] & 0x0000ff00) << 8) | ((w[7] & 0x0000ff00) << 16);
key[6] = ((w[1] & 0x00ff0000) >> 16) | ((w[3] & 0x00ff0000) >> 8) | (w[5] & 0x00ff0000) | ((w[7] & 0x00ff0000) << 8);
key[7] = ((w[1] & 0xff000000) >> 24) | ((w[3] & 0xff000000) >> 16) | ((w[5] & 0xff000000) >> 8) | (w[7] & 0xff000000);
/* encryption: s_i := E_{key_i} (h_i) */
#ifndef USE_GCC_ASM_IA32
{
unsigned l, r, tmp;
GOST94_ENCRYPT(s, i, key, ctx->hash, sbox);
}
#else /* USE_GCC_ASM_IA32 */
__asm __volatile(
"movl %%ebx, %13\n\t"
GOST94_ENCRYPT_GCC_ASM_X86() /* optimized for x86 Intel Core 2 */
"movl %13, %%ebx\n\t"
: "=S" (s[i]), "=D" (s[i + 1]) /* 0,1: s[i]=esi, s[i + 1]=edi */
: "d" (sbox), "D" (ctx->hash[i]), "S" (ctx->hash[i + 1]), /* 2,3,4: edx=sbox,edi=r,esi=l */
"m" (key[0]), "m" (key[1]), "m" (key[2]), "m" (key[3]), /* 5, 6, 7, 8 */
"m" (key[4]), "m" (key[5]), "m" (key[6]), "m" (key[7]), /* 9,10,11,12 */
"m" (w[0]) /* store EBX in w[0], cause it's used for PIC on *BSD. */
/* We avoid push/pop instructions incompatible with gcc -fomit-frame-pointer */
: "cc", "eax", "ecx");
#endif /* USE_GCC_ASM_IA32 */
if (i == 0) {
/* w:= A(u) ^ A^2(v) */
w[0] = u[2] ^ v[4], w[1] = u[3] ^ v[5];
w[2] = u[4] ^ v[6], w[3] = u[5] ^ v[7];
w[4] = u[6] ^ (v[0] ^= v[2]);
w[5] = u[7] ^ (v[1] ^= v[3]);
w[6] = (u[0] ^= u[2]) ^ (v[2] ^= v[4]);
w[7] = (u[1] ^= u[3]) ^ (v[3] ^= v[5]);
} else if ((i & 2) != 0) {
if (i == 6) break;
/* w := A^2(u) xor A^4(v) xor C_3; u := A(u) xor C_3 */
/* C_3=0xff00ffff000000ffff0000ff00ffff0000ff00ff00ff00ffff00ff00ff00ff00 */
u[2] ^= u[4] ^ 0x000000ff;
u[3] ^= u[5] ^ 0xff00ffff;
u[4] ^= 0xff00ff00;
u[5] ^= 0xff00ff00;
u[6] ^= 0x00ff00ff;
u[7] ^= 0x00ff00ff;
u[0] ^= 0x00ffff00;
u[1] ^= 0xff0000ff;
w[0] = u[4] ^ v[0];
w[2] = u[6] ^ v[2];
w[4] = u[0] ^ (v[4] ^= v[6]);
w[6] = u[2] ^ (v[6] ^= v[0]);
w[1] = u[5] ^ v[1];
w[3] = u[7] ^ v[3];
w[5] = u[1] ^ (v[5] ^= v[7]);
w[7] = u[3] ^ (v[7] ^= v[1]);
} else {
/* i==4 here */
/* w:= A( A^2(u) xor C_3 ) xor A^6(v) */
w[0] = u[6] ^ v[4], w[1] = u[7] ^ v[5];
w[2] = u[0] ^ v[6], w[3] = u[1] ^ v[7];
w[4] = u[2] ^ (v[0] ^= v[2]);
w[5] = u[3] ^ (v[1] ^= v[3]);
w[6] = (u[4] ^= u[6]) ^ (v[2] ^= v[4]);
w[7] = (u[5] ^= u[7]) ^ (v[3] ^= v[5]);
}
}
/* step hash function: x(block, hash) := psi^61(hash xor psi(block xor psi^12(S))) */
/* 12 rounds of the LFSR and xor in */
u[0] = block[0] ^ s[6];
u[1] = block[1] ^ s[7];
u[2] = block[2] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff) ^ (s[1] & 0xffff) ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[7] & 0xffff0000) ^ (s[7] >> 16);
u[3] = block[3] ^ (s[0] & 0xffff) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^ (s[1] << 16) ^ (s[1] >> 16) ^
(s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
u[4] = block[4] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[0] >> 16) ^
(s[1] & 0xffff0000) ^ (s[1] >> 16) ^ (s[2] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
u[5] = block[5] ^ (s[0] << 16) ^ (s[0] >> 16) ^ (s[0] & 0xffff0000) ^
(s[1] & 0xffff) ^ s[2] ^ (s[2] >> 16) ^ (s[3] << 16) ^ (s[3] >> 16) ^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff0000) ^ (s[7] << 16) ^ (s[7] >> 16);
u[6] = block[6] ^ s[0] ^ (s[1] >> 16) ^ (s[2] << 16) ^ s[3] ^ (s[3] >> 16)
^ (s[4] << 16) ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ s[6] ^ (s[6] << 16) ^ (s[6] >> 16) ^ (s[7] << 16);
u[7] = block[7] ^ (s[0] & 0xffff0000) ^ (s[0] << 16) ^ (s[1] & 0xffff) ^
(s[1] << 16) ^ (s[2] >> 16) ^ (s[3] << 16) ^ s[4] ^ (s[4] >> 16) ^ (s[5] << 16) ^ (s[5] >> 16) ^ (s[6] >> 16) ^ (s[7] & 0xffff) ^ (s[7] << 16) ^ (s[7] >> 16);
/* 1 round of the LFSR (a mixing transformation) and xor with */
v[0] = ctx->hash[0] ^ (u[1] << 16) ^ (u[0] >> 16);
v[1] = ctx->hash[1] ^ (u[2] << 16) ^ (u[1] >> 16);
v[2] = ctx->hash[2] ^ (u[3] << 16) ^ (u[2] >> 16);
v[3] = ctx->hash[3] ^ (u[4] << 16) ^ (u[3] >> 16);
v[4] = ctx->hash[4] ^ (u[5] << 16) ^ (u[4] >> 16);
v[5] = ctx->hash[5] ^ (u[6] << 16) ^ (u[5] >> 16);
v[6] = ctx->hash[6] ^ (u[7] << 16) ^ (u[6] >> 16);
v[7] = ctx->hash[7] ^ (u[0] & 0xffff0000) ^ (u[0] << 16) ^ (u[1] & 0xffff0000) ^ (u[1] << 16) ^ (u[6] << 16) ^ (u[7] & 0xffff0000) ^ (u[7] >> 16);
/* 61 rounds of LFSR, mixing up hash */
ctx->hash[0] = (v[0] & 0xffff0000) ^ (v[0] << 16) ^ (v[0] >> 16) ^
(v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^
(v[3] >> 16) ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[5] ^
(v[6] >> 16) ^ (v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff);
ctx->hash[1] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^
(v[1] & 0xffff) ^ v[2] ^ (v[2] >> 16) ^ (v[3] << 16) ^
(v[4] >> 16) ^ (v[5] << 16) ^ (v[6] << 16) ^ v[6] ^
(v[7] & 0xffff0000) ^ (v[7] >> 16);
ctx->hash[2] = (v[0] & 0xffff) ^ (v[0] << 16) ^ (v[1] << 16) ^
(v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ (v[3] >> 16) ^
v[3] ^ (v[4] << 16) ^ (v[5] >> 16) ^ v[6] ^ (v[6] >> 16) ^
(v[7] & 0xffff) ^ (v[7] << 16) ^ (v[7] >> 16);
ctx->hash[3] = (v[0] << 16) ^ (v[0] >> 16) ^ (v[0] & 0xffff0000) ^
(v[1] & 0xffff0000) ^ (v[1] >> 16) ^ (v[2] << 16) ^
(v[2] >> 16) ^ v[2] ^ (v[3] << 16) ^ (v[4] >> 16) ^ v[4] ^
(v[5] << 16) ^ (v[6] << 16) ^ (v[7] & 0xffff) ^ (v[7] >> 16);
ctx->hash[4] = (v[0] >> 16) ^ (v[1] << 16) ^ v[1] ^ (v[2] >> 16) ^ v[2] ^
(v[3] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^
(v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16);
ctx->hash[5] = (v[0] << 16) ^ (v[0] & 0xffff0000) ^ (v[1] << 16) ^
(v[1] >> 16) ^ (v[1] & 0xffff0000) ^ (v[2] << 16) ^ v[2] ^
(v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ (v[4] >> 16) ^ v[4] ^
(v[5] << 16) ^ (v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^
(v[7] << 16) ^ (v[7] >> 16) ^ (v[7] & 0xffff0000);
ctx->hash[6] = v[0] ^ v[2] ^ (v[2] >> 16) ^ v[3] ^ (v[3] << 16) ^ v[4] ^
(v[4] >> 16) ^ (v[5] << 16) ^ (v[5] >> 16) ^ v[5] ^
(v[6] << 16) ^ (v[6] >> 16) ^ v[6] ^ (v[7] << 16) ^ v[7];
ctx->hash[7] = v[0] ^ (v[0] >> 16) ^ (v[1] << 16) ^ (v[1] >> 16) ^
(v[2] << 16) ^ (v[3] >> 16) ^ v[3] ^ (v[4] << 16) ^ v[4] ^
(v[5] >> 16) ^ v[5] ^ (v[6] << 16) ^ (v[6] >> 16) ^ (v[7] << 16) ^ v[7];
}
/**
* This function calculates hash value by 256-bit blocks.
* It updates 256-bit check sum as follows:
* *(uint256_t)(ctx->sum) += *(uint256_t*)block;
* and then updates intermediate hash value ctx->hash
* by calling rhash_gost94_block_compress().
*
* @param ctx algorithm context
* @param block the 256-bit message block to process
*/
static void rhash_gost94_compute_sum_and_hash(gost94_ctx* ctx, const unsigned* block)
{
#if IS_LITTLE_ENDIAN
# define block_le block
# define LOAD_BLOCK_LE(i)
#else
unsigned block_le[8]; /* tmp buffer for little endian number */
# define LOAD_BLOCK_LE(i) (block_le[i] = le2me_32(block[i]))
#endif
/* This optimization doesn't improve speed much,
* and saves too little memory, but it was fun to write! =) */
#ifdef USE_GCC_ASM_IA32
__asm __volatile(
"addl %0, (%1)\n\t"
"movl 4(%2), %0\n\t"
"adcl %0, 4(%1)\n\t"
"movl 8(%2), %0\n\t"
"adcl %0, 8(%1)\n\t"
"movl 12(%2), %0\n\t"
"adcl %0, 12(%1)\n\t"
"movl 16(%2), %0\n\t"
"adcl %0, 16(%1)\n\t"
"movl 20(%2), %0\n\t"
"adcl %0, 20(%1)\n\t"
"movl 24(%2), %0\n\t"
"adcl %0, 24(%1)\n\t"
"movl 28(%2), %0\n\t"
"adcl %0, 28(%1)\n\t"
: : "r" (block[0]), "r" (ctx->sum), "r" (block)
: "0", "memory", "cc" );
#elif defined(USE_GCC_ASM_X64)
const uint64_t* block64 = (const uint64_t*)block;
uint64_t* sum64 = (uint64_t*)ctx->sum;
__asm __volatile(
"addq %4, %0\n\t"
"adcq %5, %1\n\t"
"adcq %6, %2\n\t"
"adcq %7, %3\n\t"
: "+m" (sum64[0]), "+m" (sum64[1]), "+m" (sum64[2]), "+m" (sum64[3])
: "r" (block64[0]), "r" (block64[1]), "r" (block64[2]), "r" (block64[3])
: "cc" );
#else /* USE_GCC_ASM_IA32 */
unsigned i, carry = 0;
/* compute the 256-bit sum */
for (i = 0; i < 8; i++) {
LOAD_BLOCK_LE(i);
ctx->sum[i] += block_le[i] + carry;
carry = (ctx->sum[i] < block_le[i] ? 1 :
ctx->sum[i] == block_le[i] ? carry : 0);
}
#endif /* USE_GCC_ASM_IA32 */
/* update message hash */
rhash_gost94_block_compress(ctx, block_le);
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_gost94_update(gost94_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 31;
ctx->length += size;
/* fill partial block */
if (index) {
unsigned left = gost94_block_size - index;
memcpy(ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_gost94_compute_sum_and_hash(ctx, (unsigned*)ctx->message);
msg += left;
size -= left;
}
while (size >= gost94_block_size) {
unsigned* aligned_message_block;
#if (defined(__GNUC__) && defined(CPU_X64))
if (IS_ALIGNED_64(msg)) {
#else
if (IS_ALIGNED_32(msg)) {
#endif
/* the most common case is processing of an already aligned message
on little-endian CPU without copying it */
aligned_message_block = (unsigned*)msg;
} else {
memcpy(ctx->message, msg, gost94_block_size);
aligned_message_block = (unsigned*)ctx->message;
}
rhash_gost94_compute_sum_and_hash(ctx, aligned_message_block);
msg += gost94_block_size;
size -= gost94_block_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Finish hashing and store message digest into given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_gost94_final(gost94_ctx* ctx, unsigned char result[32])
{
unsigned index = (unsigned)ctx->length & 31;
unsigned* msg32 = (unsigned*)ctx->message;
/* pad the last block with zeroes and hash it */
if (index > 0) {
memset(ctx->message + index, 0, 32 - index);
rhash_gost94_compute_sum_and_hash(ctx, msg32);
}
/* hash the message length and the sum */
msg32[0] = (unsigned)(ctx->length << 3);
msg32[1] = (unsigned)(ctx->length >> 29);
memset(msg32 + 2, 0, sizeof(unsigned) * 6);
rhash_gost94_block_compress(ctx, msg32);
rhash_gost94_block_compress(ctx, ctx->sum);
/* convert hash state to result bytes */
le32_copy(result, 0, ctx->hash, gost94_hash_length);
}
#ifdef GENERATE_GOST94_LOOKUP_TABLE
ALIGN_ATTR(64)
unsigned rhash_gost94_sbox[4][256];
unsigned rhash_gost94_sbox_cryptpro[4][256];
/**
* Calculate a lookup table from S-Boxes.
* A substitution table is used to speed up hash calculation.
*
* @param out pointer to the lookup table to fill
* @param src pointer to eight S-Boxes to fill the table from
*/
static void rhash_gost94_fill_sbox(unsigned out[4][256], const unsigned char src[8][16])
{
int a, b, i;
unsigned long ax, bx, cx, dx;
for (i = 0, a = 0; a < 16; a++) {
ax = (unsigned)src[1][a] << 15;
bx = (unsigned)src[3][a] << 23;
cx = ROTL32((unsigned)src[5][a], 31);
dx = (unsigned)src[7][a] << 7;
for (b = 0; b < 16; b++, i++) {
out[0][i] = ax | ((unsigned)src[0][b] << 11);
out[1][i] = bx | ((unsigned)src[2][b] << 19);
out[2][i] = cx | ((unsigned)src[4][b] << 27);
out[3][i] = dx | ((unsigned)src[6][b] << 3);
}
}
}
/**
* Initialize the GOST lookup tables for both parameters sets.
* Two lookup tables contain 8 KiB in total, so calculating
* them at rine-time can save a little space in the exutable file
* in trade of consuming some time at pogram start.
*/
void rhash_gost94_init_table(void)
{
/* Test parameters set. Eight 4-bit S-Boxes defined by GOST R 34.10-94
* standard for testing the hash function.
* Also given by RFC 4357 section 11.2 */
static const unsigned char sbox[8][16] = {
{ 4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3 },
{ 14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9 },
{ 5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11 },
{ 7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3 },
{ 6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2 },
{ 4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14 },
{ 13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12 },
{ 1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12 }
};
/* Parameter set recommended by RFC 4357.
* Eight 4-bit S-Boxes as defined by RFC 4357 section 11.2 */
static const unsigned char sbox_cryptpro[8][16] = {
{ 10, 4, 5, 6, 8, 1, 3, 7, 13, 12, 14, 0, 9, 2, 11, 15 },
{ 5, 15, 4, 0, 2, 13, 11, 9, 1, 7, 6, 3, 12, 14, 10, 8 },
{ 7, 15, 12, 14, 9, 4, 1, 0, 3, 11, 5, 2, 6, 10, 8, 13 },
{ 4, 10, 7, 12, 0, 15, 2, 8, 14, 1, 6, 5, 13, 11, 9, 3 },
{ 7, 6, 4, 11, 9, 12, 2, 10, 1, 8, 0, 14, 15, 13, 3, 5 },
{ 7, 6, 2, 4, 13, 9, 15, 0, 10, 1, 5, 11, 8, 14, 12, 3 },
{ 13, 14, 4, 1, 7, 0, 5, 10, 3, 12, 8, 15, 6, 2, 9, 11 },
{ 1, 3, 10, 9, 5, 11, 4, 15, 8, 6, 7, 14, 13, 0, 2, 12 }
};
rhash_gost94_fill_sbox(rhash_gost94_sbox, sbox);
rhash_gost94_fill_sbox(rhash_gost94_sbox_cryptpro, sbox_cryptpro);
}
#else /* GENERATE_GOST94_LOOKUP_TABLE */
/* pre-initialized GOST lookup tables based on rotated S-Box */
ALIGN_ATTR(64)
unsigned rhash_gost94_sbox[4][256] = {
{
0x72000, 0x75000, 0x74800, 0x71000, 0x76800,
0x74000, 0x70000, 0x77000, 0x73000, 0x75800,
0x70800, 0x76000, 0x73800, 0x77800, 0x72800,
0x71800, 0x5A000, 0x5D000, 0x5C800, 0x59000,
0x5E800, 0x5C000, 0x58000, 0x5F000, 0x5B000,
0x5D800, 0x58800, 0x5E000, 0x5B800, 0x5F800,
0x5A800, 0x59800, 0x22000, 0x25000, 0x24800,
0x21000, 0x26800, 0x24000, 0x20000, 0x27000,
0x23000, 0x25800, 0x20800, 0x26000, 0x23800,
0x27800, 0x22800, 0x21800, 0x62000, 0x65000,
0x64800, 0x61000, 0x66800, 0x64000, 0x60000,
0x67000, 0x63000, 0x65800, 0x60800, 0x66000,
0x63800, 0x67800, 0x62800, 0x61800, 0x32000,
0x35000, 0x34800, 0x31000, 0x36800, 0x34000,
0x30000, 0x37000, 0x33000, 0x35800, 0x30800,
0x36000, 0x33800, 0x37800, 0x32800, 0x31800,
0x6A000, 0x6D000, 0x6C800, 0x69000, 0x6E800,
0x6C000, 0x68000, 0x6F000, 0x6B000, 0x6D800,
0x68800, 0x6E000, 0x6B800, 0x6F800, 0x6A800,
0x69800, 0x7A000, 0x7D000, 0x7C800, 0x79000,
0x7E800, 0x7C000, 0x78000, 0x7F000, 0x7B000,
0x7D800, 0x78800, 0x7E000, 0x7B800, 0x7F800,
0x7A800, 0x79800, 0x52000, 0x55000, 0x54800,
0x51000, 0x56800, 0x54000, 0x50000, 0x57000,
0x53000, 0x55800, 0x50800, 0x56000, 0x53800,
0x57800, 0x52800, 0x51800, 0x12000, 0x15000,
0x14800, 0x11000, 0x16800, 0x14000, 0x10000,
0x17000, 0x13000, 0x15800, 0x10800, 0x16000,
0x13800, 0x17800, 0x12800, 0x11800, 0x1A000,
0x1D000, 0x1C800, 0x19000, 0x1E800, 0x1C000,
0x18000, 0x1F000, 0x1B000, 0x1D800, 0x18800,
0x1E000, 0x1B800, 0x1F800, 0x1A800, 0x19800,
0x42000, 0x45000, 0x44800, 0x41000, 0x46800,
0x44000, 0x40000, 0x47000, 0x43000, 0x45800,
0x40800, 0x46000, 0x43800, 0x47800, 0x42800,
0x41800, 0xA000, 0xD000, 0xC800, 0x9000,
0xE800, 0xC000, 0x8000, 0xF000, 0xB000,
0xD800, 0x8800, 0xE000, 0xB800, 0xF800,
0xA800, 0x9800, 0x2000, 0x5000, 0x4800,
0x1000, 0x6800, 0x4000, 0x0, 0x7000,
0x3000, 0x5800, 0x800, 0x6000, 0x3800,
0x7800, 0x2800, 0x1800, 0x3A000, 0x3D000,
0x3C800, 0x39000, 0x3E800, 0x3C000, 0x38000,
0x3F000, 0x3B000, 0x3D800, 0x38800, 0x3E000,
0x3B800, 0x3F800, 0x3A800, 0x39800, 0x2A000,
0x2D000, 0x2C800, 0x29000, 0x2E800, 0x2C000,
0x28000, 0x2F000, 0x2B000, 0x2D800, 0x28800,
0x2E000, 0x2B800, 0x2F800, 0x2A800, 0x29800,
0x4A000, 0x4D000, 0x4C800, 0x49000, 0x4E800,
0x4C000, 0x48000, 0x4F000, 0x4B000, 0x4D800,
0x48800, 0x4E000, 0x4B800, 0x4F800, 0x4A800,
0x49800
}, {
0x3A80000, 0x3C00000, 0x3880000, 0x3E80000, 0x3D00000,
0x3980000, 0x3A00000, 0x3900000, 0x3F00000, 0x3F80000,
0x3E00000, 0x3B80000, 0x3B00000, 0x3800000, 0x3C80000,
0x3D80000, 0x6A80000, 0x6C00000, 0x6880000, 0x6E80000,
0x6D00000, 0x6980000, 0x6A00000, 0x6900000, 0x6F00000,
0x6F80000, 0x6E00000, 0x6B80000, 0x6B00000, 0x6800000,
0x6C80000, 0x6D80000, 0x5280000, 0x5400000, 0x5080000,
0x5680000, 0x5500000, 0x5180000, 0x5200000, 0x5100000,
0x5700000, 0x5780000, 0x5600000, 0x5380000, 0x5300000,
0x5000000, 0x5480000, 0x5580000, 0xA80000, 0xC00000,
0x880000, 0xE80000, 0xD00000, 0x980000, 0xA00000,
0x900000, 0xF00000, 0xF80000, 0xE00000, 0xB80000,
0xB00000, 0x800000, 0xC80000, 0xD80000, 0x280000,
0x400000, 0x80000, 0x680000, 0x500000, 0x180000,
0x200000, 0x100000, 0x700000, 0x780000, 0x600000,
0x380000, 0x300000, 0x0, 0x480000, 0x580000,
0x4280000, 0x4400000, 0x4080000, 0x4680000, 0x4500000,
0x4180000, 0x4200000, 0x4100000, 0x4700000, 0x4780000,
0x4600000, 0x4380000, 0x4300000, 0x4000000, 0x4480000,
0x4580000, 0x4A80000, 0x4C00000, 0x4880000, 0x4E80000,
0x4D00000, 0x4980000, 0x4A00000, 0x4900000, 0x4F00000,
0x4F80000, 0x4E00000, 0x4B80000, 0x4B00000, 0x4800000,
0x4C80000, 0x4D80000, 0x7A80000, 0x7C00000, 0x7880000,
0x7E80000, 0x7D00000, 0x7980000, 0x7A00000, 0x7900000,
0x7F00000, 0x7F80000, 0x7E00000, 0x7B80000, 0x7B00000,
0x7800000, 0x7C80000, 0x7D80000, 0x7280000, 0x7400000,
0x7080000, 0x7680000, 0x7500000, 0x7180000, 0x7200000,
0x7100000, 0x7700000, 0x7780000, 0x7600000, 0x7380000,
0x7300000, 0x7000000, 0x7480000, 0x7580000, 0x2280000,
0x2400000, 0x2080000, 0x2680000, 0x2500000, 0x2180000,
0x2200000, 0x2100000, 0x2700000, 0x2780000, 0x2600000,
0x2380000, 0x2300000, 0x2000000, 0x2480000, 0x2580000,
0x3280000, 0x3400000, 0x3080000, 0x3680000, 0x3500000,
0x3180000, 0x3200000, 0x3100000, 0x3700000, 0x3780000,
0x3600000, 0x3380000, 0x3300000, 0x3000000, 0x3480000,
0x3580000, 0x6280000, 0x6400000, 0x6080000, 0x6680000,
0x6500000, 0x6180000, 0x6200000, 0x6100000, 0x6700000,
0x6780000, 0x6600000, 0x6380000, 0x6300000, 0x6000000,
0x6480000, 0x6580000, 0x5A80000, 0x5C00000, 0x5880000,
0x5E80000, 0x5D00000, 0x5980000, 0x5A00000, 0x5900000,
0x5F00000, 0x5F80000, 0x5E00000, 0x5B80000, 0x5B00000,
0x5800000, 0x5C80000, 0x5D80000, 0x1280000, 0x1400000,
0x1080000, 0x1680000, 0x1500000, 0x1180000, 0x1200000,
0x1100000, 0x1700000, 0x1780000, 0x1600000, 0x1380000,
0x1300000, 0x1000000, 0x1480000, 0x1580000, 0x2A80000,
0x2C00000, 0x2880000, 0x2E80000, 0x2D00000, 0x2980000,
0x2A00000, 0x2900000, 0x2F00000, 0x2F80000, 0x2E00000,
0x2B80000, 0x2B00000, 0x2800000, 0x2C80000, 0x2D80000,
0x1A80000, 0x1C00000, 0x1880000, 0x1E80000, 0x1D00000,
0x1980000, 0x1A00000, 0x1900000, 0x1F00000, 0x1F80000,
0x1E00000, 0x1B80000, 0x1B00000, 0x1800000, 0x1C80000,
0x1D80000
}, {
0x30000002, 0x60000002, 0x38000002, 0x8000002,
0x28000002, 0x78000002, 0x68000002, 0x40000002,
0x20000002, 0x50000002, 0x48000002, 0x70000002,
0x2, 0x18000002, 0x58000002, 0x10000002,
0xB0000005, 0xE0000005, 0xB8000005, 0x88000005,
0xA8000005, 0xF8000005, 0xE8000005, 0xC0000005,
0xA0000005, 0xD0000005, 0xC8000005, 0xF0000005,
0x80000005, 0x98000005, 0xD8000005, 0x90000005,
0x30000005, 0x60000005, 0x38000005, 0x8000005,
0x28000005, 0x78000005, 0x68000005, 0x40000005,
0x20000005, 0x50000005, 0x48000005, 0x70000005,
0x5, 0x18000005, 0x58000005, 0x10000005,
0x30000000, 0x60000000, 0x38000000, 0x8000000,
0x28000000, 0x78000000, 0x68000000, 0x40000000,
0x20000000, 0x50000000, 0x48000000, 0x70000000,
0x0, 0x18000000, 0x58000000, 0x10000000,
0xB0000003, 0xE0000003, 0xB8000003, 0x88000003,
0xA8000003, 0xF8000003, 0xE8000003, 0xC0000003,
0xA0000003, 0xD0000003, 0xC8000003, 0xF0000003,
0x80000003, 0x98000003, 0xD8000003, 0x90000003,
0x30000001, 0x60000001, 0x38000001, 0x8000001,
0x28000001, 0x78000001, 0x68000001, 0x40000001,
0x20000001, 0x50000001, 0x48000001, 0x70000001,
0x1, 0x18000001, 0x58000001, 0x10000001,
0xB0000000, 0xE0000000, 0xB8000000, 0x88000000,
0xA8000000, 0xF8000000, 0xE8000000, 0xC0000000,
0xA0000000, 0xD0000000, 0xC8000000, 0xF0000000,
0x80000000, 0x98000000, 0xD8000000, 0x90000000,
0xB0000006, 0xE0000006, 0xB8000006, 0x88000006,
0xA8000006, 0xF8000006, 0xE8000006, 0xC0000006,
0xA0000006, 0xD0000006, 0xC8000006, 0xF0000006,
0x80000006, 0x98000006, 0xD8000006, 0x90000006,
0xB0000001, 0xE0000001, 0xB8000001, 0x88000001,
0xA8000001, 0xF8000001, 0xE8000001, 0xC0000001,
0xA0000001, 0xD0000001, 0xC8000001, 0xF0000001,
0x80000001, 0x98000001, 0xD8000001, 0x90000001,
0x30000003, 0x60000003, 0x38000003, 0x8000003,
0x28000003, 0x78000003, 0x68000003, 0x40000003,
0x20000003, 0x50000003, 0x48000003, 0x70000003,
0x3, 0x18000003, 0x58000003, 0x10000003,
0x30000004, 0x60000004, 0x38000004, 0x8000004,
0x28000004, 0x78000004, 0x68000004, 0x40000004,
0x20000004, 0x50000004, 0x48000004, 0x70000004,
0x4, 0x18000004, 0x58000004, 0x10000004,
0xB0000002, 0xE0000002, 0xB8000002, 0x88000002,
0xA8000002, 0xF8000002, 0xE8000002, 0xC0000002,
0xA0000002, 0xD0000002, 0xC8000002, 0xF0000002,
0x80000002, 0x98000002, 0xD8000002, 0x90000002,
0xB0000004, 0xE0000004, 0xB8000004, 0x88000004,
0xA8000004, 0xF8000004, 0xE8000004, 0xC0000004,
0xA0000004, 0xD0000004, 0xC8000004, 0xF0000004,
0x80000004, 0x98000004, 0xD8000004, 0x90000004,
0x30000006, 0x60000006, 0x38000006, 0x8000006,
0x28000006, 0x78000006, 0x68000006, 0x40000006,
0x20000006, 0x50000006, 0x48000006, 0x70000006,
0x6, 0x18000006, 0x58000006, 0x10000006,
0xB0000007, 0xE0000007, 0xB8000007, 0x88000007,
0xA8000007, 0xF8000007, 0xE8000007, 0xC0000007,
0xA0000007, 0xD0000007, 0xC8000007, 0xF0000007,
0x80000007, 0x98000007, 0xD8000007, 0x90000007,
0x30000007, 0x60000007, 0x38000007, 0x8000007,
0x28000007, 0x78000007, 0x68000007, 0x40000007,
0x20000007, 0x50000007, 0x48000007, 0x70000007,
0x7, 0x18000007, 0x58000007, 0x10000007
}, {
0xE8, 0xD8, 0xA0, 0x88, 0x98, 0xF8, 0xA8, 0xC8, 0x80, 0xD0,
0xF0, 0xB8, 0xB0, 0xC0, 0x90, 0xE0, 0x7E8, 0x7D8, 0x7A0, 0x788,
0x798, 0x7F8, 0x7A8, 0x7C8, 0x780, 0x7D0, 0x7F0, 0x7B8, 0x7B0, 0x7C0,
0x790, 0x7E0, 0x6E8, 0x6D8, 0x6A0, 0x688, 0x698, 0x6F8, 0x6A8, 0x6C8,
0x680, 0x6D0, 0x6F0, 0x6B8, 0x6B0, 0x6C0, 0x690, 0x6E0, 0x68, 0x58,
0x20, 0x8, 0x18, 0x78, 0x28, 0x48, 0x0, 0x50, 0x70, 0x38,
0x30, 0x40, 0x10, 0x60, 0x2E8, 0x2D8, 0x2A0, 0x288, 0x298, 0x2F8,
0x2A8, 0x2C8, 0x280, 0x2D0, 0x2F0, 0x2B8, 0x2B0, 0x2C0, 0x290, 0x2E0,
0x3E8, 0x3D8, 0x3A0, 0x388, 0x398, 0x3F8, 0x3A8, 0x3C8, 0x380, 0x3D0,
0x3F0, 0x3B8, 0x3B0, 0x3C0, 0x390, 0x3E0, 0x568, 0x558, 0x520, 0x508,
0x518, 0x578, 0x528, 0x548, 0x500, 0x550, 0x570, 0x538, 0x530, 0x540,
0x510, 0x560, 0x268, 0x258, 0x220, 0x208, 0x218, 0x278, 0x228, 0x248,
0x200, 0x250, 0x270, 0x238, 0x230, 0x240, 0x210, 0x260, 0x4E8, 0x4D8,
0x4A0, 0x488, 0x498, 0x4F8, 0x4A8, 0x4C8, 0x480, 0x4D0, 0x4F0, 0x4B8,
0x4B0, 0x4C0, 0x490, 0x4E0, 0x168, 0x158, 0x120, 0x108, 0x118, 0x178,
0x128, 0x148, 0x100, 0x150, 0x170, 0x138, 0x130, 0x140, 0x110, 0x160,
0x1E8, 0x1D8, 0x1A0, 0x188, 0x198, 0x1F8, 0x1A8, 0x1C8, 0x180, 0x1D0,
0x1F0, 0x1B8, 0x1B0, 0x1C0, 0x190, 0x1E0, 0x768, 0x758, 0x720, 0x708,
0x718, 0x778, 0x728, 0x748, 0x700, 0x750, 0x770, 0x738, 0x730, 0x740,
0x710, 0x760, 0x368, 0x358, 0x320, 0x308, 0x318, 0x378, 0x328, 0x348,
0x300, 0x350, 0x370, 0x338, 0x330, 0x340, 0x310, 0x360, 0x5E8, 0x5D8,
0x5A0, 0x588, 0x598, 0x5F8, 0x5A8, 0x5C8, 0x580, 0x5D0, 0x5F0, 0x5B8,
0x5B0, 0x5C0, 0x590, 0x5E0, 0x468, 0x458, 0x420, 0x408, 0x418, 0x478,
0x428, 0x448, 0x400, 0x450, 0x470, 0x438, 0x430, 0x440, 0x410, 0x460,
0x668, 0x658, 0x620, 0x608, 0x618, 0x678, 0x628, 0x648, 0x600, 0x650,
0x670, 0x638, 0x630, 0x640, 0x610, 0x660
}
};
/* pre-initialized GOST lookup tables based on rotated S-Box */
unsigned rhash_gost94_sbox_cryptpro[4][256] = {
{
0x2d000, 0x2a000, 0x2a800, 0x2b000, 0x2c000,
0x28800, 0x29800, 0x2b800, 0x2e800, 0x2e000,
0x2f000, 0x28000, 0x2c800, 0x29000, 0x2d800,
0x2f800, 0x7d000, 0x7a000, 0x7a800, 0x7b000,
0x7c000, 0x78800, 0x79800, 0x7b800, 0x7e800,
0x7e000, 0x7f000, 0x78000, 0x7c800, 0x79000,
0x7d800, 0x7f800, 0x25000, 0x22000, 0x22800,
0x23000, 0x24000, 0x20800, 0x21800, 0x23800,
0x26800, 0x26000, 0x27000, 0x20000, 0x24800,
0x21000, 0x25800, 0x27800, 0x5000, 0x2000,
0x2800, 0x3000, 0x4000, 0x800, 0x1800,
0x3800, 0x6800, 0x6000, 0x7000, 0x0,
0x4800, 0x1000, 0x5800, 0x7800, 0x15000,
0x12000, 0x12800, 0x13000, 0x14000, 0x10800,
0x11800, 0x13800, 0x16800, 0x16000, 0x17000,
0x10000, 0x14800, 0x11000, 0x15800, 0x17800,
0x6d000, 0x6a000, 0x6a800, 0x6b000, 0x6c000,
0x68800, 0x69800, 0x6b800, 0x6e800, 0x6e000,
0x6f000, 0x68000, 0x6c800, 0x69000, 0x6d800,
0x6f800, 0x5d000, 0x5a000, 0x5a800, 0x5b000,
0x5c000, 0x58800, 0x59800, 0x5b800, 0x5e800,
0x5e000, 0x5f000, 0x58000, 0x5c800, 0x59000,
0x5d800, 0x5f800, 0x4d000, 0x4a000, 0x4a800,
0x4b000, 0x4c000, 0x48800, 0x49800, 0x4b800,
0x4e800, 0x4e000, 0x4f000, 0x48000, 0x4c800,
0x49000, 0x4d800, 0x4f800, 0xd000, 0xa000,
0xa800, 0xb000, 0xc000, 0x8800, 0x9800,
0xb800, 0xe800, 0xe000, 0xf000, 0x8000,
0xc800, 0x9000, 0xd800, 0xf800, 0x3d000,
0x3a000, 0x3a800, 0x3b000, 0x3c000, 0x38800,
0x39800, 0x3b800, 0x3e800, 0x3e000, 0x3f000,
0x38000, 0x3c800, 0x39000, 0x3d800, 0x3f800,
0x35000, 0x32000, 0x32800, 0x33000, 0x34000,
0x30800, 0x31800, 0x33800, 0x36800, 0x36000,
0x37000, 0x30000, 0x34800, 0x31000, 0x35800,
0x37800, 0x1d000, 0x1a000, 0x1a800, 0x1b000,
0x1c000, 0x18800, 0x19800, 0x1b800, 0x1e800,
0x1e000, 0x1f000, 0x18000, 0x1c800, 0x19000,
0x1d800, 0x1f800, 0x65000, 0x62000, 0x62800,
0x63000, 0x64000, 0x60800, 0x61800, 0x63800,
0x66800, 0x66000, 0x67000, 0x60000, 0x64800,
0x61000, 0x65800, 0x67800, 0x75000, 0x72000,
0x72800, 0x73000, 0x74000, 0x70800, 0x71800,
0x73800, 0x76800, 0x76000, 0x77000, 0x70000,
0x74800, 0x71000, 0x75800, 0x77800, 0x55000,
0x52000, 0x52800, 0x53000, 0x54000, 0x50800,
0x51800, 0x53800, 0x56800, 0x56000, 0x57000,
0x50000, 0x54800, 0x51000, 0x55800, 0x57800,
0x45000, 0x42000, 0x42800, 0x43000, 0x44000,
0x40800, 0x41800, 0x43800, 0x46800, 0x46000,
0x47000, 0x40000, 0x44800, 0x41000, 0x45800, 0x47800
}, {
0x2380000, 0x2780000, 0x2600000, 0x2700000, 0x2480000,
0x2200000, 0x2080000, 0x2000000, 0x2180000, 0x2580000,
0x2280000, 0x2100000, 0x2300000, 0x2500000, 0x2400000,
0x2680000, 0x5380000, 0x5780000, 0x5600000, 0x5700000,
0x5480000, 0x5200000, 0x5080000, 0x5000000, 0x5180000,
0x5580000, 0x5280000, 0x5100000, 0x5300000, 0x5500000,
0x5400000, 0x5680000, 0x3b80000, 0x3f80000, 0x3e00000,
0x3f00000, 0x3c80000, 0x3a00000, 0x3880000, 0x3800000,
0x3980000, 0x3d80000, 0x3a80000, 0x3900000, 0x3b00000,
0x3d00000, 0x3c00000, 0x3e80000, 0x6380000, 0x6780000,
0x6600000, 0x6700000, 0x6480000, 0x6200000, 0x6080000,
0x6000000, 0x6180000, 0x6580000, 0x6280000, 0x6100000,
0x6300000, 0x6500000, 0x6400000, 0x6680000, 0x380000,
0x780000, 0x600000, 0x700000, 0x480000, 0x200000,
0x80000, 0x0, 0x180000, 0x580000, 0x280000,
0x100000, 0x300000, 0x500000, 0x400000, 0x680000,
0x7b80000, 0x7f80000, 0x7e00000, 0x7f00000, 0x7c80000,
0x7a00000, 0x7880000, 0x7800000, 0x7980000, 0x7d80000,
0x7a80000, 0x7900000, 0x7b00000, 0x7d00000, 0x7c00000,
0x7e80000, 0x1380000, 0x1780000, 0x1600000, 0x1700000,
0x1480000, 0x1200000, 0x1080000, 0x1000000, 0x1180000,
0x1580000, 0x1280000, 0x1100000, 0x1300000, 0x1500000,
0x1400000, 0x1680000, 0x4380000, 0x4780000, 0x4600000,
0x4700000, 0x4480000, 0x4200000, 0x4080000, 0x4000000,
0x4180000, 0x4580000, 0x4280000, 0x4100000, 0x4300000,
0x4500000, 0x4400000, 0x4680000, 0x7380000, 0x7780000,
0x7600000, 0x7700000, 0x7480000, 0x7200000, 0x7080000,
0x7000000, 0x7180000, 0x7580000, 0x7280000, 0x7100000,
0x7300000, 0x7500000, 0x7400000, 0x7680000, 0xb80000,
0xf80000, 0xe00000, 0xf00000, 0xc80000, 0xa00000,
0x880000, 0x800000, 0x980000, 0xd80000, 0xa80000,
0x900000, 0xb00000, 0xd00000, 0xc00000, 0xe80000,
0x3380000, 0x3780000, 0x3600000, 0x3700000, 0x3480000,
0x3200000, 0x3080000, 0x3000000, 0x3180000, 0x3580000,
0x3280000, 0x3100000, 0x3300000, 0x3500000, 0x3400000,
0x3680000, 0x2b80000, 0x2f80000, 0x2e00000, 0x2f00000,
0x2c80000, 0x2a00000, 0x2880000, 0x2800000, 0x2980000,
0x2d80000, 0x2a80000, 0x2900000, 0x2b00000, 0x2d00000,
0x2c00000, 0x2e80000, 0x6b80000, 0x6f80000, 0x6e00000,
0x6f00000, 0x6c80000, 0x6a00000, 0x6880000, 0x6800000,
0x6980000, 0x6d80000, 0x6a80000, 0x6900000, 0x6b00000,
0x6d00000, 0x6c00000, 0x6e80000, 0x5b80000, 0x5f80000,
0x5e00000, 0x5f00000, 0x5c80000, 0x5a00000, 0x5880000,
0x5800000, 0x5980000, 0x5d80000, 0x5a80000, 0x5900000,
0x5b00000, 0x5d00000, 0x5c00000, 0x5e80000, 0x4b80000,
0x4f80000, 0x4e00000, 0x4f00000, 0x4c80000, 0x4a00000,
0x4880000, 0x4800000, 0x4980000, 0x4d80000, 0x4a80000,
0x4900000, 0x4b00000, 0x4d00000, 0x4c00000, 0x4e80000,
0x1b80000, 0x1f80000, 0x1e00000, 0x1f00000, 0x1c80000,
0x1a00000, 0x1880000, 0x1800000, 0x1980000, 0x1d80000,
0x1a80000, 0x1900000, 0x1b00000, 0x1d00000, 0x1c00000,
0x1e80000
}, {
0xb8000003, 0xb0000003, 0xa0000003, 0xd8000003, 0xc8000003,
0xe0000003, 0x90000003, 0xd0000003, 0x88000003, 0xc0000003,
0x80000003, 0xf0000003, 0xf8000003, 0xe8000003, 0x98000003,
0xa8000003, 0x38000003, 0x30000003, 0x20000003, 0x58000003,
0x48000003, 0x60000003, 0x10000003, 0x50000003, 0x8000003,
0x40000003, 0x3, 0x70000003, 0x78000003, 0x68000003,
0x18000003, 0x28000003, 0x38000001, 0x30000001, 0x20000001,
0x58000001, 0x48000001, 0x60000001, 0x10000001, 0x50000001,
0x8000001, 0x40000001, 0x1, 0x70000001, 0x78000001,
0x68000001, 0x18000001, 0x28000001, 0x38000002, 0x30000002,
0x20000002, 0x58000002, 0x48000002, 0x60000002, 0x10000002,
0x50000002, 0x8000002, 0x40000002, 0x2, 0x70000002,
0x78000002, 0x68000002, 0x18000002, 0x28000002, 0xb8000006,
0xb0000006, 0xa0000006, 0xd8000006, 0xc8000006, 0xe0000006,
0x90000006, 0xd0000006, 0x88000006, 0xc0000006, 0x80000006,
0xf0000006, 0xf8000006, 0xe8000006, 0x98000006, 0xa8000006,
0xb8000004, 0xb0000004, 0xa0000004, 0xd8000004, 0xc8000004,
0xe0000004, 0x90000004, 0xd0000004, 0x88000004, 0xc0000004,
0x80000004, 0xf0000004, 0xf8000004, 0xe8000004, 0x98000004,
0xa8000004, 0xb8000007, 0xb0000007, 0xa0000007, 0xd8000007,
0xc8000007, 0xe0000007, 0x90000007, 0xd0000007, 0x88000007,
0xc0000007, 0x80000007, 0xf0000007, 0xf8000007, 0xe8000007,
0x98000007, 0xa8000007, 0x38000000, 0x30000000, 0x20000000,
0x58000000, 0x48000000, 0x60000000, 0x10000000, 0x50000000,
0x8000000, 0x40000000, 0x0, 0x70000000, 0x78000000,
0x68000000, 0x18000000, 0x28000000, 0x38000005, 0x30000005,
0x20000005, 0x58000005, 0x48000005, 0x60000005, 0x10000005,
0x50000005, 0x8000005, 0x40000005, 0x5, 0x70000005,
0x78000005, 0x68000005, 0x18000005, 0x28000005, 0xb8000000,
0xb0000000, 0xa0000000, 0xd8000000, 0xc8000000, 0xe0000000,
0x90000000, 0xd0000000, 0x88000000, 0xc0000000, 0x80000000,
0xf0000000, 0xf8000000, 0xe8000000, 0x98000000, 0xa8000000,
0xb8000002, 0xb0000002, 0xa0000002, 0xd8000002, 0xc8000002,
0xe0000002, 0x90000002, 0xd0000002, 0x88000002, 0xc0000002,
0x80000002, 0xf0000002, 0xf8000002, 0xe8000002, 0x98000002,
0xa8000002, 0xb8000005, 0xb0000005, 0xa0000005, 0xd8000005,
0xc8000005, 0xe0000005, 0x90000005, 0xd0000005, 0x88000005,
0xc0000005, 0x80000005, 0xf0000005, 0xf8000005, 0xe8000005,
0x98000005, 0xa8000005, 0x38000004, 0x30000004, 0x20000004,
0x58000004, 0x48000004, 0x60000004, 0x10000004, 0x50000004,
0x8000004, 0x40000004, 0x4, 0x70000004, 0x78000004,
0x68000004, 0x18000004, 0x28000004, 0x38000007, 0x30000007,
0x20000007, 0x58000007, 0x48000007, 0x60000007, 0x10000007,
0x50000007, 0x8000007, 0x40000007, 0x7, 0x70000007,
0x78000007, 0x68000007, 0x18000007, 0x28000007, 0x38000006,
0x30000006, 0x20000006, 0x58000006, 0x48000006, 0x60000006,
0x10000006, 0x50000006, 0x8000006, 0x40000006, 0x6,
0x70000006, 0x78000006, 0x68000006, 0x18000006, 0x28000006,
0xb8000001, 0xb0000001, 0xa0000001, 0xd8000001, 0xc8000001,
0xe0000001, 0x90000001, 0xd0000001, 0x88000001, 0xc0000001,
0x80000001, 0xf0000001, 0xf8000001, 0xe8000001, 0x98000001,
0xa8000001
}, {
0xe8, 0xf0, 0xa0, 0x88, 0xb8, 0x80, 0xa8, 0xd0, 0x98, 0xe0,
0xc0, 0xf8, 0xb0, 0x90, 0xc8, 0xd8, 0x1e8, 0x1f0, 0x1a0, 0x188,
0x1b8, 0x180, 0x1a8, 0x1d0, 0x198, 0x1e0, 0x1c0, 0x1f8, 0x1b0, 0x190,
0x1c8, 0x1d8, 0x568, 0x570, 0x520, 0x508, 0x538, 0x500, 0x528, 0x550,
0x518, 0x560, 0x540, 0x578, 0x530, 0x510, 0x548, 0x558, 0x4e8, 0x4f0,
0x4a0, 0x488, 0x4b8, 0x480, 0x4a8, 0x4d0, 0x498, 0x4e0, 0x4c0, 0x4f8,
0x4b0, 0x490, 0x4c8, 0x4d8, 0x2e8, 0x2f0, 0x2a0, 0x288, 0x2b8, 0x280,
0x2a8, 0x2d0, 0x298, 0x2e0, 0x2c0, 0x2f8, 0x2b0, 0x290, 0x2c8, 0x2d8,
0x5e8, 0x5f0, 0x5a0, 0x588, 0x5b8, 0x580, 0x5a8, 0x5d0, 0x598, 0x5e0,
0x5c0, 0x5f8, 0x5b0, 0x590, 0x5c8, 0x5d8, 0x268, 0x270, 0x220, 0x208,
0x238, 0x200, 0x228, 0x250, 0x218, 0x260, 0x240, 0x278, 0x230, 0x210,
0x248, 0x258, 0x7e8, 0x7f0, 0x7a0, 0x788, 0x7b8, 0x780, 0x7a8, 0x7d0,
0x798, 0x7e0, 0x7c0, 0x7f8, 0x7b0, 0x790, 0x7c8, 0x7d8, 0x468, 0x470,
0x420, 0x408, 0x438, 0x400, 0x428, 0x450, 0x418, 0x460, 0x440, 0x478,
0x430, 0x410, 0x448, 0x458, 0x368, 0x370, 0x320, 0x308, 0x338, 0x300,
0x328, 0x350, 0x318, 0x360, 0x340, 0x378, 0x330, 0x310, 0x348, 0x358,
0x3e8, 0x3f0, 0x3a0, 0x388, 0x3b8, 0x380, 0x3a8, 0x3d0, 0x398, 0x3e0,
0x3c0, 0x3f8, 0x3b0, 0x390, 0x3c8, 0x3d8, 0x768, 0x770, 0x720, 0x708,
0x738, 0x700, 0x728, 0x750, 0x718, 0x760, 0x740, 0x778, 0x730, 0x710,
0x748, 0x758, 0x6e8, 0x6f0, 0x6a0, 0x688, 0x6b8, 0x680, 0x6a8, 0x6d0,
0x698, 0x6e0, 0x6c0, 0x6f8, 0x6b0, 0x690, 0x6c8, 0x6d8, 0x68, 0x70,
0x20, 0x8, 0x38, 0x0, 0x28, 0x50, 0x18, 0x60, 0x40, 0x78,
0x30, 0x10, 0x48, 0x58, 0x168, 0x170, 0x120, 0x108, 0x138, 0x100,
0x128, 0x150, 0x118, 0x160, 0x140, 0x178, 0x130, 0x110, 0x148, 0x158,
0x668, 0x670, 0x620, 0x608, 0x638, 0x600, 0x628, 0x650, 0x618, 0x660,
0x640, 0x678, 0x630, 0x610, 0x648, 0x658
}
};
#endif /* GENERATE_GOST94_LOOKUP_TABLE */
rhash-1.4.6/librhash/tiger.h 0000664 0000000 0000000 00000001521 14703622112 014403 0 ustar root root /* tiger.h */
#ifndef TIGER_H
#define TIGER_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define tiger_block_size 64
#define tiger_hash_length 24
/* algorithm context */
typedef struct tiger_ctx
{
/* the order of the fields slightly influence the algorithm speed */
uint64_t hash[3]; /* algorithm 192-bit state */
unsigned char message[tiger_block_size]; /* 512-bit buffer for leftovers */
uint64_t length; /* processed message length */
} tiger_ctx;
/* hash functions */
#ifndef NO_TIGER2
void rhash_tiger2_init(tiger_ctx* ctx);
#endif /* NO_TIGER2 */
void rhash_tiger_init(tiger_ctx* ctx);
void rhash_tiger_update(tiger_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_tiger_final(tiger_ctx* ctx, unsigned char result[24]);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* TIGER_H */
rhash-1.4.6/librhash/test_utils.h 0000664 0000000 0000000 00000001454 15010476501 015476 0 ustar root root /** @file test_utils.h timer and benchmarking functions */
#ifndef TEST_UTILS_H
#define TEST_UTILS_H
#include
#ifdef __cplusplus
extern "C" {
#endif
/**
* Benchmarking flag: don't print intermediate benchmarking info.
*/
#define RHASH_BENCHMARK_QUIET 1
/**
* Benchmarking flag: measure the CPU "clocks per byte" speed.
*/
#define RHASH_BENCHMARK_CPB 2
/**
* Benchmarking flag: print benchmark result in tab-delimed format.
*/
#define RHASH_BENCHMARK_RAW 4
/**
* Benchmark a hash algorithm.
*
* @param hash_id hash algorithm identifier
* @param flags benchmark flags
* @param output the stream to print results
*/
void test_run_benchmark(unsigned hash_id, unsigned flags,
FILE* output);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* TEST_UTILS_H */
rhash-1.4.6/librhash/ed2k.c 0000664 0000000 0000000 00000010444 14703622112 014115 0 ustar root root /* ed2k.c - an implementation of EDonkey 2000 Hash Algorithm.
*
* Copyright (c) 2006, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* This file implements eMule-compatible version of algorithm.
* Note that eDonkey and eMule ed2k hashes are different only for
* files containing exactly multiple of 9728000 bytes.
*
* The file data is divided into full chunks of 9500 KiB (9728000 bytes) plus
* a remainder chunk, and a separate 128-bit MD4 hash is computed for each.
* If the file length is an exact multiple of 9500 KiB, the remainder zero
* size chunk is still used at the end of the hash list. The ed2k hash is
* computed by concatenating the chunks' MD4 hashes in order and hashing the
* result using MD4. Although, if the file is composed of a single non-full
* chunk, its MD4 hash is returned with no further modifications.
*
* See http://en.wikipedia.org/wiki/EDonkey_network for algorithm description.
*/
#include
#include "ed2k.h"
/* each hashed file is divided into 9500 KiB sized chunks */
#define ED2K_CHUNK_SIZE 9728000
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_ed2k_init(ed2k_ctx* ctx)
{
rhash_md4_init(&ctx->md4_context);
rhash_md4_init(&ctx->md4_context_inner);
ctx->not_emule = 0;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_ed2k_update(ed2k_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned char chunk_md4_hash[16];
unsigned blockleft = ED2K_CHUNK_SIZE - (unsigned)ctx->md4_context_inner.length;
/* note: eMule-compatible algorithm hashes by md4_inner
* the messages which sizes are multiple of 9728000
* and then processes obtained hash by external md4 */
while ( size >= blockleft )
{
if (size == blockleft && ctx->not_emule) break;
/* if internal ed2k chunk is full, then finalize it */
rhash_md4_update(&ctx->md4_context_inner, msg, blockleft);
msg += blockleft;
size -= blockleft;
blockleft = ED2K_CHUNK_SIZE;
/* just finished an ed2k chunk, updating md4_external context */
rhash_md4_final(&ctx->md4_context_inner, chunk_md4_hash);
rhash_md4_update(&ctx->md4_context, chunk_md4_hash, 16);
rhash_md4_init(&ctx->md4_context_inner);
}
if (size) {
/* hash leftovers */
rhash_md4_update(&ctx->md4_context_inner, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_ed2k_final(ed2k_ctx* ctx, unsigned char result[16])
{
/* check if hashed message size is greater or equal to ED2K_CHUNK_SIZE */
if ( ctx->md4_context.length ) {
/* note: weird eMule algorithm always processes the inner
* md4 context, no matter if it contains data or is empty */
/* if any data are left in the md4_context_inner */
if ( (size_t)ctx->md4_context_inner.length > 0 || !ctx->not_emule)
{
/* emule algorithm processes aditional block, even if it's empty */
unsigned char md4_digest_inner[16];
rhash_md4_final(&ctx->md4_context_inner, md4_digest_inner);
rhash_md4_update(&ctx->md4_context, md4_digest_inner, 16);
}
/* first call final to flush md4 buffer and finalize the hash value */
rhash_md4_final(&ctx->md4_context, result);
/* store the calculated ed2k hash in the md4_context_inner.hash */
memcpy(&ctx->md4_context_inner.hash, &ctx->md4_context.hash, md4_hash_size);
} else {
/* return just the message MD4 hash */
if (result) rhash_md4_final(&ctx->md4_context_inner, result);
}
}
rhash-1.4.6/librhash/md4.h 0000664 0000000 0000000 00000001271 14703622112 013757 0 ustar root root /* md4.h */
#ifndef MD4_HIDER
#define MD4_HIDER
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define md4_block_size 64
#define md4_hash_size 16
/* algorithm context */
typedef struct md4_ctx
{
unsigned hash[4]; /* 128-bit algorithm internal hashing state */
unsigned message[md4_block_size / 4]; /* 512-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
} md4_ctx;
/* hash functions */
void rhash_md4_init(md4_ctx* ctx);
void rhash_md4_update(md4_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_md4_final(md4_ctx* ctx, unsigned char result[16]);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* MD4_HIDER */
rhash-1.4.6/librhash/aich.h 0000664 0000000 0000000 00000003037 14703622112 014201 0 ustar root root /* aich.h */
#ifndef AICH_H
#define AICH_H
#include "algorithms.h"
#include "sha1.h"
#ifdef __cplusplus
extern "C" {
#endif
/* algorithm context */
typedef struct aich_ctx
{
sha1_ctx sha1_context; /* context used to hash tree leaves */
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
unsigned long reserved; /* need more space for openssl sha1 context */
#endif
unsigned index; /* algorithm position in the current ed2k chunk */
int error; /* non-zero if a memory error occurred, 0 otherwise */
size_t chunks_count; /* the number of ed2k chunks hashed */
size_t allocated; /* allocated size of the chunk_table */
unsigned char (*block_hashes)[sha1_hash_size];
void** chunk_table; /* table of chunk hashes */
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
rhash_hashing_methods sha1_methods;
#endif
} aich_ctx;
/* hash functions */
void rhash_aich_init(aich_ctx* ctx);
void rhash_aich_update(aich_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_aich_final(aich_ctx* ctx, unsigned char result[20]);
#if !defined(NO_IMPORT_EXPORT)
size_t rhash_aich_export(const aich_ctx* ctx, void* out, size_t size);
size_t rhash_aich_import(aich_ctx* ctx, const void* in, size_t size);
#endif /* !defined(NO_IMPORT_EXPORT) */
/* Clean up context by freeing allocated memory.
* The function is called automatically by rhash_aich_final.
* Shall be called when aborting hash calculations. */
void rhash_aich_cleanup(aich_ctx* ctx);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* AICH_H */
rhash-1.4.6/librhash/whirlpool.h 0000644 0000000 0000000 00000001711 13135503555 015316 0 ustar root root /* whirlpool.h */
#ifndef WHIRLPOOL_H
#define WHIRLPOOL_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define whirlpool_block_size 64
/* algorithm context */
typedef struct whirlpool_ctx
{
uint64_t hash[8]; /* 512-bit algorithm internal hashing state */
unsigned char message[whirlpool_block_size]; /* 512-bit buffer to hash */
/* Note: original algorith uses 256-bit counter, allowing to hash up to
2^256 bits sized message. For optimization we use here 64-bit counter,
thus reducing maximal message size to 2^64 bits = 2 Exbibytes = 2^21 TiB) */
uint64_t length; /* number of processed bytes */
} whirlpool_ctx;
/* hash functions */
void rhash_whirlpool_init(whirlpool_ctx* ctx);
void rhash_whirlpool_update(whirlpool_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_whirlpool_final(whirlpool_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* WHIRLPOOL_H */
rhash-1.4.6/librhash/algorithms.h 0000664 0000000 0000000 00000011040 15010476501 015440 0 ustar root root /* algorithms.h - rhash library algorithms */
#ifndef RHASH_ALGORITHMS_H
#define RHASH_ALGORITHMS_H
#include "rhash.h"
#include "byte_order.h"
#include
#ifdef __cplusplus
extern "C" {
#endif
#ifndef RHASH_API
/* modifier for RHash library functions */
# define RHASH_API
#endif
/**
* Bit flag: default hash output format is base32.
*/
#define RHASH_INFO_BASE32 1
/**
* Information about a hash function.
*/
typedef struct rhash_info
{
/**
* Hash function indentifier.
*/
unsigned hash_id;
/**
* Flags bitmask, including RHASH_INFO_BASE32 bit.
*/
unsigned flags;
/**
The size of of the raw message digest in bytes.
*/
size_t digest_size;
/**
* The hash function name.
*/
const char* name;
/**
* The corresponding paramenter name in a magnet link.
*/
const char* magnet_name;
} rhash_info;
typedef void (*pinit_t)(void* ctx);
typedef void (*pupdate_t)(void* ctx, const void* msg, size_t size);
typedef void (*pfinal_t)(void* ctx, unsigned char* result);
typedef void (*pcleanup_t)(void* ctx);
/**
* Information about a hash function
*/
typedef struct rhash_hash_info
{
rhash_info* info;
size_t context_size;
ptrdiff_t digest_diff;
pinit_t init;
pupdate_t update;
pfinal_t final;
pcleanup_t cleanup;
} rhash_hash_info;
/**
* Information on a hash function and its context
*/
typedef struct rhash_vector_item
{
const struct rhash_hash_info* hash_info;
void* context;
} rhash_vector_item;
/**
* The rhash context containing contexts for several hash functions
*/
typedef struct rhash_context_ext
{
struct rhash_context rc;
unsigned hash_vector_size; /* number of contained hash sums */
unsigned flags;
volatile unsigned state;
rhash_callback_t callback;
void* callback_data;
void* bt_ctx;
rhash_vector_item vector[]; /* contexts of contained hash sums */
} rhash_context_ext;
extern rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT];
extern rhash_hash_info* rhash_info_table;
extern int rhash_info_size;
extern rhash_info info_crc32;
extern rhash_info info_crc32c;
extern rhash_info info_md4;
extern rhash_info info_md5;
extern rhash_info info_sha1;
extern rhash_info info_tiger;
extern rhash_info info_tth ;
extern rhash_info info_btih;
extern rhash_info info_ed2k;
extern rhash_info info_aich;
extern rhash_info info_whirlpool;
extern rhash_info info_rmd160;
extern rhash_info info_gost;
extern rhash_info info_gostpro;
extern rhash_info info_has160;
extern rhash_info info_snf128;
extern rhash_info info_snf256;
extern rhash_info info_sha224;
extern rhash_info info_sha256;
extern rhash_info info_sha384;
extern rhash_info info_sha512;
extern rhash_info info_sha3_224;
extern rhash_info info_sha3_256;
extern rhash_info info_sha3_384;
extern rhash_info info_sha3_512;
extern rhash_info info_edr256;
extern rhash_info info_edr512;
#define IS_EXTENDED_HASH_ID(hash_id) ((hash_id) & RHASH_EXTENDED_BIT)
#define GET_EXTENDED_HASH_ID_INDEX(hash_id) ((unsigned)((hash_id) & ~RHASH_EXTENDED_BIT))
#define EXTENDED_HASH_ID(index) ((unsigned)(RHASH_EXTENDED_BIT | (index)))
#define EXTENDED_SHA1 EXTENDED_HASH_ID(3)
#define EXTENDED_BTIH EXTENDED_HASH_ID(6)
#define EXTENDED_WHIRLPOOL EXTENDED_HASH_ID(9)
/* rhash_info flags */
#define F_BS32 1 /* default output in base32 */
#define F_SWAP32 2 /* big endian flag */
#define F_SWAP64 4
#define F_SPCEXP 8 /* needs special import/export logic */
/* define endianness flags */
#if IS_LITTLE_ENDIAN
#define F_LE32 0
#define F_LE64 0
#define F_BE32 F_SWAP32
#define F_BE64 F_SWAP64
#else
#define F_LE32 F_SWAP32
#define F_LE64 F_SWAP64
#define F_BE32 0
#define F_BE64 0
#endif
void rhash_init_algorithms(void);
const rhash_hash_info* rhash_hash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */
const unsigned* rhash_get_all_hash_ids(unsigned all_id, size_t* count);
#if !defined(NO_IMPORT_EXPORT)
size_t rhash_export_alg(unsigned hash_id, const void* ctx, void* out, size_t size);
size_t rhash_import_alg(unsigned hash_id, void* ctx, const void* in, size_t size);
#endif /* !defined(NO_IMPORT_EXPORT) */
#if defined(OPENSSL_RUNTIME) && !defined(USE_OPENSSL)
# define USE_OPENSSL
#endif
#ifdef USE_OPENSSL
typedef struct rhash_hashing_methods
{
pinit_t init;
pupdate_t update;
pfinal_t final;
} rhash_hashing_methods;
enum rhash_methods_type
{
METHODS_RHASH,
METHODS_OPENSSL,
METHODS_SELECTED,
};
void rhash_load_sha1_methods(rhash_hashing_methods* methods, int methods_type);
#define ARE_OPENSSL_METHODS(methods) ((methods).init != (void (*)(void*))&rhash_sha1_init)
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_ALGORITHMS_H */
rhash-1.4.6/librhash/plug_openssl.c 0000664 0000000 0000000 00000024761 15010476501 016012 0 ustar root root /* plug_openssl.c - plug-in openssl algorithms
*
* Copyright (c) 2011, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
#include "util.h"
#include "plug_openssl.h"
#include
#include
#include
#ifndef OPENSSL_NO_MD4
# include
# define PLUGIN_MD4 RHASH_MD4
#else
# define PLUGIN_MD4 0
#endif
#ifndef OPENSSL_NO_MD5
# include
# define PLUGIN_MD5 RHASH_MD5
#else
# define PLUGIN_MD5 0
#endif
#ifndef OPENSSL_NO_SHA
#include
# define PLUGIN_SHA1_SHA2 \
(RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512)
#else
# define PLUGIN_SHA1_SHA2 0
#endif
#ifndef OPENSSL_NO_RIPEMD
# include
# define PLUGIN_RIPEMD160 RHASH_RIPEMD160
#else
# define PLUGIN_RIPEMD160 0
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
# include
# define PLUGIN_WHIRLPOOL RHASH_WHIRLPOOL
#else
# define PLUGIN_WHIRLPOOL 0
#endif
#if defined(OPENSSL_RUNTIME)
# if defined(_WIN32) || defined(__CYGWIN__)
# define WIN32_LEAN_AND_MEAN
# include
# else
# include
# endif
#endif
#define OPENSSL_DEFAULT_HASH_MASK (PLUGIN_MD5 | PLUGIN_SHA1_SHA2)
#define PLUGIN_SUPPORTED_HASH_MASK \
(PLUGIN_MD4 | PLUGIN_MD5 | PLUGIN_SHA1_SHA2 | PLUGIN_RIPEMD160 | PLUGIN_WHIRLPOOL)
/* the mask of ids of hashing algorithms to use from the OpenSSL library */
unsigned openssl_enabled_hash_mask = OPENSSL_DEFAULT_HASH_MASK;
unsigned openssl_available_algorithms_hash_mask = 0;
#ifdef OPENSSL_RUNTIME
typedef void (*os_fin_t)(void*, void*);
# define OS_METHOD(name) os_fin_t p##name##_final = 0
OS_METHOD(MD4);
OS_METHOD(MD5);
OS_METHOD(RIPEMD160);
OS_METHOD(SHA1);
OS_METHOD(SHA224);
OS_METHOD(SHA256);
OS_METHOD(SHA384);
OS_METHOD(SHA512);
OS_METHOD(WHIRLPOOL);
# define CALL_FINAL(name, result, ctx) p##name##_final(result, ctx)
# define HASH_INFO_METHODS(name) 0, 0, wrap##name##_Final, 0
#else
/* for load-time linking */
# define CALL_FINAL(name, result, ctx) name##_Final(result, ctx)
# define HASH_INFO_METHODS(name) (pinit_t)(void(*)(void))name##_Init, (pupdate_t)(void(*)(void))name##_Update, wrap##name##_Final, 0
#endif
/* The openssl *_Update functions have the same signature as RHash ones:
* void update_func(void* ctx, const void* msg, size_t size),
* so we can use them in RHash directly. But the _Final functions
* have different order of arguments, so we need to wrap them. */
#define WRAP_FINAL(name, CTX_TYPE) \
static void wrap##name##_Final(void* ctx, unsigned char* result) { \
CALL_FINAL(name, result, (CTX_TYPE*)ctx); \
}
#ifndef OPENSSL_NO_MD4
WRAP_FINAL(MD4, MD4_CTX)
#endif
#ifndef OPENSSL_NO_MD5
WRAP_FINAL(MD5, MD5_CTX)
#endif
#ifndef OPENSSL_NO_SHA
WRAP_FINAL(SHA1, SHA_CTX)
WRAP_FINAL(SHA224, SHA256_CTX)
WRAP_FINAL(SHA256, SHA256_CTX)
WRAP_FINAL(SHA384, SHA512_CTX)
WRAP_FINAL(SHA512, SHA512_CTX)
#endif
#ifndef OPENSSL_NO_RIPEMD
WRAP_FINAL(RIPEMD160, RIPEMD160_CTX)
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
/* wrapping WHIRLPOOL_Final requires special attention. */
static void wrapWHIRLPOOL_Final(void* ctx, unsigned char* result)
{
/* must pass NULL as the result argument, otherwise ctx will be zeroed */
CALL_FINAL(WHIRLPOOL, NULL, ctx);
memcpy(result, ((WHIRLPOOL_CTX*)ctx)->H.c, 64);
}
rhash_info info_ossl_whirlpool = { EXTENDED_WHIRLPOOL, 0, 64, "WHIRLPOOL", "whirlpool" };
#endif
#define NO_HASH_INFO { 0, 0, 0, 0, 0, 0, 0 }
/* The table of supported OpenSSL hash functions */
rhash_hash_info rhash_openssl_hash_info[9] =
{
#ifndef OPENSSL_NO_MD4
{ &info_md4, sizeof(MD4_CTX), offsetof(MD4_CTX, A), HASH_INFO_METHODS(MD4) }, /* 128 bit */
#else
NO_HASH_INFO,
#endif
#ifndef OPENSSL_NO_MD5
{ &info_md5, sizeof(MD5_CTX), offsetof(MD5_CTX, A), HASH_INFO_METHODS(MD5) }, /* 128 bit */
#else
NO_HASH_INFO,
#endif
#ifndef OPENSSL_NO_SHA
{ &info_sha1, sizeof(SHA_CTX), offsetof(SHA_CTX, h0), HASH_INFO_METHODS(SHA1) }, /* 160 bit */
{ &info_sha224, sizeof(SHA256_CTX), offsetof(SHA256_CTX, h), HASH_INFO_METHODS(SHA224) }, /* 224 bit */
{ &info_sha256, sizeof(SHA256_CTX), offsetof(SHA256_CTX, h), HASH_INFO_METHODS(SHA256) }, /* 256 bit */
{ &info_sha384, sizeof(SHA512_CTX), offsetof(SHA512_CTX, h), HASH_INFO_METHODS(SHA384) }, /* 384 bit */
{ &info_sha512, sizeof(SHA512_CTX), offsetof(SHA512_CTX, h), HASH_INFO_METHODS(SHA512) }, /* 512 bit */
#else
NO_HASH_INFO, NO_HASH_INFO, NO_HASH_INFO, NO_HASH_INFO, NO_HASH_INFO,
#endif
#ifndef OPENSSL_NO_RIPEMD
{ &info_rmd160, sizeof(RIPEMD160_CTX), offsetof(RIPEMD160_CTX, A), HASH_INFO_METHODS(RIPEMD160) }, /* 160 bit */
#else
NO_HASH_INFO,
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
{ &info_ossl_whirlpool, sizeof(WHIRLPOOL_CTX), offsetof(WHIRLPOOL_CTX, H.c), HASH_INFO_METHODS(WHIRLPOOL) }, /* 512 bit */
#else
NO_HASH_INFO,
#endif
};
/* The rhash_updated_hash_info static array initialized by rhash_plug_openssl() replaces
* rhash internal algorithms table. It is kept in an uninitialized-data segment
* taking no space in the executable. */
rhash_hash_info rhash_updated_hash_info[RHASH_HASH_COUNT];
#ifdef OPENSSL_RUNTIME
#if (defined(_WIN32) || defined(__CYGWIN__)) /* __CYGWIN__ is also defined in MSYS */
# define GET_DLSYM(name) (void(*)(void))GetProcAddress(handle, name)
#else /* _WIN32 */
# define GET_DLSYM(name) dlsym(handle, name)
#endif /* _WIN32 */
#define LOAD_ADDR(n, name) \
p##name##_final = (os_fin_t)GET_DLSYM(#name "_Final"); \
rhash_openssl_hash_info[n].update = (pupdate_t)GET_DLSYM(#name "_Update"); \
rhash_openssl_hash_info[n].init = (rhash_openssl_hash_info[n].update && p##name##_final ? \
(pinit_t)GET_DLSYM(#name "_Init") : 0);
/**
* Load OpenSSL DLL at runtime, store pointers to functions of all
* supported hash algorithms.
*
* @return 1 on success, 0 if the library not found
*/
static int load_openssl_runtime(void)
{
#if defined(_WIN32) || defined(__CYGWIN__)
HMODULE handle = 0;
size_t i;
# if defined(_WIN32)
static const char* libNames[] = {
"libeay32.dll",
};
# elif defined(__MSYS__) /* MSYS also defines __CYGWIN__ */
static const char* libNames[] = {
"msys-crypto-1.1.dll",
"msys-crypto-1.0.0.dll",
};
# elif defined(__CYGWIN__)
static const char* libNames[] = {
"cygcrypto-1.1.dll",
"cygcrypto-1.0.0.dll",
};
# endif
/* suppress the error popup dialogs */
UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
SetErrorMode(oldErrorMode | SEM_FAILCRITICALERRORS);
for (i = 0; !handle && i < RHASH_COUNTOF(libNames); i++)
handle = LoadLibraryA(libNames[i]);
SetErrorMode(oldErrorMode); /* restore error mode */
#else
static const char* libNames[] = {
"libcrypto.so.3",
"libcrypto.so.1.1",
"libcrypto.so.1.0.2",
"libcrypto.so.1.0.0",
"libcrypto.so.0.9.8",
"libcrypto.so",
};
void* handle = 0;
size_t i;
for (i = 0; !handle && i < RHASH_COUNTOF(libNames); i++)
handle = dlopen(libNames[i], RTLD_NOW);
#endif /* defined(_WIN32) || defined(__CYGWIN__) */
if (!handle)
return 0; /* could not load OpenSSL */
#ifndef OPENSSL_NO_MD4
LOAD_ADDR(0, MD4)
#endif
#ifndef OPENSSL_NO_MD5
LOAD_ADDR(1, MD5);
#endif
#ifndef OPENSSL_NO_SHA
LOAD_ADDR(2, SHA1);
LOAD_ADDR(3, SHA224);
LOAD_ADDR(4, SHA256);
LOAD_ADDR(5, SHA384);
LOAD_ADDR(6, SHA512);
#endif
#ifndef OPENSSL_NO_RIPEMD
LOAD_ADDR(7, RIPEMD160);
#endif
#ifndef OPENSSL_NO_WHIRLPOOL
LOAD_ADDR(8, WHIRLPOOL);
#endif
return 1;
}
#endif /* OPENSSL_RUNTIME */
/**
* Replace several RHash internal algorithms with the OpenSSL ones.
* It can replace MD4/MD5, SHA1/SHA2, RIPEMD, WHIRLPOOL.
*
* @return 1 on success, 0 if OpenSSL library not found
*/
int rhash_plug_openssl(void)
{
size_t i;
uint64_t bit;
unsigned bit_index;
assert(rhash_info_size <= RHASH_HASH_COUNT); /* buffer-overflow protection */
if ((openssl_enabled_hash_mask & PLUGIN_SUPPORTED_HASH_MASK) == 0)
return 1; /* do not load OpenSSL */
#ifdef OPENSSL_RUNTIME
if (!load_openssl_runtime())
return 0;
#endif
memcpy(rhash_updated_hash_info, rhash_info_table, sizeof(rhash_updated_hash_info));
/* replace internal rhash methods with the OpenSSL ones */
for (i = 0; i < (int)RHASH_COUNTOF(rhash_openssl_hash_info); i++)
{
rhash_hash_info* method = &rhash_openssl_hash_info[i];
if (!method->init)
continue;
bit_index = GET_EXTENDED_HASH_ID_INDEX(method->info->hash_id);
bit = I64(1) << bit_index;
openssl_available_algorithms_hash_mask |= bit;
if ((openssl_enabled_hash_mask & bit) == 0)
continue;
assert(method->info->hash_id == rhash_updated_hash_info[bit_index].info->hash_id);
memcpy(&rhash_updated_hash_info[bit_index], method, sizeof(rhash_hash_info));
}
rhash_info_table = rhash_updated_hash_info;
return 1;
}
/**
* Returns bit-mask of OpenSSL algorithms supported by the plugin.
*
* @return the bit-mask of available OpenSSL algorithms
*/
unsigned rhash_get_openssl_supported_hash_mask(void)
{
return PLUGIN_SUPPORTED_HASH_MASK;
}
/**
* Returns bit-mask of available OpenSSL algorithms, if the OpenSSL has
* been successfully loaded, zero otherwise. Only supported by the plugin
* algorithms are listed.
*
* @return the bit-mask of available OpenSSL algorithms
*/
unsigned rhash_get_openssl_available_hash_mask(void)
{
return openssl_available_algorithms_hash_mask;
}
/**
* Returns bit-mask of enabled OpenSSL algorithms, if the OpenSSL has
* been successfully loaded, zero otherwise.
* Only available algorithms are listed.
*
* @return the bit-mask of enabled OpenSSL algorithms
*/
unsigned rhash_get_openssl_enabled_hash_mask(void)
{
return openssl_enabled_hash_mask & openssl_available_algorithms_hash_mask;
}
/**
* Set bit-mask of enabled OpenSSL algorithms.
*
* @return the bit-mask of enabled OpenSSL algorithms
*/
void rhash_set_openssl_enabled_hash_mask(unsigned mask)
{
mask &= (openssl_available_algorithms_hash_mask ?
openssl_available_algorithms_hash_mask :
PLUGIN_SUPPORTED_HASH_MASK);
openssl_enabled_hash_mask = mask;
}
#else
typedef int dummy_declaration_required_by_strict_iso_c;
#endif /* defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) */
rhash-1.4.6/librhash/blake2b.h 0000664 0000000 0000000 00000001060 14703622112 014571 0 ustar root root /* blake2b.h */
#ifndef BLAKE2B_H
#define BLAKE2B_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define blake2b_block_size 128
#define blake2b_hash_size 64
typedef struct blake2b_ctx
{
uint64_t hash[8];
uint64_t message[16];
uint64_t length;
} blake2b_ctx;
void rhash_blake2b_init(blake2b_ctx* ctx);
void rhash_blake2b_update(blake2b_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_blake2b_final(blake2b_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* BLAKE2B_H */
rhash-1.4.6/librhash/sha3.h 0000664 0000000 0000000 00000002665 14703622112 014141 0 ustar root root /* sha3.h */
#ifndef RHASH_SHA3_H
#define RHASH_SHA3_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sha3_224_hash_size 28
#define sha3_256_hash_size 32
#define sha3_384_hash_size 48
#define sha3_512_hash_size 64
#define sha3_max_permutation_size 25
#define sha3_max_rate_in_qwords 24
/**
* SHA3 Algorithm context.
*/
typedef struct sha3_ctx
{
/* 1600 bits algorithm hashing state */
uint64_t hash[sha3_max_permutation_size];
/* 1536-bit buffer for leftovers */
uint64_t message[sha3_max_rate_in_qwords];
/* count of bytes in the message[] buffer */
unsigned rest;
/* size of a message block processed at once */
unsigned block_size;
} sha3_ctx;
/* methods for calculating the hash function */
void rhash_sha3_224_init(sha3_ctx* ctx);
void rhash_sha3_256_init(sha3_ctx* ctx);
void rhash_sha3_384_init(sha3_ctx* ctx);
void rhash_sha3_512_init(sha3_ctx* ctx);
void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result);
#ifdef USE_KECCAK
#define rhash_keccak_224_init rhash_sha3_224_init
#define rhash_keccak_256_init rhash_sha3_256_init
#define rhash_keccak_384_init rhash_sha3_384_init
#define rhash_keccak_512_init rhash_sha3_512_init
#define rhash_keccak_update rhash_sha3_update
void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_SHA3_H */
rhash-1.4.6/librhash/test_utils.c 0000664 0000000 0000000 00000016320 15010476501 015467 0 ustar root root /* test_utils.c - functions to benchmark hash algorithms,
*
* Copyright (c) 2010, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "test_utils.h"
#ifdef USE_RHASH_DLL
# define RHASH_API __declspec(dllimport)
#endif
#include "byte_order.h"
#include "rhash.h"
#if defined(_WIN32) || defined(__CYGWIN__)
/**
* Platform-dependent time delta.
*/
typedef unsigned long long timedelta_t;
#else
# include /* for timeval */
/**
* Platform-dependent time delta.
*/
typedef struct timeval timedelta_t;
#endif
/* DEFINE read_tsc() if possible */
#if (defined(CPU_IA32)) || defined(CPU_X64)
#if defined( _MSC_VER ) /* if MS VC */
# include
# pragma intrinsic( __rdtsc )
# define read_tsc() __rdtsc()
# define HAVE_TSC
#elif defined( __GNUC__ ) /* if GCC */
static uint64_t read_tsc(void) {
unsigned long lo, hi;
__asm volatile("rdtsc" : "=a" (lo), "=d" (hi));
return (((uint64_t)hi) << 32) + lo;
}
# define HAVE_TSC
#endif /* _MSC_VER, __GNUC__ */
#endif /* CPU_IA32, CPU_X64 */
/* TIMER FUNCTIONS */
#if defined(_WIN32) || defined(__CYGWIN__)
# define WIN32_LEAN_AND_MEAN
# include
# define get_timedelta(delta) QueryPerformanceCounter((LARGE_INTEGER*)delta)
#else
# define get_timedelta(delta) gettimeofday(delta, NULL)
#endif
/**
* Return real-value representing number of seconds
* stored in the given timeval structure.
* The function is used with timers, when printing time statistics.
*
* @deprecated This function shall be removed soon
*
* @param delta time delta to be converted
* @return number of seconds
*/
static double fsec(timedelta_t* timer)
{
#if defined(_WIN32) || defined(__CYGWIN__)
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return (double)*timer / freq.QuadPart;
#else
return ((double)timer->tv_usec / 1000000.0) + timer->tv_sec;
#endif
}
static void rhash_timer_start(timedelta_t* timer)
{
get_timedelta(timer);
}
static double rhash_timer_stop(timedelta_t* timer)
{
timedelta_t end;
get_timedelta(&end);
#if defined(_WIN32) || defined(__CYGWIN__)
*timer = end - *timer;
#else
timer->tv_sec = end.tv_sec - timer->tv_sec - (end.tv_usec >= timer->tv_usec ? 0 : 1);
timer->tv_usec = end.tv_usec + (end.tv_usec >= timer->tv_usec ? 0 : 1000000 ) - timer->tv_usec;
#endif
return fsec(timer);
}
#if defined(_WIN32) || defined(__CYGWIN__)
/**
* Set process priority and affinity to use all cpu's but the first one.
* This improves benchmark results on a multi-cpu systems.
*
* @deprecated This function shall be removed soon
*/
static void benchmark_cpu_init(void)
{
DWORD_PTR dwProcessMask, dwSysMask, dwDesired;
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
if ( GetProcessAffinityMask(GetCurrentProcess(), &dwProcessMask, &dwSysMask) ) {
dwDesired = dwSysMask & (dwProcessMask & ~1); /* remove the first processor */
dwDesired = (dwDesired ? dwDesired : dwSysMask & ~1);
if (dwDesired != 0) {
SetProcessAffinityMask(GetCurrentProcess(), dwDesired);
}
}
}
#endif
/**
* Hash a repeated message chunk by specified hash function.
*
* @deprecated This function shall be removed soon
*
* @param hash_id hash function identifier
* @param message a message chunk to hash
* @param msg_size message chunk size
* @param count number of chunks
* @param out computed hash
* @return 1 on success, 0 on error
*/
static int hash_in_loop(unsigned hash_id, const unsigned char* message, size_t msg_size, int count, unsigned char* out)
{
int i;
struct rhash_context* context = rhash_init(hash_id);
if (!context) return 0;
/* process the repeated message buffer */
for (i = 0; i < count; i++) rhash_update(context, message, msg_size);
rhash_final(context, out);
rhash_free(context);
return 1;
}
void test_run_benchmark(unsigned hash_id, unsigned flags, FILE* output)
{
unsigned char ALIGN_ATTR(64) message[8192]; /* 8 KiB */
timedelta_t timer;
int i, j;
size_t sz_mb, msg_size;
double time, total_time = 0;
const int rounds = 4;
const char* hash_name;
unsigned char out[130];
#ifdef HAVE_TSC
double cpb = 0;
#endif /* HAVE_TSC */
#if defined(_WIN32) || defined(__CYGWIN__)
benchmark_cpu_init(); /* set cpu affinity to improve test results */
#endif
/* set message size for fast and slow hash functions */
msg_size = 1073741824 / 2;
if (hash_id & (RHASH_WHIRLPOOL | RHASH_SNEFRU128 | RHASH_SNEFRU256 | RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512)) {
msg_size /= 8;
} else if (hash_id & (RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_SHA384 | RHASH_SHA512)) {
msg_size /= 2;
}
sz_mb = msg_size / (1 << 20); /* size in MiB */
hash_name = rhash_get_name(hash_id);
if (!hash_name) hash_name = ""; /* benchmarking several hashes*/
for (i = 0; i < (int)sizeof(message); i++) message[i] = i & 0xff;
for (j = 0; j < rounds; j++) {
rhash_timer_start(&timer);
hash_in_loop(hash_id, message, sizeof(message), (int)(msg_size / sizeof(message)), out);
time = rhash_timer_stop(&timer);
total_time += time;
if ((flags & (RHASH_BENCHMARK_QUIET | RHASH_BENCHMARK_RAW)) == 0) {
fprintf(output, "%s %u MiB calculated in %.3f sec, %.3f MBps\n", hash_name, (unsigned)sz_mb, time, (double)sz_mb / time);
fflush(output);
}
}
#if defined(HAVE_TSC)
/* measure the CPU "clocks per byte" speed */
if (flags & RHASH_BENCHMARK_CPB) {
unsigned int c1 = -1, c2 = -1;
unsigned volatile long long cy0, cy1, cy2;
int msg_size = 128 * 1024;
/* make 200 tries */
for (i = 0; i < 200; i++) {
cy0 = read_tsc();
hash_in_loop(hash_id, message, sizeof(message), msg_size / sizeof(message), out);
cy1 = read_tsc();
hash_in_loop(hash_id, message, sizeof(message), msg_size / sizeof(message), out);
hash_in_loop(hash_id, message, sizeof(message), msg_size / sizeof(message), out);
cy2 = read_tsc();
cy2 -= cy1;
cy1 -= cy0;
c1 = (unsigned int)(c1 > cy1 ? cy1 : c1);
c2 = (unsigned int)(c2 > cy2 ? cy2 : c2);
}
cpb = ((c2 - c1) + 1) / (double)msg_size;
}
#endif /* HAVE_TSC */
if (flags & RHASH_BENCHMARK_RAW) {
/* output result in a "raw" machine-readable format */
fprintf(output, "%s\t%u\t%.3f\t%.3f", hash_name, ((unsigned)sz_mb * rounds), total_time, (double)(sz_mb * rounds) / total_time);
#if defined(HAVE_TSC)
if (flags & RHASH_BENCHMARK_CPB) fprintf(output, "\t%.2f", cpb);
#endif /* HAVE_TSC */
fprintf(output, "\n");
} else {
fprintf(output, "%s %u MiB total in %.3f sec, %.3f MBps", hash_name, ((unsigned)sz_mb * rounds), total_time, (double)(sz_mb * rounds) / total_time);
#if defined(HAVE_TSC)
if (flags & RHASH_BENCHMARK_CPB) fprintf(output, ", CPB=%.2f", cpb);
#endif /* HAVE_TSC */
fprintf(output, "\n");
}
}
rhash-1.4.6/librhash/blake2s.h 0000664 0000000 0000000 00000001057 14703622112 014620 0 ustar root root /* blake2s.h */
#ifndef BLAKE2S_H
#define BLAKE2S_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define blake2s_block_size 64
#define blake2s_hash_size 32
typedef struct blake2s_ctx
{
uint32_t hash[8];
uint32_t message[16];
uint64_t length;
} blake2s_ctx;
void rhash_blake2s_init(blake2s_ctx* ctx);
void rhash_blake2s_update(blake2s_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_blake2s_final(blake2s_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* BLAKE2S_H */
rhash-1.4.6/librhash/test_lib.c 0000664 0000000 0000000 00000237236 15010476501 015110 0 ustar root root /* test_lib.c - unit tests and benchmark for LibRHash algorithms
*
* Copyright (c) 2008, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "test_lib.h"
#include "byte_order.h"
#include "test_utils.h"
#ifdef USE_RHASH_DLL
# define RHASH_API __declspec(dllimport)
#endif
#include "rhash.h"
#include "rhash_torrent.h"
#include
#include
#include
#include
#include
#include
#include
#if defined(_WIN32)
# include
#endif
/*=========================================================================*
* Test vectors *
*=========================================================================*/
/* verified by cksfv */
const char* crc32_tests[] = {
"", "00000000",
"a", "E8B7BE43",
"abc", "352441C2",
"message digest", "20159D7F",
"abcdefghijklmnopqrstuvwxyz", "4C2750BD",
"The quick brown fox jumps over the lazy dog", "414FA339",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "1FC2E6D2",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "7CA94A72",
0
};
const char* crc32c_tests[] = {
"", "00000000",
"a", "C1D04330",
"abc", "364B3FB7",
"message digest", "02BD79D0",
"abcdefghijklmnopqrstuvwxyz", "9EE6EF25",
"The quick brown fox jumps over the lazy dog", "22620404",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "A245D57D",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "477A6781",
0
};
const char* md4_tests[] = {
"", "31D6CFE0D16AE931B73C59D7E0C089C0",
"a", "BDE52CB31DE33E46245E05FBDBD6FB24",
"abc", "A448017AAF21D8525FC10AE87AA6729D",
"message digest", "D9130A8164549FE818874806E1C7014B",
"abcdefghijklmnopqrstuvwxyz", "D79E1C308AA5BBCDEEA8ED63DF412DA9",
"The quick brown fox jumps over the lazy dog", "1BEE69A46BA811185C194762ABAEAE90",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "043F8582F241DB351CE627E153E7F0E4",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "E33B4DDC9C38F2199C3E7B164FCC0536",
0
};
/* for short messages ed2k test vectors coincide with md4 */
#define ed2k_tests md4_tests
/* test vectors from spec */
const char* md5_tests[] = {
"", "D41D8CD98F00B204E9800998ECF8427E",
"a", "0CC175B9C0F1B6A831C399E269772661",
"abc", "900150983CD24FB0D6963F7D28E17F72",
"message digest", "F96B697D7CB7938D525A2F31AAF161D0",
"abcdefghijklmnopqrstuvwxyz", "C3FCD3D76192E4007DFB496CCA67E13B",
"The quick brown fox jumps over the lazy dog", "9E107D9D372BB6826BD81D3542A419D6",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "D174AB98D277D9F5A5611C2C9F419D9F",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57EDF4A22BE3C955AC49DA2E2107B67A",
0
};
/* test vectors from spec */
const char* sha1_tests[] = {
"", "DA39A3EE5E6B4B0D3255BFEF95601890AFD80709",
"a", "86F7E437FAA5A7FCE15D1DDCB9EAEAEA377667B8",
"abc", "A9993E364706816ABA3E25717850C26C9CD0D89D",
"message digest", "C12252CEDA8BE8994D5FA0290A47231C1D16AAE3",
"The quick brown fox jumps over the lazy dog", "2FD4E1C67A2D28FCED849EE1BB76E7391B93EB12",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "761C457BF73B14D27E9E9265C46F4B4DDA11F940",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "50ABF5706A150990A08B2C5EA40FA0E585554732",
0
};
/* tests from spec and NESSIE test vectors */
const char* tiger_tests[] = {
"", "3293AC630C13F0245F92BBB1766E16167A4E58492DDE73F3",
"a", "77BEFBEF2E7EF8AB2EC8F93BF587A7FC613E247F5F247809",
"abc", "2AAB1484E8C158F2BFB8C5FF41B57A525129131C957B5F93",
"Tiger", "DD00230799F5009FEC6DEBC838BB6A27DF2B9D6F110C7937",
"The quick brown fox jumps over the lazy dog", "6D12A41E72E644F017B6F0E2F7B44C6285F06DD5D2C5B075",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "F71C8583902AFB879EDFE610F82C0D4786A3A534504486B5",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789", "48CEEB6308B87D46E95D656112CDF18D97915F9765658957",
"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham", "8A866829040A410C729AD23F5ADA711603B3CDD357E4C15E",
"Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.", "CE55A6AFD591F5EBAC547FF84F89227F9331DAB0B611C889",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "C54034E5B43EB8005848A7E0AE6AAC76E4FF590AE715FD25",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "8DCEA680A17583EE502BA38A3C368651890FFBCCDC49A8CC",
"message digest", "D981F8CB78201A950DCF3048751E441C517FCA1AA55A29F6",
"abcdefghijklmnopqrstuvwxyz", "1714A472EEE57D30040412BFCC55032A0B11602FF37BEEE9",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "0F7BF9A19B9C58F2B7610DF7E84F0AC3A71C631E7B53F78E",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "8DCEA680A17583EE502BA38A3C368651890FFBCCDC49A8CC",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "1C14795529FD9F207A958F84C52F11E887FA0CABDFD91BFD",
0
};
/* verified by strong dc++ */
const char* tth_tests[] = {
"", "LWPNACQDBZRYXW3VHJVCJ64QBZNGHOHHHZWCLNQ",
"a", "CZQUWH3IYXBF5L3BGYUGZHASSMXU647IP2IKE4Y",
"abc", "ASD4UJSEH5M47PDYB46KBTSQTSGDKLBHYXOMUIA",
"message digest", "YM432MSOX5QILIH2L4TNO62E3O35WYGWSBSJOBA",
"abcdefghijklmnopqrstuvwxyz", "LMHNA2VYO465P2RDOGTR2CL6XKHZNI2X4CCUY5Y",
"The quick brown fox jumps over the lazy dog", "WLM2MITXFTCQXEOYO3M4EL5APES353NQLI66ORY",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "TF74ENF7MF2WPDE35M23NRSVKJIRKYRMTLWAHWQ",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "NBKCANQ2ODNTSV4C7YJFF3JRAV7LKTFIPHQNBJY",
0
};
const char* aich_tests[] = {
"", "3I42H3S6NNFQ2MSVX7XZKYAYSCX5QBYJ",
"a", "Q336IN72UWT7ZYK5DXOLT2XK5I3XMZ5Y",
"abc", "VGMT4NSHA2AWVOR6EVYXQUGCNSONBWE5",
"message digest", "YERFFTW2RPUJSTK7UAUQURZDDQORNKXD",
"abcdefghijklmnopqrstuvwxyz", "GLIQY64M7FSXBSQEZY37FIM5QQSA2OUJ",
"The quick brown fox jumps over the lazy dog", "F7KODRT2FUUPZ3MET3Q3W5XHHENZH2YS",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "OYOEK67XHMKNE7U6SJS4I32LJXNBD6KA",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "KCV7K4DKCUEZBIELFRPKID5A4WCVKRZS",
0
};
const char* whirlpool_tests[] = {
"", "19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3",
"a", "8ACA2602792AEC6F11A67206531FB7D7F0DFF59413145E6973C45001D0087B42D11BC645413AEFF63A42391A39145A591A92200D560195E53B478584FDAE231A",
"abc", "4E2448A4C6F486BB16B6562C73B4020BF3043E3A731BCE721AE1B303D97E6D4C7181EEBDB6C57E277D0E34957114CBD6C797FC9D95D8B582D225292076D4EEF5",
"message digest", "378C84A4126E2DC6E56DCC7458377AAC838D00032230F53CE1F5700C0FFB4D3B8421557659EF55C106B4B52AC5A4AAA692ED920052838F3362E86DBD37A8903E",
"abcdefghijklmnopqrstuvwxyz", "F1D754662636FFE92C82EBB9212A484A8D38631EAD4238F5442EE13B8054E41B08BF2A9251C30B6A0B8AAE86177AB4A6F68F673E7207865D5D9819A3DBA4EB3B",
"The quick brown fox jumps over the lazy dog", "B97DE512E91E3828B40D2B0FDCE9CEB3C4A71F9BEA8D88E75C4FA854DF36725FD2B52EB6544EDCACD6F8BEDDFEA403CB55AE31F03AD62A5EF54E42EE82C3FB35",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"DC37E008CF9EE69BF11F00ED9ABA26901DD7C28CDEC066CC6AF42E40F82F3A1E08EBA26629129D8FB7CB57211B9281A65517CC879D7B962142C65F5A7AF01467",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890",
"466EF18BABB0154D25B9D38A6414F5C08784372BCCB204D6549C4AFADB6014294D5BD8DF2A6C44E538CD047B2681A51A2C60481E88C5A20B2C2A80CF3A9A083B",
"abcdbcdecdefdefgefghfghighijhijk",
"2A987EA40F917061F5D6F0A0E4644F488A7A5A52DEEE656207C562F988E95C6916BDC8031BC5BE1B7B947639FE050B56939BAAA0ADFF9AE6745B7B181C3BE3FD",
0
};
/* test vectors from RIPEMD-160 spec */
const char* ripemd_tests[] = {
"", "9C1185A5C5E9FC54612808977EE8F548B2258D31",
"a", "0BDC9D2D256B3EE9DAAE347BE6F4DC835A467FFE",
"abc", "8EB208F7E05D987A9B044A8E98C6B087F15A0BFC",
"message digest", "5D0689EF49D2FAE572B881B123A85FFA21595F36",
"abcdefghijklmnopqrstuvwxyz", "F71C27109C692C1B56BBDCEB5B9D2865B3708DBC",
"The quick brown fox jumps over the lazy dog", "37F332F68DB77BD9D7EDD4969571AD671CF9DD3B",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "12A053384A9C0C88E405A06C27DCF49ADA62EB2B",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "B0E20B6E3116640286ED3A87A5713079B21F5189",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "9B752E45573D4B39F4DBD3323CAB82BF63326BFB",
0
};
/*
* Two important test-cases (some libraries calculate them incorrectly):
* GOST94( <100000 characters of 'a'> ) = 5C00CCC2734CDD3332D3D4749576E3C1A7DBAF0E7EA74E9FA602413C90A129FA
* GOST94( <128 characters of 'U'> ) = 53A3A3ED25180CEF0C1D85A074273E551C25660A87062A52D926A9E8FE5733A4
*/
/* test vectors from internet, verified by OpenSSL and some other programs */
const char* gost94_tests[] = {
"", "CE85B99CC46752FFFEE35CAB9A7B0278ABB4C2D2055CFF685AF4912C49490F8D",
"a", "D42C539E367C66E9C88A801F6649349C21871B4344C6A573F849FDCE62F314DD",
"abc", "F3134348C44FB1B2A277729E2285EBB5CB5E0F29C975BC753B70497C06A4D51D",
"message digest", "AD4434ECB18F2C99B60CBE59EC3D2469582B65273F48DE72DB2FDE16A4889A4D",
"The quick brown fox jumps over the lazy dog", "77B7FA410C9AC58A25F49BCA7D0468C9296529315EACA76BD1A10F376D1F4294",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "95C1AF627C356496D80274330B2CFF6A10C67B5F597087202F94D06D2338CF8E",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "CC178DCAD4DF619DCAA00AAC79CA355C00144E4ADA2793D7BD9B3518EAD3CCD3",
"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU", "53A3A3ED25180CEF0C1D85A074273E551C25660A87062A52D926A9E8FE5733A4",
/* two test strings from GOST standard */
"This is message, length=32 bytes", "B1C466D37519B82E8319819FF32595E047A28CB6F83EFF1C6916A815A637FFFA",
"Suppose the original message has length = 50 bytes", "471ABA57A60A770D3A76130635C1FBEA4EF14DE51F78B4AE57DD893B62F55208",
"The quick brown fox jumps over the lazy cog", "A3EBC4DAAAB78B0BE131DAB5737A7F67E602670D543521319150D2E14EEEC445", /* test from Wikipedia */
0
};
/* tested with openssl */
const char* gost94_cryptopro_tests[] = {
"", "981E5F3CA30C841487830F84FB433E13AC1101569B9C13584AC483234CD656C0",
"a", "E74C52DD282183BF37AF0079C9F78055715A103F17E3133CEFF1AACF2F403011",
"abc", "B285056DBF18D7392D7677369524DD14747459ED8143997E163B2986F92FD42C",
"message digest", "BC6041DD2AA401EBFA6E9886734174FEBDB4729AA972D60F549AC39B29721BA0",
"The quick brown fox jumps over the lazy dog", "9004294A361A508C586FE53D1F1B02746765E71B765472786E4770D565830A76",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "73B70A39497DE53A6E08C67B6D4DB853540F03E9389299D9B0156EF7E85D0F61",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "6BC7B38989B28CF93AE8842BF9D752905910A7528A61E5BCE0782DE43E610C90",
"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU", "1C4AC7614691BBF427FA2316216BE8F10D92EDFD37CD1027514C1008F649C4E8",
"This is message, length=32 bytes", "2CEFC2F7B7BDC514E18EA57FA74FF357E7FA17D652C75F69CB1BE7893EDE48EB",
"Suppose the original message has length = 50 bytes", "C3730C5CBCCACF915AC292676F21E8BD4EF75331D9405E5F1A61DC3130A65011",
0
};
const char* gost12_256_tests[] = {
"", "3F539A213E97C802CC229D474C6AA32A825A360B2A933A949FD925208D9CE1BB",
"a", "BA31099B9CC84EC2A671E9313572378920A705B363B031A1CB4FC03E01CE8DF3",
"abc", "4E2919CF137ED41EC4FB6270C61826CC4FFFB660341E0AF3688CD0626D23B481",
"message digest", "0D45451B2004234DE7FBD289B89C665A494FFEFE93C2FF6D6F99677C99086BFF",
"012345678901234567890123456789012345678901234567890123456789012", "9D151EEFD8590B89DAA6BA6CB74AF9275DD051026BB149A452FD84E5E57B5500",
"abcdefghijklmnopqrstuvwxyz", "C9086ED61FB0A090AAF4438EFD39F0D060CB3EC7E25343B5C4C350054BFD3E27",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "74F945F366AB17DD1E7D114AB9ADF68B97A8D6A1CBBE299CBA06B77735457F94",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "2C6644B1F5AB3E0AB56ADF1FEEB4D6A8742FCFC61B53B69C3B536AC283AB88AA",
"The quick brown fox jumps over the lazy dog", "3E7DEA7F2384B6C5A3D0E24AAA29C05E89DDD762145030EC22C71A6DB8B2C1F4",
0
};
const char* gost12_512_tests[] = {
"", "8E945DA209AA869F0455928529BCAE4679E9873AB707B55315F56CEB98BEF0A7362F715528356EE83CDA5F2AAC4C6AD2BA3A715C1BCD81CB8E9F90BF4C1C1A8A",
"012345678901234567890123456789012345678901234567890123456789012", "1B54D01A4AF5B9D5CC3D86D68D285462B19ABC2475222F35C085122BE4BA1FFA00AD30F8767B3A82384C6574F024C311E2A481332B08EF7F41797891C1646F48",
"a", "8B2A40ECAB7B7496BC4CC0F773595452BAF658849B495ACC3BA017206810EFB00420CCD73FB3297E0F7890941B84AC4A8BC27E3C95E1F97C094609E2136ABB7E",
"abc", "28156E28317DA7C98F4FE2BED6B542D0DAB85BB224445FCEDAF75D46E26D7EB8D5997F3E0915DD6B7F0AAB08D9C8BEB0D8C64BAE2AB8B3C8C6BC53B3BF0DB728",
"message digest", "96B52F322E3ECF6348D177608E2DDB084309C1642A94923C0BC50E41E4CC50E851D1DD94E4B7A35C30503CAF87E3E2AC334E2C805ADB99B5ADB5443DD4AC23C8",
"abcdefghijklmnopqrstuvwxyz", "EC7B127DCCA6B0D741B10ED42062CC4487B4A93F96CFC7FAF2E7F79778B1F44159089C91FB0910BEC0EEE7CDCA524FCF291CF933FFF406F4F3A03872F2341FF8",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "CC49B68C195D18D3FEF26F3D4A6554DB62298B96D19FBEFA52A139E8558D0528535569EBDEA172692857EDE3351C02FE9D749EF7273DCECACA5B3E295511650B",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "116201023E88D93A4D076BA77207E8702C6CFA6FCC69B82BB22AE6BE9B63F16B19BAAF8771E01E6DC25C2B4486FA3BBF8601905762CBBAD5BA25A1E034879192",
"The quick brown fox jumps over the lazy dog", "D2B793A0BB6CB5904828B5B6DCFB443BB8F33EFC06AD09368878AE4CDC8245B97E60802469BED1E7C21A64FF0B179A6A1E0BB74D92965450A0ADAB69162C00FE",
0
};
/* test vectors verified by mhash */
const char* snefru256_tests[] = {
"", "8617F366566A011837F4FB4BA5BEDEA2B892F3ED8B894023D16AE344B2BE5881",
"a", "45161589AC317BE0CEBA70DB2573DDDA6E668A31984B39BF65E4B664B584C63D",
"abc", "7D033205647A2AF3DC8339F6CB25643C33EBC622D32979C4B612B02C4903031B",
"message digest", "C5D4CE38DAA043BDD59ED15DB577500C071B917C1A46CD7B4D30B44A44C86DF8",
"abcdefghijklmnopqrstuvwxyz", "9304BB2F876D9C4F54546CF7EC59E0A006BEAD745F08C642F25A7C808E0BF86E",
"The quick brown fox jumps over the lazy dog", "674CAA75F9D8FD2089856B95E93A4FB42FA6C8702F8980E11D97A142D76CB358",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "83AA9193B62FFD269FAA43D31E6AC2678B340E2A85849470328BE9773A9E5728",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "D5FCE38A152A2D9B83AB44C29306EE45AB0AED0E38C957EC431DAB6ED6BB71B8",
0
};
/* test vectors verified by mhash */
const char* snefru128_tests[] = {
"", "8617F366566A011837F4FB4BA5BEDEA2",
"a", "BF5CE540AE51BC50399F96746C5A15BD",
"abc", "553D0648928299A0F22A275A02C83B10",
"message digest", "96D6F2F4112C4BAF29F653F1594E2D5D",
"abcdefghijklmnopqrstuvwxyz", "7840148A66B91C219C36F127A0929606",
"The quick brown fox jumps over the lazy dog", "59D9539D0DD96D635B5BDBD1395BB86C",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "0EFD7F93A549F023B79781090458923E",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "D9204ED80BB8430C0B9C244FE485814A",
0
};
/* checked against test vectors: http://www.randombit.net/text/has160.html */
const char* has160_tests[] = {
"", "307964EF34151D37C8047ADEC7AB50F4FF89762D",
"a", "4872BCBC4CD0F0A9DC7C2F7045E5B43B6C830DB8",
"abc", "975E810488CF2A3D49838478124AFCE4B1C78804",
"message digest", "2338DBC8638D31225F73086246BA529F96710BC6",
"abcdefghijklmnopqrstuvwxyz", "596185C9AB6703D0D0DBB98702BC0F5729CD1D3C",
"The quick brown fox jumps over the lazy dog", "ABE2B8C711F9E8579AA8EB40757A27B4EF14A7EA",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "CB5D7EFBCA2F02E0FB7167CABB123AF5795764E5",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "07F05C8C0773C55CA3A5A695CE6ACA4C438911B5",
0
};
/* unconfirmed test vectors */
const char* sha224_tests[] = {
"", "D14A028C2A3A2BC9476102BB288234C415A2B01F828EA62AC5B3E42F",
"a", "ABD37534C7D9A2EFB9465DE931CD7055FFDB8879563AE98078D6D6D5",
"abc", "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7",
"message digest", "2CB21C83AE2F004DE7E81C3C7019CBCB65B71AB656B22D6D0C39B8EB",
"abcdefghijklmnopqrstuvwxyz", "45A5F72C39C5CFF2522EB3429799E49E5F44B356EF926BCF390DCCC2",
"The quick brown fox jumps over the lazy dog", "730E109BD7A8A32B1CB9D9A09AA2325D2430587DDBC0C38BAD911525",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "BFF72B4FCB7D75E5632900AC5F90D219E05E97A7BDE72E740DB393D9",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "B50AECBE4E9BB0B57BC5F3AE760A8E01DB24F203FB3CDCD13148046E",
0
};
/* test vectors from the NESSIE project */
const char* sha256_tests[] = {
"", "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"a", "CA978112CA1BBDCAFAC231B39A23DC4DA786EFF8147C4E72B9807785AFEE48BB",
"abc", "BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD",
"message digest", "F7846F55CF23E14EEBEAB5B4E1550CAD5B509E3348FBC4EFA3A1413D393CB650",
"abcdefghijklmnopqrstuvwxyz", "71C480DF93D6AE2F1EFAD1447C66C9525E316218CF51FC8D9ED832F2DAF18B73",
"The quick brown fox jumps over the lazy dog", "D7A8FBB307D7809469CA9ABCB0082E4F8D5651E46D3CDB762D02D0BF37C9E592",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "248D6A61D20638B8E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "DB4BFCBD4DA0CD85A60C3C37D3FBD8805C77F15FC6B1FDFE614EE0A7C8FDB4C0",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "F371BC4A311F2B009EEF952DD83CA80E2B60026C8E935592D0F9C308453C813E",
0
};
const char* sha384_tests[] = {
"", "38B060A751AC96384CD9327EB1B1E36A21FDB71114BE07434C0CC7BF63F6E1DA274EDEBFE76F65FBD51AD2F14898B95B",
"a", "54A59B9F22B0B80880D8427E548B7C23ABD873486E1F035DCE9CD697E85175033CAA88E6D57BC35EFAE0B5AFD3145F31",
"abc", "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7",
"message digest", "473ED35167EC1F5D8E550368A3DB39BE54639F828868E9454C239FC8B52E3C61DBD0D8B4DE1390C256DCBB5D5FD99CD5",
"abcdefghijklmnopqrstuvwxyz", "FEB67349DF3DB6F5924815D6C3DC133F091809213731FE5C7B5F4999E463479FF2877F5F2936FA63BB43784B12F3EBB4",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "3391FDDDFC8DC7393707A65B1B4709397CF8B1D162AF05ABFE8F450DE5F36BC6B0455A8520BC4E6F5FE95B1FE3C8452B",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "1761336E3F7CBFE51DEB137F026F89E01A448E3B1FAFA64039C1464EE8732F11A5341A6F41E0C202294736ED64DB1A84",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "B12932B0627D1C060942F5447764155655BD4DA0C9AFA6DD9B9EF53129AF1B8FB0195996D2DE9CA0DF9D821FFEE67026",
0
};
const char* sha512_tests[] = {
"", "CF83E1357EEFB8BDF1542850D66D8007D620E4050B5715DC83F4A921D36CE9CE47D0D13C5D85F2B0FF8318D2877EEC2F63B931BD47417A81A538327AF927DA3E",
"a", "1F40FC92DA241694750979EE6CF582F2D5D7D28E18335DE05ABC54D0560E0F5302860C652BF08D560252AA5E74210546F369FBBBCE8C12CFC7957B2652FE9A75",
"abc", "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA20A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD454D4423643CE80E2A9AC94FA54CA49F",
"message digest", "107DBF389D9E9F71A3A95F6C055B9251BC5268C2BE16D6C13492EA45B0199F3309E16455AB1E96118E8A905D5597B72038DDB372A89826046DE66687BB420E7C",
"abcdefghijklmnopqrstuvwxyz", "4DBFF86CC2CA1BAE1E16468A05CB9881C97F1753BCE3619034898FAA1AABE429955A1BF8EC483D7421FE3C1646613A59ED5441FB0F321389F77F48A879C7B1F1",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "204A8FC6DDA82F0A0CED7BEB8E08A41657C16EF468B228A8279BE331A703C33596FD15C13B1B07F9AA1D3BEA57789CA031AD85C7A71DD70354EC631238CA3445",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "1E07BE23C26A86EA37EA810C8EC7809352515A970E9253C26F536CFC7A9996C45C8370583E0A78FA4A90041D71A4CEAB7423F19C71B9D5A3E01249F0BEBD5894",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "72EC1EF1124A45B047E8B7C75A932195135BB61DE24EC0D1914042246E0AEC3A2354E093D76F3048B456764346900CB130D2A4FD5DD16ABB5E30BCB850DEE843",
0
};
/* SHA3 test vectors were verified by the reference implementation of Keccak */
const char* sha3_224_tests[] = {
"", "6B4E03423667DBB73B6E15454F0EB1ABD4597F9A1B078E3F5B5A6BC7",
"a", "9E86FF69557CA95F405F081269685B38E3A819B309EE942F482B6A8B",
"abc", "E642824C3F8CF24AD09234EE7D3C766FC9A3A5168D0C94AD73B46FDF",
"message digest", "18768BB4C48EB7FC88E5DDB17EFCF2964ABD7798A39D86A4B4A1E4C8",
"abcdefghijklmnopqrstuvwxyz", "5CDECA81E123F87CAD96B9CBA999F16F6D41549608D4E0F4681B8239",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "A67C289B8250A6F437A20137985D605589A8C163D45261B15419556E",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "0526898E185869F91B3E2A76DD72A15DC6940A67C8164A044CD25CC8",
"The quick brown fox jumps over the lazy dog", "D15DADCEAA4D5D7BB3B48F446421D542E08AD8887305E28D58335795",
0
};
const char* sha3_256_tests[] = {
"", "A7FFC6F8BF1ED76651C14756A061D662F580FF4DE43B49FA82D80A4B80F8434A",
"a", "80084BF2FBA02475726FEB2CAB2D8215EAB14BC6BDD8BFB2C8151257032ECD8B",
"abc", "3A985DA74FE225B2045C172D6BD390BD855F086E3E9D525B46BFE24511431532",
"message digest", "EDCDB2069366E75243860C18C3A11465ECA34BCE6143D30C8665CEFCFD32BFFD",
"abcdefghijklmnopqrstuvwxyz", "7CAB2DC765E21B241DBC1C255CE620B29F527C6D5E7F5F843E56288F0D707521",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "A79D6A9DA47F04A3B9A9323EC9991F2105D4C78A7BC7BEEB103855A7A11DFB9F",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "293E5CE4CE54EE71990AB06E511B7CCD62722B1BEB414F5FF65C8274E0F5BE1D",
"The quick brown fox jumps over the lazy dog", "69070DDA01975C8C120C3AADA1B282394E7F032FA9CF32F4CB2259A0897DFC04",
0
};
const char* sha3_384_tests[] = {
"", "0C63A75B845E4F7D01107D852E4C2485C51A50AAAA94FC61995E71BBEE983A2AC3713831264ADB47FB6BD1E058D5F004",
"a", "1815F774F320491B48569EFEC794D249EEB59AAE46D22BF77DAFE25C5EDC28D7EA44F93EE1234AA88F61C91912A4CCD9",
"abc", "EC01498288516FC926459F58E2C6AD8DF9B473CB0FC08C2596DA7CF0E49BE4B298D88CEA927AC7F539F1EDF228376D25",
"message digest", "D9519709F44AF73E2C8E291109A979DE3D61DC02BF69DEF7FBFFDFFFE662751513F19AD57E17D4B93BA1E484FC1980D5",
"abcdefghijklmnopqrstuvwxyz", "FED399D2217AAF4C717AD0C5102C15589E1C990CC2B9A5029056A7F7485888D6AB65DB2370077A5CADB53FC9280D278F",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "D5B972302F5080D0830E0DE7B6B2CF383665A008F4C4F386A61112652C742D20CB45AA51BD4F542FC733E2719E999291",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "3C213A17F514638ACB3BF17F109F3E24C16F9F14F085B52A2F2B81ADC0DB83DF1A58DB2CE013191B8BA72D8FAE7E2A5E",
"The quick brown fox jumps over the lazy dog", "7063465E08A93BCE31CD89D2E3CA8F602498696E253592ED26F07BF7E703CF328581E1471A7BA7AB119B1A9EBDF8BE41",
0
};
const char* sha3_512_tests[] = {
"", "A69F73CCA23A9AC5C8B567DC185A756E97C982164FE25859E0D1DCC1475C80A615B2123AF1F5F94C11E3E9402C3AC558F500199D95B6D3E301758586281DCD26",
"a", "697F2D856172CB8309D6B8B97DAC4DE344B549D4DEE61EDFB4962D8698B7FA803F4F93FF24393586E28B5B957AC3D1D369420CE53332712F997BD336D09AB02A",
"abc", "B751850B1A57168A5693CD924B6B096E08F621827444F70D884F5D0240D2712E10E116E9192AF3C91A7EC57647E3934057340B4CF408D5A56592F8274EEC53F0",
"message digest", "3444E155881FA15511F57726C7D7CFE80302A7433067B29D59A71415CA9DD141AC892D310BC4D78128C98FDA839D18D7F0556F2FE7ACB3C0CDA4BFF3A25F5F59",
"abcdefghijklmnopqrstuvwxyz", "AF328D17FA28753A3C9F5CB72E376B90440B96F0289E5703B729324A975AB384EDA565FC92AADED143669900D761861687ACDC0A5FFA358BD0571AAAD80ACA68",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "D1DB17B4745B255E5EB159F66593CC9C143850979FC7A3951796ABA80165AAB536B46174CE19E3F707F0E5C6487F5F03084BC0EC9461691EF20113E42AD28163",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "9524B9A5536B91069526B4F6196B7E9475B4DA69E01F0C855797F224CD7335DDB286FD99B9B32FFE33B59AD424CC1744F6EB59137F5FB8601932E8A8AF0AE930",
"The quick brown fox jumps over the lazy dog", "01DEDD5DE4EF14642445BA5F5B97C15E47B9AD931326E4B0727CD94CEFC44FFF23F07BF543139939B49128CAF436DC1BDEE54FCB24023A08D9403F9B4BF0D450",
0
};
#ifdef USE_KECCAK
const char* keccak_224_tests[] = {
"", "F71837502BA8E10837BDD8D365ADB85591895602FC552B48B7390ABD",
"a", "7CF87D912EE7088D30EC23F8E7100D9319BFF090618B439D3FE91308",
"abc", "C30411768506EBE1C2871B1EE2E87D38DF342317300A9B97A95EC6A8",
"message digest", "B53B2CD638F440FA49916036ACDB22245673992FB1B1963B96FB9E93",
"abcdefghijklmnopqrstuvwxyz", "162BAB64DC3BA594BD3B43FD8ABEC4AA03B36C2784CAC53A58F9B076",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "4FB72D7B6B24BD1F5D4B8EF559FD9188EB66CAA01BCE34C621A05412",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "744C1765A53043E186BC30BAB07FA379B421CF0BCA8224CB83E5D45B",
"The quick brown fox jumps over the lazy dog", "310AEE6B30C47350576AC2873FA89FD190CDC488442F3EF654CF23FE",
0
};
const char* keccak_256_tests[] = {
"", "C5D2460186F7233C927E7DB2DCC703C0E500B653CA82273B7BFAD8045D85A470",
"a", "3AC225168DF54212A25C1C01FD35BEBFEA408FDAC2E31DDD6F80A4BBF9A5F1CB",
"abc", "4E03657AEA45A94FC7D47BA826C8D667C0D1E6E33A64A036EC44F58FA12D6C45",
"message digest", "856AB8A3AD0F6168A4D0BA8D77487243F3655DB6FC5B0E1669BC05B1287E0147",
"abcdefghijklmnopqrstuvwxyz", "9230175B13981DA14D2F3334F321EB78FA0473133F6DA3DE896FEB22FB258936",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "6E61C013AEF4C6765389FFCD406DD72E7E061991F4A3A8018190DB86BD21EBB4",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "1523A0CD0E7E1FAABA17E1C12210FABC49FA99A7ABC061E3D6C978EEF4F748C4",
"The quick brown fox jumps over the lazy dog", "4D741B6F1EB29CB2A9B9911C82F56FA8D73B04959D3D9D222895DF6C0B28AA15",
0
};
const char* keccak_384_tests[] = {
"", "2C23146A63A29ACF99E73B88F8C24EAA7DC60AA771780CCC006AFBFA8FE2479B2DD2B21362337441AC12B515911957FF",
"a", "85E964C0843A7EE32E6B5889D50E130E6485CFFC826A30167D1DC2B3A0CC79CBA303501A1EEABA39915F13BAAB5ABACF",
"abc", "F7DF1165F033337BE098E7D288AD6A2F74409D7A60B49C36642218DE161B1F99F8C681E4AFAF31A34DB29FB763E3C28E",
"message digest", "8A377DB088C43E44040A2BFB26676704999D90527913CABFF0A3484825DAA54D3061E67DA7D836A0805356962AF310E8",
"abcdefghijklmnopqrstuvwxyz", "C5A708EC2178D8C398461547435E482CEE0D85DE3D75DDBFF54E6606A7E9F994F023A6033B2BF4C516A5F71FC7470D1A",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "7377C5707506575C26937F3DF0D44A773F8C7452C074EE1725C1AB62F741F95059459D64CAEBF35A7C247FE28616CAB6",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "FD6E89CBE3271545F94C3E6786803260F929C1589E3091AFD58CF32EF53A4F29B69C1166CB2982E2CB65CF5EB903E669",
"The quick brown fox jumps over the lazy dog", "283990FA9D5FB731D786C5BBEE94EA4DB4910F18C62C03D173FC0A5E494422E8A0B3DA7574DAE7FA0BAF005E504063B3",
0
};
const char* keccak_512_tests[] = {
"", "0EAB42DE4C3CEB9235FC91ACFFE746B29C29A8C366B7C60E4E67C466F36A4304C00FA9CAF9D87976BA469BCBE06713B435F091EF2769FB160CDAB33D3670680E",
"a", "9C46DBEC5D03F74352CC4A4DA354B4E9796887EEB66AC292617692E765DBE400352559B16229F97B27614B51DBFBBB14613F2C10350435A8FEAF53F73BA01C7C",
"abc", "18587DC2EA106B9A1563E32B3312421CA164C7F1F07BC922A9C83D77CEA3A1E5D0C69910739025372DC14AC9642629379540C17E2A65B19D77AA511A9D00BB96",
"message digest", "CCCC49FA63822B00004CF6C889B28A035440FFB3EF50E790599935518E2AEFB0E2F1839170797F7763A5C43B2DCF02ABF579950E36358D6D04DFDDC2ABAC7545",
"abcdefghijklmnopqrstuvwxyz", "E55BDCA64DFE33F36AE3153C727833F9947D92958073F4DD02E38A82D8ACB282B1EE1330A68252A54C6D3D27306508CA765ACD45606CAEAF51D6BDC459F551F1",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "D5FA6B93D54A87BBDE52DBB44DAF96A3455DAEF9D60CDB922BC4B72A5BBBA97C5BF8C59816FEDE302FC64E98CE1B864DF7BE671C968E43D1BAE23AD76A3E702D",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "BC08A9A245E99F62753166A3226E874896DE0914565BEE0F8BE29D678E0DA66C508CC9948E8AD7BE78EAA4EDCED482253F8AB2E6768C9C8F2A2F0AFFF083D51C",
"The quick brown fox jumps over the lazy dog", "D135BB84D0439DBAC432247EE573A23EA7D3C9DEB2A968EB31D47C4FB45F1EF4422D6C531B5B9BD6F449EBCC449EA94D0A8F05F62130FDA612DA53C79659F609",
0
};
#endif /* USE_KECCAK */
/* verified by eBASH SUPERCOP implementation */
const char* edonr256_tests[] = {
"", "86E7C84024C55DBDC9339B395C95E88DB8F781719851AD1D237C6E6A8E370B80",
"a", "943AA9225A2CF154EC2E4DD81237720BA538CA8DF2FD83C0B893C5D265F353A0",
"abc", "0360F65D97C2152EA6EBE3D462BF49831E2D5F67B6140992320585D89FD271CE",
"message digest", "8D27558F4DD9307614A8166CADB136927D1E79A0C04BD8EF77C3FAFC0917E28A",
"abcdefghijklmnopqrstuvwxyz", "5415737AF0D827459EFACB7FE33C0E89CF807E6E608A4D70EF9DEB07BF3BF6BF",
"The quick brown fox jumps over the lazy dog", "E77A5AC00923B86C1811D42F1CB1198F43412A6D987DC98BDAE11E6D91399609",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "19DE86BC3F0481098A3E623AA1330995043300A9A5D6C2AD584705F62686417F",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "3B57F954420F49FAC6A80CE6CE013FDB47E71CE824DA78A8F66864203D8EF252",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "286F39D5168775C8E541ED2F0FE3ECF3146380B9C479DE41BD847E866420A776",
0
};
/* verified by eBASH SUPERCOP implementation */
const char* edonr512_tests[] = {
"", "C7AFBDF3E5B4590EB0B25000BF83FB16D4F9B722EE7F9A2DC2BD382035E8EE38D6F6F15C7B8EEC85355AC59AF989799950C64557EAB0E687D0FCBDBA90AE9704",
"a", "B59EC44F7BEEF8A04CEED38A973D77C65E22E9458D5F67B497948DA34986C093B5EFC5483FBEE55F2F740FCAD31F18D80DB44BB6B8843E7FD599188E7C07233B",
"abc", "FE79BCFA310245D9139DA8BC91B99FD022326F7F3ACA1DFDFB6C84E4125D71FE9BB6A1D41AFCE358F8472835220A7829D5146B2BBFC8E5C2627F60A9B517C1A4",
"message digest", "A76B6C5CA8778F39EC1F85D64BADBDBF329725C9A6FB92656D94A82922A26FD51D271A6F135F33157143B960CD8D7D20DC99503AA39871FD64050E061689E4E3",
"abcdefghijklmnopqrstuvwxyz", "754640B7B01782C1F345A3864B456DB805E39163FA1A06113A37CB8FB18D30F8DC43C7C3FDB407849CAD437C90DBD28E28AEFEF8898589B388ADEBA153B3DE0B",
"The quick brown fox jumps over the lazy dog", "B986ADABFA9ADB1E5B152B6D64C733389082E354FDE2FD9740FAEA6766F440EA4391FC745BB9B11A821756944077BB30723F616645492C70FA4C614DB7E9D45B",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "EE5EF974E8677636970A50E7636EC34EFB1F9D8023C715A26747D73D3665D78D2BB4962381901F76892A630133D476A278E4E3C62176FCE1563904636284415B",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "0755F846450A6F84001846E1066828727BF5975383867B87E0120F27B79482524EB01137459185F73C24C23BDD9D901AD1577C3EA1A824E6ACE34BBBA119E92F",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "0998912DA5B13FC5D7332CBC3B240E44547CE9C861867D901DD39D5A43D2EE80686BC4AD70DFF9159FE12CE94255AD5467B2B59D31562FC08B3697B67323075F",
0
};
/* verified by b2sum utility */
const char* blake2s_tests[] = {
"", "69217A3079908094E11121D042354A7C1F55B6482CA1A51E1B250DFD1ED0EEF9",
"a", "4A0D129873403037C2CD9B9048203687F6233FB6738956E0349BD4320FEC3E90",
"abc", "508C5E8C327C14E2E1A72BA34EEB452F37458B209ED63A294D999B4C86675982",
"message digest", "FA10AB775ACF89B7D3C8A6E823D586F6B67BDBAC4CE207FE145B7D3AC25CD28C",
"abcdefghijklmnopqrstuvwxyz", "BDF88EB1F86A0CDF0E840BA88FA118508369DF186C7355B4B16CF79FA2710A12",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "C75439EA17E1DE6FA4510C335DC3D3F343E6F9E1CE2773E25B4174F1DF8B119B",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "FDAEDB290A0D5AF9870864FEC2E090200989DC9CD53A3C092129E8535E8B4F66",
"The quick brown fox jumps over the lazy dog", "606BEEEC743CCBEFF6CBCDF5D5302AA855C256C29B88C8ED331EA1A6BF3C8812",
0
};
/* verified by b2sum utility */
const char* blake2b_tests[] = {
"", "786A02F742015903C6C6FD852552D272912F4740E15847618A86E217F71F5419D25E1031AFEE585313896444934EB04B903A685B1448B755D56F701AFE9BE2CE",
"a", "333FCB4EE1AA7C115355EC66CEAC917C8BFD815BF7587D325AEC1864EDD24E34D5ABE2C6B1B5EE3FACE62FED78DBEF802F2A85CB91D455A8F5249D330853CB3C",
"abc", "BA80A53F981C4D0D6A2797B69F12F6E94C212F14685AC4B74B12BB6FDBFFA2D17D87C5392AAB792DC252D5DE4533CC9518D38AA8DBF1925AB92386EDD4009923",
"message digest", "3C26CE487B1C0F062363AFA3C675EBDBF5F4EF9BDC022CFBEF91E3111CDC283840D8331FC30A8A0906CFF4BCDBCD230C61AAEC60FDFAD457ED96B709A382359A",
"abcdefghijklmnopqrstuvwxyz", "C68EDE143E416EB7B4AAAE0D8E48E55DD529EAFED10B1DF1A61416953A2B0A5666C761E7D412E6709E31FFE221B7A7A73908CB95A4D120B8B090A87D1FBEDB4C",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "99964802E5C25E703722905D3FB80046B6BCA698CA9E2CC7E49B4FE1FA087C2EDF0312DFBB275CF250A1E542FD5DC2EDD313F9C491127C2E8C0C9B24168E2D50",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "686F41EC5AFFF6E87E1F076F542AA466466FF5FBDE162C48481BA48A748D842799F5B30F5B67FC684771B33B994206D05CC310F31914EDD7B97E41860D77D282",
"The quick brown fox jumps over the lazy dog", "A8ADD4BDDDFD93E4877D2746E62817B116364A1FA7BC148D95090BC7333B3673F82401CF7AA2E4CB1ECD90296E3F14CB5413F8ED77BE73045B13914CDCD6A918",
0
};
/* verified by b3sum from github.com/BLAKE3-team/BLAKE3 */
const char* blake3_tests[] = {
"", "AF1349B9F5F9A1A6A0404DEA36DCC9499BCB25C9ADC112B7CC9A93CAE41F3262",
"a", "17762FDDD969A453925D65717AC3EEA21320B66B54342FDE15128D6CAF21215F",
"abc", "6437B3AC38465133FFB63B75273A8DB548C558465D79DB03FD359C6CD5BD9D85",
"message digest", "7BC2A2EEB95DDBF9B7ECF6ADCB76B453091C58DC43955E1D9482B1942F08D19B",
"abcdefghijklmnopqrstuvwxyz", "2468EEC8894ACFB4E4DF3A51EA916BA115D48268287754290AAE8E9E6228E85F",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "8BEE3200BAA9F3A1ACD279F049F914F110E730555FF15109BD59CDD73895E239",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "F263ACF51621980B9C8DE5DA4A17D314984E05ABE4A21CC83A07FE3E1E366DD1",
"The quick brown fox jumps over the lazy dog", "2F1514181AADCCD913ABD94CFA592701A5686AB23F8DF1DFF1B74710FEBC6D4A",
0
};
/* BTIH calculated with filename = "test.txt", verified using uTorrent */
const char* btih_with_filename_tests[] = {
"", "042C8E2D2780B0AFAE6599A02914D6C3F1515B12",
"a", "7527A903193C87093C05DE0F0F81126A4B98EE1A",
"abc", "CBF4F6D5CCDE0E6DD6BC8F013AA7F920900C11A2",
"message digest", "FFFCE897C2D5FB8ED4B6AD773CC0FFA071AEC393",
"abcdefghijklmnopqrstuvwxyz", "606A31B06B17547C226C9EA8EE00EEBA6E0E5BFC",
"The quick brown fox jumps over the lazy dog", "1EED1B4C56186456E3DE420FE69A67F53CA6A52A",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "6BD6F0B19FA3F54CE0311BF6D2D6D3955B1BD20C",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "95880C5A8EB06C1AC28BA6A531505E0F2BCD77AE",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "674E17AA21981A33892119E601DF3E2E689C4E62",
0
};
/* BTIH calculated without a filename, can't be verified by torrent tools */
const char* btih_without_a_filename_tests[] = {
"", "A4A6678B3A933D1D9A182CC38E73124F7672C7EB",
"a", "827CD89846FC132E2E67E29C2784C65443BB4DC1",
"abc", "88713704608141F4E86F58C86247CA1E3D91D864",
"message digest", "C654901E82A8FC13C343271520FAF52EBEEF2183",
"abcdefghijklmnopqrstuvwxyz", "4AE72ED186D196D8F117E449D34E216B0941FF61",
"The quick brown fox jumps over the lazy dog", "A9328020229C163BBF07181C8DF37CE84FC66589",
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "DB9A7E577A346FF058D78576102F2EB9DC849018",
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "7F8FEED959E89BB097B5F741C0342B6DF0A7864D",
"12345678901234567890123456789012345678901234567890123456789012345678901234567890", "92D6F01285FDA7D43E7D09A5AFF01C383CEEE610",
0
};
/** Set of test vectors for one hash function */
struct test_vectors_t {
/** Hash function id */
unsigned hash_id;
/** Array of pairs (message, message_digest) */
const char** tests;
};
/**
* Array of test vectors for short messages
*/
struct test_vectors_t short_test_vectors[] = {
{ RHASH_CRC32, crc32_tests },
{ RHASH_CRC32C, crc32c_tests },
{ RHASH_MD4, md4_tests },
{ RHASH_MD5, md5_tests },
{ RHASH_SHA1, sha1_tests },
{ RHASH_TIGER, tiger_tests },
{ RHASH_TTH, tth_tests },
{ RHASH_BTIH, btih_with_filename_tests },
{ RHASH_BTIH, btih_without_a_filename_tests },
{ RHASH_ED2K, ed2k_tests },
{ RHASH_AICH, aich_tests },
{ RHASH_WHIRLPOOL, whirlpool_tests },
{ RHASH_RIPEMD160, ripemd_tests },
{ RHASH_GOST12_256, gost12_256_tests },
{ RHASH_GOST12_512, gost12_512_tests },
{ RHASH_GOST94, gost94_tests },
{ RHASH_GOST94_CRYPTOPRO, gost94_cryptopro_tests },
{ RHASH_HAS160, has160_tests },
{ RHASH_SNEFRU128, snefru128_tests },
{ RHASH_SNEFRU256, snefru256_tests },
{ RHASH_SHA224, sha224_tests },
{ RHASH_SHA256, sha256_tests },
{ RHASH_SHA384, sha384_tests },
{ RHASH_SHA512, sha512_tests },
{ RHASH_SHA3_224, sha3_224_tests },
{ RHASH_SHA3_256, sha3_256_tests },
{ RHASH_SHA3_384, sha3_384_tests },
{ RHASH_SHA3_512, sha3_512_tests },
{ RHASH_EDONR256, edonr256_tests },
{ RHASH_EDONR512, edonr512_tests },
{ RHASH_BLAKE2S, blake2s_tests },
{ RHASH_BLAKE2B, blake2b_tests },
{ RHASH_BLAKE3, blake3_tests },
{ 0, 0 }
};
/*=========================================================================*
* Debug output and logging *
*=========================================================================*/
static int g_verbose = 0;
static void log_va(int level, const char* format, va_list args)
{
if (g_verbose >= level) {
vprintf(format, args);
fflush(stdout);
}
}
/**
* Print a formatted debug message.
* The message is shown only in verbose mode (-v).
* @param format the format of the message
*/
static void dbg(const char* format, ...)
{
va_list vl;
va_start(vl, format);
log_va(1, format, vl);
va_end(vl);
}
/**
* Print a formatted debug message.
* The message is shown only in very verbose mode (-v -v).
* @param format the format of the message
*/
static void dbg2(const char* format, ...)
{
va_list vl;
va_start(vl, format);
log_va(2, format, vl);
va_end(vl);
}
/**
* The total number of errors
*/
static int g_errors_count = 0;
/**
* Print a formatted error message.
* @param line the line number of the reported error
* @param format the format of the message
*/
static void log_error_impl(int line, const char* format, ...)
{
va_list vl;
va_start(vl, format);
printf("%s:%d: error: ", __FILE__, line);
log_va(0, format, vl);
va_end(vl);
g_errors_count++;
}
#define log_error(msg) \
(log_error_impl(__LINE__, (msg)))
#define log_error1(msg, a) \
(log_error_impl(__LINE__, (msg), (a)))
#define log_error2(msg, a, b) \
(log_error_impl(__LINE__, (msg), (a), (b)))
#define log_error3(msg, a, b, c) \
(log_error_impl(__LINE__, (msg), (a), (b), (c)))
#define log_error4(msg, a, b, c, d) \
(log_error_impl(__LINE__, (msg), (a), (b), (c), (d)))
#define log_error5(msg, a, b, c, d, e) \
(log_error_impl(__LINE__, (msg), (a), (b), (c), (d), (e)))
#define CHECK_NOOP {}
#define CHECK_IMPL(failed, cmd, msg) \
if (failed) { \
log_error(msg); \
cmd; \
}
#define CHECK_EQ(a, b, msg) CHECK_IMPL((a) != (b), CHECK_NOOP, msg)
#define CHECK_NE(a, b, msg) CHECK_IMPL((a) == (b), CHECK_NOOP, msg)
#define CHECK_TRUE(condition, msg) CHECK_IMPL(!(condition), CHECK_NOOP, msg)
#define REQUIRE_EQ(a, b, msg) CHECK_IMPL((a) != (b), return, msg)
#define REQUIRE_NE(a, b, msg) CHECK_IMPL((a) == (b), return, msg)
#define REQUIRE_TRUE(condition, msg) CHECK_IMPL(!(condition), return, msg)
/*=========================================================================*
* Functions for calculating a message digest *
*=========================================================================*/
enum ChunkedDataBitFlags {
CHDT_NO_FLAGS = 0,
CHDT_SET_FILENAME = 1,
CHDT_REPEAT_SMALL_CHUNK = 2
};
/**
* Calculate message digest of the data by chunks of the specified size.
*
* @param hash_id id of the hash algorithm to use
* @param data the data to hash
* @param chunk_size the size of a chunk
* @param total_size the total size of the data to be hashed
* @param flags bit flags to control the hashing process
*/
static char* hash_data_by_chunks(unsigned hash_id, const char* data, size_t chunk_size, size_t total_size, unsigned flags)
{
struct rhash_context* ctx;
size_t left, size;
static char out[130];
if (rhash_get_hash_length(hash_id) >= (int)sizeof(out)) {
log_error("too big hash length\n");
return "";
}
ctx = rhash_init(hash_id);
if (!ctx) {
log_error1("got NULL context for hash_id=0x%08x\n", hash_id);
return "";
}
if ((hash_id == RHASH_BTIH || hash_id == RHASH_ALL_HASHES) && (flags & CHDT_SET_FILENAME)) {
CHECK_NE(0, rhash_torrent_add_file(ctx, "test.txt", (unsigned long long)total_size),
"failed to add filename");
}
if (!!(flags & CHDT_REPEAT_SMALL_CHUNK)) {
/* repeat the small chunk of data until the total_size is reached */
for (left = total_size; left > 0; left -= size) {
size = (left > chunk_size ? chunk_size : left);
rhash_update(ctx, (const unsigned char*)data, size);
}
} else {
/* split the long data buffer and hash it by small chunks */
size_t index;
for (index = 0, left = total_size; left > 0; index += size, left -= size) {
size = (left > chunk_size ? chunk_size : left);
rhash_update(ctx, (const unsigned char*)data + index, size);
}
}
rhash_final(ctx, 0);
rhash_print(out, ctx, hash_id, RHPR_UPPERCASE);
rhash_free(ctx);
return out;
}
/**
* Test a hash algorithm against a message of given length, consisting
* of repeated chunks.
* Report error if calculated hash differs from the expected value.
*
* @param hash_id id of the algorithm to test
* @param data the data to hash
* @param chunk_size the size of the chunk in bytes
* @param total_size the total size of the data to be hashed
* @param hash the expected hash value
* @param flags bit flags to control the hashing process
*/
static void assert_hash_long_msg(unsigned hash_id, const char* data, size_t chunk_size, size_t total_size, const char* hash, const char* msg_name, unsigned flags)
{
char* result;
result = hash_data_by_chunks(hash_id, data, chunk_size, total_size, flags);
if (strcmp(result, hash) != 0) {
const char* hash_name = rhash_get_name(hash_id); /* the hash function name */
if (msg_name)
log_error4("%s(%s) = %s, expected %s\n", hash_name, msg_name, result, hash);
else
log_error4("%s(\"%s\") = %s, expected %s\n", hash_name, data, result, hash);
}
}
/**
* Calculate message digest for the data of given size.
*
* @param hash_id id of the hash algorithm to use
* @param data the data to hash
* @param data_size the size of the data
* @param flags bit flags to control the hashing process
*/
static char* hash_data(unsigned hash_id, const char* data, size_t data_size, unsigned flags)
{
return hash_data_by_chunks(hash_id, data, data_size, data_size, flags);
}
/**
* Calculate message digest of the given message.
*
* @param hash_id id of the hash algorithm to use
* @param str the message to hash
* @param flags bit flags to control the hashing process
*/
static char* hash_message(unsigned hash_id, const char* str, unsigned flags)
{
return hash_data(hash_id, str, strlen(str), flags);
}
/**
* Test a hash algorithm on given message by comparing the result hash value
* against the expected one. Report error on fail.
*
* @param hash_id id of the algorithm to test
* @param str the message to hash
* @param expected_hash the expected hash value
* @param flags bit flags to control the hashing process
*/
static void assert_hash(unsigned hash_id, const char* str, const char* expected_hash, unsigned flags)
{
size_t length = strlen(str);
assert_hash_long_msg(hash_id, str, length, length, expected_hash, NULL, flags);
}
/**
* Test a hash algorithm using a message consisting of given repeated character.
* Report error if calculated hash doesn't coincide with expected value.
*
* @param hash_id id of the algorithm to test
* @param ch the character the message is filled with
* @param msg_size the size of message in bytes
* @param expected_hash the expected hash value
* @param flags bit flags to control the hashing process
*/
static void assert_rep_hash(unsigned hash_id, char ch, size_t msg_size, const char* hash, unsigned flags)
{
char ALIGN_ATTR(64) msg_chunk[8192]; /* 8 KiB */
char msg_name[20];
memset(msg_chunk, ch, 8192);
if (ch >= 32)
sprintf(msg_name, "\"%c\"x%d", ch, (int)msg_size);
else
sprintf(msg_name, "\"\\%o\"x%d", (unsigned)(unsigned char)ch, (int)msg_size);
assert_hash_long_msg(hash_id, msg_chunk, 8192, msg_size, hash, msg_name, flags | CHDT_REPEAT_SMALL_CHUNK);
}
/*=========================================================================*
* Test functions *
*=========================================================================*/
/**
* Test a hash algorithm on array of known short messages.
*
* @param hash_id id of the algorithm to test
* @param ptr pointer to array of pairs
* @param flags bit flags to control the hashing process
*/
static void test_known_strings_pairs(unsigned hash_id, const char** ptr, unsigned flags)
{
for (; ptr[0] && ptr[1]; ptr += 2) {
assert_hash(hash_id, ptr[0], ptr[1], flags);
}
}
/**
* Test a hash algorithm on known short messages.
*
* @param hash_id id of the algorithm to test
*/
static void test_known_strings(unsigned hash_id)
{
int i;
dbg("test known strings\n");
for (i = 0; short_test_vectors[i].tests != 0; i++) {
if (hash_id == short_test_vectors[i].hash_id) {
unsigned flags = (short_test_vectors[i].tests == btih_with_filename_tests ? CHDT_SET_FILENAME : CHDT_NO_FLAGS);
test_known_strings_pairs(hash_id, short_test_vectors[i].tests, flags);
break;
}
}
}
/**
* Verify hash algorithms by testing them against known short messages.
*/
static void test_all_known_strings(void)
{
int i;
dbg("test all known strings\n");
for (i = 0; short_test_vectors[i].tests != 0; i++) {
unsigned flags = (short_test_vectors[i].tests == btih_with_filename_tests ? CHDT_SET_FILENAME : CHDT_NO_FLAGS);
test_known_strings_pairs(short_test_vectors[i].hash_id, short_test_vectors[i].tests, flags);
}
}
/**
* A pair .
*/
typedef struct id_to_hash_t {
int hash_id;
const char* expected_hash;
} id_to_hash_t;
/**
* Verify hash algorithms by testing them on long messages, like
* 1,000,000 charaters of 'a'.
*/
static void test_long_strings(void)
{
unsigned count;
struct id_to_hash_t tests[] = {
{ RHASH_CRC32, "DC25BFBC" }, /* verified with cksfv */
{ RHASH_CRC32C, "436FE240" },
{ RHASH_MD4, "BBCE80CC6BB65E5C6745E30D4EECA9A4" }, /* checked by md4sum */
{ RHASH_MD5, "7707D6AE4E027C70EEA2A935C2296F21" }, /* checked by md5sum */
{ RHASH_SHA1, "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" }, /* checked by sha1sum */
{ RHASH_ED2K, "BBCE80CC6BB65E5C6745E30D4EECA9A4" }, /* checked by eMule' Link Creator (uses eMule algorithm) */
{ RHASH_AICH, "KSYPATEV3KP26FJYUEEBCPL5LQJ5FGUK" }, /* checked by eMule' Link Creator */
{ RHASH_TIGER, "6DB0E2729CBEAD93D715C6A7D36302E9B3CEE0D2BC314B41" }, /* from Tiger author's page (NESSIE test vector) */
{ RHASH_TTH, "KEPTIGT4CQKF7S5EUVNJZSXXIPNMB3XSOAAQS4Y" }, /* verified with Strong DC++ */
{ RHASH_WHIRLPOOL, "0C99005BEB57EFF50A7CF005560DDF5D29057FD86B20BFD62DECA0F1CCEA4AF51FC15490EDDC47AF32BB2B66C34FF9AD8C6008AD677F77126953B226E4ED8B01" }, /* taken from the algorithm reference */
{ RHASH_RIPEMD160, "52783243C1697BDBE16D37F97F68F08325DC1528" }, /* taken from the algorithm reference */
{ RHASH_GOST94_CRYPTOPRO, "8693287AA62F9478F7CB312EC0866B6C4E4A0F11160441E8F4FFCD2715DD554F" }, /* verified with openssl */
{ RHASH_GOST94, "5C00CCC2734CDD3332D3D4749576E3C1A7DBAF0E7EA74E9FA602413C90A129FA" }, /* verified with openssl */
{ RHASH_HAS160, "D6AD6F0608B878DA9B87999C2525CC84F4C9F18D" }, /* verified against jacksum implementation */
{ RHASH_SNEFRU128, "5071F647BC51CFD48F9A8F2D2ED84829" }, /* verified by mhash */
{ RHASH_SNEFRU256, "4A02811F28C121F2162ABB251A01A2A58E6CFC27534AAB10EA6AF0A8DF17FFBF" }, /* verified by mhash */
{ RHASH_SHA224, "20794655980C91D8BBB4C1EA97618A4BF03F42581948B2EE4EE7AD67" }, /* verified against jacksum implementation */
{ RHASH_SHA256, "CDC76E5C9914FB9281A1C7E284D73E67F1809A48A497200E046D39CCC7112CD0" }, /* from NESSIE test vectors */
{ RHASH_SHA384, "9D0E1809716474CB086E834E310A4A1CED149E9C00F248527972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985" }, /* from NESSIE test vectors */
{ RHASH_SHA512, "E718483D0CE769644E2E42C7BC15B4638E1F98B13B2044285632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31BEB009C5C2C49AA2E4EADB217AD8CC09B" }, /* from NESSIE test vectors */
{ RHASH_SHA3_224, "D69335B93325192E516A912E6D19A15CB51C6ED5C15243E7A7FD653C" },
{ RHASH_SHA3_256, "5C8875AE474A3634BA4FD55EC85BFFD661F32ACA75C6D699D0CDCB6C115891C1" },
{ RHASH_SHA3_384, "EEE9E24D78C1855337983451DF97C8AD9EEDF256C6334F8E948D252D5E0E76847AA0774DDB90A842190D2C558B4B8340" },
{ RHASH_SHA3_512, "3C3A876DA14034AB60627C077BB98F7E120A2A5370212DFFB3385A18D4F38859ED311D0A9D5141CE9CC5C66EE689B266A8AA18ACE8282A0E0DB596C90B0A7B87" },
{ RHASH_EDONR256, "56F4B8DC0A41C8EA0A6A42C949883CD5DC25DF8CF4E43AD474FD4492A7A07966" }, /* verified by eBASH SUPERCOP implementation */
{ RHASH_EDONR512, "B4A5A255D67869C990FE79B5FCBDA69958794B8003F01FD11E90FEFEC35F22BD84FFA2E248E8B3C1ACD9B7EFAC5BC66616E234A6E938D3526DEE26BD0DE9C562" }, /* verified by eBASH SUPERCOP implementation */
{ RHASH_BLAKE2S, "BEC0C0E6CDE5B67ACB73B81F79A67A4079AE1C60DAC9D2661AF18E9F8B50DFA5" }, /* verified by b2sum utility */
{ RHASH_BLAKE2B, "98FB3EFB7206FD19EBF69B6F312CF7B64E3B94DBE1A17107913975A793F177E1D077609D7FBA363CBBA00D05F7AA4E4FA8715D6428104C0A75643B0FF3FD3EAF" }, /* verified by b2sum utility */
{ RHASH_BLAKE3, "616F575A1B58D4C9797D4217B9730AE5E6EB319D76EDEF6549B46F4EFE31FF8B" }, /* verified by b3sum utility */
{ RHASH_GOST12_256, "841AF1A0B2F92A800FB1B7E4AABC8E48763153C448A0FC57C90BA830E130F152" },
{ RHASH_GOST12_512, "D396A40B126B1F324465BFA7AA159859AB33FAC02DCDD4515AD231206396A266D0102367E4C544EF47D2294064E1A25342D0CD25AE3D904B45ABB1425AE41095" },
#ifdef USE_KECCAK
{ RHASH_KECCAK_224, "19F9167BE2A04C43ABD0ED554788101B9C339031ACC8E1468531303F" }, /* verified by reference implementation */
{ RHASH_KECCAK_256, "FADAE6B49F129BBB812BE8407B7B2894F34AECF6DBD1F9B0F0C7E9853098FC96" }, /* verified by reference implementation */
{ RHASH_KECCAK_384, "0C8324E1EBC182822C5E2A086CAC07C2FE00E3BCE61D01BA8AD6B71780E2DEC5FB89E5AE90CB593E57BC6258FDD94E17" }, /* verified by reference implementation */
{ RHASH_KECCAK_512, "5CF53F2E556BE5A624425EDE23D0E8B2C7814B4BA0E4E09CBBF3C2FAC7056F61E048FC341262875EBC58A5183FEA651447124370C1EBF4D6C89BC9A7731063BB" }, /* verified by reference implementation */
#endif
{ RHASH_BTIH, "90AE73EE72A12B5A3A39DCA4C5E24BE1F39B6A1B" } /* BTIH with filename="test.txt", verified using uTorrent */
};
dbg("test long strings\n");
/* test all algorithms on 1,000,000 characters of 'a' */
for (count = 0; count < RHASH_COUNTOF(tests); count++) {
unsigned flags = (tests[count].hash_id == RHASH_BTIH ? CHDT_SET_FILENAME : CHDT_NO_FLAGS);
assert_rep_hash(tests[count].hash_id, 'a', 1000000, tests[count].expected_hash, flags);
}
/* BTIH calculated without a filename. The hash value can't be verified by torrent tools */
assert_rep_hash(RHASH_BTIH, 'a', 1000000, "24742F9AE1BD416CF0A6916F2849FE7ABFAC405E", 0);
/* now we verify some specific cases, which caused problems in many libraries */
assert_rep_hash(RHASH_GOST94, '\xFF', 64, "13416C4EC74A63C3EC90CB1748FD462C7572C6C6B41844E48CC1184D1E916098", 0);
assert_rep_hash(RHASH_GOST94_CRYPTOPRO, '\xFF', 64, "58504D26B3677E756BA3F4A9FD2F14B3BA5457066A4AA1D700659B90DCDDD3C6", 0);
/* these messages verified by eMule LinkCreator (which uses eMule variant of ED2K hash) */
assert_rep_hash(RHASH_ED2K, 0, 9728000, "FC21D9AF828F92A8DF64BEAC3357425D", 0);
assert_rep_hash(RHASH_ED2K, 0, 9728000 - 1, "AC44B93FC9AFF773AB0005C911F8396F", 0);
assert_rep_hash(RHASH_ED2K, 0, 9728000 + 1, "06329E9DBA1373512C06386FE29E3C65", 0); /* msg with: 9728000 < size <= 9732096 */
assert_rep_hash(RHASH_AICH, 0, 9728000, "5D3N4HQHIUMQ7IU7A5QLPLI6RHSWOR7B", 0);
assert_rep_hash(RHASH_AICH, 0, 9728000 - 1, "L6SPMD2CM6PRZBGRQ6UFC4HJFFOATRA4", 0);
assert_rep_hash(RHASH_AICH, 0, 9728000 + 1, "HL3TFXORIUEPXUWFPY3JLR7SMKGTO4IH", 0);
#if 0
assert_rep_hash(RHASH_ED2K, 0, 9728000 * 5, "3B613901DABA54F6C0671793E28A1205", 0);
assert_rep_hash(RHASH_AICH, 0, 9728000 * 5, "EZCO3XF2RJ4FERRDEXGOSSRGL5NA5BBM", 0);
#endif
}
/**
* Verify for all algorithms, that rhash_final() returns the same result as
* rhash_print().
*/
static void test_results_consistency(void)
{
const char* msg = "a";
size_t msg_size = strlen(msg);
size_t digest_size;
struct rhash_context* ctx;
unsigned char res1[70];
char res2[70];
unsigned i, hash_id;
dbg("test results consistency\n");
for (i = 0, hash_id = 1; (hash_id & RHASH_ALL_HASHES); hash_id <<= 1, i++) {
digest_size = rhash_get_digest_size(hash_id);
REQUIRE_TRUE(digest_size < 70, "too big digest size\n");
ctx = rhash_init(hash_id);
#ifndef USE_BTIH_WITH_TEST_FILENAME
if ((hash_id & RHASH_BTIH) != 0) {
rhash_torrent_add_file(ctx, "test.txt", (unsigned long long)msg_size);
}
#endif
rhash_update(ctx, msg, msg_size);
rhash_final(ctx, res1);
rhash_print(res2, ctx, hash_id, RHPR_RAW);
rhash_free(ctx);
if (memcmp(res1, res2, digest_size) != 0) {
log_error2("inconsistent %s(\"%s\") hash results\n", rhash_get_name(hash_id), msg);
}
}
}
/**
* Verify that calculated hash doesn't depend on message alignment.
*/
static void test_unaligned_messages_consistency(void)
{
int start, alignment_size;
unsigned all_hash_ids[RHASH_HASH_COUNT];
size_t count = rhash_get_all_algorithms(RHASH_HASH_COUNT, all_hash_ids);
size_t i;
dbg("test unaligned messages consistency\n");
REQUIRE_NE(RHASH_ERROR, count, "failed to get all algorithms\n");
/* loop by hash algorithms */
for (i = 0; i < count; i++) {
unsigned hash_id = all_hash_ids[i];
char expected_hash[130];
REQUIRE_NE(0, hash_id, "bad hash_id == 0\n");
REQUIRE_TRUE(rhash_get_digest_size(hash_id) < (int)sizeof(expected_hash), "too big digest size\n");
alignment_size = (hash_id & (RHASH_TTH | RHASH_TIGER | RHASH_WHIRLPOOL | RHASH_SHA512) ? 8 : 4);
/* start message with different alignment */
for (start = 0; start < alignment_size; start++) {
char message[30];
int j, msg_length = 11 + alignment_size;
/* fill the buffer with the shifted letter sequence */
for (j = 0; j < msg_length; j++)
message[start + j] = 'a' + j;
message[start + j] = 0;
if (start == 0) {
strcpy(expected_hash, hash_message(hash_id, message + start, 0)); /* save hash value */
} else {
assert_hash(hash_id, message + start, expected_hash, 0); /* verify hash value */
}
}
}
}
/**
* Test that a message digest of a data block is independent on a chunk size.
*/
static void test_chunk_size_consistency(void)
{
char buffer[8192];
unsigned all_hash_ids[RHASH_HASH_COUNT];
size_t count = rhash_get_all_algorithms(RHASH_HASH_COUNT, all_hash_ids);
size_t i , j;
dbg("test chunk size consistency\n");
REQUIRE_NE(RHASH_ERROR, count, "failed to get all algorithms\n");
for (i = 0; i < sizeof(buffer); i++)
buffer[i] = (char)(unsigned char)(i % 255);
/* loop by hash algorithms */
for (j = 0; j < count; j++) {
unsigned hash_id = all_hash_ids[j];
char expected_hash[130];
strcpy(expected_hash, hash_data(hash_id, buffer, sizeof(buffer), 0)); /* save hash value */
for (i = 0; i < 2; i++) {
int chunk_size = (i == 0 ? 512 : 3);
char msg_name[40];
sprintf(msg_name, "8k buffer by chunks of %d bytes", chunk_size);
assert_hash_long_msg(hash_id, buffer, chunk_size, sizeof(buffer), expected_hash, msg_name, CHDT_NO_FLAGS);
}
}
}
/**
* Verify alignment of a hash function context, which is located inside of rhash context.
*/
static void test_context_alignment(void)
{
const size_t aligner = 63;
int i;
unsigned hash_ids[32];
dbg("test context alignment\n");
for (i = 0; i < 32; i++)
{
size_t count = i + 1;
rhash ctx;
char* context_ptr;
hash_ids[i] = RHASH_MD5;
ctx = rhash_init_multi(count, hash_ids);
REQUIRE_TRUE(ctx, "NULL rhash context\n");
rhash_get_context(ctx, RHASH_MD5, &context_ptr);
if (((context_ptr - (char*)0) & aligner) != 0) {
log_error4("wrong aligment %d of pointer %p for the %2d-th context (rhash = %p)\n",
(int)((context_ptr - (char*)0) & aligner), context_ptr, i, ctx);
}
rhash_free(ctx);
hash_ids[i] = RHASH_CRC32;
}
}
/**
* Verify processor endianness detected at compile time
* against the actual CPU endianness.
*/
static void test_endianness(void)
{
unsigned tmp = 1;
CHECK_EQ(*(char*)&tmp, IS_LITTLE_ENDIAN, "wrong endianness detected at compile time\n");
}
static void test_version_sanity(void)
{
unsigned version = rhash_get_version();
if (!(version & 0xff000000) || (version & 0xf0e0e0e0))
log_error1("wrong librhash version: %x\n", version);
}
/**
* Run various simple tests.
*/
static void test_generic_assumptions(void)
{
dbg("test generic assumptions\n");
if (RHASH_HASH_COUNT < rhash_popcount(RHASH_LOW_HASHES_MASK)) {
log_error2("wrong algorithms count %d for low mask 0x%x\n", RHASH_HASH_COUNT, RHASH_LOW_HASHES_MASK);
}
CHECK_TRUE(RHASH_EXTENDED_BIT & RHASH_ALL_HASHES, "bad RHASH_ALL_HASHES value");
CHECK_TRUE(!(RHASH_EXTENDED_BIT & RHASH_LOW_HASHES_MASK), "bad RHASH_LOW_HASHES_MASK value");
test_endianness();
test_version_sanity();
}
static void check_openssl_ids(size_t count, unsigned* hash_ids)
{
size_t i;
for (i = 0; i < count; i++) {
unsigned id = hash_ids[i];
if ((id & (id - 1)) != 0 || (id & 0x000f060e) == 0)
log_error2("got bad openssl algorithm id = %08x (%s)\n", id, rhash_get_name(id));
}
}
/**
* Test getting of ids.
*/
static void test_openssl_getters(void)
{
const size_t total = (size_t)RHASH_HASH_COUNT;
unsigned hash_ids[RHASH_HASH_COUNT];
size_t scount, acount, ecount;
dbg2("- test openssl calls\n");
scount = rhash_get_openssl_supported(0, NULL);
REQUIRE_TRUE(scount <= total, "openssl: supported count is greater than the total slgorithm count\n");
CHECK_EQ(scount, rhash_get_openssl_supported(0, hash_ids), "wrong openssl algorithms count\n");
CHECK_EQ(scount, rhash_get_openssl_supported(total, NULL), "wrong openssl algorithms count\n");
if (scount > 1)
CHECK_EQ(RHASH_ERROR, rhash_get_openssl_supported(1, hash_ids), "RHASH_ERROR expected\n");
CHECK_EQ(scount, rhash_get_openssl_supported(scount, hash_ids), "wrong openssl algorithms count\n");
check_openssl_ids(scount, hash_ids);
acount = rhash_get_openssl_available(0, NULL);
CHECK_TRUE(acount <= scount, "openssl: available count is greater than supported count\n");
CHECK_EQ(acount, rhash_get_openssl_available(0, hash_ids), "wrong openssl algorithms count\n");
CHECK_EQ(acount, rhash_get_openssl_available(total, NULL), "wrong openssl algorithms count\n");
CHECK_EQ(acount, rhash_get_openssl_available(acount, hash_ids), "wrong openssl algorithms count\n");
check_openssl_ids(acount, hash_ids);
ecount = rhash_get_openssl_enabled(0, NULL);
CHECK_TRUE(ecount <= acount, "openssl: enabled count is greater than available count\n");
CHECK_EQ(ecount, rhash_get_openssl_enabled(0, hash_ids), "wrong openssl algorithms count\n");
CHECK_EQ(ecount, rhash_get_openssl_enabled(total, NULL), "wrong openssl algorithms count\n");
CHECK_EQ(ecount, rhash_get_openssl_enabled(ecount, hash_ids), "wrong openssl algorithms count\n");
check_openssl_ids(ecount, hash_ids);
/* test changing the list of enabled openssl algorithms */
CHECK_EQ(RHASH_ERROR, rhash_set_openssl_enabled(total, NULL), "RHASH_ERROR expected\n");
CHECK_EQ(ecount, rhash_get_openssl_enabled(0, NULL), "enabled algorithms changed\n");
REQUIRE_EQ(total, rhash_get_all_algorithms(total, hash_ids), "failed to get all algorithms\n");
CHECK_EQ(0, rhash_set_openssl_enabled(total, hash_ids), "failed to enable all openssl algorithms\n");
CHECK_EQ(acount, rhash_get_openssl_enabled(0, NULL), "all available algorithms must be enabled\n");
CHECK_EQ(0, rhash_set_openssl_enabled(0, NULL), "disabling algorithms must work without ids array\n");
CHECK_EQ(0, rhash_get_openssl_enabled(0, NULL), "openssl algorithms were not disabled\n");
REQUIRE_EQ(acount, rhash_get_openssl_available(acount, hash_ids), "failed to get available algorithms\n");
CHECK_EQ(0, rhash_set_openssl_enabled(acount, hash_ids), "failed to enable all openssl algorithms\n");
CHECK_EQ(acount, rhash_get_openssl_enabled(0, NULL), "not all available algorithms were anbled\n");
CHECK_EQ(0, rhash_set_openssl_enabled(0, hash_ids), "failed to disable openssl algorithms\n");
CHECK_EQ(0, rhash_get_openssl_enabled(0, NULL), "openssl algorithms were not disabled\n");
}
/**
* Test getting of ids.
*/
static void test_id_getters(void)
{
const size_t count = (size_t)RHASH_HASH_COUNT;
unsigned hash_ids[RHASH_HASH_COUNT];
unsigned hash_ids2[RHASH_HASH_COUNT];
rhash ctx;
dbg("test algorithms getters\n");
CHECK_EQ(count, rhash_get_all_algorithms(0, hash_ids), "incorrect number of supported algorithms\n");
CHECK_EQ(count, rhash_get_all_algorithms(1, 0), "incorrect number of supported algorithms\n");
CHECK_EQ(RHASH_ERROR, rhash_get_all_algorithms(1, hash_ids), "RHASH_ERROR expected for small buffer\n");
CHECK_EQ(RHASH_ERROR, rhash_get_all_algorithms(count - 1, hash_ids), "RHASH_ERROR expected for small buffer\n");
REQUIRE_EQ(count, rhash_get_all_algorithms(count, hash_ids), "failed to get ids of supported algorithms\n");
ctx = rhash_init_multi(count, hash_ids);
REQUIRE_NE(0, ctx, "got invalid context\n");
CHECK_EQ(count, rhash_get_ctx_algorithms(ctx, 0, hash_ids2), "incorrect number of context algorithms\n");
CHECK_EQ(count, rhash_get_ctx_algorithms(ctx, 1, 0), "incorrect number of context algorithms\n");
CHECK_EQ(RHASH_ERROR, rhash_get_ctx_algorithms(ctx, 1, hash_ids2), "RHASH_ERROR expected for small buffer\n");
CHECK_EQ(RHASH_ERROR, rhash_get_ctx_algorithms(ctx, count - 1, hash_ids2), "RHASH_ERROR expected for small buffer\n");
REQUIRE_EQ(count, rhash_get_ctx_algorithms(ctx, count, hash_ids2), "failed to get ids of context algorithms\n");
CHECK_EQ(0, memcmp(hash_ids, hash_ids2, sizeof(hash_ids)), "unexpected algorithms ids\n");
rhash_free(ctx);
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
REQUIRE_NE(0, rhash_is_openssl_supported(), "openssl must be on\n");
#else
REQUIRE_EQ(0, rhash_is_openssl_supported(), "openssl must be off\n");
#endif
test_openssl_getters();
}
static void test_get_context(void)
{
unsigned hash_ids[2] = { RHASH_CRC32, RHASH_HAS160 };
void* context_ptr = NULL;
rhash ctx = rhash_init_multi(2, hash_ids);
REQUIRE_TRUE(ctx, "NULL rhash context\n");
CHECK_EQ(RHASH_ERROR, rhash_get_context(ctx, RHASH_MD5, &context_ptr), "RHASH_ERROR expected\n");
CHECK_EQ(RHASH_ERROR, rhash_get_context(ctx, RHASH_SHA1, &context_ptr), "RHASH_ERROR expected\n");
CHECK_EQ(0, rhash_get_context(ctx, RHASH_CRC32, &context_ptr), "failed to get context pointer\n");
REQUIRE_NE(NULL, context_ptr, "NULL context pointer\n");
CHECK_EQ(0, *(uint32_t*)context_ptr, "wrong crc32 value\n");
rhash_update(ctx, "abcd", 4);
CHECK_EQ(0, rhash_get_context(ctx, RHASH_HAS160, &context_ptr), "failed to get context pointer\n");
REQUIRE_NE(NULL, context_ptr, "NULL context pointer\n");
CHECK_EQ(0, memcmp("abcd", context_ptr, 4), "wrong message buffer content in hash context\n");
CHECK_EQ(4, *((uint64_t*)context_ptr + 8), "wrong message length in hash context\n");
rhash_free(ctx);
}
static void test_import_export(void)
{
#if !defined(NO_IMPORT_EXPORT)
unsigned export_id = RHASH_ALL_HASHES;
uint8_t data[241];
size_t i;
size_t min_sizes[3] = { 0, 1024, 8192 };
dbg("test import/export\n");
for (i = 0; i < sizeof(data); i++)
data[i] = (uint8_t)i;
for(i = 0; i < 3; i++) {
size_t min_size = min_sizes[i];
size_t size = 0;
size_t required_size;
size_t exported_size;
void* exported_data;
unsigned imported_ids[RHASH_HASH_COUNT];
size_t imported_ids_count;
size_t j;
rhash ctx = rhash_init(export_id);
rhash imported_ctx;
size_t exported_ids_count = rhash_get_ctx_algorithms(ctx, 0, 0);
CHECK_TRUE(exported_ids_count > 0, "wrong number of exported algorithms");
for (; size < min_size; size += sizeof(data))
rhash_update(ctx, data, sizeof(data));
if (export_id == RHASH_BTIH || export_id == RHASH_ALL_HASHES) {
rhash_torrent_set_program_name(ctx, "test");
rhash_torrent_add_announce(ctx, "url1");
rhash_torrent_add_announce(ctx, "url2");
rhash_torrent_add_file(ctx, "file1", 1);
rhash_torrent_add_file(ctx, "file2", 22);
rhash_torrent_set_options(ctx, RHASH_TORRENT_OPT_PRIVATE);
if ((i & 1) != 0)
rhash_final(ctx, 0);
}
dbg2("- call rhash_export NULL\n");
required_size = rhash_export(ctx, NULL, 0);
if (!required_size) {
log_error1("rhash_export failed for block size=%u\n", (unsigned)size);
return;
}
dbg2("- call rhash_export ctx\n");
exported_data = malloc(required_size);
exported_size = rhash_export(ctx, exported_data, required_size);
if (exported_size != required_size) {
log_error2("rhash_export failed: %u != %u\n", (unsigned)exported_size, (unsigned)required_size);
return;
}
dbg2("- call rhash_import\n");
imported_ctx = rhash_import(exported_data, required_size);
if (!imported_ctx) {
log_error1("rhash_import failed for block size=%u\n", (unsigned)size);
return;
}
free(exported_data);
dbg2("- call rhash_final ctx\n");
rhash_final(ctx, 0);
dbg2("- call rhash_final imported_ctx\n");
rhash_final(imported_ctx, 0);
exported_data = NULL;
imported_ids_count = rhash_get_ctx_algorithms(ctx, RHASH_HASH_COUNT, imported_ids);
CHECK_EQ(exported_ids_count, imported_ids_count, "wrong number of imported algorithms");
dbg2("- verify results\n");
for (j = 0; j < imported_ids_count; j++) {
unsigned hash_id = imported_ids[j];
static char out1[240], out2[240];
REQUIRE_NE(0, rhash_print(out1, ctx, hash_id, RHPR_UPPERCASE), "rhash_print failed");
REQUIRE_NE(0, rhash_print(out2, imported_ctx, hash_id, RHPR_UPPERCASE), "rhash_print failed");
if (strcmp(out1, out2) != 0) {
const char* hash_name = rhash_get_name(hash_id);
log_error4("import failed, wrong hash %s != %s for %s, block size=%u\n",
out1, out2, hash_name, (unsigned)size);
return;
}
}
rhash_free(ctx);
rhash_free(imported_ctx);
}
#endif /* !defined(NO_IMPORT_EXPORT) */
}
static uint64_t make_hash_mask(size_t count, unsigned hash_ids[])
{
uint64_t hash_mask = 0;
size_t i;
if (count == 1 && hash_ids[0] == RHASH_ALL_HASHES)
return RHASH_LOW_HASHES_MASK;
for (i = 0; i < count; i++) {
if ((RHASH_EXTENDED_BIT & hash_ids[i]) != 0)
hash_mask |= I64(1) << (unsigned)(hash_ids[i] & ~RHASH_EXTENDED_BIT);
else
hash_mask |= hash_ids[i];
}
return hash_mask;
}
#define TEST_PATH 0x4000000
/**
* Verify a magnet link.
*/
static void test_magnet(const char* expected,
rhash ctx, int flags, size_t count, unsigned hash_ids[])
{
static char out[2800];
const char* path = (flags & TEST_PATH ? "test.txt" : NULL);
uint64_t hash_mask = make_hash_mask(count, hash_ids);
size_t size_calculated = rhash_print_magnet_multi(NULL, 0, path, ctx, flags, count, hash_ids);
size_t size_calculated_legacy = (hash_mask < (uint64_t)RHASH_EXTENDED_BIT ?
rhash_print_magnet(NULL, path, ctx, (unsigned)hash_mask, flags) : 0);
size_t size_printed, size_printed_legacy;
REQUIRE_TRUE(size_calculated < sizeof(out), "too small buffer for magnet link\n");
CHECK_NE(0, size_calculated, "non zero buffer size expected to be returned\n");
if (size_calculated_legacy)
CHECK_EQ(size_calculated, size_calculated_legacy, "wrong size_calculated_legacy\n");
flags &= ~TEST_PATH;
if (size_calculated > 0) {
size_printed = rhash_print_magnet_multi(out, size_calculated - 1, path, ctx, flags, count, hash_ids);
CHECK_EQ(0, size_printed, "too small buffer error expected, but not occurred\n");
}
size_printed = rhash_print_magnet_multi(out, size_calculated, path, ctx, flags, count, hash_ids);
if (size_calculated_legacy)
{
size_printed_legacy = rhash_print_magnet(out, path, ctx, (unsigned)hash_mask, flags);
CHECK_EQ(size_printed, size_printed_legacy, "wrong size_printed_legacy\n");
}
if (expected && strcmp(expected, out) != 0) {
log_error2("\"%s\" != \"%s\"\n", expected, out);
} else {
size_t length = strlen(out) + 1;
if (size_printed != length) {
log_error3("rhash_print_magnet returns wrong length %u != %u for \"%s\"\n",
(unsigned)size_printed, (unsigned)length, out);
} else if (size_printed != size_calculated) {
log_error3("rhash_print_magnet(NULL, ...) returns wrong length %u != %u for \"%s\"\n",
(unsigned)size_calculated, (unsigned)size_printed, out);
}
}
}
/**
* Test printing of magnet links.
*/
static void test_magnet_links(void)
{
unsigned hash_ids_all[RHASH_HASH_COUNT];
unsigned hash_ids_tth[] = { RHASH_TTH };
unsigned hash_ids_md5[] = { RHASH_MD5 };
unsigned hash_ids_special[] = { RHASH_ED2K, RHASH_AICH, RHASH_SHA1, RHASH_BTIH };
unsigned hash_ids_crc32_tth[2] = { RHASH_CRC32, RHASH_TTH };
unsigned hash_id_all_hashes = RHASH_ALL_HASHES;
size_t count = rhash_get_all_algorithms(RHASH_HASH_COUNT, hash_ids_all);
size_t i;
rhash ctx;
dbg("test magnet links\n");
ctx = rhash_init_multi(count, hash_ids_all);
rhash_update(ctx, "a", 1);
rhash_final(ctx, 0);
dbg2("- test specific magnet links\n");
test_magnet("magnet:?xl=1&dn=test.txt&xt=urn:tree:tiger:czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y",
ctx, RHPR_FILESIZE | TEST_PATH, RHASH_COUNTOF(hash_ids_tth), hash_ids_tth);
test_magnet("magnet:?xl=1&xt=urn:md5:0CC175B9C0F1B6A831C399E269772661",
ctx, RHPR_FILESIZE | RHPR_UPPERCASE, RHASH_COUNTOF(hash_ids_md5), hash_ids_md5);
test_magnet(
"xt=urn:ed2k:bde52cb31de33e46245e05fbdbd6fb24&"
"xt=urn:aich:q336in72uwt7zyk5dxolt2xk5i3xmz5y&"
"xt=urn:sha1:q336in72uwt7zyk5dxolt2xk5i3xmz5y&"
"xt=urn:btih:827cd89846fc132e2e67e29c2784c65443bb4dc1",
ctx, RHPR_NO_MAGNET, RHASH_COUNTOF(hash_ids_special), hash_ids_special);
/* verify length calculation for all hashes */
dbg2("- test magnet link length for all hash ids\n");
for (i = 0; i < count; i++) {
unsigned hash_id = hash_ids_all[i];
test_magnet(NULL, ctx, RHPR_FILESIZE | RHPR_NO_MAGNET, 1, &hash_id);
}
test_magnet(NULL, ctx, RHPR_FILESIZE | RHPR_NO_MAGNET, 1, &hash_id_all_hashes);
rhash_free(ctx);
/* test with two hash functions */
dbg2("- test magnet link with two hash functions\n");
ctx = rhash_init_multi(RHASH_COUNTOF(hash_ids_crc32_tth), hash_ids_crc32_tth);
rhash_update(ctx, "abc", 3);
rhash_final(ctx, 0);
test_magnet(
"magnet:?xl=3&xt=urn:crc32:352441c2&"
"xt=urn:tree:tiger:asd4ujseh5m47pdyb46kbtsqtsgdklbhyxomuia",
ctx, RHPR_FILESIZE, 1, &hash_id_all_hashes);
rhash_free(ctx);
}
/*=========================================================================*
* Test file functions *
*=========================================================================*/
/**
* Create temporary file and return its path.
*
* @param filename the name of the file
* @param content the content of the file
* @return the path of the file
*/
static const char* write_temp_file(const char* filename, const char* content)
{
static char file_path[1024];
const char *tmp_dir = NULL;
FILE *fd;
size_t content_length = strlen(content);
size_t length;
int count;
#ifdef _WIN32
# define TEST_PATH_SEPARATOR '\\'
tmp_dir = getenv("TEMP");
if (!tmp_dir) tmp_dir = getenv("TMP");
#else
# define TEST_PATH_SEPARATOR '/'
tmp_dir = getenv("TMPDIR");
# ifdef P_tmpdir
if (!tmp_dir) tmp_dir = P_tmpdir;
# endif
if (!tmp_dir) tmp_dir = "/tmp";
#endif
if (!tmp_dir) {
printf("%s:%d: warning: can't detect temp dir\n", __FILE__, __LINE__);
return NULL;
}
length = strlen(tmp_dir);
if ((length + 1) >= sizeof(file_path))
return NULL;
memcpy(file_path, tmp_dir, length);
while (length > 0 && file_path[length - 1] == TEST_PATH_SEPARATOR)
file_path[--length] = '\0';
assert(length < sizeof(file_path));
count = snprintf(file_path + length, sizeof(file_path) - length,
"%c%s", TEST_PATH_SEPARATOR, filename);
if (count >= (int)(sizeof(file_path)))
return NULL;
fd = fopen(file_path, "w");
if (fd != NULL) {
length = fwrite(content, 1, content_length, fd);
fclose(fd);
if (length == content_length)
return file_path;
log_error1("failed to write to file: %s\n", file_path);
} else {
log_error1("failed to open file for writing: %s\n", file_path);
}
return NULL;
}
struct file_test_ctx {
FILE* file_fd;
int int_fd;
rhash rctx;
const char* path;
};
/**
* Test hashing of a file using rhash_file_update().
* Report error if calculated hash doesn't coincide with expected value.
*
* @param fctx the file test context
* @param offset the file offset to start hashing from
* @param expected the expected hash value
*/
static void test_update_by_file(struct file_test_ctx* fctx, size_t offset, const char* expected)
{
static char result[130];
assert(fctx->file_fd && fctx->rctx);
rhash_reset(fctx->rctx);
fseek(fctx->file_fd, (long)offset, SEEK_SET);
rhash_file_update(fctx->rctx, fctx->file_fd);
rhash_final(fctx->rctx, 0);
rhash_print(result, fctx->rctx, 0, RHPR_UPPERCASE);
if (strcmp(result, expected) != 0)
log_error4("MD5(%s:%d) = %s, expected %s\n", fctx->path, (int)offset, result, expected);
}
/**
* Test hashing of a file using rhash_update_fd().
* Report error if calculated hash doesn't coincide with expected value.
*
* @param fctx the file test context
* @param offset the file offset to start hashing from
* @param data_size the number of bytes to hash
* @param expected the expected hash value
*/
static void test_update_by_fd(struct file_test_ctx* fctx, size_t offset, unsigned long long data_size, const char* expected)
{
static char result[130];
rhash_reset(fctx->rctx);
assert(fctx->int_fd >= 0 && fctx->rctx);
lseek(fctx->int_fd, (off_t)offset, SEEK_SET);
rhash_update_fd(fctx->rctx, fctx->int_fd, data_size);
rhash_final(fctx->rctx, 0);
rhash_print(result, fctx->rctx, 0, RHPR_UPPERCASE);
if (strcmp(result, expected) != 0)
log_error5("MD5(%s:%d:%llu) = %s, expected %s\n", fctx->path, (int)offset, data_size, result, expected);
}
/**
* Test rhash_file_update() and rhash_update_fd().
*/
static void test_file_update(void)
{
const char* test_file_content = "012abc";
struct file_test_ctx fctx;
memset(&fctx, 0 , sizeof(fctx));
if (!(fctx.rctx = rhash_init(RHASH_MD5))) {
log_error("got NULL context for MD5\n");
return;
}
if (!(fctx.path = write_temp_file("test_lib.txt", test_file_content)))
return;
fctx.file_fd = fopen(fctx.path, "r");
if (fctx.file_fd) {
test_update_by_file(&fctx, 0, "CF31AB6B6F7CA8250BB701ADAB94B579");
test_update_by_file(&fctx, 3, "900150983CD24FB0D6963F7D28E17F72");
test_update_by_file(&fctx, 5, "4A8A08F09D37B73795649038408B5F33");
test_update_by_file(&fctx, 6, "D41D8CD98F00B204E9800998ECF8427E");
fclose(fctx.file_fd);
}
fctx.int_fd = open(fctx.path, O_RDONLY);
if (fctx.int_fd > 0) {
test_update_by_fd(&fctx, 0, RHASH_MAX_FILE_SIZE, "CF31AB6B6F7CA8250BB701ADAB94B579");
test_update_by_fd(&fctx, 3, RHASH_MAX_FILE_SIZE, "900150983CD24FB0D6963F7D28E17F72");
test_update_by_fd(&fctx, 3, 1, "0CC175B9C0F1B6A831C399E269772661");
test_update_by_fd(&fctx, 3, 2, "187EF4436122D1CC2F40DC2B92F0EBA0");
test_update_by_fd(&fctx, 4, 1, "92EB5FFEE6AE2FEC3AD71C777531578F");
close(fctx.int_fd);
}
unlink(fctx.path);
rhash_free(fctx.rctx);
}
/**
* Find a hash function id by its name.
*
* @param name hash algorithm name
* @return algorithm id
*/
static unsigned find_hash(const char* name)
{
unsigned hash_ids_all[RHASH_HASH_COUNT];
char buf[32];
size_t count = rhash_get_all_algorithms(RHASH_HASH_COUNT, hash_ids_all);
size_t i;
if (strlen(name) > (sizeof(buf) - 1)) return 0;
for (i = 0; name[i]; i++) buf[i] = toupper(name[i]);
buf[i] = 0;
for (i = 0; i < count; i++)
if (strcmp(buf, rhash_get_name(hash_ids_all[i])) == 0)
return hash_ids_all[i];
return 0;
}
/**
* Detect and print CPU features.
*/
static void print_cpu_features(void)
{
#if !defined(NO_HAS_CPU_FEATURE)
printf("CPU Features:%s%s\n",
(rhash_has_cpu_feature(CPU_FEATURE_SSE4_2) ? " SSE_4.2" : ""),
(rhash_has_cpu_feature(CPU_FEATURE_SHANI) ? " SHANI" : ""));
#endif
}
/**
* Print status of OpenSSL plugin.
*/
static void print_openssl_status(void)
{
unsigned available[RHASH_HASH_COUNT];
unsigned supported[RHASH_HASH_COUNT];
size_t available_count, supported_count;
if (!rhash_is_openssl_supported()) {
printf("OpenSSL is not supported\n");
return;
}
supported_count = rhash_get_openssl_supported(RHASH_HASH_COUNT, supported);
available_count = rhash_get_openssl_available(RHASH_HASH_COUNT, available);
REQUIRE_NE(RHASH_ERROR, supported_count, "failed to load supported openssl algorithms\n");
REQUIRE_NE(RHASH_ERROR, available_count, "failed to load available openssl algorithms\n");
printf("OpenSSL is supported, %s",
(available_count ? "loaded:" : "not loaded\n"));
if (available_count > 0) {
size_t i, j;
for (i = 0; i < available_count; i++)
printf(" %s", rhash_get_name(available[i]));
for (i = 0; i < supported_count; i++) {
unsigned id = supported[i];
for (j = 0; j < available_count && available[j] != id; j++);
if (j == available_count)
printf(" -%s", rhash_get_name(id));
}
printf("\n");
}
}
/**
* The program entry point.
*
* @param argc number of arguments including the program name
* @param argv program arguments including the program name
* @return program exit code
*/
int main(int argc, char* argv[])
{
int test_speed = 0, print_info = 0;
unsigned hash_id = RHASH_SHA1;
int i;
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "--info") || !strcmp(argv[i], "-i")) {
print_info = 1;
}
else if (!strcmp(argv[i], "--verbose") || !strcmp(argv[i], "-v")) {
g_verbose++;
}
else if (!strcmp(argv[i], "--speed") || !strcmp(argv[i], "-s")) {
test_speed = 1;
if ((i + 1) < argc && argv[i + 1][0] != '-') {
hash_id = find_hash(argv[i + 1]);
if (hash_id == 0) {
fprintf(stderr, "error: unknown hash_id: %s\n", argv[i + 1]);
return 1;
}
i++;
}
}
else {
printf("Options:\n"
"-h, --help Print help.\n"
"-v, --verbose Be verbose.\n"
"-i, --info Print library info\n"
"-s, --speed [HASH_NAME] Benchmark given hash algorithm\n");
return 1;
}
}
#ifndef USE_RHASH_DLL
rhash_library_init();
#endif
test_generic_assumptions();
if (print_info) {
printf("%s", compiler_flags);
print_cpu_features();
print_openssl_status();
} else if (test_speed) {
test_known_strings(hash_id);
test_run_benchmark(hash_id, 0, stdout);
} else {
test_all_known_strings();
test_long_strings();
test_results_consistency();
test_unaligned_messages_consistency();
test_chunk_size_consistency();
test_context_alignment();
test_id_getters();
test_get_context();
test_import_export();
test_magnet_links();
test_file_update();
if (g_errors_count == 0)
printf("All sums are working properly!\n");
fflush(stdout);
}
if (g_errors_count > 0)
printf("%s", compiler_flags);
return (g_errors_count == 0 ? 0 : 1);
}
rhash-1.4.6/librhash/ripemd-160.h 0000664 0000000 0000000 00000001377 14703622112 015066 0 ustar root root /* ripemd-160.h */
#ifndef RMD160_H
#define RMD160_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define ripemd160_block_size 64
#define ripemd160_hash_size 20
/* algorithm context */
typedef struct ripemd160_ctx
{
unsigned message[ripemd160_block_size / 4]; /* 512-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
unsigned hash[5]; /* 160-bit algorithm internal hashing state */
} ripemd160_ctx;
/* hash functions */
void rhash_ripemd160_init(ripemd160_ctx* ctx);
void rhash_ripemd160_update(ripemd160_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_ripemd160_final(ripemd160_ctx* ctx, unsigned char result[20]);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RMD160_H */
rhash-1.4.6/librhash/md4.c 0000664 0000000 0000000 00000014473 14703622112 013762 0 ustar root root /* md4.c - an implementation of MD4 Message-Digest Algorithm based on RFC 1320.
*
* Copyright (c) 2007, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include "byte_order.h"
#include "md4.h"
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_md4_init(md4_ctx* ctx)
{
memset(ctx, 0, sizeof(*ctx));
/* initialize state */
ctx->hash[0] = 0x67452301;
ctx->hash[1] = 0xefcdab89;
ctx->hash[2] = 0x98badcfe;
ctx->hash[3] = 0x10325476;
}
/* First, define three auxiliary functions that each take as input
* three 32-bit words and returns a 32-bit word.
* F(x,y,z) = XY v not(X) Z = ((Y xor Z) X) xor Z (the last form is faster)
* G(X,Y,Z) = XY v XZ v YZ
* H(X,Y,Z) = X xor Y xor Z */
#define MD4_F(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))
#define MD4_G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
#define MD4_H(x, y, z) ((x) ^ (y) ^ (z))
/* transformations for rounds 1, 2, and 3. */
#define MD4_ROUND1(a, b, c, d, x, s) { \
(a) += MD4_F((b), (c), (d)) + (x); \
(a) = ROTL32((a), (s)); \
}
#define MD4_ROUND2(a, b, c, d, x, s) { \
(a) += MD4_G((b), (c), (d)) + (x) + 0x5a827999; \
(a) = ROTL32((a), (s)); \
}
#define MD4_ROUND3(a, b, c, d, x, s) { \
(a) += MD4_H((b), (c), (d)) + (x) + 0x6ed9eba1; \
(a) = ROTL32((a), (s)); \
}
/**
* The core transformation. Process a 512-bit block.
* The function has been taken from RFC 1320 with little changes.
*
* @param state algorithm state
* @param x the message block to process
*/
static void rhash_md4_process_block(unsigned state[4], const unsigned* x)
{
register unsigned a, b, c, d;
a = state[0], b = state[1], c = state[2], d = state[3];
MD4_ROUND1(a, b, c, d, x[ 0], 3);
MD4_ROUND1(d, a, b, c, x[ 1], 7);
MD4_ROUND1(c, d, a, b, x[ 2], 11);
MD4_ROUND1(b, c, d, a, x[ 3], 19);
MD4_ROUND1(a, b, c, d, x[ 4], 3);
MD4_ROUND1(d, a, b, c, x[ 5], 7);
MD4_ROUND1(c, d, a, b, x[ 6], 11);
MD4_ROUND1(b, c, d, a, x[ 7], 19);
MD4_ROUND1(a, b, c, d, x[ 8], 3);
MD4_ROUND1(d, a, b, c, x[ 9], 7);
MD4_ROUND1(c, d, a, b, x[10], 11);
MD4_ROUND1(b, c, d, a, x[11], 19);
MD4_ROUND1(a, b, c, d, x[12], 3);
MD4_ROUND1(d, a, b, c, x[13], 7);
MD4_ROUND1(c, d, a, b, x[14], 11);
MD4_ROUND1(b, c, d, a, x[15], 19);
MD4_ROUND2(a, b, c, d, x[ 0], 3);
MD4_ROUND2(d, a, b, c, x[ 4], 5);
MD4_ROUND2(c, d, a, b, x[ 8], 9);
MD4_ROUND2(b, c, d, a, x[12], 13);
MD4_ROUND2(a, b, c, d, x[ 1], 3);
MD4_ROUND2(d, a, b, c, x[ 5], 5);
MD4_ROUND2(c, d, a, b, x[ 9], 9);
MD4_ROUND2(b, c, d, a, x[13], 13);
MD4_ROUND2(a, b, c, d, x[ 2], 3);
MD4_ROUND2(d, a, b, c, x[ 6], 5);
MD4_ROUND2(c, d, a, b, x[10], 9);
MD4_ROUND2(b, c, d, a, x[14], 13);
MD4_ROUND2(a, b, c, d, x[ 3], 3);
MD4_ROUND2(d, a, b, c, x[ 7], 5);
MD4_ROUND2(c, d, a, b, x[11], 9);
MD4_ROUND2(b, c, d, a, x[15], 13);
MD4_ROUND3(a, b, c, d, x[ 0], 3);
MD4_ROUND3(d, a, b, c, x[ 8], 9);
MD4_ROUND3(c, d, a, b, x[ 4], 11);
MD4_ROUND3(b, c, d, a, x[12], 15);
MD4_ROUND3(a, b, c, d, x[ 2], 3);
MD4_ROUND3(d, a, b, c, x[10], 9);
MD4_ROUND3(c, d, a, b, x[ 6], 11);
MD4_ROUND3(b, c, d, a, x[14], 15);
MD4_ROUND3(a, b, c, d, x[ 1], 3);
MD4_ROUND3(d, a, b, c, x[ 9], 9);
MD4_ROUND3(c, d, a, b, x[ 5], 11);
MD4_ROUND3(b, c, d, a, x[13], 15);
MD4_ROUND3(a, b, c, d, x[ 3], 3);
MD4_ROUND3(d, a, b, c, x[11], 9);
MD4_ROUND3(c, d, a, b, x[ 7], 11);
MD4_ROUND3(b, c, d, a, x[15], 15);
state[0] += a, state[1] += b, state[2] += c, state[3] += d;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_md4_update(md4_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
unsigned left = md4_block_size - index;
le32_copy(ctx->message, index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_md4_process_block(ctx->hash, ctx->message);
msg += left;
size -= left;
}
while (size >= md4_block_size) {
unsigned* aligned_message_block;
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
/* the most common case is processing a 32-bit aligned message
on a little-endian CPU without copying it */
aligned_message_block = (unsigned*)msg;
} else {
le32_copy(ctx->message, 0, msg, md4_block_size);
aligned_message_block = ctx->message;
}
rhash_md4_process_block(ctx->hash, aligned_message_block);
msg += md4_block_size;
size -= md4_block_size;
}
if (size) {
/* save leftovers */
le32_copy(ctx->message, 0, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_md4_final(md4_ctx* ctx, unsigned char result[16])
{
unsigned index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
/* pad message and run for last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= ~(0xFFFFFFFFu << shift);
ctx->message[index++] ^= 0x80u << shift;
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
ctx->message[index++] = 0;
}
rhash_md4_process_block(ctx->hash, ctx->message);
index = 0;
}
while (index < 14) {
ctx->message[index++] = 0;
}
ctx->message[14] = (unsigned)(ctx->length << 3);
ctx->message[15] = (unsigned)(ctx->length >> 29);
rhash_md4_process_block(ctx->hash, ctx->message);
if (result) le32_copy(result, 0, &ctx->hash, 16);
}
rhash-1.4.6/librhash/sha1.h 0000664 0000000 0000000 00000001272 14703622112 014130 0 ustar root root /* sha1.h */
#ifndef SHA1_H
#define SHA1_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define sha1_block_size 64
#define sha1_hash_size 20
/* algorithm context */
typedef struct sha1_ctx
{
unsigned char message[sha1_block_size]; /* 512-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
unsigned hash[5]; /* 160-bit algorithm internal hashing state */
} sha1_ctx;
/* hash functions */
void rhash_sha1_init(sha1_ctx* ctx);
void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* SHA1_H */
rhash-1.4.6/librhash/sha3.c 0000664 0000000 0000000 00000023775 15010476501 014142 0 ustar root root /* sha3.c - an implementation of Secure Hash Algorithm 3 (Keccak).
* based on the
* The Keccak SHA-3 submission. Submission to NIST (Round 3), 2011
* by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche
*
* Copyright (c) 2013, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include
#include "byte_order.h"
#include "sha3.h"
/* constants */
#define NumberOfRounds 24
/* SHA3 (Keccak) constants for 24 rounds */
static uint64_t keccak_round_constants[NumberOfRounds] = {
I64(0x0000000000000001), I64(0x0000000000008082), I64(0x800000000000808A), I64(0x8000000080008000),
I64(0x000000000000808B), I64(0x0000000080000001), I64(0x8000000080008081), I64(0x8000000000008009),
I64(0x000000000000008A), I64(0x0000000000000088), I64(0x0000000080008009), I64(0x000000008000000A),
I64(0x000000008000808B), I64(0x800000000000008B), I64(0x8000000000008089), I64(0x8000000000008003),
I64(0x8000000000008002), I64(0x8000000000000080), I64(0x000000000000800A), I64(0x800000008000000A),
I64(0x8000000080008081), I64(0x8000000000008080), I64(0x0000000080000001), I64(0x8000000080008008)
};
/* Initializing a sha3 context for given number of output bits */
static void rhash_keccak_init(sha3_ctx* ctx, unsigned bits)
{
/* NB: The Keccak capacity parameter = bits * 2 */
unsigned rate = 1600 - bits * 2;
memset(ctx, 0, sizeof(sha3_ctx));
ctx->block_size = rate / 8;
assert(rate <= 1600 && (rate % 64) == 0);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_224_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 224);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_256_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 256);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_384_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 384);
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha3_512_init(sha3_ctx* ctx)
{
rhash_keccak_init(ctx, 512);
}
#define XORED_A(i) A[(i)] ^ A[(i) + 5] ^ A[(i) + 10] ^ A[(i) + 15] ^ A[(i) + 20]
#define THETA_STEP(i) \
A[(i)] ^= D[(i)]; \
A[(i) + 5] ^= D[(i)]; \
A[(i) + 10] ^= D[(i)]; \
A[(i) + 15] ^= D[(i)]; \
A[(i) + 20] ^= D[(i)] \
/* Keccak theta() transformation */
static void keccak_theta(uint64_t* A)
{
uint64_t D[5];
D[0] = ROTL64(XORED_A(1), 1) ^ XORED_A(4);
D[1] = ROTL64(XORED_A(2), 1) ^ XORED_A(0);
D[2] = ROTL64(XORED_A(3), 1) ^ XORED_A(1);
D[3] = ROTL64(XORED_A(4), 1) ^ XORED_A(2);
D[4] = ROTL64(XORED_A(0), 1) ^ XORED_A(3);
THETA_STEP(0);
THETA_STEP(1);
THETA_STEP(2);
THETA_STEP(3);
THETA_STEP(4);
}
/* Keccak pi() transformation */
static void keccak_pi(uint64_t* A)
{
uint64_t A1;
A1 = A[1];
A[ 1] = A[ 6];
A[ 6] = A[ 9];
A[ 9] = A[22];
A[22] = A[14];
A[14] = A[20];
A[20] = A[ 2];
A[ 2] = A[12];
A[12] = A[13];
A[13] = A[19];
A[19] = A[23];
A[23] = A[15];
A[15] = A[ 4];
A[ 4] = A[24];
A[24] = A[21];
A[21] = A[ 8];
A[ 8] = A[16];
A[16] = A[ 5];
A[ 5] = A[ 3];
A[ 3] = A[18];
A[18] = A[17];
A[17] = A[11];
A[11] = A[ 7];
A[ 7] = A[10];
A[10] = A1;
/* note: A[ 0] is left as is */
}
#define CHI_STEP(i) \
A0 = A[0 + (i)]; \
A1 = A[1 + (i)]; \
A[0 + (i)] ^= ~A1 & A[2 + (i)]; \
A[1 + (i)] ^= ~A[2 + (i)] & A[3 + (i)]; \
A[2 + (i)] ^= ~A[3 + (i)] & A[4 + (i)]; \
A[3 + (i)] ^= ~A[4 + (i)] & A0; \
A[4 + (i)] ^= ~A0 & A1 \
/* Keccak chi() transformation */
static void keccak_chi(uint64_t* A)
{
uint64_t A0, A1;
CHI_STEP(0);
CHI_STEP(5);
CHI_STEP(10);
CHI_STEP(15);
CHI_STEP(20);
}
static void rhash_sha3_permutation(uint64_t* state)
{
int round;
for (round = 0; round < NumberOfRounds; round++)
{
keccak_theta(state);
/* apply Keccak rho() transformation */
state[ 1] = ROTL64(state[ 1], 1);
state[ 2] = ROTL64(state[ 2], 62);
state[ 3] = ROTL64(state[ 3], 28);
state[ 4] = ROTL64(state[ 4], 27);
state[ 5] = ROTL64(state[ 5], 36);
state[ 6] = ROTL64(state[ 6], 44);
state[ 7] = ROTL64(state[ 7], 6);
state[ 8] = ROTL64(state[ 8], 55);
state[ 9] = ROTL64(state[ 9], 20);
state[10] = ROTL64(state[10], 3);
state[11] = ROTL64(state[11], 10);
state[12] = ROTL64(state[12], 43);
state[13] = ROTL64(state[13], 25);
state[14] = ROTL64(state[14], 39);
state[15] = ROTL64(state[15], 41);
state[16] = ROTL64(state[16], 45);
state[17] = ROTL64(state[17], 15);
state[18] = ROTL64(state[18], 21);
state[19] = ROTL64(state[19], 8);
state[20] = ROTL64(state[20], 18);
state[21] = ROTL64(state[21], 2);
state[22] = ROTL64(state[22], 61);
state[23] = ROTL64(state[23], 56);
state[24] = ROTL64(state[24], 14);
keccak_pi(state);
keccak_chi(state);
/* apply iota(state, round) */
*state ^= keccak_round_constants[round];
}
}
/**
* The core transformation. Process the specified block of data.
*
* @param hash the algorithm state
* @param block the message block to process
* @param block_size the size of the processed block in bytes
*/
static void rhash_sha3_process_block(uint64_t hash[25], const uint64_t* block, size_t block_size)
{
/* expanded loop */
hash[ 0] ^= le2me_64(block[ 0]);
hash[ 1] ^= le2me_64(block[ 1]);
hash[ 2] ^= le2me_64(block[ 2]);
hash[ 3] ^= le2me_64(block[ 3]);
hash[ 4] ^= le2me_64(block[ 4]);
hash[ 5] ^= le2me_64(block[ 5]);
hash[ 6] ^= le2me_64(block[ 6]);
hash[ 7] ^= le2me_64(block[ 7]);
hash[ 8] ^= le2me_64(block[ 8]);
/* if not sha3-512 */
if (block_size > 72) {
hash[ 9] ^= le2me_64(block[ 9]);
hash[10] ^= le2me_64(block[10]);
hash[11] ^= le2me_64(block[11]);
hash[12] ^= le2me_64(block[12]);
/* if not sha3-384 */
if (block_size > 104) {
hash[13] ^= le2me_64(block[13]);
hash[14] ^= le2me_64(block[14]);
hash[15] ^= le2me_64(block[15]);
hash[16] ^= le2me_64(block[16]);
/* if not sha3-256 */
if (block_size > 136) {
hash[17] ^= le2me_64(block[17]);
#ifdef FULL_SHA3_FAMILY_SUPPORT
/* if not sha3-224 */
if (block_size > 144) {
hash[18] ^= le2me_64(block[18]);
hash[19] ^= le2me_64(block[19]);
hash[20] ^= le2me_64(block[20]);
hash[21] ^= le2me_64(block[21]);
hash[22] ^= le2me_64(block[22]);
hash[23] ^= le2me_64(block[23]);
hash[24] ^= le2me_64(block[24]);
}
#endif
}
}
}
/* make a permutation of the hash */
rhash_sha3_permutation(hash);
}
#define SHA3_FINALIZED 0x80000000
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha3_update(sha3_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->rest;
size_t block_size = (size_t)ctx->block_size;
if (ctx->rest & SHA3_FINALIZED) return; /* too late for additional input */
ctx->rest = (unsigned)((ctx->rest + size) % block_size);
/* fill partial block */
if (index) {
size_t left = block_size - index;
memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
msg += left;
size -= left;
}
while (size >= block_size) {
uint64_t* aligned_message_block;
if (IS_ALIGNED_64(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (uint64_t*)msg;
} else {
memcpy(ctx->message, msg, block_size);
aligned_message_block = ctx->message;
}
rhash_sha3_process_block(ctx->hash, aligned_message_block, block_size);
msg += block_size;
size -= block_size;
}
if (size) {
memcpy(ctx->message, msg, size); /* save leftovers */
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha3_final(sha3_ctx* ctx, unsigned char* result)
{
size_t digest_length = 100 - ctx->block_size / 2;
const size_t block_size = ctx->block_size;
if (!(ctx->rest & SHA3_FINALIZED))
{
/* clear the rest of the data queue */
memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
((char*)ctx->message)[ctx->rest] |= 0x06;
((char*)ctx->message)[block_size - 1] |= 0x80;
/* process final block */
rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
}
assert(block_size > digest_length);
if (result) me64_to_le_str(result, ctx->hash, digest_length);
}
#ifdef USE_KECCAK
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_keccak_final(sha3_ctx* ctx, unsigned char* result)
{
size_t digest_length = 100 - ctx->block_size / 2;
const size_t block_size = ctx->block_size;
if (!(ctx->rest & SHA3_FINALIZED))
{
/* clear the rest of the data queue */
memset((char*)ctx->message + ctx->rest, 0, block_size - ctx->rest);
((char*)ctx->message)[ctx->rest] |= 0x01;
((char*)ctx->message)[block_size - 1] |= 0x80;
/* process final block */
rhash_sha3_process_block(ctx->hash, ctx->message, block_size);
ctx->rest = SHA3_FINALIZED; /* mark context as finalized */
}
assert(block_size > digest_length);
if (result) me64_to_le_str(result, ctx->hash, digest_length);
}
#endif /* USE_KECCAK */
rhash-1.4.6/librhash/edonr.c 0000664 0000000 0000000 00000044376 14703622112 014412 0 ustar root root /* edonr.c - an implementation of EDON-R 256/224/384/512 hash functions
*
* Copyright (c) 2011, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* This implementation is based on the article:
* D. Gligoroski, R. S. Odegard, M. Mihova, S. J. Knapskog, ...,
* Cryptographic Hash Function EDON-R - Submission to NIST, 2008
*
* EDON-R has been designed to be much more efficient than SHA-2
* cryptographic hash functions, offering the same or better security.
*/
#include
#include "byte_order.h"
#include "edonr.h"
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_edonr256_init(edonr_ctx* ctx)
{
static const unsigned EDONR256_H0[16] = {
0x40414243, 0x44454647, 0x48494a4b, 0x4c4d4e4f, 0x50515253, 0x54555657,
0x58595a5b, 0x5c5d5e5f, 0x60616263, 0x64656667, 0x68696a6b, 0x6c6d6e6f,
0x70717273, 0x74757677, 0x78797a7b, 0x7c7d7e7f
};
#if FULL_CTX_INITIALIZATION
memset(ctx, 0, sizeof(*ctx));
#else
ctx->length = 0;
#endif
ctx->digest_length = edonr256_hash_size;
memcpy(ctx->u.data256.hash, EDONR256_H0, sizeof(EDONR256_H0));
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_edonr224_init(struct edonr_ctx* ctx)
{
static const unsigned EDONR224_H0[16] = {
0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617,
0x18191a1b, 0x1c1d1e1f, 0x20212223, 0x24252627, 0x28292a2b, 0x2c2d2e2f,
0x30313233, 0x24353637, 0x38393a3b, 0x3c3d3e3f
};
#if FULL_CTX_INITIALIZATION
memset(ctx, 0, sizeof(*ctx));
#else
ctx->length = 0;
#endif
ctx->digest_length = edonr224_hash_size;
memcpy(ctx->u.data256.hash, EDONR224_H0, sizeof(EDONR224_H0));
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_edonr512_init(edonr_ctx* ctx)
{
static const uint64_t EDONR512_H0[16] = {
I64(0x8081828384858687), I64(0x88898a8b8c8d8e8f), I64(0x9091929394959697),
I64(0x98999a9b9c9d9e9f), I64(0xa0a1a2a3a4a5a6a7), I64(0xa8a9aaabacadaeaf),
I64(0xb0b1b2b3b4b5b6b7), I64(0xb8b9babbbcbdbebf), I64(0xc0c1c2c3c4c5c6c7),
I64(0xc8c9cacbcccdcecf), I64(0xd0d1d2d3d4d5d6d7), I64(0xd8d9dadbdcdddedf),
I64(0xe0e1e2e3e4e5e6e7), I64(0xe8e9eaebecedeeef), I64(0xf0f1f2f3f4f5f6f7),
I64(0xf8f9fafbfcfdfeff)
};
#if FULL_CTX_INITIALIZATION
memset(ctx, 0, sizeof(*ctx));
#else
ctx->length = 0;
#endif
ctx->digest_length = edonr512_hash_size;
memcpy(ctx->u.data512.hash, EDONR512_H0, sizeof(EDONR512_H0));
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_edonr384_init(struct edonr_ctx* ctx)
{
static const uint64_t EDONR384_H0[16] = {
I64(0x0001020304050607), I64(0x08090a0b0c0d0e0f), I64(0x1011121314151617),
I64(0x18191a1b1c1d1e1f), I64(0x2021222324252627), I64(0x28292a2b2c2d2e2f),
I64(0x3031323324353637), I64(0x38393a3b3c3d3e3f), I64(0x4041424344454647),
I64(0x48494a4b4c4d4e4f), I64(0x5051525354555657), I64(0x58595a5b5c5d5e5f),
I64(0x6061626364656667), I64(0x68696a6b6c6d6e6f), I64(0x7071727374757677),
I64(0x78797a7b7c7d7e7f)
};
#if FULL_CTX_INITIALIZATION
memset(ctx, 0, sizeof(*ctx));
#else
ctx->length = 0;
#endif
ctx->digest_length = edonr384_hash_size;
memcpy(ctx->u.data512.hash, EDONR384_H0, sizeof(EDONR384_H0));
}
/* Q256 macro, taken from eBASH submission */
#define Q256(x0,x1,x2,x3,x4,x5,x6,x7,y0,y1,y2,y3,y4,y5,y6,y7,z0,z1,z2,z3,z4,z5,z6,z7) \
{\
/* The First Latin Square\
0 7 1 3 2 4 6 5\
4 1 7 6 3 0 5 2\
7 0 4 2 5 3 1 6\
1 4 0 5 6 2 7 3\
2 3 6 7 1 5 0 4\
5 2 3 1 7 6 4 0\
3 6 5 0 4 7 2 1\
6 5 2 4 0 1 3 7\
*/\
t8 = x0 + x4; \
t9 = x1 + x7; \
t12 = t8 + t9; \
t10 = x2 + x3; \
t11 = x5 + x6; \
t13 = t10 + t11; \
t0 = 0xaaaaaaaa + t12 + x2; \
t1 = t12 + x3; \
t1 = ROTL32((t1), 5); \
t2 = t12 + x6; \
t2 = ROTL32((t2), 11); \
t3 = t13 + x7; \
t3 = ROTL32((t3), 13); \
t4 = x1 + t13; \
t4 = ROTL32((t4), 17); \
t5 = t8 + t10 + x5; \
t5 = ROTL32((t5), 19); \
t6 = x0 + t9 + t11; \
t6 = ROTL32((t6), 29); \
t7 = t13 + x4; \
t7 = ROTL32((t7), 31); \
\
t16 = t0 ^ t4; \
t17 = t1 ^ t7; \
t18 = t2 ^ t3; \
t19 = t5 ^ t6; \
t8 = t3 ^ t19; \
t9 = t2 ^ t19; \
t10 = t18 ^ t5; \
t11 = t16 ^ t1; \
t12 = t16 ^ t7; \
t13 = t17 ^ t6; \
t14 = t18 ^ t4; \
t15 = t0 ^ t17; \
\
/* The Second Orthogonal Latin Square\
0 4 2 3 1 6 5 7\
7 6 3 2 5 4 1 0\
5 3 1 6 0 2 7 4\
1 0 5 4 3 7 2 6\
2 1 0 7 4 5 6 3\
3 5 7 0 6 1 4 2\
4 7 6 1 2 0 3 5\
6 2 4 5 7 3 0 1\
*/\
t16 = y0 + y1; \
t17 = y2 + y5; \
t20 = t16 + t17; \
t18 = y3 + y4; \
t22 = t16 + t18; \
t19 = y6 + y7; \
t21 = t18 + t19; \
t23 = t17 + t19; \
t0 = 0x55555555 + t20 + y7; \
t1 = t22 + y6; \
t1 = ROTL32((t1), 3); \
t2 = t20 + y3; \
t2 = ROTL32((t2), 7); \
t3 = y2 + t21; \
t3 = ROTL32((t3), 11); \
t4 = t22 + y5; \
t4 = ROTL32((t4), 17); \
t5 = t23 + y4; \
t5 = ROTL32((t5), 19); \
t6 = y1 + t23; \
t6 = ROTL32((t6), 23); \
t7 = y0 + t21; \
t7 = ROTL32((t7), 29); \
\
t16 = t0 ^ t1; \
t17 = t2 ^ t5; \
t18 = t3 ^ t4; \
t19 = t6 ^ t7; \
z5 = t8 + (t18 ^ t6); \
z6 = t9 + (t17 ^ t7); \
z7 = t10 + (t4 ^ t19); \
z0 = t11 + (t16 ^ t5); \
z1 = t12 + (t2 ^ t19); \
z2 = t13 + (t16 ^ t3); \
z3 = t14 + (t0 ^ t18); \
z4 = t15 + (t1 ^ t17); \
}
/* Q512 macro, taken from eBASH submission */
#define Q512(x0,x1,x2,x3,x4,x5,x6,x7,y0,y1,y2,y3,y4,y5,y6,y7,z0,z1,z2,z3,z4,z5,z6,z7) \
{\
/* First Latin Square\
0 7 1 3 2 4 6 5\
4 1 7 6 3 0 5 2\
7 0 4 2 5 3 1 6\
1 4 0 5 6 2 7 3\
2 3 6 7 1 5 0 4\
5 2 3 1 7 6 4 0\
3 6 5 0 4 7 2 1\
6 5 2 4 0 1 3 7\
*/\
t8 = x0 + x4; \
t9 = x1 + x7; \
t12 = t8 + t9; \
t10 = x2 + x3; \
t11 = x5 + x6; \
t13 = t10 + t11; \
t0 = I64(0xaaaaaaaaaaaaaaaa) + t12 + x2; \
t1 = t12 + x3; \
t1 = ROTL64((t1), 5); \
t2 = t12 + x6; \
t2 = ROTL64((t2),19); \
t3 = t13 + x7; \
t3 = ROTL64((t3),29); \
t4 = x1 + t13; \
t4 = ROTL64((t4),31); \
t5 = t8 + t10 + x5; \
t5 = ROTL64((t5),41); \
t6 = x0 + t9 + t11; \
t6 = ROTL64((t6),57); \
t7 = t13 + x4; \
t7 = ROTL64((t7),61); \
\
t16 = t0 ^ t4; \
t17 = t1 ^ t7; \
t18 = t2 ^ t3; \
t19 = t5 ^ t6; \
t8 = t3 ^ t19; \
t9 = t2 ^ t19; \
t10 = t18 ^ t5; \
t11 = t16 ^ t1; \
t12 = t16 ^ t7; \
t13 = t17 ^ t6; \
t14 = t18 ^ t4; \
t15 = t0 ^ t17; \
\
/* Second Orthogonal Latin Square\
0 4 2 3 1 6 5 7\
7 6 3 2 5 4 1 0\
5 3 1 6 0 2 7 4\
1 0 5 4 3 7 2 6\
2 1 0 7 4 5 6 3\
3 5 7 0 6 1 4 2\
4 7 6 1 2 0 3 5\
6 2 4 5 7 3 0 1\
*/\
t16 = y0 + y1; \
t17 = y2 + y5; \
t20 = t16 + t17; \
t18 = y3 + y4; \
t22 = t16 + t18; \
t19 = y6 + y7; \
t21 = t18 + t19; \
t23 = t17 + t19; \
t0 = I64(0x5555555555555555) + t20 + y7; \
t1 = t22 + y6; \
t1 = ROTL64((t1), 3); \
t2 = t20 + y3; \
t2 = ROTL64((t2), 17); \
t3 = y2 + t21; \
t3 = ROTL64((t3), 23); \
t4 = t22 + y5; \
t4 = ROTL64((t4), 31); \
t5 = t23 + y4; \
t5 = ROTL64((t5), 37); \
t6 = y1 + t23; \
t6 = ROTL64((t6), 45); \
t7 = y0 + t21; \
t7 = ROTL64((t7), 59); \
\
t16 = t0 ^ t1; \
t17 = t2 ^ t5; \
t18 = t3 ^ t4; \
t19 = t6 ^ t7; \
z5 = t8 + (t18 ^ t6); \
z6 = t9 + (t17 ^ t7); \
z7 = t10 + (t4 ^ t19); \
z0 = t11 + (t16 ^ t5); \
z1 = t12 + (t2 ^ t19); \
z2 = t13 + (t16 ^ t3); \
z3 = t14 + (t0 ^ t18); \
z4 = t15 + (t1 ^ t17); \
}
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_edonr256_process_block(unsigned hash[16], const unsigned* block, size_t count)
{
while (1) {
uint32_t t0, t1, t2, t3, t4, t5, t6, t7;
uint32_t t8, t9, t10, t11, t12, t13, t14, t15;
uint32_t t16, t17,t18, t19, t20, t21, t22, t23;
uint32_t p16, p17, p18, p19, p20, p21, p22, p23;
uint32_t p24, p25, p26, p27, p28, p29, p30, p31;
/* First row of quasigroup e-transformations */
Q256(block[15], block[14], block[13], block[12], block[11], block[10], block[ 9], block[ 8],
block[ 0], block[ 1], block[ 2], block[ 3], block[ 4], block[ 5], block[ 6], block[ 7],
p16, p17, p18, p19, p20, p21, p22, p23);
Q256(p16, p17, p18, p19, p20, p21, p22, p23,
block[ 8], block[ 9], block[10], block[11], block[12], block[13], block[14], block[15],
p24, p25, p26, p27, p28, p29, p30, p31);
/* Second row of quasigroup e-transformations */
Q256(hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15],
p16, p17, p18, p19, p20, p21, p22, p23,
p16, p17, p18, p19, p20, p21, p22, p23);
Q256(p16, p17, p18, p19, p20, p21, p22, p23,
p24, p25, p26, p27, p28, p29, p30, p31,
p24, p25, p26, p27, p28, p29, p30, p31);
/* Third row of quasigroup e-transformations */
Q256(p16, p17, p18, p19, p20, p21, p22, p23,
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7],
p16, p17, p18, p19, p20, p21, p22, p23);
Q256(p24, p25, p26, p27, p28, p29, p30, p31,
p16, p17, p18, p19, p20, p21, p22, p23,
p24, p25, p26, p27, p28, p29, p30, p31);
/* Fourth row of quasigroup e-transformations */
Q256(block[ 7], block[ 6], block[ 5], block[ 4], block[ 3], block[ 2], block[ 1], block[ 0],
p16, p17, p18, p19, p20, p21, p22, p23,
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7]);
Q256(hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7],
p24, p25, p26, p27, p28, p29, p30, p31,
hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]);
if (!--count) return;
block += edonr256_block_size / sizeof(unsigned);
};
}
/**
* The core transformation. Process a 1024-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_edonr512_process_block(uint64_t hash[16], const uint64_t* block, size_t count)
{
while (1) {
uint64_t t0, t1, t2, t3, t4, t5, t6, t7;
uint64_t t8, t9, t10, t11, t12, t13, t14, t15;
uint64_t t16, t17,t18, t19, t20, t21, t22, t23;
uint64_t p16, p17, p18, p19, p20, p21, p22, p23;
uint64_t p24, p25, p26, p27, p28, p29, p30, p31;
/* First row of quasigroup e-transformations */
Q512(block[15], block[14], block[13], block[12], block[11], block[10], block[ 9], block[ 8],
block[ 0], block[ 1], block[ 2], block[ 3], block[ 4], block[ 5], block[ 6], block[ 7],
p16, p17, p18, p19, p20, p21, p22, p23);
Q512(p16, p17, p18, p19, p20, p21, p22, p23,
block[ 8], block[ 9], block[10], block[11], block[12], block[13], block[14], block[15],
p24, p25, p26, p27, p28, p29, p30, p31);
/* Second row of quasigroup e-transformations */
Q512(hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15],
p16, p17, p18, p19, p20, p21, p22, p23,
p16, p17, p18, p19, p20, p21, p22, p23);
Q512(p16, p17, p18, p19, p20, p21, p22, p23,
p24, p25, p26, p27, p28, p29, p30, p31,
p24, p25, p26, p27, p28, p29, p30, p31);
/* Third row of quasigroup e-transformations */
Q512(p16, p17, p18, p19, p20, p21, p22, p23,
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7],
p16, p17, p18, p19, p20, p21, p22, p23);
Q512(p24, p25, p26, p27, p28, p29, p30, p31,
p16, p17, p18, p19, p20, p21, p22, p23,
p24, p25, p26, p27, p28, p29, p30, p31);
/* Fourth row of quasigroup e-transformations */
Q512(block[ 7], block[ 6], block[ 5], block[ 4], block[ 3], block[ 2], block[ 1], block[ 0],
p16, p17, p18, p19, p20, p21, p22, p23,
hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7]);
Q512(hash[ 0], hash[ 1], hash[ 2], hash[ 3], hash[ 4], hash[ 5], hash[ 6], hash[ 7],
p24, p25, p26, p27, p28, p29, p30, p31,
hash[ 8], hash[ 9], hash[10], hash[11], hash[12], hash[13], hash[14], hash[15]);
if (!--count) return;
block += edonr512_block_size / sizeof(uint64_t);
};
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_edonr256_update(edonr_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
size_t left = edonr256_block_size - index;
le32_copy(ctx->u.data256.message, index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1);
msg += left;
size -= left;
}
if (size >= edonr256_block_size) {
#if defined(CPU_IA32) || defined(CPU_X64)
if (1)
#else
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg))
#endif
{
/* the most common case is processing a 32-bit aligned message
on a little-endian CPU without copying it */
size_t count = size / edonr256_block_size;
rhash_edonr256_process_block(ctx->u.data256.hash, (unsigned*)msg, count);
msg += edonr256_block_size * count;
size -= edonr256_block_size * count;
} else {
do {
le32_copy(ctx->u.data256.message, 0, msg, edonr256_block_size);
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1);
msg += edonr256_block_size;
size -= edonr256_block_size;
} while (size >= edonr256_block_size);
}
}
if (size) {
le32_copy(ctx->u.data256.message, 0, msg, size); /* save leftovers */
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_edonr256_final(edonr_ctx* ctx, unsigned char* result)
{
size_t index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
/* pad message and run for the last block */
/* append the byte 0x80 to the message */
ctx->u.data256.message[index] &= ~(0xFFFFFFFFu << shift);
ctx->u.data256.message[index++] ^= 0x80u << shift;
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
ctx->u.data256.message[index++] = 0;
}
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1);
index = 0;
}
while (index < 14) {
ctx->u.data256.message[index++] = 0;
}
/* store message length in bits */
ctx->u.data256.message[14] = (unsigned)(ctx->length << 3);
ctx->u.data256.message[15] = (unsigned)(ctx->length >> 29);
rhash_edonr256_process_block(ctx->u.data256.hash, ctx->u.data256.message, 1);
if (result) {
/* copy last bytes of intermidiate hash */
int off = (ctx->digest_length <= 256 ? 64 : 128) - ctx->digest_length;
le32_copy(result, 0, ((char*)ctx->u.data256.hash) + off, ctx->digest_length);
}
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_edonr512_update(edonr_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 127;
ctx->length += size;
/* fill partial block */
if (index) {
size_t left = edonr512_block_size - index;
le64_copy(ctx->u.data512.message, index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1);
msg += left;
size -= left;
}
if (size >= edonr512_block_size) {
#if defined(CPU_IA32) || defined(CPU_X64)
if (1)
#else
if (IS_LITTLE_ENDIAN && IS_ALIGNED_64(msg))
#endif
{
/* the most common case is processing a 64-bit aligned message
on a little-endian CPU without copying it */
size_t count = size / edonr512_block_size;
rhash_edonr512_process_block(ctx->u.data512.hash, (uint64_t*)msg, count);
msg += edonr512_block_size * count;
size -= edonr512_block_size * count;
} else {
do {
le64_copy(ctx->u.data512.message, 0, msg, edonr512_block_size);
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1);
msg += edonr512_block_size;
size -= edonr512_block_size;
} while (size >= edonr512_block_size);
}
}
if (size) {
le64_copy(ctx->u.data512.message, 0, msg, size); /* save leftovers */
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_edonr512_final(edonr_ctx* ctx, unsigned char* result)
{
size_t index = ((unsigned)ctx->length & 127) >> 3;
unsigned shift = ((unsigned)ctx->length & 7) * 8;
/* pad message and run for the last block */
/* append the byte 0x80 to the message */
ctx->u.data512.message[index] &= ~(I64(0xFFFFFFFFFFFFFFFF) << shift);
ctx->u.data512.message[index++] ^= I64(0x80) << shift;
/* if no room left in the message to store 64-bit message length */
if (index == 16) {
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1);
index = 0;
}
while (index < 15) {
ctx->u.data512.message[index++] = 0;
}
/* store message length in bits */
ctx->u.data512.message[15] = ctx->length << 3;
rhash_edonr512_process_block(ctx->u.data512.hash, ctx->u.data512.message, 1);
if (result) {
/* copy last bytes of intermidiate hash */
int off = edonr512_block_size - ctx->digest_length;
le64_copy(result, 0, ((char*)ctx->u.data512.hash) + off, ctx->digest_length);
}
}
rhash-1.4.6/librhash/blake2s.c 0000664 0000000 0000000 00000011632 14703622112 014613 0 ustar root root /* blake2s.c - an implementation of blake2s hash function.
*
* Copyright (c) 2012, Samuel Neves
* Copyright (c) 2021, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "blake2s.h"
#include "byte_order.h"
#include
static const uint32_t blake2s_IV[8] =
{
0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
};
static const uint8_t blake2s_sigma[10][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
};
void rhash_blake2s_init(blake2s_ctx* ctx)
{
memset(ctx, 0, sizeof(*ctx));
/* init state by xoring IV with blake2s input parameter block */
ctx->hash[0] = blake2s_IV[0] ^ 0x01010020;
ctx->hash[1] = blake2s_IV[1];
ctx->hash[2] = blake2s_IV[2];
ctx->hash[3] = blake2s_IV[3];
ctx->hash[4] = blake2s_IV[4];
ctx->hash[5] = blake2s_IV[5];
ctx->hash[6] = blake2s_IV[6];
ctx->hash[7] = blake2s_IV[7];
}
#define G(r,i,a,b,c,d) \
do { \
a = a + b + m[blake2s_sigma[r][2*i+0]]; \
d = ROTR32(d ^ a, 16); \
c = c + d; \
b = ROTR32(b ^ c, 12); \
a = a + b + m[blake2s_sigma[r][2*i+1]]; \
d = ROTR32(d ^ a, 8); \
c = c + d; \
b = ROTR32(b ^ c, 7); \
} while(0)
#define ROUND(r) \
do { \
G(r,0,v[0],v[4],v[ 8],v[12]); \
G(r,1,v[1],v[5],v[ 9],v[13]); \
G(r,2,v[2],v[6],v[10],v[14]); \
G(r,3,v[3],v[7],v[11],v[15]); \
G(r,4,v[0],v[5],v[10],v[15]); \
G(r,5,v[1],v[6],v[11],v[12]); \
G(r,6,v[2],v[7],v[ 8],v[13]); \
G(r,7,v[3],v[4],v[ 9],v[14]); \
} while(0)
static void rhash_blake2s_process_block(blake2s_ctx* ctx, const uint32_t* m, uint32_t finalization_flag)
{
uint32_t v[16];
size_t i;
memcpy(v, ctx->hash, sizeof(uint32_t) * 8);
v[ 8] = blake2s_IV[0];
v[ 9] = blake2s_IV[1];
v[10] = blake2s_IV[2];
v[11] = blake2s_IV[3];
v[12] = blake2s_IV[4] ^ (uint32_t)ctx->length;
v[13] = blake2s_IV[5] ^ (uint32_t)(ctx->length >> 32);
v[14] = blake2s_IV[6] ^ finalization_flag;
v[15] = blake2s_IV[7];
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
ROUND(7);
ROUND(8);
ROUND(9);
for(i = 0; i < 8; ++i)
ctx->hash[i] ^= v[i] ^ v[i + 8];
}
void rhash_blake2s_update(blake2s_ctx* ctx, const unsigned char* msg, size_t size)
{
if(size > 0)
{
size_t index = (size_t)ctx->length & 63;
if(index)
{
size_t rest = blake2s_block_size - index;
if (size > rest) {
le32_copy(ctx->message, index, msg, rest); /* fill the block */
/* process the block */
size -= rest;
msg += rest;
ctx->length += rest;
index = 0;
rhash_blake2s_process_block(ctx, ctx->message, 0);
}
} else if (ctx->length) {
rhash_blake2s_process_block(ctx, ctx->message, 0);
}
while(size > blake2s_block_size) {
uint32_t* aligned_message_block;
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
aligned_message_block = (uint32_t*)msg;
} else {
le32_copy(ctx->message, 0, msg, blake2s_block_size);
aligned_message_block = ctx->message;
}
size -= blake2s_block_size;
msg += blake2s_block_size;
ctx->length += blake2s_block_size;
rhash_blake2s_process_block(ctx, aligned_message_block, 0);
}
le32_copy(ctx->message, index, msg, size); /* save leftovers */
ctx->length += size;
}
}
void rhash_blake2s_final(blake2s_ctx* ctx, unsigned char *result)
{
size_t length = (size_t)ctx->length & 63;
if (length)
{
/* pad the message with zeros */
size_t index = length >> 2;
unsigned shift = (unsigned)(length & 3) * 8;
ctx->message[index] &= ~(0xFFFFFFFFu << shift);
for(index++; index < 16; index++)
ctx->message[index] = 0;
}
rhash_blake2s_process_block(ctx, ctx->message, 0xFFFFFFFFu);
/* convert hash state to result bytes */
le32_copy(result, 0, ctx->hash, blake2s_hash_size);
}
rhash-1.4.6/librhash/byte_order.h 0000664 0000000 0000000 00000020771 15010476501 015440 0 ustar root root /* byte_order.h */
#ifndef BYTE_ORDER_H
#define BYTE_ORDER_H
#include "ustd.h"
#include
#if defined(__GLIBC__)
# include
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
# include
#elif defined (__NetBSD__) || defined(__OpenBSD__)
# include
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* if x86 compatible cpu */
#if defined(i386) || defined(__i386__) || defined(__i486__) || \
defined(__i586__) || defined(__i686__) || defined(__pentium__) || \
defined(__pentiumpro__) || defined(__pentium4__) || \
defined(__nocona__) || defined(prescott) || defined(__core2__) || \
defined(__k6__) || defined(__k8__) || defined(__athlon__) || \
defined(__amd64) || defined(__amd64__) || \
defined(__x86_64) || defined(__x86_64__) || defined(_M_IX86) || \
defined(_M_AMD64) || defined(_M_IA64) || defined(_M_X64)
/* detect if x86-64 instruction set is supported */
# if defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
# define CPU_X64
# else
# define CPU_IA32
# endif
#endif
#define RHASH_BYTE_ORDER_LE 1234
#define RHASH_BYTE_ORDER_BE 4321
#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) || \
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
#elif defined(_BYTE_ORDER)
# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
# elif defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
# endif
#elif defined(__sun) && defined(_LITTLE_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
#elif defined(__sun) && defined(_BIG_ENDIAN)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
#endif
/* try detecting endianness by CPU */
#ifdef RHASH_BYTE_ORDER
#elif defined(CPU_IA32) || defined(CPU_X64) || defined(__ia64) || defined(__ia64__) || \
defined(__alpha__) || defined(_M_ALPHA) || defined(vax) || defined(MIPSEL) || \
defined(_ARM_) || defined(__arm__) || defined(_M_ARM64) || defined(_M_ARM64EC) || \
defined(__loongarch64)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_LE
#elif defined(__sparc) || defined(__sparc__) || defined(sparc) || \
defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_POWER) || \
defined(__POWERPC__) || defined(POWERPC) || defined(__powerpc) || \
defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || \
defined(__hpux) || defined(_MIPSEB) || defined(mc68000) || \
defined(__s390__) || defined(__s390x__) || defined(sel) || defined(__hppa__)
# define RHASH_BYTE_ORDER RHASH_BYTE_ORDER_BE
#else
# error "Can't detect CPU architechture"
#endif
#define IS_BIG_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_BE)
#define IS_LITTLE_ENDIAN (RHASH_BYTE_ORDER == RHASH_BYTE_ORDER_LE)
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
#ifdef __clang__
# define HAS_CLANG_BUILTIN(x) __has_builtin(x)
#else
# define HAS_CLANG_BUILTIN(x) 0
#endif
#ifdef __GNUC__
# define HAS_GNUC(a, b) (__GNUC__ > a || (__GNUC__ == a && __GNUC_MINOR__ >= b))
#else
# define HAS_GNUC(a, b) 0
#endif
#define IS_ALIGNED_32(p) (0 == (3 & (uintptr_t)(p)))
#define IS_ALIGNED_64(p) (0 == (7 & (uintptr_t)(p)))
#if defined(_MSC_VER)
#define ALIGN_ATTR(n) __declspec(align(n))
#elif defined(__GNUC__)
#define ALIGN_ATTR(n) __attribute__((aligned (n)))
#else
#define ALIGN_ATTR(n) /* nothing */
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define I64(x) x##ui64
#else
#define I64(x) x##ULL
#endif
#if defined(_MSC_VER)
#define RHASH_INLINE __inline
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define RHASH_INLINE inline
#elif defined(__GNUC__)
#define RHASH_INLINE __inline__
#else
#define RHASH_INLINE
#endif
/* rhash_ctz - count traling zero bits */
#if HAS_GNUC(3, 4) || HAS_CLANG_BUILTIN(__builtin_ctz)
# define rhash_ctz(x) __builtin_ctz(x)
# define rhash_ctz64(x) __builtin_ctzll(x)
#else
unsigned rhash_ctz(unsigned);
unsigned rhash_ctz64(uint64_t);
#endif
/* rhash_popcount - count the number of 1-bits */
#if HAS_GNUC(3, 4) || HAS_CLANG_BUILTIN(__builtin_popcount)
# define rhash_popcount(x) __builtin_popcount(x)
#else
unsigned rhash_popcount(unsigned); /* define as function */
#endif
void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length);
void rhash_swap_memset_to_u32(void* to, int index, int c, size_t length);
void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length);
void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length);
void rhash_u32_mem_swap(unsigned* p, int length_in_u32);
/* bswap definitions */
#if HAS_GNUC(4, 3) || \
(HAS_CLANG_BUILTIN(__builtin_bswap32) && HAS_CLANG_BUILTIN(__builtin_bswap64))
# define bswap_32(x) __builtin_bswap32(x)
# define bswap_64(x) __builtin_bswap64(x)
#elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */
# define bswap_32(x) ((uint32_t)_byteswap_ulong((unsigned long)x))
# define bswap_64(x) ((uint64_t)_byteswap_uint64((__int64)x))
#else
/* fallback to generic bswap definition */
static RHASH_INLINE uint32_t bswap_32(uint32_t x)
{
# if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) && !defined(RHASH_NO_ASM)
__asm("bswap\t%0" : "=r" (x) : "0" (x)); /* gcc x86 version */
return x;
# else
x = ((x << 8) & 0xFF00FF00u) | ((x >> 8) & 0x00FF00FFu);
return (x >> 16) | (x << 16);
# endif
}
static RHASH_INLINE uint64_t bswap_64(uint64_t x)
{
union {
uint64_t ll;
uint32_t l[2];
} w, r;
w.ll = x;
r.l[0] = bswap_32(w.l[1]);
r.l[1] = bswap_32(w.l[0]);
return r.ll;
}
#endif /* bswap definitions */
#if IS_BIG_ENDIAN
# define be2me_32(x) (x)
# define be2me_64(x) (x)
# define le2me_32(x) bswap_32(x)
# define le2me_64(x) bswap_64(x)
# define be32_copy(to, index, from, length) memcpy((char*)(to) + (index), (from), (length))
# define le32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length))
# define be32_memset(to, index, c, length) memset((char*)(to) + (index), (c), (length))
# define le32_memset(to, index, c, length) rhash_swap_memset_to_u32((to), (index), (c), (length))
# define be64_copy(to, index, from, length) memcpy((char*)(to) + (index), (from), (length))
# define le64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length))
# define me64_to_be_str(to, from, length) memcpy((to), (from), (length))
# define me64_to_le_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
#else /* IS_BIG_ENDIAN */
# define be2me_32(x) bswap_32(x)
# define be2me_64(x) bswap_64(x)
# define le2me_32(x) (x)
# define le2me_64(x) (x)
# define be32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length))
# define le32_copy(to, index, from, length) memcpy((char*)(to) + (index), (from), (length))
# define be32_memset(to, index, c, length) rhash_swap_memset_to_u32((to), (index), (c), (length))
# define le32_memset(to, index, c, length) memset((char*)(to) + (index), (c), (length))
# define be64_copy(to, index, from, length) rhash_swap_copy_str_to_u64((to), (index), (from), (length))
# define le64_copy(to, index, from, length) memcpy((char*)(to) + (index), (from), (length))
# define me64_to_be_str(to, from, length) rhash_swap_copy_u64_to_str((to), (from), (length))
# define me64_to_le_str(to, from, length) memcpy((to), (from), (length))
#endif /* IS_BIG_ENDIAN */
/* ROTL/ROTR macros rotate a 32/64-bit word left/right by n bits */
#define ROTL32(dword, n) ((dword) << (n) ^ ((dword) >> (32 - (n))))
#define ROTR32(dword, n) ((dword) >> (n) ^ ((dword) << (32 - (n))))
#define ROTL64(qword, n) ((qword) << (n) ^ ((qword) >> (64 - (n))))
#define ROTR64(qword, n) ((qword) >> (n) ^ ((qword) << (64 - (n))))
#define CPU_FEATURE_SSE4_2 (52)
#define CPU_FEATURE_SHANI (29)
#if (HAS_GNUC(3, 4) || defined(__clang__)) && (defined(CPU_X64) || defined(CPU_IA32))
# define HAS_GCC_INTEL_CPUID
int has_cpu_feature(unsigned feature_bit);
#elif (_MSC_VER >= 1310) && (_M_IX86 || _M_AMD64)
# define HAS_MSVC_INTEL_CPUID
int has_cpu_feature(unsigned feature_bit);
#else
# define NO_HAS_CPU_FEATURE
# define has_cpu_feature(x) (0)
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* BYTE_ORDER_H */
rhash-1.4.6/librhash/hex.h 0000664 0000000 0000000 00000001663 14703622112 014064 0 ustar root root /* hex.h - conversion for hexadecimal and base32 strings. */
#ifndef HEX_H
#define HEX_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
void rhash_byte_to_hex(char* dest, const unsigned char* src, size_t length, int upper_case);
void rhash_byte_to_base32(char* dest, const unsigned char* src, size_t length, int upper_case);
void rhash_byte_to_base64(char* dest, const unsigned char* src, size_t length);
char* rhash_print_hex_byte(char* dest, const unsigned char byte, int upper_case);
size_t rhash_urlencode(char* dst, const char* str, size_t size, int upper_case);
size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case);
int rhash_sprintI64(char* dst, uint64_t number);
#define BASE32_LENGTH(bytes) (((bytes) * 8 + 4) / 5)
#define BASE64_LENGTH(bytes) ((((bytes) + 2) / 3) * 4)
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* HEX_H */
rhash-1.4.6/librhash/sha512.c 0000664 0000000 0000000 00000023470 14703622112 014276 0 ustar root root /* sha512.c - an implementation of SHA-384/512 hash functions
* based on FIPS 180-3 (Federal Information Processing Standart).
*
* Copyright (c) 2010, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include "byte_order.h"
#include "sha512.h"
/* SHA-384 and SHA-512 constants for 80 rounds. These qwords represent
* the first 64 bits of the fractional parts of the cube
* roots of the first 80 prime numbers. */
static const uint64_t rhash_k512[80] = {
I64(0x428a2f98d728ae22), I64(0x7137449123ef65cd), I64(0xb5c0fbcfec4d3b2f),
I64(0xe9b5dba58189dbbc), I64(0x3956c25bf348b538), I64(0x59f111f1b605d019),
I64(0x923f82a4af194f9b), I64(0xab1c5ed5da6d8118), I64(0xd807aa98a3030242),
I64(0x12835b0145706fbe), I64(0x243185be4ee4b28c), I64(0x550c7dc3d5ffb4e2),
I64(0x72be5d74f27b896f), I64(0x80deb1fe3b1696b1), I64(0x9bdc06a725c71235),
I64(0xc19bf174cf692694), I64(0xe49b69c19ef14ad2), I64(0xefbe4786384f25e3),
I64(0x0fc19dc68b8cd5b5), I64(0x240ca1cc77ac9c65), I64(0x2de92c6f592b0275),
I64(0x4a7484aa6ea6e483), I64(0x5cb0a9dcbd41fbd4), I64(0x76f988da831153b5),
I64(0x983e5152ee66dfab), I64(0xa831c66d2db43210), I64(0xb00327c898fb213f),
I64(0xbf597fc7beef0ee4), I64(0xc6e00bf33da88fc2), I64(0xd5a79147930aa725),
I64(0x06ca6351e003826f), I64(0x142929670a0e6e70), I64(0x27b70a8546d22ffc),
I64(0x2e1b21385c26c926), I64(0x4d2c6dfc5ac42aed), I64(0x53380d139d95b3df),
I64(0x650a73548baf63de), I64(0x766a0abb3c77b2a8), I64(0x81c2c92e47edaee6),
I64(0x92722c851482353b), I64(0xa2bfe8a14cf10364), I64(0xa81a664bbc423001),
I64(0xc24b8b70d0f89791), I64(0xc76c51a30654be30), I64(0xd192e819d6ef5218),
I64(0xd69906245565a910), I64(0xf40e35855771202a), I64(0x106aa07032bbd1b8),
I64(0x19a4c116b8d2d0c8), I64(0x1e376c085141ab53), I64(0x2748774cdf8eeb99),
I64(0x34b0bcb5e19b48a8), I64(0x391c0cb3c5c95a63), I64(0x4ed8aa4ae3418acb),
I64(0x5b9cca4f7763e373), I64(0x682e6ff3d6b2b8a3), I64(0x748f82ee5defb2fc),
I64(0x78a5636f43172f60), I64(0x84c87814a1f0ab72), I64(0x8cc702081a6439ec),
I64(0x90befffa23631e28), I64(0xa4506cebde82bde9), I64(0xbef9a3f7b2c67915),
I64(0xc67178f2e372532b), I64(0xca273eceea26619c), I64(0xd186b8c721c0c207),
I64(0xeada7dd6cde0eb1e), I64(0xf57d4f7fee6ed178), I64(0x06f067aa72176fba),
I64(0x0a637dc5a2c898a6), I64(0x113f9804bef90dae), I64(0x1b710b35131c471b),
I64(0x28db77f523047d84), I64(0x32caab7b40c72493), I64(0x3c9ebe0a15c9bebc),
I64(0x431d67c49c100d4c), I64(0x4cc5d4becb3e42b6), I64(0x597f299cfc657e2a),
I64(0x5fcb6fab3ad6faec), I64(0x6c44198c4a475817)
};
/* The SHA512/384 functions defined by FIPS 180-3, 4.1.3 */
/* Optimized version of Ch(x,y,z)=((x & y) | (~x & z)) */
#define Ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z))))
/* Optimized version of Maj(x,y,z)=((x & y) ^ (x & z) ^ (y & z)) */
#define Maj(x,y,z) (((x) & (y)) ^ ((z) & ((x) ^ (y))))
#define Sigma0(x) (ROTR64((x), 28) ^ ROTR64((x), 34) ^ ROTR64((x), 39))
#define Sigma1(x) (ROTR64((x), 14) ^ ROTR64((x), 18) ^ ROTR64((x), 41))
#define sigma0(x) (ROTR64((x), 1) ^ ROTR64((x), 8) ^ ((x) >> 7))
#define sigma1(x) (ROTR64((x), 19) ^ ROTR64((x), 61) ^ ((x) >> 6))
/* Recalculate element n-th of circular buffer W using formula
* W[n] = sigma1(W[n - 2]) + W[n - 7] + sigma0(W[n - 15]) + W[n - 16]; */
#define RECALCULATE_W(W,n) (W[n] += \
(sigma1(W[(n - 2) & 15]) + W[(n - 7) & 15] + sigma0(W[(n - 15) & 15])))
#define ROUND(a,b,c,d,e,f,g,h,k,data) { \
uint64_t T1 = h + Sigma1(e) + Ch(e,f,g) + k + (data); \
d += T1, h = T1 + Sigma0(a) + Maj(a,b,c); }
#define ROUND_1_16(a,b,c,d,e,f,g,h,n) \
ROUND(a,b,c,d,e,f,g,h, rhash_k512[n], W[n] = be2me_64(block[n]))
#define ROUND_17_80(a,b,c,d,e,f,g,h,n) \
ROUND(a,b,c,d,e,f,g,h, k[n], RECALCULATE_W(W, n))
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha512_init(sha512_ctx* ctx)
{
/* Initial values. These words were obtained by taking the first 32
* bits of the fractional parts of the square roots of the first
* eight prime numbers. */
static const uint64_t SHA512_H0[8] = {
I64(0x6a09e667f3bcc908), I64(0xbb67ae8584caa73b), I64(0x3c6ef372fe94f82b),
I64(0xa54ff53a5f1d36f1), I64(0x510e527fade682d1), I64(0x9b05688c2b3e6c1f),
I64(0x1f83d9abfb41bd6b), I64(0x5be0cd19137e2179)
};
memset(ctx->message, 0, sizeof(ctx->message));
ctx->length = 0;
ctx->digest_length = sha512_hash_size;
/* initialize algorithm state */
memcpy(ctx->hash, SHA512_H0, sizeof(ctx->hash));
}
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha384_init(struct sha512_ctx* ctx)
{
/* Initial values from FIPS 180-3. These words were obtained by taking
* the first sixty-four bits of the fractional parts of the square
* roots of ninth through sixteenth prime numbers. */
static const uint64_t SHA384_H0[8] = {
I64(0xcbbb9d5dc1059ed8), I64(0x629a292a367cd507), I64(0x9159015a3070dd17),
I64(0x152fecd8f70e5939), I64(0x67332667ffc00b31), I64(0x8eb44a8768581511),
I64(0xdb0c2e0d64f98fa7), I64(0x47b5481dbefa4fa4)
};
memset(ctx->message, 0, sizeof(ctx->message));
ctx->length = 0;
ctx->digest_length = sha384_hash_size;
memcpy(ctx->hash, SHA384_H0, sizeof(ctx->hash));
}
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_sha512_process_block(uint64_t hash[8], uint64_t block[16])
{
uint64_t A, B, C, D, E, F, G, H;
uint64_t W[16];
const uint64_t* k;
int i;
A = hash[0], B = hash[1], C = hash[2], D = hash[3];
E = hash[4], F = hash[5], G = hash[6], H = hash[7];
/* Compute SHA using alternate Method: FIPS 180-3 6.1.3 */
ROUND_1_16(A, B, C, D, E, F, G, H, 0);
ROUND_1_16(H, A, B, C, D, E, F, G, 1);
ROUND_1_16(G, H, A, B, C, D, E, F, 2);
ROUND_1_16(F, G, H, A, B, C, D, E, 3);
ROUND_1_16(E, F, G, H, A, B, C, D, 4);
ROUND_1_16(D, E, F, G, H, A, B, C, 5);
ROUND_1_16(C, D, E, F, G, H, A, B, 6);
ROUND_1_16(B, C, D, E, F, G, H, A, 7);
ROUND_1_16(A, B, C, D, E, F, G, H, 8);
ROUND_1_16(H, A, B, C, D, E, F, G, 9);
ROUND_1_16(G, H, A, B, C, D, E, F, 10);
ROUND_1_16(F, G, H, A, B, C, D, E, 11);
ROUND_1_16(E, F, G, H, A, B, C, D, 12);
ROUND_1_16(D, E, F, G, H, A, B, C, 13);
ROUND_1_16(C, D, E, F, G, H, A, B, 14);
ROUND_1_16(B, C, D, E, F, G, H, A, 15);
for (i = 16, k = &rhash_k512[16]; i < 80; i += 16, k += 16) {
ROUND_17_80(A, B, C, D, E, F, G, H, 0);
ROUND_17_80(H, A, B, C, D, E, F, G, 1);
ROUND_17_80(G, H, A, B, C, D, E, F, 2);
ROUND_17_80(F, G, H, A, B, C, D, E, 3);
ROUND_17_80(E, F, G, H, A, B, C, D, 4);
ROUND_17_80(D, E, F, G, H, A, B, C, 5);
ROUND_17_80(C, D, E, F, G, H, A, B, 6);
ROUND_17_80(B, C, D, E, F, G, H, A, 7);
ROUND_17_80(A, B, C, D, E, F, G, H, 8);
ROUND_17_80(H, A, B, C, D, E, F, G, 9);
ROUND_17_80(G, H, A, B, C, D, E, F, 10);
ROUND_17_80(F, G, H, A, B, C, D, E, 11);
ROUND_17_80(E, F, G, H, A, B, C, D, 12);
ROUND_17_80(D, E, F, G, H, A, B, C, 13);
ROUND_17_80(C, D, E, F, G, H, A, B, 14);
ROUND_17_80(B, C, D, E, F, G, H, A, 15);
}
hash[0] += A, hash[1] += B, hash[2] += C, hash[3] += D;
hash[4] += E, hash[5] += F, hash[6] += G, hash[7] += H;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha512_update(sha512_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 127;
ctx->length += size;
/* fill partial block */
if (index) {
size_t left = sha512_block_size - index;
memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_sha512_process_block(ctx->hash, ctx->message);
msg += left;
size -= left;
}
while (size >= sha512_block_size) {
uint64_t* aligned_message_block;
if (IS_ALIGNED_64(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (uint64_t*)msg;
} else {
memcpy(ctx->message, msg, sha512_block_size);
aligned_message_block = ctx->message;
}
rhash_sha512_process_block(ctx->hash, aligned_message_block);
msg += sha512_block_size;
size -= sha512_block_size;
}
if (size) {
memcpy(ctx->message, msg, size); /* save leftovers */
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha512_final(sha512_ctx* ctx, unsigned char* result)
{
size_t index = ((unsigned)ctx->length & 127) >> 3;
unsigned shift = ((unsigned)ctx->length & 7) * 8;
/* pad message and process the last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= le2me_64( ~(I64(0xFFFFFFFFFFFFFFFF) << shift) );
ctx->message[index++] ^= le2me_64( I64(0x80) << shift );
/* if no room left in the message to store 128-bit message length */
if (index >= 15) {
if (index == 15) ctx->message[index] = 0;
rhash_sha512_process_block(ctx->hash, ctx->message);
index = 0;
}
while (index < 15) {
ctx->message[index++] = 0;
}
ctx->message[15] = be2me_64(ctx->length << 3);
rhash_sha512_process_block(ctx->hash, ctx->message);
if (result) be64_copy(result, 0, ctx->hash, ctx->digest_length);
}
rhash-1.4.6/librhash/util.h 0000664 0000000 0000000 00000006063 15010476501 014255 0 ustar root root /* util.h */
#ifndef UTIL_H
#define UTIL_H
#include /* for aligned_alloc and __GLIBC__ version macros */
#ifdef __cplusplus
extern "C" {
#endif
/* compile-time assert */
#define RHASH_ASSERT(condition) (void)sizeof(char[1 - 2 * !(condition)])
#define RHASH_COUNTOF(array) (sizeof(array) / sizeof(*array))
/* define atomic_compare_and_swap() */
#if (defined(__GNUC__) && __GNUC__ >= 4 && (__GNUC__ > 4 || __GNUC_MINOR__ >= 1) \
&& defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) \
|| (defined(__INTEL_COMPILER) && !defined(_WIN32))
/* atomic operations are defined by ICC and GCC >= 4.1, but by the later one supposedly not for ARM */
/* note: ICC on ia64 platform possibly require ia64intrin.h, need testing */
# define atomic_compare_and_swap(ptr, oldval, newval) __sync_val_compare_and_swap(ptr, oldval, newval)
#elif defined(_MSC_VER)
# define WIN32_LEAN_AND_MEAN
# include
# define atomic_compare_and_swap(ptr, oldval, newval) InterlockedCompareExchange(ptr, newval, oldval)
#elif defined(__sun)
# include
# define atomic_compare_and_swap(ptr, oldval, newval) atomic_cas_32(ptr, oldval, newval)
#else
/* fallback case */
# define atomic_compare_and_swap(ptr, oldval, newval) { if (*(ptr) == (oldval)) *(ptr) = (newval); }
# define NO_ATOMIC_BUILTINS
#endif
/* alignment macros */
#define DEFAULT_ALIGNMENT 64
#define ALIGN_SIZE_BY(size, align) (((size) + ((align) - 1)) & ~((align) - 1))
#define IS_SIZE_ALIGNED_BY(size, align) (((size) & ((align) - 1)) == 0)
#define IS_PTR_ALIGNED_BY(ptr, align) IS_SIZE_ALIGNED_BY((uintptr_t)(ptr), (align))
/* define rhash_aligned_alloc() and rhash_aligned_free() */
#if !defined(NO_WIN32_ALIGNED_ALLOC) && defined(_WIN32)
# define HAS_WIN32_ALIGNED_ALLOC
# include
# define rhash_aligned_alloc(alignment, size) _aligned_malloc((size), (alignment))
# define rhash_aligned_free(ptr) _aligned_free(ptr)
#elif !defined(NO_STDC_ALIGNED_ALLOC) && (__STDC_VERSION__ >= 201112L || defined(_ISOC11_SOURCE)) \
&& !defined(__APPLE__) && !defined(__HAIKU__) && !defined(__sun) \
&& (!defined(__GLIBC__) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 15)) \
&& (!defined(__ANDROID_API__) || __ANDROID_API__ >= 28)
# define HAS_STDC_ALIGNED_ALLOC
# define rhash_aligned_alloc(alignment, size) aligned_alloc((alignment), ALIGN_SIZE_BY(size, alignment))
# define rhash_aligned_free(ptr) free(ptr)
#else /* defined(_WIN32) ... */
# include "ustd.h" /* for _POSIX_VERSION macro */
# if !defined(NO_POSIX_ALIGNED_ALLOC) && (_POSIX_VERSION >= 200112L || _XOPEN_SOURCE >= 600)
# define HAS_POSIX_ALIGNED_ALLOC
# define rhash_aligned_alloc(alignment, size) rhash_px_aalloc((alignment), ALIGN_SIZE_BY(size, sizeof(void*)))
# define rhash_aligned_free(ptr) free(ptr)
void* rhash_px_aalloc(size_t size, size_t alignment);
# else
# define HAS_GENERIC_ALIGNED_ALLOC
void* rhash_aligned_alloc(size_t alignment, size_t size);
void rhash_aligned_free(void* ptr);
# endif /* !defined(NO_POSIX_ALIGNED_ALLOC) ... */
#endif /* defined(_WIN32) ... */
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* UTIL_H */
rhash-1.4.6/librhash/crc32.c 0000664 0000000 0000000 00000152351 14703622112 014210 0 ustar root root /* crc32.c - an implementation of CRC32 and CRC32C hash functions
*
* Copyright (c) 2006, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#if !defined(DISABLE_CRC32) || !defined(DISABLE_CRC32C)
#include
#include "byte_order.h"
#include "crc32.h"
#if IS_LITTLE_ENDIAN
# define GET_BYTE(uint, shift) (((uint) >> (shift)) & 0xFF)
#else
# define GET_BYTE(uint, shift) (((uint) >> (24 - (shift))) & 0xFF)
#endif
/**
* Calculate CRC sum, defined by table
*/
static unsigned calculate_crc_soft(unsigned crcinit, unsigned table[8][256], const unsigned char* msg, size_t size)
{
uint32_t crc = ~crcinit;
const uint32_t* current;
/* process not aligned message head */
for (; (3 & (uintptr_t)msg) && size > 0; msg++, size--)
crc = table[0][(crc & 0xFF) ^ *msg] ^ (crc >> 8);
/* process aligned part */
for (current = (uint32_t*) msg; size >= 8; size -= 8)
{
uint32_t one = *current++ ^ le2me_32(crc);
uint32_t two = *current++;
crc = table[7][ GET_BYTE(one, 0)] ^
table[6][GET_BYTE(one, 8)] ^
table[5][GET_BYTE(one, 16)] ^
table[4][GET_BYTE(one, 24)] ^
table[3][GET_BYTE(two, 0)] ^
table[2][GET_BYTE(two, 8)] ^
table[1][GET_BYTE(two, 16)] ^
table[0][GET_BYTE(two, 24)];
}
/* process trailing bytes */
for (msg = (unsigned char*) current; size; size--)
crc = table[0][(crc & 0xFF) ^ *msg++] ^ (crc >> 8);
return ~crc;
}
#else
typedef int dummy_declaration_required_by_strict_iso_c;
#endif
#ifndef DISABLE_CRC32
unsigned rhash_crc32_table[8][256] = { {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
}, {
0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, 0x7d77f445, 0x565aa786, 0x4f4196c7,
0xc8d98a08, 0xd1c2bb49, 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, 0x87981ccf,
0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496,
0x821b9859, 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, 0xd4413fdf, 0xcd5a0e9e,
0x958424a2, 0x8c9f15e3, 0xa7b24620, 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265,
0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, 0x202a5aef, 0x0b07092c, 0x121c386d,
0xdf4636f3, 0xc65d07b2, 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, 0x9007a034,
0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c,
0xf0794f05, 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, 0xa623e883, 0xbf38d9c2,
0x38a0c50d, 0x21bbf44c, 0x0a96a78f, 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca,
0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, 0xc7cca911, 0xece1fad2, 0xf5facb93,
0x7262d75c, 0x6b79e61d, 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, 0x3d23419b,
0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60,
0xad24e1af, 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, 0xfb7e4629, 0xe2657768,
0x2f3f79f6, 0x362448b7, 0x1d091b74, 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31,
0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, 0x9a9107bb, 0xb1bc5478, 0xa8a76539,
0x3b83984b, 0x2298a90a, 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, 0x74c20e8c,
0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484,
0x71418a1a, 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, 0x271b2d9c, 0x3e001cdd,
0xb9980012, 0xa0833153, 0x8bae6290, 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5,
0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, 0xd37048ac, 0xf85d1b6f, 0xe1462a2e,
0x66de36e1, 0x7fc507a0, 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, 0x299fa026,
0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f,
0x2c1c24b0, 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, 0x7a468336, 0x635db277,
0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189,
0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, 0x7e54a903, 0x5579fac0, 0x4c62cb81,
0x8138c51f, 0x9823f45e, 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, 0xce7953d8,
0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0,
0x5e7ef3ec, 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, 0x0824546a, 0x113f652b,
0x96a779e4, 0x8fbc48a5, 0xa4911b66, 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23,
0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, 0x69cb15f8, 0x42e6463b, 0x5bfd777a,
0xdc656bb5, 0xc57e5af4, 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, 0x9324fd72
}, {
0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, 0x06cbc2eb, 0x048d7cb2, 0x054f1685,
0x0e1351b8, 0x0fd13b8f, 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, 0x0b5c473d,
0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5,
0x1235f2c8, 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, 0x16b88e7a, 0x177ae44d,
0x384d46e0, 0x398f2cd7, 0x3bc9928e, 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065,
0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, 0x3095d5b3, 0x32d36bea, 0x331101dd,
0x246be590, 0x25a98fa7, 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, 0x2124f315,
0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad,
0x709a8dc0, 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, 0x7417f172, 0x75d59b45,
0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd,
0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, 0x6a77ec5b, 0x68315202, 0x69f33835,
0x62af7f08, 0x636d153f, 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, 0x67e0698d,
0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5,
0x46c49a98, 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, 0x4249e62a, 0x438b8c1d,
0x54f16850, 0x55330267, 0x5775bc3e, 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5,
0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d,
0xe1351b80, 0xe0f771b7, 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, 0xe47a0d05,
0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd,
0xfd13b8f0, 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, 0xf99ec442, 0xf85cae75,
0xf300e948, 0xf2c2837f, 0xf0843d26, 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd,
0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, 0xdfb39f8b, 0xddf521d2, 0xdc374be5,
0xd76b0cd8, 0xd6a966ef, 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, 0xd2241a5d,
0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895,
0xcb4dafa8, 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, 0xcfc0d31a, 0xce02b92d,
0x91af9640, 0x906dfc77, 0x922b422e, 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5,
0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, 0x99770513, 0x9b31bb4a, 0x9af3d17d,
0x8d893530, 0x8c4b5f07, 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, 0x88c623b5,
0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d,
0xa9e2d0a0, 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, 0xad6fac12, 0xacadc625,
0xa7f18118, 0xa633eb2f, 0xa4755576, 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d,
0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, 0xb30fb13b, 0xb1490f62, 0xb08b6555,
0xbbd72268, 0xba15485f, 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, 0xbe9834ed
}, {
0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, 0x37def032, 0x256b5fdc, 0x9dd738b9,
0xc5b428ef, 0x7d084f8a, 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, 0x58631056,
0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26,
0x95ad7f70, 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, 0xb0c620ac, 0x087a47c9,
0xa032af3e, 0x188ec85b, 0x0a3b67b5, 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787,
0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, 0x525877e3, 0x40edd80d, 0xf851bf68,
0xf02bf8a1, 0x48979fc4, 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, 0x6dfcc018,
0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7,
0x9b14583d, 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, 0xbe7f07e1, 0x06c36084,
0x5ea070d2, 0xe61c17b7, 0xf4a9b859, 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b,
0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, 0xfcd3ff90, 0xee66507e, 0x56da371b,
0x0eb9274d, 0xb6054028, 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, 0x936e1ff4,
0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba,
0xfe92dfec, 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, 0xdbf98030, 0x6345e755,
0x6b3fa09c, 0xd383c7f9, 0xc1366817, 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825,
0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, 0x99557841, 0x8be0d7af, 0x335cb0ca,
0xed59b63b, 0x55e5d15e, 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, 0x708e8e82,
0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d,
0xbd40e1a4, 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, 0x982bbe78, 0x2097d91d,
0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2,
0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, 0x7ab5e937, 0x680046d9, 0xd0bc21bc,
0x88df31ea, 0x3063568f, 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, 0x15080953,
0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623,
0xd8c66675, 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, 0xfdad39a9, 0x45115ecc,
0x764dee06, 0xcef18963, 0xdc44268d, 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf,
0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, 0x842736db, 0x96929935, 0x2e2efe50,
0x2654b999, 0x9ee8defc, 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, 0xbb838120,
0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf,
0xd67f4138, 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, 0xf3141ee4, 0x4ba87981,
0x13cb69d7, 0xab770eb2, 0xb9c2a15c, 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e,
0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, 0xb1b8e695, 0xa30d497b, 0x1bb12e1e,
0x43d23e48, 0xfb6e592d, 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1
}, {
0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, 0xc8e08f70, 0x8f40f5a0, 0xb220dc10,
0x30704bc1, 0x0d106271, 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, 0x825097d1,
0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92,
0x5090dc43, 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, 0xdfd029e3, 0xe2b00053,
0xc1c12f04, 0xfca106b4, 0xbb017c64, 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314,
0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, 0x3951ebb5, 0x7ef19165, 0x4391b8d5,
0xa121b886, 0x9c419136, 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, 0x13016496,
0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57,
0x58f35849, 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, 0xd7b3ade9, 0xead38459,
0x68831388, 0x55e33a38, 0x124340e8, 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98,
0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, 0xf0f340bb, 0xb7533a6b, 0x8a3313db,
0x0863840a, 0x3503adba, 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, 0xba43581a,
0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d,
0xa9423c8c, 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, 0x2602c92c, 0x1b62e09c,
0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf,
0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, 0x0142247e, 0x46e25eae, 0x7b82771e,
0xb1e6b092, 0x8c869922, 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, 0x03c66c82,
0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743,
0xd1062710, 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, 0x5e46d2b0, 0x6326fb00,
0xe1766cd1, 0xdc164561, 0x9bb63fb1, 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1,
0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, 0xb8c710e6, 0xff676a36, 0xc2074386,
0x4057d457, 0x7d37fde7, 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, 0xf2770847,
0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404,
0x20b743d5, 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, 0xaff7b675, 0x92979fc5,
0xe915e8db, 0xd475c16b, 0x93d5bbbb, 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb,
0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, 0x11852c6a, 0x562556ba, 0x6b457f0a,
0x89f57f59, 0xb49556e9, 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, 0x3bd5a349,
0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888,
0x28d4c7df, 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, 0xa794327f, 0x9af41bcf,
0x18a48c1e, 0x25c4a5ae, 0x6264df7e, 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e,
0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, 0x80d4df2d, 0xc774a5fd, 0xfa148c4d,
0x78441b9c, 0x4524322c, 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, 0xca64c78c
}, {
0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, 0x50cd91b3, 0xd659e31d, 0x1d0530b8,
0xec53826d, 0x270f51c8, 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, 0xf156b2d5,
0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223,
0xef8580f6, 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, 0x39dc63eb, 0xf280b04e,
0x07ac0536, 0xccf0d693, 0x4a64a43d, 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e,
0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, 0xbb3216e8, 0x3da66446, 0xf6fab7e3,
0x047a07ad, 0xcf26d408, 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, 0x197f3715,
0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578,
0x0f580a6c, 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, 0xd901e971, 0x125d3ad4,
0xe30b8801, 0x28575ba4, 0xaec3290a, 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9,
0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, 0x5c439944, 0xdad7ebea, 0x118b384f,
0xe0dd8a9a, 0x2b81593f, 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, 0xfdd8ba22,
0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2,
0xe4a78d37, 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, 0x32fe6e2a, 0xf9a2bd8f,
0x0b220dc1, 0xc07ede64, 0x46eaacca, 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79,
0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14,
0x1eb014d8, 0xd5ecc77d, 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, 0x03b52460,
0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d,
0x1d661643, 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, 0xcb3ff55e, 0x006326fb,
0xf135942e, 0x3a69478b, 0xbcfd3525, 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496,
0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, 0x49d1805d, 0xcf45f2f3, 0x04192156,
0xf54f9383, 0x3e134026, 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, 0xe84aa33b,
0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd,
0xf6999118, 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, 0x20c07205, 0xeb9ca1a0,
0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c,
0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, 0xad760d6a, 0x2be27fc4, 0xe0beac61,
0x123e1c2f, 0xd962cf8a, 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, 0x0f3b2c97,
0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa,
0x16441b82, 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, 0xc01df89f, 0x0b412b3a,
0xfa1799ef, 0x314b4a4a, 0xb7df38e4, 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957,
0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, 0x455f88aa, 0xc3cbfa04, 0x089729a1,
0xf9c19b74, 0x329d48d1, 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, 0xe4c4abcc
}, {
0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, 0x52382fa7, 0x63d0353a, 0xc5a73e8e,
0x33ef4e67, 0x959845d3, 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, 0xf64870e9,
0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240,
0x5431d2a9, 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, 0x37e1e793, 0x9196ec27,
0xcfbd399c, 0x69ca3228, 0x582228b5, 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712,
0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, 0xae6a585c, 0x9f8242c1, 0x39f54975,
0xa863a552, 0x0e14aee6, 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, 0x6dc49bdc,
0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb,
0x440b7579, 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, 0x27db4043, 0x81ac4bf7,
0x77e43b1e, 0xd19330aa, 0xe07b2a37, 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590,
0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, 0x71edc610, 0x4005dc8d, 0xe672d739,
0x103aa7d0, 0xb64dac64, 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, 0xd59d995e,
0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b,
0xb8590282, 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, 0xdb8937b8, 0x7dfe3c0c,
0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5,
0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2,
0x8816eaf2, 0x2e61e146, 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, 0x4db1d47c,
0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b,
0xefc8763c, 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, 0x8c184306, 0x2a6f48b2,
0xdc27385b, 0x7a5033ef, 0x4bb82972, 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5,
0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, 0x1593fcc9, 0x247be654, 0x820cede0,
0x74449d09, 0xd23396bd, 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, 0xb1e3a387,
0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e,
0x139a01c7, 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, 0x704a34fd, 0xd63d3f49,
0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105,
0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62,
0xabc30345, 0x0db408f1, 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, 0x6e643dcb,
0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac,
0x03a0a617, 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, 0x6070932d, 0xc6079899,
0x304fe870, 0x9638e3c4, 0xa7d0f959, 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe,
0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, 0x3646157e, 0x07ae0fe3, 0xa1d90457,
0x579174be, 0xf1e67f0a, 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, 0x92364a30
}, {
0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, 0x48e00e64, 0xc66f0987, 0x0ac50919,
0xd3e51bb5, 0x1f4f1b2b, 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, 0xd92012ac,
0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832,
0xaf5e2a9e, 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, 0x69312319, 0xa59b2387,
0xf9766256, 0x35dc62c8, 0xbb53652b, 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f,
0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, 0x62737787, 0xecfc7064, 0x205670fa,
0x85cd537d, 0x496753e3, 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, 0x8f085a64,
0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1,
0x299dc2ed, 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, 0xeff2cb6a, 0x2358cbf4,
0xfa78d958, 0x36d2d9c6, 0xb85dde25, 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041,
0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf,
0x86c3e873, 0x4a69e8ed, 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, 0x8c06e16a,
0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2,
0x030ebb0e, 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, 0xc561b289, 0x09cbb217,
0xac509190, 0x60fa910e, 0xee7596ed, 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889,
0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, 0x37558441, 0xb9da83a2, 0x7570833c,
0x533b85da, 0x9f918544, 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, 0x59fe8cc3,
0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776,
0x2f80b4f1, 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, 0xe9efbd76, 0x2545bde8,
0xfc65af44, 0x30cfafda, 0xbe40a839, 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d,
0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95,
0x79a8fc39, 0xb502fca7, 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, 0x736df520,
0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe,
0x0513cd12, 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, 0xc37cc495, 0x0fd6c40b,
0x7aa64737, 0xb60c47a9, 0x3883404a, 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e,
0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, 0xe1a352e6, 0x6f2c5505, 0xa386559b,
0x061d761c, 0xcab77682, 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, 0x0cd87f05,
0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0,
0x83d02561, 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, 0x45bf2ce6, 0x89152c78,
0x50353ed4, 0x9c9f3e4a, 0x121039a9, 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd,
0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53,
0x2c8e0fff, 0xe0240f61, 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, 0x264b06e6
} };
/**
* Calculate CRC32 sum of a given message.
*
* @param crcinit intermediate CRC32 hash result
* @param msg the message to process
* @param size the length of the message
* @return updated CRC32 hash sum
*/
unsigned rhash_get_crc32(unsigned crcinit, const unsigned char* msg, size_t size)
{
return calculate_crc_soft(crcinit, rhash_crc32_table, msg, size);
}
#endif /* DISABLE_CRC32 */
#ifndef DISABLE_CRC32C
unsigned rhash_crc32c_table[8][256] = { {
0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,
0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,
0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,
0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,
0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,
0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,
0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,
0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,
0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,
0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,
0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,
0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,
0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,
0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,
0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,
0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,
0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,
0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,
0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,
0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351
}, {
0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899, 0x4e8a61dc, 0x5d28f9ab, 0x69cf5132, 0x7a6dc945,
0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21, 0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd,
0x3fc5f181, 0x2c6769f6, 0x1880c16f, 0x0b225918, 0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4,
0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0, 0xec5b53e5, 0xfff9cb92, 0xcb1e630b, 0xd8bcfb7c,
0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b, 0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47,
0xe29f20ba, 0xf13db8cd, 0xc5da1054, 0xd6788823, 0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff,
0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a, 0x0ec4735f, 0x1d66eb28, 0x298143b1, 0x3a23dbc6,
0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2, 0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e,
0xff17c604, 0xecb55e73, 0xd852f6ea, 0xcbf06e9d, 0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41,
0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25, 0x2c896460, 0x3f2bfc17, 0x0bcc548e, 0x186eccf9,
0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c, 0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0,
0x5dc6f43d, 0x4e646c4a, 0x7a83c4d3, 0x69215ca4, 0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78,
0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f, 0xce1644da, 0xddb4dcad, 0xe9537434, 0xfaf1ec43,
0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27, 0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb,
0xbf59d487, 0xacfb4cf0, 0x981ce469, 0x8bbe7c1e, 0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2,
0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6, 0x6cc776e3, 0x7f65ee94, 0x4b82460d, 0x5820de7a,
0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260, 0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc,
0x66d73941, 0x7575a136, 0x419209af, 0x523091d8, 0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004,
0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1, 0x8a8c6aa4, 0x992ef2d3, 0xadc95a4a, 0xbe6bc23d,
0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059, 0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185,
0x844819fb, 0x97ea818c, 0xa30d2915, 0xb0afb162, 0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be,
0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da, 0x57d6bb9f, 0x447423e8, 0x70938b71, 0x63311306,
0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3, 0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f,
0x26992bc2, 0x353bb3b5, 0x01dc1b2c, 0x127e835b, 0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287,
0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464, 0x4a5e5d21, 0x59fcc556, 0x6d1b6dcf, 0x7eb9f5b8,
0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc, 0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600,
0x3b11cd7c, 0x28b3550b, 0x1c54fd92, 0x0ff665e5, 0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439,
0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d, 0xe88f6f18, 0xfb2df76f, 0xcfca5ff6, 0xdc68c781,
0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766, 0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba,
0xe64b1c47, 0xf5e98430, 0xc10e2ca9, 0xd2acb4de, 0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502,
0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7, 0x0a104fa2, 0x19b2d7d5, 0x2d557f4c, 0x3ef7e73b,
0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f, 0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483
}, {
0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073, 0x9edea41a, 0x3b9f3664, 0xd1b1f617, 0x74f06469,
0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6, 0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac,
0x70a27d8a, 0xd5e3eff4, 0x3fcd2f87, 0x9a8cbdf9, 0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3,
0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c, 0xd62de755, 0x736c752b, 0x9942b558, 0x3c032726,
0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67, 0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d,
0xd915c5d1, 0x7c5457af, 0x967a97dc, 0x333b05a2, 0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8,
0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed, 0x0f382284, 0xaa79b0fa, 0x40577089, 0xe516e2f7,
0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828, 0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32,
0xc76580d9, 0x622412a7, 0x880ad2d4, 0x2d4b40aa, 0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0,
0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f, 0x61ea1a06, 0xc4ab8878, 0x2e85480b, 0x8bc4da75,
0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20, 0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a,
0x8f96c396, 0x2ad751e8, 0xc0f9919b, 0x65b803e5, 0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff,
0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe, 0xb8ffdfd7, 0x1dbe4da9, 0xf7908dda, 0x52d11fa4,
0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b, 0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161,
0x56830647, 0xf3c29439, 0x19ec544a, 0xbcadc634, 0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e,
0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1, 0xf00c9c98, 0x554d0ee6, 0xbf63ce95, 0x1a225ceb,
0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730, 0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a,
0xb3764986, 0x1637dbf8, 0xfc191b8b, 0x595889f5, 0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def,
0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba, 0x655baed3, 0xc01a3cad, 0x2a34fcde, 0x8f756ea0,
0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f, 0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065,
0x6a638c57, 0xcf221e29, 0x250cde5a, 0x804d4c24, 0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e,
0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1, 0xccec1688, 0x69ad84f6, 0x83834485, 0x26c2d6fb,
0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae, 0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4,
0x2290cf18, 0x87d15d66, 0x6dff9d15, 0xc8be0f6b, 0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71,
0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9, 0xd29c5380, 0x77ddc1fe, 0x9df3018d, 0x38b293f3,
0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c, 0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36,
0x3ce08a10, 0x99a1186e, 0x738fd81d, 0xd6ce4a63, 0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79,
0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6, 0x9a6f10cf, 0x3f2e82b1, 0xd50042c2, 0x7041d0bc,
0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd, 0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7,
0x9557324b, 0x3016a035, 0xda386046, 0x7f79f238, 0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622,
0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177, 0x437ad51e, 0xe63b4760, 0x0c158713, 0xa954156d,
0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2, 0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8
}, {
0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939, 0x7b2231f3, 0xa6679b4b, 0xc4451272, 0x1900b8ca,
0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf, 0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c,
0xe964b13d, 0x34211b85, 0x560392bc, 0x8b463804, 0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7,
0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2, 0x6402e328, 0xb9474990, 0xdb65c0a9, 0x06206a11,
0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2, 0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41,
0x2161776d, 0xfc24ddd5, 0x9e0654ec, 0x4343fe54, 0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7,
0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f, 0x45639445, 0x98263efd, 0xfa04b7c4, 0x27411d7c,
0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69, 0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a,
0xaba65fe7, 0x76e3f55f, 0x14c17c66, 0xc984d6de, 0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d,
0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538, 0x26c00df2, 0xfb85a74a, 0x99a72e73, 0x44e284cb,
0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3, 0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610,
0xb4868d3c, 0x69c32784, 0x0be1aebd, 0xd6a40405, 0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6,
0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255, 0x07a17a9f, 0xdae4d027, 0xb8c6591e, 0x6583f3a6,
0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3, 0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040,
0x95e7fa51, 0x48a250e9, 0x2a80d9d0, 0xf7c57368, 0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b,
0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e, 0x1881a844, 0xc5c402fc, 0xa7e68bc5, 0x7aa3217d,
0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006, 0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5,
0xa4e4aad9, 0x79a10061, 0x1b838958, 0xc6c623e0, 0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213,
0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b, 0xc0e649f1, 0x1da3e349, 0x7f816a70, 0xa2c4c0c8,
0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd, 0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e,
0x8585ddb4, 0x58c0770c, 0x3ae2fe35, 0xe7a7548d, 0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e,
0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b, 0x08e38fa1, 0xd5a62519, 0xb784ac20, 0x6ac10698,
0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0, 0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443,
0x9aa50f6f, 0x47e0a5d7, 0x25c22cee, 0xf8878656, 0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5,
0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1, 0x8224a72b, 0x5f610d93, 0x3d4384aa, 0xe0062e12,
0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07, 0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4,
0x106227e5, 0xcd278d5d, 0xaf050464, 0x7240aedc, 0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f,
0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a, 0x9d0475f0, 0x4041df48, 0x22635671, 0xff26fcc9,
0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a, 0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99,
0xd867e1b5, 0x05224b0d, 0x6700c234, 0xba45688c, 0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f,
0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57, 0xbc65029d, 0x6120a825, 0x0302211c, 0xde478ba4,
0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1, 0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842
}, {
0x00000000, 0x38116fac, 0x7022df58, 0x4833b0f4, 0xe045beb0, 0xd854d11c, 0x906761e8, 0xa8760e44,
0xc5670b91, 0xfd76643d, 0xb545d4c9, 0x8d54bb65, 0x2522b521, 0x1d33da8d, 0x55006a79, 0x6d1105d5,
0x8f2261d3, 0xb7330e7f, 0xff00be8b, 0xc711d127, 0x6f67df63, 0x5776b0cf, 0x1f45003b, 0x27546f97,
0x4a456a42, 0x725405ee, 0x3a67b51a, 0x0276dab6, 0xaa00d4f2, 0x9211bb5e, 0xda220baa, 0xe2336406,
0x1ba8b557, 0x23b9dafb, 0x6b8a6a0f, 0x539b05a3, 0xfbed0be7, 0xc3fc644b, 0x8bcfd4bf, 0xb3debb13,
0xdecfbec6, 0xe6ded16a, 0xaeed619e, 0x96fc0e32, 0x3e8a0076, 0x069b6fda, 0x4ea8df2e, 0x76b9b082,
0x948ad484, 0xac9bbb28, 0xe4a80bdc, 0xdcb96470, 0x74cf6a34, 0x4cde0598, 0x04edb56c, 0x3cfcdac0,
0x51eddf15, 0x69fcb0b9, 0x21cf004d, 0x19de6fe1, 0xb1a861a5, 0x89b90e09, 0xc18abefd, 0xf99bd151,
0x37516aae, 0x0f400502, 0x4773b5f6, 0x7f62da5a, 0xd714d41e, 0xef05bbb2, 0xa7360b46, 0x9f2764ea,
0xf236613f, 0xca270e93, 0x8214be67, 0xba05d1cb, 0x1273df8f, 0x2a62b023, 0x625100d7, 0x5a406f7b,
0xb8730b7d, 0x806264d1, 0xc851d425, 0xf040bb89, 0x5836b5cd, 0x6027da61, 0x28146a95, 0x10050539,
0x7d1400ec, 0x45056f40, 0x0d36dfb4, 0x3527b018, 0x9d51be5c, 0xa540d1f0, 0xed736104, 0xd5620ea8,
0x2cf9dff9, 0x14e8b055, 0x5cdb00a1, 0x64ca6f0d, 0xccbc6149, 0xf4ad0ee5, 0xbc9ebe11, 0x848fd1bd,
0xe99ed468, 0xd18fbbc4, 0x99bc0b30, 0xa1ad649c, 0x09db6ad8, 0x31ca0574, 0x79f9b580, 0x41e8da2c,
0xa3dbbe2a, 0x9bcad186, 0xd3f96172, 0xebe80ede, 0x439e009a, 0x7b8f6f36, 0x33bcdfc2, 0x0badb06e,
0x66bcb5bb, 0x5eadda17, 0x169e6ae3, 0x2e8f054f, 0x86f90b0b, 0xbee864a7, 0xf6dbd453, 0xcecabbff,
0x6ea2d55c, 0x56b3baf0, 0x1e800a04, 0x269165a8, 0x8ee76bec, 0xb6f60440, 0xfec5b4b4, 0xc6d4db18,
0xabc5decd, 0x93d4b161, 0xdbe70195, 0xe3f66e39, 0x4b80607d, 0x73910fd1, 0x3ba2bf25, 0x03b3d089,
0xe180b48f, 0xd991db23, 0x91a26bd7, 0xa9b3047b, 0x01c50a3f, 0x39d46593, 0x71e7d567, 0x49f6bacb,
0x24e7bf1e, 0x1cf6d0b2, 0x54c56046, 0x6cd40fea, 0xc4a201ae, 0xfcb36e02, 0xb480def6, 0x8c91b15a,
0x750a600b, 0x4d1b0fa7, 0x0528bf53, 0x3d39d0ff, 0x954fdebb, 0xad5eb117, 0xe56d01e3, 0xdd7c6e4f,
0xb06d6b9a, 0x887c0436, 0xc04fb4c2, 0xf85edb6e, 0x5028d52a, 0x6839ba86, 0x200a0a72, 0x181b65de,
0xfa2801d8, 0xc2396e74, 0x8a0ade80, 0xb21bb12c, 0x1a6dbf68, 0x227cd0c4, 0x6a4f6030, 0x525e0f9c,
0x3f4f0a49, 0x075e65e5, 0x4f6dd511, 0x777cbabd, 0xdf0ab4f9, 0xe71bdb55, 0xaf286ba1, 0x9739040d,
0x59f3bff2, 0x61e2d05e, 0x29d160aa, 0x11c00f06, 0xb9b60142, 0x81a76eee, 0xc994de1a, 0xf185b1b6,
0x9c94b463, 0xa485dbcf, 0xecb66b3b, 0xd4a70497, 0x7cd10ad3, 0x44c0657f, 0x0cf3d58b, 0x34e2ba27,
0xd6d1de21, 0xeec0b18d, 0xa6f30179, 0x9ee26ed5, 0x36946091, 0x0e850f3d, 0x46b6bfc9, 0x7ea7d065,
0x13b6d5b0, 0x2ba7ba1c, 0x63940ae8, 0x5b856544, 0xf3f36b00, 0xcbe204ac, 0x83d1b458, 0xbbc0dbf4,
0x425b0aa5, 0x7a4a6509, 0x3279d5fd, 0x0a68ba51, 0xa21eb415, 0x9a0fdbb9, 0xd23c6b4d, 0xea2d04e1,
0x873c0134, 0xbf2d6e98, 0xf71ede6c, 0xcf0fb1c0, 0x6779bf84, 0x5f68d028, 0x175b60dc, 0x2f4a0f70,
0xcd796b76, 0xf56804da, 0xbd5bb42e, 0x854adb82, 0x2d3cd5c6, 0x152dba6a, 0x5d1e0a9e, 0x650f6532,
0x081e60e7, 0x300f0f4b, 0x783cbfbf, 0x402dd013, 0xe85bde57, 0xd04ab1fb, 0x9879010f, 0xa0686ea3
}, {
0x00000000, 0xef306b19, 0xdb8ca0c3, 0x34bccbda, 0xb2f53777, 0x5dc55c6e, 0x697997b4, 0x8649fcad,
0x6006181f, 0x8f367306, 0xbb8ab8dc, 0x54bad3c5, 0xd2f32f68, 0x3dc34471, 0x097f8fab, 0xe64fe4b2,
0xc00c303e, 0x2f3c5b27, 0x1b8090fd, 0xf4b0fbe4, 0x72f90749, 0x9dc96c50, 0xa975a78a, 0x4645cc93,
0xa00a2821, 0x4f3a4338, 0x7b8688e2, 0x94b6e3fb, 0x12ff1f56, 0xfdcf744f, 0xc973bf95, 0x2643d48c,
0x85f4168d, 0x6ac47d94, 0x5e78b64e, 0xb148dd57, 0x370121fa, 0xd8314ae3, 0xec8d8139, 0x03bdea20,
0xe5f20e92, 0x0ac2658b, 0x3e7eae51, 0xd14ec548, 0x570739e5, 0xb83752fc, 0x8c8b9926, 0x63bbf23f,
0x45f826b3, 0xaac84daa, 0x9e748670, 0x7144ed69, 0xf70d11c4, 0x183d7add, 0x2c81b107, 0xc3b1da1e,
0x25fe3eac, 0xcace55b5, 0xfe729e6f, 0x1142f576, 0x970b09db, 0x783b62c2, 0x4c87a918, 0xa3b7c201,
0x0e045beb, 0xe13430f2, 0xd588fb28, 0x3ab89031, 0xbcf16c9c, 0x53c10785, 0x677dcc5f, 0x884da746,
0x6e0243f4, 0x813228ed, 0xb58ee337, 0x5abe882e, 0xdcf77483, 0x33c71f9a, 0x077bd440, 0xe84bbf59,
0xce086bd5, 0x213800cc, 0x1584cb16, 0xfab4a00f, 0x7cfd5ca2, 0x93cd37bb, 0xa771fc61, 0x48419778,
0xae0e73ca, 0x413e18d3, 0x7582d309, 0x9ab2b810, 0x1cfb44bd, 0xf3cb2fa4, 0xc777e47e, 0x28478f67,
0x8bf04d66, 0x64c0267f, 0x507ceda5, 0xbf4c86bc, 0x39057a11, 0xd6351108, 0xe289dad2, 0x0db9b1cb,
0xebf65579, 0x04c63e60, 0x307af5ba, 0xdf4a9ea3, 0x5903620e, 0xb6330917, 0x828fc2cd, 0x6dbfa9d4,
0x4bfc7d58, 0xa4cc1641, 0x9070dd9b, 0x7f40b682, 0xf9094a2f, 0x16392136, 0x2285eaec, 0xcdb581f5,
0x2bfa6547, 0xc4ca0e5e, 0xf076c584, 0x1f46ae9d, 0x990f5230, 0x763f3929, 0x4283f2f3, 0xadb399ea,
0x1c08b7d6, 0xf338dccf, 0xc7841715, 0x28b47c0c, 0xaefd80a1, 0x41cdebb8, 0x75712062, 0x9a414b7b,
0x7c0eafc9, 0x933ec4d0, 0xa7820f0a, 0x48b26413, 0xcefb98be, 0x21cbf3a7, 0x1577387d, 0xfa475364,
0xdc0487e8, 0x3334ecf1, 0x0788272b, 0xe8b84c32, 0x6ef1b09f, 0x81c1db86, 0xb57d105c, 0x5a4d7b45,
0xbc029ff7, 0x5332f4ee, 0x678e3f34, 0x88be542d, 0x0ef7a880, 0xe1c7c399, 0xd57b0843, 0x3a4b635a,
0x99fca15b, 0x76ccca42, 0x42700198, 0xad406a81, 0x2b09962c, 0xc439fd35, 0xf08536ef, 0x1fb55df6,
0xf9fab944, 0x16cad25d, 0x22761987, 0xcd46729e, 0x4b0f8e33, 0xa43fe52a, 0x90832ef0, 0x7fb345e9,
0x59f09165, 0xb6c0fa7c, 0x827c31a6, 0x6d4c5abf, 0xeb05a612, 0x0435cd0b, 0x308906d1, 0xdfb96dc8,
0x39f6897a, 0xd6c6e263, 0xe27a29b9, 0x0d4a42a0, 0x8b03be0d, 0x6433d514, 0x508f1ece, 0xbfbf75d7,
0x120cec3d, 0xfd3c8724, 0xc9804cfe, 0x26b027e7, 0xa0f9db4a, 0x4fc9b053, 0x7b757b89, 0x94451090,
0x720af422, 0x9d3a9f3b, 0xa98654e1, 0x46b63ff8, 0xc0ffc355, 0x2fcfa84c, 0x1b736396, 0xf443088f,
0xd200dc03, 0x3d30b71a, 0x098c7cc0, 0xe6bc17d9, 0x60f5eb74, 0x8fc5806d, 0xbb794bb7, 0x544920ae,
0xb206c41c, 0x5d36af05, 0x698a64df, 0x86ba0fc6, 0x00f3f36b, 0xefc39872, 0xdb7f53a8, 0x344f38b1,
0x97f8fab0, 0x78c891a9, 0x4c745a73, 0xa344316a, 0x250dcdc7, 0xca3da6de, 0xfe816d04, 0x11b1061d,
0xf7fee2af, 0x18ce89b6, 0x2c72426c, 0xc3422975, 0x450bd5d8, 0xaa3bbec1, 0x9e87751b, 0x71b71e02,
0x57f4ca8e, 0xb8c4a197, 0x8c786a4d, 0x63480154, 0xe501fdf9, 0x0a3196e0, 0x3e8d5d3a, 0xd1bd3623,
0x37f2d291, 0xd8c2b988, 0xec7e7252, 0x034e194b, 0x8507e5e6, 0x6a378eff, 0x5e8b4525, 0xb1bb2e3c
}, {
0x00000000, 0x68032cc8, 0xd0065990, 0xb8057558, 0xa5e0c5d1, 0xcde3e919, 0x75e69c41, 0x1de5b089,
0x4e2dfd53, 0x262ed19b, 0x9e2ba4c3, 0xf628880b, 0xebcd3882, 0x83ce144a, 0x3bcb6112, 0x53c84dda,
0x9c5bfaa6, 0xf458d66e, 0x4c5da336, 0x245e8ffe, 0x39bb3f77, 0x51b813bf, 0xe9bd66e7, 0x81be4a2f,
0xd27607f5, 0xba752b3d, 0x02705e65, 0x6a7372ad, 0x7796c224, 0x1f95eeec, 0xa7909bb4, 0xcf93b77c,
0x3d5b83bd, 0x5558af75, 0xed5dda2d, 0x855ef6e5, 0x98bb466c, 0xf0b86aa4, 0x48bd1ffc, 0x20be3334,
0x73767eee, 0x1b755226, 0xa370277e, 0xcb730bb6, 0xd696bb3f, 0xbe9597f7, 0x0690e2af, 0x6e93ce67,
0xa100791b, 0xc90355d3, 0x7106208b, 0x19050c43, 0x04e0bcca, 0x6ce39002, 0xd4e6e55a, 0xbce5c992,
0xef2d8448, 0x872ea880, 0x3f2bddd8, 0x5728f110, 0x4acd4199, 0x22ce6d51, 0x9acb1809, 0xf2c834c1,
0x7ab7077a, 0x12b42bb2, 0xaab15eea, 0xc2b27222, 0xdf57c2ab, 0xb754ee63, 0x0f519b3b, 0x6752b7f3,
0x349afa29, 0x5c99d6e1, 0xe49ca3b9, 0x8c9f8f71, 0x917a3ff8, 0xf9791330, 0x417c6668, 0x297f4aa0,
0xe6ecfddc, 0x8eefd114, 0x36eaa44c, 0x5ee98884, 0x430c380d, 0x2b0f14c5, 0x930a619d, 0xfb094d55,
0xa8c1008f, 0xc0c22c47, 0x78c7591f, 0x10c475d7, 0x0d21c55e, 0x6522e996, 0xdd279cce, 0xb524b006,
0x47ec84c7, 0x2fefa80f, 0x97eadd57, 0xffe9f19f, 0xe20c4116, 0x8a0f6dde, 0x320a1886, 0x5a09344e,
0x09c17994, 0x61c2555c, 0xd9c72004, 0xb1c40ccc, 0xac21bc45, 0xc422908d, 0x7c27e5d5, 0x1424c91d,
0xdbb77e61, 0xb3b452a9, 0x0bb127f1, 0x63b20b39, 0x7e57bbb0, 0x16549778, 0xae51e220, 0xc652cee8,
0x959a8332, 0xfd99affa, 0x459cdaa2, 0x2d9ff66a, 0x307a46e3, 0x58796a2b, 0xe07c1f73, 0x887f33bb,
0xf56e0ef4, 0x9d6d223c, 0x25685764, 0x4d6b7bac, 0x508ecb25, 0x388de7ed, 0x808892b5, 0xe88bbe7d,
0xbb43f3a7, 0xd340df6f, 0x6b45aa37, 0x034686ff, 0x1ea33676, 0x76a01abe, 0xcea56fe6, 0xa6a6432e,
0x6935f452, 0x0136d89a, 0xb933adc2, 0xd130810a, 0xccd53183, 0xa4d61d4b, 0x1cd36813, 0x74d044db,
0x27180901, 0x4f1b25c9, 0xf71e5091, 0x9f1d7c59, 0x82f8ccd0, 0xeafbe018, 0x52fe9540, 0x3afdb988,
0xc8358d49, 0xa036a181, 0x1833d4d9, 0x7030f811, 0x6dd54898, 0x05d66450, 0xbdd31108, 0xd5d03dc0,
0x8618701a, 0xee1b5cd2, 0x561e298a, 0x3e1d0542, 0x23f8b5cb, 0x4bfb9903, 0xf3feec5b, 0x9bfdc093,
0x546e77ef, 0x3c6d5b27, 0x84682e7f, 0xec6b02b7, 0xf18eb23e, 0x998d9ef6, 0x2188ebae, 0x498bc766,
0x1a438abc, 0x7240a674, 0xca45d32c, 0xa246ffe4, 0xbfa34f6d, 0xd7a063a5, 0x6fa516fd, 0x07a63a35,
0x8fd9098e, 0xe7da2546, 0x5fdf501e, 0x37dc7cd6, 0x2a39cc5f, 0x423ae097, 0xfa3f95cf, 0x923cb907,
0xc1f4f4dd, 0xa9f7d815, 0x11f2ad4d, 0x79f18185, 0x6414310c, 0x0c171dc4, 0xb412689c, 0xdc114454,
0x1382f328, 0x7b81dfe0, 0xc384aab8, 0xab878670, 0xb66236f9, 0xde611a31, 0x66646f69, 0x0e6743a1,
0x5daf0e7b, 0x35ac22b3, 0x8da957eb, 0xe5aa7b23, 0xf84fcbaa, 0x904ce762, 0x2849923a, 0x404abef2,
0xb2828a33, 0xda81a6fb, 0x6284d3a3, 0x0a87ff6b, 0x17624fe2, 0x7f61632a, 0xc7641672, 0xaf673aba,
0xfcaf7760, 0x94ac5ba8, 0x2ca92ef0, 0x44aa0238, 0x594fb2b1, 0x314c9e79, 0x8949eb21, 0xe14ac7e9,
0x2ed97095, 0x46da5c5d, 0xfedf2905, 0x96dc05cd, 0x8b39b544, 0xe33a998c, 0x5b3fecd4, 0x333cc01c,
0x60f48dc6, 0x08f7a10e, 0xb0f2d456, 0xd8f1f89e, 0xc5144817, 0xad1764df, 0x15121187, 0x7d113d4f
}, {
0x00000000, 0x493c7d27, 0x9278fa4e, 0xdb448769, 0x211d826d, 0x6821ff4a, 0xb3657823, 0xfa590504,
0x423b04da, 0x0b0779fd, 0xd043fe94, 0x997f83b3, 0x632686b7, 0x2a1afb90, 0xf15e7cf9, 0xb86201de,
0x847609b4, 0xcd4a7493, 0x160ef3fa, 0x5f328edd, 0xa56b8bd9, 0xec57f6fe, 0x37137197, 0x7e2f0cb0,
0xc64d0d6e, 0x8f717049, 0x5435f720, 0x1d098a07, 0xe7508f03, 0xae6cf224, 0x7528754d, 0x3c14086a,
0x0d006599, 0x443c18be, 0x9f789fd7, 0xd644e2f0, 0x2c1de7f4, 0x65219ad3, 0xbe651dba, 0xf759609d,
0x4f3b6143, 0x06071c64, 0xdd439b0d, 0x947fe62a, 0x6e26e32e, 0x271a9e09, 0xfc5e1960, 0xb5626447,
0x89766c2d, 0xc04a110a, 0x1b0e9663, 0x5232eb44, 0xa86bee40, 0xe1579367, 0x3a13140e, 0x732f6929,
0xcb4d68f7, 0x827115d0, 0x593592b9, 0x1009ef9e, 0xea50ea9a, 0xa36c97bd, 0x782810d4, 0x31146df3,
0x1a00cb32, 0x533cb615, 0x8878317c, 0xc1444c5b, 0x3b1d495f, 0x72213478, 0xa965b311, 0xe059ce36,
0x583bcfe8, 0x1107b2cf, 0xca4335a6, 0x837f4881, 0x79264d85, 0x301a30a2, 0xeb5eb7cb, 0xa262caec,
0x9e76c286, 0xd74abfa1, 0x0c0e38c8, 0x453245ef, 0xbf6b40eb, 0xf6573dcc, 0x2d13baa5, 0x642fc782,
0xdc4dc65c, 0x9571bb7b, 0x4e353c12, 0x07094135, 0xfd504431, 0xb46c3916, 0x6f28be7f, 0x2614c358,
0x1700aeab, 0x5e3cd38c, 0x857854e5, 0xcc4429c2, 0x361d2cc6, 0x7f2151e1, 0xa465d688, 0xed59abaf,
0x553baa71, 0x1c07d756, 0xc743503f, 0x8e7f2d18, 0x7426281c, 0x3d1a553b, 0xe65ed252, 0xaf62af75,
0x9376a71f, 0xda4ada38, 0x010e5d51, 0x48322076, 0xb26b2572, 0xfb575855, 0x2013df3c, 0x692fa21b,
0xd14da3c5, 0x9871dee2, 0x4335598b, 0x0a0924ac, 0xf05021a8, 0xb96c5c8f, 0x6228dbe6, 0x2b14a6c1,
0x34019664, 0x7d3deb43, 0xa6796c2a, 0xef45110d, 0x151c1409, 0x5c20692e, 0x8764ee47, 0xce589360,
0x763a92be, 0x3f06ef99, 0xe44268f0, 0xad7e15d7, 0x572710d3, 0x1e1b6df4, 0xc55fea9d, 0x8c6397ba,
0xb0779fd0, 0xf94be2f7, 0x220f659e, 0x6b3318b9, 0x916a1dbd, 0xd856609a, 0x0312e7f3, 0x4a2e9ad4,
0xf24c9b0a, 0xbb70e62d, 0x60346144, 0x29081c63, 0xd3511967, 0x9a6d6440, 0x4129e329, 0x08159e0e,
0x3901f3fd, 0x703d8eda, 0xab7909b3, 0xe2457494, 0x181c7190, 0x51200cb7, 0x8a648bde, 0xc358f6f9,
0x7b3af727, 0x32068a00, 0xe9420d69, 0xa07e704e, 0x5a27754a, 0x131b086d, 0xc85f8f04, 0x8163f223,
0xbd77fa49, 0xf44b876e, 0x2f0f0007, 0x66337d20, 0x9c6a7824, 0xd5560503, 0x0e12826a, 0x472eff4d,
0xff4cfe93, 0xb67083b4, 0x6d3404dd, 0x240879fa, 0xde517cfe, 0x976d01d9, 0x4c2986b0, 0x0515fb97,
0x2e015d56, 0x673d2071, 0xbc79a718, 0xf545da3f, 0x0f1cdf3b, 0x4620a21c, 0x9d642575, 0xd4585852,
0x6c3a598c, 0x250624ab, 0xfe42a3c2, 0xb77edee5, 0x4d27dbe1, 0x041ba6c6, 0xdf5f21af, 0x96635c88,
0xaa7754e2, 0xe34b29c5, 0x380faeac, 0x7133d38b, 0x8b6ad68f, 0xc256aba8, 0x19122cc1, 0x502e51e6,
0xe84c5038, 0xa1702d1f, 0x7a34aa76, 0x3308d751, 0xc951d255, 0x806daf72, 0x5b29281b, 0x1215553c,
0x230138cf, 0x6a3d45e8, 0xb179c281, 0xf845bfa6, 0x021cbaa2, 0x4b20c785, 0x906440ec, 0xd9583dcb,
0x613a3c15, 0x28064132, 0xf342c65b, 0xba7ebb7c, 0x4027be78, 0x091bc35f, 0xd25f4436, 0x9b633911,
0xa777317b, 0xee4b4c5c, 0x350fcb35, 0x7c33b612, 0x866ab316, 0xcf56ce31, 0x14124958, 0x5d2e347f,
0xe54c35a1, 0xac704886, 0x7734cfef, 0x3e08b2c8, 0xc451b7cc, 0x8d6dcaeb, 0x56294d82, 0x1f1530a5
} };
#ifdef HAS_INTEL_CPUID
static unsigned calculate_crc32c_choose_best(unsigned crcinit, unsigned table[8][256], const unsigned char* msg, size_t size);
static unsigned calculate_crc32c_sse42(unsigned crcinit, unsigned table[8][256], const unsigned char* msg, size_t size);
static unsigned (*calculate_crc32c_p)(unsigned crcinit, unsigned table[8][256], const unsigned char* msg, size_t size) = calculate_crc32c_choose_best;
static unsigned calculate_crc32c_choose_best(unsigned crcinit, unsigned table[8][256], const unsigned char* msg, size_t size)
{
calculate_crc32c_p = (has_cpu_feature(CPU_FEATURE_SSE4_2) ?
calculate_crc32c_sse42 : calculate_crc_soft);
return calculate_crc32c_p(crcinit, table, msg, size);
}
#ifdef CPU_X64
# define BLOCK_UINT uint64_t
# define REX_PREFIX " 0x48,"
#else
# define BLOCK_UINT uint32_t
# define REX_PREFIX ""
#endif
#define BLOCK_SIZE sizeof(BLOCK_UINT)
#define CRC32C_BLOCK(crc, data) __asm__ __volatile__( \
".byte 0xf2," REX_PREFIX " 0x0f, 0x38, 0xf1, 0xf1;" :"=S"(crc) :"0"(crc), "c"(data))
#define CRC32C_U8(crc, u8) __asm__ __volatile__( \
".byte 0xf2, 0x0f, 0x38, 0xf0, 0xf1" :"=S"(crc) :"0"(crc), "c"(u8))
static unsigned calculate_crc32c_sse42(unsigned crcinit, unsigned table[8][256], const unsigned char* msg, size_t size)
{
unsigned crc = ~crcinit;
(void)table;
if (size >= BLOCK_SIZE)
{
/* process unaligned head */
for (; ((size_t)msg) & (BLOCK_SIZE - 1); msg++, size--)
CRC32C_U8(crc, *msg);
/* process aligned blocks */
for (; size > BLOCK_SIZE; size -= BLOCK_SIZE, msg += BLOCK_SIZE)
CRC32C_BLOCK(crc, *(BLOCK_UINT*)msg);
}
/* process tail */
for (; size--; msg++)
CRC32C_U8(crc, *msg);
return ~crc;
}
#else
# define calculate_crc32c_p calculate_crc_soft
#endif
/**
* Calculate CRC32C sum of a given message.
*
* @param crcinit intermediate CRC32C hash result
* @param msg the message to process
* @param size the length of the message
* @return updated CRC32C hash sum
*/
unsigned rhash_get_crc32c(unsigned crcinit, const unsigned char* msg, size_t size)
{
return calculate_crc32c_p(crcinit, rhash_crc32c_table, msg, size);
}
#endif /* DISABLE_CRC32C */
rhash-1.4.6/librhash/snefru.c 0000664 0000000 0000000 00000160212 14703622112 014571 0 ustar root root /* snefru.c - an implementation of Snefru-128/256 Message-Digest Algorithms
*
* Copyright (c) 2009, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* Specification: Ralph C. Merkle, A Fast Software One-Way Hash Function,
* J. Cryptology, Vol. 3, No 1, pp. 43-58, 1990
*
* Info from wikipedia: Snefru is a cryptographic hash function invented
* by Ralph Merkle in 1989 which supports 128-bit and 256-bit output. It
* was named after the Egyptian Pharaoh Sneferu, continuing the tradition
* of the Khufu and Khafre block ciphers.
*
* The original design of Snefru was shown to be insecure by Eli Biham and
* Adi Shamir who were able to use differential cryptanalysis to find hash
* collisions. The design was then modified by increasing the number of
* iterations of the main pass of the algorithm from two to eight. Although
* differential cryptanalysis can break the revised version with less
* complexity than brute force search (a certificational weakness), the attack
* requires 2^88.5 operations and is thus not currently feasible in practice.
*
* The algorithm can also be run with a variable number of "rounds" of the
* internal algorithm. However, analysis by several cryptographers has shown
* that SNEFRU has weaknesses that can be exploited, and that you can find
* arbitrary messages that hash to a given 128-bit value if the 4-round
* version is used. Dr. Merkle currently recommends that only 8-round SNEFRU
* be used, but this algorithm is significantly slower than the MD5 or HAVAL
* algorithms.
*/
#include
#include
#include "byte_order.h"
#include "snefru.h"
#define SNEFRU_NUMBER_OF_ROUNDS 8
/* SNEFRU lookup table (S-Box) */
static const unsigned rhash_snefru_sbox[SNEFRU_NUMBER_OF_ROUNDS * 512] = {
0x64f9001b, 0xfeddcdf6, 0x7c8ff1e2, 0x11d71514, 0x8b8c18d3, 0xdddf881e,
0x6eab5056, 0x88ced8e1, 0x49148959, 0x69c56fd5, 0xb7994f03, 0x0fbcee3e,
0x3c264940, 0x21557e58, 0xe14b3fc2, 0x2e5cf591, 0xdceff8ce, 0x092a1648,
0xbe812936, 0xff7b0c6a, 0xd5251037, 0xafa448f1, 0x7dafc95a, 0x1ea69c3f,
0xa417abe7, 0x5890e423, 0xb0cb70c0, 0xc85025f7, 0x244d97e3, 0x1ff3595f,
0xc4ec6396, 0x59181e17, 0xe635b477, 0x354e7dbf, 0x796f7753, 0x66eb52cc,
0x77c3f995, 0x32e3a927, 0x80ccaed6, 0x4e2be89d, 0x375bbd28, 0xad1a3d05,
0x2b1b42b3, 0x16c44c71, 0x4d54bfa8, 0xe57ddc7a, 0xec6d8144, 0x5a71046b,
0xd8229650, 0x87fc8f24, 0xcbc60e09, 0xb6390366, 0xd9f76092, 0xd393a70b,
0x1d31a08a, 0x9cd971c9, 0x5c1ef445, 0x86fab694, 0xfdb44165, 0x8eaafcbe,
0x4bcac6eb, 0xfb7a94e5, 0x5789d04e, 0xfa13cf35, 0x236b8da9, 0x4133f000,
0x6224261c, 0xf412f23b, 0xe75e56a4, 0x30022116, 0xbaf17f1f, 0xd09872f9,
0xc1a3699c, 0xf1e802aa, 0x0dd145dc, 0x4fdce093, 0x8d8412f0, 0x6cd0f376,
0x3de6b73d, 0x84ba737f, 0xb43a30f2, 0x44569f69, 0x00e4eaca, 0xb58de3b0,
0x959113c8, 0xd62efee9, 0x90861f83, 0xced69874, 0x2f793cee, 0xe8571c30,
0x483665d1, 0xab07b031, 0x914c844f, 0x15bf3be8, 0x2c3f2a9a, 0x9eb95fd4,
0x92e7472d, 0x2297cc5b, 0xee5f2782, 0x5377b562, 0xdb8ebbcf, 0xf961dedd,
0xc59b5c60, 0x1bd3910d, 0x26d206ad, 0xb28514d8, 0x5ecf6b52, 0x7fea78bb,
0x504879ac, 0xed34a884, 0x36e51d3c, 0x1753741d, 0x8c47caed, 0x9d0a40ef,
0x3145e221, 0xda27eb70, 0xdf730ba3, 0x183c8789, 0x739ac0a6, 0x9a58dfc6,
0x54b134c1, 0xac3e242e, 0xcc493902, 0x7b2dda99, 0x8f15bc01, 0x29fd38c7,
0x27d5318f, 0x604aaff5, 0xf29c6818, 0xc38aa2ec, 0x1019d4c3, 0xa8fb936e,
0x20ed7b39, 0x0b686119, 0x89a0906f, 0x1cc7829e, 0x9952ef4b, 0x850e9e8c,
0xcd063a90, 0x67002f8e, 0xcfac8cb7, 0xeaa24b11, 0x988b4e6c, 0x46f066df,
0xca7eec08, 0xc7bba664, 0x831d17bd, 0x63f575e6, 0x9764350e, 0x47870d42,
0x026ca4a2, 0x8167d587, 0x61b6adab, 0xaa6564d2, 0x70da237b, 0x25e1c74a,
0xa1c901a0, 0x0eb0a5da, 0x7670f741, 0x51c05aea, 0x933dfa32, 0x0759ff1a,
0x56010ab8, 0x5fdecb78, 0x3f32edf8, 0xaebedbb9, 0x39f8326d, 0xd20858c5,
0x9b638be4, 0xa572c80a, 0x28e0a19f, 0x432099fc, 0x3a37c3cd, 0xbf95c585,
0xb392c12a, 0x6aa707d7, 0x52f66a61, 0x12d483b1, 0x96435b5e, 0x3e75802b,
0x3ba52b33, 0xa99f51a5, 0xbda1e157, 0x78c2e70c, 0xfcae7ce0, 0xd1602267,
0x2affac4d, 0x4a510947, 0x0ab2b83a, 0x7a04e579, 0x340dfd80, 0xb916e922,
0xe29d5e9b, 0xf5624af4, 0x4ca9d9af, 0x6bbd2cfe, 0xe3b7f620, 0xc2746e07,
0x5b42b9b6, 0xa06919bc, 0xf0f2c40f, 0x72217ab5, 0x14c19df3, 0xf3802dae,
0xe094beb4, 0xa2101aff, 0x0529575d, 0x55cdb27c, 0xa33bddb2, 0x6528b37d,
0x740c05db, 0xe96a62c4, 0x40782846, 0x6d30d706, 0xbbf48e2c, 0xbce2d3de,
0x049e37fa, 0x01b5e634, 0x2d886d8d, 0x7e5a2e7e, 0xd7412013, 0x06e90f97,
0xe45d3eba, 0xb8ad3386, 0x13051b25, 0x0c035354, 0x71c89b75, 0xc638fbd0,
0x197f11a1, 0xef0f08fb, 0xf8448651, 0x38409563, 0x452f4443, 0x5d464d55,
0x03d8764c, 0xb1b8d638, 0xa70bba2f, 0x94b3d210, 0xeb6692a7, 0xd409c2d9,
0x68838526, 0xa6db8a15, 0x751f6c98, 0xde769a88, 0xc9ee4668, 0x1a82a373,
0x0896aa49, 0x42233681, 0xf62c55cb, 0x9f1c5404, 0xf74fb15c, 0xc06e4312,
0x6ffe5d72, 0x8aa8678b, 0x337cd129, 0x8211cefd, 0x074a1d09, 0x52a10e5a,
0x9275a3f8, 0x4b82506c, 0x37df7e1b, 0x4c78b3c5, 0xcefab1da, 0xf472267e,
0xb63045f6, 0xd66a1fc0, 0x400298e3, 0x27e60c94, 0x87d2f1b8, 0xdf9e56cc,
0x45cd1803, 0x1d35e098, 0xcce7c736, 0x03483bf1, 0x1f7307d7, 0xc6e8f948,
0xe613c111, 0x3955c6ff, 0x1170ed7c, 0x8e95da41, 0x99c31bf4, 0xa4da8021,
0x7b5f94fb, 0xdd0da51f, 0x6562aa77, 0x556bcb23, 0xdb1bacc6, 0x798040b9,
0xbfe5378f, 0x731d55e6, 0xdaa5bfee, 0x389bbc60, 0x1b33fba4, 0x9c567204,
0x36c26c68, 0x77ee9d69, 0x8aeb3e88, 0x2d50b5ce, 0x9579e790, 0x42b13cfc,
0x33fbd32b, 0xee0503a7, 0xb5862824, 0x15e41ead, 0xc8412ef7, 0x9d441275,
0x2fcec582, 0x5ff483b7, 0x8f3931df, 0x2e5d2a7b, 0x49467bf9, 0x0653dea9,
0x2684ce35, 0x7e655e5c, 0xf12771d8, 0xbb15cc67, 0xab097ca1, 0x983dcf52,
0x10ddf026, 0x21267f57, 0x2c58f6b4, 0x31043265, 0x0bab8c01, 0xd5492099,
0xacaae619, 0x944ce54a, 0xf2d13d39, 0xadd3fc32, 0xcda08a40, 0xe2b0d451,
0x9efe08ae, 0xb9d50fd2, 0xea5cd7fd, 0xc9a749dd, 0x13ea2253, 0x832debaa,
0x24be640f, 0xe03e926a, 0x29e01cde, 0x8bf59f18, 0x0f9d00b6, 0xe1238b46,
0x1e7d8e34, 0x93619adb, 0x76b32f9f, 0xbd972cec, 0xe31fa976, 0xa68fbb10,
0xfb3ba49d, 0x8587c41d, 0xa5add1d0, 0xf3cf84bf, 0xd4e11150, 0xd9ffa6bc,
0xc3f6018c, 0xaef10572, 0x74a64b2f, 0xe7dc9559, 0x2aae35d5, 0x5b6f587f,
0xa9e353fe, 0xca4fb674, 0x04ba24a8, 0xe5c6875f, 0xdcbc6266, 0x6bc5c03f,
0x661eef02, 0xed740bab, 0x058e34e4, 0xb7e946cf, 0x88698125, 0x72ec48ed,
0xb11073a3, 0xa13485eb, 0xa2a2429c, 0xfa407547, 0x50b76713, 0x5418c37d,
0x96192da5, 0x170bb04b, 0x518a021e, 0xb0ac13d1, 0x0963fa2a, 0x4a6e10e1,
0x58472bdc, 0xf7f8d962, 0x979139ea, 0x8d856538, 0xc0997042, 0x48324d7a,
0x447623cb, 0x8cbbe364, 0x6e0c6b0e, 0xd36d63b0, 0x3f244c84, 0x3542c971,
0x2b228dc1, 0xcb0325bb, 0xf8c0d6e9, 0xde11066b, 0xa8649327, 0xfc31f83e,
0x7dd80406, 0xf916dd61, 0xd89f79d3, 0x615144c2, 0xebb45d31, 0x28002958,
0x56890a37, 0xf05b3808, 0x123ae844, 0x86839e16, 0x914b0d83, 0xc506b43c,
0xcf3cba5e, 0x7c60f5c9, 0x22deb2a0, 0x5d9c2715, 0xc77ba0ef, 0x4f45360b,
0xc1017d8b, 0xe45adc29, 0xa759909b, 0x412cd293, 0xd7d796b1, 0x00c8ff30,
0x23a34a80, 0x4ec15c91, 0x714e78b5, 0x47b9e42e, 0x78f3ea4d, 0x7f078f5b,
0x346c593a, 0xa3a87a1a, 0x9bcbfe12, 0x3d439963, 0xb2ef6d8e, 0xb8d46028,
0x6c2fd5ca, 0x62675256, 0x01f2a2f3, 0xbc96ae0a, 0x709a8920, 0xb4146e87,
0x6308b9e2, 0x64bda7ba, 0xafed6892, 0x6037f2a2, 0xf52969e0, 0x0adb43a6,
0x82811400, 0x90d0bdf0, 0x19c9549e, 0x203f6a73, 0x1accaf4f, 0x89714e6d,
0x164d4705, 0x67665f07, 0xec206170, 0x0c2182b2, 0xa02b9c81, 0x53289722,
0xf6a97686, 0x140e4179, 0x9f778849, 0x9a88e15d, 0x25cadb54, 0xd157f36f,
0x32a421c3, 0xb368e98a, 0x5a92cd0d, 0x757aa8d4, 0xc20ac278, 0x08b551c7,
0x849491e8, 0x4dc75ad6, 0x697c33be, 0xbaf0ca33, 0x46125b4e, 0x59d677b3,
0x30d9c8f2, 0xd0af860c, 0x1c7fd0fa, 0xfe0ff72c, 0x5c8d6f43, 0x57fdec3b,
0x6ab6ad97, 0xd22adf89, 0x18171785, 0x02bfe22d, 0x6db80917, 0x80b216af,
0xe85e4f9a, 0x7a1c306e, 0x6fc49bf5, 0x3af7a11c, 0x81e215e7, 0x68363fcd,
0x3e9357c8, 0xef52fd55, 0x3b8bab4c, 0x3c8cf495, 0xbefceebd, 0xfd25b714,
0xc498d83d, 0x0d2e1a8d, 0xe9f966ac, 0x0e387445, 0x435419e5, 0x5e7ebec4,
0xaa90b8d9, 0xff1a3a96, 0x4a8fe4e3, 0xf27d99cd, 0xd04a40ca, 0xcb5ff194,
0x3668275a, 0xff4816be, 0xa78b394c, 0x4c6be9db, 0x4eec38d2, 0x4296ec80,
0xcdce96f8, 0x888c2f38, 0xe75508f5, 0x7b916414, 0x060aa14a, 0xa214f327,
0xbe608daf, 0x1ebbdec2, 0x61f98ce9, 0xe92156fe, 0x4f22d7a3, 0x3f76a8d9,
0x559a4b33, 0x38ad2959, 0xf3f17e9e, 0x85e1ba91, 0xe5eba6fb, 0x73dcd48c,
0xf5c3ff78, 0x481b6058, 0x8a3297f7, 0x8f1f3bf4, 0x93785ab2, 0x477a4a5b,
0x6334eb5d, 0x6d251b2e, 0x74a9102d, 0x07e38ffa, 0x915c9c62, 0xccc275ea,
0x6be273ec, 0x3ebddd70, 0xd895796c, 0xdc54a91b, 0xc9afdf81, 0x23633f73,
0x275119b4, 0xb19f6b67, 0x50756e22, 0x2bb152e2, 0x76ea46a2, 0xa353e232,
0x2f596ad6, 0x0b1edb0b, 0x02d3d9a4, 0x78b47843, 0x64893e90, 0x40f0caad,
0xf68d3ad7, 0x46fd1707, 0x1c9c67ef, 0xb5e086de, 0x96ee6ca6, 0x9aa34774,
0x1ba4f48a, 0x8d01abfd, 0x183ee1f6, 0x5ff8aa7a, 0x17e4faae, 0x303983b0,
0x6c08668b, 0xd4ac4382, 0xe6c5849f, 0x92fefb53, 0xc1cac4ce, 0x43501388,
0x441118cf, 0xec4fb308, 0x53a08e86, 0x9e0fe0c5, 0xf91c1525, 0xac45be05,
0xd7987cb5, 0x49ba1487, 0x57938940, 0xd5877648, 0xa958727f, 0x58dfe3c3,
0xf436cf77, 0x399e4d11, 0xf0a5bfa9, 0xef61a33b, 0xa64cac60, 0x04a8d0ba,
0x030dd572, 0xb83d320f, 0xcab23045, 0xe366f2f0, 0x815d008d, 0xc897a43a,
0x1d352df3, 0xb9cc571d, 0x8bf38744, 0x72209092, 0xeba124eb, 0xfb99ce5e,
0x3bb94293, 0x28da549c, 0xaab8a228, 0xa4197785, 0x33c70296, 0x25f6259b,
0x5c85da21, 0xdf15bdee, 0x15b7c7e8, 0xe2abef75, 0xfcc19bc1, 0x417ff868,
0x14884434, 0x62825179, 0xc6d5c11c, 0x0e4705dc, 0x22700de0, 0xd3d2af18,
0x9be822a0, 0x35b669f1, 0xc42bb55c, 0x0a801252, 0x115bf0fc, 0x3cd7d856,
0xb43f5f9d, 0xc2306516, 0xa1231c47, 0xf149207e, 0x5209a795, 0x34b3ccd8,
0x67aefe54, 0x2c83924e, 0x6662cbac, 0x5eedd161, 0x84e681aa, 0x5d57d26b,
0xfa465cc4, 0x7e3ac3a8, 0xbf7c0cc6, 0xe18a9aa1, 0xc32f0a6f, 0xb22cc00d,
0x3d280369, 0x994e554f, 0x68f480d3, 0xadcff5e6, 0x3a8eb265, 0x83269831,
0xbd568a09, 0x4bc8ae6a, 0x69f56d2b, 0x0f17eac8, 0x772eb6c7, 0x9f41343c,
0xab1d0742, 0x826a6f50, 0xfea2097c, 0x1912c283, 0xce185899, 0xe4444839,
0x2d8635d5, 0x65d0b1ff, 0x865a7f17, 0x326d9fb1, 0x59e52820, 0x0090ade1,
0x753c7149, 0x9ddd8b98, 0xa5a691da, 0x0d0382bb, 0x8904c930, 0x086cb000,
0x6e69d3bd, 0x24d4e7a7, 0x05244fd0, 0x101a5e0c, 0x6a947dcb, 0xe840f77b,
0x7d0c5003, 0x7c370f1f, 0x805245ed, 0xe05e3d3f, 0x7906880e, 0xbabfcd35,
0x1a7ec697, 0x8c052324, 0x0c6ec8df, 0xd129a589, 0xc7a75b02, 0x12d81de7,
0xd9be2a66, 0x1f4263ab, 0xde73fdb6, 0x2a00680a, 0x56649e36, 0x3133ed55,
0x90fa0bf2, 0x2910a02a, 0x949d9d46, 0xa0d1dcdd, 0xcfc9b7d4, 0xd2677be5,
0x95cb36b3, 0x13cd9410, 0xdbf73313, 0xb7c6e8c0, 0xf781414b, 0x510b016d,
0xb0de1157, 0xd6b0f62c, 0xbb074ecc, 0x7f1395b7, 0xee792cf9, 0xea6fd63e,
0x5bd6938e, 0xaf02fc64, 0xdab57ab8, 0x8edb3784, 0x8716318f, 0x164d1a01,
0x26f26141, 0xb372e6b9, 0xf8fc2b06, 0x7ac00e04, 0x3727b89a, 0x97e9bca5,
0x9c2a742f, 0xbc3b1f7d, 0x7165b471, 0x609b4c29, 0x20925351, 0x5ae72112,
0x454be5d1, 0xc0ffb95f, 0xdd0ef919, 0x6f2d70c9, 0x0974c5bf, 0x98aa6263,
0x01d91e4d, 0x2184bb6e, 0x70c43c1e, 0x4d435915, 0xae7b8523, 0xb6fb06bc,
0x5431ee76, 0xfdbc5d26, 0xed77493d, 0xc5712ee4, 0xa8380437, 0x2eef261a,
0x5a79392b, 0xb8af32c2, 0x41f7720a, 0x833a61ec, 0x13dfedac, 0xc4990bc4,
0xdc0f54bc, 0xfedd5e88, 0x80da1881, 0x4dea1afd, 0xfd402cc6, 0xae67cc7a,
0xc5238525, 0x8ea01254, 0xb56b9bd5, 0x862fbd6d, 0xac8575d3, 0x6fba3714,
0xda7ebf46, 0x59cd5238, 0x8ac9dbfe, 0x353729fc, 0xe497d7f2, 0xc3ab84e0,
0xf05a114b, 0x7b887a75, 0xedc603dd, 0x5e6fe680, 0x2c84b399, 0x884eb1da,
0x1cb8c8bf, 0xaa51098a, 0xc862231c, 0x8bac2221, 0x21b387e5, 0x208a430d,
0x2a3f0f8b, 0xa5ff9cd2, 0x6012a2ea, 0x147a9ee7, 0xf62a501d, 0xb4b2e51a,
0x3ef3484c, 0xc0253c59, 0x2b82b536, 0x0aa9696b, 0xbe0c109b, 0xc70b7929,
0xce3e8a19, 0x2f66950e, 0x459f1c2c, 0xe68fb93d, 0xa3c3ff3e, 0x62b45c62,
0x300991cb, 0x01914c57, 0x7f7bc06a, 0x182831f5, 0xe7b74bca, 0xfa50f6d0,
0x523caa61, 0xe3a7cf05, 0xe9e41311, 0x280a21d1, 0x6a4297e1, 0xf24dc67e,
0xfc3189e6, 0xb72bf34f, 0x4b1e67af, 0x543402ce, 0x79a59867, 0x0648e02a,
0x00a3ac17, 0xc6208d35, 0x6e7f5f76, 0xa45bb4be, 0xf168fa63, 0x3f4125f3,
0xf311406f, 0x02706565, 0xbfe58022, 0x0cfcfdd9, 0x0735a7f7, 0x8f049092,
0xd98edc27, 0xf5c5d55c, 0xe0f201db, 0x0dcafc9a, 0x7727fb79, 0xaf43abf4,
0x26e938c1, 0x401b26a6, 0x900720fa, 0x2752d97b, 0xcff1d1b3, 0xa9d9e424,
0x42db99ab, 0x6cf8be5f, 0xe82cebe3, 0x3afb733b, 0x6b734eb6, 0x1036414a,
0x975f667c, 0x049d6377, 0xba587c60, 0xb1d10483, 0xde1aefcc, 0x1129d055,
0x72051e91, 0x6946d623, 0xf9e86ea7, 0x48768c00, 0xb0166c93, 0x9956bbf0,
0x1f1f6d84, 0xfb15e18e, 0x033b495d, 0x56e3362e, 0x4f44c53c, 0x747cba51,
0x89d37872, 0x5d9c331b, 0xd2ef9fa8, 0x254917f8, 0x1b106f47, 0x37d75553,
0xb3f053b0, 0x7dccd8ef, 0xd30eb802, 0x5889f42d, 0x610206d7, 0x1a7d34a1,
0x92d87dd8, 0xe5f4a315, 0xd1cf0e71, 0xb22dfe45, 0xb901e8eb, 0x0fc0ce5e,
0x2efa60c9, 0x2de74290, 0x36d0c906, 0x381c70e4, 0x4c6da5b5, 0x3d81a682,
0x7e381f34, 0x396c4f52, 0x95ad5901, 0x1db50c5a, 0x29982e9e, 0x1557689f,
0x3471ee42, 0xd7e2f7c0, 0x8795a1e2, 0xbc324d8d, 0xe224c3c8, 0x12837e39,
0xcdee3d74, 0x7ad2143f, 0x0e13d40c, 0x78bd4a68, 0xa2eb194d, 0xdb9451f9,
0x859b71dc, 0x5c4f5b89, 0xca14a8a4, 0xef92f003, 0x16741d98, 0x33aa4444,
0x9e967fbb, 0x092e3020, 0xd86a35b8, 0x8cc17b10, 0xe1bf08ae, 0x55693fc5,
0x7680ad13, 0x1e6546e8, 0x23b6e7b9, 0xee77a4b2, 0x08ed0533, 0x44fd2895,
0xb6393b69, 0x05d6cacf, 0x9819b209, 0xecbbb72f, 0x9a75779c, 0xeaec0749,
0x94a65aee, 0xbdf52dc3, 0xd6a25d04, 0x82008e4e, 0xa6de160f, 0x9b036afb,
0x228b3a66, 0x5fb10a70, 0xcc338b58, 0x5378a9df, 0xc908bca9, 0x4959e25b,
0x46909a97, 0x66ae8f6e, 0xdd0683e9, 0x65f994b4, 0x6426cda5, 0xc24b8840,
0x32539da0, 0x63175650, 0xd0c815ff, 0x50cbc41e, 0xf7c774a3, 0x31b0c231,
0x8d0d8116, 0x24bef16c, 0xd555d256, 0xdf47ea8c, 0x6d21eccd, 0xa887a012,
0x84542aed, 0xa7b9c1bd, 0x914c1bb1, 0xa0d5b67d, 0x438ce937, 0x7030f873,
0x71f6b0c7, 0x574576ba, 0xf8bc4541, 0x9c61d348, 0x1960579d, 0x17c4daad,
0x96a4cb0b, 0xc193f2f6, 0x756eafa2, 0x7c1d2f94, 0xf4fe2b43, 0xcb86e33a,
0xebd4c728, 0x9d18ae64, 0x9fe13e30, 0x3ce0f5de, 0xaba1f985, 0xaddc2718,
0x68ce6278, 0xd45e241f, 0xa15c82b7, 0x3b2293d4, 0x739edd32, 0x674a6bf1,
0x5b5d587f, 0x4772deaa, 0x4a63968f, 0x0be68686, 0x513d6426, 0x939a4787,
0xbba89296, 0x4ec20007, 0x818d0d08, 0xff64dfd6, 0xcb2297cb, 0xdb48a144,
0xa16cbe4b, 0xbbea1d6c, 0x5af6b6b7, 0x8a8110b6, 0xf9236ef9, 0xc98f83e6,
0x0f9c65b8, 0x252d4a89, 0xa497f068, 0xa5d7ed2d, 0x94c22845, 0x9da1c8c4,
0xe27c2e2e, 0x6e8ba2b4, 0xc3dd17fb, 0x498cd482, 0x0dfe6a9f, 0xb0705829,
0x9a1e6dc1, 0xf829717c, 0x07bb8e3a, 0xda3c0b02, 0x1af82fc7, 0x73b70955,
0x7a04379c, 0x5ee20a28, 0x83712ae5, 0xf4c47c6d, 0xdf72ba56, 0xd794858d,
0x8c0cf709, 0x18f0f390, 0xb6c69b35, 0xbf2f01db, 0x2fa74dca, 0xd0cd9127,
0xbde66cec, 0x3deebd46, 0x57c88fc3, 0xcee1406f, 0x0066385a, 0xf3c3444f,
0x3a79d5d5, 0x75751eb9, 0x3e7f8185, 0x521c2605, 0xe1aaab6e, 0x38ebb80f,
0xbee7e904, 0x61cb9647, 0xea54904e, 0x05ae00e4, 0x2d7ac65f, 0x087751a1,
0xdcd82915, 0x0921ee16, 0xdd86d33b, 0xd6bd491a, 0x40fbadf0, 0x4232cbd2,
0x33808d10, 0x39098c42, 0x193f3199, 0x0bc1e47a, 0x4a82b149, 0x02b65a8a,
0x104cdc8e, 0x24a8f52c, 0x685c6077, 0xc79f95c9, 0x1d11fe50, 0xc08dafcd,
0x7b1a9a03, 0x1c1f11d8, 0x84250e7f, 0x979db248, 0xebdc0501, 0xb9553395,
0xe3c05ea8, 0xb1e51c4c, 0x13b0e681, 0x3b407766, 0x36db3087, 0xee17c9fc,
0x6c53ecf2, 0xadccc58f, 0xc427660b, 0xefd5867d, 0x9b6d54a5, 0x6ff1aeff,
0x8e787952, 0x9e2bffe0, 0x8761d034, 0xe00bdbad, 0xae99a8d3, 0xcc03f6e2,
0xfd0ed807, 0x0e508ae3, 0xb74182ab, 0x4349245d, 0xd120a465, 0xb246a641,
0xaf3b7ab0, 0x2a6488bb, 0x4b3a0d1f, 0xe7c7e58c, 0x3faff2eb, 0x90445ffd,
0xcf38c393, 0x995d07e7, 0xf24f1b36, 0x356f6891, 0x6d6ebcbe, 0x8da9e262,
0x50fd520e, 0x5bca9e1e, 0x37472cf3, 0x69075057, 0x7ec5fded, 0x0cab892a,
0xfb2412ba, 0x1728debf, 0xa000a988, 0xd843ce79, 0x042e20dd, 0x4fe8f853,
0x56659c3c, 0x2739d119, 0xa78a6120, 0x80960375, 0x70420611, 0x85e09f78,
0xabd17e96, 0x1b513eaf, 0x1e01eb63, 0x26ad2133, 0xa890c094, 0x7613cf60,
0x817e781b, 0xa39113d7, 0xe957fa58, 0x4131b99e, 0x28b1efda, 0x66acfba7,
0xff68944a, 0x77a44fd1, 0x7f331522, 0x59ffb3fa, 0xa6df935b, 0xfa12d9df,
0xc6bf6f3f, 0x89520cf6, 0x659edd6a, 0x544da739, 0x8b052538, 0x7c30ea21,
0xc2345525, 0x15927fb2, 0x144a436b, 0xba107b8b, 0x1219ac97, 0x06730432,
0x31831ab3, 0xc55a5c24, 0xaa0fcd3e, 0xe5606be8, 0x5c88f19b, 0x4c0841ee,
0x1fe37267, 0x11f9c4f4, 0x9f1b9dae, 0x864e76d0, 0xe637c731, 0xd97d23a6,
0x32f53d5c, 0xb8161980, 0x93fa0f84, 0xcaef0870, 0x8874487e, 0x98f2cc73,
0x645fb5c6, 0xcd853659, 0x2062470d, 0x16ede8e9, 0x6b06dab5, 0x78b43900,
0xfc95b786, 0x5d8e7de1, 0x465b5954, 0xfe7ba014, 0xf7d23f7b, 0x92bc8b18,
0x03593592, 0x55cef4f7, 0x74b27317, 0x79de1fc2, 0xc8a0bfbd, 0x229398cc,
0x62a602ce, 0xbcb94661, 0x5336d206, 0xd2a375fe, 0x6a6ab483, 0x4702a5a4,
0xa2e9d73d, 0x23a2e0f1, 0x9189140a, 0x581d18dc, 0xb39a922b, 0x82356212,
0xd5f432a9, 0xd356c2a3, 0x5f765b4d, 0x450afcc8, 0x4415e137, 0xe8ecdfbc,
0xed0de3ea, 0x60d42b13, 0xf13df971, 0x71fc5da2, 0xc1455340, 0xf087742f,
0xf55e5751, 0x67b3c1f8, 0xac6b8774, 0x7dcfaaac, 0x95983bc0, 0x489bb0b1,
0x2c184223, 0x964b6726, 0x2bd3271c, 0x72266472, 0xded64530, 0x0a2aa343,
0xd4f716a0, 0xb4dad6d9, 0x2184345e, 0x512c990c, 0x29d92d08, 0x2ebe709a,
0x01144c69, 0x34584b9d, 0xe4634ed6, 0xecc963cf, 0x3c6984aa, 0x4ed056ef,
0x9ca56976, 0x8f3e80d4, 0xb5bae7c5, 0x30b5caf5, 0x63f33a64, 0xa9e4bbde,
0xf6b82298, 0x4d673c1d, 0x4b4f1121, 0xba183081, 0xc784f41f, 0xd17d0bac,
0x083d2267, 0x37b1361e, 0x3581ad05, 0xfda2f6bc, 0x1e892cdd, 0xb56d3c3a,
0x32140e46, 0x138d8aab, 0xe14773d4, 0x5b0e71df, 0x5d1fe055, 0x3fb991d3,
0xf1f46c71, 0xa325988c, 0x10f66e80, 0xb1006348, 0x726a9f60, 0x3b67f8ba,
0x4e114ef4, 0x05c52115, 0x4c5ca11c, 0x99e1efd8, 0x471b83b3, 0xcbf7e524,
0x43ad82f5, 0x690ca93b, 0xfaa61bb2, 0x12a832b5, 0xb734f943, 0xbd22aea7,
0x88fec626, 0x5e80c3e7, 0xbe3eaf5e, 0x44617652, 0xa5724475, 0xbb3b9695,
0x7f3fee8f, 0x964e7deb, 0x518c052d, 0x2a0bbc2b, 0xc2175f5c, 0x9a7b3889,
0xa70d8d0c, 0xeaccdd29, 0xcccd6658, 0x34bb25e6, 0xb8391090, 0xf651356f,
0x52987c9e, 0x0c16c1cd, 0x8e372d3c, 0x2fc6ebbd, 0x6e5da3e3, 0xb0e27239,
0x5f685738, 0x45411786, 0x067f65f8, 0x61778b40, 0x81ab2e65, 0x14c8f0f9,
0xa6b7b4ce, 0x4036eaec, 0xbf62b00a, 0xecfd5e02, 0x045449a6, 0xb20afd28,
0x2166d273, 0x0d13a863, 0x89508756, 0xd51a7530, 0x2d653f7a, 0x3cdbdbc3,
0x80c9df4f, 0x3d5812d9, 0x53fbb1f3, 0xc0f185c0, 0x7a3c3d7e, 0x68646410,
0x857607a0, 0x1d12622e, 0x97f33466, 0xdb4c9917, 0x6469607c, 0x566e043d,
0x79ef1edb, 0x2c05898d, 0xc9578e25, 0xcd380101, 0x46e04377, 0x7d1cc7a9,
0x6552b837, 0x20192608, 0xb97500c5, 0xed296b44, 0x368648b4, 0x62995cd5,
0x82731400, 0xf9aebd8b, 0x3844c0c7, 0x7c2de794, 0x33a1a770, 0x8ae528c2,
0x5a2be812, 0x1f8f4a07, 0x2b5ed7ca, 0x937eb564, 0x6fda7e11, 0xe49b5d6c,
0xb4b3244e, 0x18aa53a4, 0x3a061334, 0x4d6067a3, 0x83ba5868, 0x9bdf4dfe,
0x7449f261, 0x709f8450, 0xcad133cb, 0xde941c3f, 0xf52ae484, 0x781d77ed,
0x7e4395f0, 0xae103b59, 0x922331bb, 0x42ce50c8, 0xe6f08153, 0xe7d941d0,
0x5028ed6b, 0xb3d2c49b, 0xad4d9c3e, 0xd201fb6e, 0xa45bd5be, 0xffcb7f4b,
0x579d7806, 0xf821bb5b, 0x59d592ad, 0xd0be0c31, 0xd4e3b676, 0x0107165a,
0x0fe939d2, 0x49bcaafd, 0x55ffcfe5, 0x2ec1f783, 0xf39a09a5, 0x3eb42772,
0x19b55a5d, 0x024a0679, 0x8c83b3f7, 0x8642ba1d, 0xacacd9ea, 0x87d352c4,
0x60931f45, 0xa05f97d7, 0x1cecd42c, 0xe2fcc87b, 0xb60f94e2, 0x67a34b0b,
0xfcdd40c9, 0x0b150a27, 0xd3ee9e04, 0x582e29e9, 0x4ac22b41, 0x6ac4e1b8,
0xbccaa51a, 0x237af30e, 0xebc3b709, 0xc4a59d19, 0x284bc98a, 0xe9d41a93,
0x6bfa2018, 0x73b2d651, 0x11f9a2fa, 0xce09bff1, 0x41a470aa, 0x25888f22,
0x77e754e8, 0xf7330d8e, 0x158eab16, 0xc5d68842, 0xc685a6f6, 0xe5b82fde,
0x09ea3a96, 0x6dde1536, 0x4fa919da, 0x26c0be9f, 0x9eed6f69, 0xf05555f2,
0xe06fc285, 0x9cd76d23, 0xaf452a92, 0xefc74cb7, 0x9d6b4732, 0x8be408ee,
0x22401d0d, 0xee6c459d, 0x7587cb82, 0xe8746862, 0x5cbdde87, 0x98794278,
0x31afb94d, 0xc11e0f2f, 0x30e8fc2a, 0xcf3261ef, 0x1a3023e1, 0xaa2f86cf,
0xf202e24a, 0x8d08dcff, 0x764837c6, 0xa26374cc, 0x9f7c3e88, 0x949cc57d,
0xdd26a07f, 0xc39efab0, 0xc8f879a1, 0xdce67bb9, 0xf4b0a435, 0x912c9ae0,
0xd85603e4, 0x953a9bbf, 0xfb8290d6, 0x0aebcd5f, 0x16206a9a, 0x6c787a14,
0xd9a0f16a, 0x29bf4f74, 0x8f8bce91, 0x0e5a9354, 0xab038cb1, 0x1b8ad11b,
0xe327ff49, 0x0053da20, 0x90cf51dc, 0xda92fe6d, 0x0390ca47, 0xa8958097,
0xa9dc5baf, 0x3931e3c1, 0x840446b6, 0x63d069fb, 0xd7460299, 0x7124ecd1,
0x0791e613, 0x485918fc, 0xd635d04c, 0xdf96ac33, 0x66f2d303, 0x247056ae,
0xa1a7b2a8, 0x27d8cc9c, 0x17b6e998, 0x7bf5590f, 0xfe97f557, 0x5471d8a2,
0x83a327a1, 0x9f379f51, 0x40a7d007, 0x11307423, 0x224587c1, 0xac27d63b,
0x3b7e64ea, 0x2e1cbfa6, 0x09996000, 0x03bc0e2c, 0xd4c4478a, 0x4542e0ab,
0xfeda26d4, 0xc1d10fcb, 0x8252f596, 0x4494eb5c, 0xa362f314, 0xf5ba81fd,
0x75c3a376, 0x4ca214ca, 0xe164dedd, 0x5088fa97, 0x4b0930e0, 0x2fcfb7e8,
0x33a6f4b2, 0xc7e94211, 0x2d66c774, 0x43be8bae, 0xc663d445, 0x908eb130,
0xf4e3be15, 0x63b9d566, 0x529396b5, 0x1e1be743, 0x4d5ff63f, 0x985e4a83,
0x71ab9df7, 0xc516c6f5, 0x85c19ab4, 0x1f4daee4, 0xf2973431, 0xb713dc5e,
0x3f2e159a, 0xc824da16, 0x06bf376a, 0xb2fe23ec, 0xe39b1c22, 0xf1eecb5f,
0x08e82d52, 0x565686c2, 0xab0aea93, 0xfd47219f, 0xebdbabd7, 0x2404a185,
0x8c7312b9, 0xa8f2d828, 0x0c8902da, 0x65b42b63, 0xc0bbef62, 0x4e3e4cef,
0x788f8018, 0xee1ebab7, 0x93928f9d, 0x683d2903, 0xd3b60689, 0xafcb0ddc,
0x88a4c47a, 0xf6dd9c3d, 0x7ea5fca0, 0x8a6d7244, 0xbe11f120, 0x04ff91b8,
0x8d2dc8c0, 0x27f97fdb, 0x7f9e1f47, 0x1734f0c7, 0x26f3ed8e, 0x0df8f2bf,
0xb0833d9e, 0xe420a4e5, 0xa423cae6, 0x95616772, 0x9ae6c049, 0x075941f2,
0xd8e12812, 0x000f6f4f, 0x3c0d6b05, 0x6cef921c, 0xb82bc264, 0x396cb008,
0x5d608a6f, 0x6d7782c8, 0x186550aa, 0x6b6fec09, 0x28e70b13, 0x57ce5688,
0xecd3af84, 0x23335a95, 0x91f40cd2, 0x7b6a3b26, 0xbd32b3b6, 0x3754a6fb,
0x8ed088f0, 0xf867e87c, 0x20851746, 0x6410f9c6, 0x35380442, 0xc2ca10a7,
0x1adea27f, 0x76bddd79, 0x92742cf4, 0x0e98f7ee, 0x164e931d, 0xb9c835b3,
0x69060a99, 0xb44c531e, 0xfa7b66fe, 0xc98a5b53, 0x7d95aae9, 0x302f467b,
0x74b811de, 0xf3866abd, 0xb5b3d32d, 0xfc3157a4, 0xd251fe19, 0x0b5d8eac,
0xda71ffd5, 0x47ea05a3, 0x05c6a9e1, 0xca0ee958, 0x9939034d, 0x25dc5edf,
0x79083cb1, 0x86768450, 0xcf757d6d, 0x5972b6bc, 0xa78d59c9, 0xc4ad8d41,
0x2a362ad3, 0xd1179991, 0x601407ff, 0xdcf50917, 0x587069d0, 0xe0821ed6,
0xdbb59427, 0x73911a4b, 0x7c904fc3, 0x844afb92, 0x6f8c955d, 0xe8c0c5bb,
0xb67ab987, 0xa529d96c, 0xf91f7181, 0x618b1b06, 0xe718bb0c, 0x8bd7615b,
0xd5a93a59, 0x54aef81b, 0x772136e3, 0xce44fd9c, 0x10cda57e, 0x87d66e0b,
0x3d798967, 0x1b2c1804, 0x3edfbd68, 0x15f6e62b, 0xef68b854, 0x3896db35,
0x12b7b5e2, 0xcb489029, 0x9e4f98a5, 0x62eb77a8, 0x217c24a2, 0x964152f6,
0x49b2080a, 0x53d23ee7, 0x48fb6d69, 0x1903d190, 0x9449e494, 0xbf6e7886,
0xfb356cfa, 0x3a261365, 0x424bc1eb, 0xa1192570, 0x019ca782, 0x9d3f7e0e,
0x9c127575, 0xedf02039, 0xad57bcce, 0x5c153277, 0x81a84540, 0xbcaa7356,
0xccd59b60, 0xa62a629b, 0xa25ccd10, 0x2b5b65cf, 0x1c535832, 0x55fd4e3a,
0x31d9790d, 0xf06bc37d, 0x4afc1d71, 0xaeed5533, 0xba461634, 0xbb694b78,
0x5f3a5c73, 0x6a3c764a, 0x8fb0cca9, 0xf725684c, 0x4fe5382f, 0x1d0163af,
0x5aa07a8f, 0xe205a8ed, 0xc30bad38, 0xff22cf1f, 0x72432e2e, 0x32c2518b,
0x3487ce4e, 0x7ae0ac02, 0x709fa098, 0x0a3b395a, 0x5b4043f8, 0xa9e48c36,
0x149a8521, 0xd07dee6b, 0x46acd2f3, 0x8958dffc, 0xb3a1223c, 0xb11d31c4,
0xcd7f4d3e, 0x0f28e3ad, 0xe5b100be, 0xaac54824, 0xe9c9d7ba, 0x9bd47001,
0x80f149b0, 0x66022f0f, 0x020c4048, 0x6efa192a, 0x67073f8d, 0x13ec7bf9,
0x3655011a, 0xe6afe157, 0xd9845f6e, 0xdecc4425, 0x511ae2cc, 0xdf81b4d8,
0xd7809e55, 0xd6d883d9, 0x2cc7978c, 0x5e787cc5, 0xdd0033d1, 0xa050c937,
0x97f75dcd, 0x299de580, 0x41e2b261, 0xea5a54f1, 0x7e672590, 0xbea513bb,
0x2c906fe6, 0x86029c2b, 0x55dc4f74, 0x0553398e, 0x63e09647, 0xcafd0bab,
0x264c37df, 0x8272210f, 0x67afa669, 0x12d98a5f, 0x8cab23c4, 0x75c68bd1,
0xc3370470, 0x33f37f4e, 0x283992ff, 0xe73a3a67, 0x1032f283, 0xf5ad9fc2,
0x963f0c5d, 0x664fbc45, 0x202ba41c, 0xc7c02d80, 0x54731e84, 0x8a1085f5,
0x601d80fb, 0x2f968e55, 0x35e96812, 0xe45a8f78, 0xbd7de662, 0x3b6e6ead,
0x8097c5ef, 0x070b6781, 0xb1e508f3, 0x24e4fae3, 0xb81a7805, 0xec0fc918,
0x43c8774b, 0x9b2512a9, 0x2b05ad04, 0x32c2536f, 0xedf236e0, 0x8bc4b0cf,
0xbaceb837, 0x4535b289, 0x0d0e94c3, 0xa5a371d0, 0xad695a58, 0x39e3437d,
0x9186bffc, 0x21038c3b, 0x0aa9dff9, 0x5d1f06ce, 0x62def8a4, 0xf740a2b4,
0xa2575868, 0x682683c1, 0xdbb30fac, 0x61fe1928, 0x468a6511, 0xc61cd5f4,
0xe54d9800, 0x6b98d7f7, 0x8418b6a5, 0x5f09a5d2, 0x90b4e80b, 0x49b2c852,
0x69f11c77, 0x17412b7e, 0x7f6fc0ed, 0x56838dcc, 0x6e9546a2, 0xd0758619,
0x087b9b9a, 0xd231a01d, 0xaf46d415, 0x097060fd, 0xd920f657, 0x882d3f9f,
0x3ae7c3c9, 0xe8a00d9b, 0x4fe67ebe, 0x2ef80eb2, 0xc1916b0c, 0xf4dffea0,
0xb97eb3eb, 0xfdff84dd, 0xff8b14f1, 0xe96b0572, 0xf64b508c, 0xae220a6e,
0x4423ae5a, 0xc2bece5e, 0xde27567c, 0xfc935c63, 0x47075573, 0xe65b27f0,
0xe121fd22, 0xf2668753, 0x2debf5d7, 0x8347e08d, 0xac5eda03, 0x2a7cebe9,
0x3fe8d92e, 0x23542fe4, 0x1fa7bd50, 0xcf9b4102, 0x9d0dba39, 0x9cb8902a,
0xa7249d8b, 0x0f6d667a, 0x5ebfa9ec, 0x6a594df2, 0x79600938, 0x023b7591,
0xea2c79c8, 0xc99d07ea, 0x64cb5ee1, 0x1a9cab3d, 0x76db9527, 0xc08e012f,
0x3dfb481a, 0x872f22e7, 0x2948d15c, 0xa4782c79, 0x6f50d232, 0x78f0728a,
0x5a87aab1, 0xc4e2c19c, 0xee767387, 0x1b2a1864, 0x7b8d10d3, 0xd1713161,
0x0eeac456, 0xd8799e06, 0xb645b548, 0x4043cb65, 0xa874fb29, 0x4b12d030,
0x7d687413, 0x18ef9a1f, 0xd7631d4c, 0x5829c7da, 0xcdfa30fa, 0xc5084bb0,
0x92cd20e2, 0xd4c16940, 0x03283ec0, 0xa917813f, 0x9a587d01, 0x70041f8f,
0xdc6ab1dc, 0xddaee3d5, 0x31829742, 0x198c022d, 0x1c9eafcb, 0x5bbc6c49,
0xd3d3293a, 0x16d50007, 0x04bb8820, 0x3c5c2a41, 0x37ee7af8, 0x8eb04025,
0x9313ecba, 0xbffc4799, 0x8955a744, 0xef85d633, 0x504499a7, 0xa6ca6a86,
0xbb3d3297, 0xb34a8236, 0x6dccbe4f, 0x06143394, 0xce19fc7b, 0xccc3c6c6,
0xe36254ae, 0x77b7eda1, 0xa133dd9e, 0xebf9356a, 0x513ccf88, 0xe2a1b417,
0x972ee5bd, 0x853824cd, 0x5752f4ee, 0x6c1142e8, 0x3ea4f309, 0xb2b5934a,
0xdfd628aa, 0x59acea3e, 0xa01eb92c, 0x389964bc, 0xda305dd4, 0x019a59b7,
0x11d2ca93, 0xfaa6d3b9, 0x4e772eca, 0x72651776, 0xfb4e5b0e, 0xa38f91a8,
0x1d0663b5, 0x30f4f192, 0xb50051b6, 0xb716ccb3, 0x4abd1b59, 0x146c5f26,
0xf134e2de, 0x00f67c6c, 0xb0e1b795, 0x98aa4ec7, 0x0cc73b34, 0x654276a3,
0x8d1ba871, 0x740a5216, 0xe0d01a23, 0x9ed161d6, 0x9f36a324, 0x993ebb7f,
0xfeb9491b, 0x365ddcdb, 0x810cffc5, 0x71ec0382, 0x2249e7bf, 0x48817046,
0xf3a24a5b, 0x4288e4d9, 0x0bf5c243, 0x257fe151, 0x95b64c0d, 0x4164f066,
0xaaf7db08, 0x73b1119d, 0x8f9f7bb8, 0xd6844596, 0xf07a34a6, 0x53943d0a,
0xf9dd166d, 0x7a8957af, 0xf8ba3ce5, 0x27c9621e, 0x5cdae910, 0xc8518998,
0x941538fe, 0x136115d8, 0xaba8443c, 0x4d01f931, 0x34edf760, 0xb45f266b,
0xd5d4de14, 0x52d8ac35, 0x15cfd885, 0xcbc5cd21, 0x4cd76d4d, 0x7c80ef54,
0xbc92ee75, 0x1e56a1f6, 0xbaa20b6c, 0x9ffbad26, 0xe1f7d738, 0x794aec8d,
0xc9e9cf3c, 0x8a9a7846, 0xc57c4685, 0xb9a92fed, 0x29cb141f, 0x52f9ddb7,
0xf68ba6bc, 0x19ccc020, 0x4f584aaa, 0x3bf6a596, 0x003b7cf7, 0x54f0ce9a,
0xa7ec4303, 0x46cf0077, 0x78d33aa1, 0x215247d9, 0x74bcdf91, 0x08381d30,
0xdac43e40, 0x64872531, 0x0beffe5f, 0xb317f457, 0xaebb12da, 0xd5d0d67b,
0x7d75c6b4, 0x42a6d241, 0x1502d0a9, 0x3fd97fff, 0xc6c3ed28, 0x81868d0a,
0x92628bc5, 0x86679544, 0xfd1867af, 0x5ca3ea61, 0x568d5578, 0x4a2d71f4,
0x43c9d549, 0x8d95de2b, 0x6e5c74a0, 0x9120ffc7, 0x0d05d14a, 0xa93049d3,
0xbfa80e17, 0xf4096810, 0x043f5ef5, 0xa673b4f1, 0x6d780298, 0xa4847783,
0x5ee726fb, 0x9934c281, 0x220a588c, 0x384e240f, 0x933d5c69, 0x39e5ef47,
0x26e8b8f3, 0x4c1c6212, 0x8040f75d, 0x074b7093, 0x6625a8d7, 0x36298945,
0x76285088, 0x651d37c3, 0x24f5274d, 0xdbca3dab, 0x186b7ee1, 0xd80f8182,
0x14210c89, 0x943a3075, 0x4e6e11c4, 0x4d7e6bad, 0xf05064c8, 0x025dcd97,
0x4bc10302, 0x7cede572, 0x8f90a970, 0xab88eeba, 0xb5998029, 0x5124d839,
0xb0eeb6a3, 0x89ddabdc, 0xe8074d76, 0xa1465223, 0x32518cf2, 0x9d39d4eb,
0xc0d84524, 0xe35e6ea8, 0x7abf3804, 0x113e2348, 0x9ae6069d, 0xb4dfdabb,
0xa8c5313f, 0x23ea3f79, 0x530e36a2, 0xa5fd228b, 0x95d1d350, 0x2b14cc09,
0x40042956, 0x879d05cc, 0x2064b9ca, 0xacaca40e, 0xb29c846e, 0x9676c9e3,
0x752b7b8a, 0x7be2bcc2, 0x6bd58f5e, 0xd48f4c32, 0x606835e4, 0x9cd7c364,
0x2c269b7a, 0x3a0d079c, 0x73b683fe, 0x45374f1e, 0x10afa242, 0x577f8666,
0xddaa10f6, 0xf34f561c, 0x3d355d6b, 0xe47048ae, 0xaa13c492, 0x050344fd,
0x2aab5151, 0xf5b26ae5, 0xed919a59, 0x5ac67900, 0xf1cde380, 0x0c79a11b,
0x351533fc, 0xcd4d8e36, 0x1f856005, 0x690b9fdd, 0xe736dccf, 0x1d47bf6a,
0x7f66c72a, 0x85f21b7f, 0x983cbdb6, 0x01ebbebf, 0x035f3b99, 0xeb111f34,
0x28cefdc6, 0x5bfc9ecd, 0xf22eacb0, 0x9e41cbb2, 0xe0f8327c, 0x82e3e26f,
0xfc43fc86, 0xd0ba66df, 0x489ef2a7, 0xd9e0c81d, 0x68690d52, 0xcc451367,
0xc2232e16, 0xe95a7335, 0x0fdae19b, 0xff5b962c, 0x97596527, 0xc46db333,
0x3ed4c562, 0xc14c9d9e, 0x5d6faa21, 0x638e940d, 0xf9316d58, 0x47b3b0ea,
0x30ffcad2, 0xce1bba7d, 0x1e6108e6, 0x2e1ea33d, 0x507bf05b, 0xfafef94b,
0xd17de8e2, 0x5598b214, 0x1663f813, 0x17d25a2d, 0xeefa5ff9, 0x582f4e37,
0x12128773, 0xfef17ab8, 0x06005322, 0xbb32bbc9, 0x8c898508, 0x592c15f0,
0xd38a4054, 0x4957b7d6, 0xd2b891db, 0x37bd2d3e, 0x34ad20cb, 0x622288e9,
0x2dc7345a, 0xafb416c0, 0x1cf459b1, 0xdc7739fa, 0x0a711a25, 0x13e18a0c,
0x5f72af4c, 0x6ac8db11, 0xbe53c18e, 0x1aa569b9, 0xef551ea4, 0xa02a429f,
0xbd16e790, 0x7eb9171a, 0x77d693d8, 0x8e06993a, 0x9bde7560, 0xe5801987,
0xc37a09be, 0xb8db76ac, 0xe2087294, 0x6c81616d, 0xb7f30fe7, 0xbc9b82bd,
0xfba4e4d4, 0xc7b1012f, 0xa20c043b, 0xde9febd0, 0x2f9297ce, 0xe610aef8,
0x70b06f19, 0xc86ae00b, 0x0e01988f, 0x41192ae0, 0x448c1cb5, 0xadbe92ee,
0x7293a007, 0x1b54b5b3, 0xd61f63d1, 0xeae40a74, 0x61a72b55, 0xec83a7d5,
0x88942806, 0x90a07da5, 0xd7424b95, 0x67745b4e, 0xa31a1853, 0xca6021ef,
0xdfb56c4f, 0xcbc2d915, 0x3c48e918, 0x8bae3c63, 0x6f659c71, 0xf8b754c1,
0x2782f3de, 0xf796f168, 0x71492c84, 0x33c0f5a6, 0x3144f6ec, 0x25dc412e,
0xb16c5743, 0x83a1fa7e, 0x0997b101, 0xb627e6e8, 0xcf33905c, 0x8456fb65,
0xb29bea74, 0xc35da605, 0x305c1ca3, 0xd2e9f5bc, 0x6fd5bff4, 0xff347703,
0xfc45b163, 0xf498e068, 0xb71229fc, 0x81acc3fb, 0x78538a8b, 0x984ecf81,
0xa5da47a4, 0x8f259eef, 0x6475dc65, 0x081865b9, 0x49e14a3c, 0x19e66079,
0xd382e91b, 0x5b109794, 0x3f9f81e1, 0x4470a388, 0x41601abe, 0xaaf9f407,
0x8e175ef6, 0xed842297, 0x893a4271, 0x1790839a, 0xd566a99e, 0x6b417dee,
0x75c90d23, 0x715edb31, 0x723553f7, 0x9afb50c9, 0xfbc5f600, 0xcd3b6a4e,
0x97ed0fba, 0x29689aec, 0x63135c8e, 0xf0e26c7e, 0x0692ae7f, 0xdbb208ff,
0x2ede3e9b, 0x6a65bebd, 0xd40867e9, 0xc954afc5, 0x73b08201, 0x7ffdf809,
0x1195c24f, 0x1ca5adca, 0x74bd6d1f, 0xb393c455, 0xcadfd3fa, 0x99f13011,
0x0ebca813, 0x60e791b8, 0x6597ac7a, 0x18a7e46b, 0x09cb49d3, 0x0b27df6d,
0xcfe52f87, 0xcef66837, 0xe6328035, 0xfa87c592, 0x37baff93, 0xd71fcc99,
0xdcab205c, 0x4d7a5638, 0x48012510, 0x62797558, 0xb6cf1fe5, 0xbc311834,
0x9c2373ac, 0x14ec6175, 0xa439cbdf, 0x54afb0ea, 0xd686960b, 0xfdd0d47b,
0x7b063902, 0x8b78bac3, 0x26c6a4d5, 0x5c0055b6, 0x2376102e, 0x0411783e,
0x2aa3f1cd, 0x51fc6ea8, 0x701ce243, 0x9b2a0abb, 0x0ad93733, 0x6e80d03d,
0xaf6295d1, 0xf629896f, 0xa30b0648, 0x463d8dd4, 0x963f84cb, 0x01ff94f8,
0x8d7fefdc, 0x553611c0, 0xa97c1719, 0xb96af759, 0xe0e3c95e, 0x0528335b,
0x21fe5925, 0x821a5245, 0x807238b1, 0x67f23db5, 0xea6b4eab, 0x0da6f985,
0xab1bc85a, 0xef8c90e4, 0x4526230e, 0x38eb8b1c, 0x1b91cd91, 0x9fce5f0c,
0xf72cc72b, 0xc64f2617, 0xdaf7857d, 0x7d373cf1, 0x28eaedd7, 0x203887d0,
0xc49a155f, 0xa251b3b0, 0xf2d47ae3, 0x3d9ef267, 0x4a94ab2f, 0x7755a222,
0x0205e329, 0xc28fa7a7, 0xaec1fe51, 0x270f164c, 0x8c6d01bf, 0x53b5bc98,
0xc09d3feb, 0x834986cc, 0x4309a12c, 0x578b2a96, 0x3bb74b86, 0x69561b4a,
0x037e32f3, 0xde335b08, 0xc5156be0, 0xe7ef09ad, 0x93b834c7, 0xa7719352,
0x59302821, 0xe3529d26, 0xf961da76, 0xcb142c44, 0xa0f3b98d, 0x76502457,
0x945a414b, 0x078eeb12, 0xdff8de69, 0xeb6c8c2d, 0xbda90c4d, 0xe9c44d16,
0x168dfd66, 0xad64763b, 0xa65fd764, 0x95a29c06, 0x32d7713f, 0x40f0b277,
0x224af08f, 0x004cb5e8, 0x92574814, 0x8877d827, 0x3e5b2d04, 0x68c2d5f2,
0x86966273, 0x1d433ada, 0x8774988a, 0x3c0e0bfe, 0xddad581d, 0x2fd654ed,
0x0f4769fd, 0xc181ee9d, 0x5fd88f61, 0x341dbb3a, 0x528543f9, 0xd92235cf,
0x1ea82eb4, 0xb5cd790f, 0x91d24f1e, 0xa869e6c2, 0x61f474d2, 0xcc205add,
0x0c7bfba9, 0xbf2b0489, 0xb02d72d8, 0x2b46ece6, 0xe4dcd90a, 0xb8a11440,
0xee8a63b7, 0x854dd1a1, 0xd1e00583, 0x42b40e24, 0x9e8964de, 0xb4b35d78,
0xbec76f6e, 0x24b9c620, 0xd8d399a6, 0x5adb2190, 0x2db12730, 0x3a5866af,
0x58c8fadb, 0x5d8844e7, 0x8a4bf380, 0x15a01d70, 0x79f5c028, 0x66be3b8c,
0xf3e42b53, 0x56990039, 0x2c0c3182, 0x5e16407c, 0xecc04515, 0x6c440284,
0x4cb6701a, 0x13bfc142, 0x9d039f6a, 0x4f6e92c8, 0xa1407c62, 0x8483a095,
0xc70ae1c4, 0xe20213a2, 0xbacafc41, 0x4ecc12b3, 0x4bee3646, 0x1fe807ae,
0x25217f9c, 0x35dde5f5, 0x7a7dd6ce, 0xf89cce50, 0xac07b718, 0x7e73d2c6,
0xe563e76c, 0x123ca536, 0x3948ca56, 0x9019dd49, 0x10aa88d9, 0xc82451e2,
0x473eb6d6, 0x506fe854, 0xe8bb03a5, 0x332f4c32, 0xfe1e1e72, 0xb1ae572a,
0x7c0d7bc1, 0xe1c37eb2, 0xf542aa60, 0xf1a48ea0, 0xd067b89f, 0xbbfa195d,
0x1a049b0d, 0x315946aa, 0x36d1b447, 0x6d2ebdf0, 0x0d188a6d, 0x12cea0db,
0x7e63740e, 0x6a444821, 0x253d234f, 0x6ffc6597, 0x94a6bdef, 0x33ee1b2f,
0x0a6c00c0, 0x3aa336b1, 0x5af55d17, 0x265fb3dc, 0x0e89cf4d, 0x0786b008,
0xc80055b8, 0x6b17c3ce, 0x72b05a74, 0xd21a8d78, 0xa6b70840, 0xfe8eae77,
0xed69565c, 0x55e1bcf4, 0x585c2f60, 0xe06f1a62, 0xad67c0cd, 0x7712af88,
0x9cc26aca, 0x1888053d, 0x37eb853e, 0x9215abd7, 0xde30adfc, 0x1f1038e6,
0x70c51c8a, 0x8d586c26, 0xf72bdd90, 0x4dc3ce15, 0x68eaeefa, 0xd0e9c8b9,
0x200f9c44, 0xddd141ba, 0x024bf1d3, 0x0f64c9d4, 0xc421e9e9, 0x9d11c14c,
0x9a0dd9e4, 0x5f92ec19, 0x1b980df0, 0x1dcc4542, 0xb8fe8c56, 0x0c9c9167,
0x4e81eb49, 0xca368f27, 0xe3603b37, 0xea08accc, 0xac516992, 0xc34f513b,
0x804d100d, 0x6edca4c4, 0xfc912939, 0x29d219b0, 0x278aaa3c, 0x4868da7d,
0x54e890b7, 0xb46d735a, 0x514589aa, 0xd6c630af, 0x4980dfe8, 0xbe3ccc55,
0x59d41202, 0x650c078b, 0xaf3a9e7b, 0x3ed9827a, 0x9e79fc6e, 0xaadbfbae,
0xc5f7d803, 0x3daf7f50, 0x67b4f465, 0x73406e11, 0x39313f8c, 0x8a6e6686,
0xd8075f1f, 0xd3cbfed1, 0x69c7e49c, 0x930581e0, 0xe4b1a5a8, 0xbbc45472,
0x09ddbf58, 0xc91d687e, 0xbdbffda5, 0x88c08735, 0xe9e36bf9, 0xdb5ea9b6,
0x95559404, 0x08f432fb, 0xe24ea281, 0x64663579, 0x000b8010, 0x7914e7d5,
0x32fd0473, 0xd1a7f0a4, 0x445ab98e, 0xec72993f, 0xa29a4d32, 0xb77306d8,
0xc7c97cf6, 0x7b6ab645, 0xf5ef7adf, 0xfb2e15f7, 0xe747f757, 0x5e944354,
0x234a2669, 0x47e46359, 0x9b9d11a9, 0x40762ced, 0x56f1de98, 0x11334668,
0x890a9a70, 0x1a296113, 0xb3bd4af5, 0x163b7548, 0xd51b4f84, 0xb99b2abc,
0x3cc1dc30, 0xa9f0b56c, 0x812272b2, 0x0b233a5f, 0xb650dbf2, 0xf1a0771b,
0x36562b76, 0xdc037b0f, 0x104c97ff, 0xc2ec98d2, 0x90596f22, 0x28b6620b,
0xdf42b212, 0xfdbc4243, 0xf3fb175e, 0x4a2d8b00, 0xe8f3869b, 0x30d69bc3,
0x853714c8, 0xa7751d2e, 0x31e56dea, 0xd4840b0c, 0x9685d783, 0x068c9333,
0x8fba032c, 0x76d7bb47, 0x6d0ee22b, 0xb546794b, 0xd971b894, 0x8b09d253,
0xa0ad5761, 0xee77ba06, 0x46359f31, 0x577cc7ec, 0x52825efd, 0xa4beed95,
0x9825c52a, 0xeb48029a, 0xbaae59f8, 0xcf490ee1, 0xbc990164, 0x8ca49dfe,
0x4f38a6e7, 0x2ba98389, 0x8228f538, 0x199f64ac, 0x01a1cac5, 0xa8b51641,
0x5ce72d01, 0x8e5df26b, 0x60f28e1e, 0xcd5be125, 0xe5b376bf, 0x1c8d3116,
0x7132cbb3, 0xcb7ae320, 0xc0fa5366, 0xd7653e34, 0x971c88c2, 0xc62c7dd0,
0x34d0a3da, 0x868f6709, 0x7ae6fa8f, 0x22bbd523, 0x66cd3d5b, 0x1ef9288d,
0xf9cf58c1, 0x5b784e80, 0x7439a191, 0xae134c36, 0x9116c463, 0x2e9e1396,
0xf8611f3a, 0x2d2f3307, 0x247f37dd, 0xc1e2ff9d, 0x43c821e5, 0x05ed5cab,
0xef74e80a, 0x4cca6028, 0xf0ac3cbd, 0x5d874b29, 0x6c62f6a6, 0x4b2a2ef3,
0xb1aa2087, 0x62a5d0a3, 0x0327221c, 0xb096b4c6, 0x417ec693, 0xaba840d6,
0x789725eb, 0xf4b9e02d, 0xe6e00975, 0xcc04961a, 0x63f624bb, 0x7fa21ecb,
0x2c01ea7f, 0xb2415005, 0x2a8bbeb5, 0x83b2b14e, 0xa383d1a7, 0x5352f96a,
0x043ecdad, 0xce1918a1, 0xfa6be6c9, 0x50def36f, 0xf6b80ce2, 0x4543ef7c,
0x9953d651, 0xf257955d, 0x87244914, 0xda1e0a24, 0xffda4785, 0x14d327a2,
0x3b93c29f, 0x840684b4, 0x61ab71a0, 0x9f7b784a, 0x2fd570cf, 0x15955bde,
0x38f8d471, 0x3534a718, 0x133fb71d, 0x3fd80f52, 0x4290a8be, 0x75ff44c7,
0xa554e546, 0xe1023499, 0xbf2652e3, 0x7d20399e, 0xa1df7e82, 0x177092ee,
0x217dd3f1, 0x7c1ff8d9, 0x12113f2e, 0xbfbd0785, 0xf11793fb, 0xa5bff566,
0x83c7b0e5, 0x72fb316b, 0x75526a9a, 0x41e0e612, 0x7156ba09, 0x53ce7dee,
0x0aa26881, 0xa43e0d7d, 0x3da73ca3, 0x182761ed, 0xbd5077ff, 0x56db4aa0,
0xe792711c, 0xf0a4eb1d, 0x7f878237, 0xec65c4e8, 0x08dc8d43, 0x0f8ce142,
0x8258abda, 0xf4154e16, 0x49dec2fd, 0xcd8d5705, 0x6c2c3a0f, 0x5c12bb88,
0xeff3cdb6, 0x2c89ed8c, 0x7beba967, 0x2a142157, 0xc6d0836f, 0xb4f97e96,
0x6931e969, 0x514e6c7c, 0xa7792600, 0x0bbbf780, 0x59671bbd, 0x0707b676,
0x37482d93, 0x80af1479, 0x3805a60d, 0xe1f4cac1, 0x580b3074, 0x30b8d6ce,
0x05a304be, 0xd176626d, 0xebca97f3, 0xbb201f11, 0x6a1afe23, 0xffaa86e4,
0x62b4da49, 0x1b6629f5, 0xf5d9e092, 0xf37f3dd1, 0x619bd45b, 0xa6ec8e4f,
0x29c80939, 0x0c7c0c34, 0x9cfe6e48, 0xe65fd3ac, 0x73613b65, 0xb3c669f9,
0xbe2e8a9e, 0x286f9678, 0x5797fd13, 0x99805d75, 0xcfb641c5, 0xa91074ba,
0x6343af47, 0x6403cb46, 0x8894c8db, 0x2663034c, 0x3c40dc5e, 0x00995231,
0x96789aa2, 0x2efde4b9, 0x7dc195e1, 0x547dadd5, 0x06a8ea04, 0xf2347a63,
0x5e0dc6f7, 0x8462dfc2, 0x1e6b2c3c, 0x9bd275b3, 0x91d419e2, 0xbcefd17e,
0xb9003924, 0xd07e7320, 0xdef0495c, 0xc36ad00e, 0x1785b1ab, 0x92e20bcf,
0xb139f0e9, 0x675bb9a1, 0xaecfa4af, 0x132376cb, 0xe84589d3, 0x79a05456,
0xa2f860bc, 0x1ae4f8b5, 0x20df4db4, 0xa1e1428b, 0x3bf60a1a, 0x27ff7bf1,
0xcb44c0e7, 0xf7f587c4, 0x1f3b9b21, 0x94368f01, 0x856e23a4, 0x6f93de3f,
0x773f5bbf, 0x8b22056e, 0xdf41f654, 0xb8246ff4, 0x8d57bff2, 0xd57167ea,
0xc5699f22, 0x40734ba7, 0x5d5c2772, 0x033020a8, 0xe30a7c4d, 0xadc40fd6,
0x76353441, 0x5aa5229b, 0x81516590, 0xda49f14e, 0x4fa672a5, 0x4d9fac5f,
0x154be230, 0x8a7a5cc0, 0xce3d2f84, 0xcca15514, 0x5221360c, 0xaf0fb81e,
0x5bdd5873, 0xf6825f8f, 0x1113d228, 0x70ad996c, 0x93320051, 0x60471c53,
0xe9ba567b, 0x3a462ae3, 0x5f55e72d, 0x1d3c5ad7, 0xdcfc45ec, 0x34d812ef,
0xfa96ee1b, 0x369d1ef8, 0xc9b1a189, 0x7c1d3555, 0x50845edc, 0x4bb31877,
0x8764a060, 0x8c9a9415, 0x230e1a3a, 0xb05e9133, 0x242b9e03, 0xa3b99db7,
0xc2d7fb0a, 0x3333849d, 0xd27278d4, 0xb5d3efa6, 0x78ac28ad, 0xc7b2c135,
0x0926ecf0, 0xc1374c91, 0x74f16d98, 0x2274084a, 0x3f6d9cfa, 0x7ac0a383,
0xb73aff1f, 0x3909a23d, 0x9f1653ae, 0x4e2f3e71, 0xca5ab22a, 0xe01e3858,
0x90c5a7eb, 0x3e4a17df, 0xaa987fb0, 0x488bbd62, 0xb625062b, 0x2d776bb8,
0x43b5fc08, 0x1490d532, 0xd6d12495, 0x44e89845, 0x2fe60118, 0x9d9ef950,
0xac38133e, 0xd3864329, 0x017b255a, 0xfdc2dd26, 0x256851e6, 0x318e7086,
0x2bfa4861, 0x89eac706, 0xee5940c6, 0x68c3bc2f, 0xe260334b, 0x98da90bb,
0xf818f270, 0x4706d897, 0x212d3799, 0x4cf7e5d0, 0xd9c9649f, 0xa85db5cd,
0x35e90e82, 0x6b881152, 0xab1c02c7, 0x46752b02, 0x664f598e, 0x45ab2e64,
0xc4cdb4b2, 0xba42107f, 0xea2a808a, 0x971bf3de, 0x4a54a836, 0x4253aecc,
0x1029be68, 0x6dcc9225, 0xe4bca56a, 0xc0ae50b1, 0x7e011d94, 0xe59c162c,
0xd8e5c340, 0xd470fa0b, 0xb2be79dd, 0xd783889c, 0x1cede8f6, 0x8f4c817a,
0xddb785c9, 0x860232d8, 0x198aaad9, 0xa0814738, 0x3219cffc, 0x169546d2,
0xfc0cb759, 0x55911510, 0x04d5cec3, 0xed08cc3b, 0x0d6cf427, 0xc8e38cca,
0x0eeee3fe, 0x9ee7d7c8, 0xf9f24fa9, 0xdb04b35d, 0x9ab0c9e0, 0x651f4417,
0x028f8b07, 0x6e28d9aa, 0xfba96319, 0x8ed66687, 0xfecbc58d, 0x954ddb44,
0x7b0bdffe, 0x865d16b1, 0x49a058c0, 0x97abaa3f, 0xcaacc75d, 0xaba6c17d,
0xf8746f92, 0x6f48aeed, 0x8841d4b5, 0xf36a146a, 0x73c390ab, 0xe6fb558f,
0x87b1019e, 0x26970252, 0x246377b2, 0xcbf676ae, 0xf923db06, 0xf7389116,
0x14c81a90, 0x83114eb4, 0x8b137559, 0x95a86a7a, 0xd5b8da8c, 0xc4df780e,
0x5a9cb3e2, 0xe44d4062, 0xe8dc8ef6, 0x9d180845, 0x817ad18b, 0xc286c85b,
0x251f20de, 0xee6d5933, 0xf6edef81, 0xd4d16c1e, 0xc94a0c32, 0x8437fd22,
0x3271ee43, 0x42572aee, 0x5f91962a, 0x1c522d98, 0x59b23f0c, 0xd86b8804,
0x08c63531, 0x2c0d7a40, 0xb97c4729, 0x04964df9, 0x13c74a17, 0x5878362f,
0x4c808cd6, 0x092cb1e0, 0x6df02885, 0xa0c2105e, 0x8aba9e68, 0x64e03057,
0xe5d61325, 0x0e43a628, 0x16dbd62b, 0x2733d90b, 0x3ae57283, 0xc0c1052c,
0x4b6fb620, 0x37513953, 0xfc898bb3, 0x471b179f, 0xdf6e66b8, 0xd32142f5,
0x9b30fafc, 0x4ed92549, 0x105c6d99, 0x4acd69ff, 0x2b1a27d3, 0x6bfcc067,
0x6301a278, 0xad36e6f2, 0xef3ff64e, 0x56b3cadb, 0x0184bb61, 0x17beb9fd,
0xfaec6109, 0xa2e1ffa1, 0x2fd224f8, 0x238f5be6, 0x8f8570cf, 0xaeb5f25a,
0x4f1d3e64, 0x4377eb24, 0x1fa45346, 0xb2056386, 0x52095e76, 0xbb7b5adc,
0x3514e472, 0xdde81e6e, 0x7acea9c4, 0xac15cc48, 0x71c97d93, 0x767f941c,
0x911052a2, 0xffea09bf, 0xfe3ddcf0, 0x15ebf3aa, 0x9235b8bc, 0x75408615,
0x9a723437, 0xe1a1bd38, 0x33541b7e, 0x1bdd6856, 0xb307e13e, 0x90814bb0,
0x51d7217b, 0x0bb92219, 0x689f4500, 0xc568b01f, 0x5df3d2d7, 0x3c0ecd0d,
0x2a0244c8, 0x852574e8, 0xe72f23a9, 0x8e26ed02, 0x2d92cbdd, 0xdabc0458,
0xcdf5feb6, 0x9e4e8dcc, 0xf4f1e344, 0x0d8c436d, 0x4427603b, 0xbdd37fda,
0x80505f26, 0x8c7d2b8e, 0xb73273c5, 0x397362ea, 0x618a3811, 0x608bfb88,
0x06f7d714, 0x212e4677, 0x28efcead, 0x076c0371, 0x36a3a4d9, 0x5487b455,
0x3429a365, 0x65d467ac, 0x78ee7eeb, 0x99bf12b7, 0x4d129896, 0x772a5601,
0xcce284c7, 0x2ed85c21, 0xd099e8a4, 0xa179158a, 0x6ac0ab1a, 0x299a4807,
0xbe67a58d, 0xdc19544a, 0xb8949b54, 0x8d315779, 0xb6f849c1, 0x53c5ac34,
0x66de92a5, 0xf195dd13, 0x318d3a73, 0x301ec542, 0x0cc40da6, 0xf253ade4,
0x467ee566, 0xea5585ec, 0x3baf19bb, 0x7de9f480, 0x79006e7c, 0xa9b7a197,
0xa44bd8f1, 0xfb2ba739, 0xec342fd4, 0xed4fd32d, 0x3d1789ba, 0x400f5d7f,
0xc798f594, 0x4506a847, 0x034c0a95, 0xe2162c9d, 0x55a9cfd0, 0x692d832e,
0xcf9db2ca, 0x5e2287e9, 0xd2610ef3, 0x1ae7ecc2, 0x48399ca0, 0xa7e4269b,
0x6ee3a0af, 0x7065bfe1, 0xa6ffe708, 0x2256804c, 0x7476e21b, 0x41b0796c,
0x7c243b05, 0x000a950f, 0x1858416b, 0xf5a53c89, 0xe9fef823, 0x3f443275,
0xe0cbf091, 0x0af27b84, 0x3ebb0f27, 0x1de6f7f4, 0xc31c29f7, 0xb166de3d,
0x12932ec3, 0x9c0c0674, 0x5cda81b9, 0xd1bd9d12, 0xaffd7c82, 0x8962bca7,
0xa342c4a8, 0x62457151, 0x82089f03, 0xeb49c670, 0x5b5f6530, 0x7e28bad2,
0x20880ba3, 0xf0faafcd, 0xce82b56f, 0x0275335c, 0xc18e8afb, 0xde601d69,
0xba9b820a, 0xc8a2be4f, 0xd7cac335, 0xd9a73741, 0x115e974d, 0x7f5ac21d,
0x383bf9c6, 0xbcaeb75f, 0xfd0350ce, 0xb5d06b87, 0x9820e03c, 0x72d5f163,
0xe3644fc9, 0xa5464c4b, 0x57048fcb, 0x9690c9df, 0xdbf9eafa, 0xbff4649a,
0x053c00e3, 0xb4b61136, 0x67593dd1, 0x503ee960, 0x9fb4993a, 0x19831810,
0xc670d518, 0xb05b51d8, 0x0f3a1ce5, 0x6caa1f9c, 0xaacc31be, 0x949ed050,
0x1ead07e7, 0xa8479abd, 0xd6cffcd5, 0x936993ef, 0x472e91cb, 0x5444b5b6,
0x62be5861, 0x1be102c7, 0x63e4b31e, 0xe81f71b7, 0x9e2317c9, 0x39a408ae,
0x518024f4, 0x1731c66f, 0x68cbc918, 0x71fb0c9e, 0xd03b7fdd, 0x7d6222eb,
0x9057eda3, 0x1a34a407, 0x8cc2253d, 0xb6f6979d, 0x835675dc, 0xf319be9f,
0xbe1cd743, 0x4d32fee4, 0x77e7d887, 0x37e9ebfd, 0x15f851e8, 0x23dc3706,
0x19d78385, 0xbd506933, 0xa13ad4a6, 0x913f1a0e, 0xdde560b9, 0x9a5f0996,
0xa65a0435, 0x48d34c4d, 0xe90839a7, 0x8abba54e, 0x6fd13ce1, 0xc7eebd3c,
0x0e297602, 0x58b9bbb4, 0xef7901e6, 0x64a28a62, 0xa509875a, 0xf8834442,
0x2702c709, 0x07353f31, 0x3b39f665, 0xf5b18b49, 0x4010ae37, 0x784de00b,
0x7a1121e9, 0xde918ed3, 0xc8529dcd, 0x816a5d05, 0x02ed8298, 0x04e3dd84,
0xfd2bc3e2, 0xaf167089, 0x96af367e, 0xa4da6232, 0x18ff7325, 0x05f9a9f1,
0x4fefb9f9, 0xcd94eaa5, 0xbfaa5069, 0xa0b8c077, 0x60d86f57, 0xfe71c813,
0x29ebd2c8, 0x4ca86538, 0x6bf1a030, 0xa237b88a, 0xaa8af41d, 0xe1f7b6ec,
0xe214d953, 0x33057879, 0x49caa736, 0xfa45cff3, 0xc063b411, 0xba7e27d0,
0x31533819, 0x2a004ac1, 0x210efc3f, 0x2646885e, 0x66727dcf, 0x9d7fbf54,
0xa8dd0ea8, 0x3447cace, 0x3f0c14db, 0xb8382aac, 0x4ace3539, 0x0a518d51,
0x95178981, 0x35aee2ca, 0x73f0f7e3, 0x94281140, 0x59d0e523, 0xd292cb88,
0x565d1b27, 0x7ec8fbaf, 0x069af08d, 0xc127fd24, 0x0bc77b10, 0x5f03e7ef,
0x453e99ba, 0xeed9ff7f, 0x87b55215, 0x7915ab4c, 0xd389a358, 0x5e75ce6d,
0x28d655c0, 0xdad26c73, 0x2e2510ff, 0x9fa7eecc, 0x1d0629c3, 0xdc9c9c46,
0x2d67ecd7, 0xe75e94bd, 0x3d649e2a, 0x6c413a2b, 0x706f0d7c, 0xdfb0127b,
0x4e366b55, 0x2c825650, 0x24205720, 0xb5c998f7, 0x3e95462c, 0x756e5c72,
0x3259488f, 0x11e8771a, 0xa7c0a617, 0x577663e5, 0x089b6401, 0x8eab1941,
0xae55ef8c, 0x3aac5460, 0xd4e6262f, 0x5d979a47, 0xb19823b0, 0x7f8d6a0c,
0xffa08683, 0x0170cd0f, 0x858cd5d8, 0x53961c90, 0xc4c61556, 0x41f2f226,
0xcfcd062d, 0xf24c03b8, 0xea81df5b, 0x7be2fa52, 0xb361f98b, 0xc2901316,
0x55ba4bbc, 0x93b234a9, 0x0fbc6603, 0x80a96822, 0x6d60491f, 0x22bd00f8,
0xbcad5aad, 0x52f3f13b, 0x42fd2b28, 0xb41dd01c, 0xc52c93bf, 0xfc663094,
0x8f58d100, 0x43fecc08, 0xc6331e5d, 0xe6480f66, 0xca847204, 0x4bdf1da0,
0x30cc2efb, 0x13e02dea, 0xfb49ac45, 0xf9d4434f, 0xf47c5b9c, 0x148879c2,
0x039fc234, 0xa3db9bfc, 0xd1a1dc5c, 0x763d7cd4, 0xed6d2f93, 0xab13af6e,
0x1e8e054a, 0xd68f4f9a, 0xc30484b3, 0xd7d50afa, 0x6930855f, 0xcc07db95,
0xce746db1, 0x744e967d, 0xf16cf575, 0x8643e8b5, 0xf0eae38e, 0xe52de1d1,
0x6587dae0, 0x0c4b8121, 0x1c7ac567, 0xac0db20a, 0x36c3a812, 0x5b1a4514,
0xa9a3f868, 0xb9263baa, 0xcb3ce9d2, 0xe44fb1a4, 0x9221bc82, 0xb29390fe,
0x6ab41863, 0x974a3e2e, 0x89f531c5, 0x255ca13e, 0x8b65d348, 0xec248f78,
0xd8fc16f0, 0x50ecdeee, 0x09010792, 0x3c7d1fb2, 0xeba5426b, 0x847b417a,
0x468b40d9, 0x8dc4e680, 0x7cc1f391, 0x2f1eb086, 0x6e5baa6a, 0xe0b395da,
0xe31b2cf6, 0xd9690b0d, 0x729ec464, 0x38403dde, 0x610b80a2, 0x5cf433ab,
0xb0785fc4, 0xd512e4c6, 0xbbb7d699, 0x5a86591b, 0x10cf5376, 0x12bf9f4b,
0x980fbaa1, 0x992a4e70, 0x20fa7ae7, 0xf7996ebb, 0xc918a2be, 0x82de74f2,
0xad54209b, 0xf66b4d74, 0x1fc5b771, 0x169d9229, 0x887761df, 0x00b667d5,
0xdb425e59, 0xb72f2844, 0x9b0ac1f5, 0x9c737e3a, 0x2b85476c, 0x6722add6,
0x44a63297, 0x0d688ced, 0xabc59484, 0x4107778a, 0x8ad94c6f, 0xfe83df90,
0x0f64053f, 0xd1292e9d, 0xc5744356, 0x8dd1abb4, 0x4c4e7667, 0xfb4a7fc1,
0x74f402cb, 0x70f06afd, 0xa82286f2, 0x918dd076, 0x7a97c5ce, 0x48f7bde3,
0x6a04d11d, 0xac243ef7, 0x33ac10ca, 0x2f7a341e, 0x5f75157a, 0xf4773381,
0x591c870e, 0x78df8cc8, 0x22f3adb0, 0x251a5993, 0x09fbef66, 0x796942a8,
0x97541d2e, 0x2373daa9, 0x1bd2f142, 0xb57e8eb2, 0xe1a5bfdb, 0x7d0efa92,
0xb3442c94, 0xd2cb6447, 0x386ac97e, 0x66d61805, 0xbdada15e, 0x11bc1aa7,
0x14e9f6ea, 0xe533a0c0, 0xf935ee0a, 0x8fee8a04, 0x810d6d85, 0x7c68b6d6,
0x4edc9aa2, 0x956e897d, 0xed87581a, 0x264be9d7, 0xff4ddb29, 0x823857c2,
0xe005a9a0, 0xf1cc2450, 0x6f9951e1, 0xaade2310, 0xe70c75f5, 0x83e1a31f,
0x4f7dde8e, 0xf723b563, 0x368e0928, 0x86362b71, 0x21e8982d, 0xdfb3f92b,
0x44676352, 0x99efba31, 0x2eab4e1c, 0xfc6ca5e7, 0x0ebe5d4e, 0xa0717d0c,
0xb64f8199, 0x946b31a1, 0x5656cbc6, 0xcffec3ef, 0x622766c9, 0xfa211e35,
0x52f98b89, 0x6d01674b, 0x4978a802, 0xf651f701, 0x15b0d43d, 0xd6ff4683,
0x3463855f, 0x672ba29c, 0xbc128312, 0x4626a70d, 0xc8927a5a, 0xb8481cf9,
0x1c962262, 0xa21196ba, 0xbaba5ee9, 0x5bb162d0, 0x69943bd1, 0x0c47e35c,
0x8cc9619a, 0xe284d948, 0x271bf264, 0xc27fb398, 0x4bc70897, 0x60cf202c,
0x7f42d6aa, 0xa5a13506, 0x5d3e8860, 0xcea63d3c, 0x63bf0a8f, 0xf02e9efa,
0xb17b0674, 0xb072b1d3, 0x06e5723b, 0x3737e436, 0x24aa49c7, 0x0ded0d18,
0xdb256b14, 0x58b27877, 0xecb49f54, 0x6c40256a, 0x6ea92ffb, 0x3906aa4c,
0xc9866fd5, 0x4549323e, 0xa7b85fab, 0x1918cc27, 0x7308d7b5, 0x1e16c7ad,
0x71850b37, 0x3095fd78, 0xa63b70e6, 0xd880e2ae, 0x3e282769, 0xa39ba6bc,
0x98700fa3, 0xf34c53e8, 0x288af426, 0xb99d930f, 0xf5b99df1, 0xe9d0c8cf,
0x5ac8405d, 0x50e7217b, 0x511fbbbe, 0x2ca2e639, 0xc020301b, 0x356dbc00,
0x8e43ddb9, 0x4d327b4a, 0xf20ff3ed, 0x1dbb29bd, 0x43d44779, 0xa1b68f70,
0x6114455b, 0xe63d280b, 0x6bf6ff65, 0x10fc39e5, 0x3dae126e, 0xc1d7cf11,
0xcb60b795, 0x1789d5b3, 0x9bca36b7, 0x08306075, 0x84615608, 0x8b3a0186,
0xe88fbecd, 0x7ba47c4d, 0x2de44dac, 0x653fe58d, 0xcca0b968, 0xd7fa0e72,
0x93901780, 0x1f2c26cc, 0xae595b6b, 0xa9ecea9b, 0xe3dbf8c4, 0x319cc130,
0x12981196, 0x01a3a4de, 0x32c454b6, 0x755bd817, 0x3cd871e4, 0xa48bb8da,
0x02fdec09, 0xfd2dc2e2, 0x9e578088, 0x9a9f916d, 0x4065fe6c, 0x1853999e,
0xc7793f23, 0xdc1016bb, 0x969355ff, 0x7ef292f6, 0xcdce4adc, 0x05e24416,
0x85c16c46, 0xd441d37f, 0x57bd6855, 0x8746f54f, 0x9ca773df, 0x770bae22,
0x54828413, 0xb75e4b19, 0x04c35c03, 0xbf7cca07, 0x2955c4dd, 0x721db041,
0xb2394f33, 0x03f51387, 0x89b73c9f, 0x0b1737f3, 0x07e69024, 0x9231d245,
0x76193861, 0x88159c15, 0xdeb552d9, 0xd9767e40, 0x20c6c0c3, 0x4281977c,
0xf8afe1e0, 0xd32a0751, 0x3fc27432, 0xddf1dcc5, 0x68581f34, 0x3bcd5025,
0x0091b2ee, 0x4aeb6944, 0x1602e743, 0xea09eb58, 0xef0a2a8b, 0x641e03a5,
0xeb50e021, 0x5c8ccef8, 0x802ff0b8, 0xd5e3edfe, 0xc4dd1b49, 0x5334cd2a,
0x13f82d2f, 0x47450c20, 0x55dafbd2, 0xbec0c6f4, 0xb45d7959, 0x3ad36e8c,
0x0aa8ac57, 0x1a3c8d73, 0xe45aafb1, 0x9f664838, 0xc6880053, 0xd0039bbf,
0xee5f19eb, 0xca0041d8, 0xbbea3aaf, 0xda628291, 0x9d5c95d4, 0xadd504a6,
0xc39ab482, 0x5e9e14a4, 0x2be065f0, 0x2a13fc3a, 0x9052e8ec, 0xaf6f5afc,
0x519aa8b5, 0xbb303da9, 0xe00e2b10, 0xdfa6c1db, 0x2e6b952e, 0xee10dc23,
0x37936d09, 0x1fc42e92, 0x39b25a9f, 0x13ff89f4, 0xc8f53fea, 0x18500bc7,
0x95a0379d, 0x98f751c2, 0x2289c42f, 0xa21e4098, 0x6f391f41, 0xf27e7e58,
0x0d0df887, 0x4b79d540, 0x8e8409aa, 0x71fe46f8, 0x688a9b29, 0x3f08b548,
0x84abe03a, 0x5e91b6c1, 0xfde4c2ae, 0x251d0e72, 0x92d4fee5, 0xf9371967,
0x9175108f, 0xe6e81835, 0x8c8cb8ee, 0xb55a67b3, 0xcef138cc, 0x8b256268,
0x00d815f5, 0xe8810812, 0x77826189, 0xea73267d, 0x19b90f8d, 0x45c33bb4,
0x82477056, 0xe1770075, 0x09467aa6, 0xa7c6f54a, 0x79768742, 0x61b86bca,
0xd6644a44, 0xe33f0171, 0xc229fbcd, 0x41b08feb, 0xd1903e30, 0x65ec9080,
0x563d6fbd, 0xf56da488, 0xebf64cd8, 0x4934426b, 0x7c8592fc, 0x6aca8cf2,
0x1cea111b, 0x3a57ee7a, 0xace11c0d, 0x9942d85e, 0xc4613407, 0xfa8e643b,
0x327fc701, 0x4ca9be82, 0x3352526d, 0x2c047f63, 0xf3a8f7dd, 0x1a4a98a8,
0x762ed4d1, 0x27c75008, 0xbdf497c0, 0x7a7b84df, 0x315c28ab, 0x801f93e3,
0xf19b0ca1, 0x8f14e46a, 0xe48ba333, 0x9605e625, 0xf03ecb60, 0x60385f2d,
0x902845ba, 0x7f96d66f, 0x24bff05c, 0x2820730b, 0x947133cb, 0xd444828a,
0xb343f6f1, 0x0bef4705, 0x8da574f9, 0x01e25d6c, 0x1732793e, 0x4f0f7b27,
0x364b7117, 0xb2d1da77, 0xa6c5f1e9, 0x574ca5b1, 0x386a3076, 0xad6894d6,
0x1156d7fa, 0xa48d1d9a, 0x4794c0af, 0x150c0aa0, 0x26d348ac, 0x29fdeabe,
0xa5dede53, 0x81671e8e, 0x594ee3bf, 0xa96c56e6, 0x3426a726, 0xc5976579,
0xbc22e5e4, 0xc1006319, 0xdaafdd2a, 0xa1a1aa83, 0x3badd0e7, 0xc3b14981,
0xd770b155, 0xccd7c693, 0x42e944c5, 0x03e0064f, 0xca95b4ef, 0x3dee81c3,
0xfbbcd98c, 0x1e07e15b, 0x667ce949, 0xe7d6773f, 0x21b6124b, 0x6b2a6ef7,
0xd3278a9c, 0x9a988304, 0x75d2ae9b, 0xfe49e2ff, 0x9bc24f46, 0x74cc2cf6,
0xa3139f36, 0x6c9ef35a, 0x9fc1dffe, 0x9e5facdc, 0xaadc8bbb, 0x5abdbc5f,
0x44b3b390, 0xf754efa7, 0x5fe3bdb7, 0x4e59c886, 0x06a4c984, 0xa0338878,
0xcd513cd7, 0x63ebd27e, 0x8aba80ad, 0x50da144e, 0x5d9f4e97, 0x025b751c,
0x2d580200, 0xb6c05837, 0x580aa15d, 0x54022a6e, 0xb41a5415, 0x4863fab6,
0xb0b79957, 0x46d0d159, 0xdc2b8650, 0x20a7bb0c, 0x4a032974, 0xec8636a2,
0x8548f24c, 0xf6a2bf16, 0x1088f4b0, 0x0c2f3a94, 0x525dc396, 0x14065785,
0x2b4dca52, 0x08aeed39, 0xabedfc99, 0xb1dbcf18, 0x87f85bbc, 0xae3aff61,
0x433ccd70, 0x5b23cc64, 0x7b453213, 0x5355c545, 0x9318ec0a, 0x78692d31,
0x0a21693d, 0xd5666814, 0x05fb59d9, 0xc71985b2, 0x2abb8e0e, 0xcf6e6c91,
0xd9cfe7c6, 0xefe7132c, 0x9711ab28, 0x3ce52732, 0x12d516d2, 0x7209a0d0,
0xd278d306, 0x70fa4b7b, 0x1d407dd3, 0xdb0beba4, 0xbfd97621, 0xa8be21e1,
0x1b6f1b66, 0x30650dda, 0xba7ddbb9, 0x7df953fb, 0x9d1c3902, 0xedf0e8d5,
0xb8741ae0, 0x0f240565, 0x62cd438b, 0xc616a924, 0xaf7a96a3, 0x35365538,
0xe583af4d, 0x73415eb8, 0x23176a47, 0xfc9ccee8, 0x7efc9de2, 0x695e03cf,
0xf8ce66d4, 0x88b4781d, 0x67dd9c03, 0x3e8f9e73, 0xc0c95c51, 0xbe314d22,
0x55aa0795, 0xcb1bb011, 0xe980fdc8, 0x9c62b7ce, 0xde2d239e, 0x042cadf3,
0xffdf04de, 0x5ce6a60f, 0xd8c831ed, 0xb7b5b9ec, 0xb9cbf962, 0xe253b254,
0x0735ba1f, 0x16ac917f, 0xdd607c2b, 0x64a335c4, 0x40159a7c, 0x869222f0,
0x6ef21769, 0x839d20a5, 0xd03b24c9, 0xf412601e, 0x6d72a243, 0x0e018dfd,
0x89f3721a, 0xc94f4134, 0x2f992f20, 0x4d87253c
};
/**
* Initialize algorithm context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_snefru128_init(struct snefru_ctx* ctx)
{
memset(ctx, 0, sizeof(snefru_ctx));
ctx->digest_length = snefru128_hash_length;
}
/**
* Initialize algorithm context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_snefru256_init(struct snefru_ctx* ctx)
{
memset(ctx, 0, sizeof(snefru_ctx));
ctx->digest_length = snefru256_hash_length;
}
/**
* Core transformation, processes given 256-bit or 384-bit block.
* The algoririthm is optimized for Intel Pentum.
*
* @param ctx algorithm context
* @param block the message block to process
*/
static void rhash_snefru_process_block(snefru_ctx* ctx, unsigned* block)
{
unsigned W[16];
unsigned rot;
const unsigned* sbox;
const unsigned* const sbox_end = rhash_snefru_sbox + 512 * SNEFRU_NUMBER_OF_ROUNDS;
unsigned* const hash = ctx->hash;
{
/* fill W[] array */
W[0] = ctx->hash[0], W[1] = ctx->hash[1];
W[2] = ctx->hash[2], W[3] = ctx->hash[3];
if (ctx->digest_length == snefru256_hash_length) {
W[4] = ctx->hash[4], W[5] = ctx->hash[5];
W[6] = ctx->hash[6], W[7] = ctx->hash[7];
} else {
W[4] = be2me_32(block[0]), W[5] = be2me_32(block[1]);
W[6] = be2me_32(block[2]), W[7] = be2me_32(block[3]);
block += 4;
}
W[ 8] = be2me_32(block[0]), W[ 9] = be2me_32(block[1]);
W[10] = be2me_32(block[2]), W[11] = be2me_32(block[3]);
W[12] = be2me_32(block[4]), W[13] = be2me_32(block[5]);
W[14] = be2me_32(block[6]), W[15] = be2me_32(block[7]);
}
/* do algorithm rounds using S-Box */
for (sbox = rhash_snefru_sbox; sbox < sbox_end; sbox += 512)
{
/* cycle 4 times */
for (rot = 0x18100810; rot; rot >>= 8)
{
unsigned x;
#define SNEFERU_UPDATE_W(i) \
x = sbox[(i << 7 & 0x100) + (W[i] & 0xff)]; \
W[(i - 1) & 0x0f] ^= x; \
if (i >= 2) W[(i - 1) & 0x0f] = \
ROTR32(W[(i - 1) & 0x0f], (unsigned char)rot); \
W[(i + 1) & 0x0f] ^= x;
SNEFERU_UPDATE_W(0);
SNEFERU_UPDATE_W(1);
SNEFERU_UPDATE_W(2);
SNEFERU_UPDATE_W(3);
SNEFERU_UPDATE_W(4);
SNEFERU_UPDATE_W(5);
SNEFERU_UPDATE_W(6);
SNEFERU_UPDATE_W(7);
SNEFERU_UPDATE_W(8);
SNEFERU_UPDATE_W(9);
SNEFERU_UPDATE_W(10);
SNEFERU_UPDATE_W(11);
SNEFERU_UPDATE_W(12);
SNEFERU_UPDATE_W(13);
SNEFERU_UPDATE_W(14);
SNEFERU_UPDATE_W(15);
W[( 0) & 0x0f] = ROTR32(W[( 0) & 0x0f], (unsigned char)rot);
W[(15) & 0x0f] = ROTR32(W[(15) & 0x0f], (unsigned char)rot);
}
}
/* store current hashing state */
hash[0] ^= W[15];
hash[1] ^= W[14];
hash[2] ^= W[13];
hash[3] ^= W[12];
if (ctx->digest_length == snefru256_hash_length) {
hash[4] ^= W[11];
hash[5] ^= W[10];
hash[6] ^= W[ 9];
hash[7] ^= W[ 8];
}
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_snefru_update(snefru_ctx* ctx, const unsigned char* msg, size_t size)
{
const unsigned data_block_size = 64 - ctx->digest_length;
ctx->length += size;
/* fill partial block */
if (ctx->index) {
unsigned left = data_block_size - ctx->index;
memcpy((char*)ctx->buffer + ctx->index, msg, (size < left ? size : left));
if (size < left) {
ctx->index += (unsigned)size;
return;
}
/* process partial block */
rhash_snefru_process_block(ctx, (unsigned*)ctx->buffer);
msg += left;
size -= left;
}
while (size >= data_block_size) {
unsigned* aligned_message_block;
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
/* the most common case is processing of an already aligned message
on a little-endian CPU without copying it */
aligned_message_block = (unsigned*)msg;
} else {
memcpy(ctx->buffer, msg, data_block_size);
aligned_message_block = (unsigned*)ctx->buffer;
}
rhash_snefru_process_block(ctx, aligned_message_block);
msg += data_block_size;
size -= data_block_size;
}
ctx->index = (unsigned)size;
if (size) {
/* save leftovers */
memcpy(ctx->buffer, msg, size);
}
}
/**
* Store calculated hash into the given array.
* Finalize the hash value calculation by appending the (padded) length field.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_snefru_final(snefru_ctx* ctx, unsigned char* result)
{
const unsigned digest_dw_len = ctx->digest_length / 4; /* length in dwords */
const unsigned data_block_size = 64 - ctx->digest_length;
assert(ctx->index == (unsigned)(ctx->length % data_block_size));
if (ctx->index) {
/* pad the last data block if partially filled */
memset((char*)ctx->buffer + ctx->index, 0, data_block_size - ctx->index);
rhash_snefru_process_block(ctx, (unsigned*)ctx->buffer);
}
memset(ctx->buffer, 0, data_block_size - 8);
((unsigned*)ctx->buffer)[14 - digest_dw_len] = be2me_32((unsigned)(ctx->length >> 29));
((unsigned*)ctx->buffer)[15 - digest_dw_len] = be2me_32((unsigned)(ctx->length << 3));
rhash_snefru_process_block(ctx, (unsigned*)ctx->buffer);
be32_copy(result, 0, ctx->hash, ctx->digest_length);
}
rhash-1.4.6/librhash/rhash_torrent.c 0000664 0000000 0000000 00000004632 14703622112 016154 0 ustar root root /* rhash_torrent.c - functions to make a torrent file.
*
* Copyright (c) 2013, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* modifier for Windows DLL */
#if (defined(_WIN32) || defined(__CYGWIN__) ) && defined(RHASH_EXPORTS)
# define RHASH_API __declspec(dllexport)
#endif
#include "rhash_torrent.h"
#include "algorithms.h"
#include "torrent.h"
#include
/* obtain torrent context from rhash context */
#define BT_CTX(rctx) ((torrent_ctx*)(((rhash_context_ext*)rctx)->bt_ctx))
RHASH_API int rhash_torrent_add_file(rhash ctx, const char* filepath, unsigned long long filesize)
{
if (!BT_CTX(ctx)) return 0;
return bt_add_file(BT_CTX(ctx), filepath, filesize);
}
RHASH_API void rhash_torrent_set_options(rhash ctx, unsigned options)
{
if (!BT_CTX(ctx)) return;
bt_set_options(BT_CTX(ctx), options);
}
RHASH_API int rhash_torrent_add_announce(rhash ctx, const char* announce_url)
{
if (!BT_CTX(ctx)) return 0;
return bt_add_announce(BT_CTX(ctx), announce_url);
}
RHASH_API int rhash_torrent_set_program_name(rhash ctx, const char* name)
{
if (!BT_CTX(ctx)) return 0;
return bt_set_program_name(BT_CTX(ctx), name);
}
RHASH_API void rhash_torrent_set_piece_length(rhash ctx, size_t piece_length)
{
if (!BT_CTX(ctx)) return;
bt_set_piece_length(BT_CTX(ctx), piece_length);
}
RHASH_API size_t rhash_torrent_get_default_piece_length(unsigned long long total_size)
{
return bt_default_piece_length(total_size, 0);
}
RHASH_API void rhash_torrent_set_batch_size(rhash ctx, unsigned long long total_size)
{
if (!BT_CTX(ctx)) return;
bt_set_total_batch_size(BT_CTX(ctx), total_size);
}
RHASH_API const rhash_str* rhash_torrent_generate_content(rhash ctx)
{
torrent_ctx* tc = BT_CTX(ctx);
if (!tc || tc->error || !tc->content.str) return 0;
return (rhash_str*)(&tc->content);
}
rhash-1.4.6/librhash/has160.c 0000664 0000000 0000000 00000020341 14703622112 014267 0 ustar root root /* hash.c - an implementation of HAS-160 Algorithm.
*
* Copyright (c) 2009, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* HAS-160 is a cryptographic hash function designed for use with the
* Korean KCDSA digital signature algorithm. It derives from SHA-1,
* with assorted changes intended to increase its security.
* It produces a 160-bit message digest.
*
* HAS-160 was developed in 1998 by KISA
* (Korea Information Security Agency) + Academic.
*/
#include
#include "byte_order.h"
#include "has160.h"
/**
* Initialize algorithm context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_has160_init(has160_ctx* ctx)
{
memset(ctx, 0, sizeof(*ctx));
/* initialize algorithm state */
ctx->hash[0] = 0x67452301;
ctx->hash[1] = 0xefcdab89;
ctx->hash[2] = 0x98badcfe;
ctx->hash[3] = 0x10325476;
ctx->hash[4] = 0xc3d2e1f0;
}
/* HAS-160 boolean functions:
* F1(x,y,z) == (x AND y) OR ((NOT x) AND z) = ((y XOR z) AND x) XOR z
* F2(x,y,z) == x XOR y XOR z
* F3(x,y,z) == y XOR (x OR (NOT Z))
* F4(x,y,z) == x XOR y XOR z */
#define STEP_F1(A, B, C, D, E, msg, rot) \
E += ROTL32(A, rot) + (D ^ (B & (C ^ D))) + msg; \
B = ROTL32(B, 10);
#define STEP_F2(A, B, C, D, E, msg, rot) \
E += ROTL32(A, rot) + (B ^ C ^ D) + msg + 0x5A827999; \
B = ROTL32(B, 17);
#define STEP_F3(A, B, C, D, E, msg, rot) \
E += ROTL32(A, rot) + (C ^ (B | ~D)) + msg + 0x6ED9EBA1; \
B = ROTL32(B, 25);
#define STEP_F4(A, B, C, D, E, msg, rot) \
E += ROTL32(A, rot) + (B ^ C ^ D) + msg + 0x8F1BBCDC; \
B = ROTL32(B, 30);
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_has160_process_block(unsigned* hash, const unsigned* block)
{
unsigned X[32];
{
unsigned j;
for (j = 0; j < 16; j++) {
X[j] = le2me_32(block[j]);
}
X[16] = X[ 0] ^ X[ 1] ^ X[ 2] ^ X[ 3]; /* for rounds 1..20 */
X[17] = X[ 4] ^ X[ 5] ^ X[ 6] ^ X[ 7];
X[18] = X[ 8] ^ X[ 9] ^ X[10] ^ X[11];
X[19] = X[12] ^ X[13] ^ X[14] ^ X[15];
X[20] = X[ 3] ^ X[ 6] ^ X[ 9] ^ X[12]; /* for rounds 21..40 */
X[21] = X[ 2] ^ X[ 5] ^ X[ 8] ^ X[15];
X[22] = X[ 1] ^ X[ 4] ^ X[11] ^ X[14];
X[23] = X[ 0] ^ X[ 7] ^ X[10] ^ X[13];
X[24] = X[ 5] ^ X[ 7] ^ X[12] ^ X[14]; /* for rounds 41..60 */
X[25] = X[ 0] ^ X[ 2] ^ X[ 9] ^ X[11];
X[26] = X[ 4] ^ X[ 6] ^ X[13] ^ X[15];
X[27] = X[ 1] ^ X[ 3] ^ X[ 8] ^ X[10];
X[28] = X[ 2] ^ X[ 7] ^ X[ 8] ^ X[13]; /* for rounds 61..80 */
X[29] = X[ 3] ^ X[ 4] ^ X[ 9] ^ X[14];
X[30] = X[ 0] ^ X[ 5] ^ X[10] ^ X[15];
X[31] = X[ 1] ^ X[ 6] ^ X[11] ^ X[12];
}
{
unsigned A, B, C, D, E;
A = hash[0];
B = hash[1];
C = hash[2];
D = hash[3];
E = hash[4];
STEP_F1(A,B,C,D,E,X[18], 5);
STEP_F1(E,A,B,C,D,X[ 0],11);
STEP_F1(D,E,A,B,C,X[ 1], 7);
STEP_F1(C,D,E,A,B,X[ 2],15);
STEP_F1(B,C,D,E,A,X[ 3], 6);
STEP_F1(A,B,C,D,E,X[19],13);
STEP_F1(E,A,B,C,D,X[ 4], 8);
STEP_F1(D,E,A,B,C,X[ 5],14);
STEP_F1(C,D,E,A,B,X[ 6], 7);
STEP_F1(B,C,D,E,A,X[ 7],12);
STEP_F1(A,B,C,D,E,X[16], 9);
STEP_F1(E,A,B,C,D,X[ 8],11);
STEP_F1(D,E,A,B,C,X[ 9], 8);
STEP_F1(C,D,E,A,B,X[10],15);
STEP_F1(B,C,D,E,A,X[11], 6);
STEP_F1(A,B,C,D,E,X[17],12);
STEP_F1(E,A,B,C,D,X[12], 9);
STEP_F1(D,E,A,B,C,X[13],14);
STEP_F1(C,D,E,A,B,X[14], 5);
STEP_F1(B,C,D,E,A,X[15],13);
STEP_F2(A,B,C,D,E,X[22], 5);
STEP_F2(E,A,B,C,D,X[ 3],11);
STEP_F2(D,E,A,B,C,X[ 6], 7);
STEP_F2(C,D,E,A,B,X[ 9],15);
STEP_F2(B,C,D,E,A,X[12], 6);
STEP_F2(A,B,C,D,E,X[23],13);
STEP_F2(E,A,B,C,D,X[15], 8);
STEP_F2(D,E,A,B,C,X[ 2],14);
STEP_F2(C,D,E,A,B,X[ 5], 7);
STEP_F2(B,C,D,E,A,X[ 8],12);
STEP_F2(A,B,C,D,E,X[20], 9);
STEP_F2(E,A,B,C,D,X[11],11);
STEP_F2(D,E,A,B,C,X[14], 8);
STEP_F2(C,D,E,A,B,X[ 1],15);
STEP_F2(B,C,D,E,A,X[ 4], 6);
STEP_F2(A,B,C,D,E,X[21],12);
STEP_F2(E,A,B,C,D,X[ 7], 9);
STEP_F2(D,E,A,B,C,X[10],14);
STEP_F2(C,D,E,A,B,X[13], 5);
STEP_F2(B,C,D,E,A,X[ 0],13);
STEP_F3(A,B,C,D,E,X[26], 5);
STEP_F3(E,A,B,C,D,X[12],11);
STEP_F3(D,E,A,B,C,X[ 5], 7);
STEP_F3(C,D,E,A,B,X[14],15);
STEP_F3(B,C,D,E,A,X[ 7], 6);
STEP_F3(A,B,C,D,E,X[27],13);
STEP_F3(E,A,B,C,D,X[ 0], 8);
STEP_F3(D,E,A,B,C,X[ 9],14);
STEP_F3(C,D,E,A,B,X[ 2], 7);
STEP_F3(B,C,D,E,A,X[11],12);
STEP_F3(A,B,C,D,E,X[24], 9);
STEP_F3(E,A,B,C,D,X[ 4],11);
STEP_F3(D,E,A,B,C,X[13], 8);
STEP_F3(C,D,E,A,B,X[ 6],15);
STEP_F3(B,C,D,E,A,X[15], 6);
STEP_F3(A,B,C,D,E,X[25],12);
STEP_F3(E,A,B,C,D,X[ 8], 9);
STEP_F3(D,E,A,B,C,X[ 1],14);
STEP_F3(C,D,E,A,B,X[10], 5);
STEP_F3(B,C,D,E,A,X[ 3],13);
STEP_F4(A,B,C,D,E,X[30], 5);
STEP_F4(E,A,B,C,D,X[ 7],11);
STEP_F4(D,E,A,B,C,X[ 2], 7);
STEP_F4(C,D,E,A,B,X[13],15);
STEP_F4(B,C,D,E,A,X[ 8], 6);
STEP_F4(A,B,C,D,E,X[31],13);
STEP_F4(E,A,B,C,D,X[ 3], 8);
STEP_F4(D,E,A,B,C,X[14],14);
STEP_F4(C,D,E,A,B,X[ 9], 7);
STEP_F4(B,C,D,E,A,X[ 4],12);
STEP_F4(A,B,C,D,E,X[28], 9);
STEP_F4(E,A,B,C,D,X[15],11);
STEP_F4(D,E,A,B,C,X[10], 8);
STEP_F4(C,D,E,A,B,X[ 5],15);
STEP_F4(B,C,D,E,A,X[ 0], 6);
STEP_F4(A,B,C,D,E,X[29],12);
STEP_F4(E,A,B,C,D,X[11], 9);
STEP_F4(D,E,A,B,C,X[ 6],14);
STEP_F4(C,D,E,A,B,X[ 1], 5);
STEP_F4(B,C,D,E,A,X[12],13);
hash[0] += A;
hash[1] += B;
hash[2] += C;
hash[3] += D;
hash[4] += E;
}
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_has160_update(has160_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
unsigned left = has160_block_size - index;
memcpy((char*)ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_has160_process_block(ctx->hash, ctx->message);
msg += left;
size -= left;
}
while (size >= has160_block_size) {
unsigned* aligned_message_block;
if (IS_ALIGNED_32(msg)) {
/* the most common case is processing a 32-bit aligned message
without copying it */
aligned_message_block = (unsigned*)msg;
} else {
memcpy(ctx->message, msg, has160_block_size);
aligned_message_block = ctx->message;
}
rhash_has160_process_block(ctx->hash, aligned_message_block);
msg += has160_block_size;
size -= has160_block_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Compute and save calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_has160_final(has160_ctx* ctx, unsigned char* result)
{
unsigned shift = ((unsigned)ctx->length & 3) * 8;
unsigned index = ((unsigned)ctx->length & 63) >> 2;
/* pad message and run for last block */
#if IS_LITTLE_ENDIAN
ctx->message[index] &= ~(0xFFFFFFFFu << shift);
ctx->message[index++] ^= 0x80u << shift;
#else
ctx->message[index] &= ~(0xFFFFFFFFu >> shift);
ctx->message[index++] ^= 0x80000000u >> shift;
#endif
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
ctx->message[index++] = 0;
}
rhash_has160_process_block(ctx->hash, ctx->message);
index = 0;
}
while (index < 14) {
ctx->message[index++] = 0;
}
ctx->message[14] = le2me_32( (unsigned)(ctx->length << 3) );
ctx->message[15] = le2me_32( (unsigned)(ctx->length >> 29) );
rhash_has160_process_block(ctx->hash, ctx->message);
le32_copy(result, 0, &ctx->hash, has160_hash_size);
}
rhash-1.4.6/librhash/hex.c 0000664 0000000 0000000 00000014401 14703622112 014051 0 ustar root root /* hex.c - conversion for hexadecimal and base32 strings.
*
* Copyright (c) 2008, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "hex.h"
#include "util.h"
#include
#include
/**
* Store hexadecimal representation of a binary string to given buffer.
*
* @param dst the buffer to receive hexadecimal representation
* @param src binary string
* @param length string length
* @param upper_case flag to print string in uppercase
*/
void rhash_byte_to_hex(char* dst, const unsigned char* src, size_t length, int upper_case)
{
const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10);
for (; length > 0; src++, length--) {
const unsigned char hi = (*src >> 4) & 15;
const unsigned char lo = *src & 15;
*dst++ = (hi > 9 ? hi + hex_add : hi + '0');
*dst++ = (lo > 9 ? lo + hex_add : lo + '0');
}
*dst = '\0';
}
/**
* Encode a binary string to base32.
*
* @param dst the buffer to store result
* @param src binary string
* @param length string length
* @param upper_case flag to print string in uppercase
*/
void rhash_byte_to_base32(char* dst, const unsigned char* src, size_t length, int upper_case)
{
const char a = (upper_case ? 'A' : 'a');
unsigned shift = 0;
unsigned char word;
const unsigned char* e = src + length;
while (src < e) {
if (shift > 3) {
word = (*src & (0xFF >> shift));
shift = (shift + 5) % 8;
word <<= shift;
if (src + 1 < e)
word |= *(src + 1) >> (8 - shift);
++src;
} else {
shift = (shift + 5) % 8;
word = ( *src >> ( (8 - shift) & 7 ) ) & 0x1F;
if (shift == 0) src++;
}
*dst++ = ( word < 26 ? word + a : word + '2' - 26 );
}
*dst = '\0';
}
/**
* Encode a binary string to base64.
* Encoded output length is always a multiple of 4 bytes.
*
* @param dst the buffer to store result
* @param src binary string
* @param length string length
*/
void rhash_byte_to_base64(char* dst, const unsigned char* src, size_t length)
{
static const char* tail = "0123456789+/";
unsigned shift = 0;
unsigned char word;
const unsigned char* e = src + length;
while (src < e) {
if (shift > 2) {
word = (*src & (0xFF >> shift));
shift = (shift + 6) % 8;
word <<= shift;
if (src + 1 < e)
word |= *(src + 1) >> (8 - shift);
++src;
} else {
shift = (shift + 6) % 8;
word = ( *src >> ( (8 - shift) & 7 ) ) & 0x3F;
if (shift == 0) src++;
}
*dst++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]);
}
if (shift > 0) {
*dst++ = '=';
if (shift == 4) *dst++ = '=';
}
*dst = '\0';
}
size_t rhash_base64_url_encoded_helper(char* dst, const unsigned char* src, size_t length, int url_encode, int upper_case)
{
#define B64_CHUNK_SIZE 120
char buffer[164];
RHASH_ASSERT((BASE64_LENGTH(B64_CHUNK_SIZE) + 4) <= sizeof(buffer));
RHASH_ASSERT((B64_CHUNK_SIZE % 6) == 0);
#ifdef __clang_analyzer__
memset(buffer, 0, sizeof(buffer));
#endif
if (url_encode) {
size_t result_length = 0;
for (; length > 0; src += B64_CHUNK_SIZE) {
size_t chunk_size = (length < B64_CHUNK_SIZE ? length : B64_CHUNK_SIZE);
size_t encoded_length;
rhash_byte_to_base64(buffer, src, chunk_size);
encoded_length = rhash_urlencode(dst, buffer, BASE64_LENGTH(chunk_size), upper_case);
result_length += encoded_length;
dst += encoded_length;
length -= chunk_size;
}
return result_length;
}
rhash_byte_to_base64(dst, src, length);
return BASE64_LENGTH(length);
}
/* RFC 3986: safe url characters are ascii alpha-numeric and "-._~", other characters should be percent-encoded */
static unsigned url_safe_char_mask[4] = { 0, 0x03ff6000, 0x87fffffe, 0x47fffffe };
#define IS_URL_GOOD_CHAR(c) ((unsigned)(c) < 128 && (url_safe_char_mask[c >> 5] & (1 << (c & 31))))
/**
* URL-encode specified binary string.
*
* @param dst (nullable) buffer to output encoded string to,
* NULL to just calculate the lengths of encoded string
* @param src binary string to encode
* @param size size of the binary string
* @param upper_case flag to output hex-codes in uppercase
* @return the length of the result string
*/
size_t rhash_urlencode(char* dst, const char* src, size_t size, int upper_case)
{
const char* start;
size_t i;
if (!dst) {
size_t length = size;
for (i = 0; i < size; i++)
if (!IS_URL_GOOD_CHAR(src[i]))
length += 2;
return length;
} else {
const char hex_add = (upper_case ? 'A' - 10 : 'a' - 10);
start = dst;
/* percent-encode all but unreserved URL characters */
for (i = 0; i < size; i++) {
if (IS_URL_GOOD_CHAR(src[i])) {
*dst++ = src[i];
} else {
unsigned char hi = ((unsigned char)(src[i]) >> 4) & 0x0f;
unsigned char lo = (unsigned char)(src[i]) & 0x0f;
*dst++ = '%';
*dst++ = (hi > 9 ? hi + hex_add : hi + '0');
*dst++ = (lo > 9 ? lo + hex_add : lo + '0');
}
}
*dst = 0;
}
return dst - start;
}
/**
* Print 64-bit number with trailing '\0' to a string buffer.
* if dst is NULL, then just return the length of the number.
*
* @param dst output buffer
* @param number the number to print
* @return length of the printed number (without trailing '\0')
*/
int rhash_sprintI64(char* dst, uint64_t number)
{
/* The biggest number has 20 digits: 2^64 = 18 446 744 073 709 551 616 */
char buf[24];
char* p;
size_t length;
if (dst == NULL) {
/* just calculate the length of the number */
if (number == 0) return 1;
for (length = 0; number != 0; number /= 10) length++;
return (int)length;
}
p = buf + 23;
*p = '\0'; /* last symbol should be '\0' */
if (number == 0) {
*(--p) = '0';
} else {
for (; p >= buf && number != 0; number /= 10) {
*(--p) = '0' + (char)(number % 10);
}
}
length = buf + 23 - p;
memcpy(dst, p, length + 1);
return (int)length;
}
rhash-1.4.6/librhash/algorithms.c 0000664 0000000 0000000 00000041364 15010476501 015447 0 ustar root root /* algorithms.c - the algorithms supported by the rhash library
*
* Copyright (c) 2011, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "algorithms.h"
#include "byte_order.h"
#include "rhash.h"
#include "util.h"
/* header files of all supported hash functions */
#include "aich.h"
#include "blake2b.h"
#include "blake2s.h"
#include "blake3.h"
#include "crc32.h"
#include "ed2k.h"
#include "edonr.h"
#include "gost12.h"
#include "gost94.h"
#include "has160.h"
#include "md4.h"
#include "md5.h"
#include "ripemd-160.h"
#include "snefru.h"
#include "sha_ni.h"
#include "sha1.h"
#include "sha256.h"
#include "sha512.h"
#include "sha3.h"
#include "tiger.h"
#include "torrent.h"
#include "tth.h"
#include "whirlpool.h"
#ifdef USE_OPENSSL
# include "plug_openssl.h"
#endif /* USE_OPENSSL */
#include
static unsigned algorithms_initialized_flag = 0;
rhash_hash_info* rhash_info_table = rhash_hash_info_default;
int rhash_info_size = RHASH_HASH_COUNT;
static void rhash_crc32_init(uint32_t* crc32);
static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size);
static void rhash_crc32_final(uint32_t* crc32, unsigned char* result);
static void rhash_crc32c_init(uint32_t* crc32);
static void rhash_crc32c_update(uint32_t* crc32, const unsigned char* msg, size_t size);
static void rhash_crc32c_final(uint32_t* crc32, unsigned char* result);
rhash_info info_crc32 = { EXTENDED_HASH_ID(0), F_BE32, 4, "CRC32", "crc32" };
rhash_info info_crc32c = { EXTENDED_HASH_ID(26), F_BE32, 4, "CRC32C", "crc32c" };
rhash_info info_md4 = { EXTENDED_HASH_ID(1), F_LE32, 16, "MD4", "md4" };
rhash_info info_md5 = { EXTENDED_HASH_ID(2), F_LE32, 16, "MD5", "md5" };
rhash_info info_sha1 = { EXTENDED_HASH_ID(3), F_BE32, 20, "SHA1", "sha1" };
rhash_info info_tiger = { EXTENDED_HASH_ID(4), F_LE64, 24, "TIGER", "tiger" };
rhash_info info_tth = { EXTENDED_HASH_ID(5), F_BS32 | F_SPCEXP, 24, "TTH", "tree:tiger" };
rhash_info info_btih = { EXTENDED_HASH_ID(6), F_SPCEXP, 20, "BTIH", "btih" };
rhash_info info_ed2k = { EXTENDED_HASH_ID(7), F_LE32, 16, "ED2K", "ed2k" };
rhash_info info_aich = { EXTENDED_HASH_ID(8), F_BS32 | F_SPCEXP, 20, "AICH", "aich" };
rhash_info info_whirlpool = { EXTENDED_HASH_ID(9), F_BE64, 64, "WHIRLPOOL", "whirlpool" };
rhash_info info_rmd160 = { EXTENDED_HASH_ID(10), F_LE32, 20, "RIPEMD-160", "ripemd160" };
rhash_info info_gost94 = { EXTENDED_HASH_ID(11), F_LE32, 32, "GOST94", "gost94" };
rhash_info info_gost94pro = { EXTENDED_HASH_ID(12), F_LE32, 32, "GOST94-CRYPTOPRO", "gost94-cryptopro" };
rhash_info info_has160 = { EXTENDED_HASH_ID(13), F_LE32, 20, "HAS-160", "has160" };
rhash_info info_gost12_256 = { EXTENDED_HASH_ID(14), F_LE64, 32, "GOST12-256", "gost12-256" };
rhash_info info_gost12_512 = { EXTENDED_HASH_ID(15), F_LE64, 64, "GOST12-512", "gost12-512" };
rhash_info info_sha224 = { EXTENDED_HASH_ID(16), F_BE32, 28, "SHA-224", "sha224" };
rhash_info info_sha256 = { EXTENDED_HASH_ID(17), F_BE32, 32, "SHA-256", "sha256" };
rhash_info info_sha384 = { EXTENDED_HASH_ID(18), F_BE64, 48, "SHA-384", "sha384" };
rhash_info info_sha512 = { EXTENDED_HASH_ID(19), F_BE64, 64, "SHA-512", "sha512" };
rhash_info info_edr256 = { EXTENDED_HASH_ID(20), F_LE32, 32, "EDON-R256", "edon-r256" };
rhash_info info_edr512 = { EXTENDED_HASH_ID(21), F_LE64, 64, "EDON-R512", "edon-r512" };
rhash_info info_sha3_224 = { EXTENDED_HASH_ID(22), F_LE64, 28, "SHA3-224", "sha3-224" };
rhash_info info_sha3_256 = { EXTENDED_HASH_ID(23), F_LE64, 32, "SHA3-256", "sha3-256" };
rhash_info info_sha3_384 = { EXTENDED_HASH_ID(24), F_LE64, 48, "SHA3-384", "sha3-384" };
rhash_info info_sha3_512 = { EXTENDED_HASH_ID(25), F_LE64, 64, "SHA3-512", "sha3-512" };
rhash_info info_snf128 = { EXTENDED_HASH_ID(27), F_BE32, 16, "SNEFRU-128", "snefru128" };
rhash_info info_snf256 = { EXTENDED_HASH_ID(28), F_BE32, 32, "SNEFRU-256", "snefru256" };
rhash_info info_blake2s = { EXTENDED_HASH_ID(29), F_LE32, 32, "BLAKE2S", "blake2s" };
rhash_info info_blake2b = { EXTENDED_HASH_ID(30), F_LE64, 64, "BLAKE2B", "blake2b" };
rhash_info info_blake3 = { EXTENDED_HASH_ID(31), F_LE32 | F_SPCEXP, 32, "BLAKE3", "blake3" };
/* some helper macros */
#define dgshft(name) ((uintptr_t)((char*)&((name##_ctx*)0)->hash))
#define dgshft2(name, field) ((uintptr_t)((char*)&((name##_ctx*)0)->field))
#define ini(name) ((pinit_t)(name##_init))
#define upd(name) ((pupdate_t)(name##_update))
#define fin(name) ((pfinal_t)(name##_final))
#define iuf(name) ini(name), upd(name), fin(name)
#define iuf2(name1, name2) ini(name1), upd(name2), fin(name2)
/* information about all supported hash functions */
rhash_hash_info rhash_hash_info_default[] =
{
{ &info_crc32, sizeof(uint32_t), 0, iuf(rhash_crc32), 0 }, /* 32 bit */
{ &info_md4, sizeof(md4_ctx), dgshft(md4), iuf(rhash_md4), 0 }, /* 128 bit */
{ &info_md5, sizeof(md5_ctx), dgshft(md5), iuf(rhash_md5), 0 }, /* 128 bit */
{ &info_sha1, sizeof(sha1_ctx), dgshft(sha1), iuf(rhash_sha1), 0 }, /* 160 bit */
{ &info_tiger, sizeof(tiger_ctx), dgshft(tiger), iuf(rhash_tiger), 0 }, /* 192 bit */
{ &info_tth, sizeof(tth_ctx), dgshft2(tth, tiger.hash), iuf(rhash_tth), 0 }, /* 192 bit */
{ &info_btih, sizeof(torrent_ctx), dgshft2(torrent, btih), iuf(bt), (pcleanup_t)bt_cleanup }, /* 160 bit */
{ &info_ed2k, sizeof(ed2k_ctx), dgshft2(ed2k, md4_context_inner.hash), iuf(rhash_ed2k), 0 }, /* 128 bit */
{ &info_aich, sizeof(aich_ctx), dgshft2(aich, sha1_context.hash), iuf(rhash_aich), (pcleanup_t)rhash_aich_cleanup }, /* 160 bit */
{ &info_whirlpool, sizeof(whirlpool_ctx), dgshft(whirlpool), iuf(rhash_whirlpool), 0 }, /* 512 bit */
{ &info_rmd160, sizeof(ripemd160_ctx), dgshft(ripemd160), iuf(rhash_ripemd160), 0 }, /* 160 bit */
{ &info_gost94, sizeof(gost94_ctx), dgshft(gost94), iuf(rhash_gost94), 0 }, /* 256 bit */
{ &info_gost94pro, sizeof(gost94_ctx), dgshft(gost94), iuf2(rhash_gost94_cryptopro, rhash_gost94), 0 }, /* 256 bit */
{ &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */
{ &info_gost12_256, sizeof(gost12_ctx), dgshft2(gost12, h) + 32, iuf2(rhash_gost12_256, rhash_gost12), 0 }, /* 256 bit */
{ &info_gost12_512, sizeof(gost12_ctx), dgshft2(gost12, h), iuf2(rhash_gost12_512, rhash_gost12), 0 }, /* 512 bit */
{ &info_sha224, sizeof(sha256_ctx), dgshft(sha256), iuf2(rhash_sha224, rhash_sha256), 0 }, /* 224 bit */
{ &info_sha256, sizeof(sha256_ctx), dgshft(sha256), iuf(rhash_sha256), 0 }, /* 256 bit */
{ &info_sha384, sizeof(sha512_ctx), dgshft(sha512), iuf2(rhash_sha384, rhash_sha512), 0 }, /* 384 bit */
{ &info_sha512, sizeof(sha512_ctx), dgshft(sha512), iuf(rhash_sha512), 0 }, /* 512 bit */
{ &info_edr256, sizeof(edonr_ctx), dgshft2(edonr, u.data256.hash) + 32, iuf(rhash_edonr256), 0 }, /* 256 bit */
{ &info_edr512, sizeof(edonr_ctx), dgshft2(edonr, u.data512.hash) + 64, iuf(rhash_edonr512), 0 }, /* 512 bit */
{ &info_sha3_224, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_224, rhash_sha3), 0 }, /* 224 bit */
{ &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_256, rhash_sha3), 0 }, /* 256 bit */
{ &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_384, rhash_sha3), 0 }, /* 384 bit */
{ &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), iuf2(rhash_sha3_512, rhash_sha3), 0 }, /* 512 bit */
{ &info_crc32c, sizeof(uint32_t), 0, iuf(rhash_crc32c), 0 }, /* 32 bit */
{ &info_snf128, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru128, rhash_snefru), 0 }, /* 128 bit */
{ &info_snf256, sizeof(snefru_ctx), dgshft(snefru), iuf2(rhash_snefru256, rhash_snefru), 0 }, /* 256 bit */
{ &info_blake2s, sizeof(blake2s_ctx), dgshft(blake2s), iuf(rhash_blake2s), 0 }, /* 256 bit */
{ &info_blake2b, sizeof(blake2b_ctx), dgshft(blake2b), iuf(rhash_blake2b), 0 }, /* 512 bit */
{ &info_blake3, sizeof(blake3_ctx), dgshft2(blake3, root.hash), iuf(rhash_blake3), 0 } /* 256 bit */
};
#if defined(RHASH_SSE4_SHANI) && !defined(RHASH_DISABLE_SHANI)
static void table_init_sha_ext(void)
{
if (has_cpu_feature(CPU_FEATURE_SHANI))
{
assert(rhash_hash_info_default[3].init == (pinit_t)rhash_sha1_init);
rhash_hash_info_default[3].update = (pupdate_t)rhash_sha1_ni_update;
rhash_hash_info_default[3].final = (pfinal_t)rhash_sha1_ni_final;
assert(rhash_hash_info_default[16].init == (pinit_t)rhash_sha224_init);
rhash_hash_info_default[16].update = (pupdate_t)rhash_sha256_ni_update;
rhash_hash_info_default[16].final = (pfinal_t)rhash_sha256_ni_final;
assert(rhash_hash_info_default[17].init == (pinit_t)rhash_sha256_init);
rhash_hash_info_default[17].update = (pupdate_t)rhash_sha256_ni_update;
rhash_hash_info_default[17].final = (pfinal_t)rhash_sha256_ni_final;
}
}
#else
# define table_init_sha_ext() {}
#endif
/**
* Initialize requested algorithms.
*/
void rhash_init_algorithms(void)
{
if (algorithms_initialized_flag)
return;
/* check RHASH_HASH_COUNT */
RHASH_ASSERT((RHASH_LOW_HASHES_MASK >> RHASH_HASH_COUNT) == 0);
RHASH_ASSERT(RHASH_COUNTOF(rhash_hash_info_default) == RHASH_HASH_COUNT);
#ifdef GENERATE_GOST94_LOOKUP_TABLE
rhash_gost94_init_table();
#endif
table_init_sha_ext();
atomic_compare_and_swap(&algorithms_initialized_flag, 0, 1);
}
/**
* Returns information about a hash function by its hash_id.
*
* @param hash_id the id of hash algorithm
* @return pointer to the rhash_info structure containing the information
*/
const rhash_hash_info* rhash_hash_info_by_id(unsigned hash_id)
{
unsigned index;
if (IS_EXTENDED_HASH_ID(hash_id)) {
index = hash_id & ~RHASH_EXTENDED_BIT;
if (index >= RHASH_HASH_COUNT)
return NULL;
} else {
hash_id &= RHASH_LOW_HASHES_MASK;
/* check that one and only one bit is set */
if (!hash_id || (hash_id & (hash_id - 1)) != 0)
return NULL;
index = rhash_ctz(hash_id);
}
return &rhash_info_table[index];
}
/**
* Return array of hash identifiers of supported hash functions.
* If the all_id is different from RHASH_ALL_HASHES,
* then return hash identifiers of legacy hash functions
* to support old library clients.
*
* @param all_id constant used to get all hash identifiers
* @param count pointer to store the number of returned ids to
* @return array of hash identifiers
*/
const unsigned* rhash_get_all_hash_ids(unsigned all_id, size_t* count)
{
static const unsigned all_ids[] = {
EXTENDED_HASH_ID(0), EXTENDED_HASH_ID(1), EXTENDED_HASH_ID(2), EXTENDED_HASH_ID(3),
EXTENDED_HASH_ID(4), EXTENDED_HASH_ID(5), EXTENDED_HASH_ID(6), EXTENDED_HASH_ID(7),
EXTENDED_HASH_ID(8), EXTENDED_HASH_ID(9), EXTENDED_HASH_ID(10), EXTENDED_HASH_ID(11),
EXTENDED_HASH_ID(12), EXTENDED_HASH_ID(13), EXTENDED_HASH_ID(14), EXTENDED_HASH_ID(15),
EXTENDED_HASH_ID(16), EXTENDED_HASH_ID(17), EXTENDED_HASH_ID(18), EXTENDED_HASH_ID(19),
EXTENDED_HASH_ID(20), EXTENDED_HASH_ID(21), EXTENDED_HASH_ID(22), EXTENDED_HASH_ID(23),
EXTENDED_HASH_ID(24), EXTENDED_HASH_ID(25), EXTENDED_HASH_ID(26), EXTENDED_HASH_ID(27),
EXTENDED_HASH_ID(28), EXTENDED_HASH_ID(29), EXTENDED_HASH_ID(30), EXTENDED_HASH_ID(31)
};
#if defined(rhash_popcount)
static const unsigned count_low = rhash_popcount(RHASH_LOW_HASHES_MASK);
#else
RHASH_ASSERT(RHASH_LOW_HASHES_MASK == 0x7fffffff);
static const unsigned count_low = 31; /* popcount(RHASH_LOW_HASHES_MASK) */
#endif
RHASH_ASSERT(RHASH_COUNTOF(all_ids) == RHASH_HASH_COUNT);
*count = (all_id == RHASH_ALL_HASHES ? RHASH_HASH_COUNT : count_low);
return all_ids;
}
/* CRC32 helper functions */
/**
* Initialize crc32 hash.
*
* @param crc32 pointer to the hash to initialize
*/
static void rhash_crc32_init(uint32_t* crc32)
{
*crc32 = 0; /* note: context size is sizeof(uint32_t) */
}
/**
* Calculate message CRC32 hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param crc32 pointer to the hash
* @param msg message chunk
* @param size length of the message chunk
*/
static void rhash_crc32_update(uint32_t* crc32, const unsigned char* msg, size_t size)
{
*crc32 = rhash_get_crc32(*crc32, msg, size);
}
/**
* Store calculated hash into the given array.
*
* @param crc32 pointer to the current hash value
* @param result calculated hash in binary form
*/
static void rhash_crc32_final(uint32_t* crc32, unsigned char* result)
{
#if defined(CPU_IA32) || defined(CPU_X64)
/* intel CPUs support assigment with non 32-bit aligned pointers */
*(unsigned*)result = be2me_32(*crc32);
#else
/* correct saving BigEndian integer on all archs */
result[0] = (unsigned char)(*crc32 >> 24), result[1] = (unsigned char)(*crc32 >> 16);
result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32);
#endif
}
/**
* Initialize crc32c hash.
*
* @param crc32c pointer to the hash to initialize
*/
static void rhash_crc32c_init(uint32_t* crc32c)
{
*crc32c = 0; /* note: context size is sizeof(uint32_t) */
}
/**
* Calculate message CRC32C hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param crc32c pointer to the hash
* @param msg message chunk
* @param size length of the message chunk
*/
static void rhash_crc32c_update(uint32_t* crc32c, const unsigned char* msg, size_t size)
{
*crc32c = rhash_get_crc32c(*crc32c, msg, size);
}
/**
* Store calculated hash into the given array.
*
* @param crc32c pointer to the current hash value
* @param result calculated hash in binary form
*/
static void rhash_crc32c_final(uint32_t* crc32c, unsigned char* result)
{
#if defined(CPU_IA32) || defined(CPU_X64)
/* intel CPUs support assigment with non 32-bit aligned pointers */
*(unsigned*)result = be2me_32(*crc32c);
#else
/* correct saving BigEndian integer on all archs */
result[0] = (unsigned char)(*crc32c >> 24), result[1] = (unsigned char)(*crc32c >> 16);
result[2] = (unsigned char)(*crc32c >> 8), result[3] = (unsigned char)(*crc32c);
#endif
}
#if !defined(NO_IMPORT_EXPORT)
#define EXTENDED_TTH EXTENDED_HASH_ID(5)
#define EXTENDED_AICH EXTENDED_HASH_ID(8)
/**
* Export a hash function context to a memory region,
* or calculate the size required for context export.
*
* @param hash_id identifier of the hash function
* @param ctx the algorithm context containing current hashing state
* @param out pointer to the memory region or NULL
* @param size size of memory region
* @return the size of the exported data on success, 0 on fail.
*/
size_t rhash_export_alg(unsigned hash_id, const void* ctx, void* out, size_t size)
{
switch (hash_id)
{
case RHASH_TTH:
case EXTENDED_TTH:
return rhash_tth_export((const tth_ctx*)ctx, out, size);
case RHASH_BTIH:
case EXTENDED_BTIH:
return bt_export((const torrent_ctx*)ctx, out, size);
case RHASH_AICH:
case EXTENDED_AICH:
return rhash_aich_export((const aich_ctx*)ctx, out, size);
case RHASH_BLAKE3:
return rhash_blake3_export((const blake3_ctx*)ctx, out, size);
}
return 0;
}
/**
* Import a hash function context from a memory region.
*
* @param hash_id identifier of the hash function
* @param ctx pointer to the algorithm context
* @param in pointer to the data to import
* @param size size of data to import
* @return the size of the imported data on success, 0 on fail.
*/
size_t rhash_import_alg(unsigned hash_id, void* ctx, const void* in, size_t size)
{
switch (hash_id)
{
case RHASH_TTH:
case EXTENDED_TTH:
return rhash_tth_import((tth_ctx*)ctx, in, size);
case RHASH_BTIH:
case EXTENDED_BTIH:
return bt_import((torrent_ctx*)ctx, in, size);
case RHASH_AICH:
case EXTENDED_AICH:
return rhash_aich_import((aich_ctx*)ctx, in, size);
case RHASH_BLAKE3:
return rhash_blake3_import((blake3_ctx*)ctx, in, size);
}
return 0;
}
#endif /* !defined(NO_IMPORT_EXPORT) */
#ifdef USE_OPENSSL
void rhash_load_sha1_methods(rhash_hashing_methods* methods, int methods_type)
{
int use_openssl;
switch (methods_type) {
case METHODS_OPENSSL:
use_openssl = 1;
break;
case METHODS_SELECTED:
assert(rhash_info_table[3].info->hash_id == EXTENDED_SHA1);
use_openssl = ARE_OPENSSL_METHODS(rhash_info_table[3]);
break;
default:
use_openssl = 0;
break;
}
if (use_openssl) {
methods->init = rhash_ossl_sha1_init();
methods->update = rhash_ossl_sha1_update();
methods->final = rhash_ossl_sha1_final();
} else {
methods->init = (pinit_t)&rhash_sha1_init;
methods->update = (pupdate_t)&rhash_sha1_update;
methods->final = (pfinal_t)&rhash_sha1_final;
}
}
#endif
rhash-1.4.6/librhash/rhash.h 0000664 0000000 0000000 00000054061 15010476501 014406 0 ustar root root /** @file rhash.h LibRHash interface */
#ifndef RHASH_H
#define RHASH_H
#include
#ifdef __cplusplus
extern "C" {
#endif
#ifndef RHASH_API
/**
* Modifier for LibRHash functions
*/
# define RHASH_API
#endif
/**
* Identifiers of supported hash functions.
* The rhash_init() function allows mixing several ids using
* binary OR, to calculate several hash functions for one message.
*/
enum rhash_ids
{
RHASH_CRC32 = 0x01,
RHASH_MD4 = 0x02,
RHASH_MD5 = 0x04,
RHASH_SHA1 = 0x08,
RHASH_TIGER = 0x10,
RHASH_TTH = 0x20,
RHASH_BTIH = 0x40,
RHASH_ED2K = 0x80,
RHASH_AICH = 0x100,
RHASH_WHIRLPOOL = 0x200,
RHASH_RIPEMD160 = 0x400,
RHASH_GOST94 = 0x800,
RHASH_GOST94_CRYPTOPRO = 0x1000,
RHASH_HAS160 = 0x2000,
RHASH_GOST12_256 = 0x4000,
RHASH_GOST12_512 = 0x8000,
RHASH_SHA224 = 0x10000,
RHASH_SHA256 = 0x20000,
RHASH_SHA384 = 0x40000,
RHASH_SHA512 = 0x80000,
RHASH_EDONR256 = 0x0100000,
RHASH_EDONR512 = 0x0200000,
RHASH_SHA3_224 = 0x0400000,
RHASH_SHA3_256 = 0x0800000,
RHASH_SHA3_384 = 0x1000000,
RHASH_SHA3_512 = 0x2000000,
RHASH_CRC32C = 0x4000000,
RHASH_SNEFRU128 = 0x8000000,
RHASH_SNEFRU256 = 0x10000000,
RHASH_BLAKE2S = 0x20000000,
RHASH_BLAKE2B = 0x40000000,
RHASH_BLAKE3 = 0x8000001f,
/**
* The number of supported hash functions.
*/
RHASH_HASH_COUNT = 32,
/* bit-flag for extra hash identifiers */
RHASH_EXTENDED_BIT = (int)0x80000000,
/**
* Virtual hash id to initialize all supported hash functions.
*/
RHASH_ALL_HASHES = 0xff000000,
/**
* Legacy value.
* The bit-mask containing supported hash functions prior to rhash 1.4.5.
*/
RHASH_LOW_HASHES_MASK =
RHASH_CRC32 | RHASH_CRC32C | RHASH_MD4 | RHASH_MD5 |
RHASH_ED2K | RHASH_SHA1 |RHASH_TIGER | RHASH_TTH |
RHASH_GOST94 | RHASH_GOST94_CRYPTOPRO | RHASH_GOST12_256 | RHASH_GOST12_512 |
RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |
RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 |
RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 |
RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 |
RHASH_EDONR256 | RHASH_EDONR512 | RHASH_BLAKE2S | RHASH_BLAKE2B,
RHASH_GOST = RHASH_GOST94, /* deprecated constant name */
RHASH_GOST_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO /* deprecated constant name */
};
/**
* The rhash context structure contains contexts for several hash functions.
*/
struct rhash_context
{
/**
* The size of the hashed message.
*/
unsigned long long msg_size;
union {
/**
* The bitmask for hash functions being calculated.
*/
unsigned long long hash_mask;
/**
* @deprecated use hash_mask instead
*/
unsigned long long hash_id;
};
};
#ifndef LIBRHASH_RHASH_CTX_DEFINED
#define LIBRHASH_RHASH_CTX_DEFINED
/**
* Hashing context.
*/
typedef struct rhash_context* rhash;
#endif /* LIBRHASH_RHASH_CTX_DEFINED */
/**
* Type of a callback to be called periodically while hashing a file.
*/
typedef void (*rhash_callback_t)(void* data, unsigned long long offset);
/**
* Initialize static data of rhash algorithms
*/
RHASH_API void rhash_library_init(void);
/* HIGH-LEVEL LIBRHASH INTERFACE */
/**
* Compute a message digest of the given message.
*
* @param hash_id id of message digest to compute
* @param message the message to process
* @param length message length
* @param result buffer to receive the binary message digest value
* @return 0 on success, -1 on error
*/
RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result);
/**
* Compute a single message digest for the given file.
*
* @param hash_id id of hash function to compute
* @param filepath path to the file to process
* @param result buffer to receive message digest
* @return 0 on success, -1 on fail with error code stored in errno
*/
RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
#ifdef _WIN32
/**
* Compute a single message digest for the given file (Windows-specific function).
*
* @param hash_id id of hash function to compute
* @param filepath path to the file to process
* @param result buffer to receive the binary message digest value
* @return 0 on success, -1 on fail with error code stored in errno
*/
RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result);
#endif
/* LOW-LEVEL LIBRHASH INTERFACE */
/**
* Allocate and initialize RHash context for calculating a single or multiple hash functions.
* The context after usage must be freed by calling rhash_free().
*
* @param count the size of the hash_ids array, the count must be greater than zero
* @param hash_ids array of identifiers of hash functions. Each element must
* be an identifier of one hash function
* @return initialized rhash context, NULL on fail with error code stored in errno
*/
RHASH_API rhash rhash_init_multi(size_t count, const unsigned hash_ids[]);
/**
* Allocate and initialize RHash context for calculating a single hash function.
*
* This function also supports a deprecated way to initialize rhash context
* for multiple hash functions, by passing a bitwise union of several hash
* identifiers. Only single-bit identifiers (not greater than RHASH_SNEFRU256)
* can be used in such bitwise union.
*
* @param hash_id identifier of a hash function
* @return initialized rhash context, NULL on fail with error code stored in errno
*/
RHASH_API rhash rhash_init(unsigned hash_id);
/**
* Calculate message digests of message.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the rhash context
* @param message message chunk
* @param length length of the message chunk
* @return 0 on success, -1 on fail with error code stored in errno
*/
RHASH_API int rhash_update(rhash ctx, const void* message, size_t length);
/**
* Special value meaning "read and hash until end of file".
*/
#define RHASH_MAX_FILE_SIZE ((unsigned long long)-1)
/**
* Calculate message digests of a file or stream.
* Multiple message digests can be computed.
* First, initialize ctx parameter with rhash_init() before calling
* rhash_update_fd(). Then use rhash_final() and rhash_print()
* to retrieve message digests. Finally, call rhash_free() on ctx
* to free allocated memory or call rhash_reset() to reuse ctx.
* The file descriptor must correspond to an opened file or stream.
*
* @param ctx the rhash context (must be initialized)
* @param fd descriptor of the file to process
* @param data_size maximum bytes to process (RHASH_MAX_FILE_SIZE for entire file)
* @return 0 on success, -1 on fail with error code stored in errno
*/
RHASH_API int rhash_update_fd(rhash ctx, int fd, unsigned long long data_size);
/**
* Process a file or stream. Multiple message digests can be computed.
* First, inintialize ctx parameter with rhash_init() before calling
* rhash_file_update(). Then use rhash_final() and rhash_print()
* to retrieve message digests. Finally, call rhash_free() on ctx
* to free allocated memory or call rhash_reset() to reuse ctx.
*
* @param ctx rhash context
* @param fd descriptor of the file to process
* @return 0 on success, -1 on fail with error code stored in errno
*/
RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
/**
* Finalize message digest calculation and optionally store the first message digest.
*
* @param ctx the rhash context
* @param first_result optional buffer to store a calculated message digest with the lowest available id
* @return 0 on success, -1 on fail with error code stored in errno
*/
RHASH_API int rhash_final(rhash ctx, unsigned char* first_result);
/**
* Re-initialize RHash context to reuse it.
* Useful to speed up processing of many small messages.
*
* @param ctx context to reinitialize
*/
RHASH_API void rhash_reset(rhash ctx);
/**
* Free RHash context memory.
*
* @param ctx the context to free
*/
RHASH_API void rhash_free(rhash ctx);
/**
* Set the callback function to be called from the
* rhash_file() and rhash_file_update() functions
* on processing every file block. The file block
* size is set internally by rhash and now is 8 KiB.
*
* @param ctx rhash context
* @param callback pointer to the callback function
* @param callback_data pointer to data passed to the callback
*/
RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);
/**
* Export RHash context data to a memory region.
* The size of the memory required for export
* is returned by rhash_export(ctx, NULL, 0).
*
* @param ctx the rhash context to export
* @param out pointer to a memory region, or NULL
* @param size the size of a memory region
* @return the size of exported data on success export.
* The size of memory required for export if out is NULL.
* 0 on fail with error code stored in errno
*/
RHASH_API size_t rhash_export(rhash ctx, void* out, size_t size);
/**
* Import rhash context from a memory region.
* The returned rhash context must be released after usage
* by rhash_free().
*
* @param in pointer to a memory region
* @param size the size of a memory region
* @return imported rhash context on success,
* NULL on fail with error code stored in errno
*/
RHASH_API rhash rhash_import(const void* in, size_t size);
/* INFORMATION FUNCTIONS */
/**
* Returns the number of supported hash algorithms.
*
* @return the number of supported hash functions
*/
RHASH_API int rhash_count(void);
/**
* Returns the size of binary message digest for given hash function.
*
* @param hash_id the id of the hash function
* @return the size of the message digest in bytes
*/
RHASH_API int rhash_get_digest_size(unsigned hash_id);
/**
* Returns the length of message digest string in its default output format.
*
* @param hash_id the id of the hash function
* @return the length of the message digest
*/
RHASH_API int rhash_get_hash_length(unsigned hash_id);
/**
* Detect default message digest output format for the given hash algorithm.
*
* @param hash_id the id of hash algorithm
* @return 1 for base32 format, 0 for hexadecimal
*/
RHASH_API int rhash_is_base32(unsigned hash_id);
/**
* Returns the name of the given hash function.
*
* @param hash_id id of the hash function
* @return hash function name
*/
RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */
/**
* Returns a name part of magnet urn of the given hash algorithm.
* Such magnet_name is used to generate a magnet link of the form
* urn:<magnet_name>=<hash_value>.
*
* @param hash_id id of the hash algorithm
* @return name
*/
RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */
/* HASH SUM OUTPUT INTERFACE */
/**
* Flags for printing a message digest.
*/
enum rhash_print_sum_flags
{
/*
* Print in a default format
*/
RHPR_DEFAULT = 0x0,
/*
* Output as binary message digest
*/
RHPR_RAW = 0x1,
/*
* Print as a hexadecimal string
*/
RHPR_HEX = 0x2,
/*
* Print as a base32-encoded string
*/
RHPR_BASE32 = 0x3,
/*
* Print as a base64-encoded string
*/
RHPR_BASE64 = 0x4,
/*
* Print as an uppercase string. Can be used
* for base32 or hexadecimal format only.
*/
RHPR_UPPERCASE = 0x8,
/*
* Reverse message digest bytes. Can be used for GOST hash functions.
*/
RHPR_REVERSE = 0x10,
/*
* Don't print 'magnet:?' prefix in rhash_print_magnet
*/
RHPR_NO_MAGNET = 0x20,
/*
* Print file size in rhash_print_magnet
*/
RHPR_FILESIZE = 0x40,
/*
* Print as URL-encoded string
*/
RHPR_URLENCODE = 0x80
};
/**
* Print to the specified buffer the text representation of the given message digest.
*
* @param output a buffer to print the message digest to
* @param bytes a binary message digest to print
* @param size a size of the message digest in bytes
* @param flags a bitmask controlling how to format the message digest,
* can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32,
* RHPR_BASE64, RHPR_URLENCODE, RHPR_UPPERCASE, RHPR_REVERSE
* @return the number of written characters
*/
RHASH_API size_t rhash_print_bytes(char* output,
const unsigned char* bytes, size_t size, int flags);
/**
* Print to the specified output buffer the text representation of the message digest
* with the given hash_id. If the hash_id is zero, then print the message digest with
* the lowest hash_id calculated by the hash context.
* The function call fails if the context doesn't include the message digest with the
* given hash_id.
*
* @param output a buffer to print the message digest to
* @param context algorithms state
* @param hash_id id of the message digest to print or 0 to print the first
* message digest saved in the context.
* @param flags a bitmask controlling how to print the message digest. Can contain
* flags RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc.
* @return the number of written characters on success or 0 on fail
*/
RHASH_API size_t rhash_print(char* output, rhash context, unsigned hash_id,
int flags);
/**
* Print magnet link with given filepath and calculated message digest into the
* output buffer. The hash_mask can limit which message digests will be printed.
* The function returns the size of the required buffer.
* If output is NULL then the size of the required buffer is returned.
*
* @param output a string buffer to receive the magnet link or NULL
* @param out_size size of the output string buffer
* @param filepath the file path to be printed or NULL
* @param context algorithms state
* @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
* RHPR_FILESIZE
* @param count the size of the hash_ids array
* @param hash_ids array of identifiers of message digests to add to the magnet link
* @return number of written characters, including terminating '\0' on success, 0 on fail
*/
RHASH_API size_t rhash_print_magnet_multi(char* output, size_t size, const char* filepath,
rhash context, int flags, size_t count, const unsigned hash_ids[]);
/**
* Print magnet link with given filepath and calculated message digest into the
* output buffer. The hash_mask can limit which message digests will be printed.
* The function returns the size of the required buffer.
* If output is NULL then the size of the required buffer is returned.
*
* @param output a string buffer to receive the magnet link or NULL
* @param filepath the file path to be printed or NULL
* @param context algorithms state
* @param hash_mask bit mask of the message digest to add to the link
* @param flags can be combination of bits RHPR_UPPERCASE, RHPR_NO_MAGNET,
* RHPR_FILESIZE
* @return number of written characters, including terminating '\0' on success, 0 on fail
* @deprecated use rhash_print_magnet_multi() instead
*/
RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
rhash context, unsigned hash_mask, int flags);
/* MESSAGE API */
/**
* The type of an unsigned integer large enough to hold a pointer.
*/
#if defined(UINTPTR_MAX)
typedef uintptr_t rhash_uptr_t;
#elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
typedef unsigned long long rhash_uptr_t;
#else
typedef unsigned long rhash_uptr_t;
#endif
/**
* The value returned by rhash_ctrl on error.
*/
#define RHASH_ERROR ((size_t)-1)
/**
* Process rhash control message.
*
* @param msg_id message identifier
* @param dst message destination (can be NULL for generic messages)
* @param ldata data depending on message
* @param rdata data depending on message
* @return message-specific data
* @deprecated use rhash_ctrl() instead
*/
RHASH_API rhash_uptr_t rhash_transmit(
unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata);
/**
* Perform a generic or rhash context specific control command.
*
* @param context rhash context
* @param cmd control command id
* @param size the size of the data or command specific argument
* @param data command specific data
* @return command specific return value
*/
RHASH_API size_t rhash_ctrl(rhash context, int cmd, size_t size, void* data);
/* Commands for rhash_ctrl() */
#define RMSG_GET_CONTEXT 1
#define RMSG_CANCEL 2
#define RMSG_IS_CANCELED 3
#define RMSG_GET_FINALIZED 4
#define RMSG_SET_AUTOFINAL 5
#define RMSG_HAS_CPU_FEATURE 9
#define RMSG_GET_ALL_ALGORITHMS 14
#define RMSG_GET_CTX_ALGORITHMS 15
#define RMSG_GET_OPENSSL_SUPPORTED 16
#define RMSG_GET_OPENSSL_AVAILABLE 17
#define RMSG_GET_OPENSSL_ENABLED 18
#define RMSG_SET_OPENSSL_ENABLED 19
#define RMSG_GET_LIBRHASH_VERSION 20
/* Deprecated message ids for rhash_transmit() */
#define RMSG_SET_OPENSSL_MASK 10
#define RMSG_GET_OPENSSL_MASK 11
#define RMSG_GET_OPENSSL_SUPPORTED_MASK 12
#define RMSG_GET_OPENSSL_AVAILABLE_MASK 13
/* HELPER MACROS */
/**
* Get a pointer to the context of the specified hash function.
*/
#define rhash_get_context(ctx, hash_id, ptr) \
rhash_ctrl((ctx), RMSG_GET_CONTEXT, (hash_id), (ptr))
/**
* Cancel file processing.
*/
#define rhash_cancel(ctx) \
rhash_ctrl((ctx), RMSG_CANCEL, 0, NULL)
/**
* Return non-zero if a message digest calculation was canceled, zero otherwise.
*/
#define rhash_is_canceled(ctx) \
rhash_ctrl((ctx), RMSG_IS_CANCELED, 0, NULL)
/**
* Return non-zero if rhash_final was called for rhash_context.
*/
#define rhash_get_finalized(ctx) \
rhash_ctrl((ctx), RMSG_GET_FINALIZED, 0, NULL)
/**
* Turn on/off the auto-final flag for the given rhash_context. By default
* auto-final is on, which means rhash_final is called automatically, if
* needed when a message digest is retrieved by rhash_print call.
*/
#define rhash_set_autofinal(ctx, on) \
rhash_ctrl((ctx), RMSG_SET_AUTOFINAL, (on), NULL)
/**
* Check if the given feature is supported by CPU.
*/
#define rhash_has_cpu_feature(feature) \
rhash_ctrl(NULL, RMSG_HAS_CPU_FEATURE, (feature), NULL)
/**
* Fill the hash_ids array by identifiers of all algorithms supported
* by the library. The hash_ids array must have space to store
* at least count of unsigned elements.
* Returns RHASH_ERROR if the count and the hash_ids pointer are non-zero
* and the count is smaller then the number of supported algorithms,
* otherwise returns the number of algorithms.
*/
#define rhash_get_all_algorithms(count, hash_ids) \
rhash_ctrl(NULL, RMSG_GET_ALL_ALGORITHMS, (count), (hash_ids))
/**
* Fill the hash_ids array by identifiers of algorithms associated with the given
* rhash context. The hash_ids array must have space to store
* at least count of unsigned elements.
* Returns RHASH_ERROR if hash_ids is not NULL and count is non-zero,
* and the count is smaller then the number of algorithms in context,
* otherwise returns the number of algorithms.
*/
#define rhash_get_ctx_algorithms(ctx, count, hash_ids) \
rhash_ctrl((ctx), RMSG_GET_CTX_ALGORITHMS, (count), (hash_ids))
/**
* Get array of ids of algorithms supported by the OpenSSL plugin.
* Do not use this macro, unless reading detailed plugin info.
* Returns RHASH_ERROR if hash_ids is not NULL and count is non-zero,
* and count is lesser than the number of enabled algorithms,
* returns the number of supported algorithms otherwize.
*/
#define rhash_get_openssl_supported(count, hash_ids) \
rhash_ctrl(NULL, RMSG_GET_OPENSSL_SUPPORTED, (count), (hash_ids))
/**
* Get array of ids of algorithms available from OpenSSL library.
* Returns RHASH_ERROR if hash_ids is not NULL and count is non-zero,
* and count is lesser than the number of enabled algorithms,
* returns 0 if dynamic OpenSSL library is not found or not loaded,
* returns the number of enabled algorithms otherwize.
*/
#define rhash_get_openssl_available(count, hash_ids) \
rhash_ctrl(NULL, RMSG_GET_OPENSSL_AVAILABLE, (count), (hash_ids))
/**
* Get array of ids of "enabled" OpenSSL algorithms, which means
* the algorithms selected to be calculated by OpenSSL library.
* Returns RHASH_ERROR if hash_ids is not NULL and count is non-zero,
* and count is lesser than the number of enabled algorithms,
* returns the number of enabled algorithms otherwize.
*/
#define rhash_get_openssl_enabled(count, hash_ids) \
rhash_ctrl(NULL, RMSG_GET_OPENSSL_ENABLED, (count), (hash_ids))
/**
* Set array of algorithms to be calculated by OpenSSL library.
* The call rhash_set_openssl_enabled(0, NULL) made before rhash_library_init(),
* disables loading of the OpenSSL dynamic library.
* Returns RHASH_ERROR if hash_ids is NULL and count is non-zero, 0 otherwise.
*/
#define rhash_set_openssl_enabled(count, hash_ids) \
rhash_ctrl(NULL, RMSG_SET_OPENSSL_ENABLED, (count), (hash_ids))
/**
* Return non-zero if LibRHash has been compiled with OpenSSL support,
* and zero otherwise.
*/
#define rhash_is_openssl_supported() (rhash_get_openssl_supported(0, NULL))
/**
* Return LibRHash version.
*/
#define rhash_get_version() \
rhash_ctrl(NULL, RMSG_GET_LIBRHASH_VERSION, 0, NULL)
/* Deprecated macros to work with hash masks */
/**
* Set the bitmask of hash algorithms to be calculated by OpenSSL library.
* Return RHASH_ERROR if LibRHash is compiled without OpenSSL support.
* @deprecated use rhash_set_openssl_enabled() instead
*/
#define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0)
/**
* Return current bitmask of hash algorithms selected to be calculated by OpenSSL
* library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support.
* @deprecated use rhash_get_openssl_enabled() instead
*/
#define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0)
/**
* Return the bitmask of algorithms that can be provided by the OpenSSL plugin,
* if the library is compiled with OpenSSL support, 0 otherwise.
* This bitmask is a constant value computed at compile-time.
* @deprecated use rhash_get_openssl_supported() instead
*/
#define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0)
/**
* Return the bitmask of algorithms that are successfully loaded from
* OpenSSL library. If the library is not loaded or not supported by LibRHash,
* then return 0.
* @deprecated use rhash_get_openssl_available() instead
*/
#define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0)
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_H */
rhash-1.4.6/librhash/Doxyfile 0000664 0000000 0000000 00000317354 14703622112 014644 0 ustar root root # Doxyfile 1.8.11
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
#
# All text after a double hash (##) is considered a comment and is placed in
# front of the TAG it is preceding.
#
# All text after a single hash (#) is considered a comment and will be ignored.
# The format is:
# TAG = value [value, ...]
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
# for the list of possible encodings.
# The default value is: UTF-8.
DOXYFILE_ENCODING = UTF-8
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
# double-quotes, unless you are using Doxywizard) that should identify the
# project for which the documentation is generated. This name is used in the
# title of most generated pages and in a few other places.
# The default value is: My Project.
PROJECT_NAME = RHash
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER =
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.
PROJECT_BRIEF =
# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = docs
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
# will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where
# putting all generated files in the same directory would otherwise causes
# performance problems for the file system.
# The default value is: NO.
CREATE_SUBDIRS = NO
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
# U+3044.
# The default value is: NO.
ALLOW_UNICODE_NAMES = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
# Ukrainian and Vietnamese.
# The default value is: English.
OUTPUT_LANGUAGE = English
# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
# descriptions after the members that are listed in the file and class
# documentation (similar to Javadoc). Set to NO to disable this.
# The default value is: YES.
BRIEF_MEMBER_DESC = YES
# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
# description of a member or function before the detailed description
#
# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
# The default value is: YES.
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator that is
# used to form the text in various listings. Each string in this list, if found
# as the leading text of the brief description, will be stripped from the text
# and the result, after processing the whole list, is used as the annotated
# text. Otherwise, the brief description is used as-is. If left blank, the
# following values are used ($name is automatically replaced with the name of
# the entity):The $name class, The $name widget, The $name file, is, provides,
# specifies, contains, represents, a, an and the.
ABBREVIATE_BRIEF =
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
# doxygen will generate a detailed section even if there is only a brief
# description.
# The default value is: NO.
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
# members were ordinary class members. Constructors, destructors and assignment
# operators of the base classes will not be shown.
# The default value is: NO.
INLINE_INHERITED_MEMB = NO
# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
# before files name in the file list and in the header files. If set to NO the
# shortest path that makes the file name unique will be used
# The default value is: YES.
FULL_PATH_NAMES = YES
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
# Stripping is only done if one of the specified strings matches the left-hand
# part of the path. The tag can be used to show relative paths in the file list.
# If left blank the directory from which doxygen is run is used as the path to
# strip.
#
# Note that you can specify absolute paths here, but also relative paths, which
# will be relative from the directory where doxygen is started.
# This tag requires that the tag FULL_PATH_NAMES is set to YES.
STRIP_FROM_PATH =
# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
# path mentioned in the documentation of a class, which tells the reader which
# header file to include in order to use a class. If left blank only the name of
# the header file containing the class definition is used. Otherwise one should
# specify the list of include paths that are normally passed to the compiler
# using the -I flag.
STRIP_FROM_INC_PATH =
# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
# less readable) file names. This can be useful is your file systems doesn't
# support long names like on DOS, Mac, or CD-ROM.
# The default value is: NO.
SHORT_NAMES = NO
# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
# first line (until the first dot) of a Javadoc-style comment as the brief
# description. If set to NO, the Javadoc-style will behave just like regular Qt-
# style comments (thus requiring an explicit @brief command for a brief
# description.)
# The default value is: NO.
JAVADOC_AUTOBRIEF = YES
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
# line (until the first dot) of a Qt-style comment as the brief description. If
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
# requiring an explicit \brief command for a brief description.)
# The default value is: NO.
QT_AUTOBRIEF = NO
# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
# a brief description. This used to be the default behavior. The new default is
# to treat a multi-line C++ comment block as a detailed description. Set this
# tag to YES if you prefer the old behavior instead.
#
# Note that setting this tag to YES also means that rational rose comments are
# not recognized any more.
# The default value is: NO.
MULTILINE_CPP_IS_BRIEF = NO
# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
# documentation from any documented member that it re-implements.
# The default value is: YES.
INHERIT_DOCS = YES
# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
# page for each member. If set to NO, the documentation of a member will be part
# of the file/class/namespace that contains it.
# The default value is: NO.
SEPARATE_MEMBER_PAGES = NO
# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
# uses this value to replace tabs by spaces in code fragments.
# Minimum value: 1, maximum value: 16, default value: 4.
TAB_SIZE = 8
# This tag can be used to specify a number of aliases that act as commands in
# the documentation. An alias has the form:
# name=value
# For example adding
# "sideeffect=@par Side Effects:\n"
# will allow you to put the command \sideeffect (or @sideeffect) in the
# documentation, which will result in a user-defined paragraph with heading
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
ALIASES =
# This tag can be used to specify a number of word-keyword mappings (TCL only).
# A mapping has the form "name=value". For example adding "class=itcl::class"
# will allow you to use the command class in the itcl::class meaning.
TCL_SUBST =
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For
# instance, some of the names that are used will be different. The list of all
# members will be omitted, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_FOR_C = YES
# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
# Python sources only. Doxygen will then generate output that is more tailored
# for that language. For instance, namespaces will be presented as packages,
# qualified scopes will look different, etc.
# The default value is: NO.
OPTIMIZE_OUTPUT_JAVA = NO
# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
# sources. Doxygen will then generate output that is tailored for Fortran.
# The default value is: NO.
OPTIMIZE_FOR_FORTRAN = NO
# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
# sources. Doxygen will then generate output that is tailored for VHDL.
# The default value is: NO.
OPTIMIZE_OUTPUT_VHDL = NO
# Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given
# extension. Doxygen has a built-in mapping, but you can override or extend it
# using this tag. The format is ext=language, where ext is a file extension, and
# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
# Fortran. In the later case the parser tries to guess whether the code is fixed
# or free formatted code, this is the default for Fortran type files), VHDL. For
# instance to make doxygen treat .inc files as Fortran files (default is PHP),
# and .f files as C (default is Fortran), use: inc=Fortran f=C.
#
# Note: For files without extension you can use no_extension as a placeholder.
#
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.
EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
# documentation. See http://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
# The default value is: YES.
MARKDOWN_SUPPORT = YES
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or
# globally by setting AUTOLINK_SUPPORT to NO.
# The default value is: YES.
AUTOLINK_SUPPORT = YES
# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
# to include (a tag file for) the STL sources as input, then you should set this
# tag to YES in order to let doxygen match functions declarations and
# definitions whose arguments contain STL classes (e.g. func(std::string);
# versus func(std::string) {}). This also make the inheritance and collaboration
# diagrams that involve STL classes more complete and accurate.
# The default value is: NO.
BUILTIN_STL_SUPPORT = NO
# If you use Microsoft's C++/CLI language, you should set this option to YES to
# enable parsing support.
# The default value is: NO.
CPP_CLI_SUPPORT = NO
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
# will parse them like normal C++ but will assume all classes use public instead
# of private inheritance when no explicit protection keyword is present.
# The default value is: NO.
SIP_SUPPORT = NO
# For Microsoft's IDL there are propget and propput attributes to indicate
# getter and setter methods for a property. Setting this option to YES will make
# doxygen to replace the get and set methods by a property in the documentation.
# This will only work if the methods are indeed getting or setting a simple
# type. If this is not the case, or you want to show the methods anyway, you
# should set this option to NO.
# The default value is: YES.
IDL_PROPERTY_SUPPORT = YES
# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
# tag is set to YES then doxygen will reuse the documentation of the first
# member in the group (if any) for the other members of the group. By default
# all members of a group must be documented explicitly.
# The default value is: NO.
DISTRIBUTE_GROUP_DOC = NO
# If one adds a struct or class to a group and this option is enabled, then also
# any nested class or struct is added to the same group. By default this option
# is disabled and one has to add nested compounds explicitly via \ingroup.
# The default value is: NO.
GROUP_NESTED_COMPOUNDS = NO
# Set the SUBGROUPING tag to YES to allow class member groups of the same type
# (for instance a group of public functions) to be put as a subgroup of that
# type (e.g. under the Public Functions section). Set it to NO to prevent
# subgrouping. Alternatively, this can be done per class using the
# \nosubgrouping command.
# The default value is: YES.
SUBGROUPING = YES
# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
# are shown inside the group in which they are included (e.g. using \ingroup)
# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
# and RTF).
#
# Note that this feature does not work in combination with
# SEPARATE_MEMBER_PAGES.
# The default value is: NO.
INLINE_GROUPED_CLASSES = NO
# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
# with only public data fields or simple typedef fields will be shown inline in
# the documentation of the scope in which they are defined (i.e. file,
# namespace, or group documentation), provided this scope is documented. If set
# to NO, structs, classes, and unions are shown on a separate page (for HTML and
# Man pages) or section (for LaTeX and RTF).
# The default value is: NO.
INLINE_SIMPLE_STRUCTS = NO
# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
# enum is documented as struct, union, or enum with the name of the typedef. So
# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
# with name TypeT. When disabled the typedef will appear as a member of a file,
# namespace, or class. And the struct will be named TypeS. This can typically be
# useful for C code in case the coding convention dictates that all compound
# types are typedef'ed and only the typedef is referenced, never the tag name.
# The default value is: NO.
TYPEDEF_HIDES_STRUCT = NO
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
# cache is used to resolve symbols given their name and scope. Since this can be
# an expensive process and often the same symbol appears multiple times in the
# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
# doxygen will become slower. If the cache is too large, memory is wasted. The
# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
# symbols. At the end of a run doxygen will report the cache usage and suggest
# the optimal cache size from a speed point of view.
# Minimum value: 0, maximum value: 9, default value: 0.
LOOKUP_CACHE_SIZE = 0
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
# documentation are documented, even if no documentation was available. Private
# class members and static file members will be hidden unless the
# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
# Note: This will also disable the warnings about undocumented members that are
# normally produced when WARNINGS is set to YES.
# The default value is: NO.
EXTRACT_ALL = YES
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
# be included in the documentation.
# The default value is: NO.
EXTRACT_PRIVATE = NO
# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
# scope will be included in the documentation.
# The default value is: NO.
EXTRACT_PACKAGE = NO
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
# included in the documentation.
# The default value is: NO.
EXTRACT_STATIC = NO
# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
# locally in source files will be included in the documentation. If set to NO,
# only classes defined in header files are included. Does not have any effect
# for Java sources.
# The default value is: YES.
EXTRACT_LOCAL_CLASSES = YES
# This flag is only useful for Objective-C code. If set to YES, local methods,
# which are defined in the implementation section but not in the interface are
# included in the documentation. If set to NO, only methods in the interface are
# included.
# The default value is: NO.
EXTRACT_LOCAL_METHODS = NO
# If this flag is set to YES, the members of anonymous namespaces will be
# extracted and appear in the documentation as a namespace called
# 'anonymous_namespace{file}', where file will be replaced with the base name of
# the file that contains the anonymous namespace. By default anonymous namespace
# are hidden.
# The default value is: NO.
EXTRACT_ANON_NSPACES = NO
# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
# undocumented members inside documented classes or files. If set to NO these
# members will be included in the various overviews, but no documentation
# section is generated. This option has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set
# to NO, these classes will be included in the various overviews. This option
# has no effect if EXTRACT_ALL is enabled.
# The default value is: NO.
HIDE_UNDOC_CLASSES = NO
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
# (class|struct|union) declarations. If set to NO, these declarations will be
# included in the documentation.
# The default value is: NO.
HIDE_FRIEND_COMPOUNDS = NO
# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
# documentation blocks found inside the body of a function. If set to NO, these
# blocks will be appended to the function's detailed documentation block.
# The default value is: NO.
HIDE_IN_BODY_DOCS = NO
# The INTERNAL_DOCS tag determines if documentation that is typed after a
# \internal command is included. If the tag is set to NO then the documentation
# will be excluded. Set it to YES to include the internal documentation.
# The default value is: NO.
INTERNAL_DOCS = NO
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
# names in lower-case letters. If set to YES, upper-case letters are also
# allowed. This is useful if you have classes or files whose names only differ
# in case and if your file system supports case sensitive file names. Windows
# and Mac users are advised to set this option to NO.
# The default value is: system dependent.
CASE_SENSE_NAMES = YES
# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
# their full class and namespace scopes in the documentation. If set to YES, the
# scope will be hidden.
# The default value is: NO.
HIDE_SCOPE_NAMES = NO
# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
# append additional text to a page's title, such as Class Reference. If set to
# YES the compound reference will be hidden.
# The default value is: NO.
HIDE_COMPOUND_REFERENCE= NO
# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
# the files that are included by a file in the documentation of that file.
# The default value is: YES.
SHOW_INCLUDE_FILES = YES
# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
# grouped member an include statement to the documentation, telling the reader
# which file to include in order to use the member.
# The default value is: NO.
SHOW_GROUPED_MEMB_INC = NO
# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
# files with double quotes in the documentation rather than with sharp brackets.
# The default value is: NO.
FORCE_LOCAL_INCLUDES = NO
# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
# documentation for inline members.
# The default value is: YES.
INLINE_INFO = YES
# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
# (detailed) documentation of file and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order.
# The default value is: YES.
SORT_MEMBER_DOCS = YES
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
# descriptions of file, namespace and class members alphabetically by member
# name. If set to NO, the members will appear in declaration order. Note that
# this will also influence the order of the classes in the class list.
# The default value is: NO.
SORT_BRIEF_DOCS = NO
# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
# (brief and detailed) documentation of class members so that constructors and
# destructors are listed first. If set to NO the constructors will appear in the
# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
# member documentation.
# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
# detailed member documentation.
# The default value is: NO.
SORT_MEMBERS_CTORS_1ST = NO
# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
# of group names into alphabetical order. If set to NO the group names will
# appear in their defined order.
# The default value is: NO.
SORT_GROUP_NAMES = NO
# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
# fully-qualified names, including namespaces. If set to NO, the class list will
# be sorted only by class name, not including the namespace part.
# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
# Note: This option applies only to the class list, not to the alphabetical
# list.
# The default value is: NO.
SORT_BY_SCOPE_NAME = NO
# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
# type resolution of all parameters of a function it will reject a match between
# the prototype and the implementation of a member function even if there is
# only one candidate or it is obvious which candidate to choose by doing a
# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
# accept a match between prototype and implementation in such cases.
# The default value is: NO.
STRICT_PROTO_MATCHING = NO
# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
# list. This list is created by putting \todo commands in the documentation.
# The default value is: YES.
GENERATE_TODOLIST = YES
# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
# list. This list is created by putting \test commands in the documentation.
# The default value is: YES.
GENERATE_TESTLIST = YES
# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
# list. This list is created by putting \bug commands in the documentation.
# The default value is: YES.
GENERATE_BUGLIST = YES
# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
# the deprecated list. This list is created by putting \deprecated commands in
# the documentation.
# The default value is: YES.
GENERATE_DEPRECATEDLIST= YES
# The ENABLED_SECTIONS tag can be used to enable conditional documentation
# sections, marked by \if ... \endif and \cond
# ... \endcond blocks.
ENABLED_SECTIONS =
# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
# initial value of a variable or macro / define can have for it to appear in the
# documentation. If the initializer consists of more lines than specified here
# it will be hidden. Use a value of 0 to hide initializers completely. The
# appearance of the value of individual variables and macros / defines can be
# controlled using \showinitializer or \hideinitializer command in the
# documentation regardless of this setting.
# Minimum value: 0, maximum value: 10000, default value: 30.
MAX_INITIALIZER_LINES = 30
# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
# the bottom of the documentation of classes and structs. If set to YES, the
# list will mention the files that were used to generate the documentation.
# The default value is: YES.
SHOW_USED_FILES = YES
# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
# will remove the Files entry from the Quick Index and from the Folder Tree View
# (if specified).
# The default value is: YES.
SHOW_FILES = YES
# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
# page. This will remove the Namespaces entry from the Quick Index and from the
# Folder Tree View (if specified).
# The default value is: YES.
SHOW_NAMESPACES = YES
# The FILE_VERSION_FILTER tag can be used to specify a program or script that
# doxygen should invoke to get the current version for each file (typically from
# the version control system). Doxygen will invoke the program by executing (via
# popen()) the command command input-file, where command is the value of the
# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
# by doxygen. Whatever the program writes to standard output is used as the file
# version. For an example see the documentation.
FILE_VERSION_FILTER =
# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
# by doxygen. The layout file controls the global structure of the generated
# output files in an output format independent way. To create the layout file
# that represents doxygen's defaults, run doxygen with the -l option. You can
# optionally specify a file name after the option, if omitted DoxygenLayout.xml
# will be used as the name of the layout file.
#
# Note that if you run doxygen from a directory containing a file called
# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
# tag is left empty.
LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
CITE_BIB_FILES =
#---------------------------------------------------------------------------
# Configuration options related to warning and progress messages
#---------------------------------------------------------------------------
# The QUIET tag can be used to turn on/off the messages that are generated to
# standard output by doxygen. If QUIET is set to YES this implies that the
# messages are off.
# The default value is: NO.
QUIET = NO
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
# this implies that the warnings are on.
#
# Tip: Turn warnings on while writing the documentation.
# The default value is: YES.
WARNINGS = YES
# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
# will automatically be disabled.
# The default value is: YES.
WARN_IF_UNDOCUMENTED = YES
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as not documenting some parameters
# in a documented function, or documenting parameters that don't exist or using
# markup commands wrongly.
# The default value is: YES.
WARN_IF_DOC_ERROR = YES
# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
# are documented, but have no documentation for their parameters or return
# value. If set to NO, doxygen will only warn about wrong or incomplete
# parameter documentation, but not about the absence of documentation.
# The default value is: NO.
WARN_NO_PARAMDOC = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered.
# The default value is: NO.
WARN_AS_ERROR = NO
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
# will be replaced by the file and line number from which the warning originated
# and the warning text. Optionally the format may contain $version, which will
# be replaced by the version of the file (if it could be obtained via
# FILE_VERSION_FILTER)
# The default value is: $file:$line: $text.
WARN_FORMAT = "$file:$line: $text"
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
# error (stderr).
WARN_LOGFILE =
#---------------------------------------------------------------------------
# Configuration options related to the input files
#---------------------------------------------------------------------------
# The INPUT tag is used to specify the files and/or directories that contain
# documented source files. You may enter file names like myfile.cpp or
# directories like /usr/src/myproject. Separate the files or directories with
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = rhash.h \
rhash_torrent.h
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see: http://www.gnu.org/software/libiconv) for the list of
# possible encodings.
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
# *.h) to filter out the source-files in the directories.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# read by doxygen.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc,
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
FILE_PATTERNS =
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
# The default value is: NO.
RECURSIVE = NO
# The EXCLUDE tag can be used to specify files and/or directories that should be
# excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
#
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE =
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
# from the input.
# The default value is: NO.
EXCLUDE_SYMLINKS = NO
# If the value of the INPUT tag contains directories, you can use the
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
# certain files from those directories.
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories for example use the pattern */test/*
EXCLUDE_PATTERNS =
# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
EXCLUDE_SYMBOLS =
# The EXAMPLE_PATH tag can be used to specify one or more files or directories
# that contain example code fragments that are included (see the \include
# command).
EXAMPLE_PATH =
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
# *.h) to filter out the source-files in the directories. If left blank all
# files are included.
EXAMPLE_PATTERNS =
# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
# searched for input files to be used with the \include or \dontinclude commands
# irrespective of the value of the RECURSIVE tag.
# The default value is: NO.
EXAMPLE_RECURSIVE = NO
# The IMAGE_PATH tag can be used to specify one or more files or directories
# that contain images that are to be included in the documentation (see the
# \image command).
IMAGE_PATH =
# The INPUT_FILTER tag can be used to specify a program that doxygen should
# invoke to filter for each input file. Doxygen will invoke the filter program
# by executing (via popen()) the command:
#
#
#
# where is the value of the INPUT_FILTER tag, and is the
# name of an input file. Doxygen will then use the output that the filter
# program writes to standard output. If FILTER_PATTERNS is specified, this tag
# will be ignored.
#
# Note that the filter must not add or remove lines; it is applied before the
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
INPUT_FILTER =
# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
# basis. Doxygen will compare the file name with each pattern and apply the
# filter if there is a match. The filters are a list of the form: pattern=filter
# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
# patterns match the file name, INPUT_FILTER is applied.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
FILTER_PATTERNS =
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will also be used to filter the input files that are used for
# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
# The default value is: NO.
FILTER_SOURCE_FILES = NO
# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
# it is also possible to disable source filtering for a specific pattern using
# *.ext= (so without naming a filter).
# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
FILTER_SOURCE_PATTERNS =
# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
# is part of the input, its contents will be placed on the main page
# (index.html). This can be useful if you have a project on for instance GitHub
# and want to reuse the introduction page also for the doxygen output.
USE_MDFILE_AS_MAINPAGE =
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
# generated. Documented entities will be cross-referenced with these sources.
#
# Note: To get rid of all source code in the generated output, make sure that
# also VERBATIM_HEADERS is set to NO.
# The default value is: NO.
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
# classes and enums directly into the documentation.
# The default value is: NO.
INLINE_SOURCES = NO
# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
# special comment blocks from generated source code fragments. Normal C, C++ and
# Fortran comments will always remain visible.
# The default value is: YES.
STRIP_CODE_COMMENTS = YES
# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
# function all documented functions referencing it will be listed.
# The default value is: NO.
REFERENCED_BY_RELATION = NO
# If the REFERENCES_RELATION tag is set to YES then for each documented function
# all documented entities called/used by that function will be listed.
# The default value is: NO.
REFERENCES_RELATION = NO
# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
# to YES then the hyperlinks from functions in REFERENCES_RELATION and
# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
# link to the documentation.
# The default value is: YES.
REFERENCES_LINK_SOURCE = YES
# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
# source code will show a tooltip with additional information such as prototype,
# brief description and links to the definition and documentation. Since this
# will make the HTML file larger and loading of large files a bit slower, you
# can opt to disable this feature.
# The default value is: YES.
# This tag requires that the tag SOURCE_BROWSER is set to YES.
SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
# (see http://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
# - Install the latest version of global
# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
# - Make sure the INPUT points to the root of the source tree
# - Run doxygen as normal
#
# Doxygen will invoke htags (and that will in turn invoke gtags), so these
# tools must be available from the command line (i.e. in the search path).
#
# The result: instead of the source browser generated by doxygen, the links to
# source code will now point to the output of htags.
# The default value is: NO.
# This tag requires that the tag SOURCE_BROWSER is set to YES.
USE_HTAGS = NO
# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
# verbatim copy of the header file for each class for which an include is
# specified. Set to NO to disable this.
# See also: Section \class.
# The default value is: YES.
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
# cost of reduced performance. This can be particularly helpful with template
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
# Note: The availability of this option depends on whether or not doxygen was
# generated with the -Duse-libclang=ON option for CMake.
# The default value is: NO.
CLANG_ASSISTED_PARSING = NO
# If clang assisted parsing is enabled you can provide the compiler with command
# line options that you would normally use when invoking the compiler. Note that
# the include paths will already be set by doxygen for the files and directories
# specified with INPUT and INCLUDE_PATH.
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
CLANG_OPTIONS =
#---------------------------------------------------------------------------
# Configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
# compounds will be generated. Enable this if the project contains a lot of
# classes, structs, unions or interfaces.
# The default value is: YES.
ALPHABETICAL_INDEX = NO
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
# while generating the index headers.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the HTML output
#---------------------------------------------------------------------------
# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
# The default value is: YES.
GENERATE_HTML = YES
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_OUTPUT = html
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
# generated HTML page (for example: .htm, .php, .asp).
# The default value is: .html.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FILE_EXTENSION = .html
# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
# each generated HTML page. If the tag is left blank doxygen will generate a
# standard header.
#
# To get valid HTML the header file that includes any scripts and style sheets
# that doxygen needs, which is dependent on the configuration options used (e.g.
# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
# default header using
# doxygen -w html new_header.html new_footer.html new_stylesheet.css
# YourConfigFile
# and then modify the file new_header.html. See also section "Doxygen usage"
# for information on how to generate the default header that doxygen normally
# uses.
# Note: The header is subject to change so you typically have to regenerate the
# default header when upgrading to a newer version of doxygen. For a description
# of the possible markers and block names see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_HEADER =
# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
# generated HTML page. If the tag is left blank doxygen will generate a standard
# footer. See HTML_HEADER for more information on how to generate a default
# footer and what special commands can be used inside the footer. See also
# section "Doxygen usage" for information on how to generate the default footer
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_FOOTER =
# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
# the HTML output. If left blank doxygen will generate a default style sheet.
# See also section "Doxygen usage" for information on how to generate the style
# sheet that doxygen normally uses.
# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
# it is more robust and this tag (HTML_STYLESHEET) will in the future become
# obsolete.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_STYLESHEET =
# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# cascading style sheets that are included after the standard style sheets
# created by doxygen. Using this option one can overrule certain style aspects.
# This is preferred over using HTML_STYLESHEET since it does not replace the
# standard style sheet and is therefore more robust against future updates.
# Doxygen will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
# list). For an example see the documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the HTML output directory. Note
# that these files will be copied to the base HTML output directory. Use the
# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
# files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_HUE = 220
# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use grayscales only. A
# value of 255 will produce the most vivid colors.
# Minimum value: 0, maximum value: 255, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_SAT = 100
# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
# luminance component of the colors in the HTML output. Values below 100
# gradually make the output lighter, whereas values above 100 make the output
# darker. The value divided by 100 is the actual gamma applied, so 80 represents
# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
# change the gamma.
# Minimum value: 40, maximum value: 240, default value: 80.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
# to YES can help to show when doxygen was last run and thus if the
# documentation is up to date.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = YES
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
# documentation will contain sections that can be hidden and shown after the
# page has loaded.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_DYNAMIC_SECTIONS = NO
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
# shown in the various tree structured indices initially; the user can expand
# and collapse entries dynamically later on. Doxygen will expand the tree to
# such a level that at most the specified number of entries are visible (unless
# a fully collapsed tree already exceeds this amount). So setting the number of
# entries 1 will produce a full collapsed tree by default. 0 is a special value
# representing an infinite number of entries and will result in a full expanded
# tree by default.
# Minimum value: 0, maximum value: 9999, default value: 100.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_INDEX_NUM_ENTRIES = 100
# If the GENERATE_DOCSET tag is set to YES, additional index files will be
# generated that can be used as input for Apple's Xcode 3 integrated development
# environment (see: http://developer.apple.com/tools/xcode/), introduced with
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
# Makefile in the HTML output directory. Running make will produce the docset in
# that directory and running make install will install the docset in
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
# for more information.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_DOCSET = NO
# This tag determines the name of the docset feed. A documentation feed provides
# an umbrella under which multiple documentation sets from a single provider
# (such as a company or product suite) can be grouped.
# The default value is: Doxygen generated docs.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_FEEDNAME = "Doxygen generated docs"
# This tag specifies a string that should uniquely identify the documentation
# set bundle. This should be a reverse domain-name style string, e.g.
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_BUNDLE_ID = org.doxygen.Project
# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
# the documentation publisher. This should be a reverse domain-name style
# string, e.g. com.mycompany.MyDocSet.documentation.
# The default value is: org.doxygen.Publisher.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_PUBLISHER_ID = org.doxygen.Publisher
# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
# The default value is: Publisher.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_PUBLISHER_NAME = Publisher
# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
# Windows.
#
# The HTML Help Workshop contains a compiler that can convert all HTML output
# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
# files are now used as the Windows 98 help format, and will replace the old
# Windows help format (.hlp) on all Windows platforms in the future. Compressed
# HTML files also contain an index, a table of contents, and you can search for
# words in the documentation. The HTML workshop also contains a viewer for
# compressed HTML files.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_HTMLHELP = NO
# The CHM_FILE tag can be used to specify the file name of the resulting .chm
# file. You can add a path in front of the file if the result should not be
# written to the html output directory.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_FILE =
# The HHC_LOCATION tag can be used to specify the location (absolute path
# including file name) of the HTML help compiler (hhc.exe). If non-empty,
# doxygen will try to run the HTML help compiler on the generated index.hhp.
# The file has to be specified with full path.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
HHC_LOCATION =
# The GENERATE_CHI flag controls if a separate .chi index file is generated
# (YES) or that it should be included in the master .chm file (NO).
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
GENERATE_CHI = NO
# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
# and project file content.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
CHM_INDEX_ENCODING =
# The BINARY_TOC flag controls whether a binary table of contents is generated
# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
# enables the Previous and Next buttons.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
BINARY_TOC = NO
# The TOC_EXPAND flag can be set to YES to add extra items for group members to
# the table of contents of the HTML help documentation and to the tree view.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
TOC_EXPAND = NO
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
# (.qch) of the generated HTML documentation.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_QHP = NO
# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
# the file name of the resulting .qch file. The path specified is relative to
# the HTML output folder.
# This tag requires that the tag GENERATE_QHP is set to YES.
QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
# The QHG_LOCATION tag can be used to specify the location of Qt's
# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
# generated .qhp file.
# This tag requires that the tag GENERATE_QHP is set to YES.
QHG_LOCATION =
# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
# generated, together with the HTML files, they form an Eclipse help plugin. To
# install this plugin and make it available under the help contents menu in
# Eclipse, the contents of the directory containing the HTML and XML files needs
# to be copied into the plugins directory of eclipse. The name of the directory
# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
# After copying Eclipse needs to be restarted before the help appears.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_ECLIPSEHELP = NO
# A unique identifier for the Eclipse help plugin. When installing the plugin
# the directory name containing the HTML and XML files should also have this
# name. Each documentation set should have its own identifier.
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
ECLIPSE_DOC_ID = org.doxygen.Project
# If you want full control over the layout of the generated HTML pages it might
# be necessary to disable the index and replace it with your own. The
# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
# of each HTML page. A value of NO enables the index and the value YES disables
# it. Since the tabs in the index contain the same information as the navigation
# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
DISABLE_INDEX = NO
# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
# structure should be generated to display hierarchical information. If the tag
# value is set to YES, a side panel will be generated containing a tree-like
# index structure (just like the one that is generated for HTML Help). For this
# to work a browser that supports JavaScript, DHTML, CSS and frames is required
# (i.e. any modern browser). Windows users are probably better off using the
# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
# further fine-tune the look of the index. As an example, the default style
# sheet generated by doxygen has an example that shows how to put an image at
# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
# the same information as the tab index, you could consider setting
# DISABLE_INDEX to YES when enabling this option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
GENERATE_TREEVIEW = NO
# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
# doxygen will group on one line in the generated HTML documentation.
#
# Note that a value of 0 will completely suppress the enum values from appearing
# in the overview section.
# Minimum value: 0, maximum value: 20, default value: 4.
# This tag requires that the tag GENERATE_HTML is set to YES.
ENUM_VALUES_PER_LINE = 4
# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
# to set the initial width (in pixels) of the frame in which the tree is shown.
# Minimum value: 0, maximum value: 1500, default value: 250.
# This tag requires that the tag GENERATE_HTML is set to YES.
TREEVIEW_WIDTH = 250
# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
# external symbols imported via tag files in a separate window.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
EXT_LINKS_IN_WINDOW = NO
# Use this tag to change the font size of LaTeX formulas included as images in
# the HTML documentation. When you change the font size after a successful
# doxygen run you need to manually remove any form_*.png images from the HTML
# output directory to force them to be regenerated.
# Minimum value: 8, maximum value: 50, default value: 10.
# This tag requires that the tag GENERATE_HTML is set to YES.
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
# Note that when changing this option you need to delete any form_*.png files in
# the HTML output directory before the changes have effect.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
# http://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
# to it using the MATHJAX_RELPATH option.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
USE_MATHJAX = NO
# When MathJax is enabled you can set the default output format to be used for
# the MathJax output. See the MathJax site (see:
# http://docs.mathjax.org/en/latest/output.html) for more details.
# Possible values are: HTML-CSS (which is slower, but has the best
# compatibility), NativeMML (i.e. MathML) and SVG.
# The default value is: HTML-CSS.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_FORMAT = HTML-CSS
# When MathJax is enabled you need to specify the location relative to the HTML
# output directory using the MATHJAX_RELPATH option. The destination directory
# should contain the MathJax.js script. For instance, if the mathjax directory
# is located at the same level as the HTML output directory, then
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
# MathJax from http://www.mathjax.org before deployment.
# The default value is: http://cdn.mathjax.org/mathjax/latest.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_EXTENSIONS =
# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
# of code that will be used on startup of the MathJax code. See the MathJax site
# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
# example see the documentation.
# This tag requires that the tag USE_MATHJAX is set to YES.
MATHJAX_CODEFILE =
# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
# the HTML output. The underlying search engine uses javascript and DHTML and
# should work on any modern browser. Note that when using HTML help
# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
# there is already a search function so this one should typically be disabled.
# For large projects the javascript based search engine can be slow, then
# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
# search using the keyboard; to jump to the search box use + S
# (what the is depends on the OS and browser, but it is typically
# , /, or both). Inside the search box use the to jump into the search results window, the results can be navigated
# using the . Press to select an item or to cancel
# the search. The filter options can be selected when the cursor is inside the
# search box by pressing +. Also here use the
# to select a filter and or to activate or cancel the filter
# option.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
SEARCHENGINE = YES
# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
# implemented using a web server instead of a web client using Javascript. There
# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
# setting. When disabled, doxygen will generate a PHP script for searching and
# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
# and searching needs to be provided by external tools. See the section
# "External Indexing and Searching" for details.
# The default value is: NO.
# This tag requires that the tag SEARCHENGINE is set to YES.
SERVER_BASED_SEARCH = NO
# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
# script for searching. Instead the search results are written to an XML file
# which needs to be processed by an external indexer. Doxygen will invoke an
# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
# search results.
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: http://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTERNAL_SEARCH = NO
# The SEARCHENGINE_URL should point to a search engine hosted by a web server
# which will return the search results when EXTERNAL_SEARCH is enabled.
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
# Xapian (see: http://xapian.org/). See the section "External Indexing and
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHENGINE_URL =
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
# search data is written to a file for indexing by an external tool. With the
# SEARCHDATA_FILE tag the name of this file can be specified.
# The default file is: searchdata.xml.
# This tag requires that the tag SEARCHENGINE is set to YES.
SEARCHDATA_FILE = searchdata.xml
# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
# projects and redirect the results back to the right project.
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTERNAL_SEARCH_ID =
# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
# projects other than the one defined by this configuration file, but that are
# all added to the same external search index. Each project needs to have a
# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
# to a relative location where the documentation can be found. The format is:
# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
# This tag requires that the tag SEARCHENGINE is set to YES.
EXTRA_SEARCH_MAPPINGS =
#---------------------------------------------------------------------------
# Configuration options related to the LaTeX output
#---------------------------------------------------------------------------
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
# The default value is: YES.
GENERATE_LATEX = YES
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: latex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_OUTPUT = latex
# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
# invoked.
#
# Note that when enabling USE_PDFLATEX this option is only used for generating
# bitmaps for formulas in the HTML output, but not in the Makefile that is
# written to the output directory.
# The default file is: latex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_CMD_NAME = latex
# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
# index for LaTeX.
# The default file is: makeindex.
# This tag requires that the tag GENERATE_LATEX is set to YES.
MAKEINDEX_CMD_NAME = makeindex
# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
# documents. This may be useful for small projects and may help to save some
# trees in general.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
COMPACT_LATEX = NO
# The PAPER_TYPE tag can be used to set the paper type that is used by the
# printer.
# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
# 14 inches) and executive (7.25 x 10.5 inches).
# The default value is: a4.
# This tag requires that the tag GENERATE_LATEX is set to YES.
PAPER_TYPE = a4wide
# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
# that should be included in the LaTeX output. The package can be specified just
# by its name or with the correct syntax as to be used with the LaTeX
# \usepackage command. To get the times font for instance you can specify :
# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times}
# To use the option intlimits with the amsmath package you can specify:
# EXTRA_PACKAGES=[intlimits]{amsmath}
# If left blank no extra packages will be included.
# This tag requires that the tag GENERATE_LATEX is set to YES.
EXTRA_PACKAGES =
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
# generated LaTeX document. The header should contain everything until the first
# chapter. If it is left blank doxygen will generate a standard header. See
# section "Doxygen usage" for information on how to let doxygen write the
# default header to a separate file.
#
# Note: Only use a user-defined header if you know what you are doing! The
# following commands have a special meaning inside the header: $title,
# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
# string, for the replacement values of the other commands the user is referred
# to HTML_HEADER.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HEADER =
# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
# generated LaTeX document. The footer should contain everything after the last
# chapter. If it is left blank doxygen will generate a standard footer. See
# LATEX_HEADER for more information on how to generate a default footer and what
# special commands can be used inside the footer.
#
# Note: Only use a user-defined footer if you know what you are doing!
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_FOOTER =
# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
# LaTeX style sheets that are included after the standard style sheets created
# by doxygen. Using this option one can overrule certain style aspects. Doxygen
# will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
# list).
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_STYLESHEET =
# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
# other source files which should be copied to the LATEX_OUTPUT output
# directory. Note that the files will be copied as-is; there are no commands or
# markers available.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_EXTRA_FILES =
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
# contain links (just like the HTML output) instead of page references. This
# makes the output suitable for online browsing using a PDF viewer.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
PDF_HYPERLINKS = YES
# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
# the PDF file directly from the LaTeX files. Set this option to YES, to get a
# higher quality PDF documentation.
# The default value is: YES.
# This tag requires that the tag GENERATE_LATEX is set to YES.
USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
# command to the generated LaTeX files. This will instruct LaTeX to keep running
# if errors occur, instead of asking the user for help. This option is also used
# when generating formulas in HTML.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_BATCHMODE = NO
# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
# index chapters (such as File Index, Compound Index, etc.) in the output.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_HIDE_INDICES = NO
# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
# code with syntax highlighting in the LaTeX output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# The default value is: plain.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
#---------------------------------------------------------------------------
# Configuration options related to the RTF output
#---------------------------------------------------------------------------
# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
# RTF output is optimized for Word 97 and may not look too pretty with other RTF
# readers/editors.
# The default value is: NO.
GENERATE_RTF = NO
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: rtf.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_OUTPUT = rtf
# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
# documents. This may be useful for small projects and may help to save some
# trees in general.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
COMPACT_RTF = NO
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
# contain hyperlink fields. The RTF file will contain links (just like the HTML
# output) instead of page references. This makes the output suitable for online
# browsing using Word or some other Word compatible readers that support those
# fields.
#
# Note: WordPad (write) and others do not support links.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_HYPERLINKS = NO
# Load stylesheet definitions from file. Syntax is similar to doxygen's config
# file, i.e. a series of assignments. You only have to provide replacements,
# missing definitions are set to their default value.
#
# See also section "Doxygen usage" for information on how to generate the
# default style sheet that doxygen normally uses.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_STYLESHEET_FILE =
# Set optional variables used in the generation of an RTF document. Syntax is
# similar to doxygen's config file. A template extensions file can be generated
# using doxygen -e rtf extensionFile.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_EXTENSIONS_FILE =
# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
# with syntax highlighting in the RTF output.
#
# Note that which sources are shown also depends on other settings such as
# SOURCE_BROWSER.
# The default value is: NO.
# This tag requires that the tag GENERATE_RTF is set to YES.
RTF_SOURCE_CODE = NO
#---------------------------------------------------------------------------
# Configuration options related to the man page output
#---------------------------------------------------------------------------
# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
# classes and files.
# The default value is: NO.
GENERATE_MAN = NO
# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it. A directory man3 will be created inside the directory specified by
# MAN_OUTPUT.
# The default directory is: man.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_OUTPUT = man
# The MAN_EXTENSION tag determines the extension that is added to the generated
# man pages. In case the manual section does not start with a number, the number
# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
# optional.
# The default value is: .3.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_EXTENSION = .3
# The MAN_SUBDIR tag determines the name of the directory created within
# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
# MAN_EXTENSION with the initial . removed.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_SUBDIR =
# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
# will generate one additional man file for each entity documented in the real
# man page(s). These additional files only source the real man page, but without
# them the man command would be unable to find the correct page.
# The default value is: NO.
# This tag requires that the tag GENERATE_MAN is set to YES.
MAN_LINKS = NO
#---------------------------------------------------------------------------
# Configuration options related to the XML output
#---------------------------------------------------------------------------
# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
# captures the structure of the code including all documentation.
# The default value is: NO.
GENERATE_XML = NO
# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
# it.
# The default directory is: xml.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_OUTPUT = xml
# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
# listings (including syntax highlighting and cross-referencing information) to
# the XML output. Note that enabling this will significantly increase the size
# of the XML output.
# The default value is: YES.
# This tag requires that the tag GENERATE_XML is set to YES.
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# Configuration options related to the DOCBOOK output
#---------------------------------------------------------------------------
# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
# that can be used to generate PDF.
# The default value is: NO.
GENERATE_DOCBOOK = NO
# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
# front of it.
# The default directory is: docbook.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_OUTPUT = docbook
# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
# program listings (including syntax highlighting and cross-referencing
# information) to the DOCBOOK output. Note that enabling this will significantly
# increase the size of the DOCBOOK output.
# The default value is: NO.
# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
DOCBOOK_PROGRAMLISTING = NO
#---------------------------------------------------------------------------
# Configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
# AutoGen Definitions (see http://autogen.sf.net) file that captures the
# structure of the code including all documentation. Note that this feature is
# still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
# file that captures the structure of the code including all documentation.
#
# Note that this feature is still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_PERLMOD = NO
# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
# output from the Perl module output.
# The default value is: NO.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_LATEX = NO
# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
# formatted so it can be parsed by a human reader. This is useful if you want to
# understand what is going on. On the other hand, if this tag is set to NO, the
# size of the Perl module output will be much smaller and Perl will parse it
# just the same.
# The default value is: YES.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_PRETTY = YES
# The names of the make variables in the generated doxyrules.make file are
# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
# so different doxyrules.make files included by the same Makefile don't
# overwrite each other's variables.
# This tag requires that the tag GENERATE_PERLMOD is set to YES.
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
# C-preprocessor directives found in the sources and include files.
# The default value is: YES.
ENABLE_PREPROCESSING = YES
# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
# in the source code. If set to NO, only conditional compilation will be
# performed. Macro expansion can be done in a controlled way by setting
# EXPAND_ONLY_PREDEF to YES.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
MACRO_EXPANSION = NO
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
# the macro expansion is limited to the macros specified with the PREDEFINED and
# EXPAND_AS_DEFINED tags.
# The default value is: NO.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_ONLY_PREDEF = NO
# If the SEARCH_INCLUDES tag is set to YES, the include files in the
# INCLUDE_PATH will be searched if a #include is found.
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by the
# preprocessor.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
# patterns (like *.h and *.hpp) to filter out the header-files in the
# directories. If left blank, the patterns specified with FILE_PATTERNS will be
# used.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
INCLUDE_FILE_PATTERNS =
# The PREDEFINED tag can be used to specify one or more macro names that are
# defined before the preprocessor is started (similar to the -D option of e.g.
# gcc). The argument of the tag is a list of macros of the form: name or
# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
# is assumed. To prevent a macro definition from being undefined via #undef or
# recursively expanded use the := operator instead of the = operator.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
PREDEFINED =
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
# tag can be used to specify a list of macro names that should be expanded. The
# macro definition that is found in the sources will be used. Use the PREDEFINED
# tag if you want to use a different macro definition that overrules the
# definition found in the source code.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
EXPAND_AS_DEFINED =
# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
# remove all references to function-like macros that are alone on a line, have
# an all uppercase name, and do not end with a semicolon. Such function macros
# are typically used for boiler-plate code, and will confuse the parser if not
# removed.
# The default value is: YES.
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration options related to external references
#---------------------------------------------------------------------------
# The TAGFILES tag can be used to specify one or more tag files. For each tag
# file the location of the external documentation should be added. The format of
# a tag file without this location is as follows:
# TAGFILES = file1 file2 ...
# Adding location for the tag files is done as follows:
# TAGFILES = file1=loc1 "file2 = loc2" ...
# where loc1 and loc2 can be relative or absolute paths or URLs. See the
# section "Linking to external documentation" for more information about the use
# of tag files.
# Note: Each tag file must have a unique name (where the name does NOT include
# the path). If a tag file is not located in the directory in which doxygen is
# run, you must also specify the path to the tagfile here.
TAGFILES =
# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
# tag file that is based on the input files it reads. See section "Linking to
# external documentation" for more information about the usage of tag files.
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
# the class index. If set to NO, only the inherited external classes will be
# listed.
# The default value is: NO.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will be
# listed.
# The default value is: YES.
EXTERNAL_GROUPS = YES
# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
# the related pages index. If set to NO, only the current project's pages will
# be listed.
# The default value is: YES.
EXTERNAL_PAGES = YES
# The PERL_PATH should be the absolute path and name of the perl script
# interpreter (i.e. the result of 'which perl').
# The default file (with absolute path) is: /usr/bin/perl.
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
MSCGEN_PATH =
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
# If left empty dia is assumed to be found in the default search path.
DIA_PATH =
# If set to YES the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
# The default value is: YES.
HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: YES.
HAVE_DOT = NO
# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
# to run in parallel. When set to 0 doxygen will base this on the number of
# processors available in the system. You can set it explicitly to a value
# larger than 0 to get control over the balance between CPU load and processing
# speed.
# Minimum value: 0, maximum value: 32, default value: 0.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_NUM_THREADS = 0
# When you want a differently looking font in the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by
# setting DOT_FONTPATH to the directory containing the font.
# The default value is: Helvetica.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTNAME = Helvetica
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs.
# Minimum value: 4, maximum value: 24, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTSIZE = 10
# By default doxygen will tell dot to use the default font as specified with
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
# the path where dot can find it using this tag.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTPATH =
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
# each documented class showing the direct and indirect inheritance relations.
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
# graph for each documented class showing the direct and indirect implementation
# dependencies (inheritance, containment, and class references variables) of the
# class with other documented classes.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
COLLABORATION_GRAPH = YES
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
# groups, showing the direct groups dependencies.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GROUP_GRAPHS = YES
# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
# collaboration diagrams in a style similar to the OMG's Unified Modeling
# Language.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
UML_LOOK = NO
# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
# class node. If there are many fields or methods and many nodes the graph may
# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
# number of items for each type to make the size more manageable. Set this to 0
# for no limit. Note that the threshold may be exceeded by 50% before the limit
# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
# but if the number exceeds 15, the total amount of fields shown is limited to
# 10.
# Minimum value: 0, maximum value: 100, default value: 10.
# This tag requires that the tag HAVE_DOT is set to YES.
UML_LIMIT_NUM_FIELDS = 10
# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
# collaboration graphs will show the relations between templates and their
# instances.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
TEMPLATE_RELATIONS = NO
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
# YES then doxygen will generate a graph for each documented file showing the
# direct and indirect include dependencies of the file with other documented
# files.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
INCLUDE_GRAPH = YES
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
# set to YES then doxygen will generate a graph for each documented file showing
# the direct and indirect include dependencies of the file with other documented
# files.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
INCLUDED_BY_GRAPH = YES
# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
# dependency graph for every global function or class method.
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable call graphs for selected
# functions only using the \callgraph command. Disabling a call graph can be
# accomplished by means of the command \hidecallgraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALL_GRAPH = NO
# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
# dependency graph for every global function or class method.
#
# Note that enabling this option will significantly increase the time of a run.
# So in most cases it will be better to enable caller graphs for selected
# functions only using the \callergraph command. Disabling a caller graph can be
# accomplished by means of the command \hidecallergraph.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
CALLER_GRAPH = NO
# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
# hierarchy of all classes instead of a textual one.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GRAPHICAL_HIERARCHY = YES
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
# dependencies a directory has on other directories in a graphical way. The
# dependency relations are determined by the #include relations between the
# files in the directories.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
DIRECTORY_GRAPH = YES
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. For an explanation of the image formats see the section
# output formats in the documentation of the dot tool (Graphviz (see:
# http://www.graphviz.org/)).
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo,
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and
# png:gdiplus:gdiplus.
# The default value is: png.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_IMAGE_FORMAT = png
# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
# enable generation of interactive SVG images that allow zooming and panning.
#
# Note that this requires a modern browser other than Internet Explorer. Tested
# and working are Firefox, Chrome, Safari, and Opera.
# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
# the SVG files visible. Older versions of IE do not have SVG support.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
INTERACTIVE_SVG = NO
# The DOT_PATH tag can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_PATH =
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the \dotfile
# command).
# This tag requires that the tag HAVE_DOT is set to YES.
DOTFILE_DIRS =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
# command).
MSCFILE_DIRS =
# The DIAFILE_DIRS tag can be used to specify one or more directories that
# contain dia files that are included in the documentation (see the \diafile
# command).
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
# PlantUML is not used or called during a preprocessing step. Doxygen will
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
PLANTUML_JAR_PATH =
# When using plantuml, the specified paths are searched for files specified by
# the !include statement in a plantuml block.
PLANTUML_INCLUDE_PATH =
# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
# that will be shown in the graph. If the number of nodes in a graph becomes
# larger than this value, doxygen will truncate the graph, which is visualized
# by representing a node as a red box. Note that doxygen if the number of direct
# children of the root node in a graph is already larger than
# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
# Minimum value: 0, maximum value: 10000, default value: 50.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_GRAPH_MAX_NODES = 50
# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
# generated by dot. A depth value of 3 means that only nodes reachable from the
# root by following a path via at most 3 edges will be shown. Nodes that lay
# further from the root node will be omitted. Note that setting this option to 1
# or 2 may greatly reduce the computation time needed for large code bases. Also
# note that the size of a graph can be further restricted by
# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
# Minimum value: 0, maximum value: 1000, default value: 0.
# This tag requires that the tag HAVE_DOT is set to YES.
MAX_DOT_GRAPH_DEPTH = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not seem
# to support this out of the box.
#
# Warning: Depending on the platform used, enabling this option may lead to
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
# read).
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
# this, this feature is disabled by default.
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_MULTI_TARGETS = NO
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
# graphs.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
GENERATE_LEGEND = YES
# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
# files that are used to generate the various graphs.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_CLEANUP = YES
rhash-1.4.6/librhash/byte_order.c 0000664 0000000 0000000 00000023520 15010476501 015426 0 ustar root root /* byte_order.c - byte order related platform dependent routines,
*
* Copyright (c) 2008, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "byte_order.h"
#include
#ifndef rhash_ctz
# if _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64) /* if MSVC++ >= 2002 on x86/x64 */
# include
# pragma intrinsic(_BitScanForward)
/**
* Returns index of the trailing bit of x.
*
* @param x the number to process
* @return zero-based index of the trailing bit
*/
unsigned rhash_ctz(unsigned x)
{
unsigned long index;
unsigned char isNonzero = _BitScanForward(&index, x); /* MSVC intrinsic */
return (isNonzero ? (unsigned)index : 0);
}
# else /* _MSC_VER >= 1300... */
/**
* Returns index of the least significant set bit in a 32-bit number.
* This operation is also known as Count Trailing Zeros (CTZ).
*
* The function is a portable, branch-free equivalent of GCC's __builtin_ctz(),
* using a De Bruijn sequence for constant-time lookup.
*
* @param x 32-bit unsigned integer to analyze (must not be zero)
* @return zero-based index of the least significant set bit (0 to 31)
*
* @note Undefined behavior when `x == 0`. The current implementation
* returns 0, but this value must not be relied upon.
*/
unsigned rhash_ctz(unsigned x)
{
/* array for conversion to bit position */
static unsigned char bit_pos[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
/* The De Bruijn bit-scan was devised in 1997, according to Donald Knuth
* by Martin Lauter. The constant 0x077CB531UL is a De Bruijn sequence,
* which produces a unique pattern of bits into the high 5 bits for each
* possible bit position that it is multiplied against.
* See http://graphics.stanford.edu/~seander/bithacks.html
* and http://chessprogramming.wikispaces.com/BitScan */
return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27];
}
# endif /* _MSC_VER >= 1300... */
#endif /* rhash_ctz */
#ifndef rhash_ctz64
/**
* Returns the zero-based index of the least significant set bit in a 64-bit number.
* This operation is also known as Count Trailing Zeros (CTZ).
*
* The function is a portable, branch-free equivalent of GCC's __builtin_ctzll().
* Uses a 32-bit optimized implementation with magic constant `0x78291ACF`,
* based on Matt Taylor's original algorithm (2003).
*
* @param x 64-bit unsigned integer to analyze (must not be zero)
* @return zero-based index of the least significant set bit (0 to 63)
*
* @note Undefined behavior when `x == 0`. The current implementation
* returns 63, but this value must not be relied upon.
* @see rhash_ctz() for 32-bit version.
*/
unsigned rhash_ctz64(uint64_t x)
{
/* lookup table mapping hash values to bit position */
static unsigned char bit_pos[64] = {
63, 30, 3, 32, 59, 14, 11, 33, 60, 24, 50, 9, 55, 19, 21, 34,
61, 29, 2, 53, 51, 23, 41, 18, 56, 28, 1, 43, 46, 27, 0, 35,
62, 31, 58, 4, 5, 49, 54, 6, 15, 52, 12, 40, 7, 42, 45, 16,
25, 57, 48, 13, 10, 39, 8, 44, 20, 47, 38, 22, 17, 37, 36, 26
};
/* transform 0b01000 -> 0b01111 (isolate least significant bit) */
x ^= x - 1;
/* fold 64-bit value to 32-bit to be efficient on 32-bit systems */
uint32_t folded = (uint32_t)((x >> 32) ^ x);
/* Use Matt Taylor's multiplication trick (2003):
* - multiply by (specially chosen) magic constant 0x78291ACF
* - use top 6 bits of result (>>26) as table index
* Original discussion:
* https://groups.google.com/g/comp.lang.asm.x86/c/3pVGzQGb1ys/m/fPpKBKNi848J
* https://groups.google.com/g/comp.lang.asm.x86/c/3pVGzQGb1ys/m/230qffQJYvQJ
*/
return bit_pos[folded * 0x78291ACF >> 26];
}
#endif /* rhash_ctz64 */
#ifndef rhash_popcount
/**
* Returns the number of 1-bits in x.
*
* @param x the value to process
* @return the number of 1-bits
*/
unsigned rhash_popcount(unsigned x)
{
x -= (x >>1) & 0x55555555;
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
x = ((x >> 4) + x) & 0x0f0f0f0f;
return (x * 0x01010101) >> 24;
}
#endif /* rhash_popcount */
/**
* Copy a memory block with simultaneous exchanging byte order.
* The byte order is changed from little-endian 32-bit integers
* to big-endian (or vice-versa).
*
* @param to the pointer where to copy memory block
* @param index the index to start writing from
* @param from the source block to copy
* @param length length of the memory block
*/
void rhash_swap_copy_str_to_u32(void* to, int index, const void* from, size_t length)
{
/* if all pointers and length are 32-bits aligned */
if ( 0 == (( (uintptr_t)to | (uintptr_t)from | (uintptr_t)index | length ) & 3) ) {
/* copy memory as 32-bit words */
const uint32_t* src = (const uint32_t*)from;
const uint32_t* end = (const uint32_t*)((const char*)src + length);
uint32_t* dst = (uint32_t*)((char*)to + index);
for (; src < end; dst++, src++)
*dst = bswap_32(*src);
} else {
const char* src = (const char*)from;
for (length += index; (size_t)index < length; index++)
((char*)to)[index ^ 3] = *(src++);
}
}
/**
* Fill a memory block by a character with changing byte order.
* The byte order is changed from little-endian 32-bit integers
* to big-endian (or vice-versa).
*
* @param to the pointer where to copy memory block
* @param index the index to start writing from
* @param c the character to fill the block with
* @param length length of the memory block
*/
void rhash_swap_memset_to_u32(void* to, int index, int c, size_t length)
{
const size_t end = length + (size_t)index;
for (; (index & 3) && (size_t)index < end; index++)
((char*)to)[index ^ 3] = (char)c;
length = end - (size_t)index;
memset((char*)to + index, c, length & ~3);
for (; (size_t)index < end; index++)
((char*)to)[index ^ 3] = (char)c;
}
/**
* Copy a memory block with changed byte order.
* The byte order is changed from little-endian 64-bit integers
* to big-endian (or vice-versa).
*
* @param to the pointer where to copy memory block
* @param index the index to start writing from
* @param from the source block to copy
* @param length length of the memory block
*/
void rhash_swap_copy_str_to_u64(void* to, int index, const void* from, size_t length)
{
/* if all pointers and length are 64-bits aligned */
if ( 0 == (( (uintptr_t)to | (uintptr_t)from | (uintptr_t)index | length ) & 7) ) {
/* copy aligned memory block as 64-bit integers */
const uint64_t* src = (const uint64_t*)from;
const uint64_t* end = (const uint64_t*)((const char*)src + length);
uint64_t* dst = (uint64_t*)((char*)to + index);
while (src < end) *(dst++) = bswap_64( *(src++) );
} else {
const char* src = (const char*)from;
for (length += index; (size_t)index < length; index++) ((char*)to)[index ^ 7] = *(src++);
}
}
/**
* Copy data from a sequence of 64-bit words to a binary string of given length,
* while changing byte order.
*
* @param to the binary string to receive data
* @param from the source sequence of 64-bit words
* @param length the size in bytes of the data being copied
*/
void rhash_swap_copy_u64_to_str(void* to, const void* from, size_t length)
{
/* if all pointers and length are 64-bits aligned */
if ( 0 == (( (uintptr_t)to | (uintptr_t)from | length ) & 7) ) {
/* copy aligned memory block as 64-bit integers */
const uint64_t* src = (const uint64_t*)from;
const uint64_t* end = (const uint64_t*)((const char*)src + length);
uint64_t* dst = (uint64_t*)to;
while (src < end) *(dst++) = bswap_64( *(src++) );
} else {
size_t index;
char* dst = (char*)to;
for (index = 0; index < length; index++) *(dst++) = ((char*)from)[index ^ 7];
}
}
/**
* Exchange byte order in the given array of 32-bit integers.
*
* @param arr the array to process
* @param length array length
*/
void rhash_u32_mem_swap(unsigned* arr, int length)
{
unsigned* end = arr + length;
for (; arr < end; arr++) {
*arr = bswap_32(*arr);
}
}
#if !defined(has_cpu_feature)
# if defined(HAS_GCC_INTEL_CPUID)
# include
# define RHASH_CPUID(id, regs) \
__get_cpuid(id, &(regs[0]), &(regs[1]), &(regs[2]), &(regs[3]));
# if HAS_GNUC(6, 3)
# define RHASH_CPUIDEX(id, sub_id, regs) \
__get_cpuid_count(id, sub_id, ®s[0], ®s[1], ®s[2], ®s[3]);
# endif
# elif defined(HAS_MSVC_INTEL_CPUID)
# define RHASH_CPUID(id, regs) __cpuid((int*)regs, id)
# if _MSC_VER >= 1600
# define RHASH_CPUIDEX(id, sub_id, regs) __cpuidex((int*)regs, id, sub_id);
# endif
# else
# error "Unsupported platform"
#endif /* HAS_GCC_INTEL_CPUID */
static uint64_t get_cpuid_features(void)
{
uint32_t cpu_info[4] = {0};
uint64_t result = 0;
/* Request basic CPU functions */
RHASH_CPUID(1, cpu_info);
/* Store features, but clear bit 29 to store SHANI bit later */
result = ((((uint64_t)cpu_info[2]) << 32) ^
(cpu_info[3] & ~(1 << 29)));
#ifdef RHASH_CPUIDEX
/* Check if CPUID requests for feature_id >= 7 are supported */
RHASH_CPUID(0, cpu_info);
if (cpu_info[0] >= 7)
{
/* Request CPUID AX=7 CX=0 to get SHANI bit */
RHASH_CPUIDEX(7, 0, cpu_info);
result |= (cpu_info[1] & (1 << 29));
}
#endif
return result;
}
int has_cpu_feature(unsigned feature_bit)
{
static uint64_t features;
const uint64_t feature = I64(1) << feature_bit;
if (!features)
features = (get_cpuid_features() | 1);
return !!(features & feature);
}
#endif /* has_cpu_feature */
rhash-1.4.6/librhash/tiger.c 0000664 0000000 0000000 00000014632 14703622112 014405 0 ustar root root /* tiger.c - an implementation of Tiger Hash Function
* based on the article by
* Ross Anderson and Eli Biham "Tiger: A Fast New Hash Function".
*
* Copyright (c) 2007, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include "byte_order.h"
#include "tiger.h"
#ifdef NO_TIGER2
# define TIGER2_FLAG I64(0)
#else
# define TIGER2_FLAG I64(0x8000000000000000)
#endif /* NO_TIGER2 */
#define LENGTH_MASK (~TIGER2_FLAG)
#define INITIALIZE_TIGER_STATE(state) \
state[0] = I64(0x0123456789ABCDEF); \
state[1] = I64(0xFEDCBA9876543210); \
state[2] = I64(0xF096A5B4C3B2E187);
/**
* Initialize Tiger context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_tiger_init(tiger_ctx* ctx)
{
ctx->length = 0;
INITIALIZE_TIGER_STATE(ctx->hash);
}
#ifndef NO_TIGER2
/**
* Initialize Tiger2 context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_tiger2_init(tiger_ctx* ctx)
{
ctx->length = TIGER2_FLAG;
INITIALIZE_TIGER_STATE(ctx->hash);
}
#endif /* NO_TIGER2 */
/* lookup tables */
extern uint64_t rhash_tiger_sboxes[4][256];
#define t1 rhash_tiger_sboxes[0]
#define t2 rhash_tiger_sboxes[1]
#define t3 rhash_tiger_sboxes[2]
#define t4 rhash_tiger_sboxes[3]
#ifdef CPU_X64 /* for x86-64 */
#define round(a,b,c,x,mul) \
c ^= x; \
a -= t1[(uint8_t)(c)] ^ \
t2[(uint8_t)((c) >> (2 * 8))] ^ \
t3[(uint8_t)((c) >> (4 * 8))] ^ \
t4[(uint8_t)((c) >> (6 * 8))] ; \
b += t4[(uint8_t)((c) >> (1 * 8))] ^ \
t3[(uint8_t)((c) >> (3 * 8))] ^ \
t2[(uint8_t)((c) >> (5 * 8))] ^ \
t1[(uint8_t)((c) >> (7 * 8))]; \
b *= mul;
#else /* for IA32 */
#define round(a,b,c,x,mul) \
c ^= x; \
a -= t1[(uint8_t)(c)] ^ \
t2[(uint8_t)(((uint32_t)(c)) >> (2 * 8))] ^ \
t3[(uint8_t)((c) >> (4 * 8))] ^ \
t4[(uint8_t)(((uint32_t)((c) >> (4 * 8))) >> (2 * 8))] ; \
b += t4[(uint8_t)(((uint32_t)(c)) >> (1 * 8))] ^ \
t3[(uint8_t)(((uint32_t)(c)) >> (3 * 8))] ^ \
t2[(uint8_t)(((uint32_t)((c) >> (4 * 8))) >> (1 * 8))] ^ \
t1[(uint8_t)(((uint32_t)((c) >> (4 * 8))) >> (3 * 8))]; \
b *= mul;
#endif /* CPU_X64 */
#define pass(a,b,c,mul) \
round(a,b,c,x0,mul) \
round(b,c,a,x1,mul) \
round(c,a,b,x2,mul) \
round(a,b,c,x3,mul) \
round(b,c,a,x4,mul) \
round(c,a,b,x5,mul) \
round(a,b,c,x6,mul) \
round(b,c,a,x7,mul)
#define key_schedule { \
x0 -= x7 ^ I64(0xA5A5A5A5A5A5A5A5); \
x1 ^= x0; \
x2 += x1; \
x3 -= x2 ^ ((~x1)<<19); \
x4 ^= x3; \
x5 += x4; \
x6 -= x5 ^ ((~x4)>>23); \
x7 ^= x6; \
x0 += x7; \
x1 -= x0 ^ ((~x7)<<19); \
x2 ^= x1; \
x3 += x2; \
x4 -= x3 ^ ((~x2)>>23); \
x5 ^= x4; \
x6 += x5; \
x7 -= x6 ^ I64(0x0123456789ABCDEF); \
}
/**
* The core transformation. Process a 512-bit block.
*
* @param state the algorithm state
* @param block the message block to process
*/
static void rhash_tiger_process_block(uint64_t state[3], uint64_t* block)
{
/* Optimized for GCC IA32.
The order of declarations is important for compiler. */
uint64_t a, b, c;
uint64_t x0, x1, x2, x3, x4, x5, x6, x7;
#ifndef CPU_X64
uint64_t tmp;
char i;
#endif
x0 = le2me_64(block[0]); x1 = le2me_64(block[1]);
x2 = le2me_64(block[2]); x3 = le2me_64(block[3]);
x4 = le2me_64(block[4]); x5 = le2me_64(block[5]);
x6 = le2me_64(block[6]); x7 = le2me_64(block[7]);
a = state[0];
b = state[1];
c = state[2];
/* passes and key shedules */
#ifndef CPU_X64
for (i = 0; i < 3; i++) {
if (i != 0) key_schedule;
pass(a, b, c, (i == 0 ? 5 : i == 1 ? 7 : 9));
tmp = a;
a = c;
c = b;
b = tmp;
}
#else
pass(a, b, c, 5);
key_schedule;
pass(c, a, b, 7);
key_schedule;
pass(b, c, a, 9);
#endif
/* feedforward operation */
state[0] = a ^ state[0];
state[1] = b - state[1];
state[2] = c + state[2];
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_tiger_update(tiger_ctx* ctx, const unsigned char* msg, size_t size)
{
size_t index = (size_t)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
size_t left = tiger_block_size - index;
if (size < left) {
if (size > 0)
memcpy(ctx->message + index, msg, size);
return;
} else {
memcpy(ctx->message + index, msg, left);
rhash_tiger_process_block(ctx->hash, (uint64_t*)ctx->message);
msg += left;
size -= left;
}
}
while (size >= tiger_block_size) {
if (IS_ALIGNED_64(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
rhash_tiger_process_block(ctx->hash, (uint64_t*)msg);
} else {
memcpy(ctx->message, msg, tiger_block_size);
rhash_tiger_process_block(ctx->hash, (uint64_t*)ctx->message);
}
msg += tiger_block_size;
size -= tiger_block_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_tiger_final(tiger_ctx* ctx, unsigned char result[24])
{
unsigned index = (unsigned)ctx->length & 63;
uint64_t* msg64 = (uint64_t*)ctx->message;
/* pad message and run for last block */
/* append the byte 0x01 to the message */
ctx->message[index++] = (ctx->length & TIGER2_FLAG ? 0x80 : 0x01);
/* if no room left in the message to store 64-bit message length */
if (index > 56) {
/* then fill the rest with zeros and process it */
while (index < 64) {
ctx->message[index++] = 0;
}
rhash_tiger_process_block(ctx->hash, msg64);
index = 0;
}
while (index < 56) {
ctx->message[index++] = 0;
}
msg64[7] = le2me_64((ctx->length & LENGTH_MASK) << 3);
rhash_tiger_process_block(ctx->hash, msg64);
/* save result hash */
le64_copy(result, 0, &ctx->hash, 24);
}
rhash-1.4.6/librhash/tth.h 0000664 0000000 0000000 00000001440 14703622112 014070 0 ustar root root #ifndef TTH_H
#define TTH_H
#include "ustd.h"
#include "tiger.h"
#ifdef __cplusplus
extern "C" {
#endif
/* algorithm context */
typedef struct tth_ctx
{
tiger_ctx tiger; /* context used to hash tree leaves */
uint64_t block_count; /* number of processed blocks */
uint64_t stack[64 * 3];
} tth_ctx;
/* hash functions */
void rhash_tth_init(tth_ctx* ctx);
void rhash_tth_update(tth_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_tth_final(tth_ctx* ctx, unsigned char result[24]);
#if !defined(NO_IMPORT_EXPORT)
size_t rhash_tth_export(const tth_ctx* ctx, void* out, size_t size);
size_t rhash_tth_import(tth_ctx* ctx, const void* in, size_t size);
#endif /* !defined(NO_IMPORT_EXPORT) */
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* TTH_H */
rhash-1.4.6/librhash/rhash_torrent.h 0000664 0000000 0000000 00000006000 14703622112 016150 0 ustar root root /* rhash_torrent.h */
#ifndef RHASH_TORRENT_H
#define RHASH_TORRENT_H
#include
#ifdef __cplusplus
extern "C" {
#endif
#ifndef RHASH_API
/* modifier for LibRHash functions */
# define RHASH_API
#endif
#ifndef LIBRHASH_RHASH_CTX_DEFINED
#define LIBRHASH_RHASH_CTX_DEFINED
/**
* Hashing context.
*/
typedef struct rhash_context* rhash;
#endif /* LIBRHASH_RHASH_CTX_DEFINED */
/**
* Binary string with length.
*/
typedef struct rhash_str
{
char* str;
size_t length;
} rhash_str;
/* possible torrent options */
/**
* Torrent option: generate private BitTorrent.
*/
#define RHASH_TORRENT_OPT_PRIVATE 1
/**
* Torrent option: calculate infohash without torrent file body.
*/
#define RHASH_TORRENT_OPT_INFOHASH_ONLY 2
/**
* Torrent option: generate transmiision-compatible torrent file.
*/
#define RHASH_TORRENT_OPT_TRANSMISSION 4
/* torrent functions */
/**
* Add a file info into the batch of files of given torrent.
*
* @param ctx rhash context
* @param filepath file path
* @param filesize file size
* @return non-zero on success, zero on fail
*/
RHASH_API int rhash_torrent_add_file(rhash ctx, const char* filepath, unsigned long long filesize);
/**
* Set the torrent algorithm options.
*
* @param ctx rhash context
* @param options the options to set
*/
RHASH_API void rhash_torrent_set_options(rhash ctx, unsigned options);
/**
* Add an torrent announcement-URL for storing into torrent file.
*
* @param ctx rhash context
* @param announce_url the announcement-URL
* @return non-zero on success, zero on error
*/
RHASH_API int rhash_torrent_add_announce(rhash ctx, const char* announce_url);
/**
* Set optional name of the program generating the torrent
* for storing into torrent file.
*
* @param ctx rhash context
* @param name the program name
* @return non-zero on success, zero on error
*/
RHASH_API int rhash_torrent_set_program_name(rhash ctx, const char* name);
/**
* Set length of a file piece.
*
* @param ctx rhash context
* @param piece_length the piece length in bytes
*/
RHASH_API void rhash_torrent_set_piece_length(rhash ctx, size_t piece_length);
/**
* Calculate, using uTorrent algorithm, the default torrent piece length
* for a given torrent batch size.
*
* @param total_size the total size of files included into a torrent file
* @return piece length for the torrent file
*/
RHASH_API size_t rhash_torrent_get_default_piece_length(unsigned long long total_size);
/**
* Set a torrent batch size (the total size of files included into this torrent).
*
* @param ctx rhash context
* @param total_size total size of files included into the torrent file
*/
RHASH_API void rhash_torrent_set_batch_size(rhash ctx, unsigned long long total_size);
/**
* Get the content of the generated torrent file.
*
* @param ctx rhash context
* @return binary string with the torrent file content on success, NULL on fail
*/
RHASH_API const rhash_str* rhash_torrent_generate_content(rhash ctx);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_TORRENT_H */
rhash-1.4.6/librhash/gost12.h 0000664 0000000 0000000 00000001323 14703622112 014410 0 ustar root root /* gost12.h */
#ifndef GOST12_H
#define GOST12_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define gost12_block_size 64
#define gost12_256_hash_size 32
#define gost12_512_hash_size 64
/* algorithm context */
typedef struct gost12_ctx {
uint64_t h[8];
uint64_t N[8];
uint64_t S[8];
uint64_t message[8];
unsigned index;
unsigned hash_size;
} gost12_ctx;
/* hash functions */
void rhash_gost12_256_init(gost12_ctx* ctx);
void rhash_gost12_512_init(gost12_ctx* ctx);
void rhash_gost12_update(gost12_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_gost12_final(gost12_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* GOST12_H */
rhash-1.4.6/librhash/md5.c 0000664 0000000 0000000 00000017424 14703622112 013762 0 ustar root root /* md5.c - an implementation of the MD5 algorithm, based on RFC 1321.
*
* Copyright (c) 2007, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include "byte_order.h"
#include "md5.h"
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_md5_init(md5_ctx* ctx)
{
memset(ctx, 0, sizeof(*ctx));
/* initialize state */
ctx->hash[0] = 0x67452301;
ctx->hash[1] = 0xefcdab89;
ctx->hash[2] = 0x98badcfe;
ctx->hash[3] = 0x10325476;
}
/* First, define four auxiliary functions that each take as input
* three 32-bit words and returns a 32-bit word.*/
/* F(x,y,z) = ((y XOR z) AND x) XOR z - is faster then original version */
#define MD5_F(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))
#define MD5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define MD5_H(x, y, z) ((x) ^ (y) ^ (z))
#define MD5_I(x, y, z) ((y) ^ ((x) | (~z)))
/* transformations for rounds 1, 2, 3, and 4. */
#define MD5_ROUND1(a, b, c, d, x, s, ac) { \
(a) += MD5_F((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
}
#define MD5_ROUND2(a, b, c, d, x, s, ac) { \
(a) += MD5_G((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
}
#define MD5_ROUND3(a, b, c, d, x, s, ac) { \
(a) += MD5_H((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
}
#define MD5_ROUND4(a, b, c, d, x, s, ac) { \
(a) += MD5_I((b), (c), (d)) + (x) + (ac); \
(a) = ROTL32((a), (s)); \
(a) += (b); \
}
/**
* The core transformation. Process a 512-bit block.
* The function has been taken from RFC 1321 with little changes.
*
* @param state algorithm state
* @param x the message block to process
*/
static void rhash_md5_process_block(unsigned state[4], const unsigned* x)
{
register unsigned a, b, c, d;
a = state[0];
b = state[1];
c = state[2];
d = state[3];
MD5_ROUND1(a, b, c, d, x[ 0], 7, 0xd76aa478);
MD5_ROUND1(d, a, b, c, x[ 1], 12, 0xe8c7b756);
MD5_ROUND1(c, d, a, b, x[ 2], 17, 0x242070db);
MD5_ROUND1(b, c, d, a, x[ 3], 22, 0xc1bdceee);
MD5_ROUND1(a, b, c, d, x[ 4], 7, 0xf57c0faf);
MD5_ROUND1(d, a, b, c, x[ 5], 12, 0x4787c62a);
MD5_ROUND1(c, d, a, b, x[ 6], 17, 0xa8304613);
MD5_ROUND1(b, c, d, a, x[ 7], 22, 0xfd469501);
MD5_ROUND1(a, b, c, d, x[ 8], 7, 0x698098d8);
MD5_ROUND1(d, a, b, c, x[ 9], 12, 0x8b44f7af);
MD5_ROUND1(c, d, a, b, x[10], 17, 0xffff5bb1);
MD5_ROUND1(b, c, d, a, x[11], 22, 0x895cd7be);
MD5_ROUND1(a, b, c, d, x[12], 7, 0x6b901122);
MD5_ROUND1(d, a, b, c, x[13], 12, 0xfd987193);
MD5_ROUND1(c, d, a, b, x[14], 17, 0xa679438e);
MD5_ROUND1(b, c, d, a, x[15], 22, 0x49b40821);
MD5_ROUND2(a, b, c, d, x[ 1], 5, 0xf61e2562);
MD5_ROUND2(d, a, b, c, x[ 6], 9, 0xc040b340);
MD5_ROUND2(c, d, a, b, x[11], 14, 0x265e5a51);
MD5_ROUND2(b, c, d, a, x[ 0], 20, 0xe9b6c7aa);
MD5_ROUND2(a, b, c, d, x[ 5], 5, 0xd62f105d);
MD5_ROUND2(d, a, b, c, x[10], 9, 0x2441453);
MD5_ROUND2(c, d, a, b, x[15], 14, 0xd8a1e681);
MD5_ROUND2(b, c, d, a, x[ 4], 20, 0xe7d3fbc8);
MD5_ROUND2(a, b, c, d, x[ 9], 5, 0x21e1cde6);
MD5_ROUND2(d, a, b, c, x[14], 9, 0xc33707d6);
MD5_ROUND2(c, d, a, b, x[ 3], 14, 0xf4d50d87);
MD5_ROUND2(b, c, d, a, x[ 8], 20, 0x455a14ed);
MD5_ROUND2(a, b, c, d, x[13], 5, 0xa9e3e905);
MD5_ROUND2(d, a, b, c, x[ 2], 9, 0xfcefa3f8);
MD5_ROUND2(c, d, a, b, x[ 7], 14, 0x676f02d9);
MD5_ROUND2(b, c, d, a, x[12], 20, 0x8d2a4c8a);
MD5_ROUND3(a, b, c, d, x[ 5], 4, 0xfffa3942);
MD5_ROUND3(d, a, b, c, x[ 8], 11, 0x8771f681);
MD5_ROUND3(c, d, a, b, x[11], 16, 0x6d9d6122);
MD5_ROUND3(b, c, d, a, x[14], 23, 0xfde5380c);
MD5_ROUND3(a, b, c, d, x[ 1], 4, 0xa4beea44);
MD5_ROUND3(d, a, b, c, x[ 4], 11, 0x4bdecfa9);
MD5_ROUND3(c, d, a, b, x[ 7], 16, 0xf6bb4b60);
MD5_ROUND3(b, c, d, a, x[10], 23, 0xbebfbc70);
MD5_ROUND3(a, b, c, d, x[13], 4, 0x289b7ec6);
MD5_ROUND3(d, a, b, c, x[ 0], 11, 0xeaa127fa);
MD5_ROUND3(c, d, a, b, x[ 3], 16, 0xd4ef3085);
MD5_ROUND3(b, c, d, a, x[ 6], 23, 0x4881d05);
MD5_ROUND3(a, b, c, d, x[ 9], 4, 0xd9d4d039);
MD5_ROUND3(d, a, b, c, x[12], 11, 0xe6db99e5);
MD5_ROUND3(c, d, a, b, x[15], 16, 0x1fa27cf8);
MD5_ROUND3(b, c, d, a, x[ 2], 23, 0xc4ac5665);
MD5_ROUND4(a, b, c, d, x[ 0], 6, 0xf4292244);
MD5_ROUND4(d, a, b, c, x[ 7], 10, 0x432aff97);
MD5_ROUND4(c, d, a, b, x[14], 15, 0xab9423a7);
MD5_ROUND4(b, c, d, a, x[ 5], 21, 0xfc93a039);
MD5_ROUND4(a, b, c, d, x[12], 6, 0x655b59c3);
MD5_ROUND4(d, a, b, c, x[ 3], 10, 0x8f0ccc92);
MD5_ROUND4(c, d, a, b, x[10], 15, 0xffeff47d);
MD5_ROUND4(b, c, d, a, x[ 1], 21, 0x85845dd1);
MD5_ROUND4(a, b, c, d, x[ 8], 6, 0x6fa87e4f);
MD5_ROUND4(d, a, b, c, x[15], 10, 0xfe2ce6e0);
MD5_ROUND4(c, d, a, b, x[ 6], 15, 0xa3014314);
MD5_ROUND4(b, c, d, a, x[13], 21, 0x4e0811a1);
MD5_ROUND4(a, b, c, d, x[ 4], 6, 0xf7537e82);
MD5_ROUND4(d, a, b, c, x[11], 10, 0xbd3af235);
MD5_ROUND4(c, d, a, b, x[ 2], 15, 0x2ad7d2bb);
MD5_ROUND4(b, c, d, a, x[ 9], 21, 0xeb86d391);
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
unsigned left = md5_block_size - index;
le32_copy(ctx->message, index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_md5_process_block(ctx->hash, ctx->message);
msg += left;
size -= left;
}
while (size >= md5_block_size) {
unsigned* aligned_message_block;
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
/* the most common case is processing a 32-bit aligned message
on a little-endian CPU without copying it */
aligned_message_block = (unsigned*)msg;
} else {
le32_copy(ctx->message, 0, msg, md5_block_size);
aligned_message_block = ctx->message;
}
rhash_md5_process_block(ctx->hash, aligned_message_block);
msg += md5_block_size;
size -= md5_block_size;
}
if (size) {
/* save leftovers */
le32_copy(ctx->message, 0, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_md5_final(md5_ctx* ctx, unsigned char* result)
{
unsigned index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
/* pad message and run for last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= ~(0xFFFFFFFFu << shift);
ctx->message[index++] ^= 0x80u << shift;
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
ctx->message[index++] = 0;
}
rhash_md5_process_block(ctx->hash, ctx->message);
index = 0;
}
while (index < 14) {
ctx->message[index++] = 0;
}
ctx->message[14] = (unsigned)(ctx->length << 3);
ctx->message[15] = (unsigned)(ctx->length >> 29);
rhash_md5_process_block(ctx->hash, ctx->message);
if (result) le32_copy(result, 0, &ctx->hash, 16);
}
rhash-1.4.6/librhash/has160.h 0000664 0000000 0000000 00000001301 14703622112 014267 0 ustar root root /* has160.h */
#ifndef HAS160_H
#define HAS160_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define has160_block_size 64
#define has160_hash_size 20
typedef struct has160_ctx
{
unsigned message[has160_block_size / 4]; /* 512-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
unsigned hash[5]; /* 160-bit algorithm internal hashing state */
} has160_ctx;
/* hash functions */
void rhash_has160_init(has160_ctx* ctx);
void rhash_has160_update(has160_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_has160_final(has160_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* HAS160_H */
rhash-1.4.6/librhash/sha1.c 0000664 0000000 0000000 00000026217 14703622112 014131 0 ustar root root /* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1)
* based on RFC 3174.
*
* Copyright (c) 2008, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include "byte_order.h"
#include "sha1.h"
/**
* Initialize context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_sha1_init(sha1_ctx* ctx)
{
ctx->length = 0;
/* initialize algorithm state */
ctx->hash[0] = 0x67452301;
ctx->hash[1] = 0xefcdab89;
ctx->hash[2] = 0x98badcfe;
ctx->hash[3] = 0x10325476;
ctx->hash[4] = 0xc3d2e1f0;
}
/* constants for SHA1 rounds */
static const uint32_t K0 = 0x5a827999;
static const uint32_t K1 = 0x6ed9eba1;
static const uint32_t K2 = 0x8f1bbcdc;
static const uint32_t K3 = 0xca62c1d6;
/* round functions for SHA1 */
#define CHO(X,Y,Z) (((X)&(Y))|((~(X))&(Z)))
#define PAR(X,Y,Z) ((X)^(Y)^(Z))
#define MAJ(X,Y,Z) (((X)&(Y))|((X)&(Z))|((Y)&(Z)))
#define ROUND_0(a,b,c,d,e, FF, k, w) e += FF(b, c, d )+ROTL32(a,5)+k+w
#define ROUND_1(a,b,c,d,e, FF, k, w) e += FF(b,ROTL32(c,30), d )+ROTL32(a,5)+k+w
#define ROUND_2(a,b,c,d,e, FF, k, w) e += FF(b,ROTL32(c,30),ROTL32(d,30))+ROTL32(a,5)+k+w
#define ROUND(a,b,c,d,e, FF, k, w) e = ROTL32(e,30)+FF(b,ROTL32(c,30),ROTL32(d,30))+ROTL32(a,5)+k+w
/**
* The core transformation. Process a 512-bit block.
* The function has been taken from RFC 3174 with little changes.
*
* @param hash algorithm state
* @param block the message block to process
*/
static void rhash_sha1_process_block(unsigned* hash, const unsigned* block)
{
uint32_t W[80]; /* Word sequence */
uint32_t A, B, C, D, E; /* Word buffers */
A = hash[0];
B = hash[1];
C = hash[2];
D = hash[3];
E = hash[4];
/* 0..19 */
W[ 0] = be2me_32(block[ 0]);
ROUND_0(A,B,C,D,E, CHO, K0, W[ 0]);
W[ 1] = be2me_32(block[ 1]);
ROUND_1(E,A,B,C,D, CHO, K0, W[ 1]);
W[ 2] = be2me_32(block[ 2]);
ROUND_2(D,E,A,B,C, CHO, K0, W[ 2]);
W[ 3] = be2me_32(block[ 3]);
ROUND(C,D,E,A,B, CHO, K0, W[ 3]);
W[ 4] = be2me_32(block[ 4]);
ROUND(B,C,D,E,A, CHO, K0, W[ 4]);
W[ 5] = be2me_32(block[ 5]);
ROUND(A,B,C,D,E, CHO, K0, W[ 5]);
W[ 6] = be2me_32(block[ 6]);
ROUND(E,A,B,C,D, CHO, K0, W[ 6]);
W[ 7] = be2me_32(block[ 7]);
ROUND(D,E,A,B,C, CHO, K0, W[ 7]);
W[ 8] = be2me_32(block[ 8]);
ROUND(C,D,E,A,B, CHO, K0, W[ 8]);
W[ 9] = be2me_32(block[ 9]);
ROUND(B,C,D,E,A, CHO, K0, W[ 9]);
W[10] = be2me_32(block[10]);
ROUND(A,B,C,D,E, CHO, K0, W[10]);
W[11] = be2me_32(block[11]);
ROUND(E,A,B,C,D, CHO, K0, W[11]);
W[12] = be2me_32(block[12]);
ROUND(D,E,A,B,C, CHO, K0, W[12]);
W[13] = be2me_32(block[13]);
ROUND(C,D,E,A,B, CHO, K0, W[13]);
W[14] = be2me_32(block[14]);
ROUND(B,C,D,E,A, CHO, K0, W[14]);
W[15] = be2me_32(block[15]);
ROUND(A,B,C,D,E, CHO, K0, W[15]);
W[16] = ROTL32(W[13] ^ W[ 8] ^ W[ 2] ^ W[ 0], 1);
ROUND(E,A,B,C,D, CHO, K0, W[16]);
W[17] = ROTL32(W[14] ^ W[ 9] ^ W[ 3] ^ W[ 1], 1);
ROUND(D,E,A,B,C, CHO, K0, W[17]);
W[18] = ROTL32(W[15] ^ W[10] ^ W[ 4] ^ W[ 2], 1);
ROUND(C,D,E,A,B, CHO, K0, W[18]);
W[19] = ROTL32(W[16] ^ W[11] ^ W[ 5] ^ W[ 3], 1);
ROUND(B,C,D,E,A, CHO, K0, W[19]);
/* 20..39 */
W[20] = ROTL32(W[17] ^ W[12] ^ W[ 6] ^ W[ 4], 1);
ROUND(A,B,C,D,E, PAR, K1, W[20]);
W[21] = ROTL32(W[18] ^ W[13] ^ W[ 7] ^ W[ 5], 1);
ROUND(E,A,B,C,D, PAR, K1, W[21]);
W[22] = ROTL32(W[19] ^ W[14] ^ W[ 8] ^ W[ 6], 1);
ROUND(D,E,A,B,C, PAR, K1, W[22]);
W[23] = ROTL32(W[20] ^ W[15] ^ W[ 9] ^ W[ 7], 1);
ROUND(C,D,E,A,B, PAR, K1, W[23]);
W[24] = ROTL32(W[21] ^ W[16] ^ W[10] ^ W[ 8], 1);
ROUND(B,C,D,E,A, PAR, K1, W[24]);
W[25] = ROTL32(W[22] ^ W[17] ^ W[11] ^ W[ 9], 1);
ROUND(A,B,C,D,E, PAR, K1, W[25]);
W[26] = ROTL32(W[23] ^ W[18] ^ W[12] ^ W[10], 1);
ROUND(E,A,B,C,D, PAR, K1, W[26]);
W[27] = ROTL32(W[24] ^ W[19] ^ W[13] ^ W[11], 1);
ROUND(D,E,A,B,C, PAR, K1, W[27]);
W[28] = ROTL32(W[25] ^ W[20] ^ W[14] ^ W[12], 1);
ROUND(C,D,E,A,B, PAR, K1, W[28]);
W[29] = ROTL32(W[26] ^ W[21] ^ W[15] ^ W[13], 1);
ROUND(B,C,D,E,A, PAR, K1, W[29]);
W[30] = ROTL32(W[27] ^ W[22] ^ W[16] ^ W[14], 1);
ROUND(A,B,C,D,E, PAR, K1, W[30]);
W[31] = ROTL32(W[28] ^ W[23] ^ W[17] ^ W[15], 1);
ROUND(E,A,B,C,D, PAR, K1, W[31]);
W[32] = ROTL32(W[29] ^ W[24] ^ W[18] ^ W[16], 1);
ROUND(D,E,A,B,C, PAR, K1, W[32]);
W[33] = ROTL32(W[30] ^ W[25] ^ W[19] ^ W[17], 1);
ROUND(C,D,E,A,B, PAR, K1, W[33]);
W[34] = ROTL32(W[31] ^ W[26] ^ W[20] ^ W[18], 1);
ROUND(B,C,D,E,A, PAR, K1, W[34]);
W[35] = ROTL32(W[32] ^ W[27] ^ W[21] ^ W[19], 1);
ROUND(A,B,C,D,E, PAR, K1, W[35]);
W[36] = ROTL32(W[33] ^ W[28] ^ W[22] ^ W[20], 1);
ROUND(E,A,B,C,D, PAR, K1, W[36]);
W[37] = ROTL32(W[34] ^ W[29] ^ W[23] ^ W[21], 1);
ROUND(D,E,A,B,C, PAR, K1, W[37]);
W[38] = ROTL32(W[35] ^ W[30] ^ W[24] ^ W[22], 1);
ROUND(C,D,E,A,B, PAR, K1, W[38]);
W[39] = ROTL32(W[36] ^ W[31] ^ W[25] ^ W[23], 1);
ROUND(B,C,D,E,A, PAR, K1, W[39]);
/* 40..59 */
W[40] = ROTL32(W[37] ^ W[32] ^ W[26] ^ W[24], 1);
ROUND(A,B,C,D,E, MAJ, K2, W[40]);
W[41] = ROTL32(W[38] ^ W[33] ^ W[27] ^ W[25], 1);
ROUND(E,A,B,C,D, MAJ, K2, W[41]);
W[42] = ROTL32(W[39] ^ W[34] ^ W[28] ^ W[26], 1);
ROUND(D,E,A,B,C, MAJ, K2, W[42]);
W[43] = ROTL32(W[40] ^ W[35] ^ W[29] ^ W[27], 1);
ROUND(C,D,E,A,B, MAJ, K2, W[43]);
W[44] = ROTL32(W[41] ^ W[36] ^ W[30] ^ W[28], 1);
ROUND(B,C,D,E,A, MAJ, K2, W[44]);
W[45] = ROTL32(W[42] ^ W[37] ^ W[31] ^ W[29], 1);
ROUND(A,B,C,D,E, MAJ, K2, W[45]);
W[46] = ROTL32(W[43] ^ W[38] ^ W[32] ^ W[30], 1);
ROUND(E,A,B,C,D, MAJ, K2, W[46]);
W[47] = ROTL32(W[44] ^ W[39] ^ W[33] ^ W[31], 1);
ROUND(D,E,A,B,C, MAJ, K2, W[47]);
W[48] = ROTL32(W[45] ^ W[40] ^ W[34] ^ W[32], 1);
ROUND(C,D,E,A,B, MAJ, K2, W[48]);
W[49] = ROTL32(W[46] ^ W[41] ^ W[35] ^ W[33], 1);
ROUND(B,C,D,E,A, MAJ, K2, W[49]);
W[50] = ROTL32(W[47] ^ W[42] ^ W[36] ^ W[34], 1);
ROUND(A,B,C,D,E, MAJ, K2, W[50]);
W[51] = ROTL32(W[48] ^ W[43] ^ W[37] ^ W[35], 1);
ROUND(E,A,B,C,D, MAJ, K2, W[51]);
W[52] = ROTL32(W[49] ^ W[44] ^ W[38] ^ W[36], 1);
ROUND(D,E,A,B,C, MAJ, K2, W[52]);
W[53] = ROTL32(W[50] ^ W[45] ^ W[39] ^ W[37], 1);
ROUND(C,D,E,A,B, MAJ, K2, W[53]);
W[54] = ROTL32(W[51] ^ W[46] ^ W[40] ^ W[38], 1);
ROUND(B,C,D,E,A, MAJ, K2, W[54]);
W[55] = ROTL32(W[52] ^ W[47] ^ W[41] ^ W[39], 1);
ROUND(A,B,C,D,E, MAJ, K2, W[55]);
W[56] = ROTL32(W[53] ^ W[48] ^ W[42] ^ W[40], 1);
ROUND(E,A,B,C,D, MAJ, K2, W[56]);
W[57] = ROTL32(W[54] ^ W[49] ^ W[43] ^ W[41], 1);
ROUND(D,E,A,B,C, MAJ, K2, W[57]);
W[58] = ROTL32(W[55] ^ W[50] ^ W[44] ^ W[42], 1);
ROUND(C,D,E,A,B, MAJ, K2, W[58]);
W[59] = ROTL32(W[56] ^ W[51] ^ W[45] ^ W[43], 1);
ROUND(B,C,D,E,A, MAJ, K2, W[59]);
/* 60..79 */
W[60] = ROTL32(W[57] ^ W[52] ^ W[46] ^ W[44], 1);
ROUND(A,B,C,D,E, PAR, K3, W[60]);
W[61] = ROTL32(W[58] ^ W[53] ^ W[47] ^ W[45], 1);
ROUND(E,A,B,C,D, PAR, K3, W[61]);
W[62] = ROTL32(W[59] ^ W[54] ^ W[48] ^ W[46], 1);
ROUND(D,E,A,B,C, PAR, K3, W[62]);
W[63] = ROTL32(W[60] ^ W[55] ^ W[49] ^ W[47], 1);
ROUND(C,D,E,A,B, PAR, K3, W[63]);
W[64] = ROTL32(W[61] ^ W[56] ^ W[50] ^ W[48], 1);
ROUND(B,C,D,E,A, PAR, K3, W[64]);
W[65] = ROTL32(W[62] ^ W[57] ^ W[51] ^ W[49], 1);
ROUND(A,B,C,D,E, PAR, K3, W[65]);
W[66] = ROTL32(W[63] ^ W[58] ^ W[52] ^ W[50], 1);
ROUND(E,A,B,C,D, PAR, K3, W[66]);
W[67] = ROTL32(W[64] ^ W[59] ^ W[53] ^ W[51], 1);
ROUND(D,E,A,B,C, PAR, K3, W[67]);
W[68] = ROTL32(W[65] ^ W[60] ^ W[54] ^ W[52], 1);
ROUND(C,D,E,A,B, PAR, K3, W[68]);
W[69] = ROTL32(W[66] ^ W[61] ^ W[55] ^ W[53], 1);
ROUND(B,C,D,E,A, PAR, K3, W[69]);
W[70] = ROTL32(W[67] ^ W[62] ^ W[56] ^ W[54], 1);
ROUND(A,B,C,D,E, PAR, K3, W[70]);
W[71] = ROTL32(W[68] ^ W[63] ^ W[57] ^ W[55], 1);
ROUND(E,A,B,C,D, PAR, K3, W[71]);
W[72] = ROTL32(W[69] ^ W[64] ^ W[58] ^ W[56], 1);
ROUND(D,E,A,B,C, PAR, K3, W[72]);
W[73] = ROTL32(W[70] ^ W[65] ^ W[59] ^ W[57], 1);
ROUND(C,D,E,A,B, PAR, K3, W[73]);
W[74] = ROTL32(W[71] ^ W[66] ^ W[60] ^ W[58], 1);
ROUND(B,C,D,E,A, PAR, K3, W[74]);
W[75] = ROTL32(W[72] ^ W[67] ^ W[61] ^ W[59], 1);
ROUND(A,B,C,D,E, PAR, K3, W[75]);
W[76] = ROTL32(W[73] ^ W[68] ^ W[62] ^ W[60], 1);
ROUND(E,A,B,C,D, PAR, K3, W[76]);
W[77] = ROTL32(W[74] ^ W[69] ^ W[63] ^ W[61], 1);
ROUND(D,E,A,B,C, PAR, K3, W[77]);
W[78] = ROTL32(W[75] ^ W[70] ^ W[64] ^ W[62], 1);
ROUND(C,D,E,A,B, PAR, K3, W[78]);
W[79] = ROTL32(W[76] ^ W[71] ^ W[65] ^ W[63], 1);
ROUND(B,C,D,E,A, PAR, K3, W[79]);
hash[0] += A;
hash[1] += B;
hash[2] += ROTL32(C,30);
hash[3] += ROTL32(D,30);
hash[4] += ROTL32(E,30);
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
unsigned left = sha1_block_size - index;
memcpy(ctx->message + index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_sha1_process_block(ctx->hash, (unsigned*)ctx->message);
msg += left;
size -= left;
}
while (size >= sha1_block_size) {
unsigned* aligned_message_block;
if (IS_ALIGNED_32(msg)) {
/* the most common case is processing of an already aligned message
without copying it */
aligned_message_block = (unsigned*)msg;
} else {
memcpy(ctx->message, msg, sha1_block_size);
aligned_message_block = (unsigned*)ctx->message;
}
rhash_sha1_process_block(ctx->hash, aligned_message_block);
msg += sha1_block_size;
size -= sha1_block_size;
}
if (size) {
/* save leftovers */
memcpy(ctx->message, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result)
{
unsigned index = (unsigned)ctx->length & 63;
unsigned* msg32 = (unsigned*)ctx->message;
/* pad message and run for last block */
ctx->message[index++] = 0x80;
while ((index & 3) != 0) {
ctx->message[index++] = 0;
}
index >>= 2;
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
msg32[index++] = 0;
}
rhash_sha1_process_block(ctx->hash, msg32);
index = 0;
}
while (index < 14) {
msg32[index++] = 0;
}
msg32[14] = be2me_32( (unsigned)(ctx->length >> 29) );
msg32[15] = be2me_32( (unsigned)(ctx->length << 3) );
rhash_sha1_process_block(ctx->hash, msg32);
if (result) be32_copy(result, 0, &ctx->hash, sha1_hash_size);
}
rhash-1.4.6/librhash/gost94.h 0000664 0000000 0000000 00000001757 14703622112 014435 0 ustar root root /* gost94.h */
#ifndef GOST94_H
#define GOST94_H
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define gost94_block_size 32
#define gost94_hash_length 32
/* algorithm context */
typedef struct gost94_ctx
{
unsigned hash[8]; /* algorithm 256-bit state */
unsigned sum[8]; /* sum of processed message blocks */
unsigned char message[gost94_block_size]; /* 256-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
unsigned cryptpro; /* boolean flag, the type of sbox to use */
} gost94_ctx;
/* hash functions */
void rhash_gost94_init(gost94_ctx* ctx);
void rhash_gost94_cryptopro_init(gost94_ctx* ctx);
void rhash_gost94_update(gost94_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_gost94_final(gost94_ctx* ctx, unsigned char result[32]);
#ifdef GENERATE_GOST94_LOOKUP_TABLE
void rhash_gost94_init_table(void); /* initialize algorithm static data */
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* GOST94_H */
rhash-1.4.6/librhash/blake2b.c 0000664 0000000 0000000 00000012247 14703622112 014575 0 ustar root root /* blake2b.c - an implementation of blake2b hash function.
*
* Copyright (c) 2012, Samuel Neves
* Copyright (c) 2021, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "blake2b.h"
#include "byte_order.h"
#include
static const uint64_t blake2b_IV[8] =
{
I64(0x6a09e667f3bcc908), I64(0xbb67ae8584caa73b),
I64(0x3c6ef372fe94f82b), I64(0xa54ff53a5f1d36f1),
I64(0x510e527fade682d1), I64(0x9b05688c2b3e6c1f),
I64(0x1f83d9abfb41bd6b), I64(0x5be0cd19137e2179)
};
static const uint8_t blake2b_sigma[12][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
};
void rhash_blake2b_init(blake2b_ctx* ctx)
{
memset(ctx, 0, sizeof(*ctx));
/* init state by xoring IV with blake2b input parameter block */
ctx->hash[0] = blake2b_IV[0] ^ I64(0x01010040);
ctx->hash[1] = blake2b_IV[1];
ctx->hash[2] = blake2b_IV[2];
ctx->hash[3] = blake2b_IV[3];
ctx->hash[4] = blake2b_IV[4];
ctx->hash[5] = blake2b_IV[5];
ctx->hash[6] = blake2b_IV[6];
ctx->hash[7] = blake2b_IV[7];
}
#define G(r,i,a,b,c,d) \
do { \
a = a + b + m[blake2b_sigma[r][2*i+0]]; \
d = ROTR64(d ^ a, 32); \
c = c + d; \
b = ROTR64(b ^ c, 24); \
a = a + b + m[blake2b_sigma[r][2*i+1]]; \
d = ROTR64(d ^ a, 16); \
c = c + d; \
b = ROTR64(b ^ c, 63); \
} while(0)
#define ROUND(r) \
do { \
G(r,0,v[0],v[4],v[ 8],v[12]); \
G(r,1,v[1],v[5],v[ 9],v[13]); \
G(r,2,v[2],v[6],v[10],v[14]); \
G(r,3,v[3],v[7],v[11],v[15]); \
G(r,4,v[0],v[5],v[10],v[15]); \
G(r,5,v[1],v[6],v[11],v[12]); \
G(r,6,v[2],v[7],v[ 8],v[13]); \
G(r,7,v[3],v[4],v[ 9],v[14]); \
} while(0)
static void rhash_blake2b_process_block(blake2b_ctx* ctx, const uint64_t* m, uint64_t finalization_flag)
{
uint64_t v[16];
size_t i;
memcpy(v, ctx->hash, sizeof(uint64_t) * 8);
v[ 8] = blake2b_IV[0];
v[ 9] = blake2b_IV[1];
v[10] = blake2b_IV[2];
v[11] = blake2b_IV[3];
v[12] = blake2b_IV[4] ^ ctx->length; /* length correction */
v[13] = blake2b_IV[5];
v[14] = blake2b_IV[6] ^ finalization_flag;
v[15] = blake2b_IV[7];
ROUND(0);
ROUND(1);
ROUND(2);
ROUND(3);
ROUND(4);
ROUND(5);
ROUND(6);
ROUND(7);
ROUND(8);
ROUND(9);
ROUND(10);
ROUND(11);
for(i = 0; i < 8; ++i)
ctx->hash[i] ^= v[i] ^ v[i + 8];
}
void rhash_blake2b_update(blake2b_ctx* ctx, const unsigned char* msg, size_t size)
{
if(size > 0)
{
size_t index = (size_t)ctx->length & 127;
if(index)
{
size_t rest = blake2b_block_size - index;
if (size > rest) {
le64_copy(ctx->message, index, msg, rest); /* fill the block */
/* process the block */
size -= rest;
msg += rest;
ctx->length += rest;
index = 0;
rhash_blake2b_process_block(ctx, ctx->message, I64(0));
}
} else if (ctx->length) {
rhash_blake2b_process_block(ctx, ctx->message, I64(0));
}
while(size > blake2b_block_size) {
uint64_t* aligned_message_block;
if (IS_LITTLE_ENDIAN && IS_ALIGNED_64(msg)) {
aligned_message_block = (uint64_t*)msg;
} else {
le64_copy(ctx->message, 0, msg, blake2b_block_size);
aligned_message_block = ctx->message;
}
size -= blake2b_block_size;
msg += blake2b_block_size;
ctx->length += blake2b_block_size;
rhash_blake2b_process_block(ctx, aligned_message_block, I64(0));
}
le64_copy(ctx->message, index, msg, size); /* save leftovers */
ctx->length += size;
}
}
void rhash_blake2b_final(blake2b_ctx* ctx, unsigned char *result)
{
size_t length = (size_t)ctx->length & 127;
if (length)
{
/* pad the message with zeros */
size_t index = length >> 3;
size_t shift = (length & 7) * 8;
ctx->message[index] &= ~(I64(0xFFFFFFFFFFFFFFFF) << shift);
for(index++; index < 16; index++)
ctx->message[index] = 0;
}
rhash_blake2b_process_block(ctx, ctx->message, I64(0xFFFFFFFFFFFFFFFF));
/* convert hash state to result bytes */
le64_copy(result, 0, ctx->hash, blake2b_hash_size);
}
rhash-1.4.6/librhash/ripemd-160.c 0000664 0000000 0000000 00000025473 14703622112 015064 0 ustar root root /* ripemd-160.c - an implementation of RIPEMD-160 Hash function
* based on the original aritcle:
* H. Dobbertin, A. Bosselaers, B. Preneel, RIPEMD-160: A strengthened version
* of RIPEMD, Lecture Notes in Computer, 1996, V.1039, pp.71-82
*
* Copyright (c) 2009, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include "byte_order.h"
#include "ripemd-160.h"
/**
* Initialize algorithm context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_ripemd160_init(ripemd160_ctx* ctx)
{
memset(ctx->message, 0, sizeof(ctx->message));
ctx->length = 0;
/* initialize state */
ctx->hash[0] = 0x67452301;
ctx->hash[1] = 0xefcdab89;
ctx->hash[2] = 0x98badcfe;
ctx->hash[3] = 0x10325476;
ctx->hash[4] = 0xc3d2e1f0;
}
/* five boolean functions */
#define F1(x, y, z) ((x) ^ (y) ^ (z))
#define F2(x, y, z) ((((y) ^ (z)) & (x)) ^ (z))
#define F3(x, y, z) (((x) | ~(y)) ^ (z))
#define F4(x, y, z) ((((x) ^ (y)) & (z)) ^ (y))
#define F5(x, y, z) ((x) ^ ((y) | ~(z)))
#define RMD_FUNC(FUNC, A, B, C, D, E, X, S, K) \
(A) += FUNC((B), (C), (D)) + (X) + K; \
(A) = ROTL32((A), (S)) + (E); \
(C) = ROTL32((C), 10);
/* steps for the left and right half of algorithm */
#define L1(A, B, C, D, E, X, S) RMD_FUNC(F1, A, B, C, D, E, X, S, 0)
#define L2(A, B, C, D, E, X, S) RMD_FUNC(F2, A, B, C, D, E, X, S, 0x5a827999UL)
#define L3(A, B, C, D, E, X, S) RMD_FUNC(F3, A, B, C, D, E, X, S, 0x6ed9eba1UL)
#define L4(A, B, C, D, E, X, S) RMD_FUNC(F4, A, B, C, D, E, X, S, 0x8f1bbcdcUL)
#define L5(A, B, C, D, E, X, S) RMD_FUNC(F5, A, B, C, D, E, X, S, 0xa953fd4eUL)
#define R1(A, B, C, D, E, X, S) RMD_FUNC(F5, A, B, C, D, E, X, S, 0x50a28be6UL)
#define R2(A, B, C, D, E, X, S) RMD_FUNC(F4, A, B, C, D, E, X, S, 0x5c4dd124UL)
#define R3(A, B, C, D, E, X, S) RMD_FUNC(F3, A, B, C, D, E, X, S, 0x6d703ef3UL)
#define R4(A, B, C, D, E, X, S) RMD_FUNC(F2, A, B, C, D, E, X, S, 0x7a6d76e9UL)
#define R5(A, B, C, D, E, X, S) RMD_FUNC(F1, A, B, C, D, E, X, S, 0)
/**
* The core transformation. Process a 512-bit block.
*
* @param hash algorithm intermediate hash
* @param X the message block to process
*/
static void rhash_ripemd160_process_block(unsigned* hash, const unsigned* X)
{
register unsigned A = hash[0], B = hash[1], C = hash[2], D = hash[3], E = hash[4];
register unsigned a1 = hash[0], b1 = hash[1], c1 = hash[2], d1 = hash[3], e1 = hash[4];
/* rounds of the left and right half interleaved */
L1(a1, b1, c1, d1, e1, X[ 0], 11);
R1(A, B, C, D, E, X[ 5], 8);
L1(e1, a1, b1, c1, d1, X[ 1], 14);
R1(E, A, B, C, D, X[14], 9);
L1(d1, e1, a1, b1, c1, X[ 2], 15);
R1(D, E, A, B, C, X[ 7], 9);
L1(c1, d1, e1, a1, b1, X[ 3], 12);
R1(C, D, E, A, B, X[ 0], 11);
L1(b1, c1, d1, e1, a1, X[ 4], 5);
R1(B, C, D, E, A, X[ 9], 13);
L1(a1, b1, c1, d1, e1, X[ 5], 8);
R1(A, B, C, D, E, X[ 2], 15);
L1(e1, a1, b1, c1, d1, X[ 6], 7);
R1(E, A, B, C, D, X[11], 15);
L1(d1, e1, a1, b1, c1, X[ 7], 9);
R1(D, E, A, B, C, X[ 4], 5);
L1(c1, d1, e1, a1, b1, X[ 8], 11);
R1(C, D, E, A, B, X[13], 7);
L1(b1, c1, d1, e1, a1, X[ 9], 13);
R1(B, C, D, E, A, X[ 6], 7);
L1(a1, b1, c1, d1, e1, X[10], 14);
R1(A, B, C, D, E, X[15], 8);
L1(e1, a1, b1, c1, d1, X[11], 15);
R1(E, A, B, C, D, X[ 8], 11);
L1(d1, e1, a1, b1, c1, X[12], 6);
R1(D, E, A, B, C, X[ 1], 14);
L1(c1, d1, e1, a1, b1, X[13], 7);
R1(C, D, E, A, B, X[10], 14);
L1(b1, c1, d1, e1, a1, X[14], 9);
R1(B, C, D, E, A, X[ 3], 12);
L1(a1, b1, c1, d1, e1, X[15], 8);
R1(A, B, C, D, E, X[12], 6);
L2(e1, a1, b1, c1, d1, X[ 7], 7);
R2(E, A, B, C, D, X[ 6], 9);
L2(d1, e1, a1, b1, c1, X[ 4], 6);
R2(D, E, A, B, C, X[11], 13);
L2(c1, d1, e1, a1, b1, X[13], 8);
R2(C, D, E, A, B, X[ 3], 15);
L2(b1, c1, d1, e1, a1, X[ 1], 13);
R2(B, C, D, E, A, X[ 7], 7);
L2(a1, b1, c1, d1, e1, X[10], 11);
R2(A, B, C, D, E, X[ 0], 12);
L2(e1, a1, b1, c1, d1, X[ 6], 9);
R2(E, A, B, C, D, X[13], 8);
L2(d1, e1, a1, b1, c1, X[15], 7);
R2(D, E, A, B, C, X[ 5], 9);
L2(c1, d1, e1, a1, b1, X[ 3], 15);
R2(C, D, E, A, B, X[10], 11);
L2(b1, c1, d1, e1, a1, X[12], 7);
R2(B, C, D, E, A, X[14], 7);
L2(a1, b1, c1, d1, e1, X[ 0], 12);
R2(A, B, C, D, E, X[15], 7);
L2(e1, a1, b1, c1, d1, X[ 9], 15);
R2(E, A, B, C, D, X[ 8], 12);
L2(d1, e1, a1, b1, c1, X[ 5], 9);
R2(D, E, A, B, C, X[12], 7);
L2(c1, d1, e1, a1, b1, X[ 2], 11);
R2(C, D, E, A, B, X[ 4], 6);
L2(b1, c1, d1, e1, a1, X[14], 7);
R2(B, C, D, E, A, X[ 9], 15);
L2(a1, b1, c1, d1, e1, X[11], 13);
R2(A, B, C, D, E, X[ 1], 13);
L2(e1, a1, b1, c1, d1, X[ 8], 12);
R2(E, A, B, C, D, X[ 2], 11);
L3(d1, e1, a1, b1, c1, X[ 3], 11);
R3(D, E, A, B, C, X[15], 9);
L3(c1, d1, e1, a1, b1, X[10], 13);
R3(C, D, E, A, B, X[ 5], 7);
L3(b1, c1, d1, e1, a1, X[14], 6);
R3(B, C, D, E, A, X[ 1], 15);
L3(a1, b1, c1, d1, e1, X[ 4], 7);
R3(A, B, C, D, E, X[ 3], 11);
L3(e1, a1, b1, c1, d1, X[ 9], 14);
R3(E, A, B, C, D, X[ 7], 8);
L3(d1, e1, a1, b1, c1, X[15], 9);
R3(D, E, A, B, C, X[14], 6);
L3(c1, d1, e1, a1, b1, X[ 8], 13);
R3(C, D, E, A, B, X[ 6], 6);
L3(b1, c1, d1, e1, a1, X[ 1], 15);
R3(B, C, D, E, A, X[ 9], 14);
L3(a1, b1, c1, d1, e1, X[ 2], 14);
R3(A, B, C, D, E, X[11], 12);
L3(e1, a1, b1, c1, d1, X[ 7], 8);
R3(E, A, B, C, D, X[ 8], 13);
L3(d1, e1, a1, b1, c1, X[ 0], 13);
R3(D, E, A, B, C, X[12], 5);
L3(c1, d1, e1, a1, b1, X[ 6], 6);
R3(C, D, E, A, B, X[ 2], 14);
L3(b1, c1, d1, e1, a1, X[13], 5);
R3(B, C, D, E, A, X[10], 13);
L3(a1, b1, c1, d1, e1, X[11], 12);
R3(A, B, C, D, E, X[ 0], 13);
L3(e1, a1, b1, c1, d1, X[ 5], 7);
R3(E, A, B, C, D, X[ 4], 7);
L3(d1, e1, a1, b1, c1, X[12], 5);
R3(D, E, A, B, C, X[13], 5);
L4(c1, d1, e1, a1, b1, X[ 1], 11);
R4(C, D, E, A, B, X[ 8], 15);
L4(b1, c1, d1, e1, a1, X[ 9], 12);
R4(B, C, D, E, A, X[ 6], 5);
L4(a1, b1, c1, d1, e1, X[11], 14);
R4(A, B, C, D, E, X[ 4], 8);
L4(e1, a1, b1, c1, d1, X[10], 15);
R4(E, A, B, C, D, X[ 1], 11);
L4(d1, e1, a1, b1, c1, X[ 0], 14);
R4(D, E, A, B, C, X[ 3], 14);
L4(c1, d1, e1, a1, b1, X[ 8], 15);
R4(C, D, E, A, B, X[11], 14);
L4(b1, c1, d1, e1, a1, X[12], 9);
R4(B, C, D, E, A, X[15], 6);
L4(a1, b1, c1, d1, e1, X[ 4], 8);
R4(A, B, C, D, E, X[ 0], 14);
L4(e1, a1, b1, c1, d1, X[13], 9);
R4(E, A, B, C, D, X[ 5], 6);
L4(d1, e1, a1, b1, c1, X[ 3], 14);
R4(D, E, A, B, C, X[12], 9);
L4(c1, d1, e1, a1, b1, X[ 7], 5);
R4(C, D, E, A, B, X[ 2], 12);
L4(b1, c1, d1, e1, a1, X[15], 6);
R4(B, C, D, E, A, X[13], 9);
L4(a1, b1, c1, d1, e1, X[14], 8);
R4(A, B, C, D, E, X[ 9], 12);
L4(e1, a1, b1, c1, d1, X[ 5], 6);
R4(E, A, B, C, D, X[ 7], 5);
L4(d1, e1, a1, b1, c1, X[ 6], 5);
R4(D, E, A, B, C, X[10], 15);
L4(c1, d1, e1, a1, b1, X[ 2], 12);
R4(C, D, E, A, B, X[14], 8);
L5(b1, c1, d1, e1, a1, X[ 4], 9);
R5(B, C, D, E, A, X[12] , 8);
L5(a1, b1, c1, d1, e1, X[ 0], 15);
R5(A, B, C, D, E, X[15] , 5);
L5(e1, a1, b1, c1, d1, X[ 5], 5);
R5(E, A, B, C, D, X[10] , 12);
L5(d1, e1, a1, b1, c1, X[ 9], 11);
R5(D, E, A, B, C, X[ 4] , 9);
L5(c1, d1, e1, a1, b1, X[ 7], 6);
R5(C, D, E, A, B, X[ 1] , 12);
L5(b1, c1, d1, e1, a1, X[12], 8);
R5(B, C, D, E, A, X[ 5] , 5);
L5(a1, b1, c1, d1, e1, X[ 2], 13);
R5(A, B, C, D, E, X[ 8] , 14);
L5(e1, a1, b1, c1, d1, X[10], 12);
R5(E, A, B, C, D, X[ 7] , 6);
L5(d1, e1, a1, b1, c1, X[14], 5);
R5(D, E, A, B, C, X[ 6] , 8);
L5(c1, d1, e1, a1, b1, X[ 1], 12);
R5(C, D, E, A, B, X[ 2] , 13);
L5(b1, c1, d1, e1, a1, X[ 3], 13);
R5(B, C, D, E, A, X[13] , 6);
L5(a1, b1, c1, d1, e1, X[ 8], 14);
R5(A, B, C, D, E, X[14] , 5);
L5(e1, a1, b1, c1, d1, X[11], 11);
R5(E, A, B, C, D, X[ 0] , 15);
L5(d1, e1, a1, b1, c1, X[ 6], 8);
R5(D, E, A, B, C, X[ 3] , 13);
L5(c1, d1, e1, a1, b1, X[15], 5);
R5(C, D, E, A, B, X[ 9] , 11);
L5(b1, c1, d1, e1, a1, X[13], 6);
R5(B, C, D, E, A, X[11] , 11);
/* update intermediate hash */
D += c1 + hash[1];
hash[1] = hash[2] + d1 + E;
hash[2] = hash[3] + e1 + A;
hash[3] = hash[4] + a1 + B;
hash[4] = hash[0] + b1 + C;
hash[0] = D;
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_ripemd160_update(ripemd160_ctx* ctx, const unsigned char* msg, size_t size)
{
unsigned index = (unsigned)ctx->length & 63;
ctx->length += size;
/* fill partial block */
if (index) {
unsigned left = ripemd160_block_size - index;
le32_copy(ctx->message, index, msg, (size < left ? size : left));
if (size < left) return;
/* process partial block */
rhash_ripemd160_process_block(ctx->hash, (unsigned*)ctx->message);
msg += left;
size -= left;
}
while (size >= ripemd160_block_size) {
unsigned* aligned_message_block;
if (IS_LITTLE_ENDIAN && IS_ALIGNED_32(msg)) {
/* the most common case is processing of an already aligned message
on little-endian CPU without copying it */
aligned_message_block = (unsigned*)msg;
} else {
le32_copy(ctx->message, 0, msg, ripemd160_block_size);
aligned_message_block = ctx->message;
}
rhash_ripemd160_process_block(ctx->hash, aligned_message_block);
msg += ripemd160_block_size;
size -= ripemd160_block_size;
}
if (size) {
/* save leftovers */
le32_copy(ctx->message, 0, msg, size);
}
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_ripemd160_final(ripemd160_ctx* ctx, unsigned char result[20])
{
unsigned index = ((unsigned)ctx->length & 63) >> 2;
unsigned shift = ((unsigned)ctx->length & 3) * 8;
/* pad message and run for last block */
/* append the byte 0x80 to the message */
ctx->message[index] &= ~(0xFFFFFFFFu << shift);
ctx->message[index++] ^= 0x80u << shift;
/* if no room left in the message to store 64-bit message length */
if (index > 14) {
/* then fill the rest with zeros and process it */
while (index < 16) {
ctx->message[index++] = 0;
}
rhash_ripemd160_process_block(ctx->hash, ctx->message);
index = 0;
}
while (index < 14) {
ctx->message[index++] = 0;
}
ctx->message[14] = (unsigned)(ctx->length << 3);
ctx->message[15] = (unsigned)(ctx->length >> 29);
rhash_ripemd160_process_block(ctx->hash, ctx->message);
le32_copy(result, 0, &ctx->hash, 20);
}
rhash-1.4.6/librhash/gost12.c 0000664 0000000 0000000 00000170235 15010476501 014415 0 ustar root root /* gost12.c - an implementation of the GOST R 34.11-2012 hash function,
* the Russian cryptographic standard.
* See also RFC 6986.
*
* Copyright (c) 2019, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "gost12.h"
#include
#include "byte_order.h"
#if defined(__GNUC__) && defined(CPU_IA32) && !defined(__clang__) && !defined(RHASH_NO_ASM)
# define USE_GCC_ASM_IA32
#elif defined(__GNUC__) && defined(CPU_X64) && !defined(RHASH_NO_ASM)
# define USE_GCC_ASM_X64
#endif
ALIGN_ATTR(64)
static const uint64_t TR[8][256] =
{
{
I64(0xD01F715B5C7EF8E6),I64(0x16FA240980778325),I64(0xA8A42E857EE049C8),I64(0x6AC1068FA186465B),
I64(0x6E417BD7A2E9320B),I64(0x665C8167A437DAAB),I64(0x7666681AA89617F6),I64(0x4B959163700BDCF5),
I64(0xF14BE6B78DF36248),I64(0xC585BD689A625CFF),I64(0x9557D7FCA67D82CB),I64(0x89F0B969AF6DD366),
I64(0xB0833D48749F6C35),I64(0xA1998C23B1ECBC7C),I64(0x8D70C431AC02A736),I64(0xD6DFBC2FD0A8B69E),
I64(0x37AEB3E551FA198B),I64(0x0B7D128A40B5CF9C),I64(0x5A8F2008B5780CBC),I64(0xEDEC882284E333E5),
I64(0xD25FC177D3C7C2CE),I64(0x5E0F5D50B61778EC),I64(0x1D873683C0C24CB9),I64(0xAD040BCBB45D208C),
I64(0x2F89A0285B853C76),I64(0x5732FFF6791B8D58),I64(0x3E9311439EF6EC3F),I64(0xC9183A809FD3C00F),
I64(0x83ADF3F5260A01EE),I64(0xA6791941F4E8EF10),I64(0x103AE97D0CA1CD5D),I64(0x2CE948121DEE1B4A),
I64(0x39738421DBF2BF53),I64(0x093DA2A6CF0CF5B4),I64(0xCD9847D89CBCB45F),I64(0xF9561C078B2D8AE8),
I64(0x9C6A755A6971777F),I64(0xBC1EBAA0712EF0C5),I64(0x72E61542ABF963A6),I64(0x78BB5FDE229EB12E),
I64(0x14BA94250FCEB90D),I64(0x844D6697630E5282),I64(0x98EA08026A1E032F),I64(0xF06BBEA144217F5C),
I64(0xDB6263D11CCB377A),I64(0x641C314B2B8EE083),I64(0x320E96AB9B4770CF),I64(0x1EE7DEB986A96B85),
I64(0xE96CF57A878C47B5),I64(0xFDD6615F8842FEB8),I64(0xC83862965601DD1B),I64(0x2EA9F83E92572162),
I64(0xF876441142FF97FC),I64(0xEB2C455608357D9D),I64(0x5612A7E0B0C9904C),I64(0x6C01CBFB2D500823),
I64(0x4548A6A7FA037A2D),I64(0xABC4C6BF388B6EF4),I64(0xBADE77D4FDF8BEBD),I64(0x799B07C8EB4CAC3A),
I64(0x0C9D87E805B19CF0),I64(0xCB588AAC106AFA27),I64(0xEA0C1D40C1E76089),I64(0x2869354A1E816F1A),
I64(0xFF96D17307FBC490),I64(0x9F0A9D602F1A5043),I64(0x96373FC6E016A5F7),I64(0x5292DAB8B3A6E41C),
I64(0x9B8AE0382C752413),I64(0x4F15EC3B7364A8A5),I64(0x3FB349555724F12B),I64(0xC7C50D4415DB66D7),
I64(0x92B7429EE379D1A7),I64(0xD37F99611A15DFDA),I64(0x231427C05E34A086),I64(0xA439A96D7B51D538),
I64(0xB403401077F01865),I64(0xDDA2AEA5901D7902),I64(0x0A5D4A9C8967D288),I64(0xC265280ADF660F93),
I64(0x8BB0094520D4E94E),I64(0x2A29856691385532),I64(0x42A833C5BF072941),I64(0x73C64D54622B7EB2),
I64(0x07E095624504536C),I64(0x8A905153E906F45A),I64(0x6F6123C16B3B2F1F),I64(0xC6E55552DC097BC3),
I64(0x4468FEB133D16739),I64(0xE211E7F0C7398829),I64(0xA2F96419F7879B40),I64(0x19074BDBC3AD38E9),
I64(0xF4EBC3F9474E0B0C),I64(0x43886BD376D53455),I64(0xD8028BEB5AA01046),I64(0x51F23282F5CDC320),
I64(0xE7B1C2BE0D84E16D),I64(0x081DFAB006DEE8A0),I64(0x3B33340D544B857B),I64(0x7F5BCABC679AE242),
I64(0x0EDD37C48A08A6D8),I64(0x81ED43D9A9B33BC6),I64(0xB1A3655EBD4D7121),I64(0x69A1EEB5E7ED6167),
I64(0xF6AB73D5C8F73124),I64(0x1A67A3E185C61FD5),I64(0x2DC91004D43C065E),I64(0x0240B02C8FB93A28),
I64(0x90F7F2B26CC0EB8F),I64(0x3CD3A16F114FD617),I64(0xAAE49EA9F15973E0),I64(0x06C0CD748CD64E78),
I64(0xDA423BC7D5192A6E),I64(0xC345701C16B41287),I64(0x6D2193EDE4821537),I64(0xFCF639494190E3AC),
I64(0x7C3B228621F1C57E),I64(0xFB16AC2B0494B0C0),I64(0xBF7E529A3745D7F9),I64(0x6881B6A32E3F7C73),
I64(0xCA78D2BAD9B8E733),I64(0xBBFE2FC2342AA3A9),I64(0x0DBDDFFECC6381E4),I64(0x70A6A56E2440598E),
I64(0xE4D12A844BEFC651),I64(0x8C509C2765D0BA22),I64(0xEE8C6018C28814D9),I64(0x17DA7C1F49A59E31),
I64(0x609C4C1328E194D3),I64(0xB3E3D57232F44B09),I64(0x91D7AAA4A512F69B),I64(0x0FFD6FD243DABBCC),
I64(0x50D26A943C1FDE34),I64(0x6BE15E9968545B4F),I64(0x94778FEA6FAF9FDF),I64(0x2B09DD7058EA4826),
I64(0x677CD9716DE5C7BF),I64(0x49D5214FFFB2E6DD),I64(0x0360E83A466B273C),I64(0x1FC786AF4F7B7691),
I64(0xA0B9D435783EA168),I64(0xD49F0C035F118CB6),I64(0x01205816C9D21D14),I64(0xAC2453DD7D8F3D98),
I64(0x545217CC3F70AA64),I64(0x26B4028E9489C9C2),I64(0xDEC2469FD6765E3E),I64(0x04807D58036F7450),
I64(0xE5F17292823DDB45),I64(0xF30B569B024A5860),I64(0x62DCFC3FA758AEFB),I64(0xE84CAD6C4E5E5AA1),
I64(0xCCB81FCE556EA94B),I64(0x53B282AE7A74F908),I64(0x1B47FBF74C1402C1),I64(0x368EEBF39828049F),
I64(0x7AFBEFF2AD278B06),I64(0xBE5E0A8CFE97CAED),I64(0xCFD8F7F413058E77),I64(0xF78B2BC301252C30),
I64(0x4D555C17FCDD928D),I64(0x5F2F05467FC565F8),I64(0x24F4B2A21B30F3EA),I64(0x860DD6BBECB768AA),
I64(0x4C750401350F8F99),I64(0x0000000000000000),I64(0xECCCD0344D312EF1),I64(0xB5231806BE220571),
I64(0xC105C030990D28AF),I64(0x653C695DE25CFD97),I64(0x159ACC33C61CA419),I64(0xB89EC7F872418495),
I64(0xA9847693B73254DC),I64(0x58CF90243AC13694),I64(0x59EFC832F3132B80),I64(0x5C4FED7C39AE42C4),
I64(0x828DABE3EFD81CFA),I64(0xD13F294D95ACE5F2),I64(0x7D1B7A90E823D86A),I64(0xB643F03CF849224D),
I64(0x3DF3F979D89DCB03),I64(0x7426D836272F2DDE),I64(0xDFE21E891FA4432A),I64(0x3A136C1B9D99986F),
I64(0xFA36F43DCD46ADD4),I64(0xC025982650DF35BB),I64(0x856D3E81AADC4F96),I64(0xC4A5E57E53B041EB),
I64(0x4708168B75BA4005),I64(0xAF44BBE73BE41AA4),I64(0x971767D029C4B8E3),I64(0xB9BE9FEEBB939981),
I64(0x215497ECD18D9AAE),I64(0x316E7E91DD2C57F3),I64(0xCEF8AFE2DAD79363),I64(0x3853DC371220A247),
I64(0x35EE03C9DE4323A3),I64(0xE6919AA8C456FC79),I64(0xE05157DC4880B201),I64(0x7BDBB7E464F59612),
I64(0x127A59518318F775),I64(0x332ECEBD52956DDB),I64(0x8F30741D23BB9D1E),I64(0xD922D3FD93720D52),
I64(0x7746300C61440AE2),I64(0x25D4EAB4D2E2EEFE),I64(0x75068020EEFD30CA),I64(0x135A01474ACAEA61),
I64(0x304E268714FE4AE7),I64(0xA519F17BB283C82C),I64(0xDC82F6B359CF6416),I64(0x5BAF781E7CAA11A8),
I64(0xB2C38D64FB26561D),I64(0x34CE5BDF17913EB7),I64(0x5D6FB56AF07C5FD0),I64(0x182713CD0A7F25FD),
I64(0x9E2AC576E6C84D57),I64(0x9AAAB82EE5A73907),I64(0xA3D93C0F3E558654),I64(0x7E7B92AAAE48FF56),
I64(0x872D8EAD256575BE),I64(0x41C8DBFFF96C0E7D),I64(0x99CA5014A3CC1E3B),I64(0x40E883E930BE1369),
I64(0x1CA76E95091051AD),I64(0x4E35B42DBAB6B5B1),I64(0x05A0254ECABD6944),I64(0xE1710FCA8152AF15),
I64(0xF22B0E8DCB984574),I64(0xB763A82A319B3F59),I64(0x63FCA4296E8AB3EF),I64(0x9D4A2D4CA0A36A6B),
I64(0xE331BFE60EEB953D),I64(0xD5BF541596C391A2),I64(0xF5CB9BEF8E9C1618),I64(0x46284E9DBC685D11),
I64(0x2074CFFA185F87BA),I64(0xBD3EE2B6B8FCEDD1),I64(0xAE64E3F1F23607B0),I64(0xFEB68965CE29D984),
I64(0x55724FDAF6A2B770),I64(0x29496D5CD753720E),I64(0xA75941573D3AF204),I64(0x8E102C0BEA69800A),
I64(0x111AB16BC573D049),I64(0xD7FFE439197AAB8A),I64(0xEFAC380E0B5A09CD),I64(0x48F579593660FBC9),
I64(0x22347FD697E6BD92),I64(0x61BC1405E13389C7),I64(0x4AB5C975B9D9C1E1),I64(0x80CD1BCF606126D2),
I64(0x7186FD78ED92449A),I64(0x93971A882AABCCB3),I64(0x88D0E17F66BFCE72),I64(0x27945A985D5BD4D6)
},
{
I64(0xDE553F8C05A811C8),I64(0x1906B59631B4F565),I64(0x436E70D6B1964FF7),I64(0x36D343CB8B1E9D85),
I64(0x843DFACC858AAB5A),I64(0xFDFC95C299BFC7F9),I64(0x0F634BDEA1D51FA2),I64(0x6D458B3B76EFB3CD),
I64(0x85C3F77CF8593F80),I64(0x3C91315FBE737CB2),I64(0x2148B03366ACE398),I64(0x18F8B8264C6761BF),
I64(0xC830C1C495C9FB0F),I64(0x981A76102086A0AA),I64(0xAA16012142F35760),I64(0x35CC54060C763CF6),
I64(0x42907D66CC45DB2D),I64(0x8203D44B965AF4BC),I64(0x3D6F3CEFC3A0E868),I64(0xBC73FF69D292BDA7),
I64(0x8722ED0102E20A29),I64(0x8F8185E8CD34DEB7),I64(0x9B0561DDA7EE01D9),I64(0x5335A0193227FAD6),
I64(0xC9CECC74E81A6FD5),I64(0x54F5832E5C2431EA),I64(0x99E47BA05D553470),I64(0xF7BEE756ACD226CE),
I64(0x384E05A5571816FD),I64(0xD1367452A47D0E6A),I64(0xF29FDE1C386AD85B),I64(0x320C77316275F7CA),
I64(0xD0C879E2D9AE9AB0),I64(0xDB7406C69110EF5D),I64(0x45505E51A2461011),I64(0xFC029872E46C5323),
I64(0xFA3CB6F5F7BC0CC5),I64(0x031F17CD8768A173),I64(0xBD8DF2D9AF41297D),I64(0x9D3B4F5AB43E5E3F),
I64(0x4071671B36FEEE84),I64(0x716207E7D3E3B83D),I64(0x48D20FF2F9283A1A),I64(0x27769EB4757CBC7E),
I64(0x5C56EBC793F2E574),I64(0xA48B474F9EF5DC18),I64(0x52CBADA94FF46E0C),I64(0x60C7DA982D8199C6),
I64(0x0E9D466EDC068B78),I64(0x4EEC2175EAF865FC),I64(0x550B8E9E21F7A530),I64(0x6B7BA5BC653FEC2B),
I64(0x5EB7F1BA6949D0DD),I64(0x57EA94E3DB4C9099),I64(0xF640EAE6D101B214),I64(0xDD4A284182C0B0BB),
I64(0xFF1D8FBF6304F250),I64(0xB8ACCB933BF9D7E8),I64(0xE8867C478EB68C4D),I64(0x3F8E2692391BDDC1),
I64(0xCB2FD60912A15A7C),I64(0xAEC935DBAB983D2F),I64(0xF55FFD2B56691367),I64(0x80E2CE366CE1C115),
I64(0x179BF3F8EDB27E1D),I64(0x01FE0DB07DD394DA),I64(0xDA8A0B76ECC37B87),I64(0x44AE53E1DF9584CB),
I64(0xB310B4B77347A205),I64(0xDFAB323C787B8512),I64(0x3B511268D070B78E),I64(0x65E6E3D2B9396753),
I64(0x6864B271E2574D58),I64(0x259784C98FC789D7),I64(0x02E11A7DFABB35A9),I64(0x8841A6DFA337158B),
I64(0x7ADE78C39B5DCDD0),I64(0xB7CF804D9A2CC84A),I64(0x20B6BD831B7F7742),I64(0x75BD331D3A88D272),
I64(0x418F6AAB4B2D7A5E),I64(0xD9951CBB6BABDAF4),I64(0xB6318DFDE7FF5C90),I64(0x1F389B112264AA83),
I64(0x492C024284FBAEC0),I64(0xE33A0363C608F9A0),I64(0x2688930408AF28A4),I64(0xC7538A1A341CE4AD),
I64(0x5DA8E677EE2171AE),I64(0x8C9E92254A5C7FC4),I64(0x63D8CD55AAE938B5),I64(0x29EBD8DAA97A3706),
I64(0x959827B37BE88AA1),I64(0x1484E4356ADADF6E),I64(0xA7945082199D7D6B),I64(0xBF6CE8A455FA1CD4),
I64(0x9CC542EAC9EDCAE5),I64(0x79C16F0E1C356CA3),I64(0x89BFAB6FDEE48151),I64(0xD4174D1830C5F0FF),
I64(0x9258048415EB419D),I64(0x6139D72850520D1C),I64(0x6A85A80C18EC78F1),I64(0xCD11F88E0171059A),
I64(0xCCEFF53E7CA29140),I64(0xD229639F2315AF19),I64(0x90B91EF9EF507434),I64(0x5977D28D074A1BE1),
I64(0x311360FCE51D56B9),I64(0xC093A92D5A1F2F91),I64(0x1A19A25BB6DC5416),I64(0xEB996B8A09DE2D3E),
I64(0xFEE3820F1ED7668A),I64(0xD7085AD5B7AD518C),I64(0x7FFF41890FE53345),I64(0xEC5948BD67DDE602),
I64(0x2FD5F65DBAAA68E0),I64(0xA5754AFFE32648C2),I64(0xF8DDAC880D07396C),I64(0x6FA491468C548664),
I64(0x0C7C5C1326BDBED1),I64(0x4A33158F03930FB3),I64(0x699ABFC19F84D982),I64(0xE4FA2054A80B329C),
I64(0x6707F9AF438252FA),I64(0x08A368E9CFD6D49E),I64(0x47B1442C58FD25B8),I64(0xBBB3DC5EBC91769B),
I64(0x1665FE489061EAC7),I64(0x33F27A811FA66310),I64(0x93A609346838D547),I64(0x30ED6D4C98CEC263),
I64(0x1DD9816CD8DF9F2A),I64(0x94662A03063B1E7B),I64(0x83FDD9FBEB896066),I64(0x7B207573E68E590A),
I64(0x5F49FC0A149A4407),I64(0x343259B671A5A82C),I64(0xFBC2BB458A6F981F),I64(0xC272B350A0A41A38),
I64(0x3AAF1FD8ADA32354),I64(0x6CBB868B0B3C2717),I64(0xA2B569C88D2583FE),I64(0xF180C9D1BF027928),
I64(0xAF37386BD64BA9F5),I64(0x12BACAB2790A8088),I64(0x4C0D3B0810435055),I64(0xB2EEB9070E9436DF),
I64(0xC5B29067CEA7D104),I64(0xDCB425F1FF132461),I64(0x4F122CC5972BF126),I64(0xAC282FA651230886),
I64(0xE7E537992F6393EF),I64(0xE61B3A2952B00735),I64(0x709C0A57AE302CE7),I64(0xE02514AE416058D3),
I64(0xC44C9DD7B37445DE),I64(0x5A68C5408022BA92),I64(0x1C278CDCA50C0BF0),I64(0x6E5A9CF6F18712BE),
I64(0x86DCE0B17F319EF3),I64(0x2D34EC2040115D49),I64(0x4BCD183F7E409B69),I64(0x2815D56AD4A9A3DC),
I64(0x24698979F2141D0D),I64(0x0000000000000000),I64(0x1EC696A15FB73E59),I64(0xD86B110B16784E2E),
I64(0x8E7F8858B0E74A6D),I64(0x063E2E8713D05FE6),I64(0xE2C40ED3BBDB6D7A),I64(0xB1F1AECA89FC97AC),
I64(0xE1DB191E3CB3CC09),I64(0x6418EE62C4EAF389),I64(0xC6AD87AA49CF7077),I64(0xD6F65765CA7EC556),
I64(0x9AFB6C6DDA3D9503),I64(0x7CE05644888D9236),I64(0x8D609F95378FEB1E),I64(0x23A9AA4E9C17D631),
I64(0x6226C0E5D73AAC6F),I64(0x56149953A69F0443),I64(0xEEB852C09D66D3AB),I64(0x2B0AC2A753C102AF),
I64(0x07C023376E03CB3C),I64(0x2CCAE1903DC2C993),I64(0xD3D76E2F5EC63BC3),I64(0x9E2458973356FF4C),
I64(0xA66A5D32644EE9B1),I64(0x0A427294356DE137),I64(0x783F62BE61E6F879),I64(0x1344C70204D91452),
I64(0x5B96C8F0FDF12E48),I64(0xA90916ECC59BF613),I64(0xBE92E5142829880E),I64(0x727D102A548B194E),
I64(0x1BE7AFEBCB0FC0CC),I64(0x3E702B2244C8491B),I64(0xD5E940A84D166425),I64(0x66F9F41F3E51C620),
I64(0xABE80C913F20C3BA),I64(0xF07EC461C2D1EDF2),I64(0xF361D3AC45B94C81),I64(0x0521394A94B8FE95),
I64(0xADD622162CF09C5C),I64(0xE97871F7F3651897),I64(0xF4A1F09B2BBA87BD),I64(0x095D6559B2054044),
I64(0x0BBC7F2448BE75ED),I64(0x2AF4CF172E129675),I64(0x157AE98517094BB4),I64(0x9FDA55274E856B96),
I64(0x914713499283E0EE),I64(0xB952C623462A4332),I64(0x74433EAD475B46A8),I64(0x8B5EB112245FB4F8),
I64(0xA34B6478F0F61724),I64(0x11A5DD7FFE6221FB),I64(0xC16DA49D27CCBB4B),I64(0x76A224D0BDE07301),
I64(0x8AA0BCA2598C2022),I64(0x4DF336B86D90C48F),I64(0xEA67663A740DB9E4),I64(0xEF465F70E0B54771),
I64(0x39B008152ACB8227),I64(0x7D1E5BF4F55E06EC),I64(0x105BD0CF83B1B521),I64(0x775C2960C033E7DB),
I64(0x7E014C397236A79F),I64(0x811CC386113255CF),I64(0xEDA7450D1A0E72D8),I64(0x5889DF3D7A998F3B),
I64(0x2E2BFBEDC779FC3A),I64(0xCE0EEF438619A4E9),I64(0x372D4E7BF6CD095F),I64(0x04DF34FAE96B6A4F),
I64(0xF923A13870D4ADB6),I64(0xA1AA7E050A4D228D),I64(0xA8F71B5CB84862C9),I64(0xB52E9A306097FDE3),
I64(0x0D8251A35B6E2A0B),I64(0x2257A7FEE1C442EB),I64(0x73831D9A29588D94),I64(0x51D4BA64C89CCF7F),
I64(0x502AB7D4B54F5BA5),I64(0x97793DCE8153BF08),I64(0xE5042DE4D5D8A646),I64(0x9687307EFC802BD2),
I64(0xA05473B5779EB657),I64(0xB4D097801D446939),I64(0xCFF0E2F3FBCA3033),I64(0xC38CBEE0DD778EE2),
I64(0x464F499C252EB162),I64(0xCAD1DBB96F72CEA6),I64(0xBA4DD1EEC142E241),I64(0xB00FA37AF42F0376)
},
{
I64(0xCCE4CD3AA968B245),I64(0x089D5484E80B7FAF),I64(0x638246C1B3548304),I64(0xD2FE0EC8C2355492),
I64(0xA7FBDF7FF2374EEE),I64(0x4DF1600C92337A16),I64(0x84E503EA523B12FB),I64(0x0790BBFD53AB0C4A),
I64(0x198A780F38F6EA9D),I64(0x2AB30C8F55EC48CB),I64(0xE0F7FED6B2C49DB5),I64(0xB6ECF3F422CADBDC),
I64(0x409C9A541358DF11),I64(0xD3CE8A56DFDE3FE3),I64(0xC3E9224312C8C1A0),I64(0x0D6DFA58816BA507),
I64(0xDDF3E1B179952777),I64(0x04C02A42748BB1D9),I64(0x94C2ABFF9F2DECB8),I64(0x4F91752DA8F8ACF4),
I64(0x78682BEFB169BF7B),I64(0xE1C77A48AF2FF6C4),I64(0x0C5D7EC69C80CE76),I64(0x4CC1E4928FD81167),
I64(0xFEED3D24D9997B62),I64(0x518BB6DFC3A54A23),I64(0x6DBF2D26151F9B90),I64(0xB5BC624B05EA664F),
I64(0xE86AAA525ACFE21A),I64(0x4801CED0FB53A0BE),I64(0xC91463E6C00868ED),I64(0x1027A815CD16FE43),
I64(0xF67069A0319204CD),I64(0xB04CCC976C8ABCE7),I64(0xC0B9B3FC35E87C33),I64(0xF380C77C58F2DE65),
I64(0x50BB3241DE4E2152),I64(0xDF93F490435EF195),I64(0xF1E0D25D62390887),I64(0xAF668BFB1A3C3141),
I64(0xBC11B251F00A7291),I64(0x73A5EED47E427D47),I64(0x25BEE3F6EE4C3B2E),I64(0x43CC0BEB34786282),
I64(0xC824E778DDE3039C),I64(0xF97D86D98A327728),I64(0xF2B043E24519B514),I64(0xE297EBF7880F4B57),
I64(0x3A94A49A98FAB688),I64(0x868516CB68F0C419),I64(0xEFFA11AF0964EE50),I64(0xA4AB4EC0D517F37D),
I64(0xA9C6B498547C567A),I64(0x8E18424F80FBBBB6),I64(0x0BCDC53BCF2BC23C),I64(0x137739AAEA3643D0),
I64(0x2C1333EC1BAC2FF0),I64(0x8D48D3F0A7DB0625),I64(0x1E1AC3F26B5DE6D7),I64(0xF520F81F16B2B95E),
I64(0x9F0F6EC450062E84),I64(0x0130849E1DEB6B71),I64(0xD45E31AB8C7533A9),I64(0x652279A2FD14E43F),
I64(0x3209F01E70F1C927),I64(0xBE71A770CAC1A473),I64(0x0E3D6BE7A64B1894),I64(0x7EC8148CFF29D840),
I64(0xCB7476C7FAC3BE0F),I64(0x72956A4A63A91636),I64(0x37F95EC21991138F),I64(0x9E3FEA5A4DED45F5),
I64(0x7B38BA50964902E8),I64(0x222E580BBDE73764),I64(0x61E253E0899F55E6),I64(0xFC8D2805E352AD80),
I64(0x35994BE3235AC56D),I64(0x09ADD01AF5E014DE),I64(0x5E8659A6780539C6),I64(0xB17C48097161D796),
I64(0x026015213ACBD6E2),I64(0xD1AE9F77E515E901),I64(0xB7DC776A3F21B0AD),I64(0xABA6A1B96EB78098),
I64(0x9BCF4486248D9F5D),I64(0x582666C536455EFD),I64(0xFDBDAC9BFEB9C6F1),I64(0xC47999BE4163CDEA),
I64(0x765540081722A7EF),I64(0x3E548ED8EC710751),I64(0x3D041F67CB51BAC2),I64(0x7958AF71AC82D40A),
I64(0x36C9DA5C047A78FE),I64(0xED9A048E33AF38B2),I64(0x26EE7249C96C86BD),I64(0x900281BDEBA65D61),
I64(0x11172C8BD0FD9532),I64(0xEA0ABF73600434F8),I64(0x42FC8F75299309F3),I64(0x34A9CF7D3EB1AE1C),
I64(0x2B838811480723BA),I64(0x5CE64C8742CEEF24),I64(0x1ADAE9B01FD6570E),I64(0x3C349BF9D6BAD1B3),
I64(0x82453C891C7B75C0),I64(0x97923A40B80D512B),I64(0x4A61DBF1C198765C),I64(0xB48CE6D518010D3E),
I64(0xCFB45C858E480FD6),I64(0xD933CBF30D1E96AE),I64(0xD70EA014AB558E3A),I64(0xC189376228031742),
I64(0x9262949CD16D8B83),I64(0xEB3A3BED7DEF5F89),I64(0x49314A4EE6B8CBCF),I64(0xDCC3652F647E4C06),
I64(0xDA635A4C2A3E2B3D),I64(0x470C21A940F3D35B),I64(0x315961A157D174B4),I64(0x6672E81DDA3459AC),
I64(0x5B76F77A1165E36E),I64(0x445CB01667D36EC8),I64(0xC5491D205C88A69B),I64(0x456C34887A3805B9),
I64(0xFFDDB9BAC4721013),I64(0x99AF51A71E4649BF),I64(0xA15BE01CBC7729D5),I64(0x52DB2760E485F7B0),
I64(0x8C78576EBA306D54),I64(0xAE560F6507D75A30),I64(0x95F22F6182C687C9),I64(0x71C5FBF54489ABA5),
I64(0xCA44F259E728D57E),I64(0x88B87D2CCEBBDC8D),I64(0xBAB18D32BE4A15AA),I64(0x8BE8EC93E99B611E),
I64(0x17B713E89EBDF209),I64(0xB31C5D284BAA0174),I64(0xEECA9531148F8521),I64(0xB8D198138481C348),
I64(0x8988F9B2D350B7FC),I64(0xB9E11C8D996AA839),I64(0x5A4673E40C8E881F),I64(0x1687977683569978),
I64(0xBF4123EED72ACF02),I64(0x4EA1F1B3B513C785),I64(0xE767452BE16F91FF),I64(0x7505D1B730021A7C),
I64(0xA59BCA5EC8FC980C),I64(0xAD069EDA20F7E7A3),I64(0x38F4B1BBA231606A),I64(0x60D2D77E94743E97),
I64(0x9AFFC0183966F42C),I64(0x248E6768F3A7505F),I64(0xCDD449A4B483D934),I64(0x87B59255751BAF68),
I64(0x1BEA6D2E023D3C7F),I64(0x6B1F12455B5FFCAB),I64(0x743555292DE9710D),I64(0xD8034F6D10F5FDDF),
I64(0xC6198C9F7BA81B08),I64(0xBB8109ACA3A17EDB),I64(0xFA2D1766AD12CABB),I64(0xC729080166437079),
I64(0x9C5FFF7B77269317),I64(0x0000000000000000),I64(0x15D706C9A47624EB),I64(0x6FDF38072FD44D72),
I64(0x5FB6DD3865EE52B7),I64(0xA33BF53D86BCFF37),I64(0xE657C1B5FC84FA8E),I64(0xAA962527735CEBE9),
I64(0x39C43525BFDA0B1B),I64(0x204E4D2A872CE186),I64(0x7A083ECE8BA26999),I64(0x554B9C9DB72EFBFA),
I64(0xB22CD9B656416A05),I64(0x96A2BEDEA5E63A5A),I64(0x802529A826B0A322),I64(0x8115AD363B5BC853),
I64(0x8375B81701901EB1),I64(0x3069E53F4A3A1FC5),I64(0xBD2136CFEDE119E0),I64(0x18BAFC91251D81EC),
I64(0x1D4A524D4C7D5B44),I64(0x05F0AEDC6960DAA8),I64(0x29E39D3072CCF558),I64(0x70F57F6B5962C0D4),
I64(0x989FD53903AD22CE),I64(0xF84D024797D91C59),I64(0x547B1803AAC5908B),I64(0xF0D056C37FD263F6),
I64(0xD56EB535919E58D8),I64(0x1C7AD6D351963035),I64(0x2E7326CD2167F912),I64(0xAC361A443D1C8CD2),
I64(0x697F076461942A49),I64(0x4B515F6FDC731D2D),I64(0x8AD8680DF4700A6F),I64(0x41AC1ECA0EB3B460),
I64(0x7D988533D80965D3),I64(0xA8F6300649973D0B),I64(0x7765C4960AC9CC9E),I64(0x7CA801ADC5E20EA2),
I64(0xDEA3700E5EB59AE4),I64(0xA06B6482A19C42A4),I64(0x6A2F96DB46B497DA),I64(0x27DEF6D7D487EDCC),
I64(0x463CA5375D18B82A),I64(0xA6CB5BE1EFDC259F),I64(0x53EBA3FEF96E9CC1),I64(0xCE84D81B93A364A7),
I64(0xF4107C810B59D22F),I64(0x333974806D1AA256),I64(0x0F0DEF79BBA073E5),I64(0x231EDC95A00C5C15),
I64(0xE437D494C64F2C6C),I64(0x91320523F64D3610),I64(0x67426C83C7DF32DD),I64(0x6EEFBC99323F2603),
I64(0x9D6F7BE56ACDF866),I64(0x5916E25B2BAE358C),I64(0x7FF89012E2C2B331),I64(0x035091BF2720BD93),
I64(0x561B0D22900E4669),I64(0x28D319AE6F279E29),I64(0x2F43A2533C8C9263),I64(0xD09E1BE9F8FE8270),
I64(0xF740ED3E2C796FBC),I64(0xDB53DED237D5404C),I64(0x62B2C25FAEBFE875),I64(0x0AFD41A5D2C0A94D),
I64(0x6412FD3CE0FF8F4E),I64(0xE3A76F6995E42026),I64(0x6C8FA9B808F4F0E1),I64(0xC2D9A6DD0F23AAD1),
I64(0x8F28C6D19D10D0C7),I64(0x85D587744FD0798A),I64(0xA20B71A39B579446),I64(0x684F83FA7C7F4138),
I64(0xE507500ADBA4471D),I64(0x3F640A46F19A6C20),I64(0x1247BD34F7DD28A1),I64(0x2D23B77206474481),
I64(0x93521002CC86E0F2),I64(0x572B89BC8DE52D18),I64(0xFB1D93F8B0F9A1CA),I64(0xE95A2ECC4724896B),
I64(0x3BA420048511DDF9),I64(0xD63E248AB6BEE54B),I64(0x5DD6C8195F258455),I64(0x06A03F634E40673B),
I64(0x1F2A476C76B68DA6),I64(0x217EC9B49AC78AF7),I64(0xECAA80102E4453C3),I64(0x14E78257B99D4F9A)
},
{
I64(0x20329B2CC87BBA05),I64(0x4F5EB6F86546A531),I64(0xD4F44775F751B6B1),I64(0x8266A47B850DFA8B),
I64(0xBB986AA15A6CA985),I64(0xC979EB08F9AE0F99),I64(0x2DA6F447A2375EA1),I64(0x1E74275DCD7D8576),
I64(0xBC20180A800BC5F8),I64(0xB4A2F701B2DC65BE),I64(0xE726946F981B6D66),I64(0x48E6C453BF21C94C),
I64(0x42CAD9930F0A4195),I64(0xEFA47B64AACCCD20),I64(0x71180A8960409A42),I64(0x8BB3329BF6A44E0C),
I64(0xD34C35DE2D36DACC),I64(0xA92F5B7CBC23DC96),I64(0xB31A85AA68BB09C3),I64(0x13E04836A73161D2),
I64(0xB24DFC4129C51D02),I64(0x8AE44B70B7DA5ACD),I64(0xE671ED84D96579A7),I64(0xA4BB3417D66F3832),
I64(0x4572AB38D56D2DE8),I64(0xB1B47761EA47215C),I64(0xE81C09CF70ABA15D),I64(0xFFBDB872CE7F90AC),
I64(0xA8782297FD5DC857),I64(0x0D946F6B6A4CE4A4),I64(0xE4DF1F4F5B995138),I64(0x9EBC71EDCA8C5762),
I64(0x0A2C1DC0B02B88D9),I64(0x3B503C115D9D7B91),I64(0xC64376A8111EC3A2),I64(0xCEC199A323C963E4),
I64(0xDC76A87EC58616F7),I64(0x09D596E073A9B487),I64(0x14583A9D7D560DAF),I64(0xF4C6DC593F2A0CB4),
I64(0xDD21D19584F80236),I64(0x4A4836983DDDE1D3),I64(0xE58866A41AE745F9),I64(0xF591A5B27E541875),
I64(0x891DC05074586693),I64(0x5B068C651810A89E),I64(0xA30346BC0C08544F),I64(0x3DBF3751C684032D),
I64(0x2A1E86EC785032DC),I64(0xF73F5779FCA830EA),I64(0xB60C05CA30204D21),I64(0x0CC316802B32F065),
I64(0x8770241BDD96BE69),I64(0xB861E18199EE95DB),I64(0xF805CAD91418FCD1),I64(0x29E70DCCBBD20E82),
I64(0xC7140F435060D763),I64(0x0F3A9DA0E8B0CC3B),I64(0xA2543F574D76408E),I64(0xBD7761E1C175D139),
I64(0x4B1F4F737CA3F512),I64(0x6DC2DF1F2FC137AB),I64(0xF1D05C3967B14856),I64(0xA742BF3715ED046C),
I64(0x654030141D1697ED),I64(0x07B872ABDA676C7D),I64(0x3CE84EBA87FA17EC),I64(0xC1FB0403CB79AFDF),
I64(0x3E46BC7105063F73),I64(0x278AE987121CD678),I64(0xA1ADB4778EF47CD0),I64(0x26DD906C5362C2B9),
I64(0x05168060589B44E2),I64(0xFBFC41F9D79AC08F),I64(0x0E6DE44BA9CED8FA),I64(0x9FEB08068BF243A3),
I64(0x7B341749D06B129B),I64(0x229C69E74A87929A),I64(0xE09EE6C4427C011B),I64(0x5692E30E725C4C3A),
I64(0xDA99A33E5E9F6E4B),I64(0x353DD85AF453A36B),I64(0x25241B4C90E0FEE7),I64(0x5DE987258309D022),
I64(0xE230140FC0802984),I64(0x93281E86A0C0B3C6),I64(0xF229D719A4337408),I64(0x6F6C2DD4AD3D1F34),
I64(0x8EA5B2FBAE3F0AEE),I64(0x8331DD90C473EE4A),I64(0x346AA1B1B52DB7AA),I64(0xDF8F235E06042AA9),
I64(0xCC6F6B68A1354B7B),I64(0x6C95A6F46EBF236A),I64(0x52D31A856BB91C19),I64(0x1A35DED6D498D555),
I64(0xF37EAEF2E54D60C9),I64(0x72E181A9A3C2A61C),I64(0x98537AAD51952FDE),I64(0x16F6C856FFAA2530),
I64(0xD960281E9D1D5215),I64(0x3A0745FA1CE36F50),I64(0x0B7B642BF1559C18),I64(0x59A87EAE9AEC8001),
I64(0x5E100C05408BEC7C),I64(0x0441F98B19E55023),I64(0xD70DCC5534D38AEF),I64(0x927F676DE1BEA707),
I64(0x9769E70DB925E3E5),I64(0x7A636EA29115065A),I64(0x468B201816EF11B6),I64(0xAB81A9B73EDFF409),
I64(0xC0AC7DE88A07BB1E),I64(0x1F235EB68C0391B7),I64(0x6056B074458DD30F),I64(0xBE8EEAC102F7ED67),
I64(0xCD381283E04B5FBA),I64(0x5CBEFECEC277C4E3),I64(0xD21B4C356C48CE0D),I64(0x1019C31664B35D8C),
I64(0x247362A7D19EEA26),I64(0xEBE582EFB3299D03),I64(0x02AEF2CB82FC289F),I64(0x86275DF09CE8AAA8),
I64(0x28B07427FAAC1A43),I64(0x38A9B7319E1F47CF),I64(0xC82E92E3B8D01B58),I64(0x06EF0B409B1978BC),
I64(0x62F842BFC771FB90),I64(0x9904034610EB3B1F),I64(0xDED85AB5477A3E68),I64(0x90D195A663428F98),
I64(0x5384636E2AC708D8),I64(0xCBD719C37B522706),I64(0xAE9729D76644B0EB),I64(0x7C8C65E20A0C7EE6),
I64(0x80C856B007F1D214),I64(0x8C0B40302CC32271),I64(0xDBCEDAD51FE17A8A),I64(0x740E8AE938DBDEA0),
I64(0xA615C6DC549310AD),I64(0x19CC55F6171AE90B),I64(0x49B1BDB8FE5FDD8D),I64(0xED0A89AF2830E5BF),
I64(0x6A7AADB4F5A65BD6),I64(0x7E22972988F05679),I64(0xF952B3325566E810),I64(0x39FECEDADF61530E),
I64(0x6101C99F04F3C7CE),I64(0x2E5F7F6761B562FF),I64(0xF08725D226CF5C97),I64(0x63AF3B54860FEF51),
I64(0x8FF2CB10EF411E2F),I64(0x884AB9BB35267252),I64(0x4DF04433E7BA8DAE),I64(0x9AFD8866D3690741),
I64(0x66B9BB34DE94ABB3),I64(0x9BAAF18D92171380),I64(0x543C11C5F0A064A5),I64(0x17A1B1BDBED431F1),
I64(0xB5F58EEAF3A2717F),I64(0xC355F6C849858740),I64(0xEC5DF044694EF17E),I64(0xD83751F5DC6346D4),
I64(0xFC4433520DFDACF2),I64(0x0000000000000000),I64(0x5A51F58E596EBC5F),I64(0x3285AAF12E34CF16),
I64(0x8D5C39DB6DBD36B0),I64(0x12B731DDE64F7513),I64(0x94906C2D7AA7DFBB),I64(0x302B583AACC8E789),
I64(0x9D45FACD090E6B3C),I64(0x2165E2C78905AEC4),I64(0x68D45F7F775A7349),I64(0x189B2C1D5664FDCA),
I64(0xE1C99F2F030215DA),I64(0x6983269436246788),I64(0x8489AF3B1E148237),I64(0xE94B702431D5B59C),
I64(0x33D2D31A6F4ADBD7),I64(0xBFD9932A4389F9A6),I64(0xB0E30E8AAB39359D),I64(0xD1E2C715AFCAF253),
I64(0x150F43763C28196E),I64(0xC4ED846393E2EB3D),I64(0x03F98B20C3823C5E),I64(0xFD134AB94C83B833),
I64(0x556B682EB1DE7064),I64(0x36C4537A37D19F35),I64(0x7559F30279A5CA61),I64(0x799AE58252973A04),
I64(0x9C12832648707FFD),I64(0x78CD9C6913E92EC5),I64(0x1D8DAC7D0EFFB928),I64(0x439DA0784E745554),
I64(0x413352B3CC887DCB),I64(0xBACF134A1B12BD44),I64(0x114EBAFD25CD494D),I64(0x2F08068C20CB763E),
I64(0x76A07822BA27F63F),I64(0xEAB2FB04F25789C2),I64(0xE3676DE481FE3D45),I64(0x1B62A73D95E6C194),
I64(0x641749FF5C68832C),I64(0xA5EC4DFC97112CF3),I64(0xF6682E92BDD6242B),I64(0x3F11C59A44782BB2),
I64(0x317C21D1EDB6F348),I64(0xD65AB5BE75AD9E2E),I64(0x6B2DD45FB4D84F17),I64(0xFAAB381296E4D44E),
I64(0xD0B5BEFEEEB4E692),I64(0x0882EF0B32D7A046),I64(0x512A91A5A83B2047),I64(0x963E9EE6F85BF724),
I64(0x4E09CF132438B1F0),I64(0x77F701C9FB59E2FE),I64(0x7DDB1C094B726A27),I64(0x5F4775EE01F5F8BD),
I64(0x9186EC4D223C9B59),I64(0xFEEAC1998F01846D),I64(0xAC39DB1CE4B89874),I64(0xB75B7C21715E59E0),
I64(0xAFC0503C273AA42A),I64(0x6E3B543FEC430BF5),I64(0x704F7362213E8E83),I64(0x58FF0745DB9294C0),
I64(0x67EEC2DF9FEABF72),I64(0xA0FACD9CCF8A6811),I64(0xB936986AD890811A),I64(0x95C715C63BD9CB7A),
I64(0xCA8060283A2C33C7),I64(0x507DE84EE9453486),I64(0x85DED6D05F6A96F6),I64(0x1CDAD5964F81ADE9),
I64(0xD5A33E9EB62FA270),I64(0x40642B588DF6690A),I64(0x7F75EEC2C98E42B8),I64(0x2CF18DACE3494A60),
I64(0x23CB100C0BF9865B),I64(0xEEF3028FEBB2D9E1),I64(0x4425D2D394133929),I64(0xAAD6D05C7FA1E0C8),
I64(0xAD6EA2F7A5C68CB5),I64(0xC2028F2308FB9381),I64(0x819F2F5B468FC6D5),I64(0xC5BAFD88D29CFFFC),
I64(0x47DC59F357910577),I64(0x2B49FF07392E261D),I64(0x57C59AE5332258FB),I64(0x73B6F842E2BCB2DD),
I64(0xCF96E04862B77725),I64(0x4CA73DD8A6C4996F),I64(0x015779EB417E14C1),I64(0x37932A9176AF8BF4)
},
{
I64(0x190A2C9B249DF23E),I64(0x2F62F8B62263E1E9),I64(0x7A7F754740993655),I64(0x330B7BA4D5564D9F),
I64(0x4C17A16A46672582),I64(0xB22F08EB7D05F5B8),I64(0x535F47F40BC148CC),I64(0x3AEC5D27D4883037),
I64(0x10ED0A1825438F96),I64(0x516101F72C233D17),I64(0x13CC6F949FD04EAE),I64(0x739853C441474BFD),
I64(0x653793D90D3F5B1B),I64(0x5240647B96B0FC2F),I64(0x0C84890AD27623E0),I64(0xD7189B32703AAEA3),
I64(0x2685DE3523BD9C41),I64(0x99317C5B11BFFEFA),I64(0x0D9BAA854F079703),I64(0x70B93648FBD48AC5),
I64(0xA80441FCE30BC6BE),I64(0x7287704BDC36FF1E),I64(0xB65384ED33DC1F13),I64(0xD36417343EE34408),
I64(0x39CD38AB6E1BF10F),I64(0x5AB861770A1F3564),I64(0x0EBACF09F594563B),I64(0xD04572B884708530),
I64(0x3CAE9722BDB3AF47),I64(0x4A556B6F2F5CBAF2),I64(0xE1704F1F76C4BD74),I64(0x5EC4ED7144C6DFCF),
I64(0x16AFC01D4C7810E6),I64(0x283F113CD629CA7A),I64(0xAF59A8761741ED2D),I64(0xEED5A3991E215FAC),
I64(0x3BF37EA849F984D4),I64(0xE413E096A56CE33C),I64(0x2C439D3A98F020D1),I64(0x637559DC6404C46B),
I64(0x9E6C95D1E5F5D569),I64(0x24BB9836045FE99A),I64(0x44EFA466DAC8ECC9),I64(0xC6EAB2A5C80895D6),
I64(0x803B50C035220CC4),I64(0x0321658CBA93C138),I64(0x8F9EBC465DC7EE1C),I64(0xD15A5137190131D3),
I64(0x0FA5EC8668E5E2D8),I64(0x91C979578D1037B1),I64(0x0642CA05693B9F70),I64(0xEFCA80168350EB4F),
I64(0x38D21B24F36A45EC),I64(0xBEAB81E1AF73D658),I64(0x8CBFD9CAE7542F24),I64(0xFD19CC0D81F11102),
I64(0x0AC6430FBB4DBC90),I64(0x1D76A09D6A441895),I64(0x2A01573FF1CBBFA1),I64(0xB572E161894FDE2B),
I64(0x8124734FA853B827),I64(0x614B1FDF43E6B1B0),I64(0x68AC395C4238CC18),I64(0x21D837BFD7F7B7D2),
I64(0x20C714304A860331),I64(0x5CFAAB726324AA14),I64(0x74C5BA4EB50D606E),I64(0xF3A3030474654739),
I64(0x23E671BCF015C209),I64(0x45F087E947B9582A),I64(0xD8BD77B418DF4C7B),I64(0xE06F6C90EBB50997),
I64(0x0BD96080263C0873),I64(0x7E03F9410E40DCFE),I64(0xB8E94BE4C6484928),I64(0xFB5B0608E8CA8E72),
I64(0x1A2B49179E0E3306),I64(0x4E29E76961855059),I64(0x4F36C4E6FCF4E4BA),I64(0x49740EE395CF7BCA),
I64(0xC2963EA386D17F7D),I64(0x90D65AD810618352),I64(0x12D34C1B02A1FA4D),I64(0xFA44258775BB3A91),
I64(0x18150F14B9EC46DD),I64(0x1491861E6B9A653D),I64(0x9A1019D7AB2C3FC2),I64(0x3668D42D06FE13D7),
I64(0xDCC1FBB25606A6D0),I64(0x969490DD795A1C22),I64(0x3549B1A1BC6DD2EF),I64(0xC94F5E23A0ED770E),
I64(0xB9F6686B5B39FDCB),I64(0xC4D4F4A6EFEAE00D),I64(0xE732851A1FFF2204),I64(0x94AAD6DE5EB869F9),
I64(0x3F8FF2AE07206E7F),I64(0xFE38A9813B62D03A),I64(0xA7A1AD7A8BEE2466),I64(0x7B6056C8DDE882B6),
I64(0x302A1E286FC58CA7),I64(0x8DA0FA457A259BC7),I64(0xB3302B64E074415B),I64(0x5402AE7EFF8B635F),
I64(0x08F8050C9CAFC94B),I64(0xAE468BF98A3059CE),I64(0x88C355CCA98DC58F),I64(0xB10E6D67C7963480),
I64(0xBAD70DE7E1AA3CF3),I64(0xBFB4A26E320262BB),I64(0xCB711820870F02D5),I64(0xCE12B7A954A75C9D),
I64(0x563CE87DD8691684),I64(0x9F73B65E7884618A),I64(0x2B1E74B06CBA0B42),I64(0x47CEC1EA605B2DF1),
I64(0x1C698312F735AC76),I64(0x5FDBCEFED9B76B2C),I64(0x831A354C8FB1CDFC),I64(0x820516C312C0791F),
I64(0xB74CA762AEADABF0),I64(0xFC06EF821C80A5E1),I64(0x5723CBF24518A267),I64(0x9D4DF05D5F661451),
I64(0x588627742DFD40BF),I64(0xDA8331B73F3D39A0),I64(0x17B0E392D109A405),I64(0xF965400BCF28FBA9),
I64(0x7C3DBF4229A2A925),I64(0x023E460327E275DB),I64(0x6CD0B55A0CE126B3),I64(0xE62DA695828E96E7),
I64(0x42AD6E63B3F373B9),I64(0xE50CC319381D57DF),I64(0xC5CBD729729B54EE),I64(0x46D1E265FD2A9912),
I64(0x6428B056904EEFF8),I64(0x8BE23040131E04B7),I64(0x6709D5DA2ADD2EC0),I64(0x075DE98AF44A2B93),
I64(0x8447DCC67BFBE66F),I64(0x6616F655B7AC9A23),I64(0xD607B8BDED4B1A40),I64(0x0563AF89D3A85E48),
I64(0x3DB1B4AD20C21BA4),I64(0x11F22997B8323B75),I64(0x292032B34B587E99),I64(0x7F1CDACE9331681D),
I64(0x8E819FC9C0B65AFF),I64(0xA1E3677FE2D5BB16),I64(0xCD33D225EE349DA5),I64(0xD9A2543B85AEF898),
I64(0x795E10CBFA0AF76D),I64(0x25A4BBB9992E5D79),I64(0x78413344677B438E),I64(0xF0826688CEF68601),
I64(0xD27B34BBA392F0EB),I64(0x551D8DF162FAD7BC),I64(0x1E57C511D0D7D9AD),I64(0xDEFFBDB171E4D30B),
I64(0xF4FEEA8E802F6CAA),I64(0xA480C8F6317DE55E),I64(0xA0FC44F07FA40FF5),I64(0x95B5F551C3C9DD1A),
I64(0x22F952336D6476EA),I64(0x0000000000000000),I64(0xA6BE8EF5169F9085),I64(0xCC2CF1AA73452946),
I64(0x2E7DDB39BF12550A),I64(0xD526DD3157D8DB78),I64(0x486B2D6C08BECF29),I64(0x9B0F3A58365D8B21),
I64(0xAC78CDFAADD22C15),I64(0xBC95C7E28891A383),I64(0x6A927F5F65DAB9C3),I64(0xC3891D2C1BA0CB9E),
I64(0xEAA92F9F50F8B507),I64(0xCF0D9426C9D6E87E),I64(0xCA6E3BAF1A7EB636),I64(0xAB25247059980786),
I64(0x69B31AD3DF4978FB),I64(0xE2512A93CC577C4C),I64(0xFF278A0EA61364D9),I64(0x71A615C766A53E26),
I64(0x89DC764334FC716C),I64(0xF87A638452594F4A),I64(0xF2BC208BE914F3DA),I64(0x8766B94AC1682757),
I64(0xBBC82E687CDB8810),I64(0x626A7A53F9757088),I64(0xA2C202F358467A2E),I64(0x4D0882E5DB169161),
I64(0x09E7268301DE7DA8),I64(0xE897699C771AC0DC),I64(0xC8507DAC3D9CC3ED),I64(0xC0A878A0A1330AA6),
I64(0x978BB352E42BA8C1),I64(0xE9884A13EA6B743F),I64(0x279AFDBABECC28A2),I64(0x047C8C064ED9EAAB),
I64(0x507E2278B15289F4),I64(0x599904FBB08CF45C),I64(0xBD8AE46D15E01760),I64(0x31353DA7F2B43844),
I64(0x8558FF49E68A528C),I64(0x76FBFC4D92EF15B5),I64(0x3456922E211C660C),I64(0x86799AC55C1993B4),
I64(0x3E90D1219A51DA9C),I64(0x2D5CBEB505819432),I64(0x982E5FD48CCE4A19),I64(0xDB9C1238A24C8D43),
I64(0xD439FEBECAA96F9B),I64(0x418C0BEF0960B281),I64(0x158EA591F6EBD1DE),I64(0x1F48E69E4DA66D4E),
I64(0x8AFD13CF8E6FB054),I64(0xF5E1C9011D5ED849),I64(0xE34E091C5126C8AF),I64(0xAD67EE7530A398F6),
I64(0x43B24DEC2E82C75A),I64(0x75DA99C1287CD48D),I64(0x92E81CDB3783F689),I64(0xA3DD217CC537CECD),
I64(0x60543C50DE970553),I64(0x93F73F54AAF2426A),I64(0xA91B62737E7A725D),I64(0xF19D4507538732E2),
I64(0x77E4DFC20F9EA156),I64(0x7D229CCDB4D31DC6),I64(0x1B346A98037F87E5),I64(0xEDF4C615A4B29E94),
I64(0x4093286094110662),I64(0xB0114EE85AE78063),I64(0x6FF1D0D6B672E78B),I64(0x6DCF96D591909250),
I64(0xDFE09E3EEC9567E8),I64(0x3214582B4827F97C),I64(0xB46DC2EE143E6AC8),I64(0xF6C0AC8DA7CD1971),
I64(0xEBB60C10CD8901E4),I64(0xF7DF8F023ABCAD92),I64(0x9C52D3D2C217A0B2),I64(0x6B8D5CD0F8AB0D20),
I64(0x3777F7A29B8FA734),I64(0x011F238F9D71B4E3),I64(0xC1B75B2F3C42BE45),I64(0x5DE588FDFE551EF7),
I64(0x6EEEF3592B035368),I64(0xAA3A07FFC4E9B365),I64(0xECEBE59A39C32A77),I64(0x5BA742F8976E8187),
I64(0x4B4A48E0B22D0E11),I64(0xDDDED83DCB771233),I64(0xA59FEB79AC0C51BD),I64(0xC7F5912A55792135)
},
{
I64(0x6D6AE04668A9B08A),I64(0x3AB3F04B0BE8C743),I64(0xE51E166B54B3C908),I64(0xBE90A9EB35C2F139),
I64(0xB2C7066637F2BEC1),I64(0xAA6945613392202C),I64(0x9A28C36F3B5201EB),I64(0xDDCE5A93AB536994),
I64(0x0E34133EF6382827),I64(0x52A02BA1EC55048B),I64(0xA2F88F97C4B2A177),I64(0x8640E513CA2251A5),
I64(0xCDF1D36258137622),I64(0xFE6CB708DEDF8DDB),I64(0x8A174A9EC8121E5D),I64(0x679896036B81560E),
I64(0x59ED033395795FEE),I64(0x1DD778AB8B74EDAF),I64(0xEE533EF92D9F926D),I64(0x2A8C79BAF8A8D8F5),
I64(0x6BCF398E69B119F6),I64(0xE20491742FAFDD95),I64(0x276488E0809C2AEC),I64(0xEA955B82D88F5CCE),
I64(0x7102C63A99D9E0C4),I64(0xF9763017A5C39946),I64(0x429FA2501F151B3D),I64(0x4659C72BEA05D59E),
I64(0x984B7FDCCF5A6634),I64(0xF742232953FBB161),I64(0x3041860E08C021C7),I64(0x747BFD9616CD9386),
I64(0x4BB1367192312787),I64(0x1B72A1638A6C44D3),I64(0x4A0E68A6E8359A66),I64(0x169A5039F258B6CA),
I64(0xB98A2EF44EDEE5A4),I64(0xD9083FE85E43A737),I64(0x967F6CE239624E13),I64(0x8874F62D3C1A7982),
I64(0x3C1629830AF06E3F),I64(0x9165EBFD427E5A8E),I64(0xB5DD81794CEEAA5C),I64(0x0DE8F15A7834F219),
I64(0x70BD98EDE3DD5D25),I64(0xACCC9CA9328A8950),I64(0x56664EDA1945CA28),I64(0x221DB34C0F8859AE),
I64(0x26DBD637FA98970D),I64(0x1ACDFFB4F068F932),I64(0x4585254F64090FA0),I64(0x72DE245E17D53AFA),
I64(0x1546B25D7C546CF4),I64(0x207E0FFFFB803E71),I64(0xFAAAD2732BCF4378),I64(0xB462DFAE36EA17BD),
I64(0xCF926FD1AC1B11FD),I64(0xE0672DC7DBA7BA4A),I64(0xD3FA49AD5D6B41B3),I64(0x8BA81449B216A3BC),
I64(0x14F9EC8A0650D115),I64(0x40FC1EE3EB1D7CE2),I64(0x23A2ED9B758CE44F),I64(0x782C521B14FDDC7E),
I64(0x1C68267CF170504E),I64(0xBCF31558C1CA96E6),I64(0xA781B43B4BA6D235),I64(0xF6FD7DFE29FF0C80),
I64(0xB0A4BAD5C3FAD91E),I64(0xD199F51EA963266C),I64(0x414340349119C103),I64(0x5405F269ED4DADF7),
I64(0xABD61BB649969DCD),I64(0x6813DBEAE7BDC3C8),I64(0x65FB2AB09F8931D1),I64(0xF1E7FAE152E3181D),
I64(0xC1A67CEF5A2339DA),I64(0x7A4FEEA8E0F5BBA1),I64(0x1E0B9ACF05783791),I64(0x5B8EBF8061713831),
I64(0x80E53CDBCB3AF8D9),I64(0x7E898BD315E57502),I64(0xC6BCFBF0213F2D47),I64(0x95A38E86B76E942D),
I64(0x092E94218D243CBA),I64(0x8339DEBF453622E7),I64(0xB11BE402B9FE64FF),I64(0x57D9100D634177C9),
I64(0xCC4E8DB52217CBC3),I64(0x3B0CAE9C71EC7AA2),I64(0xFB158CA451CBFE99),I64(0x2B33276D82AC6514),
I64(0x01BF5ED77A04BDE1),I64(0xC5601994AF33F779),I64(0x75C4A3416CC92E67),I64(0xF3844652A6EB7FC2),
I64(0x3487E375FDD0EF64),I64(0x18AE430704609EED),I64(0x4D14EFB993298EFB),I64(0x815A620CB13E4538),
I64(0x125C354207487869),I64(0x9EEEA614CE42CF48),I64(0xCE2D3106D61FAC1C),I64(0xBBE99247BAD6827B),
I64(0x071A871F7B1C149D),I64(0x2E4A1CC10DB81656),I64(0x77A71FF298C149B8),I64(0x06A5D9C80118A97C),
I64(0xAD73C27E488E34B1),I64(0x443A7B981E0DB241),I64(0xE3BBCFA355AB6074),I64(0x0AF276450328E684),
I64(0x73617A896DD1871B),I64(0x58525DE4EF7DE20F),I64(0xB7BE3DCAB8E6CD83),I64(0x19111DD07E64230C),
I64(0x842359A03E2A367A),I64(0x103F89F1F3401FB6),I64(0xDC710444D157D475),I64(0xB835702334DA5845),
I64(0x4320FC876511A6DC),I64(0xD026ABC9D3679B8D),I64(0x17250EEE885C0B2B),I64(0x90DAB52A387AE76F),
I64(0x31FED8D972C49C26),I64(0x89CBA8FA461EC463),I64(0x2FF5421677BCABB7),I64(0x396F122F85E41D7D),
I64(0xA09B332430BAC6A8),I64(0xC888E8CED7070560),I64(0xAEAF201AC682EE8F),I64(0x1180D7268944A257),
I64(0xF058A43628E7A5FC),I64(0xBD4C4B8FBBCE2B07),I64(0xA1246DF34ABE7B49),I64(0x7D5569B79BE9AF3C),
I64(0xA9B5A705BD9EFA12),I64(0xDB6B835BAA4BC0E8),I64(0x05793BAC8F147342),I64(0x21C1512881848390),
I64(0xFDB0556C50D357E5),I64(0x613D4FCB6A99FF72),I64(0x03DCE2648E0CDA3E),I64(0xE949B9E6568386F0),
I64(0xFC0F0BBB2AD7EA04),I64(0x6A70675913B5A417),I64(0x7F36D5046FE1C8E3),I64(0x0C57AF8D02304FF8),
I64(0x32223ABDFCC84618),I64(0x0891CAF6F720815B),I64(0xA63EEAEC31A26FD4),I64(0x2507345374944D33),
I64(0x49D28AC266394058),I64(0xF5219F9AA7F3D6BE),I64(0x2D96FEA583B4CC68),I64(0x5A31E1571B7585D0),
I64(0x8ED12FE53D02D0FE),I64(0xDFADE6205F5B0E4B),I64(0x4CABB16EE92D331A),I64(0x04C6657BF510CEA3),
I64(0xD73C2CD6A87B8F10),I64(0xE1D87310A1A307AB),I64(0x6CD5BE9112AD0D6B),I64(0x97C032354366F3F2),
I64(0xD4E0CEB22677552E),I64(0x0000000000000000),I64(0x29509BDE76A402CB),I64(0xC27A9E8BD42FE3E4),
I64(0x5EF7842CEE654B73),I64(0xAF107ECDBC86536E),I64(0x3FCACBE784FCB401),I64(0xD55F90655C73E8CF),
I64(0xE6C2F40FDABF1336),I64(0xE8F6E7312C873B11),I64(0xEB2A0555A28BE12F),I64(0xE4A148BC2EB774E9),
I64(0x9B979DB84156BC0A),I64(0x6EB60222E6A56AB4),I64(0x87FFBBC4B026EC44),I64(0xC703A5275B3B90A6),
I64(0x47E699FC9001687F),I64(0x9C8D1AA73A4AA897),I64(0x7CEA3760E1ED12DD),I64(0x4EC80DDD1D2554C5),
I64(0x13E36B957D4CC588),I64(0x5D2B66486069914D),I64(0x92B90999CC7280B0),I64(0x517CC9C56259DEB5),
I64(0xC937B619AD03B881),I64(0xEC30824AD997F5B2),I64(0xA45D565FC5AA080B),I64(0xD6837201D27F32F1),
I64(0x635EF3789E9198AD),I64(0x531F75769651B96A),I64(0x4F77530A6721E924),I64(0x486DD4151C3DFDB9),
I64(0x5F48DAFB9461F692),I64(0x375B011173DC355A),I64(0x3DA9775470F4D3DE),I64(0x8D0DCD81B30E0AC0),
I64(0x36E45FC609D888BB),I64(0x55BAACBE97491016),I64(0x8CB29356C90AB721),I64(0x76184125E2C5F459),
I64(0x99F4210BB55EDBD5),I64(0x6F095CF59CA1D755),I64(0x9F51F8C3B44672A9),I64(0x3538BDA287D45285),
I64(0x50C39712185D6354),I64(0xF23B1885DCEFC223),I64(0x79930CCC6EF9619F),I64(0xED8FDC9DA3934853),
I64(0xCB540AAA590BDF5E),I64(0x5C94389F1A6D2CAC),I64(0xE77DAAD8A0BBAED7),I64(0x28EFC5090CA0BF2A),
I64(0xBF2FF73C4FC64CD8),I64(0xB37858B14DF60320),I64(0xF8C96EC0DFC724A7),I64(0x828680683F329F06),
I64(0x941CD051CD6A29CC),I64(0xC3C5C05CAE2B5E05),I64(0xB601631DC2E27062),I64(0xC01922382027843B),
I64(0x24B86A840E90F0D2),I64(0xD245177A276FFC52),I64(0x0F8B4DE98C3C95C6),I64(0x3E759530FEF809E0),
I64(0x0B4D2892792C5B65),I64(0xC4DF4743D5374A98),I64(0xA5E20888BFAEB5EA),I64(0xBA56CC90C0D23F9A),
I64(0x38D04CF8FFE0A09C),I64(0x62E1ADAFE495254C),I64(0x0263BCB3F40867DF),I64(0xCAEB547D230F62BF),
I64(0x6082111C109D4293),I64(0xDAD4DD8CD04F7D09),I64(0xEFEC602E579B2F8C),I64(0x1FB4C4187F7C8A70),
I64(0xFFD3E9DFA4DB303A),I64(0x7BF0B07F9AF10640),I64(0xF49EC14DDDF76B5F),I64(0x8F6E713247066D1F),
I64(0x339D646A86CCFBF9),I64(0x64447467E58D8C30),I64(0x2C29A072F9B07189),I64(0xD8B7613F24471AD6),
I64(0x6627C8D41185EBEF),I64(0xA347D140BEB61C96),I64(0xDE12B8F7255FB3AA),I64(0x9D324470404E1576),
I64(0x9306574EB6763D51),I64(0xA80AF9D2C79A47F3),I64(0x859C0777442E8B9B),I64(0x69AC853D9DB97E29)
},
{
I64(0xC3407DFC2DE6377E),I64(0x5B9E93EEA4256F77),I64(0xADB58FDD50C845E0),I64(0x5219FF11A75BED86),
I64(0x356B61CFD90B1DE9),I64(0xFB8F406E25ABE037),I64(0x7A5A0231C0F60796),I64(0x9D3CD216E1F5020B),
I64(0x0C6550FB6B48D8F3),I64(0xF57508C427FF1C62),I64(0x4AD35FFA71CB407D),I64(0x6290A2DA1666AA6D),
I64(0xE284EC2349355F9F),I64(0xB3C307C53D7C84EC),I64(0x05E23C0468365A02),I64(0x190BAC4D6C9EBFA8),
I64(0x94BBBEE9E28B80FA),I64(0xA34FC777529CB9B5),I64(0xCC7B39F095BCD978),I64(0x2426ADDB0CE532E3),
I64(0x7E79329312CE4FC7),I64(0xAB09A72EEBEC2917),I64(0xF8D15499F6B9D6C2),I64(0x1A55B8BABF8C895D),
I64(0xDB8ADD17FB769A85),I64(0xB57F2F368658E81B),I64(0x8ACD36F18F3F41F6),I64(0x5CE3B7BBA50F11D3),
I64(0x114DCC14D5EE2F0A),I64(0xB91A7FCDED1030E8),I64(0x81D5425FE55DE7A1),I64(0xB6213BC1554ADEEE),
I64(0x80144EF95F53F5F2),I64(0x1E7688186DB4C10C),I64(0x3B912965DB5FE1BC),I64(0xC281715A97E8252D),
I64(0x54A5D7E21C7F8171),I64(0x4B12535CCBC5522E),I64(0x1D289CEFBEA6F7F9),I64(0x6EF5F2217D2E729E),
I64(0xE6A7DC819B0D17CE),I64(0x1B94B41C05829B0E),I64(0x33D7493C622F711E),I64(0xDCF7F942FA5CE421),
I64(0x600FBA8B7F7A8ECB),I64(0x46B60F011A83988E),I64(0x235B898E0DCF4C47),I64(0x957AB24F588592A9),
I64(0x4354330572B5C28C),I64(0xA5F3EF84E9B8D542),I64(0x8C711E02341B2D01),I64(0x0B1874AE6A62A657),
I64(0x1213D8E306FC19FF),I64(0xFE6D7C6A4D9DBA35),I64(0x65ED868F174CD4C9),I64(0x88522EA0E6236550),
I64(0x899322065C2D7703),I64(0xC01E690BFEF4018B),I64(0x915982ED8ABDDAF8),I64(0xBE675B98EC3A4E4C),
I64(0xA996BF7F82F00DB1),I64(0xE1DAF8D49A27696A),I64(0x2EFFD5D3DC8986E7),I64(0xD153A51F2B1A2E81),
I64(0x18CAA0EBD690ADFB),I64(0x390E3134B243C51A),I64(0x2778B92CDFF70416),I64(0x029F1851691C24A6),
I64(0x5E7CAFEACC133575),I64(0xFA4E4CC89FA5F264),I64(0x5A5F9F481E2B7D24),I64(0x484C47AB18D764DB),
I64(0x400A27F2A1A7F479),I64(0xAEEB9B2A83DA7315),I64(0x721C626879869734),I64(0x042330A2D2384851),
I64(0x85F672FD3765AFF0),I64(0xBA446B3A3E02061D),I64(0x73DD6ECEC3888567),I64(0xFFAC70CCF793A866),
I64(0xDFA9EDB5294ED2D4),I64(0x6C6AEA7014325638),I64(0x834A5A0E8C41C307),I64(0xCDBA35562FB2CB2B),
I64(0x0AD97808D06CB404),I64(0x0F3B440CB85AEE06),I64(0xE5F9C876481F213B),I64(0x98DEEE1289C35809),
I64(0x59018BBFCD394BD1),I64(0xE01BF47220297B39),I64(0xDE68E1139340C087),I64(0x9FA3CA4788E926AD),
I64(0xBB85679C840C144E),I64(0x53D8F3B71D55FFD5),I64(0x0DA45C5DD146CAA0),I64(0x6F34FE87C72060CD),
I64(0x57FBC315CF6DB784),I64(0xCEE421A1FCA0FDDE),I64(0x3D2D0196607B8D4B),I64(0x642C8A29AD42C69A),
I64(0x14AFF010BDD87508),I64(0xAC74837BEAC657B3),I64(0x3216459AD821634D),I64(0x3FB219C70967A9ED),
I64(0x06BC28F3BB246CF7),I64(0xF2082C9126D562C6),I64(0x66B39278C45EE23C),I64(0xBD394F6F3F2878B9),
I64(0xFD33689D9E8F8CC0),I64(0x37F4799EB017394F),I64(0x108CC0B26FE03D59),I64(0xDA4BD1B1417888D6),
I64(0xB09D1332EE6EB219),I64(0x2F3ED975668794B4),I64(0x58C0871977375982),I64(0x7561463D78ACE990),
I64(0x09876CFF037E82F1),I64(0x7FB83E35A8C05D94),I64(0x26B9B58A65F91645),I64(0xEF20B07E9873953F),
I64(0x3148516D0B3355B8),I64(0x41CB2B541BA9E62A),I64(0x790416C613E43163),I64(0xA011D380818E8F40),
I64(0x3A5025C36151F3EF),I64(0xD57095BDF92266D0),I64(0x498D4B0DA2D97688),I64(0x8B0C3A57353153A5),
I64(0x21C491DF64D368E1),I64(0x8F2F0AF5E7091BF4),I64(0x2DA1C1240F9BB012),I64(0xC43D59A92CCC49DA),
I64(0xBFA6573E56345C1F),I64(0x828B56A8364FD154),I64(0x9A41F643E0DF7CAF),I64(0xBCF843C985266AEA),
I64(0x2B1DE9D7B4BFDCE5),I64(0x20059D79DEDD7AB2),I64(0x6DABE6D6AE3C446B),I64(0x45E81BF6C991AE7B),
I64(0x6351AE7CAC68B83E),I64(0xA432E32253B6C711),I64(0xD092A9B991143CD2),I64(0xCAC711032E98B58F),
I64(0xD8D4C9E02864AC70),I64(0xC5FC550F96C25B89),I64(0xD7EF8DEC903E4276),I64(0x67729EDE7E50F06F),
I64(0xEAC28C7AF045CF3D),I64(0xB15C1F945460A04A),I64(0x9CFDDEB05BFB1058),I64(0x93C69ABCE3A1FE5E),
I64(0xEB0380DC4A4BDD6E),I64(0xD20DB1E8F8081874),I64(0x229A8528B7C15E14),I64(0x44291750739FBC28),
I64(0xD3CCBD4E42060A27),I64(0xF62B1C33F4ED2A97),I64(0x86A8660AE4779905),I64(0xD62E814A2A305025),
I64(0x477703A7A08D8ADD),I64(0x7B9B0E977AF815C5),I64(0x78C51A60A9EA2330),I64(0xA6ADFB733AAAE3B7),
I64(0x97E5AA1E3199B60F),I64(0x0000000000000000),I64(0xF4B404629DF10E31),I64(0x5564DB44A6719322),
I64(0x9207961A59AFEC0D),I64(0x9624A6B88B97A45C),I64(0x363575380A192B1C),I64(0x2C60CD82B595A241),
I64(0x7D272664C1DC7932),I64(0x7142769FAA94A1C1),I64(0xA1D0DF263B809D13),I64(0x1630E841D4C451AE),
I64(0xC1DF65AD44FA13D8),I64(0x13D2D445BCF20BAC),I64(0xD915C546926ABE23),I64(0x38CF3D92084DD749),
I64(0xE766D0272103059D),I64(0xC7634D5EFFDE7F2F),I64(0x077D2455012A7EA4),I64(0xEDBFA82FF16FB199),
I64(0xAF2A978C39D46146),I64(0x42953FA3C8BBD0DF),I64(0xCB061DA59496A7DC),I64(0x25E7A17DB6EB20B0),
I64(0x34AA6D6963050FBA),I64(0xA76CF7D580A4F1E4),I64(0xF7EA10954EE338C4),I64(0xFCF2643B24819E93),
I64(0xCF252D0746AEEF8D),I64(0x4EF06F58A3F3082C),I64(0x563ACFB37563A5D7),I64(0x5086E740CE47C920),
I64(0x2982F186DDA3F843),I64(0x87696AAC5E798B56),I64(0x5D22BB1D1F010380),I64(0x035E14F7D31236F5),
I64(0x3CEC0D30DA759F18),I64(0xF3C920379CDB7095),I64(0xB8DB736B571E22BB),I64(0xDD36F5E44052F672),
I64(0xAAC8AB8851E23B44),I64(0xA857B3D938FE1FE2),I64(0x17F1E4E76ECA43FD),I64(0xEC7EA4894B61A3CA),
I64(0x9E62C6E132E734FE),I64(0xD4B1991B432C7483),I64(0x6AD6C283AF163ACF),I64(0x1CE9904904A8E5AA),
I64(0x5FBDA34C761D2726),I64(0xF910583F4CB7C491),I64(0xC6A241F845D06D7C),I64(0x4F3163FE19FD1A7F),
I64(0xE99C988D2357F9C8),I64(0x8EEE06535D0709A7),I64(0x0EFA48AA0254FC55),I64(0xB4BE23903C56FA48),
I64(0x763F52CAABBEDF65),I64(0xEEE1BCD8227D876C),I64(0xE345E085F33B4DCC),I64(0x3E731561B369BBBE),
I64(0x2843FD2067ADEA10),I64(0x2ADCE5710EB1CEB6),I64(0xB7E03767EF44CCBD),I64(0x8DB012A48E153F52),
I64(0x61CEB62DC5749C98),I64(0xE85D942B9959EB9B),I64(0x4C6F7709CAEF2C8A),I64(0x84377E5B8D6BBDA3),
I64(0x30895DCBB13D47EB),I64(0x74A04A9BC2A2FBC3),I64(0x6B17CE251518289C),I64(0xE438C4D0F2113368),
I64(0x1FB784BED7BAD35F),I64(0x9B80FAE55AD16EFC),I64(0x77FE5E6C11B0CD36),I64(0xC858095247849129),
I64(0x08466059B97090A2),I64(0x01C10CA6BA0E1253),I64(0x6988D6747C040C3A),I64(0x6849DAD2C60A1E69),
I64(0x5147EBE67449DB73),I64(0xC99905F4FD8A837A),I64(0x991FE2B433CD4A5A),I64(0xF09734C04FC94660),
I64(0xA28ECBD1E892ABE6),I64(0xF1563866F5C75433),I64(0x4DAE7BAF70E13ED9),I64(0x7CE62AC27BD26B61),
I64(0x70837A39109AB392),I64(0x90988E4B30B3C8AB),I64(0xB2020B63877296BF),I64(0x156EFCB607D6675B)
},
{
I64(0xE63F55CE97C331D0),I64(0x25B506B0015BBA16),I64(0xC8706E29E6AD9BA8),I64(0x5B43D3775D521F6A),
I64(0x0BFA3D577035106E),I64(0xAB95FC172AFB0E66),I64(0xF64B63979E7A3276),I64(0xF58B4562649DAD4B),
I64(0x48F7C3DBAE0C83F1),I64(0xFF31916642F5C8C5),I64(0xCBB048DC1C4A0495),I64(0x66B8F83CDF622989),
I64(0x35C130E908E2B9B0),I64(0x7C761A61F0B34FA1),I64(0x3601161CF205268D),I64(0x9E54CCFE2219B7D6),
I64(0x8B7D90A538940837),I64(0x9CD403588EA35D0B),I64(0xBC3C6FEA9CCC5B5A),I64(0xE5FF733B6D24AEED),
I64(0xCEED22DE0F7EB8D2),I64(0xEC8581CAB1AB545E),I64(0xB96105E88FF8E71D),I64(0x8CA03501871A5EAD),
I64(0x76CCCE65D6DB2A2F),I64(0x5883F582A7B58057),I64(0x3F7BE4ED2E8ADC3E),I64(0x0FE7BE06355CD9C9),
I64(0xEE054E6C1D11BE83),I64(0x1074365909B903A6),I64(0x5DDE9F80B4813C10),I64(0x4A770C7D02B6692C),
I64(0x5379C8D5D7809039),I64(0xB4067448161ED409),I64(0x5F5E5026183BD6CD),I64(0xE898029BF4C29DF9),
I64(0x7FB63C940A54D09C),I64(0xC5171F897F4BA8BC),I64(0xA6F28DB7B31D3D72),I64(0x2E4F3BE7716EAA78),
I64(0x0D6771A099E63314),I64(0x82076254E41BF284),I64(0x2F0FD2B42733DF98),I64(0x5C9E76D3E2DC49F0),
I64(0x7AEB569619606CDB),I64(0x83478B07B2468764),I64(0xCFADCB8D5923CD32),I64(0x85DAC7F05B95A41E),
I64(0xB5469D1B4043A1E9),I64(0xB821ECBBD9A592FD),I64(0x1B8E0B0E798C13C8),I64(0x62A57B6D9A0BE02E),
I64(0xFCF1B793B81257F8),I64(0x9D94EA0BD8FE28EB),I64(0x4CEA408AEB654A56),I64(0x23284A47E888996C),
I64(0x2D8F1D128B893545),I64(0xF4CBAC3132C0D8AB),I64(0xBD7C86B9CA912EBA),I64(0x3A268EEF3DBE6079),
I64(0xF0D62F6077A9110C),I64(0x2735C916ADE150CB),I64(0x89FD5F03942EE2EA),I64(0x1ACEE25D2FD16628),
I64(0x90F39BAB41181BFF),I64(0x430DFE8CDE39939F),I64(0xF70B8AC4C8274796),I64(0x1C53AEAAC6024552),
I64(0x13B410ACF35E9C9B),I64(0xA532AB4249FAA24F),I64(0x2B1251E5625A163F),I64(0xD7E3E676DA4841C7),
I64(0xA7B264E4E5404892),I64(0xDA8497D643AE72D3),I64(0x861AE105A1723B23),I64(0x38A6414991048AA4),
I64(0x6578DEC92585B6B4),I64(0x0280CFA6ACBAEADD),I64(0x88BDB650C273970A),I64(0x9333BD5EBBFF84C2),
I64(0x4E6A8F2C47DFA08B),I64(0x321C954DB76CEF2A),I64(0x418D312A72837942),I64(0xB29B38BFFFCDF773),
I64(0x6C022C38F90A4C07),I64(0x5A033A240B0F6A8A),I64(0x1F93885F3CE5DA6F),I64(0xC38A537E96988BC6),
I64(0x39E6A81AC759FF44),I64(0x29929E43CEE0FCE2),I64(0x40CDD87924DE0CA2),I64(0xE9D8EBC8A29FE819),
I64(0x0C2798F3CFBB46F4),I64(0x55E484223E53B343),I64(0x4650948ECD0D2FD8),I64(0x20E86CB2126F0651),
I64(0x6D42C56BAF5739E7),I64(0xA06FC1405ACE1E08),I64(0x7BABBFC54F3D193B),I64(0x424D17DF8864E67F),
I64(0xD8045870EF14980E),I64(0xC6D7397C85AC3781),I64(0x21A885E1443273B1),I64(0x67F8116F893F5C69),
I64(0x24F5EFE35706CFF6),I64(0xD56329D076F2AB1A),I64(0x5E1EB9754E66A32D),I64(0x28D2771098BD8902),
I64(0x8F6013F47DFDC190),I64(0x17A993FDB637553C),I64(0xE0A219397E1012AA),I64(0x786B9930B5DA8606),
I64(0x6E82E39E55B0A6DA),I64(0x875A0856F72F4EC3),I64(0x3741FF4FA458536D),I64(0xAC4859B3957558FC),
I64(0x7EF6D5C75C09A57C),I64(0xC04A758B6C7F14FB),I64(0xF9ACDD91AB26EBBF),I64(0x7391A467C5EF9668),
I64(0x335C7C1EE1319ACA),I64(0xA91533B18641E4BB),I64(0xE4BF9A683B79DB0D),I64(0x8E20FAA72BA0B470),
I64(0x51F907737B3A7AE4),I64(0x2268A314BED5EC8C),I64(0xD944B123B949EDEE),I64(0x31DCB3B84D8B7017),
I64(0xD3FE65279F218860),I64(0x097AF2F1DC8FFAB3),I64(0x9B09A6FC312D0B91),I64(0xCC6DED78A3C4520F),
I64(0x3481D9BA5EBFCC50),I64(0x4F2A667F1182D56B),I64(0xDFD9FDD4509ACE94),I64(0x26752045FBBC252B),
I64(0xBFFC491F662BC467),I64(0xDD593272FC202449),I64(0x3CBBC218D46D4303),I64(0x91B372F817456E1F),
I64(0x681FAF69BC6385A0),I64(0xB686BBEEBAA43ED4),I64(0x1469B5084CD0CA01),I64(0x98C98009CBCA94AC),
I64(0x6438379A73D8C354),I64(0xC2CABA2DC0C5FE26),I64(0x3E3B0DBE78D7A9DE),I64(0x50B9EE202D670F04),
I64(0x4590B27B37EAB0E5),I64(0x6025B4CB36B10AF3),I64(0xFB2C1237079C0162),I64(0xA12F28130C936BE8),
I64(0x4B37E52E54EB1CCC),I64(0x083A1BA28AD28F53),I64(0xC10A9CD83A22611B),I64(0x9F1425AD7444C236),
I64(0x069D4CF7E9D3237A),I64(0xEDC56899E7F621BE),I64(0x778C273680865FCF),I64(0x309C5AEB1BD605F7),
I64(0x8DE0DC52D1472B4D),I64(0xF8EC34C2FD7B9E5F),I64(0xEA18CD3D58787724),I64(0xAAD515447CA67B86),
I64(0x9989695A9D97E14C),I64(0x0000000000000000),I64(0xF196C63321F464EC),I64(0x71116BC169557CB5),
I64(0xAF887F466F92C7C1),I64(0x972E3E0FFE964D65),I64(0x190EC4A8D536F915),I64(0x95AEF1A9522CA7B8),
I64(0xDC19DB21AA7D51A9),I64(0x94EE18FA0471D258),I64(0x8087ADF248A11859),I64(0xC457F6DA2916DD5C),
I64(0xFA6CFB6451C17482),I64(0xF256E0C6DB13FBD1),I64(0x6A9F60CF10D96F7D),I64(0x4DAAA9D9BD383FB6),
I64(0x03C026F5FAE79F3D),I64(0xDE99148706C7BB74),I64(0x2A52B8B6340763DF),I64(0x6FC20ACD03EDD33A),
I64(0xD423C08320AFDEFA),I64(0xBBE1CA4E23420DC0),I64(0x966ED75CA8CB3885),I64(0xEB58246E0E2502C4),
I64(0x055D6A021334BC47),I64(0xA47242111FA7D7AF),I64(0xE3623FCC84F78D97),I64(0x81C744A11EFC6DB9),
I64(0xAEC8961539CFB221),I64(0xF31609958D4E8E31),I64(0x63E5923ECC5695CE),I64(0x47107DDD9B505A38),
I64(0xA3AFE7B5A0298135),I64(0x792B7063E387F3E6),I64(0x0140E953565D75E0),I64(0x12F4F9FFA503E97B),
I64(0x750CE8902C3CB512),I64(0xDBC47E8515F30733),I64(0x1ED3610C6AB8AF8F),I64(0x5239218681DDE5D9),
I64(0xE222D69FD2AAF877),I64(0xFE71783514A8BD25),I64(0xCAF0A18F4A177175),I64(0x61655D9860EC7F13),
I64(0xE77FBC9DC19E4430),I64(0x2CCFF441DDD440A5),I64(0x16E97AAEE06A20DC),I64(0xA855DAE2D01C915B),
I64(0x1D1347F9905F30B2),I64(0xB7C652BDECF94B34),I64(0xD03E43D265C6175D),I64(0xFDB15EC0EE4F2218),
I64(0x57644B8492E9599E),I64(0x07DDA5A4BF8E569A),I64(0x54A46D71680EC6A3),I64(0x5624A2D7C4B42C7E),
I64(0xBEBCA04C3076B187),I64(0x7D36F332A6EE3A41),I64(0x3B6667BC6BE31599),I64(0x695F463AEA3EF040),
I64(0xAD08B0E0C3282D1C),I64(0xB15B1E4A052A684E),I64(0x44D05B2861B7C505),I64(0x15295C5B1A8DBFE1),
I64(0x744C01C37A61C0F2),I64(0x59C31CD1F1E8F5B7),I64(0xEF45A73F4B4CCB63),I64(0x6BDF899C46841A9D),
I64(0x3DFB2B4B823036E3),I64(0xA2EF0EE6F674F4D5),I64(0x184E2DFB836B8CF5),I64(0x1134DF0A5FE47646),
I64(0xBAA1231D751F7820),I64(0xD17EAA81339B62BD),I64(0xB01BF71953771DAE),I64(0x849A2EA30DC8D1FE),
I64(0x705182923F080955),I64(0x0EA757556301AC29),I64(0x041D83514569C9A7),I64(0x0ABAD4042668658E),
I64(0x49B72A88F851F611),I64(0x8A3D79F66EC97DD7),I64(0xCD2D042BF59927EF),I64(0xC930877AB0F0EE48),
I64(0x9273540DEDA2F122),I64(0xC797D02FD3F14261),I64(0xE1E2F06A284D674A),I64(0xD2BE8C74C97CFD80),
I64(0x9A494FAF67707E71),I64(0xB3DBD1ECA9908293),I64(0x72D14D3493B2E388),I64(0xD6A30F258C153427)
}
};
static const uint64_t gost12_iteration_constants[12][8] =
{
{
I64(0xdd806559f2a64507),I64(0x05767436cc744d23),I64(0xa2422a08a460d315),I64(0x4b7ce09192676901),
I64(0x714eb88d7585c4fc),I64(0x2f6a76432e45d016),I64(0xebcb2f81c0657c1f),I64(0xb1085bda1ecadae9)
},
{
I64(0xe679047021b19bb7),I64(0x55dda21bd7cbcd56),I64(0x5cb561c2db0aa7ca),I64(0x9ab5176b12d69958),
I64(0x61d55e0f16b50131),I64(0xf3feea720a232b98),I64(0x4fe39d460f70b5d7),I64(0x6fa3b58aa99d2f1a)
},
{
I64(0x991e96f50aba0ab2),I64(0xc2b6f443867adb31),I64(0xc1c93a376062db09),I64(0xd3e20fe490359eb1),
I64(0xf2ea7514b1297b7b),I64(0x06f15e5f529c1f8b),I64(0x0a39fc286a3d8435),I64(0xf574dcac2bce2fc7)
},
{
I64(0x220cbebc84e3d12e),I64(0x3453eaa193e837f1),I64(0xd8b71333935203be),I64(0xa9d72c82ed03d675),
I64(0x9d721cad685e353f),I64(0x488e857e335c3c7d),I64(0xf948e1a05d71e4dd),I64(0xef1fdfb3e81566d2)
},
{
I64(0x601758fd7c6cfe57),I64(0x7a56a27ea9ea63f5),I64(0xdfff00b723271a16),I64(0xbfcd1747253af5a3),
I64(0x359e35d7800fffbd),I64(0x7f151c1f1686104a),I64(0x9a3f410c6ca92363),I64(0x4bea6bacad474799)
},
{
I64(0xfa68407a46647d6e),I64(0xbf71c57236904f35),I64(0x0af21f66c2bec6b6),I64(0xcffaa6b71c9ab7b4),
I64(0x187f9ab49af08ec6),I64(0x2d66c4f95142a46c),I64(0x6fa4c33b7a3039c0),I64(0xae4faeae1d3ad3d9)
},
{
I64(0x8886564d3a14d493),I64(0x3517454ca23c4af3),I64(0x06476983284a0504),I64(0x0992abc52d822c37),
I64(0xd3473e33197a93c9),I64(0x399ec6c7e6bf87c9),I64(0x51ac86febf240954),I64(0xf4c70e16eeaac5ec)
},
{
I64(0xa47f0dd4bf02e71e),I64(0x36acc2355951a8d9),I64(0x69d18d2bd1a5c42f),I64(0xf4892bcb929b0690),
I64(0x89b4443b4ddbc49a),I64(0x4eb7f8719c36de1e),I64(0x03e7aa020c6e4141),I64(0x9b1f5b424d93c9a7)
},
{
I64(0x7261445183235adb),I64(0x0e38dc92cb1f2a60),I64(0x7b2b8a9aa6079c54),I64(0x800a440bdbb2ceb1),
I64(0x3cd955b7e00d0984),I64(0x3a7d3a1b25894224),I64(0x944c9ad8ec165fde),I64(0x378f5a541631229b)
},
{
I64(0x74b4c7fb98459ced),I64(0x3698fad1153bb6c3),I64(0x7a1e6c303b7652f4),I64(0x9fe76702af69334b),
I64(0x1fffe18a1b336103),I64(0x8941e71cff8a78db),I64(0x382ae548b2e4f3f3),I64(0xabbedea680056f52)
},
{
I64(0x6bcaa4cd81f32d1b),I64(0xdea2594ac06fd85d),I64(0xefbacd1d7d476e98),I64(0x8a1d71efea48b9ca),
I64(0x2001802114846679),I64(0xd8fa6bbbebab0761),I64(0x3002c6cd635afe94),I64(0x7bcd9ed0efc889fb)
},
{
I64(0x48bc924af11bd720),I64(0xfaf417d5d9b21b99),I64(0xe71da4aa88e12852),I64(0x5d80ef9d1891cc86),
I64(0xf82012d430219f9b),I64(0xcda43c32bcdf1d77),I64(0xd21380b00449b17a),I64(0x378ee767f11631ba)
}
};
static const uint64_t zero_512[8] = { 0,0,0,0,0,0,0,0 };
/**
* Initialize algorithm context.
*
* @param ctx context to initialize
* @param hash_size the size of the digest in bytes
*/
static RHASH_INLINE void rhash_gost12_init(gost12_ctx* ctx, unsigned hash_size)
{
memset(ctx, 0, sizeof(gost12_ctx));
if (hash_size != gost12_512_hash_size)
memset(ctx->h, 1, gost12_512_hash_size);
ctx->hash_size = hash_size;
}
/**
* Initialize algorithm context for 256-bit sized digest.
*
* @param ctx context to initialize
* @param hash_size the size of the digest in bytes
*/
void rhash_gost12_256_init(gost12_ctx* ctx)
{
rhash_gost12_init(ctx, gost12_256_hash_size);
}
/**
* Initialize algorithm context for 512-bit sized digest.
*
* @param ctx context to initialize
* @param hash_size the size of the digest in bytes
*/
void rhash_gost12_512_init(gost12_ctx* ctx)
{
rhash_gost12_init(ctx, gost12_512_hash_size);
}
#define xor_uint512(x, y, z) { \
z[0] = x[0] ^ y[0]; \
z[1] = x[1] ^ y[1]; \
z[2] = x[2] ^ y[2]; \
z[3] = x[3] ^ y[3]; \
z[4] = x[4] ^ y[4]; \
z[5] = x[5] ^ y[5]; \
z[6] = x[6] ^ y[6]; \
z[7] = x[7] ^ y[7]; \
}
static void LPSX(const uint64_t* a, const uint64_t* b, uint64_t* result)
{
register uint64_t r0, r1, r2, r3, r4, r5, r6, r7;
int i;
/* calculate xor_uint512(a, b) */
r0 = a[0] ^ b[0];
r1 = a[1] ^ b[1];
r2 = a[2] ^ b[2];
r3 = a[3] ^ b[3];
r4 = a[4] ^ b[4];
r5 = a[5] ^ b[5];
r6 = a[6] ^ b[6];
r7 = a[7] ^ b[7];
/* apply L P S transformations */
for (i = 0; i <= 7; i++)
{
result[i] = TR[0][(r0 >> (i << 3)) & 0xFF];
result[i] ^= TR[1][(r1 >> (i << 3)) & 0xFF];
result[i] ^= TR[2][(r2 >> (i << 3)) & 0xFF];
result[i] ^= TR[3][(r3 >> (i << 3)) & 0xFF];
result[i] ^= TR[4][(r4 >> (i << 3)) & 0xFF];
result[i] ^= TR[5][(r5 >> (i << 3)) & 0xFF];
result[i] ^= TR[6][(r6 >> (i << 3)) & 0xFF];
result[i] ^= TR[7][(r7 >> (i << 3)) & 0xFF];
}
}
/*
* Implementaion of the function g_N(h,m) = E(LPS(h xor N),m) xor h xor m,
* where E(K, ) = X[K1 3 ]L PSX[K12] .. . L PSX[K2]LPSX[K1](m).
*/
static void g_N(const uint64_t N[], uint64_t h[], const uint64_t m[])
{
uint64_t K_i[8];
uint64_t state[8];
unsigned int i;
/* the first iteration of E(K_i, m): calculate and apply K_1 */
LPSX(h, N, K_i);
LPSX(K_i, m, state);
/* rounds 2,...,11 of E(K_i, m) */
#if 0
LPSX(K_i, gost12_iteration_constants[0], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[1], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[2], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[3], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[4], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[5], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[6], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[7], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[8], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[9], K_i);
LPSX(K_i, state, state);
LPSX(K_i, gost12_iteration_constants[10], K_i);
LPSX(K_i, state, state);
#else
for (i = 0; i < 11; i++)
{
LPSX(K_i, gost12_iteration_constants[i], K_i);
LPSX(K_i, state, state);
}
#endif
/* the round 12 of E(K_i, m) */
LPSX(K_i, gost12_iteration_constants[11], K_i);
xor_uint512(K_i, state, state);
/* the last step: calculate h = (state XOR h XOR m) */
xor_uint512(state, h, state);
xor_uint512(state, m, h);
}
static RHASH_INLINE void add_uint512(uint64_t sum[], const uint64_t x[])
{
/* usless but fun optimization for x86 */
#if defined(USE_GCC_ASM_IA32)
__asm(
"movl (%1), %%eax\n\taddl %%eax, (%0)\n\t"
"movl 4(%1), %%ecx\n\tadcl %%ecx, 4(%0)\n\t"
"movl 8(%1), %%eax\n\tadcl %%eax, 8(%0)\n\t"
"movl 12(%1), %%ecx\n\tadcl %%ecx, 12(%0)\n\t"
"movl 16(%1), %%eax\n\tadcl %%eax, 16(%0)\n\t"
"movl 20(%1), %%ecx\n\tadcl %%ecx, 20(%0)\n\t"
"movl 24(%1), %%eax\n\tadcl %%eax, 24(%0)\n\t"
"movl 28(%1), %%ecx\n\tadcl %%ecx, 28(%0)\n\t"
"movl 32(%1), %%eax\n\tadcl %%eax, 32(%0)\n\t"
"movl 36(%1), %%ecx\n\tadcl %%ecx, 36(%0)\n\t"
"movl 40(%1), %%eax\n\tadcl %%eax, 40(%0)\n\t"
"movl 44(%1), %%ecx\n\tadcl %%ecx, 44(%0)\n\t"
"movl 48(%1), %%eax\n\tadcl %%eax, 48(%0)\n\t"
"movl 52(%1), %%ecx\n\tadcl %%ecx, 52(%0)\n\t"
"movl 56(%1), %%eax\n\tadcl %%eax, 56(%0)\n\t"
"movl 60(%1), %%ecx\n\tadcl %%ecx, 60(%0)\n\t"
: : "r" (sum), "r" (x)
: "eax", "ecx", "memory", "cc" );
#elif defined(USE_GCC_ASM_X64)
__asm(
"movq (%1), %%rax\n\taddq %%rax, (%0)\n\t"
"movq 8(%1), %%rax\n\tadcq %%rax, 8(%0)\n\t"
"movq 16(%1), %%rax\n\tadcq %%rax, 16(%0)\n\t"
"movq 24(%1), %%rax\n\tadcq %%rax, 24(%0)\n\t"
"movq 32(%1), %%rax\n\tadcq %%rax, 32(%0)\n\t"
"movq 40(%1), %%rax\n\tadcq %%rax, 40(%0)\n\t"
"movq 48(%1), %%rax\n\tadcq %%rax, 48(%0)\n\t"
"movq 56(%1), %%rax\n\tadcq %%rax, 56(%0)\n\t"
: : "r" (sum), "r" (x)
: "rax", "memory", "cc" );
#else /* defined(USE_GCC_ASM_IA32) */
int i;
uint64_t carry = 0;
/* compute the 512-bit sum */
for (i = 0; i < 8; i++)
{
sum[i] += x[i] + carry;
carry = (sum[i] < x[i] ? 1 : sum[i] == x[i] ? carry : 0);
}
#endif /* USE_GCC_ASM_IA32 */
}
static const uint64_t stage2_constant[8] = { I64(512), 0, 0, 0, 0, 0, 0, 0 };
static RHASH_INLINE void rhash_gost12_stage2(gost12_ctx* ctx, uint64_t m[])
{
g_N(ctx->N, ctx->h, m);
add_uint512(ctx->N, stage2_constant);
add_uint512(ctx->S, m);
}
void rhash_gost12_update(gost12_ctx* ctx, const unsigned char* msg, size_t size)
{
if (ctx->index)
{
size_t rest = gost12_block_size - ctx->index;
le64_copy(ctx->message, ctx->index, msg, (size < rest ? size : rest));
ctx->index += (unsigned)size;
if (size < rest)
return;
/* process partial block */
rhash_gost12_stage2(ctx, ctx->message);
msg += rest;
size -= rest;
ctx->index = 0;
}
if (IS_LITTLE_ENDIAN && IS_ALIGNED_64(msg))
{
while (size >= gost12_block_size)
{
rhash_gost12_stage2(ctx, (uint64_t*)msg);
msg += gost12_block_size;
size -= gost12_block_size;
}
} else {
while (size >= gost12_block_size)
{
le64_copy(ctx->message, 0, msg, gost12_block_size);
rhash_gost12_stage2(ctx, ctx->message);
msg += gost12_block_size;
size -= gost12_block_size;
}
}
if (size)
{
ctx->index = (unsigned)size;
le64_copy(ctx->message, 0, msg, size); /* save leftovers */
}
}
void rhash_gost12_final(gost12_ctx* ctx, unsigned char* result)
{
uint64_t unprocessed_bits_count[8] = { 0,0,0,0,0,0,0,0 };
size_t index_u64 = ctx->index >> 3;
unsigned shift = (ctx->index & 7) * 8;
unprocessed_bits_count[0] = ctx->index * 8;
ctx->message[index_u64] &= ~(I64(0xFFFFFFFFFFFFFFFF) << shift);
ctx->message[index_u64++] ^= I64(0x01) << shift;
memset(&ctx->message[index_u64], 0, gost12_block_size - index_u64 * 8);
/* apply gost12 stage 3 */
g_N(ctx->N, ctx->h, ctx->message);
add_uint512(ctx->N, unprocessed_bits_count);
add_uint512(ctx->S, ctx->message);
g_N(zero_512, ctx->h, ctx->N);
g_N(zero_512, ctx->h, ctx->S);
le64_copy(result, 0, &(ctx->h[8 - ctx->hash_size / 8]), ctx->hash_size);
}
rhash-1.4.6/librhash/test_lib.h 0000664 0000000 0000000 00000013203 15010500453 015071 0 ustar root root /** @file test_lib.h - detect compiler defines */
#ifndef TEST_LIB_H
#define TEST_LIB_H
#include "byte_order.h"
#include "util.h"
#include
/* first some magic to convert a macro value to a string */
#define STRINGIZE_ARG(x) #x
#define EXPAND_TO_STRING(x) STRINGIZE_ARG(x)
/* the string containing defined macros */
char* compiler_flags = "Compile-time flags:"
#ifdef i386
" i386"
#endif
#ifdef __i386__
" __i386__"
#endif
#ifdef __i486__
" __i486__"
#endif
#ifdef __i586__
" __i586__"
#endif
#ifdef __i686__
" __i686__"
#endif
#ifdef __pentium__
" __pentium__"
#endif
#ifdef __pentiumpro__
" __pentiumpro__"
#endif
#ifdef __pentium4__
" __pentium4__"
#endif
#ifdef __nocona__
" __nocona__"
#endif
#ifdef prescott
" prescott"
#endif
#ifdef __core2__
" __core2__"
#endif
#ifdef __k6__
" __k6__"
#endif
#ifdef __k8__
" __k8__"
#endif
#ifdef __athlon__
" __athlon__"
#endif
#ifdef __amd64
" __amd64"
#endif
#ifdef __amd64__
" __amd64__"
#endif
#ifdef __x86_64
" __x86_64"
#endif
#ifdef __x86_64__
" __x86_64__"
#endif
#ifdef _M_IX86
" _M_IX86"
#endif
#ifdef _M_AMD64
" _M_AMD64"
#endif
#ifdef _M_IA64
" _M_IA64"
#endif
#ifdef _M_X64
" _M_X64"
#endif
#ifdef _LP64
" _LP64"
#endif
#ifdef __LP64__
" __LP64__"
#endif
#ifdef __ia64
" __ia64"
#endif
#ifdef __ia64__
" __ia64__"
#endif
#ifdef __alpha__
" __alpha__"
#endif
#ifdef _M_ALPHA
" _M_ALPHA"
#endif
#ifdef _ARM_
" _ARM_"
#endif
#ifdef __arm__
" __arm__"
#endif
#ifdef _M_ARM64
" _M_ARM64"
#endif
#ifdef _M_ARM64EC
" _M_ARM64EC"
#endif
#ifdef __loongarch64
" __loongarch64"
#endif
#ifdef MIPSEL
" MIPSEL"
#endif
#ifdef __sparc
" __sparc"
#endif
#ifdef __sparc__
" __sparc__"
#endif
#ifdef sparc
" sparc"
#endif
#ifdef _ARCH_PPC
" _ARCH_PPC"
#endif
#ifdef _ARCH_PPC64
" _ARCH_PPC64"
#endif
#ifdef _POWER
" _POWER"
#endif
#ifdef __POWERPC__
" __POWERPC__"
#endif
#ifdef POWERPC
" POWERPC"
#endif
#ifdef __powerpc
" __powerpc"
#endif
#ifdef __powerpc__
" __powerpc__"
#endif
#ifdef __powerpc64__
" __powerpc64__"
#endif
#ifdef __ppc__
" __ppc__"
#endif
#ifdef __hppa__
" __hppa__"
#endif
#ifdef __hpux
" __hpux"
#endif
#ifdef _MIPSEB
" _MIPSEB"
#endif
#ifdef mc68000
" mc68000"
#endif
#ifdef __s390__
" __s390__"
#endif
#ifdef __s390x__
" __s390x__"
#endif
#ifdef sel
" sel"
#endif
#ifdef vax
" vax"
#endif
/* detect compiler and OS */
#ifdef _MSC_VER
" _MSC_VER=" EXPAND_TO_STRING(_MSC_VER)
#endif
#ifdef __BORLANDC__
" __BORLANDC__"
#endif
#if defined(__GNUC__) && defined(__VERSION__)
" __VERSION__=" __VERSION__
" (__GNUC__=" EXPAND_TO_STRING(__GNUC__) ",__GNUC_MINOR__=" EXPAND_TO_STRING(__GNUC_MINOR__) ")"
#endif
#ifdef __INTEL_COMPILER
" __INTEL_COMPILER=" EXPAND_TO_STRING(__INTEL_COMPILER)
#endif
#ifdef __clang__
" __clang__"
#endif
#ifdef __llvm__
" __llvm__"
#endif
#ifdef __TINYC__ /* tcc */
" __TINYC__"
#endif
#ifdef __cplusplus /* С++ */
" __cplusplus"
#endif
#ifdef _ISOC11_SOURCE
" _ISOC11_SOURCE"
#endif
#ifdef __STDC_VERSION__
" __STDC_VERSION__=" EXPAND_TO_STRING(__STDC_VERSION__)
#endif
#ifdef _POSIX_VERSION
" _POSIX_VERSION=" EXPAND_TO_STRING(_POSIX_VERSION)
#endif
#ifdef _POSIX_C_SOURCE
" _POSIX_C_SOURCE=" EXPAND_TO_STRING(_POSIX_C_SOURCE)
#endif
#ifdef _XOPEN_SOURCE
" _XOPEN_SOURCE=" EXPAND_TO_STRING(_XOPEN_SOURCE)
#endif
#ifdef __ANDROID_API__
" __ANDROID_API__=" EXPAND_TO_STRING(__ANDROID_API__)
#endif
#ifdef __STRICT_ANSI__
" __STRICT_ANSI__"
#endif
#ifdef __MINGW32__
" __MINGW32__"
#endif
#ifdef __MINGW64__
" __MINGW64__"
#endif
#ifdef __CYGWIN__
" __CYGWIN__"
#endif
#ifdef __MSYS__
" __MSYS__"
#endif
#ifdef _WIN32
" _WIN32"
#endif
#ifdef _WIN64
" _WIN64"
#endif
#ifdef __linux
" __linux"
#endif
#ifdef __sun /* Solaris */
" __sun"
#endif
#ifdef __DragonFly__
" __DragonFly__"
#endif
#ifdef __FreeBSD__
" __FreeBSD__"
#endif
#ifdef __OpenBSD__
" __OpenBSD__"
#endif
#ifdef __NetBSD__
" __NetBSD__"
#endif
#ifdef __HAIKU__
" __HAIKU__"
#endif
#ifdef __APPLE__
" __APPLE__"
#endif
#ifdef __MACH__ /* Mac OS X = __APPLE__ & __MACH__ on gcc/icc */
" __MACH__"
#endif
#ifdef __GLIBC__ /* GLIBC >= 6 */
" __GLIBC__"
" (__GLIBC__=" EXPAND_TO_STRING(__GLIBC__) ",__GLIBC_MINOR__=" EXPAND_TO_STRING(__GLIBC_MINOR__) ")"
#endif
#ifdef __UCLIBC__
" __UCLIBC__"
#endif
#ifdef _UNICODE
" _UNICODE"
#endif
#ifdef __PIC__
" __PIC__"
#endif
/* rhash-related macro */
#ifdef USE_RHASH_DLL
" USE_RHASH_DLL"
#endif
#ifdef USE_KECCAK
" USE_KECCAK"
#endif
#ifdef USE_OPENSSL
" USE_OPENSSL"
#endif
#ifdef OPENSSL_RUNTIME
" OPENSSL_RUNTIME"
#endif
#ifdef NO_ATOMIC_BUILTINS
" NO_ATOMIC_BUILTINS"
#endif
#ifdef HAS_WIN32_ALIGNED_ALLOC
" HAS_WIN32_ALIGNED_ALLOC"
#endif
#ifdef HAS_STDC_ALIGNED_ALLOC
" HAS_STDC_ALIGNED_ALLOC"
#endif
#if defined(HAS_POSIX_ALIGNED_ALLOC)
" HAS_POSIX_ALIGNED_ALLOC"
#endif
#ifdef HAS_GENERIC_ALIGNED_ALLOC
" HAS_GENERIC_ALIGNED_ALLOC"
#endif
/* cpu features */
#ifdef HAS_GCC_INTEL_CPUID
" HAS_GCC_INTEL_CPUID"
#endif
#ifdef HAS_MSVC_INTEL_CPUID
" HAS_MSVC_INTEL_CPUID"
#endif
#ifdef CPU_X64
" CPU_X64"
#endif
#ifdef CPU_IA32
" CPU_IA32"
#endif
#if IS_LITTLE_ENDIAN
" IS_LITTLE_ENDIAN"
#endif
#if IS_BIG_ENDIAN
" IS_BIG_ENDIAN"
#endif
#if defined(__BYTE_ORDER)
# if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER==__LITTLE_ENDIAN)
" (__BYTE_ORDER==__LITTLE_ENDIAN)"
# elif defined(__BIG_ENDIAN) && (__BYTE_ORDER==__BIG_ENDIAN)
" (__BYTE_ORDER==__BIG_ENDIAN)"
# endif
#endif
#if defined(_BYTE_ORDER)
# if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER==_LITTLE_ENDIAN)
" (_BYTE_ORDER==_LITTLE_ENDIAN)"
# elif defined(_BIG_ENDIAN) && (_BYTE_ORDER==_BIG_ENDIAN)
" (_BYTE_ORDER==_BIG_ENDIAN)"
# endif
#elif defined(_LITTLE_ENDIAN)
" _LITTLE_ENDIAN" /* Solaris case */
#elif defined(_BIG_ENDIAN)
" _BIG_ENDIAN"
#endif
"\n";
#endif /* TEST_LIB_H */
rhash-1.4.6/librhash/torrent.h 0000664 0000000 0000000 00000005230 14703622112 014767 0 ustar root root /* torrent.h */
#ifndef TORRENT_H
#define TORRENT_H
#include "algorithms.h"
#include "sha1.h"
#ifdef __cplusplus
extern "C" {
#endif
#define btih_hash_size 20
/* vector structure */
typedef struct torrent_vect
{
void** array; /* array of elements of the vector */
size_t size; /* vector size */
size_t allocated; /* number of allocated elements */
} torrent_vect;
/* a binary string */
typedef struct torrent_str
{
char* str;
size_t length;
size_t allocated;
} torrent_str;
/* BitTorrent algorithm context */
typedef struct torrent_ctx
{
unsigned char btih[20]; /* resulting BTIH hash sum */
unsigned options; /* algorithm options */
sha1_ctx sha1_context; /* context for hashing current file piece */
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
unsigned long reserved; /* need more space for OpenSSL SHA1 context */
#endif
size_t index; /* byte index in the current piece */
size_t piece_length; /* length of a torrent file piece */
size_t piece_count; /* the number of pieces processed */
size_t error; /* non-zero if error occurred, zero otherwise */
torrent_vect hash_blocks; /* array of blocks storing SHA1 hashes */
torrent_vect files; /* names of files in a torrent batch */
torrent_vect announce; /* announce URLs */
char* program_name; /* the name of the program */
torrent_str content; /* the content of generated torrent file */
#if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME)
rhash_hashing_methods sha1_methods;
#endif
} torrent_ctx;
void bt_init(torrent_ctx* ctx);
void bt_update(torrent_ctx* ctx, const void* msg, size_t size);
void bt_final(torrent_ctx* ctx, unsigned char result[20]);
void bt_cleanup(torrent_ctx* ctx);
#if !defined(NO_IMPORT_EXPORT)
size_t bt_export(const torrent_ctx* ctx, void* out, size_t size);
size_t bt_import(torrent_ctx* ctx, const void* in, size_t size);
#endif /* !defined(NO_IMPORT_EXPORT) */
unsigned char* bt_get_btih(torrent_ctx* ctx);
size_t bt_get_text(torrent_ctx* ctx, char** pstr);
/* possible options */
#define BT_OPT_PRIVATE 1
#define BT_OPT_INFOHASH_ONLY 2
#define BT_OPT_TRANSMISSION 4
void bt_set_options(torrent_ctx* ctx, unsigned options);
int bt_add_file(torrent_ctx* ctx, const char* path, uint64_t filesize);
int bt_add_announce(torrent_ctx* ctx, const char* announce_url);
int bt_set_program_name(torrent_ctx* ctx, const char* name);
void bt_set_piece_length(torrent_ctx* ctx, size_t piece_length);
void bt_set_total_batch_size(torrent_ctx* ctx, uint64_t total_size);
size_t bt_default_piece_length(uint64_t total_size, int transmission);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* TORRENT_H */
rhash-1.4.6/librhash/ustd.h 0000664 0000000 0000000 00000001604 14703622112 014252 0 ustar root root /* ustd.h common macros and includes */
#ifndef LIBRHASH_USTD_H
#define LIBRHASH_USTD_H
#if _MSC_VER > 1000
# include /* size_t for vc6.0 */
# if _MSC_VER >= 1600
/* Visual Studio >= 2010 has stdint.h */
# include
# else
/* vc6.0 has bug with __int8, so using char instead */
typedef signed char int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef signed __int64 int64_t;
typedef unsigned char uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
# endif /* _MSC_VER >= 1600 */
/* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */
# pragma warning(disable : 4996)
#else /* _MSC_VER > 1000 */
# include
# include
#endif /* _MSC_VER > 1000 */
#endif /* LIBRHASH_USTD_H */
rhash-1.4.6/librhash/md5.h 0000664 0000000 0000000 00000001266 14703622112 013764 0 ustar root root /* md5.h */
#ifndef MD5_HIDER
#define MD5_HIDER
#include "ustd.h"
#ifdef __cplusplus
extern "C" {
#endif
#define md5_block_size 64
#define md5_hash_size 16
/* algorithm context */
typedef struct md5_ctx
{
unsigned message[md5_block_size / 4]; /* 512-bit buffer for leftovers */
uint64_t length; /* number of processed bytes */
unsigned hash[4]; /* 128-bit algorithm internal hashing state */
} md5_ctx;
/* hash functions */
void rhash_md5_init(md5_ctx* ctx);
void rhash_md5_update(md5_ctx* ctx, const unsigned char* msg, size_t size);
void rhash_md5_final(md5_ctx* ctx, unsigned char* result);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* MD5_HIDER */
rhash-1.4.6/librhash/aich.c 0000664 0000000 0000000 00000042565 15010476501 014206 0 ustar root root /* aich.c - an implementation of EMule AICH Algorithm.
* Description: http://www.amule.org/wiki/index.php/AICH.
*
* Copyright (c) 2008, Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* The AICH Algorithm:
*
* Each ed2k chunk (9728000 bytes) is divided into 53 parts (52x 180KB and
* 1x 140KB) and each of these parts are hashed using the SHA1 algorithm.
* Each of these hashes is called a Block Hash. By combining pairs of Block
* Hashes (i.e. each part with the part next to it) algorithm will get a whole
* tree of hashes (this tree which is therefore a hashset made of all of the
* other Block Hashes is called the AICH Hashset). Each hash which is neither
* a Block Hash nor the Root Hash, is a Verifying Hash. The hash at the top
* level is the Root Hash and it is supposed to be provided by the ed2k link
* when releasing.
*/
#include "aich.h"
#include "util.h"
#include
#include
#include
#include
#if defined(USE_OPENSSL)
#define SHA1_INIT(ctx) ((pinit_t)ctx->sha1_methods.init)(&ctx->sha1_context)
#define SHA1_UPDATE(ctx, msg, size) ((pupdate_t)ctx->sha1_methods.update)(&ctx->sha1_context, (msg), (size))
#define SHA1_FINAL(ctx, result) ((pfinal_t)ctx->sha1_methods.final)(&ctx->sha1_context, (result))
#else
# define SHA1_INIT(ctx) rhash_sha1_init(&ctx->sha1_context)
# define SHA1_UPDATE(ctx, msg, size) rhash_sha1_update(&ctx->sha1_context, (msg), (size))
# define SHA1_FINAL(ctx, result) rhash_sha1_final(&ctx->sha1_context, (result))
#endif
#define ED2K_CHUNK_SIZE 9728000
#define FULL_BLOCK_SIZE 184320
#define LAST_BLOCK_SIZE 143360
#define BLOCKS_PER_CHUNK 53
#define BLOCK_HASHES_SIZE (BLOCKS_PER_CHUNK * sha1_hash_size)
/*
* AICH algorithm could be implemented a bit faster if it knows
* a hashed message size beforehand. It would allow
* to build balanced tree while hashing the message.
*
* This AICH implementation works with unknown
* message size like other well-known hash algorithms.
* So, it just stores sha1 hashes and builds balanced tree
* only on the last step, when the full message processed
* and its size got to be known.
*/
/**
* Initialize algorithm context before calculating hash.
*
* @param ctx context to initialize
*/
void rhash_aich_init(aich_ctx* ctx)
{
memset(ctx, 0, sizeof(aich_ctx));
#if defined(USE_OPENSSL)
assert(rhash_info_table[3].info->hash_id == EXTENDED_SHA1);
assert(rhash_info_table[3].context_size <= (sizeof(sha1_ctx) + sizeof(unsigned long)));
rhash_load_sha1_methods(&ctx->sha1_methods, METHODS_SELECTED);
#endif
SHA1_INIT(ctx);
}
/* define macrosses to access chunk table */
#define CT_BITS 8
#define CT_GROUP_SIZE (1 << CT_BITS)
typedef unsigned char hash_pair_t[2][sha1_hash_size];
typedef hash_pair_t hash_pairs_group_t[CT_GROUP_SIZE];
#define CT_INDEX(chunk_num) ((chunk_num) & (CT_GROUP_SIZE - 1))
#define GET_HASH_PAIR(ctx, chunk_num) \
(((hash_pair_t*)(ctx->chunk_table[chunk_num >> CT_BITS]))[CT_INDEX(chunk_num)])
/**
* Resize the table if needed to ensure it contains space for given chunk_num.
* and allocate hash_pairs_group_t element at this index.
*
* @param ctx algorithm context
* @param chunk_num the number of chunks required
*/
static void rhash_aich_chunk_table_extend(aich_ctx* ctx, unsigned chunk_num)
{
unsigned index = (chunk_num >> CT_BITS);
assert(CT_INDEX(chunk_num) == 0);
RHASH_ASSERT(sizeof(hash_pair_t) == 40);
RHASH_ASSERT(sizeof(hash_pairs_group_t) == (40 * CT_GROUP_SIZE)); /* 10KiB */
RHASH_ASSERT(CT_GROUP_SIZE == 256);
/* check main assumptions */
assert(ctx->chunk_table == 0 || ctx->chunk_table[index - 1] != 0); /* table is empty or full */
assert(index <= ctx->allocated);
/* check if there is enough space allocated */
if (index >= ctx->allocated) {
/* resize the table by allocating some extra space */
size_t new_size = (ctx->allocated == 0 ? 64 : ctx->allocated * 2);
void** new_block;
assert(index == ctx->allocated);
/* re-size the chunk table to new_size */
new_block = (void**)realloc(ctx->chunk_table, new_size * sizeof(void*));
if (new_block == 0) {
free(ctx->chunk_table);
ctx->chunk_table = 0;
ctx->error = 1;
return;
}
memset(new_block + ctx->allocated, 0, (new_size - ctx->allocated) * sizeof(void*));
ctx->chunk_table = new_block;
ctx->allocated = new_size;
}
/* add new hash_pairs_group_t block to the table */
assert(index < ctx->allocated);
assert(ctx->chunk_table != 0);
assert(ctx->chunk_table[index] == 0);
ctx->chunk_table[index] = malloc(sizeof(hash_pairs_group_t));
if (ctx->chunk_table[index] == 0)
ctx->error = 1;
}
/**
* Free dynamically allocated memory for internal structures
* used by hashing algorithm.
*
* @param ctx AICH algorithm context to cleanup
*/
void rhash_aich_cleanup(aich_ctx* ctx)
{
size_t i;
size_t table_size = (ctx->chunks_count + CT_GROUP_SIZE - 1) / CT_GROUP_SIZE;
if (ctx->chunk_table != 0) {
assert(table_size <= ctx->allocated);
assert(table_size == ctx->allocated || ctx->chunk_table[table_size] == 0);
for (i = 0; i < table_size; i++)
free(ctx->chunk_table[i]);
free(ctx->chunk_table);
ctx->chunk_table = 0;
}
free(ctx->block_hashes);
ctx->block_hashes = 0;
}
#define AICH_HASH_FULL_TREE 0
#define AICH_HASH_LEFT_BRANCH 1
#define AICH_HASH_RIGHT_BRANCH 2
/**
* Calculate an AICH tree hash, based ether on hashes of 180KB parts
* (for an ed2k chunk) or on stored ed2k chunks (for the whole tree hash).
*
* @param ctx algorithm context
* @param result pointer to receive calculated tree hash
* @param type the type of hash to calculate, can be one of constants
* AICH_HASH_LEFT_BRANCH, AICH_HASH_RIGHT_BRANCH or AICH_HASH_FULL_TREE.
*/
static void rhash_aich_hash_tree(aich_ctx* ctx, unsigned char* result, int type)
{
unsigned index = 0; /* leaf index */
unsigned blocks;
int level = 0;
unsigned is_left_branch = (type == AICH_HASH_RIGHT_BRANCH ? 0x0 : 0x1);
uint64_t path = is_left_branch;
unsigned blocks_stack[56];
unsigned char sha1_stack[56][sha1_hash_size];
if (ctx->error)
return;
assert(ctx->index <= ED2K_CHUNK_SIZE);
assert(type == AICH_HASH_FULL_TREE ? ctx->chunk_table != 0 : ctx->block_hashes != 0);
/* calculate number of leafs in the tree */
blocks_stack[0] = blocks = (unsigned)(type == AICH_HASH_FULL_TREE ?
ctx->chunks_count : (ctx->index + FULL_BLOCK_SIZE - 1) / FULL_BLOCK_SIZE);
while (1) {
unsigned char sha1_message[sha1_hash_size];
unsigned char* leaf_hash;
/* go into the left branches until a leaf block is reached */
while (blocks > 1) {
/* step down into the left branch */
blocks = (blocks + ((unsigned)path & 0x1)) / 2;
level++;
assert(level < 56); /* assumption filesize < (2^56 * 9MiB) */
blocks_stack[level] = blocks;
path = (path << 1) | 0x1; /* mark branch as left */
}
/* read a leaf hash */
leaf_hash = &(ctx->block_hashes[index][0]);
if (type == AICH_HASH_FULL_TREE) {
is_left_branch = (unsigned)path & 0x1;
leaf_hash = GET_HASH_PAIR(ctx, index)[is_left_branch];
}
index++;
/* climb up the tree until a left branch is reached */
for (; level > 0 && (path & 0x01) == 0; path >>= 1) {
SHA1_INIT(ctx);
SHA1_UPDATE(ctx, sha1_stack[level], sha1_hash_size);
SHA1_UPDATE(ctx, leaf_hash, sha1_hash_size);
SHA1_FINAL(ctx, sha1_message);
leaf_hash = sha1_message;
level--;
}
memcpy((level > 0 ? sha1_stack[level] : result), leaf_hash, 20);
if (level == 0) break;
/* jump at the current level from left to right branch */
path &= ~0x1; /* mark branch as right */
is_left_branch = ((unsigned)path >> 1) & 1;
/* calculate number of blocks at right branch of the current level */
blocks_stack[level] =
(blocks_stack[level - 1] + 1 - is_left_branch) / 2;
blocks = blocks_stack[level];
}
}
#define AICH_PROCESS_FINAL_BLOCK 1
#define AICH_PROCESS_FLUSH_BLOCK 2
/**
* Calculate and store a hash for a 180K/140K block.
* Also, if it is the last block of a 9.2MiB ed2k chunk or of the hashed message,
* then also calculate the AICH tree-hash of the current ed2k chunk.
*
* @param ctx algorithm context
* @param type the actions to take, can be combination of bits AICH_PROCESS_FINAL_BLOCK
* and AICH_PROCESS_FLUSH_BLOCK
*/
static void rhash_aich_process_block(aich_ctx* ctx, int type)
{
assert(type != 0);
assert(ctx->index <= ED2K_CHUNK_SIZE);
/* if there is unprocessed data left in the current 180K block. */
if ((type & AICH_PROCESS_FLUSH_BLOCK) != 0)
{
/* ensure that the block_hashes array is allocated to save the result */
if (ctx->block_hashes == NULL) {
ctx->block_hashes = (unsigned char (*)[sha1_hash_size])malloc(BLOCK_HASHES_SIZE);
if (ctx->block_hashes == NULL) {
ctx->error = 1;
return;
}
}
/* store the 180-KiB block hash to the block_hashes array */
assert(((ctx->index - 1) / FULL_BLOCK_SIZE) < BLOCKS_PER_CHUNK);
SHA1_FINAL(ctx, ctx->block_hashes[(ctx->index - 1) / FULL_BLOCK_SIZE]);
}
/* check, if it's time to calculate the tree hash for the current ed2k chunk */
if (ctx->index >= ED2K_CHUNK_SIZE || (type & AICH_PROCESS_FINAL_BLOCK)) {
unsigned char (*pair)[sha1_hash_size];
/* ensure, that we have the space to store tree hash */
if (CT_INDEX(ctx->chunks_count) == 0) {
rhash_aich_chunk_table_extend(ctx, (unsigned)ctx->chunks_count);
if (ctx->error)
return;
}
assert(ctx->chunk_table != 0);
assert(ctx->block_hashes != 0);
/* calculate tree hash and save results to chunk_table */
pair = GET_HASH_PAIR(ctx, ctx->chunks_count);
/* small optimization: skip a left-branch-hash for the last chunk */
if (!(type & AICH_PROCESS_FINAL_BLOCK) || ctx->chunks_count == 0) {
/* calculate a tree hash to be used in left branch */
rhash_aich_hash_tree(ctx, pair[1], AICH_HASH_LEFT_BRANCH);
}
/* small optimization: skip right-branch-hash for the very first chunk */
if (ctx->chunks_count > 0) {
/* calculate a tree hash to be used in right branch */
rhash_aich_hash_tree(ctx, pair[0], AICH_HASH_RIGHT_BRANCH);
}
ctx->index = 0; /* mark that the entire ed2k chunk has been processed */
ctx->chunks_count++;
}
}
/**
* Calculate message hash.
* Can be called repeatedly with chunks of the message to be hashed.
*
* @param ctx the algorithm context containing current hashing state
* @param msg message chunk
* @param size length of the message chunk
*/
void rhash_aich_update(aich_ctx* ctx, const unsigned char* msg, size_t size)
{
if (ctx->error)
return;
while (size > 0) {
unsigned left_in_chunk = ED2K_CHUNK_SIZE - ctx->index;
unsigned block_left = (left_in_chunk <= LAST_BLOCK_SIZE ? left_in_chunk :
FULL_BLOCK_SIZE - ctx->index % FULL_BLOCK_SIZE);
assert(block_left > 0);
if (size >= block_left) {
SHA1_UPDATE(ctx, msg, block_left);
msg += block_left;
size -= block_left;
ctx->index += block_left;
/* process a 180KiB-blok */
rhash_aich_process_block(ctx, AICH_PROCESS_FLUSH_BLOCK);
SHA1_INIT(ctx);
} else {
/* add to a leaf block */
SHA1_UPDATE(ctx, msg, size);
ctx->index += (unsigned)size;
break;
}
}
assert(ctx->index < ED2K_CHUNK_SIZE);
}
/**
* Store calculated hash into the given array.
*
* @param ctx the algorithm context containing current hashing state
* @param result calculated hash in binary form
*/
void rhash_aich_final(aich_ctx* ctx, unsigned char result[20])
{
uint64_t total_size =
((uint64_t)ctx->chunks_count * ED2K_CHUNK_SIZE) + ctx->index;
unsigned char* const hash = (unsigned char*)ctx->sha1_context.hash;
if (ctx->chunks_count == 0 && ctx->block_hashes == NULL) {
assert(ctx->index < FULL_BLOCK_SIZE);
#if defined(USE_OPENSSL)
SHA1_FINAL(ctx, hash); /* return just sha1 hash */
#else
SHA1_FINAL(ctx, 0); /* return just sha1 hash */
#if IS_LITTLE_ENDIAN
rhash_u32_mem_swap(ctx->sha1_context.hash, 5);
#endif
#endif
if (result) memcpy(result, hash, sha1_hash_size);
return;
}
/* if there is unprocessed data left in the last 180K block */
if ((ctx->index % FULL_BLOCK_SIZE) > 0) {
/* then process the last block */
rhash_aich_process_block(ctx, ctx->block_hashes != NULL ?
AICH_PROCESS_FINAL_BLOCK | AICH_PROCESS_FLUSH_BLOCK : AICH_PROCESS_FLUSH_BLOCK);
}
/* if processed message was shorter than a ed2k chunk */
if (ctx->chunks_count == 0) {
/* then return the aich hash for the first chunk */
rhash_aich_hash_tree(ctx, hash, AICH_HASH_LEFT_BRANCH);
} else {
if (ctx->index > 0) {
/* process the last block of the message */
rhash_aich_process_block(ctx, AICH_PROCESS_FINAL_BLOCK);
}
assert(ctx->chunks_count > 0);
assert(ctx->block_hashes != NULL);
rhash_aich_hash_tree(ctx, hash, AICH_HASH_FULL_TREE);
}
rhash_aich_cleanup(ctx);
ctx->sha1_context.length = total_size; /* store total message size */
if (result) memcpy(result, hash, sha1_hash_size);
}
#if !defined(NO_IMPORT_EXPORT)
# define AICH_CTX_OSSL_FLAG 0x10
/**
* Export aich context to a memory region, or calculate the
* size required for context export.
*
* @param ctx the algorithm context containing current hashing state
* @param out pointer to the memory region or NULL
* @param size size of memory region
* @return the size of the exported data on success, 0 on fail.
*/
size_t rhash_aich_export(const aich_ctx* ctx, void* out, size_t size)
{
const size_t head_size = sizeof(size_t);
const size_t ctx_head_size = offsetof(aich_ctx, block_hashes);
const size_t block_hashes_size = (ctx->block_hashes ? BLOCK_HASHES_SIZE : 0);
const size_t chunk_table_size = sizeof(hash_pair_t) * ctx->chunks_count;
const size_t exported_size = head_size + ctx_head_size + block_hashes_size + chunk_table_size;
char* out_ptr = (char*)out;
if (!out)
return exported_size;
if (size < exported_size)
return 0;
*(size_t*)out_ptr = sizeof(aich_ctx);
out_ptr += head_size;
memcpy(out_ptr, ctx, ctx_head_size);
out_ptr += ctx_head_size;
if (ctx->block_hashes) {
memcpy(out_ptr, ctx->block_hashes, BLOCK_HASHES_SIZE);
out_ptr += BLOCK_HASHES_SIZE;
}
if (chunk_table_size > 0) {
size_t left_size = chunk_table_size;
size_t index;
assert(ctx->chunk_table != NULL);
for (index = 0; left_size > 0; index++) {
size_t group_size = (left_size < sizeof(hash_pairs_group_t) ?
left_size : sizeof(hash_pairs_group_t));
memcpy(out_ptr, ctx->chunk_table[index], group_size);
out_ptr += group_size;
left_size -= group_size;
}
assert(left_size == 0);
}
assert(!out || (size_t)(out_ptr - (char*)out) == exported_size);
#if defined(USE_OPENSSL)
if (out_ptr && ARE_OPENSSL_METHODS(ctx->sha1_methods)) {
int* error_ptr = (int*)((char*)out + head_size + offsetof(aich_ctx, error));
*error_ptr |= AICH_CTX_OSSL_FLAG;
RHASH_ASSERT(sizeof(*error_ptr) == sizeof(ctx->error));
}
#endif
return exported_size;
}
/**
* Import aich context from a memory region.
*
* @param ctx pointer to the algorithm context
* @param in pointer to the data to import
* @param size size of data to import
* @return the size of the imported data on success, 0 on fail.
*/
size_t rhash_aich_import(aich_ctx* ctx, const void* in, size_t size)
{
const size_t head_size = sizeof(size_t);
const size_t ctx_head_size = offsetof(aich_ctx, block_hashes);
const char* in_ptr = (const char*)in;
size_t imported_size = head_size + ctx_head_size;
size_t block_hashes_size;
size_t chunk_table_size;
if (size < imported_size)
return 0;
if(*(size_t*)in_ptr != sizeof(aich_ctx))
return 0;
in_ptr += head_size;
memset(ctx, 0, sizeof(aich_ctx));
memcpy(ctx, in_ptr, ctx_head_size);
in_ptr += ctx_head_size;
block_hashes_size = (ctx->block_hashes ? BLOCK_HASHES_SIZE : 0);
chunk_table_size = sizeof(hash_pair_t) * ctx->chunks_count;
imported_size += block_hashes_size + chunk_table_size;
if (size < imported_size)
return 0;
if (ctx->block_hashes != NULL) {
ctx->block_hashes = (unsigned char (*)[sha1_hash_size])malloc(BLOCK_HASHES_SIZE);
if (!ctx->block_hashes)
return 0;
memcpy(ctx->block_hashes, in_ptr, BLOCK_HASHES_SIZE);
in_ptr += BLOCK_HASHES_SIZE;
}
if (ctx->allocated > 0) {
size_t index;
ctx->chunk_table = (void**)malloc(ctx->allocated * sizeof(void*));
if (!ctx->chunk_table) {
ctx->error = 1;
return 0;
}
memset(ctx->chunk_table, 0, ctx->allocated * sizeof(void*));
for (index = 0; chunk_table_size > 0; index++) {
size_t group_size = (chunk_table_size < sizeof(hash_pairs_group_t) ?
chunk_table_size : sizeof(hash_pairs_group_t));
assert(index < ctx->allocated);
ctx->chunk_table[index] = malloc(sizeof(hash_pairs_group_t));
if (ctx->chunk_table[index] == 0) {
ctx->error = 1;
return 0;
}
memcpy(ctx->chunk_table[index], in_ptr, group_size);
chunk_table_size -= group_size;
in_ptr += group_size;
}
}
assert((size_t)(in_ptr - (char*)in) == imported_size);
#if defined(USE_OPENSSL)
if ((ctx->error & AICH_CTX_OSSL_FLAG) != 0) {
ctx->error &= ~AICH_CTX_OSSL_FLAG;
rhash_load_sha1_methods(&ctx->sha1_methods, METHODS_OPENSSL);
} else {
rhash_load_sha1_methods(&ctx->sha1_methods, METHODS_RHASH);
}
#endif
return imported_size;
}
#endif /* !defined(NO_IMPORT_EXPORT) */
rhash-1.4.6/rhash_main.h 0000664 0000000 0000000 00000001722 14703622112 013611 0 ustar root root /* rhash_main.h */
#ifndef RHASH_MAIN_H
#define RHASH_MAIN_H
#include "file.h"
#ifdef __cplusplus
extern "C" {
#endif
enum StopFlags {
InterruptedFlag = 1,
FatalErrorFlag = 2
};
/**
* Runtime data.
*/
struct rhash_t
{
FILE* out;
FILE* log;
file_t out_file;
file_t log_file;
file_t upd_file;
file_t config_file;
char* printf_str;
struct print_item* print_list;
struct strbuf_t* template_text;
struct update_ctx* update_context;
struct rhash_context* rctx;
uint64_t last_hash_mask;
unsigned hash_ids[64];
size_t hash_ids_count;
int is_sfv;
int non_fatal_error;
unsigned stop_flags;
/* missed, ok and processed files statistics */
unsigned processed;
unsigned ok;
unsigned miss;
uint64_t total_size;
uint64_t batch_size;
};
/** static variable, holding most of the runtime data */
extern struct rhash_t rhash_data;
void rhash_destroy(struct rhash_t*);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* RHASH_MAIN_H */
rhash-1.4.6/file.h 0000664 0000000 0000000 00000012666 15010476501 012431 0 ustar root root /* file.h - file abstraction layer */
#ifndef FILE_H
#define FILE_H
#include
#include
#include /* for wchar_t */
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
typedef wchar_t file_tchar;
# define SYS_PATH_SEPARATOR '\\'
# define ALIEN_PATH_SEPARATOR '/'
# define IS_PATH_SEPARATOR(c) ((c) == '\\' || (c) == '/')
# define IS_PATH_SEPARATOR_W(c) ((c) == L'\\' || (c) == L'/')
#else
typedef char file_tchar;
# define SYS_PATH_SEPARATOR '/'
# define ALIEN_PATH_SEPARATOR '\\'
# define IS_PATH_SEPARATOR(c) ((c) == '/')
#endif /* _WIN32 */
typedef file_tchar* tpath_t;
typedef const file_tchar* ctpath_t;
/* Generic path functions */
char* make_path(const char* dir, const char* filename, unsigned flags);
#ifdef _WIN32
tpath_t make_wpath(ctpath_t dir_path, size_t dir_len, ctpath_t sub_path);
# define make_tpath(dir_path, sub_path) make_wpath(dir_path, (size_t)-1, sub_path)
#else
# define make_tpath(dir_path, sub_path) make_path(dir_path, sub_path, FileInitUseRealPathAsIs)
#endif /* _WIN32 */
const char* get_basename(const char* path);
/**
* Portable file information.
*/
typedef struct file_t
{
tpath_t real_path;
const char* print_path;
#ifdef _WIN32
const char* native_path; /* print_path in native encoding */
#endif
char* data;
uint64_t size;
uint64_t mtime;
unsigned mode;
} file_t;
/* bit constants for the file_t.mode bit mask */
enum FileModeBits {
FileIsDir = 0x01,
FileIsLnk = 0x02,
FileIsReg = 0x04,
FileIsInaccessible = 0x08,
FileIsRoot = 0x10,
FileIsData = 0x20,
FileIsList = 0x40,
FileIsStdStream = 0x80,
FileIsStdin = FileIsStdStream,
FileContentIsUtf8 = 0x100,
FileInitReusePath = 0x1000,
FileInitUtf8PrintPath = 0x2000,
FileInitRunFstat = 0x4000,
FileInitRunLstat = 0x8000,
FileInitUpdatePrintPathLastSlash = 0x10000,
FileInitUpdatePrintPathToForwardSlashes = 0x20000,
FileInitUpdatePrintPathSlashes = 0x40000,
FileInitUseRealPathAsIs = 0x80000,
FileMaskUpdatePrintPath = (FileInitUpdatePrintPathLastSlash |
FileInitUpdatePrintPathToForwardSlashes | FileInitUpdatePrintPathSlashes),
FileMaskStatBits = (FileIsDir | FileIsLnk | FileIsReg | FileIsInaccessible),
FileMaskIsSpecial = (FileIsData | FileIsList | FileIsStdStream),
FileMaskModeBits = (FileMaskStatBits | FileIsRoot | FileMaskIsSpecial | FileContentIsUtf8),
FileMaskSavedChar = 0xff000000,
};
#define FILE_ISDIR(file) ((file)->mode & FileIsDir)
#define FILE_ISLNK(file) ((file)->mode & FileIsLnk)
#define FILE_ISREG(file) ((file)->mode & FileIsReg)
#define FILE_ISBAD(file) ((file)->mode & FileIsInaccessible)
#define FILE_ISDATA(file) ((file)->mode & FileIsData)
#define FILE_ISLIST(file) ((file)->mode & FileIsList)
#define FILE_ISSTDIN(file) ((file)->mode & FileIsStdin)
#define FILE_ISSTDSTREAM(file) ((file)->mode & FileIsStdStream)
#define FILE_ISSPECIAL(file) ((file)->mode & (FileMaskIsSpecial))
#define FILE_IS_IN_UTF8(file) ((file)->mode & (FileContentIsUtf8))
/* file functions */
int file_init(file_t* file, ctpath_t path, unsigned init_flags);
int file_init_by_print_path(file_t* file, file_t* prepend_dir, const char* print_path, unsigned init_flags);
void file_cleanup(file_t* file);
void file_clone(file_t* file, const file_t* orig_file);
void file_swap(file_t* first, file_t* second);
int are_paths_equal(ctpath_t path, struct file_t* file);
enum FileGetPrintPathFlags {
FPathPrimaryEncoding = 0,
FPathUtf8 = 0x1,
FPathNative = 0x2,
FPathBaseName = 0x4,
FPathDirName = 0x8,
FPathNotNull = 0x10,
FPathReal = 0x20,
};
const char* file_get_print_path(file_t* file, unsigned flags);
enum FileModifyOperations {
FModifyAppendSuffix,
FModifyInsertBeforeExtension,
FModifyRemoveExtension,
FModifyGetParentDir,
};
int file_modify_path(file_t* dst, file_t* src, const char* str, int operation);
enum FileStatModes {
FNoMode = 0,
FUseLstat = FileInitRunLstat,
};
int file_stat(file_t* file, int fstat_flags);
enum FileFOpenModes {
FOpenRead = 1,
FOpenWrite = 2,
FOpenBin = 4,
FOpenMask = 7,
FOpenRW = FOpenRead | FOpenWrite,
FOpenReadBin = FOpenRead | FOpenBin,
FOpenWriteBin = FOpenWrite | FOpenBin,
FOpenRWBin = FOpenRW | FOpenBin,
};
int file_open(file_t* file, int open_flags);
FILE* file_fopen(file_t* file, int fopen_flags);
int file_rename(const file_t* from, const file_t* to);
int file_move_to_bak(file_t* file);
int file_is_readable(file_t* file);
/**
* A file list iterator.
*/
typedef struct file_list_t
{
FILE* fd;
file_t current_file;
unsigned state;
} file_list_t;
int file_list_open(file_list_t* list, file_t* file);
int file_list_read(file_list_t* list);
void file_list_close(file_list_t* list);
#ifndef _WIN32
# define dirent_get_tname(d) ((d)->d_name)
# define rsh_topendir(p) opendir(p)
#else
/* readdir structures and functions */
# define DIR WIN_DIR
# define dirent win_dirent
# define opendir win_opendir
# define readdir win_readdir
# define closedir win_closedir
# define dirent_get_tname(d) ((d)->d_wname)
# define rsh_topendir(p) win_wopendir(p)
/* dirent struct for windows to traverse directory content */
struct win_dirent
{
char* d_name; /* file name */
wchar_t* d_wname; /* file name in Unicode (UTF-16) */
int d_isdir; /* non-zero if file is a directory */
};
struct WIN_DIR_t;
typedef struct WIN_DIR_t WIN_DIR;
WIN_DIR* win_opendir(const char*);
WIN_DIR* win_wopendir(const wchar_t*);
struct win_dirent* win_readdir(WIN_DIR*);
void win_closedir(WIN_DIR*);
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* FILE_H */
rhash-1.4.6/win_utils.c 0000664 0000000 0000000 00000045042 15010476501 013514 0 ustar root root /* win_utils.c - utility functions for Windows and CygWin */
#if defined(_WIN32) || defined(__CYGWIN__)
/* Fix #138: require to use MSVCRT implementation of *printf functions */
#define __USE_MINGW_ANSI_STDIO 0
#include "win_utils.h"
# define WIN32_LEAN_AND_MEAN
#include
#include
#include
/**
* Set process priority and affinity to use any CPU but the first one,
* this improves benchmark results on a multi-core systems.
*/
void set_benchmark_cpu_affinity(void)
{
DWORD_PTR dwProcessMask, dwSysMask, dwDesired;
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
if ( GetProcessAffinityMask(GetCurrentProcess(), &dwProcessMask, &dwSysMask) ) {
dwDesired = dwSysMask & (dwProcessMask & ~1); /* remove the first processor */
dwDesired = (dwDesired ? dwDesired : dwSysMask & ~1);
if (dwDesired != 0) {
SetProcessAffinityMask(GetCurrentProcess(), dwDesired);
}
}
}
#ifdef _WIN32
/* Windows-only (non-CygWin) functions */
#include "file.h"
#include "parse_cmdline.h"
#include /* for _SH_DENYWR */
#include /* for _O_RDONLY, _O_BINARY */
#include /* for isatty */
#include
#include
#include
/* QuickFix for broken output, caused by libintl fwprintf and vfwprintf */
#ifdef fwprintf
# undef fwprintf
#endif
#ifdef vfwprintf
# undef vfwprintf
#endif
struct console_data_t
{
unsigned console_flags;
unsigned saved_cursor_size;
unsigned primary_codepage;
unsigned secondary_codepage;
wchar_t format_buffer[4096];
wchar_t printf_result[65536];
wchar_t program_dir[32768];
};
struct console_data_t console_data;
/**
* Convert a c-string as wide character string using given codepage
* and print it to the given buffer.
*
* @param str the string to convert
* @param codepage the codepage to use
* @param buffer buffer to print the string to
* @param buf_size buffer size in bytes
* @return converted string on success, NULL on fail with error code stored in errno
*/
static wchar_t* cstr_to_wchar_buffer(const char* str, int codepage, wchar_t* buffer, size_t buf_size)
{
size_t length = buf_size / sizeof(wchar_t);
if (length > INT_MAX) {
errno = EINVAL;
return NULL;
}
if (MultiByteToWideChar(codepage, 0, str, -1, buffer, (int)length) != 0)
return buffer;
set_errno_from_last_file_error();
return NULL; /* conversion failed */
}
/**
* Convert a c-string to wide character string using given codepage.
* The result is allocated with malloc and must be freed by caller.
*
* @param str the string to convert
* @param codepage the codepage to use
* @param exact_conversion non-zero to require exact encoding conversion, 0 otherwise
* @return converted string on success, NULL on fail with error code stored in errno
*/
static wchar_t* cstr_to_wchar(const char* str, int codepage, int exact_conversion)
{
DWORD flags = (exact_conversion ? MB_ERR_INVALID_CHARS : 0);
int size = MultiByteToWideChar(codepage, flags, str, -1, NULL, 0);
if (size != 0) {
wchar_t* buf = (wchar_t*)rsh_malloc(size * sizeof(wchar_t));
if (MultiByteToWideChar(codepage, flags, str, -1, buf, size) != 0)
return buf;
}
set_errno_from_last_file_error();
return NULL; /* conversion failed */
}
/**
* Convert a wide character string to c-string using given codepage.
* The result is allocated with malloc and must be freed by caller.
*
* @param wstr the wide string to convert
* @param codepage the codepage to use
* @param exact_conversion non-zero to require exact encoding conversion, 0 otherwise
* @return converted string on success, NULL on fail with error code stored in errno
*/
static char* wchar_to_cstr(const wchar_t* wstr, int codepage, int exact_conversion)
{
int size;
BOOL bUsedDefChar = FALSE;
BOOL* lpUsedDefaultChar = (exact_conversion && codepage != CP_UTF8 ? &bUsedDefChar : NULL);
if (codepage == -1) {
codepage = (opt.flags & OPT_UTF8 ? CP_UTF8 : (opt.flags & OPT_ENC_DOS) ? CP_OEMCP : CP_ACP);
}
size = WideCharToMultiByte(codepage, 0, wstr, -1, NULL, 0, 0, NULL);
/* size=0 is returned only on fail, cause even an empty string requires buffer size=1 */
if (size != 0) {
char* buf = (char*)rsh_malloc(size);
if (WideCharToMultiByte(codepage, 0, wstr, -1, buf, size, 0, lpUsedDefaultChar) != 0) {
if (!bUsedDefChar)
return buf;
free(buf);
errno = EILSEQ;
return NULL;
}
free(buf);
}
set_errno_from_last_file_error();
return NULL;
}
/**
* Convert c-string to wide string using encoding and transformation specified by flags.
* The result is allocated with malloc and must be freed by caller.
*
* @param str the C-string to convert
* @param flags bit-mask containing the following bits: ConvertToPrimaryEncoding, ConvertToSecondaryEncoding,
* ConvertToUtf8, ConvertToNative, ConvertPath, ConvertExact
* @return converted wide string on success, NULL on fail with error code stored in errno
*/
wchar_t* convert_str_to_wcs(const char* str, unsigned flags)
{
int is_utf8 = flags & (opt.flags & OPT_UTF8 ? (ConvertToUtf8 | ConvertToPrimaryEncoding) : (ConvertToUtf8 | ConvertToSecondaryEncoding));
int codepage = (is_utf8 ? CP_UTF8 : (opt.flags & OPT_ENC_DOS) ? CP_OEMCP : CP_ACP);
wchar_t* wstr = cstr_to_wchar(str, codepage, (flags & ConvertExact));
if (wstr && (flags & ConvertPath)) {
wchar_t* long_path = get_long_path_if_needed(wstr);
if (long_path) {
free(wstr);
return long_path;
}
}
return wstr;
}
/**
* Convert wide string to c-string using encoding and transformation specified by flags.
*
* @param str the C-string to convert
* @param flags bit-mask containing the following bits: ConvertToPrimaryEncoding, ConvertToSecondaryEncoding,
* ConvertToUtf8, ConvertToNative, ConvertPath, ConvertExact
* @return converted wide string on success, NULL on fail with error code stored in errno
*/
char* convert_wcs_to_str(const wchar_t* wstr, unsigned flags)
{
int is_utf8 = flags & (opt.flags & OPT_UTF8 ? (ConvertToUtf8 | ConvertToPrimaryEncoding) : (ConvertToUtf8 | ConvertToSecondaryEncoding));
int codepage = (is_utf8 ? CP_UTF8 : (opt.flags & OPT_ENC_DOS) ? CP_OEMCP : CP_ACP);
/* skip path UNC prefix, if found */
if ((flags & ConvertPath) && IS_UNC_PREFIX(wstr))
wstr += UNC_PREFIX_SIZE;
return wchar_to_cstr(wstr, codepage, (flags & ConvertExact));
}
/**
* Convert c-string encoding, the encoding is specified by flags.
*
* @param str the C-string to convert
* @param flags bit-mask containing the following bits: ConvertToUtf8, ConvertToNative, ConvertExact
* @return converted wide string on success, NULL on fail with error code stored in errno
*/
char* convert_str_encoding(const char* str, unsigned flags)
{
int convert_from = (flags & ConvertToUtf8 ? ConvertNativeToWcs : ConvertUtf8ToWcs) | (flags & ConvertExact);
wchar_t* wstr;
assert((flags & ~(ConvertToUtf8 | ConvertToNative | ConvertExact)) == 0); /* disallow invalid flags */
if ((flags & (ConvertToUtf8 | ConvertToNative)) == 0) {
errno = EINVAL;
return NULL; /* error: no conversion needed */
}
wstr = convert_str_to_wcs(str, convert_from);
if (wstr) {
char* res = convert_wcs_to_str(wstr, flags);
free(wstr);
return res;
}
return NULL;
}
/**
* Allocate a wide string containing long file path with UNC prefix,
* if it is needed to access the path, otherwise return NULL.
*
* @param wpath original file path, can be a relative one
* @return allocated long file path if it is needed to access
* the path, NULL otherwise
*/
wchar_t* get_long_path_if_needed(const wchar_t* wpath)
{
size_t length;
size_t index;
size_t spaces_count = 0;
if (IS_UNC_PREFIX(wpath))
return NULL;
length = wcslen(wpath);
/* Do not end a file or directory name with a space or a period on Windows.
See https://learn.microsoft.com/en-gb/windows/win32/fileio/naming-a-file */
for (index = length; index > 0 && wpath[index - 1] == ' '; --index, ++spaces_count);
if (length > 200 || spaces_count > 0) {
/* get required buffer size, including the terminating null character */
DWORD size = GetFullPathNameW(wpath, 0, NULL, NULL);
if (size > 0) {
size_t buffer_size = (size + spaces_count + UNC_PREFIX_SIZE) * sizeof(wchar_t);
wchar_t* result = (wchar_t*)rsh_malloc(buffer_size);
wcscpy(result, L"\\\\?\\");
/* get path length without the terminating null character */
size = GetFullPathNameW(wpath, size, result + UNC_PREFIX_SIZE, NULL);
if (size > 0) {
if (spaces_count > 0)
wcscpy(result + UNC_PREFIX_SIZE + size, wpath + index);
return result;
}
free(result);
}
}
return NULL;
}
/* the range of error codes for access errors */
#define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
#define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
/**
* Convert the GetLastError() value to errno-compatible code.
*
* @return errno-compatible error code
*/
static int convert_last_error_to_errno(void)
{
DWORD error_code = GetLastError();
switch (error_code)
{
case NO_ERROR:
return 0;
case ERROR_FILE_NOT_FOUND:
case ERROR_PATH_NOT_FOUND:
case ERROR_INVALID_DRIVE:
case ERROR_INVALID_NAME:
case ERROR_BAD_NETPATH:
case ERROR_BAD_PATHNAME:
case ERROR_FILENAME_EXCED_RANGE:
return ENOENT;
case ERROR_TOO_MANY_OPEN_FILES:
return EMFILE;
case ERROR_ACCESS_DENIED:
case ERROR_SHARING_VIOLATION:
return EACCES;
case ERROR_NETWORK_ACCESS_DENIED:
case ERROR_FAIL_I24:
case ERROR_SEEK_ON_DEVICE:
return EACCES;
case ERROR_LOCK_VIOLATION:
case ERROR_DRIVE_LOCKED:
case ERROR_NOT_LOCKED:
case ERROR_LOCK_FAILED:
return EACCES;
case ERROR_INVALID_HANDLE:
return EBADF;
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_INVALID_BLOCK:
case ERROR_NOT_ENOUGH_QUOTA:
case ERROR_INSUFFICIENT_BUFFER:
return ENOMEM;
case ERROR_INVALID_ACCESS:
case ERROR_INVALID_DATA:
case ERROR_INVALID_PARAMETER:
case ERROR_INVALID_FLAGS:
return EINVAL;
case ERROR_BROKEN_PIPE:
case ERROR_NO_DATA:
return EPIPE;
case ERROR_DISK_FULL:
return ENOSPC;
case ERROR_ALREADY_EXISTS:
return EEXIST;
case ERROR_NESTING_NOT_ALLOWED:
return EAGAIN;
case ERROR_NO_UNICODE_TRANSLATION:
return EILSEQ;
}
/* try to detect error by range */
if (MIN_EACCES_RANGE <= error_code && error_code <= MAX_EACCES_RANGE) {
return EACCES;
} else {
return EINVAL;
}
}
/**
* Assign errno to the error value converted from the GetLastError().
*/
void set_errno_from_last_file_error(void)
{
errno = convert_last_error_to_errno();
}
/* functions to setup/restore console */
/**
* Restore console on program exit.
*/
static void restore_cursor(void)
{
CONSOLE_CURSOR_INFO cci;
HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);
if (hOut != INVALID_HANDLE_VALUE && console_data.saved_cursor_size) {
/* restore cursor size and visibility */
cci.dwSize = console_data.saved_cursor_size;
cci.bVisible = 1;
SetConsoleCursorInfo(hOut, &cci);
}
}
/**
* Hide console cursor.
*/
void hide_cursor(void)
{
CONSOLE_CURSOR_INFO cci;
HANDLE hOut = GetStdHandle(STD_ERROR_HANDLE);
if (hOut != INVALID_HANDLE_VALUE && GetConsoleCursorInfo(hOut, &cci))
{
/* store current cursor size and visibility flag */
console_data.saved_cursor_size = (cci.bVisible ? cci.dwSize : 0);
/* now hide cursor */
cci.bVisible = 0;
SetConsoleCursorInfo(hOut, &cci); /* hide cursor */
rsh_install_exit_handler(restore_cursor);
}
}
/**
* Prepare console on program initialization: change console font codepage
* according to program options and hide cursor.
*/
void setup_console(void)
{
/* the default encoding is UTF-8 */
if ((opt.flags & OPT_ENCODING) == 0)
opt.flags |= OPT_UTF8;
console_data.console_flags = 0;
console_data.saved_cursor_size = 0;
console_data.primary_codepage = (opt.flags & OPT_UTF8 ? CP_UTF8 : (opt.flags & OPT_ENC_DOS) ? CP_OEMCP : CP_ACP);
console_data.secondary_codepage = (!(opt.flags & OPT_UTF8) ? CP_UTF8 : (opt.flags & OPT_ENC_DOS) ? CP_OEMCP : CP_ACP);
/* note: we are using numbers 1 = _fileno(stdout), 2 = _fileno(stderr) */
/* cause _fileno() is undefined, when compiling as strict ansi C. */
if (isatty(1))
console_data.console_flags |= 1;
if (isatty(2))
console_data.console_flags |= 2;
if ((opt.flags & OPT_UTF8) != 0)
{
if (console_data.console_flags & 1)
_setmode(1, _O_U8TEXT);
if (console_data.console_flags & 2)
_setmode(2, _O_U8TEXT);
#ifdef USE_GETTEXT
bind_textdomain_codeset(TEXT_DOMAIN, "utf-8");
#endif /* USE_GETTEXT */
}
else
{
setlocale(LC_CTYPE, opt.flags & OPT_ENC_DOS ? ".OCP" : ".ACP");
}
}
wchar_t* get_program_dir(void)
{
return console_data.program_dir;
}
/**
* Check if the given stream is connected to console.
*
* @param stream the stream to check
* @return 1 if the stream is connected to console, 0 otherwise
*/
int win_is_console_stream(FILE* stream)
{
return ((stream == stdout && (console_data.console_flags & 1))
|| (stream == stderr && (console_data.console_flags & 2)));
}
/**
* Detect the program directory.
*/
void init_program_dir(void)
{
DWORD buf_size = sizeof(console_data.program_dir) / sizeof(console_data.program_dir[0]);
DWORD length;
length = GetModuleFileNameW(NULL, console_data.program_dir, buf_size);
if (length == 0 || length >= buf_size) {
console_data.program_dir[0] = 0;
return;
}
/* remove trailng file name with the last path separator */
for (; length > 0 && !IS_PATH_SEPARATOR_W(console_data.program_dir[length]); length--);
for (; length > 0 && IS_PATH_SEPARATOR_W(console_data.program_dir[length]); length--);
console_data.program_dir[length + 1] = 0;
}
#ifdef USE_GETTEXT
/**
* Check that the path points to an existing directory.
*
* @param path the path to check
* @return 1 if the argument is a directory, 0 otherwise
*/
static int is_directory(const char* path)
{
DWORD res = GetFileAttributesA(path);
return (res != INVALID_FILE_ATTRIBUTES &&
!!(res & FILE_ATTRIBUTE_DIRECTORY));
}
/**
* Set the locale directory relative to ${PROGRAM_DIR}/locale.
*/
void setup_locale_dir(void)
{
wchar_t* short_dir;
char* program_dir = NULL;
char* locale_dir;
DWORD buf_size;
DWORD res;
if (!console_data.program_dir[0]) return;
buf_size = GetShortPathNameW(console_data.program_dir, NULL, 0);
if (!buf_size) return;
short_dir = (wchar_t*)rsh_malloc(sizeof(wchar_t) * buf_size);
res = GetShortPathNameW(console_data.program_dir, short_dir, buf_size);
if (res > 0 && res < buf_size)
program_dir = convert_wcs_to_str(short_dir, ConvertToPrimaryEncoding);
free(short_dir);
if (!program_dir) return;
locale_dir = make_path(program_dir, "locale", 0);
free(program_dir);
if (!locale_dir) return;
if (is_directory(locale_dir))
bindtextdomain(TEXT_DOMAIN, locale_dir);
free(locale_dir);
}
#endif /* USE_GETTEXT */
#define USE_CSTR_ARGS 0
#define USE_WSTR_ARGS 1
/**
* Print formatted data to the specified file descriptor,
* handling proper printing UTF-8 strings to Windows console.
*
* @param out file descriptor
* @param format data format string
* @param str_type wide/c-string type of string arguments
* @param args list of arguments
* @return the number of characters printed, -1 on error
*/
static int win_vfprintf_encoded(FILE* out, const char* format, int str_type, va_list args)
{
int res;
if (!win_is_console_stream(out)) {
return vfprintf(out, (format ? format : "%s"), args);
} else if (str_type == USE_CSTR_ARGS) {
/* thread-unsafe code: using a static buffer */
static char buffer[8192];
res = vsnprintf(buffer, sizeof(buffer) - 1, format, args);
if (res >= 0) {
wchar_t *wstr = cstr_to_wchar_buffer(buffer, console_data.primary_codepage, console_data.printf_result, sizeof(console_data.printf_result));
res = (wstr ? fwprintf(out, L"%s", wstr) : -1);
}
} else {
wchar_t* wformat = (!format || (format[0] == '%' && format[1] == 's' && !format[2]) ? L"%s" :
cstr_to_wchar_buffer(format, console_data.primary_codepage, console_data.format_buffer, sizeof(console_data.format_buffer)));
res = vfwprintf(out, (wformat ? wformat : L"[UTF8 conversion error]\n"), args);
assert(str_type == USE_WSTR_ARGS);
}
/* fix: win7 incorrectly sets _IOERR(=0x20) flag of the stream for UTF-8 encoding, so clear it */
if (res >= 0)
clearerr(out);
return res;
}
/**
* Print formatted data to the specified file descriptor,
* handling proper printing UTF-8 strings to Windows console.
*
* @param out file descriptor
* @param format data format string
* @param args list of arguments
* @return the number of characters printed, -1 on error
*/
int win_vfprintf(FILE* out, const char* format, va_list args)
{
return win_vfprintf_encoded(out, format, USE_CSTR_ARGS, args);
}
/**
* Print formatted data to the specified file descriptor,
* handling proper printing UTF-8 strings to Windows console.
*
* @param out file descriptor
* @param format data format string
* @return the number of characters printed, -1 on error
*/
int win_fprintf(FILE* out, const char* format, ...)
{
int res;
va_list args;
va_start(args, format);
res = win_vfprintf_encoded(out, format, USE_CSTR_ARGS, args);
va_end(args);
return res;
}
/**
* Print formatted data to the specified file descriptor,
* handling proper printing UTF-8 strings to Windows console.
*
* @param out file descriptor
* @param format data format string
* @return the number of characters printed, -1 on error
*/
int win_fprintf_warg(FILE* out, const char* format, ...)
{
int res;
va_list args;
va_start(args, format);
res = win_vfprintf_encoded(out, format, USE_WSTR_ARGS, args);
va_end(args);
return res;
}
/**
* Write a buffer to a stream.
*
* @param ptr pointer to the buffer to write
* @param size size of an items in the buffer
* @param count the number of items to write
* @param out the stream to write to
* @return the number of items written, -1 on error
*/
size_t win_fwrite(const void* ptr, size_t size, size_t count, FILE* out)
{
if (!win_is_console_stream(out))
return fwrite(ptr, size, count, out);
{
size_t i;
const char* buf = (const char*)ptr;
size *= count;
if (!size)
return 0;
for (i = 0; i < size && buf[i] > 0; i++);
if (i == size)
{
wchar_t* wstr = rsh_malloc(sizeof(wchar_t) * (size + 1));
int res;
for (i = 0; i < size; i++)
wstr[i] = (wchar_t)buf[i];
wstr[size] = L'\0';
res = fwprintf(out, L"%s", wstr);
free(wstr);
if (res < 0)
return res;
}
else
{
for (i = 0; (i + 8) <= size; i += 8)
if (fwprintf(out, L"%C%C%C%C%C%C%C%C", buf[i], buf[i + 1], buf[i + 2],
buf[i + 3], buf[i + 4], buf[i + 5], buf[i + 6], buf[i + 7]) < 0)
return -1;
for (; i < size; i++)
if (fwprintf(out, L"%C", buf[i]) < 0)
return -1;
}
/* fix: win7 incorrectly sets _IOERR(=0x20) flag of the stream for UTF-8 encoding, so clear it */
clearerr(out);
return count;
}
}
#endif /* _WIN32 */
#else
typedef int dummy_declaration_required_by_strict_iso_c;
#endif /* defined(_WIN32) || defined(__CYGWIN__) */
rhash-1.4.6/bindings/ 0000775 0000000 0000000 00000000000 15010731530 013117 5 ustar root root rhash-1.4.6/bindings/Makefile 0000664 0000000 0000000 00000007304 14703622112 014566 0 ustar root root VERSION := $(shell sed -ne 's/^version=\(.*\)/\1/p' version.properties)
BINDINGS = java mono perl python ruby php
FILES = Makefile version.properties ChangeLog COPYING
DESTDIR =
PREFIX = /usr/local
RUBY ?= ruby
PYTHON ?= python3
PERL ?= perl
PERL_LIBRHASH_TYPE ?= auto
PERL_OPTIMIZE ?= -O2 -g -Wall
ARCHIVE_GZIP = rhash-bindings-$(VERSION)-src.tar.gz
COPYDIR = rhash-bindings-$(VERSION)
CP = cp -l --parents
all: configure build test
clean: distclean
configure: $(patsubst %, configure-%, $(filter perl ruby php, $(BINDINGS)))
build: $(patsubst %, build-%, $(BINDINGS))
test: $(patsubst %, test-%, $(BINDINGS))
install: $(patsubst %, install-%, $(filter perl ruby php, $(BINDINGS)))
distclean: $(patsubst %, clean-%, $(BINDINGS))
configure-perl: perl/Makefile
configure-ruby: ruby/Makefile
configure-php: php/Makefile
perl/Makefile: perl/Makefile.PL
cd perl && LIBRHASH="$(PERL_LIBRHASH_TYPE)" $(PERL) Makefile.PL INSTALLDIRS=vendor
php/Makefile: php/config.m4
cd php && phpize && ./configure --with-rhash
ruby/Makefile: ruby/extconf.rb
$(RUBY) -C ruby extconf.rb
build-java:
+$(MAKE) -C java build-binary
build-perl: configure-perl
+$(MAKE) -C perl OPTIMIZE="$(PERL_OPTIMIZE)"
build-php: configure-php
+$(MAKE) -C php
build-python:
cd python && $(PYTHON) -m build
build-ruby: configure-ruby
+$(MAKE) -C ruby
build-mono:
+$(MAKE) -C mono
test-java:
+$(MAKE) -C java test
test-perl:
+$(MAKE) -C perl test
test-php:
+$(MAKE) -C php test TEST_PHP_ARGS=-q
test-ruby:
$(RUBY) -C ruby -I. test_rhash.rb
test-mono:
+$(MAKE) -C mono test
test-python:
cd python && PYTHONPATH=. $(PYTHON) tests/rhash_test.py
install-ruby:
# clear MAKEFLAGS to overcome ruby1.8 mkmf concurrency bug
+MAKEFLAGS= $(MAKE) -C ruby install DESTDIR=$(DESTDIR) sitedir=$(DESTDIR)/usr/lib/ruby
install-perl:
+$(MAKE) -C perl install DESTDIR=$(DESTDIR)
install-php:
+$(MAKE) -C php install INSTALL_ROOT=$(DESTDIR)
copy-dist:
mkdir -p $(COPYDIR)
find java ruby python -type f -regex '.*\(\.\([hc]\|java\|py\|rb\|txt\)\|Makefile\)' -exec $(CP) '{}' $(COPYDIR)/ \;
find mono -type f -regex '.*\(\.\([hc]\|cs\|xml\|txt\|snk\|sln\|csproj\|config\)\|Makefile\)' -exec $(CP) '{}' "$(COPYDIR)/" \;
$(CP) $(shell sed -e 's/\([^ ]*\).*/perl\/\1/' perl/MANIFEST) "$(COPYDIR)/"
find php -type f -regex '.*\.\(m4\|c\|h\|phpt\)' -exec $(CP) '{}' "$(COPYDIR)/" \;
$(CP) $(FILES) "$(COPYDIR)/"
gzip: distclean
rm -rf "$(COPYDIR)" $(ARCHIVE_GZIP)
+$(MAKE) copy-dist
tar -czf $(ARCHIVE_GZIP) --owner=root:0 --group=root:0 "$(COPYDIR)"
rm -rf "$(COPYDIR)"
PERL_PKG_VER = $(shell [ -f perl/Rhash.pm ] && sed -ne "s/^our \+.VERSION *= *'\([0-9\.]*\)';/\1/p;" perl/Rhash.pm)
PERL_PKG = Crypt-RHash-$(PERL_PKG_VER)
cpan:
[ -f ../librhash/rhash.h ]
echo "$(PERL_PKG_VER)" | grep -q '^[0-9\.]\+$$'
rm -rf $(PERL_PKG)/ $(PERL_PKG).tar.gz
mkdir -p $(PERL_PKG)/librhash/
grep -q / perl/MANIFEST && mkdir -p `sed -ne '/\//s/\([^\/]*\/\).*/$(PERL_PKG)\/\1/p' perl/MANIFEST | sort | uniq`
for f in `sed 's/ .*//' perl/MANIFEST`; do cp perl/$$f $(PERL_PKG)/$$f; done
cp ../docs/CONTRIBUTING.md ../COPYING $(PERL_PKG)/
cp ../librhash/*.[hc] ../version.h $(PERL_PKG)/librhash/
( echo CONTRIBUTING.md; echo COPYING ) >> $(PERL_PKG)/MANIFEST
find $(PERL_PKG)/librhash/ -type f -printf "librhash/%f\n" | sort >> $(PERL_PKG)/MANIFEST
tar -czf $(PERL_PKG).tar.gz --owner=root:0 --group=root:0 $(PERL_PKG)/
rm -rf $(PERL_PKG)/
clean-java:
+$(MAKE) -C java distclean
clean-mono:
+$(MAKE) -C mono clean
clean-ruby:
+[ ! -f ruby/Makefile ] || $(MAKE) -C ruby distclean
clean-perl:
+[ ! -f perl/Makefile ] || $(MAKE) -C perl distclean
clean-php:
[ ! -f php/configure ] || (cd php && phpize --clean)
clean-python:
rm -rf python/dist/ python/rhash_Rhash.egg-info/ python/tests/__pycache__/
rhash-1.4.6/bindings/python/ 0000755 0000000 0000000 00000000000 15010731530 014436 5 ustar root root rhash-1.4.6/bindings/python/tests/ 0000775 0000000 0000000 00000000000 15010731530 015602 5 ustar root root rhash-1.4.6/bindings/python/tests/__init__.py 0000664 0000000 0000000 00000000000 14703622112 017704 0 ustar root root rhash-1.4.6/bindings/python/tests/rhash_test.py 0000664 0000000 0000000 00000025003 15010517705 020326 0 ustar root root # Copyright (c) 2011, Aleksey Kravchenko
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
"""Unit-tests for the rhash module."""
import os
import unittest
import rhash
# pylint: disable=too-many-public-methods, pointless-statement
class TestRHash(unittest.TestCase):
"""The test-case class for the rhash module."""
maxDiff = 1024
def test_all_hashes(self):
"""Verify all hash functions."""
ctx = rhash.RHash(rhash.ALL)
ctx.update("a")
ctx.finish()
self.assertEqual("e8b7be43", ctx.hash(rhash.CRC32))
self.assertEqual("c1d04330", ctx.hash(rhash.CRC32C))
self.assertEqual("bde52cb31de33e46245e05fbdbd6fb24", ctx.hash(rhash.MD4))
self.assertEqual("0cc175b9c0f1b6a831c399e269772661", ctx.hash(rhash.MD5))
self.assertEqual("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", ctx.hash(rhash.SHA1))
self.assertEqual(
"77befbef2e7ef8ab2ec8f93bf587a7fc613e247f5f247809", ctx.hash(rhash.TIGER)
)
self.assertEqual("czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y", ctx.hash(rhash.TTH))
self.assertEqual(40, len(ctx.hash(rhash.BTIH)))
self.assertEqual("bde52cb31de33e46245e05fbdbd6fb24", ctx.hash(rhash.ED2K))
self.assertEqual("q336in72uwt7zyk5dxolt2xk5i3xmz5y", ctx.hash(rhash.AICH))
self.assertEqual(
"8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42"
"d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a",
ctx.hash(rhash.WHIRLPOOL),
)
self.assertEqual(
"0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", ctx.hash(rhash.RIPEMD160)
)
self.assertEqual(
"d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd",
ctx.hash(rhash.GOST94),
)
self.assertEqual(
"e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011",
ctx.hash(rhash.GOST94_CRYPTOPRO),
)
self.assertEqual(
"ba31099b9cc84ec2a671e9313572378920a705b363b031a1cb4fc03e01ce8df3",
ctx.hash(rhash.GOST12_256),
)
self.assertEqual(
"8b2a40ecab7b7496bc4cc0f773595452baf658849b495acc3ba017206810efb0"
"0420ccd73fb3297e0f7890941b84ac4a8bc27e3c95e1f97c094609e2136abb7e",
ctx.hash(rhash.GOST12_512),
)
self.assertEqual(
"4872bcbc4cd0f0a9dc7c2f7045e5b43b6c830db8", ctx.hash(rhash.HAS160)
)
self.assertEqual("bf5ce540ae51bc50399f96746c5a15bd", ctx.hash(rhash.SNEFRU128))
self.assertEqual(
"45161589ac317be0ceba70db2573ddda6e668a31984b39bf65e4b664b584c63d",
ctx.hash(rhash.SNEFRU256),
)
self.assertEqual(
"abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5",
ctx.hash(rhash.SHA2_224),
)
self.assertEqual(
"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
ctx.hash(rhash.SHA2_256),
)
self.assertEqual(
"54a59b9f22b0b80880d8427e548b7c23abd873486e1f035d"
"ce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31",
ctx.hash(rhash.SHA2_384),
)
self.assertEqual(
"1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f53"
"02860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75",
ctx.hash(rhash.SHA2_512),
)
self.assertEqual(
"943aa9225a2cf154ec2e4dd81237720ba538ca8df2fd83c0b893c5d265f353a0",
ctx.hash(rhash.EDONR256),
)
self.assertEqual(
"b59ec44f7beef8a04ceed38a973d77c65e22e9458d5f67b497948da34986c093"
"b5efc5483fbee55f2f740fcad31f18d80db44bb6b8843e7fd599188e7c07233b",
ctx.hash(rhash.EDONR512),
)
self.assertEqual(
"9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b",
ctx.hash(rhash.SHA3_224),
)
self.assertEqual(
"80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b",
ctx.hash(rhash.SHA3_256),
)
self.assertEqual(
"1815f774f320491b48569efec794d249eeb59aae46d22bf7"
"7dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9",
ctx.hash(rhash.SHA3_384),
)
self.assertEqual(
"697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa80"
"3f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a",
ctx.hash(rhash.SHA3_512),
)
self.assertEqual(
"4a0d129873403037c2cd9b9048203687f6233fb6738956e0349bd4320fec3e90",
ctx.hash(rhash.BLAKE2S),
)
self.assertEqual(
"333fcb4ee1aa7c115355ec66ceac917c8bfd815bf7587d325aec1864edd24e34"
"d5abe2c6b1b5ee3face62fed78dbef802f2a85cb91d455a8f5249d330853cb3c",
ctx.hash(rhash.BLAKE2B),
)
self.assertEqual(
"17762fddd969a453925d65717ac3eea21320b66b54342fde15128d6caf21215f",
ctx.hash(rhash.BLAKE3),
)
# Test reset
ctx.reset().finish()
# Verify MD5( "" )
self.assertEqual("d41d8cd98f00b204e9800998ecf8427e", ctx.hash(rhash.MD5))
def test_update(self):
"""Test sequential updates."""
ctx = rhash.RHash(rhash.CRC32, rhash.MD5)
ctx.update("Hello, ").update("world!").finish()
self.assertEqual("EBE6C6E6", ctx.hex_upper(rhash.CRC32))
self.assertEqual("6cd3556deb0da54bca060b4c39479839", ctx.hex(rhash.MD5))
def test_shift_operator(self):
"""Test the << operator."""
ctx = rhash.RHash(rhash.MD5)
ctx << "a" << "bc"
# Verify MD5( "abc" )
self.assertEqual("900150983cd24fb0d6963f7d28e17f72", str(ctx.finish()))
def test_hash_msg(self):
"""Test hash_msg() function."""
self.assertEqual(
"900150983cd24fb0d6963f7d28e17f72", rhash.hash_msg("abc", rhash.MD5)
)
def test_output_formats(self):
"""Test all output formats of a message digest."""
ctx = rhash.RHash(rhash.MD5, rhash.TTH).finish()
self.assertEqual(
"5d9ed00a030e638bdb753a6a24fb900e5a63b8e73e6c25b6", ctx.hex(rhash.TTH)
)
self.assertEqual("2qoyzwmpaczaj2mabgmoz6ccpy", ctx.base32(rhash.MD5))
self.assertEqual("1B2M2Y8AsgTpgAmY7PhCfg==", ctx.base64(rhash.MD5))
self.assertEqual(
b"\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e",
ctx.raw(rhash.MD5),
)
def test_magnet(self):
"""Test calculation of a magnet link."""
ctx = rhash.RHash(rhash.MD5, rhash.TTH)
ctx.update("abc").finish()
self.assertEqual(
"magnet:?xl=3&dn=file.txt&"
"xt=urn:md5:900150983cd24fb0d6963f7d28e17f72&"
"xt=urn:tree:tiger:asd4ujseh5m47pdyb46kbtsqtsgdklbhyxomuia",
ctx.magnet("file.txt"),
)
def test_update_file(self):
"""Test update_file() method."""
path = "python_test_input_123.txt"
with open(path, "wb") as file:
file.write(b"\0\1\2\n")
ctx = rhash.RHash(rhash.SHA1)
ctx.update_file(path).finish()
self.assertEqual("e3869ec477661fad6b9fc25914bb2eee5455b483", str(ctx))
self.assertEqual(
"e3869ec477661fad6b9fc25914bb2eee5455b483",
rhash.hash_file(path, rhash.SHA1),
)
self.assertEqual(
"magnet:?xl=4&dn=python_test_input_123.txt&"
"xt=urn:crc32:f2653eb7&"
"xt=urn:tree:tiger:c6docz63fpef5pdfpz35z7mw2iozshxlpr4erza",
rhash.make_magnet(path, rhash.CRC32, rhash.TTH),
)
os.remove(path)
def test_librhash_version(self):
"""Test get_librhash_version() function."""
version = rhash.get_librhash_version()
self.assertTrue(isinstance(version, str))
self.assertRegex(version, r"^[1-9]\d*\.\d+\.\d+$")
ver = rhash.get_librhash_version_int()
major, minor, patch = (ver >> 24, (ver >> 16) & 255, (ver >> 8) & 255)
self.assertTrue(1 <= major <= 9)
self.assertTrue(0 <= minor <= 9)
self.assertTrue(0 <= patch <= 9)
def test_the_with_operator(self):
"""Test the with operator."""
with rhash.RHash(rhash.CRC32, rhash.MD5) as ctx:
ctx.update("a").finish()
self.assertEqual("e8b7be43", ctx.hash(rhash.CRC32))
self.assertEqual("btaxlooa6g3kqmodthrgs5zgme", ctx.base32(rhash.MD5))
if rhash.get_librhash_version_int() > 0x01040400:
with self.assertRaises(rhash.InvalidArgumentError):
ctx.base32(rhash.SHA1)
with self.assertRaises(rhash.InvalidArgumentError):
ctx.base64(rhash.SHA1)
with self.assertRaises(rhash.InvalidArgumentError):
ctx.hex(rhash.SHA1)
with self.assertRaises(rhash.InvalidArgumentError):
ctx.raw(rhash.SHA1)
if rhash.get_librhash_version_int() > 0x01040400:
with self.assertRaises(rhash.InvalidArgumentError):
with rhash.RHash(rhash.CRC32, rhash.MD5) as ctx:
ctx.hash(rhash.SHA1)
def test_store_and_load(self):
"""Test store/load methods."""
try:
with rhash.RHash(rhash.CRC32, rhash.MD5) as ctx1:
ctx1.update("a")
data = ctx1.store()
self.assertTrue(data)
self.assertTrue(isinstance(data, bytes))
ctx2 = rhash.RHash.load(data)
self.assertEqual(data, ctx2.store())
ctx1.update("bc").finish()
ctx2.update("bc").finish()
self.assertEqual("352441c2", ctx2.hash(rhash.CRC32))
self.assertEqual("900150983cd24fb0d6963f7d28e17f72", ctx2.hash(rhash.MD5))
self.assertEqual(ctx1.store(), ctx2.store())
except NotImplementedError:
pass
if __name__ == "__main__":
unittest.main()
rhash-1.4.6/bindings/python/rhash/ 0000755 0000000 0000000 00000000000 15010731530 015543 5 ustar root root rhash-1.4.6/bindings/python/rhash/__init__.py 0000664 0000000 0000000 00000004326 15010512155 017663 0 ustar root root # Copyright (c) 2021, Aleksey Kravchenko
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
"""Python rhash module."""
from .rhash import (
ALL,
CRC32,
CRC32C,
MD4,
MD5,
SHA1,
TIGER,
TTH,
BTIH,
ED2K,
AICH,
WHIRLPOOL,
RIPEMD160,
GOST94,
GOST94_CRYPTOPRO,
GOST12_256,
GOST12_512,
HAS160,
SHA2_224,
SHA2_256,
SHA2_384,
SHA2_512,
EDONR256,
EDONR512,
SHA3_224,
SHA3_256,
SHA3_384,
SHA3_512,
BLAKE2S,
BLAKE2B,
BLAKE3,
SNEFRU128,
SNEFRU256,
RHash,
InvalidArgumentError,
hash_msg,
hash_file,
make_magnet,
get_librhash_version,
get_librhash_version_int,
)
# Import deprecated constants and functions
from .rhash import SHA224, SHA256, SHA384, SHA512
from .rhash import hash_for_msg, hash_for_file, magnet_for_file
__all__ = [
"ALL",
"CRC32",
"CRC32C",
"MD4",
"MD5",
"SHA1",
"TIGER",
"TTH",
"BTIH",
"ED2K",
"AICH",
"WHIRLPOOL",
"RIPEMD160",
"GOST94",
"GOST94_CRYPTOPRO",
"GOST12_256",
"GOST12_512",
"HAS160",
"SHA2_224",
"SHA2_256",
"SHA2_384",
"SHA2_512",
"EDONR256",
"EDONR512",
"SHA3_224",
"SHA3_256",
"SHA3_384",
"SHA3_512",
"BLAKE2S",
"BLAKE2B",
"BLAKE3",
"SNEFRU128",
"SNEFRU256",
"RHash",
"InvalidArgumentError",
"hash_msg",
"hash_file",
"make_magnet",
"get_librhash_version",
"get_librhash_version_int",
"SHA224",
"SHA256",
"SHA384",
"SHA512",
"hash_for_msg",
"hash_for_file",
"magnet_for_file",
]
rhash-1.4.6/bindings/python/rhash/rhash.py 0000664 0000000 0000000 00000035763 15010520654 017245 0 ustar root root # Copyright (c) 2011, Sergey Basalaev ,
# Aleksey Kravchenko
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
"""Python bindings for LibRHash.
Librhash is a library for computing message digests and
magnet links for various hash functions. The simplest way to
calculate a message digest of a string or file is by using
one of the functions:
hash_msg(message, hash_id)
hash_file(filepath, hash_id)
make_magnet(filepath, hash_ids)
Here hash_id is one of the constants CRC32, CRC32C, MD4, MD5,
SHA1, TIGER, TTH, BTIH, ED2K, AICH, WHIRLPOOL, RIPEMD160,
GOST94, GOST94_CRYPTOPRO, GOST12_256, GOST12_512, HAS160, SHA2_224,
SHA2_256, SHA2_384, SHA2_512, SHA3_224, SHA3_256, SHA3_384, SHA3_512,
BLAKE2S, BLAKE2B, EDONR256, EDONR512, SNEFRU128, SNEFRU256.
The first two functions will return the default text representation
of the message digest they compute. The latter will return the
magnet link for the file. In this function you can OR-combine
several hash_ids, like
>>> print make_magnet('rhash.py', CRC32, MD5)
magnet:?xl=6041&dn=rhash.py&xt=urn:crc32:f5866f7a&xt=urn:md5:
f88e6c1620361da9d04e2a2a1c788059
Next, this module provides a class to calculate several message digests
simultaneously in an incremental way. Example of using it:
>>> hasher = RHash(CRC32, MD5)
>>> hasher.update('Hello, ')
>>> hasher << 'world' << '!'
>>> hasher.finish()
>>> print hasher.HEX(CRC32)
EBE6C6E6
>>> print hasher.hex(MD5)
6cd3556deb0da54bca060b4c39479839
In this example RHash object is first created for a set of
hashing algorithms. Then, data for hashing is given in chunks
with methods update(message) and update_file(filepath).
Finally, call finish() to end up all remaining calculations.
To receive text represenation of the message digest use one
of the methods hex(), HEX(), base32(), BASE32() and base64().
The hash() method outputs message digest in its default
format. Binary message digest may be obtained with raw().
All of these methods accept hash_id as argument, but
hash_id can be omitted if the instance of RHash was created
to compute message digest of a single hash function.
Method magnet(filepath) will generate magnet link containing
message digests computed by the RHash object.
"""
import sys
import warnings
from ctypes import (
CDLL,
POINTER,
c_char_p,
c_int,
c_size_t,
c_uint,
c_ulonglong,
c_void_p,
create_string_buffer,
)
# initialization
if sys.platform == "win32":
_LIBNAME = "librhash.dll"
elif sys.platform == "darwin":
_LIBNAME = "librhash.1.dylib"
elif sys.platform == "cygwin":
_LIBNAME = "cygrhash.dll"
elif sys.platform == "msys":
_LIBNAME = "msys-rhash.dll"
else:
_LIBNAME = "librhash.so.1"
_LIBRHASH = CDLL(_LIBNAME)
_LIBRHASH.rhash_library_init()
# function prototypes
_LIBRHASH.rhash_init.argtypes = [c_uint]
_LIBRHASH.rhash_init.restype = c_void_p
_LIBRHASH.rhash_init_multi.argtypes = [c_size_t, POINTER(c_uint)]
_LIBRHASH.rhash_init_multi.restype = c_void_p
_LIBRHASH.rhash_free.argtypes = [c_void_p]
_LIBRHASH.rhash_reset.argtypes = [c_void_p]
_LIBRHASH.rhash_update.argtypes = [c_void_p, c_char_p, c_size_t]
_LIBRHASH.rhash_final.argtypes = [c_void_p, c_char_p]
_LIBRHASH.rhash_print.argtypes = [c_char_p, c_void_p, c_uint, c_int]
_LIBRHASH.rhash_print.restype = c_size_t
_LIBRHASH.rhash_print_magnet.argtypes = [c_char_p, c_char_p, c_void_p, c_uint, c_int]
_LIBRHASH.rhash_print_magnet.restype = c_size_t
_LIBRHASH.rhash_export.argtypes = [c_void_p, c_char_p, c_size_t]
_LIBRHASH.rhash_export.restype = c_size_t
_LIBRHASH.rhash_import.argtypes = [c_char_p, c_size_t]
_LIBRHASH.rhash_import.restype = c_void_p
_LIBRHASH.rhash_transmit.argtypes = [c_uint, c_void_p, c_size_t, c_void_p]
_HAS_RHASH_CTRL = hasattr(_LIBRHASH, "rhash_ctrl")
if _HAS_RHASH_CTRL:
_LIBRHASH.rhash_ctrl.argtypes = [c_void_p, c_int, c_size_t, c_void_p]
_LIBRHASH.rhash_ctrl.restype = c_size_t
def _run_rhash_ctrl(ctx, command, count=0, data=None):
return _LIBRHASH.rhash_ctrl(ctx, command, count, data)
else:
def _run_rhash_ctrl(ctx, command, count=0, data=0):
return _LIBRHASH.rhash_transmit(command, ctx, count, data)
_HAS_RHASH_UPDATE_FD = hasattr(_LIBRHASH, "rhash_update_fd")
_HAS_EXTENDED_HASH_IDS = _HAS_RHASH_UPDATE_FD
if _HAS_RHASH_UPDATE_FD:
_LIBRHASH.rhash_update_fd.argtypes = [c_void_p, c_int, c_ulonglong]
_LIBRHASH.rhash_ctrl.restype = c_int
# conversion of a string to binary data with Python 2/3 compatibility
if sys.version < "3":
def _s2b(string):
"""Python 2: just return the string."""
return string
def _msg_to_bytes(msg):
"""Convert the msg parameter to a string."""
if isinstance(msg, str):
return msg
return str(msg)
else:
import codecs
def _s2b(string):
"""Python 3: convert the string to binary data."""
return codecs.utf_8_encode(string)[0]
def _msg_to_bytes(msg):
"""Convert the msg parameter to binary data."""
if isinstance(msg, bytes):
return msg
if isinstance(msg, str):
return _s2b(msg)
return _s2b(str(msg))
# hash_id values
CRC32 = 0x01
MD4 = 0x02
MD5 = 0x04
SHA1 = 0x08
TIGER = 0x10
TTH = 0x20
BTIH = 0x40
ED2K = 0x80
AICH = 0x100
WHIRLPOOL = 0x200
RIPEMD160 = 0x400
GOST94 = 0x800
GOST94_CRYPTOPRO = 0x1000
HAS160 = 0x2000
GOST12_256 = 0x4000
GOST12_512 = 0x8000
SHA2_224 = 0x10000
SHA2_256 = 0x20000
SHA2_384 = 0x40000
SHA2_512 = 0x80000
EDONR256 = 0x100000
EDONR512 = 0x200000
SHA3_224 = 0x0400000
SHA3_256 = 0x0800000
SHA3_384 = 0x1000000
SHA3_512 = 0x2000000
CRC32C = 0x4000000
SNEFRU128 = 0x08000000
SNEFRU256 = 0x10000000
BLAKE2S = 0x20000000
BLAKE2B = 0x40000000
BLAKE3 = 0x8000001F
if _HAS_EXTENDED_HASH_IDS:
ALL = 0xFF000000
else:
ALL = 0x7FFFFFFF
_LOW_HASH_MASK = 0x7FFFFFFF
_EXTENDED_BIT = 0x80000000
_MAX_HASH_COUNT = 256
# four deprecated constants
SHA224 = 0x10000
SHA256 = 0x20000
SHA384 = 0x40000
SHA512 = 0x80000
# rhash_print values
_RHPR_RAW = 1
_RHPR_HEX = 2
_RHPR_BASE32 = 3
_RHPR_BASE64 = 4
_RHPR_UPPERCASE = 8
_RHPR_NO_MAGNET = 0x20
_RHPR_FILESIZE = 0x40
_CTLR_SET_AUTOFINAL = 5
_CTLR_GET_CTX_ALGORITHMS = 15
_CTLR_GET_LIBRHASH_VERSION = 20
class InvalidArgumentError(ValueError):
"""Raised on an invalid argument value."""
class RHash(object):
"""Class to compute message digests and magnet links."""
__context_key = object()
def __init__(self, *hash_ids):
"""Construct RHash object."""
if len(hash_ids) == 2 and hash_ids[0] == RHash.__context_key:
self._ctx = hash_ids[1]
elif RHash._are_good_ids(hash_ids):
uint_ids = (c_uint * len(hash_ids))(*hash_ids)
self._ctx = _LIBRHASH.rhash_init_multi(len(hash_ids), uint_ids)
else:
self._ctx = _LIBRHASH.rhash_init(RHash._get_hash_mask(hash_ids))
if not self._ctx:
raise RuntimeError("No RHash context")
# switching off the auto-final feature
_run_rhash_ctrl(self._ctx, _CTLR_SET_AUTOFINAL)
def __enter__(self):
"""Enter the runtime context related to the RHash object."""
return self
def __exit__(self, _type, _value, _traceback):
"""Exit the runtime context related to the RHash object."""
self._cleanup()
self._ctx = None
def __del__(self):
"""Destroy RHash object."""
self._cleanup()
def __str__(self):
"""Return the message digest."""
return self._print(0, 0)
def _cleanup(self):
"""Cleanup allocated resources."""
if self._ctx is not None:
_LIBRHASH.rhash_free(self._ctx)
@staticmethod
def _are_good_ids(hash_ids):
for alg_id in hash_ids:
if not isinstance(alg_id, int) or alg_id <= 0:
raise InvalidArgumentError("Invalid value of hash_ids")
if (alg_id & _EXTENDED_BIT) == 0:
if ((alg_id - 1) & alg_id) != 0:
return False
elif not _HAS_EXTENDED_HASH_IDS:
raise InvalidArgumentError(
"Hash_id is not supported by the installed librhash version"
)
elif (alg_id & _LOW_HASH_MASK) > _MAX_HASH_COUNT:
return False
return True
@staticmethod
def _get_hash_mask(hash_ids):
hash_mask = 0
for hash_id in hash_ids:
hash_mask = hash_mask | hash_id
if hash_mask > 0:
return hash_mask
raise InvalidArgumentError("Invalid value of hash_ids")
def reset(self):
"""Reset this object to initial state."""
_LIBRHASH.rhash_reset(self._ctx)
return self
def update(self, message):
"""Update this object with new data chunk."""
data = _msg_to_bytes(message)
_LIBRHASH.rhash_update(self._ctx, data, len(data))
return self
def __lshift__(self, message):
"""Update this object with new data chunk."""
return self.update(message)
def update_file(self, filepath):
"""Update this object with data from the given file."""
with open(filepath, "rb") as file:
buf = file.read(8192)
while len(buf) > 0:
self.update(buf)
buf = file.read(8192)
return self
def finish(self):
"""Flush buffered data and calculate message digests."""
_LIBRHASH.rhash_final(self._ctx, None)
return self
def _print(self, hash_id, flags):
"""Retrieve the message digest in the specified format."""
buf = create_string_buffer(130)
size = _LIBRHASH.rhash_print(buf, self._ctx, hash_id, flags)
if not size:
raise InvalidArgumentError(
"Requested message digest for an unsupported hash_id = {}".format(hash_id)
)
if (flags & 3) == _RHPR_RAW:
return buf[0:size]
return buf[0:size].decode()
def raw(self, hash_id=0):
"""Return the message digest as raw binary data."""
return self._print(hash_id, _RHPR_RAW)
def hex(self, hash_id=0):
"""Return the message digest as a hexadecimal lower-case string."""
return self._print(hash_id, _RHPR_HEX)
def base32(self, hash_id=0):
"""Return the message digest as a Base32 lower-case string."""
return self._print(hash_id, _RHPR_BASE32)
def base64(self, hash_id=0):
"""Return the message digest as a Base64 string."""
return self._print(hash_id, _RHPR_BASE64)
def hex_upper(self, hash_id=0):
"""Return the message digest as a hexadecimal upper-case string."""
return self._print(hash_id, _RHPR_HEX | _RHPR_UPPERCASE)
def base32_upper(self, hash_id=0):
"""Return the message digest as a Base32 upper-case string."""
return self._print(hash_id, _RHPR_BASE32 | _RHPR_UPPERCASE)
# deprecated aliases
HEX = hex_upper
BASE32 = base32_upper
def magnet(self, filepath):
"""Return magnet link with all message digests computed by this object."""
hash_mask = ALL
if get_librhash_version_int() == 0x01040500:
# Quickfix for rhash_print_magnet() in v1.4.5
uint_ids = (c_uint * 32)()
count = _run_rhash_ctrl(self._ctx, _CTLR_GET_CTX_ALGORITHMS, 32, uint_ids)
if 0 < count < 32:
hash_mask = 0
for hash_bit in uint_ids[0:count]:
hash_mask = hash_mask | hash_bit
size = _LIBRHASH.rhash_print_magnet(
None, _s2b(filepath), self._ctx, hash_mask, _RHPR_FILESIZE
)
buf = create_string_buffer(size)
_LIBRHASH.rhash_print_magnet(
buf, _s2b(filepath), self._ctx, hash_mask, _RHPR_FILESIZE
)
return buf[0:size - 1].decode("utf-8")
def hash(self, hash_id=0):
"""Return the message digest for the given hash function in its default format."""
return self._print(hash_id, 0)
def store(self):
"""Store RHash context into a block of bytes."""
size = _LIBRHASH.rhash_export(self._ctx, None, 0)
if size > 0:
buf = create_string_buffer(size)
exported_size = _LIBRHASH.rhash_export(self._ctx, buf, size)
if size == exported_size:
return buf.raw
raise RuntimeError("Store failed")
@staticmethod
def load(data):
"""Load a previously stored RHash context from a block of bytes."""
if not isinstance(data, bytes):
raise InvalidArgumentError("Invalid argument type")
ctx = _LIBRHASH.rhash_import(data, len(data))
if ctx:
return RHash(RHash.__context_key, ctx)
raise RuntimeError("Load failed")
# simplified interface functions
def hash_msg(message, hash_id):
"""Compute and return the message digest (in its default format) of the message."""
handle = RHash(hash_id)
handle.update(message).finish()
return str(handle)
def hash_file(filepath, hash_id):
"""Compute and return the message digest (in its default format) for file content."""
handle = RHash(hash_id)
handle.update_file(filepath).finish()
return str(handle)
def make_magnet(filepath, *hash_ids):
"""Compute and return the magnet link for the file."""
handle = RHash(*hash_ids)
handle.update_file(filepath).finish()
return handle.magnet(filepath)
def get_librhash_version_int():
"""Return the version of the loaded LibRHash library as integer."""
return _run_rhash_ctrl(None, _CTLR_GET_LIBRHASH_VERSION)
def get_librhash_version():
"""Return the version of the loaded LibRHash library as string."""
ver = get_librhash_version_int()
return "{}.{}.{}".format(ver >> 24, (ver >> 16) & 255, (ver >> 8) & 255)
# deprecated functions
def _deprecation(message):
warnings.warn(message, category=DeprecationWarning, stacklevel=2)
def hash_for_msg(message, hash_id):
"""Deprecated function to compute a hash of a message."""
_deprecation("Call to deprecated function hash_for_msg(), should use hash_msg().")
return hash_msg(message, hash_id)
def hash_for_file(filepath, hash_id):
"""Deprecated function to compute a hash of a file."""
_deprecation("Call to deprecated function hash_for_file(), should use hash_file().")
return hash_file(filepath, hash_id)
def magnet_for_file(filepath, hash_mask):
"""Deprecated function to compute a magnet link for a file."""
_deprecation("Deprecated function magnet_for_file() called, use make_magnet().")
return make_magnet(filepath, hash_mask)
rhash-1.4.6/bindings/COPYING 0000664 0000000 0000000 00000001334 14703622112 014156 0 ustar root root
BSD Zero Clause License
Copyright (c) 2011, Aleksey Kravchenko and Sergey Basalaev
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
rhash-1.4.6/bindings/ChangeLog 0000644 0000000 0000000 00000001366 13135507623 014707 0 ustar root root Fri Aug 1 2014 Aleksey
* python 3 support
* update SHA3 test vectors to follow the changes of the spec
Sun Jan 19 2014 Aleksey
* renamed perl module to the Crypt::Rhash
Tue Sep 17 2013 Aleksey
* === Version 1.3.0 ===
Tue Dec 25 2012 Aleksey
* === Version 1.2.10 ===
Sun May 13 2012 Aleksey
* BugFix: python crashed on ia64
Tue Apr 17 2012 Aleksey
* PHP bindings for librhash
Sat Apr 14 2012 Aleksey
* === Version 1.2.9 ===
Sun Nov 06 2011 Sergey Basalaev
* .NET/Mono bindings to librhash
Wed Sep 14 2011 Aleksey
* === Version 1.2.8 ===
Wed Sep 14 2011 Aleksey
* Perl bindings
Sat Jul 9 2011 Sergey Basalaev
* Ruby bindings
Thu Jun 16 2011 Sergey Basalaev
* Python bindings
Sun Jun 12 2011 Sergey Basalaev
* LibRHash Java bindings
rhash-1.4.6/bindings/version.properties 0000664 0000000 0000000 00000000016 15010730604 016720 0 ustar root root version=1.4.6
rhash-1.4.6/bindings/java/ 0000755 0000000 0000000 00000000000 15010731530 014036 5 ustar root root rhash-1.4.6/bindings/java/Makefile 0000664 0000000 0000000 00000006020 14703622112 015501 0 ustar root root #!/usr/bin/make -f
# This file is a part of Java Bindings for Librhash
#
# Copyright (c) 2011, Sergey Basalaev
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
JAVA = java
JAVAC = javac
JAVADOC = javadoc
JAVAH = javah
JAR = jar
JUNIT_CLASSPATH = /usr/share/java/junit4.jar
VERSION = $(shell sed -ne 's/^version=\(.*\)/\1/p' ../version.properties)
JAVASRC_DIR = src
CSRC_DIR = native
DEST_DIR ?= dist
CLASSES_DIR = classes
JAVADOC_DIR = javadoc
TEST_DIR = test
JAVA_FILES := $(shell find $(JAVASRC_DIR) -name '*.java')
JNI_FILES := $(shell find $(CSRC_DIR) -name '*.c' -o -name '*.h')
LIB_PREFIX ?= lib
LIB_SUFFIX ?= .so
JNI_LIBRARY = $(LIB_PREFIX)rhash-jni$(LIB_SUFFIX)
JARFILE = $(DEST_DIR)/rhash-$(VERSION).jar
JAVADOC_FILE = $(DEST_DIR)/rhash-$(VERSION)-javadoc.zip
JAVADOC_API_URL = http://download.oracle.com/javase/6/docs/api/
all: build-binary javadoc
build-binary: jar jar-symlink jni
jar: $(JARFILE)
jni: $(DEST_DIR)/$(JNI_LIBRARY)
zip-javadoc: $(JAVADOC_FILE)
jar-symlink:
mkdir -p $(DEST_DIR)
ln -fs rhash-$(VERSION).jar $(DEST_DIR)/rhash.jar
$(JARFILE): $(JAVA_FILES)
+$(MAKE) compile-classes
mkdir -p $(DEST_DIR)
$(JAR) cf $(JARFILE) -C $(CLASSES_DIR) org/
compile-classes:
mkdir -p $(CLASSES_DIR)
$(JAVAC) -d $(CLASSES_DIR) -sourcepath $(JAVASRC_DIR) $(JAVA_FILES)
update-header: compile-classes
$(JAVAH) -o $(CSRC_DIR)/bindings.h -classpath $(CLASSES_DIR) org.sf.rhash.Bindings
$(DEST_DIR)/$(JNI_LIBRARY): $(JNI_FILES)
+$(MAKE) -C $(CSRC_DIR)
mkdir -p $(DEST_DIR)
cp $(CSRC_DIR)/$(JNI_LIBRARY) $(DEST_DIR)
javadoc: clean-javadoc
$(JAVADOC) -windowtitle 'RHash' \
-sourcepath $(JAVASRC_DIR) \
-subpackages org \
-d $(JAVADOC_DIR) \
-link $(JAVADOC_API_URL)
$(JAVADOC_FILE): $(JAVA_FILES)
+$(MAKE) javadoc
jar -cMf $(JAVADOC_FILE) $(JAVADOC_DIR)
$(TEST_DIR)/RHashTest.class: $(JARFILE) $(TEST_DIR)/RHashTest.java
$(JAVAC) -classpath $(JARFILE):$(JUNIT_CLASSPATH) $(TEST_DIR)/RHashTest.java
test: $(TEST_DIR)/RHashTest.class jni
$(JAVA) -classpath $(TEST_DIR):$(JARFILE):$(JUNIT_CLASSPATH) -Djava.library.path=$(DEST_DIR) junit.textui.TestRunner RHashTest
clean: clean-javadoc clean-jni clean-classes clean-test
clean-javadoc:
rm -rf $(JAVADOC_DIR)
clean-classes:
rm -rf $(CLASSES_DIR)
clean-jni:
+$(MAKE) -C $(CSRC_DIR) clean
clean-test:
rm -f $(TEST_DIR)/*.class
distclean: clean
rm -rf $(DEST_DIR)
.PHONY: jar jni javadoc test clean clean-javadoc distclean
rhash-1.4.6/bindings/java/native/ 0000755 0000000 0000000 00000000000 15010731530 015324 5 ustar root root rhash-1.4.6/bindings/java/native/Makefile 0000664 0000000 0000000 00000003215 14703622112 016772 0 ustar root root #!/usr/bin/make -f
# This file is a part of Java Bindings for Librhash
#
# Copyright (c) 2011, Sergey Basalaev
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
CC ?= gcc
JAVAC ?= javac
CFLAGS ?= -g -O2
LDFLAGS ?=
LIBRHASH_INC ?=
LIBRHASH_LD ?=
ALLLDFLAGS = $(LDFLAGS) -lrhash $(LIBRHASH_LD)
ALLCFLAGS = $(CFLAGS) $(LIBRHASH_INC) -fPIC
#Platform dependent
JAVAC_PATH = $(shell readlink -f $(shell command -v $(JAVAC)))
JDK_HOME ?=$(realpath $(dir $(JAVAC_PATH))/..)
JNI_CFLAGS1 = $(shell test -d "$(JDK_HOME)/include" && echo -I$(JDK_HOME)/include)
JNI_CFLAGS2 = $(shell test -d "$(JDK_HOME)/include/linux" && echo -I$(JDK_HOME)/include/linux)
JNI_CFLAGS ?= $(JNI_CFLAGS1) $(JNI_CFLAGS2)
LIB_PREFIX ?= lib
LIB_SUFFIX ?= .so
OBJECTS = bindings.o digest.o
LIBRARY = $(LIB_PREFIX)rhash-jni$(LIB_SUFFIX)
all: $(LIBRARY)
bindings.o: bindings.c bindings.h
$(CC) $(ALLCFLAGS) $(JNI_CFLAGS) -c $< -o $@
digest.o: digest.c digest.h
$(CC) $(ALLCFLAGS) -c $< -o $@
$(LIBRARY): $(OBJECTS)
$(CC) -shared -o $@ $(OBJECTS) $(ALLLDFLAGS)
clean:
rm -f *.o $(LIBRARY)
rhash-1.4.6/bindings/java/native/bindings.c 0000664 0000000 0000000 00000014541 14703622112 017277 0 ustar root root /*
* This file is a part of Java Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include
#ifdef __GNUC__
#include
#define TO_RHASH(a) ((rhash)(intptr_t)(a))
#define TO_DIGEST(a) ((Digest)(intptr_t)(a))
#define TO_JLONG(a) ((jlong)(intptr_t)(a))
#else
#define TO_RHASH(a) ((rhash)(a))
#define TO_DIGEST(a) ((Digest)(a))
#define TO_JLONG(a) ((jlong)(a))
#endif /* __GNUC__ */
#include "bindings.h"
#include "digest.h"
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_library_init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1library_1init
(JNIEnv *env, jclass clz) {
rhash_library_init();
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_count
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_sf_rhash_Bindings_rhash_1count
(JNIEnv *env, jclass clz) {
return rhash_count();
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_msg
* Signature: (I[BII)J
*/
JNIEXPORT jlong JNICALL Java_org_sf_rhash_Bindings_rhash_1msg
(JNIEnv *env, jclass clz, jint hash_id, jbyteArray buf, jint ofs, jint len) {
// reading data
void* msg = malloc(len);
(*env)->GetByteArrayRegion(env, buf, ofs, len, msg);
// creating and populating Digest
Digest obj = malloc(sizeof(DigestStruct));
obj->hash_len = rhash_get_digest_size(hash_id);
obj->hash_data = calloc(obj->hash_len, sizeof(unsigned char));
rhash_msg(hash_id, msg, len, obj->hash_data);
//cleaning
free(msg);
//returning
return TO_JLONG(obj);
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_print_bytes
* Signature: (JI)[B
*/
JNIEXPORT jbyteArray JNICALL Java_org_sf_rhash_Bindings_rhash_1print_1bytes
(JNIEnv *env, jclass clz, jlong ptr, jint flags) {
Digest obj = TO_DIGEST(ptr);
char output[130];
int len = rhash_print_bytes(output, obj->hash_data, obj->hash_len, flags);
jbyteArray arr = (*env)->NewByteArray(env, len);
(*env)->SetByteArrayRegion(env, arr, 0, len, (jbyte*)output);
return arr;
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_print_magnet
* Signature: (JLjava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sf_rhash_Bindings_rhash_1print_1magnet
(JNIEnv *env, jclass clz, jlong context, jstring filepath, jint flags) {
const char* fpath = (filepath != NULL) ?
(*env)->GetStringUTFChars(env, filepath, NULL) : NULL;
size_t len = rhash_print_magnet(NULL, fpath, TO_RHASH(context), flags, RHPR_FILESIZE);
char *buf = (char*)malloc(len);
rhash_print_magnet(buf, fpath, TO_RHASH(context), flags, RHPR_FILESIZE);
if (filepath != NULL) {
(*env)->ReleaseStringUTFChars(env, filepath, fpath);
}
jstring str = (*env)->NewStringUTF(env, buf);
free(buf);
return str;
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_is_base32
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_org_sf_rhash_Bindings_rhash_1is_1base32
(JNIEnv *env, jclass clz, jint hash_id) {
return rhash_is_base32(hash_id);
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_get_digest_size
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_org_sf_rhash_Bindings_rhash_1get_1digest_1size
(JNIEnv *env, jclass clz, jint hash_id) {
return rhash_get_digest_size(hash_id);
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_init
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_org_sf_rhash_Bindings_rhash_1init
(JNIEnv *env, jclass clz, jint hash_flags) {
rhash ctx = rhash_init(hash_flags);
rhash_set_autofinal(ctx, 0);
return TO_JLONG(ctx);
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_update
* Signature: (J[BII)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1update
(JNIEnv *env, jclass clz, jlong context, jbyteArray data, jint ofs, jint len) {
void* msg = malloc(len);
(*env)->GetByteArrayRegion(env, data, ofs, len, msg);
rhash_update(TO_RHASH(context), msg, len);
free(msg);
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_final
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1final
(JNIEnv *env, jclass clz, jlong context) {
rhash_final(TO_RHASH(context), NULL);
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_reset
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1reset
(JNIEnv *env, jclass clz, jlong context) {
rhash_reset(TO_RHASH(context));
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_print
* Signature: (JI)J
*/
JNIEXPORT jlong JNICALL Java_org_sf_rhash_Bindings_rhash_1print
(JNIEnv *env, jclass clz, jlong context, jint hash_id) {
Digest obj = malloc(sizeof(DigestStruct));
obj->hash_len = rhash_get_digest_size(hash_id);
obj->hash_data = calloc(obj->hash_len, sizeof(unsigned char));
rhash_print((char*)obj->hash_data, TO_RHASH(context), hash_id, RHPR_RAW);
return TO_JLONG(obj);
}
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_free
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1free
(JNIEnv *env, jclass clz, jlong context) {
rhash_free(TO_RHASH(context));
}
/*
* Class: org_sf_rhash_Bindings
* Method: compareDigests
* Signature: (JJ)Z
*/
JNIEXPORT jboolean JNICALL Java_org_sf_rhash_Bindings_compareDigests
(JNIEnv *env, jclass clz, jlong ptr1, jlong ptr2) {
return compareDigests(TO_DIGEST(ptr1), TO_DIGEST(ptr2));
}
/*
* Class: org_sf_rhash_Bindings
* Method: hashcodeForDigest
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_org_sf_rhash_Bindings_hashcodeForDigest
(JNIEnv *env, jclass clz, jlong ptr) {
return hashcodeForDigest(TO_DIGEST(ptr));
}
/*
* Class: org_sf_rhash_Bindings
* Method: freeDigest
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_freeDigest
(JNIEnv *env, jclass clz, jlong ptr) {
freeDigest(TO_DIGEST(ptr));
}
rhash-1.4.6/bindings/java/native/bindings.h 0000644 0000000 0000000 00000006462 13135503555 017314 0 ustar root root /* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class org_sf_rhash_Bindings */
#ifndef _Included_org_sf_rhash_Bindings
#define _Included_org_sf_rhash_Bindings
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_library_init
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1library_1init
(JNIEnv *, jclass);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_count
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_sf_rhash_Bindings_rhash_1count
(JNIEnv *, jclass);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_msg
* Signature: (I[BII)J
*/
JNIEXPORT jlong JNICALL Java_org_sf_rhash_Bindings_rhash_1msg
(JNIEnv *, jclass, jint, jbyteArray, jint, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_print_bytes
* Signature: (JI)[B
*/
JNIEXPORT jbyteArray JNICALL Java_org_sf_rhash_Bindings_rhash_1print_1bytes
(JNIEnv *, jclass, jlong, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_print_magnet
* Signature: (JLjava/lang/String;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sf_rhash_Bindings_rhash_1print_1magnet
(JNIEnv *, jclass, jlong, jstring, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_is_base32
* Signature: (I)Z
*/
JNIEXPORT jboolean JNICALL Java_org_sf_rhash_Bindings_rhash_1is_1base32
(JNIEnv *, jclass, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_get_digest_size
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_org_sf_rhash_Bindings_rhash_1get_1digest_1size
(JNIEnv *, jclass, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_init
* Signature: (I)J
*/
JNIEXPORT jlong JNICALL Java_org_sf_rhash_Bindings_rhash_1init
(JNIEnv *, jclass, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_update
* Signature: (J[BII)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1update
(JNIEnv *, jclass, jlong, jbyteArray, jint, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_final
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1final
(JNIEnv *, jclass, jlong);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_reset
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1reset
(JNIEnv *, jclass, jlong);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_print
* Signature: (JI)J
*/
JNIEXPORT jlong JNICALL Java_org_sf_rhash_Bindings_rhash_1print
(JNIEnv *, jclass, jlong, jint);
/*
* Class: org_sf_rhash_Bindings
* Method: rhash_free
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_rhash_1free
(JNIEnv *, jclass, jlong);
/*
* Class: org_sf_rhash_Bindings
* Method: compareDigests
* Signature: (JJ)Z
*/
JNIEXPORT jboolean JNICALL Java_org_sf_rhash_Bindings_compareDigests
(JNIEnv *, jclass, jlong, jlong);
/*
* Class: org_sf_rhash_Bindings
* Method: hashcodeForDigest
* Signature: (J)I
*/
JNIEXPORT jint JNICALL Java_org_sf_rhash_Bindings_hashcodeForDigest
(JNIEnv *, jclass, jlong);
/*
* Class: org_sf_rhash_Bindings
* Method: freeDigest
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_org_sf_rhash_Bindings_freeDigest
(JNIEnv *, jclass, jlong);
#ifdef __cplusplus
}
#endif
#endif
rhash-1.4.6/bindings/java/native/digest.h 0000664 0000000 0000000 00000002674 14703622112 016772 0 ustar root root /*
* This file is a part of Java Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* This is convenient structure to hold message digest. */
#ifndef DIGEST_H
#define DIGEST_H
typedef struct {
int hash_id;
size_t hash_len;
unsigned char *hash_data;
} DigestStruct;
typedef DigestStruct* Digest;
/**
* Frees memory occupated by Digest.
* @param obj object to free
*/
void freeDigest(Digest obj);
/**
* Compares two Digest instances.
* @param obj1 first object to compare
* @param obj2 second object to compare
* @return 1 if objects are equal, 0 otherwise
*/
int compareDigests(Digest obj1, Digest obj2);
/**
* Calculates hashcode for Digest.
* @param obj object to calculate hash code
*/
int hashcodeForDigest(Digest obj);
#endif /* DIGEST_H */
rhash-1.4.6/bindings/java/native/digest.c 0000664 0000000 0000000 00000002575 14703622112 016765 0 ustar root root /*
* This file is a part of Java Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include
#include "digest.h"
void freeDigest(Digest obj) {
free(obj->hash_data);
free(obj);
}
int compareDigests(Digest o1, Digest o2) {
if (o1->hash_len != o2->hash_len) return 0;
return memcmp(o1->hash_data, o2->hash_data, o1->hash_len) == 0;
}
int hashcodeForDigest(Digest obj) {
int hash = 123321, i;
for (i = 0; i < obj->hash_len; i++) {
switch (i % 3) {
case 0: hash ^= obj->hash_data[i];
case 1: hash ^= obj->hash_data[i] << 8;
case 2: hash ^= obj->hash_data[i] << 16;
case 3: hash ^= obj->hash_data[i] << 24;
}
}
return hash ^ (obj->hash_id + obj->hash_len);
}
rhash-1.4.6/bindings/java/src/ 0000755 0000000 0000000 00000000000 15010731530 014625 5 ustar root root rhash-1.4.6/bindings/java/src/org/ 0000755 0000000 0000000 00000000000 15010731530 015414 5 ustar root root rhash-1.4.6/bindings/java/src/org/sf/ 0000755 0000000 0000000 00000000000 15010731530 016024 5 ustar root root rhash-1.4.6/bindings/java/src/org/sf/rhash/ 0000755 0000000 0000000 00000000000 15010731530 017131 5 ustar root root rhash-1.4.6/bindings/java/src/org/sf/rhash/HashType.java 0000664 0000000 0000000 00000006606 14703622112 021536 0 ustar root root /*
* This file is a part of Java Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
package org.sf.rhash;
/**
* Type of hashing algorithm. Supported algorithms are CRC32, CRC32C,
* MD4, MD5, SHA1/SHA2/SHA3, Tiger, DC++ TTH, BitTorrent BTIH, AICH,
* EDonkey 2000 hash, GOST R 34.11-94, GOST R 34.11-2012, RIPEMD-160,
* HAS-160, BLAKE2s/BLAKE2b, EDON-R 256/512, Whirlpool and Snefru-128/256.
*/
public enum HashType {
/** CRC32 checksum. */
CRC32(1),
/** MD4 hash. */
MD4(1 << 1),
/** MD5 hash. */
MD5(1 << 2),
/** SHA-1 hash. */
SHA1(1 << 3),
/** Tiger hash. */
TIGER(1 << 4),
/** Tiger tree hash */
TTH(1 << 5),
/** BitTorrent info hash. */
BTIH(1 << 6),
/** EDonkey 2000 hash. */
ED2K(1 << 7),
/** eMule AICH. */
AICH(1 << 8),
/** Whirlpool hash. */
WHIRLPOOL(1 << 9),
/** RIPEMD-160 hash. */
RIPEMD160(1 << 10),
/** GOST R 34.11-94. */
GOST94(1 << 11),
GOST94_CRYPTOPRO(1 << 12),
/** HAS-160 hash. */
HAS160(1 << 13),
/** GOST R 34.11-2012 - 256 bit. */
GOST12_256(1 << 14),
/** GOST R 34.11-2012 - 512 bit. */
GOST12_512(1 << 15),
/** SHA-224 hash. */
SHA224(1 << 16),
/** SHA-256 hash. */
SHA256(1 << 17),
/** SHA-384 hash. */
SHA384(1 << 18),
/** SHA-512 hash. */
SHA512(1 << 19),
/** EDON-R 256. */
EDONR256(1 << 20),
/** EDON-R 512. */
EDONR512(1 << 21),
/** SHA3-224 hash. */
SHA3_224(1 << 22),
/** SHA3-256 hash. */
SHA3_256(1 << 23),
/** SHA3-384 hash. */
SHA3_384(1 << 24),
/** SHA3-512 hash. */
SHA3_512(1 << 25),
/** CRC32C checksum. */
CRC32C(1 << 26),
/** Snefru-128 hash. */
SNEFRU128(1 << 27),
/** Snefru-256 hash. */
SNEFRU256(1 << 28),
/** BLAKE2s hash. */
BLAKE2S(1 << 29),
/** BLAKE2b hash. */
BLAKE2B(1 << 30);
/** hash_id for the native API */
private int hashId;
/**
* Construct HashType for specified native hash_id
* @param hashId hash identifier for native API
*/
private HashType(int hashId) {
this.hashId = hashId;
}
/**
* Returns hash_id for the native API.
* @return hash identifier
*/
int hashId() {
return hashId;
}
/**
* Returns lowest HashType
for given id mask.
* Used by RHash.getDigest()
.
* @param flags mask of hash identifiers
* @return HashType
object or null
* if no HashType
for given mask exists
*/
static HashType forHashFlags(int flags) {
if (flags == 0) return null;
int lowest = 0;
while ((flags % 2) == 0) {
flags >>>= 1;
lowest++;
}
for (HashType t : HashType.values()) {
if (t.hashId == (1 << lowest)) return t;
}
return null;
}
/**
* Returns size of binary digest for this type.
* @return size of binary digest, in bytes
*/
public int getDigestSize() {
return Bindings.rhash_get_digest_size(hashId);
}
}
rhash-1.4.6/bindings/java/src/org/sf/rhash/Digest.java 0000664 0000000 0000000 00000007742 14703622112 021232 0 ustar root root /*
* This file is a part of Java Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
package org.sf.rhash;
/**
* Message digest.
*/
public final class Digest {
static final int RAW = 0x1;
static final int HEX = 0x2;
static final int BASE32 = 0x3;
static final int BASE64 = 0x4;
static final int UPPERCASE = 0x8;
static final int REVERSE = 0x10;
private final HashType type;
/** Pointer to native structure. */
private final long digest_ptr;
/**
* Creates new Digest
.
* @param ptr pointer to the native object
* @param type hash type
*/
Digest(long ptr, HashType type) {
this.digest_ptr = ptr;
this.type = type;
}
/**
* Returns type of hashing algorithm that produced
* this digest.
*
* @return type of hashing algorithm
*/
public HashType hashType() {
return type;
}
/**
* Returns value of this digest as raw bytes.
* This method allocates new byte array, modifying it
* has no effect on this Digest
.
*
* @return value of this digest as raw bytes
* @see #hex()
* @see #base32()
* @see #base64()
*/
public byte[] raw() {
return Bindings.rhash_print_bytes(digest_ptr, RAW);
}
/**
* Returns value of this digest as hexadecimal string.
*
* @return value of the digest as hexadecimal string
* @see #raw()
* @see #base32()
* @see #base64()
*/
public String hex() {
return new String(Bindings.rhash_print_bytes(digest_ptr, HEX));
}
/**
* Returns value of this digest as base32 string.
*
* @return value of the digest as base32 string
* @see #raw()
* @see #hex()
* @see #base64()
*/
public String base32() {
return new String(Bindings.rhash_print_bytes(digest_ptr, BASE32));
}
/**
* Returns value of this digest as base64 string.
*
* @return value of the digest as base64 string
* @see #raw()
* @see #hex()
* @see #base32()
*/
public String base64() {
return new String(Bindings.rhash_print_bytes(digest_ptr, BASE64));
}
/**
* Called by garbage collector to free native resources.
*/
@Override
protected void finalize() {
Bindings.freeDigest(digest_ptr);
}
/**
* Returns string representation of this object.
* If default output for hashing algorithm is base32 then
* returned value is the same as if base32()
* method was called; otherwise value is the same as returned
* by hex()
method.
*
* @return string representation of this object
* @see #base32()
* @see #hex()
*/
@Override
public String toString() {
return (Bindings.rhash_is_base32(type.hashId())) ? base32() : hex();
}
/**
* Tests whether this object equals to another one
* @param obj object to compare to
* @return
* true
if obj
is Digest
* instance with the same HashType
and value;
* otherwise false
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Digest)) return false;
final Digest other = (Digest)obj;
if (!this.hashType().equals(other.hashType())) return false;
if (this.digest_ptr == other.digest_ptr) return true;
return Bindings.compareDigests(this.digest_ptr, other.digest_ptr);
}
/**
* Returns hash code for this object.
* @return hash code for the object
*/
@Override
public int hashCode() {
return Bindings.hashcodeForDigest(digest_ptr);
}
}
rhash-1.4.6/bindings/java/src/org/sf/rhash/Bindings.java 0000664 0000000 0000000 00000010413 14703622112 021535 0 ustar root root /*
* This file is a part of Java Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
package org.sf.rhash;
/**
* Glue to the native API.
*/
final class Bindings {
/** This class is not instantiable. */
private Bindings() { }
/**
* Initializes library.
*/
static native void rhash_library_init();
/**
* Returns the number of supported hash algorithms.
*/
static native int rhash_count();
/**
* Computes a hash of the given data.
*
* @param hash_id id of hash function
* @param data the data to process
* @param ofs offset in data array from which to start processing
* @param len data length
* @return pointer to the native digest object
*/
static native long rhash_msg(int hash_id, byte[] data, int ofs, int len);
/**
* Prints text representation of a given digest.
*
* @param rhash pointer to native digest object
* @param flags output flags
* @return text representation as byte array
*/
static native byte[] rhash_print_bytes(long rhash, int flags);
/**
* Returns magnet link for given hash context and hashing algorithms.
*
* @param rhash pointer to native digest object
* @param filename the name of the file to incorporate in magnet
* @param flags mask of hash_id values
* @return magnet string
*/
static native String rhash_print_magnet(long rhash, String filename, int flags);
/**
* Tests whether given default hash algorithm output is base32.
* @param hash_id id of hash function
* @return true
if default output for hash algorithm is base32,
* false
otherwise
*/
static native boolean rhash_is_base32(int hash_id);
/**
* Returns size of binary message digest.
* @param hash_id id of hash function
* @return size of message digest
*/
static native int rhash_get_digest_size(int hash_id);
/**
* Creates new hash context.
* @param flags mask of hash_id values
* @return pointer to the native hash context
*/
static native long rhash_init(int flags);
/**
* Updates hash context with given data.
* @param rhash pointer to native hash context
* @param data data to process
* @param ofs index of the first byte to process
* @param len count of bytes to process
*/
static native void rhash_update(long rhash, byte[] data, int ofs, int len);
/**
* Finalizes hash context.
* @param rhash pointer to native hash context
*/
static native void rhash_final(long rhash);
/**
* Resets hash context.
* @param rhash pointer to native hash context
*/
static native void rhash_reset(long rhash);
/**
* Generates message digest for given context and hash_id.
* @param rhash pointer to native hash context
* @param hash_id id of hashing algorithm
* @return pointer to native digest
*/
static native long rhash_print(long rhash, int hash_id);
/**
* Frees hash context.
* @param rhash pointer to native hash context
*/
static native void rhash_free(long rhash);
/**
* Compares two native hash objects.
* @param hash1 pointer to first object
* @param hash2 pointer to second object
* @return true
if objects are the same,
* false
otherwise
*/
static native boolean compareDigests(long hash1, long hash2);
/**
* Computes hashcode for native digest object.
* @param hash pointer to first object
* @return hash code for the object
*/
static native int hashcodeForDigest(long hash);
/**
* Frees previously created native digest object.
*/
static native void freeDigest(long hash);
static {
System.loadLibrary("rhash-jni");
rhash_library_init();
}
}
rhash-1.4.6/bindings/java/src/org/sf/rhash/RHash.java 0000664 0000000 0000000 00000034151 14703622112 021012 0 ustar root root /*
* This file is a part of Java Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
package org.sf.rhash;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Set;
/**
* Incremental hasher.
* This class allows you to do incremental hashing for set
* of hashing algorithms.
*
* To do hashing RHash
instance is first created
* and then filled with message chunks using update()
* methods. Finally, finish()
should be called to end
* all calculations and generate digests, which then can be obtained
* with getDigest()
method. Note, that trying to update
* finished RHash
has no effect other than throwing
* IllegalStateException
though you can reuse this class
* by calling reset()
method, returning it to the state
* which was immediately after creating.
*
* To quickly produce message digest for a single message/file
* and a single algorithm you may use convenience methods
* RHash.computeHash()
.
*
* This class is thread safe.
*
*/
public final class RHash {
/* == EXCEPTION MESSAGES == */
static private final String ERR_FINISHED = "RHash is finished, data update is not possible";
static private final String ERR_NOHASH = "No HashTypes specified";
static private final String ERR_UNFINISHED = "RHash should be finished before generating Digest";
static private final String ERR_WRONGTYPE = "RHash was not created to generate Digest for ";
/**
* Computes hash of given range in data.
* This method calculates message digest for byte subsequence
* in array data
starting from data[ofs]
* and ending at data[ofs+len-1]
.
*
* @param type type of hash algorithm
* @param data the bytes to process
* @param ofs index of the first byte in array to process
* @param len count of bytes to process
* @return message digest for specified subarray
* @throws NullPointerException
* if either type
or data
* is null
* @throws IndexOutOfBoundsException
* if ofs < 0
, len < 0
or
* ofs+len > data.length
*/
static public Digest computeHash(HashType type, byte[] data, int ofs, int len) {
if (type == null || data == null) {
throw new NullPointerException();
}
if (ofs < 0 || len < 0 || ofs+len > data.length) {
throw new IndexOutOfBoundsException();
}
return new Digest(Bindings.rhash_msg(type.hashId(), data, ofs, len), type);
}
/**
* Computes hash of given data.
*
* @param type type of hash algorithm
* @param data the bytes to process
* @return message digest for specified array
* @throws NullPointerException
* if either type
or data
* is null
*/
static public Digest computeHash(HashType type, byte[] data) {
return computeHash(type, data, 0, data.length);
}
/**
* Computes hash of given string.
* String is encoded into a sequence of bytes
* using the specified charset.
*
* @param type type of hash algorithm
* @param str the string to process
* @param encoding encoding to use
* @return message digest for specified string
* @throws NullPointerException if any of arguments is null
* @throws UnsupportedEncodingException if specified encoding is not supported
*/
static public Digest computeHash(HashType type, String str, String encoding)
throws UnsupportedEncodingException {
if (type == null || str == null || encoding == null) {
throw new NullPointerException();
}
return computeHash(type, str.getBytes(encoding));
}
/**
* Computes hash of given string.
* String is encoded into a sequence of bytes using the
* default platform encoding.
*
* @param type type of hash algorithm
* @param str the string to process
* @return message digest for specified string
* @throws NullPointerException if any of arguments is null
*/
static public Digest computeHash(HashType type, String str) {
if (type == null || str == null) throw new NullPointerException();
return computeHash(type, str.getBytes());
}
/**
* Computes hash of given string.
* @param type type of hash algorithm
* @param file the file to process
* @return data hash
* @throws NullPointerException if any of arguments is null
* @throws IOException
* if an I/O error occurs while hashing
*/
static public Digest computeHash(HashType type, File file) throws IOException {
if (type == null || file == null) {
throw new NullPointerException();
}
RHash hasher = new RHash(type);
hasher.update(file).finish();
return hasher.getDigest();
}
/**
* Produces magnet link for specified file using specified hash functions.
*
* @param filename the file to generate magnet for
* @param types types of hashing algorithms
*/
static public String getMagnetFor(String filename, HashType... types) throws IOException {
RHash hasher = new RHash(types);
hasher.update(new File(filename)).finish();
return hasher.getMagnet(filename);
}
/**
* Produces magnet link for specified file using specified hash functions.
*
* @param filename the file to generate magnet for
* @param types set of hashing types
*/
static public String getMagnetFor(String filename, Set types) throws IOException {
RHash hasher = new RHash(types);
hasher.update(new File(filename)).finish();
return hasher.getMagnet(filename);
}
/** Indicates whether this RHash
is finished. */
private boolean finished = false;
/** Mask of hash_id values. */
private final int hash_flags;
/** Pointer to the native hash context. */
private final long context_ptr;
/** Default hash type used in getDigest()
. */
private final HashType deftype;
/**
* Creates new RHash
to compute
* message digests for given types.
* @param types types of hashing algorithms
* @throws NullPointerException
* if any of arguments is null
* @throws IllegalArgumentException
* if zero hash types specified
*/
public RHash(HashType... types) {
if (types.length == 0) {
throw new IllegalArgumentException(ERR_NOHASH);
}
int flags = 0;
HashType def = types[0];
for (HashType t : types) {
flags |= t.hashId();
if (def.compareTo(t) > 0) def = t;
}
this.deftype = def;
this.hash_flags = flags;
this.context_ptr = Bindings.rhash_init(flags);
}
/**
* Creates new RHash
to compute
* message digests for given types.
* @param types set of hashing types
* @throws NullPointerException
* if argument is null
* @throws IllegalArgumentException
* if argument is empty set
*/
public RHash(Set types) {
if (types.isEmpty()) {
throw new IllegalArgumentException(ERR_NOHASH);
}
int flags = 0;
HashType def = null;
for (HashType t : types) {
flags |= t.hashId();
if (def == null || def.compareTo(t) > 0) def = t;
}
this.deftype = def;
this.hash_flags = flags;
this.context_ptr = Bindings.rhash_init(flags);
}
/**
* Updates this RHash
with new data chunk.
* This method hashes bytes from data[ofs]
* through data[ofs+len-1]
.
*
* @param data data to be hashed
* @param ofs index of the first byte to hash
* @param len number of bytes to hash
* @return this object
* @throws NullPointerException
* if data
is null
* @throws IndexOutOfBoundsException
* if ofs < 0
, len < 0
or
* ofs+len > data.length
* @throws IllegalStateException
* if finish()
was called and there were no
* subsequent calls of reset()
*/
public synchronized RHash update(byte[] data, int ofs, int len) {
if (finished) {
throw new IllegalStateException(ERR_FINISHED);
}
if (ofs < 0 || len < 0 || ofs+len > data.length) {
throw new IndexOutOfBoundsException();
}
Bindings.rhash_update(context_ptr, data, ofs, len);
return this;
}
/**
* Updates this RHash
with new data chunk.
* This method has the same effect as
* update(data, 0, data.length)
*
* @param data data to be hashed
* @return this object
* @throws NullPointerException
* if data
is null
* @throws IllegalStateException
* if finish()
was called and there were no
* subsequent calls of reset()
*/
public RHash update(byte[] data) {
return update(data, 0, data.length);
}
/**
* Updates this RHash
with new data chunk.
* String is encoded into a sequence of bytes using the
* default platform encoding.
*
* @param str string to be hashed
* @return this object
* @throws NullPointerException
* if str
is null
* @throws IllegalStateException
* if finish()
was called and there were no
* subsequent calls of reset()
*/
public RHash update(String str) {
return update(str.getBytes());
}
/**
* Updates this RHash
with data from given file.
*
* @param file file to be hashed
* @return this object
* @throws IOException if an I/O error occurs
* @throws NullPointerException
* if file
is null
* @throws IllegalStateException
* if finish()
was called and there were no
* subsequent calls of reset()
*/
public synchronized RHash update(File file) throws IOException {
if (finished) {
throw new IllegalStateException(ERR_FINISHED);
}
InputStream in = new FileInputStream(file);
byte[] buf = new byte[8192]; //shouldn't we avoid magic numbers?
int len = in.read(buf);
while (len > 0) {
this.update(buf, 0, len);
len = in.read(buf);
}
in.close();
return this;
}
/**
* Finishes calculation of hash codes.
* Does nothing if RHash
is already finished.
*/
public synchronized void finish() {
if (!finished) {
Bindings.rhash_final(context_ptr);
finished = true;
}
}
/**
* Resets this RHash
to initial state.
* The RHash
becomes available to process
* new data chunks. Note, that this method returns
* RHash
to the state after creating the
* object, NOT the state when hashing continues.
* Therefore, all previously calculated message digests are lost
* and process starts from the very beginning.
*/
public synchronized void reset() {
Bindings.rhash_reset(context_ptr);
finished = false;
}
/**
* Tests whether this RHash
is finished or not.
* @return
* false
if this RHash
is ready to
* receive new data for hashing;
* true
if hash calculations are finished
*/
public boolean isFinished() {
return finished;
}
/**
* Returns digest for given hash type.
*
* @param type hash type
* @return Digest
for processed data
* @throws NullPointerException
* if type
is null
* @throws IllegalStateException
* if this RHash
is not finished
* @throws IllegalArgumentException
* if this RHash
was not created to calculate
* hash for specified algorithm
*/
public Digest getDigest(HashType type) {
if (type == null) {
throw new NullPointerException();
}
if (!finished) {
throw new IllegalStateException(ERR_UNFINISHED);
}
if ((hash_flags & type.hashId()) == 0) {
throw new IllegalArgumentException(ERR_WRONGTYPE+type);
}
return new Digest(Bindings.rhash_print(context_ptr, type.hashId()), type);
}
/**
* Returns digest for processed data.
* If more than one hashing type was passed to the
* RHash
constructor, then the least
* hash type (in the order induced by
* {@link Enum#compareTo(Enum) compareTo()}) is used.
*
* @return Digest
for processed data
* @throws IllegalStateException
* if this RHash
is not finished
*/
public Digest getDigest() {
return getDigest(deftype);
}
/**
* Returns magnet link that includes filename
* and message digests for the specified hash functions.
* Message digests only for computed hash functions are included into the link.
*
* @param filename file name to include into the magnet link, can be null
* @return magnet link
* @throws IllegalStateException
* if this RHash
is not finished
*/
public String getMagnet(String filename, HashType... types) {
if (!finished) {
throw new IllegalStateException(ERR_UNFINISHED);
}
int flags = 0;
for (HashType t : types) {
flags |= t.hashId();
}
return Bindings.rhash_print_magnet(context_ptr, filename, flags);
}
/**
* Returns magnet link that includes filename
* and all computed message digests.
*
* @param filename file name to include into the magnet link, can be null
* @return magnet link
* @throws IllegalStateException
* if this RHash
is not finished
*/
public String getMagnet(String filename) {
if (!finished) {
throw new IllegalStateException(ERR_UNFINISHED);
}
return Bindings.rhash_print_magnet(context_ptr, filename, hash_flags);
}
/**
* Called by garbage collector to free native resources.
*/
@Override
protected void finalize() {
Bindings.rhash_free(context_ptr);
}
}
rhash-1.4.6/bindings/java/src/org/sf/rhash/package-info.java 0000664 0000000 0000000 00000005300 14703622112 022323 0 ustar root root /*
* This file is a part of Java Bindings for LibRHash
*
* Copyright (c) 2011, Sergey Basalaev
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* Java bindings for LibRHash.
* LibRHash is a library for computing message digests and magnet links
* for various hash functions. List of all supported hash functions can be
* found in {@link org.sf.rhash.HashType} class description.
*
* In its simplest usage to calculate a hash for message or file
* you just need to use one of RHash.computeHash()
* methods:
*
* RHash.computeHash("Hello, world!");
* RHash.computeHash(new byte[] { 0, 1, 2, 3});
* RHash.computeHash(new File("SomeFile.txt"));
* These methods return value of type Digest
which is
* a message digest. To convert Digest
in human readable
* format you might use one of methods
* {@link org.sf.rhash.Digest#hex() hex()},
* {@link org.sf.rhash.Digest#base32() base32()},
* {@link org.sf.rhash.Digest#base64() base64()} or
* {@link org.sf.rhash.Digest#raw() raw()}.
*
* Next, RHash
allows you to do incremental hashing,
* processing data given in portions like it was one big byte sequence.
* To do this you first need to create RHash
instance
* with a set of needed hash algorithms and then to fill it using
* update()
:
*
* RHash hasher = new RHash(HashType.MD5);
* hasher.update("Foo").update(new File("Bar.zip")).finish();
* Digest result = hasher.getDigest();
* Method finish()
should be called before obtaining
* digest to end all calculations and generate result.
*
* You can setup RHash
to calculate several digests
* at once, passing corresponding HashType
s in
* constructor. Specifically, you can calculate all of them creating
* RHash
like
*
* new Rhash(EnumSet.allOf(HashType.class));
* In this case to obtain digest for particular hash type use
* {@link org.sf.rhash.RHash#getDigest(HashType) }
* method.
*
*/
package org.sf.rhash;
rhash-1.4.6/bindings/java/test/ 0000755 0000000 0000000 00000000000 15010731530 015015 5 ustar root root rhash-1.4.6/bindings/java/test/RHashTest.java 0000664 0000000 0000000 00000011365 14703622112 017540 0 ustar root root import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.EnumSet;
import org.sf.rhash.*;
import static org.sf.rhash.HashType.*;
import org.junit.Test;
import junit.framework.JUnit4TestAdapter;
import static junit.framework.TestCase.*;
public class RHashTest {
@Test
public void testAllHashes() {
RHash r = new RHash(EnumSet.allOf(HashType.class));
r.update("a").finish();
assertEquals("e8b7be43", r.getDigest(CRC32).toString());
assertEquals("c1d04330", r.getDigest(CRC32C).toString());
assertEquals("bde52cb31de33e46245e05fbdbd6fb24", r.getDigest(MD4).toString());
assertEquals("0cc175b9c0f1b6a831c399e269772661", r.getDigest(MD5).toString());
assertEquals("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", r.getDigest(SHA1).toString());
assertEquals("77befbef2e7ef8ab2ec8f93bf587a7fc613e247f5f247809", r.getDigest(TIGER).toString());
assertEquals("czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y", r.getDigest(TTH).toString());
assertEquals(40, r.getDigest(BTIH).toString().length());
assertEquals("bde52cb31de33e46245e05fbdbd6fb24", r.getDigest(ED2K).toString());
assertEquals("q336in72uwt7zyk5dxolt2xk5i3xmz5y", r.getDigest(AICH).toString());
assertEquals("8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a", r.getDigest(WHIRLPOOL).toString());
assertEquals("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", r.getDigest(RIPEMD160).toString());
assertEquals("d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd", r.getDigest(GOST94).toString());
assertEquals("e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", r.getDigest(GOST94_CRYPTOPRO).toString());
assertEquals("4872bcbc4cd0f0a9dc7c2f7045e5b43b6c830db8", r.getDigest(HAS160).toString());
assertEquals("ba31099b9cc84ec2a671e9313572378920a705b363b031a1cb4fc03e01ce8df3", r.getDigest(GOST12_256).toString());
assertEquals("8b2a40ecab7b7496bc4cc0f773595452baf658849b495acc3ba017206810efb00420ccd73fb3297e0f7890941b84ac4a8bc27e3c95e1f97c094609e2136abb7e", r.getDigest(GOST12_512).toString());
assertEquals("abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", r.getDigest(SHA224).toString());
assertEquals("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", r.getDigest(SHA256).toString());
assertEquals("54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", r.getDigest(SHA384).toString());
assertEquals("1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", r.getDigest(SHA512).toString());
assertEquals("943aa9225a2cf154ec2e4dd81237720ba538ca8df2fd83c0b893c5d265f353a0", r.getDigest(EDONR256).toString());
assertEquals("b59ec44f7beef8a04ceed38a973d77c65e22e9458d5f67b497948da34986c093b5efc5483fbee55f2f740fcad31f18d80db44bb6b8843e7fd599188e7c07233b", r.getDigest(EDONR512).toString());
assertEquals("9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b", r.getDigest(SHA3_224).toString());
assertEquals("80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b", r.getDigest(SHA3_256).toString());
assertEquals("1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9", r.getDigest(SHA3_384).toString());
assertEquals("697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a", r.getDigest(SHA3_512).toString());
assertEquals("bf5ce540ae51bc50399f96746c5a15bd", r.getDigest(SNEFRU128).toString());
assertEquals("45161589ac317be0ceba70db2573ddda6e668a31984b39bf65e4b664b584c63d", r.getDigest(SNEFRU256).toString());
assertEquals("4a0d129873403037c2cd9b9048203687f6233fb6738956e0349bd4320fec3e90", r.getDigest(BLAKE2S).toString());
assertEquals("333fcb4ee1aa7c115355ec66ceac917c8bfd815bf7587d325aec1864edd24e34d5abe2c6b1b5ee3face62fed78dbef802f2a85cb91d455a8f5249d330853cb3c", r.getDigest(BLAKE2B).toString());
r.reset();
r.finish();
assertEquals("d41d8cd98f00b204e9800998ecf8427e", r.getDigest(MD5).toString()); // MD5 of ""
}
@Test
public void testMagnet() {
RHash r = new RHash(MD5, TTH);
r.update("abc").finish();
assertEquals("magnet:?xl=3&dn=file.txt&xt=urn:md5:900150983cd24fb0d6963f7d28e17f72&xt=urn:tree:tiger:asd4ujseh5m47pdyb46kbtsqtsgdklbhyxomuia", r.getMagnet("file.txt"));
}
@Test
public void testUpdateFile() throws IOException {
File f = new File("java_test_input_123.txt");
PrintStream out = new PrintStream(f);
out.println("\0\1\2");
out.flush();
out.close();
assertEquals("e3869ec477661fad6b9fc25914bb2eee5455b483", RHash.computeHash(SHA1, f).toString());
f.delete();
}
public static junit.framework.Test suite(){
return new JUnit4TestAdapter(RHashTest.class);
}
}
rhash-1.4.6/bindings/ruby/ 0000755 0000000 0000000 00000000000 15010731530 014076 5 ustar root root rhash-1.4.6/bindings/ruby/test_rhash.rb 0000664 0000000 0000000 00000011045 14703622112 016575 0 ustar root root #!/usr/bin/ruby
require "test/unit"
require "rhash"
class TestRHash < Test::Unit::TestCase
def test_all_hashes
r = RHash.new(RHash::ALL)
r.update("a").finish()
assert_equal("e8b7be43", r.to_s(RHash::CRC32))
assert_equal("c1d04330", r.to_s(RHash::CRC32C))
assert_equal("bde52cb31de33e46245e05fbdbd6fb24", r.to_s(RHash::MD4))
assert_equal("0cc175b9c0f1b6a831c399e269772661", r.to_s(RHash::MD5))
assert_equal("86f7e437faa5a7fce15d1ddcb9eaeaea377667b8", r.to_s(RHash::SHA1))
assert_equal("77befbef2e7ef8ab2ec8f93bf587a7fc613e247f5f247809", r.to_s(RHash::TIGER))
assert_equal("czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y", r.to_s(RHash::TTH))
assert_equal(40, r.to_s(RHash::BTIH).length())
assert_equal("bde52cb31de33e46245e05fbdbd6fb24", r.to_s(RHash::ED2K))
assert_equal("q336in72uwt7zyk5dxolt2xk5i3xmz5y", r.to_s(RHash::AICH))
assert_equal("8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a", r.to_s(RHash::WHIRLPOOL))
assert_equal("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", r.to_s(RHash::RIPEMD160))
assert_equal("d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd", r.to_s(RHash::GOST94))
assert_equal("e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", r.to_s(RHash::GOST94_CRYPTOPRO))
assert_equal("ba31099b9cc84ec2a671e9313572378920a705b363b031a1cb4fc03e01ce8df3", r.to_s(RHash::GOST12_256))
assert_equal("8b2a40ecab7b7496bc4cc0f773595452baf658849b495acc3ba017206810efb00420ccd73fb3297e0f7890941b84ac4a8bc27e3c95e1f97c094609e2136abb7e", r.to_s(RHash::GOST12_512))
assert_equal("4872bcbc4cd0f0a9dc7c2f7045e5b43b6c830db8", r.to_s(RHash::HAS160))
assert_equal("bf5ce540ae51bc50399f96746c5a15bd", r.to_s(RHash::SNEFRU128))
assert_equal("45161589ac317be0ceba70db2573ddda6e668a31984b39bf65e4b664b584c63d", r.to_s(RHash::SNEFRU256))
assert_equal("abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5", r.to_s(RHash::SHA224))
assert_equal("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb", r.to_s(RHash::SHA256))
assert_equal("54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31", r.to_s(RHash::SHA384))
assert_equal("1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75", r.to_s(RHash::SHA512))
assert_equal("943aa9225a2cf154ec2e4dd81237720ba538ca8df2fd83c0b893c5d265f353a0", r.to_s(RHash::EDONR256))
assert_equal("b59ec44f7beef8a04ceed38a973d77c65e22e9458d5f67b497948da34986c093b5efc5483fbee55f2f740fcad31f18d80db44bb6b8843e7fd599188e7c07233b", r.to_s(RHash::EDONR512))
assert_equal("9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b", r.to_s(RHash::SHA3_224))
assert_equal("80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b", r.to_s(RHash::SHA3_256))
assert_equal("1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9", r.to_s(RHash::SHA3_384))
assert_equal("697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a", r.to_s(RHash::SHA3_512))
assert_equal("4a0d129873403037c2cd9b9048203687f6233fb6738956e0349bd4320fec3e90", r.to_s(RHash::BLAKE2S))
assert_equal("333fcb4ee1aa7c115355ec66ceac917c8bfd815bf7587d325aec1864edd24e34d5abe2c6b1b5ee3face62fed78dbef802f2a85cb91d455a8f5249d330853cb3c", r.to_s(RHash::BLAKE2B))
assert_equal("d41d8cd98f00b204e9800998ecf8427e", r.reset().finish().to_s(RHash::MD5)) # MD5( "" )
end
def test_shift_operator
r = RHash.new(RHash::MD5)
r << "a" << "bc"
assert_equal("900150983cd24fb0d6963f7d28e17f72", r.finish().to_s()) # MD5( "abc" )
end
def test_output
r = RHash.new(RHash::MD5, RHash::TTH)
r.finish()
assert_equal("5d9ed00a030e638bdb753a6a24fb900e5a63b8e73e6c25b6", r.to_hex(RHash::TTH))
assert_equal("2qoyzwmpaczaj2mabgmoz6ccpy", r.to_base32(RHash::MD5))
assert_equal("1B2M2Y8AsgTpgAmY7PhCfg==", r.to_base64(RHash::MD5))
assert_equal(["d41d8cd98f00b204e9800998ecf8427e"].pack('H*'), r.to_raw(RHash::MD5))
end
def test_magnet
r = RHash.new(RHash::MD5, RHash::TTH)
r.update("abc").finish()
assert_equal("magnet:?xl=3&dn=file.txt&xt=urn:md5:900150983cd24fb0d6963f7d28e17f72&xt=urn:tree:tiger:asd4ujseh5m47pdyb46kbtsqtsgdklbhyxomuia", r.magnet("file.txt"))
end
def test_update_file
path = "ruby_test_input_123.txt"
File.open(path, 'wb') { |f| f.write("\0\1\2\n") }
r = RHash.new(RHash::SHA1)
r.update_file(path).finish()
assert_equal("e3869ec477661fad6b9fc25914bb2eee5455b483", r.to_s(RHash::SHA1))
File.delete(path)
end
end
rhash-1.4.6/bindings/ruby/rhash.c 0000664 0000000 0000000 00000026743 14703622112 015370 0 ustar root root /*
* Ruby Bindings for Librhash
*
* Copyright (c) 2011, Sergey Basalaev and
* Aleksey Kravchenko
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include
#include
/* RHash class. */
static VALUE cRHash;
static void rh_free(rhash ctx) {
rhash_free(ctx);
}
/**
* call-seq:
* rhash.update(data) -> RHash
* rhash << data -> RHash
*
* Updates this RHash
with new data chunk.
*/
static VALUE rh_update(VALUE self, VALUE msg) {
rhash ctx;
Data_Get_Struct(self, struct rhash_context, ctx);
if (TYPE(msg) != T_STRING) {
msg = rb_obj_as_string(msg); /* convert to string */
}
rhash_update(ctx, RSTRING_PTR(msg), RSTRING_LEN(msg));
return self;
}
/* declaring non-static method to fix a warning on an unused function */
VALUE rh_update_file(VALUE self, VALUE file);
/**
* call-seq:
* rhash.update_file(filename) -> RHash
*
* Updates this RHash
with data from given file.
*/
VALUE rh_update_file(VALUE self, VALUE file) {
// this function is actually implemented in pure Ruby below
// this allows us to handle files in platform-independent way
return self;
}
/**
* call-seq:
* rhash.finish
*
* Finishes calculation for all data buffered by
* update
and stops calculation of message digests.
*/
static VALUE rh_finish(VALUE self) {
rhash ctx;
Data_Get_Struct(self, struct rhash_context, ctx);
rhash_final(ctx, NULL);
return self;
}
/**
* call-seq:
* rhash.reset
*
* Resets this RHash to initial state.
* The RHash becomes available to process
* new data chunks.
*/
static VALUE rh_reset(VALUE self) {
rhash ctx;
Data_Get_Struct(self, struct rhash_context, ctx);
rhash_reset(ctx);
return self;
}
static VALUE rh_print(VALUE self, VALUE type, int flags) {
int len;
char buf[130];
rhash ctx;
Data_Get_Struct(self, struct rhash_context, ctx);
len = rhash_print(buf, ctx, type == Qnil ? 0 : FIX2INT(type), flags);
return rb_str_new(buf, len);
}
/**
* call-seq:
* rhash.to_raw(id)
* rhash.to_raw
*
* Returns value of the RHash digest as raw bytes.
* If RHash was created with a single hashing algorithm
* then argument may be omitted.
*/
static VALUE rh_to_raw(int argc, VALUE* argv, VALUE self) {
VALUE type;
rb_scan_args(argc, argv, "01", &type);
return rh_print(self, type, RHPR_RAW);
}
/**
* call-seq:
* rhash.to_hex(id)
* rhash.to_hex
*
* Returns value of the RHash digest as hexadecimal string.
* If RHash was created with a single hashing algorithm
* then argument may be omitted.
*/
static VALUE rh_to_hex(int argc, VALUE* argv, VALUE self) {
VALUE type;
rb_scan_args(argc, argv, "01", &type);
return rh_print(self, type, RHPR_HEX);
}
/**
* call-seq:
* rhash.to_base32(id)
* rhash.to_base32
*
* Returns value of the RHash digest as base32 string.
* If RHash was created with a single hashing algorithm
* then argument may be omitted.
*/
static VALUE rh_to_base32(int argc, VALUE* argv, VALUE self) {
VALUE type;
rb_scan_args(argc, argv, "01", &type);
return rh_print(self, type, RHPR_BASE32);
}
/**
* call-seq:
* rhash.magnet(filepath)
* rhash.magnet
*
* Returns magnet link with all message digests computed by
* the RHash object.
* if filepath is specified, then it is url-encoded
* and included into the resulting magnet link.
*/
static VALUE rh_magnet(int argc, VALUE* argv, VALUE self) {
VALUE value;
const char* filepath = 0;
char* buf;
size_t buf_size;
rhash ctx;
Data_Get_Struct(self, struct rhash_context, ctx);
rb_scan_args(argc, argv, "01", &value);
if (value != Qnil) {
if (TYPE(value) != T_STRING) value = rb_obj_as_string(value);
filepath = RSTRING_PTR(value);
}
buf_size = rhash_print_magnet(0, filepath, ctx, RHASH_ALL_HASHES, RHPR_FILESIZE);
buf = (char*)malloc(buf_size);
if (!buf) return Qnil;
rhash_print_magnet(buf, filepath, ctx, RHASH_ALL_HASHES, RHPR_FILESIZE);
value = rb_str_new2(buf);
free(buf);
return value;
}
/**
* call-seq:
* rhash.to_base64(id)
* rhash.to_base64
*
* Returns value of the RHash digest as base64 string.
* If RHash was created with a single hashing algorithm
* then argument may be omitted.
*/
static VALUE rh_to_base64(int argc, VALUE* argv, VALUE self) {
VALUE type;
rb_scan_args(argc, argv, "01", &type);
return rh_print(self, type, RHPR_BASE64);
}
/**
* call-seq:
* rhash.to_s(id)
* rhash.to_s
*
* Returns value of the RHash digest for given algorithm
* as string in default format. If RHash was created with
* a single hashing algorithm then argument may be omitted.
*/
static VALUE rh_to_s(int argc, VALUE* argv, VALUE self) {
VALUE type;
rb_scan_args(argc, argv, "01", &type);
return rh_print(self, type, 0);
}
/**
* call-seq:
* RHash.base32?(id) -> true or false
*
* Returns true if default format for given hash algorithm is
* base32 and false if it is hexadecimal.
*/
static VALUE rh_is_base32(VALUE self, VALUE type) {
return rhash_is_base32(FIX2INT(type)) ? Qtrue : Qfalse;
}
static VALUE rh_init(int argc, VALUE *argv, VALUE self) {
return self;
}
/**
* call-seq:
* RHash.new(id, ...)
*
* Creates RHash object to calculate message digests for given algorithms.
* Parameters should be constants defined in this class.
*/
VALUE rh_new(int argc, VALUE* argv, VALUE clz) {
rhash ctx;
VALUE newobj;
int flags = 0, i;
for (i=0; iRHash object is first created
* for a set of hashing algorithms.
*
* Next, data for hashing is given in chunks with methods
* update
and update_file
. Finally,
* call finish
to end up all remaining calculations.
*
* To receive text represenation of the message digest use one
* of methods to_hex
, to_base32
and
* to_base64
. Binary message digest may be obtained
* with to_raw
. All of these methods accept algorithm
* value as argument. It may be omitted if RHash
was
* created to compute hash for only a single hashing algorithm.
*/
void Init_rhash() {
rhash_library_init();
cRHash = rb_define_class("RHash", rb_cObject);
rb_define_singleton_method(cRHash, "new", rh_new, -1);
rb_define_singleton_method(cRHash, "base32?", rh_is_base32, 1);
rb_define_method(cRHash, "initialize", rh_init, -1);
rb_define_method(cRHash, "update", rh_update, 1);
rb_define_method(cRHash, "<<", rh_update, 1);
rb_define_method(cRHash, "finish", rh_finish, 0);
rb_define_method(cRHash, "reset", rh_reset, 0);
rb_define_method(cRHash, "to_raw", rh_to_raw, -1);
rb_define_method(cRHash, "to_hex", rh_to_hex, -1);
rb_define_method(cRHash, "to_base32", rh_to_base32, -1);
rb_define_method(cRHash, "to_base64", rh_to_base64, -1);
rb_define_method(cRHash, "to_s", rh_to_s, -1);
rb_define_method(cRHash, "magnet", rh_magnet, -1);
rb_eval_string(
"class RHash \n\
def update_file(filename) \n\
f = File.open(filename, 'rb') \n\
while block = f.read(4096) \n\
self.update(block) \n\
end \n\
f.close \n\
self \n\
end \n\
end\n\
\n\
def RHash.hash_for_msg(msg, hash_id)\n\
RHash.new(hash_id).update(msg).finish.to_s\n\
end\n\
\n\
def RHash.hash_for_file(filename, hash_id)\n\
RHash.new(hash_id).update_file(filename).finish.to_s\n\
end\n\
\n\
def RHash.magnet_for_file(filename, *hash_ids)\n\
RHash.new(*hash_ids).update_file(filename).finish.magnet(filename)\n\
end");
/** CRC32 checksum. */
rb_define_const(cRHash, "CRC32", INT2FIX(RHASH_CRC32));
/** CRC32C checksum. */
rb_define_const(cRHash, "CRC32C", INT2FIX(RHASH_CRC32C));
/** MD4 hash. */
rb_define_const(cRHash, "MD4", INT2FIX(RHASH_MD4));
/** MD5 hash. */
rb_define_const(cRHash, "MD5", INT2FIX(RHASH_MD5));
/** SHA-1 hash. */
rb_define_const(cRHash, "SHA1", INT2FIX(RHASH_SHA1));
/** Tiger hash. */
rb_define_const(cRHash, "TIGER", INT2FIX(RHASH_TIGER));
/** Tiger tree hash */
rb_define_const(cRHash, "TTH", INT2FIX(RHASH_TTH));
/** BitTorrent info hash. */
rb_define_const(cRHash, "BTIH", INT2FIX(RHASH_BTIH));
/** EDonkey 2000 hash. */
rb_define_const(cRHash, "ED2K", INT2FIX(RHASH_ED2K));
/** eMule AICH. */
rb_define_const(cRHash, "AICH", INT2FIX(RHASH_AICH));
/** Whirlpool hash. */
rb_define_const(cRHash, "WHIRLPOOL", INT2FIX(RHASH_WHIRLPOOL));
/** RIPEMD-160 hash. */
rb_define_const(cRHash, "RIPEMD160", INT2FIX(RHASH_RIPEMD160));
/** GOST R 34.11-94. */
rb_define_const(cRHash, "GOST94", INT2FIX(RHASH_GOST94));
/** GOST R 34.11-94 - CryptoPro. */
rb_define_const(cRHash, "GOST94_CRYPTOPRO", INT2FIX(RHASH_GOST94_CRYPTOPRO));
/** GOST R 34.11-2012 - 256-bit. */
rb_define_const(cRHash, "GOST12_256", INT2FIX(RHASH_GOST12_256));
/** GOST R 34.11-2012 - 512 bit. */
rb_define_const(cRHash, "GOST12_512", INT2FIX(RHASH_GOST12_512));
/** HAS-160 hash. */
rb_define_const(cRHash, "HAS160", INT2FIX(RHASH_HAS160));
/** SHA-224 hash. */
rb_define_const(cRHash, "SHA224", INT2FIX(RHASH_SHA224));
/** SHA-256 hash. */
rb_define_const(cRHash, "SHA256", INT2FIX(RHASH_SHA256));
/** SHA-384 hash. */
rb_define_const(cRHash, "SHA384", INT2FIX(RHASH_SHA384));
/** SHA-512 hash. */
rb_define_const(cRHash, "SHA512", INT2FIX(RHASH_SHA512));
/** EDON-R 256. */
rb_define_const(cRHash, "EDONR256", INT2FIX(RHASH_EDONR256));
/** EDON-R 512. */
rb_define_const(cRHash, "EDONR512", INT2FIX(RHASH_EDONR512));
/** SHA3-224 hash. */
rb_define_const(cRHash, "SHA3_224", INT2FIX(RHASH_SHA3_224));
/** SHA3-256 hash. */
rb_define_const(cRHash, "SHA3_256", INT2FIX(RHASH_SHA3_256));
/** SHA3-384 hash. */
rb_define_const(cRHash, "SHA3_384", INT2FIX(RHASH_SHA3_384));
/** SHA3-512 hash. */
rb_define_const(cRHash, "SHA3_512", INT2FIX(RHASH_SHA3_512));
/** Snefru-128 hash. */
rb_define_const(cRHash, "SNEFRU128", INT2FIX(RHASH_SNEFRU128));
/** Snefru-256 hash. */
rb_define_const(cRHash, "SNEFRU256", INT2FIX(RHASH_SNEFRU256));
/** BLAKE2s hash. */
rb_define_const(cRHash, "BLAKE2S", INT2FIX(RHASH_BLAKE2S));
/** BLAKE2b hash. */
rb_define_const(cRHash, "BLAKE2B", INT2FIX(RHASH_BLAKE2B));
/** Compute message digests for all available algorithms. */
rb_define_const(cRHash, "ALL", INT2FIX(RHASH_ALL_HASHES));
}
rhash-1.4.6/bindings/ruby/extconf.rb 0000664 0000000 0000000 00000000365 14703622112 016102 0 ustar root root require 'mkmf'
if ENV['LIBRHASH_INC']
$CFLAGS += ' ' + ENV['LIBRHASH_INC']
else
have_header('rhash.h')
end
$LDFLAGS += ' ' + ENV['LIBRHASH_LD'] if ENV['LIBRHASH_LD']
$LDFLAGS += ' -lrhash'
dir_config('rhash')
create_makefile('rhash')
rhash-1.4.6/bindings/perl/ 0000755 0000000 0000000 00000000000 15010731530 014057 5 ustar root root rhash-1.4.6/bindings/perl/Rhash.pm 0000664 0000000 0000000 00000033756 15010476501 015506 0 ustar root root package Crypt::Rhash;
use 5.006001;
use strict;
use warnings;
require Exporter;
our @ISA = (qw(Exporter));
# possible tags for export
our %EXPORT_TAGS = (
Functions => [qw(raw2hex raw2base32 raw2base64)],
Constants => [qw(RHASH_CRC32 RHASH_CRC32C RHASH_MD4 RHASH_MD5
RHASH_SHA1 RHASH_TIGER RHASH_TTH RHASH_BTIH RHASH_ED2K
RHASH_AICH RHASH_WHIRLPOOL RHASH_RIPEMD160 RHASH_GOST94
RHASH_GOST94_CRYPTOPRO RHASH_GOST12_256 RHASH_GOST12_512
RHASH_SHA224 RHASH_SHA256 RHASH_SHA384 RHASH_SHA512
RHASH_SHA3_224 RHASH_SHA3_256 RHASH_SHA3_384 RHASH_SHA3_512
RHASH_BLAKE2S RHASH_BLAKE2B RHASH_EDONR256 RHASH_EDONR512
RHASH_HAS160 RHASH_SNEFRU128 RHASH_SNEFRU256 RHASH_ALL)]
);
Exporter::export_tags( );
Exporter::export_ok_tags( qw(Functions Constants) );
our $VERSION = '1.05';
require XSLoader;
XSLoader::load('Crypt::Rhash', $VERSION);
##############################################################################
# identifiers of hash functions
use constant RHASH_CRC32 => 0x01;
use constant RHASH_MD4 => 0x02;
use constant RHASH_MD5 => 0x04;
use constant RHASH_SHA1 => 0x08;
use constant RHASH_TIGER => 0x10;
use constant RHASH_TTH => 0x20;
use constant RHASH_BTIH => 0x40;
use constant RHASH_ED2K => 0x80;
use constant RHASH_AICH => 0x100;
use constant RHASH_WHIRLPOOL => 0x200;
use constant RHASH_RIPEMD160 => 0x400;
use constant RHASH_GOST94 => 0x800;
use constant RHASH_GOST94_CRYPTOPRO => 0x1000;
use constant RHASH_HAS160 => 0x2000;
use constant RHASH_GOST12_256 => 0x4000;
use constant RHASH_GOST12_512 => 0x8000;
use constant RHASH_SHA224 => 0x10000;
use constant RHASH_SHA256 => 0x20000;
use constant RHASH_SHA384 => 0x40000;
use constant RHASH_SHA512 => 0x80000;
use constant RHASH_EDONR256 => 0x100000;
use constant RHASH_EDONR512 => 0x200000;
use constant RHASH_SHA3_224 => 0x0400000;
use constant RHASH_SHA3_256 => 0x0800000;
use constant RHASH_SHA3_384 => 0x1000000;
use constant RHASH_SHA3_512 => 0x2000000;
use constant RHASH_CRC32C => 0x4000000;
use constant RHASH_SNEFRU128 => 0x8000000;
use constant RHASH_SNEFRU256 => 0x10000000;
use constant RHASH_BLAKE2S => 0x20000000;
use constant RHASH_BLAKE2B => 0x40000000;
use constant RHASH_ALL => 0x7FFFFFFF;
##############################################################################
# Rhash class methods
# Rhash object constructor
sub new($$@)
{
my ($class, @hash_ids) = @_;
# validate @hash_ids to be an array of hash identifiers
scalar(@_) > 0 or die "hash_id not specified\n";
for my $id (@hash_ids) {
if (ref($id) || !scalar($id) || (scalar($id) & RHASH_ALL) != $id) {
die "bad hash_id = " . scalar($id) . " " . ref($id) . "\n";
}
}
# handle legacy initialization by a single bitmask
if (scalar(@hash_ids) == 1 && ($hash_ids[0] & ($hash_ids[0] - 1)) != 0) {
# Split the bit mask into the array of single bits
for (my $mask = shift(@hash_ids); $mask; $mask = $mask & ($mask - 1)) {
push(@hash_ids, $mask & -$mask);
}
}
my $context = rhash_init_multi_wrapper(\@hash_ids) or return undef;
my $self = {
context => $context,
};
return bless $self, $class;
}
# destructor
sub DESTROY($)
{
my $self = shift;
# the 'if' added as workaround for perl 'global destruction' bug
# ($self->{context} can disappear on global destruction)
rhash_free($self->{context}) if $self->{context};
}
sub update($$)
{
my $self = shift;
my $message = shift;
rhash_update($self->{context}, $message);
return $self;
}
sub update_fd($$;$$)
{
my ($self, $fd, $start, $size) = @_;
my $res = 0;
my $num = 0;
binmode($fd);
if(defined($start)) {
seek($fd, scalar($start), 0) or return undef;
}
my $data;
if(defined($size)) {
for(my $left = scalar($size); $left > 0; $left -= 8192) {
($res = read($fd, $data,
($left < 8192 ? $left : 8192))) || last;
rhash_update($self->{context}, $data);
$num += $res;
}
} else {
while( ($res = read($fd, $data, 8192)) ) {
rhash_update($self->{context}, $data);
$num += $res;
}
}
return (defined($res) ? $num : undef); # return undef on read error
}
sub update_file($$;$$)
{
my ($self, $file, $start, $size) = @_;
open(my $fd, "<", $file) or return undef;
my $res = $self->update_fd($fd, $start, $size);
close($fd);
return $res;
}
sub final($)
{
my $self = shift;
rhash_final($self->{context});
return $self;
}
sub reset($)
{
my $self = shift;
rhash_reset($self->{context});
return $self;
}
sub hashed_length($)
{
my $self = shift;
return rhash_get_hashed_length($self->{context});
}
sub hash_id($)
{
my $self = shift;
return rhash_get_hash_id($self->{context});
}
##############################################################################
# Message digest formatting functions
# printing constants
use constant RHPR_DEFAULT => 0x0;
use constant RHPR_RAW => 0x1;
use constant RHPR_HEX => 0x2;
use constant RHPR_BASE32 => 0x3;
use constant RHPR_BASE64 => 0x4;
use constant RHPR_UPPERCASE => 0x8;
use constant RHPR_REVERSE => 0x10;
sub hash($;$$)
{
my $self = shift;
my $hash_id = scalar(shift) || 0;
my $print_flags = scalar(shift) || RHPR_DEFAULT;
return rhash_print_wrapper($self->{context}, $hash_id, $print_flags);
}
sub hash_base32($;$)
{
hash($_[0], $_[1], RHPR_BASE32);
}
sub hash_base64($;$)
{
hash($_[0], $_[1], RHPR_BASE64);
}
sub hash_hex($;$)
{
hash($_[0], $_[1], RHPR_HEX);
}
sub hash_rhex($;$)
{
hash($_[0], $_[1], RHPR_HEX | RHPR_REVERSE);
}
sub hash_raw($;$)
{
hash($_[0], $_[1], RHPR_RAW);
}
sub magnet_link($;$@)
{
my ($self, $filename, @hash_ids) = @_;
my $hash_mask = 0;
if (scalar(@hash_ids)) {
for my $id (@hash_ids) {
if (ref($id) || !scalar($id) || (scalar($id) & RHASH_ALL) != $id) {
die "bad hash_id = " . scalar($id) . " " . ref($id) . "\n";
}
$hash_mask = $hash_mask | scalar($id);
}
} else {
$hash_mask = undef;
}
return rhash_print_magnet_wrapper($self->{context}, $filename, $hash_mask);
}
our $AUTOLOAD;
# report error if a script called unexisting method/field
sub AUTOLOAD
{
my ($self, $field, $type, $pkg) = ($_[0], $AUTOLOAD, undef, __PACKAGE__);
$field =~ s/.*://;
die "function $field does not exist\n" if $field =~ /^(rhash_|raw2)/;
die "no arguments specified to $field()\n" if !@_;
die "the $field() argument is undefined\n" if !defined $self;
($type = ref($self)) && $type eq $pkg || die "the $field() argument is not a $pkg reference\n";
my $text = (exists $self->{$field} ? "is not accessible" : "does not exist");
die "the method $field() $text in the class $pkg\n";
}
# static functions
sub msg($$)
{
my ($hash_id, $msg) = @_;
my $raw = rhash_msg_wrapper($hash_id, $msg); # get a binary message digest
return (is_base32($hash_id) ? raw2base32($raw) : raw2hex($raw));
}
1;
__END__
# Below is Rhash module documentation in the standard POD format
=head1 NAME
Crypt::Rhash - Compute message digests and magnet links
=head1 SYNOPSIS
use Crypt::Rhash;
my $msg = "a message text";
print "MD5 = " . Crypt::Rhash::msg(RHASH_MD5, $msg) . "\n";
or
use Crypt::Rhash;
my $filepath = "/tmp/file.txt";
# Calculate two hash functions simultaneously
my $r = Crypt::Rhash->new(RHASH_SHA1, RHASH_SHA512);
$res = $r->update_file($filepath);
defined($res) or die "failed to read $filepath: $!\n";
print "SHA1 = " . $r->hash(RHASH_SHA1) . "\n";
print "SHA512 = " . $r->hash(RHASH_SHA512) . "\n";
=head1 DESCRIPTION
Crypt::Rhash module is an object-oriented interface to LibRHash library,
allowing simultaneous calculation of several hash functions for a file or a
text message.
Calculated message digest can be obtained in hexadecimal, BASE32, BASE64, raw
binary format or as a magnet link.
=head1 SUPPORTED ALGORITHMS
The module supports the following hash functions:
CRC32, CRC32C, MD4, MD5, SHA1, SHA256, SHA512, SHA3, AICH, ED2K, Tiger,
DC++ TTH, GOST R 34.11-94, GOST R 34.11-2012, BitTorrent BTIH, RIPEMD-160,
HAS-160, BLAKE2s/BLAKE2b, EDON-R 256/512, Whirlpool and Snefru-128/256.
=head1 CONSTRUCTOR
Creates and returns new Crypt::Rhash object.
my $r = Crypt::Rhash->new($hash_id1, $hash_id2, ...);
my $p = new Crypt::Rhash($hash_id1, ...); # alternative way to call the constructor
Constructor accepts the following constants as arguments:
RHASH_CRC32,
RHASH_CRC32C,
RHASH_MD4,
RHASH_MD5,
RHASH_SHA1,
RHASH_TIGER,
RHASH_TTH,
RHASH_BTIH,
RHASH_ED2K,
RHASH_AICH,
RHASH_WHIRLPOOL,
RHASH_RIPEMD160,
RHASH_GOST94,
RHASH_GOST94_CRYPTOPRO,
RHASH_GOST12_256,
RHASH_GOST12_512
RHASH_HAS160,
RHASH_SHA224,
RHASH_SHA256,
RHASH_SHA384,
RHASH_SHA512,
RHASH_SHA3_224,
RHASH_SHA3_256,
RHASH_SHA3_384,
RHASH_SHA3_512,
RHASH_EDONR256,
RHASH_EDONR512,
RHASH_SNEFRU128,
RHASH_SNEFRU256,
RHASH_BLAKE2S,
RHASH_BLAKE2B,
RHASH_ALL
The RHASH_ALL bit mask is bitwise union of all listed above bit-flags.
An object created as Crypt::Rhash->new(RHASH_ALL) calculates all
supported hash functions for the same data.
=head1 COMPUTING MESSAGE DIGESTS
=over
=item $rhash->update( $msg )
Calculates message digests of the $msg string.
The method can be called repeatedly with chunks of the message to be hashed.
It returns the $rhash object itself allowing the following construction:
$rhash = Crypt::Rhash->new(RHASH_MD5)->update( $chunk1 )->update( $chunk2 );
=item $rhash->update_file( $file_path, $start, $size )
=item $rhash->update_fd( $fd, $start, $size )
Calculate a message digest of the file (or its part) specified by $file_path or a file descriptor $fd.
The update_fd method doesn't close the $fd, leaving the file position after the hashed block.
The optional $start and $size specify the block of the file to process. If $start is undefined,
then the file is read from the start. If $size is undefined, then the file is read till the end.
No error is reported if the $size is greater than the number of the unread bytes left in the file.
Returns the number of characters actually read, 0 at the end of file,
or undef if there was an error (in the latter case $! is also set).
use Crypt::Rhash;
my $r = new Crypt::Rhash(RHASH_SHA1);
open(my $fd, "<", "input.txt") or die "cannot open < input.txt: $!\n";
while ((my $n = $r->update_fd($fd, undef, 1024) != 0)) {
print "$n bytes hashed. The SHA1 is " . $r->final()->hash() . "\n";
$r->reset();
}
defined($n) or die "read error for input.txt: $!\n";
close($fd);
=item $rhash->final()
Finishes calculation for all data buffered by updating methods and stops
message digest calculation. The function is called automatically by any
of the $rhash->hash*() methods if the final() call was skipped.
=item $rhash->reset()
Resets the $rhash object to the initial state.
=item $rhash->hashed_length()
Returns the total length of the hashed message.
=item $rhash->hash_id()
Returns the hash mask, the $rhash object was constructed with.
=back
=head1 FORMATTING MESSAGE DIGEST
Computed message digest can be formatted as a hexadecimal string (in the forward or
reverse byte order), a base32/base64-encoded string or as raw binary data.
=over
=item $rhash->hash( $hash_id )
Returns the message digest in the default format,
which can be hexadecimal or base32. Actually the method is equivalent of
(Crypt::Rhash::is_base32($hash_id) ? $rhash->hash_base32($hash_id) :
$rhash->hash_hex($hash_id))
If the optional $hash_id parameter is omitted or zero, then the method returns
the message digest for the algorithm contained in $rhash with the lowest identifier.
=item $rhash->hash_hex( $hash_id )
Returns the specified message digest in the hexadecimal format.
use Crypt::Rhash;
my $msg = "abc";
print "MD5 = " . Crypt::Rhash->new(RHASH_MD5)->update($msg)->hash_hex() . "\n";
=item $rhash->hash_rhex( $hash_id )
Returns the specified message digest in the hexadecimal format with reversed order of bytes.
Some programs prefer to output the GOST R 34.11-94 message digest in this format.
=item $rhash->hash_base32( $hash_id )
Returns the specified message digest in the base32 format.
=item $rhash->hash_base64( $hash_id )
Returns the specified message digest in the base64 format.
=item $rhash->magnet_link( $filename, $hash_mask )
Returns the magnet link containing the computed message digests, filesize,
and, optionaly, $filename. The $filename (if specified) is URL-encoded,
by converting special characters into the % form.
The optional parameter $hash_mask can limit which message digests to put
into the link.
=back
=head1 STATIC METHODS
=over
=item Crypt::Rhash::count()
Returns the number of supported hash functions
=item Crypt::Rhash::is_base32($hash_id)
Returns nonzero if default output format is Base32 for the hash function specified by $hash_id.
Returns zero if default format is hexadecimal.
=item Crypt::Rhash::get_digest_size($hash_id)
Returns the size in bytes of raw binary message digest of the specified hash function.
=item Crypt::Rhash::get_hash_length($hash_id)
Returns the length of a message digest in default output format for the specified hash function.
=item Crypt::Rhash::get_name($hash_id)
Returns the name of the specified hash function.
=item Crypt::Rhash::librhash_version_string()
Returns the version of LibRHash as string.
=back
=head1 ALTERNATIVE WAY TO COMPUTE A MESSAGE DIGEST
=over
=item Crypt::Rhash::msg($hash_id, $message)
Computes and returns a single message digest (in its default format) of the $message by the selected hash function.
use Crypt::Rhash;
print "SHA1( 'abc' ) = " . Crypt::Rhash::msg(RHASH_SHA1, "abc") . "\n";
=back
=head1 LICENSE
BSD Zero Clause License
Copyright (c) 2011, Aleksey Kravchenko
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
=cut
rhash-1.4.6/bindings/perl/Rhash.xs 0000664 0000000 0000000 00000017014 15010476501 015511 0 ustar root root #include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include
#include
typedef unsigned long long ulonglong;
/* helper macros and functions */
#define BASE32_LENGTH(size) (((size) * 8 + 4) / 5)
#define BASE64_LENGTH(size) ((((size) + 2) / 3) * 4)
void verify_single_bit_hash_id(unsigned hash_id, CV* cv)
{
const char* error;
const GV *gv;
const char *func_name;
if(0 == (hash_id & RHASH_ALL_HASHES)) {
error = "%s: unsupported hash_id = 0x%x";
} else if(0 != (hash_id & (hash_id - 1))) {
error = "%s: hash_id is not a single bit: 0x%x";
} else {
return; /* success */
}
gv = CvGV(cv);
func_name = (gv ? GvNAME(gv) : "Rhash");
croak(error, func_name, hash_id);
}
/* allocate a perl string scalar variable, containing str_len + 1 bytes */
SV * allocate_string_buffer(STRLEN str_len)
{
SV * sv = newSV(str_len); /* allocates (str_len + 1) bytes */
SvPOK_only(sv);
SvCUR_set(sv, str_len);
return sv;
}
MODULE = Crypt::Rhash PACKAGE = Crypt::Rhash
##############################################################################
# Initialize LibRHash in the module bootstrap function
BOOT:
rhash_library_init();
##############################################################################
# perl bindings for Hi-level functions
SV *
rhash_msg_wrapper(hash_id, message)
unsigned hash_id
PROTOTYPE: $$
PREINIT:
STRLEN length;
unsigned char out[264];
int res;
INPUT:
char* message = SvPV(ST(1), length);
CODE:
verify_single_bit_hash_id(hash_id, cv);
res = rhash_msg(hash_id, message, length, out);
if(res < 0) {
croak("%s: %s", "rhash_msg_wrapper", strerror(errno));
}
RETVAL = newSVpv((char*)out, rhash_get_digest_size(hash_id));
OUTPUT:
RETVAL
SV *
rhash_file_wrapper(hash_id, filepath)
unsigned hash_id
char * filepath
PROTOTYPE: $$
PREINIT:
int res;
unsigned char out[264];
CODE:
verify_single_bit_hash_id(hash_id, cv);
res = rhash_file(hash_id, filepath, out);
if(res < 0) {
croak("%s: %s: %s", "rhash_file", filepath, strerror(errno));
}
RETVAL = newSVpv((char*)out, rhash_get_digest_size(hash_id));
OUTPUT:
RETVAL
##############################################################################
# perl bindings for Low-level functions
struct rhash_context *
rhash_init_multi_wrapper(AV* array)
PROTOTYPE: $
PREINIT:
unsigned hash_ids[64];
size_t length = 0;
int i;
CODE:
for (i = 0; i <= av_len(array); i++) {
SV** elem = av_fetch(array, i, 0);
if (elem != NULL) {
if (length >= (sizeof(hash_ids)/sizeof(*hash_ids)))
croak("too many hash identifiers passed");
hash_ids[length] = (unsigned)SvNV(*elem);
length++;
}
}
if (length == 0)
croak("at least one hash identifier must be passed");
RETVAL = rhash_init_multi(length, hash_ids);
OUTPUT:
RETVAL
int
rhash_update(ctx, message)
struct rhash_context * ctx
PROTOTYPE: $$
PREINIT:
STRLEN length;
INPUT:
char* message = SvPV(ST(1), length);
CODE:
RETVAL = rhash_update(ctx, message, length);
OUTPUT:
RETVAL
int
rhash_final(ctx)
struct rhash_context * ctx
PROTOTYPE: $
CODE:
RETVAL = rhash_final(ctx, 0);
OUTPUT:
RETVAL
void
rhash_reset(ctx)
struct rhash_context * ctx
PROTOTYPE: $
void
rhash_free(ctx)
struct rhash_context * ctx
PROTOTYPE: $
SV *
rhash_print_wrapper(ctx, hash_id, flags = 0)
struct rhash_context * ctx
unsigned hash_id
int flags
PROTOTYPE: $$;$
PREINIT:
int len;
char out[264];
CODE:
if(hash_id != 0) verify_single_bit_hash_id(hash_id, cv);
len = rhash_print(out, ctx, hash_id, flags);
/* set exact length to support raw output (RHPR_RAW) */
RETVAL = newSVpv(out, len);
OUTPUT:
RETVAL
SV *
rhash_print_magnet_wrapper(ctx, filename, hash_mask)
struct rhash_context * ctx
SV * filename
SV * hash_mask
PROTOTYPE: $;$$
PREINIT:
/* process undefined values */
char * name = (SvOK(filename) ? SvPV_nolen(filename) : 0);
unsigned mask = (SvOK(hash_mask) ? (unsigned)SvUV(hash_mask) : RHASH_ALL_HASHES);
size_t buf_size;
CODE:
/* allocate a string buffer and print magnet link into it */
buf_size = rhash_print_magnet(0, name, ctx, mask, RHPR_FILESIZE);
RETVAL = allocate_string_buffer(buf_size - 1);
rhash_print_magnet(SvPVX(RETVAL), name, ctx, mask, RHPR_FILESIZE);
/* note: length(RETVAL) = (buf_size - 1),
* so the following call is not required:
* SvCUR_set(RETVAL, strlen(SvPVX(RETVAL))); */
OUTPUT:
RETVAL
unsigned
rhash_get_hash_id(ctx)
struct rhash_context * ctx
PROTOTYPE: $
CODE:
RETVAL = ctx->hash_id;
OUTPUT:
RETVAL
ulonglong
rhash_get_hashed_length(ctx)
struct rhash_context * ctx
PROTOTYPE: $
CODE:
RETVAL = ctx->msg_size;
OUTPUT:
RETVAL
##############################################################################
# Information functions
int
count()
CODE:
RETVAL = rhash_count();
OUTPUT:
RETVAL
SV *
librhash_version_string()
PREINIT:
unsigned version;
CODE:
version = rhash_get_version();
RETVAL = allocate_string_buffer(20);
sprintf(SvPVX(RETVAL), "%u.%u.%u", (version >> 24) & 255, (version >> 16) & 255, (version >> 8) & 255);
SvCUR_set(RETVAL, strlen(SvPVX(RETVAL)));
OUTPUT:
RETVAL
int
librhash_version()
CODE:
RETVAL = rhash_get_version();
OUTPUT:
RETVAL
int
is_base32(hash_id)
unsigned hash_id
PROTOTYPE: $
CODE:
RETVAL = rhash_is_base32(hash_id);
OUTPUT:
RETVAL
int
get_digest_size(hash_id)
unsigned hash_id
PROTOTYPE: $
CODE:
RETVAL = rhash_get_digest_size(hash_id);
OUTPUT:
RETVAL
int
get_hash_length(hash_id)
unsigned hash_id
PROTOTYPE: $
CODE:
RETVAL = rhash_get_hash_length(hash_id);
OUTPUT:
RETVAL
const char *
get_name(hash_id)
unsigned hash_id
PROTOTYPE: $
CODE:
RETVAL = rhash_get_name(hash_id);
OUTPUT:
RETVAL
##############################################################################
# Hash printing functions
##############################################################################
# Hash conversion functions
SV *
raw2hex(bytes)
PROTOTYPE: $
PREINIT:
STRLEN size;
INPUT:
unsigned char * bytes = (unsigned char*)SvPV(ST(0), size);
CODE:
RETVAL = allocate_string_buffer(size * 2);
rhash_print_bytes(SvPVX(RETVAL), bytes, size, RHPR_HEX);
OUTPUT:
RETVAL
SV *
raw2base32(bytes)
PROTOTYPE: $
PREINIT:
STRLEN size;
INPUT:
unsigned char * bytes = (unsigned char*)SvPV(ST(0), size);
CODE:
RETVAL = allocate_string_buffer(BASE32_LENGTH(size));
rhash_print_bytes(SvPVX(RETVAL), bytes, size, RHPR_BASE32);
OUTPUT:
RETVAL
SV *
raw2base64(bytes)
PROTOTYPE: $
PREINIT:
STRLEN size;
INPUT:
unsigned char * bytes = (unsigned char*)SvPV(ST(0), size);
CODE:
RETVAL = allocate_string_buffer(BASE64_LENGTH(size));
rhash_print_bytes(SvPVX(RETVAL), bytes, size, RHPR_BASE64);
OUTPUT:
RETVAL
##############################################################################
# BTIH / BitTorrent support functions
void
rhash_bt_add_filename(ctx, filename, filesize)
struct rhash_context * ctx
char * filename
ulonglong filesize
PROTOTYPE: $$$
CODE:
rhash_torrent_add_file(ctx, filename, filesize);
void
rhash_bt_set_piece_length(ctx, piece_length)
struct rhash_context * ctx
unsigned piece_length
PROTOTYPE: $$
CODE:
rhash_torrent_set_piece_length(ctx, piece_length);
void
rhash_bt_set_private(ctx)
struct rhash_context * ctx
PROTOTYPE: $
CODE:
rhash_torrent_set_options(ctx, RHASH_TORRENT_OPT_PRIVATE);
SV *
rhash_bt_get_torrent_text(ctx)
struct rhash_context * ctx
PROTOTYPE: $
PREINIT:
const rhash_str* text;
CODE:
text = rhash_torrent_generate_content(ctx);
if(!text) {
XSRETURN_UNDEF;
}
RETVAL = newSVpv(text->str, text->length);
OUTPUT:
RETVAL
rhash-1.4.6/bindings/perl/META.yml 0000664 0000000 0000000 00000001270 15010476501 015336 0 ustar root root ---
abstract: 'Library for computing message digests and magnet links'
author:
- 'Aleksey Kravchenko'
build_requires:
ExtUtils::MakeMaker: 0
configure_requires:
ExtUtils::MakeMaker: 0
dynamic_config: 0
generated_by: 'ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.133380'
license: open_source
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
version: 1.4
name: Crypt-Rhash
no_index:
directory:
- t
- inc
requires: {}
resources:
bugtracker: https://github.com/rhash/RHash/issues
homepage: http://rhash.sf.net/
license: https://github.com/rhash/RHash/blob/master/COPYING
repository: https://github.com/rhash/RHash
version: 1.05
rhash-1.4.6/bindings/perl/typemap 0000664 0000000 0000000 00000000142 14703622112 015463 0 ustar root root struct rhash_context * T_PTROBJ
rhash_uptr_t T_NV
ulonglong T_NV
const char * T_PV
rhash-1.4.6/bindings/perl/Makefile.PL 0000664 0000000 0000000 00000007265 15010476501 016051 0 ustar root root use strict;
use warnings;
use Cwd;
use ExtUtils::MakeMaker;
use File::Copy;
my $libs = '';
my $def = '';
my $inc = '';
my $obj = '';
my $clean = '';
my $inc_dir = undef;
my $lib_dir = undef;
my $rh_builtin_dir = 'librhash';
my $rh_local_dir = getcwd() . '/../../librhash';
my $rh_type = $ENV{'LIBRHASH'} || 'auto';
my $custom_inc = $ENV{'LIBRHASH_INC'} || '';
my $custom_ld = $ENV{'LIBRHASH_LD'} || '';
sub has_librhash {
return (-f $_[0] . '/rhash.h');
}
if ($rh_type eq 'auto')
{
$rh_type = ($custom_ld =~ /-L/ ? 'custom' :
has_librhash($rh_builtin_dir) ? 'builtin' :
has_librhash($rh_local_dir) ? 'local' : 'system' );
print "Selected librhash type: $rh_type\n";
}
if ($rh_type ne 'custom')
{
$inc_dir = ($rh_type eq 'builtin' ? $rh_builtin_dir :
$rh_type eq 'local' ? $rh_local_dir :
$rh_type eq 'system' ? '' : die("Unknown type LIBRHASH='$rh_type'"));
$lib_dir = $inc_dir if $rh_type ne 'builtin';
!$inc_dir || -d $inc_dir || die "Not a directory: '$inc_dir'";
!$inc_dir || has_librhash($inc_dir) || die "No librhash headers at: '$inc_dir'";
$inc = "-I$inc_dir" if $inc_dir;
$libs = "-L$lib_dir" if $lib_dir;
$libs .= ' -lrhash' if $rh_type ne 'builtin';
} else {
# set custom compile and linking flags
$inc = $custom_inc;
$libs = $custom_ld;
}
sub read_librhash_version($) {
my $path = $_[0] . "/version.h";
open my $fh, "<", $path or die "could not open $path: $!";
chomp(my @lines = <$fh>);
close $fh;
foreach (@lines) {
if (/^#define VERSION "(\d+)\.(\d+)\.(\d+)"/) {
return sprintf("0x%02x%02x%02x%02x", $1, $2, $3, 0);
}
}
return '0';
}
# copy and rename *.c files by prepending underscore '_'
sub copy_c_files($) {
my $from_dir = $_[0];
my @result = ();
(opendir my($dh), $from_dir) or die "Can't open $from_dir: $!";
my @files = grep { /(?= $df);
#print "copy $from -> $to\n";
copy($from, $to)
or die "Can't copy $from to $to: $!";
}
return @result;
}
if($rh_type eq 'builtin') {
# using sources of the builtin librhash
my $librhash_version = read_librhash_version($rh_builtin_dir);
my @c_files = copy_c_files($rh_builtin_dir);
$clean = join(' ', @c_files);
$obj = join(' ', map { s/\.c$/\$(OBJ_EXT)/; $_ } @c_files) . ' ';
$def = '-DRHASH_XVERSION=' . $librhash_version;
}
# make setting optional MakeMaker parameters more readable
sub OPTIONAL {
return () unless $ExtUtils::MakeMaker::VERSION ge shift;
return @_;
}
# see ExtUtils::MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written
WriteMakefile(
NAME => 'Crypt::Rhash',
ABSTRACT => 'Library for computing message digests and magnet links',
AUTHOR => 'Aleksey Kravchenko',
VERSION_FROM => 'Rhash.pm', # finds $VERSION
OPTIONAL( '6.31',
LICENSE => 'open_source',
),
OPTIONAL( '6.46',
# Use META_ADD instead of META_MERGE so that we can remove
# any build-time dependencies that MakeMaker will put into
# the requires field.
META_ADD => {
resources => {
homepage => 'http://rhash.sf.net/',
bugtracker => 'https://github.com/rhash/RHash/issues',
license => 'https://github.com/rhash/RHash/blob/master/COPYING',
repository => 'https://github.com/rhash/RHash',
},
},
),
LIBS => [ $libs ],
DEFINE => $def,
INC => $inc,
OBJECT => $obj . 'Rhash$(OBJ_EXT)',
clean => {
FILES => $clean,
},
);
rhash-1.4.6/bindings/perl/README 0000664 0000000 0000000 00000002367 14703622112 014754 0 ustar root root
Crypt::Rhash module allows to compute various hash sums and magnet links.
The following hash sums are supported: CRC32, CRC32C, MD4, MD5,
SHA1, SHA256, SHA512, SHA3, Tiger, TTH, Torrent BTIH, AICH, ED2K,
GOST R 34.11-94, GOST R 34.11-2012, RIPEMD-160, HAS-160,
EDON-R 256/512, WHIRLPOOL and SNEFRU.
BUILDING THE MODULE
-------------------
The module can be built using the sequence of commands:
perl Makefile.PL
make
make test
INSTALLATION
------------
To install Crypt::Rhash, run the following command:
make install
LICENSE
-------
BSD Zero Clause License
Copyright (c) 2011, Aleksey Kravchenko
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
rhash-1.4.6/bindings/perl/t/ 0000755 0000000 0000000 00000000000 15010731530 014322 5 ustar root root rhash-1.4.6/bindings/perl/t/3test_all_hash_functions.t 0000664 0000000 0000000 00000006162 14703622112 021506 0 ustar root root use Test::More tests => 31;
use Crypt::Rhash;
#########################
$r = new Crypt::Rhash(RHASH_ALL);
$r->update("a")->final();
is( $r->hash(RHASH_CRC32), "e8b7be43");
is( $r->hash(RHASH_CRC32C), "c1d04330");
is( $r->hash(RHASH_MD4), "bde52cb31de33e46245e05fbdbd6fb24");
is( $r->hash(RHASH_MD5), "0cc175b9c0f1b6a831c399e269772661");
is( $r->hash(RHASH_SHA1), "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8");
is( $r->hash(RHASH_TIGER), "77befbef2e7ef8ab2ec8f93bf587a7fc613e247f5f247809");
is( $r->hash(RHASH_TTH), "czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y");
is( length($r->hash(RHASH_BTIH)), 40);
is( $r->hash(RHASH_ED2K), "bde52cb31de33e46245e05fbdbd6fb24");
is( $r->hash(RHASH_AICH), "q336in72uwt7zyk5dxolt2xk5i3xmz5y");
is( $r->hash(RHASH_WHIRLPOOL), "8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a");
is( $r->hash(RHASH_RIPEMD160), "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe");
is( $r->hash(RHASH_GOST94), "d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd");
is( $r->hash(RHASH_GOST94_CRYPTOPRO), "e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011");
is( $r->hash(RHASH_GOST12_256), "ba31099b9cc84ec2a671e9313572378920a705b363b031a1cb4fc03e01ce8df3");
is( $r->hash(RHASH_GOST12_512), "8b2a40ecab7b7496bc4cc0f773595452baf658849b495acc3ba017206810efb00420ccd73fb3297e0f7890941b84ac4a8bc27e3c95e1f97c094609e2136abb7e");
is( $r->hash(RHASH_HAS160), "4872bcbc4cd0f0a9dc7c2f7045e5b43b6c830db8");
is( $r->hash(RHASH_SHA224), "abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5");
is( $r->hash(RHASH_SHA256), "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb");
is( $r->hash(RHASH_SHA384), "54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31");
is( $r->hash(RHASH_SHA512), "1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75");
is( $r->hash(RHASH_EDONR256), "943aa9225a2cf154ec2e4dd81237720ba538ca8df2fd83c0b893c5d265f353a0");
is( $r->hash(RHASH_EDONR512), "b59ec44f7beef8a04ceed38a973d77c65e22e9458d5f67b497948da34986c093b5efc5483fbee55f2f740fcad31f18d80db44bb6b8843e7fd599188e7c07233b");
is( $r->hash(RHASH_SHA3_224), "9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b");
is( $r->hash(RHASH_SHA3_256), "80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b");
is( $r->hash(RHASH_SHA3_384), "1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9");
is( $r->hash(RHASH_SHA3_512), "697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a");
is( $r->hash(RHASH_SNEFRU128), "bf5ce540ae51bc50399f96746c5a15bd");
is( $r->hash(RHASH_SNEFRU256), "45161589ac317be0ceba70db2573ddda6e668a31984b39bf65e4b664b584c63d");
is( $r->hash(RHASH_BLAKE2S), "4a0d129873403037c2cd9b9048203687f6233fb6738956e0349bd4320fec3e90");
is( $r->hash(RHASH_BLAKE2B), "333fcb4ee1aa7c115355ec66ceac917c8bfd815bf7587d325aec1864edd24e34d5abe2c6b1b5ee3face62fed78dbef802f2a85cb91d455a8f5249d330853cb3c");
__END__
rhash-1.4.6/bindings/perl/t/1test_hash_calculation.t 0000664 0000000 0000000 00000004474 15010476501 021147 0 ustar root root use Test::More tests => 25;
BEGIN { use_ok('Crypt::Rhash') };
#########################
# test script
$msg = "message digest";
ok( $r = new Crypt::Rhash(RHASH_MD5, RHASH_TTH));
ok( $r->update($msg) );
is( $r->hash(), "f96b697d7cb7938d525a2f31aaf161d0"); # prints the first hash by default
is( $r->hash(RHASH_TTH), "ym432msox5qilih2l4tno62e3o35wygwsbsjoba");
is( $r->hash_hex(RHASH_TTH), "c339bd324ebf6085a0fa5f26d77b44dbb7db60d690649704");
is( $r->hash_hex(RHASH_MD5), "f96b697d7cb7938d525a2f31aaf161d0");
is( $r->hash_rhex(RHASH_MD5), "d061f1aa312f5a528d93b77c7d696bf9");
is( $r->hash_base32(RHASH_MD5), "7fvws7l4w6jy2us2f4y2v4lb2a");
is( $r->hash_base64(RHASH_MD5), "+WtpfXy3k41SWi8xqvFh0A==");
is( $r->hash_raw(RHASH_MD5), "\xf9\x6b\x69\x7d\x7c\xb7\x93\x8d\x52\x5a\x2f\x31\xaa\xf1\x61\xd0");
is( $r->hashed_length(), length($msg));
is( $r->reset()->hash(), "d41d8cd98f00b204e9800998ecf8427e");
is( $r->hashed_length(), 0);
is( $r->hash_id(), (RHASH_MD5 | RHASH_TTH));
$r = undef; # destruct the Rhash object
#########################
# test hashing a file
$file = "msg.txt";
open FILE, ">$file" or die $!;
binmode FILE;
print FILE $msg;
close FILE;
$r = new Crypt::Rhash(RHASH_MD5);
is( $r->update_file($file), 14);
is( $r->hash(), "f96b697d7cb7938d525a2f31aaf161d0");
is( $r->reset()->update_file($file, 4, 1), 1);
is( $r->hash(), "0cc175b9c0f1b6a831c399e269772661");
open $fd, "<$file" or die $!;
binmode $fd;
is( $r->reset()->update_fd($fd), 14);
is( $r->hash(), "f96b697d7cb7938d525a2f31aaf161d0");
close $fd;
unlink($file);
#########################
# test magnet_link() method
$r = new Crypt::Rhash(RHASH_ALL);
$r->update("a")->final();
is( $r->magnet_link("test.txt", RHASH_MD5, RHASH_SHA1), "magnet:?xl=1&dn=test.txt&xt=urn:md5:0cc175b9c0f1b6a831c399e269772661&xt=urn:sha1:q336in72uwt7zyk5dxolt2xk5i3xmz5y");
is( $r->magnet_link(undef, RHASH_ED2K, RHASH_AICH, RHASH_TTH), "magnet:?xl=1&xt=urn:ed2k:bde52cb31de33e46245e05fbdbd6fb24&xt=urn:aich:q336in72uwt7zyk5dxolt2xk5i3xmz5y&xt=urn:tree:tiger:czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y");
$r = new Crypt::Rhash(RHASH_CRC32, RHASH_MD4);
$r->update("abc")->final();
is( $r->magnet_link(), "magnet:?xl=3&xt=urn:crc32:352441c2&xt=urn:md4:a448017aaf21d8525fc10ae87aa6729d");
is( $r->magnet_link("t"), "magnet:?xl=3&dn=t&xt=urn:crc32:352441c2&xt=urn:md4:a448017aaf21d8525fc10ae87aa6729d");
__END__
rhash-1.4.6/bindings/perl/t/2test_static_functions.t 0000664 0000000 0000000 00000001426 14703622112 021217 0 ustar root root use Test::More tests => 12;
use Crypt::Rhash;# qw( :Functions );
#########################
# Rhash module static functions
ok(RHASH_CRC32 > 0);
ok(&Crypt::Rhash::count() > 0);
is(&Crypt::Rhash::get_digest_size(RHASH_CRC32), 4);
is(&Crypt::Rhash::get_hash_length(RHASH_CRC32), 8);
is(&Crypt::Rhash::is_base32(RHASH_CRC32), 0);
is(&Crypt::Rhash::is_base32(RHASH_TTH), 1);
is(&Crypt::Rhash::get_name(RHASH_CRC32), "CRC32");
like(&Crypt::Rhash::librhash_version_string(), qr/^\d+\.\d+\.\d+$/);
# test conversion functions
is(&raw2hex("test msg"), "74657374206d7367");
is(&raw2base32("test msg"), "orsxg5banvzwo");
is(&raw2base64("test msg"), "dGVzdCBtc2c=");
$msg = "message digest";
# test msg() hashing method
is(&Crypt::Rhash::msg(RHASH_MD5, $msg), "f96b697d7cb7938d525a2f31aaf161d0");
rhash-1.4.6/bindings/perl/META.json 0000664 0000000 0000000 00000002234 15010476501 015507 0 ustar root root {
"abstract" : "Library for computing message digests and magnet links",
"author" : [
"Aleksey Kravchenko"
],
"dynamic_config" : 0,
"generated_by" : "ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.133380",
"license" : [
"open_source"
],
"meta-spec" : {
"url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
"version" : "2"
},
"name" : "Crypt-Rhash",
"no_index" : {
"directory" : [
"t",
"inc"
]
},
"prereqs" : {
"build" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"configure" : {
"requires" : {
"ExtUtils::MakeMaker" : "0"
}
},
"runtime" : {
"requires" : {}
}
},
"release_status" : "stable",
"resources" : {
"bugtracker" : {
"web" : "https://github.com/rhash/RHash/issues"
},
"homepage" : "http://rhash.sf.net/",
"license" : [
"https://github.com/rhash/RHash/blob/master/COPYING"
],
"repository" : {
"url" : "https://github.com/rhash/RHash"
}
},
"version" : "1.05"
}
rhash-1.4.6/bindings/perl/MANIFEST 0000644 0000000 0000000 00000000461 13135506347 015225 0 ustar root root Makefile.PL
README
Rhash.pm
Rhash.xs
t/1test_hash_calculation.t
t/2test_static_functions.t
t/3test_all_hash_functions.t
typemap
MANIFEST
META.yml Module YAML meta-data (added by MakeMaker)
META.json Module JSON meta-data (added by MakeMaker)
rhash-1.4.6/bindings/mono/ 0000755 0000000 0000000 00000000000 15010731530 014065 5 ustar root root rhash-1.4.6/bindings/mono/Makefile 0000664 0000000 0000000 00000002547 14703622112 015542 0 ustar root root #!/usr/bin/make -f
# This file is a part of Mono Bindings for Librhash
#
# Copyright (c) 2011, Sergey Basalaev
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
CS?=mcs
MDOC?=mdoc
SOURCES=AssemblyInfo.cs Bindings.cs Hasher.cs HashType.cs
all: assembly assemble-doc html
assembly: RHash.dll RHash.dll.mdb
RHash.dll RHash.dll.mdb: $(SOURCES)
$(CS) -target:library -out:RHash.dll -debug -keyfile:RHash.snk $(SOURCES)
update-doc: RHash.dll
$(MDOC) update RHash.dll -o doc
assemble-doc: RHash.tree RHash.zip
RHash.tree RHash.zip:
$(MDOC) assemble -o RHash doc
html:
$(MDOC) export-html -o html doc
test: RHash.dll
+$(MAKE) -C test
clean:
rm -f RHash.dll RHash.dll.mdb
rm -f RHash.tree RHash.zip
rm -rf html
+$(MAKE) -C test clean
.PHONY : clean html test
rhash-1.4.6/bindings/mono/RHash.snk 0000644 0000000 0000000 00000001124 13135503555 015617 0 ustar root root $ RSA2 /Ìðo»¥‰#ú&¦Ù¢*sÁ‚„lãµÒº£‚ï@Ȉ˜_¥Î¥¨|N=Ÿ:ùÿ™¤ØÂQ¨E椧 |’PD`*/œvlMaQOFDÿR˜%è52²ëKÖ°°Å›9HÇÉn¹3ªžôT!¢
G›ý_¶ ŸRõ¼ïD‡¯]Ë#*8YTÄ}`œo3S†5FC\Ÿ˜lîüØ´—¯é«ªµjé„“@Ý*¬#¾Å«n,3¦õÛ>€ºœä~?#ái²Eè‚%Žyr
dwn~ô„Âßttj7{í€óE ß;Ý>4µêfó¼|U>ìÜ;ŽŸ€vÂe}9 Xb"õ;oïÑÍT¹Û{*eê«dÀkÁ&‡¦zì++87ÖÁƒîèªÖN- üÏúZƒ6^c Ý¥ÝC¦[OC8gÿ§:
4à›ê‡:Ù1>º”ƒ‹