rhash-1.3.1/0000755000175000017500000000000012263273121012474 5ustar alekseyalekseyrhash-1.3.1/file_mask.h0000644000175000017500000000115712263252342014605 0ustar alekseyaleksey/* 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.1/README0000644000175000017500000000472212155136036013364 0ustar alekseyaleksey === 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. Features: * Output in a predefined (SFV, BSD-like) or a user-defined format. * Can calculate Magnet links. * Updating hash files (adding hash sums of files missing in the hash file). * Calculates several hash sums in one pass * Ability to process directories recursively. * Portability: the program works the same on Linux, *BSD 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 http://sf.net/apps/mediawiki/rhash/index.php?title=Hash_sums * 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.1/INSTALL0000644000175000017500000000151712263252342013533 0ustar alekseyaleksey Linux Installation: =================== You need GCC (or Intel Compiler) and GNU Make. To compile and install the program just type 'make install' To test the compiled program run 'make test'. RPM package can be created by commands 'make rpm' or 'setarch i586 make rpm'. For internationalization support RHash should be compiled with gettext library make ADDCFLAGS="-DUSE_GETTEXT" To compile with openssl support use the following flags make ADDCFLAGS="-DOPENSSL_RUNTIME -rdynamic" ADDLDFLAGS="-ldl" The LibRHash static/shared library can be compiled by 'make lib-static' or 'make lib-shared' Windows Installation: ===================== You need MinGW compiler and MSYS environment. To compile the program run 'make'. Optionally you can run 'make test'. The LibRHash DLL can be created by cd librhash && make dll test-dll rhash-1.3.1/rhash_main.h0000644000175000017500000000164012263252342014761 0ustar alekseyaleksey/* rhash_main.h */ #ifndef RHASH_MAIN_H #define RHASH_MAIN_H #include #ifdef __cplusplus extern "C" { #endif /** * Runtime data. */ struct rhash_t { FILE *out; FILE *log; FILE *upd_fd; /* descriptor of a crc file to update */ int saved_console_codepage; /* saved codepage */ unsigned saved_cursor_size; char* printf_str; struct print_item *print_list; struct strbuf_t *template_text; struct rhash_context* rctx; int interrupted; /* non-zero if program was interrupted */ /* missed, ok and processed files statistics */ unsigned processed; unsigned ok; unsigned miss; uint64_t total_size; uint64_t batch_size; int error_flag; /* non-zero if any error occurred */ }; /** static variable, holding most of the runtime data */ extern struct rhash_t rhash_data; void rhash_destroy(struct rhash_t*); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* RHASH_MAIN_H */ rhash-1.3.1/po/0000755000175000017500000000000012263273121013112 5ustar alekseyalekseyrhash-1.3.1/po/gl.po0000644000175000017500000002415212155136036014063 0ustar alekseyaleksey# Galician translation for rhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the rhash package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: rhash\n" "Report-Msgid-Bugs-To: Aleksey \n" "POT-Creation-Date: 2012-11-22 00:04+0700\n" "PO-Revision-Date: 2012-06-15 18:23+0000\n" "Last-Translator: Miguel Anxo Bouzada \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-12-30 18:56+0000\n" "X-Generator: Launchpad (build 16378)\n" #. TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv #: calc_sums.c:269 #, c-format msgid "wrong embedded CRC32, should be %s\n" msgstr "" #: calc_sums.c:293 hash_update.c:358 #, c-format msgid "can't move %s to %s: %s\n" msgstr "non é posíbel mover %s cara %s: %s\n" #: calc_sums.c:341 #, c-format msgid "%s saved\n" msgstr "%s gardado\n" #: calc_sums.c:543 #, c-format msgid "file name doesn't contain a CRC32: %s\n" msgstr "o nome do ficheiro non conten un CRC32: %s\n" #: calc_sums.c:563 #, c-format msgid "" "\n" "--( Verifying %s )%s\n" msgstr "" "\n" "--( Verificando %s )%s\n" #: calc_sums.c:586 #, c-format msgid "file is binary: %s\n" msgstr "o ficheiro é binario: %s\n" #: calc_sums.c:702 #, c-format msgid "; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n" msgstr "; Xerado por %s v%s el %4u-%02u-%02u a las %02u:%02u.%02u\n" #: calc_sums.c:705 #, c-format msgid "" "; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" msgstr "" "; Escrito por Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" #: hash_check.c:481 #, c-format msgid "unknown hash in magnet link: %s\n" msgstr "hash descoñecido na ligazón magnética: %s\n" #: hash_check.c:534 #, c-format msgid "can't parse line: %s\n" msgstr "non foi posíbel analizar a liña: %s\n" #: hash_update.c:40 #, c-format msgid "Updating: %s\n" msgstr "Actualizando: %s\n" #: hash_update.c:95 #, c-format msgid "skipping binary file %s\n" msgstr "omitindo o ficheiro binario %s\n" #: hash_update.c:196 #, c-format msgid "Updated: %s\n" msgstr "Actualizado: %s\n" #: output.c:100 #, c-format msgid "Interrupted by user...\n" msgstr "Interrompido polo usuario...\n" #: output.c:134 #, c-format msgid "ERROR" msgstr "ERRO" #: output.c:139 #, c-format msgid ", size is %s should be %s" msgstr ", o tamaño é %s debería ser %s" #: output.c:144 #, c-format msgid ", embedded CRC32 should be %s" msgstr "" #: output.c:174 #, c-format msgid ", %s is %s should be %s" msgstr ", %s é %s debería ser %s" #. TRANSLATORS: use at least 3 characters to overwrite "99%" #: output.c:202 #, c-format msgid "OK \n" msgstr "Aceptar\n" #. TRANSLATORS: ERR is short for 'error' #: output.c:204 #, c-format msgid "ERR\n" msgstr "ERR\n" #: output.c:309 #, c-format msgid "" "\n" "Checking %s\n" msgstr "" "\n" "Comprobando %s\n" #: output.c:311 #, c-format msgid "" "\n" "Processing %s\n" msgstr "" "\n" "Procesando %s\n" #: output.c:477 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: output.c:516 #, c-format msgid "Everything OK\n" msgstr "Todo corecto\n" #: output.c:518 #, c-format msgid "Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n" msgstr "" "Producíronse algúns erros: Erros:%-3u Perdidos:%-3u Correctos:%-3u Total:%-" "3u\n" #: output.c:538 #, c-format msgid "Total %.3f sec, %4.2f MBps\n" msgstr "Total %.3f seg, %4.2f MBps\n" #: output.c:540 #, c-format msgid "Calculated in %.3f sec, %4.2f MBps\n" msgstr "Calculado en %.3f seg, %4.2f MBps\n" #: parse_cmdline.c:42 #, c-format msgid "" "%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" msgstr "" "%s\n" "Uso: %s [OPCIÓN...] [FICHEIRO | -]...\n" " %s --printf= [FICHEIRO | -]...\n" "\n" #: parse_cmdline.c:45 #, c-format msgid "Options:\n" msgstr "" #: parse_cmdline.c:47 msgid "Print program version and exit.\n" msgstr "" #: parse_cmdline.c:48 msgid "Print this help screen.\n" msgstr "" #: parse_cmdline.c:49 msgid "Calculate CRC32 hash sum.\n" msgstr "" #: parse_cmdline.c:50 msgid "Calculate MD4 hash sum.\n" msgstr "" #: parse_cmdline.c:51 msgid "Calculate MD5 hash sum.\n" msgstr "" #: parse_cmdline.c:52 msgid "Calculate SHA1 hash sum.\n" msgstr "" #: parse_cmdline.c:53 msgid "Calculate SHA2 hash sum.\n" msgstr "" #: parse_cmdline.c:54 msgid "Calculate TTH sum.\n" msgstr "" #: parse_cmdline.c:55 msgid "Calculate BitTorrent InfoHash.\n" msgstr "" #: parse_cmdline.c:56 msgid "Calculate AICH hash.\n" msgstr "" #: parse_cmdline.c:57 msgid "Calculate eDonkey hash sum.\n" msgstr "" #: parse_cmdline.c:58 msgid "Calculate and print eDonkey link.\n" msgstr "" #: parse_cmdline.c:59 msgid "Calculate Tiger hash sum.\n" msgstr "" #: parse_cmdline.c:60 msgid "Calculate GOST R 34.11-94 hash.\n" msgstr "" #: parse_cmdline.c:61 msgid "CryptoPro version of the GOST R 34.11-94 hash.\n" msgstr "" #: parse_cmdline.c:62 msgid "Calculate RIPEMD-160 hash.\n" msgstr "" #: parse_cmdline.c:63 msgid "Calculate HAS-160 hash.\n" msgstr "" #: parse_cmdline.c:64 msgid "Calculate EDON-R 256/512 hash.\n" msgstr "" #: parse_cmdline.c:65 msgid "Calculate SNEFRU-128/256 hash.\n" msgstr "" #: parse_cmdline.c:66 msgid "Calculate all supported hashes.\n" msgstr "" #: parse_cmdline.c:67 msgid "Check hash files specified by command line.\n" msgstr "" #: parse_cmdline.c:68 msgid "Update hash files specified by command line.\n" msgstr "" #: parse_cmdline.c:69 msgid "Rename files by inserting crc32 sum into name.\n" msgstr "" #: parse_cmdline.c:70 msgid "Verify files by crc32 sum embedded in their names.\n" msgstr "" #: parse_cmdline.c:71 msgid "List the names of supported hashes, one per line.\n" msgstr "" #: parse_cmdline.c:72 msgid "Benchmark selected algorithm.\n" msgstr "" #: parse_cmdline.c:73 msgid "Be verbose.\n" msgstr "" #: parse_cmdline.c:74 msgid "Process directories recursively.\n" msgstr "" #: parse_cmdline.c:75 msgid "Don't print OK messages for successfully verified files.\n" msgstr "" #: parse_cmdline.c:76 msgid "Ignore case of filenames when updating hash files.\n" msgstr "" #: parse_cmdline.c:77 msgid "Show percents, while calculating or checking hashes.\n" msgstr "" #: parse_cmdline.c:78 msgid "Output per-file and total processing speed.\n" msgstr "" #: parse_cmdline.c:79 msgid "Descend at most levels of directories.\n" msgstr "" #: parse_cmdline.c:80 msgid "File to output calculation or checking results.\n" msgstr "" #: parse_cmdline.c:81 msgid "File to log errors and verbose information.\n" msgstr "" #: parse_cmdline.c:82 msgid "Print hash sums, using SFV format (default).\n" msgstr "" #: parse_cmdline.c:83 msgid "Print hash sums, using BSD-like format.\n" msgstr "" #: parse_cmdline.c:84 msgid "Print hash sums, using simple format.\n" msgstr "" #: parse_cmdline.c:85 msgid "Print hash sums as magnet links.\n" msgstr "" #: parse_cmdline.c:86 msgid "Create torrent files.\n" msgstr "" #: parse_cmdline.c:88 msgid "Use Windows codepage for output (Windows only).\n" msgstr "Usa o código de páxina de Windows para a saída (só Windows).\n" #: parse_cmdline.c:90 msgid "Load a printf-like template from the \n" msgstr "Carga una platilla de tipo printf desde el \n" #: parse_cmdline.c:92 msgid "" "Format and print hash sums.\n" " See the RHash manual for details.\n" msgstr "" "Formatea e imprime sumas de comprobación (hash).\n" " Ver el manual RHash para más detalles.\n" #: parse_cmdline.c:155 #, c-format msgid "openssl option doesn't support '%s' hash\n" msgstr "a opción openssl non é compatíbel con hash «%s»\n" #: parse_cmdline.c:162 msgid "compiled without openssl support\n" msgstr "compilado sen compatibilidade openssl\n" #. TRANSLATORS: Keep secret ;) #: parse_cmdline.c:183 msgid "Purrr..." msgstr "Purrr..." #: parse_cmdline.c:198 #, c-format msgid "maxdepth parameter is not a number: %s\n" msgstr "o parámetro maxdepth non é un número: %s\n" #: parse_cmdline.c:215 #, c-format msgid "bt-piece-length parameter is not a number: %s\n" msgstr "o parámetro bt-piece-lenght non é un número: %s\n" #: parse_cmdline.c:236 msgid "wrong path-separator, use '//' instead of '/' on MSYS\n" msgstr "separador de ruta erróneo, use «//» no canto de «/» en MSYS\n" #: parse_cmdline.c:240 #, c-format msgid "path-separator is not '/' or '\\': %s\n" msgstr "o separador de ruta non é nin «/» nin «\\»: %s\n" #: parse_cmdline.c:373 #, c-format msgid "unknown option: %s" msgstr "opción descoñecida: %s" #: parse_cmdline.c:401 parse_cmdline.c:739 #, c-format msgid "argument is required for option %s\n" msgstr "precisase o argumento para a opción %s\n" #: parse_cmdline.c:529 #, c-format msgid "%s: can't parse line \"%s\"\n" msgstr "%s: non é posíbel analizar a liña «%s»\n" #: parse_cmdline.c:542 #, c-format msgid "%s: unknown option \"%s\"\n" msgstr "%s: opción «%s» descoñecida\n" #: parse_cmdline.c:663 msgid "CommandLineToArgvW failed\n" msgstr "Produciuse un fallo en CommandLineToArgvW\n" #: parse_cmdline.c:883 #, c-format msgid "Config file: %s\n" msgstr "Ficheiro de configuración: %s\n" #: parse_cmdline.c:883 msgid "None" msgstr "Ningún" #: parse_cmdline.c:891 msgid "incompatible program modes\n" msgstr "modos de programa incompatíbeis\n" #: parse_cmdline.c:896 msgid "too many formating options\n" msgstr "demasiadas opcións de formatado\n" #: rhash_main.c:131 #, c-format msgid "%s: template file is too big\n" msgstr "%s: o ficheiro de modelo é grande de máis\n" #: rhash_main.c:199 #, c-format msgid "%s v%s benchmarking...\n" msgstr "" #: rhash_main.c:207 msgid "no files/directories were specified at command line\n" msgstr "non se especificaron ficheiro/directorios na liña de ordes\n" #: rhash_main.c:211 #, c-format msgid "" "Usage: %s [OPTION...] ...\n" "\n" "Run `%s --help' for more help.\n" msgstr "" "Uso: %s [OPCIÓN...] ...\n" "\n" "Execute «%s --help» para obter máis axuda.\n" #: rhash_main.c:228 #, c-format msgid "Format string is: %s\n" msgstr "A cadea de formato é: %s\n" rhash-1.3.1/po/ru.po0000644000175000017500000003352512053307667014122 0ustar alekseyaleksey# Translation of RHash messages to Russian # Copyright (C) 2011 RHash Software Corp. # This file is distributed under the same license as the RHash package. # # Aleksey , 2011. msgid "" msgstr "" "Project-Id-Version: rhash\n" "Report-Msgid-Bugs-To: Aleksey \n" "POT-Creation-Date: 2012-11-22 00:04+0700\n" "PO-Revision-Date: 2011-09-18 09:47+0000\n" "Last-Translator: Sergey Basalaev \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2011-09-19 09:08+0000\n" "X-Generator: Launchpad (build 13980)\n" #. TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv #: calc_sums.c:269 #, c-format msgid "wrong embedded CRC32, should be %s\n" msgstr "неправильная встроенная CRC32, должна быть %s\n" #: calc_sums.c:293 hash_update.c:358 #, c-format msgid "can't move %s to %s: %s\n" msgstr "не удалось переместить %s в %s: %s\n" #: calc_sums.c:341 #, c-format msgid "%s saved\n" msgstr "%s сохранён\n" #: calc_sums.c:543 #, c-format msgid "file name doesn't contain a CRC32: %s\n" msgstr "имя файла не содержит CRC32: %s\n" #: calc_sums.c:563 #, c-format msgid "" "\n" "--( Verifying %s )%s\n" msgstr "" "\n" "--( Проверка %s )-%s\n" #: calc_sums.c:586 #, c-format msgid "file is binary: %s\n" msgstr "двоичный файл: %s\n" #: calc_sums.c:702 #, c-format msgid "; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n" msgstr "; Создано программой %s v%s %4u-%02u-%02u %02u:%02u.%02u\n" #: calc_sums.c:705 #, c-format msgid "" "; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" msgstr "" "; Написано Алексеем (Академгородок) - http://rhash.sourceforge.net/\n" ";\n" #: hash_check.c:481 #, c-format msgid "unknown hash in magnet link: %s\n" msgstr "неизвестный хэш в magnet-ссылке: %s\n" #: hash_check.c:534 #, c-format msgid "can't parse line: %s\n" msgstr "не удалось разобрать строку: %s\n" #: hash_update.c:40 #, c-format msgid "Updating: %s\n" msgstr "Обновление: %s\n" #: hash_update.c:95 #, c-format msgid "skipping binary file %s\n" msgstr "пропуск двоичного файла %s\n" #: hash_update.c:196 #, c-format msgid "Updated: %s\n" msgstr "Обновлён файл: %s\n" #: output.c:100 #, c-format msgid "Interrupted by user...\n" msgstr "Прервано пользователем...\n" #: output.c:134 #, c-format msgid "ERROR" msgstr "ОШИБКА" #: output.c:139 #, c-format msgid ", size is %s should be %s" msgstr "; размер равен %s, должен быть %s" #: output.c:144 #, c-format msgid ", embedded CRC32 should be %s" msgstr "; встроенная CRC32 сумма должна быть %s" #: output.c:174 #, c-format msgid ", %s is %s should be %s" msgstr "; %s равна, %s должна быть %s" #. TRANSLATORS: use at least 3 characters to overwrite "99%" #: output.c:202 #, c-format msgid "OK \n" msgstr "Успех \n" #. TRANSLATORS: ERR is short for 'error' #: output.c:204 #, c-format msgid "ERR\n" msgstr "ОШИБКА\n" #: output.c:309 #, c-format msgid "" "\n" "Checking %s\n" msgstr "" "\n" "Проверка %s\n" #: output.c:311 #, c-format msgid "" "\n" "Processing %s\n" msgstr "" "\n" "Обработка %s\n" #: output.c:477 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: output.c:516 #, c-format msgid "Everything OK\n" msgstr "Всё успешно проверено\n" #: output.c:518 #, c-format msgid "Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n" msgstr "" "Произошло ошибок: Несовпадений:%-3u Отсутствуют:%-3u Удачно:%-3u Всего:%-3u\n" #: output.c:538 #, c-format msgid "Total %.3f sec, %4.2f MBps\n" msgstr "Всего %.3f с, %4.2f Мбайт/с\n" #: output.c:540 #, c-format msgid "Calculated in %.3f sec, %4.2f MBps\n" msgstr "Считалось %.3f с, %4.2f Мбайт/с\n" #: parse_cmdline.c:42 #, c-format msgid "" "%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" msgstr "" "%s\n" "Синтаксис: %s [ОПЦИИ...] [ФАЙЛ | -]...\n" " %s --printf=<форматирующая строка> [ФАЙЛ | -]...\n" "\n" #: parse_cmdline.c:45 #, c-format msgid "Options:\n" msgstr "Опции:\n" #: parse_cmdline.c:47 msgid "Print program version and exit.\n" msgstr "Вывести версию программы и выйти.\n" #: parse_cmdline.c:48 msgid "Print this help screen.\n" msgstr "Вывести эту справку.\n" #: parse_cmdline.c:49 msgid "Calculate CRC32 hash sum.\n" msgstr "Вычислить хэш-сумму CRC32.\n" #: parse_cmdline.c:50 msgid "Calculate MD4 hash sum.\n" msgstr "Вычислить хэш-сумму MD4.\n" #: parse_cmdline.c:51 msgid "Calculate MD5 hash sum.\n" msgstr "Вычислить хэш-сумму MD5.\n" #: parse_cmdline.c:52 msgid "Calculate SHA1 hash sum.\n" msgstr "Вычислить хэш-сумму SHA1.\n" #: parse_cmdline.c:53 msgid "Calculate SHA2 hash sum.\n" msgstr "Вычислить указанную хэш-сумму SHA2.\n" #: parse_cmdline.c:54 msgid "Calculate TTH sum.\n" msgstr "Вычислить хэш-сумму TTH sum.\n" #: parse_cmdline.c:55 msgid "Calculate BitTorrent InfoHash.\n" msgstr "Вычислить хэш-сумму BitTorrent InfoHash.\n" #: parse_cmdline.c:56 msgid "Calculate AICH hash.\n" msgstr "Вычислить хэш-сумму AICH hash.\n" #: parse_cmdline.c:57 msgid "Calculate eDonkey hash sum.\n" msgstr "Вычислить хэш-сумму eDonkey.\n" #: parse_cmdline.c:58 msgid "Calculate and print eDonkey link.\n" msgstr "Вычислить хэш-сумму и вывести ссылку eDonkey.\n" #: parse_cmdline.c:59 msgid "Calculate Tiger hash sum.\n" msgstr "Вычислить хэш-сумму Tiger.\n" #: parse_cmdline.c:60 msgid "Calculate GOST R 34.11-94 hash.\n" msgstr "Вычислить хэш-сумму GOST R 34.11-94.\n" #: parse_cmdline.c:61 msgid "CryptoPro version of the GOST R 34.11-94 hash.\n" msgstr "Вычислить CryptoPro версию хэша GOST R 34.11-94.\n" #: parse_cmdline.c:62 msgid "Calculate RIPEMD-160 hash.\n" msgstr "Вычислить хэш-сумму RIPEMD-160.\n" #: parse_cmdline.c:63 msgid "Calculate HAS-160 hash.\n" msgstr "Вычислить хэш-сумму HAS-160.\n" #: parse_cmdline.c:64 msgid "Calculate EDON-R 256/512 hash.\n" msgstr "Вычислить хэш-сумму EDON-R 256/512.\n" #: parse_cmdline.c:65 msgid "Calculate SNEFRU-128/256 hash.\n" msgstr "Вычислить хэш-сумму SNEFRU-128/256.\n" #: parse_cmdline.c:66 msgid "Calculate all supported hashes.\n" msgstr "Вычислить все поддерживаемые хэш-суммы.\n" #: parse_cmdline.c:67 msgid "Check hash files specified by command line.\n" msgstr "Проверить хэш-файлы, указанные в командной строке.\n" #: parse_cmdline.c:68 msgid "Update hash files specified by command line.\n" msgstr "Обновить хэш-файлы, указанные в командной строке.\n" #: parse_cmdline.c:69 msgid "Rename files by inserting crc32 sum into name.\n" msgstr "Переименовать файлы, вставляя в имя хэш CRC32.\n" #: parse_cmdline.c:70 msgid "Verify files by crc32 sum embedded in their names.\n" msgstr "Проверить файлы по хэшу CRC32 в имени файла.\n" #: parse_cmdline.c:71 msgid "List the names of supported hashes, one per line.\n" msgstr "Напечатать имена всех поддерживаемых хэшей, по одному в строчку.\n" #: parse_cmdline.c:72 msgid "Benchmark selected algorithm.\n" msgstr "Запустить тест производительности выбранного алгоритма.\n" #: parse_cmdline.c:73 msgid "Be verbose.\n" msgstr "Включить подробный вывод.\n" #: parse_cmdline.c:74 msgid "Process directories recursively.\n" msgstr "Обрабатывать директории рекурсивно.\n" #: parse_cmdline.c:75 msgid "Don't print OK messages for successfully verified files.\n" msgstr "Не печатать строки «Успех» для удачно проверенных файлов.\n" #: parse_cmdline.c:76 msgid "Ignore case of filenames when updating hash files.\n" msgstr "Обновляя файлы, не учитывать регистр в именах файлов.\n" #: parse_cmdline.c:77 msgid "Show percents, while calculating or checking hashes.\n" msgstr "Показывать проценты, при вычислении и проверке хэш-сумм.\n" #: parse_cmdline.c:78 msgid "Output per-file and total processing speed.\n" msgstr "Выводить скорость обработки каждого файла.\n" #: parse_cmdline.c:79 msgid "Descend at most levels of directories.\n" msgstr "Спускаться не более чем на уровней директорий.\n" #: parse_cmdline.c:80 msgid "File to output calculation or checking results.\n" msgstr "Файл для вывода результатов вычисления и проверки хэш-сумм.\n" #: parse_cmdline.c:81 msgid "File to log errors and verbose information.\n" msgstr "Файл для вывода ошибок и подробной информации.\n" #: parse_cmdline.c:82 msgid "Print hash sums, using SFV format (default).\n" msgstr "Печатать хэш суммы в SFV формате (по-умолчанию).\n" #: parse_cmdline.c:83 msgid "Print hash sums, using BSD-like format.\n" msgstr "Печатать хэш суммы в BSD-like формате.\n" #: parse_cmdline.c:84 msgid "Print hash sums, using simple format.\n" msgstr "Печатать хэш суммы в «простом» формате.\n" #: parse_cmdline.c:85 msgid "Print hash sums as magnet links.\n" msgstr "Печатать хэш суммы в виде magnet-ссылок.\n" #: parse_cmdline.c:86 msgid "Create torrent files.\n" msgstr "Создавать torrent-файлы.\n" #: parse_cmdline.c:88 msgid "Use Windows codepage for output (Windows only).\n" msgstr "Выводить в кодовой странице Windows (только в Windows).\n" #: parse_cmdline.c:90 msgid "Load a printf-like template from the \n" msgstr "Загрузить форматирующий шаблон из файла\n" #: parse_cmdline.c:92 msgid "" "Format and print hash sums.\n" " See the RHash manual for details.\n" msgstr "" "Задать формат вывода хэш сумм.\n" " См. подробности в файле помощи RHash.\n" #: parse_cmdline.c:155 #, c-format msgid "openssl option doesn't support '%s' hash\n" msgstr "опция openssl не поддерживает хэш «%s»\n" #: parse_cmdline.c:162 msgid "compiled without openssl support\n" msgstr "скомпилровано без поддержки openssl\n" #. TRANSLATORS: Keep secret ;) #: parse_cmdline.c:183 msgid "Purrr..." msgstr "Муррр..." #: parse_cmdline.c:198 #, c-format msgid "maxdepth parameter is not a number: %s\n" msgstr "параметр опции maxdepth не число: %s\n" #: parse_cmdline.c:215 #, c-format msgid "bt-piece-length parameter is not a number: %s\n" msgstr "параметр опции bt-piece-length не число: %s\n" #: parse_cmdline.c:236 msgid "wrong path-separator, use '//' instead of '/' on MSYS\n" msgstr "неверный разделитель пути, используйте '//' вместо '/' на MSYS\n" #: parse_cmdline.c:240 #, c-format msgid "path-separator is not '/' or '\\': %s\n" msgstr "неверный разделитель пути к файлу: %s\n" #: parse_cmdline.c:373 #, c-format msgid "unknown option: %s" msgstr "неизвестная опция «%s»" #: parse_cmdline.c:401 parse_cmdline.c:739 #, c-format msgid "argument is required for option %s\n" msgstr "для опции «%s» требуется аргумент\n" #: parse_cmdline.c:529 #, c-format msgid "%s: can't parse line \"%s\"\n" msgstr "%s: не удалось разобрать строку «%s»\n" #: parse_cmdline.c:542 #, c-format msgid "%s: unknown option \"%s\"\n" msgstr "%s: неизвестная опция «%s»\n" #: parse_cmdline.c:663 msgid "CommandLineToArgvW failed\n" msgstr "сбой CommandLineToArgvW\n" #: parse_cmdline.c:883 #, c-format msgid "Config file: %s\n" msgstr "Файл конфигурации: %s\n" #: parse_cmdline.c:883 msgid "None" msgstr "отсутствует" #: parse_cmdline.c:891 msgid "incompatible program modes\n" msgstr "несовместимые режимы работы программы\n" #: parse_cmdline.c:896 msgid "too many formating options\n" msgstr "слишком много опций форматирования\n" #: rhash_main.c:131 #, c-format msgid "%s: template file is too big\n" msgstr "%s: слишком большой файл шаблона\n" #: rhash_main.c:199 #, c-format msgid "%s v%s benchmarking...\n" msgstr "%s v%s тест производительности...\n" #: rhash_main.c:207 msgid "no files/directories were specified at command line\n" msgstr "файлы/директории не указаны в командной строке\n" #: rhash_main.c:211 #, c-format msgid "" "Usage: %s [OPTION...] ...\n" "\n" "Run `%s --help' for more help.\n" msgstr "" "Синтаксис: %s [ОПЦИИ...] <ФАЙЛ>...\n" "\n" "Запустите `%s --help' для подробной справки.\n" #: rhash_main.c:228 #, c-format msgid "Format string is: %s\n" msgstr "Форматирующая строка: %s\n" rhash-1.3.1/po/de.po0000644000175000017500000002417312155136036014054 0ustar alekseyaleksey# German translation for rhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the rhash package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: rhash\n" "Report-Msgid-Bugs-To: Aleksey \n" "POT-Creation-Date: 2012-11-22 00:04+0700\n" "PO-Revision-Date: 2012-11-22 08:46+0000\n" "Last-Translator: Matthias Loidolt \n" "Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-12-30 18:56+0000\n" "X-Generator: Launchpad (build 16378)\n" #. TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv #: calc_sums.c:269 #, c-format msgid "wrong embedded CRC32, should be %s\n" msgstr "" #: calc_sums.c:293 hash_update.c:358 #, c-format msgid "can't move %s to %s: %s\n" msgstr "Verschieben von %s nach %s nicht möglich: %s\n" #: calc_sums.c:341 #, c-format msgid "%s saved\n" msgstr "%s gespeichert\n" #: calc_sums.c:543 #, c-format msgid "file name doesn't contain a CRC32: %s\n" msgstr "Dateiname enthält kein CRC32: %s\n" #: calc_sums.c:563 #, c-format msgid "" "\n" "--( Verifying %s )%s\n" msgstr "" "\n" "--(Verifiziere %s)%s\n" #: calc_sums.c:586 #, c-format msgid "file is binary: %s\n" msgstr "Datei ist binär: %s\n" #: calc_sums.c:702 #, c-format msgid "; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n" msgstr "; Erzeugt von %s v%s am %4u-%02u-%02u um %02u:%02u.%02u\n" #: calc_sums.c:705 #, c-format msgid "" "; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" msgstr "" "; Geschrieben von Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" #: hash_check.c:481 #, c-format msgid "unknown hash in magnet link: %s\n" msgstr "Unbekannter Hash in Magnet-Link: %s\n" #: hash_check.c:534 #, c-format msgid "can't parse line: %s\n" msgstr "kann Zeile nicht analysieren: %s\n" #: hash_update.c:40 #, c-format msgid "Updating: %s\n" msgstr "Aktualisierung: %s\n" #: hash_update.c:95 #, c-format msgid "skipping binary file %s\n" msgstr "Binärdatei %s wird übersprungen\n" #: hash_update.c:196 #, c-format msgid "Updated: %s\n" msgstr "Aktualisiert: %s\n" #: output.c:100 #, c-format msgid "Interrupted by user...\n" msgstr "Vom Benutzer unterbrochen...\n" #: output.c:134 #, c-format msgid "ERROR" msgstr "FEHLER" #: output.c:139 #, c-format msgid ", size is %s should be %s" msgstr ", Größe ist %s, sollte aber %s sein" #: output.c:144 #, c-format msgid ", embedded CRC32 should be %s" msgstr ", eingeschlossenes CRC32 sollte %s sein." #: output.c:174 #, c-format msgid ", %s is %s should be %s" msgstr ", %s ist %s, sollte aber %s sein" #. TRANSLATORS: use at least 3 characters to overwrite "99%" #: output.c:202 #, c-format msgid "OK \n" msgstr "OK \n" #. TRANSLATORS: ERR is short for 'error' #: output.c:204 #, c-format msgid "ERR\n" msgstr "FEHLER\n" #: output.c:309 #, c-format msgid "" "\n" "Checking %s\n" msgstr "" "\n" "Überprüfe %s\n" #: output.c:311 #, c-format msgid "" "\n" "Processing %s\n" msgstr "" "\n" "Verarbeite %s\n" #: output.c:477 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: output.c:516 #, c-format msgid "Everything OK\n" msgstr "Alles OK\n" #: output.c:518 #, c-format msgid "Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n" msgstr "" "Aufgetretene Fehler: Fehler:%-3u Verloren:%-3u Gelungen:%-3u Insgesamt:%-3u\n" #: output.c:538 #, c-format msgid "Total %.3f sec, %4.2f MBps\n" msgstr "Insgesamt %.3f Sekunden, %4.2f Mbit/s\n" #: output.c:540 #, c-format msgid "Calculated in %.3f sec, %4.2f MBps\n" msgstr "Berechnet in %.3f Sekunden, %4.2f Mbit/s\n" #: parse_cmdline.c:42 #, c-format msgid "" "%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" msgstr "" "%s\n" "Benutzung: %s [Option] [Datei | -]....\n" " %s --printf= [Datei | -]...\n" "\n" #: parse_cmdline.c:45 #, c-format msgid "Options:\n" msgstr "Optionen:\n" #: parse_cmdline.c:47 msgid "Print program version and exit.\n" msgstr "" #: parse_cmdline.c:48 msgid "Print this help screen.\n" msgstr "" #: parse_cmdline.c:49 msgid "Calculate CRC32 hash sum.\n" msgstr "Berechnen Sie die CRC32-Hashsumme\n" #: parse_cmdline.c:50 msgid "Calculate MD4 hash sum.\n" msgstr "Berechnen Sie die MD4-Hashsumme\n" #: parse_cmdline.c:51 msgid "Calculate MD5 hash sum.\n" msgstr "" #: parse_cmdline.c:52 msgid "Calculate SHA1 hash sum.\n" msgstr "" #: parse_cmdline.c:53 msgid "Calculate SHA2 hash sum.\n" msgstr "" #: parse_cmdline.c:54 msgid "Calculate TTH sum.\n" msgstr "" #: parse_cmdline.c:55 msgid "Calculate BitTorrent InfoHash.\n" msgstr "" #: parse_cmdline.c:56 msgid "Calculate AICH hash.\n" msgstr "" #: parse_cmdline.c:57 msgid "Calculate eDonkey hash sum.\n" msgstr "" #: parse_cmdline.c:58 msgid "Calculate and print eDonkey link.\n" msgstr "" #: parse_cmdline.c:59 msgid "Calculate Tiger hash sum.\n" msgstr "" #: parse_cmdline.c:60 msgid "Calculate GOST R 34.11-94 hash.\n" msgstr "" #: parse_cmdline.c:61 msgid "CryptoPro version of the GOST R 34.11-94 hash.\n" msgstr "" #: parse_cmdline.c:62 msgid "Calculate RIPEMD-160 hash.\n" msgstr "" #: parse_cmdline.c:63 msgid "Calculate HAS-160 hash.\n" msgstr "" #: parse_cmdline.c:64 msgid "Calculate EDON-R 256/512 hash.\n" msgstr "" #: parse_cmdline.c:65 msgid "Calculate SNEFRU-128/256 hash.\n" msgstr "" #: parse_cmdline.c:66 msgid "Calculate all supported hashes.\n" msgstr "" #: parse_cmdline.c:67 msgid "Check hash files specified by command line.\n" msgstr "" #: parse_cmdline.c:68 msgid "Update hash files specified by command line.\n" msgstr "" #: parse_cmdline.c:69 msgid "Rename files by inserting crc32 sum into name.\n" msgstr "" #: parse_cmdline.c:70 msgid "Verify files by crc32 sum embedded in their names.\n" msgstr "" #: parse_cmdline.c:71 msgid "List the names of supported hashes, one per line.\n" msgstr "" #: parse_cmdline.c:72 msgid "Benchmark selected algorithm.\n" msgstr "" #: parse_cmdline.c:73 msgid "Be verbose.\n" msgstr "" #: parse_cmdline.c:74 msgid "Process directories recursively.\n" msgstr "" #: parse_cmdline.c:75 msgid "Don't print OK messages for successfully verified files.\n" msgstr "" #: parse_cmdline.c:76 msgid "Ignore case of filenames when updating hash files.\n" msgstr "" #: parse_cmdline.c:77 msgid "Show percents, while calculating or checking hashes.\n" msgstr "" #: parse_cmdline.c:78 msgid "Output per-file and total processing speed.\n" msgstr "" #: parse_cmdline.c:79 msgid "Descend at most levels of directories.\n" msgstr "" #: parse_cmdline.c:80 msgid "File to output calculation or checking results.\n" msgstr "" #: parse_cmdline.c:81 msgid "File to log errors and verbose information.\n" msgstr "" #: parse_cmdline.c:82 msgid "Print hash sums, using SFV format (default).\n" msgstr "" #: parse_cmdline.c:83 msgid "Print hash sums, using BSD-like format.\n" msgstr "" #: parse_cmdline.c:84 msgid "Print hash sums, using simple format.\n" msgstr "" #: parse_cmdline.c:85 msgid "Print hash sums as magnet links.\n" msgstr "" #: parse_cmdline.c:86 msgid "Create torrent files.\n" msgstr "Torrent-Dateien erstellen.\n" #: parse_cmdline.c:88 msgid "Use Windows codepage for output (Windows only).\n" msgstr "Benutze Windows Zeichensatz zur Ausgabe (nur Windowsversion).\n" #: parse_cmdline.c:90 msgid "Load a printf-like template from the \n" msgstr "Lade eine printf-artige Vorlage aus der \n" #: parse_cmdline.c:92 msgid "" "Format and print hash sums.\n" " See the RHash manual for details.\n" msgstr "" "Gebe Hashsummen formatiert aus.\n" " Schauen sie in das RHash Handbuch, um mehr zu erfahren.\n" #: parse_cmdline.c:155 #, c-format msgid "openssl option doesn't support '%s' hash\n" msgstr "Die openssl-Option unterstützt den '%s' Hash nicht.\n" #: parse_cmdline.c:162 msgid "compiled without openssl support\n" msgstr "Wurde ohne openssl-Unterstützung kompiliert.\n" #. TRANSLATORS: Keep secret ;) #: parse_cmdline.c:183 msgid "Purrr..." msgstr "Purrr..." #: parse_cmdline.c:198 #, c-format msgid "maxdepth parameter is not a number: %s\n" msgstr "maxdepth Parameter ist keine Zahl: %s\n" #: parse_cmdline.c:215 #, c-format msgid "bt-piece-length parameter is not a number: %s\n" msgstr "bt-piece-length Parameter ist keine Zahl: %s\n" #: parse_cmdline.c:236 msgid "wrong path-separator, use '//' instead of '/' on MSYS\n" msgstr "Falsches Pfad-Trennzeichen, verwende '//' statt '/' bei MSYS\n" #: parse_cmdline.c:240 #, c-format msgid "path-separator is not '/' or '\\': %s\n" msgstr "Pfad-Trennzeichen ist nicht '/' oder '\\': %s\n" #: parse_cmdline.c:373 #, c-format msgid "unknown option: %s" msgstr "unbekannte Option: %s" #: parse_cmdline.c:401 parse_cmdline.c:739 #, c-format msgid "argument is required for option %s\n" msgstr "Argument ist erforderlich für Option %s\n" #: parse_cmdline.c:529 #, c-format msgid "%s: can't parse line \"%s\"\n" msgstr "%s: kann Zeile \"%s\" nicht analysieren.\n" #: parse_cmdline.c:542 #, c-format msgid "%s: unknown option \"%s\"\n" msgstr "%s: unbekannte Option \"%s\"\n" #: parse_cmdline.c:663 msgid "CommandLineToArgvW failed\n" msgstr "Umwandlung der Eingabe in ein Argument schlug fehl.\n" #: parse_cmdline.c:883 #, c-format msgid "Config file: %s\n" msgstr "Konfigurationsdatei: %s\n" #: parse_cmdline.c:883 msgid "None" msgstr "Keine" #: parse_cmdline.c:891 msgid "incompatible program modes\n" msgstr "Inkompatible Programmmodi\n" #: parse_cmdline.c:896 msgid "too many formating options\n" msgstr "Zu viele Formatierungsangaben\n" #: rhash_main.c:131 #, c-format msgid "%s: template file is too big\n" msgstr "%s: Vorlagendatei ist zu groß.\n" #: rhash_main.c:199 #, c-format msgid "%s v%s benchmarking...\n" msgstr "%s v%s vergleichen...\n" #: rhash_main.c:207 msgid "no files/directories were specified at command line\n" msgstr "Auf der Kommandozeile wurden keine Dateien/Verzeichnise angegeben.\n" #: rhash_main.c:211 #, c-format msgid "" "Usage: %s [OPTION...] ...\n" "\n" "Run `%s --help' for more help.\n" msgstr "" #: rhash_main.c:228 #, c-format msgid "Format string is: %s\n" msgstr "" rhash-1.3.1/po/it.po0000644000175000017500000002764512155136036014107 0ustar alekseyaleksey# Italian translation for rhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the rhash package. # # FIRST AUTHOR , 2011. # Valter Mura , 2011. msgid "" msgstr "" "Project-Id-Version: rhash\n" "Report-Msgid-Bugs-To: Aleksey \n" "POT-Creation-Date: 2012-06-15 13:08+0700\n" "PO-Revision-Date: 2012-06-15 18:22+0000\n" "Last-Translator: Valter Mura \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-11-12 15:28+0000\n" "X-Generator: Launchpad (build 16251)\n" #. TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv #: calc_sums.c:269 #, c-format msgid "wrong embedded CRC32, should be %s\n" msgstr "CRC32 incorporato non corretto, dovrebbe essere %s\n" #: calc_sums.c:293 hash_update.c:358 #, c-format msgid "can't move %s to %s: %s\n" msgstr "impossibile spostare %s in %s: %s\n" #: calc_sums.c:341 #, c-format msgid "%s saved\n" msgstr "%s salvato\n" #: calc_sums.c:543 #, c-format msgid "file name doesn't contain a CRC32: %s\n" msgstr "il nome del file non contiene un CRC32: %s\n" #: calc_sums.c:563 #, c-format msgid "" "\n" "--( Verifying %s )%s\n" msgstr "" "\n" "--( verifica in corso di %s )%s\n" #: calc_sums.c:586 #, c-format msgid "file is binary: %s\n" msgstr "il file è binario: %s\n" #: calc_sums.c:702 #, c-format msgid "; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n" msgstr "; Generato da %s v%s il %4u-%02u-%02u alle %02u:%02u.%02u\n" #: calc_sums.c:705 #, c-format msgid "" "; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" msgstr "" "; Scritto da Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" #: hash_check.c:481 #, c-format msgid "unknown hash in magnet link: %s\n" msgstr "hash sconosciuto nel magnet link: %s\n" #: hash_check.c:534 #, c-format msgid "can't parse line: %s\n" msgstr "impossibile analizzare la riga: %s\n" #: hash_update.c:40 #, c-format msgid "Updating: %s\n" msgstr "Aggiornamento in corso: %s\n" #: hash_update.c:95 #, c-format msgid "skipping binary file %s\n" msgstr "il file binario %s verrà tralasciato\n" #: hash_update.c:196 #, c-format msgid "Updated: %s\n" msgstr "Aggiornato: %s\n" #: output.c:100 #, c-format msgid "Interrupted by user...\n" msgstr "Interrotto dall'utente...\n" #: output.c:134 #, c-format msgid "ERROR" msgstr "ERRORE" #: output.c:139 #, c-format msgid ", size is %s should be %s" msgstr ", la dimensione è %s deve essere %s" #: output.c:144 #, c-format msgid ", embedded CRC32 should be %s" msgstr ", il CRC32 incorporato deve essere %s" #: output.c:174 #, c-format msgid ", %s is %s should be %s" msgstr ", %s è %s deve essere %s" #. TRANSLATORS: use at least 3 characters to overwrite "99%" #: output.c:202 #, c-format msgid "OK \n" msgstr "OK \n" #. TRANSLATORS: ERR is short for 'error' #: output.c:204 #, c-format msgid "ERR\n" msgstr "ERR\n" #: output.c:309 #, c-format msgid "" "\n" "Checking %s\n" msgstr "" "\n" "Controllo in corso di %s\n" #: output.c:311 #, c-format msgid "" "\n" "Processing %s\n" msgstr "" "\n" "Elaborazione in corso di %s\n" #: output.c:477 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: output.c:516 #, c-format msgid "Everything OK\n" msgstr "Tutto OK\n" #: output.c:518 #, c-format msgid "Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n" msgstr "" "Errori verificatisi: Errori:%-3u Persi:%-3u Riusciti:%-3u Totale:%-3u\n" #: output.c:538 #, c-format msgid "Total %.3f sec, %4.2f MBps\n" msgstr "Totale %.3f sec, %4.2f MBps\n" #: output.c:540 #, c-format msgid "Calculated in %.3f sec, %4.2f MBps\n" msgstr "Calcolato in %.3f sec, %4.2f MBps\n" #: parse_cmdline.c:42 #, c-format msgid "" "%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" msgstr "" "%s\n" "Uso: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" #: parse_cmdline.c:45 #, c-format msgid "Options:\n" msgstr "Opzioni:\n" #: parse_cmdline.c:47 msgid "Print program version and exit.\n" msgstr "Mostra la versione del programma ed esce.\n" #: parse_cmdline.c:48 msgid "Print this help screen.\n" msgstr "Mostra la schermata di questa guida.\n" #: parse_cmdline.c:49 msgid "Calculate CRC32 hash sum.\n" msgstr "Calcola la somma hash CRC32.\n" #: parse_cmdline.c:50 msgid "Calculate MD4 hash sum.\n" msgstr "Calcola la somma hash MD4.\n" #: parse_cmdline.c:51 msgid "Calculate MD5 hash sum.\n" msgstr "Calcola la somma hash MD5.\n" #: parse_cmdline.c:52 msgid "Calculate SHA1 hash sum.\n" msgstr "Calcola la somma hash SHA1.\n" #: parse_cmdline.c:53 msgid "Calculate SHA2 hash sum.\n" msgstr "Calcola la somma hash SHA2.\n" #: parse_cmdline.c:54 msgid "Calculate TTH sum.\n" msgstr "Calcola la somma TTH.\n" #: parse_cmdline.c:55 msgid "Calculate BitTorrent InfoHash.\n" msgstr "Calcola l'informazione hash BitTorrent.\n" #: parse_cmdline.c:56 msgid "Calculate AICH hash.\n" msgstr "Calcola l'hash AICH.\n" #: parse_cmdline.c:57 msgid "Calculate eDonkey hash sum.\n" msgstr "Calcola la somma hash eDonkey.\n" #: parse_cmdline.c:58 msgid "Calculate and print eDonkey link.\n" msgstr "Calcola e mostra il collegamento eDonkey.\n" #: parse_cmdline.c:59 msgid "Calculate Tiger hash sum.\n" msgstr "Calcola la somma hash Tiger.\n" #: parse_cmdline.c:60 msgid "Calculate GOST R 34.11-94 hash.\n" msgstr "Calcola l'hash GOST R 34.11-94.\n" #: parse_cmdline.c:61 msgid "CryptoPro version of the GOST R 34.11-94 hash.\n" msgstr "Versione CryptoPro dell'hash GOST R 34.11-94.\n" #: parse_cmdline.c:62 msgid "Calculate RIPEMD-160 hash.\n" msgstr "Calcola l'hash RIPEMD-160.\n" #: parse_cmdline.c:63 msgid "Calculate HAS-160 hash.\n" msgstr "Calcola l'hash HAS-160.\n" #: parse_cmdline.c:64 msgid "Calculate EDON-R 256/512 hash.\n" msgstr "Calcola l'hash EDON-R 256/512.\n" #: parse_cmdline.c:65 msgid "Calculate SNEFRU-128/256 hash.\n" msgstr "Calcola l'hash SNEFRU-128/256.\n" #: parse_cmdline.c:66 msgid "Calculate all supported hashes.\n" msgstr "Calcola tutti gli hash supportati.\n" #: parse_cmdline.c:67 msgid "Check hash files specified by command line.\n" msgstr "Verifica i file hash specificati dalla riga di comando.\n" #: parse_cmdline.c:68 msgid "Update hash files specified by command line.\n" msgstr "Aggiorna i file hash specificati dalla riga di comando.\n" #: parse_cmdline.c:69 msgid "Rename files by inserting crc32 sum into name.\n" msgstr "Rinomina i file inserendo la somma crc32 nel nome.\n" #: parse_cmdline.c:70 msgid "Verify files by crc32 sum embedded in their names.\n" msgstr "Verifica i file dalla somma crc32 incorporata nei loro nomi.\n" #: parse_cmdline.c:71 msgid "List the names of supported hashes, one per line.\n" msgstr "Elenca i nomi degli hash supportati, uno per riga.\n" #: parse_cmdline.c:72 msgid "Benchmark selected algorithm.\n" msgstr "Esegue il benchmark dell'algoritmo selezionato.\n" #: parse_cmdline.c:73 msgid "Be verbose.\n" msgstr "Modo verboso.\n" #: parse_cmdline.c:74 msgid "Process directories recursively.\n" msgstr "Elabora ricorsivamente le directory.\n" #: parse_cmdline.c:75 msgid "Don't print OK messages for successfully verified files.\n" msgstr "Non mostra i messaggi di OK per i file verificati correttamente.\n" #: parse_cmdline.c:76 msgid "Ignore case of filenames when updating hash files.\n" msgstr "" "Ignora le maiuscole dei nomi_file quando si aggiornano i file hash.\n" #: parse_cmdline.c:77 msgid "Show percents, while calculating or checking hashes.\n" msgstr "" "Mostra le percentuali durante il calcolo o il controllo degli hash.\n" #: parse_cmdline.c:78 msgid "Output per-file and total processing speed.\n" msgstr "Visualizza la velocità di elaborazione totale e per file.\n" #: parse_cmdline.c:79 msgid "Descend at most levels of directories.\n" msgstr "" "Analizza in profondità le directory fino a un massimo di livelli.\n" #: parse_cmdline.c:80 msgid "File to output calculation or checking results.\n" msgstr "File in cui restituire il calcolo o i risultati del controllo.\n" #: parse_cmdline.c:81 msgid "File to log errors and verbose information.\n" msgstr "File in cui registrare gli errori e le informazioni dettagliate.\n" #: parse_cmdline.c:82 msgid "Print hash sums, using SFV format (default).\n" msgstr "Mostra le somme hash, utilizzando il formato SFV (predefinito).\n" #: parse_cmdline.c:83 msgid "Print hash sums, using BSD-like format.\n" msgstr "Mostra le somme hash, utilizzando il formato in stile BSD.\n" #: parse_cmdline.c:84 msgid "Print hash sums, using simple format.\n" msgstr "Mostra le somme hash, utilizzando il formato semplice.\n" #: parse_cmdline.c:85 msgid "Print hash sums as magnet links.\n" msgstr "Mostra le somme hash come magnet link.\n" #: parse_cmdline.c:86 msgid "Create torrent files.\n" msgstr "Crea file torrent.\n" #: parse_cmdline.c:88 msgid "Use Windows codepage for output (Windows only).\n" msgstr "Usa il codice Windows per il risultato (solo Windows).\n" #: parse_cmdline.c:90 msgid "Load a printf-like template from the \n" msgstr "Carica un modello tipo printf dal \n" #: parse_cmdline.c:92 msgid "" "Format and print hash sums.\n" " See the RHash manual for details.\n" msgstr "" "Formatta e mostra somme hash.\n" " Consultare il manuale RHash per dettagli.\n" #: parse_cmdline.c:155 #, c-format msgid "openssl option doesn't support '%s' hash\n" msgstr "l'opzione openssl non supporta l'hash '%s'\n" #: parse_cmdline.c:162 msgid "compiled without openssl support\n" msgstr "compilato senza supporto openssl\n" #. TRANSLATORS: Keep secret ;) #: parse_cmdline.c:183 msgid "Purrr..." msgstr "Purrr..." #: parse_cmdline.c:198 #, c-format msgid "maxdepth parameter is not a number: %s\n" msgstr "il parametro maxdepth non è un numero: %s\n" #: parse_cmdline.c:215 #, c-format msgid "bt-piece-length parameter is not a number: %s\n" msgstr "il parametro bt-piece-length non è un numero: %s\n" #: parse_cmdline.c:236 msgid "wrong path-separator, use '//' instead of '/' on MSYS\n" msgstr "separatore percorso errato, usare '//' anziché '/' su MSYS\n" #: parse_cmdline.c:240 #, c-format msgid "path-separator is not '/' or '\\': %s\n" msgstr "il separatore percorso non è '/' o '\\': %s\n" #: parse_cmdline.c:373 #, c-format msgid "unknown option: %s" msgstr "opzione sconosciuta: %s" #: parse_cmdline.c:401 parse_cmdline.c:739 #, c-format msgid "argument is required for option %s\n" msgstr "è richiesto l'argomento per l'opzione %s\n" #: parse_cmdline.c:529 #, c-format msgid "%s: can't parse line \"%s\"\n" msgstr "%s: impossibile analizzare la riga \"%s\"\n" #: parse_cmdline.c:542 #, c-format msgid "%s: unknown option \"%s\"\n" msgstr "%s: opzione sconosciuta \"%s\"\n" #: parse_cmdline.c:663 msgid "CommandLineToArgvW failed\n" msgstr "CommandLineToArgvW non riuscito\n" #: parse_cmdline.c:883 #, c-format msgid "Config file: %s\n" msgstr "File di configurazione: %s\n" #: parse_cmdline.c:883 msgid "None" msgstr "Nessuno" #: parse_cmdline.c:891 msgid "incompatible program modes\n" msgstr "modalità di programma incompatibili\n" #: parse_cmdline.c:896 msgid "too many formating options\n" msgstr "troppe opzioni di formato\n" #: rhash_main.c:131 #, c-format msgid "%s: template file is too big\n" msgstr "%s: il file del modello è troppo grande\n" #: rhash_main.c:199 #, c-format msgid "%s v%s benchmarking...\n" msgstr "%s v%s benchmark in corso...\n" #: rhash_main.c:207 msgid "no files/directories were specified at command line\n" msgstr "" "nessun file o directory sono stati specificati alla riga di comando\n" #: rhash_main.c:211 #, c-format msgid "" "Usage: %s [OPTION...] ...\n" "\n" "Run `%s --help' for more help.\n" msgstr "" "Uso: %s [OPTION...] ...\n" "\n" "Avviare `%s --help' per ulteriore aiuto.\n" #: rhash_main.c:228 #, c-format msgid "Format string is: %s\n" msgstr "La stringa del formato: %s\n" rhash-1.3.1/po/es.po0000644000175000017500000002434312155136036014072 0ustar alekseyaleksey# Spanish translation for rhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the rhash package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: rhash\n" "Report-Msgid-Bugs-To: Aleksey \n" "POT-Creation-Date: 2012-11-22 00:04+0700\n" "PO-Revision-Date: 2012-11-22 08:47+0000\n" "Last-Translator: Aleksey Kravchenko \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2012-12-30 18:56+0000\n" "X-Generator: Launchpad (build 16378)\n" #. TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv #: calc_sums.c:269 #, c-format msgid "wrong embedded CRC32, should be %s\n" msgstr "" #: calc_sums.c:293 hash_update.c:358 #, c-format msgid "can't move %s to %s: %s\n" msgstr "no se puede mover %s a %s: %s\n" #: calc_sums.c:341 #, c-format msgid "%s saved\n" msgstr "%s guardado\n" #: calc_sums.c:543 #, c-format msgid "file name doesn't contain a CRC32: %s\n" msgstr "el nombre del archivo no contiene un CRC32: %s\n" #: calc_sums.c:563 #, c-format msgid "" "\n" "--( Verifying %s )%s\n" msgstr "" "\n" "--( Verificando %s )%s\n" #: calc_sums.c:586 #, c-format msgid "file is binary: %s\n" msgstr "el archivo es binario: %s\n" #: calc_sums.c:702 #, c-format msgid "; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n" msgstr "; Generado por %s v%s el %4u-%02u-%02u a las %02u:%02u.%02u\n" #: calc_sums.c:705 #, c-format msgid "" "; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" msgstr "" "; Escrito por Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" #: hash_check.c:481 #, c-format msgid "unknown hash in magnet link: %s\n" msgstr "hash desconocido en el enlace magnético: %s\n" #: hash_check.c:534 #, c-format msgid "can't parse line: %s\n" msgstr "no se pudo analizar la línea: %s\n" #: hash_update.c:40 #, c-format msgid "Updating: %s\n" msgstr "Actualizando: %s\n" #: hash_update.c:95 #, c-format msgid "skipping binary file %s\n" msgstr "omitiendo archivo binario %s\n" #: hash_update.c:196 #, c-format msgid "Updated: %s\n" msgstr "Actualizado: %s\n" #: output.c:100 #, c-format msgid "Interrupted by user...\n" msgstr "Interrumpido por el usuario...\n" #: output.c:134 #, c-format msgid "ERROR" msgstr "ERROR" #: output.c:139 #, c-format msgid ", size is %s should be %s" msgstr ", el tamaño es %s debería ser %s" #: output.c:144 #, c-format msgid ", embedded CRC32 should be %s" msgstr ", el CRC32 incrustado debería ser %s" #: output.c:174 #, c-format msgid ", %s is %s should be %s" msgstr ", %s es %s debería ser %s" #. TRANSLATORS: use at least 3 characters to overwrite "99%" #: output.c:202 #, c-format msgid "OK \n" msgstr "OK \n" #. TRANSLATORS: ERR is short for 'error' #: output.c:204 #, c-format msgid "ERR\n" msgstr "ERR\n" #: output.c:309 #, c-format msgid "" "\n" "Checking %s\n" msgstr "" "\n" "Comprobando %s\n" #: output.c:311 #, c-format msgid "" "\n" "Processing %s\n" msgstr "" "\n" "Procesando %s\n" #: output.c:477 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: output.c:516 #, c-format msgid "Everything OK\n" msgstr "Todo bien\n" #: output.c:518 #, c-format msgid "Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n" msgstr "" "Se han producido errores: Errores:%-3u Omitidos:%-3u Con éxito:%-3u Total:%-" "3u\n" #: output.c:538 #, c-format msgid "Total %.3f sec, %4.2f MBps\n" msgstr "Total %.3f seg, %4.2f MBps\n" #: output.c:540 #, c-format msgid "Calculated in %.3f sec, %4.2f MBps\n" msgstr "Calculado en %.3f seg, %4.2f MBps\n" #: parse_cmdline.c:42 #, c-format msgid "" "%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" msgstr "" "%s\n" "Uso: %s [OPCIÓN...] [ARCHIVO | -]...\n" " %s --printf= [ARCHIVO | -]...\n" "\n" #: parse_cmdline.c:45 #, c-format msgid "Options:\n" msgstr "Opciones:\n" #: parse_cmdline.c:47 msgid "Print program version and exit.\n" msgstr "Muestra la versión de programa y termina.\n" #: parse_cmdline.c:48 msgid "Print this help screen.\n" msgstr "Muestra esta ayuda.\n" #: parse_cmdline.c:49 msgid "Calculate CRC32 hash sum.\n" msgstr "" #: parse_cmdline.c:50 msgid "Calculate MD4 hash sum.\n" msgstr "" #: parse_cmdline.c:51 msgid "Calculate MD5 hash sum.\n" msgstr "" #: parse_cmdline.c:52 msgid "Calculate SHA1 hash sum.\n" msgstr "" #: parse_cmdline.c:53 msgid "Calculate SHA2 hash sum.\n" msgstr "" #: parse_cmdline.c:54 msgid "Calculate TTH sum.\n" msgstr "Calcular la suma de hash TTH.\n" #: parse_cmdline.c:55 msgid "Calculate BitTorrent InfoHash.\n" msgstr "" #: parse_cmdline.c:56 msgid "Calculate AICH hash.\n" msgstr "" #: parse_cmdline.c:57 msgid "Calculate eDonkey hash sum.\n" msgstr "" #: parse_cmdline.c:58 msgid "Calculate and print eDonkey link.\n" msgstr "" #: parse_cmdline.c:59 msgid "Calculate Tiger hash sum.\n" msgstr "" #: parse_cmdline.c:60 msgid "Calculate GOST R 34.11-94 hash.\n" msgstr "" #: parse_cmdline.c:61 msgid "CryptoPro version of the GOST R 34.11-94 hash.\n" msgstr "" #: parse_cmdline.c:62 msgid "Calculate RIPEMD-160 hash.\n" msgstr "" #: parse_cmdline.c:63 msgid "Calculate HAS-160 hash.\n" msgstr "" #: parse_cmdline.c:64 msgid "Calculate EDON-R 256/512 hash.\n" msgstr "" #: parse_cmdline.c:65 msgid "Calculate SNEFRU-128/256 hash.\n" msgstr "" #: parse_cmdline.c:66 msgid "Calculate all supported hashes.\n" msgstr "" #: parse_cmdline.c:67 msgid "Check hash files specified by command line.\n" msgstr "" #: parse_cmdline.c:68 msgid "Update hash files specified by command line.\n" msgstr "" #: parse_cmdline.c:69 msgid "Rename files by inserting crc32 sum into name.\n" msgstr "" #: parse_cmdline.c:70 msgid "Verify files by crc32 sum embedded in their names.\n" msgstr "" #: parse_cmdline.c:71 msgid "List the names of supported hashes, one per line.\n" msgstr "" #: parse_cmdline.c:72 msgid "Benchmark selected algorithm.\n" msgstr "" #: parse_cmdline.c:73 msgid "Be verbose.\n" msgstr "" #: parse_cmdline.c:74 msgid "Process directories recursively.\n" msgstr "" #: parse_cmdline.c:75 msgid "Don't print OK messages for successfully verified files.\n" msgstr "" #: parse_cmdline.c:76 msgid "Ignore case of filenames when updating hash files.\n" msgstr "" #: parse_cmdline.c:77 msgid "Show percents, while calculating or checking hashes.\n" msgstr "" #: parse_cmdline.c:78 msgid "Output per-file and total processing speed.\n" msgstr "" #: parse_cmdline.c:79 msgid "Descend at most levels of directories.\n" msgstr "" #: parse_cmdline.c:80 msgid "File to output calculation or checking results.\n" msgstr "" #: parse_cmdline.c:81 msgid "File to log errors and verbose information.\n" msgstr "" #: parse_cmdline.c:82 msgid "Print hash sums, using SFV format (default).\n" msgstr "" #: parse_cmdline.c:83 msgid "Print hash sums, using BSD-like format.\n" msgstr "" #: parse_cmdline.c:84 msgid "Print hash sums, using simple format.\n" msgstr "" #: parse_cmdline.c:85 msgid "Print hash sums as magnet links.\n" msgstr "" #: parse_cmdline.c:86 msgid "Create torrent files.\n" msgstr "" #: parse_cmdline.c:88 msgid "Use Windows codepage for output (Windows only).\n" msgstr "Usa el código de página de Windows para la salida (solo Windows).\n" #: parse_cmdline.c:90 msgid "Load a printf-like template from the \n" msgstr "Carga una platilla de tipo printf desde el \n" #: parse_cmdline.c:92 msgid "" "Format and print hash sums.\n" " See the RHash manual for details.\n" msgstr "" "Formatea e imprime sumas de comprobación (hash).\n" " Ver el manual RHash para más detalles.\n" #: parse_cmdline.c:155 #, c-format msgid "openssl option doesn't support '%s' hash\n" msgstr "la opción openssl no es compatible con el hash «%s»\n" #: parse_cmdline.c:162 msgid "compiled without openssl support\n" msgstr "compilado sin soporte openssl\n" #. TRANSLATORS: Keep secret ;) #: parse_cmdline.c:183 msgid "Purrr..." msgstr "Ronroneo..." #: parse_cmdline.c:198 #, c-format msgid "maxdepth parameter is not a number: %s\n" msgstr "el parámetro maxdepth no es un número: %s\n" #: parse_cmdline.c:215 #, c-format msgid "bt-piece-length parameter is not a number: %s\n" msgstr "el parámetro bt-piece-lenght no es un número: %s\n" #: parse_cmdline.c:236 msgid "wrong path-separator, use '//' instead of '/' on MSYS\n" msgstr "separador de ruta erróneo, usa «//» en vez de «/» en MSYS\n" #: parse_cmdline.c:240 #, c-format msgid "path-separator is not '/' or '\\': %s\n" msgstr "el separador de ruta no es ni «/» ni «\\»: %s\n" #: parse_cmdline.c:373 #, c-format msgid "unknown option: %s" msgstr "opción desconocida: %s" #: parse_cmdline.c:401 parse_cmdline.c:739 #, c-format msgid "argument is required for option %s\n" msgstr "el argumento se necesita para la opción %s\n" #: parse_cmdline.c:529 #, c-format msgid "%s: can't parse line \"%s\"\n" msgstr "%s: no se puede analizar la línea «%s»\n" #: parse_cmdline.c:542 #, c-format msgid "%s: unknown option \"%s\"\n" msgstr "%s: opción «%s» desconocida\n" #: parse_cmdline.c:663 msgid "CommandLineToArgvW failed\n" msgstr "CommandLineToArgvW ha fallado\n" #: parse_cmdline.c:883 #, c-format msgid "Config file: %s\n" msgstr "Archivo de configuración: %s\n" #: parse_cmdline.c:883 msgid "None" msgstr "Ninguno" #: parse_cmdline.c:891 msgid "incompatible program modes\n" msgstr "modos de programa incompatibles\n" #: parse_cmdline.c:896 msgid "too many formating options\n" msgstr "demasiadas opciones de formateo\n" #: rhash_main.c:131 #, c-format msgid "%s: template file is too big\n" msgstr "%s: el archivo de plantilla es demasiado grande\n" #: rhash_main.c:199 #, c-format msgid "%s v%s benchmarking...\n" msgstr "" #: rhash_main.c:207 msgid "no files/directories were specified at command line\n" msgstr "no se han especificado archivos/directorios en la línea de órdenes\n" #: rhash_main.c:211 #, c-format msgid "" "Usage: %s [OPTION...] ...\n" "\n" "Run `%s --help' for more help.\n" msgstr "" "Uso: %s [OPCION...] ...\n" "\n" "Ejecute «%s --help» para más ayuda.\n" #: rhash_main.c:228 #, c-format msgid "Format string is: %s\n" msgstr "La cadena de formato es: %s\n" rhash-1.3.1/po/en_AU.po0000644000175000017500000002643312053307667014463 0ustar alekseyaleksey# English (Australia) translation for rhash # Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 # This file is distributed under the same license as the rhash package. # FIRST AUTHOR , 2011. # msgid "" msgstr "" "Project-Id-Version: rhash\n" "Report-Msgid-Bugs-To: Aleksey \n" "POT-Creation-Date: 2012-11-22 00:04+0700\n" "PO-Revision-Date: 2011-09-25 08:15+0000\n" "Last-Translator: Joel Pickett \n" "Language-Team: English (Australia) \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Launchpad-Export-Date: 2011-09-25 19:36+0000\n" "X-Generator: Launchpad (build 14012)\n" #. TRANSLATORS: sample filename with embedded CRC32: file_[A1B2C3D4].mkv #: calc_sums.c:269 #, c-format msgid "wrong embedded CRC32, should be %s\n" msgstr "wrong embedded CRC32, should be %s\n" #: calc_sums.c:293 hash_update.c:358 #, c-format msgid "can't move %s to %s: %s\n" msgstr "can't move %s to %s: %s\n" #: calc_sums.c:341 #, c-format msgid "%s saved\n" msgstr "%s saved\n" #: calc_sums.c:543 #, c-format msgid "file name doesn't contain a CRC32: %s\n" msgstr "file name doesn't contain a CRC32: %s\n" #: calc_sums.c:563 #, c-format msgid "" "\n" "--( Verifying %s )%s\n" msgstr "" "\n" "--( Verifying %s )%s\n" #: calc_sums.c:586 #, c-format msgid "file is binary: %s\n" msgstr "file is binary: %s\n" #: calc_sums.c:702 #, c-format msgid "; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n" msgstr "; Generated by %s v%s on %4u-%02u-%02u at %02u:%02u.%02u\n" #: calc_sums.c:705 #, c-format msgid "" "; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" msgstr "" "; Written by Aleksey (Akademgorodok) - http://rhash.sourceforge.net/\n" ";\n" #: hash_check.c:481 #, c-format msgid "unknown hash in magnet link: %s\n" msgstr "unknown hash in magnet link: %s\n" #: hash_check.c:534 #, c-format msgid "can't parse line: %s\n" msgstr "can't parse line: %s\n" #: hash_update.c:40 #, c-format msgid "Updating: %s\n" msgstr "Updating: %s\n" #: hash_update.c:95 #, c-format msgid "skipping binary file %s\n" msgstr "skipping binary file %s\n" #: hash_update.c:196 #, c-format msgid "Updated: %s\n" msgstr "Updated: %s\n" #: output.c:100 #, c-format msgid "Interrupted by user...\n" msgstr "Interrupted by user...\n" #: output.c:134 #, c-format msgid "ERROR" msgstr "ERROR" #: output.c:139 #, c-format msgid ", size is %s should be %s" msgstr ", size is %s should be %s" #: output.c:144 #, c-format msgid ", embedded CRC32 should be %s" msgstr ", embedded CRC32 should be %s" #: output.c:174 #, c-format msgid ", %s is %s should be %s" msgstr ", %s is %s should be %s" #. TRANSLATORS: use at least 3 characters to overwrite "99%" #: output.c:202 #, c-format msgid "OK \n" msgstr "OK \n" #. TRANSLATORS: ERR is short for 'error' #: output.c:204 #, c-format msgid "ERR\n" msgstr "ERR\n" #: output.c:309 #, c-format msgid "" "\n" "Checking %s\n" msgstr "" "\n" "Checking %s\n" #: output.c:311 #, c-format msgid "" "\n" "Processing %s\n" msgstr "" "\n" "Processing %s\n" #: output.c:477 #, c-format msgid "%s: %s\n" msgstr "%s: %s\n" #: output.c:516 #, c-format msgid "Everything OK\n" msgstr "Everything OK\n" #: output.c:518 #, c-format msgid "Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n" msgstr "Errors Occurred: Errors:%-3u Miss:%-3u Success:%-3u Total:%-3u\n" #: output.c:538 #, c-format msgid "Total %.3f sec, %4.2f MBps\n" msgstr "Total %.3f sec, %4.2f MBps\n" #: output.c:540 #, c-format msgid "Calculated in %.3f sec, %4.2f MBps\n" msgstr "Calculated in %.3f sec, %4.2f MBps\n" #: parse_cmdline.c:42 #, c-format msgid "" "%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" msgstr "" "%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n" "\n" #: parse_cmdline.c:45 #, c-format msgid "Options:\n" msgstr "Options:\n" #: parse_cmdline.c:47 msgid "Print program version and exit.\n" msgstr "Print program version and exit.\n" #: parse_cmdline.c:48 msgid "Print this help screen.\n" msgstr "Print this help screen.\n" #: parse_cmdline.c:49 msgid "Calculate CRC32 hash sum.\n" msgstr "Calculate CRC32 hash sum.\n" #: parse_cmdline.c:50 msgid "Calculate MD4 hash sum.\n" msgstr "Calculate MD4 hash sum.\n" #: parse_cmdline.c:51 msgid "Calculate MD5 hash sum.\n" msgstr "Calculate MD5 hash sum.\n" #: parse_cmdline.c:52 msgid "Calculate SHA1 hash sum.\n" msgstr "Calculate SHA1 hash sum.\n" #: parse_cmdline.c:53 msgid "Calculate SHA2 hash sum.\n" msgstr "Calculate SHA2 hash sum.\n" #: parse_cmdline.c:54 msgid "Calculate TTH sum.\n" msgstr "Calculate TTH sum.\n" #: parse_cmdline.c:55 msgid "Calculate BitTorrent InfoHash.\n" msgstr "Calculate BitTorrent InfoHash.\n" #: parse_cmdline.c:56 msgid "Calculate AICH hash.\n" msgstr "Calculate AICH hash.\n" #: parse_cmdline.c:57 msgid "Calculate eDonkey hash sum.\n" msgstr "Calculate eDonkey hash sum.\n" #: parse_cmdline.c:58 msgid "Calculate and print eDonkey link.\n" msgstr "Calculate and print eDonkey link.\n" #: parse_cmdline.c:59 msgid "Calculate Tiger hash sum.\n" msgstr "Calculate Tiger hash sum.\n" #: parse_cmdline.c:60 msgid "Calculate GOST R 34.11-94 hash.\n" msgstr "Calculate GOST R 34.11-94 hash.\n" #: parse_cmdline.c:61 msgid "CryptoPro version of the GOST R 34.11-94 hash.\n" msgstr "CryptoPro version of the GOST R 34.11-94 hash.\n" #: parse_cmdline.c:62 msgid "Calculate RIPEMD-160 hash.\n" msgstr "Calculate RIPEMD-160 hash.\n" #: parse_cmdline.c:63 msgid "Calculate HAS-160 hash.\n" msgstr "Calculate HAS-160 hash.\n" #: parse_cmdline.c:64 msgid "Calculate EDON-R 256/512 hash.\n" msgstr "Calculate EDON-R 256/512 hash.\n" #: parse_cmdline.c:65 msgid "Calculate SNEFRU-128/256 hash.\n" msgstr "Calculate SNEFRU-128/256 hash.\n" #: parse_cmdline.c:66 msgid "Calculate all supported hashes.\n" msgstr "Calculate all supported hashes.\n" #: parse_cmdline.c:67 msgid "Check hash files specified by command line.\n" msgstr "Check hash files specified by command line.\n" #: parse_cmdline.c:68 msgid "Update hash files specified by command line.\n" msgstr "Update hash files specified by command line.\n" #: parse_cmdline.c:69 msgid "Rename files by inserting crc32 sum into name.\n" msgstr "Rename files by inserting crc32 sum into name.\n" #: parse_cmdline.c:70 msgid "Verify files by crc32 sum embedded in their names.\n" msgstr "Verify files by crc32 sum embedded in their names.\n" #: parse_cmdline.c:71 msgid "List the names of supported hashes, one per line.\n" msgstr "List the names of supported hashes, one per line.\n" #: parse_cmdline.c:72 msgid "Benchmark selected algorithm.\n" msgstr "Benchmark selected algorithm.\n" #: parse_cmdline.c:73 msgid "Be verbose.\n" msgstr "Be verbose.\n" #: parse_cmdline.c:74 msgid "Process directories recursively.\n" msgstr "Process directories recursively.\n" #: parse_cmdline.c:75 msgid "Don't print OK messages for successfully verified files.\n" msgstr "Don't print OK messages for successfully verified files.\n" #: parse_cmdline.c:76 msgid "Ignore case of filenames when updating hash files.\n" msgstr "Ignore case of filenames when updating hash files.\n" #: parse_cmdline.c:77 msgid "Show percents, while calculating or checking hashes.\n" msgstr "Show percents, while calculating or checking hashes.\n" #: parse_cmdline.c:78 msgid "Output per-file and total processing speed.\n" msgstr "Output per-file and total processing speed.\n" #: parse_cmdline.c:79 msgid "Descend at most levels of directories.\n" msgstr "Descend at most levels of directories.\n" #: parse_cmdline.c:80 msgid "File to output calculation or checking results.\n" msgstr "File to output calculation or checking results.\n" #: parse_cmdline.c:81 msgid "File to log errors and verbose information.\n" msgstr "File to log errors and verbose information.\n" #: parse_cmdline.c:82 msgid "Print hash sums, using SFV format (default).\n" msgstr "Print hash sums, using SFV format (default).\n" #: parse_cmdline.c:83 msgid "Print hash sums, using BSD-like format.\n" msgstr "Print hash sums, using BSD-like format.\n" #: parse_cmdline.c:84 msgid "Print hash sums, using simple format.\n" msgstr "Print hash sums, using simple format.\n" #: parse_cmdline.c:85 msgid "Print hash sums as magnet links.\n" msgstr "Print hash sums as magnet links.\n" #: parse_cmdline.c:86 msgid "Create torrent files.\n" msgstr "Create torrent files.\n" #: parse_cmdline.c:88 msgid "Use Windows codepage for output (Windows only).\n" msgstr "Use Windows codepage for output (Windows only).\n" #: parse_cmdline.c:90 msgid "Load a printf-like template from the \n" msgstr "Load a printf-like template from the \n" #: parse_cmdline.c:92 msgid "" "Format and print hash sums.\n" " See the RHash manual for details.\n" msgstr "" "Format and print hash sums.\n" " See the RHash manual for details.\n" #: parse_cmdline.c:155 #, c-format msgid "openssl option doesn't support '%s' hash\n" msgstr "openssl option doesn't support '%s' hash\n" #: parse_cmdline.c:162 msgid "compiled without openssl support\n" msgstr "compiled without openssl support\n" #. TRANSLATORS: Keep secret ;) #: parse_cmdline.c:183 msgid "Purrr..." msgstr "Purrr..." #: parse_cmdline.c:198 #, c-format msgid "maxdepth parameter is not a number: %s\n" msgstr "maxdepth parameter is not a number: %s\n" #: parse_cmdline.c:215 #, c-format msgid "bt-piece-length parameter is not a number: %s\n" msgstr "bt-piece-length parameter is not a number: %s\n" #: parse_cmdline.c:236 msgid "wrong path-separator, use '//' instead of '/' on MSYS\n" msgstr "wrong path-separator, use '//' instead of '/' on MSYS\n" #: parse_cmdline.c:240 #, c-format msgid "path-separator is not '/' or '\\': %s\n" msgstr "path-separator is not '/' or '\\': %s\n" #: parse_cmdline.c:373 #, c-format msgid "unknown option: %s" msgstr "unknown option: %s" #: parse_cmdline.c:401 parse_cmdline.c:739 #, c-format msgid "argument is required for option %s\n" msgstr "argument is required for option %s\n" #: parse_cmdline.c:529 #, c-format msgid "%s: can't parse line \"%s\"\n" msgstr "%s: can't parse line \"%s\"\n" #: parse_cmdline.c:542 #, c-format msgid "%s: unknown option \"%s\"\n" msgstr "%s: unknown option \"%s\"\n" #: parse_cmdline.c:663 msgid "CommandLineToArgvW failed\n" msgstr "CommandLineToArgvW failed\n" #: parse_cmdline.c:883 #, c-format msgid "Config file: %s\n" msgstr "Config file: %s\n" #: parse_cmdline.c:883 msgid "None" msgstr "None" #: parse_cmdline.c:891 msgid "incompatible program modes\n" msgstr "incompatible program modes\n" #: parse_cmdline.c:896 msgid "too many formating options\n" msgstr "too many formatting options\n" #: rhash_main.c:131 #, c-format msgid "%s: template file is too big\n" msgstr "%s: template file is too big\n" #: rhash_main.c:199 #, c-format msgid "%s v%s benchmarking...\n" msgstr "%s v%s benchmarking...\n" #: rhash_main.c:207 msgid "no files/directories were specified at command line\n" msgstr "no files/directories were specified at command line\n" #: rhash_main.c:211 #, c-format msgid "" "Usage: %s [OPTION...] ...\n" "\n" "Run `%s --help' for more help.\n" msgstr "" "Usage: %s [OPTION...] ...\n" "\n" "Run `%s --help' for more help.\n" #: rhash_main.c:228 #, c-format msgid "Format string is: %s\n" msgstr "Format string is: %s\n" rhash-1.3.1/file_set.c0000644000175000017500000001200112155136036014427 0ustar alekseyaleksey/* file_set.c */ #include /* qsort */ #include /* fopen */ #include /* ptrdiff_t */ #include #include /* isspace */ #include #include "librhash/rhash.h" #include "common_func.h" #include "hash_print.h" #include "parse_cmdline.h" #include "rhash_main.h" #include "output.h" #include "file_set.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.1/tests/0000755000175000017500000000000012263273121013636 5ustar alekseyalekseyrhash-1.3.1/tests/test_rhash.sh0000755000175000017500000002326612263252342016354 0ustar alekseyaleksey#!/bin/bash if [ "$1" = "--full" ]; then FULL_TEST=1; shift; fi [ -x "$1" ] && rhash="$(cd ${1%/*} && echo $PWD/${1##*/})" || rhash="../rhash"; cd $(dirname "$0") # chdir after getting absolute path of $1, but before checking for ../rhash [ -x "$rhash" ] || rhash="`which rhash`" if [ ! -x $rhash ]; then echo "Fatal: $rhash not found" exit 1 fi [ "$rhash" != "../rhash" ] && echo "Testing $rhash" #version="`$rhash -V|sed 's/^.* v//'`" HASHOPT="`$rhash --list-hashes|sed 's/ .*$//;s/-\([0-9R]\)/\1/'|tr A-Z a-z`" test_num=1; sub_test=0; new_test() { printf "%2u. %s" $test_num "$1" test_num=$((test_num+1)); sub_test=0; } # verify obtained value $1 against the expected value $2 check() { sub_test=$((sub_test+1)); if [ "$1" = "$2" ]; then test "$3" = "." || echo "Ok" else tt=$( test "$3" = "." -o "$sub_test" -gt 1 && echo " Subtest #$sub_test" ) echo "Failed$tt" echo "obtained: \"$1\"" echo "expected: \"$2\"" return 1; # error fi return 0; } # match obtained value $1 against given grep-regexp $2 match_line() { if echo "$1" | grep -vq "$2"; then printf "obtained: \"%s\"\n" "$1" echo "regexp: /$2/" return 1; fi return 0; } # match obtained value $1 against given grep-regexp $2 match() { sub_test=$((sub_test+1)); if echo "$1" | grep -vq "$2"; then tt=$( test "$3" = "." -o "$sub_test" -gt 1 && echo " Subtest #$sub_test" ) echo "Failed$tt" echo "obtained: \"$1\"" echo "regexp: /$2/" return 1; # error else test "$3" = "." || echo "Ok" fi return 0; } new_test "test with text string: " TEST_STR="test_string1" TEST_RESULT=$( echo -n "$TEST_STR" | $rhash -CHMETAGW --sfv - | tail -1 ) TEST_EXPECTED="(stdin) F0099E81 B78F440152DBAD00E77017074DC15417 EA8511AE2CA899D68DB423AD751B446C6F958507 R37TT7VDWGK26FUDTFANGUJBFKYDGAV4ARK3EEI 9EDCAE6F50EFE09F0837DA66A8B88C13 5KCRDLRMVCM5NDNUEOWXKG2ENRXZLBIH 01D00FBBA6A0903499385151BF678CDF4294986CF5B76A6A5660AC5834FA429E12861BC5174C7648CA4086B0FCE3F211F80423824E9A9589A20FC43A81D8B752 3D3E1DB92A2030B1287769AAD2190DD69EED5911644EC6E7BB7AEAB5FC701BE3" check "$TEST_RESULT" "$TEST_EXPECTED" new_test "test with 1Kb data file: " awk 'BEGIN{ for(i=0; i<256*4; i++) { printf("%c", i%256) } }' > test1K.data TEST_RESULT=$( $rhash --printf "%f %C %M %H %E %G %T %A %W\n" test1K.data 2>/dev/null ) TEST_EXPECTED="test1K.data B70B4C26 B2EA9F7FCEA831A4A63B213F41A8855B 5B00669C480D5CFFBDFA8BDBA99561160F2D1B77 5AE257C47E9BE1243EE32AABE408FB6B 890BB3EE5DBE4DA22D6719A14EFD9109B220607E1086C1ABBB51EEAC2B044CBB 4OQY25UN2XHIDQPV5U6BXAZ47INUCYGIBK7LFNI LMAGNHCIBVOP7PP2RPN2TFLBCYHS2G3X D606B7F44BD288759F8869D880D9D4A2F159D739005E72D00F93B814E8C04E657F40C838E4D6F9030A8C9E0308A4E3B450246250243B2F09E09FA5A24761E26B" check "$TEST_RESULT" "$TEST_EXPECTED" . # test reversed GOST hashes and verification of them TEST_RESULT=$( $rhash --simple --gost --gost-cryptopro --gost-reverse test1K.data ) TEST_EXPECTED="test1K.data bb4c042bacee51bbabc186107e6020b20991fd4ea119672da24dbe5deeb30b89 06cc52d9a7fb5137d01667d1641683620060391722a56222bb4b14ab332ec9d9" check "$TEST_RESULT" "$TEST_EXPECTED" . TEST_RESULT=$( $rhash --simple --gost --gost-cryptopro --gost-reverse test1K.data | $rhash -vc - 2>/dev/null | grep test1K.data ) match "$TEST_RESULT" "^test1K.data *OK" # Test the SFV format using test1K.data from the previous test new_test "test default format: " $rhash test1K.data | ( read l; match_line "$l" "^; Generated by RHash" read l; match_line "$l" "^; Written by" read l; match_line "$l" "^;\$" read l; match_line "$l" "^; *1024 [0-9:\.]\{8\} [0-9-]\{10\} test1K.data\$" read l; match_line "$l" "^test1K.data B70B4C26\$" ) > match_err.log [ ! -s match_err.log ] && echo "Ok" || echo "Failed" && cat match_err.log rm -f match_err.log new_test "test %x, %b, %B modifiers: " TEST_RESULT=$( echo -n "a" | $rhash -p '%f %s %xC %bc %bM %Bh %bE %bg %xT %xa %bW\n' - ) TEST_EXPECTED="(stdin) 1 E8B7BE43 5c334qy BTAXLOOA6G3KQMODTHRGS5ZGME hvfkN/qlp/zhXR3cuerq6jd2Z7g= XXSSZMY54M7EMJC6AX55XVX3EQ 2qwfhhrwprtotsekqapwmsjutqqyog2ditdkk47yjh644yxtctoq 16614B1F68C5C25EAF6136286C9C12932F4F73E87E90A273 86f7e437faa5a7fce15d1ddcb9eaeaea377667b8 RLFCMATZFLWG6ENGOIDFGH5X27YN75MUCMKF42LTYRIADUAIPNBNCG6GIVATV37WHJBDSGRZCRNFSGUSEAGVMAMV4U5UPBME7WXCGGQ" check "$TEST_RESULT" "$TEST_EXPECTED" new_test "test special characters: " TEST_RESULT=$( echo | $rhash -p '\63\1\277\x0\x1\t\\ \x34\r\n' - ) TEST_EXPECTED=$( printf '\63\1\277\\x0\1\t\\ 4\r\n' ) check "$TEST_RESULT" "$TEST_EXPECTED" new_test "test eDonkey link: " TEST_RESULT=$( echo -n "a" | $rhash -p '%f %L %l\n' - ) TEST_EXPECTED="(stdin) ed2k://|file|(stdin)|1|BDE52CB31DE33E46245E05FBDBD6FB24|h=Q336IN72UWT7ZYK5DXOLT2XK5I3XMZ5Y|/ ed2k://|file|(stdin)|1|bde52cb31de33e46245e05fbdbd6fb24|h=q336in72uwt7zyk5dxolt2xk5i3xmz5y|/" check "$TEST_RESULT" "$TEST_EXPECTED" . # here we should test checking of ed2k links but it is currently unsupported TEST_RESULT=$( $rhash -L test1K.data | $rhash -vc - 2>/dev/null | grep test1K.data ) match "$TEST_RESULT" "^test1K.data *OK" if [ "$FULL_TEST" = 1 ]; then new_test "test all hash options: " errors=0 for opt in $HASHOPT ; do TEST_RESULT=$( echo -n "a" | $rhash --$opt --simple - ) match "$TEST_RESULT" "\b[0-9a-z]\{8,128\}\b" . || errors=$((errors+1)) # TEST_RESULT=$( echo -n "a" | $rhash --$opt --sfv - | grep -v '^;' ) # match "$TEST_RESULT" "\b[0-9a-zA-Z]\{8,128\}\b" . || errors=$((errors+1)) # TEST_RESULT=$( echo -n "a" | $rhash --$opt --bsd - ) # match "$TEST_RESULT" "\b[0-9a-z]\{8,128\}$" . || errors=$((errors+1)) done check $errors 0 fi new_test "test checking all hashes: " TEST_RESULT=$( $rhash --simple -a test1K.data | $rhash -vc - 2>/dev/null | grep test1K.data ) match "$TEST_RESULT" "^test1K.data *OK" new_test "test checking magnet link: " TEST_RESULT=$( $rhash --magnet -a test1K.data | $rhash -vc - 2>&1 | grep -i '\(warn\|test1K.data\)' ) TEST_EXPECTED="^test1K.data *OK" match "$TEST_RESULT" "$TEST_EXPECTED" new_test "test bsd format checking: " TEST_RESULT=$( $rhash --bsd -a test1K.data | $rhash -vc - 2>&1 | grep -i '\(warn\|err\)' ) check "$TEST_RESULT" "" new_test "test checking w/o filename: " $rhash -p '%c\n%m\n%e\n%h\n%g\n%t\n%a\n' test1K.data > test1K.data.hash TEST_RESULT=$( $rhash -vc test1K.data.hash 2>&1 | grep -i '\(warn\|err\)' ) TEST_EXPECTED="" check "$TEST_RESULT" "$TEST_EXPECTED" new_test "test checking embedded crc: " echo -n 'A' > 'test_[D3D99E8B].data' && echo -n 'A' > 'test_[D3D99E8C].data' # first verify checking an existing crc32 while '--embed-crc' option is set TEST_RESULT=$( $rhash -C --simple 'test_[D3D99E8B].data' | $rhash -vc --embed-crc - 2>/dev/null | grep data ) match "$TEST_RESULT" "^test_.*OK" . TEST_RESULT=$( $rhash -C --simple 'test_[D3D99E8C].data' | $rhash -vc --embed-crc - 2>/dev/null | grep data ) match "$TEST_RESULT" "^test_.*ERROR, embedded CRC32 should be" . # second verify --check-embedded option TEST_RESULT=$( $rhash --check-embedded 'test_[D3D99E8B].data' 2>/dev/null | grep data ) match "$TEST_RESULT" "test_.*OK" . TEST_RESULT=$( $rhash --check-embedded 'test_[D3D99E8C].data' 2>/dev/null | grep data ) match "$TEST_RESULT" "test_.*ERR" . mv 'test_[D3D99E8B].data' 'test.data' # at last test --embed-crc with --embed-crc-delimiter options TEST_RESULT=$( $rhash --simple --embed-crc --embed-crc-delimiter=_ 'test.data' 2>/dev/null ) check "$TEST_RESULT" "d3d99e8b test_[D3D99E8B].data" rm 'test_[D3D99E8B].data' 'test_[D3D99E8C].data' new_test "test wrong sums detection: " echo -n WRONG | $rhash -p '%c\n%m\n%e\n%h\n%g\n%t\n%a\n%w\n' - > test1K.data.hash TEST_RESULT=$( $rhash -vc test1K.data.hash 2>&1 | grep 'OK' ) check "$TEST_RESULT" "" rm test1K.data.hash new_test "test *accept options: " rm -rf test_dir/ mkdir test_dir 2>/dev/null && touch test_dir/file.txt test_dir/file.bin if [ -n "$MSYSTEM" ]; then SLASH=//; else SLASH="/"; fi # correctly handle MSYS posix path conversion TEST_RESULT=$( $rhash -rC --simple --accept=.bin --path-separator=$SLASH test_dir ) check "$TEST_RESULT" "00000000 test_dir/file.bin" . TEST_RESULT=$( $rhash -rC --simple --accept=.txt --path-separator=\\ test_dir ) check "$TEST_RESULT" "00000000 test_dir\\file.txt" . # test --crc-accept and also --path-separator options # note: path-separator doesn't affect the following '( Verifying )' message TEST_RESULT=$( $rhash -rc --crc-accept=.bin test_dir 2>/dev/null | sed -n '/Verifying/s/-//gp' ) match "$TEST_RESULT" "( Verifying test_dir.file\\.bin )" rm -rf test_dir/ new_test "test ignoring of log files: " touch test_file1.out test_file2.out TEST_RESULT=$( $rhash -C --simple test_file1.out test_file2.out -o test_file1.out -l test_file2.out 2>/dev/null ) check "$TEST_RESULT" "" . TEST_RESULT=$( $rhash -c test_file1.out test_file2.out -o test_file1.out -l test_file2.out 2>/dev/null ) check "$TEST_RESULT" "" rm test_file1.out test_file2.out new_test "test creating torrent file: " TEST_RESULT=$( $rhash --btih --torrent --bt-private --bt-piece-length=512 --bt-announce=http://tracker.org/ 'test1K.data' 2>/dev/null ) check "$TEST_RESULT" "29f7e9ef0f41954225990c513cac954058721dd2 test1K.data" rm test1K.data.torrent # Big file test new_test "test with 512 KiB of data: " TEST_512K_RESULT=$( awk 'BEGIN{ for(i=256*2048-1; i>=0; i--) { printf("%c", i%256); } }' | $rhash --simple -CHMETAGW - ) TEST_512K_EXPECTED="(stdin) f26e5571 56591858ed59c3122cdeaeb5d32d3592 f629b470578236e1b0edb96028eb9af728cc27fc vkg7atf26rt5at4jry63lhxmjn5dotww4xedslq 56fd3c004775bc0c667f3f5e23a092f9 6gnw6lf6ve5hdxxytdhhfjiyhm3m66w7 e8843c19609f0b72cb25e4c5b1a1ddfe7078972d89ab78f980b3f6c711f9cabfcbf3ac5e66661d9638a82d96ed5b51dc34e27d402c35cbb296d01cb31976af5d 2cdbbbd51999052cc783637bd28d52e20ced0fb75a908401e696a5fd085157ec" check "$TEST_512K_RESULT" "$TEST_512K_EXPECTED" rm -f test1K.data rhash-1.3.1/Makefile0000644000175000017500000003046012263271535014146 0ustar alekseyaleksey# Sample usage: # compile with debug info: make CFLAGS=-g # compile for pentiumpro: make CFLAGS="-O2 -DNDEBUG -march=i586 -mcpu=pentiumpro -fomit-frame-pointer" # create rpm with statically linked program: make rpm ADDLDFLAGS="-static -s -Wl,--gc-sections" VERSION = 1.3.1 PREFIX = /usr/local CC = gcc # using OPTFLAGS/OPTLDFLAGS for compatibilty with old scripts using this makefile OPTFLAGS = -O2 -DNDEBUG -fomit-frame-pointer -ffunction-sections -fdata-sections OPTLDFLAGS = CFLAGS = $(OPTFLAGS) LDFLAGS = $(OPTLDFLAGS) ADDCFLAGS = ADDLDFLAGS = ALLCFLAGS = -pipe $(CFLAGS) $(ADDCFLAGS) \ -Wall -W -Wstrict-prototypes -Wnested-externs -Winline -Wpointer-arith \ -Wbad-function-cast -Wmissing-prototypes -Wmissing-declarations LDLIBRHASH = -Llibrhash -lrhash ALLLDFLAGS = $(LDLIBRHASH) $(LDFLAGS) $(ADDLDFLAGS) SHAREDLIB = librhash/librhash.so.0 SHRDLFLAGS = $(SHAREDLIB) $(LDFLAGS) $(ADDLDFLAGS) HEADERS = calc_sums.h hash_print.h common_func.h hash_update.h file_mask.h file_set.h find_file.h hash_check.h output.h parse_cmdline.h rhash_main.h win_utils.h version.h SOURCES = calc_sums.c hash_print.c common_func.c hash_update.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_mask.o file_set.o find_file.o hash_check.o output.o parse_cmdline.o rhash_main.o win_utils.o OUTDIR = PROGNAME = rhash TARGET = $(OUTDIR)$(PROGNAME) SHARED_TRG = $(TARGET)_shared SYMLINKS = sfv-hash tiger-hash tth-hash whirlpool-hash has160-hash gost-hash ed2k-link magnet-link SPECFILE = dist/rhash.spec LIN_DIST_FILES = Makefile ChangeLog INSTALL COPYING README \ $(SPECFILE) $(SPECFILE).in $(SOURCES) $(HEADERS) tests/test_rhash.sh \ dist/rhash.1 dist/rhash.1.win.sed dist/rhash.1.html WIN_DIST_FILES = dist/MD5.bat dist/magnet.bat dist/rhashrc.sample WIN_SRC_FILES = win32/dirent.h win32/stdint.h win32/unistd.h win32/platform-dependent.h \ win32/vc-2010/rhash.vcxproj LIBRHASH_FILES = librhash/algorithms.c librhash/algorithms.h \ librhash/byte_order.c librhash/byte_order.h librhash/rhash_timing.c librhash/rhash_timing.h \ librhash/plug_openssl.c librhash/plug_openssl.h librhash/rhash.c librhash/rhash.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.c librhash/util.h librhash/config.h librhash/Makefile I18N_FILES = po/de.po po/en_AU.po po/es.po po/gl.po po/it.po po/ru.po DIST_FILES = $(LIN_DIST_FILES) $(LIBRHASH_FILES) $(WIN_DIST_FILES) $(WIN_SRC_FILES) $(I18N_FILES) DESTDIR = BINDIR = $(PREFIX)/bin MANDIR = $(PREFIX)/share/man LOCALEDIR = $(PREFIX)/share/locale RPMTOP = rpms RPMDIRS = SOURCES SPECS BUILD SRPMS RPMS LIBRHASH = librhash/librhash.a # Set variables according to GNU coding standard INSTALL = install INSTALL_PROGRAM = $(INSTALL) -m 755 INSTALL_DATA = $(INSTALL) -m 644 all: $(TARGET) build-shared: $(SHARED_TRG) lib-shared: $(SHAREDLIB) lib-static: $(LIBRHASH) install: all install-binary install-data install-symlinks install-shared: $(SHARED_TRG) install-shared-binary install-data install-symlinks uninstall: uninstall-binary uninstall-data uninstall-symlinks # creating archives WIN_SUFFIX = win32 ARCHIVE_BZIP = rhash-$(VERSION)-src.tar.bz2 ARCHIVE_GZIP = rhash-$(VERSION)-src.tar.gz ARCHIVE_FULL = rhash-$(VERSION)-full-src.tar.gz ARCHIVE_DEB_GZ = rhash_$(VERSION).orig.tar.gz ARCHIVE_7Z = rhash-$(VERSION)-src.tar.7z ARCHIVE_ZIP = rhash-$(VERSION)-$(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) install-binary: $(INSTALL) -d $(DESTDIR)$(BINDIR) $(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BINDIR) # install dynamically linked binary install-shared-binary: $(INSTALL) -d $(DESTDIR)$(BINDIR) $(INSTALL_PROGRAM) $(SHARED_TRG) $(DESTDIR)$(BINDIR)/rhash install-data: $(INSTALL) -d $(DESTDIR)$(MANDIR)/man1 $(DESTDIR)/etc $(INSTALL_DATA) dist/rhash.1 $(DESTDIR)$(MANDIR)/man1/rhash.1 sed -e 's/\x0D//g' dist/rhashrc.sample > rhashrc && $(INSTALL_DATA) rhashrc $(DESTDIR)/etc/rhashrc rm -f rhashrc # dependencies should be properly set, otherwise 'make -j' can run install targets in parallel install-symlinks: for f in $(SYMLINKS); do ln -fs rhash $(DESTDIR)$(BINDIR)/$$f; done cd $(DESTDIR)$(MANDIR)/man1 && for f in $(SYMLINKS); do ln -fs rhash.1* $$f.1; done uninstall-binary: rm -f $(DESTDIR)$(BINDIR)/$(PROGNAME) uninstall-data: rm -f $(DESTDIR)$(MANDIR)/man1/rhash.1 uninstall-symlinks: for f in $(SYMLINKS); do rm -f $(DESTDIR)$(BINDIR)/$$f; done install-lib-static: $(LIBRHASH) +make -C librhash install-lib-static install-lib-shared: $(SHAREDLIB) +make -C librhash install-lib-shared $(SHAREDLIB): +make -C librhash lib-shared $(LIBRHASH): $(LIBRHASH_FILES) +make -C librhash lib-static test-static-lib: $(LIBRHASH) +make -C librhash test-static test-shared-lib: $(SHAREDLIB) +make -C librhash test-shared test-libs: $(LIBRHASH) $(SHAREDLIB) +make -C librhash test-static test-shared test: test-static test-static: $(TARGET) chmod +x tests/test_$(PROGNAME).sh tests/test_$(PROGNAME).sh test-shared: $(SHARED_TRG) test-shared-lib chmod +x tests/test_$(PROGNAME).sh LD_LIBRARY_PATH=../librhash:$(LD_LIBRARY_PATH) tests/test_rhash.sh ./$(SHARED_TRG) version.h: Makefile echo "#define VERSION \"$(VERSION)\"" > version.h # check version check: version.h grep -q '\* === Version $(VERSION) ===' ChangeLog grep -q '^#define VERSION "$(VERSION)"' version.h [ ! -d bindings -o bindings/version.properties -nt Makefile ] || \ echo "version=$(VERSION)" > bindings/version.properties [ -s dist/rhash.1.html ] $(TARGET): $(OBJECTS) $(LIBRHASH) $(CC) $(OBJECTS) -o $@ $(ALLLDFLAGS) $(SHARED_TRG): $(OBJECTS) $(SHAREDLIB) $(CC) $(OBJECTS) -o $(SHARED_TRG) $(SHRDLFLAGS) # 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 common_func.h librhash/util.h librhash/hex.h \ librhash/rhash.h librhash/rhash_timing.h parse_cmdline.h rhash_main.h \ file_set.h calc_sums.h hash_check.h hash_print.h output.h win_utils.h \ version.h $(CC) -c $(ALLCFLAGS) $< -o $@ common_func.o: common_func.c common_func.h librhash/util.h librhash/hex.h \ win_utils.h parse_cmdline.h $(CC) -c $(ALLCFLAGS) $< -o $@ hash_print.o: hash_print.c common_func.h librhash/util.h librhash/hex.h \ librhash/byte_order.h calc_sums.h librhash/rhash.h hash_check.h \ parse_cmdline.h hash_print.h $(CC) -c $(ALLCFLAGS) $< -o $@ hash_update.o: hash_update.c common_func.h librhash/util.h \ librhash/rhash_timing.h win_utils.h parse_cmdline.h output.h rhash_main.h \ file_set.h calc_sums.h librhash/rhash.h hash_check.h file_mask.h \ hash_update.h $(CC) -c $(ALLCFLAGS) $< -o $@ file_mask.o: file_mask.c common_func.h librhash/util.h file_mask.h $(CC) -c $(ALLCFLAGS) $< -o $@ file_set.o: file_set.c librhash/hex.h librhash/crc32.h common_func.h \ librhash/util.h hash_print.h parse_cmdline.h rhash_main.h output.h \ file_set.h calc_sums.h librhash/rhash.h hash_check.h $(CC) -c $(ALLCFLAGS) $< -o $@ find_file.o: find_file.c common_func.h librhash/util.h win_utils.h \ find_file.h $(CC) -c $(ALLCFLAGS) $< -o $@ hash_check.o: hash_check.c librhash/hex.h librhash/byte_order.h \ librhash/rhash.h output.h parse_cmdline.h hash_print.h hash_check.h $(CC) -c $(ALLCFLAGS) $< -o $@ output.o: output.c common_func.h librhash/util.h librhash/rhash.h \ calc_sums.h hash_check.h parse_cmdline.h rhash_main.h output.h $(CC) -c $(ALLCFLAGS) $< -o $@ parse_cmdline.o: parse_cmdline.c common_func.h librhash/util.h \ librhash/rhash.h librhash/plug_openssl.h win_utils.h file_mask.h \ hash_print.h output.h rhash_main.h version.h parse_cmdline.h $(CC) -c $(ALLCFLAGS) $< -o $@ rhash_main.o: rhash_main.c common_func.h librhash/util.h \ librhash/rhash_timing.h win_utils.h find_file.h file_set.h calc_sums.h \ librhash/rhash.h hash_check.h hash_update.h file_mask.h hash_print.h \ parse_cmdline.h output.h version.h rhash_main.h $(CC) -c $(ALLCFLAGS) $< -o $@ win_utils.o: win_utils.c common_func.h librhash/util.h parse_cmdline.h \ rhash_main.h win_utils.h $(CC) -c $(ALLCFLAGS) $< -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=Animegorodok -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 tests/test_$(PROGNAME).sh clean-bindings: +make -C bindings distclean copy-dist: $(DIST_FILES) permissions rm -rf $(PROGNAME)-$(VERSION) mkdir $(PROGNAME)-$(VERSION) cp -rl --parents $(DIST_FILES) $(PROGNAME)-$(VERSION)/ gzip: check +make copy-dist tar czf $(ARCHIVE_GZIP) $(PROGNAME)-$(VERSION)/ rm -rf $(PROGNAME)-$(VERSION) gzip-bindings: +make -C bindings gzip ARCHIVE_GZIP=../rhash-bindings-$(VERSION)-src.tar.gz gzip-full: check clean-bindings +make copy-dist +make -C bindings copy-dist COPYDIR=../$(PROGNAME)-$(VERSION)/bindings tar czf $(ARCHIVE_FULL) $(PROGNAME)-$(VERSION)/ rm -rf $(PROGNAME)-$(VERSION) bzip: check +make copy-dist tar cjf $(ARCHIVE_BZIP) $(PROGNAME)-$(VERSION)/ rm -rf $(PROGNAME)-$(VERSION) 7z: check +make copy-dist tar cf - $(PROGNAME)-$(VERSION)/ | 7zr a -si $(ARCHIVE_7Z) rm -rf $(PROGNAME)-$(VERSION) $(ARCHIVE_ZIP): $(WIN_DIST_FILES) dist/rhash.1.win.html [ -s dist/rhash.1.win.html -a -x $(TARGET) ] -rm -rf $(WIN_ZIP_DIR) mkdir $(WIN_ZIP_DIR) cp $(TARGET).exe ChangeLog $(WIN_DIST_FILES) $(WIN_ZIP_DIR)/ cp dist/rhash.1.win.html $(WIN_ZIP_DIR)/rhash-doc.html # -[ -f $(OUTDIR)libeay32.dll ] && cp $(OUTDIR)libeay32.dll $(WIN_ZIP_DIR)/ zip -9r $(ARCHIVE_ZIP) $(WIN_ZIP_DIR) rm -rf $(WIN_ZIP_DIR) $(ARCHIVE_DEB_GZ) : $(DIST_FILES) +make $(ARCHIVE_GZIP) mv -f $(ARCHIVE_GZIP) $(ARCHIVE_DEB_GZ) # rpm packaging $(SPECFILE): $(SPECFILE).in Makefile 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) distclean: clean clean: +make -C librhash clean rm -f *.o $(SHARED_TRG) $(TARGET) rm -f po/*.gmo po/*.po~ update-po: xgettext *.c -k_ -cTRANSLATORS -o po/rhash.pot \ --msgid-bugs-address='Aleksey ' --package-name='RHash' for f in po/*.po; do \ msgmerge -U $$f po/rhash.pot; \ done compile-gmo: for f in po/*.po; do \ g=`basename $$f .po`; \ msgfmt $$f -o po/$$g.gmo; \ done install-gmo: compile-gmo for f in po/*.gmo; do \ l=`basename $$f .gmo`; \ $(INSTALL) -d $(DESTDIR)$(LOCALEDIR)/$$l/LC_MESSAGES; \ $(INSTALL_DATA) -T $$f $(DESTDIR)$(LOCALEDIR)/$$l/LC_MESSAGES/rhash.mo; \ done .PHONY: all install uninstall lib-shared lib-static dist dist-full zip \ test test-static test-shared test-libs test-static-lib test-shared-lib \ check copy-dist gzip gzip-bindings gzip-full bzip 7z zip clean clean-bindings \ update-po compile-gmo install-gmo rhash-1.3.1/hash_check.h0000644000175000017500000000374711740576066014755 0ustar alekseyaleksey/* 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_be; /* 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); /* 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.1/file_set.h0000644000175000017500000000224611630572174014452 0ustar alekseyaleksey/* 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.1/version.h0000644000175000017500000000003012263271543014331 0ustar alekseyaleksey#define VERSION "1.3.1" rhash-1.3.1/COPYING0000644000175000017500000000135712263262624013543 0ustar alekseyaleksey 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.1/hash_print.h0000644000175000017500000000146311702333250015005 0ustar alekseyaleksey/* hash_print.h - functions to print hash sums */ #ifndef HASH_PRINT_H #define HASH_PRINT_H #ifdef __cplusplus extern "C" { #endif typedef struct print_item { struct print_item *next; unsigned flags; unsigned hash_id; unsigned width; const char *data; } print_item; 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 strbuf_t; 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); void init_hash_info_table(void); void init_printf_format(struct strbuf_t* out); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* HASH_PRINT_H */ rhash-1.3.1/dist/0000755000175000017500000000000012263273121013437 5ustar alekseyalekseyrhash-1.3.1/dist/rhash.10000644000175000017500000002341012052450726014632 0ustar alekseyaleksey.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, 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 formating 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 formating 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 "\-\-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" Process 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 calculate sums for. .IP "\-t, \-\-crc\-accept=" Comma\(hydelimited list of crc files extensions. .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" Set tracker announcement url for torrent file. Note that this url doesn't change 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 formated 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}, %{sha224}, %{sha256}, %{sha384}, %{sha512}, %{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}, %{Sha512}. .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 formated as .RS variable = value .RE where the .I variable can be a text part of any command line option, like .I magnet, .I printf, .I percents, etc. Simple boolean values can be set using `1', `on' or `yes'. 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.1/dist/rhash.spec.in0000644000175000017500000001467012263271611016037 0ustar alekseyaleksey%define version @VERSION@ # major is the part of the shared library name after the .so %define major 0 %define libname %mklibname rhash %{major} %define devlibname %mklibname -d rhash %define is_mandrake %(test -e /etc/mandrake-release && echo 1 || echo 0) %define is_suse %(test -e /etc/SuSE-release && echo 1 || echo 0) %define is_fedora %(test -e /etc/fedora-release && echo 1 || echo 0) Summary: Utility for computing hash sums and creating magnet links. Name: rhash Version: %{version} Release: 1 Copyright: MIT Group: Applications/File 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, libopenssl1.0.0-devel %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 %{__make} build-shared lib-static CFLAGS="$RPM_OPT_FLAGS -DNDEBUG -DUSE_OPENSSL -DOPENSSL_RUNTIME -rdynamic" LDFLAGS=-ldl %check %{__make} test-shared CFLAGS="$RPM_OPT_FLAGS -DNDEBUG" %install %{__make} install-shared install-lib-static install-lib-shared PREFIX=/usr DESTDIR="$RPM_BUILD_ROOT" MANDIR="%{_mandir}" LIBDIR="%{_libdir}" %clean rm -rf "$RPM_BUILD_ROOT" %files %defattr(-,root,root) %doc COPYING README ChangeLog dist/rhash.1.html /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 * Wed Jan 08 2014 Aleksey 1.3.1-1mdk * Tue Jun 11 2013 Aleksey 1.3.0-1mdk * Tue Dec 25 2012 Aleksey 1.2.10-1mdk * Sat Apr 14 2012 Aleksey 1.2.9-1mdk * Wed Sep 14 2011 Aleksey 1.2.8-1mdk * Sun Aug 14 2011 Aleksey 1.2.7-1mdk * Tue Jun 14 2011 Aleksey 1.2.6-1mdk * Wed May 18 2011 Aleksey 1.2.5-1mdk * Fri Apr 15 2011 Aleksey 1.2.4-1mdk * Sun Mar 27 2011 Aleksey 1.2.3-1mdk * Fri Jan 14 2011 Aleksey 1.2.2-1mdk * Tue Dec 14 2010 Aleksey 1.2.1-1mdk * Sun Nov 14 2010 Aleksey 1.2.0-1mdk * Fri Oct 15 2010 Aleksey 1.1.9-1mdk * Wed Apr 14 2010 Aleksey 1.1.8-1mdk * Wed Mar 31 2010 Aleksey 1.1.7-1mdk * Wed Feb 24 2010 Aleksey 1.1.6-1mdk * Thu Jan 28 2010 Aleksey 1.1.5-1mdk * Mon Dec 14 2009 Aleksey 1.1.4-1mdk * Sun Nov 29 2009 Aleksey 1.1.3-1mdk * Mon Jun 15 2009 Aleksey 1.1.2-1mdk * Mon Mar 23 2009 Aleksey 1.1.1-1mdk * Sat Mar 14 2009 Aleksey 1.1.0-1mdk * Sat Feb 14 2009 Aleksey 1.0.8-1mdk * Sun Dec 14 2008 Aleksey 1.0.7-1mdk * Fri Nov 14 2008 Aleksey 1.0.6-1mdk * Sun Sep 14 2008 Aleksey 1.0.5-1mdk * Wed Jul 9 2008 Aleksey 1.0.4-1mdk * Sat Jun 28 2008 Aleksey 1.0.3-1mdk * Sat Jun 14 2008 Aleksey 1.0.2-1mdk * Wed May 15 2008 Aleksey 1.0.1-1mdk * Fri Dec 14 2007 Aleksey 1.0-1mdk * Thu Sep 13 2007 Aleksey 0.9.2-1mdk * Sun May 27 2007 Aleksey 0.9.1-1mdk * Sun May 13 2007 Aleksey 0.9-1mdk * Fri May 11 2007 Aleksey 0.8.9-1mdk * Wed May 02 2007 Aleksey 0.8.8-1mdk * Mon Apr 16 2007 Aleksey 0.8.7-1mdk * Mon Mar 26 2007 Aleksey 0.8.6-1mdk * Wed Jan 31 2007 Aleksey 0.8.5-1mdk * Sun Nov 05 2006 Aleksey 0.8.4-1mdk * Mon Apr 10 2006 Aleksey 0.8.3-1mdk * Thu Mar 30 2006 Aleksey 0.8.2-1mdk * Wed Jan 25 2006 Aleksey 0.8.1-1mdk * Mon Jan 23 2006 Aleksey 0.8-1mdk * Sat Jan 14 2006 Aleksey 0.7-1mdk * Fri Sep 02 2005 Aleksey 0.6-1mdk * Sun Aug 14 2005 Aleksey 0.5-1mdk The first public version rhash-1.3.1/dist/rhash.1.html0000644000175000017500000003151112052746163015601 0ustar alekseyaleksey RHASH(1) manual page Table of Contents

Name

rhash - calculate/check CRC32, MD5, SHA1, GOST, TTH, BTIH or other hash sums.

Synopsis

rhash [ option ]... [ file ]...

Description

RHash (Recursive Hasher) computes and verifies various message digests (hash sums) of files. Supported message digests include CRC32, MD4, MD5, SHA1, SHA256, SHA512, 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 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’.

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.
-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 formating options --printf and --template.
-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 formating options. Hashes are calculated for those files from the same directory as the hash file, which are yet not present in it.
-k, --check-embedded
Verify files by crc32 sum embedded in their names.
--torrent
Create a torrent file for each processed file.
-h, --help
Help: print help screen and exit.
-V, --version
Version: print version and exit.
-B, --benchmark
Run benchmark for selected algorithm(s).

Hash Sums Options

-C, --crc32
CRC32: calculate and print CRC32 hash sum.
--md4
MD4: calculate and print MD4 hash sum.
-M, --md5
MD5: calculate and print MD5 hash sum.
-H, --sha1
SHA1: calculate and print SHA1 hash sum.
--sha224, --sha256, --sha384, --sha512
Calculate specified SHA2 hash sum.
--tiger
Tiger: calculate and print Tiger hash sum.
-T, --tth
TTH: calculate and print DC++ TTH sum.
--btih
BTIH: calculate and print BitTorrent Info Hash.
-A, --aich
AICH: calculate and print AICH hash.
-E, --ed2k
ED2K: calculate and print eDonkey 2000 hash sum.
-L, --ed2k-link
eDonkey link: calculate and print eDonkey link.
-W, --whirlpool
Whirlpool: calculate and print Whirlpool hash sum.
-G, --gost
GOST: calculate and print GOST R 34.11-94 hash, the Russian GOST standard hash function.
--gost-cryptopro
GOST-CRYPTOPRO: calculate and print CryptoPro version of the GOST R 34.11-94 hash function.
--ripemd160
RIPEMD-160: calculate and print RIPEMD-160 hash sum.
--has160
HAS-160: calculate and print HAS-160 hash sum.
--snefru128, --snefru256
SNEFRU: calculate and print SNEFRU-128/256 hash sums.
--edonr256, --edonr512
EDON-R: calculate and print EDON-R 256/512 hash sums.

-a, --all
Calculate all supported hash sums.
--list-hashes
List names of all supported hashes, one per line.

Miscellaneous Options

-r, --recursive
Process directories recursively.
-v, --verbose
Be verbose.
--percents
Show percents, while calculating or checking sums
--skip-ok
Don’t print OK messages for successfully verified files.
-i, --ignore-case
Ignore case of filenames when updating crc files.
--speed
Print per-file and the total processing speed.
-e, --embed-crc
Rename files by inserting crc32 sum into name.
--embed-crc-delimiter=<delimiter>
Insert specified <delimiter> before a crc sum in the --embed-crc mode, default is white space. The <delimiter> can be a character or empty string.
--path-separator=<separator>
Use specified path separator to display paths.
-q, --accept=<list>
Set a comma-delimited list of extensions of the files to calculate sums for.
-t, --crc-accept=<list>
Comma-delimited list of crc files extensions.
--maxdepth=<levels>
Descend at most <levels> (a non-negative integer) levels of directories below the command line arguments. ‘--maxdepth 0’ means only apply the tests and actions to the command line arguments.
-o, --output=<file-path>
Set the file to output calculated hashes and verification results to.
-l, --log=<file-path>
Set the file to log errors and verbose information to.
--openssl=<list>
Specify which hash functions should be calculated using the OpenSSL library. The <list> 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.
--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.
--bt-batch=<file-path>
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 <directory> can be useful in this mode.
--bt-private
Generate BTIH for a private BitTorrent tracker.
--bt-piece-length
Set the piece length value for torrent file.
--bt-announce
Set tracker announcement url for torrent file. Note that this url doesn’t change BTIH hash.
--benchmark-raw
Switch benchmark output format to be a machine-readable tab-delimited text with hash function name, speed, cpu clocks per byte. This option works only if the --benchmark option was specified.
-- (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.

Output Format Options

--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.
-m, --magnet
Print hash sums formated as magnet links.
--bsd
Use BSD output format. Each hash sum is printed on separate line after hash name and file’s path, enclosed in parentheses.
--simple
Use simple output format. Each line will consist of filename and hash sums specified by options.
--uppercase
Print hash sums in upper case.
--lowercase
Print hash sums in lower case.
--template=<file>
Read printf-like template from given <file>. See the --printf option.
-p, --printf=<format>
Format: print format string the standard output, interpreting ‘\’ escapes and ‘%’ directives. The escapes and directives are:
\n
Newline.
\r
Carriage return.
\t
Horizontal tab.
\\
A literal backslash (‘\’).
\0
ASCII NUL.
\NNN
The character which octal ASCII code is NNN.
\xNN
The character which hexadecimal ASCII code is NN.

A ‘\’ character followed by any other character is treated as an ordinary character, so they both are printed.

%%
A literal percent sign.
%p
File’s path.
%f
File’s name.
%u
URL-encoded filename.
%s
File’s size in bytes.
%{mtime}
File’s last modification time.
%a or %A
AICH hash sum.
%c or %C
CRC32 hash sum. Use %c for lowercase and %C for uppercase characters.
%g or %G
GOST R 34.11-94 hash.
%h or %H
SHA1 hash.
%e or %E
ED2K hash sum.
%l or %L
EDonkey ed2k://... link.
%m or %M
MD5 hash.
%r or %R
RIPEMD-160 hash.
%t or %T
TTH sum.
%w or %W
Whirlpool hash.
%{md4}, %{sha224}, %{sha256}, %{sha384}, %{sha512}, %{tiger}, %{btih}, %{gost-cryptopro}, %{has160}, %{snefru128}, %{snefru256}, %{edon-r256}, %{edon-r512}
Print specified hash sum. Actually the %{<hash sum>} 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}, %{Sha512}.
%x<hash>, %b<hash>, %B<hash>, %@<hash>
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.

Config File

RHash looks for a config file at $HOME/.rhashrc and /etc/rhashrc.

The config file consists of lines formated as

variable = value

where the variable can be a text part of any command line option, like magnet, printf, percents, etc. Simple boolean values can be set using ‘1’, ‘on’ or ‘yes’.

Empty lines and lines starting with ‘#’ or ‘;’ are ignored.

Example config file:

# This is a comment line
percents = on
crc-accept = .sfv,.md5,.sha1,.sha256,.sha512,.tth,.magnet

Author

Aleksey Kravchenko <rhash.admin@gmail.com>

See Also

md5sum(1) cksfv(1) ed2k_hash(1)

Bugs

Bug reports are welcome! Send them by email or post to the SourceForge Bug Tracking System http://sourceforge.net/projects/rhash/


Table of Contents

rhash-1.3.1/dist/rhash.1.win.sed0000644000175000017500000000055611630572174016211 0ustar alekseyaleksey#!/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\ \ and on Linux/Unix } rhash-1.3.1/dist/magnet.bat0000644000175000017500000000011411630572174015405 0ustar alekseyaleksey@REM generate magnet links @rhash.exe --magnet %1 %2 %3 %4 %5 %6 %7 %8 %9 rhash-1.3.1/dist/rhash.spec0000644000175000017500000001466412263271655015445 0ustar alekseyaleksey%define version 1.3.1 # major is the part of the shared library name after the .so %define major 0 %define libname %mklibname rhash %{major} %define devlibname %mklibname -d rhash %define is_mandrake %(test -e /etc/mandrake-release && echo 1 || echo 0) %define is_suse %(test -e /etc/SuSE-release && echo 1 || echo 0) %define is_fedora %(test -e /etc/fedora-release && echo 1 || echo 0) Summary: Utility for computing hash sums and creating magnet links. Name: rhash Version: %{version} Release: 1 Copyright: MIT Group: Applications/File 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, libopenssl1.0.0-devel %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 %{__make} build-shared lib-static CFLAGS="$RPM_OPT_FLAGS -DNDEBUG -DUSE_OPENSSL -DOPENSSL_RUNTIME -rdynamic" LDFLAGS=-ldl %check %{__make} test-shared CFLAGS="$RPM_OPT_FLAGS -DNDEBUG" %install %{__make} install-shared install-lib-static install-lib-shared PREFIX=/usr DESTDIR="$RPM_BUILD_ROOT" MANDIR="%{_mandir}" LIBDIR="%{_libdir}" %clean rm -rf "$RPM_BUILD_ROOT" %files %defattr(-,root,root) %doc COPYING README ChangeLog dist/rhash.1.html /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 * Wed Jan 08 2014 Aleksey 1.3.1-1mdk * Tue Jun 11 2013 Aleksey 1.3.0-1mdk * Tue Dec 25 2012 Aleksey 1.2.10-1mdk * Sat Apr 14 2012 Aleksey 1.2.9-1mdk * Wed Sep 14 2011 Aleksey 1.2.8-1mdk * Sun Aug 14 2011 Aleksey 1.2.7-1mdk * Tue Jun 14 2011 Aleksey 1.2.6-1mdk * Wed May 18 2011 Aleksey 1.2.5-1mdk * Fri Apr 15 2011 Aleksey 1.2.4-1mdk * Sun Mar 27 2011 Aleksey 1.2.3-1mdk * Fri Jan 14 2011 Aleksey 1.2.2-1mdk * Tue Dec 14 2010 Aleksey 1.2.1-1mdk * Sun Nov 14 2010 Aleksey 1.2.0-1mdk * Fri Oct 15 2010 Aleksey 1.1.9-1mdk * Wed Apr 14 2010 Aleksey 1.1.8-1mdk * Wed Mar 31 2010 Aleksey 1.1.7-1mdk * Wed Feb 24 2010 Aleksey 1.1.6-1mdk * Thu Jan 28 2010 Aleksey 1.1.5-1mdk * Mon Dec 14 2009 Aleksey 1.1.4-1mdk * Sun Nov 29 2009 Aleksey 1.1.3-1mdk * Mon Jun 15 2009 Aleksey 1.1.2-1mdk * Mon Mar 23 2009 Aleksey 1.1.1-1mdk * Sat Mar 14 2009 Aleksey 1.1.0-1mdk * Sat Feb 14 2009 Aleksey 1.0.8-1mdk * Sun Dec 14 2008 Aleksey 1.0.7-1mdk * Fri Nov 14 2008 Aleksey 1.0.6-1mdk * Sun Sep 14 2008 Aleksey 1.0.5-1mdk * Wed Jul 9 2008 Aleksey 1.0.4-1mdk * Sat Jun 28 2008 Aleksey 1.0.3-1mdk * Sat Jun 14 2008 Aleksey 1.0.2-1mdk * Wed May 15 2008 Aleksey 1.0.1-1mdk * Fri Dec 14 2007 Aleksey 1.0-1mdk * Thu Sep 13 2007 Aleksey 0.9.2-1mdk * Sun May 27 2007 Aleksey 0.9.1-1mdk * Sun May 13 2007 Aleksey 0.9-1mdk * Fri May 11 2007 Aleksey 0.8.9-1mdk * Wed May 02 2007 Aleksey 0.8.8-1mdk * Mon Apr 16 2007 Aleksey 0.8.7-1mdk * Mon Mar 26 2007 Aleksey 0.8.6-1mdk * Wed Jan 31 2007 Aleksey 0.8.5-1mdk * Sun Nov 05 2006 Aleksey 0.8.4-1mdk * Mon Apr 10 2006 Aleksey 0.8.3-1mdk * Thu Mar 30 2006 Aleksey 0.8.2-1mdk * Wed Jan 25 2006 Aleksey 0.8.1-1mdk * Mon Jan 23 2006 Aleksey 0.8-1mdk * Sat Jan 14 2006 Aleksey 0.7-1mdk * Fri Sep 02 2005 Aleksey 0.6-1mdk * Sun Aug 14 2005 Aleksey 0.5-1mdk The first public version rhash-1.3.1/dist/MD5.bat0000644000175000017500000000010511630572174014517 0ustar alekseyaleksey@REM generate md5 file @rhash.exe --md5 %1 %2 %3 %4 %5 %6 %7 %8 %9 rhash-1.3.1/dist/rhashrc.sample0000644000175000017500000000104411630572174016302 0ustar alekseyaleksey; 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.1/win_utils.h0000644000175000017500000000326312263252342014670 0ustar alekseyaleksey/* win_utils.h utility functions for Windows */ #ifndef WIN_UTILS_H #define WIN_UTILS_H /* windows only definitions */ #ifdef _WIN32 #include "common_func.h" #ifdef __cplusplus extern "C" { #endif /* encoding conversion functions */ wchar_t* c2w(const char* str, int try_no); char* w2c(const wchar_t* wstr); char* win_to_utf8(const char* str); #define win_is_utf8() (opt.flags & OPT_UTF8) #define WIN_DEFAULT_ENCODING -1 char* wchar_to_cstr(const wchar_t* wstr, int codepage, int* failed); /* file functions */ FILE* win_fopen_ex(const char* path, const char* mode, int exclusive); #define fopen(path, mode) win_fopen_ex(path, mode, 0) #define win_fopen_bin(path, mode) win_fopen_ex(path, mode, 1) int win_stat(const char* path, struct rsh_stat_struct *buffer); int can_open_exclusive(const char* path); void set_errno_from_last_file_error(void); wchar_t* make_pathw(const wchar_t* dir_path, size_t dir_len, wchar_t* filename); void set_benchmark_cpu_affinity(void); void setup_console(void); void restore_console(void); /* readdir structures and functions */ #define DIR WIN_DIR #define dirent win_dirent #define opendir win_opendir #define readdir win_readdir #define closedir win_closedir /* dirent struct for windows to traverse directory content */ struct win_dirent { char* d_name; /* file name */ wchar_t* d_wname; /* file name in Unicode (UTF-16) */ int d_isdir; /* non-zero if file is a directory */ }; struct WIN_DIR_t; typedef struct WIN_DIR_t WIN_DIR; WIN_DIR* win_opendir(const char*); WIN_DIR* win_wopendir(const wchar_t*); struct win_dirent* win_readdir(WIN_DIR*); void win_closedir(WIN_DIR*); #ifdef __cplusplus } #endif #endif /* _WIN32 */ #endif /* WIN_UTILS_H */ rhash-1.3.1/common_func.h0000644000175000017500000001647612263252342015170 0ustar alekseyaleksey/* common_func.h */ #ifndef COMMON_FUNC_H #define COMMON_FUNC_H /* use 64-bit off_t. * these macros must be defined before any include file */ #define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 /* internationalization support via gettext/libintl */ #ifdef USE_GETTEXT # include # define _(str) gettext(str) # ifdef _WIN32 # define LOCALEDIR "./locale" # else /* _WIN32 */ # define LOCALEDIR "/usr/share/locale" # endif /* _WIN32 */ #else # define _(str) (str) #endif /* USE_GETTEXT */ #include #include #include /* for time_t */ #include /* for wchar_t */ #ifndef _WIN32 #include /* for timeval */ /*#else #include */ #elif _MSC_VER > 1300 #include "win32/platform-dependent.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 #else typedef char rsh_tchar; # define RSH_T(str) str #endif /* _WIN32 */ #ifdef _WIN32 # define IF_WINDOWS(code) code # define SYS_PATH_SEPARATOR '\\' # define IS_PATH_SEPARATOR(c) ((c) == '\\' || (c) == '/') # define IS_PATH_SEPARATOR_W(c) ((c) == L'\\' || (c) == L'/') # define is_utf8() win_is_utf8() # define to_utf8(str) win_to_utf8(str) #else /* non _WIN32 part */ # define IF_WINDOWS(code) # define SYS_PATH_SEPARATOR '/' # define IS_PATH_SEPARATOR(c) ((c) == '/') /* stub for utf8 */ # define is_utf8() 1 # define to_utf8(str) NULL #endif /* _WIN32 */ /** * Portable file information. */ typedef struct file_t { char* path; wchar_t* wpath; uint64_t size; uint64_t mtime; unsigned mode; } file_t; /* bit constants for the file_t.mode bit mask */ #define FILE_IFDIR 0x01 #define FILE_IFLNK 0x02 #define FILE_IFROOT 0x10 #define FILE_IFSTDIN 0x20 #define FILE_ISDIR(file) ((file)->mode & FILE_IFDIR) /* file 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(const rsh_tchar* a, const rsh_tchar* b); void print_time(FILE *out, time_t time); void print_time64(FILE *out, uint64_t time); void rsh_file_cleanup(file_t* file); int rsh_file_stat(file_t* file); int rsh_file_stat2(file_t* file, int use_lstat); #ifdef _WIN32 # define get_file_tpath(file) ((file)->wpath) int rsh_file_statw(file_t* file); # define rsh_fopen_bin(path, mode) win_fopen_bin(path, mode) #else # define get_file_tpath(file) ((file)->path) # define rsh_fopen_bin(path, mode) fopen(path, mode) #endif /* rhash stat function */ #if (__MSVCRT_VERSION__ >= 0x0601) || (_MSC_VER >= 1400) # define rsh_stat_struct __stat64 # define rsh_stat(path, st) win_stat(path, st) # define clib_wstat(path, st) _wstat64(path, st) #elif defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER)) # define rsh_stat_struct _stati64 # define rsh_stat(path, st) win_stat(path, st) # define clib_wstat(path, st) _wstati64(path, st) #else # define rsh_stat_struct stat # define rsh_stat(path, st) stat(path, st) /* # define clib_wstat(path, st) _wstat32(path, st) */ #endif typedef struct rsh_stat_struct rsh_stat_buf; unsigned rhash_get_ticks(void); void rhash_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(wchar_t* str, const char* srcfile, int srcline); #endif extern void (*rsh_exit)(int code); 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.1/librhash/0000755000175000017500000000000012263273121014270 5ustar alekseyalekseyrhash-1.3.1/librhash/sha3.h0000644000175000017500000000222312155136036015301 0ustar alekseyaleksey/* 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 __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* RHASH_SHA3_H */ rhash-1.3.1/librhash/has160.h0000644000175000017500000000130112155136036015441 0ustar alekseyaleksey/* 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.1/librhash/snefru.h0000644000175000017500000000210712155136036015746 0ustar alekseyaleksey/* 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.1/librhash/byte_order.c0000644000175000017500000001272612263252612016604 0ustar alekseyaleksey/* 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" #if !(__GNUC__ >= 4 || (__GNUC__ ==3 && __GNUC_MINOR__ >= 4)) /* if !GCC or GCC < 4.3 */ # 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)((v & -v) * 0x077CB531U)) >> 27]; } # endif /* _MSC_VER >= 1300... */ #endif /* !(GCC >= 4.3) */ /** * 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); while(src < end) *(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.1/librhash/md4.h0000644000175000017500000000127112155136036015131 0ustar alekseyaleksey/* 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.1/librhash/hex.h0000644000175000017500000000142712155136036015234 0ustar alekseyaleksey/* 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.1/librhash/rhash.h0000644000175000017500000002106112155136036015551 0ustar alekseyaleksey/** @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; /** type of a pointer passed to all hashing functions */ typedef struct rhash_context* rhash; /** 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 formated 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(_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)(str)) /** Convert a rhash_uptr_t to a void* pointer */ #define RHASH_UPTR2PVOID(u) ((void*)((char*)0 + (u))) /* 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_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. */ #define rhash_get_openssl_mask() rhash_transmit(RMSG_GET_OPENSSL_MASK, NULL, 0, 0); /** The bit mask of hash algorithms implemented by OpenSSL */ #if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) # define RHASH_OPENSSL_SUPPORTED_HASHES (RHASH_MD4 | RHASH_MD5 | \ RHASH_SHA1 | RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | \ RHASH_SHA512 | RHASH_RIPEMD160 | RHASH_WHIRLPOOL) #else # define RHASH_OPENSSL_SUPPORTED_HASHES 0 #endif #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* RHASH_H */ rhash-1.3.1/librhash/ed2k.c0000644000175000017500000001045412052450726015271 0ustar alekseyaleksey/* 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.1/librhash/tth.h0000644000175000017500000000112012155136036015235 0ustar alekseyaleksey#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.1/librhash/whirlpool_sbox.c0000644000175000017500000015012712052450726017520 0ustar alekseyaleksey/* 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.1/librhash/crc32.c0000644000175000017500000001507612052450726015365 0ustar alekseyaleksey/* 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.1/librhash/Makefile0000644000175000017500000001573412155416441015746 0ustar alekseyaleksey# Makefile for LibRHash CC = gcc AR = ar #NOTE: NDEBUG turns off asserts OPTFLAGS = -O2 -DNDEBUG -fomit-frame-pointer -ffunction-sections -fdata-sections OPTLDFLAGS = CFLAGS = $(OPTFLAGS) LDFLAGS = $(OPTLDFLAGS) ADDCFLAGS = LIBCFLAGS = ADDLDFLAGS = DEFS = -DIN_RHASH PRGCFLAGS = -pipe $(DEFS) $(ADDCFLAGS) $(CFLAGS) \ -Wall -W -Wstrict-prototypes -Wnested-externs -Winline -Wpointer-arith \ -Wbad-function-cast -Wmissing-prototypes -Wmissing-declarations ALLCFLAGS = $(LIBCFLAGS) $(PRGCFLAGS) LDRHASH = -L. -lrhash LIBLDFLAGS = $(LDFLAGS) $(ADDLDFLAGS) HEADERS = algorithms.h byte_order.h plug_openssl.h rhash.h rhash_timing.h util.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 whirlpool.h SOURCES = algorithms.c byte_order.c plug_openssl.c rhash.c rhash_timing.c util.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 util.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_timing.h # installation directories and names DESTDIR = PREFIX = /usr/local INCDIR = $(PREFIX)/include LIBDIR = $(PREFIX)/lib LIBRARY = librhash.a SONAME = librhash.so.0 SOLINK = librhash.so TEST_TARGET = test_hashes TEST_SHARED = test_shared # Set variables according to GNU coding standard INSTALL = install INSTALL_DATA = $(INSTALL) -m 644 INSTALL_SHARED = $(INSTALL) -m 644 all: $(LIBRARY) lib-static: $(LIBRARY) lib-shared: $(SONAME) libs-all: lib-static lib-shared dist-clean: clean install-lib-static: $(LIBRARY) install-headers $(INSTALL) -d $(DESTDIR)$(LIBDIR) $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBDIR)/ ln -s $(SONAME) $(DESTDIR)$(LIBDIR)/$(SOLINK) install-lib-shared: $(SONAME) $(INSTALL) -d $(DESTDIR)$(LIBDIR) $(INSTALL_SHARED) $(SONAME) $(DESTDIR)$(LIBDIR)/ uninstall-lib-static: uninstall-headers rm -f $(DESTDIR)$(LIBDIR)/$(LIBRARY) rm -f $(DESTDIR)$(LIBDIR)/$(SOLINK) uninstall-lib-shared: rm -f $(DESTDIR)$(LIBDIR)/$(SONAME) install-headers: $(INSTALL) -d $(DESTDIR)$(INCDIR) $(INSTALL_DATA) $(LIB_HEADERS) $(DESTDIR)$(INCDIR)/ uninstall-headers: for f in $(LIB_HEADERS); do rm -f "$(DESTDIR)$(INCDIR)/$$f"; done # not using GNU make extensions for compatibility with Unix/*BSD make #%.o: %.c # $(CC) -c $(ALLCFLAGS) $< -o $@ # NOTE: dependences were generated by 'gcc -MM -DIN_RHASH -DUSE_OPENSSL *.c' # we are using plain old makefile style to support BSD make aich.o: aich.c byte_order.h ustd.h config.h algorithms.h rhash.h aich.h \ sha1.h $(CC) -c $(ALLCFLAGS) $< -o $@ algorithms.o: algorithms.c byte_order.h ustd.h config.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 $(ALLCFLAGS) $< -o $@ byte_order.o: byte_order.c byte_order.h ustd.h config.h $(CC) -c $(ALLCFLAGS) $< -o $@ crc32.o: crc32.c byte_order.h ustd.h config.h crc32.h $(CC) -c $(ALLCFLAGS) $< -o $@ ed2k.o: ed2k.c ed2k.h md4.h ustd.h $(CC) -c $(ALLCFLAGS) $< -o $@ edonr.o: edonr.c byte_order.h ustd.h config.h edonr.h $(CC) -c $(ALLCFLAGS) $< -o $@ gost.o: gost.c byte_order.h ustd.h config.h gost.h $(CC) -c $(ALLCFLAGS) $< -o $@ has160.o: has160.c byte_order.h ustd.h config.h has160.h $(CC) -c $(ALLCFLAGS) $< -o $@ hex.o: hex.c hex.h ustd.h $(CC) -c $(ALLCFLAGS) $< -o $@ md4.o: md4.c byte_order.h ustd.h config.h md4.h $(CC) -c $(ALLCFLAGS) $< -o $@ md5.o: md5.c byte_order.h ustd.h config.h md5.h $(CC) -c $(ALLCFLAGS) $< -o $@ plug_openssl.o: plug_openssl.c algorithms.h rhash.h byte_order.h ustd.h \ config.h plug_openssl.h $(CC) -c $(ALLCFLAGS) $< -o $@ rhash.o: rhash.c byte_order.h ustd.h config.h algorithms.h rhash.h \ torrent.h sha1.h plug_openssl.h util.h hex.h $(CC) -c $(ALLCFLAGS) $< -o $@ rhash_timing.o: rhash_timing.c byte_order.h ustd.h config.h rhash.h \ rhash_timing.h $(CC) -c $(ALLCFLAGS) $< -o $@ ripemd-160.o: ripemd-160.c byte_order.h ustd.h config.h ripemd-160.h $(CC) -c $(ALLCFLAGS) $< -o $@ sha1.o: sha1.c byte_order.h ustd.h config.h sha1.h $(CC) -c $(ALLCFLAGS) $< -o $@ sha256.o: sha256.c byte_order.h ustd.h config.h sha256.h $(CC) -c $(ALLCFLAGS) $< -o $@ sha512.o: sha512.c byte_order.h ustd.h config.h sha512.h $(CC) -c $(ALLCFLAGS) $< -o $@ sha3.o: sha3.c byte_order.h ustd.h config.h sha3.h $(CC) -c $(ALLCFLAGS) $< -o $@ snefru.o: snefru.c byte_order.h ustd.h config.h snefru.h $(CC) -c $(ALLCFLAGS) $< -o $@ test_hashes.o: test_hashes.c byte_order.h ustd.h config.h rhash_timing.h \ rhash.h test_hashes.h $(CC) -c $(ALLCFLAGS) $< -o $@ tiger.o: tiger.c byte_order.h ustd.h config.h tiger.h $(CC) -c $(ALLCFLAGS) $< -o $@ tiger_sbox.o: tiger_sbox.c byte_order.h ustd.h config.h $(CC) -c $(ALLCFLAGS) $< -o $@ torrent.o: torrent.c byte_order.h ustd.h config.h algorithms.h rhash.h \ hex.h torrent.h sha1.h $(CC) -c $(ALLCFLAGS) $< -o $@ tth.o: tth.c byte_order.h ustd.h config.h tth.h tiger.h $(CC) -c $(ALLCFLAGS) $< -o $@ util.o: util.c util.h $(CC) -c $(ALLCFLAGS) $< -o $@ whirlpool.o: whirlpool.c byte_order.h ustd.h config.h whirlpool.h $(CC) -c $(ALLCFLAGS) $< -o $@ whirlpool_sbox.o: whirlpool_sbox.c byte_order.h ustd.h config.h $(CC) -c $(ALLCFLAGS) $< -o $@ # MINGW dll target DLLNAME = librhash.dll dll: $(DLLNAME) $(DLLNAME): $(SOURCES) sed -n '1s/.*/{ global:/p; s/^RHASH_API.* \([a-z0-9_]\+\)(.*/ \1;/p; $$s/.*/local: *; };/p' $(LIB_HEADERS) > exports.sym $(CC) -DRHASH_EXPORTS $(ALLCFLAGS) -shared $(SOURCES) -Wl,--version-script,exports.sym,--output-def,librhash.def,-soname,$@ $(LIBLDFLAGS) -o $@ test-dll: $(DLLNAME) test_hashes.o $(CC) $(PRGCFLAGS) test_hashes.o $(DLLNAME) -o $(TEST_SHARED) && ./$(TEST_SHARED) # shared and static libraries $(SONAME): $(SOURCES) sed -n '1s/.*/{ global:/p; s/^RHASH_API.* \([a-z0-9_]\+\)(.*/ \1;/p; $$s/.*/local: *; };/p' $(LIB_HEADERS) > exports.sym $(CC) -fpic $(ALLCFLAGS) -shared $(SOURCES) -Wl,--version-script,exports.sym,-soname,$(SONAME) $(LIBLDFLAGS) -o $@ ln -s $(SONAME) $(SOLINK) # use 'nm -Cg --defined-only $@' to view exported symbols $(LIBRARY): $(OBJECTS) $(AR) cqs $@ $(OBJECTS) # $(AR) cr $(LIBRARY) $(OBJECTS) && runlib $(LIBRARY) $(TEST_TARGET): $(LIBRARY) test_hashes.o $(CC) $(ALLCFLAGS) test_hashes.o $(LIBRARY) $(LIBLDFLAGS) -o $@ test-shared: $(SONAME) test_hashes.o $(CC) $(PRGCFLAGS) test_hashes.o $(SONAME) $(LIBLDFLAGS) -o $(TEST_SHARED) LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./$(TEST_SHARED) test-static: $(TEST_TARGET) ./$(TEST_TARGET) test: test-static if [ -f $(SONAME) ]; then make test-shared; fi # if [ -f $(DLLNAME) ]; then make test-dll; fi clean: rm -f *.o $(LIBRARY) $(TEST_TARGET) $(TEST_SHARED) $(SONAME) $(SOLINK) exports.sym $(DLLNAME) librhash.def rhash-1.3.1/librhash/md5.h0000644000175000017500000000127112155136036015132 0ustar alekseyaleksey/* 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.1/librhash/tiger_sbox.c0000644000175000017500000006667312052450726016627 0ustar alekseyaleksey/* 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.1/librhash/plug_openssl.h0000644000175000017500000000120312155136036017152 0ustar alekseyaleksey/* 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 */ #define RHASH_OPENSSL_DEFAULT_HASHES (RHASH_MD5 | RHASH_SHA1 | \ RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 | \ RHASH_WHIRLPOOL) extern unsigned rhash_openssl_hash_mask; /* mask of hash sums to use */ #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) */ #endif /* RHASH_PLUG_OPENSSL_H */ rhash-1.3.1/librhash/ripemd-160.c0000644000175000017500000002471512052450726016235 0ustar alekseyaleksey/* 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] &= ~(0xFFFFFFFF << shift); ctx->message[index++] ^= 0x80 << 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.1/librhash/algorithms.c0000644000175000017500000002224512263252342016614 0ustar alekseyaleksey/* 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.1/librhash/aich.h0000644000175000017500000000237012155136036015352 0ustar alekseyaleksey/* 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.1/librhash/rhash_timing.h0000644000175000017500000000204412052450726017121 0ustar alekseyaleksey/** @file rhash_timing.h timer and benchmarking functions */ #ifndef RHASH_TIMING_H #define RHASH_TIMING_H #ifdef __cplusplus extern "C" { #endif #ifndef RHASH_API /* modifier for LibRHash functions */ # define RHASH_API #endif /* portable timer definition */ #ifdef _WIN32 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.1/librhash/edonr.h0000644000175000017500000000270712155136036015561 0ustar alekseyaleksey/* 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.1/librhash/sha256.h0000644000175000017500000000155312155136036015460 0ustar alekseyaleksey/* 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.1/librhash/sha512.h0000644000175000017500000000155212155136036015452 0ustar alekseyaleksey/* 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.1/librhash/snefru.c0000644000175000017500000016021412052450726015746 0ustar alekseyaleksey/* 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.1/librhash/whirlpool.c0000644000175000017500000001571712052450726016472 0ustar alekseyaleksey/* 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 K1[8]; /* key used in even rounds */ uint64_t K2[8]; /* key used in odd rounds */ uint64_t state1[8]; /* state used in even rounds */ uint64_t state2[8]; /* state used in odd rounds */ /* 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 intermediate hash state */ state1[i] = hash[i] = be2me_64(p_block[i]) ^ (K1[i] = hash[i]); } /* iterate over algorithm rounds */ for(i = 0; i < number_of_rounds; i++) { /* compute K^i from K^{i-1} */ K2[0] = WHIRLPOOL_OP(K1, 0) ^ rc[i]; K2[1] = WHIRLPOOL_OP(K1, 1); K2[2] = WHIRLPOOL_OP(K1, 2); K2[3] = WHIRLPOOL_OP(K1, 3); K2[4] = WHIRLPOOL_OP(K1, 4); K2[5] = WHIRLPOOL_OP(K1, 5); K2[6] = WHIRLPOOL_OP(K1, 6); K2[7] = WHIRLPOOL_OP(K1, 7); /* apply the i-th round transformation */ state2[0] = WHIRLPOOL_OP(state1, 0) ^ K2[0]; state2[1] = WHIRLPOOL_OP(state1, 1) ^ K2[1]; state2[2] = WHIRLPOOL_OP(state1, 2) ^ K2[2]; state2[3] = WHIRLPOOL_OP(state1, 3) ^ K2[3]; state2[4] = WHIRLPOOL_OP(state1, 4) ^ K2[4]; state2[5] = WHIRLPOOL_OP(state1, 5) ^ K2[5]; state2[6] = WHIRLPOOL_OP(state1, 6) ^ K2[6]; state2[7] = WHIRLPOOL_OP(state1, 7) ^ K2[7]; i++; /* compute K^i from K^{i-1} */ K1[0] = WHIRLPOOL_OP(K2, 0) ^ rc[i]; K1[1] = WHIRLPOOL_OP(K2, 1); K1[2] = WHIRLPOOL_OP(K2, 2); K1[3] = WHIRLPOOL_OP(K2, 3); K1[4] = WHIRLPOOL_OP(K2, 4); K1[5] = WHIRLPOOL_OP(K2, 5); K1[6] = WHIRLPOOL_OP(K2, 6); K1[7] = WHIRLPOOL_OP(K2, 7); /* apply the i-th round transformation */ state1[0] = WHIRLPOOL_OP(state2, 0) ^ K1[0]; state1[1] = WHIRLPOOL_OP(state2, 1) ^ K1[1]; state1[2] = WHIRLPOOL_OP(state2, 2) ^ K1[2]; state1[3] = WHIRLPOOL_OP(state2, 3) ^ K1[3]; state1[4] = WHIRLPOOL_OP(state2, 4) ^ K1[4]; state1[5] = WHIRLPOOL_OP(state2, 5) ^ K1[5]; state1[6] = WHIRLPOOL_OP(state2, 6) ^ K1[6]; state1[7] = WHIRLPOOL_OP(state2, 7) ^ K1[7]; } /* apply the Miyaguchi-Preneel compression function */ hash[0] ^= state1[0]; hash[1] ^= state1[1]; hash[2] ^= state1[2]; hash[3] ^= state1[3]; hash[4] ^= state1[4]; hash[5] ^= state1[5]; hash[6] ^= state1[6]; hash[7] ^= state1[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.1/librhash/plug_openssl.c0000644000175000017500000001642412263252342017157 0ustar alekseyaleksey/* 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 #include #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) #include #define USE_OPENSSL_WHIRLPOOL #endif #include "algorithms.h" #include "plug_openssl.h" #if defined(OPENSSL_RUNTIME) # ifdef _WIN32 # include # else # include # endif #endif /* the mask of ids of hashing algorithms to use from the OpenSLL library */ unsigned rhash_openssl_hash_mask = RHASH_OPENSSL_DEFAULT_HASHES; #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 /* non-runtime 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_FINAL(RIPEMD160) WRAP_FINAL2(SHA1, SHA_CTX) WRAP_FINAL2(SHA224, SHA256_CTX) WRAP_FINAL(SHA256) WRAP_FINAL2(SHA384, SHA512_CTX) WRAP_FINAL(SHA512) /* wrapping WHIRLPOOL_Final requires special attention. */ #ifdef USE_OPENSSL_WHIRLPOOL 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_rmd160, sizeof(RIPEMD160_CTX), offsetof(RIPEMD160_CTX, A), HASH_INFO_METHODS(RIPEMD160) }, /* 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 */ #ifdef USE_OPENSSL_WHIRLPOOL /* note: should be flags=0 */ { &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 #ifdef _WIN32 #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) { #ifdef _WIN32 HMODULE handle; /* suppress the error popup dialogs */ UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); SetErrorMode(oldErrorMode | SEM_FAILCRITICALERRORS); handle = LoadLibraryA("libeay32.dll"); SetErrorMode(oldErrorMode); /* restore error mode */ #else void* handle = dlopen("libcrypto.so", RTLD_NOW); if(!handle) handle = dlopen("libcrypto.so.1.0.0", RTLD_NOW); /* hotfix */ 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, RIPEMD160); LOAD_ADDR(4, SHA224); LOAD_ADDR(5, SHA256); LOAD_ADDR(6, SHA384); LOAD_ADDR(7, SHA512); #ifdef USE_OPENSSL_WHIRLPOOL LOAD_ADDR(8, WHIRLPOOL); #endif return 1; } #endif /** * Replace several RHash internal algorithms with the OpenSSL ones. * It replaces MD4/MD5, SHA1/SHA2, RIPEMD, WHIRLPOOL. * * @return 1 on success, 0 if OpenSSL library not found */ int rhash_plug_openssl(void) { int i, 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((rhash_openssl_hash_mask & method->info->hash_id) == 0) continue; if(!method->init) 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; } #endif /* defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) */ rhash-1.3.1/librhash/rhash.c0000644000175000017500000006333212263252347015557 0ustar alekseyaleksey/* 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(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[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 = 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)) { if(ectx->state != STATE_ACTIVE) break; /* stop if canceled */ length = fread(buffer, 1, block_size, fd); /* read can return -1 on error */ if(length == (size_t)-1) { res = -1; /* note: fread sets errno */ 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) 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) 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(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_set_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_STR2UPTR(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 /* 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.1/librhash/test_hashes.h0000644000175000017500000000746112155136036016766 0ustar alekseyaleksey/* test_hashes.h - detect compiler defines */ /* 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 __x86_64 " __x86_64" #endif #ifdef __x86_64__ " __x86_64__" #endif #ifdef _M_AMD64 " _M_AMD64" #endif #ifdef _M_X64 " _M_X64" #endif #ifdef CPU_X64 " CPU_X64" #endif #ifdef CPU_IA32 " CPU_IA32" #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__) " GCC=" __VERSION__ #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 __MINGW32__ " __MINGW32__" #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 /* other defines */ #ifdef __STDC_VERSION__ " __STDC_VERSION__=" EXPAND_TO_STRING(__STDC_VERSION__) #endif #ifdef _UNICODE " _UNICODE" #endif #ifdef __STRICT_ANSI__ " __STRICT_ANSI__" #endif #ifdef __PIC__ " __PIC__" #endif #ifdef USE_RHASH_DLL " USE_RHASH_DLL" #endif #ifdef USE_OPENSSL " USE_OPENSSL" #endif #ifdef OPENSSL_RUNTIME " OPENSSL_RUNTIME" #endif /* detect endianness */ #ifdef CPU_LITTLE_ENDIAN " CPU_LITTLE_ENDIAN" #endif #ifdef CPU_BIG_ENDIAN " CPU_BIG_ENDIAN" #endif #if defined(__BYTE_ORDER) #if (__BYTE_ORDER==__LITTLE_ENDIAN) " (__BYTE_ORDER==__LITTLE_ENDIAN)" #elif (__BYTE_ORDER==__BIG_ENDIAN) " (__BYTE_ORDER==__BIG_ENDIAN)" #endif #endif "\n"; rhash-1.3.1/librhash/tth.c0000644000175000017500000000714712052450726015250 0ustar alekseyaleksey/* 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.1/librhash/sha512.c0000644000175000017500000002333612052450726015452 0ustar alekseyaleksey/* 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.1/librhash/sha1.h0000644000175000017500000000127212155136036015302 0ustar alekseyaleksey/* 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.1/librhash/byte_order.h0000644000175000017500000001404012263252522016600 0ustar alekseyaleksey/* byte_order.h */ #ifndef BYTE_ORDER_H #define BYTE_ORDER_H #include "ustd.h" #include #ifdef IN_RHASH #include "config.h" #endif #ifdef __GLIBC__ # 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 /* detect CPU endianness */ #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \ __BYTE_ORDER == __LITTLE_ENDIAN) || \ defined(CPU_IA32) || defined(CPU_X64) || \ defined(__ia64) || defined(__ia64__) || defined(__alpha__) || defined(_M_ALPHA) || \ defined(vax) || defined(MIPSEL) || defined(_ARM_) # define CPU_LITTLE_ENDIAN # define IS_BIG_ENDIAN 0 # define IS_LITTLE_ENDIAN 1 #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \ __BYTE_ORDER == __BIG_ENDIAN) || \ 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 CPU_BIG_ENDIAN # define IS_BIG_ENDIAN 1 # define IS_LITTLE_ENDIAN 0 #else # error "Can't detect CPU architechture" #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##LL #endif /* convert a hash flag to index */ #if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) /* GCC < 3.4 */ # 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); /* define bswap_32 */ #if defined(__GNUC__) && defined(CPU_IA32) && !defined(__i386__) /* for intel x86 CPU */ static inline uint32_t bswap_32(uint32_t x) { __asm("bswap\t%0" : "=r" (x) : "0" (x)); return x; } #elif defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) /* for GCC >= 4.3 */ # define bswap_32(x) __builtin_bswap32(x) #elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ # define bswap_32(x) _byteswap_ulong((unsigned long)x) #elif !defined(__STRICT_ANSI__) /* general bswap_32 definition */ static inline uint32_t bswap_32(uint32_t x) { x = ((x << 8) & 0xFF00FF00) | ((x >> 8) & 0x00FF00FF); return (x >> 16) | (x << 16); } #else #define bswap_32(x) ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24)) #endif /* bswap_32 */ #if defined(__GNUC__) && (__GNUC__ >= 4) && (__GNUC__ > 4 || __GNUC_MINOR__ >= 3) # define bswap_64(x) __builtin_bswap64(x) #elif (_MSC_VER > 1300) && (defined(CPU_IA32) || defined(CPU_X64)) /* MS VC */ # define bswap_64(x) _byteswap_uint64((__int64)x) #elif !defined(__STRICT_ANSI__) static 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; } #else #error "bswap_64 unsupported" #endif #ifdef CPU_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 /* CPU_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 /* CPU_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.1/librhash/hex.c0000644000175000017500000001227112052450726015227 0ustar alekseyaleksey/* 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.1/librhash/md5.c0000644000175000017500000001742112052450726015132 0ustar alekseyaleksey/* 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] &= ~(0xFFFFFFFF << shift); ctx->message[index++] ^= 0x80 << 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.1/librhash/algorithms.h0000644000175000017500000000544412155136036016624 0ustar alekseyaleksey/* 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 */ #ifndef CPU_BIG_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.1/librhash/md4.c0000644000175000017500000001447012052450726015132 0ustar alekseyaleksey/* 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] &= ~(0xFFFFFFFF << shift); ctx->message[index++] ^= 0x80 << 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.1/librhash/tiger.h0000644000175000017500000000150312155136036015555 0ustar alekseyaleksey/* 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.1/librhash/sha3.c0000644000175000017500000002227612263252347015312 0ustar alekseyaleksey/* 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) { 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); } /* Keccak theta() transformation */ static void keccak_theta(uint64_t *A) { unsigned int x; uint64_t C[5], D[5]; for(x = 0; x < 5; x++) { C[x] = A[x] ^ A[x + 5] ^ A[x + 10] ^ A[x + 15] ^ A[x + 20]; } D[0] = ROTL64(C[1], 1) ^ C[4]; D[1] = ROTL64(C[2], 1) ^ C[0]; D[2] = ROTL64(C[3], 1) ^ C[1]; D[3] = ROTL64(C[4], 1) ^ C[2]; D[4] = ROTL64(C[0], 1) ^ C[3]; for(x = 0; x < 5; x++) { A[x] ^= D[x]; A[x + 5] ^= D[x]; A[x + 10] ^= D[x]; A[x + 15] ^= D[x]; A[x + 20] ^= D[x]; } } /* 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 */ } /* Keccak chi() transformation */ static void keccak_chi(uint64_t *A) { int i; for(i = 0; i < 25; i += 5) { uint64_t 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; } } 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] |= 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); } rhash-1.3.1/librhash/edonr.c0000644000175000017500000004375012052450726015560 0ustar alekseyaleksey/* 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] &= ~(0xFFFFFFFF << shift); ctx->u.data256.message[index++] ^= 0x80 << 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.1/librhash/has160.c0000644000175000017500000002033112052450726015441 0ustar alekseyaleksey/* 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 */ #ifdef CPU_LITTLE_ENDIAN ctx->message[index] &= ~(0xFFFFFFFF << shift); ctx->message[index++] ^= 0x80 << shift; #else ctx->message[index] &= ~(0xFFFFFFFF >> shift); ctx->message[index++] ^= 0x80000000 >> 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.1/librhash/gost.h0000644000175000017500000000171112155136036015420 0ustar alekseyaleksey/* 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.1/librhash/ustd.h0000644000175000017500000000132312155136036015422 0ustar alekseyaleksey/* ustd.h common macros and includes */ #ifndef LIBRHASH_USTD_H #define LIBRHASH_USTD_H #if _MSC_VER >= 1300 # define int64_t __int64 # define int32_t __int32 # define int16_t __int16 # define int8_t __int8 # define uint64_t unsigned __int64 # define uint32_t unsigned __int32 # define uint16_t unsigned __int16 # define uint8_t unsigned __int8 /* disable warnings: The POSIX name for this item is deprecated. Use the ISO C++ conformant name. */ #pragma warning(disable : 4996) #else /* _MSC_VER >= 1300 */ # include # include #endif /* _MSC_VER >= 1300 */ #if _MSC_VER <= 1300 # include /* size_t for vc6.0 */ #endif /* _MSC_VER <= 1300 */ #endif /* LIBRHASH_USTD_H */ rhash-1.3.1/librhash/sha1.c0000644000175000017500000001200312052450726015270 0ustar alekseyaleksey/* 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.1/librhash/whirlpool.h0000644000175000017500000000171112155136036016463 0ustar alekseyaleksey/* 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.1/librhash/util.h0000644000175000017500000000210011634147737015425 0ustar alekseyaleksey/* 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.1/librhash/test_hashes.c0000644000175000017500000013156412263252342016762 0ustar alekseyaleksey/* 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" #ifdef USE_RHASH_DLL # define RHASH_API __declspec(dllimport) #endif #include "rhash.h" #include "test_hashes.h" /*=========================================================================* * Data for tests * *=========================================================================*/ const char* crc32_tests[] = { /* verified with cksfv */ "", "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 hash values are equal to 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 sites 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 progs */ 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[] = { "", "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* sha3_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* sha3_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* sha3_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 }; /* 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 }; #define USE_BTIH_WITH_TEST_FILENAME const char* btih_tests[] = { #ifdef USE_BTIH_WITH_TEST_FILENAME /* BTIH calculated with filename = "test.txt", verified using uTorrent */ "", "B9E3C388E3D6B5F63EA5CE61F79C23E2C50EF95B", "a", "C277260F7EC3DAB6D15F9B38796578029ED9B32B", "abc", "D8C4B957D2EEB55D39B2FE68AB924EB007355050", "message digest", "8FE65F36D46DEAB1A347CE005A025F302D35D408", "abcdefghijklmnopqrstuvwxyz", "2932DC7AA83123F822E9431F8F10F2C740D0EDF0", "The quick brown fox jumps over the lazy dog", "C39D1F8950FDB39C2366E9A6CD7814AC3686CA55", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "4405635D7611838250EEF66AA8F03980C42AD2CB", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "A6583B70D9634170940AEEDFE2AD37DADC99B5D4", "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "545472D099CE50D075A318429C48BE54DDA02731", #else /* BTIH calculated without a filename, can't be verified by torrent tools */ "", "A66A2FA70401A9DCA25C7C39937921D377A24C1A", "a", "FD408E9D024B58A57AA1313EFF14005FF8B2C5D1", "abc", "83FFAAFFA483B91FBC284D1930F2DEE886515AFB", "message digest", "8208E521BBECEA61711F787824FB301ED3E2C16C", "abcdefghijklmnopqrstuvwxyz", "47D855AE785FEE80A210DF1512B72AE96A50C99E", "The quick brown fox jumps over the lazy dog", "987147B78B586249263F89E8E7C4E636225BC1F7", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "5E4886F153F905528055DEB7C5181F459064D9F4", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "867A6364D160679F8F7C41C126EAFCB9E8759CE6", "12345678901234567890123456789012345678901234567890123456789012345678901234567890", "1BFF44EA31BDF301B9E02689815295C4BB25635F", #endif 0 }; typedef struct known_strings_t { unsigned hash_id; const char** tests; } known_strings_t; known_strings_t known_strings[] = { { 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_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 } }; /*=========================================================================* * Helper functions to hash messages * *=========================================================================*/ static int g_errors = 0; /* total number of errors occured */ #ifdef UNDER_CE /* if Windows CE */ static char *g_msg = NULL; /* string buffer to store errors */ #endif static void log_message(char* format, ...) { va_list vl; #ifndef UNDER_CE /* not Windows CE */ va_start(vl, format); vprintf(format, vl); fflush(stdout); #else char str[300]; int add_nl = (g_msg == NULL); va_start(vl, format); vsprintf(str, format, vl); g_msg = (char*)realloc(g_msg, (g_msg ? strlen(g_msg) : 0) + strlen(str) + 3); if(add_nl) strcat(g_msg, "\r\n"); strcat(g_msg, str); #endif 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 */ static char* repeat_hash(unsigned hash_id, const char* chunk, size_t chunk_size, size_t msg_size) { 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); #ifdef USE_BTIH_WITH_TEST_FILENAME if((hash_id & RHASH_BTIH) != 0) { unsigned long long total_size = msg_size; rhash_transmit(RMSG_BT_ADD_FILE, ctx, RHASH_STR2UPTR("test.txt"), (rhash_uptr_t)&total_size); } #endif 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 */ 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) { char* result; result = repeat_hash(hash_id, msg_chunk, chunk_size, msg_size); 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 */ static char* hash_message(unsigned hash_id, const char* msg) { size_t msg_size = strlen(msg); return repeat_hash(hash_id, msg, msg_size, msg_size); } /** * 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 */ static void assert_hash(unsigned hash_id, const char* msg, const char* expected_hash) { size_t msg_size = strlen(msg); assert_hash_long_msg(hash_id, msg, msg_size, msg_size, expected_hash, NULL); } /** * 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 */ static void assert_rep_hash(unsigned hash_id, char ch, size_t msg_size, const char* hash) { 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); } /*=========================================================================* * 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 */ static void test_known_strings_pairs(unsigned hash_id, const char** ptr) { for(; ptr[0] && ptr[1]; ptr += 2) { assert_hash(hash_id, ptr[0], ptr[1]); } } /** * 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; known_strings[i].tests != 0; i++) { if(hash_id == known_strings[i].hash_id) { test_known_strings_pairs(hash_id, known_strings[i].tests); break; } } } /** * Verify hash algorithms by testing them against known short messages. */ static void test_all_known_strings(void) { int i; for(i = 0; known_strings[i].tests != 0; i++) { assert(i < (int)(sizeof(known_strings) / sizeof(known_strings_t))); test_known_strings_pairs(known_strings[i].hash_id, known_strings[i].tests); } } /** * 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, "19F9167BE2A04C43ABD0ED554788101B9C339031ACC8E1468531303F" }, /* verified by refence implementation */ { RHASH_SHA3_256, "FADAE6B49F129BBB812BE8407B7B2894F34AECF6DBD1F9B0F0C7E9853098FC96" }, /* verified by refence implementation */ { RHASH_SHA3_384, "0C8324E1EBC182822C5E2A086CAC07C2FE00E3BCE61D01BA8AD6B71780E2DEC5FB89E5AE90CB593E57BC6258FDD94E17" }, /* verified by refence implementation */ { RHASH_SHA3_512, "5CF53F2E556BE5A624425EDE23D0E8B2C7814B4BA0E4E09CBBF3C2FAC7056F61E048FC341262875EBC58A5183FEA651447124370C1EBF4D6C89BC9A7731063BB" }, /* verified by refence implementation */ { RHASH_EDONR256, "56F4B8DC0A41C8EA0A6A42C949883CD5DC25DF8CF4E43AD474FD4492A7A07966" }, /* verified by eBASH SUPERCOP implementation */ { RHASH_EDONR512, "B4A5A255D67869C990FE79B5FCBDA69958794B8003F01FD11E90FEFEC35F22BD84FFA2E248E8B3C1ACD9B7EFAC5BC66616E234A6E938D3526DEE26BD0DE9C562" }, /* verified by eBASH SUPERCOP implementation */ #ifdef USE_BTIH_WITH_TEST_FILENAME { RHASH_BTIH, "0DA5C5A6BA0D067C4DE134BB5AD525544DB11A6C" }, /* BTIH with filename="test.txt", verified using uTorrent */ #else { RHASH_BTIH, "30CF71DEFC48D497D4C6DCA8FAB203C1E253A53F" }, /* BTIH calculated without a filename, can't be verified by torrent tools */ #endif }; /* test all algorithms on 1,000,000 charaters of 'a' */ for(count = 0; count < (sizeof(tests) / sizeof(id_to_hash_t)); count++) { assert_rep_hash(tests[count].hash_id, 'a', 1000000, tests[count].expected_hash); } /* now we verify some specific cases */ assert_rep_hash(RHASH_GOST, 0xFF, 64, "13416C4EC74A63C3EC90CB1748FD462C7572C6C6B41844E48CC1184D1E916098"); assert_rep_hash(RHASH_GOST_CRYPTOPRO, 0xFF, 64, "58504D26B3677E756BA3F4A9FD2F14B3BA5457066A4AA1D700659B90DCDDD3C6"); /* these messages verified by eMule LinkCreator (which uses eMule variant of ED2K hash) */ assert_rep_hash(RHASH_ED2K, 0, 9728000, "FC21D9AF828F92A8DF64BEAC3357425D"); assert_rep_hash(RHASH_ED2K, 0, 9728000 - 1, "AC44B93FC9AFF773AB0005C911F8396F"); assert_rep_hash(RHASH_ED2K, 0, 9728000 + 1, "06329E9DBA1373512C06386FE29E3C65"); /* msg with: 9728000 < size <= 9732096 */ assert_rep_hash(RHASH_AICH, 0, 9728000, "5D3N4HQHIUMQ7IU7A5QLPLI6RHSWOR7B"); assert_rep_hash(RHASH_AICH, 0, 9728000 - 1, "L6SPMD2CM6PRZBGRQ6UFC4HJFFOATRA4"); assert_rep_hash(RHASH_AICH, 0, 9728000 + 1, "HL3TFXORIUEPXUWFPY3JLR7SMKGTO4IH"); #if 0 assert_rep_hash(RHASH_ED2K, 0, 9728000 * 5, "3B613901DABA54F6C0671793E28A1205"); assert_rep_hash(RHASH_AICH, 0, 9728000 * 5, "EZCO3XF2RJ4FERRDEXGOSSRGL5NA5BBM"); #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; 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); #ifdef USE_BTIH_WITH_TEST_FILENAME if((hash_id & RHASH_BTIH) != 0) { unsigned long long total_size = msg_size; rhash_transmit(RMSG_BT_ADD_FILE, ctx, RHASH_STR2UPTR("test.txt"), (rhash_uptr_t)&total_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)); } else { /* verify obtained hash value */ assert_hash(hash_id, message + start, expected_hash); } } } } /** * 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:7vai5hicjnmkk6vbge7p6faal74lfror", 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 hash 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; } /* define program entry point */ #ifndef UNDER_CE /* if not Windows CE */ /** * The application entry point under Linux and Windows. * * @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[]) { /* rhash_transmit(RMSG_SET_OPENSSL_MASK, 0, RHASH_ALL_HASHES, 0); */ #ifndef USE_RHASH_DLL rhash_library_init(); #endif test_generic_assumptions(); if(argc > 1 && 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(argc > 1 && strcmp(argv[1], "--flags") == 0) { printf("%s", compiler_flags); } 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); } #else /* UNDER_CE */ #include #include /** * Convert a single-byte string to a two-byte (wchar_t*). * * @param str the string to convert * @return converted string of wchar_t */ wchar_t *char2wchar(char* str) { size_t origsize; wchar_t *wmsg; origsize = strlen(str) + 1; wmsg = (wchar_t*)malloc(origsize * 2); mbstowcs(wmsg, str, origsize); return wmsg; } /** * The program entry point under Windows CE * * @param argc number of arguments including program name * @param argv program argumants including its name */ int _tmain(int argc, _TCHAR* argv[]) { wchar_t *wmsg; (void)argc; (void)argv; test_known_strings(); test_alignment(); wmsg = char2wchar(g_msg ? g_msg : "Success!\r\nAll sums are working properly."); MessageBox(NULL, wmsg, _T("caption"), MB_OK | MB_ICONEXCLAMATION); free(wmsg); free(g_msg); return (g_errors == 0 ? 0 : 1); } #endif /* UNDER_CE */ rhash-1.3.1/librhash/util.c0000644000175000017500000000142412155136036015415 0ustar alekseyaleksey/* util.c - utility functions * * 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 "util.h" rhash-1.3.1/librhash/crc32.h0000644000175000017500000000070511630572174015366 0ustar alekseyaleksey/* 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.1/librhash/tiger.c0000644000175000017500000001371512052450726015561 0ustar alekseyaleksey/* 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.1/librhash/sha256.c0000644000175000017500000002065212052450726015455 0ustar alekseyaleksey/* 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(~(0xFFFFFFFF << shift)); ctx->message[index++] ^= le2me_32(0x80 << 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.1/librhash/torrent.h0000644000175000017500000000441312263252342016142 0ustar alekseyaleksey/* 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 */ char* program_name; /* the name of the program */ char* announce; /* announce URL */ 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_set_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.1/librhash/gost.c0000644000175000017500000011563712052450726015431 0ustar alekseyaleksey/* 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(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) { #ifdef CPU_BIG_ENDIAN unsigned block_le[8]; /* tmp buffer for little endian number */ # define LOAD_BLOCK_LE(i) (block_le[i] = le2me_32(block[i])) #else # define block_le block # define LOAD_BLOCK_LE(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 * standart 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.1/librhash/rhash_timing.c0000644000175000017500000001673412155136036017126 0ustar alekseyaleksey/* 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(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 inline volatile uint64_t read_tsc(void) {*/ static uint64_t read_tsc(void) { unsigned long lo, hi; __asm volatile("rdtsc" : "=a" (lo), "=d" (hi)); /*__asm volatile("cpuid; rdtsc" : "=a" (lo), "=d" (hi) : "ebx", "ecx"); */ return (((uint64_t)hi) << 32) + lo; } # define HAVE_TSC #endif /* _MSC_VER, __GNUC__ */ #endif /* CPU_IA32, CPU_X64 */ /* TIMER FUNCTIONS */ #ifdef _WIN32 #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. * * @param delta time delta to be converted * @return number of seconds */ static double fsec(timedelta_t* timer) { #ifdef _WIN32 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. * * @param timer timer to start */ void rhash_timer_start(timedelta_t* timer) { get_timedelta(timer); } /** * Stop given timer. * * @param timer the timer to stop * @return number of seconds timed */ double rhash_timer_stop(timedelta_t* timer) { timedelta_t end; get_timedelta(&end); #ifdef _WIN32 *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); } #ifdef _WIN32 /** * Set process priority and affinity to use all cpu's but the first one. * This improves benchmark results on a multi-cpu systems. */ 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 /* #define BENCHMARK_HASH_SIMULTANEOUSLY - should support in future */ /** * 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 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. * * @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 */ #ifdef _WIN32 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*/ /*fprintf(output, " benchmark:"); for(i = 1; i & RHASH_ALL_HASHES; i <<= 1) { if(i & opt.sum_flags) printf(" %s", rhash_get_name(i)); } fprintf(output, "\n"); fflush(output);*/ 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; /*printf("%8.2f", ((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.1/librhash/torrent.c0000644000175000017500000003606012263252342016140 0ustar alekseyaleksey/* 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 /** 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 = 65536; #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 of hash blocks and file paths */ bt_vector_clean(&ctx->hash_blocks); bt_vector_clean(&ctx->files); free(ctx->program_name); free(ctx->announce); ctx->announce = ctx->program_name = 0; free(ctx->content.str); } 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)) 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; 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 = 64K for total_size < 64M, * length = 4M for total_size >= 2G, * length = top_bit(total_size) / 512 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 < 67108864) return 65536; if(total_size >= I64(2147483648) ) return 4194304; for(hi_bit = 67108864 << 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); } /* write torrent header to the ctx->torrent string buffer */ if((ctx->options & BT_OPT_INFOHASH_ONLY) == 0) { bt_str_append(ctx, "d"); if(ctx->announce) { bt_bencode_str(ctx, "8:announce", ctx->announce); } 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"); bt_str_append(ctx, "4:infod"); /* start 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; } /** * Set torrent announcement-URL for storing into torrent file. * * @param ctx the torrent algorithm context * @param announce_url the announcement-URL * @return non-zero on success, zero on error */ int bt_set_announce(torrent_ctx *ctx, const char* announce_url) { free(ctx->announce); ctx->announce = strdup(announce_url); return (ctx->announce != NULL); } /** * 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.1/librhash/config.h0000644000175000017500000000005311630572174015713 0ustar alekseyaleksey/* config.h */ /*#define OPENSSL_RUNTIME*/ rhash-1.3.1/librhash/ed2k.h0000644000175000017500000000121211630572174015271 0ustar alekseyaleksey/* 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.1/librhash/ripemd-160.h0000644000175000017500000000137712155136036016240 0ustar alekseyaleksey/* 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.1/librhash/aich.c0000644000175000017500000003214112263252342015343 0ustar alekseyaleksey/* 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[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 */ #ifdef CPU_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.1/output.c0000644000175000017500000003447312263252342014215 0ustar alekseyaleksey/* output.c */ #include "common_func.h" /* should be included before the C library files */ #include #include #include #include #include /* exit() */ #include #include #include "librhash/rhash.h" #include "calc_sums.h" #include "parse_cmdline.h" #include "rhash_main.h" #include "win_utils.h" #include "output.h" /*#ifdef _WIN32 #define WIN32_USE_CURSOR #endif*/ #ifdef _WIN32 #include #include /* for _SH_DENYNO */ #endif #ifdef WIN32_USE_CURSOR #include #endif /* global pointer to the selected method of percents output */ struct percents_output_info_t *percents_output = NULL; /** * Print a formated message to program log, and flush the log stream. * * @param format print a formated message to the program log * @param args */ static void log_va_msg(const char* format, va_list args) { vfprintf(rhash_data.log, format, args); fflush(rhash_data.log); } /** * Print a formated message to program log, and flush the log stream. * * @param format print a formated 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 program log. * * @param format print a formated message to the program log */ void log_error(const char* format, ...) { va_list ap; va_start(ap, format); fprintf(rhash_data.log, "%s: ", PROGRAM_NAME); log_va_msg(format, ap); } /** * Print an error to program log. * * @param filepath the path to file caused the error */ void log_warning(const char* format, ...) { va_list ap; va_start(ap, format); fprintf(rhash_data.log, "%s: ", PROGRAM_NAME); log_va_msg(format, ap); } /** * Print a file error to 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)); } /** * 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; #ifdef WIN32_USE_CURSOR HANDLE hOut; unsigned short cur_x, cur_y; /* cursor position, where to print percents */ #endif }; 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)); 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); 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); 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); fprintf(rhash_data.out, _(", %s is %s should be %s"), rhash_get_name(hid), actual, expected_hash); } } 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) { fprintf(rhash_data.out, "%-51s ", info->print_path); } if(print_result) { if(info->error == -1) { /* print error to stdout */ 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%" */ 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)) { fprintf(rhash_data.log, _("\nChecking %s\n"), info->print_path); } else { 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 ); 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) { #ifdef WIN32_USE_CURSOR CONSOLE_SCREEN_BUFFER_INFO csbInfo; percents.hOut = NULL; #endif (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 */ fprintf(rhash_data.log, "%-51s ", info->print_path); #ifdef WIN32_USE_CURSOR if(percents.use_cursor) { /* store cursor coordinates */ percents.hOut = GetStdHandle(STD_ERROR_HANDLE); if(percents.hOut == INVALID_HANDLE_VALUE || !GetConsoleScreenBufferInfo(percents.hOut, &csbInfo)) { percents.hOut = NULL; return 0; } else { percents.cur_x = csbInfo.dwCursorPosition.X; percents.cur_y = csbInfo.dwCursorPosition.Y; } } #endif 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; #ifdef WIN32_USE_CURSOR COORD dwCursorPosition; if(percents.use_cursor && percents.hOut == NULL) return; #endif 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) { fprintf(rhash_data.log, "%u%%", perc); percents.points = perc; } else { fprintf(rhash_data.log, "%c", rot[(percents.points++) & 3]); } #ifdef WIN32_USE_CURSOR if(percents.use_cursor) { fflush(rhash_data.log); /* rewind the cursor position */ dwCursorPosition.X = percents.cur_x; dwCursorPosition.Y = percents.cur_y; SetConsoleCursorPosition(percents.hOut, dwCursorPosition); } else #endif { 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; #ifdef WIN32_USE_CURSOR if(percents.use_cursor && percents.hOut == NULL) return; #endif 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 { 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) { #ifdef _WIN32 if( !(*p_stream = _wfsopen(stream_path, L"w", _SH_DENYNO)) ) { log_file_error(w2c((wchar_t*)stream_path)); #else if( !(*p_stream = fopen(stream_path, "w")) ) { log_file_error(stream_path); #endif 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); 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; } 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 */ fprintf(rhash_data.out, _("Everything OK\n")); } else { 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) { fprintf(rhash_data.log, _("Total %.3f sec, %4.2f MBps\n"), time, speed); } else { fprintf(rhash_data.log, _("Calculated in %.3f sec, %4.2f MBps\n"), time, speed); } fflush(rhash_data.log); } rhash-1.3.1/ChangeLog0000644000175000017500000004265312263271560014265 0ustar alekseyalekseyWed Jan 8 2014 * === 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} formating 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 formated 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 formating 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 standart 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.1/file_mask.c0000644000175000017500000000416312263252342014600 0ustar alekseyaleksey/* file_mask.c */ #include #include #include #include #include "common_func.h" #include "file_mask.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.1/hash_check.c0000644000175000017500000005125312155136036014731 0ustar alekseyaleksey/* hash_check.c */ #include #include #include /* isspace */ #include "librhash/rhash.h" #include "output.h" #include "common_func.h" #include "parse_cmdline.h" #include "hash_print.h" #include "hash_check.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-formated 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 frhexcmp(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; } /** * 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) { unsigned char* c = (unsigned char*)rhash_get_context_ptr(ctx, RHASH_CRC32); unsigned crc32_be = ((unsigned)c[0] << 24) | ((unsigned)c[1] << 16) | ((unsigned)c[2] << 8) | (unsigned)c[3]; if(crc32_be != hashes->embedded_crc32_be) { 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(frhexcmp(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.1/parse_cmdline.h0000644000175000017500000000527012263252342015460 0ustar alekseyaleksey/* parse_cmdline.h */ #ifndef PARSE_CMD_LINE_H #define PARSE_CMD_LINE_H #include #ifdef __cplusplus extern "C" { #endif /* The official name of the program */ #define PROGRAM_NAME "RHash" #define CMD_FILENAME "rhash" #ifdef _WIN32 typedef wchar_t opt_tchar; #else typedef char opt_tchar; #endif /** * Options bit flags and constants. */ enum { OPT_ED2K_LINK = 0x10000000, /* program modes */ MODE_CHECK = 0x1, MODE_CHECK_EMBEDDED = 0x2, MODE_UPDATE = 0x4, MODE_BENCHMARK = 0x8, MODE_TORRENT = 0x10, /* misc options */ OPT_EMBED_CRC = 0x20, OPT_RECURSIVE = 0x40, OPT_SKIP_OK = 0x80, OPT_IGNORE_CASE = 0x100, OPT_VERBOSE = 0x200, OPT_PERCENTS = 0x400, OPT_SPEED = 0x800, OPT_BT_PRIVATE = 0x1000, OPT_UPPERCASE = 0x2000, OPT_LOWERCASE = 0x4000, OPT_GOST_REVERSE = 0x8000, OPT_BENCH_RAW = 0x10000, #ifdef _WIN32 OPT_UTF8 = 0x10000000, OPT_ANSI = 0x20000000, OPT_OEM = 0x40000000, OPT_ENCODING = OPT_UTF8|OPT_ANSI|OPT_OEM, #endif FMT_BSD = 1, FMT_SFV = 2, FMT_SIMPLE = 4, FMT_MAGNET = 8, OPT_FORMAT_MASK = FMT_BSD|FMT_SFV|FMT_SIMPLE|FMT_MAGNET }; struct vector_t; /** * Parsed program options. */ struct options_t { unsigned flags; /* program options */ unsigned sum_flags; /* flags to specify what sums will be calculated */ unsigned fmt; /* flags to specify output format to use */ unsigned mode; /* flags to specify program mode */ const char* config_file; /* config file path */ char* printf_str; /* printf-like format */ char* template_file; /* printf-like template file path */ opt_tchar* output; /* file to output calculation or checking results to */ opt_tchar* log; /* file to log percents and other info to */ char* embed_crc_delimiter; char path_separator; int find_max_depth; struct vector_t *files_accept; /* suffixes of files for which sums will be calculated */ struct vector_t *crc_accept; /* suffixes of crc files to verify or update */ unsigned openssl_mask; /* mask which OpenSSL hashes to use */ size_t bt_piece_length; /* BitTorrent piece length */ char* bt_announce; /* BitTorrent announce URL */ char* bt_batch_file; /* path to save batch torrent to */ char** argv; int n_files; /* the number of files obtained from the command line */ struct file_search_data* search_data; /* files obtained from the command line */ struct vector_t *mem; /* heap variables that should be freed */ }; extern struct options_t opt; void read_options(int argc, char *argv[]); void options_destroy(struct options_t*); #ifdef _WIN32 int detect_encoding(wchar_t** wargv, int nArg); #endif #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* PARSE_CMD_LINE_H */ rhash-1.3.1/hash_update.h0000644000175000017500000000041211740576066015144 0ustar alekseyaleksey/* 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.1/find_file.c0000644000175000017500000002601412263262624014570 0ustar alekseyaleksey/* find_file.c * * find_file function for searching through directory trees doing work * on each file found similar to the Unix find command. */ #include "common_func.h" /* should be included before the C library files */ #include #include #include #include #include /* ino_t */ #include /* opendir/readdir */ #include #include #include #include "output.h" #include "win_utils.h" #include "find_file.h" #if defined(_WIN32) #include #endif #if !defined(_WIN32) && (defined(_BSD_SOURCE) || _XOPEN_SOURCE >= 500) # define USE_LSTAT 1 #else # define USE_LSTAT 0 #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); /* allocate and fill the file_search_data */ file_search_data* create_file_search_data(rsh_tchar** paths, size_t count, int max_depth) { size_t i; 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 = max_depth; #ifdef _WIN32 /* expand wildcards and fill the root_files */ for(i = 0; i < count; i++) { int added = 0; size_t length, index; wchar_t* path = paths[i]; 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; 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 = (rsh_file_statw(&file) < 0); } /* quietly skip unconvertible file names */ if(!file.path || failed) { 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); } } else { file_t file; int failed; file.wpath = path; /* if filepath is a dash string "-" */ if ((path[0] == L'-' && path[1] == L'\0')) { file.mtime = file.size = 0; file.mode = FILE_IFSTDIN; file.path = rsh_strdup("(stdin)"); } else { file.path = wchar_to_cstr(file.wpath, WIN_DEFAULT_ENCODING, &failed); if (failed) { log_error(_("Can't convert the path to local encoding: %s\n"), file.path); free(file.path); continue; } if (rsh_file_statw(&file) < 0) { log_file_error(file.path); free(file.path); continue; } } /* mark the file as obtained from the command line */ file.mode |= FILE_IFROOT; file.wpath = rsh_wcsdup(path); add_root_file(data, &file); } } /* for */ #else /* copy file paths */ for(i = 0; i < count; i++) { file_t file; file.path = rsh_strdup(paths[i]); file.wpath = 0; file.mtime = file.size = 0; if (IS_DASH_STR(file.path)) { file.mode = FILE_IFSTDIN; } else if (rsh_file_stat2(&file, USE_LSTAT) < 0) { log_file_error(file.path); free(file.path); continue; } file.mode |= FILE_IFROOT; add_root_file(data, &file); } #endif return data; } /** * Free memory allocated by the file_search_data structure */ void destroy_file_search_data(file_search_data* 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); rsh_file_cleanup(file); } rsh_blocks_vector_destroy(&data->root_files); } void scan_files(file_search_data* data) { size_t i; size_t count = data->root_files.size; 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_ISDIR(file)) { if(data->max_depth != 0) { find_file(file, data); } else if((data->options & FIND_LOG_ERRORS) != 0) { errno = EISDIR; log_file_error(file->path); } continue; } else { /* process a regular file or a dash '-' path */ data->call_back(file, data->call_back_data); } } } /** * A entry of a list containing files from 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 left; 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 options the options specifying how to walk the directory tree * @return 0 on success, -1 on error */ int find_file(file_t* start_dir, file_search_data* options) { dir_entry *dirs_stack = NULL; /* root of the dir_list */ dir_iterator* it; int level = 0; int max_depth = options->max_depth; int flags = options->options; 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((flags & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS)) == 0) { if(!options->call_back(start_dir, options->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].left = 1; it[0].dir_path = 0; memset(&file, 0, sizeof(file)); while(!(options->options & FIND_CANCEL)) { dir_entry **insert_at; char* dir_path; DIR *dp; struct dirent *de; /* climb down from the tree */ while(--it[level].left < 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].left >= 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].left = 0; it[level].dir_path = dir_path; if((flags & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS)) == FIND_WALK_DEPTH_FIRST) { file.path = rsh_strdup(dir_path); rsh_file_stat2(&file, USE_LSTAT); /* check if we should skip the directory */ if(!options->call_back(&file, options->call_back_data)) { rsh_file_cleanup(&file); continue; } } /* 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.path = make_path(dir_path, de->d_name); if(!file.path) continue; res = rsh_file_stat2(&file, USE_LSTAT); if(res >= 0) { /* process the file or directory */ if(FILE_ISDIR(&file) && (flags & (FIND_WALK_DEPTH_FIRST | FIND_SKIP_DIRS))) { res = 1; } else { /* handle file by callback function */ res = options->call_back(&file, options->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) { /* 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].left++; } } } else if (options->options & FIND_LOG_ERRORS) { /* report error only if FIND_LOG_ERRORS option is set */ log_file_error(file.path); } rsh_file_cleanup(&file); } closedir(dp); } while (dirs_stack) { dir_entry_drop_head(&dirs_stack); } while (level) { free(it[level--].dir_path); } free(it); rsh_file_cleanup(&file); return 0; } rhash-1.3.1/calc_sums.h0000644000175000017500000000324112155136036014621 0ustar alekseyaleksey/* 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 #include /* struct stat */ #include /* stat() */ /** * 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*); void save_torrent_to(const char* path, struct rhash_context* rctx); int calculate_and_print_sums(FILE* out, file_t* file, const char *print_path); int check_hash_file(file_t* file, int chdir); int rename_file_by_embeding_crc32(struct file_info *info); void print_sfv_banner(FILE* out); int print_sfv_header_line(FILE* out, file_t* file, const char* printpath); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* CALC_SUMS_H */ rhash-1.3.1/find_file.h0000644000175000017500000000173712263252342014576 0ustar alekseyaleksey/* find_file.h - declaration of find_file function. * * find_file function searches through a directory tree calling a call_back on * each file. */ #ifndef FIND_FILE_H #define FIND_FILE_H #include "common_func.h" #ifdef __cplusplus extern "C" { #endif /* find_file options */ #define FIND_WALK_DEPTH_FIRST 1 #define FIND_FOLLOW_LINKS 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* create_file_search_data(rsh_tchar** paths, size_t count, int max_depth); void destroy_file_search_data(file_search_data* data); void scan_files(file_search_data* data); int find_file(file_t* start_dir, file_search_data* options); #ifdef __cplusplus } /* extern "C" */ #endif /* __cplusplus */ #endif /* FIND_FILE_H */ rhash-1.3.1/win_utils.c0000644000175000017500000003232512263252342014664 0ustar alekseyaleksey/* win_utils.c - Windows-specific utility functions */ #ifdef _WIN32 #include #include /* for _SH_DENYWR */ #include #include /* for _O_RDONLY, _O_BINARY */ #include /* for isatty */ #include #include #include #include "common_func.h" #include "parse_cmdline.h" #include "rhash_main.h" #include "win_utils.h" /** * Convert a c-string to wide character string using given codepage * * @param str the string to convert * @param codepage the codepage to use * @return converted string on success, NULL on fail */ static wchar_t* cstr_to_wchar(const char* str, int codepage) { wchar_t* buf; int size = MultiByteToWideChar(codepage, MB_ERR_INVALID_CHARS, str, -1, NULL, 0); if(size == 0) return NULL; /* conversion failed */ buf = (wchar_t*)rsh_malloc(size * sizeof(wchar_t)); MultiByteToWideChar(codepage, 0, str, -1, buf, size); return buf; } /** * Convert c-string to wide string using primary or secondary codepage. * * @param str the C-string to convert * @param try_no 0 for primary codepage, 1 for a secondary one * @return converted wide string on success, NULL on error */ wchar_t* c2w(const char* str, int try_no) { int is_utf = (try_no == (opt.flags & OPT_UTF8 ? 0 : 1)); int codepage = (is_utf ? CP_UTF8 : (opt.flags & OPT_OEM) ? CP_OEMCP : CP_ACP); return cstr_to_wchar(str, codepage); } /** * Convert a UTF8-encoded string to wide string. * * @param str the UTF8-encoded string to convert * @return wide string on success, NULL on error */ static wchar_t* utf8_to_wchar(const char* utf8_str) { return cstr_to_wchar(utf8_str, CP_UTF8); } /** * Convert a wide character string to c-string using given codepage. * Optionally set a flag if conversion failed. * * @param wstr the wide string to convert * @param codepage the codepage to use * @param failed pointer to the flag, to on failed conversion, can be NULL * @return converted string on success, NULL on fail */ char* wchar_to_cstr(const wchar_t* wstr, int codepage, int* failed) { int size; char *buf; BOOL bUsedDefChar, *lpUsedDefaultChar; if(codepage == -1) { codepage = (opt.flags & OPT_UTF8 ? CP_UTF8 : (opt.flags & OPT_OEM) ? CP_OEMCP : CP_ACP); } /* note: lpUsedDefaultChar must be NULL for CP_UTF8, otrherwise WideCharToMultiByte() will fail */ lpUsedDefaultChar = (failed && codepage != CP_UTF8 ? &bUsedDefChar : NULL); size = WideCharToMultiByte(codepage, 0, wstr, -1, 0, 0, 0, 0); if(size == 0) { if (failed) *failed = 1; return NULL; /* conversion failed */ } buf = (char*)rsh_malloc(size); WideCharToMultiByte(codepage, 0, wstr, -1, buf, size, 0, lpUsedDefaultChar); if(failed) *failed = (lpUsedDefaultChar && *lpUsedDefaultChar); return buf; } /** * Convert wide string to multi-byte c-string using codepage specified * by command line options. * * @param wstr the wide string to convert * @return c-string on success, NULL on fail */ char* w2c(const wchar_t* wstr) { return wchar_to_cstr(wstr, -1, NULL); } /** * Convert given C-string from encoding specified by * command line options to utf8. * * @param str the string to convert * @return converted string on success, NULL on fail */ char* win_to_utf8(const char* str) { char* res; wchar_t* buf; assert((opt.flags & (OPT_UTF8 | OPT_OEM | OPT_ANSI)) != 0); if(opt.flags & OPT_UTF8) return rsh_strdup(str); if((buf = c2w(str, 0)) == NULL) return NULL; res = wchar_to_cstr(buf, CP_UTF8, NULL); free(buf); return res; } /** * Open file path given in the current encoding, using desired shared access. * * @param path file path * @param mode string specifying file opening mode * @param exclusive non-zero to prohibit write access to the file * @return file descriptor on success, NULL on error */ FILE* win_fopen_ex(const char* path, const char* mode, int exclusive) { FILE* fd = 0; int i; wchar_t* wmode = utf8_to_wchar(mode); assert(wmode != NULL); /* try two code pages */ for(i = 0; i < 2; i++) { wchar_t* wpath = c2w(path, i); if(wpath == NULL) continue; fd = _wfsopen(wpath, wmode, (exclusive ? _SH_DENYWR : _SH_DENYNO)); free(wpath); if(fd || errno != ENOENT) break; } free(wmode); return fd; } /** * stat() a file with encoding support. * * @param path the file path * @param buffer pointer to the buffer to store file properties to * @return 0 on success, -1 on error */ int win_stat(const char* path, struct rsh_stat_struct *buffer) { int i, res = -1; for(i = 0; i < 2; i++) { wchar_t* wpath = c2w(path, i); if(wpath == NULL) continue; res = clib_wstat(wpath, buffer); free(wpath); if(res == 0 || errno != ENOENT) break; } return res; } /** * 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 can_open_exclusive(const char* path) { int i, res = 0; for(i = 0; i < 2 && res == 0; i++) { int fd; wchar_t* wpath = c2w(path, i); if(wpath == NULL) continue; fd = _wsopen(wpath, _O_RDONLY | _O_BINARY, _SH_DENYWR, 0); if(fd >= 0) { res = 1; _close(fd); } free(wpath); } return res; } /* the range of error codes for access errors */ #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED /** * Convert the GetLastError() value to the assignable to errno. * * @return errno-compatible error code */ static int convert_last_error_to_errno(void) { DWORD error_code = GetLastError(); switch (error_code) { case NO_ERROR: return 0; case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: case ERROR_INVALID_DRIVE: case ERROR_BAD_NETPATH: case ERROR_BAD_PATHNAME: case ERROR_FILENAME_EXCED_RANGE: return ENOENT; case ERROR_TOO_MANY_OPEN_FILES: return EMFILE; case ERROR_ACCESS_DENIED: case ERROR_SHARING_VIOLATION: return EACCES; case ERROR_NETWORK_ACCESS_DENIED: case ERROR_FAIL_I24: case ERROR_SEEK_ON_DEVICE: return EACCES; case ERROR_LOCK_VIOLATION: case ERROR_DRIVE_LOCKED: case ERROR_NOT_LOCKED: case ERROR_LOCK_FAILED: return EACCES; case ERROR_INVALID_HANDLE: return EBADF; case ERROR_NOT_ENOUGH_MEMORY: case ERROR_INVALID_BLOCK: case ERROR_NOT_ENOUGH_QUOTA: return ENOMEM; case ERROR_INVALID_ACCESS: case ERROR_INVALID_DATA: case ERROR_INVALID_PARAMETER: return EINVAL; case ERROR_BROKEN_PIPE: case ERROR_NO_DATA: return EPIPE; case ERROR_DISK_FULL: return ENOSPC; case ERROR_ALREADY_EXISTS: return EEXIST; case ERROR_NESTING_NOT_ALLOWED: return EAGAIN; } /* try to detect error by range */ if (MIN_EACCES_RANGE <= error_code && error_code <= MAX_EACCES_RANGE) { return EACCES; } else { return EINVAL; } } /** * Assign errno to the error value converted from the GetLastError(). */ void set_errno_from_last_file_error(void) { errno = convert_last_error_to_errno(); } /** * Concatenate directory path with filename, unicode version. * * @param dir_path directory path * @param dir_len length of directory path in characters * @param filename the file name to append to the directory * @return concatenated path */ wchar_t* make_pathw(const wchar_t* dir_path, size_t dir_len, wchar_t* filename) { wchar_t* res; size_t len; if(dir_path == 0) dir_len = 0; else { /* remove leading path separators from filename */ while(IS_PATH_SEPARATOR_W(*filename)) filename++; if(dir_len == (size_t)-1) dir_len = wcslen(dir_path); } len = wcslen(filename); res = (wchar_t*)rsh_malloc((dir_len + len + 2) * sizeof(wchar_t)); if(dir_len > 0) { memcpy(res, dir_path, dir_len * sizeof(wchar_t)); if(res[dir_len - 1] != (wchar_t)SYS_PATH_SEPARATOR) { /* append path separator to the directory */ res[dir_len++] = (wchar_t)SYS_PATH_SEPARATOR; } } /* append filename */ memcpy(res + dir_len, filename, (len + 1) * sizeof(wchar_t)); return res; } /* functions to setup/restore console */ /** * Prepare console on program initialization: change console font codepage * according to program options and hide cursor. */ void setup_console(void) { HANDLE hOut; CONSOLE_CURSOR_INFO cci; int cp = (opt.flags&OPT_UTF8 ? CP_UTF8 : opt.flags&OPT_ANSI ? GetACP() : GetOEMCP()); rhash_data.saved_console_codepage = -1; /* note: we are using numbers 1 = _fileno(stdout), 2 = _fileno(stderr) */ /* cause _fileno() is undefined, when compiling as strict ansi C. */ if(cp > 0 && IsValidCodePage(cp) && (isatty(1) || isatty(2)) ) { rhash_data.saved_console_codepage = GetConsoleOutputCP(); SetConsoleOutputCP(cp); setlocale(LC_CTYPE, opt.flags&OPT_UTF8 ? "C" : opt.flags&OPT_ANSI ? ".ACP" : ".OCP"); rsh_exit = rhash_exit; } if((opt.flags & OPT_PERCENTS) != 0) { hOut = GetStdHandle(STD_ERROR_HANDLE); if(hOut != INVALID_HANDLE_VALUE) { /* store current cursor size and visibility flag */ GetConsoleCursorInfo(hOut, &cci); rhash_data.saved_cursor_size = (cci.bVisible ? cci.dwSize : 0); /* now hide cursor */ cci.bVisible = 0; SetConsoleCursorInfo(hOut, &cci); /* hide cursor */ } } } /** * Restore console on program exit. */ void restore_console(void) { HANDLE hOut; CONSOLE_CURSOR_INFO cci; if(rhash_data.saved_console_codepage > 0) { SetConsoleOutputCP(rhash_data.saved_console_codepage); } hOut = GetStdHandle(STD_ERROR_HANDLE); if(hOut != INVALID_HANDLE_VALUE && rhash_data.saved_cursor_size) { /* restore cursor size and visibility */ cci.dwSize = rhash_data.saved_cursor_size; cci.bVisible = 1; SetConsoleCursorInfo(hOut, &cci); } } /**************************************************************************** * Directory functions * ****************************************************************************/ struct WIN_DIR_t { WIN32_FIND_DATAW findFileData; HANDLE hFind; struct win_dirent dir; int state; /* 0 - not started, -1 - ended, >=0 file index */ }; /** * Open directory iterator for reading the directory content. * * @param dir_path directory path * @return pointer to directory stream. On error, NULL is returned, * and errno is set appropriately. */ WIN_DIR* win_opendir(const char* dir_path) { WIN_DIR* d; wchar_t* wpath; /* append '\*' to the dir_path */ size_t len = strlen(dir_path); char *path = (char*)malloc(len + 3); if(!path) return NULL; /* failed, malloc also set errno = ENOMEM */ strcpy(path, dir_path); strcpy(path + len, "\\*"); d = (WIN_DIR*)malloc(sizeof(WIN_DIR)); if(!d) { free(path); return NULL; } memset(d, 0, sizeof(WIN_DIR)); wpath = c2w(path, 0); d->hFind = (wpath != NULL ? FindFirstFileW(wpath, &d->findFileData) : INVALID_HANDLE_VALUE); free(wpath); if(d->hFind == INVALID_HANDLE_VALUE && GetLastError() != ERROR_ACCESS_DENIED) { wpath = c2w(path, 1); /* try to use secondary codepage */ if(wpath) { d->hFind = FindFirstFileW(wpath, &d->findFileData); free(wpath); } } free(path); if(d->hFind == INVALID_HANDLE_VALUE && GetLastError() == ERROR_ACCESS_DENIED) { free(d); errno = EACCES; return NULL; } set_errno_from_last_file_error(); d->state = (d->hFind == INVALID_HANDLE_VALUE ? -1 : 0); d->dir.d_name = NULL; return d; } /** * Open a directory for reading its content. * For simplicity the function supposes that dir_path points to an * existing directory and doesn't check for this error. * The Unicode version of the function. * * @param dir_path directory path * @return pointer to directory iterator */ WIN_DIR* win_wopendir(const wchar_t* dir_path) { WIN_DIR* d; /* append '\*' to the dir_path */ wchar_t *wpath = make_pathw(dir_path, (size_t)-1, L"*"); d = (WIN_DIR*)rsh_malloc(sizeof(WIN_DIR)); d->hFind = FindFirstFileW(wpath, &d->findFileData); free(wpath); if(d->hFind == INVALID_HANDLE_VALUE && GetLastError() == ERROR_ACCESS_DENIED) { free(d); errno = EACCES; return NULL; } /* note: we suppose if INVALID_HANDLE_VALUE was returned, then the file listing is empty */ d->state = (d->hFind == INVALID_HANDLE_VALUE ? -1 : 0); d->dir.d_name = NULL; return d; } /** * Close a directory iterator. * * @param d pointer to the directory iterator */ void win_closedir(WIN_DIR* d) { if(d->hFind != INVALID_HANDLE_VALUE) { FindClose(d->hFind); } free(d->dir.d_name); free(d); } /** * Read a directory content. * * @param d pointer to the directory iterator * @return directory entry or NULL if no entries left */ struct win_dirent* win_readdir(WIN_DIR* d) { char* filename; int failed; if(d->state == -1) return NULL; if(d->dir.d_name != NULL) { free(d->dir.d_name); d->dir.d_name = NULL; } for(;;) { if(d->state > 0) { if( !FindNextFileW(d->hFind, &d->findFileData) ) { /* the directory listing has ended */ d->state = -1; return NULL; } } d->state++; if(d->findFileData.cFileName[0] == L'.' && (d->findFileData.cFileName[1] == 0 || (d->findFileData.cFileName[1] == L'.' && d->findFileData.cFileName[2] == 0))) { /* simplified implementation, skips '.' and '..' names */ continue; } d->dir.d_name = filename = wchar_to_cstr(d->findFileData.cFileName, WIN_DEFAULT_ENCODING, &failed); if(filename && !failed) { d->dir.d_wname = d->findFileData.cFileName; d->dir.d_isdir = (0 != (d->findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)); return &d->dir; } /* quietly skip an invalid filename and repeat the search */ if(filename) { free(filename); d->dir.d_name = NULL; } } } #endif /* _WIN32 */ rhash-1.3.1/parse_cmdline.c0000644000175000017500000007574712263252342015473 0ustar alekseyaleksey/* parse_cmdline.c - parsing of command line options */ #include "common_func.h" /* should be included before the C library files */ #include #include #include #include #include #include /* stat() */ #ifdef _WIN32 #include /* for SetFileApisToOEM(), CharToOem() */ #endif #include "librhash/rhash.h" #include "win_utils.h" #include "file_mask.h" #include "find_file.h" #include "hash_print.h" #include "output.h" #include "rhash_main.h" #include "version.h" #include "parse_cmdline.h" #define VERSION_STRING PROGRAM_NAME " v" VERSION "\n" typedef struct options_t options_t; struct options_t conf_opt; /* config file parsed options */ struct options_t opt; /* command line options */ static void print_help_line(const char* option, const char* text) { 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 */ fprintf(rhash_data.out, _("%s\n" "Usage: %s [OPTION...] [FILE | -]...\n" " %s --printf= [FILE | -]...\n\n"), VERSION_STRING, CMD_FILENAME, CMD_FILENAME); 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(" --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")); 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) fprintf(rhash_data.out, "%s\n", hash_name); } rsh_exit(0); } /** * Process --accept and --crc-accept options. * * @param o pointer to the options structure to update * @param accept_string comma delimited string to parse * @param type non-zero for the crc_accept option */ static void crc_accept(options_t *o, char* accept_string, unsigned type) { file_mask_array** ptr = (type ? &o->crc_accept : &o->files_accept); if(!*ptr) *ptr = file_mask_new(); file_mask_add_list(*ptr, accept_string); } /** * 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) { #if defined(USE_OPENSSL) || defined(OPENSSL_RUNTIME) char *cur, *next; (void)type; 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 & RHASH_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 (void)type; (void)openssl_hashes; (void)o; log_warning(_("compiled without openssl support\n")); #endif } /** * Process --video option. * * @param o pointer to the options structure to update */ static void accept_video(options_t *o) { crc_accept(o, ".avi,.ogm,.mkv,.mp4,.mpeg,.mpg,.asf,.rm,.wmv,.vob", 0); } /** * Say nya! Keep secret! =) */ static void nya(void) { fprintf(rhash_data.out, " /\\__/\\\n (^ _ ^.) %s\n (_uu__)\n", /* TRANSLATORS: Keep 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_PRNT = 6, /* 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_PRNT, 'V', 0, "version", VERSION_STRING, 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_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", crc_accept, 0 }, { F_PFNC, 't', 0, "crc-accept", crc_accept, 1 }, { 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_CSTR, 0, 0, "bt-announce", &opt.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 } }; /** * 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"), (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) { /* leave the value in UTF-16 */ value = (char*)rsh_wcsdup((wchar_t*)option->parameter); } 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: /* 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) { # define CONF_FILE_NAME "rhashrc" struct rsh_stat_struct st; char *dir1, *path; #ifndef _WIN32 /* Linux/Unix part */ /* first check for $HOME/.rhashrc file */ if( (dir1 = getenv("HOME")) ) { path = make_path(dir1, ".rhashrc"); if(rsh_stat(path, &st) >= 0) { rsh_vector_add_ptr(opt.mem, path); return (conf_opt.config_file = path); } free(path); } /* then check for global config */ if(rsh_stat( (path = "/etc/" CONF_FILE_NAME), &st) >= 0) { 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"); rsh_vector_add_ptr(opt.mem, path = make_path(dir1, CONF_FILE_NAME)); free(dir1); if(rsh_stat(path, &st) >= 0) { return (conf_opt.config_file = 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); rsh_vector_add_ptr(opt.mem, path = make_path(dir1, CONF_FILE_NAME)); free(dir1); if(rsh_stat(path, &st) >= 0) { return (conf_opt.config_file = 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[] = {"1", "on", "yes", 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; /* "--