pax_global_header00006660000000000000000000000064132520767710014524gustar00rootroot0000000000000052 comment=10779cbca99c0f5dcb5aae4a0c7caca46a4f9bd6 RHash-1.3.6/000077500000000000000000000000001325207677100125405ustar00rootroot00000000000000RHash-1.3.6/.gitignore000066400000000000000000000003271325207677100145320ustar00rootroot00000000000000/dist/rhash.spec /dist/rhash.1.* /dist/librhash.pc /librhash/exports.sym po/*.gmo /rhash /rhash_shared /rhash_static /librhash/test_shared /librhash/test_static config.mak *.[ao] *.exe *.dll *.def *.so *.so.0 *.log RHash-1.3.6/COPYING000066400000000000000000000013571325207677100136010ustar00rootroot00000000000000 RHash License Copyright (c) 2005-2014 Aleksey Kravchenko Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. The Software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! RHash-1.3.6/ChangeLog000066400000000000000000000477421325207677100143300ustar00rootroot00000000000000Wed 14 Mar 2018 Aleksey * === Version 1.3.6 === * support --file-list option Sun 11 Mar 2018 And Sch * librhash: speedup sha3 Sun Feb 18 2018 Aleksey * Bugfix: fix --follow option Mon Jan 29 2018 J. Peter Mugaas * better MSYS and CygWin support Fri Jan 26 2018 Aleksey * configuration script Mon Sep 4 2017 Aleksey * Bugfix: broken binary hash output Mon Aug 28 2017 Aleksey * Bugfix: fix running on WinXP Mon Aug 14 2017 Aleksey * === Version 1.3.5 === * look for locales directory at PROGRAM_DIRECTORY\locale on Windows * look for config at PROGRAM_DIRECTORY\rhashrc on Windows Fri Aug 4 2017 Aleksey * support LibRhash bindings to PHP7 Sun Jul 30 2017 Aleksey * Bugfix: illegal instruction error on macOS Sat Jul 29 2017 Aleksey * improve utf-8 support on Windows Thu Jul 27 2017 Aleksey * Bugfix: fix access to long paths on Windows Mon Jul 17 2017 Aleksey * add ca, fr, ro translations Sun Jul 16 2017 Darío Hereñú * full Spanish translation Mon Jul 10 2017 James Le Cuirot * correct build/install command for freebsd Mon Jul 10 2017 Przemyslaw Pawelczyk * compilation fixes for aarch64 and musl Mon Jul 10 2017 Aleksey * improve support of clang on macOS Sun Nov 6 2016 Aleksey * === Version 1.3.4 === Tue Nov 17 2015 Alexey Dokuchaev, Kurt Jaeger * compilation fixes for FreeBSD Sat Aug 9 2014 Aleksey * return non zero exit code if a file was not found Tue Aug 5 2014 Aleksey * === Version 1.3.3 === Mon Aug 4 2014 And Sch, Aleksey * librhash: small optimization of Whirlpool Sat Aug 2 2014 Aleksey * option --exclude for skipping some files during recursive scanning Fri Aug 1 2014 Aleksey * update the SHA3 algorithm to follow the changes of the FIPS 202 draft Wed Jul 30 2014 Aleksey * support torrents with more than one announce url Tue Jul 29 2014 Aleksey * LibRHash now exports torrent functions Mon Jul 21 2014 Tsukasa Oi * fixed test_rhash.sh script failing on the en_US.UTF-8 locale Wed Jul 16 2014 Aleksey * changed the `-p' format names of sha* families, see manpage * set a boolean in config to true by a string `true', `on' or `yes' Sun Jul 13 2014 Aleksey * Ctrl-C now interrupts benchmarking Wed Jul 2 2014 Aleksey * === Version 1.3.2 === Sat Jun 21 2014 Aleksey * report warnings on files locked by some processes Thu Jun 19 2014 Brad Campbell * ignore non-regular files while scanning directories recursively Wed Jun 18 2014 Aleksey * option --follow for following symlinks to directories Sun Apr 13 2014 ZinnKid * BTIH piece length calculation updated to follow the uTorrent algorithm change Wed Jan 8 2014 Aleksey * === Version 1.3.1 === * Exclude the files specified by -o and -l from processing Sat Jan 4 2014 Aleksey * Improved directory scanning Sat Dec 28 2013 Aleksey * Bugfix: suppress the R6034 error popup on Windows Fri Oct 25 2013 Aleksey * Fixed 'value too large' error on 32-bit Linux Thu Sep 19 2013 Aleksey * Bugfix: corrected sha3-224 for big-endian processors Tue Sep 17 2013 Aleksey * === Version 1.3.0 === Tue May 21 2013 Aleksey * Fixed output of percents when two or more files are hashed Mon Apr 29 2013 Aleksey * Supported SHA3 (Keccak) hash function Sat Apr 27 2013 Aleksey * Fixed memory leaks Tue Apr 23 2013 Aleksey * Bugfix: %{mtime} formatting option was broken Mon Dec 31 2012 Aleksey * imported translations from Launchpad: de, es, gl, it Tue Dec 25 2012 Aleksey * === Version 1.2.10 === Mon Nov 5 2012 Aleksey * Bugfix: incorrect GOST hash for ("\FF" x 64) on non-x86 CPU Mon Oct 8 2012 Aleksey * Shortcut -k for --check-embedded Thu Sep 27 2012 Aleksey * Bugfix: non-zero exit code if some files were not found * improved Ctrl-C processing Sat Aug 4 2012 Aleksey * Bugfix: path issue with verification of hash files Mon Jun 25 2012 Aleksey * Bugfix: different BTIH were generated for the same file 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 === Fri Apr 13 2012 Aleksey, Sergey Basalaev * translations: de, en_AU, es, gl, it Sun Apr 08 2012 Aleksey * Bugfix: handling UNC filenames on Windows * option --bt-batch for batch torrents Sat Jan 7 2012 Aleksey * librhash: rhash_print_magnet function 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, SBasalaev * LibRHash bindings to Java, Perl, Python, Ruby Tue Sep 6 2011 Aleksey * librhash: implemented auto-final feature, turned on by default Tue Sep 6 2011 Aleksey, SBasalaev * Russian translation Sat Sep 3 2011 Aleksey * Bugfix: not enough trailing '=' in a base64-encoded hash Sat Aug 20 2011 Aleksey * Bugfix: fix broken --openssl option parsing * Bugfix: buffer overflow when using --embed-crc-delimiter * Bugfix: segmentation fault on SUSE Linux Sun Aug 14 2011 Aleksey * === Version 1.2.7 === Sun Aug 7 2011 Aleksey * Bugfix: percents option was broken in v1.2.6 Fri Aug 5 2011 Aleksey * supported verification of sha256, sha512 and other hash sums Mon Jul 11 2011 Aleksey * librhash: rhash_cancel() macro to cancel hashing from another thread Fri Jun 24 2011 Aleksey * Bugfix: repaired default output encoding to be UTF-8 on Windows Wed Jun 22 2011 Aleksey * Bugfix: crash on WinXP Thu Jun 16 2011 Aleksey * === Version 1.2.6 === Sat Jun 11 2011 Aleksey * allowed options to be intermixed with file names in arbitrary order * switched option -G and the '%G' printf pattern to print GOST hash * Bugfix: --output failed for cyrillic file name Wed Jun 8 2011 Aleksey * librhash: better shared library compilation/testing support Mon Jun 6 2011 Aleksey * librhash: exported benchmarking functions in the shared library * librhash: added prefix to all functions to avoid poluting linker namespace * librhash: fixed rare alignment bugs in rhash_print and EDON-R 512 Sat May 28 2011 Aleksey * librhash: loading openssl at runtime if it is present * Bugfix: LLVM GOST amd64 asm compilation error Wed May 18 2011 Aleksey * === Version 1.2.5 === * option --openssl allows to replace some algorithms by the OpenSSL ones * Bugfix: incorrect recursive traversing of very long UTF-8 filepaths Wed Apr 27 2011 Aleksey * Bugfix: corrected calculation of BTIH hash and torrent files Fri Apr 15 2011 Aleksey * === Version 1.2.4 === * option --benchmark-raw for machine-readable benchmark output format * on Intel/AMD CPUs benchmark now prints the clocks-per-byte value Tue Apr 5 2011 Aleksey * changed config file locations Fri Apr 1 2011 Aleksey * Bugfix: repaired --path-separator on linux/unix Sun Mar 27 2011 Aleksey * === Version 1.2.3 === Fri Mar 25 2011 Aleksey * one-line percent for linux/unix Mon Mar 14 2011 Aleksey * added printf modificator %{mtime} to print the last modified date of a file Thu Feb 17 2011 Aleksey * Bugfix: verification of base2-like formatted md5 hash sums Fri Jan 14 2011 Aleksey * === Version 1.2.2 === * one-line percents (windows only) Tue Jan 11 2011 Aleksey * supported EDON-R 256/512 hash sums Sun Dec 19 2010 Aleksey * increased process priority when benchmarking on windows Thu Dec 16 2010 Aleksey * Bugfix: eight hash sums were broken on PowerPC * Bugfix: --accept/--crc-accept were not working since 1.1.9 Tue Dec 14 2010 Aleksey * === Version 1.2.1 === * Bugfix: GOST broken on OpenSolaris since 1.2.0 * option --list-hashes: list names of all supported hashes, one per line Mon Nov 29 2010 Aleksey * SHA 224/256/384/512 hash functions supported * Bugfix: broken asm compilation on openbsd and freebsd Wed Nov 24 2010 Aleksey * option --path-separator= for directories scanning Sun Nov 14 2010 Aleksey * === Version 1.2.0 === * --gost-cryptopro option: calculate GOST with CryptoPro parameters * --gost-reverse option: reverse bytes in GOST hash sum * Bugfix: btih/gost/ripemd/has160/snefru were not verified correctly in bsd and magnet formats Fri Oct 29 2010 Aleksey * Bugfix: rhash compiled by MS VC skipped files of size >4Gb Fri Oct 15 2010 Aleksey * === Version 1.1.9 === * new interface for internal library librhash Mon Jul 5 2010 Ruslan Nikolaev * GOST algorithm x86-64 assembler optimization Sun Apr 25 2010 Aleksey * new options --uppercase and --lowercase * Bugfix: GOST worked incorrectly when compiled by GCC with `-O0' Wed Apr 21 2010 Aleksey * windows distribution updated Fri Apr 16 2010 Aleksey * BugFix: options with string values were incorrectly loaded from config Wed Apr 14 2010 Aleksey * === Version 1.1.8 === * option --template= to read printf-like template from Mon Apr 12 2010 Xiangli Huang * BugFix: `--recursive *' traversed parent directory .. under windows * BugFix: `--check ' reported strange warning for dirs Mon Apr 12 2010 Aleksey * printf-directives starting with capital letter print upper-cased hashes, e.g. %{Gost} * %u directive switched to print url-encoded filename (alias for %{urlname}) * ed2k links verification supported Fri Apr 9 2010 Aleksey * BugFix: linking problem on OpenSolaris * filenames in urls are now always utf8-encoded (Windows only fix) Wed Apr 7 2010 Aleksey * '%B','%@' modifiers to print base64/raw representation of any hash (e.g. '%BM') Wed Mar 31 2010 Aleksey * === Version 1.1.7 === * option --btih to print BitTorrent infohash * option --torrent to create torrent file * option --bt-private for private torrents * option --bt-piece-length to change torrent piece length * option --bt-announce to set torrent announcement url Tue Mar 30 2010 Aleksey * the -m option made to be an alias for --magnet Mon Mar 29 2010 Xiangli Huang * print program version, when benchmarking Fri Mar 26 2010 Aleksey * Bugfix: infite loop while recursively updating hash files under Windows Thu Mar 4 2010 Aleksey * maxdepth parameter now is checked to be a number Thu Feb 25 2010 Aleksey * output tiger hash in the big-endian order Wed Feb 24 2010 Aleksey * === Version 1.1.6 === * man page updated * now all supported hashes are verified when cheking magnet links * benchmark now reports the size of the hashed message Fri Feb 19 2010 Aleksey * Bugfix: fixed GOST for big-endian systems Wed Feb 17 2010 Aleksey * Bugfix: buffer owerflow while parsing long command line under Windows Sun Feb 14 2010 Aleksey * Bugfix: fixed HAS-160 for big-endian systems Wed Feb 3 2010 Aleksey * Bugfix: crash while printing sfv header for files modified before 1970 Fri Jan 29 2010 Aleksey * Bugfix: sfv-hash symlink now sets default print format to SFV * Bugfix: ed2k-link symlink did not work as expected Thu Jan 28 2010 Aleksey * === Version 1.1.5 === * option --utf8 under Windows, also UTF8 now is the default encoding * Bugfix: non-existing files were reported twice in `-r --sfv' mode Wed Jan 27 2010 Aleksey * option --embed-crc-delimiter= to insert before a crc sum in -e mode * alias -e for --embed-crc * alias -B for --benchmark Mon Jan 11 2010 Aleksey * Bugfix: percents output fixed for files of more than 4Gb of data Fri Dec 18 2009 Aleksey * AICH algorithm has been re-written to process files of unknown size like stdin, pipes, sockets * ED2K switched to use eMule algorithm when filesize is an exact multiple of 9728000 bytes Thu Dec 17 2009 Aleksey * Bugfix: buffer overflow when printing eDonkey links for 0-sized files * Bugfix: --ripemd160 and --md4 option were broken * added `%R' printf entity for RIPEMD-160 Mon Dec 14 2009 Aleksey * === Version 1.1.4 === * supported algorithms: RIPEMD-160, HAS-160, GOST, MD4, SNEFRU-128, SNEFRU-256 * long printf format entities, e.g. %{md4}, %{has160}, %{gost}, %{snefru256} * `u' printf modifier for uppercase hashes, e.g. %u{gost} * switched to %{urlname} printf-entity for url-encoded file name * useful symlinks are installed by `make install-symlinks' Sun Dec 6 2009 Aleksey * WHIRLPOOL hash function supported, option --whirlpool Wed Dec 2 2009 Aleksey * print file checking statistics when --check-embedded specified Sun Nov 29 2009 Aleksey * === Version 1.1.3 === * forbid simultaneous usage of --check, --update and --check-embedded options Sun Nov 22 2009 Aleksey * Bugfix: Checking of md5 file always reported OK * --check-embedded option to verify files by crc32 sum embedded in their names. * --embed-crc option to rename processed files by embedding crc32 sum into name. Mon Nov 9 2009 Aleksey * --benchmark option now prints names of tested hash sums * use magnet format as default if the program name contains 'magnet' Wed Jun 24 2009 Aleksey * supported checking of files containing a single hash sum without a filename Mon Jun 15 2009 Aleksey * === Version 1.1.2 === * verification of files with magnet links supported Wed May 20 2009 Aleksey * Bugfix: --skip-ok was broken since 1.1.0 Fri May 15 2009 Aleksey * Bugfix: checking of ed2k hashes was broken since version 1.1.0 * Bugfix: --verbose lead to crash under OpenSolaris when config file not present Mon Mar 23 2009 Aleksey * === Version 1.1.1 === * config file described in the man page * Bugfix: buffer owerflow when printing tiger hash Sat Mar 21 2009 Aleksey * Bugfix: some options couldn't be read from config file Sat Mar 14 2009 Aleksey * === Version 1.1.0 === * various small changes and refactoring Tue Mar 10 2009 Aleksey * option --speed to print per-file and total speed statistics Thu Mar 5 2009 Aleksey * option --output to write calculation and check results to a file * option --log to log percents, speed and verbose messages Wed Mar 4 2009 Aleksey * option --percents to show wget-like percents Tue Feb 26 2009 Aleksey * Bugfix: fixed processing of unaligned messages in the get_crc32() function Sat Feb 14 2009 Aleksey * === Version 1.0.8 === * --magnet option supported to format sums as a magnet link * Bugfix: printf option from config conflicted with command line Sun Dec 14 2008 Aleksey * === Version 1.0.7 === * config file supported to load default options values * if --verbose, report verification errors as "sum is XXXXXXXX, should be YYYYYYYY" * '%h' modifier changed to '%x' Fri Nov 14 2008 Aleksey * === Version 1.0.6 === * reg-file for FAR user menu Thu Oct 9 2008 Aleksey * interpret '#' symbol as a comment Sat Sep 20 2008 ivan386 * under windows skip files openned for writing * Bugfix: printf arguments %p and %f corrected Sun Sep 14 2008 Aleksey * === Version 1.0.5 === Wed Aug 6 2008 Aleksey * '%b','%h' modifiers to print base32/hex representation of any hash (e.g. '%bH') * supported -p '\0' symbol * supported setting width for filesizes (e.g. -p '%12s') Tue Jul 22 2008 Aleksey * --verbose prints read speed statistics to stderr after each file * read buffer increased to 2 MiB Wed Jul 9 2008 Aleksey * === Version 1.0.4 === * '%u' prints URL-encoded filename * EDonkey links now have URL-encoded filename and contain AICH hash Mon Jul 7 2008 Aleksey * AICH hashsums supported, option --aich Sat Jun 28 2008 Aleksey * === Version 1.0.3 === * ed2k calculation fixed for files with 9728000 < filesize <= 9732096 * Big-endian processors supported for all sums Sat Jun 14 2008 Aleksey * === Version 1.0.2 === Fri Jun 6 2008 Aleksey * --benchmark option added * skip locked files under win32 when calculating 'em sums Tue May 20 2008 Aleksey * Bugfix: updating of md5 files was broken * Bugfix: more rigid parsing of base32/hex hash sums Wed May 15 2008 Aleksey * === Version 1.0.1 === * Bugfix: last line without '\n' couldn't be parsed Wed May 14 2008 Aleksey * Bugfix: empty lines were not skipped, when verifying a crc file * option '--skip-ok' to skip OK messages for successfuly verified files Tue Jan 22 2008 Aleksey * option '-a' to print all supported hash sums * Changed default behavior: if no formatting option are set, sfv header is printed only for --crc32 Wed Dec 19 2007 Aleksey * Bugfix: fixed buffer overflow for command line -p '%%%%d' * Bugfix: fixed size calculation for stdin (rhash -p '%s' - = 56 * Tiger hash optimised to be 5% faster Wed May 02 2007 Aleksey * === Version 0.8.8 === Sun Apr 22 2007 Aleksey * added options --accept and --crc-accept * added --verbose option * added --maxdepth option * added check before verifying a crc file that it isn't a binary file Mon Apr 16 2007 Aleksey * === Version 0.8.7 === * Tiger hash sum optimised for IA32 Tue Apr 10 2007 Aleksey * Bugfix: --update of sfv files worked incorrectly under windows Mon Apr 09 2007 Aleksey * implemented Tiger hash function Sun Apr 01 2007 Aleksey * added check before updating a crc file that it isn't a binary file Mon Mar 26 2007 Aleksey * === Version 0.8.6 === * Ctrl+C now prints a message and partitial statistics Sat Mar 24 2007 Aleksey * default format changed to SFV Mon Mar 19 2007 Aleksey * updating of crc files supported Wed Jan 31 2007 Aleksey * === Version 0.8.5 === * supported many short options as one argument, e.g. '-MCEr' * option -S (--sha1) changed to -H * Bugfix: program crashed under BSD while printing SFV file header Sun Nov 05 2006 Aleksey * === Version 0.8.4 === * Bugfix: errors/miss stats calculation corrected Sun Oct 29 2006 Aleksey * supported "-c -" option to check hash sums from stdin * added stdout flushing after each processed file * the program returns exit code 0 on success and 1 if an error occurred Fri Sep 08 2006 Aleksey * corrected parsing of md5-like files with star-prepended filenames Wed Apr 19 2006 Aleksey * checking of md5/sha1 files in *BSD format supported * improved I/O errors handling Mon Apr 10 2006 Aleksey * === Version 0.8.3 === * cheking of files in standard md5sum/sha1sum format supported * default output format for md5/sha1/ed2k sums changed * man page rewrited Thu Mar 30 2006 Aleksey * === Version 0.8.2 === * GCC 2.96 supported Thu Feb 23 2006 Aleksey * Bugfix: files with .SFV extension (in uppercase) were skiped while recursive checking Wed Jan 25 2006 Aleksey * === Version 0.8.1 === * option --check now works with --recursive * Bugfix: corrected output format when checking files * Bugfix: files wasn't opened as binary on Windows when checking sums Mon Jan 23 2006 Aleksey * === Version 0.8 === * documentation now distributed with windows version * some *.bat files added to windows version Sun Jan 22 2006 Aleksey * --check option added, to check hash sums files * --ansi option added (for Windows version only) * program name is parsed now to specify default sums to compute Sat Jan 14 2006 Aleksey * Bugfix: console windows version now uses OEM (DOS) character set for output * === Version 0.7 === * some fixes in sfv format output Fri Sep 16 2005 Aleksey * --recursive option added * --ed2k-link option added Fri Sep 02 2005 Aleksey * === Version 0.6 === Sun Aug 28 2005 Aleksey * Bugfix: files wasn't opened as binary on win32 * --sfv format now implies uppercase hashes Wed Aug 24 2005 Aleksey * added .spec file and Makefile 'rpm' target Sun Aug 14 2005 Aleksey * === Version 0.5 === * the first public version * win32 platform supported Mon Aug 08 2005 Aleksey * Bugfix: fixed calculation of md5/ed2k hashes for AMD64 Fri Aug 05 2005 Aleksey * === Version 0.06 === * initial linux version supporting crc32, md5, ed2k and sha1 RHash-1.3.6/INSTALL.md000066400000000000000000000026551325207677100142000ustar00rootroot00000000000000 Installation ============ Build Prerequisites ------------------- - GCC or Intel Compiler for Linux / macOS / Unix. - MinGW or MS VC++ for Windows. - (optionally) gettext library for internationalization - (optionally) OpenSSL for optimized algorithms Build and install ----------------- To compile and install the program use command ```sh ./configure && make && make install ``` The compiled program and library can be tested by command `make test test-lib` To compile using MS VC++, take the project file from /win32/vc-2010/ directory. Enabling features ----------------- RHash can use optimized algorithms of MD5, SHA1, SHA2 from the OpenSSL library. To link OpenSSL at run-time (preffered way), configure RHash as ```sh ./configure --enable-openssl-runtime ``` To link it at load-time, use options ```sh ./configure --enable-openssl --disable-openssl-runtime ``` Internationalization support can be compiled and installed by commands ```sh ./configure --enable-gettext make install install-gmo ``` Run `./configure --help` for a full list of configuration options. Building an OS native package ----------------------------- When building a package for an OS Repository, one should correctly specify system directories, e.g.: ```sh ./configure --sysconfdir=/etc --exec-prefix=/usr ``` Example of installing RHash with shared and static LibRHash library: ```sh ./configure --enable-lib-static make install install-lib-so-link ``` RHash-1.3.6/Makefile000066400000000000000000000301331325207677100142000ustar00rootroot00000000000000 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 = calc_sums.o hash_print.o common_func.o hash_update.o file.o file_mask.o file_set.o find_file.o hash_check.o output.o parse_cmdline.o rhash_main.o win_utils.o WIN_DIST_FILES = dist/MD5.bat dist/magnet.bat dist/rhashrc.sample OTHER_FILES = configure Makefile ChangeLog INSTALL.md COPYING README \ dist/rhash.spec.in dist/rhash.1 dist/rhash.1.win.sed \ tests/test_rhash.sh tests/test1K.data win32/vc-2010/rhash.vcxproj 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/rhash_timing.c librhash/rhash_timing.h \ librhash/aich.c librhash/aich.h librhash/crc32.c librhash/crc32.h \ librhash/ed2k.c librhash/ed2k.h librhash/edonr.c librhash/edonr.h \ librhash/gost.c librhash/gost.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/snefru.c librhash/snefru.h librhash/tiger.c librhash/tiger.h \ librhash/tiger_sbox.c librhash/tth.c librhash/tth.h librhash/whirlpool.c \ librhash/whirlpool.h librhash/whirlpool_sbox.c librhash/test_hashes.c \ librhash/test_hashes.h librhash/torrent.h librhash/torrent.c librhash/ustd.h \ 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/ro.po po/ru.po ALL_FILES = $(SOURCES) $(HEADERS) $(LIBRHASH_FILES) $(OTHER_FILES) $(WIN_DIST_FILES) $(I18N_FILES) SPECFILE = dist/rhash.spec LIBRHASH_PC = dist/librhash.pc RHASH_NAME = rhash RHASH_BINARY = rhash$(EXEC_EXT) CONFDIR_MACRO = -DSYSCONFDIR=\"$(SYSCONFDIR)\" RPMTOP = rpms RPMDIRS = SOURCES SPECS BUILD SRPMS RPMS INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_DATA = $(INSTALL) -m 644 all: $(BUILD_TARGETS) install: build-install-binary install-data install-symlinks $(EXTRA_INSTALL) build-static: $(RHASH_STATIC) build-shared: $(RHASH_SHARED) lib-shared: $(LIBRHASH_SHARED) lib-static: $(LIBRHASH_STATIC) 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_BZIP = $(PACKAGE_NAME)-src.tar.bz2 ARCHIVE_GZIP = $(PACKAGE_NAME)-src.tar.gz ARCHIVE_FULL = $(PACKAGE_NAME)-full-src.tar.gz ARCHIVE_DEB_GZ = $(RHASH_NAME)_$(VERSION).orig.tar.gz ARCHIVE_7Z = $(PACKAGE_NAME)-src.tar.7z ARCHIVE_ZIP = $(PACKAGE_NAME)-$(WIN_SUFFIX).zip WIN_ZIP_DIR = RHash-$(VERSION)-$(WIN_SUFFIX) dist: gzip gzip-bindings dist-full: gzip-full win-dist: zip zip: $(ARCHIVE_ZIP) dgz: check $(ARCHIVE_DEB_GZ) 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 -fs $(RHASH_BINARY) $$f$(EXEC_EXT); done cd $(MANDIR)/man1 && for f in $(SYMLINKS); do ln -fs 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) +cd librhash && $(MAKE) install-lib-static install-lib-shared: $(LIBRHASH_SHARED) +cd librhash && $(MAKE) install-lib-shared 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-$(BUILD_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: test-$(BUILD_TYPE) test-static: $(RHASH_STATIC) chmod +x tests/test_rhash.sh tests/test_rhash.sh ./$(RHASH_STATIC) test-shared: $(RHASH_SHARED) chmod +x tests/test_rhash.sh tests/test_rhash.sh --shared ./$(RHASH_SHARED) print-info: lib-$(BUILD_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_STATIC): $(OBJECTS) $(LIBRHASH_STATIC) $(CC) $(OBJECTS) $(LIBRHASH_STATIC) $(BIN_STATIC_LDFLAGS) -o $@ $(RHASH_SHARED): $(OBJECTS) $(LIBRHASH_SHARED) $(CC) $(OBJECTS) $(LIBRHASH_SHARED) $(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 platform.h calc_sums.h common_func.h \ hash_check.h file.h hash_print.h output.h parse_cmdline.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 parse_cmdline.h version.h \ win_utils.h $(CC) -c $(CFLAGS) $< -o $@ file.o: file.c file.h common_func.h win_utils.h $(CC) -c $(CFLAGS) $< -o $@ file_mask.o: file_mask.c file_mask.h common_func.h $(CC) -c $(CFLAGS) $< -o $@ file_set.o: file_set.c file_set.h calc_sums.h common_func.h hash_check.h \ hash_print.h output.h parse_cmdline.h rhash_main.h librhash/rhash.h $(CC) -c $(CFLAGS) $< -o $@ find_file.o: find_file.c platform.h find_file.h common_func.h file.h \ output.h win_utils.h $(CC) -c $(CFLAGS) $< -o $@ hash_check.o: hash_check.c hash_check.h hash_print.h common_func.h \ output.h parse_cmdline.h librhash/rhash.h $(CC) -c $(CFLAGS) $< -o $@ hash_print.o: hash_print.c hash_print.h calc_sums.h common_func.h \ hash_check.h file.h parse_cmdline.h win_utils.h librhash/rhash.h $(CC) -c $(CFLAGS) $< -o $@ hash_update.o: hash_update.c common_func.h calc_sums.h hash_check.h \ file.h file_set.h file_mask.h hash_print.h hash_update.h output.h \ parse_cmdline.h rhash_main.h win_utils.h $(CC) -c $(CFLAGS) $< -o $@ output.o: output.c platform.h output.h calc_sums.h common_func.h \ hash_check.h parse_cmdline.h rhash_main.h win_utils.h librhash/rhash.h $(CC) -c $(CFLAGS) $< -o $@ parse_cmdline.o: parse_cmdline.c parse_cmdline.h common_func.h \ file_mask.h find_file.h file.h hash_print.h output.h rhash_main.h \ win_utils.h librhash/rhash.h $(CC) -c $(CFLAGS) $< -o $@ rhash_main.o: rhash_main.c rhash_main.h calc_sums.h common_func.h \ hash_check.h file_mask.h find_file.h file.h hash_print.h hash_update.h \ parse_cmdline.h output.h win_utils.h librhash/rhash.h $(CC) -c $(CFLAGS) $< -o $@ win_utils.o: win_utils.c win_utils.h common_func.h file.h parse_cmdline.h \ rhash_main.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 -which rman 2>/dev/null && (rman -fHTML -roff dist/rhash.1 | sed -e '/ $@) dist/rhash.1.txt: dist/rhash.1 -which groff &>/dev/null && (groff -t -e -mandoc -Tascii dist/rhash.1 | sed -e 's/.\[[0-9]*m//g' > $@) cpp-doc: cppdoc_cmd -title=RHash -company=Akademgorodok -classdir=classdoc -module="cppdoc-standard" -overwrite -extensions="c,h" -languages="c=cpp,h=cpp" -generate-deprecations-list=false $(SOURCES) $(HEADERS) ./Documentation/CppDoc/index.html permissions: find . dist librhash po win32 win32/vc-2010 -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)/ gzip: check +$(MAKE) copy-dist tar czf $(ARCHIVE_GZIP) --owner=root --group=root $(PACKAGE_NAME)/ rm -rf $(PACKAGE_NAME) gzip-bindings: +cd bindings && $(MAKE) gzip ARCHIVE_GZIP=../rhash-bindings-$(VERSION)-src.tar.gz gzip-full: check clean-bindings +$(MAKE) copy-dist +cd bindings && $(MAKE) copy-dist COPYDIR=../$(PACKAGE_NAME)/bindings tar czf $(ARCHIVE_FULL) --owner=root:0 --group=root:0 $(PACKAGE_NAME)/ rm -rf $(PACKAGE_NAME) bzip: check +$(MAKE) copy-dist tar cjf $(ARCHIVE_BZIP) --owner=root:0 --group=root:0 $(PACKAGE_NAME)/ rm -rf $(PACKAGE_NAME) 7z: check +$(MAKE) copy-dist tar cf - --owner=root:0 --group=root:0 $(PACKAGE_NAME)/ | 7zr a -si $(ARCHIVE_7Z) rm -rf $(PACKAGE_NAME) $(ARCHIVE_ZIP): $(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 zip -9r $(ARCHIVE_ZIP) $(WIN_ZIP_DIR) rm -rf $(WIN_ZIP_DIR) $(ARCHIVE_DEB_GZ) : $(ALL_FILES) +$(MAKE) $(ARCHIVE_GZIP) mv -f $(ARCHIVE_GZIP) $(ARCHIVE_DEB_GZ) # rpm packaging $(SPECFILE): $(SPECFILE).in config.mak sed -e 's/@VERSION@/$(VERSION)/' $(SPECFILE).in > $(SPECFILE) rpm: gzip -for i in $(RPMDIRS); do mkdir -p $(RPMTOP)/$$i; done cp -f $(ARCHIVE_GZIP) $(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_SHARED) $(RHASH_STATIC) rm -f po/*.gmo po/*.po~ distclean: clean-local rm -f config.log config.mak $(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 compile-gmo: for f in $(I18N_FILES); do \ g=`basename $$f .po`; \ msgfmt $$f -o po/$$g.gmo; \ done 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-shared build-static lib-shared lib-static clean clean-bindings distclean clean-local \ test test-shared test-static test-lib test-libs test-lib-shared test-lib-static \ install build-install-binary install-binary install-lib-shared install-lib-static \ 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 cpp-doc mkdir-bin permissions \ bzip dgz dist dist-full gzip gzip-bindings gzip-full rpm win-dist zip RHash-1.3.6/README000066400000000000000000000047211325207677100134240ustar00rootroot00000000000000 === RHash program === RHash is a console utility for calculation and verification of magnet links and a wide range of hash sums like CRC32, MD4, MD5, SHA1, SHA256, SHA512, SHA3, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru. Hash sums are used to ensure and verify integrity of large volumes of data for a long-term storing or transferring. Program features: * Output in a predefined (SFV, BSD-like) or a user-defined format. * Calculation of Magnet links. * Ability to process directories recursively. * Updating hash files (adding hash sums of files missing in the hash file). * Calculates several hash sums in one pass. * Portability: the program works the same on Linux, Unix, macOS or Windows. === The LibRHash library === LibRHash is a professional, portable, thread-safe C library for computing a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512, SHA3, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru. Hash sums are used to ensure and verify integrity of large volumes of data for a long-term storing or transferring. Features: * Small and easy to learn interface. * Hi-level and Low-level API. * Allows calculating of several hash functions simultaneously. * Portability: the library works on Linux, *BSD and Windows. === Links === * Project Home Page: http://rhash.sourceforge.net/ * Official Releases: http://sf.net/projects/rhash/files/rhash/ * RHash hash functions descriptions http://rhash.anz.ru/hashes.php * The table of the hash functions supported by RHash https://sf.net/p/rhash/wiki/HashFunctions/ * ECRYPT: The Hash Function Zoo http://ehash.iaik.tugraz.at/wiki/The_Hash_Function_Zoo === Getting latest source code === The latest source code can be obtained from Git repository by command: git clone git://github.com/rhash/RHash.git === Notes on RHash License === The RHash program and LibRHash library are distributed under RHash License, see the COPYING file for details. In particular, the program, the library and source code can be used free of charge under the MIT, BSD, GPL, commercial or freeware license without additional restrictions. In the case the OSI-approved license is required the MIT license should be used. RHash-1.3.6/bindings/000077500000000000000000000000001325207677100143355ustar00rootroot00000000000000RHash-1.3.6/bindings/COPYING000066400000000000000000000014271325207677100153740ustar00rootroot00000000000000 RHash License Copyright (c) 2011-2014 Aleksey Kravchenko Copyright (c) 2011-2012 Sergey Basalaev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. The Software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! RHash-1.3.6/bindings/ChangeLog000066400000000000000000000013661325207677100161150ustar00rootroot00000000000000Fri 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.3.6/bindings/Makefile000066400000000000000000000066121325207677100160020ustar00rootroot00000000000000VERSION := $(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 ?= python PERL ?= perl CP = cp -l --parents PERL_OPTIMIZE = -O2 -g -Wall ARCHIVE_GZIP = rhash-bindings-$(VERSION)-src.tar.gz COPYDIR = rhash-bindings-$(VERSION) 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))) configure-perl: perl/Makefile configure-ruby: ruby/Makefile configure-php: php/Makefile perl/Makefile: perl/Makefile.PL cd perl && USE_SYSTEM_LIBRHASH=1 $(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: # not required 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: $(PYTHON) python/test_rhash.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 -u` sed -e 's/^\([^ ]*\)\( .*\)\?/cp perl\/\1 $(PERL_PKG)\/\1/' perl/MANIFEST > _cpy.sh sh _cpy.sh && rm -f _cpy.sh cp ../librhash/*.[hc] $(PERL_PKG)/librhash/ cp perl/MANIFEST $(PERL_PKG)/ 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)/ distclean: +$(MAKE) -C java distclean +$(MAKE) -C mono clean +[ ! -f ruby/Makefile ] || $(MAKE) -C ruby distclean +[ ! -f perl/Makefile ] || $(MAKE) -C perl distclean [ ! -f php/configure ] || (cd php && phpize --clean) rm -f python/*.pyc RHash-1.3.6/bindings/java/000077500000000000000000000000001325207677100152565ustar00rootroot00000000000000RHash-1.3.6/bindings/java/.gitignore000066400000000000000000000000361325207677100172450ustar00rootroot00000000000000classes/* dist/* *.so *.class RHash-1.3.6/bindings/java/Makefile000066400000000000000000000061311325207677100167170ustar00rootroot00000000000000#!/usr/bin/make -f # This file is a part of Java Bindings for Librhash # Copyright (c) 2011-2012, Sergey Basalaev # Librhash is (c) 2011-2012, Aleksey Kravchenko # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. Use it at your own risk! 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.3.6/bindings/java/native/000077500000000000000000000000001325207677100165445ustar00rootroot00000000000000RHash-1.3.6/bindings/java/native/Makefile000066400000000000000000000026511325207677100202100ustar00rootroot00000000000000#!/usr/bin/make -f # This file is a part of Java Bindings for Librhash # Copyright (c) 2011-2012, Sergey Basalaev # Librhash is (c) 2011-2012, Aleksey Kravchenko # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. Use it at your own risk! CC = gcc CFLAGS = -g -O2 LDFLAGS = LIBRHASH_INC = LIBRHASH_LD = ALLLDFLAGS = $(LDFLAGS) -lrhash $(LIBRHASH_LD) ALLCFLAGS = $(CFLAGS) $(LIBRHASH_INC) -fPIC #Platform dependent JNI_CFLAGS = -I/usr/lib/jvm/default-java/include 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.3.6/bindings/java/native/bindings.c000066400000000000000000000146551325207677100205200ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ #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.3.6/bindings/java/native/bindings.h000066400000000000000000000064621325207677100205220ustar00rootroot00000000000000/* 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.3.6/bindings/java/native/digest.c000066400000000000000000000027111325207677100201700ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ #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.3.6/bindings/java/native/digest.h000066400000000000000000000030101325207677100201660ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ /* 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.3.6/bindings/java/src/000077500000000000000000000000001325207677100160455ustar00rootroot00000000000000RHash-1.3.6/bindings/java/src/org/000077500000000000000000000000001325207677100166345ustar00rootroot00000000000000RHash-1.3.6/bindings/java/src/org/sf/000077500000000000000000000000001325207677100172445ustar00rootroot00000000000000RHash-1.3.6/bindings/java/src/org/sf/rhash/000077500000000000000000000000001325207677100203515ustar00rootroot00000000000000RHash-1.3.6/bindings/java/src/org/sf/rhash/Bindings.java000066400000000000000000000105321325207677100227520ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ 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.3.6/bindings/java/src/org/sf/rhash/Digest.java000066400000000000000000000100641325207677100224340ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ 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.3.6/bindings/java/src/org/sf/rhash/HashType.java000066400000000000000000000063111325207677100227420ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, 2014, Sergey Basalaev * Librhash is (c) 2011-2014, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ package org.sf.rhash; /** * Type of hashing algorithm. * Supported algorithms are MD4, MD5, SHA1/SHA2, Tiger, * DC++ TTH, BitTorrent BTIH, AICH, EDonkey 2000 hash, GOST R 34.11-94, * RIPEMD-160, HAS-160, 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. */ GOST(1 << 11), GOST_CRYPTOPRO(1 << 12), /** HAS-160 hash. */ HAS160(1 << 13), /** Snefru-128 hash. */ SNEFRU128(1 << 14), /** Snefru-256 hash. */ SNEFRU256(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); /** 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() { //TODO: rhash_get_digest_size return -1; } } RHash-1.3.6/bindings/java/src/org/sf/rhash/RHash.java000066400000000000000000000342441325207677100222300ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ 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 with given hashes. * * @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 with given hashes. * * @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 hashes 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 specified filename * and hashes for given algorithms. Only hashes that were * computed by this RHash are included. * * @param filename file name to include in magnet, may 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 for given filename. * Magnet includes all hashes that were computed * by this RHash. * * @param filename file name to include in magnet, may 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.3.6/bindings/java/src/org/sf/rhash/package-info.java000066400000000000000000000053451325207677100235470ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ /** * Java bindings for librhash. * Librhash is a library for computing and verifying hash sums. * 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 HashTypes 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.3.6/bindings/java/test/000077500000000000000000000000001325207677100162355ustar00rootroot00000000000000RHash-1.3.6/bindings/java/test/RHashTest.java000066400000000000000000000101351325207677100207450ustar00rootroot00000000000000import 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("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(GOST).toString()); assertEquals("e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", r.getDigest(GOST_CRYPTOPRO).toString()); assertEquals("4872bcbc4cd0f0a9dc7c2f7045e5b43b6c830db8", r.getDigest(HAS160).toString()); assertEquals("bf5ce540ae51bc50399f96746c5a15bd", r.getDigest(SNEFRU128).toString()); assertEquals("45161589ac317be0ceba70db2573ddda6e668a31984b39bf65e4b664b584c63d", r.getDigest(SNEFRU256).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()); 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.3.6/bindings/mono/000077500000000000000000000000001325207677100153055ustar00rootroot00000000000000RHash-1.3.6/bindings/mono/.gitignore000066400000000000000000000001211325207677100172670ustar00rootroot00000000000000bin RHash.dll RHash.dll.mdb RHash.pidb RHash.tree RHash.userprefs RHash.zip html RHash-1.3.6/bindings/mono/AssemblyInfo.cs000066400000000000000000000035401325207677100202310ustar00rootroot00000000000000/* * This file is a part of Mono Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ using System.Reflection; using System.Runtime.CompilerServices; // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. [assembly: AssemblyTitle("RHash")] [assembly: AssemblyDescription(".NET/Mono bindings for librhash")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("(c) 2011, Sergey Basalaev")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. [assembly: AssemblyVersion("1.0.1.1")] // The following attributes are used to specify the signing key for the assembly, // if desired. See the Mono documentation for more information about signing. [assembly: AssemblyDelaySign(false)] //[assembly: AssemblyKeyFile("RHash.snk")] RHash-1.3.6/bindings/mono/Bindings.cs000066400000000000000000000037751325207677100174050ustar00rootroot00000000000000/* * This file is a part of Mono Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ using System; using System.Runtime.InteropServices; using System.Text; namespace RHash { /* Pointer to native structure. */ sealed class Bindings { private const string librhash = "librhash.dll"; private Bindings() { } static Bindings() { rhash_library_init(); } [DllImport (librhash)] public static extern void rhash_library_init(); [DllImport (librhash)] public static extern IntPtr rhash_init(uint hash_ids); [DllImport (librhash)] public static extern void rhash_update(IntPtr ctx, byte[] message, int length); //may crash, rhash_final actually have 2 arguments [DllImport (librhash)] public static extern void rhash_final(IntPtr ctx, IntPtr unused); [DllImport (librhash)] public static extern void rhash_reset(IntPtr ctx); [DllImport (librhash)] public static extern void rhash_free(IntPtr ctx); [DllImport (librhash, CharSet=CharSet.Ansi)] public static extern void rhash_print(StringBuilder output, IntPtr ctx, uint hash_id, int flags); [DllImport (librhash)] public static extern int rhash_print_magnet(StringBuilder output, String filepath, IntPtr ctx, uint hash_mask, int flags); } } RHash-1.3.6/bindings/mono/HashType.cs000066400000000000000000000043201325207677100173600ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, 2014, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ using System; namespace RHash { /* * Type of hashing algorithm. * Supported algorithms are MD4, MD5, SHA1/SHA2, Tiger, * DC++ TTH, BitTorrent BTIH, AICH, EDonkey 2000 hash, GOST R 34.11-94, * RIPEMD-160, HAS-160, EDON-R 256/512, Whirlpool and Snefru-128/256. */ public enum HashType : uint { /* 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. */ GOST = 1 << 11, GOST_CRYPTOPRO = 1 << 12, /* HAS-160 hash. */ HAS160 = 1 << 13, /* Snefru-128 hash. */ SNEFRU128 = 1 << 14, /* Snefru-256 hash. */ SNEFRU256 = 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 } } RHash-1.3.6/bindings/mono/Hasher.cs000066400000000000000000000122231325207677100170460ustar00rootroot00000000000000/* * This file is a part of Java Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ using System; using System.IO; using System.Text; namespace RHash { public sealed class Hasher { private const int DEFAULT = 0x0; /* output as binary message digest */ private const int RAW = 0x1; /* print as a hexadecimal string */ private const int HEX = 0x2; /* print as a base32-encoded string */ private const int BASE32 = 0x3; /* print as a base64-encoded string */ private const int BASE64 = 0x4; /* Print as an uppercase string. */ private const int UPPERCASE = 0x8; /* Reverse hash bytes. */ private const int REVERSE = 0x10; /* Print file size. */ private const int FILESIZE = 0x40; private uint hash_ids; /* Pointer to the native structure. */ private IntPtr ptr; public Hasher (HashType hashtype) { this.hash_ids = (uint)hashtype; this.ptr = Bindings.rhash_init(hash_ids); } public Hasher (uint hashmask) { this.hash_ids = hashmask; this.ptr = Bindings.rhash_init(hash_ids); if (ptr == IntPtr.Zero) throw new ArgumentException("Invalid mask of hashes", "hashmask"); } ~Hasher() { if (ptr != IntPtr.Zero) { Bindings.rhash_free(ptr); ptr = IntPtr.Zero; } } public Hasher Update(byte[] buf) { Bindings.rhash_update(ptr, buf, buf.Length); return this; } public Hasher Update(byte[] buf, int len) { if (len < 0 || len >= buf.Length) { throw new IndexOutOfRangeException(); } Bindings.rhash_update(ptr, buf, len); return this; } public Hasher UpdateFile(string filename) { Stream file = new FileStream(filename, FileMode.Open); byte[] buf = new byte[8192]; int len = file.Read(buf, 0, 8192); while (len > 0) { Bindings.rhash_update(ptr, buf, len); len = file.Read(buf, 0, 8192); } file.Close(); return this; } public void Finish() { Bindings.rhash_final(ptr, IntPtr.Zero); } public void Reset() { Bindings.rhash_reset(ptr); } public override string ToString() { StringBuilder sb = new StringBuilder(130); Bindings.rhash_print(sb, ptr, 0, 0); return sb.ToString(); } public string ToString(HashType type) { if ((hash_ids & (uint)type) == 0) { throw new ArgumentException("This hasher does not support hash type "+type, "type"); } StringBuilder sb = new StringBuilder(130); Bindings.rhash_print(sb, ptr, (uint)type, 0); return sb.ToString(); } public string ToHex(HashType type) { if ((hash_ids & (uint)type) == 0) { throw new ArgumentException("This hasher does not support hash type "+type, "type"); } StringBuilder sb = new StringBuilder(130); Bindings.rhash_print(sb, ptr, (uint)type, HEX); return sb.ToString(); } public string ToBase32(HashType type) { if ((hash_ids & (uint)type) == 0) { throw new ArgumentException("This hasher does not support hash type "+type, "type"); } StringBuilder sb = new StringBuilder(130); Bindings.rhash_print(sb, ptr, (uint)type, BASE32); return sb.ToString(); } public string ToBase64(HashType type) { if ((hash_ids & (uint)type) == 0) { throw new ArgumentException("This hasher does not support hash type "+type, "type"); } StringBuilder sb = new StringBuilder(130); Bindings.rhash_print(sb, ptr, (uint)type, BASE32); return sb.ToString(); } public string ToRaw(HashType type) { if ((hash_ids & (uint)type) == 0) { throw new ArgumentException("This hasher does not support hash type "+type, "type"); } StringBuilder sb = new StringBuilder(130); Bindings.rhash_print(sb, ptr, (uint)type, RAW); return sb.ToString(); } public string GetMagnet(string filepath) { return GetMagnet(filepath, hash_ids); } public string GetMagnet(string filepath, uint hashmask) { int len = Bindings.rhash_print_magnet(null, filepath, ptr, hashmask, FILESIZE); StringBuilder sb = new StringBuilder(len); Bindings.rhash_print_magnet(sb, filepath, ptr, hashmask, FILESIZE); return sb.ToString(); } public static string GetHashForMsg(byte[] buf, HashType type) { return new Hasher(type).Update(buf).ToString(type); } public static string GetHashForFile(string filename, HashType type) { return new Hasher(type).UpdateFile(filename).ToString(type); } public static string GetMagnetFor(string filepath, uint hashmask) { return new Hasher(hashmask).UpdateFile(filepath).GetMagnet(filepath); } } } RHash-1.3.6/bindings/mono/Makefile000066400000000000000000000026631325207677100167540ustar00rootroot00000000000000#!/usr/bin/make -f # This file is a part of Mono Bindings for Librhash # Copyright (c) 2011-2012, Sergey Basalaev # Librhash is (c) 2011-2012, Aleksey Kravchenko # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. Use it at your own risk! 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.3.6/bindings/mono/RHash.csproj000066400000000000000000000034141325207677100175360ustar00rootroot00000000000000 Debug AnyCPU 10.0.0 2.0 {2EC1635A-308E-46E4-B016-017C2AF3CDD9} Library RHash RHash v4.0 .NET/Mono bindings for librhash 1.0 true full false bin\Debug DEBUG prompt 4 false none false bin\Release prompt 4 false RHash-1.3.6/bindings/mono/RHash.dll.config000066400000000000000000000002651325207677100202560ustar00rootroot00000000000000 RHash-1.3.6/bindings/mono/RHash.sln000066400000000000000000000022301325207677100170250ustar00rootroot00000000000000 Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RHash", "RHash.csproj", "{2EC1635A-308E-46E4-B016-017C2AF3CDD9}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {2EC1635A-308E-46E4-B016-017C2AF3CDD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2EC1635A-308E-46E4-B016-017C2AF3CDD9}.Debug|Any CPU.Build.0 = Debug|Any CPU {2EC1635A-308E-46E4-B016-017C2AF3CDD9}.Release|Any CPU.ActiveCfg = Release|Any CPU {2EC1635A-308E-46E4-B016-017C2AF3CDD9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(MonoDevelopProperties) = preSolution StartupItem = RHash.csproj Policies = $0 $0.DotNetNamingPolicy = $1 $1.DirectoryNamespaceAssociation = None $1.ResourceNamePolicy = FileFormatDefault $0.StandardHeader = $2 $2.Text = $2.IncludeInNewFiles = True description = .NET/Mono bindings for librhash version = 1.0 EndGlobalSection EndGlobal RHash-1.3.6/bindings/mono/RHash.snk000066400000000000000000000011241325207677100170250ustar00rootroot00000000000000$RSA2/o#&٢*slҺ@Ȉ_Υ|N=:QEʧ|PD`*/vlMaQOFDR%52Kְś9Hn3T! G_ RD]#*8YT}`o 3S5FC\l髪j@*#ūn,3>~?#iE%yr dwn~ttj7{E ;>4f|U>;ve}9 Xb";oT{*edk&z++87֍N- Z6^cݥC[OC8g: 4:1> RHash 1.0.1.1 System.Enum Type of hashing algorithm. Supported algorithms are MD4, MD5, SHA1/SHA2, Tiger, DC++ TTH, BitTorrent BTIH, AICH, EDonkey 2000 hash, GOST R 34.11-94, RIPEMD-160, HAS-160, EDON-R 256/512, Whirlpool and Snefru-128/256. Constants may be OR-combined to form mask of hashes. Field 1.0.1.1 RHash.HashType eMule AICH. Field 1.0.1.1 RHash.HashType BitTorrent info hash. Field 1.0.1.1 RHash.HashType CRC32 checksum. Field 1.0.1.1 RHash.HashType EDonkey 2000 hash. Field 1.0.1.1 RHash.HashType EDON-R 256. Field 1.0.1.1 RHash.HashType EDON-R 512. Field 1.0.1.1 RHash.HashType GOST R 34.11-94. Field 1.0.1.1 RHash.HashType GOST R 34.11-94, CryptoPro version. Field 1.0.1.1 RHash.HashType HAS-160 hash. Field 1.0.1.1 RHash.HashType MD4 hash. Field 1.0.1.1 RHash.HashType MD5 hash. Field 1.0.1.1 RHash.HashType RIPEMD-160 hash. Field 1.0.1.1 RHash.HashType SHA-1 hash. Field 1.0.1.1 RHash.HashType SHA-224 hash. Field 1.0.1.1 RHash.HashType SHA-256 hash. Field 1.0.1.1 RHash.HashType SHA3-224 hash. Field 1.0.1.1 RHash.HashType SHA3-256 hash. Field 1.0.1.1 RHash.HashType SHA3-384 hash. Field 1.0.1.1 RHash.HashType SHA3-512 hash. Field 1.0.1.1 RHash.HashType SHA-384 hash. Field 1.0.1.1 RHash.HashType SHA-512 hash. Field 1.0.1.1 RHash.HashType Snefru-128 hash. Field 1.0.1.1 RHash.HashType Snefru-256 hash. Field 1.0.1.1 RHash.HashType Tiger hash. Field 1.0.1.1 RHash.HashType Tiger tree hash. Field 1.0.1.1 RHash.HashType Whirlpool hash. RHash-1.3.6/bindings/mono/doc/RHash/Hasher.xml000066400000000000000000000451221325207677100210170ustar00rootroot00000000000000 RHash 1.0.1.1 System.Object Incremental hasher. This class allows you to do incremental hashing for set of hashing algorithms. Constructor 1.0.1.1 Type of hashing algorithm. Creates new Hasher to compute message digest for given type. To be added. Constructor 1.0.1.1 Mask created of one or more values. Creates new Hasher to compute message digests for given set of hashing algorithms. Mask should be created from ORed HashType values. The next example will create Hasher that computes both CRC32 and MD5 sums: new Hasher((uint)HashType.CRC32 | (uint)HashType.MD5); Argument is zero or contains invalid bits. Method 1.0.1.1 System.Void Called by garbage collector to free native resources. To be added. Method 1.0.1.1 System.Void Finishes calculation of hashes. Processes any buffered data and finishes computation of hash sums. Method 1.0.1.1 System.String File to compute hash for. Type of hash to compute. Computes message digest for given file. Message digest as returned by . To be added. Method 1.0.1.1 System.String Binary message to compute hash for. Type of hash to compute. Computes message digest for given binary message. Message digest, as returned by . To be added. Method 1.0.1.1 System.String File path to be included in magnet. May be null. Generates magnet link with given filename. Magnet link. Magnet includes all hashes computed by this hasher. If filepath is null then returned magnet does not contain a filename. Method 1.0.1.1 System.String File path to be included in magnet. May be null. Mask created from one or more values. Generates magnet link with given filename and hashes. Magnet link. Only hashes that were computed by this Hasher are included in the output. If filepath is null then returned magnet does not contain a filename. Method 1.0.1.1 System.String File to process. Mask created of one or more values. Generates magnet for specified file with given hashes. Magnet link. Returned magnet includes file name and all computed hashes. Method 1.0.1.1 System.Void Resets this Hasher to initial state. The Hasher becomes available to process new data chunks. Note, that this method returns Hasher to the state after creating the object, NOT the state when hashing continues. Therefore, all previously calculated hashes are lost and process starts from the very beginning. Method 1.0.1.1 System.String Type of hashing algorithm. Returns value of computed digest as base32 string. Message digest in form of base32 string. To be added. This Hasher does not compute hash of given type. Method 1.0.1.1 System.String Type of hashing algorithm. Returns value of computed digest as base64 string. Message digest in form of base64 string. To be added. This Hasher does not compute hash of given type. Method 1.0.1.1 System.String Type of hashing algorithm. Returns value of computed digest as hexadecimal string. Message digest in form of hexadecimal string. To be added. This Hasher does not compute hash of given type. Method 1.0.1.1 System.String Type of hashing algorithm. Returns value of computed digest as raw bytes encoded in ANSI string. Message digest as raw bytes encoded in an ANSI string. To be added. This Hasher does not compute hash of given type. Method 1.0.1.1 System.String Returns value of computed digest as string in default format. Message digest as string. For Hasher created using constructor, this method returns the same string as method with the hash type used in constructor. Method 1.0.1.1 System.String Type of hashing algorithm. Returns value of computed digest as string in default format. Message digest for given hashing algorithm. If default output for hashing algorithm is base32 then returned value is the same as if method was called; otherwise value is the same as returned by method. This Hasher does not compute hash of given type. Method 1.0.1.1 RHash.Hasher Data for hashing. Updates this Hasher with new data chunk. This hasher. To be added. Method 1.0.1.1 RHash.Hasher Data for hashing. Number of bytes in array to hash. Updates this Hasher with new data chunk. This Hasher. To be added. Argument len is negative or greater than buffer length. Method 1.0.1.1 RHash.Hasher Name of the file to process. Updates this Hasher with data from given file. This Hasher. To be added. RHash-1.3.6/bindings/mono/doc/index.xml000066400000000000000000000037531325207677100177130ustar00rootroot00000000000000 [00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00 00 24 00 00 52 53 41 31 00 04 00 00 11 00 00 00 2f cc 17 f0 6f bb a5 89 23 fa 26 a6 d9 a2 2a 73 c1 0f 82 84 6c e3 b5 d2 ba a3 82 ef 40 c8 88 8d 16 98 9d 5f a5 ce a5 a8 7c 4e 3d 9f 3a f9 ff 99 a4 d8 c2 51 a8 45 ca a7 df 00 7c 92 07 50 44 60 2a 2f 9c 08 76 6c 4d 61 1a 51 4f 46 44 ff 8f 52 98 25 e8 04 08 35 ee a5 ac 32 b2 eb 4b d6 b0 b0 c5 9b 39 48 0f c7 c9 6e 16 9d b9 33 aa 9e f4 54 21 a2 8d 0a 47 9b fd 15 5f c2 17 b6 09 9f 52 8f ] System.Reflection.AssemblyCompany("") System.Reflection.AssemblyConfiguration("") System.Reflection.AssemblyCopyright("(c) 2011, Sergey Basalaev") System.Reflection.AssemblyDescription(".NET/Mono bindings for librhash") System.Reflection.AssemblyProduct("") System.Reflection.AssemblyTitle("RHash") System.Reflection.AssemblyTrademark("") System.Runtime.CompilerServices.RuntimeCompatibility(WrapNonExceptionThrows=true) To be added. (c) 2011, Sergey Basalaev RHash RHash-1.3.6/bindings/mono/doc/ns-RHash.xml000066400000000000000000000024161325207677100202220ustar00rootroot00000000000000 .NET/Mono bindings to librhash. Librhash is a library for computing and verifying hash sums that supports many hashing algorithms. This module provides class for incremental hashing that utilizes the library. Sample usage of it you can see from the following example: Hasher hasher = new Hasher((uint)HashType.CRC32 | (uint)HashType.MD5); hasher.Update(bytebuffer).UpdateFile("SomeFile.txt"); hasher.Finish(); Console.WriteLine(hasher.ToHex(HashType.CRC32)); Console.WriteLine(hasher.ToBase32(HashType.MD5)); In this example object is first created for a set of hashing algorithms. Next, data for hashing is given in chunks with methods Update() and UpdateFile(). Finally, call Finish() to end up all remaining calculations. To receive text represenation of the message digest use one of methods ToHex(), ToBase32() and ToBase64(). Binary message digest may be obtained with ToRaw(). All of these methods accept algorithm value as argument. It may be omitted if Hasher was created to compute hash for only a single hashing algorithm. RHash-1.3.6/bindings/mono/test/000077500000000000000000000000001325207677100162645ustar00rootroot00000000000000RHash-1.3.6/bindings/mono/test/12345.txt000066400000000000000000000000061325207677100174770ustar00rootroot0000000000000012345 RHash-1.3.6/bindings/mono/test/Makefile000066400000000000000000000017761325207677100177370ustar00rootroot00000000000000#!/usr/bin/make -f # This file is a part of Mono Bindings for Librhash # Copyright (c) 2011-2012, Sergey Basalaev # Librhash is (c) 2011-2012, Aleksey Kravchenko # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. Use it at your own risk! MONO?=mono CS?=mcs MONO_PATH?=.. test: Test.exe MONO_PATH="$(MONO_PATH)" $(MONO) Test.exe Test.exe: Test.cs $(CS) -r:RHash.dll -lib:.. Test.cs clean: rm -f Test.exe RHash-1.3.6/bindings/mono/test/Test.cs000066400000000000000000000131621325207677100175350ustar00rootroot00000000000000/* * This file is a part of Mono Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ using System; using System.Collections.Generic; using RHash; class Test { static void Main(string[] args) { byte[] testbytes = {(byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'\n'}; Dictionary hashes = new Dictionary(); hashes.Add(HashType.CRC32, "261dafe6"); hashes.Add(HashType.MD4, "b1a45cdad19cb02482323fac9cea9b9f"); hashes.Add(HashType.MD5, "d577273ff885c3f84dadb8578bb41399"); hashes.Add(HashType.SHA1, "2672275fe0c456fb671e4f417fb2f9892c7573ba"); hashes.Add(HashType.SHA224, "ea2fa9708c96b4acb281be31fa98827addc5017305b7a038a3fca413"); hashes.Add(HashType.SHA256, "f33ae3bc9a22cd7564990a794789954409977013966fb1a8f43c35776b833a95"); hashes.Add(HashType.SHA384, "4e1cbb008acaa65ba788e3f150f7a8689c8fca289a57a65ef65b28f11ba61e59c3f4ddf069ca9521a9ac0e02eade4dae"); hashes.Add(HashType.SHA512, "f2dc0119c9dac46f49d3b7d0be1f61adf7619b770ff076fb11a2f61ff3fcba6b68d224588c4983670da31b33b4efabd448e38a2fda508622cc33ff8304ddf49c"); hashes.Add(HashType.TIGER, "6a31f8b7b80bab8b45263f56b5f609f93daf47d0a086bda5"); hashes.Add(HashType.TTH, "dctamcmte5tqwam5afghps2xpx3yeozwj2odzcq"); //hashes.Add(HashType.BTIH, "d4344cf79b89e4732c6241e730ac3f945d7a774c"); hashes.Add(HashType.AICH, "ezzcox7ayrlpwzy6j5ax7mxzrewhk452"); hashes.Add(HashType.ED2K, "b1a45cdad19cb02482323fac9cea9b9f"); hashes.Add(HashType.WHIRLPOOL, "0e8ce019c9d5185d2103a4ff015ec92587da9b22e77ad34f2eddbba9705b3602bc6ede67f5b5e4dd225e7762208ea54895b26c39fc550914d6eca9604b724d11"); hashes.Add(HashType.GOST, "0aaaf17200323d024437837d6f6f6384a4a108474cff03cd349ac12776713f5f"); hashes.Add(HashType.GOST_CRYPTOPRO, "2ed45a995ffdd7a2e5d9ab212c91cec5c65448e6a0840749a00f326ccb0c936d"); hashes.Add(HashType.RIPEMD160, "ead888178685c5d3a0400befba9188e4da3d5144"); hashes.Add(HashType.HAS160, "c7589afd23462e76703b1f7a031010eec70180d4"); hashes.Add(HashType.SNEFRU128, "d559a2b62f6f44111324f85208723707"); hashes.Add(HashType.SNEFRU256, "1b59927d85a9349a87796620fe2ff401a06a7ba48794498ebab978efc3a68912"); hashes.Add(HashType.EDONR256, "c3d2bbfd63f7461a806f756bf4efeb224036331a9c1d867d251e9e480b18e6fb"); hashes.Add(HashType.EDONR512, "a040056378fbd1f9a528677defd141c964fab9c429003fecf2eadfc20c8980cf2e083a1b4e74d5369af3cc0537bcf9b386fedf3613c9ee6c44f54f11bcf3feae"); hashes.Add(HashType.SHA3_224, "952f55abd73d0efd9656982f65c4dc837a6a129de02464b85d04cb18"); hashes.Add(HashType.SHA3_256, "f627c8f9355399ef45e1a6b6e5a9e6a3abcb3e1b6255603357bffa9f2211ba7e"); hashes.Add(HashType.SHA3_384, "0529075e85bcdc06da94cbc83c53b7402c5032440210a1a24d9ccca481ddbd6c1309ae0ef23741f13352a4f3382dee51"); hashes.Add(HashType.SHA3_512, "fdd7e7b9655f4f0ef89056e864a2d2dce3602404480281c88455e3a98f728aa08b3f116e6b434200a035e0780d9237ca367c976c5506f7c6f367e6b65447d97c"); Console.WriteLine("\nTests: hashes for message"); int errcount1 = 0; foreach (HashType t in hashes.Keys) { string mustbe = hashes[t]; string got = Hasher.GetHashForMsg(testbytes, t); if (!got.Equals(mustbe)) { Console.WriteLine("Test for {0} failed: expected '{1}', got '{2}'\n", t, mustbe, got); errcount1++; } } Console.WriteLine("{0} tests / {1} failed\n", hashes.Count, errcount1); Console.WriteLine("\nTests: hashes for file"); int errcount2 = 0; foreach (HashType t in hashes.Keys) { string mustbe = hashes[t]; string got = Hasher.GetHashForFile("12345.txt", t); if (!got.Equals(mustbe)) { Console.WriteLine("Test for {0} failed: expected '{1}', got '{2}'\n", t, mustbe, got); errcount2++; } } Console.WriteLine("{0} tests / {1} failed\n", hashes.Count, errcount2); Console.WriteLine("\nTests: magnet links"); int errcount3 = 0; { // magnet by static method string mustbe = "magnet:?xl=6&dn=12345.txt&xt=urn:crc32:261dafe6&xt=urn:md5:d577273ff885c3f84dadb8578bb41399"; string got = Hasher.GetMagnetFor("12345.txt", (uint)HashType.CRC32 | (uint)HashType.MD5); if (!got.Equals(mustbe)) { Console.WriteLine("Magnet by static method test failed: expected '{0}', got '{1}'\n", mustbe, got); errcount3++; } // magnet with null argument Hasher hasher = new Hasher((uint)HashType.CRC32 | (uint)HashType.MD5); hasher.UpdateFile("12345.txt").Finish(); mustbe = "magnet:?xl=6&xt=urn:crc32:261dafe6"; got = hasher.GetMagnet(null, (uint)HashType.CRC32 | (uint)HashType.AICH); if (!got.Equals(mustbe)) { Console.WriteLine("Magnet with null argument test failed: expected '{0}', got '{1}'\n", mustbe, got); errcount3++; } } Console.WriteLine("{0} tests / {1} failed\n", 2, errcount3); System.Environment.ExitCode = errcount1 + errcount2 + errcount3; } } RHash-1.3.6/bindings/perl/000077500000000000000000000000001325207677100152775ustar00rootroot00000000000000RHash-1.3.6/bindings/perl/.gitignore000066400000000000000000000000641325207677100172670ustar00rootroot00000000000000blib/ Makefile Rhash.c Rhash.bs pm_to_blib MYMETA.* RHash-1.3.6/bindings/perl/MANIFEST000066400000000000000000000004611325207677100164310ustar00rootroot00000000000000Makefile.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.3.6/bindings/perl/META.json000066400000000000000000000022671325207677100167270ustar00rootroot00000000000000{ "abstract" : "Library for computing hash sums and magnet links", "author" : [ "Aleksey Kravchenko" ], "dynamic_config" : 0, "generated_by" : "ExtUtils::MakeMaker version 6.84, CPAN::Meta::Converter version 2.133380", "license" : [ "unrestricted" ], "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://sourceforge.net/p/rhash/bugs/" }, "homepage" : "http://rhash.sf.net/", "license" : [ "http://rhash.anz.ru/license.php" ], "repository" : { "url" : "https://github.com/rhash/RHash" } }, "version" : "0.94" } RHash-1.3.6/bindings/perl/META.yml000066400000000000000000000012721325207677100165520ustar00rootroot00000000000000--- abstract: 'Library for computing hash sums 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: unrestricted 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://sourceforge.net/p/rhash/bugs/ homepage: http://rhash.sf.net/ license: http://rhash.anz.ru/license.php repository: https://github.com/rhash/RHash version: 0.94 RHash-1.3.6/bindings/perl/Makefile.PL000066400000000000000000000051611325207677100172540ustar00rootroot00000000000000use strict; use warnings; use ExtUtils::MakeMaker; use File::Copy; my $libs = ''; my $inc = ''; my $obj = ''; my $clean = ''; # set the location of LibRHash headers and the linking flags $inc = $ENV{'LIBRHASH_INC'} if defined($ENV{'LIBRHASH_INC'}); if(defined($ENV{'LIBRHASH_LD'}) && $ENV{'LIBRHASH_LD'} =~ /-L/) { $libs = $ENV{'LIBRHASH_LD'} . ' ' . $libs; } # use a system-wide librhash $libs = '-lrhash' if (defined($ENV{'USE_SYSTEM_LIBRHASH'})); # 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; } my $local_dir = 'librhash'; if($inc eq '' && $libs eq '' && -f $local_dir . '/rhash.h') { # use the local version of librhash print "Using builtin LibRHash\n"; $inc = '-I' . $local_dir; my @c_files = copy_c_files($local_dir); $clean = join(' ', @c_files); $obj = join(' ', map { s/\.c$/\$(OBJ_EXT)/; $_ } @c_files) . ' '; } # 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 hash sums and magnet links', AUTHOR => 'Aleksey Kravchenko', VERSION_FROM => 'Rhash.pm', # finds $VERSION OPTIONAL( '6.31', LICENSE => 'unrestricted', ), 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/', license => 'http://rhash.anz.ru/license.php', bugtracker => 'https://sourceforge.net/p/rhash/bugs/', repository => 'https://github.com/rhash/RHash', }, }, ), LIBS => [ $libs ], DEFINE => '', # e.g., '-DHAVE_SOMETHING' INC => $inc, # e.g., '-I/usr/include/other' OBJECT => $obj . 'Rhash$(OBJ_EXT)', clean => { FILES => $clean, }, ); RHash-1.3.6/bindings/perl/README000066400000000000000000000022361325207677100161620ustar00rootroot00000000000000 Crypt::Rhash module allows to compute various hash sums and magnet links. The following hash sums are supported: CRC32, MD4, MD5, SHA1, SHA256, SHA512, SHA3, Tiger, TTH, Torrent BTIH, AICH, ED2K, GOST R 34.11-94, 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 ------- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! RHash-1.3.6/bindings/perl/Rhash.pm000066400000000000000000000301761325207677100167110ustar00rootroot00000000000000package Crypt::Rhash; use 5.008008; 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_MD4 RHASH_MD5 RHASH_SHA1 RHASH_TIGER RHASH_TTH RHASH_BTIH RHASH_ED2K RHASH_AICH RHASH_WHIRLPOOL RHASH_RIPEMD160 RHASH_GOST RHASH_GOST_CRYPTOPRO RHASH_HAS160 RHASH_SNEFRU128 RHASH_SNEFRU256 RHASH_SHA224 RHASH_SHA256 RHASH_SHA384 RHASH_SHA512 RHASH_EDONR256 RHASH_EDONR512 RHASH_SHA3_224 RHASH_SHA3_256 RHASH_SHA3_384 RHASH_SHA3_512 RHASH_ALL)] ); Exporter::export_tags( ); Exporter::export_ok_tags( qw(Functions Constants) ); our $VERSION = '0.94'; require XSLoader; XSLoader::load('Crypt::Rhash', $VERSION); ############################################################################## # ids 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_GOST => 0x800; use constant RHASH_GOST_CRYPTOPRO => 0x1000; use constant RHASH_HAS160 => 0x2000; use constant RHASH_SNEFRU128 => 0x4000; use constant RHASH_SNEFRU256 => 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_ALL => 0x3FFFFFF; ############################################################################## # Rhash class methods # Rhash object constructor sub new { my $hash_id = $_[1] or die "hash_id not specified"; my $context = rhash_init(scalar($hash_id)) or return undef; my $self = { context => $context, }; return bless $self; } # 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}); } ############################################################################## # Hash 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($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_mask) = @_; return rhash_print_magnet($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" if $field =~ /^(rhash_|raw2)/; die "no arguments specified to $field()" if !@_; die "the $field() argument is undefined" if !defined $self; ($type = ref($self)) && $type eq $pkg || die "the $field() argument is not a $pkg reference"; my $text = (exists $self->{$field} ? "is not accessible" : "does not exist"); die "the method $field() $text in the class $pkg"; } # static functions sub msg($$) { my ($hash_id, $msg) = @_; my $raw = rhash_msg_raw($hash_id, $msg); # get binary hash 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 hash sums and magnet links =head1 SYNOPSIS use Crypt::Rhash; my $msg = "a message text"; print "MD5 = " . Crypt::Rhash::msg(RHASH_MD5, $msg) . "\n"; # Calculate two hash functions simultaneously my $r = Crypt::Rhash->new(RHASH_MD5 | RHASH_SHA1); $r->update("a message text")->update(" another message"); print "MD5 = " . $r->hash(RHASH_MD5) . "\n"; print "SHA1 = " . $r->hash(RHASH_SHA1) . "\n"; =head1 DESCRIPTION Crypt::Rhash module is an object-oriented interface to the LibRHash library, allowing simultaneous calculation of several hash functions for a file or a text message. Resulting hash digest can be obtained in hexadecimal, BASE32, BASE64, raw binary format or as a magnet link. =head1 SUPPORTED ALGORITHMS The module supports the following hashing algorithms: CRC32, MD4, MD5, SHA1, SHA256, SHA512, SHA3, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160, HAS-160, EDON-R 256/512, Whirlpool and Snefru-128/256. =head1 CONSTRUCTOR Creates and returns new Crypt::Rhash object. my $r = Crypt::Rhash->new($hash_id); my $p = new Crypt::Rhash($hash_id); # alternative way to call the constructor The $hash_id parameter can be union (via bitwise OR) of any of the following bit-flags: RHASH_CRC32, RHASH_MD4, RHASH_MD5, RHASH_SHA1, RHASH_TIGER, RHASH_TTH, RHASH_BTIH, RHASH_ED2K, RHASH_AICH, RHASH_WHIRLPOOL, RHASH_RIPEMD160, RHASH_GOST, RHASH_GOST_CRYPTOPRO, 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 Also the RHASH_ALL bit mask is the union of all listed bit-flags. So the object created via Crypt::Rhash->new(RHASH_ALL) calculates all supported hash functions for the same data. =head1 COMPUTING HASHES =over =item $rhash->update( $msg ) Calculates hashes 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 hash 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 hash. 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 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: $!"; while ((my $n = $r->update_fd($fd, undef, 1024) != 0)) { print "$n bytes hashed. The SHA1 hash is " . $r->final()->hash() . "\n"; $r->reset(); } defined($n) or die "read error for input.txt: $!"; close($fd); =item $rhash->final() Finishes calculation for all data buffered by updating methods and stops hash 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 HASH VALUE Computed hash 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 hash string 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 hash for the algorithm contained in $rhash with the lowest identifier. =item $rhash->hash_hex( $hash_id ) Returns the specified hash 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 hash in the hexadecimal format with reversed order of bytes. Some programs prefer to output the GOST R 34.11-94 hash in this format. =item $rhash->hash_base32( $hash_id ) Returns the specified hash in the base32 format. =item $rhash->hash_base64( $hash_id ) Returns the specified hash in the base64 format. =item $rhash->magnet_link( $filename, $hash_mask ) Returns the magnet link containing the computed hashes, 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 hash values to put into the link. =back =head1 STATIC METHODS =over =item Crypt::Rhash::count() Returns the number of supported hash algorithms =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 hash of the specified hash algorithm. =item Crypt::Rhash::get_hash_length($hash_id) Returns the length of a hash string in default output format for the specified hash algorithm. =item Crypt::Rhash::get_name($hash_id) Returns the name of the specified hash algorithm. =back =head1 ALTERNATIVE WAY TO COMPUTE HASH =over =item Crypt::Rhash::msg($hash_id, $message) Computes and returns a single hash (in its default format) of the $message by the selected hash algorithm. use Crypt::Rhash; print "SHA1( 'abc' ) = " . Crypt::Rhash::msg(RHASH_SHA1, "abc") . "\n"; =back =head1 LICENSE Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. The Software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! =cut RHash-1.3.6/bindings/perl/Rhash.xs000066400000000000000000000161121325207677100167210ustar00rootroot00000000000000#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #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: unknown hash hash_id = %d"; } else if(0 != (hash_id & (hash_id - 1))) { error = "%s: hash_id is not a single bit: %d"; } 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_raw(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_raw", strerror(errno)); } RETVAL = newSVpv((char*)out, rhash_get_digest_size(hash_id)); OUTPUT: RETVAL SV * rhash_file_raw(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 rhash_context * rhash_init(hash_id) unsigned hash_id PROTOTYPE: $ int rhash_update(ctx, message) 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) rhash_context * ctx PROTOTYPE: $ CODE: RETVAL = rhash_final(ctx, 0); OUTPUT: RETVAL void rhash_reset(ctx) rhash_context * ctx PROTOTYPE: $ void rhash_free(ctx) rhash_context * ctx PROTOTYPE: $ SV * rhash_print(ctx, hash_id, flags = 0) 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(ctx, filename, hash_mask) 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) rhash_context * ctx PROTOTYPE: $ CODE: RETVAL = ctx->hash_id; OUTPUT: RETVAL ulonglong rhash_get_hashed_length(ctx) rhash_context * ctx PROTOTYPE: $ CODE: RETVAL = ctx->msg_size; OUTPUT: RETVAL ############################################################################## # Hash information functions int count() CODE: RETVAL = rhash_count(); 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 # rhash_print_bytes should not be used directly #SV * #rhash_print_bytes(bytes, flags) # PROTOTYPE: $;$ # PREINIT: # STRLEN size; # INPUT: # unsigned char * bytes = SvPV(ST(0), size); # int flags # CODE: # RETVAL = allocate_string_buffer(size * 2); # rhash_print_bytes(SvPVX(RETVAL), bytes, size, flags); # OUTPUT: # RETVAL #rhash_uptr_t #rhash_transmit(msg_id, dst, ldata, rdata) # unsigned msg_id # void * dst # rhash_uptr_t ldata # rhash_uptr_t rdata ############################################################################## # BTIH / BitTorrent support functions void rhash_bt_add_filename(ctx, filename, filesize) rhash_context * ctx char * filename ulonglong filesize PROTOTYPE: $$$ CODE: rhash_transmit(RMSG_BT_ADD_FILE, ctx, RHASH_STR2UPTR(filename), (rhash_uptr_t)&filesize); void rhash_bt_set_piece_length(ctx, piece_length) rhash_context * ctx unsigned piece_length PROTOTYPE: $$ CODE: rhash_transmit(RMSG_BT_SET_PIECE_LENGTH, ctx, RHASH_STR2UPTR(piece_length), 0); void rhash_bt_set_private(ctx) rhash_context * ctx PROTOTYPE: $ CODE: rhash_transmit(RMSG_BT_SET_OPTIONS, ctx, RHASH_BT_OPT_PRIVATE, 0); SV * rhash_bt_get_torrent_text(ctx) rhash_context * ctx PROTOTYPE: $ PREINIT: size_t len; char *text; CODE: len = rhash_transmit(RMSG_BT_GET_TEXT, ctx, RHASH_STR2UPTR(&text), 0); if(len == RHASH_ERROR) { XSRETURN_UNDEF; } RETVAL = newSVpv(text, len); OUTPUT: RETVAL RHash-1.3.6/bindings/perl/t/000077500000000000000000000000001325207677100155425ustar00rootroot00000000000000RHash-1.3.6/bindings/perl/t/1test_hash_calculation.t000066400000000000000000000043661325207677100223610ustar00rootroot00000000000000use Test::More tests => 22; 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->reset()->hash(), "d41d8cd98f00b204e9800998ecf8427e"); is( $r->hashed_length(), length($msg)); 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"); #print "MD5 (\"$msg\") = ". $r->update_file($file)->hash() . "\n"; 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"); __END__ RHash-1.3.6/bindings/perl/t/2test_static_functions.t000066400000000000000000000013211325207677100224240ustar00rootroot00000000000000use Test::More tests => 11; 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"); # 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.3.6/bindings/perl/t/3test_all_hash_functions.t000066400000000000000000000050671325207677100227240ustar00rootroot00000000000000use Test::More tests => 26; use Crypt::Rhash; ######################### $r = new Crypt::Rhash(RHASH_ALL); $r->update("a")->final(); is( $r->hash(RHASH_CRC32), "e8b7be43"); 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_GOST), "d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd"); is( $r->hash(RHASH_GOST_CRYPTOPRO), "e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011"); is( $r->hash(RHASH_HAS160), "4872bcbc4cd0f0a9dc7c2f7045e5b43b6c830db8"); is( $r->hash(RHASH_SNEFRU128), "bf5ce540ae51bc50399f96746c5a15bd"); is( $r->hash(RHASH_SNEFRU256), "45161589ac317be0ceba70db2573ddda6e668a31984b39bf65e4b664b584c63d"); 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"); __END__ RHash-1.3.6/bindings/perl/typemap000066400000000000000000000001061325207677100166760ustar00rootroot00000000000000rhash_context * T_PTROBJ rhash_uptr_t T_NV ulonglong T_NV RHash-1.3.6/bindings/php/000077500000000000000000000000001325207677100151245ustar00rootroot00000000000000RHash-1.3.6/bindings/php/config.m4000066400000000000000000000024101325207677100166300ustar00rootroot00000000000000dnl dnl config.m4 for RHash extension dnl PHP_ARG_WITH(rhash, for RHash support, [ --with-rhash[=DIR] Include RHash support.]) if test "$PHP_RHASH" != "no"; then if test -r $PHP_RHASH/include/rhash.h; then RHASH_INCLUDE_DIR=$PHP_RHASH/include RHASH_LIB_DIR=$PHP_RHASH/lib elif test -r $PHP_RHASH/rhash.h; then RHASH_INCLUDE_DIR=$PHP_RHASH RHASH_LIB_DIR=$PHP_RHASH else AC_MSG_CHECKING(for RHash in default path) for i in /usr/local /usr; do if test -r $i/include/rhash.h; then RHASH_INCLUDE_DIR=$i/include RHASH_LIB_DIR=$i/lib AC_MSG_RESULT(found at $i) break fi done fi if test -z "$RHASH_INCLUDE_DIR" -a -r ../../librhash/rhash.h; then RHASH_INCLUDE_DIR=$(pwd)/../../librhash RHASH_LIB_DIR=$RHASH_INCLUDE_DIR AC_MSG_RESULT(found at $RHASH_INCLUDE_DIR) fi if test -z "$RHASH_INCLUDE_DIR"; then AC_MSG_RESULT(not found) AC_MSG_ERROR(Please reinstall the librhash - rhash.h should be in /include/) fi AC_DEFINE(HAVE_RHASH, 1, [Whether you have RHash]) PHP_ADD_INCLUDE($RHASH_INCLUDE_DIR) PHP_ADD_LIBRARY_WITH_PATH(rhash, $RHASH_LIB_DIR, RHASH_SHARED_LIBADD) PHP_NEW_EXTENSION(rhash, php_rhash.c, $ext_shared) PHP_SUBST(RHASH_SHARED_LIBADD) fi RHash-1.3.6/bindings/php/php_compatibility.h000066400000000000000000000020741325207677100210200ustar00rootroot00000000000000#ifndef PHP_PORTABLE_H #define PHP_PORTABLE_H #if PHP_MAJOR_VERSION < 7 struct _zend_string { char *val; int len; int persistent; }; typedef struct _zend_string zend_string; #define RETURN_NEW_STR(s) RETURN_STRINGL(s->val,s->len,0); static zend_always_inline zend_string *zend_string_alloc(int len, int persistent) { /* aligned to 8 bytes size of buffer to hold (len + 1) characters */ int alligned_size = (len + 1 + 7) & ~7; /* single alloc, so free the buf, will also free the struct */ char *buf = safe_pemalloc(sizeof(zend_string) + alligned_size, 1, 0, persistent); zend_string *str = (zend_string *)(buf + alligned_size); str->val = buf; str->len = len; str->persistent = persistent; return str; } /* compatibility macros */ # define _RETURN_STRING(str) RETURN_STRING(str, 1) # define _RETURN_STRINGL(str, l) RETURN_STRINGL(str, l, 1) typedef long zend_long; typedef int strsize_t; #else # define _RETURN_STRING(str) RETURN_STRING(str) # define _RETURN_STRINGL(str, l) RETURN_STRINGL(str, l) typedef size_t strsize_t; #endif #endif /* PHP_PORTABLE_H */ RHash-1.3.6/bindings/php/php_rhash.c000066400000000000000000000452101325207677100172460ustar00rootroot00000000000000/* php_rhash.c */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_streams.h" #include "php_rhash.h" #include "php_compatibility.h" #define PHP_RHASH_VERSION "1.2.9" /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_rhash_count, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_get_digest_size, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_is_base32, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_get_name, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_msg, 0) ZEND_ARG_INFO(0, hash_id) ZEND_ARG_INFO(0, message) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_file, 0) ZEND_ARG_INFO(0, hash_id) ZEND_ARG_INFO(0, path) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_magnet_func, 0) ZEND_ARG_INFO(0, hash_id) ZEND_ARG_INFO(0, path) ZEND_END_ARG_INFO() /* }}} */ /* {{{ The table of global functions */ static zend_function_entry rhash_functions[] = { PHP_FE(rhash_count, arginfo_rhash_count) PHP_FE(rhash_get_digest_size, arginfo_rhash_get_digest_size) PHP_FE(rhash_is_base32, arginfo_rhash_is_base32) PHP_FE(rhash_get_name, arginfo_rhash_get_name) PHP_FE(rhash_msg, arginfo_rhash_msg) PHP_FE(rhash_file, arginfo_rhash_file) PHP_FE(rhash_magnet, arginfo_rhash_magnet_func) PHP_FE_END }; /* }}} */ /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash__construct, 0, 0, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_update, 0) ZEND_ARG_INFO(0, message) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_update_stream, 0, 0, 1) ZEND_ARG_INFO(0, handle) ZEND_ARG_INFO(0, start) ZEND_ARG_INFO(0, size) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_update_file, 0, 0, 1) ZEND_ARG_INFO(0, path) ZEND_ARG_INFO(0, start) ZEND_ARG_INFO(0, size) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_final, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_reset, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_rhash_hashed_length, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_hash, 0, 0, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_raw, 0, 0, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_hex, 0, 0, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_base32, 0, 0, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_base64, 0, 0, 0) ZEND_ARG_INFO(0, hash_id) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_rhash_magnet, 0, 0, 0) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO() /* }}} */ /* {{{ The table of the RHash class methods */ zend_function_entry rhash_methods[] = { PHP_ME(RHash, __construct, arginfo_rhash__construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR) PHP_ME(RHash, update, arginfo_rhash_update, ZEND_ACC_PUBLIC) PHP_ME(RHash, update_stream, arginfo_rhash_update_stream, ZEND_ACC_PUBLIC) PHP_ME(RHash, update_file, arginfo_rhash_update_file, ZEND_ACC_PUBLIC) PHP_ME(RHash, final, arginfo_rhash_final, ZEND_ACC_PUBLIC) PHP_ME(RHash, reset, arginfo_rhash_reset, ZEND_ACC_PUBLIC) PHP_ME(RHash, hashed_length, arginfo_rhash_hashed_length, ZEND_ACC_PUBLIC) PHP_ME(RHash, hash, arginfo_rhash_hash, ZEND_ACC_PUBLIC) PHP_ME(RHash, raw, arginfo_rhash_raw, ZEND_ACC_PUBLIC) PHP_ME(RHash, hex, arginfo_rhash_hex, ZEND_ACC_PUBLIC) PHP_ME(RHash, base32, arginfo_rhash_base32, ZEND_ACC_PUBLIC) PHP_ME(RHash, base64, arginfo_rhash_base64, ZEND_ACC_PUBLIC) PHP_ME(RHash, magnet, arginfo_rhash_magnet, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ zend_class_entry *rhash_ce; zend_object_handlers rhash_object_handlers; /* {{{ Module struct */ zend_module_entry rhash_module_entry = { #if ZEND_MODULE_API_NO >= 20010901 STANDARD_MODULE_HEADER, #endif "rhash", /* extension name */ rhash_functions, /* function list */ PHP_MINIT(rhash), /* process startup */ PHP_MSHUTDOWN(rhash), /* process shutdown */ NULL, NULL, PHP_MINFO(rhash), /* extension info */ #if ZEND_MODULE_API_NO >= 20010901 PHP_RHASH_VERSION, /* extension version */ #endif STANDARD_MODULE_PROPERTIES }; /* }}} */ #ifdef COMPILE_DL_RHASH ZEND_GET_MODULE(rhash) #endif #define REGISTER_RHASH_CONSTANT(c) REGISTER_LONG_CONSTANT(#c, c, CONST_CS | CONST_PERSISTENT) #define RHASH_ALL RHASH_ALL_HASHES #if PHP_MAJOR_VERSION < 7 typedef struct _rhash_object { zend_object zobj; rhash rhash; } rhash_object; # define get_rhash_object(this_zval) ((rhash_object*)zend_object_store_get_object(this_zval TSRMLS_CC)) # define get_rhash_object_from_zend_object(object) (rhash_object *)(object) #else typedef struct _rhash_object { rhash rhash; zend_object zobj; } rhash_object; static rhash_object * get_rhash_object(zval *this_zval) { zend_object *zobj = Z_OBJ_P(this_zval); return (rhash_object *)((char *)zobj - XtOffsetOf(rhash_object, zobj)); } # define get_rhash_object_from_zend_object(object) (rhash_object *)((char *)object - XtOffsetOf(rhash_object, zobj)); #endif static void rhash_free_object(zend_object *object TSRMLS_DC) { rhash_object *obj = get_rhash_object_from_zend_object(object); if (obj->rhash) rhash_free(obj->rhash); /* call Zend's free handler, which will free object properties */ zend_object_std_dtor(object TSRMLS_CC); #if PHP_MAJOR_VERSION < 7 efree(object); #endif } /* Allocate memory for new rhash_object */ #if PHP_MAJOR_VERSION < 7 static zend_object_value rhash_create_object(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; rhash_object *obj = (rhash_object *)emalloc(sizeof(rhash_object)); memset(obj, 0, sizeof(rhash_object)); zend_object_std_init(&obj->zobj, ce TSRMLS_CC); obj->rhash = NULL; /* call object_properties_init(), because extending classes may use properties. */ object_properties_init(&obj->zobj, ce); retval.handle = zend_objects_store_put(obj, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t)rhash_free_object, NULL TSRMLS_CC); retval.handlers = &rhash_object_handlers; return retval; } #else static zend_object *rhash_create_object(zend_class_entry *ce TSRMLS_DC) { rhash_object *obj = ecalloc(1, sizeof(*obj) + zend_object_properties_size(ce)); zend_object_std_init(&obj->zobj, ce TSRMLS_CC); obj->zobj.handlers = &rhash_object_handlers; return &obj->zobj; } #endif /* {{{ PHP_MINIT_FUNCTION(rhash) */ PHP_MINIT_FUNCTION(rhash) { zend_class_entry ce; rhash_library_init(); /* initialize LibRHash */ /* register RHash class, its methods and handlers */ INIT_CLASS_ENTRY(ce, "RHash", rhash_methods); rhash_ce = zend_register_internal_class(&ce TSRMLS_CC); rhash_ce->create_object = rhash_create_object; memcpy(&rhash_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); rhash_object_handlers.clone_obj = NULL; #if PHP_MAJOR_VERSION >= 7 rhash_object_handlers.free_obj = rhash_free_object; /* This is the free handler */ rhash_object_handlers.offset = XtOffsetOf(rhash_object, zobj); #endif REGISTER_RHASH_CONSTANT(RHASH_CRC32); REGISTER_RHASH_CONSTANT(RHASH_MD4); REGISTER_RHASH_CONSTANT(RHASH_MD5); REGISTER_RHASH_CONSTANT(RHASH_SHA1); REGISTER_RHASH_CONSTANT(RHASH_TIGER); REGISTER_RHASH_CONSTANT(RHASH_TTH); REGISTER_RHASH_CONSTANT(RHASH_BTIH); REGISTER_RHASH_CONSTANT(RHASH_ED2K); REGISTER_RHASH_CONSTANT(RHASH_AICH); REGISTER_RHASH_CONSTANT(RHASH_WHIRLPOOL); REGISTER_RHASH_CONSTANT(RHASH_RIPEMD160); REGISTER_RHASH_CONSTANT(RHASH_GOST); REGISTER_RHASH_CONSTANT(RHASH_GOST_CRYPTOPRO); REGISTER_RHASH_CONSTANT(RHASH_HAS160); REGISTER_RHASH_CONSTANT(RHASH_SNEFRU128); REGISTER_RHASH_CONSTANT(RHASH_SNEFRU256); REGISTER_RHASH_CONSTANT(RHASH_SHA224); REGISTER_RHASH_CONSTANT(RHASH_SHA256); REGISTER_RHASH_CONSTANT(RHASH_SHA384); REGISTER_RHASH_CONSTANT(RHASH_SHA512); REGISTER_RHASH_CONSTANT(RHASH_EDONR256); REGISTER_RHASH_CONSTANT(RHASH_EDONR512); REGISTER_RHASH_CONSTANT(RHASH_SHA3_224); REGISTER_RHASH_CONSTANT(RHASH_SHA3_256); REGISTER_RHASH_CONSTANT(RHASH_SHA3_384); REGISTER_RHASH_CONSTANT(RHASH_SHA3_512); REGISTER_RHASH_CONSTANT(RHASH_ALL); return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION(rhash) */ PHP_MSHUTDOWN_FUNCTION(rhash) { return SUCCESS; } /* }}} */ /* {{{ PHP_MINFO_FUNCTION(rhash) */ PHP_MINFO_FUNCTION(rhash) { php_info_print_table_start(); php_info_print_table_row(2, "rhash support", "enabled"); php_info_print_table_end(); } /* }}} */ /* Global functions */ /* {{{ proto int rhash_count() Returns the number of supported hash functions */ PHP_FUNCTION(rhash_count) { RETURN_LONG(rhash_count()); } /* }}} */ /* {{{ proto int rhash_get_digest_size(int hash_id) Returns the size in bytes of message digest of the specified hash function */ PHP_FUNCTION(rhash_get_digest_size) { zend_long hash_id; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &hash_id) == FAILURE) { RETURN_FALSE; } RETURN_LONG(rhash_get_digest_size((unsigned)hash_id)); } /* }}} */ /* {{{ proto boolean rhash_is_base32(int hash_id) Returns true if default format of message digest is base32 and false if it's hexadecimal */ PHP_FUNCTION(rhash_is_base32) { zend_long hash_id; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &hash_id) == FAILURE) { RETURN_FALSE; } RETURN_BOOL(rhash_is_base32((unsigned)hash_id)); } /* }}} */ /* {{{ proto string rhash_get_name(int hash_id) Returns the name of the specified hash function */ PHP_FUNCTION(rhash_get_name) { zend_long hash_id; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &hash_id) == FAILURE) { RETURN_FALSE; } _RETURN_STRING(rhash_get_name((unsigned)hash_id)); } /* }}} */ /* {{{ proto string rhash_msg(int hash_id, string message) Returns message digest for the message string */ PHP_FUNCTION(rhash_msg) { zend_long hash_id; char *s; strsize_t s_len; strsize_t length; rhash context = NULL; char buffer[130]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &hash_id, &s, &s_len) == FAILURE) { RETURN_NULL(); } if (!(context = rhash_init((unsigned)hash_id))) { RETURN_NULL(); } rhash_update(context, s, s_len); rhash_final(context, 0); length = rhash_print(buffer, context, (unsigned)hash_id, 0); rhash_free(context); _RETURN_STRINGL(buffer, length); } /* Calculate hash for a php stream. Returns SUCCESS or FAILURE. */ static strsize_t _php_rhash_stream(INTERNAL_FUNCTION_PARAMETERS, rhash context, php_stream *stream, zend_long start, zend_long size) { char data[8192]; if (context == NULL) { rhash_object *obj = get_rhash_object(getThis()); if ((context = obj->rhash) == NULL) return FAILURE; } if (start >= 0) { if (php_stream_seek(stream, start, SEEK_SET) < 0) return FAILURE; } if (size >= 0) { while (size > 0 && !php_stream_eof(stream)) { int length = php_stream_read(stream, data, (size < 8192 ? size : 8192)); if (!length) return FAILURE; size -= length; rhash_update(context, data, length); } } else { while (!php_stream_eof(stream)) { int length = php_stream_read(stream, data, 8192); if (!length) return FAILURE; rhash_update(context, data, length); } } return SUCCESS; } /* }}} */ /* Calculate hash of the given file or its part. Returns SUCCESS or FAILURE. */ static strsize_t _php_rhash_file(INTERNAL_FUNCTION_PARAMETERS, rhash context, char* path, zend_long start, zend_long size) { strsize_t res; php_stream *stream = php_stream_open_wrapper(path, "rb", 0, 0); if (stream == NULL) return FAILURE; res = _php_rhash_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, context, stream, start, size); php_stream_close(stream); return res; } /* }}} */ /* {{{ proto string rhash_file(int hash_id, string path) Computes and returns message digest for a file. Returns NULL on failure. */ PHP_FUNCTION(rhash_file) { zend_long hash_id = 0; char *path; strsize_t path_len; rhash context = NULL; char buffer[130]; int buffer_length; strsize_t res; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lp", &hash_id, &path, &path_len) == FAILURE) { RETURN_NULL(); } if (!hash_id || !(context = rhash_init(hash_id))) { RETURN_NULL() } res = _php_rhash_file(INTERNAL_FUNCTION_PARAM_PASSTHRU, context, path, -1, -1); rhash_final(context, 0); buffer_length = rhash_print(buffer, context, hash_id, 0); rhash_free(context); /* return NULL on failure */ if (res != SUCCESS) { RETURN_NULL(); } _RETURN_STRINGL(buffer, buffer_length); } /* }}} */ /* {{{ proto string rhash_magnet(int hash_id, string path) Computes and returns magnet link for a file. Returns NULL on failure. */ PHP_FUNCTION(rhash_magnet) { zend_long hash_id = 0; char *path; strsize_t path_len; rhash context = NULL; zend_string* str; size_t buffer_size; strsize_t res; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lp", &hash_id, &path, &path_len) == FAILURE) { RETURN_NULL(); } if (!hash_id || !(context = rhash_init(hash_id))) { RETURN_NULL(); } res = _php_rhash_file(INTERNAL_FUNCTION_PARAM_PASSTHRU, context, path, -1, -1); if (res != SUCCESS) RETURN_NULL(); rhash_final(context, 0); buffer_size = rhash_print_magnet(0, path, context, hash_id, RHPR_FILESIZE); str = zend_string_alloc(buffer_size - 1, 0); if (!str) { rhash_free(context); RETURN_NULL(); } rhash_print_magnet(str->val, path, context, hash_id, RHPR_FILESIZE); rhash_free(context); RETURN_NEW_STR(str); } /* }}} */ /* RHash class methods */ /* {{{ proto RHash::__construct([int hash_id]) Creates new RHash object */ PHP_METHOD(RHash, __construct) { zend_long hash_id = 0; rhash context = NULL; rhash_object *obj; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &hash_id) == FAILURE) { RETURN_NULL(); } if (!hash_id) hash_id = RHASH_ALL_HASHES; if (!(context = rhash_init(hash_id))) { RETURN_NULL(); } rhash_set_autofinal(context, 0); obj = get_rhash_object(getThis()); obj->rhash = context; } /* }}} */ /* {{{ proto RHash RHash::update(string message) Updates RHash object with new data chunk and returns $this */ PHP_METHOD(RHash, update) { char *s; strsize_t s_len; zval *object = getThis(); rhash_object *obj = get_rhash_object(object); if (obj->rhash == NULL || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s, &s_len) == FAILURE) { RETURN_FALSE; } rhash_update(obj->rhash, s, s_len); Z_ADDREF(*object); *return_value = *object; } /* }}} */ /* {{{ proto boolean RHash::update_stream(resource handle[, int start[, int size]]) Returns true if successfully calculated hashes for a (part of) stream, false on error */ PHP_METHOD(RHash, update_stream) { zval *handle; strsize_t res; zend_long start = -1, size = -1; php_stream *stream; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|ll", &handle, &start, &size) == FAILURE) { RETURN_FALSE; } #if PHP_MAJOR_VERSION < 7 php_stream_from_zval_no_verify(stream, &handle); #else php_stream_from_zval_no_verify(stream, handle); #endif if (stream == NULL) RETURN_FALSE; res = _php_rhash_stream(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, stream, start, size); RETURN_BOOL(res == SUCCESS); } /* }}} */ /* {{{ proto boolean RHash::update_file(string path[, int start[, int size]]) Returns true if successfully calculated hashes for a (part of) file, false on error */ PHP_METHOD(RHash, update_file) { char *path; strsize_t len; zend_long start = -1, size = -1; strsize_t res = zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "p|ll", &path, &len, &start, &size); if (res == SUCCESS) { res = _php_rhash_file(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, path, start, size); } RETURN_BOOL(res == SUCCESS); } /* }}} */ /* {{{ proto RHash RHash::final() Finalizes calculation for all hashed data and returns $this */ PHP_METHOD(RHash, final) { zval *object = getThis(); rhash_object *obj = get_rhash_object(object); if (obj->rhash == NULL) RETURN_FALSE; rhash_final(obj->rhash, NULL); Z_ADDREF(*object); *return_value = *object; } /* }}} */ /* {{{ proto RHash RHash::reset() Resets RHash object to initial state and returns $this */ PHP_METHOD(RHash, reset) { zval *object = getThis(); rhash_object *obj = get_rhash_object(object); if (obj->rhash == NULL) RETURN_FALSE; rhash_reset(obj->rhash); Z_ADDREF(*object); *return_value = *object; } /* }}} */ /* {{{ proto int RHash::hashed_length() Returns length in bytes of the hashed data */ PHP_METHOD(RHash, hashed_length) { rhash_object *obj = get_rhash_object(getThis()); if (obj->rhash == NULL) RETURN_FALSE; RETURN_LONG((long)obj->rhash->msg_size); } /* }}} */ /* {{{ _php_get_hash(RHash this_class[, int hash_id], int print_flags) Returns calculated hash in the specified format */ static void _php_get_hash(INTERNAL_FUNCTION_PARAMETERS, int print_flags) { zend_long hash_id = 0; char buffer[130]; int length; rhash_object *obj = get_rhash_object(getThis()); if (obj->rhash == NULL || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &hash_id) == FAILURE) { RETURN_FALSE; } length = rhash_print(buffer, obj->rhash, hash_id, print_flags); _RETURN_STRINGL(buffer, length) } /* }}} */ /* {{{ proto string RHash::hash([int hash_id]) Returns hash value in default format */ PHP_METHOD(RHash, hash) { _php_get_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } /* }}} */ /* {{{ proto string RHash::raw([int hash_id]) Returns hash value as raw bytes */ PHP_METHOD(RHash, raw) { _php_get_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, RHPR_RAW); } /* }}} */ /* {{{ proto string RHash::hex([int hash_id]) Returns hash value as hexadecimal string */ PHP_METHOD(RHash, hex) { _php_get_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, RHPR_HEX); } /* }}} */ /* {{{ proto string RHash::base32([int hash_id]) Returns hash value as base32 string */ PHP_METHOD(RHash, base32) { _php_get_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, RHPR_BASE32); } /* }}} */ /* {{{ proto string RHash::base64([int hash_id]) Returns hash value as base64 string */ PHP_METHOD(RHash, base64) { _php_get_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, RHPR_BASE64); } /* }}} */ /* {{{ proto string RHash::magnet([string filename]) Returns magnet link with all hashes computed by the RHash object */ PHP_METHOD(RHash, magnet) { char *s = 0; strsize_t s_len; size_t buf_size; zend_string *magnet_str; rhash_object *obj = get_rhash_object(getThis()); if (obj->rhash == NULL || zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &s, &s_len) == FAILURE) { RETURN_FALSE; } buf_size = rhash_print_magnet(0, s, obj->rhash, RHASH_ALL_HASHES, RHPR_FILESIZE); magnet_str = zend_string_alloc(buf_size - 1, 0); if (!magnet_str) RETURN_FALSE; rhash_print_magnet(magnet_str->val, s, obj->rhash, RHASH_ALL_HASHES, RHPR_FILESIZE); RETURN_NEW_STR(magnet_str); } /* }}} */ RHash-1.3.6/bindings/php/php_rhash.h000066400000000000000000000014571325207677100172600ustar00rootroot00000000000000#ifndef PHP_RHASH_H #define PHP_RHASH_H extern zend_module_entry rhash_module_entry; #define phpext_rhash_ptr &rhash_module_entry PHP_MINIT_FUNCTION(rhash); PHP_MSHUTDOWN_FUNCTION(rhash); PHP_MINFO_FUNCTION(rhash); PHP_FUNCTION(rhash_count); PHP_FUNCTION(rhash_get_digest_size); PHP_FUNCTION(rhash_get_name); PHP_FUNCTION(rhash_is_base32); PHP_FUNCTION(rhash_msg); PHP_FUNCTION(rhash_file); PHP_FUNCTION(rhash_magnet); PHP_METHOD(RHash, __construct); PHP_METHOD(RHash, update); PHP_METHOD(RHash, update_stream); PHP_METHOD(RHash, update_file); PHP_METHOD(RHash, final); PHP_METHOD(RHash, reset); PHP_METHOD(RHash, hashed_length); PHP_METHOD(RHash, hash); PHP_METHOD(RHash, raw); PHP_METHOD(RHash, hex); PHP_METHOD(RHash, base32); PHP_METHOD(RHash, base64); PHP_METHOD(RHash, magnet); #endif /* PHP_RHASH_H */ RHash-1.3.6/bindings/php/tests/000077500000000000000000000000001325207677100162665ustar00rootroot00000000000000RHash-1.3.6/bindings/php/tests/001.phpt000066400000000000000000000006131325207677100174630ustar00rootroot00000000000000--TEST-- test RHash global functions --FILE-- = 26) . "\n"; echo rhash_get_digest_size(RHASH_CRC32) . "\n"; echo (int)rhash_is_base32(RHASH_MD5) . "\n"; echo (int)rhash_is_base32(RHASH_AICH) . "\n"; echo rhash_get_name(RHASH_SHA1) . "\n"; echo rhash_msg(RHASH_TTH, 'abc') . "\n"; echo "Done\n"; ?> --EXPECTF-- 1 4 0 1 SHA1 asd4ujseh5m47pdyb46kbtsqtsgdklbhyxomuia Done RHash-1.3.6/bindings/php/tests/002.phpt000066400000000000000000000061601325207677100174670ustar00rootroot00000000000000--TEST-- test RHash basic methods --FILE-- update('a')->final(); echo $r->hashed_length() . "\n"; echo $r->hash(RHASH_CRC32) . "\n"; echo $r->hash(RHASH_MD4) . "\n"; echo $r->hash(RHASH_MD5) . "\n"; echo $r->hash(RHASH_SHA1) . "\n"; echo $r->hash(RHASH_TIGER) . "\n"; echo $r->hash(RHASH_TTH) . "\n"; echo strlen($r->hash(RHASH_BTIH)) . "\n"; echo $r->hash(RHASH_ED2K) . "\n"; echo $r->hash(RHASH_AICH) . "\n"; echo $r->hash(RHASH_WHIRLPOOL) . "\n"; echo $r->hash(RHASH_RIPEMD160) . "\n"; echo $r->hash(RHASH_GOST) . "\n"; echo $r->hash(RHASH_GOST_CRYPTOPRO) . "\n"; echo $r->hash(RHASH_HAS160) . "\n"; echo $r->hash(RHASH_SNEFRU128) . "\n"; echo $r->hash(RHASH_SNEFRU256) . "\n"; echo $r->hash(RHASH_SHA224) . "\n"; echo $r->hash(RHASH_SHA256) . "\n"; echo $r->hash(RHASH_SHA384) . "\n"; echo $r->hash(RHASH_SHA512) . "\n"; echo $r->hash(RHASH_SHA3_224) . "\n"; echo $r->hash(RHASH_SHA3_256) . "\n"; echo $r->hash(RHASH_SHA3_384) . "\n"; echo $r->hash(RHASH_SHA3_512) . "\n"; echo $r->hash(RHASH_EDONR256) . "\n"; echo $r->hash(RHASH_EDONR512) . "\n"; echo $r->raw(RHASH_SHA1) . "\n"; echo $r->hex(RHASH_TTH) . "\n"; echo $r->base32(RHASH_SHA1) . "\n"; echo $r->base64(RHASH_SHA1) . "\n"; $r = new RHash(RHASH_CRC32 | RHASH_AICH); echo $r->update('a')->final()->magnet('file.txt') . "\n"; echo "Done\n"; ?> --EXPECTF-- 1 e8b7be43 bde52cb31de33e46245e05fbdbd6fb24 0cc175b9c0f1b6a831c399e269772661 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 77befbef2e7ef8ab2ec8f93bf587a7fc613e247f5f247809 czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y 40 bde52cb31de33e46245e05fbdbd6fb24 q336in72uwt7zyk5dxolt2xk5i3xmz5y 8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a 0bdc9d2d256b3ee9daae347be6f4dc835a467ffe d42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011 4872bcbc4cd0f0a9dc7c2f7045e5b43b6c830db8 bf5ce540ae51bc50399f96746c5a15bd 45161589ac317be0ceba70db2573ddda6e668a31984b39bf65e4b664b584c63d abd37534c7d9a2efb9465de931cd7055ffdb8879563ae98078d6d6d5 ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb 54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75 9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b 80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b 1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9 697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a 943aa9225a2cf154ec2e4dd81237720ba538ca8df2fd83c0b893c5d265f353a0 b59ec44f7beef8a04ceed38a973d77c65e22e9458d5f67b497948da34986c093b5efc5483fbee55f2f740fcad31f18d80db44bb6b8843e7fd599188e7c07233b 7]ܹ7vg 16614b1f68c5c25eaf6136286c9c12932f4f73e87e90a273 q336in72uwt7zyk5dxolt2xk5i3xmz5y hvfkN/qlp/zhXR3cuerq6jd2Z7g= magnet:?xl=1&dn=file.txt&xt=urn:aich:q336in72uwt7zyk5dxolt2xk5i3xmz5y&xt=urn:crc32:e8b7be43 Done RHash-1.3.6/bindings/php/tests/003.phpt000066400000000000000000000017121325207677100174660ustar00rootroot00000000000000--TEST-- test RHash file methods --FILE-- update_stream($handle, 3, 3); echo $r->final()->magnet($filename) . "\n"; fclose($handle); $r->reset()->update_file($filename); echo $r->final()->magnet($filename) . "\n"; $r->reset()->update_file($filename, 2, 1); echo $r->final()->magnet($filename) . "\n"; // test global file reading functions echo rhash_file(RHASH_TTH, $filename) . "\n"; echo rhash_magnet(RHASH_TTH, $filename) . "\n"; unlink($filename); echo "Done\n"; ?> --EXPECTF-- magnet:?xl=3&dn=003_test.txt&xt=urn:md5:900150983cd24fb0d6963f7d28e17f72 magnet:?xl=12&dn=003_test.txt&xt=urn:md5:5a73501e89118bfc45e19f26c0bb2c33 magnet:?xl=13&dn=003_test.txt&xt=urn:md5:c81e728d9d4c2f636f067f89cc14862c 2yu5rdna7qwl6e3ivtgzleuft766u72dxnlzdri magnet:?xl=9&dn=003_test.txt&xt=urn:tree:tiger:2yu5rdna7qwl6e3ivtgzleuft766u72dxnlzdri Done RHash-1.3.6/bindings/python/000077500000000000000000000000001325207677100156565ustar00rootroot00000000000000RHash-1.3.6/bindings/python/.gitignore000066400000000000000000000000061325207677100176420ustar00rootroot00000000000000*.pyc RHash-1.3.6/bindings/python/rhash.py000066400000000000000000000226441325207677100173450ustar00rootroot00000000000000# Python Bindings for Librhash # Copyright (c) 2011-2012, Sergey Basalaev # Librhash is (c) 2011-2012, Aleksey Kravchenko # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. Use it at your own risk! """Python bindings for librhash Librhash is a library for computing and verifying hash sums that supports many hashing algorithms. The simplest way to calculate hash of a message or a file is by using one of the functions: hash_for_msg(message, hash_id) hash_for_file(filename, hash_id) magnet_for_file(filename, hash_ids) Here hash_id is one of the constants CRC32, MD4, MD5, SHA1, TIGER, TTH, BTIH, ED2K, AICH, WHIRLPOOL, RIPEMD160, GOST, GOST_CRYPTOPRO, HAS160, SNEFRU128, SNEFRU256, SHA224, SHA256, SHA384, SHA512, SHA3_224, SHA3_256, SHA3_384, SHA3_512, EDONR256 or EDONR512. The first two functions will return the default text representation of the message digest they compute. The latter will return magnet link for the file. In this function you can OR-combine several hash_ids, like >>> print magnet_for_file('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 hashes 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(filename). 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(), base64() 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. It may be omitted if RHash was created to compute hash for only a single hashing algorithm. Method magnet(filename) will generate magnet link with all hashes computed by the RHash object. """ # public API __all__ = [ 'ALL', 'CRC32', 'MD4', 'MD5', 'SHA1', 'TIGER', 'TTH', 'BTIH', 'ED2K', 'AICH', 'WHIRLPOOL', 'RIPEMD160', 'GOST', 'GOST_CRYPTOPRO', 'HAS160', 'SNEFRU128', 'SNEFRU256', 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'EDONR256', 'EDONR512', 'SHA3_224', 'SHA3_256', 'SHA3_384', 'SHA3_512', 'RHash', 'hash_for_msg', 'hash_for_file', 'magnet_for_file'] import sys from ctypes import ( CDLL, c_char_p, c_int, c_size_t, c_uint, c_void_p, create_string_buffer) # initialization if sys.platform == 'win32': LIBNAME = 'librhash.dll' elif sys.platform == 'darwin': LIBNAME = 'librhash.0.dylib' elif sys.platform == 'cygwin': LIBNAME = 'cygrhash.dll' elif sys.platform == 'msys': LIBNAME = 'msys-rhash.dll' else: LIBNAME = 'librhash.so.0' LIBRHASH = CDLL(LIBNAME) LIBRHASH.rhash_library_init() # function prototypes LIBRHASH.rhash_init.argtypes = [c_uint] LIBRHASH.rhash_init.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_transmit.argtypes = [c_uint, c_void_p, c_size_t, c_size_t] # 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 GOST = 0x800 GOST_CRYPTOPRO = 0x1000 HAS160 = 0x2000 SNEFRU128 = 0x4000 SNEFRU256 = 0x8000 SHA224 = 0x10000 SHA256 = 0x20000 SHA384 = 0x40000 SHA512 = 0x80000 EDONR256 = 0x100000 EDONR512 = 0x200000 SHA3_224 = 0x0400000 SHA3_256 = 0x0800000 SHA3_384 = 0x1000000 SHA3_512 = 0x2000000 ALL = SHA3_512*2 - 1 #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 class RHash(object): 'Incremental hasher' def __init__(self, hash_ids): if hash_ids == 0: self._ctx = None raise ValueError('Invalid argument') self._ctx = LIBRHASH.rhash_init(hash_ids) #switching off the autofinal feature LIBRHASH.rhash_transmit(5, self._ctx, 0, 0) def __del__(self): if self._ctx != None: LIBRHASH.rhash_free(self._ctx) 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): return self.update(message) def update_file(self, filename): """Update this object with data from the given file.""" file = open(filename, 'rb') buf = file.read(8192) while len(buf) > 0: self.update(buf) buf = file.read(8192) file.close() return self def finish(self): """Calculate hashes for all the data buffered by the update() method. """ LIBRHASH.rhash_final(self._ctx, None) return self def _print(self, hash_id, flags): """Retrieve the message hash in required format.""" buf = create_string_buffer(130) size = LIBRHASH.rhash_print(buf, self._ctx, hash_id, flags) if (flags & 3) == RHPR_RAW: return buf[0:size] else: return buf[0:size].decode() def raw(self, hash_id=0): """Returns the message hash as raw binary data.""" return self._print(hash_id, RHPR_RAW) def hex(self, hash_id=0): """Returns the message hash as a hexadecimal lower-case string.""" return self._print(hash_id, RHPR_HEX) def base32(self, hash_id=0): """Returns the message hash as a Base32 lower-case string.""" return self._print(hash_id, RHPR_BASE32) def base64(self, hash_id=0): """Returns the message hash as a Base64 string.""" return self._print(hash_id, RHPR_BASE64) # pylint: disable=invalid-name def HEX(self, hash_id=0): """Returns the message hash as a hexadecimal upper-case string.""" return self._print(hash_id, RHPR_HEX | RHPR_UPPERCASE) def BASE32(self, hash_id=0): """Returns the message hash as a Base32 upper-case string.""" return self._print(hash_id, RHPR_BASE32 | RHPR_UPPERCASE) # pylint: enable=invalid-name def magnet(self, filepath): """Returns magnet link with all hashes computed by this object.""" size = LIBRHASH.rhash_print_magnet( None, _s2b(filepath), self._ctx, ALL, RHPR_FILESIZE) buf = create_string_buffer(size) LIBRHASH.rhash_print_magnet( buf, _s2b(filepath), self._ctx, ALL, RHPR_FILESIZE) return buf[0:size-1].decode('utf-8') def hash(self, hash_id=0): """Returns the message digest for the given hash function as a string in the default format.""" return self._print(hash_id, 0) def __str__(self): return self._print(0, 0) def hash_for_msg(message, hash_id): """Computes and returns the message digest (in its default format) of the message""" handle = RHash(hash_id) handle.update(message).finish() return str(handle) def hash_for_file(filename, hash_id): """Computes and returns the message digest (in its default format) of the file content""" handle = RHash(hash_id) handle.update_file(filename).finish() return str(handle) def magnet_for_file(filename, hash_mask): """Computes and returns the magnet link for the file.""" handle = RHash(hash_mask) handle.update_file(filename).finish() return handle.magnet(filename) RHash-1.3.6/bindings/python/test_rhash.py000066400000000000000000000157761325207677100204140ustar00rootroot00000000000000# UnitTest for Librhash Python Bindings # Copyright (c) 2011-2012, Aleksey Kravchenko # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so. # # This library is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. Use it at your own risk! """Unit-tests for the rhash module""" import rhash import os import unittest # pylint: disable=too-many-public-methods, pointless-statement class TestRHash(unittest.TestCase): """The test-case class for the rhash module""" 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('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( '8aca2602792aec6f11a67206531fb7d7f0dff59413145e6973c45001d0087b42d11bc645413aeff63a42391a39145a591a92200d560195e53b478584fdae231a', ctx.hash(rhash.WHIRLPOOL)) self.assertEqual( '0bdc9d2d256b3ee9daae347be6f4dc835a467ffe', ctx.hash(rhash.RIPEMD160)) self.assertEqual( 'd42c539e367c66e9c88a801f6649349c21871b4344c6a573f849fdce62f314dd', ctx.hash(rhash.GOST)) self.assertEqual( 'e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011', ctx.hash(rhash.GOST_CRYPTOPRO)) 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.SHA224)) self.assertEqual( 'ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb', ctx.hash(rhash.SHA256)) self.assertEqual( '54a59b9f22b0b80880d8427e548b7c23abd873486e1f035dce9cd697e85175033caa88e6d57bc35efae0b5afd3145f31', ctx.hash(rhash.SHA384)) self.assertEqual( '1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75', ctx.hash(rhash.SHA512)) self.assertEqual( '943aa9225a2cf154ec2e4dd81237720ba538ca8df2fd83c0b893c5d265f353a0', ctx.hash(rhash.EDONR256)) self.assertEqual( 'b59ec44f7beef8a04ceed38a973d77c65e22e9458d5f67b497948da34986c093b5efc5483fbee55f2f740fcad31f18d80db44bb6b8843e7fd599188e7c07233b', ctx.hash(rhash.EDONR512)) self.assertEqual( '9e86ff69557ca95f405f081269685b38e3a819b309ee942f482b6a8b', ctx.hash(rhash.SHA3_224)) self.assertEqual( '80084bf2fba02475726feb2cab2d8215eab14bc6bdd8bfb2c8151257032ecd8b', ctx.hash(rhash.SHA3_256)) self.assertEqual( '1815f774f320491b48569efec794d249eeb59aae46d22bf77dafe25c5edc28d7ea44f93ee1234aa88f61c91912a4ccd9', ctx.hash(rhash.SHA3_384)) self.assertEqual( '697f2d856172cb8309d6b8b97dac4de344b549d4dee61edfb4962d8698b7fa803f4f93ff24393586e28b5b957ac3d1d369420ce53332712f997bd336d09ab02a', ctx.hash(rhash.SHA3_512)) # test reset self.assertEqual( 'd41d8cd98f00b204e9800998ecf8427e', ctx.reset().finish().hash(rhash.MD5)) # MD5( '' ) def test_update(self): """Test the sequential update calls""" ctx = rhash.RHash(rhash.CRC32 | rhash.MD5) ctx.update('Hello, ').update('world!').finish() self.assertEqual('EBE6C6E6', ctx.HEX(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' # MD5( 'abc' ) self.assertEqual('900150983cd24fb0d6963f7d28e17f72', str(ctx.finish())) def test_hash_for_msg(self): """Test the hash_for_msg() function""" self.assertEqual( '900150983cd24fb0d6963f7d28e17f72', rhash.hash_for_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 the update_file() method""" path = 'python_test_input_123.txt' file = open(path, 'wb') file.write(b"\0\1\2\n") file.close() ctx = rhash.RHash(rhash.SHA1) ctx.update_file(path).finish() self.assertEqual('e3869ec477661fad6b9fc25914bb2eee5455b483', str(ctx)) self.assertEqual( 'e3869ec477661fad6b9fc25914bb2eee5455b483', rhash.hash_for_file(path, rhash.SHA1)) self.assertEqual( 'magnet:?xl=4&dn=python_test_input_123.txt&xt=urn:tree:tiger:c6docz63fpef5pdfpz35z7mw2iozshxlpr4erza', rhash.magnet_for_file(path, rhash.TTH)) os.remove(path) if __name__ == '__main__': unittest.main() RHash-1.3.6/bindings/ruby/000077500000000000000000000000001325207677100153165ustar00rootroot00000000000000RHash-1.3.6/bindings/ruby/.gitignore000066400000000000000000000000331325207677100173020ustar00rootroot00000000000000mkmf.log rhash.so Makefile RHash-1.3.6/bindings/ruby/extconf.rb000066400000000000000000000003601325207677100173100ustar00rootroot00000000000000require '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.3.6/bindings/ruby/rhash.c000066400000000000000000000257641325207677100166050ustar00rootroot00000000000000/* * Ruby Bindings for Librhash * Copyright (c) 2011-2012, Sergey Basalaev * Librhash is (c) 2011-2012, Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. Use it at your own risk! */ #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 hashes. */ 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) { char buf[130]; rhash ctx; Data_Get_Struct(self, struct rhash_context, ctx); int 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 hashes 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 hashes for given algorithms. * Parameters should be constants defined in this class. */ VALUE rh_new(int argc, VALUE* argv, VALUE clz) { 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)); /** 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, "GOST", INT2FIX(RHASH_GOST)); /** GOST R 34.11-94. */ rb_define_const(cRHash, "GOST_CRYPTOPRO", INT2FIX(RHASH_GOST_CRYPTOPRO)); /** HAS-160 hash. */ rb_define_const(cRHash, "HAS160", INT2FIX(RHASH_HAS160)); /** Snefru-128 hash. */ rb_define_const(cRHash, "SNEFRU128", INT2FIX(RHASH_SNEFRU128)); /** Snefru-256 hash. */ rb_define_const(cRHash, "SNEFRU256", INT2FIX(RHASH_SNEFRU256)); /** 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)); /** Create RHash with this parameter to compute hashes for all available algorithms. */ rb_define_const(cRHash, "ALL", INT2FIX(RHASH_ALL_HASHES)); } RHash-1.3.6/bindings/ruby/test_rhash.rb000066400000000000000000000077021325207677100200150ustar00rootroot00000000000000#!/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("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::GOST)) assert_equal("e74c52dd282183bf37af0079c9f78055715a103f17e3133ceff1aacf2f403011", r.to_s(RHash::GOST_CRYPTOPRO)) 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("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.3.6/bindings/version.properties000066400000000000000000000000161325207677100201350ustar00rootroot00000000000000version=1.3.6 RHash-1.3.6/calc_sums.c000066400000000000000000000541371325207677100146670ustar00rootroot00000000000000/* calc_sums.c - crc calculating and printing functions */ #include "platform.h" /* unlink() on unix */ #include #include #include /* free() */ #include #include #ifdef _WIN32 # include /* _O_BINARY */ # include #endif #include "calc_sums.h" #include "common_func.h" #include "file.h" #include "hash_print.h" #include "output.h" #include "parse_cmdline.h" #include "rhash_main.h" #include "win_utils.h" #include "librhash/rhash.h" #include "librhash/rhash_torrent.h" /** * Initialize BTIH hash function. Unlike other algorithms BTIH * requires more data for correct computation. * * @param info the file data */ static void init_btih_data(struct file_info *info) { assert((info->rctx->hash_id & RHASH_BTIH) != 0); rhash_torrent_add_file(info->rctx, file_info_get_utf8_print_path(info), info->size); rhash_torrent_set_program_name(info->rctx, get_bt_program_name()); if (opt.flags & OPT_BT_PRIVATE) { rhash_torrent_set_options(info->rctx, RHASH_TORRENT_OPT_PRIVATE); } if (opt.bt_announce) { size_t i; for (i = 0; i < opt.bt_announce->size; i++) { rhash_torrent_add_announce(info->rctx, (const char*)opt.bt_announce->array[i]); } } if (opt.bt_piece_length) { rhash_torrent_set_piece_length(info->rctx, opt.bt_piece_length); } else if (opt.bt_batch_file && rhash_data.batch_size) { rhash_torrent_set_batch_size(info->rctx, rhash_data.batch_size); } } /** * (Re)-initialize RHash context, to calculate hash sums. * * @param info the file data */ static void re_init_rhash_context(struct file_info *info) { if (rhash_data.rctx != 0) { if (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) { /* a set of hash sums can change from file to file */ rhash_free(rhash_data.rctx); rhash_data.rctx = 0; } else { info->rctx = rhash_data.rctx; if (opt.bt_batch_file) { /* add another file to the torrent batch */ rhash_torrent_add_file(info->rctx, file_info_get_utf8_print_path(info), info->size); return; } else { rhash_reset(rhash_data.rctx); } } } if (rhash_data.rctx == 0) { rhash_data.rctx = rhash_init(info->sums_flags); info->rctx = rhash_data.rctx; } if (info->sums_flags & RHASH_BTIH) { /* re-initialize BitTorrent data */ init_btih_data(info); } } /** * Calculate hash sums simultaneously, according to the info->sums_flags. * Calculated hashes are stored in info->rctx. * * @param info file data. The info->full_path can be "-" to denote stdin * @return 0 on success, -1 on fail with error code stored in errno */ static int calc_sums(struct file_info *info) { FILE* fd = stdin; /* stdin */ int res; assert(info->file); if (info->file->mode & FILE_IFSTDIN) { info->print_path = "(stdin)"; #ifdef _WIN32 /* using 0 instead of _fileno(stdin). _fileno() is undefined under 'gcc -ansi' */ if (setmode(0, _O_BINARY) < 0) { return -1; } #endif } else { if ((opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) && FILE_ISDIR(info->file)) { errno = EISDIR; return -1; } info->size = info->file->size; /* total size, in bytes */ if (!info->sums_flags) return 0; /* skip without reporting an error the files * opened exclusively by another process */ fd = file_fopen(info->file, FOpenRead | FOpenBin); if (!fd) return -1; } re_init_rhash_context(info); /* save initial msg_size, for correct calculation of percents */ info->msg_offset = info->rctx->msg_size; if (percents_output->update != 0) { rhash_set_callback(info->rctx, (rhash_callback_t)percents_output->update, info); } /* read and hash file content */ if ((res = rhash_file_update(info->rctx, fd)) != -1) { if (!opt.bt_batch_file) { rhash_final(info->rctx, 0); /* finalize hashing */ } } /* calculate real file size */ info->size = info->rctx->msg_size - info->msg_offset; rhash_data.total_size += info->size; if (fd != stdin) fclose(fd); return res; } /** * Free memory allocated by given file_info structure. * * @param info pointer the structure to de-initialize */ void file_info_destroy(struct file_info* info) { free(info->utf8_print_path); free(info->allocated_ptr); } /** * Store print_path in a file_info struct, replacing if needed * system path separators with specified by user command line option. * * @param info pointer to the the file_info structure to change * @param print_path the print path to store */ static void file_info_set_print_path(struct file_info* info, const char* print_path) { char *p; char wrong_sep; /* check if path separator was specified by command line options */ if (opt.path_separator) { wrong_sep = (opt.path_separator == '/' ? '\\' : '/'); if ((p = (char*)strchr(print_path, wrong_sep)) != NULL) { info->allocated_ptr = rsh_strdup(print_path); info->print_path = info->allocated_ptr; p = info->allocated_ptr + (p - print_path); /* replace wrong_sep in the print_path with separator defined by options */ for (; *p; p++) { if (*p == wrong_sep) *p = opt.path_separator; } return; } } /* if path was not replaces, than just store the value */ info->print_path = print_path; } /** * Return utf8 version of print_path. * * @param info file information * @return utf8 string on success, NULL if couldn't convert. */ const char* file_info_get_utf8_print_path(struct file_info* info) { if (info->utf8_print_path == NULL) { if (is_utf8()) return info->print_path; info->utf8_print_path = to_utf8(info->print_path); } return info->utf8_print_path; } /* functions to calculate and print file sums */ /** * Search for a crc32 hash sum in the given file name. * * @param filepath the path to the file. * @param crc32 pointer to integer to receive parsed hash sum. * @return non zero if crc32 was found, zero otherwise. */ static int find_embedded_crc32(const char* filepath, unsigned* crc32) { const char* e = filepath + strlen(filepath) - 10; unsigned char raw[4]; /* search for the sum enclosed in brackets */ for (; e >= filepath && !IS_PATH_SEPARATOR(*e); e--) { if ((*e == '[' && e[9] == ']') || (*e == '(' && e[9] == ')')) { const char *p = e + 8; for (; p > e && IS_HEX(*p); p--); if (p == e) { rhash_hex_to_byte(e + 1, raw, 8); *crc32 = ((unsigned)raw[0] << 24) | ((unsigned)raw[1] << 16) | ((unsigned)raw[2] << 8) | (unsigned)raw[3]; return 1; } e -= 9; } } return 0; } /** * Rename given file inserting its crc32 sum enclosed into square braces * and placing it right before the file extension. * * @param info pointer to the data of the file to rename. * @return 0 on success, -1 on fail with error code in errno */ int rename_file_by_embeding_crc32(struct file_info *info) { size_t len = strlen(info->full_path); const char* p = info->full_path + len; const char* c = p - 1; char* new_path; char* insertion_point; unsigned crc32; assert((info->rctx->hash_id & RHASH_CRC32) != 0); /* check if the filename contains a CRC32 sum */ if (find_embedded_crc32(info->print_path, &crc32)) { /* compare with calculated CRC32 */ if (crc32 != get_crc32(info->rctx)) { char crc32_str[9]; rhash_print(crc32_str, info->rctx, RHASH_CRC32, RHPR_UPPERCASE); /* TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv */ log_warning(_("wrong embedded CRC32, should be %s\n"), crc32_str); } else return 0; } /* find file extension (as the place to insert the hash sum) */ for (; c >= info->full_path && !IS_PATH_SEPARATOR(*c); c--) { if (*c == '.') { p = c; break; } } /* now p is the point to insert delimiter + hash string in brackets */ new_path = (char*)rsh_malloc(len + 12); insertion_point = new_path + (p - info->full_path); memcpy(new_path, info->full_path, p - info->full_path); if (opt.embed_crc_delimiter && *opt.embed_crc_delimiter) *(insertion_point++) = *opt.embed_crc_delimiter; rhash_print(insertion_point+1, info->rctx, RHASH_CRC32, RHPR_UPPERCASE); insertion_point[0] = '['; insertion_point[9] = ']'; /* ']' overrides '\0' inserted by rhash_print_sum() */ strcpy(insertion_point + 10, p); /* append file extension */ /* rename the file */ if (rename(info->full_path, new_path) < 0) { log_error(_("can't move %s to %s: %s\n"), info->full_path, new_path, strerror(errno)); free(new_path); return -1; } /* change file name in the file info structure */ if (info->print_path >= info->full_path && info->print_path < p) { file_info_set_print_path(info, new_path + len - strlen(info->print_path)); } else { file_info_set_print_path(info, new_path); } free(info->full_path); info->full_path = new_path; return 0; } /** * Save torrent file to the given path. * * @param path the path to save torrent file to * @param rctx the context containing torrent data * @return 0 on success, -1 on fail with error code in errno */ int save_torrent_to(const char* path, rhash_context* rctx) { file_t file; FILE* fd; int res = 0; const rhash_str* text = rhash_torrent_generate_content(rctx); if (!text) { errno = ENOMEM; log_file_error(path); return -1; } if (if_file_exists(path)) { /* make backup copy of the existing torrent file */ char *bak_path = str_append(path, ".bak"); unlink(bak_path); rename(path, bak_path); free(bak_path); } /* write the torrent file */ file_init(&file, path, FILE_OPT_DONT_FREE_PATH); fd = file_fopen(&file, FOpenWrite | FOpenBin); if (fd && text->length == fwrite(text->str, 1, text->length, fd) && !ferror(fd) && !fflush(fd)) { log_msg(_("%s saved\n"), path); } else { log_file_error(path); res = -1; } if (fd) fclose(fd); file_cleanup(&file); return res; } /** * Save torrent file. * * @param info information about the hashed file */ static void save_torrent(struct file_info* info) { /* append .torrent extension to the file path */ char* path = str_append(info->full_path, ".torrent"); save_torrent_to(path, info->rctx); free(path); } /** * Calculate and print file hash sums using printf format. * * @param out a stream to print to * @param file the file to calculate sums for * @param print_path the path to print * @return 0 on success, -1 on fail */ int calculate_and_print_sums(FILE* out, file_t* file, const char *print_path) { struct file_info info; timedelta_t timer; int res = 0; memset(&info, 0, sizeof(info)); info.file = file; info.full_path = rsh_strdup(file->path); file_info_set_print_path(&info, print_path); info.size = 0; info.sums_flags = opt.sum_flags; if (file->mode & FILE_IFSTDIN) { print_path = "(stdin)"; } else { if (file->mode & FILE_IFDIR) return 0; /* don't handle directories */ info.size = file->size; /* total size, in bytes */ } /* initialize percents output */ init_percents(&info); rsh_timer_start(&timer); if (info.sums_flags) { /* calculate sums */ if (calc_sums(&info) < 0) { /* print i/o error */ log_file_t_error(file); res = -1; } if (rhash_data.interrupted) { report_interrupted(); return 0; } } info.time = rsh_timer_stop(&timer); finish_percents(&info, res); if (opt.flags & OPT_EMBED_CRC) { /* rename the file */ rename_file_by_embeding_crc32(&info); } if ((opt.mode & MODE_TORRENT) && !opt.bt_batch_file) { save_torrent(&info); } if ((opt.mode & MODE_UPDATE) && opt.fmt == FMT_SFV) { /* updating SFV file: print SFV header line */ print_sfv_header_line(rhash_data.upd_fd, file, 0); if (opt.flags & OPT_VERBOSE) { print_sfv_header_line(rhash_data.log, file, 0); fflush(rhash_data.log); } file_cleanup(file); } if (rhash_data.print_list && res >= 0) { if (!opt.bt_batch_file) { print_line(out, rhash_data.print_list, &info); /* print calculated line to stderr or log-file if verbose */ if ((opt.mode & MODE_UPDATE) && (opt.flags & OPT_VERBOSE)) { print_line(rhash_data.log, rhash_data.print_list, &info); } } if ((opt.flags & OPT_SPEED) && info.sums_flags) { print_file_time_stats(&info); } } free(info.full_path); file_info_destroy(&info); return res; } /** * Verify hash sums of the file. * * @param info structure file path to process * @return zero on success, -1 on file error, -2 if hash sums are different */ static int verify_sums(struct file_info *info) { timedelta_t timer; int res = 0; errno = 0; /* initialize percents output */ init_percents(info); rsh_timer_start(&timer); if (calc_sums(info) < 0) { finish_percents(info, -1); return -1; } info->time = rsh_timer_stop(&timer); if (rhash_data.interrupted) { report_interrupted(); return 0; } if ((opt.flags & OPT_EMBED_CRC) && find_embedded_crc32( info->print_path, &info->hc.embedded_crc32)) { info->hc.flags |= HC_HAS_EMBCRC32; assert(info->hc.hash_mask & RHASH_CRC32); } if (!hash_check_verify(&info->hc, info->rctx)) { res = -2; } finish_percents(info, res); if ((opt.flags & OPT_SPEED) && info->sums_flags) { print_file_time_stats(info); } return res; } /** * Check hash sums in a hash file. * Lines beginning with ';' and '#' are ignored. * * @param hash_file_path - the path of the file with hash sums to verify. * @param chdir - true if function should emulate chdir to directory of filepath before checking it. * @return zero on success, -1 on fail */ int check_hash_file(file_t* file, int chdir) { FILE *fd; char buf[2048]; size_t pos; const char *ralign; timedelta_t timer; struct file_info info; const char* hash_file_path = file->path; int res = 0, line_num = 0; double time; /* process --check-embedded option */ if (opt.mode & MODE_CHECK_EMBEDDED) { unsigned crc32; if (find_embedded_crc32(hash_file_path, &crc32)) { /* initialize file_info structure */ memset(&info, 0, sizeof(info)); info.full_path = rsh_strdup(hash_file_path); info.file = file; file_info_set_print_path(&info, info.full_path); info.sums_flags = info.hc.hash_mask = RHASH_CRC32; info.hc.flags = HC_HAS_EMBCRC32; info.hc.embedded_crc32 = crc32; res = verify_sums(&info); fflush(rhash_data.out); if (!rhash_data.interrupted) { if (res == 0) rhash_data.ok++; else if (res == -1 && errno == ENOENT) rhash_data.miss++; rhash_data.processed++; } free(info.full_path); file_info_destroy(&info); } else { log_warning(_("file name doesn't contain a CRC32: %s\n"), hash_file_path); return -1; } return 0; } /* initialize statistics */ rhash_data.processed = rhash_data.ok = rhash_data.miss = 0; rhash_data.total_size = 0; if (file->mode & FILE_IFSTDIN) { fd = stdin; hash_file_path = ""; } else if ( !(fd = file_fopen(file, FOpenRead | FOpenBin) )) { log_file_error(hash_file_path); return -1; } pos = strlen(hash_file_path)+16; ralign = str_set(buf, '-', (pos < 80 ? 80 - (int)pos : 2)); rsh_fprintf(rhash_data.out, _("\n--( Verifying %s )%s\n"), hash_file_path, ralign); fflush(rhash_data.out); rsh_timer_start(&timer); /* mark the directory part of the path, by setting the pos index */ if (chdir) { pos = strlen(hash_file_path); for (; pos > 0 && !IS_PATH_SEPARATOR(hash_file_path[pos]); pos--); if (IS_PATH_SEPARATOR(hash_file_path[pos])) pos++; } else pos = 0; /* read crc file line by line */ for (line_num = 0; fgets(buf, 2048, fd); line_num++) { char* line = buf; char* path_without_ext = NULL; /* skip unicode BOM */ if (line_num == 0 && buf[0] == (char)0xEF && buf[1] == (char)0xBB && buf[2] == (char)0xBF) line += 3; if (*line == 0) continue; /* skip empty lines */ if (is_binary_string(line)) { log_error(_("file is binary: %s\n"), hash_file_path); if (fd != stdin) fclose(fd); return -1; } /* skip comments and empty lines */ if (IS_COMMENT(*line) || *line == '\r' || *line == '\n') continue; memset(&info, 0, sizeof(info)); if (!hash_check_parse_line(line, &info.hc, !feof(fd))) continue; if (info.hc.hash_mask == 0) continue; info.print_path = info.hc.file_path; info.sums_flags = info.hc.hash_mask; /* see if crc file contains a hash sum without a filename */ if (info.print_path == NULL) { char* point; path_without_ext = rsh_strdup(hash_file_path); point = strrchr(path_without_ext, '.'); if (point) { *point = '\0'; file_info_set_print_path(&info, path_without_ext); } } if (info.print_path != NULL) { file_t file_to_check; int is_absolute = IS_PATH_SEPARATOR(info.print_path[0]); IF_WINDOWS(is_absolute = is_absolute || (info.print_path[0] && info.print_path[1] == ':')); /* if filename shall be prepended by a directory path */ if (pos && !is_absolute) { size_t len = strlen(info.print_path); info.full_path = (char*)rsh_malloc(pos + len + 1); memcpy(info.full_path, hash_file_path, pos); strcpy(info.full_path + pos, info.print_path); } else { info.full_path = rsh_strdup(info.print_path); } memset(&file_to_check, 0, sizeof(file_t)); file_to_check.path = info.full_path; file_stat(&file_to_check, 0); info.file = &file_to_check; /* verify hash sums of the file */ res = verify_sums(&info); fflush(rhash_data.out); file_cleanup(&file_to_check); file_info_destroy(&info); if (rhash_data.interrupted) { free(path_without_ext); break; } /* update statistics */ if (res == 0) rhash_data.ok++; else if (res == -1 && errno == ENOENT) rhash_data.miss++; rhash_data.processed++; } free(path_without_ext); } time = rsh_timer_stop(&timer); rsh_fprintf(rhash_data.out, "%s\n", str_set(buf, '-', 80)); print_check_stats(); if (rhash_data.processed != rhash_data.ok) rhash_data.error_flag = 1; if (opt.flags & OPT_SPEED && rhash_data.processed > 1) { print_time_stats(time, rhash_data.total_size, 1); } rhash_data.processed = 0; res = ferror(fd); /* check that crc file has been read without errors */ if (fd != stdin) fclose(fd); return (res == 0 ? 0 : -1); } /*========================================================================= * Benchmark functions *=========================================================================*/ /** * Hash a repeated message chunk by specified hash function. * * @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 benchmark_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 && !rhash_data.interrupted; i++) { rhash_update(context, message, msg_size); } rhash_final(context, out); rhash_free(context); return 1; } #if defined(_MSC_VER) #define ALIGN_DATA(n) __declspec(align(n)) #elif defined(__GNUC__) #define ALIGN_DATA(n) __attribute__((aligned (n))) #else #define ALIGN_DATA(n) /* do nothing */ #endif /* define read_tsc() if possible */ #if defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64__) || defined(_M_AMD64) || defined(_M_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 /* x86/amd64 arch */ void run_benchmark(unsigned hash_id, unsigned flags) { unsigned char ALIGN_DATA(16) 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 */ #ifdef _WIN32 set_benchmark_cpu_affinity(); /* 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_GOST | RHASH_GOST_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 && !rhash_data.interrupted; j++) { rsh_timer_start(&timer); benchmark_loop(hash_id, message, sizeof(message), (int)(msg_size / sizeof(message)), out); time = rsh_timer_stop(&timer); total_time += time; if ((flags & BENCHMARK_RAW) == 0 && !rhash_data.interrupted) { rsh_fprintf(rhash_data.out, "%s %u MiB calculated in %.3f sec, %.3f MBps\n", hash_name, (unsigned)sz_mb, time, (double)sz_mb / time); fflush(rhash_data.out); } } #if defined(HAVE_TSC) /* measure the CPU "clocks per byte" speed */ if ((flags & BENCHMARK_CPB) != 0 && !rhash_data.interrupted) { 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(); benchmark_loop(hash_id, message, sizeof(message), msg_size / sizeof(message), out); cy1 = read_tsc(); benchmark_loop(hash_id, message, sizeof(message), msg_size / sizeof(message), out); benchmark_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 (rhash_data.interrupted) { report_interrupted(); return; } if (flags & BENCHMARK_RAW) { /* output result in a "raw" machine-readable format */ rsh_fprintf(rhash_data.out, "%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 & BENCHMARK_CPB) { rsh_fprintf(rhash_data.out, "\t%.2f", cpb); } #endif /* HAVE_TSC */ rsh_fprintf(rhash_data.out, "\n"); } else { rsh_fprintf(rhash_data.out, "%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 & BENCHMARK_CPB) { rsh_fprintf(rhash_data.out, ", CPB=%.2f", cpb); } #endif /* HAVE_TSC */ rsh_fprintf(rhash_data.out, "\n"); } } RHash-1.3.6/calc_sums.h000066400000000000000000000036531325207677100146710ustar00rootroot00000000000000/* calc_sums.h */ #ifndef CALC_SUMS_H #define CALC_SUMS_H #include #include "common_func.h" #include "hash_check.h" #ifdef __cplusplus extern "C" { #endif struct file_t; /** * Information about a file to calculate/verify hashes for. */ struct file_info { /* the file path (in system encoding). It can be changed * if a crc sum is embedded into the filename. */ char* full_path; const char* print_path; /* the part of the path for printing */ char* utf8_print_path; /* file path in UTF8 */ uint64_t size; /* the size of the hashed file */ uint64_t msg_offset; /* rctx->msg_size before hashing this file */ double time; /* file processing time in seconds */ struct file_t* file; /* the file being processed */ struct rhash_context* rctx; /* state of hash algorithms */ int error; /* -1 for i/o error, -2 for wrong sum, 0 on success */ char* allocated_ptr; unsigned sums_flags; /* mask of ids of calculated hash functions */ struct hash_check hc; /* hash values parsed from a hash file */ }; void file_info_destroy(struct file_info*); /* free allocated memory */ const char* file_info_get_utf8_print_path(struct file_info*); int save_torrent_to(const char* path, struct rhash_context* rctx); int calculate_and_print_sums(FILE* out, struct file_t* file, const char *print_path); int check_hash_file(struct file_t* file, int chdir); int rename_file_by_embeding_crc32(struct file_info *info); /* 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 a hash algorithm. * * @param hash_id hash algorithm identifier * @param flags benchmark flags, can contain BENCHMARK_CPB, BENCHMARK_RAW */ void run_benchmark(unsigned hash_id, unsigned flags); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* CALC_SUMS_H */ RHash-1.3.6/common_func.c000066400000000000000000000421221325207677100152100ustar00rootroot00000000000000/* common_func.c - functions used almost everywhere */ #include #include #include #include #include #include #include #if defined( _WIN32) || defined(__CYGWIN__) # include #endif #include "common_func.h" #include "parse_cmdline.h" #include "version.h" #include "win_utils.h" /*========================================================================= * String functions *=========================================================================*/ /** * Print a 0-terminated string representation of a 64-bit number to * a string buffer. * * @param dst the string buffer to write the number to * @param number the 64-bit number to output * @param min_width the minimum width, the number must take */ void sprintI64(char *dst, uint64_t number, int min_width) { char buf[24]; /* internal buffer to output the number to */ size_t len; char *p = buf + 23; /* start filling from the buffer end */ *(p--) = 0; /* last symbol should be '\0' */ if (number == 0) { *(p--) = '0'; } else { for (; p >= buf && number != 0; p--, number /= 10) { *p = '0' + (char)(number % 10); } } len = buf + 22 - p; if ((size_t)min_width > len) { memset(dst, 0x20, min_width - len); /* fill by spaces */ dst += min_width - len; } memcpy(dst, p+1, len+1); /* copy the number to the output buffer */ } /** * Calculate length of decimal representation of given 64-bit integer. * * @param num integer to calculate the length for * @return length of decimal representation */ int int_len(uint64_t num) { int len; for (len = 0; num; len++, num /= 10); return (len == 0 ? 1 : len); /* note: int_len(0) == 1 */ } /** * Convert a byte to a hexadecimal string. The result, consisting of two * hexadecimal digits is stored into a buffer. * * @param dst the buffer to receive two symbols of hex representation * @param byte the byte to decode * @param upper_case flag to print string in uppercase * @return pointer to the next char in buffer (dst+2) */ static char* print_hex_byte(char *dst, const unsigned char byte, int upper_case) { const char add = (upper_case ? 'A' - 10 : 'a' - 10); unsigned char c = (byte >> 4) & 15; *dst++ = (c > 9 ? c + add : c + '0'); c = byte & 15; *dst++ = (c > 9 ? c + add : c + '0'); return dst; } /* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */ #define IS_GOOD_URL_CHAR(c) (isalnum((unsigned char)c) || strchr("$-_.!'(),", c)) /** * URL-encode a string. * * @param dst buffer to receive result or NULL to calculate * the lengths of encoded string * @param filename the file name * @return the length of the result string */ int urlencode(char *dst, const char *name) { const char *start; if (!dst) { int len; for (len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3); return len; } /* encode URL as specified by RFC 1738 */ for (start = dst; *name; name++) { if ( IS_GOOD_URL_CHAR(*name) ) { *dst++ = *name; } else { *dst++ = '%'; dst = print_hex_byte(dst, *name, 'A'); } } *dst = 0; return (int)(dst - start); } /** * Convert given string to lower case. * The result string will be allocated by malloc. * The allocated memory should be freed by calling free(). * * @param str a string to convert * @return converted string allocated by malloc */ char* str_tolower(const char* str) { char* buf = rsh_strdup(str); char* p; if (buf) { for (p = buf; *p; p++) *p = tolower(*p); } return buf; } /** * Remove spaces from the begin and the end of the string. * * @param str the modifiable buffer with the string * @return trimmed string */ char* str_trim(char* str) { char* last = str + strlen(str) - 1; while (isspace((unsigned char)*str)) str++; while (isspace((unsigned char)*last) && last > str) *(last--) = 0; return str; } /** * Fill a buffer with NULL-terminated string consisting * solely of a given repeated character. * * @param buf the modifiable buffer to fill * @param ch the character to fill string with * @param length the length of the string to construct * @return the buffer */ char* str_set(char* buf, int ch, int length) { memset(buf, ch, length); buf[length] = '\0'; return buf; } /** * Concatenates two strings and returns allocated buffer with result. * * @param orig original string * @param append the string to append * @return the buffer */ char* str_append(const char* orig, const char* append) { size_t len1 = strlen(orig); size_t len2 = strlen(append); char* res = (char*)rsh_malloc(len1 + len2 + 1); /* concatenate two strings */ memcpy(res, orig, len1); memcpy(res + len1, append, len2 + 1); return res; } /** * Check if a string is a binary string, which means the string contain * a character with ACII code below 0x20 other than '\r', '\n', '\t'. * * @param str a string to check * @return non zero if string is binary */ int is_binary_string(const char* str) { for (; *str; str++) { if (((unsigned char)*str) < 32 && ((1 << (unsigned char)*str) & ~0x2600)) { return 1; } } return 0; } /** * Count number of utf8 characters in a 0-terminated string * * @param str the string to measure * @return number of utf8 characters in the string */ size_t strlen_utf8_c(const char *str) { size_t length = 0; for (; *str; str++) { if ((*str & 0xc0) != 0x80) length++; } return length; } /*========================================================================= * Program version information *=========================================================================*/ const char* get_version_string(void) { static const char* version_string = VERSION; return version_string; } const char* get_bt_program_name(void) { static const char* bt_program_name = PROGRAM_NAME "/" VERSION; return bt_program_name; } /*========================================================================= * Timer functions *=========================================================================*/ /** * Return real-value representing number of seconds * stored in the given timeval structure. * The function is used with timers, when printing time statistics. * * @param delta time delta to be converted * @return number of seconds */ static double rsh_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 } #if defined( _WIN32) || defined(__CYGWIN__) #define get_timedelta(delta) QueryPerformanceCounter((LARGE_INTEGER*)delta) #else #define get_timedelta(delta) gettimeofday(delta, NULL) #endif void rsh_timer_start(timedelta_t* timer) { get_timedelta(timer); } double rsh_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 rsh_fsec(timer); } unsigned rhash_get_ticks(void) { #if defined( _WIN32) || defined(__CYGWIN__) return GetTickCount(); #else struct timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec * 1000 + tv.tv_usec / 1000); #endif } /*========================================================================= * Custom program exit function *=========================================================================*/ struct rhash_exit_handlers_t { unsigned handlers_count; exit_handler_t handlers[4]; } rhash_exit_handlers = { 0, { 0 } }; /** * Install a handler to be called on program exit. * * @param handler the hadler to add */ void rsh_install_exit_handler(exit_handler_t handler) { if (rhash_exit_handlers.handlers_count >= (sizeof(rhash_exit_handlers.handlers) / sizeof(rhash_exit_handlers.handlers[0]))) { assert(!"to many handlers"); rsh_exit(2); } rhash_exit_handlers.handlers[rhash_exit_handlers.handlers_count] = handler; rhash_exit_handlers.handlers_count++; } /** * Remove the last installed exit handler. */ void rsh_remove_exit_handler(void) { if (rhash_exit_handlers.handlers_count == 0) { assert(rhash_exit_handlers.handlers_count > 0 && "no handlers installed"); rsh_exit(2); } rhash_exit_handlers.handlers_count--; } /** * Call all installed exit handlers, starting from the latest one, and exit the program. * * @param code the program exit code */ void rsh_exit(int code) { while (rhash_exit_handlers.handlers_count > 0) rhash_exit_handlers.handlers[--rhash_exit_handlers.handlers_count](); exit(code); } /*========================================================================= * Error reporting functions *=========================================================================*/ static void report_error_default(const char* srcfile, int srcline, const char* format, ...); void (*rsh_report_error)(const char* srcfile, int srcline, const char* format, ...) = report_error_default; /** * Print given library failure to stderr. * * @param srcfile source file to report error on fail * @param srcline source code line to be reported on fail * @param format printf-formatted error message */ static void report_error_default(const char* srcfile, int srcline, const char* format, ...) { va_list ap; rsh_fprintf(stderr, "RHash: error at %s:%u: ", srcfile, srcline); va_start(ap, format); rsh_vfprintf(stderr, format, ap); /* report the error to stderr */ va_end(ap); } /*========================================================================= * Memory functions *=========================================================================*/ /** * Allocates a buffer via malloc with reporting memory error to stderr. * * @param size size of the block to allocate * @param srcfile source file to report error on fail * @param srcline source code line to be reported on fail * @return allocated block */ void* rhash_malloc(size_t size, const char* srcfile, int srcline) { void* res = malloc(size); if (!res) { rsh_report_error(srcfile, srcline, "%s(%u) failed\n", "malloc", (unsigned)size); rsh_exit(2); } return res; } /** * Allocates a buffer via calloc with reporting memory error to stderr. * * @param num number of elements to be allocated * @param size size of elements * @param srcfile source file to report error on fail * @param srcline source code line to be reported on fail * @return allocated block */ void* rhash_calloc(size_t num, size_t size, const char* srcfile, int srcline) { void* res = calloc(num, size); if (!res) { rsh_report_error(srcfile, srcline, "calloc(%u, %u) failed\n", (unsigned)num, (unsigned)size); rsh_exit(2); } return res; } /** * Duplicate c-string with reporting memory error to stderr. * * @param str the zero-terminated string to duplicate * @param srcfile source file to report error on fail * @param srcline source code line to be reported on fail * @return allocated memory buffer with copied string */ char* rhash_strdup(const char* str, const char* srcfile, int srcline) { #ifndef __STRICT_ANSI__ char* res = strdup(str); #else char* res = (char*)malloc(strlen(str)+1); if (res) strcpy(res, str); #endif if (!res) { rsh_report_error(srcfile, srcline, "strdup(\"%s\") failed\n", str); rsh_exit(2); } return res; } #ifdef _WIN32 /** * Duplicate wide string with reporting memory error to stderr. * * @param str the zero-terminated string to duplicate * @param srcfile source file to report error on fail * @param srcline source code line to be reported on fail * @return allocated memory buffer with copied string */ wchar_t* rhash_wcsdup(const wchar_t* str, const char* srcfile, int srcline) { #ifndef __STRICT_ANSI__ wchar_t* res = wcsdup(str); #else wchar_t* res = (wchar_t*)malloc((wcslen(str) + 1) * sizeof(wchar_t)); if (res) wcscpy(res, str); #endif if (!res) { rsh_report_error(srcfile, srcline, "wcsdup(\"%u\") failed\n", (wcslen(str) + 1)); rsh_exit(2); } return res; } #endif /** * Reallocates a buffer via realloc with reporting memory error to stderr. * * @param mem a memory block to re-allocate * @param size the new size of the block * @param srcfile source file to report error on fail * @param srcline source code line to be reported on fail * @return re-allocated memory buffer */ void* rhash_realloc(void* mem, size_t size, const char* srcfile, int srcline) { void* res = realloc(mem, size); if (!res) { rsh_report_error(srcfile, srcline, "realloc(%p, %u) failed\n", mem, (unsigned)size); rsh_exit(2); } return res; } /*========================================================================= * Containers *=========================================================================*/ /** * Allocate an empty vector. * * @param destructor pointer to the cleanup/deallocate function called * on each element when the vector is destructed, * NULL if items doesn't need to be freed * @return allocated vector */ vector_t* rsh_vector_new(void (*destructor)(void*)) { vector_t* ptr = (vector_t*)rsh_malloc(sizeof(vector_t)); memset(ptr, 0, sizeof(vector_t)); ptr->destructor = destructor; return ptr; } /** * Allocate an empty vector of pointers to memory blocks, * which will be deallocated at destruction time by calling free(). * * @return allocated vector */ struct vector_t* rsh_vector_new_simple(void) { return rsh_vector_new(free); } /** * Release memory allocated by vector, but the vector structure itself. * * @param vect the vector to free */ void rsh_vector_destroy(vector_t* vect) { if (!vect) return; if (vect->destructor) { unsigned i; for (i=0; isize; i++) vect->destructor(vect->array[i]); } free(vect->array); vect->size = vect->allocated = 0; vect->array = 0; } /** * Release all memory allocated by vector. * * @param vect the vector to free */ void rsh_vector_free(vector_t* vect) { rsh_vector_destroy(vect); free(vect); } /** * Add an item to vector. * * @param vect vector to add item to * @param item the item to add */ void rsh_vector_add_ptr(vector_t* vect, void* item) { /* check if vect contains enough space for the next item */ if (vect->size >= vect->allocated) { size_t size = (vect->allocated==0 ? 128 : vect->allocated * 2); vect->array = (void**)rsh_realloc(vect->array, size * sizeof(void*)); vect->allocated = size; } /* add new item to the vector */ vect->array[vect->size] = item; vect->size++; } /** * Add a sized item to vector. * * @param vect pointer to the vector to add item to * @param item_size the size of a vector item */ void rsh_vector_add_empty(struct vector_t* vect, size_t item_size) { /* check if vect contains enough space for next item */ if (vect->size >= vect->allocated) { size_t size = (vect->allocated==0 ? 128 : vect->allocated * 2); vect->array = (void**)rsh_realloc(vect->array, size * item_size); vect->allocated = size; } vect->size++; } /** * Initialize empty blocks vector. * * @param bvector pointer to the blocks vector */ void rsh_blocks_vector_init(blocks_vector_t* bvector) { memset(bvector, 0, sizeof(*bvector)); bvector->blocks.destructor = free; } /** * Free memory allocated by blocks vector, the function * doesn't deallocate memory additionally allocated for each element. * * @param bvector pointer to the blocks vector */ void rsh_blocks_vector_destroy(blocks_vector_t* bvector) { rsh_vector_destroy(&bvector->blocks); } /*========================================================================= * String buffer functions *=========================================================================*/ /** * Allocate an empty string buffer. * * @return allocated string buffer */ strbuf_t* rsh_str_new(void) { strbuf_t *res = (strbuf_t*)malloc(sizeof(strbuf_t)); memset(res, 0, sizeof(strbuf_t)); return res; } /** * Free memory allocated by string buffer object * * @param ptr pointer to the string buffer to destroy */ void rsh_str_free(strbuf_t* ptr) { if (ptr) { free(ptr->str); free(ptr); } } /** * Grow, if needed, internal buffer of the given string to ensure it contains * at least new_size number bytes. * * @param str pointer to the string-buffer object * @param new_size number of bytes buffer must contain */ void rsh_str_ensure_size(strbuf_t *str, size_t new_size) { if (new_size >= (size_t)str->allocated) { if (new_size < 64) new_size = 64; str->str = (char*)rsh_realloc(str->str, new_size); str->allocated = new_size; } } /** * Append a sequence of single-byte characters of the specified length to * string buffer. The array is fully copied even if it contains the '\\0' * character. The function ensures the string buffer still contains * null-terminated string. * * @param str pointer to the string buffer * @param text the text to append * @param length number of character to append. */ void rsh_str_append_n(strbuf_t *str, const char* text, size_t length) { rsh_str_ensure_length(str, str->len + length + 1); memcpy(str->str + str->len, text, length); str->len += length; str->str[str->len] = '\0'; } /** * Append a null-terminated string to the string string buffer. * * @param str pointer to the string buffer * @param text the null-terminated string to append */ void rsh_str_append(strbuf_t *str, const char* text) { rsh_str_append_n(str, text, strlen(text)); } RHash-1.3.6/common_func.h000066400000000000000000000151061325207677100152170ustar00rootroot00000000000000/* common_func.h - commonly used functions */ #ifndef COMMON_FUNC_H #define COMMON_FUNC_H /* internationalization support via gettext/libintl */ #ifdef USE_GETTEXT # include # define _(str) gettext(str) # define TEXT_DOMAIN "rhash" # ifndef LOCALEDIR # define LOCALEDIR "/usr/share/locale" # endif /* LOCALEDIR */ #else # define _(str) (str) #endif /* USE_GETTEXT */ #include #include #include /* for time_t */ #include /* for wchar_t */ #if !defined( _WIN32) && !defined(__CYGWIN__) # include /* for timeval */ #elif _MSC_VER > 1300 # include "platform.h" #endif #ifdef __cplusplus extern "C" { #endif /* string function */ void sprintI64(char *dst, uint64_t number, int max_width); int int_len(uint64_t num); int urlencode(char *dst, const char *name); int is_binary_string(const char* str); char* str_tolower(const char* str); char* str_trim(char* str); char* str_set(char* buf, int ch, int size); char* str_append(const char* orig, const char* append); size_t strlen_utf8_c(const char *str); #define IS_COMMENT(c) ((c) == ';' || (c) == '#') #ifdef _WIN32 typedef wchar_t rsh_tchar; # define RSH_T(str) L##str # define t2c(tstr) (w2c(tstr)) #else typedef char rsh_tchar; # define RSH_T(str) str # define t2c(tstr) (tstr) #endif /* _WIN32 */ typedef rsh_tchar* tstr_t; typedef const rsh_tchar* ctstr_t; #ifdef _WIN32 # define IF_WINDOWS(code) code # define is_utf8() win_is_utf8() # define to_utf8(str) win_to_utf8(str) #else /* non _WIN32 part */ # define IF_WINDOWS(code) /* stub for utf8 */ # define is_utf8() 1 # define to_utf8(str) NULL #endif /* _WIN32 */ /* version information */ const char* get_version_string(void); const char* get_bt_program_name(void); #ifdef _WIN32 # define rsh_fprintf win_fprintf # define rsh_vfprintf win_vfprintf # define rsh_fwrite win_fwrite #else # define rsh_fprintf fprintf # define rsh_vfprintf vfprintf # define rsh_fwrite fwrite #endif /* time data and functions */ /* portable timer definition */ #if defined( _WIN32) || defined(__CYGWIN__) typedef unsigned long long timedelta_t; #else #include /* for timeval */ typedef struct timeval timedelta_t; #endif /** * Start a timer. * * @param timer timer to start */ void rsh_timer_start(timedelta_t* timer); /** * Stop given timer. * * @param timer the timer to stop * @return number of seconds timed */ double rsh_timer_stop(timedelta_t* timer); /** * Return ticks in milliseconds for time intervals measurement. * This function should be optimized for speed and retrieve * internal clock value, if possible. * * @return ticks count in milliseconds */ unsigned rhash_get_ticks(void); /* program exit handlers */ typedef void (*exit_handler_t)(void); void rsh_install_exit_handler(exit_handler_t handler); void rsh_remove_exit_handler(void); void rsh_exit(int code); /* clever malloc with error detection */ #define rsh_malloc(size) rhash_malloc(size, __FILE__, __LINE__) #define rsh_calloc(num, size) rhash_calloc(num, size, __FILE__, __LINE__) #define rsh_strdup(str) rhash_strdup(str, __FILE__, __LINE__) #define rsh_realloc(mem, size) rhash_realloc(mem, size, __FILE__, __LINE__) void* rhash_malloc(size_t size, const char* srcfile, int srcline); void* rhash_calloc(size_t num, size_t size, const char* srcfile, int srcline); char* rhash_strdup(const char* str, const char* srcfile, int srcline); void* rhash_realloc(void* mem, size_t size, const char* srcfile, int srcline); #ifdef _WIN32 #define rsh_wcsdup(str) rhash_wcsdup(str, __FILE__, __LINE__) wchar_t* rhash_wcsdup(const wchar_t* str, const char* srcfile, int srcline); #endif extern void (*rsh_report_error)(const char* srcfile, int srcline, const char* format, ...); /* vector functions */ typedef struct vector_t { void **array; size_t size; size_t allocated; void (*destructor)(void*); } vector_t; vector_t* rsh_vector_new(void (*destructor)(void*)); vector_t* rsh_vector_new_simple(void); void rsh_vector_free(vector_t* vect); void rsh_vector_destroy(vector_t* vect); void rsh_vector_add_ptr(vector_t* vect, void *item); void rsh_vector_add_empty(vector_t* vect, size_t item_size); #define rsh_vector_add_uint32(vect, item) { \ rsh_vector_add_empty(vect, item_size); \ ((unsigned*)(vect)->array)[(vect)->size - 1] = item; \ } #define rsh_vector_add_item(vect, item, item_size) { \ rsh_vector_add_empty(vect, item_size); \ memcpy(((char*)(vect)->array) + item_size * ((vect)->size - 1), item, item_size); \ } /* a vector pattern implementation, allocating elements by blocks */ typedef struct blocks_vector_t { size_t size; vector_t blocks; } blocks_vector_t; void rsh_blocks_vector_init(blocks_vector_t*); void rsh_blocks_vector_destroy(blocks_vector_t* vect); #define rsh_blocks_vector_get_item(bvector, index, blocksize, item_type) \ (&((item_type*)((bvector)->blocks.array[(index) / (blocksize)]))[(index) % (blocksize)]) #define rsh_blocks_vector_get_ptr(bvector, index, blocksize, item_size) \ (&((unsigned char*)((bvector)->blocks.array[(index) / (blocksize)]))[(item_size) * ((index) % (blocksize))]) #define rsh_blocks_vector_add(bvector, item, blocksize, item_size) { \ if (((bvector)->size % (blocksize)) == 0) \ rsh_vector_add_ptr(&((bvector)->blocks), rsh_malloc((item_size) * (blocksize))); \ memcpy(rsh_blocks_vector_get_ptr((bvector), (bvector)->size, (blocksize), (item_size)), (item), (item_size)); \ (bvector)->size++; \ } #define rsh_blocks_vector_add_ptr(bvector, ptr, blocksize) { \ if (((bvector)->size % (blocksize)) == 0) \ rsh_vector_add_ptr(&((bvector)->blocks), rsh_malloc(sizeof(void*) * (blocksize))); \ ((void***)(bvector)->blocks.array)[(bvector)->size / (blocksize)][(bvector)->size % (blocksize)] = (void*)ptr; \ (bvector)->size++; \ } #define rsh_blocks_vector_add_empty(bvector, blocksize, item_size) { \ if ( (((bvector)->size++) % (blocksize)) == 0) \ rsh_vector_add_ptr(&((bvector)->blocks), rsh_malloc((item_size) * (blocksize))); \ } /* string buffer functions */ typedef struct strbuf_t { char* str; size_t allocated; size_t len; } strbuf_t; strbuf_t* rsh_str_new(void); void rsh_str_free(strbuf_t* buf); void rsh_str_ensure_size(strbuf_t *str, size_t new_size); void rsh_str_append_n(strbuf_t *str, const char* text, size_t len); void rsh_str_append(strbuf_t *str, const char* text); #define rsh_str_ensure_length(str, len) \ if ((size_t)(len) >= (size_t)(str)->allocated) rsh_str_ensure_size((str), (len) + 1); #define rsh_wstr_ensure_length(str, len) \ if ((size_t)((len) + sizeof(wchar_t)) > (size_t)(str)->allocated) rsh_str_ensure_size((str), (len) + sizeof(wchar_t)); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* COMMON_FUNC_H */ RHash-1.3.6/configure000077500000000000000000000637001325207677100144550ustar00rootroot00000000000000#!/bin/sh # set default values OPT_OPENSSL=auto OPT_OPENSSL_RUNTIME=auto OPT_GETTEXT=auto export LC_ALL=C CFG_LINE="$*" INSTALL_PREFIX="/usr/local" test -z "$CC" && CC=cc CMD_AR=ar CMD_INSTALL=install BUILD_DEBUG= BUILD_STATIC=auto BUILD_EXTRA_CFLAGS= BUILD_EXTRA_LDFLAGS= CHECK_LDFLAGS= WARN_CFLAGS="-Wall -W -Wstrict-prototypes -Wnested-externs -Winline -Wpointer-arith -Wbad-function-cast -Wmissing-prototypes -Wmissing-declarations" INSTALL_SYMLINKS="sfv-hash tiger-hash tth-hash whirlpool-hash has160-hash gost-hash edonr256-hash edonr512-hash ed2k-link magnet-link" INSTALL_LIB_STATIC=auto INSTALL_LIB_SHARED=auto INSTALL_PKGCONFIGDIR="$PKG_INSTALLDIR" case $(echo -n) in -n) # SysV style ECHO_N= ECHO_C='\c' ;; *) # BSD style ECHO_N='-n ' ECHO_C= ;; esac # display error message and exit die () { echo echo "Error: $@" >&2 echo >&2 test -f "$TMPLOG" && echo "Error: $@" >> "$TMPLOG" rm -f "$TMPBIN" "$TMPC" "$TMPT" echo "Check \"$TMPLOG\" if you do not understand why it failed." exit 1 } print_help() { cat << EOF Usage: configure [OPTIONS]... Generic Options: -h, --help display this help and exit --cc=COMPILER C compiler to build RHash [gcc] --ar=AR librarian to build RHash [ar] --target=PLATFORM target platform (i386-linux, arm-linux, etc) --with-install=PATH path to a custom install program Directory Options: --prefix=DIR prefix directory for installation [/usr/local] --exec-prefix=DIR prefix directory for binaries [PREFIX] --bindir=DIR directory for installing binaries [EXEC_PREFIX/bin] --sysconfdir=DIR directory to look for configuration file [PREFIX/etc] --mandir=DIR directory for installing man pages [PREFIX/share/man] --libdir=DIR directory for the rhash library [EXEC_PREFIX/lib] --pkgconfigdir=DIR directory for pkg-config files [LIBDIR/pkgconfig] --localedir=DIR directory for locale files [PREFIX/share/locale] Features options: --disable-FEATURE do not include FEATURE --enable-gettext enable gettext (localization) support [autodetect] --enable-openssl enable OpenSSL (optimized hash functions) support [autodetect] --enable-openssl-runtime load OpenSSL at runtime if present [autodetect] --enable-static statically link RHash binary --enable-lib-static build and install LibRHash static library [auto] --enable-lib-shared build and install LibRHash shared library [auto] --enable-symlinks[=LIST] install symlinks to the binary [enable] Use these options if autodetection fails: --extra-cflags=FLAGS extra CFLAGS --extra-ldflags=FLAGS extra LDFLAGS EOF exit 0 } get_opt_value() { echo $(echo $* | cut -d '=' -f 2-) } for OPT do case "$OPT" in --help|-help|-h) print_help ;; --prefix=*) INSTALL_PREFIX=$(get_opt_value $OPT) ;; --exec-prefix=*) INSTALL_EXEC_PREFIX=$(get_opt_value $OPT) INSTALL_EXEC_PREFIX_SET=yes ;; --bindir=*) INSTALL_BINDIR=$(get_opt_value $OPT) ;; --mandir=*) INSTALL_MANDIR=$(get_opt_value $OPT) ;; --sysconfdir=*) INSTALL_SYSCONFDIR=$(get_opt_value $OPT) ;; --libdir=*) INSTALL_LIBDIR=$(get_opt_value $OPT) ;; --pkgconfigdir=*) INSTALL_PKGCONFIGDIR=$(get_opt_value $OPT) ;; --localedir=*) INSTALL_LOCALEDIR=$(get_opt_value $OPT) ;; --enable-gettext) OPT_GETTEXT=yes ;; --disable-gettext) OPT_GETTEXT=no ;; --enable-openssl) OPT_OPENSSL=yes ;; --disable-openssl) OPT_OPENSSL=no ;; --enable-openssl-runtime) OPT_OPENSSL_RUNTIME=yes ;; --disable-openssl-runtime) OPT_OPENSSL_RUNTIME=no ;; --target=*) BUILD_TARGET=$(get_opt_value $OPT) ;; --cc=*) CC=$(get_opt_value $OPT) ;; --ar=*) CMD_AR=$(get_opt_value $OPT) ;; --enable-static) BUILD_STATIC=yes ;; --disable-static) BUILD_STATIC=no ;; --enable-lib-static) INSTALL_LIB_STATIC=yes ;; --disable-lib-static) INSTALL_LIB_STATIC=no ;; --enable-lib-shared) INSTALL_LIB_SHARED=yes ;; --disable-lib-shared) INSTALL_LIB_SHARED=no ;; --enable-symlinks) # use default INSTALL_SYMLINKS list ;; --enable-symlinks=*) INSTALL_SYMLINKS=$(get_opt_value $OPT) ;; --disable-symlinks) INSTALL_SYMLINKS= ;; --enable-debug) BUILD_DEBUG='-g' ;; --enable-debug=*) BUILD_DEBUG='-g'$(get_opt_value $OPT) ;; --disable-debug) BUILD_DEBUG= ;; --with-install=*) CMD_INSTALL=$(get_opt_value $OPT) ;; --extra-cflags=*) BUILD_EXTRA_CFLAGS=$(get_opt_value $OPT) ;; --extra-ldflags=*) BUILD_EXTRA_LDFLAGS=$(get_opt_value $OPT) ;; *) echo "unknown option $OPT" exit 1 ;; esac shift done # set variables which use INSTALL_PREFIX test -z "$INSTALL_EXEC_PREFIX_SET" && INSTALL_EXEC_PREFIX="$INSTALL_PREFIX" test -z "$INSTALL_BINDIR" && INSTALL_BINDIR="$INSTALL_EXEC_PREFIX/bin" test -z "$INSTALL_MANDIR" && INSTALL_MANDIR="$INSTALL_PREFIX/share/man" test -z "$INSTALL_SYSCONFDIR" && INSTALL_SYSCONFDIR="$INSTALL_PREFIX/etc" test -z "$INSTALL_INCDIR" && INSTALL_INCDIR="$INSTALL_PREFIX/include" test -z "$INSTALL_LIBDIR" && INSTALL_LIBDIR="$INSTALL_EXEC_PREFIX/lib" test -z "$INSTALL_PKGCONFIGDIR" && INSTALL_PKGCONFIGDIR="$INSTALL_LIBDIR/pkgconfig" test -z "$INSTALL_LOCALEDIR" && INSTALL_LOCALEDIR="$INSTALL_PREFIX/share/locale" # detect and prepare tmp directory for DETECT_TMP in "$TMPDIR" "$TEMPDIR" "/tmp" ; do test -d "$DETECT_TMP" && break done RANDNUM=$RANDOM test -z $RANDNUM && which jot >/dev/null && RANDNUM=$(jot -r 1 1 32767) BUILD_TMPDIR="$DETECT_TMP/rhash-configure-$RANDNUM-$$" mkdir $BUILD_TMPDIR || die "Unable to create tmp dir." TMPC="$BUILD_TMPDIR/tmp.c" TMPT="$BUILD_TMPDIR/tmp.txt" TMPBIN="$BUILD_TMPDIR/tmp" TMPLOG="config.log" rm -f "$TMPLOG" echo "Configuration parameters: \"$CFG_LINE\"" > "$TMPLOG" echo "Symlinks to install: $INSTALL_SYMLINKS" >> "$TMPLOG" echo >> "$TMPLOG" remove_tmpdir() { rm -rf "$BUILD_TMPDIR" } trap remove_tmpdir EXIT str_concat() { echo ${ECHO_N} $@ ${ECHO_C} } yn_nonempty() { test -n "$1" && echo yes || echo no; } # Use this before starting a check start_check() { echo "============ Checking for $1 ============" >> "$TMPLOG" echo ${ECHO_N} "Checking for $1 ... ${ECHO_C}" res_comment="" } # Use this to echo the results of a check finish_check() { if test "$res_comment" ; then res_comment="($res_comment)" fi echo "Result is: $1 $res_comment" >> "$TMPLOG" echo "=============================================" >> "$TMPLOG" echo "" >> "$TMPLOG" echo "$1 $res_comment" res_comment="" } # check source file compilation and return exit code compile_check() { source="$1" shift echo >> "$TMPLOG" echo "----- source file: $source -----" >> "$TMPLOG" cat "$source" >> "$TMPLOG" echo "----- end of file: $source -----" >> "$TMPLOG" echo "$CC $OPTFLAGS $WARN_CFLAGS $CFLAGS $source $BUILD_EXTRA_CFLAGS $BUILD_EXTRA_LDFLAGS $CHECK_LDFLAGS -o $TMPBIN $@" >> "$TMPLOG" rm -f "$TMPBIN" $CC $OPTFLAGS $WARN_CFLAGS $CFLAGS "$source" $BUILD_EXTRA_CFLAGS $BUILD_EXTRA_LDFLAGS $CHECK_LDFLAGS -o "$TMPBIN" "$@" >> "$TMPLOG" 2>&1 TMPRES="$?" echo "Compilation result: $TMPRES" >> "$TMPLOG" echo >> "$TMPLOG" return "$TMPRES" } cc_check() { compile_check $TMPC $@ } create_c_file() { rm -f "$TMPC" if test -n "$1"; then echo "#include <$1>" > $TMPC || die "Can't write to the $TMPC file" fi } cc_check_macro() { create_c_file "$1" cat >> $TMPC << EOF #ifndef $2 #error condition not true: $2 #endif int main(void) { return 0; } EOF shift 2 cc_check $@ } cc_check_cflag() { echo "int main(void) { return 0; }" > $TMPC cc_check $@ } cc_check_headers() { rm -f "$TMPC" while test -n "$1"; do echo "#include <$1>" >> $TMPC shift done echo "int main(void) { return 0; }" >> $TMPC cc_check "-c" } cc_check_statement() { create_c_file "$1" cat >> $TMPC << EOF int main(void) { $2 return 0; } EOF shift 2 cc_check $@ } # detect host and target OS start_check "target OS" HOST_OS=$(uname -s 2>&1) case "$HOST_OS" in Linux|FreeBSD|NetBSD|OpenBSD|DragonFly|BSD/OS|Darwin|SunOS|QNX|GNU|MorphOS|AIX|AmigaOS|Haiku) ;; IRIX*) HOST_OS=IRIX ;; GNU/kFreeBSD) HOST_OS=FreeBSD ;; HP-UX*) HOST_OS=HP-UX ;; MINGW32*) HOST_OS=MINGW32 ;; MINGW64*) HOST_OS=MINGW64 ;; MSYS*) HOST_OS=MSYS ;; [cC][yY][gG][wW][iI][nN]*) HOST_OS=CYGWIN ;; OS/2*) HOST_OS=OS/2 ;; *) HOST_OS="$HOST_OS-UNKNOWN" ;; esac if test -z "$BUILD_TARGET" ; then # host's CPU/instruction set set_host_arch() { case "$1" in x86_64|amd64|i[3-9]86*|i86pc|x86|x86pc|k5|k6|k6_2|k6_3|k6-2|k6-3|pentium*|athlon*|i586_i686|i586-i686) HOST_ARCH=i386 ;; ia64) HOST_ARCH=ia64 ;; macppc|ppc*|Power*) HOST_ARCH=ppc ;; alpha) HOST_ARCH=alpha ;; sun4*|sparc*) HOST_ARCH=sparc ;; parisc*|hppa*|9000*) HOST_ARCH=hppa ;; aarch64*) HOST_ARCH=aarch64 ;; arm*|zaurus|cats) HOST_ARCH=arm ;; sh3|sh4|sh4a) HOST_ARCH=sh ;; s390) HOST_ARCH=s390 ;; s390x) HOST_ARCH=s390x ;; *mips*) HOST_ARCH=mips ;; nios2) HOST_ARCH=nios2 ;; vax) HOST_ARCH=vax ;; xtensa*) HOST_ARCH=xtensa ;; *) HOST_ARCH=UNKNOWN ;; esac } set_host_arch "$(uname -m 2>&1)" if test "$HOST_ARCH" = UNKNOWN ; then set_host_arch "$(uname -p 2>&1)" fi TARGET_OS="$HOST_OS" TARGET_ARCH="$HOST_ARCH" else set_target_os() { component=$1 part=$(echo $BUILD_TARGET | cut -d '-' -f $component) case "$(echo $part | tr '[A-Z]' '[a-z]')" in linux) TARGET_OS=Linux ;; freebsd) TARGET_OS=FreeBSD ;; gnu/kfreebsd) TARGET_OS=FreeBSD ;; netbsd) TARGET_OS=NetBSD ;; bsd/os) TARGET_OS=BSD/OS ;; openbsd) TARGET_OS=OpenBSD ;; dragonfly) TARGET_OS=DragonFly ;; sunos) TARGET_OS=SunOS ;; qnx) TARGET_OS=QNX ;; morphos) TARGET_OS=MorphOS ;; amigaos) TARGET_OS=AmigaOS ;; mingw32*) TARGET_OS=MINGW32 ;; wine) TARGET_OS=Wine ;; esac } TARGET_OS="UNKNOWN" set_target_os 3 if test "$TARGET_OS" = UNKNOWN ; then set_target_os 2 fi TARGET_ARCH=$(echo $BUILD_TARGET | cut -d '-' -f 1) if test "$(echo $TARGET_ARCH)" != "x86_64" ; then TARGET_ARCH=$(echo $TARGET_ARCH | tr '_' '-') fi fi echo "Host OS : $HOST_OS" >> "$TMPLOG" echo "Target OS : $TARGET_OS" >> "$TMPLOG" echo "Target ARCH: $TARGET_ARCH" >> "$TMPLOG" finish_check "$TARGET_OS" test "$TARGET_OS" = UNKNOWN && die "Unknown target OS, please specify the --target option" OS_LC="$(echo $TARGET_OS | tr '[A-Z]' '[a-z]')" aix() { test "$OS_LC" = "aix"; } amigaos() { test "$OS_LC" = "amigaos"; } bsdos() { test "$OS_LC" = "bsd/os"; } darwin() { test "$OS_LC" = "darwin"; } dragonfly() { test "$OS_LC" = "dragonfly"; } freebsd() { test "$OS_LC" = "freebsd" || test "$OS_LC" = "gnu/kfreebsd"; } gnu() { test "$OS_LC" = "gnu"; } hpux() { test "$OS_LC" = "hp-ux"; } irix() { test "$OS_LC" = "irix"; } linux() { test "$OS_LC" = "linux"; } mingw32() { test "$OS_LC" = "mingw32"; } mingw64() { test "$OS_LC" = "mingw64"; } msys() { test "$OS_LC" = "msys"; } cygwin() { test "$OS_LC" = "cygwin"; } netbsd() { test "$OS_LC" = "netbsd"; } openbsd() { test "$OS_LC" = "openbsd"; } os2() { test "$OS_LC" = "os/2"; } qnx() { test "$OS_LC" = "qnx"; } sunos() { test "$OS_LC" = "sunos"; } wine() { test "$OS_LC" = "wine"; } win32() { cygwin || mingw32 || mingw64 || msys || wine; } posix_make() { aix || bsdos || hpux || irix || qnx || sunos; } # Checking CC version... # Intel C++ Compilers (no autoselect, use CC=/some/binary ./configure) cc_vendor= if test "$(basename $CC)" = "icc" || test "$(basename $CC)" = "ecc"; then start_check "$CC version" cc_vendor=intel cc_name=$($CC -V 2>&1 | head -n 1 | cut -d ',' -f 1) cc_version=$($CC -V 2>&1 | head -n 1 | cut -d ',' -f 2 | cut -d ' ' -f 3) _cc_major=$(echo $cc_version | cut -d '.' -f 1) _cc_minor=$(echo $cc_version | cut -d '.' -f 2) case $cc_version in '') cc_version="v. ?.??, bad" cc_fail=yes ;; 10.1|11.1|12.*|13.*) cc_version="$cc_version, ok" ;; *) cc_version="$cc_version, bad" cc_fail=yes ;; esac finish_check "$cc_version" else CC_TMP="$CC" for CC in "$CC_TMP" gcc cc ; do if "$CC" -v >/dev/null 2>&1; then cc_name_tmp=$($CC -v 2>&1 | tail -n 1 | cut -d ' ' -f 1) if test "$cc_name_tmp" = "gcc"; then cc_name=$cc_name_tmp start_check "$CC version" cc_vendor=gnu cc_version=$($CC -dumpversion 2>&1) case $cc_version in 2.96*) cc_fail=yes ;; *) _cc_major=$(echo $cc_version | cut -d '.' -f 1) _cc_minor=$(echo $cc_version | cut -d '.' -f 2) _cc_mini=$(echo $cc_version | cut -d '.' -f 3) ;; esac finish_check "$cc_version" break fi if $CC -v 2>&1 | grep -q "clang"; then start_check "$CC version" cc_vendor=clang cc_version=$($CC -dumpversion 2>&1) finish_check "clang $cc_version" break fi cc_name_tmp=$($CC -V 2>&1 | head -n 1 | cut -d ' ' -f 2,3) if test "$cc_name_tmp" = "Sun C"; then start_check "$CC version" cc_vendor=sun cc_version=$($CC -V 2>&1 | head -n 1 | cut -d ' ' -f 4) res_comment="experimental support" finish_check "Sun C $cc_version" break fi fi done fi # icc test -z "$cc_vendor" && die "compiler not found" test "$cc_fail" = "yes" && die "unsupported compiler version" # select optimization flags has_optimization() { # posix-compatible way to find -O option for OPT in $BUILD_EXTRA_CFLAGS; do case "$OPT" in -O[0-3]|-O) return 0 ;; esac done return 1 } has_optimization && OPTLEVEL= || OPTLEVEL="-O2" OPTFLAGS="-pipe -DNDEBUG -fomit-frame-pointer -ffunction-sections -fdata-sections" OPTFLAGS=$(str_concat $BUILD_DEBUG $OPTLEVEL $OPTFLAGS) # detect proper shared library name SHARED_PREFIX="lib" STATIC_PREFIX="lib" SHARED_EXT=".so.0" STATIC_EXT=".a" SOLINK_EXT=".so" EXEC_EXT= NEED_IMPLIB=no NEED_SOLINK=yes INSTALL_SO_DIR=$INSTALL_LIBDIR if win32; then EXEC_EXT=".exe" SHARED_EXT=".dll" NEED_IMPLIB=yes NEED_SOLINK=no INSTALL_SO_DIR=$INSTALL_BINDIR if msys; then SHARED_PREFIX="msys-" elif cygwin; then SHARED_PREFIX="cyg" fi elif darwin; then SHARED_EXT=".0.dylib" SOLINK_EXT=".dylib" fi # check for linker flags LD_STATIC=-static test "$BUILD_STATIC" = "auto" && BUILD_STATIC=no test "$OPT_OPENSSL_RUNTIME" = "yes" && ! win32 && LD_STATIC= if test -n "$LD_STATIC"; then start_check "linker support for $LD_STATIC" if cc_check_cflag "$LD_STATIC"; then test "$BUILD_STATIC" = "yes" && CHECK_LDFLAGS=$LD_STATIC else LD_STATIC= fi finish_check $(yn_nonempty "$LD_STATIC") fi test "$OPT_OPENSSL_RUNTIME" = "auto" && test "$BUILD_STATIC" = "yes" && ! win32 && OPT_OPENSSL_RUNTIME=no ALLOW_RUNTIME_LINKING=yes LIBDL_LDFLAGS= if ! win32 && test "$OPT_OPENSSL_RUNTIME" != "no"; then start_check "linker support for dlopen" ALLOW_RUNTIME_LINKING=no if cc_check_statement "dlfcn.h" 'dlopen("", RTLD_NOW);'; then ALLOW_RUNTIME_LINKING=yes elif cc_check_statement "dlfcn.h" 'dlopen("", RTLD_NOW);' "-ldl"; then ALLOW_RUNTIME_LINKING=yes LIBDL_LDFLAGS="-ldl" fi finish_check "$ALLOW_RUNTIME_LINKING" fi SHARED_VSCRIPT= if ! darwin; then start_check "linker support for --version-script" echo "{ local: *; };" > $TMPT cc_check_cflag "-Wl,--version-script,$TMPT -shared" && SHARED_VSCRIPT=",--version-script,exports.sym" finish_check $(yn_nonempty "$SHARED_VSCRIPT") fi WIN_LDFLAGS= if win32; then start_check "linker support for --nxcompat --no-seh --dynamicbase" cc_check_cflag "-Wl,--nxcompat,--no-seh,--dynamicbase" && WIN_LDFLAGS="-Wl,--nxcompat,--no-seh,--dynamicbase" finish_check $(yn_nonempty "$WIN_LDFLAGS") fi # detect library names and build flags LIBRHASH_SHARED="${SHARED_PREFIX}rhash${SHARED_EXT}" LIBRHASH_STATIC="${STATIC_PREFIX}rhash${STATIC_EXT}" LIBRHASH_SOLINK="${SHARED_PREFIX}rhash${SOLINK_EXT}" LIBRHASH_SOLINK_TARGET= test "$NEED_SOLINK" = "yes" && LIBRHASH_SOLINK_TARGET=$LIBRHASH_SOLINK LIBRHASH_DEF="${SHARED_PREFIX}rhash.def" LIBRHASH_IMPLIB="${STATIC_PREFIX}rhash${SHARED_EXT}${STATIC_EXT}" LIBRHASH_EXPORTS_FILE="exports.sym" LIBRHASH_EXPORTS_TARGET= LIBRHASH_SH_CFLAGS="" LIBRHASH_SH_LDFLAGS="" LIBRHASH_RM_FILES= LIBRHASH_LEGACY_HEADERS= if win32; then LIBRHASH_SH_CFLAGS="-DRHASH_EXPORTS" LIBRHASH_SH_LDFLAGS="-shared -Wl,--out-implib=${LIBRHASH_IMPLIB}${SHARED_VSCRIPT},--output-def,${LIBRHASH_DEF}" test -n "$SHARED_VSCRIPT" && LIBRHASH_EXPORTS_TARGET=$LIBRHASH_EXPORTS_FILE LIBRHASH_RM_FILES="${LIBRHASH_IMPLIB} ${LIBRHASH_DEF}" elif darwin; then LIBRHASH_SH_CFLAGS="-fpic" LIBRHASH_SH_LDFLAGS='-dynamiclib -Wl,-install_name,$(LIBDIR)/$@' else LIBRHASH_LEGACY_HEADERS="rhash_timing.h" LIBRHASH_SH_CFLAGS="-fpic" LIBRHASH_SH_LDFLAGS="-shared -Wl${SHARED_VSCRIPT},-soname,\$(LIBRHASH_SHARED)" test -n "$SHARED_VSCRIPT" && LIBRHASH_EXPORTS_TARGET=$LIBRHASH_EXPORTS_FILE fi LIBRHASH_RM_FILES=$(str_concat $LIBRHASH_RM_FILES $LIBRHASH_EXPORTS_TARGET $LIBRHASH_SOLINK_TARGET) RHASH_DEFINES= LIBRHASH_DEFINES= GETTEXT_LDFLAGS= OPENSSL_LDFLAGS= if test "$OPT_GETTEXT" != "no"; then start_check "gettext" GETTEXT_FOUND=no if cc_check_headers "libintl.h"; then if cc_check_statement "libintl.h" "gettext(\"\");"; then GETTEXT_FOUND=found elif cc_check_statement "libintl.h" "gettext(\"\");" "-lintl"; then GETTEXT_LDFLAGS="-lintl" GETTEXT_FOUND=found elif cc_check_statement "libintl.h" "gettext(\"\");" "-lintl -liconv"; then GETTEXT_LDFLAGS="-lintl -liconv" GETTEXT_FOUND=found fi fi test "$GETTEXT_FOUND" = "found" && RHASH_DEFINES=$(str_concat $RHASH_DEFINES -DUSE_GETTEXT) finish_check $GETTEXT_FOUND test "$OPT_GETTEXT" = "yes" && test "$GETTEXT_FOUND" = "no" && die "gettext library not found" fi if test "$OPT_OPENSSL" != "no"; then start_check "OpenSSL" test "$OPT_OPENSSL" = "auto" && test "$OPT_OPENSSL_RUNTIME" = "yes" && OPT_OPENSSL=yes OPENSSL_FOUND=no if test "$ALLOW_RUNTIME_LINKING" = "no"; then echo "No runtime library loading, because dlopen() is not found!" >> "$TMPLOG" test "$OPT_OPENSSL_RUNTIME" = "yes" && die "dlopen() is required for OpenSSL runtime loading" OPT_OPENSSL_RUNTIME=no fi OPENSSL_HEADERS="openssl/opensslconf.h openssl/md4.h openssl/md5.h openssl/sha.h" if cc_check_headers $OPENSSL_HEADERS; then if test "$OPT_OPENSSL_RUNTIME" != "no"; then OPENSSL_FOUND=runtime LIBRHASH_DEFINES=$(str_concat $LIBRHASH_DEFINES -DOPENSSL_RUNTIME) OPENSSL_LDFLAGS="$LIBDL_LDFLAGS" # note: libdl should disable -static test -n "$LIBDL_LDFLAGS" && LD_STATIC= elif win32 && cc_check_statement "openssl/md5.h" "MD5_Init(NULL);" "-leay32"; then OPENSSL_FOUND=found LIBRHASH_DEFINES=$(str_concat $LIBRHASH_DEFINES -DUSE_OPENSSL) OPENSSL_LDFLAGS="-leay32" elif cc_check_statement "openssl/md5.h" "MD5_Init(NULL);" "-lcrypto"; then OPENSSL_FOUND=found LIBRHASH_DEFINES=$(str_concat $LIBRHASH_DEFINES -DUSE_OPENSSL) OPENSSL_LDFLAGS="-lcrypto" fi fi finish_check $OPENSSL_FOUND test "$OPT_OPENSSL" = "yes" && test "$OPENSSL_FOUND" = "no" && die "OpenSSL library not found" fi # building of static/shared binary an library RHASH_STATIC=rhash_static RHASH_SHARED=rhash_shared RHASH_BUILD_TARGETS= RHASH_EXTRA_INSTALL= LIBRHASH_BUILD_TARGETS= LIBRHASH_TEST_TARGETS= EXTRA_INSTALL_LIBSHARED= EXTRA_UNINSTALL_LIBSHARED= if test "$BUILD_STATIC" = "yes"; then RHASH_STATIC=rhash RHASH_BUILD_TYPE=static RHASH_BUILD_TARGETS="\$(RHASH_STATIC)" test "$INSTALL_LIB_SHARED" = "yes" && RHASH_BUILD_TARGETS="$RHASH_BUILD_TARGETS \$(LIBRHASH_SHARED)" else RHASH_SHARED=rhash RHASH_BUILD_TYPE=shared RHASH_BUILD_TARGETS="\$(RHASH_SHARED)" test "$INSTALL_LIB_SHARED" = "auto" && INSTALL_LIB_SHARED=yes test "$INSTALL_LIB_STATIC" = "yes" && RHASH_BUILD_TARGETS="$RHASH_BUILD_TARGETS \$(LIBRHASH_STATIC)" fi if test "$INSTALL_LIB_STATIC" = "yes"; then RHASH_EXTRA_INSTALL=$(str_concat $RHASH_EXTRA_INSTALL install-lib-static) LIBRHASH_BUILD_TARGETS=$LIBRHASH_STATIC LIBRHASH_TEST_TARGETS=test-static fi if test "$NEED_IMPLIB" = "yes"; then EXTRA_INSTALL_LIBSHARED="install-implib" EXTRA_UNINSTALL_LIBSHARED="uninstall-implib" fi if test "$INSTALL_LIB_SHARED" = "yes"; then RHASH_EXTRA_INSTALL=$(str_concat $RHASH_EXTRA_INSTALL install-lib-shared) LIBRHASH_BUILD_TARGETS=$(str_concat $LIBRHASH_BUILD_TARGETS $LIBRHASH_SHARED) LIBRHASH_TEST_TARGETS=$(str_concat $LIBRHASH_TEST_TARGETS test-shared) fi # check for old POSIX make posix_make && Q_ASSIGN="=" || Q_ASSIGN="?=" # detect source directories start_check "sources" HAS_RHASH=no HAS_LIBRHASH=no HAS_BINDINGS=no RHASH_VERSION= BINDINGS_VERSION= RHASH_SRC= LIBRHASH_SRC= LIBRHASH_PC= BINDINGS_SRC= SRC_FOUND=no test -f Makefile || die "Makefile not found" if test -f rhash_main.c; then HAS_RHASH=yes SRC_FOUND=RHash if test -d librhash; then HAS_LIBRHASH=yes LIBRHASH_SRC=librhash/ fi if test -f bindings/version.properties; then HAS_BINDINGS=yes BINDINGS_SRC=bindings/ fi elif test -f rhash.c; then HAS_LIBRHASH=yes SRC_FOUND=LibRHash elif test -f version.properties; then HAS_BINDINGS=yes SRC_FOUND="RHash bindings" fi echo "RHASH_SRC=$RHASH_SRC, LIBRHASH_SRC=$LIBRHASH_SRC, BINDINGS_SRC=$BINDINGS_SRC" >> "$TMPLOG" # check version good_version() { echo "$1" | grep -q '^[1-9]\.[1-9][0-9]*\.[1-9]' ; } if test "$HAS_RHASH" = "yes"; then test -f "${RHASH_SRC}version.h" || die "${RHASH_SRC}version.h not found" RHASH_VERSION=$(cut -d'"' -f2 "${RHASH_SRC}version.h") echo "RHASH_VERSION=$RHASH_VERSION" >> "$TMPLOG" good_version "$RHASH_VERSION" || die "wrong version: $RHASH_VERSION" test "$HAS_LIBRHASH" = "yes" && LIBRHASH_PC=dist/librhash.pc fi if test "$HAS_BINDINGS" = "yes"; then BINDINGS_VERSION=$(cut -d = -f 2 "${BINDINGS_SRC}version.properties") echo "BINDINGS_VERSION=$BINDINGS_VERSION" >> "$TMPLOG" good_version "$BINDINGS_VERSION" || die "wrong bindings version: $BINDINGS_VERSION" test -z "$RHASH_VERSION" && RHASH_VERSION="$BINDINGS_VERSION" fi test -n "$RHASH_VERSION" && SRC_FOUND="$SRC_FOUND $RHASH_VERSION" finish_check "$SRC_FOUND" test "$SRC_FOUND" = "no" && die "sources not found" if test "$HAS_BINDINGS" = "yes" && test "$BINDINGS_VERSION" != "$RHASH_VERSION"; then echo "Updating ${BINDINGS_SRC}version.properties" echo "version=$RHASH_VERSION" > ${BINDINGS_SRC}version.properties fi if test "$HAS_RHASH" = "yes"; then echo "Writing ${RHASH_SRC}config.mak" cat > ${RHASH_SRC}config.mak << EOF # -------- Generated by configure ----------- DESTDIR $Q_ASSIGN BINDIR = \$(DESTDIR)$INSTALL_BINDIR SYSCONFDIR = \$(DESTDIR)$INSTALL_SYSCONFDIR MANDIR = \$(DESTDIR)$INSTALL_MANDIR PKGCONFIGDIR = \$(DESTDIR)$INSTALL_PKGCONFIGDIR LOCALEDIR = \$(DESTDIR)$INSTALL_LOCALEDIR AR = $CMD_AR CC = $CC INSTALL = $CMD_INSTALL LIBRHASH_STATIC = librhash/$LIBRHASH_STATIC LIBRHASH_SHARED = librhash/$LIBRHASH_SHARED BUILD_TYPE = $RHASH_BUILD_TYPE VERSION = $RHASH_VERSION EXEC_EXT = $EXEC_EXT RHASH_STATIC = $RHASH_STATIC\$(EXEC_EXT) RHASH_SHARED = $RHASH_SHARED\$(EXEC_EXT) BUILD_TARGETS = $RHASH_BUILD_TARGETS EXTRA_INSTALL = $RHASH_EXTRA_INSTALL SYMLINKS = $INSTALL_SYMLINKS OPTFLAGS = $OPTFLAGS OPTLDFLAGS = $WIN_LDFLAGS WARN_CFLAGS = $WARN_CFLAGS ADDCFLAGS = $BUILD_EXTRA_CFLAGS ADDLDFLAGS = $BUILD_EXTRA_LDFLAGS CFLAGS = $RHASH_DEFINES \$(OPTFLAGS) \$(WARN_CFLAGS) \$(ADDCFLAGS) LDFLAGS = \$(OPTLDFLAGS) \$(ADDLDFLAGS) $GETTEXT_LDFLAGS BIN_STATIC_LDFLAGS = \$(LDFLAGS) $(str_concat $LD_STATIC $OPENSSL_LDFLAGS) EOF fi if test "$HAS_LIBRHASH" = "yes"; then echo "Writing ${LIBRHASH_SRC}config.mak" cat > ${LIBRHASH_SRC}config.mak << EOF # -------- Generated by configure ----------- DESTDIR $Q_ASSIGN INCDIR = \$(DESTDIR)$INSTALL_INCDIR LIBDIR = \$(DESTDIR)$INSTALL_LIBDIR SO_DIR = \$(DESTDIR)$INSTALL_SO_DIR AR = $CMD_AR CC = $CC INSTALL = $CMD_INSTALL LIBRHASH_STATIC = $LIBRHASH_STATIC LIBRHASH_SHARED = $LIBRHASH_SHARED LIBRHASH_SOLINK = $LIBRHASH_SOLINK LIBRHASH_DEF = $LIBRHASH_DEF LIBRHASH_IMPLIB = $LIBRHASH_IMPLIB EXPORTS_FILE = $LIBRHASH_EXPORTS_FILE RM_FILES = $LIBRHASH_RM_FILES BUILD_TYPE = $RHASH_BUILD_TYPE EXEC_EXT = $EXEC_EXT LEGACY_HEADERS = $LIBRHASH_LEGACY_HEADERS EXPORTS_TARGET = $LIBRHASH_EXPORTS_TARGET BUILD_TARGETS = $LIBRHASH_BUILD_TARGETS TEST_TARGETS = $LIBRHASH_TEST_TARGETS SOLINK_TARGET = $LIBRHASH_SOLINK_TARGET EXTRA_INSTALL_LIBSHARED = $EXTRA_INSTALL_LIBSHARED EXTRA_UNINSTALL_LIBSHARED = $EXTRA_UNINSTALL_LIBSHARED OPTFLAGS = $OPTFLAGS OPTLDFLAGS = $WIN_LDFLAGS WARN_CFLAGS = $WARN_CFLAGS ADDCFLAGS = $BUILD_EXTRA_CFLAGS ADDLDFLAGS = $BUILD_EXTRA_LDFLAGS CFLAGS = $LIBRHASH_DEFINES \$(OPTFLAGS) \$(WARN_CFLAGS) \$(ADDCFLAGS) LDFLAGS = \$(OPTLDFLAGS) \$(ADDLDFLAGS) SHARED_CFLAGS = \$(CFLAGS) $LIBRHASH_SH_CFLAGS SHARED_LDFLAGS = \$(LDFLAGS) $(str_concat $OPENSSL_LDFLAGS $LIBRHASH_SH_LDFLAGS) BIN_STATIC_LDFLAGS = \$(LDFLAGS) $(str_concat $LD_STATIC $OPENSSL_LDFLAGS) EOF fi if test -n "$LIBRHASH_PC"; then PC_EXC="$INSTALL_EXEC_PREFIX" PC_INC="$INSTALL_INCDIR" PC_LIB="$INSTALL_LIBDIR" test "$PC_EXC" = "${INSTALL_PREFIX}" && PC_EXC='${prefix}' test "$PC_INC" = "${INSTALL_PREFIX}/include" && PC_INC='${prefix}/include' test "$PC_LIB" = "${INSTALL_EXEC_PREFIX}/lib" && PC_LIB='${exec_prefix}/lib' echo "Writing ${LIBRHASH_PC}" cat > $LIBRHASH_PC << EOF prefix=${INSTALL_PREFIX} exec_prefix=${PC_EXC} libdir=${PC_LIB} includedir=${PC_INC} Name: librash Description: LibRHash shared library Version: ${RHASH_VERSION} Cflags: -I\${includedir} Libs: -L\${libdir} -lrhash Libs.private: ${OPENSSL_LDFLAGS} EOF fiRHash-1.3.6/dist/000077500000000000000000000000001325207677100135035ustar00rootroot00000000000000RHash-1.3.6/dist/MD5.bat000066400000000000000000000001051325207677100145540ustar00rootroot00000000000000@REM generate md5 file @rhash.exe --md5 %1 %2 %3 %4 %5 %6 %7 %8 %9 RHash-1.3.6/dist/magnet.bat000066400000000000000000000001141325207677100154420ustar00rootroot00000000000000@REM generate magnet links @rhash.exe --magnet %1 %2 %3 %4 %5 %6 %7 %8 %9 RHash-1.3.6/dist/rhash.1000066400000000000000000000246341325207677100147030ustar00rootroot00000000000000.TH RHASH 1 "APR 2010" Linux "User Manuals" .SH NAME rhash \- calculate/check CRC32, MD5, SHA1, GOST, TTH, BTIH or other hash sums. .SH SYNOPSIS .B rhash [ .I option .B ]... [ .I file .B ]... .SH DESCRIPTION .B RHash (Recursive Hasher) computes and verifies various message digests (hash sums) of files. Supported message digests include CRC32, MD4, MD5, SHA1, SHA256, SHA512, SHA3, Tiger, DC++ TTH, BitTorrent BTIH, AICH, ED2K, GOST R 34.11\-94, RIPEMD\-160, HAS\-160, EDON\-R 256/512, Whirlpool, Snefru\-128/256. The program can create and verify Magnet links and eDonkey ed2k:// links, see \-\-magnet and \-\-ed2k\-link options. A dash string parameter `\-' is interpreted as stdin file. By default .B rhash prints sums in SFV format with CRC32 hash sum only. The format can be changed by options \-\-bsd, \-\-magnet, \-\-simple, \-\-printf, \-\-template. To output all sums use the `\-a' option. The default output format can also be changed by renaming the program or placing a hardlink/symlink to it with a name containing strings `crc32', `md4', `md5', `sha1', `sha256' `sha512', `tiger', `tth', `btih', `aich', `ed2k', `ed2k\-link', `gost', `gost\-cryptopro', `ripemd160', `has160', `whirlpool', `edonr256', `edonr512', `snefru128', `snefru256', `sfv' or `magnet'. .SH PROGRAM MODE OPTIONS The default mode is to print hash sums for all files and directory trees specified by command line. The mode can be set by the following options. .IP "\-c, \-\-check" Check hash files specified by command line. RHash can verify hash files in SFV and BSD formats, standard MD5 and SHA1 files, and text files containing magnet or ed2k links (one link per line). Empty lines and lines starting with `;' or `#' are skipped. In fact RHash can verify most hash files generated by itself without formatting options \-\-printf and \-\-template. .IP "\-u, \-\-update" Update hash files specified by command line. The program calculates and appends hashes to the updated hash file in the format specified by formatting options. Hashes are calculated for those files from the same directory as the hash file, which are yet not present in it. .IP "\-k, \-\-check\-embedded" Verify files by crc32 sum embedded in their names. .IP "\-\-torrent" Create a torrent file for each processed file. .IP "\-h, \-\-help" Help: print help screen and exit. .IP "\-V, \-\-version" Version: print version and exit. .IP "\-B, \-\-benchmark" Run benchmark for selected algorithm(s). .SH HASH SUMS OPTIONS .IP "\-C, \-\-crc32" CRC32: calculate and print CRC32 hash sum. .IP "\-\-md4" MD4: calculate and print MD4 hash sum. .IP "\-M, \-\-md5" MD5: calculate and print MD5 hash sum. .IP "\-H, \-\-sha1" SHA1: calculate and print SHA1 hash sum. .IP "\-\-sha224, \-\-sha256, \-\-sha384, \-\-sha512" Calculate specified SHA2 hash sum. .IP "\-\-sha3-224, \-\-sha3-256, \-\-sha3-384, \-\-sha3-512" Calculate specified SHA3 hash sum. .IP "\-\-tiger" Tiger: calculate and print Tiger hash sum. .IP "\-T, \-\-tth" TTH: calculate and print DC++ TTH sum. .IP "\-\-btih" BTIH: calculate and print BitTorrent Info Hash. .IP "\-A, \-\-aich" AICH: calculate and print AICH hash. .IP "\-E, \-\-ed2k" ED2K: calculate and print eDonkey 2000 hash sum. .IP "\-L, \-\-ed2k\-link" eDonkey link: calculate and print eDonkey link. .IP "\-W, \-\-whirlpool" Whirlpool: calculate and print Whirlpool hash sum. .IP "\-G, \-\-gost" GOST: calculate and print GOST R 34.11\-94 hash, the Russian GOST standard hash function. .IP "\-\-gost\-cryptopro" GOST\-CRYPTOPRO: calculate and print CryptoPro version of the GOST R 34.11\-94 hash function. .IP "\-\-ripemd160" RIPEMD\-160: calculate and print RIPEMD\-160 hash sum. .IP "\-\-has160" HAS\-160: calculate and print HAS\-160 hash sum. .IP "\-\-snefru128, \-\-snefru256" SNEFRU: calculate and print SNEFRU\-128/256 hash sums. .IP "\-\-edonr256, \-\-edonr512" EDON\-R: calculate and print EDON\-R 256/512 hash sums. .IP "\-a, \-\-all" Calculate all supported hash sums. .IP "\-\-list\-hashes" List names of all supported hashes, one per line. .SH MISCELLANEOUS OPTIONS .IP "\-r, \-\-recursive" Recursively process directories, specified by command line. .IP "\-\-file\-list=" Process a file-list. File-list is a text file, containing paths to files, one path per line. .IP "\-\-follow" Follow symbolic links when processing directories recursively. .IP "\-v, \-\-verbose" Be verbose. .IP "\-\-percents" Show percents, while calculating or checking sums .IP "\-\-skip\-ok" Don't print OK messages for successfully verified files. .IP "\-i, \-\-ignore\-case" Ignore case of filenames when updating crc files. .IP "\-\-speed" Print per\-file and the total processing speed. .IP "\-e, \-\-embed\-crc" Rename files by inserting crc32 sum into name. .IP "\-\-embed\-crc\-delimiter=" Insert specified before a crc sum in the \-\-embed\-crc mode, default is white space. The can be a character or empty string. .IP "\-\-path\-separator=" Use specified path separator to display paths. .IP "\-q, \-\-accept=" Set a comma\(hydelimited list of extensions of the files to process. .IP "\-\-exclude=" Set a comma\(hydelimited list of extensions of the files to exclude from processing. .IP "\-t, \-\-crc\-accept=" Set a comma\(hydelimited list of extensions of the hash files to verify. .IP "\-\-maxdepth=" Descend at most (a non\(hynegative integer) levels of directories below the command line arguments. `\-\-maxdepth 0' means only apply the tests and actions to the command line arguments. .IP "\-o, \-\-output=" Set the file to output calculated hashes and verification results to. .IP "\-l, \-\-log=" Set the file to log errors and verbose information to. .IP "\-\-openssl=" Specify which hash functions should be calculated using the OpenSSL library. The is a comma delimited list of hash names, but only those supported by openssl are allowed, e.g. md4, md5, sha1, sha256, ripemd160. See openssl documentation for the full list. .IP "\-\-gost\-reverse" Reverse bytes in hexadecimal output of the GOST hash sum. The most significant bytes of the hash will be printed first. Default order is the least significant bytes first. .IP "\-\-bt\-batch=" Turn on torrent batch mode (implies torrent mode). Calculates batch-torrent for the files specified at command line and saves the torrent file to the file\-path. The option \-r can be useful in this mode. .IP "\-\-bt\-private" Generate BTIH for a private BitTorrent tracker. .IP "\-\-bt\-piece\-length" Set the .I "piece length" value for torrent file. .IP "\-\-bt\-announce=" Add a tracker announce URL to the created torrent file(s). Several URLs can be passed by specifying the option mutltiple times. This option doesn't change the BTIH hash. .IP "\-\-benchmark\-raw" Switch benchmark output format to be a machine\(hyreadable tab\(hydelimited text with hash function name, speed, cpu clocks per byte. This option works only if the \-\-benchmark option was specified. .IP "\-\- (double dash)" Mark the end of command line options. All parameters following the double dash are interpreted as files or directories. It is typically used to process filenames starting with a dash `\-'. Alternatively you can specify './' or full path before such files, so they will not look like options anymore. .SH OUTPUT FORMAT OPTIONS .IP "\-\-sfv" Print hash sums in the SFV (Simple File Verification) output format (default). But unlike common SFV file, not only CRC32, but any hash sums specified by options can be printed. .IP "\-m, \-\-magnet" Print hash sums formatted as magnet links. .IP "\-\-bsd" Use BSD output format. Each hash sum is printed on separate line after hash name and file's path, enclosed in parentheses. .IP "\-\-simple" Use simple output format. Each line will consist of filename and hash sums specified by options. .IP "\-\-uppercase" Print hash sums in upper case. .IP "\-\-lowercase" Print hash sums in lower case. .IP "\-\-template=" Read printf\(hylike template from given . See the \-\-printf option. .IP "\-p, \-\-printf=" Format: print .I format string the standard output, interpreting `\e' escapes and `%' directives. The escapes and directives are: .RS .IP \en Newline. .IP \er Carriage return. .IP \et Horizontal tab. .IP \e\e A literal backslash (`\e'). .IP \e0 ASCII NUL. .IP \eNNN The character which octal ASCII code is NNN. .IP \exNN The character which hexadecimal ASCII code is NN. .PP A `\e' character followed by any other character is treated as an ordinary character, so they both are printed. .IP %% A literal percent sign. .IP %p File's path. .IP %f File's name. .IP %u URL\(hyencoded filename. .IP %s File's size in bytes. .IP %{mtime} File's last modification time. .IP "%a or %A" AICH hash sum. .IP "%c or %C" CRC32 hash sum. Use %c for lowercase and %C for uppercase characters. .IP "%g or %G" GOST R 34.11\-94 hash. .IP "%h or %H" SHA1 hash. .IP "%e or %E" ED2K hash sum. .IP "%l or %L" EDonkey ed2k://... link. .IP "%m or %M" MD5 hash. .IP "%r or %R" RIPEMD-160 hash. .IP "%t or %T" TTH sum. .IP "%w or %W" Whirlpool hash. .IP "%{md4}, %{sha-224}, %{sha-256}, %{sha-384}, %{sha-512}, %{sha3-224},\ %{sha3-256}, %{sha3-384}, %{sha3-512} %{tiger}, %{btih}, %{gost\-cryptopro},\ %{has160}, %{snefru128}, %{snefru256}, %{edon\-r256}, %{edon\-r512}" Print specified hash sum. Actually the %{} directive can print any supported hash sum. If a hash sum name starts with a capital letter then the hash is printed in uppercase, e.g. %{TTH}, %{Sha-512}. .IP "%x, %b, %B, %@" Use one of these prefixes to output a hash sum in hexadecimal, base32, base64 or raw (binary) format respectively, e.g. %b{md4}, %BH or %xT. .RE .SH CONFIG FILE RHash looks for a config file at $HOME/.rhashrc and /etc/rhashrc. The config file consists of lines formatted as .RS variable = value .RE where the .I variable can be a name of any command line option, like .I magnet, .I printf, .I percents, etc. A boolean variable can be set to true by a value `on', `yes' or `true', any other value sets the variable to false. Empty lines and lines starting with `#' or `;' are ignored. Example config file: .nf # This is a comment line percents = on crc-accept = .sfv,.md5,.sha1,.sha256,.sha512,.tth,.magnet .fi .SH AUTHOR Aleksey Kravchenko .SH "SEE ALSO" .BR md5sum (1) .BR cksfv (1) .BR ed2k_hash (1) .SH BUGS Bug reports are welcome! Send them by email or post to the SourceForge Bug Tracking System .I http://sourceforge.net/projects/rhash/ RHash-1.3.6/dist/rhash.1.win.sed000066400000000000000000000006161325207677100162430ustar00rootroot00000000000000#!/bin/sed # insert encoding options before sfv /^\.IP "\\-\\-sfv"/ { i\ .IP "\\-\\-ansi"\ Use Windows codepage for output.\ .IP "\\-\\-oem"\ Use DOS (OEM) codepage for output.\ .IP "\\-\\-utf8"\ Use UTF\\-8 codepage for output. } / looks for a config file/ { a\ on Windows at\ %APPDATA%\\\\RHash\\\\rhashrc, %HOMEDRIVE%%HOMEPATH%\\\\rhashrc, {PROGRAM_DIRECTORY}\\\\rhashrc\ \ and on Linux/Unix } RHash-1.3.6/dist/rhash.spec.in000066400000000000000000000072261325207677100161000ustar00rootroot00000000000000# This file is automatically generated from rhash.spec.in %define version @VERSION@ %define make %{?__make}%{!?__make:make} # major is the part of the shared library name after the .so %define major 0 %if 0%{?mgaversion:1} %define libname %mklibname rhash %{major} %define devlibname %mklibname -d rhash %define opensll_dev libopenssl1.0.0-devel %else %define libname librhash%{major} %define devlibname rhash-devel %define opensll_dev openssl-devel %endif Summary: Utility for computing hash sums and creating magnet links. Name: rhash Version: %{version} Release: 1%{?dist} License: MIT %if 0%{?suse_version} Group: Productivity/File utilities %else Group: Applications/File %endif Vendor: Novosibirsk, Animegorodok Packager: Aleksey Kravchenko URL: http://rhash.sourceforge.net/ Source: http://downloads.sourceforge.net/rhash/rhash-%{version}-src.tar.gz BuildRoot: %{_builddir}/%{name}-%{version}-root BuildRequires: gcc, %{opensll_dev} %description RHash is a console utility for calculation and verification of magnet links and a wide range of hash sums like CRC32, MD4, MD5, SHA1, SHA256, SHA512, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru. Hash sums are used to ensure and verify integrity of large volumes of data for a long-term storing or transferring. Features: * Output in a predefined (SFV, BSD-like) or a user-defined format. * Calculation of Magnet links. * Ability to process directories recursively. * Updating hash files (adding hash sums of files missing in the hash file). * Portability: the program works the same on Linux, *BSD or Windows. # LibRHash shared library, contains librhash.so.[major] only %package -n %{libname} Summary: LibRHash shared library Group: System/Libraries Provides: librhash = %{version}-%{release} %description -n %{libname} LibRHash is a professional, portable, thread-safe C library for computing a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru. Hash sums are used to ensure and verify integrity of large volumes of data for a long-term storing or transferring. %package -n %{devlibname} Summary: Headers and static library for LibRHash Group: Development/C Requires: %{libname} = %{version} #(!) MANDATORY Provides: librhash-devel = %{version}-%{release} %description -n %{devlibname} LibRHash is a professional, portable, thread-safe C library for computing a wide variety of hash sums, such as CRC32, MD4, MD5, SHA1, SHA256, SHA512, AICH, ED2K, Tiger, DC++ TTH, BitTorrent BTIH, GOST R 34.11-94, RIPEMD-160, HAS-160, EDON-R, Whirlpool and Snefru. Hash sums are used to ensure and verify integrity of large volumes of data for a long-term storing or transferring. %prep %setup %build ./configure --enable-openssl-runtime --disable-gettext --enable-lib-static \ --prefix=/usr --sysconfdir=/etc --mandir="%{_mandir}" --libdir="%{_libdir}" \ --extra-cflags="$RPM_OPT_FLAGS" %{make} %check %{make} test %install %{make} install install-lib-so-link DESTDIR="$RPM_BUILD_ROOT" %clean rm -rf "$RPM_BUILD_ROOT" %files %defattr(-,root,root) %doc ChangeLog COPYING README /usr/bin/* /etc/rhashrc %{_mandir}/man1/ %files -n %{devlibname} %defattr(-,root,root) %{_libdir}/librhash.a %{_libdir}/librhash.so %{_includedir}/*.h %files -n %{libname} %defattr(-,root,root) %doc COPYING README ChangeLog %{_libdir}/librhash.so.%{major} %post -n %{libname} ldconfig %postun -n %{libname} ldconfig %changelog RHash-1.3.6/dist/rhashrc.sample000066400000000000000000000010441325207677100163370ustar00rootroot00000000000000; The RHash config file config ; crc32 is the default hash sum #crc32=on #md5=on #sha1=on ; use windows code page (useful only under windows) #ansi=on ; ignore case in filenames, when verifying crc files #ignore-case=on ; directories are not scanned recursively by default #recursive=on ; OK messages are printed by default #skip-ok=on ; accept only *.sfv files while recursively checking directories #crc-accept=.sfv #crc-accept=.sfv,.md5,.sha1,.tiger,.tth,.aich ; percents are switched off by default #percents=on RHash-1.3.6/docs/000077500000000000000000000000001325207677100134705ustar00rootroot00000000000000RHash-1.3.6/docs/CONTRIBUTING.md000066400000000000000000000034411325207677100157230ustar00rootroot00000000000000# Contribution guidelines for the RHash project There are many ways of contributing to the project. * Contributing by writing code * Hunting bugs * Translating to other languages * Packaging RHash to a new distribution * Contributing money ## Contributing by writing code * Fixing bugs and implementing features, check current [issues]. * Updating documentation ## Translating to other languages For online translation you need to register at the [Launchpad] platform. Then visit [RHash translations] and translate untranslated strings. Alternatively, you can translate one of [po files](../po/) and send a patch. ## Hunting bugs * Test RHash with miscellaneous options. Try different OS and different environments. * Test compilation by different compilers. * Try static/dynamic analysis or phasing. If you have a found bug, try to reproduce it with the latest version, compiled from the [repository]. Collect information about you environment, particularly use command: ```sh make -C librhash print-info ``` File new bugs at the [issues] page. ## Packaging RHash to a new distribution Check if your OS distribution has the latest RHash. If not, then make a package and publish it into the OS repository. ## Contributing money Support RHash If you like the project, please consider [donating] a few dollars. [issues]: https://github.com/rhash/RHash/issues [Launchpad]: https://launchpad.net/ [RHash translations]: https://translations.launchpad.net/rhash/ [repository]: https://github.com/rhash/RHash/ [donating]: http://sourceforge.net/donate/index.php?group_id=205103 RHash-1.3.6/docs/LIBRHASH.md000066400000000000000000000063641325207677100152170ustar00rootroot00000000000000LibRHash Library ================ **LibRHash** is a professional, portable, thread-safe *C* library for computing a wide variety of hash sums. ### Main features * Small and easy to learn interface. * Hi-level and Low-level API. * Calculates several hash functions simultaneously in one pass. * Extremely portable: works the same on Linux, Unix, macOS or Windows. * Written in pure C, small in size, open source. Scripting Languages Support --------------------------- LibRHash has [bindings] to several programming languages: *Java*, *C#*, *Perl*, *PHP*, *Python*, *Ruby*. License ------- The library is licensed under [RHash License]. Basically the library and its source code can be used for free in Commercial, [Open Source] and other projects. Usage examples -------------- ### Low-level interface * Calculating MD4 and MD5 digests simultaneously of a million characters of 'a' ```c #include "rhash.h" /* LibRHash interface */ int main(int argc, char *argv[]) { rhash context; char digest[64]; char output[130]; int i; rhash_library_init(); /* initialize static data */ context = rhash_init(RHASH_MD4 | RHASH_MD5); if(!context) { fprintf(stderr, "error: couldn't initialize rhash context\n"); return 1; } for(i = 0; i < 1000000; i++) { rhash_update(context, "a", 1); } rhash_final(context, NULL); /* finalize hash calculation */ /* output digest as a hexadecimal hash string */ rhash_print(output, context, RHASH_MD4, RHPR_UPPERCASE); printf("%s ('a'x1000000) = %s\n", rhash_get_name(RHASH_MD4), output); rhash_print(output, context, RHASH_MD5, RHPR_UPPERCASE); printf("%s ('a'x1000000) = %s\n", rhash_get_name(RHASH_MD5), output); rhash_free(context); return 0; } ``` ### Hi-level interface * Calculating SHA1 hash of a string ```c #include #include "rhash.h" /* LibRHash interface */ int main(int argc, char *argv[]) { const char* msg = "message digest"; char digest[64]; char output[130]; rhash_library_init(); /* initialize static data */ int res = rhash_msg(RHASH_SHA1, msg, strlen(msg), digest); if(res < 0) { fprintf(stderr, "hash calculation error\n"); return 1; } /* convert binary digest to hexadecimal string */ rhash_print_bytes(output, digest, rhash_get_digest_size(RHASH_SHA1), (RHPR_HEX | RHPR_UPPERCASE)); printf("%s (\"%s\") = %s\n", rhash_get_name(RHASH_SHA1), msg, output); return 0; } ``` * Calculating TTH hash of a file ```c #include #include "rhash.h" /* LibRHash interface */ int main(int argc, char *argv[]) { const char* filepath = "test_file.txt"; char digest[64]; char output[130]; rhash_library_init(); /* initialize static data */ int res = rhash_file(RHASH_TTH, filepath, digest); if(res < 0) { fprintf(stderr, "LibRHash error: %s: %s\n", filepath, strerror(errno)); return 1; } /* convert binary digest to hexadecimal string */ rhash_print_bytes(output, digest, rhash_get_digest_size(RHASH_TTH), (RHPR_BASE32 | RHPR_UPPERCASE)); printf("%s (%s) = %s\n", rhash_get_name(RHASH_TTH), filepath, output); return 0; } ``` [bindings]: ../bindings/ [RHash License]: ../COPYING [Open Source]: http://en.wikipedia.org/wiki/Open_Source RHash-1.3.6/file.c000066400000000000000000000271551325207677100136350ustar00rootroot00000000000000/* file.c - file abstraction layer */ /* use 64-bit off_t. * these macros must be defined before any included file */ #undef _LARGEFILE64_SOURCE #undef _FILE_OFFSET_BITS #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include "file.h" #include "common_func.h" #include "win_utils.h" #if defined( _WIN32) || defined(__CYGWIN__) # include # include /* for _SH_DENYWR */ # include /* _O_RDONLY, _O_BINARY */ # include #endif #ifdef __cplusplus extern "C" { #endif /*========================================================================= * Path functions *=========================================================================*/ /** * Return file name without path. * * @param path file path * @return file name */ const char* get_basename(const char* path) { const char *p = path + strlen(path) - 1; for (; p >= path && !IS_PATH_SEPARATOR(*p); p--); return (p+1); } /** * Return allocated buffer with the directory part of the path. * The buffer must be freed by calling free(). * * @param path file path * @return directory */ char* get_dirname(const char* path) { const char *p = path + strlen(path) - 1; char *res; for (; p > path && !IS_PATH_SEPARATOR(*p); p--); if ((p - path) > 1) { res = (char*)rsh_malloc(p-path+1); memcpy(res, path, p-path); res[p-path] = 0; return res; } else { return rsh_strdup("."); } } /** * Assemble a filepath from its directory and filename. * * @param dir_path directory path * @param filename the file name * @return assembled file path */ char* make_path(const char* dir_path, const char* filename) { char* buf; size_t len; assert(dir_path); assert(filename); /* remove leading path separators from filename */ while (IS_PATH_SEPARATOR(*filename)) filename++; if (dir_path[0] == '.' && dir_path[1] == 0) { /* do not extend filename for dir_path="." */ return rsh_strdup(filename); } /* copy directory path */ len = strlen(dir_path); buf = (char*)rsh_malloc(len + strlen(filename) + 2); strcpy(buf, dir_path); /* separate directory from filename */ if (len > 0 && !IS_PATH_SEPARATOR(buf[len-1])) { buf[len++] = SYS_PATH_SEPARATOR; } /* append filename */ strcpy(buf+len, filename); return buf; } #define IS_ANY_SLASH(c) ((c) == RSH_T('/') || (c) == RSH_T('\\')) /** * Compare paths. * * @param a the first path * @param b the second path * @return 1 if paths a equal, 0 otherwise */ int are_paths_equal(ctpath_t a, ctpath_t b) { if (!a || !b) return 0; if (a[0] == RSH_T('.') && IS_ANY_SLASH(a[1])) a += 2; if (b[0] == RSH_T('.') && IS_ANY_SLASH(b[1])) b += 2; for (; *a; ++a, ++b) { if (*a != *b && (!IS_ANY_SLASH(*b) || !IS_ANY_SLASH(*a))) { /* paths are different */ return 0; } } /* check if both paths terminated */ return (*a == *b); } /** * Check if a path points to a regular file. * * @param path the path to check * @return 1 if file exists an is a regular file, 0 otherwise */ int is_regular_file(const char* path) { int is_regular = 0; file_t file; file_init(&file, path, FILE_OPT_DONT_FREE_PATH); if (file_stat(&file, 0) >= 0) { is_regular = FILE_ISREG(&file); } file_cleanup(&file); return is_regular; } /** * Check if a file exists at the specified path. * * @param path the path to check * @return 1 if file exists, 0 otherwise. */ int if_file_exists(const char* path) { int exists; file_t file; file_init(&file, path, FILE_OPT_DONT_FREE_PATH); exists = (file_stat(&file, 0) >= 0); file_cleanup(&file); return exists; } /*========================================================================= * file_t functions *=========================================================================*/ void file_init(file_t* file, const char* path, int finit_flags) { memset(file, 0, sizeof(*file)); if ((finit_flags & FILE_OPT_DONT_FREE_PATH) != 0) { file->path = (char*)path; file->mode = (unsigned)finit_flags; } else { file->path = rsh_strdup(path); } } /** * Free the memory allocated by the fields of the file_t structure. * * @param file the file_t structure to clean */ void file_cleanup(file_t* file) { if ((file->mode & FILE_OPT_DONT_FREE_PATH) == 0) free(file->path); file->path = NULL; #ifdef _WIN32 if ((file->mode & FILE_OPT_DONT_FREE_WPATH) == 0) free(file->wpath); file->wpath = NULL; #endif /* _WIN32 */ file->mtime = file->size = 0; file->mode = 0; } /** * Append the specified suffix to the src file path. * * @param dst result of appending * @param src the path to append the suffix to * @param suffix the suffix to append */ void file_path_append(file_t* dst, file_t* src, const char* suffix) { memset(dst, 0, sizeof(*dst)); #ifdef _WIN32 if (src->wpath) { wchar_t* wsuffix = c2w(suffix, 0); assert(wsuffix != 0); size_t src_len = wcslen(src->wpath); size_t dst_len = src_len + wcslen(wsuffix) + 1; dst->wpath = (wchar_t*)rsh_malloc(dst_len * sizeof(wchar_t)); wcscpy(dst->wpath, src->wpath); wcscpy(dst->wpath + src_len, wsuffix); dst->path = w2c(dst->wpath); /* for legacy file handling */ return; } #endif assert(!!file->path); size_t src_len = strlen(src->path); size_t dst_len = src_len + strlen(suffix) + 1; dst->path = (char*)rsh_malloc(dst_len); strcpy(dst->path, src->path); strcpy(dst->path + src_len, suffix); } #ifdef _WIN32 /** * Retrieve file information (type, size, mtime) into file_t fields. * * @param file the file information * @return 0 on success, -1 on error */ static int file_statw(file_t* file) { WIN32_FILE_ATTRIBUTE_DATA data; wchar_t* long_path = get_long_path_if_needed(file->wpath); /* read file attributes */ if (GetFileAttributesExW((long_path ? long_path : file->wpath), GetFileExInfoStandard, &data)) { uint64_t u; file->size = (((uint64_t)data.nFileSizeHigh) << 32) + data.nFileSizeLow; file->mode |= (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? FILE_IFDIR : FILE_IFREG); if ((data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) file->mode |= FILE_IFLNK; /* the number of 100-nanosecond intervals since January 1, 1601 */ u = (((uint64_t)data.ftLastWriteTime.dwHighDateTime) << 32) + data.ftLastWriteTime.dwLowDateTime; /* convert to second and subtract the epoch difference */ file->mtime = u / 10000000 - 11644473600LL; free(long_path); return 0; } free(long_path); set_errno_from_last_file_error(); return -1; } #endif /** * Retrieve file information (type, size, mtime) into file_t fields. * * @param file the file information * @param fstat_flags bitmask consisting of FileStatModes bits * @return 0 on success, -1 on error */ int file_stat(file_t* file, int fstat_flags) { #ifdef _WIN32 int i; (void)fstat_flags; /* ignore on windows */ file->size = 0; file->mtime = 0; file->mode &= (FILE_OPT_DONT_FREE_PATH | FILE_OPT_DONT_FREE_WPATH | FILE_IFROOT | FILE_IFSTDIN); if (file->wpath) return file_statw(file); for (i = 0; i < 2; i++) { file->wpath = c2w_long_path(file->path, i); if (file->wpath == NULL) continue; if (file_statw(file) == 0) return 0; /* success */ free(file->wpath); file->wpath = NULL; } assert(errno != 0); return -1; #else struct stat st; int res = 0; file->size = 0; file->mtime = 0; file->mode &= (FILE_OPT_DONT_FREE_PATH | FILE_IFROOT | FILE_IFSTDIN); if ((fstat_flags & FUseLstat) != 0) { if (lstat(file->path, &st) < 0) return -1; if (S_ISLNK(st.st_mode)) file->mode |= FILE_IFLNK; /* it's a symlink */ } else res = stat(file->path, &st); if (res == 0) { file->size = st.st_size; file->mtime = st.st_mtime; if (S_ISDIR(st.st_mode)) { file->mode |= FILE_IFDIR; } else if (S_ISREG(st.st_mode)) { /* it's a regular file or a symlink pointing to a regular file */ file->mode |= FILE_IFREG; } } return res; #endif } /** * Retrieve file information (type, size, mtime) into file_t fields. * * @param file the file information * @param fopen_flags bitmask consisting of FileFOpenModes bits * @return 0 on success, -1 on error */ FILE* file_fopen(file_t* file, int fopen_flags) { const file_tchar* possible_modes[8] = { 0, RSH_T("r"), RSH_T("w"), RSH_T("r+"), 0, RSH_T("rb"), RSH_T("wb"), RSH_T("r+b") }; const file_tchar* mode = possible_modes[fopen_flags & FOpenMask]; assert((fopen_flags & FOpenRW) != 0); assert((fopen_flags & FOpenRW) != 0); #ifdef _WIN32 if (!file->wpath) { int i; FILE* fd = 0; for (i = 0; i < 2; i++) { file->wpath = c2w_long_path(file->path, i); if (file->wpath == NULL) continue; fd = _wfsopen(file->wpath, mode, _SH_DENYNO); if (fd || errno != ENOENT) break; free(file->wpath); file->wpath = 0; } return fd; } return _wfsopen(file->wpath, mode, _SH_DENYNO); #else return fopen(file->path, mode); #endif } #ifdef _WIN32 FILE* rsh_tfopen(ctpath_t tpath, file_tchar* tmode) { return _wfsopen(tpath, tmode, _SH_DENYNO); } #endif /** * Rename or move the file. The source and destination paths should be on the same device. * * @param from the source file * @param to the destination path * @return 0 on success, -1 on error */ int file_rename(file_t* from, file_t* to) { #ifdef _WIN32 if (from->wpath && to->wpath) { /* Windows: file must be removed before overwriting it */ _wunlink(to->wpath); return _wrename(from->wpath, to->wpath); } assert(from->path && to->path); unlink(to->path); #endif return rename(from->path, to->path); } #ifdef _WIN32 static int win_can_open_exclusive(wchar_t* wpath) { int fd = _wsopen(wpath, _O_RDONLY | _O_BINARY, _SH_DENYWR, 0); if (fd < 0) return 0; _close(fd); return 1; } /** * Check if given file can be opened with exclusive write access. * * @param path path to the file * @return 1 if file can be opened, 0 otherwise */ int file_is_write_locked(file_t* file) { int i, res = 0; if (file->wpath) return win_can_open_exclusive(file->wpath); for (i = 0; i < 2 && !res; i++) { file->wpath = c2w_long_path(file->path, i); if(file->wpath && win_can_open_exclusive(file->wpath)) return 1; free(file->wpath); } file->wpath = NULL; return 0; } #endif /*========================================================================= * file-list functions *=========================================================================*/ /** * Open a file, containing a list of file paths, to iterate over those paths * using the file_list_read() function. * * @param list the file_list_t structure to initialize * @param file_path the file to open * @return 0 on success, -1 on error and set errno */ int file_list_open(file_list_t* list, file_t* file_path) { memset(list, 0, sizeof(file_list_t)); list->fd = file_fopen(file_path, FOpenRead | FOpenBin); return (list->fd ? 0 : -1); } /** * Close file_list_t and free allocated memory. */ void file_list_close(file_list_t* list) { if (list->fd) { fclose(list->fd); list->fd = 0; } file_cleanup(&list->current_file); } enum FileListStateBits { NotFirstLine = 1 }; /** * Iterate over file list. * * @param list the file list to iterate over * @return 1 if next file have been obtained, 0 on EOF or error */ int file_list_read(file_list_t* list) { char buf[2048]; file_cleanup(&list->current_file); while(fgets(buf, 2048, list->fd)) { char *p; char* line = buf; char *buf_back = buf + sizeof(buf) - 1; /* detect and skip BOM */ if (buf[0] == (char)0xEF && buf[1] == (char)0xBB && buf[2] == (char)0xBF && !(list->state & NotFirstLine)) line += 3; list->state |= NotFirstLine; for (p = line; p < buf_back && *p && *p != '\r' && *p != '\n'; p++); *p = 0; if (*line == '\0') continue; /* skip empty lines */ file_init(&list->current_file, line, 0); return 1; } return 0; } #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ RHash-1.3.6/file.h000066400000000000000000000052071325207677100136340ustar00rootroot00000000000000/* file.h - file abstraction layer */ #ifndef FILE_H #define FILE_H #include #include #include /* for wchar_t */ #if _MSC_VER > 1300 # include "platform.h" #endif #ifdef __cplusplus extern "C" { #endif #ifdef _WIN32 typedef wchar_t file_tchar; # define SYS_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 IS_PATH_SEPARATOR(c) ((c) == '/') #endif /* _WIN32 */ typedef file_tchar* tpath_t; typedef const file_tchar* ctpath_t; /* Generic path functions */ const char* get_basename(const char* path); char* get_dirname(const char* path); char* make_path(const char* dir, const char* filename); int are_paths_equal(ctpath_t a, ctpath_t b); int is_regular_file(const char* path); /* shall be deprecated */ int if_file_exists(const char* path); /** * Portable file information. */ typedef struct file_t { char* path; #ifdef _WIN32 wchar_t* wpath; #endif uint64_t size; uint64_t mtime; unsigned mode; } file_t; #ifdef _WIN32 # define FILE_TPATH(file) ((file)->wpath) #else # define FILE_TPATH(file) ((file)->path) #endif /* bit constants for the file_t.mode bit mask */ #define FILE_IFDIR 0x01 #define FILE_IFLNK 0x02 #define FILE_IFREG 0x04 #define FILE_IFROOT 0x10 #define FILE_IFSTDIN 0x20 #define FILE_IFLIST 0x40 #define FILE_OPT_DONT_FREE_PATH 0x200 #define FILE_OPT_DONT_FREE_WPATH 0x400 #define FILE_ISDIR(file) ((file)->mode & FILE_IFDIR) #define FILE_ISLNK(file) ((file)->mode & FILE_IFLNK) #define FILE_ISREG(file) ((file)->mode & FILE_IFREG) /* file functions */ void file_init(file_t* file, const char* path, int finit_flags); void file_cleanup(file_t* file); void file_path_append(file_t* dst, file_t* src, const char* suffix); enum FileStatModes { FNoMode = 0, FUseLstat = 1 }; int file_stat(file_t* file, int fstat_flags); enum FileFOpenModes { FOpenRead = 1, FOpenWrite = 2, FOpenRW = 3, FOpenBin = 4, FOpenMask = 7 }; FILE* file_fopen(file_t* file, int fopen_flags); int file_rename(file_t* from, file_t* to); #ifdef _WIN32 FILE* rsh_tfopen(ctpath_t tpath, file_tchar* tmode); int file_is_write_locked(file_t* file); #else # define file_is_write_locked(f) (0) # define rsh_tfopen(tpath, tmode) fopen(tpath, tmode) #endif 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_path); int file_list_read(file_list_t* list); void file_list_close(file_list_t* list); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* FILE_H */ RHash-1.3.6/file_mask.c000066400000000000000000000042401325207677100146360ustar00rootroot00000000000000/* file_mask.c - matching file against a list of file masks */ #include #include #include #include #include "file_mask.h" #include "common_func.h" /** * Convert the given string to lower-case then put it into * the specified array of 'file masks'. * * @param arr array of file masks * @param mask a string to add */ static void file_mask_add(file_mask_array* vect, const char* mask) { rsh_vector_add_ptr(vect, str_tolower(mask)); } /** * Construct array from a comma-separated list of strings. * * @param comma_separated_list the comma-separated list of strings * @return constructed array */ file_mask_array* file_mask_new_from_list(const char* comma_separated_list) { file_mask_array* vect = file_mask_new(); file_mask_add_list(vect, comma_separated_list); return vect; } /** * Split the given string by comma and put the parts into array. * * @param vect the array to put the parsed elements to * @param comma_separated_list the string to split */ void file_mask_add_list(file_mask_array* vect, const char* comma_separated_list) { char *buf, *cur, *next; if (!comma_separated_list || !*comma_separated_list) { return; } buf = rsh_strdup(comma_separated_list); for (cur = buf; cur && *cur; cur = next) { next = strchr(cur, ','); if (next) *(next++) = '\0'; if (*cur != '\0') file_mask_add(vect, cur); } free(buf); } /** * Match a given name against a list of string trailers. * Usually used to match a filename against list of file extensions. * * @param vect the array of string trailers * @param name the name to match * @return 1 if matched, 0 otherwise */ int file_mask_match(file_mask_array* vect, const char* name) { unsigned i; int res = 0; size_t len, namelen; char* buf; /* all names should match against an empty array */ if (!vect || !vect->size) return 1; /* get a lowercase name version to ignore case when matching */ buf = str_tolower(name); namelen = strlen(buf); for (i = 0; i < vect->size; i++) { len = strlen((char*)vect->array[i]); if (namelen >= len && memcmp(buf + namelen - len, vect->array[i], len) == 0) { res = 1; /* matched */ break; } } free(buf); return res; } RHash-1.3.6/file_mask.h000066400000000000000000000011571325207677100146470ustar00rootroot00000000000000/* file_mask.h */ #ifndef FILE_MASK_H #define FILE_MASK_H #ifdef __cplusplus extern "C" { #endif #include "common_func.h" /* an array to store rules for file acceptance */ typedef struct vector_t file_mask_array; #define file_mask_new() rsh_vector_new_simple() #define file_mask_free(v) rsh_vector_free(v) file_mask_array* file_mask_new_from_list(const char* comma_separated_list); void file_mask_add_list(file_mask_array* vect, const char* comma_separated_list); int file_mask_match(file_mask_array* vect, const char* name); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* FILE_MASK_H */ RHash-1.3.6/file_set.c000066400000000000000000000120711325207677100144770ustar00rootroot00000000000000/* file_set.c - functions to manipulate a set of files */ #include #include /* isspace */ #include /* ptrdiff_t */ #include /* qsort */ #include /* fopen */ #include #include "file_set.h" #include "common_func.h" #include "hash_print.h" #include "output.h" #include "parse_cmdline.h" #include "rhash_main.h" #include "librhash/rhash.h" /** * Generate a hash for a string. * * @param string the string to hash * @return a string hash */ static unsigned file_set_make_hash(const char* string) { unsigned hash; if (rhash_msg(RHASH_CRC32, string, strlen(string), (unsigned char*)&hash) < 0) return 0; return hash; } /** * Set file path of the given item. * * @param item pointer to the item to change * @param filepath the file path to set */ static int file_set_item_set_filepath(file_set_item* item, const char* filepath) { if (item->search_filepath != item->filepath) free(item->search_filepath); free(item->filepath); item->filepath = rsh_strdup(filepath); if (!item->filepath) return 0; /* apply str_tolower if CASE_INSENSITIVE */ /* Note: strcasecmp() is not used instead of search_filepath due to portability issue */ /* Note: item->search_filepath is always correctly freed by file_set_item_free() */ item->search_filepath = (opt.flags & OPT_IGNORE_CASE ? str_tolower(item->filepath) : item->filepath); item->hash = file_set_make_hash(item->search_filepath); return 1; } /** * Allocate a file_set_item structure and initialize it with a filepath. * * @param filepath a filepath to initialize the file_set_item * @return allocated file_set_item structure */ static file_set_item* file_set_item_new(const char* filepath) { file_set_item *item = (file_set_item*)rsh_malloc(sizeof(file_set_item)); memset(item, 0, sizeof(file_set_item)); if (filepath) { if (!file_set_item_set_filepath(item, filepath)) { free(item); return NULL; } } return item; } /** * Free memory allocated by file_set_item. * * @param item the item to delete */ void file_set_item_free(file_set_item *item) { if (item->search_filepath != item->filepath) { free(item->search_filepath); } free(item->filepath); free(item); } /** * Call-back function to compare two file items by search_filepath, using hashes * * @param pp_rec1 the first item to compare * @param pp_rec2 the second item to compare * @return 0 if items are equal, -1 if pp_rec1 < pp_rec2, 1 otherwise */ static int crc_pp_rec_compare(const void *pp_rec1, const void *pp_rec2) { const file_set_item *rec1 = *(file_set_item *const *)pp_rec1; const file_set_item *rec2 = *(file_set_item *const *)pp_rec2; if (rec1->hash != rec2->hash) return (rec1->hash < rec2->hash ? -1 : 1); return strcmp(rec1->search_filepath, rec2->search_filepath); } /** * Compare two file items by filepath. * * @param rec1 pointer to the first file_set_item structure * @param rec2 pointer to the second file_set_item structure * @return 0 if files have the same filepath, and -1 or 1 (strcmp result) if not */ static int path_compare(const void *rec1, const void *rec2) { return strcmp((*(file_set_item *const *)rec1)->filepath, (*(file_set_item *const *)rec2)->filepath); } /** * Sort given file_set using hashes of search_filepath for fast binary search. * * @param set the file_set to sort */ void file_set_sort(file_set *set) { if (set->array) qsort(set->array, set->size, sizeof(file_set_item*), crc_pp_rec_compare); } /** * Sort files in the specified file_set by file path. * * @param set the file-set to sort */ void file_set_sort_by_path(file_set *set) { qsort(set->array, set->size, sizeof(file_set_item*), path_compare); } /** * Create and add a file_set_item with given filepath to given file_set * * @param set the file_set to add the item to * @param filepath the item file path */ void file_set_add_name(file_set *set, const char* filepath) { file_set_item* item = file_set_item_new(filepath); if (item) file_set_add(set, item); } /** * Find a file path in the file_set. * * @param set the file_set to search * @param filepath the file path to search for * @return 1 if filepath is found, 0 otherwise */ int file_set_exist(file_set *set, const char* filepath) { int a, b, c; int cmp, res = 0; unsigned hash; char* search_filepath; if (!set->size) return 0; /* not found */ assert(set->array != NULL); /* apply str_tolower if case shall be ignored */ search_filepath = (opt.flags & OPT_IGNORE_CASE ? str_tolower(filepath) : (char*)filepath); /* generate hash to speedup the search */ hash = file_set_make_hash(search_filepath); /* fast binary search */ for (a = -1, b = (int)set->size; (a + 1) < b;) { file_set_item *item; c = (a + b) / 2; assert(0 <= c && c < (int)set->size); item = (file_set_item*)set->array[c]; if (hash != item->hash) { cmp = (hash < item->hash ? -1 : 1); } else { cmp = strcmp(search_filepath, item->search_filepath); if (cmp == 0) { res = 1; /* file path has been found */ break; } } if (cmp < 0) b = c; else a = c; } if (search_filepath != filepath) free(search_filepath); return res; } RHash-1.3.6/file_set.h000066400000000000000000000022451325207677100145060ustar00rootroot00000000000000/* file_set.h - functions to manipulate a set of files with their hash sums */ #ifndef FILE_SET_H #define FILE_SET_H #include "calc_sums.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.3.6/find_file.c000066400000000000000000000273071325207677100146340ustar00rootroot00000000000000/* find_file.c - functions for recursive scan of directories. */ #include #include #include #include #include #include "platform.h" #include "find_file.h" #include "common_func.h" #include "output.h" #include "win_utils.h" #ifdef _WIN32 # include #else # include /* opendir/readdir */ #endif #define IS_DASH_STR(s) ((s)[0] == '-' && (s)[1] == '\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 fill the file_search_data */ 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; } void file_search_add_file(file_search_data* data, tstr_t path, int is_file_list) { #ifdef _WIN32 /* expand wildcards and fill the root_files */ int added = 0; size_t length, index; wchar_t* p = wcschr(path, L'\0') - 1; /* strip trailing '\','/' symbols (if not preceded by ':') */ for (; p > path && IS_PATH_SEPARATOR_W(*p) && p[-1] != L':'; p--) *p = 0; /* Expand a wildcard in the current file path and store results into data->root_files. * If a wildcard is not found then just the file path is stored. * NB, only wildcards in the last filename of the path are expanded. */ 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; /* 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 { file_t file; int failed; if (IS_CURRENT_OR_PARENT_DIRW(d.cFileName)) continue; memset(&file, 0, sizeof(file)); file.wpath = make_pathw(parent, index + 1, d.cFileName); if (!file.wpath) continue; /* skip directories if not in recursive mode */ if (data->max_depth == 0 && (d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) continue; /* convert file name */ file.path = wchar_to_cstr(file.wpath, WIN_DEFAULT_ENCODING, &failed); if (!failed) { failed = (file_stat(&file, 0) < 0); } /* quietly skip unconvertible file names */ if (!file.path || failed) { if (failed) { data->errors_count++; } free(file.path); free(file.wpath); continue; } /* fill the file information */ file.mode |= FILE_IFROOT; add_root_file(data, &file); added++; } while (FindNextFileW(handle, &d)); FindClose(handle); } else { /* report error on the specified wildcard */ char * cpath = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, NULL); set_errno_from_last_file_error(); log_file_error(cpath); free(cpath); data->errors_count++; } } else { int failed; file_t file; memset(&file, 0, sizeof(file)); /* if filepath is a dash string "-" */ if ((path[0] == L'-' && path[1] == L'\0')) { file.mode = FILE_IFSTDIN; file.path = rsh_strdup("(stdin)"); } else { file.path = wchar_to_cstr(path, WIN_DEFAULT_ENCODING, &failed); if (failed) { log_error(_("can't convert the file path to local encoding: %s\n"), file.path); free(file.path); data->errors_count++; return; } file.wpath = path; if (file_stat(&file, 0) < 0) { log_file_t_error(&file); free(file.path); data->errors_count++; return; } } /* mark the file as obtained from the command line */ file.mode |= FILE_IFROOT; if (is_file_list) file.mode |= FILE_IFLIST; file.wpath = rsh_wcsdup(path); add_root_file(data, &file); } #else /* copy file path */ file_t file; file_init(&file, path, 0); if (IS_DASH_STR(file.path)) { file.mode = FILE_IFSTDIN; } else if (file_stat(&file, FUseLstat) < 0) { log_file_t_error(&file); file_cleanup(&file); data->errors_count++; return; } file.mode |= FILE_IFROOT; if (is_file_list) file.mode |= FILE_IFLIST; add_root_file(data, &file); #endif /* _WIN32 */ } /** * Free memory allocated by the file_search_data structure */ 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); } } 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 & FILE_IFROOT)); /* check if file is a directory */ if (!!(file->mode & FILE_IFLIST)) { file_list_t list; if (file_list_open(&list, file) < 0) { log_file_t_error(file); continue; } while (file_list_read(&list)) { data->call_back(&list.current_file, data->call_back_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_file_t_error(file); } } else { /* process a regular file or a dash '-' path */ data->call_back(file, data->call_back_data); } } } /** * An entry of a list containing content of a directory. */ typedef struct dir_entry { struct dir_entry *next; char* filename; unsigned type; /* a directory, symlink, etc. */ } dir_entry; /** * Allocate and initialize a dir_entry. * * @param next next dir_entry in list * @param filename a filename to store in the dir_entry * @param type type of dir_entry * @return allocated dir_entry */ static dir_entry* dir_entry_new(dir_entry *next, char* filename, unsigned type) { dir_entry* e = (dir_entry*)malloc(sizeof(dir_entry)); if (!e) return NULL; if (filename) { e->filename = rsh_strdup(filename); if (!e->filename) { free(e); return NULL; } } else { e->filename = NULL; } e->next = next; e->type = type; return e; } /** * Insert a dir_entry with given filename and type in list. * * @param at the position before which the 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, char* 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; char* 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_flags = (data->options & FIND_FOLLOW_SYMLINKS ? 0 : FUseLstat); 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->call_back(start_dir, data->call_back_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; char* dir_path; DIR *dp; struct dirent *de; /* climb 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); 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_path(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_strdup(start_dir->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, 1); res = file_stat(&file, fstat_flags); /* check if we should skip the directory */ if (res < 0 || !data->call_back(&file, data->call_back_data)) { if (res < 0 && (options & FIND_LOG_ERRORS)) { data->errors_count++; } file_cleanup(&file); continue; } } file_cleanup(&file); /* step into directory */ dp = opendir(dir_path); if (!dp) continue; insert_at = &dirs_stack; while ((de = readdir(dp)) != NULL) { int res; /* skip the "." and ".." directories */ if (IS_CURRENT_OR_PARENT_DIR(de->d_name)) continue; file.mode = 0; file.path = make_path(dir_path, de->d_name); if (!file.path) continue; res = file_stat(&file, fstat_flags); 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->call_back(&file, data->call_back_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, de->d_name, 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_file_t_error(&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); assert(file.path == 0); return 0; } RHash-1.3.6/find_file.h000066400000000000000000000016011325207677100146260ustar00rootroot00000000000000/* find_file.h - functions for recursive scan of directories. */ #ifndef FIND_FILE_H #define FIND_FILE_H #include "common_func.h" #include "file.h" #ifdef __cplusplus extern "C" { #endif /* find_file options */ #define FIND_WALK_DEPTH_FIRST 1 #define FIND_FOLLOW_SYMLINKS 2 #define FIND_SKIP_DIRS 4 #define FIND_LOG_ERRORS 8 #define FIND_CANCEL 16 /** * Options for file search. */ typedef struct file_search_data { int options; int max_depth; blocks_vector_t root_files; int (*call_back)(file_t* file, int data); int call_back_data; int errors_count; } file_search_data; file_search_data* file_search_data_new(void); void file_search_add_file(file_search_data* data, tstr_t path, int is_file_list); void file_search_data_free(file_search_data* data); void scan_files(file_search_data* data); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* FIND_FILE_H */ RHash-1.3.6/hash_check.c000066400000000000000000000520031325207677100147640ustar00rootroot00000000000000/* hash_check.c - verification of hashes of files */ #include #include /* isspace */ #include #include "hash_check.h" #include "hash_print.h" #include "common_func.h" #include "output.h" #include "parse_cmdline.h" #include "librhash/rhash.h" /* hash conversion macros and functions */ #define HEX2DIGIT(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(bytes) (((bytes) * 8 + 4) / 5) /** * 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++) = HEX2DIGIT(*(str++)); len--; } /* parse the rest - an even-sized hexadecimal string */ for (; len >= 2; len -= 2, str += 2) { *(bin++) = (HEX2DIGIT(str[0]) << 4) | HEX2DIGIT(str[1]); } } /** * Decode an URL-encoded string in the specified buffer. * * @param buffer the 0-terminated URL-encoded string */ static void urldecode(char *buffer) { char *wpos = buffer; /* set writing position */ for (; *buffer; wpos++) { *wpos = *(buffer++); /* copy non-escaped characters */ if (*wpos == '%') { if (*buffer == '%') { buffer++; /* interpret '%%' as single '%' */ } else if (IS_HEX(*buffer)) { /* decode character from the % form */ int ch = HEX2DIGIT(*buffer); buffer++; if (IS_HEX(*buffer)) { ch = (ch << 4) | HEX2DIGIT(*buffer); buffer++; } *wpos = (char)ch; } } } *wpos = '\0'; /* terminate decoded string */ } #ifndef _WIN32 /** * Convert a windows file path to a UNIX one, replacing '\\' by '/'. * * @param path the path to convert * @return converted path */ static void process_backslashes(char* path) { for (;*path;path++) { if (*path == '\\') *path = '/'; } } #else /* _WIN32 */ #define process_backslashes(path) #endif /* _WIN32 */ /* convert a hash flag to index */ #if __GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */ # define get_ctz(x) __builtin_ctz(x) #else /** * Returns index of the trailing bit of a 32-bit number. * This is a plain C equivalent for GCC __builtin_ctz() bit scan. * * @param x the number to process * @return zero-based index of the trailing bit */ unsigned get_ctz(unsigned x) { /* see http://graphics.stanford.edu/~seander/bithacks.html */ 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 }; return bit_pos[((uint32_t)((x & -(int)x) * 0x077CB531U)) >> 27]; } #endif /* (GCC >= 4.3) */ /** * Encode a hash function digest size into a small number in {0,...,24}. * The digest size must be a positive number not greater then 128. * * @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) { int pow, code; /* check (0 < size && size <= 128)) */ if ((unsigned)(digest_size - 1) > 127) return 32; pow = get_ctz(digest_size >> 2); code = ((digest_size >> (pow + 3)) << 3) | pow; return (code <= 24 ? code : 32); } /** * Calculate an OR-ed mask of hash-ids by a length of hash in bytes. * * @param digest_size length of a hash in bytes. * @return mask of hash-ids with given hash length, 0 on fail. */ static unsigned hash_check_mask_by_digest_size(int digest_size) { static unsigned mask[26] = { 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0 }; int code; if (mask[25] == 0) { unsigned hid; for (hid = 1; hid <= RHASH_ALL_HASHES; hid <<= 1) { code = code_digest_size(rhash_get_digest_size(hid)); assert(0 <= code && code <= 24); if (code <= 24) mask[code] |= hid; /* 'if' for paranoid protection */ } mask[25] = 1; } code = code_digest_size(digest_size); return (code <= 24 ? mask[code] : 0); } #define HV_BIN 0 #define HV_HEX 1 #define HV_B32 2 /** * Test if a character is a hexadecimal/base32 digit. * * @param c the character to test * @return result of the test, a combination of flags HV_HEX and HV_B32 */ static int test_hash_char(char c) { return (IS_HEX(c) ? HV_HEX : 0) | (IS_BASE32(c) ? HV_B32 : 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 hash string * @return type of detected hash as combination of HV_HEX and HV_B32 flags */ static int detect_hash_type(char **ptr, char *end, int *p_len) { int len = 0; int char_type = 0, next_type = (HV_HEX | HV_B32); if (*ptr < end) { /* search forward (but no more then 129 symbols) */ if ((end - *ptr) >= 129) end = *ptr + 129; for (; (next_type &= test_hash_char(**ptr)) && *ptr <= end; len++, (*ptr)++) { char_type = next_type; } } else { /* search backward (but no more then 129 symbols) */ if ((*ptr-end) >= 129) end = *ptr - 129; for (; (next_type &= test_hash_char((*ptr)[-1])) && *ptr >= end; len++, (*ptr)--) { char_type = next_type; } } *p_len = len; return char_type; } /** * Test that the given string contain a hexadecimal or base32 hash string * of one of supported hash sums. * * @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 hash string * @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 & HV_HEX) && (len & 7) == 0 && len <= 256) { int pow = get_ctz(len >> 3); int code = ((len >> (pow + 4)) << 3) | pow; if (code < 32 && ((1 << code) & 0x101061d)) hash_type |= HV_HEX; } if ((char_type & HV_B32) && (len == 32 || len == 39)) { hash_type |= HV_B32; } if (hash_type != 0) { *p_len = len; } return hash_type; } /** * Detect ASCII-7 white spaces (not including Unicode whitespaces). * Note that isspace() is locale specific and detect Unicode spaces, * like U+00A0. */ static int rhash_isspace(char ch) { return (((unsigned char)ch) <= 0x7F && isspace((unsigned char)ch)); } /** * Information about found token */ typedef struct hc_search { char* begin; /* start of the buffer to search */ char* end; /* end of the buffer to search */ hash_check* hc; unsigned expected_hash_id; int hash_type; char* url_name; size_t url_length; } hc_search; /** * Parse the buffer pointed by search->begin, into tokens specified by format * string. The format string can contain the following special characters: * '\1' - hash function name, '\2' - any hash, '\3' - specified hash, * '\4' - an URL-encoded file name, '\5' - a file size, * '\6' - a required-space, '\7' - a space or string 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 search->begin and search->end pointers on success. * * @param search the structure to store parsed tokens info * @param format the format string * @return 1 on success, 0 if couldn't find specified token(s) */ static int hash_check_find_str(hc_search *search, const char* format) { int backward = 0; char buf[20]; const char *fend = strchr(format, '\0'); char* begin = search->begin; char* end = search->end; hash_check* hc = search->hc; hash_value hv; int unsaved_hashval = 0; memset(&hv, 0, sizeof(hash_value)); while (format < fend) { const char *search_str; int i, 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 0; if (0 != memcmp(search_str, (backward ? end - len : begin), len)) return 0; if (backward) end -= len; else begin += len; continue; } assert(len == 0); /* find substring specified by single character */ switch (*search_str) { case '\1': /* parse 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 0; /* limit name length */ buf[len] = toupper(begin[len]); } begin += len; if (len == 0) return 0; /* not alpha-numeric sequence */ buf[len] = '\0'; search->expected_hash_id = 0; /* find hash_id by a hash function name */ for (i = 0; i < RHASH_HASH_COUNT; i++) { if (strcmp(buf, hash_info_table[i].name) == 0) { search->expected_hash_id = 1 << i; search->hash_type = (HV_HEX | HV_B32); break; } } break; case '\2': case '\3': if (backward) { hv.format = test_hash_string(&end, begin, &len); hv.offset = (unsigned short)(end - hc->data); } else { hv.offset = (unsigned short)(begin - hc->data); hv.format = test_hash_string(&begin, end, &len); } if (!hv.format) return 0; if (*search_str == '\3') { /* verify hash type */ int dlen = rhash_get_digest_size(search->expected_hash_id); hv.format &= search->hash_type; if ((!(hv.format & HV_HEX) || len != (dlen * 2)) && (!(hv.format & HV_B32) || len != BASE32_LENGTH(dlen))) return 0; hv.hash_id = search->expected_hash_id; } else hv.hash_id = 0; hv.length = (unsigned char)len; unsaved_hashval = 1; break; case '\4': /* get URL-encoded name */ search->url_name = begin; search->url_length = strcspn(begin, "?&|"); if (search->url_length == 0) return 0; /* empty name */ begin += search->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 0; else { hc->file_size = file_size; hc->flags |= HC_HAS_FILESIZE; } break; case '\6': case '\7': case ' ': if (backward) for (; begin < end && rhash_isspace(end[-1]); end--, len++); else for (; rhash_isspace(*begin) && begin < end; begin++, len++); /* check if space is mandatory */ if (*search_str != ' ' && len == 0) { /* for '\6' check (len > 0) */ /* for '\7' check (len > 0 || begin == end) */ if (*search_str == '\6' || begin < end) return 0; } break; case '$': backward = 1; /* switch to parsing string backward */ break; default: if ((backward ? *(--end) : *(begin++)) != *search_str) return 0; } } if (unsaved_hashval && hc->hashes_num < HC_MAX_HASHES) { hc->hashes[hc->hashes_num++] = hv; } search->begin = begin; search->end = end; return 1; } /* macros used by hash_check_parse_line() */ #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)) /** * 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 line the line to parse * @param hashes structure to store parsed hashes, file path and file size * @return 1 on success, 0 if couldn't parse the line */ int hash_check_parse_line(char* line, hash_check* hashes, int check_eol) { hc_search hs; char* le = strchr(line, '\0'); /* set pointer to the end of line */ char* url_name = NULL; size_t url_length = 0; int single_hash = 0; int reversed = 0; int bad = 0; int i, j; /* return if EOL not found at the end of the line */ if ( line[0]=='\0' || (le[-1] != '\n' && check_eol) ) return 0; /* note: not using str_tim because 'le' is re-used below */ /* remove trailing white spaces */ while (rhash_isspace(le[-1]) && le > line) *(--le) = 0; /* skip white spaces at the start of the line */ while (rhash_isspace(*line)) line++; memset(&hs, 0, sizeof(hs)); hs.begin = line; hs.end = le; hs.hc = hashes; memset(hashes, 0, sizeof(hash_check)); hashes->data = line; hashes->file_size = (uint64_t)-1; if (strncmp(line, "magnet:?", 8) == 0) { hs.begin += 8; /* loop by magnet link parameters */ while (1) { char* next = strchr(hs.begin, '&'); char* param_end = (next ? next++ : hs.end); char* hf_end; if ((hs.begin += 3) < param_end) { switch (THREEC2U(hs.begin[-3], hs.begin[-2], hs.begin[-1])) { case THREEC2U('d', 'n', '='): /* URL-encoded file path */ url_name = hs.begin; url_length = param_end - hs.begin; break; case THREEC2U('x', 'l', '='): /* file size */ if (!hash_check_find_str(&hs, "\5")) bad = 1; if (hs.begin != param_end) bad = 1; break; case THREEC2U('x', 't', '='): /* a file hash */ /* find last ':' character (hash name can be complex like tree:tiger) */ for (hf_end = param_end - 1; *hf_end != ':' && hf_end > hs.begin; hf_end--); /* test for the "urn:" string */ if ((hs.begin += 4) >= hf_end) return 0; if (FOURC2U('u', 'r', 'n', ':') != FOURC2U(hs.begin[-4], hs.begin[-3], hs.begin[-2], hs.begin[-1])) return 0; /* find hash by its magnet link specific URN name */ for (i = 0; i < RHASH_HASH_COUNT; i++) { const char* urn = rhash_get_magnet_name(1 << i); size_t len = hf_end - hs.begin; if (strncmp(hs.begin, urn, len) == 0 && urn[len] == '\0') break; } if (i >= RHASH_HASH_COUNT) { if (opt.flags & OPT_VERBOSE) { *hf_end = '\0'; log_warning(_("unknown hash in magnet link: %s\n"), hs.begin); } return 0; } hs.begin = hf_end + 1; hs.expected_hash_id = 1 << i; hs.hash_type = (HV_HEX | HV_B32); if (!hash_check_find_str(&hs, "\3")) bad = 1; if (hs.begin != param_end) bad = 1; break; /* note: this switch () skips all unknown parameters */ } } if (!bad && next) hs.begin = next; else break; } if (!url_name) bad = 1; /* file path parameter is mandatory */ } else if (strncmp(line, "ed2k://|file|", 13) == 0) { hs.begin += 13; hs.expected_hash_id = RHASH_ED2K; hs.hash_type = HV_HEX; if (hash_check_find_str(&hs, "\4|\5|\3|")) { url_name = hs.url_name; url_length = hs.url_length; } else bad = 1; /* try to parse optional AICH hash */ hs.expected_hash_id = RHASH_AICH; hs.hash_type = (HV_HEX | HV_B32); /* AICH is usually base32-encoded*/ hash_check_find_str(&hs, "h=\3|"); } else { if (hash_check_find_str(&hs, "\1 ( $ ) = \3")) { /* BSD-formatted line has been processed */ } else if (hash_check_find_str(&hs, "$\6\2")) { while (hash_check_find_str(&hs, "$\6\2")); if (hashes->hashes_num > 1) reversed = 1; } else if (hash_check_find_str(&hs, "\2\7")) { if (hs.begin == hs.end) { /* the line contains no file path, only a single hash */ single_hash = 1; } else { while (hash_check_find_str(&hs, "\2\6")); /* drop an asterisk before filename if present */ if (*hs.begin == '*') hs.begin++; } } else bad = 1; if (hs.begin >= hs.end && !single_hash) bad = 1; } if (bad) { log_warning(_("can't parse line: %s\n"), line); return 0; } assert(hashes->file_path == 0); /* if !single_hash then we shall extract filepath from the line */ if (url_name) { hashes->file_path = url_name; url_name[url_length] = '\0'; urldecode(url_name); /* decode filename from URL */ process_backslashes(url_name); } else if (!single_hash) { assert(hs.begin < hs.end); hashes->file_path = hs.begin; *hs.end = '\0'; process_backslashes(hs.begin); } if (reversed) { /* change the order of hash values from reversed back to forward */ for (i = 0, j = hashes->hashes_num - 1; i < j; i++, j--) { hash_value tmp = hashes->hashes[i]; hashes->hashes[i] = hashes->hashes[j]; hashes->hashes[j] = tmp; } } /* post-process parsed hashes */ for (i = 0; i < hashes->hashes_num; i++) { hash_value *hv = &hashes->hashes[i]; char *hash_str = hashes->data + hv->offset; if (hv->hash_id == 0) { /* calculate hash mask */ unsigned mask = 0; if (hv->format & HV_HEX) { mask |= hash_check_mask_by_digest_size(hv->length >> 1); } if (hv->format & HV_B32) { assert(((hv->length * 5 / 8) & 3) == 0); mask |= hash_check_mask_by_digest_size(hv->length * 5 / 8); } assert(mask != 0); if ((mask & opt.sum_flags) != 0) mask &= opt.sum_flags; hv->hash_id = mask; } hashes->hash_mask |= hv->hash_id; /* change the hash string to be upper-case */ for (j = 0; j < (int)hv->length; j++) { if (hash_str[j] >= 'a') hash_str[j] &= ~0x20; } hash_str[j] = '\0'; /* terminate the hash string */ } return 1; } /** * Forward and reverse hex string compare. Compares two hexadecimal strings * using forward and reversed byte order. The function is used to compare * GOST hashes which can be reversed, because byte order of * an output string is not specified by GOST standard. * The function acts almost the same way as memcmp, but always returns * 1 for unmatched strings. * * @param mem1 the first byte string * @param mem2 the second byte string * @param size the length of byte strings to much * @return 0 if strings are matched, 1 otherwise. */ static int fr_hex_cmp(const void* mem1, const void* mem2, size_t size) { const char *p1, *p2, *pe; if (memcmp(mem1, mem2, size) == 0) return 0; if ((size & 1) != 0) return 1; /* support only even size */ p1 = (const char*)mem1, p2 = ((const char*)mem2) + size - 2; for (pe = ((const char*)mem1) + size / 2; p1 < pe; p1 += 2, p2 -= 2) { if (p1[0] != p2[0] || p1[1] != p2[1]) return 1; } 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 hash sum */ 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 hashes against original values. * Also verify the file size and embedded CRC32 if present. * The HC_WRONG_* bits are set in the hashes->flags field on fail. * * @param hashes 'original' parsed hash values, to verify against * @param ctx the rhash context containing calculated hash values * @return 1 on success, 0 on fail */ int hash_check_verify(hash_check* hashes, struct rhash_context* ctx) { unsigned unverified_mask; unsigned hid; unsigned printed; char hex[132], b32[104]; int j; /* verify file size, if present */ if ((hashes->flags & HC_HAS_FILESIZE) != 0 && hashes->file_size != ctx->msg_size) hashes->flags |= HC_WRONG_FILESIZE; /* verify embedded CRC32 hash sum, if present */ if ((hashes->flags & HC_HAS_EMBCRC32) != 0 && get_crc32(ctx) != hashes->embedded_crc32) hashes->flags |= HC_WRONG_EMBCRC32; /* return if nothing else to verify */ if (hashes->hashes_num == 0) return !HC_FAILED(hashes->flags); unverified_mask = (1 << hashes->hashes_num) - 1; for (hid = 1; hid <= RHASH_ALL_HASHES; hid <<= 1) { if ((hashes->hash_mask & hid) == 0) continue; printed = 0; for (j = 0; j < hashes->hashes_num; j++) { hash_value *hv = &hashes->hashes[j]; char *hash_str, *hash_orig; int dgst_size; /* skip already verified hashes and hashes with different digest size */ if (!(unverified_mask & (1 << j)) || !(hv->hash_id & hid)) continue; dgst_size = rhash_get_digest_size(hid); if (hv->length == (dgst_size * 2)) { assert(hv->format & HV_HEX); assert(hv->length <= 128); /* print hexadecimal value, if not printed yet */ if ((printed & HV_HEX) == 0) { rhash_print(hex, ctx, hid, RHPR_HEX | RHPR_UPPERCASE); printed |= HV_HEX; } hash_str = hex; } else { assert(hv->format & HV_B32); assert(hv->length == BASE32_LENGTH(dgst_size)); assert(hv->length <= 103); /* print base32 value, if not printed yet */ if ((printed & HV_B32) == 0) { rhash_print(b32, ctx, hid, RHPR_BASE32 | RHPR_UPPERCASE); printed |= HV_B32; } hash_str = b32; } hash_orig = hashes->data + hv->offset; if ((hid & (RHASH_GOST | RHASH_GOST_CRYPTOPRO)) != 0) { if (fr_hex_cmp(hash_orig, hash_str, hv->length) != 0) continue; } else { if (memcmp(hash_orig, hash_str, hv->length) != 0) continue; } unverified_mask &= ~(1 << j); /* the j-th hash verified */ hashes->found_hash_ids |= hid; /* end loop if all hashes were successfully verified */ if (unverified_mask == 0) goto hc_verify_exit; } } hc_verify_exit: /* we use label/goto to jump out of two nested loops */ hashes->wrong_hashes = unverified_mask; if (unverified_mask != 0) hashes->flags |= HC_WRONG_HASHES; return !HC_FAILED(hashes->flags); } RHash-1.3.6/hash_check.h000066400000000000000000000040231325207677100147700ustar00rootroot00000000000000/* hash_check.h - functions to parse a file with hash sums to verify it */ #ifndef HASH_CHECK_H #define HASH_CHECK_H #include #ifdef __cplusplus extern "C" { #endif /* bit flags for hash_check.flags */ #define HC_HAS_FILESIZE 1 #define HC_HAS_EMBCRC32 2 #define HC_WRONG_FILESIZE 4 #define HC_WRONG_EMBCRC32 8 #define HC_WRONG_HASHES 16 #define HC_FAILED(flags) ((flags) & (HC_WRONG_FILESIZE | HC_WRONG_EMBCRC32 | HC_WRONG_HASHES)) #define HC_MAX_HASHES 32 /** * Parsed hash value. */ typedef struct hash_value { unsigned hash_id; /* the id of hash, if it was detected */ unsigned short offset; unsigned char length; unsigned char format; } hash_value; struct rhash_context; /** * Parsed file info, like the path, size and file hash values. */ typedef struct hash_check { char *file_path; /* parsed file path */ uint64_t file_size; /* parsed file size, e.g. from magnet link */ unsigned hash_mask; /* the mask of hash ids to verify against */ unsigned flags; /* bit flags */ unsigned embedded_crc32; /* CRC32 embedded into filename */ char *data; /* the buffer with the current hash file line */ unsigned found_hash_ids; /* bit mask for matched hash ids */ unsigned wrong_hashes; /* bit mask for mismatched hashes */ int hashes_num; /* number of parsed hashes */ hash_value hashes[HC_MAX_HASHES]; } hash_check; int hash_check_parse_line(char* line, hash_check* hashes, int check_eol); int hash_check_verify(hash_check* hashes, struct rhash_context* ctx); void rhash_base32_to_byte(const char* str, unsigned char* bin, int len); void rhash_hex_to_byte(const char* str, unsigned char* bin, int len); unsigned get_crc32(struct rhash_context* ctx); /* note: IS_HEX() is defined on ASCII-8 while isxdigit() only when isascii()==true */ #define IS_HEX(c) ((c) <= '9' ? (c) >= '0' : (unsigned)(((c) - 'A') & ~0x20) <= ('F' - 'A' + 0U)) #define IS_BASE32(c) (((c) <= '7' ? ('2' <= (c)) : (unsigned)(((c) - 'A') & ~0x20) <= ('Z' - 'A' + 0U))) #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* HASH_CHECK_H */ RHash-1.3.6/hash_print.c000066400000000000000000000460631325207677100150540ustar00rootroot00000000000000/* hash_print.c - output hash sums using printf-like format */ #include #include #include #include #ifdef _WIN32 # include # include #endif /* _WIN32 */ #include "hash_print.h" #include "calc_sums.h" #include "common_func.h" #include "file.h" #include "parse_cmdline.h" #include "win_utils.h" #include "librhash/rhash.h" /*========================================================================= * Formatted output functions and structures *=========================================================================*/ /** * The table with information about hash functions. */ print_hash_info hash_info_table[32]; /** * Possible types of a print_item. */ enum { PRINT_ED2K_LINK = 0x100000, PRINT_FLAG_UPPERCASE = 0x200000, PRINT_FLAG_RAW = 0x0400000, PRINT_FLAG_HEX = 0x0800000, PRINT_FLAG_BASE32 = 0x1000000, PRINT_FLAG_BASE64 = 0x2000000, PRINT_FLAG_PAD_WITH_ZERO = 0x4000000, PRINT_FLAGS_ALL = PRINT_FLAG_UPPERCASE | PRINT_FLAG_PAD_WITH_ZERO | PRINT_FLAG_RAW | PRINT_FLAG_HEX | PRINT_FLAG_BASE32 | PRINT_FLAG_BASE64, PRINT_STR = 0x10000000, PRINT_ZERO, PRINT_NEWLINE, PRINT_FILEPATH, PRINT_BASENAME, PRINT_URLNAME, PRINT_SIZE, PRINT_MTIME /*PRINT_ATIME, PRINT_CTIME*/ }; /* parse a token following a percent sign '%' */ static print_item* parse_percent_item(const char** str); /** * Allocate new print_item. * * @param flags the print_item flags * @param hash_id optional hash_id * @param data optional string to store * @return allocated print_item */ static print_item* new_print_item(unsigned flags, unsigned hash_id, const char *data) { print_item* item = (print_item*)rsh_malloc(sizeof(print_item)); item->flags = flags; item->hash_id = hash_id; item->width = 0; item->data = (data ? rsh_strdup(data) : NULL); item->next = NULL; return item; } /** * Parse an escaped sequence in a printf-like format string. * * @param pformat pointer to the sequence, the pointer * is changed to point to the next symbol after parsed sequence * @return result character */ static char parse_escaped_char(const char **pformat) { const char* start = *pformat; switch ( *((*pformat)++) ) { case '0': return '\0'; case 't': return '\t'; case 'r': return '\r'; case 'n': return '\n'; case '\\': return '\\'; case 'x': /* \xNN byte with hexadecimal value NN (1 to 2 digits) */ if ( IS_HEX(**pformat) ) { int ch; ch = (**pformat <= '9' ? **pformat & 15 : (**pformat + 9) & 15); (*pformat) ++; if (IS_HEX(**pformat)) { /* read the second digit */ ch = 16 * ch + (**pformat <= '9' ? **pformat & 15 : (**pformat + 9) & 15); (*pformat)++; } return ch; } break; default: (*pformat)--; /* \NNN - character with octal value NNN (1 to 3 digits) */ if ('0' < **pformat && **pformat <= '7') { int ch = *((*pformat)++) - '0'; if ('0' <= **pformat && **pformat <= '7') { ch = ch * 8 + *((*pformat)++) - '0'; if ('0' <= **pformat && **pformat <= '7') ch = ch * 8 + *((*pformat)++) - '0'; } return (char)ch; } } *pformat = start; return '\\'; } /** * Parse format string. * * @return a print_item list with parsed information */ print_item* parse_print_string(const char* format, unsigned *sum_mask) { char *buf, *p; print_item *list = NULL, **tail, *item = NULL; buf = p = (char*)rsh_malloc( strlen(format) + 1 ); tail = &list; *sum_mask = 0; for (;;) { while (*format && *format != '%' && *format != '\\') *(p++) = *(format++); if (*format == '\\') { format++; *p = parse_escaped_char(&format); if (*p == '\0') { item = new_print_item(PRINT_ZERO, 0, NULL); #ifdef _WIN32 } else if (*p == '\n') { item = new_print_item(PRINT_NEWLINE, 0, NULL); #endif } else { p++; continue; } } else if (*format == '%') { if ( *(++format) == '%' ) { *(p++) = *format++; continue; } else { item = parse_percent_item(&format); if (!item) { *(p++) = '%'; continue; } if (item->hash_id) *sum_mask |= item->hash_id; } } if (p > buf || (!*format && list == NULL && item == NULL)) { *p = '\0'; *tail = new_print_item(PRINT_STR, 0, buf); tail = &(*tail)->next; p = buf; } if (item) { *tail = item; tail = &item->next; item = NULL; } if (!*format) break; }; free(buf); return list; } /** * Convert given case-insensitive name to a printf directive id * * @param name printf directive name (not a 0-terminated) * @param length name length * @return directive id on success, 0 on fail */ static unsigned printf_name_to_id(const char* name, size_t length, unsigned *flags) { char buf[20]; size_t i; print_hash_info *info = hash_info_table; unsigned bit; if (length > (sizeof(buf)-1)) return 0; for (i = 0; i < length; i++) buf[i] = tolower(name[i]); /* check for old '%{urlname}' directive for compatibility */ if (length == 7 && memcmp(buf, "urlname", 7) == 0) { *flags = PRINT_URLNAME; return 0; } else if (length == 5 && memcmp(buf, "mtime", 5) == 0) { *flags = PRINT_MTIME; return 0; } for (bit = 1; bit <= RHASH_ALL_HASHES; bit = bit << 1, info++) { if (memcmp(buf, info->short_name, length) == 0 && info->short_name[length] == 0) return bit; } return 0; } /** * Parse a token followed by a percent sign in a printf-like format string. * * @return a print_item with parsed information */ print_item* parse_percent_item(const char** str) { const char* format = *str; const char* p = NULL; unsigned hash_id = 0; unsigned modifier_flags = 0; int id_found = 0; int width = 0; int pad_with_zero_bit = 0; print_item* item = NULL; static const char *short_hash = "CMHTGWRAE"; static const char *short_other = "Llpfus"; static const unsigned hash_ids[] = { RHASH_CRC32, RHASH_MD5, RHASH_SHA1, RHASH_TTH, RHASH_GOST, RHASH_WHIRLPOOL, RHASH_RIPEMD160, RHASH_AICH, RHASH_ED2K }; static const unsigned other_flags[] = { PRINT_ED2K_LINK, PRINT_ED2K_LINK, PRINT_FILEPATH, PRINT_BASENAME, PRINT_URLNAME, PRINT_SIZE }; /* detect the padding by zeros */ if (*format == '0') { pad_with_zero_bit = PRINT_FLAG_PAD_WITH_ZERO; format++; } /* parse the 'b','B','x' and '@' flags */ if (*format == 'x') { modifier_flags |= PRINT_FLAG_HEX; format++; } else if (*format == 'b') { modifier_flags |= PRINT_FLAG_BASE32; format++; } else if (*format == 'B') { modifier_flags |= PRINT_FLAG_BASE64; format++; } else if (*format == '@') { modifier_flags |= PRINT_FLAG_RAW; format++; } for (; isdigit((unsigned char)*format); format++) width = 10 * width + (*format - '0'); /* if a complicated token enconuntered */ if (*format == '{') { /* parse the token of the kind "%{some-token}" */ const char* p = ++format; for (; isalnum((unsigned char)*p) || (*p == '-'); p++); if (*p == '}') { hash_id = printf_name_to_id(format, (int)(p - (format)), &modifier_flags); format--; if (hash_id || modifier_flags == PRINT_URLNAME || modifier_flags == PRINT_MTIME) { /* set uppercase flag if the first letter of printf-entity is uppercase */ modifier_flags |= (format[1] & 0x20 ? 0 : PRINT_FLAG_UPPERCASE); format = p; id_found = 1; } } else { format--; } } /* if still not found a token denoting a hash function */ if (!id_found) { const char upper = *format & ~0x20; /* if the string terminated just after the '%' character */ if ( *format == '\0' ) return NULL; /* look for a known token */ if ( (p = strchr(short_hash, upper)) ) { assert( (p - short_hash) < (int)(sizeof(hash_ids) / sizeof(unsigned)) ); hash_id = hash_ids[p - short_hash]; modifier_flags |= (*format & 0x20 ? 0 : PRINT_FLAG_UPPERCASE); } else if ( (p = strchr(short_other, *format)) ) { assert( (p - short_other) < (int)(sizeof(other_flags) / sizeof(unsigned)) ); modifier_flags = other_flags[p - short_other]; if (modifier_flags == PRINT_ED2K_LINK) { modifier_flags |= (*p & 0x20 ? 0 : PRINT_FLAG_UPPERCASE); hash_id = RHASH_ED2K | RHASH_AICH; } } else { return 0; /* no valid token found */ } } modifier_flags |= pad_with_zero_bit; item = new_print_item(modifier_flags, hash_id, NULL); item->width = width; *str = ++format; return item; } /** * Print EDonkey 2000 url for given file to a stream. * * @param out the stream where to print url to * @param filename the file name * @param filesize the file size * @param sums the file hash sums */ static void fprint_ed2k_url(FILE* out, struct file_info *info, int print_type) { const char *filename = get_basename(file_info_get_utf8_print_path(info)); int upper_case = (print_type & PRINT_FLAG_UPPERCASE ? RHPR_UPPERCASE : 0); int len = urlencode(NULL, filename) + int_len(info->size) + (info->sums_flags & RHASH_AICH ? 84 : 49); char* buf = (char*)rsh_malloc( len + 1 ); char* dst = buf; assert(info->sums_flags & (RHASH_ED2K|RHASH_AICH)); assert(info->rctx); strcpy(dst, "ed2k://|file|"); dst += 13; dst += urlencode(dst, filename); *dst++ = '|'; sprintI64(dst, info->size, 0); dst += strlen(dst); *dst++ = '|'; rhash_print(dst, info->rctx, RHASH_ED2K, upper_case); dst += 32; if ((info->sums_flags & RHASH_AICH) != 0) { strcpy(dst, "|h="); rhash_print(dst += 3, info->rctx, RHASH_AICH, RHPR_BASE32 | upper_case); dst += 32; } strcpy(dst, "|/"); rsh_fprintf(out, "%s", buf); free(buf); } /** * Output aligned uint64_t number to specified output stream. * * @param out the stream to output to * @param filesize the 64-bit integer to output, usually a file size * @param width minimal width of integer to output * @param flag =1 if the integer shall be prepended by zeros */ static void fprintI64(FILE* out, uint64_t filesize, int width, int zero_pad) { char *buf = (char*)rsh_malloc(width > 40 ? width + 1 : 41); int len = int_len(filesize); sprintI64(buf, filesize, width); if (len < width && zero_pad) { memset(buf, '0', width-len); } rsh_fprintf(out, "%s", buf); free(buf); } /** * Print time formatted as hh:mm.ss YYYY-MM-DD to a file stream. * * @param out the stream to print the time to * @param time the time to print */ static void print_time(FILE *out, time_t time) { struct tm *t = localtime(&time); static struct tm zero_tm; if (t == NULL) { /* if a strange day, then print `00:00.00 1900-01-00' */ t = &zero_tm; t->tm_hour = t->tm_min = t->tm_sec = t->tm_year = t->tm_mon = t->tm_mday = 0; } rsh_fprintf(out, "%02u:%02u.%02u %4u-%02u-%02u", t->tm_hour, t->tm_min, t->tm_sec, (1900 + t->tm_year), t->tm_mon + 1, t->tm_mday); } /** * Print time formatted as hh:mm.ss YYYY-MM-DD to a file stream. * * @param out the stream to print the time to * @param time the time to print */ static void print_time64(FILE *out, uint64_t time) { print_time(out, (time_t)time); } /** * Print formatted file information to given output stream. * * @param out the stream to print information to * @param list the format according to which information shall be printed * @param info the file information */ void print_line(FILE* out, print_item* list, struct file_info *info) { const char* basename = get_basename(info->print_path), *tmp; char *url = NULL, *ed2k_url = NULL; char buffer[130]; #ifdef _WIN32 /* switch to binary mode to correctly output binary hashes */ int out_fd = _fileno(out); int old_mode = (out_fd > 0 && !isatty(out_fd) ? _setmode(out_fd, _O_BINARY) : -1); #endif for (; list; list = list->next) { int print_type = list->flags & ~(PRINT_FLAGS_ALL); size_t len; /* output a hash function digest */ if (list->hash_id && print_type != PRINT_ED2K_LINK) { unsigned hash_id = list->hash_id; int print_flags = (list->flags & PRINT_FLAG_UPPERCASE ? RHPR_UPPERCASE : 0) | (list->flags & PRINT_FLAG_RAW ? RHPR_RAW : 0) | (list->flags & PRINT_FLAG_BASE32 ? RHPR_BASE32 : 0) | (list->flags & PRINT_FLAG_BASE64 ? RHPR_BASE64 : 0) | (list->flags & PRINT_FLAG_HEX ? RHPR_HEX : 0); if ((hash_id == RHASH_GOST || hash_id == RHASH_GOST_CRYPTOPRO) && (opt.flags & OPT_GOST_REVERSE)) print_flags |= RHPR_REVERSE; len = rhash_print(buffer, info->rctx, hash_id, print_flags); assert(len < sizeof(buffer)); /* output the hash, exit on fail */ rsh_fwrite(buffer, 1, len, out); continue; } /* output other special items: filepath, URL-encoded filename etc. */ switch (print_type) { case PRINT_STR: rsh_fprintf(out, "%s", list->data); break; case PRINT_ZERO: /* the '\0' character */ rsh_fprintf(out, "%c", 0); break; #ifdef _WIN32 case PRINT_NEWLINE: rsh_fprintf(out, "%s", "\r\n"); break; #endif case PRINT_FILEPATH: rsh_fprintf(out, "%s", info->print_path); break; case PRINT_BASENAME: /* the filename without directory */ rsh_fprintf(out, "%s", basename); break; case PRINT_URLNAME: /* URL-encoded filename */ if (!url) { tmp = get_basename(file_info_get_utf8_print_path(info)); url = (char*)rsh_malloc(urlencode(NULL, tmp) + 1); urlencode(url, tmp); } rsh_fprintf(out, "%s", url); break; case PRINT_MTIME: /* the last-modified tine of the filename */ print_time64(out, info->file->mtime); break; case PRINT_SIZE: /* file size */ fprintI64(out, info->size, list->width, (list->flags & PRINT_FLAG_PAD_WITH_ZERO)); break; case PRINT_ED2K_LINK: fprint_ed2k_url(out, info, list->flags); break; } } free(url); free(ed2k_url); fflush(out); #ifdef _WIN32 if (old_mode >= 0) _setmode(out_fd, old_mode); #endif } /** * Release memory allocated by given print_item list. * * @param list the list to free */ void free_print_list(print_item* list) { while (list) { print_item* next = list->next; free((char*)list->data); free(list); list = next; } } /*========================================================================= * initialization of internal data *=========================================================================*/ /** * Initialize information about hashes, stored in the * hash_info_table global variable. */ void init_hash_info_table(void) { unsigned index, bit; unsigned short_opt_mask = RHASH_CRC32 | RHASH_MD5 | RHASH_SHA1 | RHASH_TTH | RHASH_ED2K | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 | RHASH_GOST | OPT_ED2K_LINK; char* short_opt = "cmhteawrgl"; print_hash_info *info = hash_info_table; unsigned fullmask = RHASH_ALL_HASHES | OPT_ED2K_LINK; memset(hash_info_table, 0, sizeof(hash_info_table)); for (index = 0, bit = 1; bit <= fullmask; index++, bit = bit << 1, info++) { const char *p; char *e, *d; info->short_char = ((bit & short_opt_mask) != 0 && *short_opt ? *(short_opt++) : 0); info->name = (bit & RHASH_ALL_HASHES ? rhash_get_name(bit) : "ED2K-LINK"); assert(strlen(info->name) < 15); p = info->name; d = info->short_name; e = info->short_name + 15; /* buffer overflow protection */ if (memcmp(info->name, "SHA", 3) == 0) { strcpy(d, p); for (; *d && d < e; d++) { if ('A' <= *d && *d <= 'Z') { *d |= 0x20; } } } else { for (; *p && d < e; p++) { if (*p != '-' || p[1] >= '9') { *(d++) = (*p | 0x20); } } } *d = 0; } } /** * Initialize printf string according to program options. * The function is called only when a printf format string is not specified * from command line, so it should be constructed from other options. * * @param out a string buffer to place the resulting format string into. */ void init_printf_format(strbuf_t* out) { const char* fmt, *tail = 0; unsigned bit, index = 0; int uppercase; char up_flag; unsigned force_base32_mask = 0; if (!opt.fmt) { /* print SFV header for CRC32 or if no hash sums options specified */ opt.fmt = (opt.sum_flags == RHASH_CRC32 || !opt.sum_flags ? FMT_SFV : FMT_SIMPLE); } uppercase = ((opt.flags & OPT_UPPERCASE) || (!(opt.flags & OPT_LOWERCASE) && (opt.fmt & FMT_SFV))); up_flag = (uppercase ? ~0x20 : 0xFF); rsh_str_ensure_size(out, 1024); /* allocate big enough buffer */ if (opt.sum_flags & OPT_ED2K_LINK) { rsh_str_append_n(out, "%l", 2); out->str[1] &= up_flag; return; } if (opt.sum_flags == 0) return; if (opt.fmt == FMT_BSD) { fmt = "\003(%p) = \001\\n"; } else if (opt.fmt == FMT_MAGNET) { rsh_str_append(out, "magnet:?xl=%s&dn=%{urlname}"); fmt = "&xt=urn:\002:\001"; force_base32_mask = (RHASH_SHA1 | RHASH_BTIH); tail = "\\n"; } else if (opt.fmt == FMT_SIMPLE && 0 == (opt.sum_flags & (opt.sum_flags - 1))) { fmt = "\001 %p\\n"; } else { rsh_str_append_n(out, "%p", 2); fmt = (opt.fmt == FMT_SFV ? " \001" : " \001"); tail = "\\n"; } /* loop by hashes */ for (bit = 1 << index; bit <= opt.sum_flags; bit = bit << 1, index++) { const char *p; print_hash_info *info; if ((bit & opt.sum_flags) == 0) continue; p = fmt; info = &hash_info_table[index]; /* ensure the output buffer have enough space */ rsh_str_ensure_size(out, out->len + 256); for (;;) { int i; while (*p >= 0x20) out->str[out->len++] = *(p++); if (*p == 0) break; switch ((int)*(p++)) { case 1: out->str[out->len++] = '%'; if ( (bit & force_base32_mask) != 0 ) { out->str[out->len++] = 'b'; } if (info->short_char) out->str[out->len++] = info->short_char & up_flag; else { char *letter; out->str[out->len++] = '{'; letter = out->str + out->len; rsh_str_append(out, info->short_name); *letter &= up_flag; out->str[out->len++] = '}'; } break; case 2: rsh_str_append(out, rhash_get_magnet_name(bit)); break; case 3: rsh_str_append(out, info->name); i = (int)strlen(info->name); for (i = (i < 5 ? 6 - i : 1); i > 0; i--) out->str[out->len++] = ' '; break; } } } if (tail) { rsh_str_append(out, tail); } out->str[out->len] = '\0'; } /*========================================================================= * SFV format output functions *=========================================================================*/ /** * Format file information into SFV line and print it to the specified stream. * * @param out the stream to print the file information to * @param file the file info to print * @return 0 on success, -1 on fail with error code stored in errno */ int print_sfv_header_line(FILE* out, file_t* file, const char* printpath) { char buf[24]; /* skip stdin stream */ if ((file->mode & FILE_IFSTDIN) != 0) return 0; #ifdef _WIN32 /* skip file if it can't be opened with exclusive sharing rights */ if (!can_open_exclusive(file->path)) { return 0; } #endif if (!printpath) printpath = file->path; if (printpath[0] == '.' && IS_PATH_SEPARATOR(printpath[1])) printpath += 2; sprintI64(buf, file->size, 12); rsh_fprintf(out, "; %s ", buf); print_time64(out, file->mtime); rsh_fprintf(out, " %s\n", printpath); return 0; } /** * Print an SFV header banner. The banner consist of 3 comment lines, * with the program description and current time. * * @param out a stream to print to */ void print_sfv_banner(FILE* out) { time_t cur_time = time(NULL); struct tm *t = localtime(&cur_time); if (t) { rsh_fprintf(out, _("; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n"), PROGRAM_NAME, get_version_string(), (1900 + t->tm_year), t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec); rsh_fprintf(out, _("; Written by Kravchenko Aleksey (Akademgorodok) - http://rhash.sf.net/\n;\n")); } } RHash-1.3.6/hash_print.h000066400000000000000000000022621325207677100150520ustar00rootroot00000000000000/* hash_print.h - functions to print hash sums */ #ifndef HASH_PRINT_H #define HASH_PRINT_H #include #ifdef __cplusplus extern "C" { #endif /** * An element of a list specifying an output format. */ typedef struct print_item { struct print_item *next; unsigned flags; unsigned hash_id; unsigned width; const char *data; } print_item; /** * Name and other info of a hash function */ typedef struct print_hash_info { char short_name[16]; char short_char; const char *name; } print_hash_info; extern print_hash_info hash_info_table[]; struct file_info; struct file_t; struct strbuf_t; /* initialization of static data */ void init_hash_info_table(void); void init_printf_format(struct strbuf_t* out); /* formatted output of hash sums and file information */ print_item* parse_print_string(const char* format, unsigned *sum_mask); void print_line(FILE* out, print_item* list, struct file_info *info); void free_print_list(print_item* list); /* SFV format functions */ void print_sfv_banner(FILE* out); int print_sfv_header_line(FILE* out, struct file_t* file, const char* printpath); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* HASH_PRINT_H */ RHash-1.3.6/hash_update.c000066400000000000000000000221511325207677100151720ustar00rootroot00000000000000/* hash_update.c - functions to update a crc file */ #include #include #include /* for qsort */ #include #ifndef _WIN32 # include #endif #include "calc_sums.h" #include "common_func.h" #include "file.h" #include "file_set.h" #include "file_mask.h" #include "hash_print.h" #include "hash_update.h" #include "output.h" #include "parse_cmdline.h" #include "rhash_main.h" #include "win_utils.h" /* first define some internal functions, implemented later in this file */ static int add_new_crc_entries(file_t* file, file_set *crc_entries); static int file_set_load_from_crc_file(file_set *set, file_t* file); static int fix_sfv_header(file_t* file); /** * Update given crc file, by adding to it hashes of files from the same * directory, but which the crc file doesn't contain yet. * * @param file the file containing hash sums * @return 0 on success, -1 on fail */ int update_hash_file(file_t* file) { file_set* crc_entries; timedelta_t timer; int res; if (opt.flags & OPT_VERBOSE) { log_msg(_("Updating: %s\n"), file->path); } crc_entries = file_set_new(); res = file_set_load_from_crc_file(crc_entries, file); if (opt.flags & OPT_SPEED) rsh_timer_start(&timer); rhash_data.total_size = 0; rhash_data.processed = 0; if (res == 0) { /* add the crc file itself to the set of excluded from re-calculation files */ file_set_add_name(crc_entries, get_basename(file->path)); file_set_sort(crc_entries); /* update crc file with sums of files not present in the crc_entries */ res = add_new_crc_entries(file, crc_entries); } file_set_free(crc_entries); if (opt.flags & OPT_SPEED && rhash_data.processed > 0) { double time = rsh_timer_stop(&timer); print_time_stats(time, rhash_data.total_size, 1); } return res; } /** * Load a set of files from given crc file. * * @param set the file set to store loaded files * @param file the file containing hash sums to load * @return 0 on success, -1 on fail with error code in errno */ static int file_set_load_from_crc_file(file_set *set, file_t* file) { FILE *fd; int line_num; char buf[2048]; hash_check hc; if ( !(fd = file_fopen(file, FOpenRead | FOpenBin) )) { /* if file not exist, it will be created */ return (errno == ENOENT ? 0 : -1); } for (line_num = 0; fgets(buf, 2048, fd); line_num++) { char* line = buf; /* skip unicode BOM */ if (line_num == 0 && buf[0] == (char)0xEF && buf[1] == (char)0xBB && buf[2] == (char)0xBF) line += 3; if (*line == 0) continue; /* skip empty lines */ if (is_binary_string(line)) { log_error(_("skipping binary file %s\n"), file->path); fclose(fd); return -1; } if (IS_COMMENT(*line) || *line == '\r' || *line == '\n') continue; /* parse a hash file line */ if (hash_check_parse_line(line, &hc, !feof(fd))) { /* store file info to the file set */ if (hc.file_path) file_set_add_name(set, hc.file_path); } } fclose(fd); return 0; } /** * Add hash sums of files from given file-set to a specified hash-file. * A specified directory path will be prepended to the path of added files, * if it is not a current directory. * * @param file the hash file to add the hash sums to * @param dir_path the directory path to prepend * @param files_to_add the set of files to hash and add * @return 0 on success, -1 on error */ static int add_sums_to_file(file_t* file, char* dir_path, file_set *files_to_add) { FILE* fd; unsigned i; int ch; /* SFV banner will be printed only in SFV mode and only for empty crc files */ int print_banner = (opt.fmt == FMT_SFV); file->size = 0; if (file_stat(file, 0) == 0) { if (print_banner && file->size > 0) print_banner = 0; } /* open the hash file for writing */ if ( !(fd = file_fopen(file, FOpenRead | FOpenWrite) )) { log_file_t_error(file); return -1; } rhash_data.upd_fd = fd; if (file->size > 0) { /* read the last character of the file to check if it is EOL */ if (fseek(fd, -1, SEEK_END) != 0) { log_file_t_error(file); return -1; } ch = fgetc(fd); /* somehow writing doesn't work without seeking */ if (fseek(fd, 0, SEEK_END) != 0) { log_file_t_error(file); return -1; } /* write EOL if it wasn't present */ if (ch != '\n' && ch != '\r') { /* fputc('\n', fd); */ rsh_fprintf(fd, "\n"); } } /* append hash sums to the updated crc file */ for (i = 0; i < files_to_add->size; i++, rhash_data.processed++) { file_t file; char *print_path = file_set_get(files_to_add, i)->filepath; memset(&file, 0, sizeof(file)); if (dir_path[0] != '.' || dir_path[1] != 0) { /* prepend the file path by directory path */ file_init(&file, make_path(dir_path, print_path), 0); } else { file_init(&file, print_path, FILE_OPT_DONT_FREE_PATH); } if (opt.fmt == FMT_SFV) { if (print_banner) { print_sfv_banner(fd); print_banner = 0; } } file_stat(&file, 0); /* print hash sums to the crc file */ calculate_and_print_sums(fd, &file, print_path); file_cleanup(&file); if (rhash_data.interrupted) { fclose(fd); return 0; } } fclose(fd); log_msg(_("Updated: %s\n"), file->path); return 0; } /** * Read a directory and load files not present in the crc_entries file-set * into the files_to_add file-set. * * @param dir_path the path of the directory to load files from * @param crc_entries file-set of files which should be skipped * @param files_to_add file-set to load the list of files into * @return 0 on success, -1 on error (and errno is set) */ static int load_filtered_dir(const char* dir_path, file_set *crc_entries, file_set *files_to_add) { DIR *dp; struct dirent *de; /* read directory */ dp = opendir(dir_path); if (!dp) return -1; while ((de = readdir(dp)) != NULL) { char *path; unsigned is_regular; /* skip "." and ".." directories */ if (de->d_name[0] == '.' && (de->d_name[1] == 0 || (de->d_name[1] == '.' && de->d_name[2] == 0))) { continue; } /* check if the file is a regular one */ path = make_path(dir_path, de->d_name); is_regular = is_regular_file(path); free(path); /* skip non-regular files (directories, device files, e.t.c.), * as well as files not accepted by current file filter * and files already present in the crc_entries file set */ if (!is_regular || !file_mask_match(opt.files_accept, de->d_name) || (opt.files_exclude && file_mask_match(opt.files_exclude, de->d_name)) || file_set_exist(crc_entries, de->d_name)) { continue; } file_set_add_name(files_to_add, de->d_name); } return 0; } /** * Calculate and add to the given hash-file the hash-sums for all files * from the same directory as the hash-file, but absent from given * crc_entries file-set. * *

If SFV format was specified by a command line switch, the after adding * hash sums SFV header of the file is fixed by moving all lines starting * with a semicolon before other lines. So an SFV-formatted hash-file * will remain correct. * * @param file the hash-file to add sums into * @param crc_entries file-set of files to omit from adding * @return 0 on success, -1 on error */ static int add_new_crc_entries(file_t* file, file_set *crc_entries) { file_set* files_to_add; char* dir_path; int res = 0; dir_path = get_dirname(file->path); files_to_add = file_set_new(); /* load into files_to_add files from directory not present in the crc_entries */ load_filtered_dir(dir_path, crc_entries, files_to_add); if (files_to_add->size > 0) { /* sort files by path */ file_set_sort_by_path(files_to_add); /* calculate and write crc sums to the file */ res = add_sums_to_file(file, dir_path, files_to_add); if (res == 0 && opt.fmt == FMT_SFV && !rhash_data.interrupted) { /* move SFV header from the end of updated file to its head */ res = fix_sfv_header(file); } } file_set_free(files_to_add); free(dir_path); return res; } /** * Move all SFV header lines (i.e. all lines starting with a semicolon) * from the end of updated file to its head. * * @param file the hash file requiring fixing of its SFV header */ static int fix_sfv_header(file_t* file) { FILE* in; FILE* out; char line[2048]; file_t new_file; int err = 0; if ( !(in = file_fopen(file, FOpenRead))) { log_file_t_error(file); return -1; } /* open a temporary file for writing */ file_path_append(&new_file, file, ".new"); if ( !(out = file_fopen(&new_file, FOpenWrite) )) { log_file_t_error(&new_file); file_cleanup(&new_file); fclose(in); return -1; } /* The first, output all commented lines to the file header */ while (fgets(line, 2048, in)) { if (*line == ';') { if (fputs(line, out) < 0) break; } } if (!ferror(out) && !ferror(in)) { fseek(in, 0, SEEK_SET); /* The second, output non-commented lines */ while (fgets(line, 2048, in)) { if (*line != ';') { if (fputs(line, out) < 0) break; } } } if (ferror(in)) { log_file_t_error(file); err = 1; } if (ferror(out)) { log_file_t_error(&new_file); err = 1; } fclose(in); fclose(out); /* overwrite the hash file with a new one */ if (!err && file_rename(&new_file, file) < 0) { log_error(_("can't move %s to %s: %s\n"), new_file.path, file->path, strerror(errno)); } file_cleanup(&new_file); return (err ? -1 : 0); } RHash-1.3.6/hash_update.h000066400000000000000000000004121325207677100151730ustar00rootroot00000000000000/* hash_update.h - functions to update a crc file */ #ifndef HASH_UPDATE_H #define HASH_UPDATE_H #ifdef __cplusplus extern "C" { #endif int update_hash_file(file_t* file); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* HASH_UPDATE_H */ RHash-1.3.6/librhash/000077500000000000000000000000001325207677100143345ustar00rootroot00000000000000RHash-1.3.6/librhash/Doxyfile000066400000000000000000001776521325207677100160640ustar00rootroot00000000000000# Doxyfile 1.6.3 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = 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 = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = 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 cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it parses. # With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this tag. # The format is ext=language, where ext is a file extension, and language is one of # the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP, # Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. Note that for custom extensions you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen 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. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penality. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will rougly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols SYMBOL_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the (brief and detailed) documentation of class members so that constructors and destructors are listed first. If set to NO (the default) the constructors will appear in the respective orders defined by SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by # doxygen. The layout file controls the global structure of the generated output files # in an output format independent way. The create the layout file that represents # doxygen's defaults, run doxygen with the -l option. You can optionally specify a # file name after the option, if omitted DoxygenLayout.xml will be used as the name # of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = rhash.h rhash.c rhash_timing.h rhash_timing.c # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER # are set, an additional index file will be generated that can be used as input for # Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated # HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add. # For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's # filter section matches. # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, # and Class Hierarchy pages using a tree view instead of an ordered list. USE_INLINE_TREES = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # When the SEARCHENGINE tag is enabled doxygen will generate a search box for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be implemented using a PHP enabled web server instead of at the web client using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server based approach is that it scales better to large projects and allows full text search. The disadvances is that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = 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. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include source code with syntax highlighting in the LaTeX output. Note that which sources are shown also depends on other settings such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all 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. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES RHash-1.3.6/librhash/Makefile000066400000000000000000000150721325207677100160010ustar00rootroot00000000000000# Makefile for LibRHash include config.mak HEADERS = algorithms.h byte_order.h plug_openssl.h rhash.h rhash_timing.h rhash_torrent.h aich.h crc32.h ed2k.h edonr.h hex.h md4.h md5.h sha1.h sha256.h sha512.h sha3.h ripemd-160.h gost.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_timing.c rhash_torrent.c aich.c crc32.c ed2k.c edonr.c hex.c md4.c md5.c sha1.c sha256.c sha512.c sha3.c ripemd-160.c gost.c has160.c snefru.c tiger.c tiger_sbox.c tth.c torrent.c whirlpool.c whirlpool_sbox.c OBJECTS = algorithms.o byte_order.o plug_openssl.o rhash.o rhash_timing.o rhash_torrent.o aich.o crc32.o ed2k.o edonr.o hex.o md4.o md5.o sha1.o sha256.o sha512.o sha3.o ripemd-160.o gost.o has160.o snefru.o tiger.o tiger_sbox.o tth.o torrent.o whirlpool.o whirlpool_sbox.o LIB_HEADERS = rhash.h rhash_torrent.h SO_HEADERS = $(LIB_HEADERS) $(LEGACY_HEADERS) TEST_STATIC = test_static$(EXEC_EXT) TEST_SHARED = test_shared$(EXEC_EXT) INSTALL_DATA = $(INSTALL) -m 644 INSTALL_SHARED = $(INSTALL) -m 644 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-headers $(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)/ install-implib: $(INSTALL) -d $(LIBDIR) $(INSTALL_SHARED) $(LIBRHASH_IMPLIB) $(LIBDIR)/ install-so-link: $(INSTALL) -d $(LIBDIR) ln -s $(LIBRHASH_SHARED) $(LIBDIR)/$(LIBRHASH_SOLINK) uninstall-lib-static: uninstall-headers rm -f $(LIBDIR)/$(LIBRHASH_STATIC) uninstall-lib-shared: $(EXTRA_UNINSTALL_LIBSHARED) rm -f $(LIBDIR)/$(LIBRHASH_SHARED) uninstall-implib: rm -f $(LIBDIR)/$(IMPLIBNAME) uninstall-so-link: rm -f $(LIBDIR)/$(LIBRHASH_SOLINK) install-headers: $(INSTALL) -d $(INCDIR) $(INSTALL_DATA) $(LIB_HEADERS) $(INCDIR)/ uninstall-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 byte_order.h ustd.h algorithms.h rhash.h aich.h sha1.h $(CC) -c $(CFLAGS) $< -o $@ algorithms.o: algorithms.c byte_order.h ustd.h rhash.h algorithms.h \ aich.h sha1.h crc32.h ed2k.h md4.h edonr.h gost.h has160.h md5.h \ ripemd-160.h snefru.h sha256.h sha512.h sha3.h tiger.h torrent.h tth.h \ whirlpool.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 $@ gost.o: gost.c byte_order.h ustd.h gost.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 $(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 algorithms.h rhash.h byte_order.h ustd.h \ plug_openssl.h $(CC) -c $(CFLAGS) $< -o $@ rhash.o: rhash.c byte_order.h ustd.h algorithms.h rhash.h torrent.h \ sha1.h plug_openssl.h util.h hex.h $(CC) -c $(CFLAGS) $< -o $@ rhash_timing.o: rhash_timing.c byte_order.h ustd.h rhash.h rhash_timing.h $(CC) -c $(CFLAGS) $< -o $@ rhash_torrent.o: rhash_torrent.c algorithms.h rhash.h byte_order.h ustd.h \ torrent.h sha1.h rhash_torrent.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 $@ 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_hashes.o: test_hashes.c byte_order.h ustd.h rhash_timing.h \ rhash_torrent.h rhash.h test_hashes.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 byte_order.h ustd.h algorithms.h rhash.h hex.h \ torrent.h sha1.h $(CC) -c $(CFLAGS) $< -o $@ tth.o: tth.c byte_order.h ustd.h tth.h tiger.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): $(SO_HEADERS) sed -ne '1s/.*/{ global:/p; s/^RHASH_API.* \(rhash_[a-z0-9_]*\)(.*/ \1;/p; $$s/.*/local: *; };/p' $(SO_HEADERS) > $@ $(LIBRHASH_SOLINK): rm -f $(LIBRHASH_SOLINK) ln -s $(LIBRHASH_SHARED) $(LIBRHASH_SOLINK) $(LIBRHASH_SHARED): $(SOURCES) $(EXPORTS_TARGET) $(SOLINK_TARGET) $(CC) $(SHARED_CFLAGS) $(SOURCES) $(SHARED_LDFLAGS) -o $@ # build static library $(LIBRHASH_STATIC): $(OBJECTS) $(AR) cqs $@ $(OBJECTS) # test targets $(TEST_SHARED): $(LIBRHASH_SHARED) test_hashes.o $(CC) $(CFLAGS) test_hashes.o $(LIBRHASH_SHARED) $(LDFLAGS) -o $@ $(TEST_STATIC): $(LIBRHASH_STATIC) test_hashes.o $(CC) $(CFLAGS) test_hashes.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-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-headers \ uninstall-lib uninstall-lib-shared uninstall-lib-static uninstall-so-link \ install-implib uninstall-implib RHash-1.3.6/librhash/aich.c000066400000000000000000000322311325207677100154050ustar00rootroot00000000000000/* aich.c - an implementation of EMule AICH Algorithm. * Description: http://www.amule.org/wiki/index.php/AICH. * * Copyright: 2008-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! * * 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 #include #include #include "byte_order.h" #include "algorithms.h" #include "aich.h" #define ED2K_CHUNK_SIZE 9728000 #define FULL_BLOCK_SIZE 184320 #define LAST_BLOCK_SIZE 143360 #define BLOCKS_PER_CHUNK 53 /* * The Algorithm could be a little faster if it knows a * hashed message size beforehand. This would allow * to build balanced tree while hashing the message. * * But this AICH implementation works with unknown * message size like other well-known hash algorithms * (it was fun to write a such one). * So, it just stores sha1 hashes and builds balanced tree * only on the last step, when the full message processed * and its size is already known. */ #ifdef USE_OPENSSL #define SHA1_INIT(ctx) ((pinit_t)ctx->sha_init)(&ctx->sha1_context) #define SHA1_UPDATE(ctx, msg, size) ((pupdate_t)ctx->sha_update)(&ctx->sha1_context, (msg), (size)) #define SHA1_FINAL(ctx, result) ((pfinal_t)ctx->sha_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 /** * Initialize algorithm context before calculaing hash. * * @param ctx context to initialize */ void rhash_aich_init(aich_ctx *ctx) { memset(ctx, 0, sizeof(aich_ctx)); #ifdef USE_OPENSSL { rhash_hash_info *sha1_info = &rhash_info_table[3]; assert(sha1_info->info->hash_id == RHASH_SHA1); assert(sha1_info->context_size <= (sizeof(sha1_ctx) + sizeof(unsigned long))); ctx->sha_init = sha1_info->init; ctx->sha_update = sha1_info->update; ctx->sha_final = sha1_info->final; } #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(sizeof(hash_pair_t) == 40); assert(sizeof(hash_pairs_group_t) == (40 * CT_GROUP_SIZE)); /* 10KiB */ assert(CT_GROUP_SIZE == 256); assert(CT_INDEX(chunk_num) == 0); /* 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); assert(index == ctx->allocated); /* re-allocate the chunk table to contain new_size void*-pointers */ ctx->chunk_table = (void**)realloc(ctx->chunk_table, new_size * sizeof(void*)); if (ctx->chunk_table == 0) { ctx->error = 1; return; } memset(ctx->chunk_table + ctx->allocated, 0, (new_size - ctx->allocated) * sizeof(void*)); 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_number + 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_number : (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(BLOCKS_PER_CHUNK * sha1_hash_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_number) == 0) { rhash_aich_chunk_table_extend(ctx, (unsigned)ctx->chunks_number); 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_number); /* small optimization: skip a left-branch-hash for the last chunk */ if (!(type & AICH_PROCESS_FINAL_BLOCK) || ctx->chunks_number == 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_number > 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 whole ed2k chunk was processed */ ctx->chunks_number++; } } /** * 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_number * ED2K_CHUNK_SIZE) + ctx->index; unsigned char* const hash = (unsigned char*)ctx->sha1_context.hash; if (ctx->chunks_number == 0 && ctx->block_hashes == NULL) { assert(ctx->index < FULL_BLOCK_SIZE); #ifdef 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_number == 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_number > 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); } RHash-1.3.6/librhash/aich.h000066400000000000000000000023701325207677100154130ustar00rootroot00000000000000/* aich.h */ #ifndef AICH_H #define AICH_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 */ void *sha_init, *sha_update, *sha_final; #endif unsigned index; /* algorithm position in the current ed2k chunk */ unsigned char (*block_hashes)[sha1_hash_size]; void** chunk_table; /* table of chunk hashes */ size_t allocated; /* allocated size of the chunk_table */ size_t chunks_number; /* number of ed2k chunks hashed */ int error; /* non-zero if a memory error occurred, 0 otherwise */ } 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]); /* 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.3.6/librhash/algorithms.c000066400000000000000000000222451325207677100166560ustar00rootroot00000000000000/* algorithms.c - the algorithms supported by the rhash library * * Copyright: 2011-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include #include "byte_order.h" #include "rhash.h" #include "algorithms.h" /* header files of all supported hash sums */ #include "aich.h" #include "crc32.h" #include "ed2k.h" #include "edonr.h" #include "gost.h" #include "has160.h" #include "md4.h" #include "md5.h" #include "ripemd-160.h" #include "snefru.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 /* note: BTIH and AICH depends on the used SHA1 algorithm */ # define NEED_OPENSSL_INIT (RHASH_MD4 | RHASH_MD5 | \ RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | \ RHASH_BTIH | RHASH_AICH | RHASH_RIPEMD160 | RHASH_WHIRLPOOL) #else # define NEED_OPENSSL_INIT 0 #endif /* USE_OPENSSL */ #ifdef GENERATE_GOST_LOOKUP_TABLE # define NEED_GOST_INIT (RHASH_GOST | RHASH_GOST_CRYPTOPRO) #else # define NEED_GOST_INIT 0 #endif /* GENERATE_GOST_LOOKUP_TABLE */ #ifdef GENERATE_CRC32_TABLE # define NEED_CRC32_INIT RHASH_CRC32 #else # define NEED_CRC32_INIT 0 #endif /* GENERATE_CRC32_TABLE */ #define RHASH_NEED_INIT_ALG (NEED_CRC32_INIT | NEED_GOST_INIT | NEED_OPENSSL_INIT) unsigned rhash_uninitialized_algorithms = RHASH_NEED_INIT_ALG; 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); rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" }; rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" }; rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" }; rhash_info info_sha1 = { RHASH_SHA1, F_BE32, 20, "SHA1", "sha1" }; rhash_info info_tiger = { RHASH_TIGER, F_LE64, 24, "TIGER", "tiger" }; rhash_info info_tth = { RHASH_TTH, F_BS32, 24, "TTH", "tree:tiger" }; rhash_info info_btih = { RHASH_BTIH, 0, 20, "BTIH", "btih" }; rhash_info info_ed2k = { RHASH_ED2K, F_LE32, 16, "ED2K", "ed2k" }; rhash_info info_aich = { RHASH_AICH, F_BS32, 20, "AICH", "aich" }; rhash_info info_whirlpool = { RHASH_WHIRLPOOL, F_BE64, 64, "WHIRLPOOL", "whirlpool" }; rhash_info info_rmd160 = { RHASH_RIPEMD160, F_LE32, 20, "RIPEMD-160", "ripemd160" }; rhash_info info_gost = { RHASH_GOST, F_LE32, 32, "GOST", "gost" }; rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "GOST-CRYPTOPRO", "gost-cryptopro" }; rhash_info info_has160 = { RHASH_HAS160, F_LE32, 20, "HAS-160", "has160" }; rhash_info info_snf128 = { RHASH_SNEFRU128, F_BE32, 16, "SNEFRU-128", "snefru128" }; rhash_info info_snf256 = { RHASH_SNEFRU256, F_BE32, 32, "SNEFRU-256", "snefru256" }; rhash_info info_sha224 = { RHASH_SHA224, F_BE32, 28, "SHA-224", "sha224" }; rhash_info info_sha256 = { RHASH_SHA256, F_BE32, 32, "SHA-256", "sha256" }; rhash_info info_sha384 = { RHASH_SHA384, F_BE64, 48, "SHA-384", "sha384" }; rhash_info info_sha512 = { RHASH_SHA512, F_BE64, 64, "SHA-512", "sha512" }; rhash_info info_edr256 = { RHASH_EDONR256, F_LE32, 32, "EDON-R256", "edon-r256" }; rhash_info info_edr512 = { RHASH_EDONR512, F_LE64, 64, "EDON-R512", "edon-r512" }; rhash_info info_sha3_224 = { RHASH_SHA3_224, F_LE64, 28, "SHA3-224", "sha3-224" }; rhash_info info_sha3_256 = { RHASH_SHA3_256, F_LE64, 32, "SHA3-256", "sha3-256" }; rhash_info info_sha3_384 = { RHASH_SHA3_384, F_LE64, 48, "SHA3-384", "sha3-384" }; rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512" }; /* some helper macros */ #define dgshft(name) (((char*)&((name##_ctx*)0)->hash) - (char*)0) #define dgshft2(name, field) (((char*)&((name##_ctx*)0)->field) - (char*)0) #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 diuf(name) dgshft(name), ini(name), upd(name), fin(name) /* information about all hashes */ rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] = { { &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_gost, sizeof(gost_ctx), dgshft(gost), iuf(rhash_gost), 0 }, /* 256 bit */ { &info_gostpro, sizeof(gost_ctx), dgshft(gost), ini(rhash_gost_cryptopro), upd(rhash_gost), fin(rhash_gost), 0 }, /* 256 bit */ { &info_has160, sizeof(has160_ctx), dgshft(has160), iuf(rhash_has160), 0 }, /* 160 bit */ { &info_snf128, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru128), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 128 bit */ { &info_snf256, sizeof(snefru_ctx), dgshft(snefru), ini(rhash_snefru256), upd(rhash_snefru), fin(rhash_snefru), 0 }, /* 256 bit */ { &info_sha224, sizeof(sha256_ctx), dgshft(sha256), ini(rhash_sha224), upd(rhash_sha256), fin(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), ini(rhash_sha384), upd(rhash_sha512), fin(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), ini(rhash_sha3_224), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 224 bit */ { &info_sha3_256, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_256), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 256 bit */ { &info_sha3_384, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_384), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 384 bit */ { &info_sha3_512, sizeof(sha3_ctx), dgshft(sha3), ini(rhash_sha3_512), upd(rhash_sha3), fin(rhash_sha3), 0 }, /* 512 bit */ }; /** * Initialize requested algorithms. */ void rhash_init_algorithms(unsigned mask) { (void)mask; /* unused now */ /* verify that RHASH_HASH_COUNT is the index of the major bit of RHASH_ALL_HASHES */ assert(1 == (RHASH_ALL_HASHES >> (RHASH_HASH_COUNT - 1))); #ifdef GENERATE_CRC32_TABLE rhash_crc32_init_table(); #endif #ifdef GENERATE_GOST_LOOKUP_TABLE rhash_gost_init_table(); #endif rhash_uninitialized_algorithms = 0; } /* 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 } RHash-1.3.6/librhash/algorithms.h000066400000000000000000000054421325207677100166630ustar00rootroot00000000000000/* algorithms.h - rhash library algorithms */ #ifndef RHASH_ALGORITHMS_H #define RHASH_ALGORITHMS_H #include /* for ptrdiff_t */ #include "rhash.h" #include "byte_order.h" #ifdef __cplusplus extern "C" { #endif #ifndef RHASH_API /* modifier for RHash library functions */ # define RHASH_API #endif typedef void (*pinit_t)(void*); typedef void (*pupdate_t)(void *ctx, const void* msg, size_t size); typedef void (*pfinal_t)(void*, unsigned char*); typedef void (*pcleanup_t)(void*); /** * 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 { 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; unsigned state; void *callback, *callback_data; void *bt_ctx; rhash_vector_item vector[1]; /* 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 unsigned rhash_uninitialized_algorithms; extern rhash_info info_crc32; 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; /* rhash_info flags */ #define F_BS32 1 /* default output in base32 */ #define F_SWAP32 2 /* Big endian flag */ #define F_SWAP64 4 /* 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(unsigned mask); #if defined(OPENSSL_RUNTIME) && !defined(USE_OPENSSL) # define USE_OPENSSL #endif #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* RHASH_ALGORITHMS_H */ RHash-1.3.6/librhash/byte_order.c000066400000000000000000000126371325207677100166470ustar00rootroot00000000000000/* byte_order.c - byte order related platform dependent routines, * * Copyright: 2008-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include "byte_order.h" #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 trailing bit of a 32-bit number. * This is a plain C equivalent for GCC __builtin_ctz() bit scan. * * @param x the number to process * @return zero-based index of the trailing bit */ 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 */ /** * 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 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | 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++); } } /** * 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 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | 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 == (( (int)((char*)to - (char*)0) | ((char*)from - (char*)0) | 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); } } RHash-1.3.6/librhash/byte_order.h000066400000000000000000000162551325207677100166540ustar00rootroot00000000000000/* 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__) # 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) # 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 #define IS_ALIGNED_32(p) (0 == (3 & ((const char*)(p) - (const char*)0))) #define IS_ALIGNED_64(p) (0 == (7 & ((const char*)(p) - (const char*)0))) #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 #ifndef __STRICT_ANSI__ #define RHASH_INLINE inline #elif defined(__GNUC__) #define RHASH_INLINE __inline__ #else #define RHASH_INLINE #endif /* define rhash_ctz - count traling zero bits */ #if (defined(__GNUC__) && __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) || \ (defined(__clang__) && __has_builtin(__builtin_ctz)) /* GCC >= 3.4 or clang */ # define rhash_ctz(x) __builtin_ctz(x) #else unsigned rhash_ctz(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_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 (defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3)) || \ (defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64)) /* GCC >= 4.3 or clang */ # 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) _byteswap_ulong((unsigned long)x) # define bswap_64(x) _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((to) + (index), (from), (length)) # define le32_copy(to, index, from, length) rhash_swap_copy_str_to_u32((to), (index), (from), (length)) # define be64_copy(to, index, from, length) memcpy((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((to) + (index), (from), (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((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)))) #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* BYTE_ORDER_H */ RHash-1.3.6/librhash/crc32.c000066400000000000000000000151041325207677100154150ustar00rootroot00000000000000/* crc32.c - an implementation of CRC32 hash function * * Copyright: 2006-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "crc32.h" #ifdef GENERATE_CRC32_TABLE unsigned rhash_crc32_table[256]; /** * Initialize global array rhash_crc32_table. The array takes 1 KiB of * the program size, so generating array at run-time can save a little space. */ void rhash_crc32_init_table(void) { unsigned crc, poly; int i, j; poly = 0xEDB88320; for (i = 0; i < 256; i++) { crc = i; for (j = 8; j > 0; j--) { if (crc & 1) crc = (crc >> 1) ^ poly; else crc >>= 1; } rhash_crc32_table[i] = crc; } } #else /* CRC32_GENTABLE */ unsigned rhash_crc32_table[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, }; #endif /* CRC32_GENTABLE */ /** * Calculate CRC32 sum for a null-terminated string. * * @param crcinit intermediate crc32 hash result * @param str the string to process * @return updated crc32 sum */ unsigned rhash_get_crc32_str(unsigned crcinit, const char *str) { return rhash_get_crc32(crcinit, (const unsigned char*)str, strlen(str)); } /** * 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) { register unsigned crc = crcinit ^ 0xFFFFFFFF; const unsigned char *e; /* process not aligned message head */ for (; (3 & (msg - (unsigned char*)0)) && size > 0; msg++, size--) crc = rhash_crc32_table[(crc ^ *msg) & 0xFF] ^ (crc >> 8); /* fast CRC32 calculation of a DWORD-aligned message */ for (e = msg + (size & ~15); msg < e; msg += 16) { crc ^= le2me_32( ((const unsigned *)msg)[0] ); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc ^= le2me_32( ((const unsigned *)msg)[1] ); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc ^= le2me_32( ((const unsigned *)msg)[2] ); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc ^= le2me_32( ((const unsigned *)msg)[3] ); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); crc = rhash_crc32_table[crc & 0xFF] ^ (crc >> 8); } /* process not aligned message tail */ for (e = msg + (size & 15); msg < e; msg++) { crc = rhash_crc32_table[(crc ^ *msg) & 0xFF] ^ (crc >> 8); } return (crc ^ 0xFFFFFFFF); } RHash-1.3.6/librhash/crc32.h000066400000000000000000000007051325207677100154230ustar00rootroot00000000000000/* crc32.h */ #ifndef CRC32_H #define CRC32_H #ifdef __cplusplus extern "C" { #endif /* hash functions */ unsigned rhash_get_crc32(unsigned crcinit, const unsigned char* msg, size_t size); unsigned rhash_get_crc32_str(unsigned crcinit, const char* str); #ifdef GENERATE_CRC32_TABLE void rhash_crc32_init_table(void); /* initialize algorithm static data */ #endif #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* CRC32_H */ RHash-1.3.6/librhash/ed2k.c000066400000000000000000000104621325207677100153300ustar00rootroot00000000000000/* ed2k.c - an implementation of EDonkey 2000 Hash Algorithm. * * Copyright: 2006-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! * * 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 calculaing 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.3.6/librhash/ed2k.h000066400000000000000000000012121325207677100153260ustar00rootroot00000000000000/* 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.3.6/librhash/edonr.c000066400000000000000000000440031325207677100156100ustar00rootroot00000000000000/* edonr.c - an implementation of EDON-R 256/224/384/512 hash functions * * Copyright: 2011-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! * * 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 same or better security. */ #include #include "byte_order.h" #include "edonr.h" /** * Initialize context before calculaing 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 }; memcpy(ctx->u.data256.hash, EDONR256_H0, sizeof(EDONR256_H0)); ctx->length = 0; ctx->digest_length = edonr256_hash_size; } /** * Initialize context before calculaing 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 }; ctx->length = 0; ctx->digest_length = edonr224_hash_size; memcpy(ctx->u.data256.hash, EDONR224_H0, sizeof(EDONR224_H0)); } /** * Initialize context before calculaing 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) }; ctx->length = 0; ctx->digest_length = edonr512_hash_size; memcpy(ctx->u.data512.hash, EDONR512_H0, sizeof(EDONR512_H0)); } /** * Initialize context before calculaing 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) }; ctx->length = 0; ctx->digest_length = edonr224_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 += edonr256_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((char*)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((char*)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.3.6/librhash/edonr.h000066400000000000000000000027071325207677100156220ustar00rootroot00000000000000/* 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.3.6/librhash/gost.c000066400000000000000000001157031325207677100154630ustar00rootroot00000000000000/* gost.c - an implementation of GOST Hash Function * based on the Russian Standard GOST R 34.11-94. * See also RFC 4357. * * Copyright: 2009-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "gost.h" extern unsigned rhash_gost_sbox[4][256]; extern unsigned rhash_gost_sbox_cryptpro[4][256]; /** * Initialize algorithm context before calculaing hash * with test parameters set. * * @param ctx context to initialize */ void rhash_gost_init(gost_ctx *ctx) { memset(ctx, 0, sizeof(gost_ctx)); } /** * Initialize GOST algorithm context with CryptoPro parameter set. * * @param ctx context to initialize */ void rhash_gost_cryptopro_init(gost_ctx *ctx) { rhash_gost_init(ctx); ctx->cryptpro = 1; } #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 /* * 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 GOST_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 GOST_ENCRYPT(result, i, key, hash, sbox) \ r = hash[i], l = hash[i + 1]; \ GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \ GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \ GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \ GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \ GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \ GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \ GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \ GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \ GOST_ENCRYPT_ROUND(key[0], key[1], sbox) \ GOST_ENCRYPT_ROUND(key[2], key[3], sbox) \ GOST_ENCRYPT_ROUND(key[4], key[5], sbox) \ GOST_ENCRYPT_ROUND(key[6], key[7], sbox) \ GOST_ENCRYPT_ROUND(key[7], key[6], sbox) \ GOST_ENCRYPT_ROUND(key[5], key[4], sbox) \ GOST_ENCRYPT_ROUND(key[3], key[2], sbox) \ GOST_ENCRYPT_ROUND(key[1], key[0], sbox) \ result[i] = l, result[i + 1] = r; #else /* USE_GCC_ASM_IA32 */ /* a faster x86 version of GOST_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 GOST_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_gost_block_compress(gost_ctx *ctx, const unsigned* block) { unsigned i; unsigned key[8], u[8], v[8], w[8], s[8]; unsigned *sbox = (ctx->cryptpro ? (unsigned*)rhash_gost_sbox_cryptpro : (unsigned*)rhash_gost_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; GOST_ENCRYPT(s, i, key, ctx->hash, sbox); } #else /* USE_GCC_ASM_IA32 */ __asm __volatile( "movl %%ebx, %13\n\t" GOST_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_gost_block_compress(). * * @param ctx algorithm context * @param block the 256-bit message block to process */ static void rhash_gost_compute_sum_and_hash(gost_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_gost_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_gost_update(gost_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 = gost_block_size - index; memcpy(ctx->message + index, msg, (size < left ? size : left)); if (size < left) return; /* process partial block */ rhash_gost_compute_sum_and_hash(ctx, (unsigned*)ctx->message); msg += left; size -= left; } while (size >= gost_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, gost_block_size); aligned_message_block = (unsigned*)ctx->message; } rhash_gost_compute_sum_and_hash(ctx, aligned_message_block); msg += gost_block_size; size -= gost_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_gost_final(gost_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_gost_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_gost_block_compress(ctx, msg32); rhash_gost_block_compress(ctx, ctx->sum); /* convert hash state to result bytes */ le32_copy(result, 0, ctx->hash, gost_hash_length); } #ifdef GENERATE_GOST_LOOKUP_TABLE unsigned rhash_gost_sbox[4][256]; unsigned rhash_gost_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_gost_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_gost_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_gost_fill_sbox(rhash_gost_sbox, sbox); rhash_gost_fill_sbox(rhash_gost_sbox_cryptpro, sbox_cryptpro); } #else /* GENERATE_GOST_LOOKUP_TABLE */ /* pre-initialized GOST lookup tables based on rotated S-Box */ unsigned rhash_gost_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_gost_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_GOST_LOOKUP_TABLE */ RHash-1.3.6/librhash/gost.h000066400000000000000000000017111325207677100154610ustar00rootroot00000000000000/* gost.h */ #ifndef GOST_H #define GOST_H #include "ustd.h" #ifdef __cplusplus extern "C" { #endif #define gost_block_size 32 #define gost_hash_length 32 /* algorithm context */ typedef struct gost_ctx { unsigned hash[8]; /* algorithm 256-bit state */ unsigned sum[8]; /* sum of processed message blocks */ unsigned char message[gost_block_size]; /* 256-bit buffer for leftovers */ uint64_t length; /* number of processed bytes */ unsigned cryptpro; /* boolean flag, the type of sbox to use */ } gost_ctx; /* hash functions */ void rhash_gost_init(gost_ctx *ctx); void rhash_gost_cryptopro_init(gost_ctx *ctx); void rhash_gost_update(gost_ctx *ctx, const unsigned char* msg, size_t size); void rhash_gost_final(gost_ctx *ctx, unsigned char result[32]); #ifdef GENERATE_GOST_LOOKUP_TABLE void rhash_gost_init_table(void); /* initialize algorithm static data */ #endif #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* GOST_H */ RHash-1.3.6/librhash/has160.c000066400000000000000000000203421325207677100155030ustar00rootroot00000000000000/* hash.c - an implementation of HAS-160 Algorithm. * * Copyright: 2009-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! * * 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 calculaing hash. * * @param ctx context to initialize */ void rhash_has160_init(has160_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; } /* 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.3.6/librhash/has160.h000066400000000000000000000013011325207677100155020ustar00rootroot00000000000000/* 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.3.6/librhash/hex.c000066400000000000000000000123151325207677100152660ustar00rootroot00000000000000/* hex.c - conversion for hexadecimal and base32 strings. * * Copyright: 2008-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include #include "hex.h" /** * Convert a byte to a hexadecimal number. The result, consisting of two * hexadecimal digits is stored into a buffer. * * @param dest the buffer to receive two symbols of hex representation * @param byte the byte to decode * @param upper_case flag to print string in uppercase * @return pointer to the chararcter just after the written number (dest + 2) */ char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case) { const char add = (upper_case ? 'A' - 10 : 'a' - 10); unsigned char c = (byte >> 4) & 15; *dest++ = (c > 9 ? c + add : c + '0'); c = byte & 15; *dest++ = (c > 9 ? c + add : c + '0'); return dest; } /** * Store hexadecimal representation of a binary string to given buffer. * * @param dest the buffer to receive hexadecimal representation * @param src binary string * @param len string length * @param upper_case flag to print string in uppercase */ void rhash_byte_to_hex(char *dest, const unsigned char *src, unsigned len, int upper_case) { while (len-- > 0) { dest = rhash_print_hex_byte(dest, *src++, upper_case); } *dest = '\0'; } /** * Encode a binary string to base32. * * @param dest the buffer to store result * @param src binary string * @param len string length * @param upper_case flag to print string in uppercase */ void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case) { const char a = (upper_case ? 'A' : 'a'); unsigned shift = 0; unsigned char word; const unsigned char* e = src + len; 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++; } *dest++ = ( word < 26 ? word + a : word + '2' - 26 ); } *dest = '\0'; } /** * Encode a binary string to base64. * Encoded output length is always a multiple of 4 bytes. * * @param dest the buffer to store result * @param src binary string * @param len string length */ void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len) { static const char* tail = "0123456789+/"; unsigned shift = 0; unsigned char word; const unsigned char* e = src + len; 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++; } *dest++ = ( word < 52 ? (word < 26 ? word + 'A' : word - 26 + 'a') : tail[word - 52]); } if (shift > 0) { *dest++ = '='; if (shift == 4) *dest++ = '='; } *dest = '\0'; } /* unsafe characters are "<>{}[]%#/|\^~`@:;?=&+ */ #define IS_GOOD_URL_CHAR(c) (isalnum((unsigned char)c) || strchr("$-_.!'(),", c)) /** * URL-encode a string. * * @param dst buffer to receive result or NULL to calculate * the lengths of encoded string * @param filename the file name * @return the length of the result string */ int rhash_urlencode(char *dst, const char *name) { const char *start; if (!dst) { int len; for (len = 0; *name; name++) len += (IS_GOOD_URL_CHAR(*name) ? 1 : 3); return len; } /* encode URL as specified by RFC 1738 */ for (start = dst; *name; name++) { if ( IS_GOOD_URL_CHAR(*name) ) { *dst++ = *name; } else { *dst++ = '%'; dst = rhash_print_hex_byte(dst, *name, 'A'); } } *dst = 0; return (int)(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], *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.3.6/librhash/hex.h000066400000000000000000000014271325207677100152750ustar00rootroot00000000000000/* 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, unsigned len, int upper_case); void rhash_byte_to_base32(char* dest, const unsigned char* src, unsigned len, int upper_case); void rhash_byte_to_base64(char* dest, const unsigned char* src, unsigned len); char* rhash_print_hex_byte(char *dest, const unsigned char byte, int upper_case); int rhash_urlencode(char *dst, const char *name); 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.3.6/librhash/md4.c000066400000000000000000000145031325207677100151670ustar00rootroot00000000000000/* md4.c - an implementation of MD4 Message-Digest Algorithm based on RFC 1320. * * Copyright: 2007-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "md4.h" /** * Initialize context before calculaing hash. * * @param ctx context to initialize */ void rhash_md4_init(md4_ctx *ctx) { ctx->length = 0; /* 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((char*)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.3.6/librhash/md4.h000066400000000000000000000012711325207677100151720ustar00rootroot00000000000000/* 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.3.6/librhash/md5.c000066400000000000000000000174341325207677100151760ustar00rootroot00000000000000/* md5.c - an implementation of the MD5 algorithm, based on RFC 1321. * * Copyright: 2007-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "md5.h" /** * Initialize context before calculaing hash. * * @param ctx context to initialize */ void rhash_md5_init(md5_ctx *ctx) { ctx->length = 0; /* 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((char*)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.3.6/librhash/md5.h000066400000000000000000000012711325207677100151730ustar00rootroot00000000000000/* 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[16]); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* MD5_HIDER */ RHash-1.3.6/librhash/plug_openssl.c000066400000000000000000000221011325207677100172060ustar00rootroot00000000000000/* plug_openssl.c - plug-in openssl algorithms * * Copyright: 2011-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) #include #include #include #include #include #include #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 #include "algorithms.h" #include "plug_openssl.h" #if defined(OPENSSL_RUNTIME) # if(defined(_WIN32) || defined(__CYGWIN__)) # include # else # include # endif #endif #define OPENSSL_DEFAULT_HASH_MASK (RHASH_MD5 | RHASH_SHA1 | \ RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512) #define PLUGIN_SUPPORTED_HASH_MASK (RHASH_MD4 | RHASH_MD5 | RHASH_SHA1 | \ RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | \ PLUGIN_RIPEMD160 | PLUGIN_WHIRLPOOL) /* the mask of ids of hashing algorithms to use from the OpenSSL library */ unsigned rhash_openssl_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)name##_Init, (pupdate_t)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) WRAP_FINAL2(name, name##_CTX) #define WRAP_FINAL2(name, CTX_TYPE) \ static void wrap##name##_Final(void* ctx, unsigned char* result) { \ CALL_FINAL(name, result, (CTX_TYPE*)ctx); \ } WRAP_FINAL(MD4) WRAP_FINAL(MD5) WRAP_FINAL2(SHA1, SHA_CTX) WRAP_FINAL2(SHA224, SHA256_CTX) WRAP_FINAL(SHA256) WRAP_FINAL2(SHA384, SHA512_CTX) WRAP_FINAL(SHA512) #ifndef OPENSSL_NO_RIPEMD WRAP_FINAL(RIPEMD160) #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); } #endif rhash_info info_sslwhpl = { RHASH_WHIRLPOOL, 0, 64, "WHIRLPOOL", "whirlpool" }; /* The table of supported OpenSSL hash functions */ rhash_hash_info rhash_openssl_methods[] = { { &info_md4, sizeof(MD4_CTX), offsetof(MD4_CTX, A), HASH_INFO_METHODS(MD4) }, /* 128 bit */ { &info_md5, sizeof(MD5_CTX), offsetof(MD5_CTX, A), HASH_INFO_METHODS(MD5) }, /* 128 bit */ { &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 */ #ifndef OPENSSL_NO_RIPEMD { &info_rmd160, sizeof(RIPEMD160_CTX), offsetof(RIPEMD160_CTX, A), HASH_INFO_METHODS(RIPEMD160) }, /* 160 bit */ #else { 0, 0, 0, 0, 0, 0, 0}, #endif #ifndef OPENSSL_NO_WHIRLPOOL { &info_sslwhpl, sizeof(WHIRLPOOL_CTX), offsetof(WHIRLPOOL_CTX, H.c), HASH_INFO_METHODS(WHIRLPOOL) }, /* 512 bit */ #endif }; /* The rhash_openssl_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_openssl_hash_info[RHASH_HASH_COUNT]; #ifdef OPENSSL_RUNTIME #if (defined(_WIN32) || defined(__CYGWIN__)) /* __CYGWIN__ is also defined in MSYS */ #define LOAD_ADDR(n, name) \ p##name##_final = (os_fin_t)GetProcAddress(handle, #name "_Final"); \ rhash_openssl_methods[n].update = (pupdate_t)GetProcAddress(handle, #name "_Update"); \ rhash_openssl_methods[n].init = (rhash_openssl_methods[n].update && p##name##_final ? \ (pinit_t)GetProcAddress(handle, #name "_Init") : 0); #else /* _WIN32 */ #define LOAD_ADDR(n, name) \ p##name##_final = (os_fin_t)dlsym(handle, #name "_Final"); \ rhash_openssl_methods[n].update = (pupdate_t)dlsym(handle, #name "_Update"); \ rhash_openssl_methods[n].init = (rhash_openssl_methods[n].update && p##name##_final ? \ (pinit_t)dlsym(handle, #name "_Init") : 0); #endif /* _WIN32 */ /** * 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; /* suppress the error popup dialogs */ UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); SetErrorMode(oldErrorMode | SEM_FAILCRITICALERRORS); #if defined(_WIN32) handle = LoadLibraryA("libeay32.dll"); #elif defined(__MSYS__) /* MSYS also defines __CYGWIN__ */ handle = LoadLibraryA("msys-crypto-1.0.0.dll"); #elif defined(__CYGWIN__) handle = LoadLibraryA("cygcrypto-1.0.0.dll"); #endif SetErrorMode(oldErrorMode); /* restore error mode */ #else void* handle = dlopen("libcrypto.so", RTLD_NOW); if (!handle) handle = dlopen("libcrypto.so.1.1", RTLD_NOW); if (!handle) handle = dlopen("libcrypto.so.1.0.2", RTLD_NOW); if (!handle) handle = dlopen("libcrypto.so.1.0.0", RTLD_NOW); if (!handle) handle = dlopen("libcrypto.so.0.9.8", RTLD_NOW); #endif if (handle == NULL) return 0; /* could not load OpenSSL */ LOAD_ADDR(0, MD4) LOAD_ADDR(1, MD5); LOAD_ADDR(2, SHA1); LOAD_ADDR(3, SHA224); LOAD_ADDR(4, SHA256); LOAD_ADDR(5, SHA384); LOAD_ADDR(6, SHA512); #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; unsigned bit_index; assert(rhash_info_size <= RHASH_HASH_COUNT); /* buffer-overflow protection */ if ( (rhash_openssl_hash_mask & RHASH_OPENSSL_SUPPORTED_HASHES) == 0) { return 1; /* do not load OpenSSL */ } #ifdef OPENSSL_RUNTIME if (!load_openssl_runtime()) return 0; #endif memcpy(rhash_openssl_hash_info, rhash_info_table, sizeof(rhash_openssl_hash_info)); /* replace internal rhash methods with the OpenSSL ones */ for (i = 0; i < (int)(sizeof(rhash_openssl_methods) / sizeof(rhash_hash_info)); i++) { rhash_hash_info *method = &rhash_openssl_methods[i]; if (!method->init) continue; openssl_available_algorithms_hash_mask |= method->info->hash_id; if ((rhash_openssl_hash_mask & method->info->hash_id) == 0) continue; bit_index = rhash_ctz(method->info->hash_id); assert(method->info->hash_id == rhash_openssl_hash_info[bit_index].info->hash_id); memcpy(&rhash_openssl_hash_info[bit_index], method, sizeof(rhash_hash_info)); } rhash_info_table = rhash_openssl_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; } #else typedef int dummy_declaration_required_by_strict_iso_c; #endif /* defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) */ RHash-1.3.6/librhash/plug_openssl.h000066400000000000000000000013141325207677100172160ustar00rootroot00000000000000/* plug_openssl.h - plug-in openssl algorithms */ #ifndef RHASH_PLUG_OPENSSL_H #define RHASH_PLUG_OPENSSL_H #if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) #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); extern unsigned rhash_openssl_hash_mask; /* mask of hash sums to use */ #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #else # define rhash_get_openssl_supported_hash_mask() (0) # define rhash_get_openssl_available_hash_mask() (0) #endif /* defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) */ #endif /* RHASH_PLUG_OPENSSL_H */ RHash-1.3.6/librhash/rhash.c000066400000000000000000000640641325207677100156170ustar00rootroot00000000000000/* rhash.c - implementation of LibRHash library calls * * Copyright: 2008-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ /* macros for large file support, must be defined before any include file */ #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #include /* memset() */ #include /* free() */ #include /* ptrdiff_t */ #include #include #include /* modifier for Windows DLL */ #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS) # define RHASH_API __declspec(dllexport) #endif #include "byte_order.h" #include "algorithms.h" #include "torrent.h" #include "plug_openssl.h" #include "util.h" #include "hex.h" #include "rhash.h" /* RHash library interface */ #define STATE_ACTIVE 0xb01dbabe #define STATE_STOPED 0xdeadbeef #define STATE_DELETED 0xdecea5ed #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_REVERSE) /** * Initialize static data of rhash algorithms */ void rhash_library_init(void) { rhash_init_algorithms(RHASH_ALL_HASHES); #ifdef USE_OPENSSL rhash_plug_openssl(); #endif } /** * Returns the number of supported hash algorithms. * * @return the number of supported hash functions */ int RHASH_API rhash_count(void) { return rhash_info_size; } /* Lo-level rhash library functions */ /** * Allocate and initialize RHash context for calculating hash(es). * After initializing rhash_update()/rhash_final() functions should be used. * Then the context must be freed by calling rhash_free(). * * @param hash_id union of bit flags, containing ids of hashes to calculate. * @return initialized rhash context, NULL on error and errno is set */ RHASH_API rhash rhash_init(unsigned hash_id) { unsigned tail_bit_index; /* index of hash_id trailing bit */ unsigned num = 0; /* number of hashes to compute */ rhash_context_ext *rctx = NULL; /* allocated rhash context */ size_t hash_size_sum = 0; /* size of hash contexts to store in rctx */ unsigned i, bit_index, id; struct rhash_hash_info* info; size_t aligned_size; char* phash_ctx; hash_id &= RHASH_ALL_HASHES; if (hash_id == 0) { errno = EINVAL; return NULL; } tail_bit_index = rhash_ctz(hash_id); /* get trailing bit index */ assert(tail_bit_index < RHASH_HASH_COUNT); id = 1 << tail_bit_index; if (hash_id == id) { /* handle the most common case of only one hash */ num = 1; info = &rhash_info_table[tail_bit_index]; hash_size_sum = info->context_size; } else { /* another case: hash_id contains several hashes */ for (bit_index = tail_bit_index; id <= hash_id; bit_index++, id = id << 1) { assert(id != 0); assert(bit_index < RHASH_HASH_COUNT); info = &rhash_info_table[bit_index]; if (hash_id & id) { /* align sizes by 8 bytes */ aligned_size = (info->context_size + 7) & ~7; hash_size_sum += aligned_size; num++; } } assert(num > 1); } /* align the size of the rhash context common part */ aligned_size = ((offsetof(rhash_context_ext, vector) + sizeof(rhash_vector_item) * num) + 7) & ~7; assert(aligned_size >= sizeof(rhash_context_ext)); /* allocate rhash context with enough memory to store contexts of all used hashes */ rctx = (rhash_context_ext*)malloc(aligned_size + hash_size_sum); if (rctx == NULL) return NULL; /* initialize common fields of the rhash context */ memset(rctx, 0, sizeof(rhash_context_ext)); rctx->rc.hash_id = hash_id; rctx->flags = RCTX_AUTO_FINAL; /* turn on auto-final by default */ rctx->state = STATE_ACTIVE; rctx->hash_vector_size = num; /* aligned hash contexts follows rctx->vector[num] in the same memory block */ phash_ctx = (char*)rctx + aligned_size; assert(phash_ctx >= (char*)&rctx->vector[num]); /* initialize context for every hash in a loop */ for (bit_index = tail_bit_index, id = 1 << tail_bit_index, i = 0; id <= hash_id; bit_index++, id = id << 1) { /* check if a hash function with given id shall be included into rctx */ if ((hash_id & id) != 0) { info = &rhash_info_table[bit_index]; assert(info->context_size > 0); assert(((phash_ctx - (char*)0) & 7) == 0); /* hash context is aligned */ assert(info->init != NULL); rctx->vector[i].hash_info = info; rctx->vector[i].context = phash_ctx; /* BTIH initialization is complex, save pointer for later */ if ((id & RHASH_BTIH) != 0) rctx->bt_ctx = phash_ctx; phash_ctx += (info->context_size + 7) & ~7; /* initialize the i-th hash context */ info->init(rctx->vector[i].context); i++; } } return &rctx->rc; /* return allocated and initialized rhash context */ } /** * Free RHash context memory. * * @param ctx the context to free. */ void rhash_free(rhash ctx) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; unsigned i; if (ctx == 0) return; assert(ectx->hash_vector_size <= RHASH_HASH_COUNT); 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++) { struct rhash_hash_info* info = ectx->vector[i].hash_info; if (info->cleanup != 0) { info->cleanup(ectx->vector[i].context); } } free(ectx); } /** * 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) { 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); ectx->state = STATE_ACTIVE; /* re-activate the structure */ /* re-initialize every hash in a loop */ for (i = 0; i < ectx->hash_vector_size; i++) { 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 */ } /** * Calculate hashes 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; On fail return -1 and set errno */ 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++) { 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 */ } /** * Finalize hash calculation and optionally store the first hash. * * @param ctx the rhash context * @param first_result optional buffer to store a calculated hash with the lowest available id * @return 0 on success; On fail return -1 and set errno */ 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++) { 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 */ } /** * Store digest for given hash_id. * If hash_id is zero, function stores digest for a hash with the lowest id found in the context. * For nonzero hash_id the context must contain it, otherwise function silently does nothing. * * @param ctx rhash context * @param hash_id id of hash to retrieve or zero for hash with the lowest available id * @param result buffer to put the hash into */ static void rhash_put_digest(rhash ctx, unsigned hash_id, unsigned char* result) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; unsigned i; rhash_vector_item *item; struct rhash_hash_info* info; unsigned char* digest; assert(ectx); assert(ectx->hash_vector_size > 0 && ectx->hash_vector_size <= RHASH_HASH_COUNT); /* finalize context if not yet finalized and auto-final is on */ if ((ectx->flags & RCTX_FINALIZED_MASK) == RCTX_AUTO_FINAL) { rhash_final(ctx, NULL); } if (hash_id == 0) { item = &ectx->vector[0]; /* get the first hash */ info = item->hash_info; } else { for (i = 0;; i++) { if (i >= ectx->hash_vector_size) { return; /* hash_id not found, do nothing */ } item = &ectx->vector[i]; info = item->hash_info; if (info->info->hash_id == hash_id) break; } } 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); } } /** * 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) { ((rhash_context_ext*)ctx)->callback = (void*)callback; ((rhash_context_ext*)ctx)->callback_data = callback_data; } /* hi-level message hashing interface */ /** * Compute a hash of the given message. * * @param hash_id id of hash sum to compute * @param message the message to process * @param length message length * @param result buffer to receive binary hash string * @return 0 on success, -1 on error */ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result) { rhash ctx; hash_id &= RHASH_ALL_HASHES; ctx = rhash_init(hash_id); if (ctx == NULL) return -1; rhash_update(ctx, message, length); rhash_final(ctx, result); rhash_free(ctx); return 0; } /** * Hash a file or stream. Multiple hashes can be computed. * First, inintialize ctx parameter with rhash_init() before calling * rhash_file_update(). Then use rhash_final() and rhash_print() * to retrive hash values. Finaly 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 hash * @return 0 on success, -1 on error and errno is set */ RHASH_API int rhash_file_update(rhash ctx, FILE* fd) { rhash_context_ext* const ectx = (rhash_context_ext*)ctx; const size_t block_size = 8192; unsigned char *buffer, *pmem; size_t length = 0, align8; int res = 0; if (ectx->state != STATE_ACTIVE) return 0; /* do nothing if canceled */ if (ctx == NULL) { errno = EINVAL; return -1; } pmem = (unsigned char*)malloc(block_size + 8); if (!pmem) return -1; /* errno is set to ENOMEM according to UNIX 98 */ align8 = ((unsigned char*)0 - pmem) & 7; buffer = pmem + align8; while (!feof(fd)) { /* stop if canceled */ if (ectx->state != STATE_ACTIVE) break; length = fread(buffer, 1, block_size, fd); if (ferror(fd)) { res = -1; /* note: errno contains error code */ break; } else if (length) { rhash_update(ctx, buffer, length); if (ectx->callback) { ((rhash_callback_t)ectx->callback)(ectx->callback_data, ectx->rc.msg_size); } } } free(buffer); return res; } /** * Compute a single hash for given file. * * @param hash_id id of hash sum to compute * @param filepath path to the file to hash * @param result buffer to receive hash value with the lowest requested id * @return 0 on success, -1 on error and errno is set */ RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result) { FILE* fd; rhash ctx; int res; hash_id &= RHASH_ALL_HASHES; if (hash_id == 0) { errno = EINVAL; return -1; } if ((fd = fopen(filepath, "rb")) == NULL) return -1; if ((ctx = rhash_init(hash_id)) == NULL) { fclose(fd); return -1; } res = rhash_file_update(ctx, fd); /* hash the file */ fclose(fd); rhash_final(ctx, result); rhash_free(ctx); return res; } #ifdef _WIN32 /* windows only function */ #include /** * Compute a single hash for given file. * * @param hash_id id of hash sum to compute * @param filepath path to the file to hash * @param result buffer to receive hash value with the lowest requested id * @return 0 on success, -1 on error, -1 on error and errno is set */ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result) { FILE* fd; rhash ctx; int res; hash_id &= RHASH_ALL_HASHES; if (hash_id == 0) { errno = EINVAL; return -1; } if ((fd = _wfsopen(filepath, L"rb", _SH_DENYWR)) == NULL) return -1; if ((ctx = rhash_init(hash_id)) == NULL) { fclose(fd); return -1; } res = rhash_file_update(ctx, fd); /* hash the file */ fclose(fd); rhash_final(ctx, result); rhash_free(ctx); return res; } #endif /* RHash information functions */ /** * 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_info* rhash_info_by_id(unsigned hash_id) { hash_id &= RHASH_ALL_HASHES; /* check that only one bit is set */ if (hash_id != (hash_id & -(int)hash_id)) return NULL; /* note: alternative condition is (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) */ return rhash_info_table[rhash_ctz(hash_id)].info; } /** * Detect default digest output format for 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) { /* fast method is just to test a bit-mask */ return ((hash_id & (RHASH_TTH | RHASH_AICH)) != 0); } /** * Returns size of binary digest for given hash algorithm. * * @param hash_id the id of hash algorithm * @return digest size in bytes */ RHASH_API int rhash_get_digest_size(unsigned hash_id) { hash_id &= RHASH_ALL_HASHES; if (hash_id == 0 || (hash_id & (hash_id - 1)) != 0) return -1; return (int)rhash_info_table[rhash_ctz(hash_id)].info->digest_size; } /** * Returns length of digest hash string in default output format. * * @param hash_id the id of hash algorithm * @return the length of hash string */ 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); } /** * Returns a name of given hash algorithm. * * @param hash_id the id of hash algorithm * @return algorithm name */ RHASH_API const char* rhash_get_name(unsigned hash_id) { const rhash_info* info = rhash_info_by_id(hash_id); return (info ? info->name : 0); } /** * 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 the id of hash algorithm * @return name */ 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 : 0); } static size_t rhash_get_magnet_url_size(const char* filepath, rhash context, unsigned hash_mask, int flags) { size_t size = 0; /* count terminating '\0' */ unsigned bit, hash = context->hash_id & hash_mask; /* RHPR_NO_MAGNET, RHPR_FILESIZE */ if ((flags & RHPR_NO_MAGNET) == 0) { size += 8; } if ((flags & RHPR_FILESIZE) != 0) { uint64_t num = context->msg_size; size += 4; if (num == 0) size++; else { for (; num; num /= 10, size++); } } if (filepath) { size += 4 + rhash_urlencode(NULL, filepath); } /* loop through hash values */ for (bit = hash & -(int)hash; bit <= hash; bit <<= 1) { const char* name; if ((bit & hash) == 0) continue; if ((name = rhash_get_magnet_name(bit)) == 0) continue; size += (7 + 2) + strlen(name); size += rhash_print(NULL, context, bit, (bit & (RHASH_SHA1 | RHASH_BTIH) ? RHPR_BASE32 : 0)); } return size; } /** * Print magnet link with given filepath and calculated hash sums into the * output buffer. The hash_mask can limit which hash values will be printed. * The function returns the size of the required buffer. * If output is NULL the . * * @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 hash sums 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 */ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, rhash context, unsigned hash_mask, int flags) { int i; const char* begin = output; if (output == NULL) return rhash_get_magnet_url_size( filepath, context, hash_mask, flags); /* 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, context->msg_size); *(output++) = '&'; } if (filepath) { strcpy(output, "dn="); output += 3; output += rhash_urlencode(output, filepath); *(output++) = '&'; } flags &= RHPR_UPPERCASE; for (i = 0; i < 2; i++) { unsigned bit; unsigned hash = context->hash_id & hash_mask; hash = (i == 0 ? hash & (RHASH_ED2K | RHASH_AICH) : hash & ~(RHASH_ED2K | RHASH_AICH)); if (!hash) continue; /* loop through hash values */ for (bit = hash & -(int)hash; bit <= hash; bit <<= 1) { const char* name; if ((bit & hash) == 0) continue; if (!(name = rhash_get_magnet_name(bit))) continue; strcpy(output, "xt=urn:"); output += 7; strcpy(output, name); output += strlen(name); *(output++) = ':'; output += rhash_print(output, context, bit, (bit & (RHASH_SHA1 | RHASH_BTIH) ? flags | RHPR_BASE32 : flags)); *(output++) = '&'; } } output[-1] = '\0'; /* terminate the line */ return (output - begin); } /* hash sum output */ /** * Print a text presentation of a given hash sum to the specified buffer, * * @param output a buffer to print the hash to * @param bytes a hash sum to print * @param size a size of hash sum in bytes * @param flags a bit-mask controlling how to format the hash sum, * can be a mix of the flags: RHPR_RAW, RHPR_HEX, RHPR_BASE32, * RHPR_BASE64, RHPR_UPPERCASE, RHPR_REVERSE * @return the number of written characters */ size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags) { size_t str_len; int upper_case = (flags & RHPR_UPPERCASE); int format = (flags & ~RHPR_MODIFIER); switch (format) { case RHPR_HEX: str_len = size * 2; rhash_byte_to_hex(output, bytes, (unsigned)size, upper_case); break; case RHPR_BASE32: str_len = BASE32_LENGTH(size); rhash_byte_to_base32(output, bytes, (unsigned)size, upper_case); break; case RHPR_BASE64: str_len = BASE64_LENGTH(size); rhash_byte_to_base64(output, bytes, (unsigned)size); break; default: str_len = size; memcpy(output, bytes, size); break; } return str_len; } /** * Print text presentation of a hash sum with given hash_id to the specified * output buffer. If the hash_id is zero, then print the hash sum with * the lowest id stored in the hash context. * The function call fails if the context doesn't include a hash with the * given hash_id. * * @param output a buffer to print the hash to * @param context algorithms state * @param hash_id id of the hash sum to print or 0 to print the first hash * saved in the context. * @param flags a bitmask controlling how to print the hash. Can contain flags * RHPR_UPPERCASE, RHPR_HEX, RHPR_BASE32, RHPR_BASE64, etc. * @return the number of written characters on success or 0 on fail */ size_t RHASH_API rhash_print(char* output, rhash context, unsigned hash_id, int flags) { const rhash_info* info; unsigned char digest[80]; size_t digest_size; info = (hash_id != 0 ? rhash_info_by_id(hash_id) : ((rhash_context_ext*)context)->vector[0].hash_info->info); if (info == NULL) return 0; 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) { 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); default: return digest_size; } } /* note: use info->hash_id, cause hash_id can be 0 */ rhash_put_digest(context, info->hash_id, digest); if ((flags & ~RHPR_UPPERCASE) == (RHPR_REVERSE | RHPR_HEX)) { /* reverse the digest */ unsigned char *p = digest, *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) #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 /** * Process a BitTorrent-related rhash message. * * @param msg_id message identifier * @param bt BitTorrent context * @param ldata data depending on message * @param rdata data depending on message * @return message-specific data */ static rhash_uptr_t process_bt_msg(unsigned msg_id, torrent_ctx* bt, rhash_uptr_t ldata, rhash_uptr_t rdata) { if (bt == NULL) return RHASH_ERROR; switch (msg_id) { case RMSG_BT_ADD_FILE: bt_add_file(bt, (const char*)ldata, *(unsigned long long*)rdata); break; case RMSG_BT_SET_OPTIONS: bt_set_options(bt, (unsigned)ldata); break; case RMSG_BT_SET_ANNOUNCE: bt_add_announce(bt, (const char*)ldata); break; case RMSG_BT_SET_PIECE_LENGTH: bt_set_piece_length(bt, (size_t)ldata); break; case RMSG_BT_SET_BATCH_SIZE: bt_set_piece_length(bt, bt_default_piece_length(*(unsigned long long*)ldata)); break; case RMSG_BT_SET_PROGRAM_NAME: bt_set_program_name(bt, (const char*)ldata); break; case RMSG_BT_GET_TEXT: return (rhash_uptr_t)bt_get_text(bt, (char**)ldata); default: return RHASH_ERROR; /* unknown message */ } return 0; } #define PVOID2UPTR(p) ((rhash_uptr_t)(((char*)(p)) + 0)) /** * Process a rhash 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 */ RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata) { /* for messages working with rhash context */ rhash_context_ext* const ctx = (rhash_context_ext*)dst; switch (msg_id) { case RMSG_GET_CONTEXT: { unsigned i; for (i = 0; i < ctx->hash_vector_size; i++) { struct rhash_hash_info* info = ctx->vector[i].hash_info; if (info->info->hash_id == (unsigned)ldata) return PVOID2UPTR(ctx->vector[i].context); } return (rhash_uptr_t)0; } case RMSG_CANCEL: /* mark rhash context as canceled, in a multithreaded program */ atomic_compare_and_swap(&ctx->state, STATE_ACTIVE, STATE_STOPED); return 0; case RMSG_IS_CANCELED: return (ctx->state == STATE_STOPED); case RMSG_GET_FINALIZED: return ((ctx->flags & RCTX_FINALIZED) != 0); case RMSG_SET_AUTOFINAL: ctx->flags &= ~RCTX_AUTO_FINAL; if (ldata) ctx->flags |= RCTX_AUTO_FINAL; break; /* OpenSSL related messages */ #ifdef USE_OPENSSL case RMSG_SET_OPENSSL_MASK: rhash_openssl_hash_mask = (unsigned)ldata; break; case RMSG_GET_OPENSSL_MASK: return rhash_openssl_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(); /* BitTorrent related messages */ case RMSG_BT_ADD_FILE: case RMSG_BT_SET_OPTIONS: case RMSG_BT_SET_ANNOUNCE: case RMSG_BT_SET_PIECE_LENGTH: case RMSG_BT_SET_PROGRAM_NAME: case RMSG_BT_GET_TEXT: case RMSG_BT_SET_BATCH_SIZE: return process_bt_msg(msg_id, (torrent_ctx*)(((rhash_context_ext*)dst)->bt_ctx), ldata, rdata); default: return RHASH_ERROR; /* unknown message */ } return 0; } RHash-1.3.6/librhash/rhash.h000066400000000000000000000226451325207677100156230ustar00rootroot00000000000000/** @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_GOST = 0x800, RHASH_GOST_CRYPTOPRO = 0x1000, RHASH_HAS160 = 0x2000, RHASH_SNEFRU128 = 0x4000, RHASH_SNEFRU256 = 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, /** The bit-mask containing all supported hashe functions */ RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 | RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO | 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, /** The number of supported hash functions */ RHASH_HASH_COUNT = 26 }; /** * The rhash context structure contains contexts for several hash functions */ typedef struct rhash_context { /** The size of the hashed message */ unsigned long long msg_size; /** * The bit-mask containing identifiers of the hashes being calculated */ unsigned hash_id; } rhash_context; #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); RHASH_API void rhash_library_init(void); /* initialize static data */ /* hi-level hashing functions */ RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result); RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result); RHASH_API int rhash_file_update(rhash ctx, FILE* fd); #ifdef _WIN32 /* windows only function */ RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result); #endif /* lo-level interface */ RHASH_API rhash rhash_init(unsigned hash_id); /*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/ RHASH_API int rhash_update(rhash ctx, const void* message, size_t length); RHASH_API int rhash_final(rhash ctx, unsigned char* first_result); RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */ RHASH_API void rhash_free(rhash ctx); /* additional lo-level functions */ RHASH_API void rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data); /** 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 bit-mask, including RHASH_INFO_BASE32 bit */ unsigned flags; /** size of binary message digest in bytes */ size_t digest_size; const char* name; const char* magnet_name; } rhash_info; /* information functions */ RHASH_API int rhash_count(void); /* number of supported hashes */ RHASH_API int rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */ RHASH_API int rhash_get_hash_length(unsigned hash_id); /* length of formatted hash string */ RHASH_API int rhash_is_base32(unsigned hash_id); /* default digest output format */ RHASH_API const char* rhash_get_name(unsigned hash_id); /* get hash function name */ RHASH_API const char* rhash_get_magnet_name(unsigned hash_id); /* get name part of magnet urn */ /* note, that rhash_info_by_id() is not exported to a shared library or DLL */ const rhash_info* rhash_info_by_id(unsigned hash_id); /* get hash sum info by hash id */ /** * Flags for printing a hash sum */ 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 hash bytes. Can be used for GOST hash. */ 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, }; /* output hash into the given buffer */ RHASH_API size_t rhash_print_bytes(char* output, const unsigned char* bytes, size_t size, int flags); RHASH_API size_t rhash_print(char* output, rhash ctx, unsigned hash_id, int flags); /* output magnet URL into the given buffer */ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath, rhash context, unsigned hash_mask, int flags); /* macros for 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_transmit on error */ #define RHASH_ERROR ((rhash_uptr_t)-1) /** Convert a pointer to rhash_uptr_t */ #define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str)) /** Convert a rhash_uptr_t to a void* pointer */ #define RHASH_UPTR2PVOID(u) ((void*)((u) + 0)) /* rhash API to set/get data via messages */ RHASH_API rhash_uptr_t rhash_transmit( unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata); /* rhash message constants */ #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_SET_OPENSSL_MASK 10 #define RMSG_GET_OPENSSL_MASK 11 #define RMSG_GET_OPENSSL_SUPPORTED_MASK 12 #define RMSG_GET_OPENSSL_AVAILABLE_MASK 13 #define RMSG_BT_ADD_FILE 32 #define RMSG_BT_SET_OPTIONS 33 #define RMSG_BT_SET_ANNOUNCE 34 #define RMSG_BT_SET_PIECE_LENGTH 35 #define RMSG_BT_SET_PROGRAM_NAME 36 #define RMSG_BT_GET_TEXT 37 #define RMSG_BT_SET_BATCH_SIZE 38 /* possible BitTorrent options for the RMSG_BT_SET_OPTIONS message */ #define RHASH_BT_OPT_PRIVATE 1 #define RHASH_BT_OPT_INFOHASH_ONLY 2 /* helper macros */ /** Get a pointer to context of the specified hash function */ #define rhash_get_context_ptr(ctx, hash_id) RHASH_UPTR2PVOID(rhash_transmit(RMSG_GET_CONTEXT, ctx, hash_id, 0)) /** Cancel hash calculation of a file */ #define rhash_cancel(ctx) rhash_transmit(RMSG_CANCEL, ctx, 0, 0) /** Return non-zero if hash calculation was canceled, zero otherwise */ #define rhash_is_canceled(ctx) rhash_transmit(RMSG_IS_CANCELED, ctx, 0, 0) /** Return non-zero if rhash_final was called for rhash_context */ #define rhash_get_finalized(ctx) rhash_transmit(RMSG_GET_FINALIZED, ctx, 0, 0) /** * 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 hash value is retrived by rhash_print call. */ #define rhash_set_autofinal(ctx, on) rhash_transmit(RMSG_SET_AUTOFINAL, ctx, on, 0) /** * Set the bit-mask of hash algorithms to be calculated by OpenSSL library. * The call rhash_set_openssl_mask(0) made before rhash_library_init(), * turns off loading of the OpenSSL dynamic library. * This call works if the LibRHash was compiled with OpenSSL support. */ #define rhash_set_openssl_mask(mask) rhash_transmit(RMSG_SET_OPENSSL_MASK, NULL, mask, 0) /** * Return current bit-mask of hash algorithms selected to be calculated by OpenSSL * library. Return RHASH_ERROR if LibRHash is compiled without OpenSSL support. */ #define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0) /** * Return the bit-mask of algorithms that can be provided by the OpenSSL plugin, * if the library is compiled with OpenSSL support, 0 otherwise. This bit-mask is * a constant value computed at compile-time. */ #define rhash_get_openssl_supported_mask() rhash_transmit(RMSG_GET_OPENSSL_SUPPORTED_MASK, NULL, 0, 0) /** * Return the bit-mask of algorithms that are successfully loaded from * OpenSSL library. If the library is not loaded or not supported by LibRHash, * then return 0. */ #define rhash_get_openssl_available_mask() rhash_transmit(RMSG_GET_OPENSSL_AVAILABLE_MASK, NULL, 0, 0) /** * Return non-zero if LibRHash hash been compiled with OpenSSL support, * and zero otherwise. */ #define rhash_is_openssl_supported() (rhash_get_openssl_mask() != RHASH_ERROR) /** Legacy macro. The bit mask of hash algorithms implemented by OpenSSL */ # define RHASH_OPENSSL_SUPPORTED_HASHES (rhash_get_openssl_supported_mask()) #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* RHASH_H */ RHash-1.3.6/librhash/rhash_timing.c000066400000000000000000000173641325207677100171670ustar00rootroot00000000000000/* rhash_timing.c - functions to benchmark hash algorithms, * * Copyright: 2010-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ /* modifier for Windows dll */ #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(RHASH_EXPORTS) # define RHASH_API __declspec(dllexport) #endif #include "byte_order.h" #include "rhash.h" #include "rhash_timing.h" /* 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__) #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 } /** * Start a timer. * * @deprecated This function shall be removed soon, since * it is not related to the hashing library main functionality. * * @param timer timer to start */ void rhash_timer_start(timedelta_t* timer) { get_timedelta(timer); } /** * Stop given timer. * * @deprecated This function shall be removed soon, since * it is not related to the hashing library main functionality. * * @param timer the timer to stop * @return number of seconds timed */ 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; } /** * Benchmark a hash algorithm. * * @deprecated This function shall be removed soon, since * it is not related to the hashing library main functionality. * * @param hash_id hash algorithm identifier * @param flags benchmark flags, can be RHASH_BENCHMARK_QUIET and RHASH_BENCHMARK_CPB * @param output the stream to print results */ void rhash_run_benchmark(unsigned hash_id, unsigned flags, FILE* output) { unsigned char ALIGN_ATTR(16) 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_GOST | RHASH_GOST_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.3.6/librhash/rhash_timing.h000066400000000000000000000025771325207677100171740ustar00rootroot00000000000000/** @file rhash_timing.h timer and benchmarking functions */ #ifndef RHASH_TIMING_H #define RHASH_TIMING_H /**************************************************************************** * Warning: all functions in this file are deprecated and will be removed * from the library in the future. They are still exported for backward * compatibility. ****************************************************************************/ #ifdef __cplusplus extern "C" { #endif #ifndef RHASH_API /* modifier for LibRHash functions */ # define RHASH_API #endif /* portable timer definition */ #if defined(_WIN32) || defined(__CYGWIN__) typedef unsigned long long timedelta_t; #else #include /* for timeval */ typedef struct timeval timedelta_t; #endif /* timer functions */ RHASH_API void rhash_timer_start(timedelta_t* timer); RHASH_API double rhash_timer_stop(timedelta_t* timer); /* flags for running a benchmark */ /** 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 RHASH_API void rhash_run_benchmark(unsigned hash_id, unsigned flags, FILE* output); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* RHASH_TIMING_H */ RHash-1.3.6/librhash/rhash_torrent.c000066400000000000000000000043511325207677100173650ustar00rootroot00000000000000/* rhash_torrent.c - functions to make a torrent file. * * Copyright: 2013-2014 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include /* modifier for Windows DLL */ #if (defined(_WIN32) || defined(__CYGWIN__) ) && defined(RHASH_EXPORTS) # define RHASH_API __declspec(dllexport) #endif #include "algorithms.h" #include "torrent.h" #include "rhash_torrent.h" /* 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, uint64_t 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(uint64_t total_size) { return bt_default_piece_length(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.3.6/librhash/rhash_torrent.h000066400000000000000000000056661325207677100174040ustar00rootroot00000000000000/* rhash_torrent.h */ #ifndef RHASH_TORRENT_H #define RHASH_TORRENT_H #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 */ #define RHASH_TORRENT_OPT_PRIVATE 1 #define RHASH_TORRENT_OPT_INFOHASH_ONLY 2 /* 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, uint64_t 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(uint64_t total_size); /* * Macro to set a torrent batch size (the total size of files included into this torrent). * It's defined as rhash_torrent_set_piece_length(ctx, rhash_torrent_get_default_piece_length(total_size)) * * @param ctx rhash context * @param total_size total size of files included into the torrent file */ #define rhash_torrent_set_batch_size(ctx, total_size) \ rhash_torrent_set_piece_length((ctx), rhash_torrent_get_default_piece_length(total_size)) /** * Get the content of the generated torrent file. * * @param ctx rhash context * @return binary string with the torrent file content, if successful. * On fail the function returns NULL. */ RHASH_API const rhash_str* rhash_torrent_generate_content(rhash ctx); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* RHASH_TORRENT_H */ RHash-1.3.6/librhash/ripemd-160.c000066400000000000000000000247271325207677100163000ustar00rootroot00000000000000/* 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: 2009-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "ripemd-160.h" /** * Initialize algorithm context before calculaing hash. * * @param ctx context to initialize */ void rhash_ripemd160_init(ripemd160_ctx *ctx) { 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]; unsigned a1, b1, c1, d1, e1; /* rounds of the left half */ L1(A, B, C, D, E, X[ 0], 11); L1(E, A, B, C, D, X[ 1], 14); L1(D, E, A, B, C, X[ 2], 15); L1(C, D, E, A, B, X[ 3], 12); L1(B, C, D, E, A, X[ 4], 5); L1(A, B, C, D, E, X[ 5], 8); L1(E, A, B, C, D, X[ 6], 7); L1(D, E, A, B, C, X[ 7], 9); L1(C, D, E, A, B, X[ 8], 11); L1(B, C, D, E, A, X[ 9], 13); L1(A, B, C, D, E, X[10], 14); L1(E, A, B, C, D, X[11], 15); L1(D, E, A, B, C, X[12], 6); L1(C, D, E, A, B, X[13], 7); L1(B, C, D, E, A, X[14], 9); L1(A, B, C, D, E, X[15], 8); L2(E, A, B, C, D, X[ 7], 7); L2(D, E, A, B, C, X[ 4], 6); L2(C, D, E, A, B, X[13], 8); L2(B, C, D, E, A, X[ 1], 13); L2(A, B, C, D, E, X[10], 11); L2(E, A, B, C, D, X[ 6], 9); L2(D, E, A, B, C, X[15], 7); L2(C, D, E, A, B, X[ 3], 15); L2(B, C, D, E, A, X[12], 7); L2(A, B, C, D, E, X[ 0], 12); L2(E, A, B, C, D, X[ 9], 15); L2(D, E, A, B, C, X[ 5], 9); L2(C, D, E, A, B, X[ 2], 11); L2(B, C, D, E, A, X[14], 7); L2(A, B, C, D, E, X[11], 13); L2(E, A, B, C, D, X[ 8], 12); L3(D, E, A, B, C, X[ 3], 11); L3(C, D, E, A, B, X[10], 13); L3(B, C, D, E, A, X[14], 6); L3(A, B, C, D, E, X[ 4], 7); L3(E, A, B, C, D, X[ 9], 14); L3(D, E, A, B, C, X[15], 9); L3(C, D, E, A, B, X[ 8], 13); L3(B, C, D, E, A, X[ 1], 15); L3(A, B, C, D, E, X[ 2], 14); L3(E, A, B, C, D, X[ 7], 8); L3(D, E, A, B, C, X[ 0], 13); L3(C, D, E, A, B, X[ 6], 6); L3(B, C, D, E, A, X[13], 5); L3(A, B, C, D, E, X[11], 12); L3(E, A, B, C, D, X[ 5], 7); L3(D, E, A, B, C, X[12], 5); L4(C, D, E, A, B, X[ 1], 11); L4(B, C, D, E, A, X[ 9], 12); L4(A, B, C, D, E, X[11], 14); L4(E, A, B, C, D, X[10], 15); L4(D, E, A, B, C, X[ 0], 14); L4(C, D, E, A, B, X[ 8], 15); L4(B, C, D, E, A, X[12], 9); L4(A, B, C, D, E, X[ 4], 8); L4(E, A, B, C, D, X[13], 9); L4(D, E, A, B, C, X[ 3], 14); L4(C, D, E, A, B, X[ 7], 5); L4(B, C, D, E, A, X[15], 6); L4(A, B, C, D, E, X[14], 8); L4(E, A, B, C, D, X[ 5], 6); L4(D, E, A, B, C, X[ 6], 5); L4(C, D, E, A, B, X[ 2], 12); L5(B, C, D, E, A, X[ 4], 9); L5(A, B, C, D, E, X[ 0], 15); L5(E, A, B, C, D, X[ 5], 5); L5(D, E, A, B, C, X[ 9], 11); L5(C, D, E, A, B, X[ 7], 6); L5(B, C, D, E, A, X[12], 8); L5(A, B, C, D, E, X[ 2], 13); L5(E, A, B, C, D, X[10], 12); L5(D, E, A, B, C, X[14], 5); L5(C, D, E, A, B, X[ 1], 12); L5(B, C, D, E, A, X[ 3], 13); L5(A, B, C, D, E, X[ 8], 14); L5(E, A, B, C, D, X[11], 11); L5(D, E, A, B, C, X[ 6], 8); L5(C, D, E, A, B, X[15], 5); L5(B, C, D, E, A, X[13], 6); a1 = A, b1 = B, c1 = C, d1 = D, e1 = E; A = hash[0], B = hash[1], C = hash[2], D = hash[3], E = hash[4]; /* rounds of the right half */ R1(A, B, C, D, E, X[ 5], 8); R1(E, A, B, C, D, X[14], 9); R1(D, E, A, B, C, X[ 7], 9); R1(C, D, E, A, B, X[ 0], 11); R1(B, C, D, E, A, X[ 9], 13); R1(A, B, C, D, E, X[ 2], 15); R1(E, A, B, C, D, X[11], 15); R1(D, E, A, B, C, X[ 4], 5); R1(C, D, E, A, B, X[13], 7); R1(B, C, D, E, A, X[ 6], 7); R1(A, B, C, D, E, X[15], 8); R1(E, A, B, C, D, X[ 8], 11); R1(D, E, A, B, C, X[ 1], 14); R1(C, D, E, A, B, X[10], 14); R1(B, C, D, E, A, X[ 3], 12); R1(A, B, C, D, E, X[12], 6); R2(E, A, B, C, D, X[ 6], 9); R2(D, E, A, B, C, X[11], 13); R2(C, D, E, A, B, X[ 3], 15); R2(B, C, D, E, A, X[ 7], 7); R2(A, B, C, D, E, X[ 0], 12); R2(E, A, B, C, D, X[13], 8); R2(D, E, A, B, C, X[ 5], 9); R2(C, D, E, A, B, X[10], 11); R2(B, C, D, E, A, X[14], 7); R2(A, B, C, D, E, X[15], 7); R2(E, A, B, C, D, X[ 8], 12); R2(D, E, A, B, C, X[12], 7); R2(C, D, E, A, B, X[ 4], 6); R2(B, C, D, E, A, X[ 9], 15); R2(A, B, C, D, E, X[ 1], 13); R2(E, A, B, C, D, X[ 2], 11); R3(D, E, A, B, C, X[15], 9); R3(C, D, E, A, B, X[ 5], 7); R3(B, C, D, E, A, X[ 1], 15); R3(A, B, C, D, E, X[ 3], 11); R3(E, A, B, C, D, X[ 7], 8); R3(D, E, A, B, C, X[14], 6); R3(C, D, E, A, B, X[ 6], 6); R3(B, C, D, E, A, X[ 9], 14); R3(A, B, C, D, E, X[11], 12); R3(E, A, B, C, D, X[ 8], 13); R3(D, E, A, B, C, X[12], 5); R3(C, D, E, A, B, X[ 2], 14); R3(B, C, D, E, A, X[10], 13); R3(A, B, C, D, E, X[ 0], 13); R3(E, A, B, C, D, X[ 4], 7); R3(D, E, A, B, C, X[13], 5); R4(C, D, E, A, B, X[ 8], 15); R4(B, C, D, E, A, X[ 6], 5); R4(A, B, C, D, E, X[ 4], 8); R4(E, A, B, C, D, X[ 1], 11); R4(D, E, A, B, C, X[ 3], 14); R4(C, D, E, A, B, X[11], 14); R4(B, C, D, E, A, X[15], 6); R4(A, B, C, D, E, X[ 0], 14); R4(E, A, B, C, D, X[ 5], 6); R4(D, E, A, B, C, X[12], 9); R4(C, D, E, A, B, X[ 2], 12); R4(B, C, D, E, A, X[13], 9); R4(A, B, C, D, E, X[ 9], 12); R4(E, A, B, C, D, X[ 7], 5); R4(D, E, A, B, C, X[10], 15); R4(C, D, E, A, B, X[14], 8); R5(B, C, D, E, A, X[12] , 8); R5(A, B, C, D, E, X[15] , 5); R5(E, A, B, C, D, X[10] , 12); R5(D, E, A, B, C, X[ 4] , 9); R5(C, D, E, A, B, X[ 1] , 12); R5(B, C, D, E, A, X[ 5] , 5); R5(A, B, C, D, E, X[ 8] , 14); R5(E, A, B, C, D, X[ 7] , 6); R5(D, E, A, B, C, X[ 6] , 8); R5(C, D, E, A, B, X[ 2] , 13); R5(B, C, D, E, A, X[13] , 6); R5(A, B, C, D, E, X[14] , 5); R5(E, A, B, C, D, X[ 0] , 15); R5(D, E, A, B, C, X[ 3] , 13); R5(C, D, E, A, B, X[ 9] , 11); 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((char*)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.3.6/librhash/ripemd-160.h000066400000000000000000000013771325207677100163010ustar00rootroot00000000000000/* 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.3.6/librhash/sha1.c000066400000000000000000000120231325207677100153320ustar00rootroot00000000000000/* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1) * based on RFC 3174. * * Copyright: 2008-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "sha1.h" /** * Initialize context before calculaing 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; } /** * 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) { int t; /* Loop counter */ uint32_t temp; /* Temporary word value */ uint32_t W[80]; /* Word sequence */ uint32_t A, B, C, D, E; /* Word buffers */ /* initialize the first 16 words in the array W */ for (t = 0; t < 16; t++) { /* note: it is much faster to apply be2me here, then using be32_copy */ W[t] = be2me_32(block[t]); } /* initialize the rest */ for (t = 16; t < 80; t++) { W[t] = ROTL32(W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16], 1); } A = hash[0]; B = hash[1]; C = hash[2]; D = hash[3]; E = hash[4]; for (t = 0; t < 20; t++) { /* the following is faster than ((B & C) | ((~B) & D)) */ temp = ROTL32(A, 5) + (((C ^ D) & B) ^ D) + E + W[t] + 0x5A827999; E = D; D = C; C = ROTL32(B, 30); B = A; A = temp; } for (t = 20; t < 40; t++) { temp = ROTL32(A, 5) + (B ^ C ^ D) + E + W[t] + 0x6ED9EBA1; E = D; D = C; C = ROTL32(B, 30); B = A; A = temp; } for (t = 40; t < 60; t++) { temp = ROTL32(A, 5) + ((B & C) | (B & D) | (C & D)) + E + W[t] + 0x8F1BBCDC; E = D; D = C; C = ROTL32(B, 30); B = A; A = temp; } for (t = 60; t < 80; t++) { temp = ROTL32(A, 5) + (B ^ C ^ D) + E + W[t] + 0xCA62C1D6; E = D; D = C; C = ROTL32(B, 30); B = A; A = temp; } 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_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.3.6/librhash/sha1.h000066400000000000000000000012721325207677100153430ustar00rootroot00000000000000/* 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.3.6/librhash/sha256.c000066400000000000000000000206661325207677100155220ustar00rootroot00000000000000/* sha256.c - an implementation of SHA-256/224 hash functions * based on FIPS 180-3 (Federal Information Processing Standart). * * Copyright: 2010-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #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 calculaing 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 }; ctx->length = 0; ctx->digest_length = sha256_hash_size; /* initialize algorithm state */ memcpy(ctx->hash, SHA256_H0, sizeof(ctx->hash)); } /** * Initialize context before calculaing 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 }; 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.3.6/librhash/sha256.h000066400000000000000000000015531325207677100155210ustar00rootroot00000000000000/* 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[32]); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* SHA256_H */ RHash-1.3.6/librhash/sha3.c000066400000000000000000000240021325207677100153340ustar00rootroot00000000000000/* 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: 2013 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #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.3.6/librhash/sha3.h000066400000000000000000000026651325207677100153540ustar00rootroot00000000000000/* 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.3.6/librhash/sha512.c000066400000000000000000000233501325207677100155060ustar00rootroot00000000000000/* sha512.c - an implementation of SHA-384/512 hash functions * based on FIPS 180-3 (Federal Information Processing Standart). * * Copyright: 2010-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #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) }; ctx->length = 0; ctx->digest_length = sha512_hash_size; /* initialize algorithm state */ memcpy(ctx->hash, SHA512_H0, sizeof(ctx->hash)); } /** * Initialize context before calculaing 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) }; 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.3.6/librhash/sha512.h000066400000000000000000000015521325207677100155130ustar00rootroot00000000000000/* 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.3.6/librhash/snefru.c000066400000000000000000001602271325207677100160120ustar00rootroot00000000000000/* snefru.c - an implementation of Snefru-128/256 Message-Digest Algorithms * * Copyright: 2009-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! * * 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 calculaing 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 calculaing 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.3.6/librhash/snefru.h000066400000000000000000000021071325207677100160070ustar00rootroot00000000000000/* 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.3.6/librhash/test_hashes.c000066400000000000000000001437341325207677100170260ustar00rootroot00000000000000/* test_hashes.c - unit tests and benchmark for LibRHash algorithms * * Copyright: 2008-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include #include #include #include #include #include "byte_order.h" #include "rhash_timing.h" #include "rhash_torrent.h" #ifdef USE_RHASH_DLL # define RHASH_API __declspec(dllimport) #endif #include "rhash.h" #include "test_hashes.h" /*=========================================================================* * 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* 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_hashes[] = { "", "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): * GOST( <100000 characters of 'a'> ) = 5C00CCC2734CDD3332D3D4749576E3C1A7DBAF0E7EA74E9FA602413C90A129FA * GOST( <128 characters of 'U'> ) = 53A3A3ED25180CEF0C1D85A074273E551C25660A87062A52D926A9E8FE5733A4 */ /* test vectors from internet, verified by OpenSSL and some other programs */ const char* gost_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* gost_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 }; /* 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 }; /* 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_MD4, md4_tests }, { RHASH_MD5, md5_tests }, { RHASH_SHA1, sha1_tests }, { RHASH_TIGER, tiger_hashes }, { 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_GOST, gost_tests }, { RHASH_GOST_CRYPTOPRO, gost_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 }, { 0, 0 } }; /*=========================================================================* * Functions for calculating a message digest * *=========================================================================*/ /** * The total number of errors */ static int g_errors = 0; /** * Print a formatted message to the message log. * @param format the format of the message */ static void log_message(char* format, ...) { va_list vl; va_start(vl, format); vprintf(format, vl); fflush(stdout); va_end(vl); } /** * Calculate hash of the message specified by chunk string, repeated until * the given length is reached. * * @param hash_id id of the hash algorithm to use * @param msg_chunk the message chunk as a null-terminated string * @param chunk_size the size of the chunk in bytes * @param count the number of chunks in the message * @param set_filename boolean flag: set a filename for the BTIH hash */ static char* repeat_hash(unsigned hash_id, const char* chunk, size_t chunk_size, size_t msg_size, int set_filename) { struct rhash_context *ctx; size_t left, size; static char out[130]; assert(rhash_get_hash_length(hash_id) < 130); ctx = rhash_init(hash_id); if ((hash_id & RHASH_BTIH) && set_filename) { rhash_torrent_add_file(ctx, "test.txt", (unsigned long long)msg_size); } for (left = msg_size; left > 0; left -= size) { size = (left > chunk_size ? chunk_size : left); rhash_update(ctx, (const unsigned char*)chunk, 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 msg_chunk the message chunk as a null-terminated string * @param chunk_size the size of the chunk in bytes * @param count the number of chunks in the message * @param hash the expected hash value * @param set_filename need to set a filename for BTIH hash */ static void assert_hash_long_msg(unsigned hash_id, const char* msg_chunk, size_t chunk_size, size_t msg_size, const char* hash, const char* msg_name, int set_filename) { char* result; result = repeat_hash(hash_id, msg_chunk, chunk_size, msg_size, set_filename); if (strcmp(result, hash) != 0) { const char* hash_name = rhash_get_name(hash_id); /* the hash function name */ if (msg_name) log_message("failed: %s(%s) = %s, expected %s\n", hash_name, msg_name, result, hash); else log_message("failed: %s(\"%s\") = %s, expected %s\n", hash_name, msg_chunk, result, hash); g_errors++; } } /** * Calculate hash of the given message. * * @param hash_id id of the hash algorithm to use * @param msg the message to hash * @param set_filename need to set a filename for BTIH hash */ static char* hash_message(unsigned hash_id, const char* msg, int set_filename) { size_t msg_size = strlen(msg); return repeat_hash(hash_id, msg, msg_size, msg_size, set_filename); } /** * 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 message the message to hash * @param expected_hash the expected hash value * @param set_filename need to set a filename for BTIH hash */ static void assert_hash(unsigned hash_id, const char* msg, const char* expected_hash, int set_filename) { size_t msg_size = strlen(msg); assert_hash_long_msg(hash_id, msg, msg_size, msg_size, expected_hash, NULL, set_filename); } /** * 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 set_filename need to set a filename for BTIH hash */ static void assert_rep_hash(unsigned hash_id, char ch, size_t msg_size, const char* hash, int set_filename) { char ALIGN_ATTR(16) 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, set_filename); } /*=========================================================================* * 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 set_filename need to set a filename for BTIH hash */ static void test_known_strings_pairs(unsigned hash_id, const char** ptr, int set_filename) { for (; ptr[0] && ptr[1]; ptr += 2) { assert_hash(hash_id, ptr[0], ptr[1], set_filename); } } /** * 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; for (i = 0; short_test_vectors[i].tests != 0; i++) { if (hash_id == short_test_vectors[i].hash_id) { int set_filename = (short_test_vectors[i].tests == btih_with_filename_tests); test_known_strings_pairs(hash_id, short_test_vectors[i].tests, set_filename); break; } } } /** * Verify hash algorithms by testing them against known short messages. */ static void test_all_known_strings(void) { int i; for (i = 0; short_test_vectors[i].tests != 0; i++) { int set_filename = (short_test_vectors[i].tests == btih_with_filename_tests); test_known_strings_pairs(short_test_vectors[i].hash_id, short_test_vectors[i].tests, set_filename); } } /** * 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_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_GOST_CRYPTOPRO, "8693287AA62F9478F7CB312EC0866B6C4E4A0F11160441E8F4FFCD2715DD554F" }, /* verified with openssl */ { RHASH_GOST, "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_BTIH, "90AE73EE72A12B5A3A39DCA4C5E24BE1F39B6A1B" } /* BTIH with filename="test.txt", verified using uTorrent */ #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 }; /* test all algorithms on 1,000,000 characters of 'a' */ for (count = 0; count < (sizeof(tests) / sizeof(id_to_hash_t)); count++) { int set_filename = (tests[count].hash_id == RHASH_BTIH); assert_rep_hash(tests[count].hash_id, 'a', 1000000, tests[count].expected_hash, set_filename); } /* 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_GOST, 0xFF, 64, "13416C4EC74A63C3EC90CB1748FD462C7572C6C6B41844E48CC1184D1E916098", 0); assert_rep_hash(RHASH_GOST_CRYPTOPRO, 0xFF, 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; for (i = 0, hash_id = 1; (hash_id & RHASH_ALL_HASHES); hash_id <<= 1, i++) { digest_size = rhash_get_digest_size(hash_id); assert(digest_size < 70); 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_message("failed: 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_alignment(void) { int i, start, hash_id, alignment_size; /* loop by sums */ for (i = 0, hash_id = 1; (hash_id & RHASH_ALL_HASHES); hash_id <<= 1, i++) { char expected_hash[130]; assert(rhash_get_digest_size(hash_id) < (int)sizeof(expected_hash)); 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 fifth shifted letter sequence */ for (j = 0; j < msg_length; j++) message[start + j] = 'a' + j; message[start + j] = 0; if (start == 0) { /* save original hash value */ strcpy(expected_hash, hash_message(hash_id, message + start, 0)); } else { /* verify obtained hash value */ assert_hash(hash_id, message + start, expected_hash, 0); } } } } /** * Verify processor endianness detected at compile-time against * with the actual CPU endianness in runtime. */ static void test_endianness(void) { unsigned tmp = 1; if (*(char*)&tmp == IS_BIG_ENDIAN) { log_message("error: wrong endianness detected at compile time\n"); g_errors++; } } /** * Run various simple tests. */ static void test_generic_assumptions(void) { unsigned mask = (1 << RHASH_HASH_COUNT) - 1; if (mask != RHASH_ALL_HASHES) { log_message("error: wrong algorithms count %d for the mask 0x%x\n", RHASH_HASH_COUNT, RHASH_ALL_HASHES); g_errors++; } test_endianness(); } #define TEST_PATH 0x4000000 /** * Verify a magnet link. */ static void assert_magnet(const char* expected, rhash ctx, unsigned mask, int flags) { static char out[240]; const char* path = (flags & TEST_PATH ? "test.txt" : NULL); size_t size; flags &= ~TEST_PATH; size = rhash_print_magnet(out, path, ctx, mask, flags); if (expected && strcmp(expected, out) != 0) { log_message("error: \"%s\" != \"%s\"\n", expected, out); g_errors++; } else { size_t size2 = strlen(out) + 1; if (size != size2) { log_message("error: rhash_print_magnet returns wrong length %d != %d for \"%s\"\n", (int)size, (int)size2, out); g_errors++; } else if (size != (size2 = rhash_print_magnet(NULL, path, ctx, mask, flags))) { log_message("error: rhash_print_magnet(NULL, ...) returns wrong length %d != %d for \"%s\"\n", (int)size2, (int)size, out); g_errors++; } } } /** * Test printing of magnet links. */ static void test_magnet(void) { unsigned bit; rhash ctx = rhash_init(RHASH_ALL_HASHES); rhash_update(ctx, "a", 1); rhash_final(ctx, 0); assert_magnet("magnet:?xl=1&dn=test.txt&xt=urn:tree:tiger:czquwh3iyxbf5l3bgyugzhassmxu647ip2ike4y", ctx, RHASH_TTH, RHPR_FILESIZE | TEST_PATH); assert_magnet("magnet:?xl=1&xt=urn:md5:0CC175B9C0F1B6A831C399E269772661", ctx, RHASH_MD5, RHPR_FILESIZE | RHPR_UPPERCASE); assert_magnet("xt=urn:ed2k:bde52cb31de33e46245e05fbdbd6fb24&xt=urn:aich:q336in72uwt7zyk5dxolt2xk5i3xmz5y&xt=urn:sha1:q336in72uwt7zyk5dxolt2xk5i3xmz5y&xt=urn:btih:qj6nrgcg7qjs4lth4kocpbggkrb3wtob", ctx, RHASH_ED2K | RHASH_AICH | RHASH_SHA1 | RHASH_BTIH, RHPR_NO_MAGNET); /* verify length calculation for all hashes */ for (bit = 1; bit < RHASH_ALL_HASHES; bit <<= 1) { assert_magnet(NULL, ctx, bit, RHPR_FILESIZE | RHPR_NO_MAGNET); } rhash_free(ctx); } /** * Find a hash function id by its name. * * @param name hash algorithm name * @return algorithm id */ static unsigned find_hash(const char* name) { char buf[30]; unsigned hash_id; int i; if (strlen(name) > (sizeof(buf) - 1)) return 0; for (i = 0; name[i]; i++) buf[i] = toupper(name[i]); buf[i] = 0; for (hash_id = 1; (hash_id & RHASH_ALL_HASHES); hash_id <<= 1) { if (strcmp(buf, rhash_get_name(hash_id)) == 0) return hash_id; } return 0; } /** * Print status of OpenSSL plugin. */ static void print_openssl_status(void) { rhash_uptr_t available = rhash_get_openssl_available_mask(); rhash_uptr_t supported = rhash_get_openssl_supported_mask(); int has_openssl = rhash_is_openssl_supported(); printf("OpenSSL %s", (has_openssl ? "supported" : "not supported")); if (has_openssl && available != RHASH_ERROR) { printf(", %s", (available ? "loaded" : "not loaded")); if (available) { unsigned hash_id; printf(":"); available &= RHASH_ALL_HASHES; for (hash_id = 1; hash_id <= available; hash_id <<= 1) { if (!!(hash_id & available)) printf(" %s", rhash_get_name(hash_id)); } supported &= (~available & RHASH_ALL_HASHES); for (hash_id = 1; hash_id <= supported; hash_id <<= 1) { if (!!(hash_id & supported)) printf(" -%s", rhash_get_name(hash_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[]) { #ifndef USE_RHASH_DLL rhash_library_init(); #endif test_generic_assumptions(); if (argc > 1) { if (strcmp(argv[1], "--speed") == 0) { unsigned hash_id = (argc > 2 ? find_hash(argv[2]) : RHASH_SHA1); if (hash_id == 0) { fprintf(stderr, "error: unknown hash_id: %s\n", argv[2]); return 1; } test_known_strings(hash_id); rhash_run_benchmark(hash_id, 0, stdout); } else if (strcmp(argv[1], "--info") == 0) { printf("%s", compiler_flags); print_openssl_status(); } else { printf("Options: [--speed [HASH_NAME]| --info]\n"); } } else { test_all_known_strings(); test_long_strings(); test_alignment(); test_results_consistency(); test_magnet(); if (g_errors == 0) printf("All sums are working properly!\n"); fflush(stdout); } if (g_errors > 0) printf("%s", compiler_flags); return (g_errors == 0 ? 0 : 1); } RHash-1.3.6/librhash/test_hashes.h000066400000000000000000000105521325207677100170220ustar00rootroot00000000000000/* test_hashes.h - detect compiler defines */ #ifndef TEST_HASHES_H #define TEST_HASHES_H #include "byte_order.h" /* 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 vax " vax" #endif #ifdef MIPSEL " MIPSEL" #endif #ifdef _ARM_ " _ARM_" #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 __hpux " __hpux" #endif #ifdef _MIPSEB " _MIPSEB" #endif #ifdef mc68000 " mc68000" #endif #ifdef __s390__ " __s390__" #endif #ifdef __s390x__ " __s390x__" #endif #ifdef sel " sel" #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 __STDC_VERSION__ " __STDC_VERSION__=" EXPAND_TO_STRING(__STDC_VERSION__) #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 __FreeBSD__ " __FreeBSD__" #endif #ifdef __OpenBSD__ " __OpenBSD__" #endif #ifdef __NetBSD__ " __NetBSD__" #endif #ifdef __APPLE__ " __APPLE__" #endif #ifdef __MACH__ /* Mac OS X = __APPLE__ & __MACH__ on gcc/icc */ " __MACH__" #endif #include #ifdef __GLIBC__ /* GLIBC >= 6 */ " __GLIBC__" #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_OPENSSL " USE_OPENSSL" #endif #ifdef OPENSSL_RUNTIME " OPENSSL_RUNTIME" #endif #ifdef CPU_X64 " CPU_X64" #endif #ifdef CPU_IA32 " CPU_IA32" #endif /* detect endianness */ #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_HASHES_H */ RHash-1.3.6/librhash/tiger.c000066400000000000000000000137271325207677100156240ustar00rootroot00000000000000/* 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: 2007-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "tiger.h" /** * Initialize algorithm context before calculaing hash. * * @param ctx context to initialize */ void rhash_tiger_init(tiger_ctx *ctx) { ctx->length = 0; ctx->tiger2 = 0; /* initialize algorithm state */ ctx->hash[0] = I64(0x0123456789ABCDEF); ctx->hash[1] = I64(0xFEDCBA9876543210); ctx->hash[2] = I64(0xF096A5B4C3B2E187); } /* 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) { 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->tiger2 ? 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 << 3); rhash_tiger_process_block(ctx->hash, msg64); /* save result hash */ le64_copy(result, 0, &ctx->hash, 24); } RHash-1.3.6/librhash/tiger.h000066400000000000000000000015031325207677100156160ustar00rootroot00000000000000/* 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 */ int tiger2; /* flag, 1 for Tiger2 algorithm, default is 0 */ } tiger_ctx; /* hash functions */ 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.3.6/librhash/tiger_sbox.c000066400000000000000000000666731325207677100166670ustar00rootroot00000000000000/* tiger_sbox.c - S-Box for Tiger hash function * * Copyright: 2007-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #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.3.6/librhash/torrent.c000066400000000000000000000375031325207677100162050ustar00rootroot00000000000000/* torrent.c - create BitTorrent files and calculate BitTorrent InfoHash (BTIH). * * Copyright: 2010-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include #include #include #include /* time() */ #include "byte_order.h" #include "algorithms.h" #include "hex.h" #include "torrent.h" #ifdef USE_OPENSSL #define SHA1_INIT(ctx) ((pinit_t)ctx->sha_init)(&ctx->sha1_context) #define SHA1_UPDATE(ctx, msg, size) ((pupdate_t)ctx->sha_update)(&ctx->sha1_context, (msg), (size)) #define SHA1_FINAL(ctx, result) ((pfinal_t)ctx->sha_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_HASH_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 /** * 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_HASH_LENGTH; assert(BT_MIN_HASH_LENGTH == bt_default_piece_length(0)); #ifdef USE_OPENSSL { /* get the methods of the selected SHA1 algorithm */ rhash_hash_info *sha1_info = &rhash_info_table[3]; assert(sha1_info->info->hash_id == RHASH_SHA1); assert(sha1_info->context_size <= (sizeof(sha1_ctx) + sizeof(unsigned long))); ctx->sha_init = sha1_info->init; ctx->sha_update = sha1_info->update; ctx->sha_final = sha1_info->final; } #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_HASH_SIZE * BT_BLOCK_SIZE); if (block == NULL || !bt_vector_add_ptr(&ctx->hash_blocks, block)) { if (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[1]; } 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); } 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 (length >= ctx->content.allocated && !ctx->error) { 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)) return; assert(ctx->content.str != 0); memcpy(ctx->content.str + ctx->content.length, text, length); ctx->content.length += length; ctx->content.str[ctx->content.length] = '\0'; } /** * B-encode given integer. * * @param ctx the torrent algorithm context * @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 str the string to encode */ static void bt_bencode_str(torrent_ctx* ctx, const char* name, const char* str) { size_t len = strlen(str); int num_len; char* p; if (name) bt_str_append(ctx, name); if (!bt_str_ensure_length(ctx, ctx->content.length + len + 21)) return; p = ctx->content.str + ctx->content.length; p += (num_len = rhash_sprintI64(p, len)); ctx->content.length += len + num_len + 1; *(p++) = ':'; memcpy(p, str, len + 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) { size_t pieces_length = ctx->piece_count * BT_HASH_SIZE; int num_len; int size, i; char* p; if (!bt_str_ensure_length(ctx, ctx->content.length + pieces_length + 21)) return; p = ctx->content.str + ctx->content.length; p += (num_len = rhash_sprintI64(p, pieces_length)); ctx->content.length += pieces_length + num_len + 1; *(p++) = ':'; p[pieces_length] = '\0'; /* terminate with \0 just in case */ for (size = (int)ctx->piece_count, i = 0; size > 0; size -= BT_BLOCK_SIZE, i++) { memcpy(p, ctx->hash_blocks.array[i], (size < BT_BLOCK_SIZE ? size : BT_BLOCK_SIZE) * BT_HASH_SIZE); p += BT_BLOCK_SIZE * BT_HASH_SIZE; } } /** * Calculate default torrent piece length, using uTorrent algorithm. * Algorithm: * length = 16K for total_size < 16M, * length = 8M for total_size >= 4G, * length = top_bit(total_size) / 1024 otherwise. * * @param total_size total hashed batch size of torrent file * @return piece length used by torrent file */ size_t bt_default_piece_length(uint64_t total_size) { uint64_t hi_bit; if (total_size < 16777216) return BT_MIN_HASH_LENGTH; if (total_size >= I64(4294967296) ) return 8388608; for (hi_bit = 16777216 << 1; hi_bit <= total_size; hi_bit <<= 1); return (size_t)(hi_bit >> 10); } /* 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); } 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"); } bt_str_append(ctx, "ee"); /* calculate BTIH */ SHA1_INIT(ctx); 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; } /** * 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; } RHash-1.3.6/librhash/torrent.h000066400000000000000000000044141325207677100162050ustar00rootroot00000000000000/* torrent.h */ #ifndef TORRENT_H #define TORRENT_H #include "ustd.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 */ void *sha_init, *sha_update, *sha_final; #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 */ 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 */ int error; /* non-zero if error occurred, zero otherwise */ } 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); 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 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); size_t bt_default_piece_length(uint64_t total_size); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* TORRENT_H */ RHash-1.3.6/librhash/tth.c000066400000000000000000000071601325207677100153030ustar00rootroot00000000000000/* tth.c - calculate TTH (Tiger Tree Hash) function. * * Copyright: 2007-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #include #include "byte_order.h" #include "tth.h" /** * Initialize context before calculaing 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); } RHash-1.3.6/librhash/tth.h000066400000000000000000000011201325207677100152760ustar00rootroot00000000000000#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[64]); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* TTH_H */ RHash-1.3.6/librhash/ustd.h000066400000000000000000000016111325207677100154630ustar00rootroot00000000000000/* 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.3.6/librhash/util.h000066400000000000000000000020771325207677100154700ustar00rootroot00000000000000/* util.h */ #ifndef UTIL_H #define UTIL_H #ifdef __cplusplus extern "C" { #endif #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) # 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 /* pray that it will work */ # define atomic_compare_and_swap(ptr, oldval, newval) { if(*(ptr) == (oldval)) *(ptr) = (newval); } # define NO_ATOMIC_BUILTINS #endif #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* UTIL_H */ RHash-1.3.6/librhash/whirlpool.c000066400000000000000000000146401325207677100165240ustar00rootroot00000000000000/* whirlpool.c - an implementation of the Whirlpool Hash Function. * * Copyright: 2009-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! * * 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 #include "byte_order.h" #include "whirlpool.h" /** * Initialize context before calculaing 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.3.6/librhash/whirlpool.h000066400000000000000000000017111325207677100165240ustar00rootroot00000000000000/* 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.3.6/librhash/whirlpool_sbox.c000066400000000000000000001501271325207677100175600ustar00rootroot00000000000000/* whirlpool_sbox.c - S-Box for the Whirlpool hash function * * Copyright: 2009-2012 Aleksey Kravchenko * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. Use this program at your own risk! */ #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.3.6/output.c000066400000000000000000000326631325207677100142560ustar00rootroot00000000000000/* output.c - output of results, errors and percents */ #include #include #include #include /* exit() */ #include #include #include "platform.h" #include "calc_sums.h" #include "common_func.h" #include "file.h" #include "output.h" #include "parse_cmdline.h" #include "rhash_main.h" #include "win_utils.h" #include "librhash/rhash.h" #ifdef _WIN32 # include #endif /* global pointer to the selected method of percents output */ struct percents_output_info_t *percents_output = NULL; /** * Print a formatted message to the program log, and flush the log stream. * * @param format print a formatted message to the program log * @param args */ static void log_va_msg(const char* format, va_list args) { rsh_vfprintf(rhash_data.log, format, args); fflush(rhash_data.log); } /** * Print a formatted message to the program log, and flush the log stream. * * @param format print a formatted message to the program log */ void log_msg(const char* format, ...) { va_list ap; va_start(ap, format); log_va_msg(format, ap); } /** * Print an error to the program log. * * @param format print a formatted message to the program log */ void log_error(const char* format, ...) { va_list ap; va_start(ap, format); rsh_fprintf(rhash_data.log, "%s: ", PROGRAM_NAME); log_va_msg(format, ap); } /** * Print an error to the program log. * * @param filepath the path to file caused the error */ void log_warning(const char* format, ...) { va_list ap; va_start(ap, format); rsh_fprintf(rhash_data.log, "%s: ", PROGRAM_NAME); log_va_msg(format, ap); } /** * Print file error to the program log. * * @param filepath path to the file, which caused the error */ void log_file_error(const char* filepath) { if (!filepath) filepath = "(null)"; log_error("%s: %s\n", filepath, strerror(errno)); } /** * Print file error to the program log. * * @param file the file, caused the error */ void log_file_t_error(const struct file_t* file) { #ifdef _WIN32 if (!file->path) log_file_error(w2c(file->wpath)); #endif log_file_error(file->path); } /** * Log the message, that the program was interrupted. * The function should be called only once. */ void report_interrupted(void) { assert(rhash_data.interrupted == 1); rhash_data.interrupted = 2; log_msg(_("Interrupted by user...\n")); } /** * Information about printed percents. */ struct percents_t { int points; int use_cursor; int same_output; unsigned ticks; }; static struct percents_t percents; /* the hash functions, which needs to be reported first on mismatch */ #define REPORT_FIRST_MASK (RHASH_MD5 | RHASH_SHA256 | RHASH_SHA512) /** * Print verbose error on hash sums mismatch. * * @param info file information with path and its hash sums. */ static void print_verbose_error(struct file_info *info) { char actual[130], expected[130]; assert(HC_FAILED(info->hc.flags)); rsh_fprintf(rhash_data.out, _("ERROR")); if (HC_WRONG_FILESIZE & info->hc.flags) { sprintI64(actual, info->rctx->msg_size, 0); sprintI64(expected, info->hc.file_size, 0); rsh_fprintf(rhash_data.out, _(", size is %s should be %s"), actual, expected); } if (HC_WRONG_EMBCRC32 & info->hc.flags) { rhash_print(expected, info->rctx, RHASH_CRC32, RHPR_UPPERCASE); rsh_fprintf(rhash_data.out, _(", embedded CRC32 should be %s"), expected); } if (HC_WRONG_HASHES & info->hc.flags) { int i; unsigned reported = 0; for (i = 0; i < info->hc.hashes_num; i++) { hash_value *hv = &info->hc.hashes[i]; char *expected_hash = info->hc.data + hv->offset; unsigned hid = hv->hash_id; int pflags; if ((info->hc.wrong_hashes & (1 << i)) == 0) continue; assert(hid != 0); /* if can't detect precise hash */ if ((hid & (hid - 1)) != 0) { /* guess the hash id */ if (hid & opt.sum_flags) hid &= opt.sum_flags; if (hid & ~info->hc.found_hash_ids) hid &= ~info->hc.found_hash_ids; if (hid & ~reported) hid &= ~reported; /* avoiding repeating */ if (hid & REPORT_FIRST_MASK) hid &= REPORT_FIRST_MASK; hid &= -(int)hid; /* take the lowest bit */ } assert(hid != 0 && (hid & (hid - 1)) == 0); /* single bit only */ reported |= hid; pflags = (hv->length == (rhash_get_digest_size(hid) * 2) ? (RHPR_HEX | RHPR_UPPERCASE) : (RHPR_BASE32 | RHPR_UPPERCASE)); rhash_print(actual, info->rctx, hid, pflags); rsh_fprintf(rhash_data.out, _(", %s is %s should be %s"), rhash_get_name(hid), actual, expected_hash); } } rsh_fprintf(rhash_data.out, "\n"); } /** * Print file path and result of its verification by hash. * Also if error occurred, print error message. * * @param info pointer to the file-info structure * @param print_name set to non-zero to print file path * @param print_result set to non-zero to print hash verification result */ static void print_check_result(struct file_info *info, int print_name, int print_result) { if (print_name) { rsh_fprintf(rhash_data.out, "%-51s ", info->print_path); } if (print_result) { if (info->error == -1) { /* print error to stdout */ rsh_fprintf(rhash_data.out, "%s\n", strerror(errno)); } else if (!HC_FAILED(info->hc.flags) || !(opt.flags & OPT_VERBOSE)) { /* TRANSLATORS: use at least 3 characters to overwrite "99%" */ rsh_fprintf(rhash_data.out, (!HC_FAILED(info->hc.flags) ? _("OK \n") : /* TRANSLATORS: ERR is short for 'error' */ _("ERR\n")) ); } else { print_verbose_error(info); } } fflush(rhash_data.out); } /** * Prepare or print result of file processing. * * @param info pointer to the file-info structure * @param init non-zero on initialization before hash calculation, * and zero after hash calculation finished. */ static void print_results_on_check(struct file_info *info, int init) { if (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) { int print_name = (opt.flags & (OPT_PERCENTS | OPT_SKIP_OK) ? !init : init); if (!init && (opt.flags & OPT_SKIP_OK) && errno == 0 && !HC_FAILED(info->hc.flags)) { return; /* skip OK message */ } print_check_result(info, print_name, !init); } } /* functions to output file info without percents */ /** * Print file name in hash checking mode. * No information is printed in other modes. * * @param info pointer to the file-info structure * @return non-zero, indicating that the output method successfully initialized */ static int dummy_init_percents(struct file_info *info) { print_results_on_check(info, 1); return 1; } /** * Print file check results without printing percents. * Information is printed only in hash verification mode. * * @param info pointer to the file-info structure * @param process_res non-zero if error occurred while hashing/checking */ static void dummy_finish_percents(struct file_info *info, int process_res) { info->error = process_res; print_results_on_check(info, 0); } /* functions to output file info with simple multi-line wget-like percents */ /** * Initialize dots percent mode. * * @param info pointer to the file-info structure * @return non-zero, indicating that the output method successfully initialized */ static int dots_init_percents(struct file_info *info) { (void)info; fflush(rhash_data.out); fflush(rhash_data.log); percents.points = 0; print_results_on_check(info, 1); return 1; } /** * Finish dots percent mode. If in hash verification mode, * then print the results of file check. * * @param info pointer to the file-info structure * @param process_res non-zero if error occurred while hashing/checking */ static void dots_finish_percents(struct file_info *info, int process_res) { char buf[80]; info->error = process_res; if ((percents.points % 74) != 0) { log_msg("%s 100%%\n", str_set(buf, ' ', 74 - (percents.points%74) )); } print_results_on_check(info, 0); } /** * Output percents by printing one dot per each processed 1MiB. * * @param info pointer to the file-info structure * @param offset the number of hashed bytes */ static void dots_update_percents(struct file_info *info, uint64_t offset) { const int pt_size = 1024*1024; /* 1MiB */ offset -= info->msg_offset; /* get real file offset */ if ( (offset % pt_size) != 0 ) return; if (percents.points == 0) { if (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) { rsh_fprintf(rhash_data.log, _("\nChecking %s\n"), info->print_path); } else { rsh_fprintf(rhash_data.log, _("\nProcessing %s\n"), info->print_path); } fflush(rhash_data.log); } putc('.', rhash_data.log); if (((++percents.points) % 74) == 0) { if (info->size > 0) { int perc = (int)( offset * 100.0 / (uint64_t)info->size + 0.5 ); rsh_fprintf(rhash_data.log, " %2u%%\n", perc); fflush(rhash_data.log); } else { putc('\n', rhash_data.log); } } } /* console one-line percents */ /** * Initialize one-line percent mode. * * @param info pointer to the file-info structure * @return non-zero if the output method successfully initialized */ static int p_init_percents(struct file_info *info) { (void)info; percents.points = 0; percents.same_output = 0; percents.use_cursor = 0; fflush(rhash_data.out); fflush(rhash_data.log); assert(rhash_data.log == stderr); /* note: this output differs from print_check_result() by file handle */ rsh_fprintf(rhash_data.log, "%-51s ", info->print_path); percents.same_output = (rhash_data.out == stdout && isatty(0)); percents.ticks = rhash_get_ticks(); return 1; } /** * Output one-line percents by printing them after file path. * If the total file length is unknow (i.e. hashing stdin), * then output a rotating stick. * * @param info pointer to the file-info structure * @param offset the number of hashed bytes */ static void p_update_percents(struct file_info *info, uint64_t offset) { static const char rot[4] = {'-', '\\', '|', '/'}; int perc = 0; unsigned ticks; if (info->size > 0) { offset -= info->msg_offset; /* use only two digits to display percents: 0%-99% */ perc = (int)( offset * 99.9 / (uint64_t)info->size ); if (percents.points == perc) return; } /* update percents no more than 20 times per second */ ticks = rhash_get_ticks(); /* clock ticks count in milliseconds */ if ((unsigned)(ticks - percents.ticks) < 50) return; /* output percents or rotated bar */ if (info->size > 0) { rsh_fprintf(rhash_data.log, "%u%%", perc); percents.points = perc; } else { rsh_fprintf(rhash_data.log, "%c", rot[(percents.points++) & 3]); } rsh_fprintf(rhash_data.log, "\r%-51s ", info->print_path); fflush(rhash_data.log); percents.ticks = ticks; } /** * Finish one-line percent mode. If in hash verification mode, * then print the results of file check. * * @param info pointer to the file-info structure * @param process_res non-zero if error occurred while hashing/checking */ static void p_finish_percents(struct file_info *info, int process_res) { int need_check_result; need_check_result = (opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) && !((opt.flags & OPT_SKIP_OK) && errno == 0 && !HC_FAILED(info->hc.flags)); info->error = process_res; if (percents.same_output && need_check_result) { print_check_result(info, 0, 1); } else { rsh_fprintf(rhash_data.log, "100%%\n"); fflush(rhash_data.log); if (need_check_result) print_check_result(info, 1, 1); } } /* three methods of percents output */ struct percents_output_info_t dummy_perc = { dummy_init_percents, 0, dummy_finish_percents, "dummy" }; struct percents_output_info_t dots_perc = { dots_init_percents, dots_update_percents, dots_finish_percents, "dots" }; struct percents_output_info_t p_perc = { p_init_percents, p_update_percents, p_finish_percents, "digits" }; static void setup_log_stream(FILE **p_stream, const opt_tchar* stream_path) { if (stream_path && !(*p_stream = rsh_tfopen(stream_path, RSH_T("w"))) ) { log_file_error(t2c(stream_path)); rsh_exit(2); } } /** * Initialize pointers to output functions. */ void setup_output(void) { rhash_data.out = stdout; rhash_data.log = stderr; setup_log_stream(&rhash_data.log, opt.log); setup_log_stream(&rhash_data.out, opt.output); } void setup_percents(void) { if (opt.flags & OPT_PERCENTS) { /* NB: we don't use _fileno() cause it is not in ISO C90, and so * is incompatible with the GCC -ansi option */ if (rhash_data.log == stderr && isatty(2)) { /* use one-line percents by default on console */ percents_output = &p_perc; IF_WINDOWS(hide_cursor()); } else { /* print percents as dots */ percents_output = &dots_perc; } } else { percents_output = &dummy_perc; /* no percents */ } } /* misc output functions */ /** * Print total statistics of crc file checking. */ void print_check_stats(void) { if (rhash_data.processed == rhash_data.ok) { /* NOTE: don't use puts() here cause it mess with printf stdout buffering */ rsh_fprintf(rhash_data.out, _("Everything OK\n")); } else { rsh_fprintf(rhash_data.out, _("Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n"), rhash_data.processed-rhash_data.ok-rhash_data.miss, rhash_data.miss, rhash_data.ok, rhash_data.processed); } fflush(rhash_data.out); } /** * Print file processing times. */ void print_file_time_stats(struct file_info* info) { print_time_stats(info->time, info->size, 0); } /** * Print processing time statistics. */ void print_time_stats(double time, uint64_t size, int total) { double speed = (time == 0 ? 0 : (double)(int64_t)size / 1048576.0 / time); if (total) { rsh_fprintf(rhash_data.log, _("Total %.3f sec, %4.2f MBps\n"), time, speed); } else { rsh_fprintf(rhash_data.log, _("Calculated in %.3f sec, %4.2f MBps\n"), time, speed); } fflush(rhash_data.log); } RHash-1.3.6/output.h000066400000000000000000000024311325207677100142510ustar00rootroot00000000000000/* output.h */ #ifndef OUTPUT_H #define OUTPUT_H #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); void (*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); void log_msg(const char* format, ...); void log_error(const char* format, ...); void log_warning(const char* format, ...); void log_file_error(const char* filepath); void log_file_t_error(const struct file_t* file); void report_interrupted(void); void print_check_stats(void); void print_time_stats(double 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.3.6/parse_cmdline.c000066400000000000000000001025221325207677100155130ustar00rootroot00000000000000/* parse_cmdline.c - parsing of command line options */ #include #include #include #include #include #ifdef _WIN32 # include /* for SetFileApisToOEM(), CharToOem() */ #endif #include "parse_cmdline.h" #include "common_func.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" 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 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* text) { rsh_fprintf(rhash_data.out, "%s%s", option, text); } /** * Print program help. */ static void print_help(void) { 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")); print_help_line(" -C, --crc32 ", _("Calculate CRC32 hash sum.\n")); print_help_line(" --md4 ", _("Calculate MD4 hash sum.\n")); print_help_line(" -M, --md5 ", _("Calculate MD5 hash sum.\n")); print_help_line(" -H, --sha1 ", _("Calculate SHA1 hash sum.\n")); print_help_line(" --sha224, --sha256, --sha384, --sha512 ", _("Calculate SHA2 hash sum.\n")); print_help_line(" --sha3-224, --sha3-256, --sha3-384, --sha3-512 ", _("Calculate SHA3 hash sum.\n")); print_help_line(" -T, --tth ", _("Calculate TTH sum.\n")); print_help_line(" --btih ", _("Calculate BitTorrent InfoHash.\n")); print_help_line(" -A, --aich ", _("Calculate AICH hash.\n")); print_help_line(" -E, --ed2k ", _("Calculate eDonkey hash sum.\n")); print_help_line(" -L, --ed2k-link ", _("Calculate and print eDonkey link.\n")); print_help_line(" --tiger ", _("Calculate Tiger hash sum.\n")); print_help_line(" -G, --gost ", _("Calculate GOST R 34.11-94 hash.\n")); print_help_line(" --gost-cryptopro ", _("CryptoPro version of the GOST R 34.11-94 hash.\n")); print_help_line(" --ripemd160 ", _("Calculate RIPEMD-160 hash.\n")); print_help_line(" --has160 ", _("Calculate HAS-160 hash.\n")); print_help_line(" --edonr256, --edonr512 ", _("Calculate EDON-R 256/512 hash.\n")); print_help_line(" --snefru128, --snefru256 ", _("Calculate SNEFRU-128/256 hash.\n")); print_help_line(" -a, --all ", _("Calculate all supported hashes.\n")); print_help_line(" -c, --check ", _("Check hash files specified by command line.\n")); print_help_line(" -u, --update ", _("Update hash files specified by command line.\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 hashes, one per line.\n")); print_help_line(" -B, --benchmark ", _("Benchmark selected algorithm.\n")); print_help_line(" -v, --verbose ", _("Be verbose.\n")); print_help_line(" -r, --recursive ", _("Process directories recursively.\n")); print_help_line(" --file-list= ", _("Process a list of files.\n")); print_help_line(" --skip-ok ", _("Don't print OK messages for successfully verified files.\n")); print_help_line(" -i, --ignore-case ", _("Ignore case of filenames when updating hash files.\n")); print_help_line(" --percents ", _("Show percents, while calculating or checking hashes.\n")); print_help_line(" --speed ", _("Output per-file and total processing speed.\n")); print_help_line(" --maxdepth= ", _("Descend at most levels of directories.\n")); if (rhash_is_openssl_supported()) print_help_line(" --openssl= ", _("List 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 hash sums, using SFV format (default).\n")); print_help_line(" --bsd ", _("Print hash sums, using BSD-like format.\n")); print_help_line(" --simple ", _("Print hash sums, using simple format.\n")); print_help_line(" -m, --magnet ", _("Print hash sums as magnet links.\n")); print_help_line(" --torrent ", _("Create torrent files.\n")); #ifdef _WIN32 print_help_line(" --ansi ", _("Use Windows 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 hash sums.\n 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) { int id; for (id = 1; id < RHASH_ALL_HASHES; id <<= 1) { const char* hash_name = rhash_get_name(id); if (hash_name) rsh_fprintf(rhash_data.out, "%s\n", hash_name); } rsh_exit(0); } enum file_suffix_type { MASK_ACCEPT, MASK_EXCLUDE, MASK_CRC_ACCEPT }; /** * Add a file-list. * * @param o pointer to the options structure to update * @param path the path to the file-list * @param type the type of the option */ static void add_file_list(options_t *o, tstr_t path, unsigned is_file_list) { if (o->search_data) { file_search_add_file(o->search_data, path, is_file_list); opt.has_files = 1; } } /** * 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 hash names * @param type ignored */ static void openssl_flags(options_t *o, char* openssl_hashes, unsigned type) { (void)type; if (rhash_is_openssl_supported()) { rhash_uptr_t openssl_supported_hashes = rhash_get_openssl_supported_mask(); char *cur, *next; o->openssl_mask = 0x80000000; /* turn off using default mask */ /* set the openssl_mask */ for (cur = openssl_hashes; cur && *cur; cur = next) { print_hash_info *info = hash_info_table; unsigned bit; size_t length; next = strchr(cur, ','); length = (next != NULL ? (size_t)(next++ - cur) : strlen(cur)); for (bit = 1; bit <= RHASH_ALL_HASHES; bit = bit << 1, info++) { if ( (bit & openssl_supported_hashes) && memcmp(cur, info->short_name, length) == 0 && info->short_name[length] == 0) { o->openssl_mask |= bit; break; } } if (bit > RHASH_ALL_HASHES) { cur[length] = '\0'; /* terminate wrong hash name */ log_warning(_("openssl option doesn't support '%s' hash\n"), cur); } } } else log_warning(_("compiled without openssl support\n")); } /** * 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 --maxdepth 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)) { log_error(_("maxdepth parameter is not a number: %s\n"), number); rsh_exit(2); } 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)) { log_error(_("bt-piece-length parameter is not a number: %s\n"), number); rsh_exit(2); } 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 { log_error(_("path-separator is not '/' or '\\': %s\n"), sep); rsh_exit(2); } } /** * 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 */ 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_TOUT = 3 | F_NEED_PARAM | F_OUTPUT_OPT, F_VFNC = 4, /* just call a function */ F_PFNC = 5 | F_NEED_PARAM, /* process option parameter by calling a handler */ F_TFNC = 6 | F_NEED_PARAM, /* process option parameter by calling a handler */ F_UFNC = 7 | F_NEED_PARAM, /* pass UTF-8 encoded parameter to the handler */ F_PRNT = 8, /* 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", &opt.mode, MODE_CHECK }, { F_UFLG, 'k', 0, "check-embedded", &opt.mode, MODE_CHECK_EMBEDDED }, { F_UFLG, 'u', 0, "update", &opt.mode, MODE_UPDATE }, { F_UFLG, 'B', 0, "benchmark", &opt.mode, MODE_BENCHMARK }, { F_UFLG, 0, 0, "torrent", &opt.mode, MODE_TORRENT }, { F_VFNC, 0, 0, "list-hashes", list_hashes, 0 }, { F_VFNC, 'h', 0, "help", print_help, 0 }, { F_VFNC, 'V', 0, "version", print_version, 0 }, /* hash sums options */ { F_UFLG, 'a', 0, "all", &opt.sum_flags, RHASH_ALL_HASHES }, { F_UFLG, 'C', 0, "crc32", &opt.sum_flags, RHASH_CRC32 }, { F_UFLG, 0, 0, "md4", &opt.sum_flags, RHASH_MD4 }, { F_UFLG, 'M', 0, "md5", &opt.sum_flags, RHASH_MD5 }, { F_UFLG, 'H', 0, "sha1", &opt.sum_flags, RHASH_SHA1 }, { F_UFLG, 0, 0, "sha224", &opt.sum_flags, RHASH_SHA224 }, { F_UFLG, 0, 0, "sha256", &opt.sum_flags, RHASH_SHA256 }, { F_UFLG, 0, 0, "sha384", &opt.sum_flags, RHASH_SHA384 }, { F_UFLG, 0, 0, "sha512", &opt.sum_flags, RHASH_SHA512 }, { F_UFLG, 0, 0, "sha3-224", &opt.sum_flags, RHASH_SHA3_224 }, { F_UFLG, 0, 0, "sha3-256", &opt.sum_flags, RHASH_SHA3_256 }, { F_UFLG, 0, 0, "sha3-384", &opt.sum_flags, RHASH_SHA3_384 }, { F_UFLG, 0, 0, "sha3-512", &opt.sum_flags, RHASH_SHA3_512 }, { F_UFLG, 0, 0, "tiger", &opt.sum_flags, RHASH_TIGER }, { F_UFLG, 'T', 0, "tth", &opt.sum_flags, RHASH_TTH }, { F_UFLG, 0, 0, "btih", &opt.sum_flags, RHASH_BTIH }, { F_UFLG, 'E', 0, "ed2k", &opt.sum_flags, RHASH_ED2K }, { F_UFLG, 'A', 0, "aich", &opt.sum_flags, RHASH_AICH }, { F_UFLG, 'G', 0, "gost", &opt.sum_flags, RHASH_GOST }, { F_UFLG, 0, 0, "gost-cryptopro", &opt.sum_flags, RHASH_GOST_CRYPTOPRO }, { F_UFLG, 'W', 0, "whirlpool", &opt.sum_flags, RHASH_WHIRLPOOL }, { F_UFLG, 0, 0, "ripemd160", &opt.sum_flags, RHASH_RIPEMD160 }, { F_UFLG, 0, 0, "has160", &opt.sum_flags, RHASH_HAS160 }, { F_UFLG, 0, 0, "snefru128", &opt.sum_flags, RHASH_SNEFRU128 }, { F_UFLG, 0, 0, "snefru256", &opt.sum_flags, RHASH_SNEFRU256 }, { F_UFLG, 0, 0, "edonr256", &opt.sum_flags, RHASH_EDONR256 }, { F_UFLG, 0, 0, "edonr512", &opt.sum_flags, RHASH_EDONR512 }, { F_UFLG, 'L', 0, "ed2k-link", &opt.sum_flags, OPT_ED2K_LINK }, /* output formats */ { F_UFLG, 0, 0, "sfv", &opt.fmt, FMT_SFV }, { F_UFLG, 0, 0, "bsd", &opt.fmt, FMT_BSD }, { F_UFLG, 0, 0, "simple", &opt.fmt, FMT_SIMPLE }, { F_UFLG, 'm', 0, "magnet", &opt.fmt, FMT_MAGNET }, { F_UFLG, 0, 0, "uppercase", &opt.flags, OPT_UPPERCASE }, { F_UFLG, 0, 0, "lowercase", &opt.flags, OPT_LOWERCASE }, { F_CSTR, 0, 0, "template", &opt.template_file, 0 }, { F_CSTR, 'p', 0, "printf", &opt.printf_str, 0 }, /* other options */ { F_UFLG, 'r', 'R', "recursive", &opt.flags, OPT_RECURSIVE }, { F_TFNC, 0, 0, "file-list", add_file_list, 1 }, { F_UFLG, 0, 0, "follow", &opt.flags, OPT_FOLLOW }, { F_UFLG, 'v', 0, "verbose", &opt.flags, OPT_VERBOSE }, { F_UFLG, 0, 0, "gost-reverse", &opt.flags, OPT_GOST_REVERSE }, { F_UFLG, 0, 0, "skip-ok", &opt.flags, OPT_SKIP_OK }, { F_UFLG, 'i', 0, "ignore-case", &opt.flags, OPT_IGNORE_CASE }, { F_UENC, 0, 0, "percents", &opt.flags, OPT_PERCENTS }, { F_UFLG, 0, 0, "speed", &opt.flags, OPT_SPEED }, { F_UFLG, 'e', 0, "embed-crc", &opt.flags, OPT_EMBED_CRC }, { F_CSTR, 0, 0, "embed-crc-delimiter", &opt.embed_crc_delimiter, 0 }, { F_PFNC, 0, 0, "path-separator", set_path_separator, 0 }, { F_TOUT, 'o', 0, "output", &opt.output, 0 }, { F_TOUT, 'l', 0, "log", &opt.log, 0 }, { F_PFNC, 'q', 0, "accept", add_file_suffix, MASK_ACCEPT }, { F_PFNC, 't', 0, "crc-accept", add_file_suffix, MASK_CRC_ACCEPT }, { F_PFNC, 0, 0, "exclude", add_file_suffix, MASK_EXCLUDE }, { F_VFNC, 0, 0, "video", accept_video, 0 }, { F_VFNC, 0, 0, "nya", nya, 0 }, { F_PFNC, 0, 0, "maxdepth", set_max_depth, 0 }, { F_UFLG, 0, 0, "bt-private", &opt.flags, OPT_BT_PRIVATE }, { F_PFNC, 0, 0, "bt-piece-length", set_bt_piece_length, 0 }, { F_UFNC, 0, 0, "bt-announce", bt_announce, 0 }, { F_CSTR, 0, 0, "bt-batch", &opt.bt_batch_file, 0 }, { F_UFLG, 0, 0, "benchmark-raw", &opt.flags, OPT_BENCH_RAW }, { F_PFNC, 0, 0, "openssl", openssl_flags, 0 }, #ifdef _WIN32 /* code pages (windows only) */ { F_UENC, 0, 0, "utf8", &opt.flags, OPT_UTF8 }, { F_UENC, 0, 0, "ansi", &opt.flags, OPT_ANSI }, { F_UENC, 0, 0, "oem", &opt.flags, OPT_OEM }, #endif { 0,0,0,0,0,0 } }; cmdline_opt_t cmdline_file = { F_TFNC, 0, 0, "FILE", add_file_list, 0 }; /** * Log a message and exit the program. * * @param msg the message to log */ static void die(const char* msg) { log_error(msg); rsh_exit(2); } /** * 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) { log_error(_("unknown option: %s\n"), (option_name ? option_name : "?")); rsh_exit(2); } /* 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) { log_error(_("argument is required for option %s\n"), option->name); rsh_exit(2); } #ifdef _WIN32 if (option_type == F_TOUT || option_type == F_TFNC) { /* 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 = wchar_to_cstr((wchar_t*)option->parameter, CP_UTF8, NULL); } else { /* convert from UTF-16 */ value = w2c((wchar_t*)option->parameter); } 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_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->ptr )(opts, value, o->param); break; case F_VFNC: ( ( void(*)(options_t *) )o->ptr )(opts); /* call option handler */ break; case F_PRNT: log_msg("%s", (char*)o->ptr); rsh_exit(0); break; default: assert(0); /* impossible option type */ } } /** * Search for config file. * * @return the relative path to config file */ static const char* find_conf_file(void) { #ifndef SYSCONFDIR # define SYSCONFDIR "/etc" #endif #define CONFIG_FILENAME "rhashrc" char *dir1, *path; #ifndef _WIN32 /* Linux/Unix part */ /* first check for $HOME/.rhashrc file */ if ( (dir1 = getenv("HOME")) ) { path = make_path(dir1, ".rhashrc"); if (is_regular_file(path)) { rsh_vector_add_ptr(opt.mem, path); return (conf_opt.config_file = path); } free(path); } /* then check for global config */ path = SYSCONFDIR "/" CONFIG_FILENAME; if (is_regular_file(path)) { return (conf_opt.config_file = path); } #else /* _WIN32 */ /* first check for the %APPDATA%\RHash\rhashrc config */ if ( (dir1 = getenv("APPDATA")) ) { dir1 = make_path(dir1, "RHash"); path = make_path(dir1, CONFIG_FILENAME); free(dir1); if (is_regular_file(path)) { rsh_vector_add_ptr(opt.mem, path); return (conf_opt.config_file = path); } free(path); } /* then check for %HOMEDRIVE%%HOMEPATH%\rhashrc */ /* note that %USERPROFILE% is generally not a user home dir */ if ( (dir1 = getenv("HOMEDRIVE")) && (path = getenv("HOMEPATH"))) { dir1 = make_path(dir1, path); path = make_path(dir1, CONFIG_FILENAME); free(dir1); if (is_regular_file(path)) { rsh_vector_add_ptr(opt.mem, path); return (conf_opt.config_file = path); } free(path); } /* check for ${PROGRAM_DIR}\rhashrc */ if (rhash_data.program_dir && (dir1 = w2c(rhash_data.program_dir))) { path = make_path(dir1, CONFIG_FILENAME); free(dir1); if (is_regular_file(path)) { rsh_vector_add_ptr(opt.mem, path); return (conf_opt.config_file = path); } free(path); } #endif /* _WIN32 */ return (conf_opt.config_file = NULL); /* config file not found */ } /** * 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; int res; /* initialize conf_opt and opt structures */ memset(&conf_opt, 0, sizeof(opt)); conf_opt.find_max_depth = -1; if (!find_conf_file()) return 0; fd = fopen(conf_opt.config_file, "r"); 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, *value; if (*line == 0 || IS_COMMENT(*line)) continue; /* search for '=' */ index = strcspn(line, "="); if (line[index] == 0) { log_warning(_("%s: can't parse line \"%s\"\n"), conf_opt.config_file, 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: unknown option \"%s\"\n"), conf_opt.config_file, 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; /* "--