[Cmake-commits] CMake branch, next, updated. v3.7.0-rc2-960-g16df580

Brad King brad.king at kitware.com
Fri Nov 4 08:55:42 EDT 2016


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  16df58045f9cc1b553fe1607177f91e23fb45b43 (commit)
       via  906934fae85a07ae489a636d2681082a2face69f (commit)
       via  33e25b1dedcda14fbcccd14281edb412a0c14cac (commit)
       via  c4cd1d2f5b8ab579c620ff7eb24ceab2b7830644 (commit)
       via  dfff0d5c4af796e2e5869bc2bb65d7d23cfbdd78 (commit)
       via  032312e95d5f799d77789faa57c657b6be409f6a (commit)
       via  72b9bf5cf8e2df6fb5290afb7c2825ec54c59640 (commit)
       via  56481623c6e615b2c90482dd8b6f880cd571561c (commit)
       via  956d93a5f04bebe404b228771c87059fa1efe261 (commit)
       via  5aebc4aa1bab731194948721301a3ed69daeaa1f (commit)
       via  77a96b0cb74c0d040be232370356fea0a1257578 (commit)
       via  b5ae698e7aea15321ee94436cdbec9747e422209 (commit)
       via  5cb1b345d932d3e0dc34a2d423894a59a6c8db35 (commit)
       via  1367fccc330b0ff314845aeb3547bbc38486913a (commit)
       via  798b0adc628ab16dbb4d04ef444b8e7db4f5cffa (commit)
      from  471d00b9b946082724d2d7b1b8ed29d54275adb2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=16df58045f9cc1b553fe1607177f91e23fb45b43
commit 16df58045f9cc1b553fe1607177f91e23fb45b43
Merge: 471d00b 906934f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Fri Nov 4 08:55:40 2016 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Fri Nov 4 08:55:40 2016 -0400

    Merge topic 'import-librhash' into next
    
    906934fa Add option to build CMake against a system librhash
    33e25b1d FindLibRHash: Add module to find the librhash package
    c4cd1d2f Remove unused cm_sha2 infrastructure
    dfff0d5c Port hash computation to cmCryptoHash
    032312e9 cmCryptoHash: Re-implement in terms of librhash
    72b9bf5c cmCryptoHash: Avoid using subclasses at client sites
    56481623 librhash: Port to KWIML for ABI and integer type information
    956d93a5 librhash: Install COPYING file with CMake documentation
    5aebc4aa librhash: Disable warnings to avoid changing 3rd party code
    77a96b0c librhash: Build the library within CMake
    b5ae698e librhash: Remove source fragments not needed for CMake
    5cb1b345 Merge branch 'upstream-librhash' into import-librhash
    1367fccc librhash 2016-11-01 (d839a1a8)
    798b0adc Add script to update librhash from upstream


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=906934fae85a07ae489a636d2681082a2face69f
commit 906934fae85a07ae489a636d2681082a2face69f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 13:31:33 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 14:07:49 2016 -0400

    Add option to build CMake against a system librhash
    
    Create a CMAKE_USE_SYSTEM_LIBRHASH option.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82a34d3..7aa8010 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -104,7 +104,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
 
   # Allow the user to enable/disable all system utility library options by
   # defining CMAKE_USE_SYSTEM_LIBRARIES or CMAKE_USE_SYSTEM_LIBRARY_${util}.
-  set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBUV ZLIB)
+  set(UTILITIES BZIP2 CURL EXPAT FORM JSONCPP LIBARCHIVE LIBLZMA LIBRHASH LIBUV ZLIB)
   foreach(util ${UTILITIES})
     if(NOT DEFINED CMAKE_USE_SYSTEM_LIBRARY_${util}
         AND DEFINED CMAKE_USE_SYSTEM_LIBRARIES)
@@ -144,6 +144,7 @@ macro(CMAKE_HANDLE_SYSTEM_LIBRARIES)
     "${CMAKE_USE_SYSTEM_LIBRARY_LIBLZMA}" "NOT CMAKE_USE_SYSTEM_LIBARCHIVE" ON)
   option(CMAKE_USE_SYSTEM_FORM "Use system-installed libform" "${CMAKE_USE_SYSTEM_LIBRARY_FORM}")
   option(CMAKE_USE_SYSTEM_JSONCPP "Use system-installed jsoncpp" "${CMAKE_USE_SYSTEM_LIBRARY_JSONCPP}")
+  option(CMAKE_USE_SYSTEM_LIBRHASH "Use system-installed librhash" "${CMAKE_USE_SYSTEM_LIBRARY_LIBRHASH}")
   option(CMAKE_USE_SYSTEM_LIBUV "Use system-installed libuv" "${CMAKE_USE_SYSTEM_LIBRARY_LIBUV}")
 
   # For now use system KWIML only if explicitly requested rather
@@ -298,9 +299,22 @@ macro (CMAKE_BUILD_UTILITIES)
     add_subdirectory(Utilities/KWIML)
   endif()
 
-  set(CMAKE_LIBRHASH_LIBRARIES cmlibrhash)
-  add_subdirectory(Utilities/cmlibrhash)
-  CMAKE_SET_TARGET_FOLDER(cmlibrhash "Utilities/3rdParty")
+  if(CMAKE_USE_SYSTEM_LIBRHASH)
+    if(NOT CMAKE_VERSION VERSION_LESS 3.0)
+      find_package(LibRHash)
+    else()
+      message(FATAL_ERROR "CMAKE_USE_SYSTEM_LIBRHASH requires CMake >= 3.0")
+    endif()
+    if(NOT LibRHash_FOUND)
+      message(FATAL_ERROR
+        "CMAKE_USE_SYSTEM_LIBRHASH is ON but LibRHash is not found!")
+    endif()
+    set(CMAKE_LIBRHASH_LIBRARIES LibRHash::LibRHash)
+  else()
+    set(CMAKE_LIBRHASH_LIBRARIES cmlibrhash)
+    add_subdirectory(Utilities/cmlibrhash)
+    CMAKE_SET_TARGET_FOLDER(cmlibrhash "Utilities/3rdParty")
+  endif()
 
   #---------------------------------------------------------------------
   # Build zlib library for Curl, CMake, and CTest.
diff --git a/Utilities/cmThirdParty.h.in b/Utilities/cmThirdParty.h.in
index 210e727..a547f0d 100644
--- a/Utilities/cmThirdParty.h.in
+++ b/Utilities/cmThirdParty.h.in
@@ -13,6 +13,7 @@
 #cmakedefine CMAKE_USE_SYSTEM_LIBLZMA
 #cmakedefine CMAKE_USE_SYSTEM_FORM
 #cmakedefine CMAKE_USE_SYSTEM_JSONCPP
+#cmakedefine CMAKE_USE_SYSTEM_LIBRHASH
 #cmakedefine CMAKE_USE_SYSTEM_LIBUV
 #cmakedefine CTEST_USE_XMLRPC
 
diff --git a/Utilities/cm_rhash.h b/Utilities/cm_rhash.h
index 23d5409..c793627 100644
--- a/Utilities/cm_rhash.h
+++ b/Utilities/cm_rhash.h
@@ -3,6 +3,12 @@
 #ifndef cm_rhash_h
 #define cm_rhash_h
 
+/* Use the LibRHash library configured for CMake.  */
+#include "cmThirdParty.h"
+#ifdef CMAKE_USE_SYSTEM_LIBRHASH
+#include <rhash.h>
+#else
 #include <cmlibrhash/librhash/rhash.h>
+#endif
 
 #endif
diff --git a/bootstrap b/bootstrap
index 4ce0dee..d54380a 100755
--- a/bootstrap
+++ b/bootstrap
@@ -493,6 +493,8 @@ Configuration:
   --no-system-liblzma     use cmake-provided liblzma library (default)
   --system-libarchive     use system-installed libarchive library
   --no-system-libarchive  use cmake-provided libarchive library (default)
+  --system-librhash       use system-installed librhash library
+  --no-system-librhash    use cmake-provided librhash library (default)
 
   --qt-gui                build the Qt-based GUI (requires Qt >= 4.2)
   --no-qt-gui             do not build the Qt-based GUI (default)
@@ -726,10 +728,10 @@ while test $# != 0; do
   --init=*) cmake_init_file=`cmake_arg "$1"` ;;
   --system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=1" ;;
   --no-system-libs) cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARIES=0" ;;
-  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-zlib|--system-liblzma)
+  --system-bzip2|--system-curl|--system-expat|--system-jsoncpp|--system-libarchive|--system-librhash|--system-zlib|--system-liblzma)
     lib=`cmake_arg "$1" "--system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=1" ;;
-  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-zlib|--no-system-liblzma)
+  --no-system-bzip2|--no-system-curl|--no-system-expat|--no-system-jsoncpp|--no-system-libarchive|--no-system-librhash|--no-system-zlib|--no-system-liblzma)
     lib=`cmake_arg "$1" "--no-system-"`
     cmake_bootstrap_system_libs="${cmake_bootstrap_system_libs} -DCMAKE_USE_SYSTEM_LIBRARY_`cmake_toupper $lib`=0" ;;
   --qt-gui) cmake_bootstrap_qt_gui="1" ;;

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=33e25b1dedcda14fbcccd14281edb412a0c14cac
commit 33e25b1dedcda14fbcccd14281edb412a0c14cac
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 13:29:31 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 14:07:49 2016 -0400

    FindLibRHash: Add module to find the librhash package
    
    Add it to a private source directory that is not installed so that we
    can use it for building CMake itself.  This will allow it to mature
    before being distributed publicly.

diff --git a/Source/Modules/FindLibRHash.cmake b/Source/Modules/FindLibRHash.cmake
new file mode 100644
index 0000000..86c6189
--- /dev/null
+++ b/Source/Modules/FindLibRHash.cmake
@@ -0,0 +1,73 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindLibRHash
+------------
+
+Find LibRHash include directory and library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+An :ref:`imported target <Imported targets>` named
+``LibRHash::LibRHash`` is provided if LibRHash has been found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This module defines the following variables:
+
+``LibRHash_FOUND``
+  True if LibRHash was found, false otherwise.
+``LibRHash_INCLUDE_DIRS``
+  Include directories needed to include LibRHash headers.
+``LibRHash_LIBRARIES``
+  Libraries needed to link to LibRHash.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+This module uses the following cache variables:
+
+``LibRHash_LIBRARY``
+  The location of the LibRHash library file.
+``LibRHash_INCLUDE_DIR``
+  The location of the LibRHash include directory containing ``rhash.h``.
+
+The cache variables should not be used by project code.
+They may be set by end users to point at LibRHash components.
+#]=======================================================================]
+
+#-----------------------------------------------------------------------------
+find_library(LibRHash_LIBRARY
+  NAMES rhash
+  )
+mark_as_advanced(LibRHash_LIBRARY)
+
+find_path(LibRHash_INCLUDE_DIR
+  NAMES rhash.h
+  )
+mark_as_advanced(LibRHash_INCLUDE_DIR)
+
+#-----------------------------------------------------------------------------
+include(${CMAKE_CURRENT_LIST_DIR}/../../Modules/FindPackageHandleStandardArgs.cmake)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibRHash
+  FOUND_VAR LibRHash_FOUND
+  REQUIRED_VARS LibRHash_LIBRARY LibRHash_INCLUDE_DIR
+  )
+set(LIBRHASH_FOUND ${LibRHash_FOUND})
+
+#-----------------------------------------------------------------------------
+# Provide documented result variables and targets.
+if(LibRHash_FOUND)
+  set(LibRHash_INCLUDE_DIRS ${LibRHash_INCLUDE_DIR})
+  set(LibRHash_LIBRARIES ${LibRHash_LIBRARY})
+  if(NOT TARGET LibRHash::LibRHash)
+    add_library(LibRHash::LibRHash UNKNOWN IMPORTED)
+    set_target_properties(LibRHash::LibRHash PROPERTIES
+      IMPORTED_LOCATION "${LibRHash_LIBRARY}"
+      INTERFACE_INCLUDE_DIRECTORIES "${LibRHash_INCLUDE_DIRS}"
+      )
+  endif()
+endif()
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 5d72e5c..3a3c76c 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1377,6 +1377,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     add_subdirectory(FindJsonCpp)
   endif()
 
+  if(CMake_TEST_FindLibRHash)
+    add_subdirectory(FindLibRHash)
+  endif()
+
   if(CMake_TEST_FindLibUV)
     add_subdirectory(FindLibUV)
   endif()
diff --git a/Tests/FindLibRHash/CMakeLists.txt b/Tests/FindLibRHash/CMakeLists.txt
new file mode 100644
index 0000000..4d3954d
--- /dev/null
+++ b/Tests/FindLibRHash/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindLibRHash.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindLibRHash/Test"
+  "${CMake_BINARY_DIR}/Tests/FindLibRHash/Test"
+  ${build_generator_args}
+  --build-project TestFindLibRHash
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindLibRHash/Test/CMakeLists.txt b/Tests/FindLibRHash/Test/CMakeLists.txt
new file mode 100644
index 0000000..37e062a
--- /dev/null
+++ b/Tests/FindLibRHash/Test/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.7)
+project(TestFindLibRHash C)
+include(CTest)
+
+# CMake does not actually provide FindLibRHash publicly.
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../Source/Modules)
+
+find_package(LibRHash REQUIRED)
+
+add_executable(test_librhash_tgt main.c)
+target_link_libraries(test_librhash_tgt LibRHash::LibRHash)
+add_test(NAME test_librhash_tgt COMMAND test_librhash_tgt)
+
+add_executable(test_librhash_var main.c)
+target_include_directories(test_librhash_var PRIVATE ${LibRHash_INCLUDE_DIRS})
+target_link_libraries(test_librhash_var PRIVATE ${LibRHash_LIBRARIES})
+add_test(NAME test_librhash_var COMMAND test_librhash_var)
diff --git a/Tests/FindLibRHash/Test/main.c b/Tests/FindLibRHash/Test/main.c
new file mode 100644
index 0000000..201dced
--- /dev/null
+++ b/Tests/FindLibRHash/Test/main.c
@@ -0,0 +1,7 @@
+#include <rhash.h>
+
+int main()
+{
+  rhash_library_init();
+  return 0;
+}

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c4cd1d2f5b8ab579c620ff7eb24ceab2b7830644
commit c4cd1d2f5b8ab579c620ff7eb24ceab2b7830644
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 13:28:03 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 14:07:49 2016 -0400

    Remove unused cm_sha2 infrastructure
    
    All clients of `cm_sha2` have been ported to `cmCryptoHash`, which now
    uses librhash internally.

diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 48dd3de..07a9fdb 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -17,7 +17,6 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
   "Utilities.cmbzip2."
   "Source.CTest.Curl"
   "Source.CursesDialog.form"
-  "Source.cm_sha2.*warning.*cast increases required alignment of target type"
   "Utilities.cmcurl"
   "Utilities.cmexpat."
   "Utilities.cmlibarchive"
@@ -84,7 +83,6 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
   "warning: Value stored to 'yytoken' is never read"
   "index_encoder.c.241.2. warning: Value stored to .out_start. is never read"
   "index.c.*warning: Access to field.*results in a dereference of a null pointer.*loaded from variable.*"
-  "cm_sha2.*warning: Value stored to.*is never read"
   "cmFortranLexer.cxx:[0-9]+:[0-9]+: warning: Call to 'realloc' has an allocation size of 0 bytes"
   "testProcess.*warning: Dereference of null pointer .loaded from variable .invalidAddress.."
   "liblzma/simple/x86.c:[0-9]+:[0-9]+: warning: The result of the '<<' expression is undefined"
diff --git a/Source/.gitattributes b/Source/.gitattributes
index 5002b2a..e9e35bd 100644
--- a/Source/.gitattributes
+++ b/Source/.gitattributes
@@ -1,6 +1,3 @@
-# Preserve upstream indentation style.
-cm_sha2.*        whitespace=indent-with-non-tab
-
 # Preserve indentation style in generated code.
 cmListFileLexer.c       whitespace=-tab-in-indent,-indent-with-non-tab
 cmFortranLexer.cxx      whitespace=-tab-in-indent,-indent-with-non-tab
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 879272c..718b022 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -626,8 +626,6 @@ set(SRCS
   cm_auto_ptr.hxx
   cm_get_date.h
   cm_get_date.c
-  cm_sha2.h
-  cm_sha2.c
   cm_utf8.h
   cm_utf8.c
   cm_codecvt.hxx
diff --git a/Source/cm_sha2.c b/Source/cm_sha2.c
deleted file mode 100644
index 649c39a..0000000
--- a/Source/cm_sha2.c
+++ /dev/null
@@ -1,1613 +0,0 @@
-/*
- * FILE:	sha2.c
- * AUTHOR:	Aaron D. Gifford
- *		http://www.aarongifford.com/computers/sha.html
- *
- * Copyright (c) 2000-2003, Aaron D. Gifford
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holder nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: sha2.c,v 1.4 2004/01/07 22:58:18 adg Exp $
- */
-
-#include <string.h>	/* memcpy()/memset() or bcopy()/bzero() */
-#include <assert.h>	/* assert() */
-#include "cm_sha2.h"	/* "sha2.h" -> "cm_sha2.h" renamed for CMake */
-
-/*
- * ASSERT NOTE:
- * Some sanity checking code is included using assert().  On my FreeBSD
- * system, this additional code can be removed by compiling with NDEBUG
- * defined.  Check your own systems manpage on assert() to see how to
- * compile WITHOUT the sanity checking code on your system.
- *
- * UNROLLED TRANSFORM LOOP NOTE:
- * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform
- * loop version for the hash transform rounds (defined using macros
- * later in this file).  Either define on the command line, for example:
- *
- *   cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c
- *
- * or define below:
- *
- *   #define SHA2_UNROLL_TRANSFORM
- *
- */
-
-
-/*** SHA-224/256/384/512 Machine Architecture Definitions *************/
-/*
- * BYTE_ORDER NOTE:
- *
- * Please make sure that your system defines BYTE_ORDER.  If your
- * architecture is little-endian, make sure it also defines
- * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
- * equivilent.
- *
- * If your system does not define the above, then you can do so by
- * hand like this:
- *
- *   #define LITTLE_ENDIAN 1234
- *   #define BIG_ENDIAN    4321
- *
- * And for little-endian machines, add:
- *
- *   #define BYTE_ORDER LITTLE_ENDIAN
- *
- * Or for big-endian machines:
- *
- *   #define BYTE_ORDER BIG_ENDIAN
- *
- * The FreeBSD machine this was written on defines BYTE_ORDER
- * appropriately by including <sys/types.h> (which in turn includes
- * <machine/endian.h> where the appropriate definitions are actually
- * made).
- */
-#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
-/* CMake modification: use byte order from KWIML.  */
-# undef BYTE_ORDER
-# undef BIG_ENDIAN
-# undef LITTLE_ENDIAN
-# define BYTE_ORDER    KWIML_ABI_ENDIAN_ID
-# define BIG_ENDIAN    KWIML_ABI_ENDIAN_ID_BIG
-# define LITTLE_ENDIAN KWIML_ABI_ENDIAN_ID_LITTLE
-#endif
-
-/* CMake modification: use types computed in header.  */
-typedef cm_sha2_uint8_t  sha_byte;	/* Exactly 1 byte */
-typedef cm_sha2_uint32_t sha_word32;	/* Exactly 4 bytes */
-typedef cm_sha2_uint64_t sha_word64;	/* Exactly 8 bytes */
-#define SHA_UINT32_C(x) KWIML_INT_UINT32_C(x)
-#define SHA_UINT64_C(x) KWIML_INT_UINT64_C(x)
-#if defined(__clang__)
-# pragma clang diagnostic ignored "-Wcast-align"
-#endif
-
-/*** ENDIAN REVERSAL MACROS *******************************************/
-#if BYTE_ORDER == LITTLE_ENDIAN
-#define REVERSE32(w,x)	{ \
-	sha_word32 tmp = (w); \
-	tmp = (tmp >> 16) | (tmp << 16); \
-	(x) = ((tmp & SHA_UINT32_C(0xff00ff00)) >> 8) | \
-	      ((tmp & SHA_UINT32_C(0x00ff00ff)) << 8); \
-}
-#define REVERSE64(w,x)	{ \
-	sha_word64 tmp = (w); \
-	tmp = (tmp >> 32) | (tmp << 32); \
-	tmp = ((tmp & SHA_UINT64_C(0xff00ff00ff00ff00)) >> 8) | \
-	      ((tmp & SHA_UINT64_C(0x00ff00ff00ff00ff)) << 8); \
-	(x) = ((tmp & SHA_UINT64_C(0xffff0000ffff0000)) >> 16) | \
-	      ((tmp & SHA_UINT64_C(0x0000ffff0000ffff)) << 16); \
-}
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-/*
- * Macro for incrementally adding the unsigned 64-bit integer n to the
- * unsigned 128-bit integer (represented using a two-element array of
- * 64-bit words):
- */
-#define ADDINC128(w,n)	{ \
-	(w)[0] += (sha_word64)(n); \
-	if ((w)[0] < (n)) { \
-		(w)[1]++; \
-	} \
-}
-
-/*
- * Macros for copying blocks of memory and for zeroing out ranges
- * of memory.  Using these macros makes it easy to switch from
- * using memset()/memcpy() and using bzero()/bcopy().
- *
- * Please define either SHA2_USE_MEMSET_MEMCPY or define
- * SHA2_USE_BZERO_BCOPY depending on which function set you
- * choose to use:
- */
-#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
-/* Default to memset()/memcpy() if no option is specified */
-#define	SHA2_USE_MEMSET_MEMCPY	1
-#endif
-#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
-/* Abort with an error if BOTH options are defined */
-#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
-#endif
-
-#ifdef SHA2_USE_MEMSET_MEMCPY
-#define MEMSET_BZERO(p,l)	memset((p), 0, (l))
-#define MEMCPY_BCOPY(d,s,l)	memcpy((d), (s), (l))
-#endif
-#ifdef SHA2_USE_BZERO_BCOPY
-#define MEMSET_BZERO(p,l)	bzero((p), (l))
-#define MEMCPY_BCOPY(d,s,l)	bcopy((s), (d), (l))
-#endif
-
-
-/*** THE SIX LOGICAL FUNCTIONS ****************************************/
-/*
- * Bit shifting and rotation (used by the six SHA-XYZ logical functions:
- *
- *   NOTE:  In the original SHA-256/384/512 document, the shift-right
- *   function was named R and the rotate-right function was called S.
- *   (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the
- *   web.)
- *
- *   The newer NIST FIPS 180-2 document uses a much clearer naming
- *   scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for
- *   rotate-left.  (See:
- *   http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
- *   on the web.)
- *
- *   WARNING: These macros must be used cautiously, since they reference
- *   supplied parameters sometimes more than once, and thus could have
- *   unexpected side-effects if used without taking this into account.
- */
-/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
-#define SHR(b,x) 		((x) >> (b))
-/* 32-bit Rotate-right (used in SHA-256): */
-#define ROTR32(b,x)	(((x) >> (b)) | ((x) << (32 - (b))))
-/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */
-#define ROTR64(b,x)	(((x) >> (b)) | ((x) << (64 - (b))))
-/* 32-bit Rotate-left (used in SHA-1): */
-#define ROTL32(b,x)	(((x) << (b)) | ((x) >> (32 - (b))))
-
-/* Two logical functions used in SHA-1, SHA-254, SHA-256, SHA-384, and SHA-512: */
-#define Ch(x,y,z)	(((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z)	(((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-/* Function used in SHA-1: */
-#define Parity(x,y,z)	((x) ^ (y) ^ (z))
-
-/* Four logical functions used in SHA-256: */
-#define Sigma0_256(x)	(ROTR32(2,  (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x)))
-#define Sigma1_256(x)	(ROTR32(6,  (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x)))
-#define sigma0_256(x)	(ROTR32(7,  (x)) ^ ROTR32(18, (x)) ^ SHR(   3 , (x)))
-#define sigma1_256(x)	(ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR(   10, (x)))
-
-/* Four of six logical functions used in SHA-384 and SHA-512: */
-#define Sigma0_512(x)	(ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x)))
-#define Sigma1_512(x)	(ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x)))
-#define sigma0_512(x)	(ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR(    7, (x)))
-#define sigma1_512(x)	(ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR(    6, (x)))
-
-/*** INTERNAL FUNCTION PROTOTYPES *************************************/
-
-/* SHA-224 and SHA-256: */
-void SHA256_Internal_Init(SHA_CTX*, const sha_word32*);
-void SHA256_Internal_Last(SHA_CTX*);
-void SHA256_Internal_Transform(SHA_CTX*, const sha_word32*);
-
-/* SHA-384 and SHA-512: */
-void SHA512_Internal_Init(SHA_CTX*, const sha_word64*);
-void SHA512_Internal_Last(SHA_CTX*);
-void SHA512_Internal_Transform(SHA_CTX*, const sha_word64*);
-
-
-/*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/
-
-/* Hash constant words K for SHA-1: */
-#define K1_0_TO_19	SHA_UINT32_C(0x5a827999)
-#define K1_20_TO_39	SHA_UINT32_C(0x6ed9eba1)
-#define K1_40_TO_59	SHA_UINT32_C(0x8f1bbcdc)
-#define K1_60_TO_79	SHA_UINT32_C(0xca62c1d6)
-
-/* Initial hash value H for SHA-1: */
-static const sha_word32 sha1_initial_hash_value[5] = {
-	SHA_UINT32_C(0x67452301),
-	SHA_UINT32_C(0xefcdab89),
-	SHA_UINT32_C(0x98badcfe),
-	SHA_UINT32_C(0x10325476),
-	SHA_UINT32_C(0xc3d2e1f0)
-};
-
-/* Hash constant words K for SHA-224 and SHA-256: */
-static const sha_word32 K256[64] = {
-	SHA_UINT32_C(0x428a2f98), SHA_UINT32_C(0x71374491),
-	SHA_UINT32_C(0xb5c0fbcf), SHA_UINT32_C(0xe9b5dba5),
-	SHA_UINT32_C(0x3956c25b), SHA_UINT32_C(0x59f111f1),
-	SHA_UINT32_C(0x923f82a4), SHA_UINT32_C(0xab1c5ed5),
-	SHA_UINT32_C(0xd807aa98), SHA_UINT32_C(0x12835b01),
-	SHA_UINT32_C(0x243185be), SHA_UINT32_C(0x550c7dc3),
-	SHA_UINT32_C(0x72be5d74), SHA_UINT32_C(0x80deb1fe),
-	SHA_UINT32_C(0x9bdc06a7), SHA_UINT32_C(0xc19bf174),
-	SHA_UINT32_C(0xe49b69c1), SHA_UINT32_C(0xefbe4786),
-	SHA_UINT32_C(0x0fc19dc6), SHA_UINT32_C(0x240ca1cc),
-	SHA_UINT32_C(0x2de92c6f), SHA_UINT32_C(0x4a7484aa),
-	SHA_UINT32_C(0x5cb0a9dc), SHA_UINT32_C(0x76f988da),
-	SHA_UINT32_C(0x983e5152), SHA_UINT32_C(0xa831c66d),
-	SHA_UINT32_C(0xb00327c8), SHA_UINT32_C(0xbf597fc7),
-	SHA_UINT32_C(0xc6e00bf3), SHA_UINT32_C(0xd5a79147),
-	SHA_UINT32_C(0x06ca6351), SHA_UINT32_C(0x14292967),
-	SHA_UINT32_C(0x27b70a85), SHA_UINT32_C(0x2e1b2138),
-	SHA_UINT32_C(0x4d2c6dfc), SHA_UINT32_C(0x53380d13),
-	SHA_UINT32_C(0x650a7354), SHA_UINT32_C(0x766a0abb),
-	SHA_UINT32_C(0x81c2c92e), SHA_UINT32_C(0x92722c85),
-	SHA_UINT32_C(0xa2bfe8a1), SHA_UINT32_C(0xa81a664b),
-	SHA_UINT32_C(0xc24b8b70), SHA_UINT32_C(0xc76c51a3),
-	SHA_UINT32_C(0xd192e819), SHA_UINT32_C(0xd6990624),
-	SHA_UINT32_C(0xf40e3585), SHA_UINT32_C(0x106aa070),
-	SHA_UINT32_C(0x19a4c116), SHA_UINT32_C(0x1e376c08),
-	SHA_UINT32_C(0x2748774c), SHA_UINT32_C(0x34b0bcb5),
-	SHA_UINT32_C(0x391c0cb3), SHA_UINT32_C(0x4ed8aa4a),
-	SHA_UINT32_C(0x5b9cca4f), SHA_UINT32_C(0x682e6ff3),
-	SHA_UINT32_C(0x748f82ee), SHA_UINT32_C(0x78a5636f),
-	SHA_UINT32_C(0x84c87814), SHA_UINT32_C(0x8cc70208),
-	SHA_UINT32_C(0x90befffa), SHA_UINT32_C(0xa4506ceb),
-	SHA_UINT32_C(0xbef9a3f7), SHA_UINT32_C(0xc67178f2)
-};
-
-/* Initial hash value H for SHA-224: */
-static const sha_word32 sha224_initial_hash_value[8] = {
-	SHA_UINT32_C(0xc1059ed8),
-	SHA_UINT32_C(0x367cd507),
-	SHA_UINT32_C(0x3070dd17),
-	SHA_UINT32_C(0xf70e5939),
-	SHA_UINT32_C(0xffc00b31),
-	SHA_UINT32_C(0x68581511),
-	SHA_UINT32_C(0x64f98fa7),
-	SHA_UINT32_C(0xbefa4fa4)
-};
-
-/* Initial hash value H for SHA-256: */
-static const sha_word32 sha256_initial_hash_value[8] = {
-	SHA_UINT32_C(0x6a09e667),
-	SHA_UINT32_C(0xbb67ae85),
-	SHA_UINT32_C(0x3c6ef372),
-	SHA_UINT32_C(0xa54ff53a),
-	SHA_UINT32_C(0x510e527f),
-	SHA_UINT32_C(0x9b05688c),
-	SHA_UINT32_C(0x1f83d9ab),
-	SHA_UINT32_C(0x5be0cd19)
-};
-
-/* Hash constant words K for SHA-384 and SHA-512: */
-static const sha_word64 K512[80] = {
-	SHA_UINT64_C(0x428a2f98d728ae22), SHA_UINT64_C(0x7137449123ef65cd),
-	SHA_UINT64_C(0xb5c0fbcfec4d3b2f), SHA_UINT64_C(0xe9b5dba58189dbbc),
-	SHA_UINT64_C(0x3956c25bf348b538), SHA_UINT64_C(0x59f111f1b605d019),
-	SHA_UINT64_C(0x923f82a4af194f9b), SHA_UINT64_C(0xab1c5ed5da6d8118),
-	SHA_UINT64_C(0xd807aa98a3030242), SHA_UINT64_C(0x12835b0145706fbe),
-	SHA_UINT64_C(0x243185be4ee4b28c), SHA_UINT64_C(0x550c7dc3d5ffb4e2),
-	SHA_UINT64_C(0x72be5d74f27b896f), SHA_UINT64_C(0x80deb1fe3b1696b1),
-	SHA_UINT64_C(0x9bdc06a725c71235), SHA_UINT64_C(0xc19bf174cf692694),
-	SHA_UINT64_C(0xe49b69c19ef14ad2), SHA_UINT64_C(0xefbe4786384f25e3),
-	SHA_UINT64_C(0x0fc19dc68b8cd5b5), SHA_UINT64_C(0x240ca1cc77ac9c65),
-	SHA_UINT64_C(0x2de92c6f592b0275), SHA_UINT64_C(0x4a7484aa6ea6e483),
-	SHA_UINT64_C(0x5cb0a9dcbd41fbd4), SHA_UINT64_C(0x76f988da831153b5),
-	SHA_UINT64_C(0x983e5152ee66dfab), SHA_UINT64_C(0xa831c66d2db43210),
-	SHA_UINT64_C(0xb00327c898fb213f), SHA_UINT64_C(0xbf597fc7beef0ee4),
-	SHA_UINT64_C(0xc6e00bf33da88fc2), SHA_UINT64_C(0xd5a79147930aa725),
-	SHA_UINT64_C(0x06ca6351e003826f), SHA_UINT64_C(0x142929670a0e6e70),
-	SHA_UINT64_C(0x27b70a8546d22ffc), SHA_UINT64_C(0x2e1b21385c26c926),
-	SHA_UINT64_C(0x4d2c6dfc5ac42aed), SHA_UINT64_C(0x53380d139d95b3df),
-	SHA_UINT64_C(0x650a73548baf63de), SHA_UINT64_C(0x766a0abb3c77b2a8),
-	SHA_UINT64_C(0x81c2c92e47edaee6), SHA_UINT64_C(0x92722c851482353b),
-	SHA_UINT64_C(0xa2bfe8a14cf10364), SHA_UINT64_C(0xa81a664bbc423001),
-	SHA_UINT64_C(0xc24b8b70d0f89791), SHA_UINT64_C(0xc76c51a30654be30),
-	SHA_UINT64_C(0xd192e819d6ef5218), SHA_UINT64_C(0xd69906245565a910),
-	SHA_UINT64_C(0xf40e35855771202a), SHA_UINT64_C(0x106aa07032bbd1b8),
-	SHA_UINT64_C(0x19a4c116b8d2d0c8), SHA_UINT64_C(0x1e376c085141ab53),
-	SHA_UINT64_C(0x2748774cdf8eeb99), SHA_UINT64_C(0x34b0bcb5e19b48a8),
-	SHA_UINT64_C(0x391c0cb3c5c95a63), SHA_UINT64_C(0x4ed8aa4ae3418acb),
-	SHA_UINT64_C(0x5b9cca4f7763e373), SHA_UINT64_C(0x682e6ff3d6b2b8a3),
-	SHA_UINT64_C(0x748f82ee5defb2fc), SHA_UINT64_C(0x78a5636f43172f60),
-	SHA_UINT64_C(0x84c87814a1f0ab72), SHA_UINT64_C(0x8cc702081a6439ec),
-	SHA_UINT64_C(0x90befffa23631e28), SHA_UINT64_C(0xa4506cebde82bde9),
-	SHA_UINT64_C(0xbef9a3f7b2c67915), SHA_UINT64_C(0xc67178f2e372532b),
-	SHA_UINT64_C(0xca273eceea26619c), SHA_UINT64_C(0xd186b8c721c0c207),
-	SHA_UINT64_C(0xeada7dd6cde0eb1e), SHA_UINT64_C(0xf57d4f7fee6ed178),
-	SHA_UINT64_C(0x06f067aa72176fba), SHA_UINT64_C(0x0a637dc5a2c898a6),
-	SHA_UINT64_C(0x113f9804bef90dae), SHA_UINT64_C(0x1b710b35131c471b),
-	SHA_UINT64_C(0x28db77f523047d84), SHA_UINT64_C(0x32caab7b40c72493),
-	SHA_UINT64_C(0x3c9ebe0a15c9bebc), SHA_UINT64_C(0x431d67c49c100d4c),
-	SHA_UINT64_C(0x4cc5d4becb3e42b6), SHA_UINT64_C(0x597f299cfc657e2a),
-	SHA_UINT64_C(0x5fcb6fab3ad6faec), SHA_UINT64_C(0x6c44198c4a475817)
-};
-
-/* Initial hash value H for SHA-384 */
-static const sha_word64 sha384_initial_hash_value[8] = {
-	SHA_UINT64_C(0xcbbb9d5dc1059ed8),
-	SHA_UINT64_C(0x629a292a367cd507),
-	SHA_UINT64_C(0x9159015a3070dd17),
-	SHA_UINT64_C(0x152fecd8f70e5939),
-	SHA_UINT64_C(0x67332667ffc00b31),
-	SHA_UINT64_C(0x8eb44a8768581511),
-	SHA_UINT64_C(0xdb0c2e0d64f98fa7),
-	SHA_UINT64_C(0x47b5481dbefa4fa4)
-};
-
-/* Initial hash value H for SHA-512 */
-static const sha_word64 sha512_initial_hash_value[8] = {
-	SHA_UINT64_C(0x6a09e667f3bcc908),
-	SHA_UINT64_C(0xbb67ae8584caa73b),
-	SHA_UINT64_C(0x3c6ef372fe94f82b),
-	SHA_UINT64_C(0xa54ff53a5f1d36f1),
-	SHA_UINT64_C(0x510e527fade682d1),
-	SHA_UINT64_C(0x9b05688c2b3e6c1f),
-	SHA_UINT64_C(0x1f83d9abfb41bd6b),
-	SHA_UINT64_C(0x5be0cd19137e2179)
-};
-
-/*
- * Constant used by SHA224/256/384/512_End() functions for converting the
- * digest to a readable hexadecimal character string:
- */
-static const char *sha_hex_digits = "0123456789abcdef";
-
-
-/*** SHA-1: ***********************************************************/
-void SHA1_Init(SHA_CTX* context) {
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	MEMCPY_BCOPY(context->s1.state, sha1_initial_hash_value, sizeof(sha_word32) * 5);
-	MEMSET_BZERO(context->s1.buffer, 64);
-	context->s1.bitcount = 0;
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-1 round macros: */
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND1_0_TO_15(a,b,c,d,e)				\
-	REVERSE32(*data++, W1[j]);				\
-	(e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) +	\
-	     K1_0_TO_19 + W1[j];	\
-	(b) = ROTL32(30, (b));		\
-	j++;
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND1_0_TO_15(a,b,c,d,e)				\
-	(e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) +	\
-	     K1_0_TO_19 + ( W1[j] = *data++ );		\
-	(b) = ROTL32(30, (b));	\
-	j++;
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND1_16_TO_19(a,b,c,d,e)	\
-	T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];	\
-	(e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) );	\
-	(b) = ROTL32(30, b);	\
-	j++;
-
-#define ROUND1_20_TO_39(a,b,c,d,e)	\
-	T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];	\
-	(e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) );	\
-	(b) = ROTL32(30, b);	\
-	j++;
-
-#define ROUND1_40_TO_59(a,b,c,d,e)	\
-	T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];	\
-	(e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) );	\
-	(b) = ROTL32(30, b);	\
-	j++;
-
-#define ROUND1_60_TO_79(a,b,c,d,e)	\
-	T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];	\
-	(e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) );	\
-	(b) = ROTL32(30, b);	\
-	j++;
-
-void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
-	sha_word32	a, b, c, d, e;
-	sha_word32	T1, *W1;
-	int		j;
-
-	W1 = (sha_word32*)context->s1.buffer;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->s1.state[0];
-	b = context->s1.state[1];
-	c = context->s1.state[2];
-	d = context->s1.state[3];
-	e = context->s1.state[4];
-
-	j = 0;
-
-	/* Rounds 0 to 15 unrolled: */
-	ROUND1_0_TO_15(a,b,c,d,e);
-	ROUND1_0_TO_15(e,a,b,c,d);
-	ROUND1_0_TO_15(d,e,a,b,c);
-	ROUND1_0_TO_15(c,d,e,a,b);
-	ROUND1_0_TO_15(b,c,d,e,a);
-	ROUND1_0_TO_15(a,b,c,d,e);
-	ROUND1_0_TO_15(e,a,b,c,d);
-	ROUND1_0_TO_15(d,e,a,b,c);
-	ROUND1_0_TO_15(c,d,e,a,b);
-	ROUND1_0_TO_15(b,c,d,e,a);
-	ROUND1_0_TO_15(a,b,c,d,e);
-	ROUND1_0_TO_15(e,a,b,c,d);
-	ROUND1_0_TO_15(d,e,a,b,c);
-	ROUND1_0_TO_15(c,d,e,a,b);
-	ROUND1_0_TO_15(b,c,d,e,a);
-	ROUND1_0_TO_15(a,b,c,d,e);
-
-	/* Rounds 16 to 19 unrolled: */
-	ROUND1_16_TO_19(e,a,b,c,d);
-	ROUND1_16_TO_19(d,e,a,b,c);
-	ROUND1_16_TO_19(c,d,e,a,b);
-	ROUND1_16_TO_19(b,c,d,e,a);
-
-	/* Rounds 20 to 39 unrolled: */
-	ROUND1_20_TO_39(a,b,c,d,e);
-	ROUND1_20_TO_39(e,a,b,c,d);
-	ROUND1_20_TO_39(d,e,a,b,c);
-	ROUND1_20_TO_39(c,d,e,a,b);
-	ROUND1_20_TO_39(b,c,d,e,a);
-	ROUND1_20_TO_39(a,b,c,d,e);
-	ROUND1_20_TO_39(e,a,b,c,d);
-	ROUND1_20_TO_39(d,e,a,b,c);
-	ROUND1_20_TO_39(c,d,e,a,b);
-	ROUND1_20_TO_39(b,c,d,e,a);
-	ROUND1_20_TO_39(a,b,c,d,e);
-	ROUND1_20_TO_39(e,a,b,c,d);
-	ROUND1_20_TO_39(d,e,a,b,c);
-	ROUND1_20_TO_39(c,d,e,a,b);
-	ROUND1_20_TO_39(b,c,d,e,a);
-	ROUND1_20_TO_39(a,b,c,d,e);
-	ROUND1_20_TO_39(e,a,b,c,d);
-	ROUND1_20_TO_39(d,e,a,b,c);
-	ROUND1_20_TO_39(c,d,e,a,b);
-	ROUND1_20_TO_39(b,c,d,e,a);
-
-	/* Rounds 40 to 59 unrolled: */
-	ROUND1_40_TO_59(a,b,c,d,e);
-	ROUND1_40_TO_59(e,a,b,c,d);
-	ROUND1_40_TO_59(d,e,a,b,c);
-	ROUND1_40_TO_59(c,d,e,a,b);
-	ROUND1_40_TO_59(b,c,d,e,a);
-	ROUND1_40_TO_59(a,b,c,d,e);
-	ROUND1_40_TO_59(e,a,b,c,d);
-	ROUND1_40_TO_59(d,e,a,b,c);
-	ROUND1_40_TO_59(c,d,e,a,b);
-	ROUND1_40_TO_59(b,c,d,e,a);
-	ROUND1_40_TO_59(a,b,c,d,e);
-	ROUND1_40_TO_59(e,a,b,c,d);
-	ROUND1_40_TO_59(d,e,a,b,c);
-	ROUND1_40_TO_59(c,d,e,a,b);
-	ROUND1_40_TO_59(b,c,d,e,a);
-	ROUND1_40_TO_59(a,b,c,d,e);
-	ROUND1_40_TO_59(e,a,b,c,d);
-	ROUND1_40_TO_59(d,e,a,b,c);
-	ROUND1_40_TO_59(c,d,e,a,b);
-	ROUND1_40_TO_59(b,c,d,e,a);
-
-	/* Rounds 60 to 79 unrolled: */
-	ROUND1_60_TO_79(a,b,c,d,e);
-	ROUND1_60_TO_79(e,a,b,c,d);
-	ROUND1_60_TO_79(d,e,a,b,c);
-	ROUND1_60_TO_79(c,d,e,a,b);
-	ROUND1_60_TO_79(b,c,d,e,a);
-	ROUND1_60_TO_79(a,b,c,d,e);
-	ROUND1_60_TO_79(e,a,b,c,d);
-	ROUND1_60_TO_79(d,e,a,b,c);
-	ROUND1_60_TO_79(c,d,e,a,b);
-	ROUND1_60_TO_79(b,c,d,e,a);
-	ROUND1_60_TO_79(a,b,c,d,e);
-	ROUND1_60_TO_79(e,a,b,c,d);
-	ROUND1_60_TO_79(d,e,a,b,c);
-	ROUND1_60_TO_79(c,d,e,a,b);
-	ROUND1_60_TO_79(b,c,d,e,a);
-	ROUND1_60_TO_79(a,b,c,d,e);
-	ROUND1_60_TO_79(e,a,b,c,d);
-	ROUND1_60_TO_79(d,e,a,b,c);
-	ROUND1_60_TO_79(c,d,e,a,b);
-	ROUND1_60_TO_79(b,c,d,e,a);
-
-	/* Compute the current intermediate hash value */
-	context->s1.state[0] += a;
-	context->s1.state[1] += b;
-	context->s1.state[2] += c;
-	context->s1.state[3] += d;
-	context->s1.state[4] += e;
-
-	/* Clean up */
-	a = b = c = d = e = T1 = 0;
-}
-
-#else  /* SHA2_UNROLL_TRANSFORM */
-
-void SHA1_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
-	sha_word32	a, b, c, d, e;
-	sha_word32	T1, *W1;
-	int		j;
-
-	W1 = (sha_word32*)context->s1.buffer;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->s1.state[0];
-	b = context->s1.state[1];
-	c = context->s1.state[2];
-	d = context->s1.state[3];
-	e = context->s1.state[4];
-	j = 0;
-	do {
-#if BYTE_ORDER == LITTLE_ENDIAN
-		T1 = data[j];
-		/* Copy data while converting to host byte order */
-		REVERSE32(*data++, W1[j]);
-		T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + W1[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-		T1 = ROTL32(5, a) + Ch(b, c, d) + e + K1_0_TO_19 + (W1[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		e = d;
-		d = c;
-		c = ROTL32(30, b);
-		b = a;
-		a = T1;
-		j++;
-	} while (j < 16);
-
-	do {
-		T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
-		T1 = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + (W1[j&0x0f] = ROTL32(1, T1));
-		e = d;
-		d = c;
-		c = ROTL32(30, b);
-		b = a;
-		a = T1;
-		j++;
-	} while (j < 20);
-
-	do {
-		T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
-		T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + (W1[j&0x0f] = ROTL32(1, T1));
-		e = d;
-		d = c;
-		c = ROTL32(30, b);
-		b = a;
-		a = T1;
-		j++;
-	} while (j < 40);
-
-	do {
-		T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
-		T1 = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + (W1[j&0x0f] = ROTL32(1, T1));
-		e = d;
-		d = c;
-		c = ROTL32(30, b);
-		b = a;
-		a = T1;
-		j++;
-	} while (j < 60);
-
-	do {
-		T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f];
-		T1 = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + (W1[j&0x0f] = ROTL32(1, T1));
-		e = d;
-		d = c;
-		c = ROTL32(30, b);
-		b = a;
-		a = T1;
-		j++;
-	} while (j < 80);
-
-
-	/* Compute the current intermediate hash value */
-	context->s1.state[0] += a;
-	context->s1.state[1] += b;
-	context->s1.state[2] += c;
-	context->s1.state[3] += d;
-	context->s1.state[4] += e;
-
-	/* Clean up */
-	a = b = c = d = e = T1 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void SHA1_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
-	unsigned int	freespace, usedspace;
-	if (len == 0) {
-		/* Calling with no data is valid - we do nothing */
-		return;
-	}
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
-
-	usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64);
-	if (usedspace > 0) {
-		/* Calculate how much free space is available in the buffer */
-		freespace = 64 - usedspace;
-
-		if (len >= freespace) {
-			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, freespace);
-			context->s1.bitcount += freespace << 3;
-			len -= freespace;
-			data += freespace;
-			SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
-		} else {
-			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->s1.buffer[usedspace], data, len);
-			context->s1.bitcount += len << 3;
-			/* Clean up: */
-			usedspace = freespace = 0;
-			return;
-		}
-	}
-	while (len >= 64) {
-		/* Process as many complete blocks as we can */
-		SHA1_Internal_Transform(context, (const sha_word32*)data);
-		context->s1.bitcount += 512;
-		len -= 64;
-		data += 64;
-	}
-	if (len > 0) {
-		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->s1.buffer, data, len);
-		context->s1.bitcount += len << 3;
-	}
-	/* Clean up: */
-	usedspace = freespace = 0;
-}
-
-void SHA1_Final(sha_byte digest[], SHA_CTX* context) {
-	sha_word32	*d = (sha_word32*)digest;
-	unsigned int	usedspace;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	if (digest == (sha_byte*)0) {
-		/*
-		 * No digest buffer, so we can do nothing
-		 * except clean up and go home
-		 */
-		MEMSET_BZERO(context, sizeof(*context));
-		return;
-	}
-
-	usedspace = (unsigned int)((context->s1.bitcount >> 3) % 64);
-	if (usedspace == 0) {
-		/* Set-up for the last transform: */
-		MEMSET_BZERO(context->s1.buffer, 56);
-
-		/* Begin padding with a 1 bit: */
-		*context->s1.buffer = 0x80;
-	} else {
-		/* Begin padding with a 1 bit: */
-		context->s1.buffer[usedspace++] = 0x80;
-
-		if (usedspace <= 56) {
-			/* Set-up for the last transform: */
-			MEMSET_BZERO(&context->s1.buffer[usedspace], 56 - usedspace);
-		} else {
-			if (usedspace < 64) {
-				MEMSET_BZERO(&context->s1.buffer[usedspace], 64 - usedspace);
-			}
-			/* Do second-to-last transform: */
-			SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
-
-			/* And set-up for the last transform: */
-			MEMSET_BZERO(context->s1.buffer, 56);
-		}
-		/* Clean up: */
-		usedspace = 0;
-	}
-	/* Set the bit count: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-	/* Convert FROM host byte order */
-	REVERSE64(context->s1.bitcount,context->s1.bitcount);
-#endif
-	MEMCPY_BCOPY(&context->s1.buffer[56], &context->s1.bitcount,
-		     sizeof(sha_word64));
-
-	/* Final transform: */
-	SHA1_Internal_Transform(context, (const sha_word32*)context->s1.buffer);
-
-	/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-	{
-		/* Convert TO host byte order */
-		int	j;
-		for (j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) {
-			REVERSE32(context->s1.state[j],context->s1.state[j]);
-			*d++ = context->s1.state[j];
-		}
-	}
-#else
-	MEMCPY_BCOPY(d, context->s1.state, SHA1_DIGEST_LENGTH);
-#endif
-
-	/* Clean up: */
-	MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA1_End(SHA_CTX* context, char buffer[]) {
-	sha_byte	digest[SHA1_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA1_Final(digest, context);
-
-		for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
-			*buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(*context));
-	}
-	MEMSET_BZERO(digest, SHA1_DIGEST_LENGTH);
-	return buffer;
-}
-
-char* SHA1_Data(const sha_byte* data, size_t len, char digest[SHA1_DIGEST_STRING_LENGTH]) {
-	SHA_CTX	context;
-
-	SHA1_Init(&context);
-	SHA1_Update(&context, data, len);
-	return SHA1_End(&context, digest);
-}
-
-
-/*** SHA-256: *********************************************************/
-void SHA256_Internal_Init(SHA_CTX* context, const sha_word32* ihv) {
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	MEMCPY_BCOPY(context->s256.state, ihv, sizeof(sha_word32) * 8);
-	MEMSET_BZERO(context->s256.buffer, 64);
-	context->s256.bitcount = 0;
-}
-
-void SHA256_Init(SHA_CTX* context) {
-	SHA256_Internal_Init(context, sha256_initial_hash_value);
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-256 round macros: */
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
-	REVERSE32(*data++, W256[j]); \
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
-	     K256[j] + W256[j]; \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h)	\
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \
-	     K256[j] + (W256[j] = *data++); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND256(a,b,c,d,e,f,g,h)	\
-	s0 = W256[(j+1)&0x0f]; \
-	s0 = sigma0_256(s0); \
-	s1 = W256[(j+14)&0x0f]; \
-	s1 = sigma1_256(s1); \
-	T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \
-	     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \
-	j++
-
-void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
-	sha_word32	a, b, c, d, e, f, g, h, s0, s1;
-	sha_word32	T1, *W256;
-	int		j;
-
-	W256 = (sha_word32*)context->s256.buffer;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->s256.state[0];
-	b = context->s256.state[1];
-	c = context->s256.state[2];
-	d = context->s256.state[3];
-	e = context->s256.state[4];
-	f = context->s256.state[5];
-	g = context->s256.state[6];
-	h = context->s256.state[7];
-
-	j = 0;
-	do {
-		/* Rounds 0 to 15 (unrolled): */
-		ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
-	} while (j < 16);
-
-	/* Now for the remaining rounds to 64: */
-	do {
-		ROUND256(a,b,c,d,e,f,g,h);
-		ROUND256(h,a,b,c,d,e,f,g);
-		ROUND256(g,h,a,b,c,d,e,f);
-		ROUND256(f,g,h,a,b,c,d,e);
-		ROUND256(e,f,g,h,a,b,c,d);
-		ROUND256(d,e,f,g,h,a,b,c);
-		ROUND256(c,d,e,f,g,h,a,b);
-		ROUND256(b,c,d,e,f,g,h,a);
-	} while (j < 64);
-
-	/* Compute the current intermediate hash value */
-	context->s256.state[0] += a;
-	context->s256.state[1] += b;
-	context->s256.state[2] += c;
-	context->s256.state[3] += d;
-	context->s256.state[4] += e;
-	context->s256.state[5] += f;
-	context->s256.state[6] += g;
-	context->s256.state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-void SHA256_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
-	sha_word32	a, b, c, d, e, f, g, h, s0, s1;
-	sha_word32	T1, T2, *W256;
-	int		j;
-
-	W256 = (sha_word32*)context->s256.buffer;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->s256.state[0];
-	b = context->s256.state[1];
-	c = context->s256.state[2];
-	d = context->s256.state[3];
-	e = context->s256.state[4];
-	f = context->s256.state[5];
-	g = context->s256.state[6];
-	h = context->s256.state[7];
-
-	j = 0;
-	do {
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Copy data while converting to host byte order */
-		REVERSE32(*data++,W256[j]);
-		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-		/* Apply the SHA-256 compression function to update a..h with copy */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_256(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 16);
-
-	do {
-		/* Part of the message block expansion: */
-		s0 = W256[(j+1)&0x0f];
-		s0 = sigma0_256(s0);
-		s1 = W256[(j+14)&0x0f];
-		s1 = sigma1_256(s1);
-
-		/* Apply the SHA-256 compression function to update a..h */
-		T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
-		     (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
-		T2 = Sigma0_256(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 64);
-
-	/* Compute the current intermediate hash value */
-	context->s256.state[0] += a;
-	context->s256.state[1] += b;
-	context->s256.state[2] += c;
-	context->s256.state[3] += d;
-	context->s256.state[4] += e;
-	context->s256.state[5] += f;
-	context->s256.state[6] += g;
-	context->s256.state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void SHA256_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
-	unsigned int	freespace, usedspace;
-
-	if (len == 0) {
-		/* Calling with no data is valid - we do nothing */
-		return;
-	}
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
-
-	usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64);
-	if (usedspace > 0) {
-		/* Calculate how much free space is available in the buffer */
-		freespace = 64 - usedspace;
-
-		if (len >= freespace) {
-			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, freespace);
-			context->s256.bitcount += freespace << 3;
-			len -= freespace;
-			data += freespace;
-			SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
-		} else {
-			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->s256.buffer[usedspace], data, len);
-			context->s256.bitcount += len << 3;
-			/* Clean up: */
-			usedspace = freespace = 0;
-			return;
-		}
-	}
-	while (len >= 64) {
-		/* Process as many complete blocks as we can */
-		SHA256_Internal_Transform(context, (const sha_word32*)data);
-		context->s256.bitcount += 512;
-		len -= 64;
-		data += 64;
-	}
-	if (len > 0) {
-		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->s256.buffer, data, len);
-		context->s256.bitcount += len << 3;
-	}
-	/* Clean up: */
-	usedspace = freespace = 0;
-}
-
-void SHA256_Internal_Last(SHA_CTX* context) {
-	unsigned int	usedspace;
-
-	usedspace = (unsigned int)((context->s256.bitcount >> 3) % 64);
-#if BYTE_ORDER == LITTLE_ENDIAN
-	/* Convert FROM host byte order */
-	REVERSE64(context->s256.bitcount,context->s256.bitcount);
-#endif
-	if (usedspace > 0) {
-		/* Begin padding with a 1 bit: */
-		context->s256.buffer[usedspace++] = 0x80;
-
-		if (usedspace <= 56) {
-			/* Set-up for the last transform: */
-			MEMSET_BZERO(&context->s256.buffer[usedspace], 56 - usedspace);
-		} else {
-			if (usedspace < 64) {
-				MEMSET_BZERO(&context->s256.buffer[usedspace], 64 - usedspace);
-			}
-			/* Do second-to-last transform: */
-			SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
-
-			/* And set-up for the last transform: */
-			MEMSET_BZERO(context->s256.buffer, 56);
-		}
-		/* Clean up: */
-		usedspace = 0;
-	} else {
-		/* Set-up for the last transform: */
-		MEMSET_BZERO(context->s256.buffer, 56);
-
-		/* Begin padding with a 1 bit: */
-		*context->s256.buffer = 0x80;
-	}
-	/* Set the bit count: */
-	MEMCPY_BCOPY(&context->s256.buffer[56], &context->s256.bitcount,
-		     sizeof(sha_word64));
-
-	/* Final transform: */
-	SHA256_Internal_Transform(context, (const sha_word32*)context->s256.buffer);
-}
-
-void SHA256_Final(sha_byte digest[], SHA_CTX* context) {
-	sha_word32	*d = (sha_word32*)digest;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha_byte*)0) {
-		SHA256_Internal_Last(context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++) {
-				REVERSE32(context->s256.state[j],context->s256.state[j]);
-				*d++ = context->s256.state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->s256.state, SHA256_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Clean up state data: */
-	MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA256_End(SHA_CTX* context, char buffer[]) {
-	sha_byte	digest[SHA256_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA256_Final(digest, context);
-
-		for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
-			*buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(*context));
-	}
-	MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH);
-	return buffer;
-}
-
-char* SHA256_Data(const sha_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) {
-	SHA_CTX	context;
-
-	SHA256_Init(&context);
-	SHA256_Update(&context, data, len);
-	return SHA256_End(&context, digest);
-}
-
-
-/*** SHA-224: *********************************************************/
-void SHA224_Init(SHA_CTX* context) {
-	SHA256_Internal_Init(context, sha224_initial_hash_value);
-}
-
-void SHA224_Internal_Transform(SHA_CTX* context, const sha_word32* data) {
-	SHA256_Internal_Transform(context, data);
-}
-
-void SHA224_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
-	SHA256_Update(context, data, len);
-}
-
-void SHA224_Final(sha_byte digest[], SHA_CTX* context) {
-	sha_word32	*d = (sha_word32*)digest;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha_byte*)0) {
-		SHA256_Internal_Last(context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++) {
-				REVERSE32(context->s256.state[j],context->s256.state[j]);
-				*d++ = context->s256.state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->s256.state, SHA224_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Clean up state data: */
-	MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA224_End(SHA_CTX* context, char buffer[]) {
-	sha_byte	digest[SHA224_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA224_Final(digest, context);
-
-		for (i = 0; i < SHA224_DIGEST_LENGTH; i++) {
-			*buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(*context));
-	}
-	MEMSET_BZERO(digest, SHA224_DIGEST_LENGTH);
-	return buffer;
-}
-
-char* SHA224_Data(const sha_byte* data, size_t len, char digest[SHA224_DIGEST_STRING_LENGTH]) {
-	SHA_CTX	context;
-
-	SHA224_Init(&context);
-	SHA224_Update(&context, data, len);
-	return SHA224_End(&context, digest);
-}
-
-
-/*** SHA-512: *********************************************************/
-void SHA512_Internal_Init(SHA_CTX* context, const sha_word64* ihv) {
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	MEMCPY_BCOPY(context->s512.state, ihv, sizeof(sha_word64) * 8);
-	MEMSET_BZERO(context->s512.buffer, 128);
-	context->s512.bitcount[0] = context->s512.bitcount[1] =  0;
-}
-
-void SHA512_Init(SHA_CTX* context) {
-	SHA512_Internal_Init(context, sha512_initial_hash_value);
-}
-
-#ifdef SHA2_UNROLL_TRANSFORM
-
-/* Unrolled SHA-512 round macros: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
-	REVERSE64(*data++, W512[j]); \
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
-	     K512[j] + W512[j]; \
-	(d) += T1, \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \
-	j++
-
-
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \
-	     K512[j] + (W512[j] = *data++); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
-	j++
-
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-#define ROUND512(a,b,c,d,e,f,g,h)	\
-	s0 = W512[(j+1)&0x0f]; \
-	s0 = sigma0_512(s0); \
-	s1 = W512[(j+14)&0x0f]; \
-	s1 = sigma1_512(s1); \
-	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \
-	     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \
-	(d) += T1; \
-	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \
-	j++
-
-void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) {
-	sha_word64	a, b, c, d, e, f, g, h, s0, s1;
-	sha_word64	T1, *W512 = (sha_word64*)context->s512.buffer;
-	int		j;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->s512.state[0];
-	b = context->s512.state[1];
-	c = context->s512.state[2];
-	d = context->s512.state[3];
-	e = context->s512.state[4];
-	f = context->s512.state[5];
-	g = context->s512.state[6];
-	h = context->s512.state[7];
-
-	j = 0;
-	do {
-		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);
-		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);
-		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);
-		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);
-		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);
-		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);
-		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);
-		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);
-	} while (j < 16);
-
-	/* Now for the remaining rounds up to 79: */
-	do {
-		ROUND512(a,b,c,d,e,f,g,h);
-		ROUND512(h,a,b,c,d,e,f,g);
-		ROUND512(g,h,a,b,c,d,e,f);
-		ROUND512(f,g,h,a,b,c,d,e);
-		ROUND512(e,f,g,h,a,b,c,d);
-		ROUND512(d,e,f,g,h,a,b,c);
-		ROUND512(c,d,e,f,g,h,a,b);
-		ROUND512(b,c,d,e,f,g,h,a);
-	} while (j < 80);
-
-	/* Compute the current intermediate hash value */
-	context->s512.state[0] += a;
-	context->s512.state[1] += b;
-	context->s512.state[2] += c;
-	context->s512.state[3] += d;
-	context->s512.state[4] += e;
-	context->s512.state[5] += f;
-	context->s512.state[6] += g;
-	context->s512.state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = 0;
-}
-
-#else /* SHA2_UNROLL_TRANSFORM */
-
-void SHA512_Internal_Transform(SHA_CTX* context, const sha_word64* data) {
-	sha_word64	a, b, c, d, e, f, g, h, s0, s1;
-	sha_word64	T1, T2, *W512 = (sha_word64*)context->s512.buffer;
-	int		j;
-
-	/* Initialize registers with the prev. intermediate value */
-	a = context->s512.state[0];
-	b = context->s512.state[1];
-	c = context->s512.state[2];
-	d = context->s512.state[3];
-	e = context->s512.state[4];
-	f = context->s512.state[5];
-	g = context->s512.state[6];
-	h = context->s512.state[7];
-
-	j = 0;
-	do {
-#if BYTE_ORDER == LITTLE_ENDIAN
-		/* Convert TO host byte order */
-		REVERSE64(*data++, W512[j]);
-		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];
-#else /* BYTE_ORDER == LITTLE_ENDIAN */
-		/* Apply the SHA-512 compression function to update a..h with copy */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-		T2 = Sigma0_512(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 16);
-
-	do {
-		/* Part of the message block expansion: */
-		s0 = W512[(j+1)&0x0f];
-		s0 = sigma0_512(s0);
-		s1 = W512[(j+14)&0x0f];
-		s1 =  sigma1_512(s1);
-
-		/* Apply the SHA-512 compression function to update a..h */
-		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +
-		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);
-		T2 = Sigma0_512(a) + Maj(a, b, c);
-		h = g;
-		g = f;
-		f = e;
-		e = d + T1;
-		d = c;
-		c = b;
-		b = a;
-		a = T1 + T2;
-
-		j++;
-	} while (j < 80);
-
-	/* Compute the current intermediate hash value */
-	context->s512.state[0] += a;
-	context->s512.state[1] += b;
-	context->s512.state[2] += c;
-	context->s512.state[3] += d;
-	context->s512.state[4] += e;
-	context->s512.state[5] += f;
-	context->s512.state[6] += g;
-	context->s512.state[7] += h;
-
-	/* Clean up */
-	a = b = c = d = e = f = g = h = T1 = T2 = 0;
-}
-
-#endif /* SHA2_UNROLL_TRANSFORM */
-
-void SHA512_Update(SHA_CTX* context, const sha_byte *data, size_t len) {
-	unsigned int	freespace, usedspace;
-
-	if (len == 0) {
-		/* Calling with no data is valid - we do nothing */
-		return;
-	}
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0 && data != (sha_byte*)0);
-
-	usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128);
-	if (usedspace > 0) {
-		/* Calculate how much free space is available in the buffer */
-		freespace = 128 - usedspace;
-
-		if (len >= freespace) {
-			/* Fill the buffer completely and process it */
-			MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, freespace);
-			ADDINC128(context->s512.bitcount, freespace << 3);
-			len -= freespace;
-			data += freespace;
-			SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
-		} else {
-			/* The buffer is not yet full */
-			MEMCPY_BCOPY(&context->s512.buffer[usedspace], data, len);
-			ADDINC128(context->s512.bitcount, len << 3);
-			/* Clean up: */
-			usedspace = freespace = 0;
-			return;
-		}
-	}
-	while (len >= 128) {
-		/* Process as many complete blocks as we can */
-		SHA512_Internal_Transform(context, (const sha_word64*)data);
-		ADDINC128(context->s512.bitcount, 1024);
-		len -= 128;
-		data += 128;
-	}
-	if (len > 0) {
-		/* There's left-overs, so save 'em */
-		MEMCPY_BCOPY(context->s512.buffer, data, len);
-		ADDINC128(context->s512.bitcount, len << 3);
-	}
-	/* Clean up: */
-	usedspace = freespace = 0;
-}
-
-void SHA512_Internal_Last(SHA_CTX* context) {
-	unsigned int	usedspace;
-
-	usedspace = (unsigned int)((context->s512.bitcount[0] >> 3) % 128);
-#if BYTE_ORDER == LITTLE_ENDIAN
-	/* Convert FROM host byte order */
-	REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]);
-	REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]);
-#endif
-	if (usedspace > 0) {
-		/* Begin padding with a 1 bit: */
-		context->s512.buffer[usedspace++] = 0x80;
-
-		if (usedspace <= 112) {
-			/* Set-up for the last transform: */
-			MEMSET_BZERO(&context->s512.buffer[usedspace], 112 - usedspace);
-		} else {
-			if (usedspace < 128) {
-				MEMSET_BZERO(&context->s512.buffer[usedspace], 128 - usedspace);
-			}
-			/* Do second-to-last transform: */
-			SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
-
-			/* And set-up for the last transform: */
-			MEMSET_BZERO(context->s512.buffer, 112);
-		}
-		/* Clean up: */
-		usedspace = 0;
-	} else {
-		/* Prepare for final transform: */
-		MEMSET_BZERO(context->s512.buffer, 112);
-
-		/* Begin padding with a 1 bit: */
-		*context->s512.buffer = 0x80;
-	}
-	/* Store the length of input data (in bits): */
-	MEMCPY_BCOPY(&context->s512.buffer[112], &context->s512.bitcount[1],
-		     sizeof(sha_word64));
-	MEMCPY_BCOPY(&context->s512.buffer[120], &context->s512.bitcount[0],
-		     sizeof(sha_word64));
-
-	/* Final transform: */
-	SHA512_Internal_Transform(context, (const sha_word64*)context->s512.buffer);
-}
-
-void SHA512_Final(sha_byte digest[], SHA_CTX* context) {
-	sha_word64	*d = (sha_word64*)digest;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha_byte*)0) {
-		SHA512_Internal_Last(context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++) {
-				REVERSE64(context->s512.state[j],context->s512.state[j]);
-				*d++ = context->s512.state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->s512.state, SHA512_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA512_End(SHA_CTX* context, char buffer[]) {
-	sha_byte	digest[SHA512_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA512_Final(digest, context);
-
-		for (i = 0; i < SHA512_DIGEST_LENGTH; i++) {
-			*buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(*context));
-	}
-	MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH);
-	return buffer;
-}
-
-char* SHA512_Data(const sha_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) {
-	SHA_CTX	context;
-
-	SHA512_Init(&context);
-	SHA512_Update(&context, data, len);
-	return SHA512_End(&context, digest);
-}
-
-
-/*** SHA-384: *********************************************************/
-void SHA384_Init(SHA_CTX* context) {
-	SHA512_Internal_Init(context, sha384_initial_hash_value);
-}
-
-void SHA384_Update(SHA_CTX* context, const sha_byte* data, size_t len) {
-	SHA512_Update(context, data, len);
-}
-
-void SHA384_Final(sha_byte digest[], SHA_CTX* context) {
-	sha_word64	*d = (sha_word64*)digest;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	/* If no digest buffer is passed, we don't bother doing this: */
-	if (digest != (sha_byte*)0) {
-		SHA512_Internal_Last(context);
-
-		/* Save the hash data for output: */
-#if BYTE_ORDER == LITTLE_ENDIAN
-		{
-			/* Convert TO host byte order */
-			int	j;
-			for (j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++) {
-				REVERSE64(context->s512.state[j],context->s512.state[j]);
-				*d++ = context->s512.state[j];
-			}
-		}
-#else
-		MEMCPY_BCOPY(d, context->s512.state, SHA384_DIGEST_LENGTH);
-#endif
-	}
-
-	/* Zero out state data */
-	MEMSET_BZERO(context, sizeof(*context));
-}
-
-char *SHA384_End(SHA_CTX* context, char buffer[]) {
-	sha_byte	digest[SHA384_DIGEST_LENGTH], *d = digest;
-	int		i;
-
-	/* Sanity check: */
-	assert(context != (SHA_CTX*)0);
-
-	if (buffer != (char*)0) {
-		SHA384_Final(digest, context);
-
-		for (i = 0; i < SHA384_DIGEST_LENGTH; i++) {
-			*buffer++ = sha_hex_digits[(*d & 0xf0) >> 4];
-			*buffer++ = sha_hex_digits[*d & 0x0f];
-			d++;
-		}
-		*buffer = (char)0;
-	} else {
-		MEMSET_BZERO(context, sizeof(*context));
-	}
-	MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH);
-	return buffer;
-}
-
-char* SHA384_Data(const sha_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) {
-	SHA_CTX	context;
-
-	SHA384_Init(&context);
-	SHA384_Update(&context, data, len);
-	return SHA384_End(&context, digest);
-}
diff --git a/Source/cm_sha2.h b/Source/cm_sha2.h
deleted file mode 100644
index f151031..0000000
--- a/Source/cm_sha2.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * FILE:    sha2.h
- * AUTHOR:  Aaron D. Gifford
- *          http://www.aarongifford.com/computers/sha.html
- *
- * Copyright (c) 2000-2003, Aaron D. Gifford
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the copyright holder nor the names of contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: sha2.h,v 1.4 2004/01/07 19:06:18 adg Exp $
- */
-
-#ifndef __SHA2_H__
-#define __SHA2_H__
-
-#include "cm_sha2_mangle.h"
-
-/* CMake modification: use integer types from KWIML.  */
-#include <cm_kwiml.h>
-typedef KWIML_INT_uint8_t cm_sha2_uint8_t;
-typedef KWIML_INT_uint32_t cm_sha2_uint32_t;
-typedef KWIML_INT_uint64_t cm_sha2_uint64_t;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*
- * Import u_intXX_t size_t type definitions from system headers.  You
- * may need to change this, or define these things yourself in this
- * file.
- */
-#include <sys/types.h>
-
-/*** SHA-224/256/384/512 Various Length Definitions *******************/
-
-/* Digest lengths for SHA-1/224/256/384/512 */
-#define   SHA1_DIGEST_LENGTH          20
-#define   SHA1_DIGEST_STRING_LENGTH  (SHA1_DIGEST_LENGTH   * 2 + 1)
-#define SHA224_DIGEST_LENGTH          28
-#define SHA224_DIGEST_STRING_LENGTH  (SHA224_DIGEST_LENGTH * 2 + 1)
-#define SHA256_DIGEST_LENGTH          32
-#define SHA256_DIGEST_STRING_LENGTH  (SHA256_DIGEST_LENGTH * 2 + 1)
-#define SHA384_DIGEST_LENGTH          48
-#define SHA384_DIGEST_STRING_LENGTH  (SHA384_DIGEST_LENGTH * 2 + 1)
-#define SHA512_DIGEST_LENGTH          64
-#define SHA512_DIGEST_STRING_LENGTH  (SHA512_DIGEST_LENGTH * 2 + 1)
-
-
-/*** SHA-224/256/384/512 Context Structures ***************************/
-
-typedef union _SHA_CTX {
-    /* SHA-1 uses this part of the union: */
-    struct {
-	cm_sha2_uint32_t state[5];
-	cm_sha2_uint64_t bitcount;
-	cm_sha2_uint8_t  buffer[64];
-    } s1;
-
-    /* SHA-224 and SHA-256 use this part of the union: */
-    struct {
-	cm_sha2_uint32_t state[8];
-	cm_sha2_uint64_t bitcount;
-	cm_sha2_uint8_t  buffer[64];
-    } s256;
-
-    /* SHA-384 and SHA-512 use this part of the union: */
-    struct {
-	cm_sha2_uint64_t state[8];
-	cm_sha2_uint64_t bitcount[2];
-	cm_sha2_uint8_t  buffer[128];
-    } s512;
-} SHA_CTX;
-
-/*** SHA-256/384/512 Function Prototypes ******************************/
-
-void SHA1_Init(SHA_CTX*);
-void SHA1_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA1_Final(cm_sha2_uint8_t[SHA1_DIGEST_LENGTH], SHA_CTX*);
-char* SHA1_End(SHA_CTX*, char[SHA1_DIGEST_STRING_LENGTH]);
-char* SHA1_Data(const cm_sha2_uint8_t*, size_t,
-		char[SHA1_DIGEST_STRING_LENGTH]);
-
-void SHA224_Init(SHA_CTX*);
-void SHA224_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA224_Final(cm_sha2_uint8_t[SHA224_DIGEST_LENGTH], SHA_CTX*);
-char* SHA224_End(SHA_CTX*, char[SHA224_DIGEST_STRING_LENGTH]);
-char* SHA224_Data(const cm_sha2_uint8_t*, size_t,
-		  char[SHA224_DIGEST_STRING_LENGTH]);
-
-void SHA256_Init(SHA_CTX*);
-void SHA256_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA256_Final(cm_sha2_uint8_t[SHA256_DIGEST_LENGTH], SHA_CTX*);
-char* SHA256_End(SHA_CTX*, char[SHA256_DIGEST_STRING_LENGTH]);
-char* SHA256_Data(const cm_sha2_uint8_t*, size_t,
-		  char[SHA256_DIGEST_STRING_LENGTH]);
-
-void SHA384_Init(SHA_CTX*);
-void SHA384_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA384_Final(cm_sha2_uint8_t[SHA384_DIGEST_LENGTH], SHA_CTX*);
-char* SHA384_End(SHA_CTX*, char[SHA384_DIGEST_STRING_LENGTH]);
-char* SHA384_Data(const cm_sha2_uint8_t*, size_t,
-		  char[SHA384_DIGEST_STRING_LENGTH]);
-
-void SHA512_Init(SHA_CTX*);
-void SHA512_Update(SHA_CTX*, const cm_sha2_uint8_t*, size_t);
-void SHA512_Final(cm_sha2_uint8_t[SHA512_DIGEST_LENGTH], SHA_CTX*);
-char* SHA512_End(SHA_CTX*, char[SHA512_DIGEST_STRING_LENGTH]);
-char* SHA512_Data(const cm_sha2_uint8_t*, size_t,
-		  char[SHA512_DIGEST_STRING_LENGTH]);
-
-#ifdef    __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __SHA2_H__ */
diff --git a/Source/cm_sha2_mangle.h b/Source/cm_sha2_mangle.h
deleted file mode 100644
index 3dce819..0000000
--- a/Source/cm_sha2_mangle.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cm_sha2_mangle_h
-#define cm_sha2_mangle_h
-
-/* Mangle sha2 symbol names to avoid possible conflict with
-   implementations in other libraries to which CMake links.  */
-#define SHA1_Data                  cmSHA1_Data
-#define SHA1_End                   cmSHA1_End
-#define SHA1_Final                 cmSHA1_Final
-#define SHA1_Init                  cmSHA1_Init
-#define SHA1_Internal_Transform    cmSHA1_Internal_Transform
-#define SHA1_Update                cmSHA1_Update
-#define SHA224_Data                cmSHA224_Data
-#define SHA224_End                 cmSHA224_End
-#define SHA224_Final               cmSHA224_Final
-#define SHA224_Init                cmSHA224_Init
-#define SHA224_Internal_Transform  cmSHA224_Internal_Transform
-#define SHA224_Update              cmSHA224_Update
-#define SHA256_Data                cmSHA256_Data
-#define SHA256_End                 cmSHA256_End
-#define SHA256_Final               cmSHA256_Final
-#define SHA256_Init                cmSHA256_Init
-#define SHA256_Internal_Init       cmSHA256_Internal_Init
-#define SHA256_Internal_Last       cmSHA256_Internal_Last
-#define SHA256_Internal_Transform  cmSHA256_Internal_Transform
-#define SHA256_Update              cmSHA256_Update
-#define SHA384_Data                cmSHA384_Data
-#define SHA384_End                 cmSHA384_End
-#define SHA384_Final               cmSHA384_Final
-#define SHA384_Init                cmSHA384_Init
-#define SHA384_Update              cmSHA384_Update
-#define SHA512_Data                cmSHA512_Data
-#define SHA512_End                 cmSHA512_End
-#define SHA512_Final               cmSHA512_Final
-#define SHA512_Init                cmSHA512_Init
-#define SHA512_Internal_Init       cmSHA512_Internal_Init
-#define SHA512_Internal_Last       cmSHA512_Internal_Last
-#define SHA512_Internal_Transform  cmSHA512_Internal_Transform
-#define SHA512_Update              cmSHA512_Update
-
-#endif
diff --git a/Utilities/Scripts/clang-format.bash b/Utilities/Scripts/clang-format.bash
index ad3b3a1..8e07c99 100755
--- a/Utilities/Scripts/clang-format.bash
+++ b/Utilities/Scripts/clang-format.bash
@@ -121,7 +121,7 @@ $git_ls -z -- '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' |
   egrep -z -v '^Source/cmListFileLexer(\.in\.l|\.c)' |
 
   # Exclude third-party sources.
-  egrep -z -v '^Source/(cm_sha2|bindexplib)' |
+  egrep -z -v '^Source/bindexplib' |
   egrep -z -v '^Source/(kwsys|CursesDialog/form)/' |
   egrep -z -v '^Utilities/(KW|cm).*/' |
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=dfff0d5c4af796e2e5869bc2bb65d7d23cfbdd78
commit dfff0d5c4af796e2e5869bc2bb65d7d23cfbdd78
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 13:21:41 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 14:07:48 2016 -0400

    Port hash computation to cmCryptoHash
    
    Avoid using KWSys MD5 or `cm_sha2` and use the `cmCryptoHash`
    abstraction instead.

diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 4c8abd9..0c4f573 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -1060,8 +1060,8 @@ std::string cmCPackWIXGenerator::CreateNewIdForPath(std::string const& path)
 std::string cmCPackWIXGenerator::CreateHashedId(
   std::string const& path, std::string const& normalizedFilename)
 {
-  CM_AUTO_PTR<cmCryptoHash> sha1 = cmCryptoHash::New("SHA1");
-  std::string hash = sha1->HashString(path.c_str());
+  cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
+  std::string const hash = sha1.HashString(path);
 
   std::string identifier;
   identifier += hash.substr(0, 7) + "_";
diff --git a/Source/CTest/cmCTestLaunch.cxx b/Source/CTest/cmCTestLaunch.cxx
index 224681a..f7a6e0b 100644
--- a/Source/CTest/cmCTestLaunch.cxx
+++ b/Source/CTest/cmCTestLaunch.cxx
@@ -4,6 +4,7 @@
 
 #include <cmConfigure.h>
 
+#include "cmCryptoHash.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
@@ -14,7 +15,6 @@
 
 #include <cm_auto_ptr.hxx>
 #include <cmsys/FStream.hxx>
-#include <cmsys/MD5.h>
 #include <cmsys/Process.h>
 #include <cmsys/RegularExpression.hxx>
 #include <iostream>
@@ -167,17 +167,14 @@ void cmCTestLaunch::ComputeFileNames()
 
   // We hash the input command working dir and command line to obtain
   // a repeatable and (probably) unique name for log files.
-  char hash[32];
-  cmsysMD5* md5 = cmsysMD5_New();
-  cmsysMD5_Initialize(md5);
-  cmsysMD5_Append(md5, (unsigned char const*)(this->CWD.c_str()), -1);
+  cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+  md5.Initialize();
+  md5.Append(this->CWD);
   for (std::vector<std::string>::const_iterator ai = this->RealArgs.begin();
        ai != this->RealArgs.end(); ++ai) {
-    cmsysMD5_Append(md5, (unsigned char const*)ai->c_str(), -1);
+    md5.Append(*ai);
   }
-  cmsysMD5_FinalizeHex(md5, hash);
-  cmsysMD5_Delete(md5);
-  this->LogHash.assign(hash, 32);
+  this->LogHash = md5.FinalizeHex();
 
   // We store stdout and stderr in temporary log files.
   this->LogOut = this->LogDir;
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 1bade57..615bd23 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -2553,7 +2553,8 @@ bool cmFileCommand::HandleDownloadCommand(std::vector<std::string> const& args)
         this->SetError("DOWNLOAD missing sum value for EXPECTED_MD5.");
         return false;
       }
-      hash = CM_AUTO_PTR<cmCryptoHash>(cmCryptoHash::New("MD5"));
+      hash =
+        CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(cmCryptoHash::AlgoMD5));
       hashMatchMSG = "MD5 sum";
       expectedHash = cmSystemTools::LowerCase(*i);
     } else if (*i == "SHOW_PROGRESS") {
diff --git a/Source/cmFilePathUuid.cxx b/Source/cmFilePathUuid.cxx
index ad434e3..03d2524 100644
--- a/Source/cmFilePathUuid.cxx
+++ b/Source/cmFilePathUuid.cxx
@@ -107,8 +107,8 @@ std::string cmFilePathUuid::GetChecksumString(
   {
     // Calculate the file ( seed + relative path + name ) checksum
     std::vector<unsigned char> hashBytes =
-      cmCryptoHash::New("SHA256")->ByteHashString(
-        sourceRelSeed + sourceRelPath + sourceFilename);
+      cmCryptoHash(cmCryptoHash::AlgoSHA256)
+        .ByteHashString(sourceRelSeed + sourceRelPath + sourceFilename);
 
     checksumBase32 =
       cmBase32Encoder().encodeString(&hashBytes[0], hashBytes.size(), false);
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index cf51c6a..42e9df1 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -44,9 +44,9 @@
 #include <string.h>
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
+#include "cmCryptoHash.h"
 #include <cm_jsoncpp_value.h>
 #include <cm_jsoncpp_writer.h>
-#include <cmsys/MD5.h>
 #endif
 
 class cmInstalledFile;
@@ -2616,14 +2616,9 @@ void cmGlobalGenerator::AddRuleHash(const std::vector<std::string>& outputs,
   // Compute a hash of the rule.
   RuleHash hash;
   {
-    unsigned char const* data =
-      reinterpret_cast<unsigned char const*>(content.c_str());
-    int length = static_cast<int>(content.length());
-    cmsysMD5* sum = cmsysMD5_New();
-    cmsysMD5_Initialize(sum);
-    cmsysMD5_Append(sum, data, length);
-    cmsysMD5_FinalizeHex(sum, hash.Data);
-    cmsysMD5_Delete(sum);
+    cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+    std::string const md5_hex = md5.HashString(content);
+    memcpy(hash.Data, md5_hex.c_str(), 32);
   }
 
   // Shorten the output name (in expected use case).
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 4aecb1d..434cb10 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -26,7 +26,7 @@
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
 #define CM_LG_ENCODE_OBJECT_NAMES
-#include <cmsys/MD5.h>
+#include "cmCryptoHash.h"
 #endif
 
 #include <algorithm>
@@ -2001,17 +2001,6 @@ void cmLocalGenerator::GenerateTargetInstallRules(
 }
 
 #if defined(CM_LG_ENCODE_OBJECT_NAMES)
-static std::string cmLocalGeneratorMD5(const char* input)
-{
-  char md5out[32];
-  cmsysMD5* md5 = cmsysMD5_New();
-  cmsysMD5_Initialize(md5);
-  cmsysMD5_Append(md5, reinterpret_cast<unsigned char const*>(input), -1);
-  cmsysMD5_FinalizeHex(md5, md5out);
-  cmsysMD5_Delete(md5);
-  return std::string(md5out, 32);
-}
-
 static bool cmLocalGeneratorShortenObjectName(std::string& objName,
                                               std::string::size_type max_len)
 {
@@ -2020,7 +2009,8 @@ static bool cmLocalGeneratorShortenObjectName(std::string& objName,
   std::string::size_type pos =
     objName.find('/', objName.size() - max_len + 32);
   if (pos != objName.npos) {
-    std::string md5name = cmLocalGeneratorMD5(objName.substr(0, pos).c_str());
+    cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+    std::string md5name = md5.HashString(objName.substr(0, pos));
     md5name += objName.substr(pos);
     objName = md5name;
 
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 27fecdf..7738ab6 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -847,8 +847,8 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
 bool cmSystemTools::ComputeFileMD5(const std::string& source, char* md5out)
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  CM_AUTO_PTR<cmCryptoHash> md5 = cmCryptoHash::New("MD5");
-  std::string str = md5->HashFile(source);
+  cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+  std::string const str = md5.HashFile(source);
   strncpy(md5out, str.c_str(), 32);
   return !str.empty();
 #else
@@ -863,8 +863,8 @@ bool cmSystemTools::ComputeFileMD5(const std::string& source, char* md5out)
 std::string cmSystemTools::ComputeStringMD5(const std::string& input)
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  CM_AUTO_PTR<cmCryptoHash> md5 = cmCryptoHash::New("MD5");
-  return md5->HashString(input);
+  cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+  return md5.HashString(input);
 #else
   (void)input;
   cmSystemTools::Message("md5sum not supported in bootstrapping mode",
diff --git a/Source/cmUuid.cxx b/Source/cmUuid.cxx
index 904bcbb..201e1cc 100644
--- a/Source/cmUuid.cxx
+++ b/Source/cmUuid.cxx
@@ -2,9 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmUuid.h"
 
-#include "cm_sha2.h"
+#include "cmCryptoHash.h"
 
-#include <cmsys/MD5.h>
 #include <string.h>
 
 cmUuid::cmUuid()
@@ -22,16 +21,12 @@ std::string cmUuid::FromMd5(std::vector<unsigned char> const& uuidNamespace,
   std::vector<unsigned char> hashInput;
   this->CreateHashInput(uuidNamespace, name, hashInput);
 
-  cmsysMD5_s* md5 = cmsysMD5_New();
-  cmsysMD5_Initialize(md5);
-  cmsysMD5_Append(md5, &hashInput[0], int(hashInput.size()));
+  cmCryptoHash md5(cmCryptoHash::AlgoMD5);
+  md5.Initialize();
+  md5.Append(&hashInput[0], hashInput.size());
+  std::vector<unsigned char> digest = md5.Finalize();
 
-  unsigned char digest[16] = { 0 };
-  cmsysMD5_Finalize(md5, digest);
-
-  cmsysMD5_Delete(md5);
-
-  return this->FromDigest(digest, 3);
+  return this->FromDigest(&digest[0], 3);
 }
 
 std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
@@ -40,16 +35,12 @@ std::string cmUuid::FromSha1(std::vector<unsigned char> const& uuidNamespace,
   std::vector<unsigned char> hashInput;
   this->CreateHashInput(uuidNamespace, name, hashInput);
 
-  SHA_CTX* sha = new SHA_CTX;
-  SHA1_Init(sha);
-  SHA1_Update(sha, &hashInput[0], hashInput.size());
-
-  unsigned char digest[SHA1_DIGEST_LENGTH] = { 0 };
-  SHA1_Final(digest, sha);
-
-  delete sha;
+  cmCryptoHash sha1(cmCryptoHash::AlgoSHA1);
+  sha1.Initialize();
+  sha1.Append(&hashInput[0], hashInput.size());
+  std::vector<unsigned char> digest = sha1.Finalize();
 
-  return this->FromDigest(digest, 5);
+  return this->FromDigest(&digest[0], 5);
 }
 
 void cmUuid::CreateHashInput(std::vector<unsigned char> const& uuidNamespace,

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=032312e95d5f799d77789faa57c657b6be409f6a
commit 032312e95d5f799d77789faa57c657b6be409f6a
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 11:33:43 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 14:07:48 2016 -0400

    cmCryptoHash: Re-implement in terms of librhash
    
    Offer direct construction with an enumeration of supported algorithms.
    Also expose the Initialize/Append/Finalize steps publicly and add a
    FinalizeHex method.

diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index 9b3f84a..f440999 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -2,31 +2,62 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCryptoHash.h"
 
-#include "cm_sha2.h"
-
+#include <cm_kwiml.h>
+#include <cm_rhash.h>
 #include <cmsys/FStream.hxx>
-#include <cmsys/MD5.h>
 #include <string.h>
 
+static unsigned int const cmCryptoHashAlgoToId[] = {
+  /* clang-format needs this comment to break after the opening brace */
+  RHASH_MD5,    //
+  RHASH_SHA1,   //
+  RHASH_SHA224, //
+  RHASH_SHA256, //
+  RHASH_SHA384, //
+  RHASH_SHA512
+};
+
+static int cmCryptoHash_rhash_library_initialized;
+
+static rhash cmCryptoHash_rhash_init(unsigned int id)
+{
+  if (!cmCryptoHash_rhash_library_initialized) {
+    cmCryptoHash_rhash_library_initialized = 1;
+    rhash_library_init();
+  }
+  return rhash_init(id);
+}
+
+cmCryptoHash::cmCryptoHash(Algo algo)
+  : Id(cmCryptoHashAlgoToId[algo])
+  , CTX(cmCryptoHash_rhash_init(Id))
+{
+}
+
+cmCryptoHash::~cmCryptoHash()
+{
+  rhash_free(this->CTX);
+}
+
 CM_AUTO_PTR<cmCryptoHash> cmCryptoHash::New(const char* algo)
 {
   if (strcmp(algo, "MD5") == 0) {
-    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashMD5);
+    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoMD5));
   }
   if (strcmp(algo, "SHA1") == 0) {
-    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA1);
+    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA1));
   }
   if (strcmp(algo, "SHA224") == 0) {
-    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA224);
+    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA224));
   }
   if (strcmp(algo, "SHA256") == 0) {
-    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA256);
+    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA256));
   }
   if (strcmp(algo, "SHA384") == 0) {
-    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA384);
+    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA384));
   }
   if (strcmp(algo, "SHA512") == 0) {
-    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHashSHA512);
+    return CM_AUTO_PTR<cmCryptoHash>(new cmCryptoHash(AlgoSHA512));
   }
   return CM_AUTO_PTR<cmCryptoHash>(CM_NULLPTR);
 }
@@ -80,7 +111,7 @@ std::vector<unsigned char> cmCryptoHash::ByteHashFile(const std::string& file)
     this->Initialize();
     {
       // Should be efficient enough on most system:
-      cm_sha2_uint64_t buffer[512];
+      KWIML_INT_uint64_t buffer[512];
       char* buffer_c = reinterpret_cast<char*>(buffer);
       unsigned char const* buffer_uc =
         reinterpret_cast<unsigned char const*>(buffer);
@@ -117,51 +148,29 @@ std::string cmCryptoHash::HashFile(const std::string& file)
   return ByteHashToString(this->ByteHashFile(file));
 }
 
-cmCryptoHashMD5::cmCryptoHashMD5()
-  : MD5(cmsysMD5_New())
+void cmCryptoHash::Initialize()
 {
+  rhash_reset(this->CTX);
 }
 
-cmCryptoHashMD5::~cmCryptoHashMD5()
+void cmCryptoHash::Append(void const* buf, size_t sz)
 {
-  cmsysMD5_Delete(this->MD5);
+  rhash_update(this->CTX, buf, sz);
 }
 
-void cmCryptoHashMD5::Initialize()
+void cmCryptoHash::Append(std::string const& str)
 {
-  cmsysMD5_Initialize(this->MD5);
+  this->Append(str.c_str(), str.size());
 }
 
-void cmCryptoHashMD5::Append(unsigned char const* buf, int sz)
+std::vector<unsigned char> cmCryptoHash::Finalize()
 {
-  cmsysMD5_Append(this->MD5, buf, sz);
+  std::vector<unsigned char> hash(rhash_get_digest_size(this->Id), 0);
+  rhash_final(this->CTX, &hash[0]);
+  return hash;
 }
 
-std::vector<unsigned char> cmCryptoHashMD5::Finalize()
+std::string cmCryptoHash::FinalizeHex()
 {
-  std::vector<unsigned char> hash(16, 0);
-  cmsysMD5_Finalize(this->MD5, &hash[0]);
-  return hash;
+  return cmCryptoHash::ByteHashToString(this->Finalize());
 }
-
-#define cmCryptoHash_SHA_CLASS_IMPL(SHA)                                      \
-  cmCryptoHash##SHA::cmCryptoHash##SHA()                                      \
-    : SHA(new SHA_CTX)                                                        \
-  {                                                                           \
-  }                                                                           \
-  cmCryptoHash##SHA::~cmCryptoHash##SHA() { delete this->SHA; }               \
-  void cmCryptoHash##SHA::Initialize() { SHA##_Init(this->SHA); }             \
-  void cmCryptoHash##SHA::Append(unsigned char const* buf, int sz)            \
-  {                                                                           \
-    SHA##_Update(this->SHA, buf, sz);                                         \
-  }                                                                           \
-  std::vector<unsigned char> cmCryptoHash##SHA::Finalize()                    \
-  {                                                                           \
-    std::vector<unsigned char> hash(SHA##_DIGEST_LENGTH, 0);                  \
-    SHA##_Final(&hash[0], this->SHA);                                         \
-    return hash;                                                              \
-  }
-
-cmCryptoHash_SHA_CLASS_IMPL(SHA1) cmCryptoHash_SHA_CLASS_IMPL(SHA224)
-  cmCryptoHash_SHA_CLASS_IMPL(SHA256) cmCryptoHash_SHA_CLASS_IMPL(SHA384)
-    cmCryptoHash_SHA_CLASS_IMPL(SHA512)
diff --git a/Source/cmCryptoHash.h b/Source/cmCryptoHash.h
index 5c2d3ca..95080ac 100644
--- a/Source/cmCryptoHash.h
+++ b/Source/cmCryptoHash.h
@@ -15,7 +15,18 @@
 class cmCryptoHash
 {
 public:
-  virtual ~cmCryptoHash() {}
+  enum Algo
+  {
+    AlgoMD5,
+    AlgoSHA1,
+    AlgoSHA224,
+    AlgoSHA256,
+    AlgoSHA384,
+    AlgoSHA512
+  };
+
+  cmCryptoHash(Algo algo);
+  ~cmCryptoHash();
 
   /// @brief Returns a new hash generator of the requested type
   /// @arg algo Hash type name. Supported hash types are
@@ -53,47 +64,15 @@ public:
   ///         An empty string otherwise.
   std::string HashFile(const std::string& file);
 
-protected:
-  virtual void Initialize() = 0;
-  virtual void Append(unsigned char const*, int) = 0;
-  virtual std::vector<unsigned char> Finalize() = 0;
-};
-
-class cmCryptoHashMD5 : public cmCryptoHash
-{
-  struct cmsysMD5_s* MD5;
-
-public:
-  cmCryptoHashMD5();
-  ~cmCryptoHashMD5() CM_OVERRIDE;
+  void Initialize();
+  void Append(void const*, size_t);
+  void Append(std::string const& str);
+  std::vector<unsigned char> Finalize();
+  std::string FinalizeHex();
 
-protected:
-  void Initialize() CM_OVERRIDE;
-  void Append(unsigned char const* buf, int sz) CM_OVERRIDE;
-  std::vector<unsigned char> Finalize() CM_OVERRIDE;
+private:
+  unsigned int Id;
+  struct rhash_context* CTX;
 };
 
-#define cmCryptoHash_SHA_CLASS_DECL(SHA)                                      \
-  class cmCryptoHash##SHA : public cmCryptoHash                               \
-  {                                                                           \
-    union _SHA_CTX* SHA;                                                      \
-                                                                              \
-  public:                                                                     \
-    cmCryptoHash##SHA();                                                      \
-    ~cmCryptoHash##SHA();                                                     \
-                                                                              \
-  protected:                                                                  \
-    virtual void Initialize();                                                \
-    virtual void Append(unsigned char const* buf, int sz);                    \
-    virtual std::vector<unsigned char> Finalize();                            \
-  }
-
-cmCryptoHash_SHA_CLASS_DECL(SHA1);
-cmCryptoHash_SHA_CLASS_DECL(SHA224);
-cmCryptoHash_SHA_CLASS_DECL(SHA256);
-cmCryptoHash_SHA_CLASS_DECL(SHA384);
-cmCryptoHash_SHA_CLASS_DECL(SHA512);
-
-#undef cmCryptoHash_SHA_CLASS_DECL
-
 #endif

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=72b9bf5cf8e2df6fb5290afb7c2825ec54c59640
commit 72b9bf5cf8e2df6fb5290afb7c2825ec54c59640
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 11:30:09 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 14:07:48 2016 -0400

    cmCryptoHash: Avoid using subclasses at client sites
    
    Use only the main `cmCryptoHash` interface.

diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 0a3a1ab..27fecdf 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -847,8 +847,8 @@ bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
 bool cmSystemTools::ComputeFileMD5(const std::string& source, char* md5out)
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  cmCryptoHashMD5 md5;
-  std::string str = md5.HashFile(source);
+  CM_AUTO_PTR<cmCryptoHash> md5 = cmCryptoHash::New("MD5");
+  std::string str = md5->HashFile(source);
   strncpy(md5out, str.c_str(), 32);
   return !str.empty();
 #else
@@ -863,8 +863,8 @@ bool cmSystemTools::ComputeFileMD5(const std::string& source, char* md5out)
 std::string cmSystemTools::ComputeStringMD5(const std::string& input)
 {
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  cmCryptoHashMD5 md5;
-  return md5.HashString(input);
+  CM_AUTO_PTR<cmCryptoHash> md5 = cmCryptoHash::New("MD5");
+  return md5->HashString(input);
 #else
   (void)input;
   cmSystemTools::Message("md5sum not supported in bootstrapping mode",

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=56481623c6e615b2c90482dd8b6f880cd571561c
commit 56481623c6e615b2c90482dd8b6f880cd571561c
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 14:04:59 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 14:07:47 2016 -0400

    librhash: Port to KWIML for ABI and integer type information

diff --git a/Utilities/cmlibrhash/librhash/byte_order.h b/Utilities/cmlibrhash/librhash/byte_order.h
index 59a6c23..f9a0fb8 100644
--- a/Utilities/cmlibrhash/librhash/byte_order.h
+++ b/Utilities/cmlibrhash/librhash/byte_order.h
@@ -4,10 +4,6 @@
 #include "ustd.h"
 #include <stdlib.h>
 
-#ifdef __GLIBC__
-# include <endian.h>
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -32,22 +28,12 @@ extern "C" {
 
 
 /* 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_) || defined(__arm__)
+#include <cm_kwiml.h>
+#if KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_LITTLE
 # 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)
+#elif KWIML_ABI_ENDIAN_ID == KWIML_ABI_ENDIAN_ID_BIG
 # define CPU_BIG_ENDIAN
 # define IS_BIG_ENDIAN 1
 # define IS_LITTLE_ENDIAN 0
diff --git a/Utilities/cmlibrhash/librhash/ustd.h b/Utilities/cmlibrhash/librhash/ustd.h
index 5bd9aac..019b931 100644
--- a/Utilities/cmlibrhash/librhash/ustd.h
+++ b/Utilities/cmlibrhash/librhash/ustd.h
@@ -9,29 +9,31 @@
 # pragma warning(push,1)
 #endif
 
-#if _MSC_VER >= 1300
+#include <cm_kwiml.h>
 
-# 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 <stdint.h>
-# include <unistd.h>
-
-#endif /* _MSC_VER >= 1300 */
-
-#if _MSC_VER <= 1300
-# include <stdlib.h> /* size_t for vc6.0 */
-#endif /* _MSC_VER <= 1300 */
+#ifndef KWIML_INT_HAVE_INT64_T
+# define int64_t KWIML_INT_int64_t
+#endif
+#ifndef KWIML_INT_HAVE_INT32_T
+# define int32_t KWIML_INT_int32_t
+#endif
+#ifndef KWIML_INT_HAVE_INT16_T
+# define int16_t KWIML_INT_int16_t
+#endif
+#ifndef KWIML_INT_HAVE_INT8_T
+# define int8_t KWIML_INT_int8_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT64_T
+# define uint64_t KWIML_INT_uint64_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT32_T
+# define uint32_t KWIML_INT_uint32_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT16_T
+# define uint16_t KWIML_INT_uint16_t
+#endif
+#ifndef KWIML_INT_HAVE_UINT8_T
+# define uint8_t KWIML_INT_uint8_t
+#endif
 
 #endif /* LIBRHASH_USTD_H */

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=956d93a5f04bebe404b228771c87059fa1efe261
commit 956d93a5f04bebe404b228771c87059fa1efe261
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 11:26:24 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 13:47:01 2016 -0400

    librhash: Install COPYING file with CMake documentation
    
    When we install using the bundled librhash source, notify users of its
    license terms.

diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt
index 968a792..340d946 100644
--- a/Utilities/cmlibrhash/CMakeLists.txt
+++ b/Utilities/cmlibrhash/CMakeLists.txt
@@ -34,3 +34,5 @@ include_directories(
   )
 
 add_library(cmlibrhash ${librhash_sources})
+
+install(FILES COPYING README DESTINATION ${CMAKE_DOC_DIR}/cmlibrhash)

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5aebc4aa1bab731194948721301a3ed69daeaa1f
commit 5aebc4aa1bab731194948721301a3ed69daeaa1f
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 11:23:36 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 13:47:01 2016 -0400

    librhash: Disable warnings to avoid changing 3rd party code
    
    Add '-w' or equivalent flag on compilers supporting it.
    Tell MSVC to use its lowest warning level inside librhash sources.

diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt
index 47d069a..968a792 100644
--- a/Utilities/cmlibrhash/CMakeLists.txt
+++ b/Utilities/cmlibrhash/CMakeLists.txt
@@ -1,5 +1,13 @@
 project(librhash C)
 
+# Disable warnings to avoid changing 3rd party code.
+if(CMAKE_C_COMPILER_ID MATCHES
+    "^(GNU|Clang|AppleClang|XL|VisualAge|SunPro|MIPSpro|HP|Intel)$")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w")
+elseif(CMAKE_C_COMPILER_ID STREQUAL "PathScale")
+  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -woffall")
+endif()
+
 set(librhash_sources
   librhash/algorithms.c
   librhash/algorithms.h
diff --git a/Utilities/cmlibrhash/librhash/ustd.h b/Utilities/cmlibrhash/librhash/ustd.h
index 38c4e3e..5bd9aac 100644
--- a/Utilities/cmlibrhash/librhash/ustd.h
+++ b/Utilities/cmlibrhash/librhash/ustd.h
@@ -5,6 +5,10 @@
 /* Include KWSys Large File Support configuration. */
 #include <cmsys/Configure.h>
 
+#if defined(_MSC_VER)
+# pragma warning(push,1)
+#endif
+
 #if _MSC_VER >= 1300
 
 # define int64_t __int64

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=77a96b0cb74c0d040be232370356fea0a1257578
commit 77a96b0cb74c0d040be232370356fea0a1257578
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 11:18:37 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 13:46:54 2016 -0400

    librhash: Build the library within CMake
    
    Update `ustd.h` to include KWSys Large File Support configuration so
    that consistent stream libraries are used (on AIX with XL).
    
    Add a `cm_rhash.h` header to include the CMake-provided copy of the
    `rhash.h` header from CMake sources.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index a5702e1..82a34d3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -298,6 +298,10 @@ macro (CMAKE_BUILD_UTILITIES)
     add_subdirectory(Utilities/KWIML)
   endif()
 
+  set(CMAKE_LIBRHASH_LIBRARIES cmlibrhash)
+  add_subdirectory(Utilities/cmlibrhash)
+  CMAKE_SET_TARGET_FOLDER(cmlibrhash "Utilities/3rdParty")
+
   #---------------------------------------------------------------------
   # Build zlib library for Curl, CMake, and CTest.
   set(CMAKE_ZLIB_HEADER "cm_zlib.h")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index cf9dbb8..879272c 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -788,6 +788,7 @@ target_link_libraries(CMakeLib cmsys
   ${CMAKE_CURL_LIBRARIES}
   ${CMAKE_JSONCPP_LIBRARIES}
   ${CMAKE_LIBUV_LIBRARIES}
+  ${CMAKE_LIBRHASH_LIBRARIES}
   ${CMake_KWIML_LIBRARIES}
   )
 
diff --git a/Utilities/cm_rhash.h b/Utilities/cm_rhash.h
new file mode 100644
index 0000000..23d5409
--- /dev/null
+++ b/Utilities/cm_rhash.h
@@ -0,0 +1,8 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm_rhash_h
+#define cm_rhash_h
+
+#include <cmlibrhash/librhash/rhash.h>
+
+#endif
diff --git a/Utilities/cmlibrhash/CMakeLists.txt b/Utilities/cmlibrhash/CMakeLists.txt
new file mode 100644
index 0000000..47d069a
--- /dev/null
+++ b/Utilities/cmlibrhash/CMakeLists.txt
@@ -0,0 +1,28 @@
+project(librhash C)
+
+set(librhash_sources
+  librhash/algorithms.c
+  librhash/algorithms.h
+  librhash/byte_order.c
+  librhash/byte_order.h
+  librhash/hex.c
+  librhash/hex.h
+  librhash/md5.c
+  librhash/md5.h
+  librhash/rhash.c
+  librhash/rhash.h
+  librhash/sha1.c
+  librhash/sha1.h
+  librhash/sha256.c
+  librhash/sha256.h
+  librhash/sha512.c
+  librhash/sha512.h
+  librhash/ustd.h
+  librhash/util.h
+  )
+
+include_directories(
+  ${KWSYS_HEADER_ROOT}
+  )
+
+add_library(cmlibrhash ${librhash_sources})
diff --git a/Utilities/cmlibrhash/librhash/ustd.h b/Utilities/cmlibrhash/librhash/ustd.h
index 94f1ae2..38c4e3e 100644
--- a/Utilities/cmlibrhash/librhash/ustd.h
+++ b/Utilities/cmlibrhash/librhash/ustd.h
@@ -2,6 +2,9 @@
 #ifndef LIBRHASH_USTD_H
 #define LIBRHASH_USTD_H
 
+/* Include KWSys Large File Support configuration. */
+#include <cmsys/Configure.h>
+
 #if _MSC_VER >= 1300
 
 # define int64_t __int64

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=b5ae698e7aea15321ee94436cdbec9747e422209
commit b5ae698e7aea15321ee94436cdbec9747e422209
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 11:15:19 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 13:46:07 2016 -0400

    librhash: Remove source fragments not needed for CMake
    
    We only need a subset of the hash algorithms supported by librhash.
    Add preprocessor conditionals to remove source fragments that we do
    not need.  Write an alternative algorithm enumeration that matches
    the indexing on our reduced array.
    
    Also remove a few fragments outright.

diff --git a/Utilities/cmlibrhash/README b/Utilities/cmlibrhash/README
index 1e51017..4ea492f 100644
--- a/Utilities/cmlibrhash/README
+++ b/Utilities/cmlibrhash/README
@@ -1,57 +1,3 @@
-                           === 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,
diff --git a/Utilities/cmlibrhash/librhash/algorithms.c b/Utilities/cmlibrhash/librhash/algorithms.c
index 1f343a1..56d20b8 100644
--- a/Utilities/cmlibrhash/librhash/algorithms.c
+++ b/Utilities/cmlibrhash/librhash/algorithms.c
@@ -22,6 +22,7 @@
 #include "algorithms.h"
 
 /* header files of all supported hash sums */
+#if 0
 #include "aich.h"
 #include "crc32.h"
 #include "ed2k.h"
@@ -29,17 +30,21 @@
 #include "gost.h"
 #include "has160.h"
 #include "md4.h"
+#endif
 #include "md5.h"
+#if 0
 #include "ripemd-160.h"
 #include "snefru.h"
+#endif
 #include "sha1.h"
 #include "sha256.h"
 #include "sha512.h"
+#if 0
 #include "sha3.h"
 #include "tiger.h"
-#include "torrent.h"
 #include "tth.h"
 #include "whirlpool.h"
+#endif
 
 #ifdef USE_OPENSSL
 /* note: BTIH and AICH depends on the used SHA1 algorithm */
@@ -66,14 +71,19 @@ 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;
 
+#if 0
 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);
+#endif
 
+#if 0
 rhash_info info_crc32 = { RHASH_CRC32, F_BE32, 4, "CRC32", "crc32" };
 rhash_info info_md4 = { RHASH_MD4, F_LE32, 16, "MD4", "md4" };
+#endif
 rhash_info info_md5 = { RHASH_MD5, F_LE32, 16, "MD5", "md5" };
 rhash_info info_sha1 = { RHASH_SHA1,      F_BE32, 20, "SHA1", "sha1" };
+#if 0
 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" };
@@ -86,16 +96,19 @@ rhash_info info_gostpro = { RHASH_GOST_CRYPTOPRO, F_LE32, 32, "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" };
+#endif
 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" };
+#if 0
 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" };
+#endif
 
 /* some helper macros */
 #define dgshft(name) (((char*)&((name##_ctx*)0)->hash) - (char*)0)
@@ -109,13 +122,15 @@ rhash_info info_sha3_512 = { RHASH_SHA3_512, F_LE64, 64, "SHA3-512", "sha3-512"
 /* information about all hashes */
 rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
 {
+#if 0
 	{ &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 */
+#endif
 	{ &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 */
+#if 0
 	{ &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 */
@@ -125,16 +140,19 @@ rhash_hash_info rhash_hash_info_default[RHASH_HASH_COUNT] =
 	{ &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 */
+#endif
 	{ &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 */
+#if 0
 	{ &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 */
+#endif
 };
 
 /**
@@ -156,6 +174,7 @@ void rhash_init_algorithms(unsigned mask)
 	rhash_uninitialized_algorithms = 0;
 }
 
+#if 0
 /* CRC32 helper functions */
 
 /**
@@ -198,3 +217,4 @@ static void rhash_crc32_final(uint32_t* crc32, unsigned char* result)
 	result[2] = (unsigned char)(*crc32 >> 8), result[3] = (unsigned char)(*crc32);
 #endif
 }
+#endif
diff --git a/Utilities/cmlibrhash/librhash/byte_order.h b/Utilities/cmlibrhash/librhash/byte_order.h
index 77b8bb9..59a6c23 100644
--- a/Utilities/cmlibrhash/librhash/byte_order.h
+++ b/Utilities/cmlibrhash/librhash/byte_order.h
@@ -4,10 +4,6 @@
 #include "ustd.h"
 #include <stdlib.h>
 
-#ifdef IN_RHASH
-#include "config.h"
-#endif
-
 #ifdef __GLIBC__
 # include <endian.h>
 #endif
diff --git a/Utilities/cmlibrhash/librhash/rhash.c b/Utilities/cmlibrhash/librhash/rhash.c
index 98cf97e..06a5da6 100644
--- a/Utilities/cmlibrhash/librhash/rhash.c
+++ b/Utilities/cmlibrhash/librhash/rhash.c
@@ -32,8 +32,6 @@
 
 #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 */
@@ -155,8 +153,10 @@ RHASH_API rhash rhash_init(unsigned hash_id)
 			rctx->vector[i].hash_info = info;
 			rctx->vector[i].context = phash_ctx;
 
+#if 0
 			/* BTIH initialization is complex, save pointer for later */
 			if ((id & RHASH_BTIH) != 0) rctx->bt_ctx = phash_ctx;
+#endif
 			phash_ctx += (info->context_size + 7) & ~7;
 
 			/* initialize the i-th hash context */
@@ -508,6 +508,7 @@ const rhash_info* rhash_info_by_id(unsigned hash_id)
 	return rhash_info_table[rhash_ctz(hash_id)].info;
 }
 
+#if 0
 /**
  * Detect default digest output format for given hash algorithm.
  *
@@ -519,6 +520,7 @@ 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);
 }
+#endif
 
 /**
  * Returns size of binary digest for given hash algorithm.
@@ -572,6 +574,7 @@ RHASH_API const char* rhash_get_magnet_name(unsigned hash_id)
 	return (info ? info->magnet_name : 0);
 }
 
+#if 0
 static size_t rhash_get_magnet_url_size(const char* filepath,
 	rhash context, unsigned hash_mask, int flags)
 {
@@ -682,6 +685,7 @@ RHASH_API size_t rhash_print_magnet(char* output, const char* filepath,
 
 	return (output - begin);
 }
+#endif
 
 /* hash sum output */
 
@@ -809,47 +813,6 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
 }
 #endif
 
-/**
- * Process a BitTorrent-related rhash message.
- *
- * @param msg_id message identifier
- * @param bt BitTorrent context
- * @param ldata data depending on message
- * @param rdata data depending on message
- * @return message-specific data
- */
-static rhash_uptr_t process_bt_msg(unsigned msg_id, torrent_ctx* bt, rhash_uptr_t ldata, rhash_uptr_t rdata)
-{
-	if (bt == NULL) return RHASH_ERROR;
-
-	switch (msg_id) {
-	case RMSG_BT_ADD_FILE:
-		bt_add_file(bt, (const char*)ldata, *(unsigned long long*)rdata);
-		break;
-	case RMSG_BT_SET_OPTIONS:
-		bt_set_options(bt, (unsigned)ldata);
-		break;
-	case RMSG_BT_SET_ANNOUNCE:
-		bt_add_announce(bt, (const char*)ldata);
-		break;
-	case RMSG_BT_SET_PIECE_LENGTH:
-		bt_set_piece_length(bt, (size_t)ldata);
-		break;
-	case RMSG_BT_SET_BATCH_SIZE:
-		bt_set_piece_length(bt,
-			bt_default_piece_length(*(unsigned long long*)ldata));
-		break;
-	case RMSG_BT_SET_PROGRAM_NAME:
-		bt_set_program_name(bt, (const char*)ldata);
-		break;
-	case RMSG_BT_GET_TEXT:
-		return (rhash_uptr_t)bt_get_text(bt, (char**)ldata);
-	default:
-		return RHASH_ERROR; /* unknown message */
-	}
-	return 0;
-}
-
 #define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0))
 
 /**
@@ -902,16 +865,6 @@ RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t l
 		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 */
 	}
diff --git a/Utilities/cmlibrhash/librhash/rhash.h b/Utilities/cmlibrhash/librhash/rhash.h
index 73ee537..2437072 100644
--- a/Utilities/cmlibrhash/librhash/rhash.h
+++ b/Utilities/cmlibrhash/librhash/rhash.h
@@ -20,6 +20,7 @@ extern "C" {
  */
 enum rhash_ids
 {
+#if 0
 	RHASH_CRC32 = 0x01,
 	RHASH_MD4   = 0x02,
 	RHASH_MD5   = 0x04,
@@ -58,6 +59,22 @@ enum rhash_ids
 
 	/** The number of supported hash functions */
 	RHASH_HASH_COUNT = 26
+#else
+	RHASH_MD5        = 0x01,
+	RHASH_SHA1       = 0x02,
+	RHASH_SHA224     = 0x04,
+	RHASH_SHA256     = 0x08,
+	RHASH_SHA384     = 0x10,
+	RHASH_SHA512     = 0x20,
+	RHASH_ALL_HASHES =
+		RHASH_MD5 |
+		RHASH_SHA1 |
+		RHASH_SHA224 |
+		RHASH_SHA256 |
+		RHASH_SHA384 |
+		RHASH_SHA512,
+	RHASH_HASH_COUNT = 6
+#endif
 };
 
 /**
@@ -213,18 +230,6 @@ RHASH_API rhash_uptr_t rhash_transmit(
 #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 */

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=5cb1b345d932d3e0dc34a2d423894a59a6c8db35
commit 5cb1b345d932d3e0dc34a2d423894a59a6c8db35
Merge: 798b0ad 1367fcc
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 13:45:29 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 13:45:29 2016 -0400

    Merge branch 'upstream-librhash' into import-librhash
    
    * upstream-librhash:
      librhash 2016-11-01 (d839a1a8)

diff --cc Utilities/cmlibrhash/.gitattributes
index 0000000,562b12e..562b12e
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/.gitattributes
+++ b/Utilities/cmlibrhash/.gitattributes
diff --cc Utilities/cmlibrhash/COPYING
index 0000000,bf65ee1..bf65ee1
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/COPYING
+++ b/Utilities/cmlibrhash/COPYING
diff --cc Utilities/cmlibrhash/README
index 0000000,1e51017..1e51017
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/README
+++ b/Utilities/cmlibrhash/README
diff --cc Utilities/cmlibrhash/librhash/algorithms.c
index 0000000,1f343a1..1f343a1
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/algorithms.c
+++ b/Utilities/cmlibrhash/librhash/algorithms.c
diff --cc Utilities/cmlibrhash/librhash/algorithms.h
index 0000000,4db2517..4db2517
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/algorithms.h
+++ b/Utilities/cmlibrhash/librhash/algorithms.h
diff --cc Utilities/cmlibrhash/librhash/byte_order.c
index 0000000,8ce6fc8..8ce6fc8
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/byte_order.c
+++ b/Utilities/cmlibrhash/librhash/byte_order.c
diff --cc Utilities/cmlibrhash/librhash/byte_order.h
index 0000000,77b8bb9..77b8bb9
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/byte_order.h
+++ b/Utilities/cmlibrhash/librhash/byte_order.h
diff --cc Utilities/cmlibrhash/librhash/hex.c
index 0000000,c941149..c941149
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/hex.c
+++ b/Utilities/cmlibrhash/librhash/hex.c
diff --cc Utilities/cmlibrhash/librhash/hex.h
index 0000000,2b365e2..2b365e2
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/hex.h
+++ b/Utilities/cmlibrhash/librhash/hex.h
diff --cc Utilities/cmlibrhash/librhash/md5.c
index 0000000,0feb090..0feb090
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/md5.c
+++ b/Utilities/cmlibrhash/librhash/md5.c
diff --cc Utilities/cmlibrhash/librhash/md5.h
index 0000000,1af6f13..1af6f13
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/md5.h
+++ b/Utilities/cmlibrhash/librhash/md5.h
diff --cc Utilities/cmlibrhash/librhash/rhash.c
index 0000000,98cf97e..98cf97e
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/rhash.c
+++ b/Utilities/cmlibrhash/librhash/rhash.c
diff --cc Utilities/cmlibrhash/librhash/rhash.h
index 0000000,73ee537..73ee537
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/rhash.h
+++ b/Utilities/cmlibrhash/librhash/rhash.h
diff --cc Utilities/cmlibrhash/librhash/sha1.c
index 0000000,f5a053b..f5a053b
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/sha1.c
+++ b/Utilities/cmlibrhash/librhash/sha1.c
diff --cc Utilities/cmlibrhash/librhash/sha1.h
index 0000000,74b2f94..74b2f94
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/sha1.h
+++ b/Utilities/cmlibrhash/librhash/sha1.h
diff --cc Utilities/cmlibrhash/librhash/sha256.c
index 0000000,064dfe2..064dfe2
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/sha256.c
+++ b/Utilities/cmlibrhash/librhash/sha256.c
diff --cc Utilities/cmlibrhash/librhash/sha256.h
index 0000000,f87ebaa..f87ebaa
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/sha256.h
+++ b/Utilities/cmlibrhash/librhash/sha256.h
diff --cc Utilities/cmlibrhash/librhash/sha512.c
index 0000000,a3e681d..a3e681d
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/sha512.c
+++ b/Utilities/cmlibrhash/librhash/sha512.c
diff --cc Utilities/cmlibrhash/librhash/sha512.h
index 0000000,7c689be..7c689be
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/sha512.h
+++ b/Utilities/cmlibrhash/librhash/sha512.h
diff --cc Utilities/cmlibrhash/librhash/ustd.h
index 0000000,94f1ae2..94f1ae2
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/ustd.h
+++ b/Utilities/cmlibrhash/librhash/ustd.h
diff --cc Utilities/cmlibrhash/librhash/util.h
index 0000000,9f37157..9f37157
mode 000000,100644..100644
--- a/Utilities/cmlibrhash/librhash/util.h
+++ b/Utilities/cmlibrhash/librhash/util.h

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=1367fccc330b0ff314845aeb3547bbc38486913a
commit 1367fccc330b0ff314845aeb3547bbc38486913a
Author:     librhash upstream <kwrobot at kitware.com>
AuthorDate: Tue Nov 1 18:21:09 2016 +0300
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 13:45:28 2016 -0400

    librhash 2016-11-01 (d839a1a8)
    
    Code extracted from:
    
        https://github.com/rhash/rhash.git
    
    at commit d839a1a853f22b8cfd26c2006ee5481739ea1114 (master).

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..562b12e
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+* -whitespace
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..bf65ee1
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,15 @@
+
+                                RHash License
+
+Copyright (c) 2005-2014 Aleksey Kravchenko <rhash.admin at gmail.com>
+
+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!
diff --git a/README b/README
new file mode 100644
index 0000000..1e51017
--- /dev/null
+++ b/README
@@ -0,0 +1,61 @@
+                           === 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.
diff --git a/librhash/algorithms.c b/librhash/algorithms.c
new file mode 100644
index 0000000..1f343a1
--- /dev/null
+++ b/librhash/algorithms.c
@@ -0,0 +1,200 @@
+/* algorithms.c - the algorithms supported by the rhash library
+ *
+ * Copyright: 2011-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <stdio.h>
+#include <assert.h>
+
+#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
+}
diff --git a/librhash/algorithms.h b/librhash/algorithms.h
new file mode 100644
index 0000000..4db2517
--- /dev/null
+++ b/librhash/algorithms.h
@@ -0,0 +1,120 @@
+/* algorithms.h - rhash library algorithms */
+#ifndef RHASH_ALGORITHMS_H
+#define RHASH_ALGORITHMS_H
+
+#include <stddef.h> /* 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 */
diff --git a/librhash/byte_order.c b/librhash/byte_order.c
new file mode 100644
index 0000000..8ce6fc8
--- /dev/null
+++ b/librhash/byte_order.c
@@ -0,0 +1,150 @@
+/* byte_order.c - byte order related platform dependent routines,
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <intrin.h>
+#  pragma intrinsic(_BitScanForward)
+
+/**
+ * Returns index of the trailing bit of x.
+ *
+ * @param x the number to process
+ * @return zero-based index of the trailing bit
+ */
+unsigned rhash_ctz(unsigned x)
+{
+	unsigned long index;
+	unsigned char isNonzero = _BitScanForward(&index, x); /* MSVC intrinsic */
+	return (isNonzero ? (unsigned)index : 0);
+}
+#  else /* _MSC_VER >= 1300... */
+
+/**
+ * Returns index of the trailing bit of a 32-bit number.
+ * This is a plain C equivalent for GCC __builtin_ctz() bit scan.
+ *
+ * @param x the number to process
+ * @return zero-based index of the trailing bit
+ */
+unsigned rhash_ctz(unsigned x)
+{
+	/* array for conversion to bit position */
+	static unsigned char bit_pos[32] =  {
+		0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
+		31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
+	};
+
+	/* The De Bruijn bit-scan was devised in 1997, according to Donald Knuth
+	 * by Martin Lauter. The constant 0x077CB531UL is a De Bruijn sequence,
+	 * which produces a unique pattern of bits into the high 5 bits for each
+	 * possible bit position that it is multiplied against.
+	 * See http://graphics.stanford.edu/~seander/bithacks.html
+	 * and http://chessprogramming.wikispaces.com/BitScan */
+	return (unsigned)bit_pos[((uint32_t)((x & -x) * 0x077CB531U)) >> 27];
+}
+#  endif /* _MSC_VER >= 1300... */
+#endif /* !(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);
+	}
+}
diff --git a/librhash/byte_order.h b/librhash/byte_order.h
new file mode 100644
index 0000000..77b8bb9
--- /dev/null
+++ b/librhash/byte_order.h
@@ -0,0 +1,171 @@
+/* byte_order.h */
+#ifndef BYTE_ORDER_H
+#define BYTE_ORDER_H
+#include "ustd.h"
+#include <stdlib.h>
+
+#ifdef IN_RHASH
+#include "config.h"
+#endif
+
+#ifdef __GLIBC__
+# include <endian.h>
+#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_) || 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 */
diff --git a/librhash/hex.c b/librhash/hex.c
new file mode 100644
index 0000000..c941149
--- /dev/null
+++ b/librhash/hex.c
@@ -0,0 +1,188 @@
+/* hex.c - conversion for hexadecimal and base32 strings.
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <string.h>
+#include <ctype.h>
+#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;
+}
diff --git a/librhash/hex.h b/librhash/hex.h
new file mode 100644
index 0000000..2b365e2
--- /dev/null
+++ b/librhash/hex.h
@@ -0,0 +1,25 @@
+/* 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 */
diff --git a/librhash/md5.c b/librhash/md5.c
new file mode 100644
index 0000000..0feb090
--- /dev/null
+++ b/librhash/md5.c
@@ -0,0 +1,236 @@
+/* md5.c - an implementation of the MD5 algorithm, based on RFC 1321.
+ *
+ * Copyright: 2007-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <string.h>
+#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);
+}
diff --git a/librhash/md5.h b/librhash/md5.h
new file mode 100644
index 0000000..1af6f13
--- /dev/null
+++ b/librhash/md5.h
@@ -0,0 +1,31 @@
+/* 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 */
diff --git a/librhash/rhash.c b/librhash/rhash.c
new file mode 100644
index 0000000..98cf97e
--- /dev/null
+++ b/librhash/rhash.c
@@ -0,0 +1,919 @@
+/* rhash.c - implementation of LibRHash library calls
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <string.h> /* memset() */
+#include <stdlib.h> /* free() */
+#include <stddef.h> /* ptrdiff_t */
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+
+/* 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)) {
+		/* stop if canceled */
+		if (ectx->state != STATE_ACTIVE) break;
+
+		length = fread(buffer, 1, block_size, fd);
+
+		if (ferror(fd)) {
+			res = -1; /* note: errno contains error code */
+			break;
+		} else if (length) {
+			rhash_update(ctx, buffer, length);
+
+			if (ectx->callback) {
+				((rhash_callback_t)ectx->callback)(ectx->callback_data, ectx->rc.msg_size);
+			}
+		}
+	}
+
+	free(buffer);
+	return res;
+}
+
+/**
+ * Compute a single hash for given file.
+ *
+ * @param hash_id id of hash sum to compute
+ * @param filepath path to the file to hash
+ * @param result buffer to receive hash value with the lowest requested id
+ * @return 0 on success, -1 on error and errno is set
+ */
+RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result)
+{
+	FILE* fd;
+	rhash ctx;
+	int res;
+
+	hash_id &= RHASH_ALL_HASHES;
+	if (hash_id == 0) {
+		errno = EINVAL;
+		return -1;
+	}
+
+	if ((fd = fopen(filepath, "rb")) == NULL) return -1;
+
+	if ((ctx = rhash_init(hash_id)) == NULL) 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 <share.h>
+
+/**
+ * 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 <windows.h>
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved);
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
+{
+	(void)hModule;
+	(void)reserved;
+	switch (reason) {
+	case DLL_PROCESS_ATTACH:
+		rhash_library_init();
+		break;
+	case DLL_PROCESS_DETACH:
+		/*rhash_library_free();*/
+	case DLL_THREAD_ATTACH:
+	case DLL_THREAD_DETACH:
+		break;
+	}
+	return TRUE;
+}
+#endif
+
+/**
+ * Process a BitTorrent-related rhash message.
+ *
+ * @param msg_id message identifier
+ * @param bt BitTorrent context
+ * @param ldata data depending on message
+ * @param rdata data depending on message
+ * @return message-specific data
+ */
+static rhash_uptr_t process_bt_msg(unsigned msg_id, torrent_ctx* bt, rhash_uptr_t ldata, rhash_uptr_t rdata)
+{
+	if (bt == NULL) return RHASH_ERROR;
+
+	switch (msg_id) {
+	case RMSG_BT_ADD_FILE:
+		bt_add_file(bt, (const char*)ldata, *(unsigned long long*)rdata);
+		break;
+	case RMSG_BT_SET_OPTIONS:
+		bt_set_options(bt, (unsigned)ldata);
+		break;
+	case RMSG_BT_SET_ANNOUNCE:
+		bt_add_announce(bt, (const char*)ldata);
+		break;
+	case RMSG_BT_SET_PIECE_LENGTH:
+		bt_set_piece_length(bt, (size_t)ldata);
+		break;
+	case RMSG_BT_SET_BATCH_SIZE:
+		bt_set_piece_length(bt,
+			bt_default_piece_length(*(unsigned long long*)ldata));
+		break;
+	case RMSG_BT_SET_PROGRAM_NAME:
+		bt_set_program_name(bt, (const char*)ldata);
+		break;
+	case RMSG_BT_GET_TEXT:
+		return (rhash_uptr_t)bt_get_text(bt, (char**)ldata);
+	default:
+		return RHASH_ERROR; /* unknown message */
+	}
+	return 0;
+}
+
+#define PVOID2UPTR(p) ((rhash_uptr_t)((char*)p - 0))
+
+/**
+ * Process a rhash message.
+ *
+ * @param msg_id message identifier
+ * @param dst message destination (can be NULL for generic messages)
+ * @param ldata data depending on message
+ * @param rdata data depending on message
+ * @return message-specific data
+ */
+RHASH_API rhash_uptr_t rhash_transmit(unsigned msg_id, void* dst, rhash_uptr_t ldata, rhash_uptr_t rdata)
+{
+	/* for messages working with rhash context */
+	rhash_context_ext* const ctx = (rhash_context_ext*)dst;
+
+	switch (msg_id) {
+	case RMSG_GET_CONTEXT:
+		{
+			unsigned i;
+			for (i = 0; i < ctx->hash_vector_size; i++) {
+				struct rhash_hash_info* info = ctx->vector[i].hash_info;
+				if (info->info->hash_id == (unsigned)ldata)
+					return PVOID2UPTR(ctx->vector[i].context);
+			}
+			return (rhash_uptr_t)0;
+		}
+
+	case RMSG_CANCEL:
+		/* mark rhash context as canceled, in a multithreaded program */
+		atomic_compare_and_swap(&ctx->state, STATE_ACTIVE, STATE_STOPED);
+		return 0;
+
+	case RMSG_IS_CANCELED:
+		return (ctx->state == STATE_STOPED);
+
+	case RMSG_GET_FINALIZED:
+		return ((ctx->flags & RCTX_FINALIZED) != 0);
+	case RMSG_SET_AUTOFINAL:
+		ctx->flags &= ~RCTX_AUTO_FINAL;
+		if (ldata) ctx->flags |= RCTX_AUTO_FINAL;
+		break;
+
+	/* OpenSSL related messages */
+#ifdef USE_OPENSSL
+	case RMSG_SET_OPENSSL_MASK:
+		rhash_openssl_hash_mask = (unsigned)ldata;
+		break;
+	case RMSG_GET_OPENSSL_MASK:
+		return rhash_openssl_hash_mask;
+#endif
+
+	/* 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;
+}
diff --git a/librhash/rhash.h b/librhash/rhash.h
new file mode 100644
index 0000000..73ee537
--- /dev/null
+++ b/librhash/rhash.h
@@ -0,0 +1,273 @@
+/** @file rhash.h LibRHash interface */
+#ifndef RHASH_H
+#define RHASH_H
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef RHASH_API
+/* modifier for LibRHash functions */
+# define RHASH_API
+#endif
+
+/**
+ * Identifiers of supported hash functions.
+ * The rhash_init() function allows mixing several ids using
+ * binary OR, to calculate several hash functions for one message.
+ */
+enum rhash_ids
+{
+	RHASH_CRC32 = 0x01,
+	RHASH_MD4   = 0x02,
+	RHASH_MD5   = 0x04,
+	RHASH_SHA1  = 0x08,
+	RHASH_TIGER = 0x10,
+	RHASH_TTH   = 0x20,
+	RHASH_BTIH  = 0x40,
+	RHASH_ED2K  = 0x80,
+	RHASH_AICH  = 0x100,
+	RHASH_WHIRLPOOL = 0x200,
+	RHASH_RIPEMD160 = 0x400,
+	RHASH_GOST      = 0x800,
+	RHASH_GOST_CRYPTOPRO = 0x1000,
+	RHASH_HAS160    = 0x2000,
+	RHASH_SNEFRU128 = 0x4000,
+	RHASH_SNEFRU256 = 0x8000,
+	RHASH_SHA224    = 0x10000,
+	RHASH_SHA256    = 0x20000,
+	RHASH_SHA384    = 0x40000,
+	RHASH_SHA512    = 0x80000,
+	RHASH_EDONR256  = 0x0100000,
+	RHASH_EDONR512  = 0x0200000,
+	RHASH_SHA3_224  = 0x0400000,
+	RHASH_SHA3_256  = 0x0800000,
+	RHASH_SHA3_384  = 0x1000000,
+	RHASH_SHA3_512  = 0x2000000,
+
+	/** The bit-mask containing all supported hashe functions */
+	RHASH_ALL_HASHES = RHASH_CRC32 | RHASH_MD4 | RHASH_MD5 | RHASH_ED2K | RHASH_SHA1 |
+		RHASH_TIGER | RHASH_TTH | RHASH_GOST | RHASH_GOST_CRYPTOPRO |
+		RHASH_BTIH | RHASH_AICH | RHASH_WHIRLPOOL | RHASH_RIPEMD160 |
+		RHASH_HAS160 | RHASH_SNEFRU128 | RHASH_SNEFRU256 |
+		RHASH_SHA224 | RHASH_SHA256 | RHASH_SHA384 | RHASH_SHA512 |
+		RHASH_SHA3_224 | RHASH_SHA3_256 | RHASH_SHA3_384 | RHASH_SHA3_512 |
+		RHASH_EDONR256 | RHASH_EDONR512,
+
+	/** The number of supported hash functions */
+	RHASH_HASH_COUNT = 26
+};
+
+/**
+ * The rhash context structure contains contexts for several hash functions
+ */
+typedef struct rhash_context
+{
+	/** The size of the hashed message */
+	unsigned long long msg_size;
+
+	/**
+	 * The bit-mask containing identifiers of the hashes being calculated
+	 */
+	unsigned hash_id;
+} rhash_context;
+
+#ifndef LIBRHASH_RHASH_CTX_DEFINED
+#define LIBRHASH_RHASH_CTX_DEFINED
+/**
+ * Hashing context.
+ */
+typedef struct rhash_context* rhash;
+#endif /* LIBRHASH_RHASH_CTX_DEFINED */
+
+/** type of a callback to be called periodically while hashing a file */
+typedef void (*rhash_callback_t)(void* data, unsigned long long offset);
+
+RHASH_API void rhash_library_init(void); /* initialize static data */
+
+/* hi-level hashing functions */
+RHASH_API int rhash_msg(unsigned hash_id, const void* message, size_t length, unsigned char* result);
+RHASH_API int rhash_file(unsigned hash_id, const char* filepath, unsigned char* result);
+RHASH_API int rhash_file_update(rhash ctx, FILE* fd);
+
+#ifdef _WIN32 /* windows only function */
+RHASH_API int rhash_wfile(unsigned hash_id, const wchar_t* filepath, unsigned char* result);
+#endif
+
+/* lo-level interface */
+RHASH_API rhash rhash_init(unsigned hash_id);
+/*RHASH_API rhash rhash_init_by_ids(unsigned hash_ids[], unsigned count);*/
+RHASH_API int  rhash_update(rhash ctx, const void* message, size_t length);
+RHASH_API int  rhash_final(rhash ctx, unsigned char* first_result);
+RHASH_API void rhash_reset(rhash ctx); /* reinitialize the context */
+RHASH_API void rhash_free(rhash ctx);
+
+/* additional lo-level functions */
+RHASH_API void  rhash_set_callback(rhash ctx, rhash_callback_t callback, void* callback_data);
+
+/** bit-flag: default hash output format is base32 */
+#define RHASH_INFO_BASE32 1
+
+/**
+ * Information about a hash function.
+ */
+typedef struct rhash_info
+{
+	/** hash function indentifier */
+	unsigned hash_id;
+	/** flags bit-mask, including RHASH_INFO_BASE32 bit */
+	unsigned flags;
+	/** size of binary message digest in bytes */
+	size_t digest_size;
+	const char* name;
+	const char* magnet_name;
+} rhash_info;
+
+/* information functions */
+RHASH_API int  rhash_count(void); /* number of supported hashes */
+RHASH_API int  rhash_get_digest_size(unsigned hash_id); /* size of binary message digest */
+RHASH_API int  rhash_get_hash_length(unsigned hash_id); /* length of 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(UINTPTR_MAX)
+typedef uintptr_t rhash_uptr_t;
+#elif defined(_LP64) || defined(__LP64__) || defined(__x86_64) || \
+	defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
+typedef unsigned long long rhash_uptr_t;
+#else
+typedef unsigned long rhash_uptr_t;
+#endif
+
+/** The value returned by rhash_transmit on error */
+#define RHASH_ERROR ((rhash_uptr_t)-1)
+/** Convert a pointer to rhash_uptr_t */
+#define RHASH_STR2UPTR(str) ((rhash_uptr_t)(char*)(str))
+/** Convert a rhash_uptr_t to a void* pointer */
+#define RHASH_UPTR2PVOID(u) ((void*)((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 */
diff --git a/librhash/sha1.c b/librhash/sha1.c
new file mode 100644
index 0000000..f5a053b
--- /dev/null
+++ b/librhash/sha1.c
@@ -0,0 +1,196 @@
+/* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1)
+ * based on RFC 3174.
+ *
+ * Copyright: 2008-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <string.h>
+#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);
+}
diff --git a/librhash/sha1.h b/librhash/sha1.h
new file mode 100644
index 0000000..74b2f94
--- /dev/null
+++ b/librhash/sha1.h
@@ -0,0 +1,31 @@
+/* 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 */
diff --git a/librhash/sha256.c b/librhash/sha256.c
new file mode 100644
index 0000000..064dfe2
--- /dev/null
+++ b/librhash/sha256.c
@@ -0,0 +1,241 @@
+/* sha256.c - an implementation of SHA-256/224 hash functions
+ * based on FIPS 180-3 (Federal Information Processing Standart).
+ *
+ * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <string.h>
+#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);
+}
diff --git a/librhash/sha256.h b/librhash/sha256.h
new file mode 100644
index 0000000..f87ebaa
--- /dev/null
+++ b/librhash/sha256.h
@@ -0,0 +1,32 @@
+/* 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 */
diff --git a/librhash/sha512.c b/librhash/sha512.c
new file mode 100644
index 0000000..a3e681d
--- /dev/null
+++ b/librhash/sha512.c
@@ -0,0 +1,255 @@
+/* sha512.c - an implementation of SHA-384/512 hash functions
+ * based on FIPS 180-3 (Federal Information Processing Standart).
+ *
+ * Copyright: 2010-2012 Aleksey Kravchenko <rhash.admin at gmail.com>
+ *
+ * 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 <string.h>
+#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);
+}
diff --git a/librhash/sha512.h b/librhash/sha512.h
new file mode 100644
index 0000000..7c689be
--- /dev/null
+++ b/librhash/sha512.h
@@ -0,0 +1,32 @@
+/* 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 */
diff --git a/librhash/ustd.h b/librhash/ustd.h
new file mode 100644
index 0000000..94f1ae2
--- /dev/null
+++ b/librhash/ustd.h
@@ -0,0 +1,30 @@
+/* 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 <stdint.h>
+# include <unistd.h>
+
+#endif /* _MSC_VER >= 1300 */
+
+#if _MSC_VER <= 1300
+# include <stdlib.h> /* size_t for vc6.0 */
+#endif /* _MSC_VER <= 1300 */
+
+#endif /* LIBRHASH_USTD_H */
diff --git a/librhash/util.h b/librhash/util.h
new file mode 100644
index 0000000..9f37157
--- /dev/null
+++ b/librhash/util.h
@@ -0,0 +1,31 @@
+/* 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 <windows.h>
+# define atomic_compare_and_swap(ptr, oldval, newval) InterlockedCompareExchange(ptr, newval, oldval)
+#elif defined(__sun)
+# include <atomic.h>
+# 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 */

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=798b0adc628ab16dbb4d04ef444b8e7db4f5cffa
commit 798b0adc628ab16dbb4d04ef444b8e7db4f5cffa
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Nov 3 11:11:37 2016 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Nov 3 13:45:22 2016 -0400

    Add script to update librhash from upstream

diff --git a/Utilities/Scripts/update-librhash.bash b/Utilities/Scripts/update-librhash.bash
new file mode 100755
index 0000000..2f67ea2
--- /dev/null
+++ b/Utilities/Scripts/update-librhash.bash
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+set -e
+set -x
+shopt -s dotglob
+
+readonly name="librhash"
+readonly ownership="librhash upstream <kwrobot at kitware.com>"
+readonly subtree="Utilities/cmlibrhash"
+readonly repo="https://github.com/rhash/rhash.git"
+readonly tag="master"
+readonly shortlog=false
+readonly paths="
+  COPYING
+  README
+  librhash/algorithms.c
+  librhash/algorithms.h
+  librhash/byte_order.c
+  librhash/byte_order.h
+  librhash/hex.c
+  librhash/hex.h
+  librhash/md5.c
+  librhash/md5.h
+  librhash/rhash.c
+  librhash/rhash.h
+  librhash/sha1.c
+  librhash/sha1.h
+  librhash/sha256.c
+  librhash/sha256.h
+  librhash/sha512.c
+  librhash/sha512.h
+  librhash/ustd.h
+  librhash/util.h
+"
+
+extract_source () {
+    git_archive
+    pushd "${extractdir}/${name}-reduced"
+    echo "* -whitespace" > .gitattributes
+    popd
+}
+
+. "${BASH_SOURCE%/*}/update-third-party.bash"

-----------------------------------------------------------------------

Summary of changes:
 CMakeLists.txt                                  |   20 +-
 CTestCustom.cmake.in                            |    2 -
 Source/.gitattributes                           |    3 -
 Source/CMakeLists.txt                           |    3 +-
 Source/CPack/WiX/cmCPackWIXGenerator.cxx        |    4 +-
 Source/CTest/cmCTestLaunch.cxx                  |   15 +-
 Source/Modules/FindLibRHash.cmake               |   73 +
 Source/cmCryptoHash.cxx                         |   97 +-
 Source/cmCryptoHash.h                           |   61 +-
 Source/cmFileCommand.cxx                        |    3 +-
 Source/cmFilePathUuid.cxx                       |    4 +-
 Source/cmGlobalGenerator.cxx                    |   13 +-
 Source/cmLocalGenerator.cxx                     |   16 +-
 Source/cmSystemTools.cxx                        |    6 +-
 Source/cmUuid.cxx                               |   31 +-
 Source/cm_sha2.c                                | 1613 -----------------------
 Source/cm_sha2.h                                |  140 --
 Source/cm_sha2_mangle.h                         |   42 -
 Tests/CMakeLists.txt                            |    4 +
 Tests/FindLibRHash/CMakeLists.txt               |   10 +
 Tests/FindLibRHash/Test/CMakeLists.txt          |   17 +
 Tests/FindLibRHash/Test/main.c                  |    7 +
 Utilities/Scripts/clang-format.bash             |    2 +-
 Utilities/Scripts/update-librhash.bash          |   43 +
 Utilities/cmThirdParty.h.in                     |    1 +
 Utilities/cm_rhash.h                            |   14 +
 Utilities/{cmcurl => cmlibrhash}/.gitattributes |    0
 Utilities/cmlibrhash/CMakeLists.txt             |   38 +
 Utilities/cmlibrhash/COPYING                    |   15 +
 Utilities/cmlibrhash/README                     |    7 +
 Utilities/cmlibrhash/librhash/algorithms.c      |  220 ++++
 Utilities/cmlibrhash/librhash/algorithms.h      |  120 ++
 Utilities/cmlibrhash/librhash/byte_order.c      |  150 +++
 Utilities/cmlibrhash/librhash/byte_order.h      |  153 +++
 Utilities/cmlibrhash/librhash/hex.c             |  188 +++
 Utilities/cmlibrhash/librhash/hex.h             |   25 +
 Utilities/cmlibrhash/librhash/md5.c             |  236 ++++
 Utilities/cmlibrhash/librhash/md5.h             |   31 +
 Utilities/cmlibrhash/librhash/rhash.c           |  872 ++++++++++++
 Utilities/cmlibrhash/librhash/rhash.h           |  278 ++++
 Utilities/cmlibrhash/librhash/sha1.c            |  196 +++
 Utilities/cmlibrhash/librhash/sha1.h            |   31 +
 Utilities/cmlibrhash/librhash/sha256.c          |  241 ++++
 Utilities/cmlibrhash/librhash/sha256.h          |   32 +
 Utilities/cmlibrhash/librhash/sha512.c          |  255 ++++
 Utilities/cmlibrhash/librhash/sha512.h          |   32 +
 Utilities/cmlibrhash/librhash/ustd.h            |   39 +
 Utilities/cmlibrhash/librhash/util.h            |   31 +
 bootstrap                                       |    6 +-
 49 files changed, 3490 insertions(+), 1950 deletions(-)
 create mode 100644 Source/Modules/FindLibRHash.cmake
 delete mode 100644 Source/cm_sha2.c
 delete mode 100644 Source/cm_sha2.h
 delete mode 100644 Source/cm_sha2_mangle.h
 create mode 100644 Tests/FindLibRHash/CMakeLists.txt
 create mode 100644 Tests/FindLibRHash/Test/CMakeLists.txt
 create mode 100644 Tests/FindLibRHash/Test/main.c
 create mode 100755 Utilities/Scripts/update-librhash.bash
 create mode 100644 Utilities/cm_rhash.h
 copy Utilities/{cmcurl => cmlibrhash}/.gitattributes (100%)
 create mode 100644 Utilities/cmlibrhash/CMakeLists.txt
 create mode 100644 Utilities/cmlibrhash/COPYING
 create mode 100644 Utilities/cmlibrhash/README
 create mode 100644 Utilities/cmlibrhash/librhash/algorithms.c
 create mode 100644 Utilities/cmlibrhash/librhash/algorithms.h
 create mode 100644 Utilities/cmlibrhash/librhash/byte_order.c
 create mode 100644 Utilities/cmlibrhash/librhash/byte_order.h
 create mode 100644 Utilities/cmlibrhash/librhash/hex.c
 create mode 100644 Utilities/cmlibrhash/librhash/hex.h
 create mode 100644 Utilities/cmlibrhash/librhash/md5.c
 create mode 100644 Utilities/cmlibrhash/librhash/md5.h
 create mode 100644 Utilities/cmlibrhash/librhash/rhash.c
 create mode 100644 Utilities/cmlibrhash/librhash/rhash.h
 create mode 100644 Utilities/cmlibrhash/librhash/sha1.c
 create mode 100644 Utilities/cmlibrhash/librhash/sha1.h
 create mode 100644 Utilities/cmlibrhash/librhash/sha256.c
 create mode 100644 Utilities/cmlibrhash/librhash/sha256.h
 create mode 100644 Utilities/cmlibrhash/librhash/sha512.c
 create mode 100644 Utilities/cmlibrhash/librhash/sha512.h
 create mode 100644 Utilities/cmlibrhash/librhash/ustd.h
 create mode 100644 Utilities/cmlibrhash/librhash/util.h


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list