* #40116: Switch to 2.3.0 libzrtpcpp version
diff --git a/jni/libzrtp/sources/.gitignore b/jni/libzrtp/sources/.gitignore
index 4876ff9..ee3d613 100644
--- a/jni/libzrtp/sources/.gitignore
+++ b/jni/libzrtp/sources/.gitignore
@@ -1,4 +1,4 @@
-build*/
+build/
 autoconf/
 doc/html/
 configure
@@ -16,8 +16,4 @@
 *.pc
 *.spec
 *~
-.DS_Store
-._.DS_Store
-._buildmac
-.directory
 
diff --git a/jni/libzrtp/sources/CMakeLists.txt b/jni/libzrtp/sources/CMakeLists.txt
index 8e0bb80..847717c 100755
--- a/jni/libzrtp/sources/CMakeLists.txt
+++ b/jni/libzrtp/sources/CMakeLists.txt
@@ -12,53 +12,13 @@
 
 PROJECT(libzrtpcpp)
 
-SET(CPACK_PACKAGE_VERSION_MAJOR 4)
-SET(CPACK_PACKAGE_VERSION_MINOR 1)
-SET(CPACK_PACKAGE_VERSION_PATCH 1)
+SET(CPACK_PACKAGE_VERSION_MAJOR 2)
+SET(CPACK_PACKAGE_VERSION_MINOR 3)
+SET(CPACK_PACKAGE_VERSION_PATCH 0)
 
-set (VERSION 4.1.1)
-set (SOVERSION 4)
-
-# Define supported command line parameters.
-#
-# Example to build the tivi client: cmake -DTIVI=true ..
-# Without any options cmake generates libzrtpcpp for use with GNU ccRTP
-#
-option(CCRTP "Build library to use with GNU ccRTP." OFF)
-option(CORE_LIB "Build core library only, no spcific client support." OFF)
-option(CRYPTO_STANDALONE "Use embedded crypto and big number modules." ON)
-option(TIVI "Build library for the tivi client, implies '-DCRYPTO_STNDALONE=true'." OFF)
-option(SQLITE "Use SQLite DB as backend for ZRTP cache." OFF)
-option(SDES "Include SDES when not building for CCRTP." ON)
-
-option(ANDROID "Generate Android makefiles (Android.mk)" ON)
-option(JAVA "Generate Java support files (requires JDK and SWIG)" OFF)
-
-
-# **** Check what and how to build ****
-#
-if (CCRTP AND TIVI)
-    MESSAGE(FATAL_ERROR "Cannot build more than one client at once. Use different build directories.")
-endif()
-
-if (CCRTP)
-    set (PACKAGE libzrtpcpp)
-    set(zrtplibName zrtpcpp)
-elseif (TIVI)
-    set (PACKAGE libzrtptivi)
-    set(zrtplibName zrtptivi)
-    set(CRYPTO_STANDALONE true)
-    set(SQLITE true)
-elseif (CORE_LIB)
-    set (PACKAGE libzrtpcore)
-    set(zrtplibName zrtpcppcore)
-else()
-    MESSAGE(WARNING "No client defined, building for GNU ccRTP.")
-    set (PACKAGE libzrtpcpp)
-    set(CCRTP true)
-    set(zrtplibName zrtpcpp)
-endif()
-
+set (VERSION 2.3.0)
+set (SOVERSION 2)
+set (PACKAGE libzrtpcpp)
 
 if(MSVC60)
     set(BUILD_STATIC ON CACHE BOOL "static linking only" FORCE)
@@ -68,18 +28,26 @@
 endif()
 
 # set to true for debug and trace during CMakeLists development
-# set(CMAKE_VERBOSE_MAKEFILE TRUE)
+set(CMAKE_VERBOSE_MAKEFILE FALSE)
 
-execute_process(COMMAND git rev-parse --short HEAD OUTPUT_VARIABLE GIT_COMMIT)
-STRING(REGEX REPLACE "(\r?\n)+$" "" GIT_COMMIT "${GIT_COMMIT}")
-
-MESSAGE( STATUS "Configuring GNU ${PROJECT_NAME} ${VERSION} for ${PACKAGE}, commit: ${GIT_COMMIT} ...")
+MESSAGE( STATUS "Configuring GNU ${PROJECT_NAME} ${VERSION}...")
 
 # include most of the fine stuff we need
+include(cmake/Modules/FindGcryptConfig.cmake)
 include(FindPkgConfig)
 include(CheckLibraryExists)
 include(CheckIncludeFiles)
-include(CheckFunctionExists)
+include(cmake/Modules/AutoArgs.cmake)
+
+if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
+    include(cmake/Modules/GeneratePackage.cmake)
+
+    GENERATE_PACKAGING(${PACKAGE} ${VERSION})
+endif()
+
+# check the -Denable-ccrtp setting, defaults to true
+enable_arg(ccrtp true "Enable GNU ccRTP support for GNU ZRTP")
+args_help()
 
 if (NOT LIB_SUFFIX)
     set(LIBDIRNAME "lib")
@@ -93,171 +61,107 @@
     set(LIBDIRNAME "lib${LIB_SUFFIX}")
 endif()
 
+# setup the Thread include and lib
+find_package(Threads)
+if(CMAKE_HAVE_PTHREAD_H)
+  set(HAVE_PTHREAD_H TRUE)
+endif()
+set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT})
+
+# define the name of the lib. zrtpcppcore does not include the ccRTP stuff.
+set(zrtplib zrtpcppcore)
+if(enable_ccrtp)
+    if (USES_CCRTP_INCLUDE_DIRS)
+        message(STATUS "  Using local commoncpp dependency")
+    else()
+        find_package(PkgConfig)
+        pkg_check_modules(USES_CCRTP libccrtp>=2.0.0)
+    endif()
+    include_directories(${USES_CCRTP_INCLUDE_DIRS})
+    link_directories(${USES_CRTP_LIBRARY_DIRS})
+    add_definitions(${USES_CCRTP_CFLAGS})
+    set (LIBS ${LIBS} ${USES_CCRTP_LDFLAGS} ${USES_CCRTP_LIBRARIES})
+    set(zrtplib zrtpcpp)
+endif()
+
+# now get info about crypto libraries
+gcr_check(GCRYPT gcrypt)
+#if(GCRYPT_FOUND)
+#  check_include_files(gcrypt.h HAVE_GCRYPT_H)
+#  set(LIBS ${LIBS} ${GCRYPT_LIBRARIES})
+#  set(BUILD_REQ "libgcrypt-devel")
+#  set(CRYPTOBACKEND="")
+#  set(PACKAGE_REQ "libgcrypt")
+#else()
+  pkg_check_modules(OPENSSL libcrypto>=0.9.8)
+  if (OPENSSL_FOUND)
+    set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIRS}) #update include files search directory
+    check_include_files(openssl/bn.h HAVE_OPENSSL_BN_H)
+    check_include_files(openssl/aes.h HAVE_OPENSSL_AES_H)
+    check_include_files(openssl/sha.h HAVE_OPENSSL_SHA_H)
+    check_library_exists(crypto EVP_CipherInit_ex "${OPENSSL_LIBDIR}" HAVE_SSL_CRYPT) #use search lib directory from pkg-config
+    set(LIBS ${LIBS} -lcrypto)
+    set(CRYPTOBACKEND "libcrypto >= 0.9.8")
+    set(BUILD_REQ "libopenssl-devel >= 0.9.8")
+    set(PACKAGE_REQ "libopenssl >= 0.9.8")
+    include_directories(${OPENSSL_INCLUDE_DIRS}) #update includes directory from pkg-config
+  else()
+    message(FATAL_ERROR "No crypto library found")
+  endif()
+#endif()
+
 check_include_files(stdlib.h HAVE_STDLIB_H)
 check_include_files(string.h HAVE_STRING_H)
 
-if (NOT CRYPTO_STANDALONE)
-    pkg_check_modules(OPENSSL libcrypto>=0.9.8)
-    if (OPENSSL_FOUND)
-      set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${OPENSSL_INCLUDE_DIRS}) #update include files search directory
-      check_include_files(openssl/bn.h HAVE_OPENSSL_BN_H)
-      check_include_files(openssl/aes.h HAVE_OPENSSL_AES_H)
-      check_include_files(openssl/sha.h HAVE_OPENSSL_SHA_H)
-      check_library_exists(crypto EVP_CipherInit_ex "${OPENSSL_LIBDIR}" HAVE_SSL_CRYPT) #use search lib directory from pkg-config
-      set(LIBS ${LIBS} -lcrypto)
-      set(CRYPTOBACKEND "libcrypto >= 0.9.8")
-      set(BUILD_REQ "libopenssl-devel >= 0.9.8")
-      set(PACKAGE_REQ "libopenssl >= 0.9.8")
-      include_directories(${OPENSSL_INCLUDE_DIRS}) #update includes directory from pkg-config
-  else()
-      message(FATAL_ERROR "No crypto library found")
-  endif()
-else()
-    # For crypto standalone mode we need to configure the bnlib. In a first step
-    # without the tests and demos.
-    check_include_files(stdint.h HAVE_STDINT_H)
-    check_include_files(stdint.h HAVE_ASSERT_H)
-    check_include_files(limits.h HAVE_LIMITS_H)
+# necessary and required modules checked, ready to generate config.h
+configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
 
-    check_function_exists(memmove HAVE_MEMMOVE)
-    check_function_exists(memcpy HAVE_MEMCPY)
+# the following set(...) commands are only to have backward
+# compatibility with autoconf stuff to generate the pc file
+set(prefix ${CMAKE_INSTALL_PREFIX})
+set(exec_prefix ${prefix}/bin)
+set(libdir ${prefix}/${LIBDIRNAME})
+set(includedir ${prefix}/include)
+set(PACKAGE pkgconfig)
+configure_file(libzrtpcpp.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/lib${zrtplib}.pc @ONLY)
 
-    # TODO: check if we compile the tests for bnlib
-    #
-    # check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
-    # check_function_exists(getrusage HAVE_GETRUSAGE)
-    # check_function_exists(clock HAVE_CLOCK)
-    # check_function_exists(time HAVE_TIME)
+configure_file(libzrtpcpp.spec.cmake ${CMAKE_CURRENT_BINARY_DIR}/libzrtpcpp.spec @ONLY)
 
-    # Check if Solaris-style gethrvtime() is available
-    # check_function_exists(gethrvtime HAVE_GETHRVTIME)
-    #
-    # until here
-
-    # necessary and required modules checked, ready to generate config.h
-    configure_file(${CMAKE_SOURCE_DIR}/bnlib/bnconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/bnconfig.h)
-endif()
-
-if (SQLITE)
-    pkg_check_modules(SQLITE3 sqlite3>=3.7)
-    if (SQLITE3_FOUND)
-        check_include_files(sqlite3.h HAVE_SQLITE_H)
-        set(LIBS ${LIBS} -lsqlite3)
-    else()
-      message(FATAL_ERROR "SQLite3 library not found")
-    endif()
-endif()
-
-# necessary and required modules checked, ready to generate config.h in top-level build directory
-configure_file(config.h.cmake ${CMAKE_BINARY_DIR}/config.h)
+#to make sure includes are first taken from those directory
+include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src)
 
 add_definitions(-g -O2 -fno-strict-aliasing)
 if(CMAKE_COMPILER_IS_GNUCXX)
-#    add_definitions(-Wno-long-long -Wno-char-subscripts)
-#    add_definitions(-Wall -ansi -pedantic)
-#    add_definitions(-Wall -pedantic)
-    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -pedantic -std=c99")
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -std=c++11")
-    add_definitions(-DNEW_STDCPP)
+  add_definitions(-Wno-long-long -Wno-char-subscripts)
+  add_definitions(-Wall -ansi -pedantic)
+  add_definitions(-DNEW_STDCPP)
 endif()
 
-include_directories(BEFORE ${CMAKE_BINARY_DIR})
-include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/zrtp)
+add_subdirectory(src)
 
-if(CRYPTO_STANDALONE)
-    add_definitions(-DSUPPORT_NON_NIST)
-    include_directories (${CMAKE_SOURCE_DIR}/bnlib)
-endif()
-
-if (SDES AND NOT CCRTP)
-    set (sdes_src ${CMAKE_SOURCE_DIR}/zrtp/ZrtpSdesStream.cpp)
-endif()
-
-# **** The following source files a common for all clients ****
-#
-set(zrtp_src_no_cache
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpCallbackWrapper.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZRtp.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpCrc32.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketCommit.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketConf2Ack.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketConfirm.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketDHPart.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketGoClear.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketClearAck.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketHelloAck.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketHello.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketError.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketErrorAck.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketPingAck.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketPing.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketSASrelay.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpPacketRelayAck.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpStateClass.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpTextData.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpConfigure.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/ZrtpCWrapper.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/Base32.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/zrtpB64Encode.c
-    ${CMAKE_SOURCE_DIR}/zrtp/zrtpB64Decode.c
-    ${CMAKE_SOURCE_DIR}/common/osSpecifics.c ${sdes_src})
-
-set(bnlib_src
-    ${CMAKE_SOURCE_DIR}/bnlib/bn00.c
-    ${CMAKE_SOURCE_DIR}/bnlib/lbn00.c
-    ${CMAKE_SOURCE_DIR}/bnlib/bn.c
-    ${CMAKE_SOURCE_DIR}/bnlib/lbnmem.c
-    ${CMAKE_SOURCE_DIR}/bnlib/sieve.c
-    ${CMAKE_SOURCE_DIR}/bnlib/prime.c
-    ${CMAKE_SOURCE_DIR}/bnlib/bnprint.c
-    ${CMAKE_SOURCE_DIR}/bnlib/jacobi.c
-    ${CMAKE_SOURCE_DIR}/bnlib/germain.c
-    ${CMAKE_SOURCE_DIR}/bnlib/ec/ec.c
-    ${CMAKE_SOURCE_DIR}/bnlib/ec/ecdh.c
-    ${CMAKE_SOURCE_DIR}/bnlib/ec/curve25519-donna.c)
-
-set(zrtp_skein_src
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/skeinMac256.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/skein256.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/skeinMac384.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/skein384.cpp)
-
-set(zrtp_crypto_src
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/zrtpDH.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/hmac256.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/sha256.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/hmac384.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/sha384.cpp
-
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/aesCFB.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/twoCFB.cpp
-    ${CMAKE_SOURCE_DIR}/zrtp/crypto/sha2.c)
-
-if (NOT SQLITE)
-    set(zrtp_src ${zrtp_src_no_cache}
-        ${CMAKE_SOURCE_DIR}/zrtp/ZIDCacheFile.cpp
-        ${CMAKE_SOURCE_DIR}/zrtp/ZIDRecordFile.cpp)
-else()
-    set(zrtp_src ${zrtp_src_no_cache}
-        ${CMAKE_SOURCE_DIR}/zrtp/ZIDCacheDb.cpp
-        ${CMAKE_SOURCE_DIR}/zrtp/ZIDRecordDb.cpp
-        ${CMAKE_SOURCE_DIR}/zrtp/zrtpCacheSqliteBackend.c)
-
-endif()
-
-if (CCRTP)
-    add_subdirectory(clients/ccrtp)
+if (enable_ccrtp)
     add_subdirectory(demo)
 endif()
 
-if (TIVI)
-    add_subdirectory(clients/tivi)
+if (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/package/)
+    MESSAGE(STATUS "package dir not found")
+    file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/package/)
 endif()
 
-if (CORE_LIB)
-    add_subdirectory(clients/no_client)
-endif()
+########### install files ###############
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${zrtplib}.pc DESTINATION ${LIBDIRNAME}/pkgconfig)
 
+if(${PROJECT_NAME} STREQUAL ${CMAKE_PROJECT_NAME})
+
+    ########### Add uninstall target ###############
+    configure_file(
+    "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
+    "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
+    IMMEDIATE @ONLY)
+    add_custom_target(uninstall
+    "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+
+endif()
 ##very usefull for macosx, specially when using gtkosx bundler
 if(APPLE)
     if (NOT CMAKE_INSTALL_NAME_DIR)
diff --git a/jni/libzrtp/sources/COPYING b/jni/libzrtp/sources/COPYING
index 02bbb60..4432540 100644
--- a/jni/libzrtp/sources/COPYING
+++ b/jni/libzrtp/sources/COPYING
@@ -1,165 +1,676 @@
-                   GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 3, 29 June 2007
 
  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
  Everyone is permitted to copy and distribute verbatim copies
  of this license document, but changing it is not allowed.
 
+			    Preamble
 
-  This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
 
-  0. Additional Definitions.
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
 
-  As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
 
-  "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
 
-  An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
 
-  A "Combined Work" is a work produced by combining or linking an
-Application with the Library.  The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
 
-  The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
 
-  The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
 
-  1. Exception to Section 3 of the GNU GPL.
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
 
-  You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
+  The precise terms and conditions for copying, distribution and
+modification follow.
 
-  2. Conveying Modified Versions.
+		       TERMS AND CONDITIONS
 
-  If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
+  0. Definitions.
 
-   a) under this License, provided that you make a good faith effort to
-   ensure that, in the event an Application does not supply the
-   function or data, the facility still operates, and performs
-   whatever part of its purpose remains meaningful, or
+  "This License" refers to version 3 of the GNU General Public License.
 
-   b) under the GNU GPL, with none of the additional permissions of
-   this License applicable to that copy.
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+ 
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
 
-  3. Object Code Incorporating Material from Library Header Files.
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
 
-  The object code form of an Application may incorporate material from
-a header file that is part of the Library.  You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
 
-   a) Give prominent notice with each copy of the object code that the
-   Library is used in it and that the Library and its use are
-   covered by this License.
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
 
-   b) Accompany the object code with a copy of the GNU GPL and this license
-   document.
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
 
-  4. Combined Works.
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
 
-  You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
+  1. Source Code.
 
-   a) Give prominent notice with each copy of the Combined Work that
-   the Library is used in it and that the Library and its use are
-   covered by this License.
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
 
-   b) Accompany the Combined Work with a copy of the GNU GPL and this license
-   document.
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
 
-   c) For a Combined Work that displays copyright notices during
-   execution, include the copyright notice for the Library among
-   these notices, as well as a reference directing the user to the
-   copies of the GNU GPL and this license document.
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
 
-   d) Do one of the following:
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
 
-       0) Convey the Minimal Corresponding Source under the terms of this
-       License, and the Corresponding Application Code in a form
-       suitable for, and under terms that permit, the user to
-       recombine or relink the Application with a modified version of
-       the Linked Version to produce a modified Combined Work, in the
-       manner specified by section 6 of the GNU GPL for conveying
-       Corresponding Source.
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
 
-       1) Use a suitable shared library mechanism for linking with the
-       Library.  A suitable mechanism is one that (a) uses at run time
-       a copy of the Library already present on the user's computer
-       system, and (b) will operate properly with a modified version
-       of the Library that is interface-compatible with the Linked
-       Version.
+  The Corresponding Source for a work in source code form is that
+same work.
 
-   e) Provide Installation Information, but only if you would otherwise
-   be required to provide such information under section 6 of the
-   GNU GPL, and only to the extent that such information is
-   necessary to install and execute a modified version of the
-   Combined Work produced by recombining or relinking the
-   Application with a modified version of the Linked Version. (If
-   you use option 4d0, the Installation Information must accompany
-   the Minimal Corresponding Source and Corresponding Application
-   Code. If you use option 4d1, you must provide the Installation
-   Information in the manner specified by section 6 of the GNU GPL
-   for conveying Corresponding Source.)
+  2. Basic Permissions.
 
-  5. Combined Libraries.
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
 
-  You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
 
-   a) Accompany the combined library with a copy of the same work based
-   on the Library, uncombined with any other library facilities,
-   conveyed under the terms of this License.
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
 
-   b) Give prominent notice with the combined library that part of it
-   is a work based on the Library, and explaining where to find the
-   accompanying uncombined form of the same work.
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
 
-  6. Revised Versions of the GNU Lesser General Public License.
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
 
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
 
-  Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
+  4. Conveying Verbatim Copies.
 
-  If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
\ No newline at end of file
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+  
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    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.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+
diff --git a/jni/libzrtp/sources/NEWS b/jni/libzrtp/sources/NEWS
index f2b72e6..6224923 100755
--- a/jni/libzrtp/sources/NEWS
+++ b/jni/libzrtp/sources/NEWS
@@ -1,128 +1,3 @@
-== GNU ZRTP 4.1.1 ==
-
-Is a bug fix release that fixes some problems when building a standalone
-version of the library, i.e. with embedded crypto algorithms and not using
-on openSSL.
-
-Another fix was necessary for NetBSD thread handling.
-
-
-== GNU ZRTP 4.1.0 ==
-
-Small enhancements when dealing with non-NIST algorithms. An application may
-set a ''algorithm selection policy'' to control the selection behaviour. In
-addition the the standrad selection policy (as per RFC6189) this version
-provides a _non-NIST_ selection policy: if the selected public key algorithm
-is a non-NIST ECC algorithm then the other selection functions prefer non-NIST
-HASH algorithms (Skein etc).
-
-
-== GNU ZRTP 4.0.0 ==
-
-For this version I added some new algorithms for the DH key agreement
-and the Skein Hash for ZRTP. Not further functional enhancments.
-
-Added a new (old) build parameter -DCORE_LIB that will build a ZRTP core
-library. This was available in V2.3 but I somehow lost this for 3.0
-You may add other build parameters, such as SQLITE and CRYPTO_STANDALONE
-if you build the core library.
-
-
-== GNU ZRTP 3.2.0 ==
-
-The main ZRTP modules contain fixes for three vulnerabilities found by Mark
-Dowd. Thus we advise application developers to use this version of the
-library. The vulnerabilities may lead to application crashes during ZRTP
-negotiation if an attacker sends prepared ZRTP packets. The fixes remove these
-attack vectors.
-
-Some small other enhancements and cleanup, mainly inside client code.
-
-Some enhancements in cache handling and the handling of retained shared
-secrets. This change was proposed by Phil, is a slight security enhacement and
-is fully backward comaptible.
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
-For details please refer to the Git logs.
-
-
-== GNU ZRTP 3.1.0 ==
-
-This version adds some new features and code that supports some other
-client and this accounts for the most changes inside this release. 
-
-The ZRTP core functionality was not changed as much (bug fixes, cleanup
-mainly) and remains fully backward compatible with older library
-versions. However, one nice enhancement was done: the addition of a standalone
-SDES support module. This module supports basic SDES only without the fancy
-stuff like many other SDES implementations. Thus it's pretty interoperable.
-
-Some other features are:
-- add some android support for a client, may serve as template for others
-- documentation and code cleanup
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
-
-== GNU ZRTP 3.0.0 ==
-
-This is a major enhancement and restructuring of the overall ZRTP
-distribution. This was necessary because more and more other clients use ZRTP
-and add their specific glue code. Also some clients are not prepared to use
-openSSL or other crypto libraries to their code and distributions. 
-
-Here a summary of the changes
-- a new directory layout to accomodate various clients
-- add standalone crypto modules, for example for AES, to have a real
-  standalone ZRTP/SRTP library that does not require any other crypto library
-  (optional via CMake configuration)
-- Re-structure ZRTP cache and add SQlite3 as optional storage backend
-
-The default settings for CMake build the normal ZRTP library that use openSSL
-as crypto backend, use the normal file based cache and include the GNU ccRTP
-modules. This is a librray that is to a large degree compatible with the
-earlier builds.
-
-Please refer to the top level CMakeFile.txt for options how to switch on the
-standalone crypto mode or the SQlite3 based cache storage.
-
-
-== GNU ZRTP 2.3.0 ==
-
-Add a "paranoid" mode to ZRTP. If and applications switches to this mode then
-the ZRTP stack _always_ asks the user to confirm the SAS thus ZRTP behaves as
-if it does not have a cache to store the retained secrets. However, setting
-the paranoid mode does not diable the cache, only the GUI behaviour.
-
-Enhance the CMake scripts to build a ZRTP library that does not contain GNU
-ccRTP modules and does not require ccRTP dependencies.
-
-== GNU ZRTP 2.2.0 ==
-
-Add stubs, callbacks and other provisions to prepare the full implementation
-of the SAS signing feature, see RFC6189, section 7.2. This feature needs
-support from applications and is rarely used if at all.
-
-As usual smaller fixes, code clean up etc.
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
-== GNU ZRTP 2.1.2 ==
-
-The main topic of this release was to add SRTCP support and some missing
-optional features of ZRTP. 
-
-As such I've added some new API and classes that applications may use to add
-SRTCP or to use the new ZRTP features. the ZRTP stack now supports PBX
-handling, refer to RFC6189 section 7.3ff.
-
-Because of some API changes clients must be compiled and linked with the new
-library.
-
 == GNU ZRTP 2.0.0 ==
 
 Modify some files to use the new uCommon/commoncpp libraries instead
@@ -275,7 +150,7 @@
 The method ''setOtherSecret(...)'' was renamed to ''setPbxSecret(...)''
 to reflect the modification in the draft.
 
-The method ''setSrtpsSecret(...)'' was renamed to ''setAuxSecret(...)''
+The methos ''setSrtpsSecret(...)'' is was renamed to ''setAuxSecret(...)''
 to reflect the modification in the draft.
 
 
diff --git a/jni/libzrtp/sources/README.md b/jni/libzrtp/sources/README.md
index f7b9966..cac0592 100644
--- a/jni/libzrtp/sources/README.md
+++ b/jni/libzrtp/sources/README.md
@@ -1,49 +1,29 @@
 ## GNU ZRTP C++
 
 This package provides a library that adds ZRTP support to the GNU
-ccRTP stack and serves as library for other RTP stacks (PJSIP, GStreamer).
-Phil Zimmermann developed ZRTP to allow ad-hoc, easy to
+ccRTP stack. Phil Zimmermann developed ZRTP to allow ad-hoc, easy to
 use key negotiation to setup Secure RTP (SRTP) sessions. GNU ZRTP works
 together with GNU ccRTP (1.5.0 or later) and provides a ZRTP
 implementation that can be directly embedded into client and server
 applications.
 
-The GNU ZRTP implementation is compliant to [RFC 6189][] and adds some more
-algorithms. Currently GNU ZRTP C++ supports the following features:
+The GNU ZRTP implementation is compliant to [RFC 6189][]. Currently GNU ZRTP
+C++ supports the following features:
 
 * multi-stream mode
-* Finite field Diffie-Hellman with 2048 and 3072 bit primes
-* Elliptic curve Diffie-Hellman with 256 and 384 bit curves (NIST curves)
-* Elliptic curves Curve25519 and Curve3617 (Dan Bernstein, Tanja Lange)
-* Skein Hash and MAC for ZRTP
-* AES-128 and AES-256 symmetric ciphers
+* Finite field Diffie-Helman with 2048 and 3072 bit primes
+* Elliptic curve Diffie-Helman with 256 and 384 bit curves
+* AES-128 and AES-256 symmetric cipher
 * Twofish-128 and Twofish-256 bit symmetric ciphers
 * The SRTP authentication methods HMAC-SHA1 with 32 bit and 80 bit length and
   the Skein MAC with 32 bit and 64 bit length
 * The Short Authentication String (SAS) type with base 32 encoding (4
-  characters) and the SAS 256 type using words.
+  characters)
 
-Some features like preshared mode are not supported but the GNU
-ZRTP C++ implementation defines the necessary external interfaces and
-functions for these enhanced features.
-
-**Note:** The Elliptic curves Cure25519 and Curve3617 are available only if you
-select the crypto standalone mode during build.
-
-The newer verisons (starting with 4.1) implement an extensible mechanisms to
-define algorithm selection policies that control selection of Hash, symmetric
-cipher, and the SRTP authentication. Currently two policies exist: _Standard_
-and _PreferNonNist_. The Standard policy selects algorihms based on the
-preferences (order) in the Hello packet, the PreferNonNist policy prefers 
-non-NIST algorithms, for example Skein and Twofish, if the selected public key
-(Diffie-Hellman) algorithm is also one of the non-NIST algorithms. This is 
-fully backward compatible and in-line with RFC6189.
-
-### SDES support
-This release also provides SDES support. The SDES implementation does not
-support all of the fancy stuff but is usable in most cases. This implementation
-however supports the new SDES crypto mixing to overcome some security issues
-for SIP forking. Please look for `draft-zimmermann-mmusic-sdesc-mix-00`.
+Enhanced features like PBX SAS relay aka *trusted Man-in-the-Middle* or
+preshared mode are not supported but the GNU ZRTP C++ implementation defines
+the necessary external interfaces and functions for these enhanced features
+(stubs only).
 
 ### Interoperability
 During the development of ZRTP and its sister implementation ZRTP4J (the Java
@@ -68,7 +48,7 @@
 functionality to C based RTP implementations. The first use of the ZRTP C
 wrapper was for the [PJSIP][] library, actually the RTP part of this
 library. The ZRTP handler for PJSIP is [here][pjzrtp]. This port enables PJSIP
-based clients to use ZRTP. One of the first clients that uses this feature is
+based clients to use ZRTP. One of the first clients that use this feature is
 *[CSipSimple][]*, an very good open source Android SIP client.
 
 [pjsip]: http://www.pjsip.org
@@ -91,21 +71,13 @@
 
 
 ### License and further information
-I changed the license of the ZRTP core source files from GPL to LGPL. Other
-sources files may have own license. Please refer to the copyright notices of
-the files.
-
-Thus most of this library is licensed under the GNU LGPL, version 3 or later.
+Please note, this library is licensed under the GNU GPL, version 3 or 
+later, and has been copyright assigned to the Free Software Foundation.
 
 For further information refer to the [ZRTP FAQ][zrtpfaq] and the
 [GNU ZRTP howto][zrtphow]. Both are part of the GNU Telephony wiki and are
 located in its documentation category.
 
-Source code in the directory `clients/tivi` and below is not licensed under the
-GNU LGPL and is for reference and review only. Refer to the copyright statments
-of the source code in these directories, in particular the sqlite3 sources which
-have their own license.
-
 [zrtphow]:  http://www.gnutelephony.org/index.php/GNU_ZRTP_How_To
 [zrtpfaq]:  http://www.gnutelephony.org/index.php/ZRTP_FAQ
 [rfc 6189]: http://tools.ietf.org/html/rfc6189
@@ -117,23 +89,11 @@
 the source archive or pulled the source from [Github][]:
 
     cd <zrtpsrc_dir>
-    mkdir build
-    cd build
-    cmake ..
-    make
-
-The CMakeLists.txt supports several options. If you don't specify any options
-then `cmake` generates the build that supports GNU ccRTP library and it uses
-the standalone cryptographic modules, thus no it's not necessary to install an
-cryptographic library on the system. Optionally you may configure ZRTP to use
-_sqlite3_ instead of a simple file to store the ZRTP cache data. For example
-
-    cmake -DSQLITE=true ..
-
-creates the build files that use _sqlite3_.
-
-Please have a look at the `CMakeLists.txt` for other options.
-
+	mkdir build
+	cd build
+	cmake ..
+	make
+	
 Running cmake in a separate `build` directory is the preferred way. Cmake and
 the following `make` generate all files in or below the build directory. Thus
 the base directory and the source directories are not polluted with `*.o`,
@@ -143,13 +103,3 @@
 different settings without mixing the two builds.
 
 [github]: http://github.com/wernerd/ZRTPCPP
-
-
-### Notes when building ZRTP C++ for Android
-
-The CMake files support creation of an `Android.mk` file for the Tivi client
-and may give you an idea how to do it for other clients. The generated
-`Android.mk` generates `buildinfo_*.c` files in the root directory. You may
-delete these files after the Android static libraries are ready.
-
-Since version 4.1.1 the example Android build files require NDK r9c.
diff --git a/jni/libzrtp/sources/bnlib/bn.c b/jni/libzrtp/sources/bnlib/bn.c
deleted file mode 100644
index 36d07fc..0000000
--- a/jni/libzrtp/sources/bnlib/bn.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * bn.c - the high-level bignum interface
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#include <bn.h>
-
-/* Functions */
-void
-bnBegin(struct BigNum *bn)
-{
-	static int bninit = 0;
-
-	if (!bninit) {
-		bnInit();
-		bninit = 1;
-	}
-
-	bn->ptr = 0;
-	bn->size = 0;
-	bn->allocated = 0;
-}
-
-void
-bnSwap(struct BigNum *a, struct BigNum *b)
-{
-	void *p;
-	unsigned t;
-
-	p = a->ptr;
-	a->ptr = b->ptr;
-	b->ptr = p;
-
-	t = a->size;
-	a->size = b->size;
-	b->size = t;
-
-	t = a->allocated;
-	a->allocated = b->allocated;
-	b->allocated = t;
-}
-
-int (*bnYield)(void);
-
-void (*bnEnd)(struct BigNum *bn);
-int (*bnPrealloc)(struct BigNum *bn, unsigned bits);
-int (*bnCopy)(struct BigNum *dest, struct BigNum const *src);
-void (*bnNorm)(struct BigNum *bn);
-void (*bnExtractBigBytes)(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned len);
-int (*bnInsertBigBytes)(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-void (*bnExtractLittleBytes)(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned len);
-int (*bnInsertLittleBytes)(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-unsigned (*bnLSWord)(struct BigNum const *src);
-int (*bnReadBit)(struct BigNum const *bn, unsigned bit);
-unsigned (*bnBits)(struct BigNum const *src);
-int (*bnAdd)(struct BigNum *dest, struct BigNum const *src);
-int (*bnSub)(struct BigNum *dest, struct BigNum const *src);
-int (*bnCmpQ)(struct BigNum const *a, unsigned b);
-int (*bnSetQ)(struct BigNum *dest, unsigned src);
-int (*bnAddQ)(struct BigNum *dest, unsigned src);
-int (*bnSubQ)(struct BigNum *dest, unsigned src);
-int (*bnCmp)(struct BigNum const *a, struct BigNum const *b);
-int (*bnSquare)(struct BigNum *dest, struct BigNum const *src);
-int (*bnMul)(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int (*bnMulQ)(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int (*bnDivMod)(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
-	struct BigNum const *d);
-int (*bnMod)(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *d);
-unsigned (*bnModQ)(struct BigNum const *src, unsigned d);
-int (*bnExpMod)(struct BigNum *result, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod);
-int (*bnDoubleExpMod)(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod);
-int (*bnTwoExpMod)(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod);
-int (*bnGcd)(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int (*bnInv)(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *mod);
-int (*bnLShift)(struct BigNum *dest, unsigned amt);
-void (*bnRShift)(struct BigNum *dest, unsigned amt);
-unsigned (*bnMakeOdd)(struct BigNum *n);
-int (*bnBasePrecompBegin)(struct BnBasePrecomp *pre, struct BigNum const *base,
-	struct BigNum const *mod, unsigned maxebits);
-int (*bnBasePrecompCopy)(struct BnBasePrecomp *dst,
-	struct BnBasePrecomp const *src);
-void (*bnBasePrecompEnd)(struct BnBasePrecomp *pre);
-int (*bnBasePrecompExpMod)(struct BigNum *dest,
-	struct BnBasePrecomp const *pre, struct BigNum const *exp,
-	struct BigNum const *mod);
-int (*bnDoubleBasePrecompExpMod)(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bn.h b/jni/libzrtp/sources/bnlib/bn.h
deleted file mode 100644
index 5cc80f0..0000000
--- a/jni/libzrtp/sources/bnlib/bn.h
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * bn.h - the interface to the bignum routines.
- * All functions which return ints can potentially allocate memory
- * and return -1 if they are unable to. All "const" arguments
- * are unmodified.
- *
- * This is not particularly asymmetric, as some operations are of the
- * form a = b @ c, while others do a @= b.  In general, outputs may not
- * point to the same struct BigNums as inputs, except as specified
- * below.  This relationship is referred to as "being the same as".
- * This is not numerical equivalence.
- *
- * The "Q" operations take "unsigned" inputs.  Higher values of the
- * extra input may work on some implementations, but 65535 is the
- * highest portable value.  Just because UNSIGNED_MAX is larger than
- * that, or you know that the word size of the library is larger than that,
- * that, does *not* mean it's allowed.
- */
-#ifndef BN_H
-#define BN_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-struct BigNum {
-	void *ptr;
-	unsigned size;	/* Note: in (variable-sized) words */
-	unsigned allocated;
-};
-
-#ifndef SWIG
-/*
- * User-supplied function: if non-NULL, this is called during long-running
- * computations.  You may put Yield() calls in here to give CPU time to
- * other processes.  You may also force the computation to be aborted,
- * by returning a value < 0, which will be the return value of the
- * bnXXX call.  (You probably want the value to be someting other than
- * -1, to distinguish it from a n out-of-memory error.)
- *
- * The functions that this is called from, and the intervals at which it
- * is called, are not well defined, just "reasonably often".  (Currently,
- * once per exponent bit in nodular exponentiation, and once per two
- * divisions in GCD and inverse computation.)
- */
-extern int (*bnYield)(void);
-
-/* Functions */
-
-/*
- * You usually never have to call this function explicitly, as
- * bnBegin() takes care of it.  If the program jumps to address 0,
- * this function has bot been called.
- */
-void bnInit(void);
-
-/*
- * This initializes an empty struct BigNum to a zero value.
- * Do not use this on a BigNum which has had a value stored in it!
- */
-void bnBegin(struct BigNum *bn);
-
-/* Swap two BigNums.  Cheap. */
-void bnSwap(struct BigNum *a, struct BigNum *b);
-
-/* Reset an initialized bigNum to empty, pending deallocation. */
-extern void (*bnEnd)(struct BigNum *bn);
-
-/*
- * If you know you'll need space in the number soon, you can use this function
- * to ensure that there is room for at least "bits" bits.  Optional.
- * Returns <0 on out of memory, but the value is unaffected.
- */
-extern int (*bnPrealloc)(struct BigNum *bn, unsigned bits);
-
-/* Hopefully obvious.  dest = src.   dest may be the same as src. */
-extern int (*bnCopy)(struct BigNum *dest, struct BigNum const *src);
-
-/*
- * Mostly done automatically, but this removes leading zero words from
- * the internal representation of the BigNum.  Use is unclear.
- */
-extern void (*bnNorm)(struct BigNum *bn);
-
-/*
- * Move bytes between the given buffer and the given BigNum encoded in
- * base 256.  I.e. after either of these, the buffer will be equal to
- * (bn / 256^lsbyte) % 256^len.  The difference is which is altered to
- * match the other!
- */
-extern void (*bnExtractBigBytes)(struct BigNum const *bn,
-	unsigned char *dest, unsigned lsbyte, unsigned len);
-extern int (*bnInsertBigBytes)(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-
-/* The same, but the buffer is little-endian. */
-extern void (*bnExtractLittleBytes)(struct BigNum const *bn,
-	unsigned char *dest, unsigned lsbyte, unsigned len);
-extern int (*bnInsertLittleBytes)(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-
-/* Return the least-significant bits (at least 16) of the BigNum */
-extern unsigned (*bnLSWord)(struct BigNum const *src);
-
-/* Return the selected bit of the BigNum (bit 0 is bn mod 2) */
-extern int (*bnReadBit)(struct BigNum const *bn, unsigned bit);
-
-/*
- * Return the number of significant bits in the BigNum.
- * 0 or 1+floor(log2(src))
- */
-extern unsigned (*bnBits)(struct BigNum const *src);
-#define bnBytes(bn) ((bnBits(bn)+7)/8)
-
-/*
- * dest += src.  dest and src may be the same.  Guaranteed not to
- * allocate memory unnecessarily, so if you're sure bnBits(dest)
- * won't change, you don't need to check the return value.
- */
-extern int (*bnAdd)(struct BigNum *dest, struct BigNum const *src);
-
-/*
- * dest -= src.  dest and src may be the same, but bnSetQ(dest, 0) is faster.
- * if dest < src, returns +1 and sets dest = src-dest.
- */
-extern int (*bnSub)(struct BigNum *dest, struct BigNum const *src);
-
-/* Return sign (-1, 0, +1) of a-b.  a <=> b --> bnCmpQ(a, b) <=> 0 */
-extern int (*bnCmpQ)(struct BigNum const *a, unsigned b);
-
-/* dest = src, where 0 <= src < 2^16. */
-extern int (*bnSetQ)(struct BigNum *dest, unsigned src);
-
-/* dest += src, where 0 <= src < 2^16 */
-extern int (*bnAddQ)(struct BigNum *dest, unsigned src);
-
-/* dest -= src, where 0 <= src < 2^16 */
-extern int (*bnSubQ)(struct BigNum *dest, unsigned src);
-
-/* Return sign (-1, 0, +1) of a-b.  a <=> b --> bnCmp(a, b) <=> 0 */
-extern int (*bnCmp)(struct BigNum const *a, struct BigNum const *b);
-
-/* dest = src^2.  dest may be the same as src, but it costs time. */
-extern int (*bnSquare)(struct BigNum *dest, struct BigNum const *src);
-
-/* dest = a * b.  dest may be the same as a or b, but it costs time. */
-extern int (*bnMul)(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-
-/* dest = a * b, where 0 <= b < 2^16.  dest and a may be the same. */
-extern int (*bnMulQ)(struct BigNum *dest, struct BigNum const *a, unsigned b);
-
-/*
- * q = n/d, r = n%d.  r may be the same as n, but not d,
- * and q may not be the same as n or d.
- * re-entrancy issue: this temporarily modifies d, but restores
- * it for return.
- */
-extern int (*bnDivMod)(struct BigNum *q, struct BigNum *r,
-	struct BigNum const *n, struct BigNum const *d);
-/*
- * dest = src % d.  dest and src may be the same, but not dest and d.
- * re-entrancy issue: this temporarily modifies d, but restores
- * it for return.
- */
-extern int (*bnMod)(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *d);
-
-/* return src % d, where 0 <= d < 2^16.  */
-extern unsigned int (*bnModQ)(struct BigNum const *src, unsigned d);
-
-/* n = n^exp, modulo "mod"   "mod" *must* be odd */
-extern int (*bnExpMod)(struct BigNum *result, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod);
-
-/*
- * dest = n1^e1 * n2^e2, modulo "mod".  "mod" *must* be odd.
- * dest may be the same as n1 or n2.
- */
-extern int (*bnDoubleExpMod)(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod);
-
-/* n = 2^exp, modulo "mod"   "mod" *must* be odd */
-extern int (*bnTwoExpMod)(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod);
-
-/* dest = gcd(a, b).  The inputs may overlap arbitrarily. */
-extern int (*bnGcd)(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-
-/* dest = src^-1, modulo "mod".  dest may be the same as src. */
-extern int (*bnInv)(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *mod);
-
-/* Shift dest left "amt" places */
-extern int (*bnLShift)(struct BigNum *dest, unsigned amt);
-/* Shift dest right "amt" places, discarding low-order bits */
-extern void (*bnRShift)(struct BigNum *dest, unsigned amt);
-
-/* For the largest 2^k that divides n, divide n by it and return k. */
-extern unsigned (*bnMakeOdd)(struct BigNum *n);
-
-/*
- * Precomputed data for rapid base^exp (mod mod) computation with fixed
- * base and mod.
- */
-struct BnBasePrecomp {
-	void *array;	/* Ponter to array of pointers to words */
-	unsigned msize;	/* Words in modulis (normalized) */
-	unsigned bits;	/* Bits per array element */
-	unsigned maxebits;	/* Maximum exponent bits */
-	unsigned entries;	/* Number of entries */
-	unsigned arraysize;
-};
-
-extern int (*bnBasePrecompBegin)(struct BnBasePrecomp *pre,
-	struct BigNum const *base, struct BigNum const *mod,
-	unsigned maxebits);
-extern void (*bnBasePrecompEnd)(struct BnBasePrecomp *pre);
-extern int (*bnBasePrecompExpMod)(struct BigNum *dest,
-	struct BnBasePrecomp const *pre, struct BigNum const *exp,
-	struct BigNum const *mod);
-extern int (*bnDoubleBasePrecompExpMod)(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod);
-#endif /* SWIF */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif/* !BN_H */
diff --git a/jni/libzrtp/sources/bnlib/bn00.c b/jni/libzrtp/sources/bnlib/bn00.c
deleted file mode 100644
index 4bc9797..0000000
--- a/jni/libzrtp/sources/bnlib/bn00.c
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * bn00.c - auto-size-detecting bn??.c file.
- *
- * Written in 1995 by Colin Plumb.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#include "bnsize00.h"
-
-#if BNSIZE64
-
-/* Include all of the C source file by reference */
-#include "bn64.c"
-#include "bninit64.c"
-
-#elif BNSIZE32
-
-/* Include all of the C source file by reference */
-#include "bn32.c"
-#include "bninit32.c"
-
-#else /* BNSIZE16 */
-
-/* Include all of the C source file by reference */
-#include "bn16.c"
-#include "bninit16.c"
-
-#endif
diff --git a/jni/libzrtp/sources/bnlib/bn16.c b/jni/libzrtp/sources/bnlib/bn16.c
deleted file mode 100644
index 98e5aa3..0000000
--- a/jni/libzrtp/sources/bnlib/bn16.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * bn16.c - the high-level bignum interface
- *
- * Like lbn16.c, this reserves the string "16" for textual replacement.
- * The string must not appear anywhere unless it is intended to be replaced
- * to generate other bignum interface functions.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h>	/* for memmove() in bnMakeOdd */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-/*
- * This was useful during debugging, so it's left in here.
- * You can ignore it.  DBMALLOC is generally undefined.
- */
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-#include "../dbmalloc/malloc.h"
-#define MALLOCDB malloc_chain_check(1)
-#else
-#define MALLOCDB (void)0
-#endif
-
-#include "lbn.h"
-#include "lbn16.h"
-#include "lbnmem.h"
-#include "bn16.h"
-#include "bn.h"
-
-/* Work-arounds for some particularly broken systems */
-#include "kludge.h"	/* For memmove() */
-
-/* Functions */
-void
-bnInit_16(void)
-{
-	bnEnd = bnEnd_16;
-	bnPrealloc = bnPrealloc_16;
-	bnCopy = bnCopy_16;
-	bnNorm = bnNorm_16;
-	bnExtractBigBytes = bnExtractBigBytes_16;
-	bnInsertBigBytes = bnInsertBigBytes_16;
-	bnExtractLittleBytes = bnExtractLittleBytes_16;
-	bnInsertLittleBytes = bnInsertLittleBytes_16;
-	bnLSWord = bnLSWord_16;
-	bnReadBit = bnReadBit_16;
-	bnBits = bnBits_16;
-	bnAdd = bnAdd_16;
-	bnSub = bnSub_16;
-	bnCmpQ = bnCmpQ_16;
-	bnSetQ = bnSetQ_16;
-	bnAddQ = bnAddQ_16;
-	bnSubQ = bnSubQ_16;
-	bnCmp = bnCmp_16;
-	bnSquare = bnSquare_16;
-	bnMul = bnMul_16;
-	bnMulQ = bnMulQ_16;
-	bnDivMod = bnDivMod_16;
-	bnMod = bnMod_16;
-	bnModQ = bnModQ_16;
-	bnExpMod = bnExpMod_16;
-	bnDoubleExpMod = bnDoubleExpMod_16;
-	bnTwoExpMod = bnTwoExpMod_16;
-	bnGcd = bnGcd_16;
-	bnInv = bnInv_16;
-	bnLShift = bnLShift_16;
-	bnRShift = bnRShift_16;
-	bnMakeOdd = bnMakeOdd_16;
-	bnBasePrecompBegin = bnBasePrecompBegin_16;
-	bnBasePrecompEnd = bnBasePrecompEnd_16;
-	bnBasePrecompExpMod = bnBasePrecompExpMod_16;
-	bnDoubleBasePrecompExpMod = bnDoubleBasePrecompExpMod_16;
-}
-
-void
-bnEnd_16(struct BigNum *bn)
-{
-	if (bn->ptr) {
-		LBNFREE((BNWORD16 *)bn->ptr, bn->allocated);
-		bn->ptr = 0;
-	}
-	bn->size = 0;
-	bn->allocated = 0;
-
-	MALLOCDB;
-}
-
-/* Internal function.  It operates in words. */
-static int
-bnResize_16(struct BigNum *bn, unsigned len)
-{
-	void *p;
-
-	/* Round size up: most mallocs impose 8-byte granularity anyway */
-	len = (len + (8/sizeof(BNWORD16) - 1)) & ~(8/sizeof(BNWORD16) - 1);
-	p = LBNREALLOC((BNWORD16 *)bn->ptr, bn->allocated, len);
-	if (!p)
-		return -1;
-	bn->ptr = p;
-	bn->allocated = len;
-
-	MALLOCDB;
-
-	return 0;
-}
-
-#define bnSizeCheck(bn, size) \
-	if (bn->allocated < size && bnResize_16(bn, size) < 0) \
-		return -1
-
-/* Preallocate enough space in bn to hold "bits" bits. */
-int
-bnPrealloc_16(struct BigNum *bn, unsigned bits)
-{
-	bits = (bits + 16-1)/16;
-	bnSizeCheck(bn, bits);
-	MALLOCDB;
-	return 0;
-}
-
-int
-bnCopy_16(struct BigNum *dest, struct BigNum const *src)
-{
-	bnSizeCheck(dest, src->size);
-	dest->size = src->size;
-	lbnCopy_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, src->size);
-	MALLOCDB;
-	return 0;
-}
-
-/* Is this ever needed?  Normalize the bn by deleting high-order 0 words */
-void
-bnNorm_16(struct BigNum *bn)
-{
-	bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, bn->size);
-}
-
-/*
- * Convert a bignum to big-endian bytes.  Returns, in big-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (leading) bytes are filled with 0.
- */
-void
-bnExtractBigBytes_16(struct BigNum const *bn, unsigned char *dest,
-                  unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size * (16 / 8);
-
-	/* Fill unused leading bytes with 0 */
-	while (s < lsbyte + len) {
-		*dest++ = 0;
-		len--;
-	}
-
-	if (len)
-		lbnExtractBigBytes_16((BNWORD16 *)bn->ptr, dest, lsbyte, len);
-	MALLOCDB;
-}
-
-/* The inverse of the above. */
-int
-bnInsertBigBytes_16(struct BigNum *bn, unsigned char const *src,
-                 unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size;
-	unsigned words = (len+lsbyte+sizeof(BNWORD16)-1) / sizeof(BNWORD16);
-
-	/* Pad with zeros as required */
-	bnSizeCheck(bn, words);
-
-	if (s < words) {
-		lbnZero_16((BNWORD16 *)bn->ptr BIGLITTLE(-s,+s), words-s);
-		s = words;
-	}
-
-	lbnInsertBigBytes_16((BNWORD16 *)bn->ptr, src, lsbyte, len);
-
-	bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, s);
-
-	MALLOCDB;
-	return 0;
-}
-
-
-/*
- * Convert a bignum to little-endian bytes.  Returns, in little-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (trailing) bytes are filled with 0.
- */
-void
-bnExtractLittleBytes_16(struct BigNum const *bn, unsigned char *dest,
-                  unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size * (16 / 8);
-
-	/* Fill unused leading bytes with 0 */
-	while (s < lsbyte + len)
-		dest[--len] = 0;
-
-	if (len)
-		lbnExtractLittleBytes_16((BNWORD16 *)bn->ptr, dest,
-		                         lsbyte, len);
-	MALLOCDB;
-}
-
-/* The inverse of the above */
-int
-bnInsertLittleBytes_16(struct BigNum *bn, unsigned char const *src,
-                       unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size;
-	unsigned words = (len+lsbyte+sizeof(BNWORD16)-1) / sizeof(BNWORD16);
-
-	/* Pad with zeros as required */
-	bnSizeCheck(bn, words);
-
-	if (s < words) {
-		lbnZero_16((BNWORD16 *)bn->ptr BIGLITTLE(-s,+s), words-s);
-		s = words;
-	}
-
-	lbnInsertLittleBytes_16((BNWORD16 *)bn->ptr, src, lsbyte, len);
-
-	bn->size = lbnNorm_16((BNWORD16 *)bn->ptr, s);
-
-	MALLOCDB;
-	return 0;
-}
-
-/* Return the least-significant word of the input. */
-unsigned
-bnLSWord_16(struct BigNum const *bn)
-{
-	return bn->size ? (unsigned)((BNWORD16 *)bn->ptr)[BIGLITTLE(-1,0)]: 0;
-}
-
-/* Return a selected bit of the data */
-int
-bnReadBit_16(struct BigNum const *bn, unsigned bit)
-{
-	BNWORD16 word;
-	if (bit/16 >= bn->size)
-		return 0;
-	word = ((BNWORD16 *)bn->ptr)[BIGLITTLE(-1-bit/16,bit/16)];
-	return (int)(word >> (bit % 16) & 1);
-}
-
-/* Count the number of significant bits. */
-unsigned
-bnBits_16(struct BigNum const *bn)
-{
-	return lbnBits_16((BNWORD16 *)bn->ptr, bn->size);
-}
-
-/* dest += src */
-int
-bnAdd_16(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s = src->size, d = dest->size;
-	BNWORD16 t;
-
-	if (!s)
-		return 0;
-
-	bnSizeCheck(dest, s);
-
-	if (d < s) {
-		lbnZero_16((BNWORD16 *)dest->ptr BIGLITTLE(-d,+d), s-d);
-		dest->size = d = s;
-		MALLOCDB;
-	}
-	t = lbnAddN_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s);
-	MALLOCDB;
-	if (t) {
-		if (d > s) {
-			t = lbnAdd1_16((BNWORD16 *)dest->ptr BIGLITTLE(-s,+s),
-			               d-s, t);
-			MALLOCDB;
-		}
-		if (t) {
-			bnSizeCheck(dest, d+1);
-			((BNWORD16 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t;
-			dest->size = d+1;
-		}
-	}
-	return 0;
-}
-
-/*
- * dest -= src.
- * If dest goes negative, this produces the absolute value of
- * the difference (the negative of the true value) and returns 1.
- * Otherwise, it returls 0.
- */
-int
-bnSub_16(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s = src->size, d = dest->size;
-	BNWORD16 t;
-
-	if (d < s  &&  d < (s = lbnNorm_16((BNWORD16 *)src->ptr, s))) {
-		bnSizeCheck(dest, s);
-		lbnZero_16((BNWORD16 *)dest->ptr BIGLITTLE(-d,+d), s-d);
-		dest->size = d = s;
-		MALLOCDB;
-	}
-	if (!s)
-		return 0;
-	t = lbnSubN_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s);
-	MALLOCDB;
-	if (t) {
-		if (d > s) {
-			t = lbnSub1_16((BNWORD16 *)dest->ptr BIGLITTLE(-s,+s),
-			               d-s, t);
-			MALLOCDB;
-		}
-		if (t) {
-			lbnNeg_16((BNWORD16 *)dest->ptr, d);
-			dest->size = lbnNorm_16((BNWORD16 *)dest->ptr,
-			                        dest->size);
-			MALLOCDB;
-			return 1;
-		}
-	}
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dest->size);
-	return 0;
-}
-
-/*
- * Compare the BigNum to the given value, which must be < 65536.
- * Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmpQ(a,b) <=> 0
- */
-int
-bnCmpQ_16(struct BigNum const *a, unsigned b)
-{
-	unsigned t;
-	BNWORD16 v;
-
-	t = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
-	/* If a is more than one word long or zero, it's easy... */
-	if (t != 1)
-		return (t > 1) ? 1 : (b ? -1 : 0);
-	v = (unsigned)((BNWORD16 *)a->ptr)[BIGLITTLE(-1,0)];
-	return (v > b) ? 1 : ((v < b) ? -1 : 0);
-}
-
-/* Set dest to a small value */
-int
-bnSetQ_16(struct BigNum *dest, unsigned src)
-{
-	if (src) {
-		bnSizeCheck(dest, 1);
-
-		((BNWORD16 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD16)src;
-		dest->size = 1;
-	} else {
-		dest->size = 0;
-	}
-	return 0;
-}
-
-/* dest += src */
-int
-bnAddQ_16(struct BigNum *dest, unsigned src)
-{
-	BNWORD16 t;
-
-	if (!dest->size)
-		return bnSetQ(dest, src);
-
-	t = lbnAdd1_16((BNWORD16 *)dest->ptr, dest->size, (BNWORD16)src);
-	MALLOCDB;
-	if (t) {
-		src = dest->size;
-		bnSizeCheck(dest, src+1);
-		((BNWORD16 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t;
-		dest->size = src+1;
-	}
-	return 0;
-}
-
-/*
- * Return value as for bnSub: 1 if subtract underflowed, in which
- * case the return is the negative of the computed value.
- */
-int
-bnSubQ_16(struct BigNum *dest, unsigned src)
-{
-	BNWORD16 t;
-
-	if (!dest->size)
-		return bnSetQ(dest, src) < 0 ? -1 : (src != 0);
-
-	t = lbnSub1_16((BNWORD16 *)dest->ptr, dest->size, src);
-	MALLOCDB;
-	if (t) {
-		/* Underflow. <= 1 word, so do it simply. */
-		lbnNeg_16((BNWORD16 *)dest->ptr, 1);
-		dest->size = 1;
-		return 1;
-	}
-/* Try to normalize?  Needing this is going to be pretty damn rare. */
-/*		dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dest->size); */
-	return 0;
-}
-
-/*
- * Compare two BigNums.  Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmp(a,b) <=> 0
- */
-int
-bnCmp_16(struct BigNum const *a, struct BigNum const *b)
-{
-	unsigned s, t;
-
-	s = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
-	t = lbnNorm_16((BNWORD16 *)b->ptr, b->size);
-
-	if (s != t)
-		return s > t ? 1 : -1;
-	return lbnCmp_16((BNWORD16 *)a->ptr, (BNWORD16 *)b->ptr, s);
-}
-
-/* dest = src*src.  This is more efficient than bnMul. */
-int
-bnSquare_16(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s;
-	BNWORD16 *srcbuf;
-
-	s = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
-	if (!s) {
-		dest->size = 0;
-		return 0;
-	}
-	bnSizeCheck(dest, 2*s);
-
-	if (src == dest) {
-		LBNALLOC(srcbuf, BNWORD16, s);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_16(srcbuf, (BNWORD16 *)src->ptr, s);
-		lbnSquare_16((BNWORD16 *)dest->ptr, (BNWORD16 *)srcbuf, s);
-		LBNFREE(srcbuf, s);
-	} else {
-		lbnSquare_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, s);
-	}
-
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, 2*s);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = a * b.  Any overlap between operands is allowed. */
-int
-bnMul_16(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
-	unsigned s, t;
-	BNWORD16 *srcbuf;
-
-	s = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
-	t = lbnNorm_16((BNWORD16 *)b->ptr, b->size);
-
-	if (!s || !t) {
-		dest->size = 0;
-		return 0;
-	}
-
-	if (a == b)
-		return bnSquare_16(dest, a);
-
-	bnSizeCheck(dest, s+t);
-
-	if (dest == a) {
-		LBNALLOC(srcbuf, BNWORD16, s);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_16(srcbuf, (BNWORD16 *)a->ptr, s);
-		lbnMul_16((BNWORD16 *)dest->ptr, srcbuf, s,
-		                                 (BNWORD16 *)b->ptr, t);
-		LBNFREE(srcbuf, s);
-	} else if (dest == b) {
-		LBNALLOC(srcbuf, BNWORD16, t);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_16(srcbuf, (BNWORD16 *)b->ptr, t);
-		lbnMul_16((BNWORD16 *)dest->ptr, (BNWORD16 *)a->ptr, s,
-		                                 srcbuf, t);
-		LBNFREE(srcbuf, t);
-	} else {
-		lbnMul_16((BNWORD16 *)dest->ptr, (BNWORD16 *)a->ptr, s,
-		                                 (BNWORD16 *)b->ptr, t);
-	}
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, s+t);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = a * b */
-int
-bnMulQ_16(struct BigNum *dest, struct BigNum const *a, unsigned b)
-{
-	unsigned s;
-
-	s = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
-	if (!s || !b) {
-		dest->size = 0;
-		return 0;
-	}
-	if (b == 1)
-		return bnCopy_16(dest, a);
-	bnSizeCheck(dest, s+1);
-	lbnMulN1_16((BNWORD16 *)dest->ptr, (BNWORD16 *)a->ptr, s, b);
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, s+1);
-	MALLOCDB;
-	return 0;
-}
-
-/* q = n/d, r = n % d */
-int
-bnDivMod_16(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
-            struct BigNum const *d)
-{
-	unsigned dsize, nsize;
-	BNWORD16 qhigh;
-
-	dsize = lbnNorm_16((BNWORD16 *)d->ptr, d->size);
-	nsize = lbnNorm_16((BNWORD16 *)n->ptr, n->size);
-
-	if (nsize < dsize) {
-		q->size = 0;	/* No quotient */
-		r->size = nsize;
-		return 0;	/* Success */
-	}
-
-	bnSizeCheck(q, nsize-dsize);
-
-	if (r != n) {	/* You are allowed to reduce in place */
-		bnSizeCheck(r, nsize);
-		lbnCopy_16((BNWORD16 *)r->ptr, (BNWORD16 *)n->ptr, nsize);
-	}
-
-	qhigh = lbnDiv_16((BNWORD16 *)q->ptr, (BNWORD16 *)r->ptr, nsize,
-	                  (BNWORD16 *)d->ptr, dsize);
-	nsize -= dsize;
-	if (qhigh) {
-		bnSizeCheck(q, nsize+1);
-		*((BNWORD16 *)q->ptr BIGLITTLE(-nsize-1,+nsize)) = qhigh;
-		q->size = nsize+1;
-	} else {
-		q->size = lbnNorm_16((BNWORD16 *)q->ptr, nsize);
-	}
-	r->size = lbnNorm_16((BNWORD16 *)r->ptr, dsize);
-	MALLOCDB;
-	return 0;
-}
-
-/* det = src % d */
-int
-bnMod_16(struct BigNum *dest, struct BigNum const *src, struct BigNum const *d)
-{
-	unsigned dsize, nsize;
-
-	nsize = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
-	dsize = lbnNorm_16((BNWORD16 *)d->ptr, d->size);
-
-
-	if (dest != src) {
-		bnSizeCheck(dest, nsize);
-		lbnCopy_16((BNWORD16 *)dest->ptr, (BNWORD16 *)src->ptr, nsize);
-	}
-
-	if (nsize < dsize) {
-		dest->size = nsize;	/* No quotient */
-		return 0;
-	}
-
-	(void)lbnDiv_16((BNWORD16 *)dest->ptr BIGLITTLE(-dsize,+dsize),
-	                (BNWORD16 *)dest->ptr, nsize,
-	                (BNWORD16 *)d->ptr, dsize);
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, dsize);
-	MALLOCDB;
-	return 0;
-}
-
-/* return src % d. */
-unsigned
-bnModQ_16(struct BigNum const *src, unsigned d)
-{
-	unsigned s;
-
-	s = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
-	if (!s)
-		return 0;
-
-	if (d & (d-1))	/* Not a power of 2 */
-		d = lbnModQ_16((BNWORD16 *)src->ptr, s, d);
-	else
-		d = (unsigned)((BNWORD16 *)src->ptr)[BIGLITTLE(-1,0)] & (d-1);
-	return d;
-}
-
-/* dest = n^exp (mod mod) */
-int
-bnExpMod_16(struct BigNum *dest, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod)
-{
-	unsigned nsize, esize, msize;
-
-	nsize = lbnNorm_16((BNWORD16 *)n->ptr, n->size);
-	esize = lbnNorm_16((BNWORD16 *)exp->ptr, exp->size);
-	msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(dest, msize);
-
-	/* Special-case base of 2 */
-	if (nsize == 1 && ((BNWORD16 *)n->ptr)[BIGLITTLE(-1,0)] == 2) {
-		if (lbnTwoExpMod_16((BNWORD16 *)dest->ptr,
-				    (BNWORD16 *)exp->ptr, esize,
-				    (BNWORD16 *)mod->ptr, msize) < 0)
-			return -1;
-	} else {
-		if (lbnExpMod_16((BNWORD16 *)dest->ptr,
-		                 (BNWORD16 *)n->ptr, nsize,
-				 (BNWORD16 *)exp->ptr, esize,
-				 (BNWORD16 *)mod->ptr, msize) < 0)
-		return -1;
-	}
-
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/*
- * dest = n1^e1 * n2^e2 (mod mod).  This is more efficient than two
- * separate modular exponentiations, and in fact asymptotically approaches
- * the cost of one.
- */
-int
-bnDoubleExpMod_16(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod)
-{
-	unsigned n1size, e1size, n2size, e2size, msize;
-
-	n1size = lbnNorm_16((BNWORD16 *)n1->ptr, n1->size);
-	e1size = lbnNorm_16((BNWORD16 *)e1->ptr, e1->size);
-	n2size = lbnNorm_16((BNWORD16 *)n2->ptr, n2->size);
-	e2size = lbnNorm_16((BNWORD16 *)e2->ptr, e2->size);
-	msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(dest, msize);
-
-	if (lbnDoubleExpMod_16((BNWORD16 *)dest->ptr,
-		(BNWORD16 *)n1->ptr, n1size, (BNWORD16 *)e1->ptr, e1size,
-		(BNWORD16 *)n2->ptr, n2size, (BNWORD16 *)e2->ptr, e2size,
-		(BNWORD16 *)mod->ptr, msize) < 0)
-		return -1;
-
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/* n = 2^exp (mod mod) */
-int
-bnTwoExpMod_16(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod)
-{
-	unsigned esize, msize;
-
-	esize = lbnNorm_16((BNWORD16 *)exp->ptr, exp->size);
-	msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(n, msize);
-
-	if (lbnTwoExpMod_16((BNWORD16 *)n->ptr, (BNWORD16 *)exp->ptr, esize,
-	                    (BNWORD16 *)mod->ptr, msize) < 0)
-		return -1;
-
-	n->size = lbnNorm_16((BNWORD16 *)n->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = gcd(a, b) */
-int
-bnGcd_16(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
-	BNWORD16 *tmp;
-	unsigned asize, bsize;
-	int i;
-
-	/* Kind of silly, but we might as well permit it... */
-	if (a == b)
-		return dest == a ? 0 : bnCopy(dest, a);
-
-	/* Ensure a is not the same as "dest" */
-	if (a == dest) {
-		a = b;
-		b = dest;
-	}
-
-	asize = lbnNorm_16((BNWORD16 *)a->ptr, a->size);
-	bsize = lbnNorm_16((BNWORD16 *)b->ptr, b->size);
-
-	bnSizeCheck(dest, bsize+1);
-
-	/* Copy a to tmp */
-	LBNALLOC(tmp, BNWORD16, asize+1);
-	if (!tmp)
-		return -1;
-	lbnCopy_16(tmp, (BNWORD16 *)a->ptr, asize);
-
-	/* Copy b to dest, if necessary */
-	if (dest != b)
-		lbnCopy_16((BNWORD16 *)dest->ptr,
-			   (BNWORD16 *)b->ptr, bsize);
-	if (bsize > asize || (bsize == asize &&
-	        lbnCmp_16((BNWORD16 *)b->ptr, (BNWORD16 *)a->ptr, asize) > 0))
-	{
-		i = lbnGcd_16((BNWORD16 *)dest->ptr, bsize, tmp, asize,
-			&dest->size);
-		if (i > 0)	/* Result in tmp, not dest */
-			lbnCopy_16((BNWORD16 *)dest->ptr, tmp, dest->size);
-	} else {
-		i = lbnGcd_16(tmp, asize, (BNWORD16 *)dest->ptr, bsize,
-			&dest->size);
-		if (i == 0)	/* Result in tmp, not dest */
-			lbnCopy_16((BNWORD16 *)dest->ptr, tmp, dest->size);
-	}
-	LBNFREE(tmp, asize+1);
-	MALLOCDB;
-	return (i < 0) ? i : 0;
-}
-
-/*
- * dest = 1/src (mod mod).  Returns >0 if gcd(src, mod) != 1 (in which case
- * the inverse does not exist).
- */
-int
-bnInv_16(struct BigNum *dest, struct BigNum const *src,
-         struct BigNum const *mod)
-{
-	unsigned s, m;
-	int i;
-
-	s = lbnNorm_16((BNWORD16 *)src->ptr, src->size);
-	m = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-
-	/* lbnInv_16 requires that the input be less than the modulus */
-	if (m < s ||
-	    (m==s && lbnCmp_16((BNWORD16 *)src->ptr, (BNWORD16 *)mod->ptr, s)))
-	{
-		bnSizeCheck(dest, s + (m==s));
-		if (dest != src)
-			lbnCopy_16((BNWORD16 *)dest->ptr,
-			           (BNWORD16 *)src->ptr, s);
-		/* Pre-reduce modulo the modulus */
-		(void)lbnDiv_16((BNWORD16 *)dest->ptr BIGLITTLE(-m,+m),
-			        (BNWORD16 *)dest->ptr, s,
-		                (BNWORD16 *)mod->ptr, m);
-		s = lbnNorm_16((BNWORD16 *)dest->ptr, m);
-		MALLOCDB;
-	} else {
-		bnSizeCheck(dest, m+1);
-		if (dest != src)
-			lbnCopy_16((BNWORD16 *)dest->ptr,
-			           (BNWORD16 *)src->ptr, s);
-	}
-
-	i = lbnInv_16((BNWORD16 *)dest->ptr, s, (BNWORD16 *)mod->ptr, m);
-	if (i == 0)
-		dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, m);
-
-	MALLOCDB;
-	return i;
-}
-
-/*
- * Shift a bignum left the appropriate number of bits,
- * multiplying by 2^amt.
- */
-int
-bnLShift_16(struct BigNum *dest, unsigned amt)
-{
-	unsigned s = dest->size;
-	BNWORD16 carry;
-
-	if (amt % 16) {
-		carry = lbnLshift_16((BNWORD16 *)dest->ptr, s, amt % 16);
-		if (carry) {
-			s++;
-			bnSizeCheck(dest, s);
-			((BNWORD16 *)dest->ptr)[BIGLITTLE(-s,s-1)] = carry;
-		}
-	}
-
-	amt /= 16;
-	if (amt) {
-		bnSizeCheck(dest, s+amt);
-		memmove((BNWORD16 *)dest->ptr BIGLITTLE(-s-amt, +amt),
-		        (BNWORD16 *)dest->ptr BIG(-s),
-			s * sizeof(BNWORD16));
-		lbnZero_16((BNWORD16 *)dest->ptr, amt);
-		s += amt;
-	}
-	dest->size = s;
-	MALLOCDB;
-	return 0;
-}
-
-/*
- * Shift a bignum right the appropriate number of bits,
- * dividing by 2^amt.
- */
-void
-bnRShift_16(struct BigNum *dest, unsigned amt)
-{
-	unsigned s = dest->size;
-
-	if (amt >= 16) {
-		memmove(
-		        (BNWORD16 *)dest->ptr BIG(-s+amt/16),
-			(BNWORD16 *)dest->ptr BIGLITTLE(-s, +amt/16),
-			(s-amt/16) * sizeof(BNWORD16));
-		s -= amt/16;
-		amt %= 16;
-	}
-
-	if (amt)
-		(void)lbnRshift_16((BNWORD16 *)dest->ptr, s, amt);
-
-	dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, s);
-	MALLOCDB;
-}
-
-/*
- * Shift a bignum right until it is odd, and return the number of
- * bits shifted.  n = d * 2^s.  Replaces n with d and returns s.
- * Returns 0 when given 0.  (Another valid answer is infinity.)
- */
-unsigned
-bnMakeOdd_16(struct BigNum *n)
-{
-	unsigned size;
-	unsigned s;	/* shift amount */
-	BNWORD16 *p;
-	BNWORD16 t;
-
-	p = (BNWORD16 *)n->ptr;
-	size = lbnNorm_16(p, n->size);
-	if (!size)
-		return 0;
-
-	t = BIGLITTLE(p[-1],p[0]);
-	s = 0;
-
-	/* See how many words we have to shift */
-	if (!t) {
-		/* Shift by words */
-		do {
-			s++;
-			BIGLITTLE(--p,p++);
-		} while ((t = BIGLITTLE(p[-1],p[0])) == 0);
-		size -= s;
-		s *= 16;
-		memmove((BNWORD16 *)n->ptr BIG(-size), p BIG(-size),
-			size * sizeof(BNWORD16));
-		p = (BNWORD16 *)n->ptr;
-		MALLOCDB;
-	}
-
-	assert(t);
-
-	if (!(t & 1)) {
-		/* Now count the bits */
-		do {
-			t >>= 1;
-			s++;
-		} while ((t & 1) == 0);
-
-		/* Shift the bits */
-		lbnRshift_16(p, size, s & (16-1));
-		/* Renormalize */
-		if (BIGLITTLE(*(p-size),*(p+(size-1))) == 0)
-			--size;
-	}
-	n->size = size;
-
-	MALLOCDB;
-	return s;
-}
-
-/*
- * Do base- and modulus-dependent precomputation for rapid computation of
- * base^exp (mod mod) with various exponents.
- *
- * See lbn16.c for the details on how the algorithm works.  Basically,
- * it involves precomputing a table of powers of base, base^(order^k),
- * for a suitable range 0 <= k < n detemined by the maximum exponent size
- * desired.  To do eht exponentiation, the exponent is expressed in base
- * "order" (sorry for the confusing terminology) and the precomputed powers
- * are combined.
- * 
- * This implementation allows only power-of-2 values for "order".  Using
- * other numbers can be more efficient, but it's more work and for the
- * popular exponent size of 160 bits, an order of 8 is optimal, so it
- * hasn't seemed worth it to implement.
- * 
- * Here's a table of the optimal power-of-2 order for various exponent
- * sizes and the associated (average) cost for an exponentiation.
- * Note that *higher* orders are more memory-efficient; the number
- * of precomputed values required is ceil(ebits/order).  (Ignore the
- * underscores in the middle of numbers; they're harmless.)
- *
- * At     2 bits, order   2 uses    0.000000 multiplies
- * At     4 bits, order   2 uses    1.000000 multiplies
- * At     8 bits, order   2 uses    3.000000 multiplies
- * At   1_6 bits, order   2 uses    7.000000 multiplies
- * At   3_2 bits, order   2 uses   15.000000 multiplies
- * At    34 bits, 15.750000 (order 4) < 1_6.000000 (order 2)
- * At   6_4 bits, order   4 uses   27.000000 multiplies
- * At    99 bits, 39.875000 (order 8) < 40.250000 (order 4)
- * At   128 bits, order   8 uses   48.500000 multiplies
- * At   256 bits, order   8 uses   85.875000 multiplies
- * At   280 bits, 92.625000 (order 1_6) < 92.875000 (order 8)
- * At   512 bits, order 1_6 uses  147.000000 multiplies
- * At   785 bits, 211.093750 (order 3_2) < 211.250000 (order 1_6)
- * At  1024 bits, order 3_2 uses  257.562500 multiplies
- * At  2048 bits, order 3_2 uses  456.093750 multiplies
- * At  2148 bits, 475.406250 (order 6_4) < 475.468750 (order 3_2)
- * At  4096 bits, order 6_4 uses  795.281250 multiplies
- * At  5726 bits, 1062.609375 (order 128) < 1062.843750 (order 6_4)
- * At  8192 bits, order 128 uses 1412.609375 multiplies
- * At 14848 bits, 2355.750000 (order 256) < 2355.929688 (order 128)
- * At 37593 bits, 5187.841797 (order 512) < 5188.144531 (order 256)
- */
-int
-bnBasePrecompBegin_16(struct BnBasePrecomp *pre, struct BigNum const *base,
-	struct BigNum const *mod, unsigned maxebits)
-{
-	int i;
-	BNWORD16 **array;	/* Array of precomputed powers of base */
-	unsigned n;	/* Number of entries in array (needed) */
-	unsigned m;	/* Number of entries in array (non-NULL) */
-	unsigned arraysize; /* Number of entries in array (allocated) */
-	unsigned bits;	/* log2(order) */
-	unsigned msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-	static unsigned const bnBasePrecompThreshTable[] = {
-		33, 98, 279, 784, 2147, 5725, 14847, 37592, (unsigned)-1
-	};
-
-	/* Clear pre in case of failure */
-	pre->array = 0;
-	pre->msize = 0;
-	pre->bits = 0;
-	pre->maxebits = 0;
-	pre->arraysize = 0;
-	pre->entries = 0;
-
-	/* Find the correct bit-window size */
-	bits = 0;
-	do
-		bits++;
-	while (maxebits > bnBasePrecompThreshTable[bits]);
-
-	/* Now the number of precomputed values we need */
-	n = (maxebits+bits-1)/bits;
-	assert(n*bits >= maxebits);
-
-	arraysize = n+1;	/* Add one trailing NULL for safety */
-	array = lbnMemAlloc(arraysize * sizeof(*array));
-	if (!array)
-		return -1;	/* Out of memory */
-
-	/* Now allocate the entries (precomputed powers of base) */
-	for (m = 0; m < n; m++) {
-		BNWORD16 *entry;
-
-		LBNALLOC(entry, BNWORD16, msize);
-		if (!entry)
-			break;
-		array[m] = entry;
-	}
-	
-	/* "m" is the number of successfully allocated entries */
-	if (m < n) {
-		/* Ran out of memory; see if we can use a smaller array */
-		BNWORD16 **newarray;
-
-		if (m < 2) {
-			n = 0;	/* Forget it */
-		} else {
-			/* How few bits can we use with what's allocated? */
-			bits = (maxebits + m - 1) / m;
-retry:
-			n = (maxebits + bits - 1) / bits;
-			if (! (n >> bits) )
-				n = 0; /* Not enough to amount to anything */
-		}
-		/* Free excess allocated array entries */
-		while (m > n) {
-			BNWORD16 *entry = array[--m];
-			LBNFREE(entry, msize);
-		}
-		if (!n) {
-			/* Give it up */
-			lbnMemFree(array, arraysize * sizeof(*array));
-			return -1;
-		}
-		/*
-		 * Try to shrink the pointer array.  This might fail, but
-		 * it's not critical.  lbnMemRealloc isn't guarnateed to
-		 * exist, so we may have to allocate, copy, and free.
-		 */
-#ifdef lbnMemRealloc
-		newarray = lbnMemRealloc(array, arraysize * sizeof(*array),
-			       (n+1) * sizeof(*array));
-		if (newarray) {
-			array = newarray;
-			arraysize = n+1;
-		}
-#else
-		newarray = lbnMemAlloc((n+1) * sizeof(*array));
-		if (newarray) {
-			memcpy(newarray, array, n * sizeof(*array));
-			lbnMemFree(array, arraysize * sizeof(*array));
-			array = newarray;
-			arraysize = n+1;
-		}
-#endif
-	}
-
-	/* Pad with null pointers */
-	while (m < arraysize)
-		array[m++] = 0;
-
-	/* Okay, we have our array, now initialize it */
-	i = lbnBasePrecompBegin_16(array, n, bits,
-		(BNWORD16 *)base->ptr, base->size,
-		(BNWORD16 *)mod->ptr, msize);
-	if (i < 0) {
-		/* Ack, still out of memory */
-		bits++;
-		m = n;
-		goto retry;
-	}
-	/* Finally, totoal success */
-	pre->array = array;
-	pre->bits = bits;
-	pre->msize = msize;
-	pre->maxebits = n * bits;
-	pre->arraysize = arraysize;
-	pre->entries = n;
-	return 0;
-}
-
-/* Free everything preallocated */
-void
-bnBasePrecompEnd_16(struct BnBasePrecomp *pre)
-{
-	BNWORD16 **array = pre->array;
-
-	if (array) {
-		unsigned entries = pre->entries;
-		unsigned msize = pre->msize;
-		unsigned m;
-
-		for (m = 0; m < entries; m++) {
-			BNWORD16 *entry = array[m];
-			if (entry)
-				LBNFREE(entry, msize);
-		}
-		lbnMemFree(array, pre->arraysize * sizeof(array));
-	}
-	pre->array = 0;
-	pre->bits = 0;
-	pre->msize = 0;
-	pre->maxebits = 0;
-	pre->arraysize = 0;
-	pre->entries = 0;
-}
-
-int
-bnBasePrecompExpMod_16(struct BigNum *dest, struct BnBasePrecomp const *pre,
-	struct BigNum const *exp, struct BigNum const *mod)
-{
-	unsigned msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-	unsigned esize = lbnNorm_16((BNWORD16 *)exp->ptr, exp->size);
-	BNWORD16 const * const *array = pre->array;
-	int i;
-
-	assert(msize == pre->msize);
-	assert(((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
-	assert(lbnBits_16((BNWORD16 *)exp->ptr, esize) <= pre->maxebits);
-
-	bnSizeCheck(dest, msize);
-	
-	i = lbnBasePrecompExp_16(dest->ptr, array, pre->bits,
-		       	exp->ptr, esize, mod->ptr, msize);
-	if (i == 0)
-		dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
-	return i;
-}
-
-int
-bnDoubleBasePrecompExpMod_16(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod)
-{
-	unsigned msize = lbnNorm_16((BNWORD16 *)mod->ptr, mod->size);
-	unsigned e1size = lbnNorm_16((BNWORD16 *)exp1->ptr, exp1->size);
-	unsigned e2size = lbnNorm_16((BNWORD16 *)exp1->ptr, exp2->size);
-	BNWORD16 const * const *array1 = pre1->array;
-	BNWORD16 const * const *array2 = pre2->array;
-	int i;
-
-	assert(msize == pre1->msize);
-	assert(msize == pre2->msize);
-	assert(((BNWORD16 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
-	assert(lbnBits_16((BNWORD16 *)exp1->ptr, e1size) <= pre1->maxebits);
-	assert(lbnBits_16((BNWORD16 *)exp2->ptr, e2size) <= pre2->maxebits);
-	assert(pre1->bits == pre2->bits);
-
-	bnSizeCheck(dest, msize);
-	
-	i = lbnDoubleBasePrecompExp_16(dest->ptr, pre1->bits, array1,
-		       	exp1->ptr, e1size, array2, exp2->ptr, e2size,
-			mod->ptr, msize);
-	if (i == 0)
-		dest->size = lbnNorm_16((BNWORD16 *)dest->ptr, msize);
-	return i;
-}
diff --git a/jni/libzrtp/sources/bnlib/bn16.h b/jni/libzrtp/sources/bnlib/bn16.h
deleted file mode 100644
index 967d45a..0000000
--- a/jni/libzrtp/sources/bnlib/bn16.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * bn16.h - interface to 16-bit bignum routines.
- */
-struct BigNum;
-struct BnBasePrecomp;
-
-void bnInit_16(void);
-void bnEnd_16(struct BigNum *bn);
-int bnPrealloc_16(struct BigNum *bn, unsigned bits);
-int bnCopy_16(struct BigNum *dest, struct BigNum const *src);
-int bnSwap_16(struct BigNum *a, struct BigNum *b);
-void bnNorm_16(struct BigNum *bn);
-void bnExtractBigBytes_16(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned dlen);
-int bnInsertBigBytes_16(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-void bnExtractLittleBytes_16(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned dlen);
-int bnInsertLittleBytes_16(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-unsigned bnLSWord_16(struct BigNum const *src);
-int bnReadBit_16(struct BigNum const *bn, unsigned bit);
-unsigned bnBits_16(struct BigNum const *src);
-int bnAdd_16(struct BigNum *dest, struct BigNum const *src);
-int bnSub_16(struct BigNum *dest, struct BigNum const *src);
-int bnCmpQ_16(struct BigNum const *a, unsigned b);
-int bnSetQ_16(struct BigNum *dest, unsigned src);
-int bnAddQ_16(struct BigNum *dest, unsigned src);
-int bnSubQ_16(struct BigNum *dest, unsigned src);
-int bnCmp_16(struct BigNum const *a, struct BigNum const *b);
-int bnSquare_16(struct BigNum *dest, struct BigNum const *src);
-int bnMul_16(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int bnMulQ_16(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int bnDivMod_16(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
-	struct BigNum const *d);
-int bnMod_16(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *d);
-unsigned bnModQ_16(struct BigNum const *src, unsigned d);
-int bnExpMod_16(struct BigNum *dest, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleExpMod_16(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod);
-int bnTwoExpMod_16(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod);
-int bnGcd_16(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int bnInv_16(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *mod);
-int bnLShift_16(struct BigNum *dest, unsigned amt);
-void bnRShift_16(struct BigNum *dest, unsigned amt);
-unsigned bnMakeOdd_16(struct BigNum *n);
-int bnBasePrecompBegin_16(struct BnBasePrecomp *pre, struct BigNum const *base,
-	struct BigNum const *mod, unsigned maxebits);
-void bnBasePrecompEnd_16(struct BnBasePrecomp *pre);
-int bnBasePrecompExpMod_16(struct BigNum *dest, struct BnBasePrecomp const *pre,
-	struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleBasePrecompExpMod_16(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bn32.c b/jni/libzrtp/sources/bnlib/bn32.c
deleted file mode 100644
index ee0d257..0000000
--- a/jni/libzrtp/sources/bnlib/bn32.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * bn32.c - the high-level bignum interface
- *
- * Like lbn32.c, this reserves the string "32" for textual replacement.
- * The string must not appear anywhere unless it is intended to be replaced
- * to generate other bignum interface functions.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h>	/* for memmove() in bnMakeOdd */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-/*
- * This was useful during debugging, so it's left in here.
- * You can ignore it.  DBMALLOC is generally undefined.
- */
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-#include "../dbmalloc/malloc.h"
-#define MALLOCDB malloc_chain_check(1)
-#else
-#define MALLOCDB (void)0
-#endif
-
-#include "lbn.h"
-#include "lbn32.h"
-#include "lbnmem.h"
-#include "bn32.h"
-#include "bn.h"
-
-/* Work-arounds for some particularly broken systems */
-#include "kludge.h"	/* For memmove() */
-
-/* Functions */
-void
-bnInit_32(void)
-{
-	bnEnd = bnEnd_32;
-	bnPrealloc = bnPrealloc_32;
-	bnCopy = bnCopy_32;
-	bnNorm = bnNorm_32;
-	bnExtractBigBytes = bnExtractBigBytes_32;
-	bnInsertBigBytes = bnInsertBigBytes_32;
-	bnExtractLittleBytes = bnExtractLittleBytes_32;
-	bnInsertLittleBytes = bnInsertLittleBytes_32;
-	bnLSWord = bnLSWord_32;
-	bnReadBit = bnReadBit_32;
-	bnBits = bnBits_32;
-	bnAdd = bnAdd_32;
-	bnSub = bnSub_32;
-	bnCmpQ = bnCmpQ_32;
-	bnSetQ = bnSetQ_32;
-	bnAddQ = bnAddQ_32;
-	bnSubQ = bnSubQ_32;
-	bnCmp = bnCmp_32;
-	bnSquare = bnSquare_32;
-	bnMul = bnMul_32;
-	bnMulQ = bnMulQ_32;
-	bnDivMod = bnDivMod_32;
-	bnMod = bnMod_32;
-	bnModQ = bnModQ_32;
-	bnExpMod = bnExpMod_32;
-	bnDoubleExpMod = bnDoubleExpMod_32;
-	bnTwoExpMod = bnTwoExpMod_32;
-	bnGcd = bnGcd_32;
-	bnInv = bnInv_32;
-	bnLShift = bnLShift_32;
-	bnRShift = bnRShift_32;
-	bnMakeOdd = bnMakeOdd_32;
-	bnBasePrecompBegin = bnBasePrecompBegin_32;
-	bnBasePrecompEnd = bnBasePrecompEnd_32;
-	bnBasePrecompExpMod = bnBasePrecompExpMod_32;
-	bnDoubleBasePrecompExpMod = bnDoubleBasePrecompExpMod_32;
-}
-
-void
-bnEnd_32(struct BigNum *bn)
-{
-	if (bn->ptr) {
-		LBNFREE((BNWORD32 *)bn->ptr, bn->allocated);
-		bn->ptr = 0;
-	}
-	bn->size = 0;
-	bn->allocated = 0;
-
-	MALLOCDB;
-}
-
-/* Internal function.  It operates in words. */
-static int
-bnResize_32(struct BigNum *bn, unsigned len)
-{
-	void *p;
-
-	/* Round size up: most mallocs impose 8-byte granularity anyway */
-	len = (len + (8/sizeof(BNWORD32) - 1)) & ~(8/sizeof(BNWORD32) - 1);
-	p = LBNREALLOC((BNWORD32 *)bn->ptr, bn->allocated, len);
-	if (!p)
-		return -1;
-	bn->ptr = p;
-	bn->allocated = len;
-
-	MALLOCDB;
-
-	return 0;
-}
-
-#define bnSizeCheck(bn, size) \
-	if (bn->allocated < size && bnResize_32(bn, size) < 0) \
-		return -1
-
-/* Preallocate enough space in bn to hold "bits" bits. */
-int
-bnPrealloc_32(struct BigNum *bn, unsigned bits)
-{
-	bits = (bits + 32-1)/32;
-	bnSizeCheck(bn, bits);
-	MALLOCDB;
-	return 0;
-}
-
-int
-bnCopy_32(struct BigNum *dest, struct BigNum const *src)
-{
-	bnSizeCheck(dest, src->size);
-	dest->size = src->size;
-	lbnCopy_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, src->size);
-	MALLOCDB;
-	return 0;
-}
-
-/* Is this ever needed?  Normalize the bn by deleting high-order 0 words */
-void
-bnNorm_32(struct BigNum *bn)
-{
-	bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, bn->size);
-}
-
-/*
- * Convert a bignum to big-endian bytes.  Returns, in big-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (leading) bytes are filled with 0.
- */
-void
-bnExtractBigBytes_32(struct BigNum const *bn, unsigned char *dest,
-                  unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size * (32 / 8);
-
-	/* Fill unused leading bytes with 0 */
-	while (s < lsbyte + len) {
-		*dest++ = 0;
-		len--;
-	}
-
-	if (len)
-		lbnExtractBigBytes_32((BNWORD32 *)bn->ptr, dest, lsbyte, len);
-	MALLOCDB;
-}
-
-/* The inverse of the above. */
-int
-bnInsertBigBytes_32(struct BigNum *bn, unsigned char const *src,
-                 unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size;
-	unsigned words = (len+lsbyte+sizeof(BNWORD32)-1) / sizeof(BNWORD32);
-
-	/* Pad with zeros as required */
-	bnSizeCheck(bn, words);
-
-	if (s < words) {
-		lbnZero_32((BNWORD32 *)bn->ptr BIGLITTLE(-s,+s), words-s);
-		s = words;
-	}
-
-	lbnInsertBigBytes_32((BNWORD32 *)bn->ptr, src, lsbyte, len);
-
-	bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, s);
-
-	MALLOCDB;
-	return 0;
-}
-
-
-/*
- * Convert a bignum to little-endian bytes.  Returns, in little-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (trailing) bytes are filled with 0.
- */
-void
-bnExtractLittleBytes_32(struct BigNum const *bn, unsigned char *dest,
-                  unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size * (32 / 8);
-
-	/* Fill unused leading bytes with 0 */
-	while (s < lsbyte + len)
-		dest[--len] = 0;
-
-	if (len)
-		lbnExtractLittleBytes_32((BNWORD32 *)bn->ptr, dest,
-		                         lsbyte, len);
-	MALLOCDB;
-}
-
-/* The inverse of the above */
-int
-bnInsertLittleBytes_32(struct BigNum *bn, unsigned char const *src,
-                       unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size;
-	unsigned words = (len+lsbyte+sizeof(BNWORD32)-1) / sizeof(BNWORD32);
-
-	/* Pad with zeros as required */
-	bnSizeCheck(bn, words);
-
-	if (s < words) {
-		lbnZero_32((BNWORD32 *)bn->ptr BIGLITTLE(-s,+s), words-s);
-		s = words;
-	}
-
-	lbnInsertLittleBytes_32((BNWORD32 *)bn->ptr, src, lsbyte, len);
-
-	bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, s);
-
-	MALLOCDB;
-	return 0;
-}
-
-/* Return the least-significant word of the input. */
-unsigned
-bnLSWord_32(struct BigNum const *bn)
-{
-	return bn->size ? (unsigned)((BNWORD32 *)bn->ptr)[BIGLITTLE(-1,0)]: 0;
-}
-
-/* Return a selected bit of the data */
-int
-bnReadBit_32(struct BigNum const *bn, unsigned bit)
-{
-	BNWORD32 word;
-	if (bit/32 >= bn->size)
-		return 0;
-	word = ((BNWORD32 *)bn->ptr)[BIGLITTLE(-1-bit/32,bit/32)];
-	return (int)(word >> (bit % 32) & 1);
-}
-
-/* Count the number of significant bits. */
-unsigned
-bnBits_32(struct BigNum const *bn)
-{
-	return lbnBits_32((BNWORD32 *)bn->ptr, bn->size);
-}
-
-/* dest += src */
-int
-bnAdd_32(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s = src->size, d = dest->size;
-	BNWORD32 t;
-
-	if (!s)
-		return 0;
-
-	bnSizeCheck(dest, s);
-
-	if (d < s) {
-		lbnZero_32((BNWORD32 *)dest->ptr BIGLITTLE(-d,+d), s-d);
-		dest->size = d = s;
-		MALLOCDB;
-	}
-	t = lbnAddN_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
-	MALLOCDB;
-	if (t) {
-		if (d > s) {
-			t = lbnAdd1_32((BNWORD32 *)dest->ptr BIGLITTLE(-s,+s),
-			               d-s, t);
-			MALLOCDB;
-		}
-		if (t) {
-			bnSizeCheck(dest, d+1);
-			((BNWORD32 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t;
-			dest->size = d+1;
-		}
-	}
-	return 0;
-}
-
-/*
- * dest -= src.
- * If dest goes negative, this produces the absolute value of
- * the difference (the negative of the true value) and returns 1.
- * Otherwise, it returls 0.
- */
-int
-bnSub_32(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s = src->size, d = dest->size;
-	BNWORD32 t;
-
-	if (d < s  &&  d < (s = lbnNorm_32((BNWORD32 *)src->ptr, s))) {
-		bnSizeCheck(dest, s);
-		lbnZero_32((BNWORD32 *)dest->ptr BIGLITTLE(-d,+d), s-d);
-		dest->size = d = s;
-		MALLOCDB;
-	}
-	if (!s)
-		return 0;
-	t = lbnSubN_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
-	MALLOCDB;
-	if (t) {
-		if (d > s) {
-			t = lbnSub1_32((BNWORD32 *)dest->ptr BIGLITTLE(-s,+s),
-			               d-s, t);
-			MALLOCDB;
-		}
-		if (t) {
-			lbnNeg_32((BNWORD32 *)dest->ptr, d);
-			dest->size = lbnNorm_32((BNWORD32 *)dest->ptr,
-			                        dest->size);
-			MALLOCDB;
-			return 1;
-		}
-	}
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dest->size);
-	return 0;
-}
-
-/*
- * Compare the BigNum to the given value, which must be < 65536.
- * Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmpQ(a,b) <=> 0
- */
-int
-bnCmpQ_32(struct BigNum const *a, unsigned b)
-{
-	unsigned t;
-	BNWORD32 v;
-
-	t = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
-	/* If a is more than one word long or zero, it's easy... */
-	if (t != 1)
-		return (t > 1) ? 1 : (b ? -1 : 0);
-	v = (unsigned)((BNWORD32 *)a->ptr)[BIGLITTLE(-1,0)];
-	return (v > b) ? 1 : ((v < b) ? -1 : 0);
-}
-
-/* Set dest to a small value */
-int
-bnSetQ_32(struct BigNum *dest, unsigned src)
-{
-	if (src) {
-		bnSizeCheck(dest, 1);
-
-		((BNWORD32 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD32)src;
-		dest->size = 1;
-	} else {
-		dest->size = 0;
-	}
-	return 0;
-}
-
-/* dest += src */
-int
-bnAddQ_32(struct BigNum *dest, unsigned src)
-{
-	BNWORD32 t;
-
-	if (!dest->size)
-		return bnSetQ(dest, src);
-
-	t = lbnAdd1_32((BNWORD32 *)dest->ptr, dest->size, (BNWORD32)src);
-	MALLOCDB;
-	if (t) {
-		src = dest->size;
-		bnSizeCheck(dest, src+1);
-		((BNWORD32 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t;
-		dest->size = src+1;
-	}
-	return 0;
-}
-
-/*
- * Return value as for bnSub: 1 if subtract underflowed, in which
- * case the return is the negative of the computed value.
- */
-int
-bnSubQ_32(struct BigNum *dest, unsigned src)
-{
-	BNWORD32 t;
-
-	if (!dest->size)
-		return bnSetQ(dest, src) < 0 ? -1 : (src != 0);
-
-	t = lbnSub1_32((BNWORD32 *)dest->ptr, dest->size, src);
-	MALLOCDB;
-	if (t) {
-		/* Underflow. <= 1 word, so do it simply. */
-		lbnNeg_32((BNWORD32 *)dest->ptr, 1);
-		dest->size = 1;
-		return 1;
-	}
-/* Try to normalize?  Needing this is going to be pretty damn rare. */
-/*		dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dest->size); */
-	return 0;
-}
-
-/*
- * Compare two BigNums.  Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmp(a,b) <=> 0
- */
-int
-bnCmp_32(struct BigNum const *a, struct BigNum const *b)
-{
-	unsigned s, t;
-
-	s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
-	t = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
-
-	if (s != t)
-		return s > t ? 1 : -1;
-	return lbnCmp_32((BNWORD32 *)a->ptr, (BNWORD32 *)b->ptr, s);
-}
-
-/* dest = src*src.  This is more efficient than bnMul. */
-int
-bnSquare_32(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s;
-	BNWORD32 *srcbuf;
-
-	s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
-	if (!s) {
-		dest->size = 0;
-		return 0;
-	}
-	bnSizeCheck(dest, 2*s);
-
-	if (src == dest) {
-		LBNALLOC(srcbuf, BNWORD32, s);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_32(srcbuf, (BNWORD32 *)src->ptr, s);
-		lbnSquare_32((BNWORD32 *)dest->ptr, (BNWORD32 *)srcbuf, s);
-		LBNFREE(srcbuf, s);
-	} else {
-		lbnSquare_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
-	}
-
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, 2*s);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = a * b.  Any overlap between operands is allowed. */
-int
-bnMul_32(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
-	unsigned s, t;
-	BNWORD32 *srcbuf;
-
-	s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
-	t = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
-
-	if (!s || !t) {
-		dest->size = 0;
-		return 0;
-	}
-
-	if (a == b)
-		return bnSquare_32(dest, a);
-
-	bnSizeCheck(dest, s+t);
-
-	if (dest == a) {
-		LBNALLOC(srcbuf, BNWORD32, s);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_32(srcbuf, (BNWORD32 *)a->ptr, s);
-		lbnMul_32((BNWORD32 *)dest->ptr, srcbuf, s,
-		                                 (BNWORD32 *)b->ptr, t);
-		LBNFREE(srcbuf, s);
-	} else if (dest == b) {
-		LBNALLOC(srcbuf, BNWORD32, t);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_32(srcbuf, (BNWORD32 *)b->ptr, t);
-		lbnMul_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s,
-		                                 srcbuf, t);
-		LBNFREE(srcbuf, t);
-	} else {
-		lbnMul_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s,
-		                                 (BNWORD32 *)b->ptr, t);
-	}
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s+t);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = a * b */
-int
-bnMulQ_32(struct BigNum *dest, struct BigNum const *a, unsigned b)
-{
-	unsigned s;
-
-	s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
-	if (!s || !b) {
-		dest->size = 0;
-		return 0;
-	}
-	if (b == 1)
-		return bnCopy_32(dest, a);
-	bnSizeCheck(dest, s+1);
-	lbnMulN1_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s, b);
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s+1);
-	MALLOCDB;
-	return 0;
-}
-
-/* q = n/d, r = n % d */
-int
-bnDivMod_32(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
-            struct BigNum const *d)
-{
-	unsigned dsize, nsize;
-	BNWORD32 qhigh;
-
-	dsize = lbnNorm_32((BNWORD32 *)d->ptr, d->size);
-	nsize = lbnNorm_32((BNWORD32 *)n->ptr, n->size);
-
-	if (nsize < dsize) {
-		q->size = 0;	/* No quotient */
-		r->size = nsize;
-		return 0;	/* Success */
-	}
-
-	bnSizeCheck(q, nsize-dsize);
-
-	if (r != n) {	/* You are allowed to reduce in place */
-		bnSizeCheck(r, nsize);
-		lbnCopy_32((BNWORD32 *)r->ptr, (BNWORD32 *)n->ptr, nsize);
-	}
-
-	qhigh = lbnDiv_32((BNWORD32 *)q->ptr, (BNWORD32 *)r->ptr, nsize,
-	                  (BNWORD32 *)d->ptr, dsize);
-	nsize -= dsize;
-	if (qhigh) {
-		bnSizeCheck(q, nsize+1);
-		*((BNWORD32 *)q->ptr BIGLITTLE(-nsize-1,+nsize)) = qhigh;
-		q->size = nsize+1;
-	} else {
-		q->size = lbnNorm_32((BNWORD32 *)q->ptr, nsize);
-	}
-	r->size = lbnNorm_32((BNWORD32 *)r->ptr, dsize);
-	MALLOCDB;
-	return 0;
-}
-
-/* det = src % d */
-int
-bnMod_32(struct BigNum *dest, struct BigNum const *src, struct BigNum const *d)
-{
-	unsigned dsize, nsize;
-
-	nsize = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
-	dsize = lbnNorm_32((BNWORD32 *)d->ptr, d->size);
-
-
-	if (dest != src) {
-		bnSizeCheck(dest, nsize);
-		lbnCopy_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, nsize);
-	}
-
-	if (nsize < dsize) {
-		dest->size = nsize;	/* No quotient */
-		return 0;
-	}
-
-	(void)lbnDiv_32((BNWORD32 *)dest->ptr BIGLITTLE(-dsize,+dsize),
-	                (BNWORD32 *)dest->ptr, nsize,
-	                (BNWORD32 *)d->ptr, dsize);
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dsize);
-	MALLOCDB;
-	return 0;
-}
-
-/* return src % d. */
-unsigned
-bnModQ_32(struct BigNum const *src, unsigned d)
-{
-	unsigned s;
-
-	s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
-	if (!s)
-		return 0;
-
-	if (d & (d-1))	/* Not a power of 2 */
-		d = lbnModQ_32((BNWORD32 *)src->ptr, s, d);
-	else
-		d = (unsigned)((BNWORD32 *)src->ptr)[BIGLITTLE(-1,0)] & (d-1);
-	return d;
-}
-
-/* dest = n^exp (mod mod) */
-int
-bnExpMod_32(struct BigNum *dest, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod)
-{
-	unsigned nsize, esize, msize;
-
-	nsize = lbnNorm_32((BNWORD32 *)n->ptr, n->size);
-	esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
-	msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(dest, msize);
-
-	/* Special-case base of 2 */
-	if (nsize == 1 && ((BNWORD32 *)n->ptr)[BIGLITTLE(-1,0)] == 2) {
-		if (lbnTwoExpMod_32((BNWORD32 *)dest->ptr,
-				    (BNWORD32 *)exp->ptr, esize,
-				    (BNWORD32 *)mod->ptr, msize) < 0)
-			return -1;
-	} else {
-		if (lbnExpMod_32((BNWORD32 *)dest->ptr,
-		                 (BNWORD32 *)n->ptr, nsize,
-				 (BNWORD32 *)exp->ptr, esize,
-				 (BNWORD32 *)mod->ptr, msize) < 0)
-		return -1;
-	}
-
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/*
- * dest = n1^e1 * n2^e2 (mod mod).  This is more efficient than two
- * separate modular exponentiations, and in fact asymptotically approaches
- * the cost of one.
- */
-int
-bnDoubleExpMod_32(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod)
-{
-	unsigned n1size, e1size, n2size, e2size, msize;
-
-	n1size = lbnNorm_32((BNWORD32 *)n1->ptr, n1->size);
-	e1size = lbnNorm_32((BNWORD32 *)e1->ptr, e1->size);
-	n2size = lbnNorm_32((BNWORD32 *)n2->ptr, n2->size);
-	e2size = lbnNorm_32((BNWORD32 *)e2->ptr, e2->size);
-	msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(dest, msize);
-
-	if (lbnDoubleExpMod_32((BNWORD32 *)dest->ptr,
-		(BNWORD32 *)n1->ptr, n1size, (BNWORD32 *)e1->ptr, e1size,
-		(BNWORD32 *)n2->ptr, n2size, (BNWORD32 *)e2->ptr, e2size,
-		(BNWORD32 *)mod->ptr, msize) < 0)
-		return -1;
-
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/* n = 2^exp (mod mod) */
-int
-bnTwoExpMod_32(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod)
-{
-	unsigned esize, msize;
-
-	esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
-	msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(n, msize);
-
-	if (lbnTwoExpMod_32((BNWORD32 *)n->ptr, (BNWORD32 *)exp->ptr, esize,
-	                    (BNWORD32 *)mod->ptr, msize) < 0)
-		return -1;
-
-	n->size = lbnNorm_32((BNWORD32 *)n->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = gcd(a, b) */
-int
-bnGcd_32(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
-	BNWORD32 *tmp;
-	unsigned asize, bsize;
-	int i;
-
-	/* Kind of silly, but we might as well permit it... */
-	if (a == b)
-		return dest == a ? 0 : bnCopy(dest, a);
-
-	/* Ensure a is not the same as "dest" */
-	if (a == dest) {
-		a = b;
-		b = dest;
-	}
-
-	asize = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
-	bsize = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
-
-	bnSizeCheck(dest, bsize+1);
-
-	/* Copy a to tmp */
-	LBNALLOC(tmp, BNWORD32, asize+1);
-	if (!tmp)
-		return -1;
-	lbnCopy_32(tmp, (BNWORD32 *)a->ptr, asize);
-
-	/* Copy b to dest, if necessary */
-	if (dest != b)
-		lbnCopy_32((BNWORD32 *)dest->ptr,
-			   (BNWORD32 *)b->ptr, bsize);
-	if (bsize > asize || (bsize == asize &&
-	        lbnCmp_32((BNWORD32 *)b->ptr, (BNWORD32 *)a->ptr, asize) > 0))
-	{
-		i = lbnGcd_32((BNWORD32 *)dest->ptr, bsize, tmp, asize,
-			&dest->size);
-		if (i > 0)	/* Result in tmp, not dest */
-			lbnCopy_32((BNWORD32 *)dest->ptr, tmp, dest->size);
-	} else {
-		i = lbnGcd_32(tmp, asize, (BNWORD32 *)dest->ptr, bsize,
-			&dest->size);
-		if (i == 0)	/* Result in tmp, not dest */
-			lbnCopy_32((BNWORD32 *)dest->ptr, tmp, dest->size);
-	}
-	LBNFREE(tmp, asize+1);
-	MALLOCDB;
-	return (i < 0) ? i : 0;
-}
-
-/*
- * dest = 1/src (mod mod).  Returns >0 if gcd(src, mod) != 1 (in which case
- * the inverse does not exist).
- */
-int
-bnInv_32(struct BigNum *dest, struct BigNum const *src,
-         struct BigNum const *mod)
-{
-	unsigned s, m;
-	int i;
-
-	s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
-	m = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-
-	/* lbnInv_32 requires that the input be less than the modulus */
-	if (m < s ||
-	    (m==s && lbnCmp_32((BNWORD32 *)src->ptr, (BNWORD32 *)mod->ptr, s)))
-	{
-		bnSizeCheck(dest, s + (m==s));
-		if (dest != src)
-			lbnCopy_32((BNWORD32 *)dest->ptr,
-			           (BNWORD32 *)src->ptr, s);
-		/* Pre-reduce modulo the modulus */
-		(void)lbnDiv_32((BNWORD32 *)dest->ptr BIGLITTLE(-m,+m),
-			        (BNWORD32 *)dest->ptr, s,
-		                (BNWORD32 *)mod->ptr, m);
-		s = lbnNorm_32((BNWORD32 *)dest->ptr, m);
-		MALLOCDB;
-	} else {
-		bnSizeCheck(dest, m+1);
-		if (dest != src)
-			lbnCopy_32((BNWORD32 *)dest->ptr,
-			           (BNWORD32 *)src->ptr, s);
-	}
-
-	i = lbnInv_32((BNWORD32 *)dest->ptr, s, (BNWORD32 *)mod->ptr, m);
-	if (i == 0)
-		dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, m);
-
-	MALLOCDB;
-	return i;
-}
-
-/*
- * Shift a bignum left the appropriate number of bits,
- * multiplying by 2^amt.
- */
-int
-bnLShift_32(struct BigNum *dest, unsigned amt)
-{
-	unsigned s = dest->size;
-	BNWORD32 carry;
-
-	if (amt % 32) {
-		carry = lbnLshift_32((BNWORD32 *)dest->ptr, s, amt % 32);
-		if (carry) {
-			s++;
-			bnSizeCheck(dest, s);
-			((BNWORD32 *)dest->ptr)[BIGLITTLE(-s,s-1)] = carry;
-		}
-	}
-
-	amt /= 32;
-	if (amt) {
-		bnSizeCheck(dest, s+amt);
-		memmove((BNWORD32 *)dest->ptr BIGLITTLE(-s-amt, +amt),
-		        (BNWORD32 *)dest->ptr BIG(-s),
-			s * sizeof(BNWORD32));
-		lbnZero_32((BNWORD32 *)dest->ptr, amt);
-		s += amt;
-	}
-	dest->size = s;
-	MALLOCDB;
-	return 0;
-}
-
-/*
- * Shift a bignum right the appropriate number of bits,
- * dividing by 2^amt.
- */
-void
-bnRShift_32(struct BigNum *dest, unsigned amt)
-{
-	unsigned s = dest->size;
-
-	if (amt >= 32) {
-		memmove(
-		        (BNWORD32 *)dest->ptr BIG(-s+amt/32),
-			(BNWORD32 *)dest->ptr BIGLITTLE(-s, +amt/32),
-			(s-amt/32) * sizeof(BNWORD32));
-		s -= amt/32;
-		amt %= 32;
-	}
-
-	if (amt)
-		(void)lbnRshift_32((BNWORD32 *)dest->ptr, s, amt);
-
-	dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s);
-	MALLOCDB;
-}
-
-/*
- * Shift a bignum right until it is odd, and return the number of
- * bits shifted.  n = d * 2^s.  Replaces n with d and returns s.
- * Returns 0 when given 0.  (Another valid answer is infinity.)
- */
-unsigned
-bnMakeOdd_32(struct BigNum *n)
-{
-	unsigned size;
-	unsigned s;	/* shift amount */
-	BNWORD32 *p;
-	BNWORD32 t;
-
-	p = (BNWORD32 *)n->ptr;
-	size = lbnNorm_32(p, n->size);
-	if (!size)
-		return 0;
-
-	t = BIGLITTLE(p[-1],p[0]);
-	s = 0;
-
-	/* See how many words we have to shift */
-	if (!t) {
-		/* Shift by words */
-		do {
-			s++;
-			BIGLITTLE(--p,p++);
-		} while ((t = BIGLITTLE(p[-1],p[0])) == 0);
-		size -= s;
-		s *= 32;
-		memmove((BNWORD32 *)n->ptr BIG(-size), p BIG(-size),
-			size * sizeof(BNWORD32));
-		p = (BNWORD32 *)n->ptr;
-		MALLOCDB;
-	}
-
-	assert(t);
-
-	if (!(t & 1)) {
-		/* Now count the bits */
-		do {
-			t >>= 1;
-			s++;
-		} while ((t & 1) == 0);
-
-		/* Shift the bits */
-		lbnRshift_32(p, size, s & (32-1));
-		/* Renormalize */
-		if (BIGLITTLE(*(p-size),*(p+(size-1))) == 0)
-			--size;
-	}
-	n->size = size;
-
-	MALLOCDB;
-	return s;
-}
-
-/*
- * Do base- and modulus-dependent precomputation for rapid computation of
- * base^exp (mod mod) with various exponents.
- *
- * See lbn32.c for the details on how the algorithm works.  Basically,
- * it involves precomputing a table of powers of base, base^(order^k),
- * for a suitable range 0 <= k < n detemined by the maximum exponent size
- * desired.  To do eht exponentiation, the exponent is expressed in base
- * "order" (sorry for the confusing terminology) and the precomputed powers
- * are combined.
- * 
- * This implementation allows only power-of-2 values for "order".  Using
- * other numbers can be more efficient, but it's more work and for the
- * popular exponent size of 320 bits, an order of 8 is optimal, so it
- * hasn't seemed worth it to implement.
- * 
- * Here's a table of the optimal power-of-2 order for various exponent
- * sizes and the associated (average) cost for an exponentiation.
- * Note that *higher* orders are more memory-efficient; the number
- * of precomputed values required is ceil(ebits/order).  (Ignore the
- * underscores in the middle of numbers; they're harmless.)
- *
- * At     2 bits, order   2 uses    0.000000 multiplies
- * At     4 bits, order   2 uses    1.000000 multiplies
- * At     8 bits, order   2 uses    3.000000 multiplies
- * At   1_6 bits, order   2 uses    7.000000 multiplies
- * At   3_2 bits, order   2 uses   15.000000 multiplies
- * At    34 bits, 15.750000 (order 4) < 1_6.000000 (order 2)
- * At   6_4 bits, order   4 uses   27.000000 multiplies
- * At    99 bits, 39.875000 (order 8) < 40.250000 (order 4)
- * At   128 bits, order   8 uses   48.500000 multiplies
- * At   256 bits, order   8 uses   85.875000 multiplies
- * At   280 bits, 92.625000 (order 1_6) < 92.875000 (order 8)
- * At   512 bits, order 1_6 uses  147.000000 multiplies
- * At   785 bits, 211.093750 (order 3_2) < 211.250000 (order 1_6)
- * At  1024 bits, order 3_2 uses  257.562500 multiplies
- * At  2048 bits, order 3_2 uses  456.093750 multiplies
- * At  2148 bits, 475.406250 (order 6_4) < 475.468750 (order 3_2)
- * At  4096 bits, order 6_4 uses  795.281250 multiplies
- * At  5726 bits, 1062.609375 (order 128) < 1062.843750 (order 6_4)
- * At  8192 bits, order 128 uses 1412.609375 multiplies
- * At 14848 bits, 2355.750000 (order 256) < 2355.929688 (order 128)
- * At 37593 bits, 5187.841797 (order 512) < 5188.144531 (order 256)
- */
-int
-bnBasePrecompBegin_32(struct BnBasePrecomp *pre, struct BigNum const *base,
-	struct BigNum const *mod, unsigned maxebits)
-{
-	int i;
-	BNWORD32 **array;	/* Array of precomputed powers of base */
-	unsigned n;	/* Number of entries in array (needed) */
-	unsigned m;	/* Number of entries in array (non-NULL) */
-	unsigned arraysize; /* Number of entries in array (allocated) */
-	unsigned bits;	/* log2(order) */
-	unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-	static unsigned const bnBasePrecompThreshTable[] = {
-		33, 98, 279, 784, 2147, 5725, 14847, 37592, (unsigned)-1
-	};
-
-	/* Clear pre in case of failure */
-	pre->array = 0;
-	pre->msize = 0;
-	pre->bits = 0;
-	pre->maxebits = 0;
-	pre->arraysize = 0;
-	pre->entries = 0;
-
-	/* Find the correct bit-window size */
-	bits = 0;
-	do
-		bits++;
-	while (maxebits > bnBasePrecompThreshTable[bits]);
-
-	/* Now the number of precomputed values we need */
-	n = (maxebits+bits-1)/bits;
-	assert(n*bits >= maxebits);
-
-	arraysize = n+1;	/* Add one trailing NULL for safety */
-	array = lbnMemAlloc(arraysize * sizeof(*array));
-	if (!array)
-		return -1;	/* Out of memory */
-
-	/* Now allocate the entries (precomputed powers of base) */
-	for (m = 0; m < n; m++) {
-		BNWORD32 *entry;
-
-		LBNALLOC(entry, BNWORD32, msize);
-		if (!entry)
-			break;
-		array[m] = entry;
-	}
-	
-	/* "m" is the number of successfully allocated entries */
-	if (m < n) {
-		/* Ran out of memory; see if we can use a smaller array */
-		BNWORD32 **newarray;
-
-		if (m < 2) {
-			n = 0;	/* Forget it */
-		} else {
-			/* How few bits can we use with what's allocated? */
-			bits = (maxebits + m - 1) / m;
-retry:
-			n = (maxebits + bits - 1) / bits;
-			if (! (n >> bits) )
-				n = 0; /* Not enough to amount to anything */
-		}
-		/* Free excess allocated array entries */
-		while (m > n) {
-			BNWORD32 *entry = array[--m];
-			LBNFREE(entry, msize);
-		}
-		if (!n) {
-			/* Give it up */
-			lbnMemFree(array, arraysize * sizeof(*array));
-			return -1;
-		}
-		/*
-		 * Try to shrink the pointer array.  This might fail, but
-		 * it's not critical.  lbnMemRealloc isn't guarnateed to
-		 * exist, so we may have to allocate, copy, and free.
-		 */
-#ifdef lbnMemRealloc
-		newarray = lbnMemRealloc(array, arraysize * sizeof(*array),
-			       (n+1) * sizeof(*array));
-		if (newarray) {
-			array = newarray;
-			arraysize = n+1;
-		}
-#else
-		newarray = lbnMemAlloc((n+1) * sizeof(*array));
-		if (newarray) {
-			memcpy(newarray, array, n * sizeof(*array));
-			lbnMemFree(array, arraysize * sizeof(*array));
-			array = newarray;
-			arraysize = n+1;
-		}
-#endif
-	}
-
-	/* Pad with null pointers */
-	while (m < arraysize)
-		array[m++] = 0;
-
-	/* Okay, we have our array, now initialize it */
-	i = lbnBasePrecompBegin_32(array, n, bits,
-		(BNWORD32 *)base->ptr, base->size,
-		(BNWORD32 *)mod->ptr, msize);
-	if (i < 0) {
-		/* Ack, still out of memory */
-		bits++;
-		m = n;
-		goto retry;
-	}
-	/* Finally, totoal success */
-	pre->array = array;
-	pre->bits = bits;
-	pre->msize = msize;
-	pre->maxebits = n * bits;
-	pre->arraysize = arraysize;
-	pre->entries = n;
-	return 0;
-}
-
-/* Free everything preallocated */
-void
-bnBasePrecompEnd_32(struct BnBasePrecomp *pre)
-{
-	BNWORD32 **array = pre->array;
-
-	if (array) {
-		unsigned entries = pre->entries;
-		unsigned msize = pre->msize;
-		unsigned m;
-
-		for (m = 0; m < entries; m++) {
-			BNWORD32 *entry = array[m];
-			if (entry)
-				LBNFREE(entry, msize);
-		}
-		lbnMemFree(array, pre->arraysize * sizeof(array));
-	}
-	pre->array = 0;
-	pre->bits = 0;
-	pre->msize = 0;
-	pre->maxebits = 0;
-	pre->arraysize = 0;
-	pre->entries = 0;
-}
-
-int
-bnBasePrecompExpMod_32(struct BigNum *dest, struct BnBasePrecomp const *pre,
-	struct BigNum const *exp, struct BigNum const *mod)
-{
-	unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-	unsigned esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
-	BNWORD32 const * const *array = pre->array;
-	int i;
-
-	assert(msize == pre->msize);
-	assert(((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
-	assert(lbnBits_32((BNWORD32 *)exp->ptr, esize) <= pre->maxebits);
-
-	bnSizeCheck(dest, msize);
-	
-	i = lbnBasePrecompExp_32(dest->ptr, array, pre->bits,
-		       	exp->ptr, esize, mod->ptr, msize);
-	if (i == 0)
-		dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
-	return i;
-}
-
-int
-bnDoubleBasePrecompExpMod_32(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod)
-{
-	unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
-	unsigned e1size = lbnNorm_32((BNWORD32 *)exp1->ptr, exp1->size);
-	unsigned e2size = lbnNorm_32((BNWORD32 *)exp1->ptr, exp2->size);
-	BNWORD32 const * const *array1 = pre1->array;
-	BNWORD32 const * const *array2 = pre2->array;
-	int i;
-
-	assert(msize == pre1->msize);
-	assert(msize == pre2->msize);
-	assert(((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
-	assert(lbnBits_32((BNWORD32 *)exp1->ptr, e1size) <= pre1->maxebits);
-	assert(lbnBits_32((BNWORD32 *)exp2->ptr, e2size) <= pre2->maxebits);
-	assert(pre1->bits == pre2->bits);
-
-	bnSizeCheck(dest, msize);
-	
-	i = lbnDoubleBasePrecompExp_32(dest->ptr, pre1->bits, array1,
-		       	exp1->ptr, e1size, array2, exp2->ptr, e2size,
-			mod->ptr, msize);
-	if (i == 0)
-		dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
-	return i;
-}
diff --git a/jni/libzrtp/sources/bnlib/bn32.h b/jni/libzrtp/sources/bnlib/bn32.h
deleted file mode 100644
index 7beba61..0000000
--- a/jni/libzrtp/sources/bnlib/bn32.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * bn32.h - interface to 32-bit bignum routines.
- */
-struct BigNum;
-struct BnBasePrecomp;
-
-void bnInit_32(void);
-void bnEnd_32(struct BigNum *bn);
-int bnPrealloc_32(struct BigNum *bn, unsigned bits);
-int bnCopy_32(struct BigNum *dest, struct BigNum const *src);
-int bnSwap_32(struct BigNum *a, struct BigNum *b);
-void bnNorm_32(struct BigNum *bn);
-void bnExtractBigBytes_32(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned dlen);
-int bnInsertBigBytes_32(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-void bnExtractLittleBytes_32(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned dlen);
-int bnInsertLittleBytes_32(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-unsigned bnLSWord_32(struct BigNum const *src);
-int bnReadBit_32(struct BigNum const *bn, unsigned bit);
-unsigned bnBits_32(struct BigNum const *src);
-int bnAdd_32(struct BigNum *dest, struct BigNum const *src);
-int bnSub_32(struct BigNum *dest, struct BigNum const *src);
-int bnCmpQ_32(struct BigNum const *a, unsigned b);
-int bnSetQ_32(struct BigNum *dest, unsigned src);
-int bnAddQ_32(struct BigNum *dest, unsigned src);
-int bnSubQ_32(struct BigNum *dest, unsigned src);
-int bnCmp_32(struct BigNum const *a, struct BigNum const *b);
-int bnSquare_32(struct BigNum *dest, struct BigNum const *src);
-int bnMul_32(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int bnMulQ_32(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int bnDivMod_32(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
-	struct BigNum const *d);
-int bnMod_32(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *d);
-unsigned bnModQ_32(struct BigNum const *src, unsigned d);
-int bnExpMod_32(struct BigNum *dest, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleExpMod_32(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod);
-int bnTwoExpMod_32(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod);
-int bnGcd_32(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int bnInv_32(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *mod);
-int bnLShift_32(struct BigNum *dest, unsigned amt);
-void bnRShift_32(struct BigNum *dest, unsigned amt);
-unsigned bnMakeOdd_32(struct BigNum *n);
-int bnBasePrecompBegin_32(struct BnBasePrecomp *pre, struct BigNum const *base,
-	struct BigNum const *mod, unsigned maxebits);
-void bnBasePrecompEnd_32(struct BnBasePrecomp *pre);
-int bnBasePrecompExpMod_32(struct BigNum *dest, struct BnBasePrecomp const *pre,
-	struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleBasePrecompExpMod_32(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bn64.c b/jni/libzrtp/sources/bnlib/bn64.c
deleted file mode 100644
index 23cf185..0000000
--- a/jni/libzrtp/sources/bnlib/bn64.c
+++ /dev/null
@@ -1,1188 +0,0 @@
-/*
- * bn64.c - the high-level bignum interface
- *
- * Like lbn64.c, this reserves the string "64" for textual replacement.
- * The string must not appear anywhere unless it is intended to be replaced
- * to generate other bignum interface functions.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h>	/* for memmove() in bnMakeOdd */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-/*
- * This was useful during debugging, so it's left in here.
- * You can ignore it.  DBMALLOC is generally undefined.
- */
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-#include "../dbmalloc/malloc.h"
-#define MALLOCDB malloc_chain_check(1)
-#else
-#define MALLOCDB (void)0
-#endif
-
-#include "lbn.h"
-#include "lbn64.h"
-#include "lbnmem.h"
-#include "bn64.h"
-#include "bn.h"
-
-/* Work-arounds for some particularly broken systems */
-#include "kludge.h"	/* For memmove() */
-
-/* Functions */
-void
-bnInit_64(void)
-{
-	bnEnd = bnEnd_64;
-	bnPrealloc = bnPrealloc_64;
-	bnCopy = bnCopy_64;
-	bnNorm = bnNorm_64;
-	bnExtractBigBytes = bnExtractBigBytes_64;
-	bnInsertBigBytes = bnInsertBigBytes_64;
-	bnExtractLittleBytes = bnExtractLittleBytes_64;
-	bnInsertLittleBytes = bnInsertLittleBytes_64;
-	bnLSWord = bnLSWord_64;
-	bnReadBit = bnReadBit_64;
-	bnBits = bnBits_64;
-	bnAdd = bnAdd_64;
-	bnSub = bnSub_64;
-	bnCmpQ = bnCmpQ_64;
-	bnSetQ = bnSetQ_64;
-	bnAddQ = bnAddQ_64;
-	bnSubQ = bnSubQ_64;
-	bnCmp = bnCmp_64;
-	bnSquare = bnSquare_64;
-	bnMul = bnMul_64;
-	bnMulQ = bnMulQ_64;
-	bnDivMod = bnDivMod_64;
-	bnMod = bnMod_64;
-	bnModQ = bnModQ_64;
-	bnExpMod = bnExpMod_64;
-	bnDoubleExpMod = bnDoubleExpMod_64;
-	bnTwoExpMod = bnTwoExpMod_64;
-	bnGcd = bnGcd_64;
-	bnInv = bnInv_64;
-	bnLShift = bnLShift_64;
-	bnRShift = bnRShift_64;
-	bnMakeOdd = bnMakeOdd_64;
-	bnBasePrecompBegin = bnBasePrecompBegin_64;
-	bnBasePrecompEnd = bnBasePrecompEnd_64;
-	bnBasePrecompExpMod = bnBasePrecompExpMod_64;
-	bnDoubleBasePrecompExpMod = bnDoubleBasePrecompExpMod_64;
-}
-
-void
-bnEnd_64(struct BigNum *bn)
-{
-	if (bn->ptr) {
-		LBNFREE((BNWORD64 *)bn->ptr, bn->allocated);
-		bn->ptr = 0;
-	}
-	bn->size = 0;
-	bn->allocated = 0;
-
-	MALLOCDB;
-}
-
-/* Internal function.  It operates in words. */
-static int
-bnResize_64(struct BigNum *bn, unsigned len)
-{
-	void *p;
-
-	/* Round size up: most mallocs impose 8-byte granularity anyway */
-	len = (len + (8/sizeof(BNWORD64) - 1)) & ~(8/sizeof(BNWORD64) - 1);
-	p = LBNREALLOC((BNWORD64 *)bn->ptr, bn->allocated, len);
-	if (!p)
-		return -1;
-	bn->ptr = p;
-	bn->allocated = len;
-
-	MALLOCDB;
-
-	return 0;
-}
-
-#define bnSizeCheck(bn, size) \
-	if (bn->allocated < size && bnResize_64(bn, size) < 0) \
-		return -1
-
-/* Preallocate enough space in bn to hold "bits" bits. */
-int
-bnPrealloc_64(struct BigNum *bn, unsigned bits)
-{
-	bits = (bits + 64-1)/64;
-	bnSizeCheck(bn, bits);
-	MALLOCDB;
-	return 0;
-}
-
-int
-bnCopy_64(struct BigNum *dest, struct BigNum const *src)
-{
-	bnSizeCheck(dest, src->size);
-	dest->size = src->size;
-	lbnCopy_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, src->size);
-	MALLOCDB;
-	return 0;
-}
-
-/* Is this ever needed?  Normalize the bn by deleting high-order 0 words */
-void
-bnNorm_64(struct BigNum *bn)
-{
-	bn->size = lbnNorm_64((BNWORD64 *)bn->ptr, bn->size);
-}
-
-/*
- * Convert a bignum to big-endian bytes.  Returns, in big-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (leading) bytes are filled with 0.
- */
-void
-bnExtractBigBytes_64(struct BigNum const *bn, unsigned char *dest,
-                  unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size * (64 / 8);
-
-	/* Fill unused leading bytes with 0 */
-	while (s < lsbyte + len) {
-		*dest++ = 0;
-		len--;
-	}
-
-	if (len)
-		lbnExtractBigBytes_64((BNWORD64 *)bn->ptr, dest, lsbyte, len);
-	MALLOCDB;
-}
-
-/* The inverse of the above. */
-int
-bnInsertBigBytes_64(struct BigNum *bn, unsigned char const *src,
-                 unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size;
-	unsigned words = (len+lsbyte+sizeof(BNWORD64)-1) / sizeof(BNWORD64);
-
-	/* Pad with zeros as required */
-	bnSizeCheck(bn, words);
-
-	if (s < words) {
-		lbnZero_64((BNWORD64 *)bn->ptr BIGLITTLE(-s,+s), words-s);
-		s = words;
-	}
-
-	lbnInsertBigBytes_64((BNWORD64 *)bn->ptr, src, lsbyte, len);
-
-	bn->size = lbnNorm_64((BNWORD64 *)bn->ptr, s);
-
-	MALLOCDB;
-	return 0;
-}
-
-
-/*
- * Convert a bignum to little-endian bytes.  Returns, in little-endian form, a
- * substring of the bignum starting from lsbyte and "len" bytes long.
- * Unused high-order (trailing) bytes are filled with 0.
- */
-void
-bnExtractLittleBytes_64(struct BigNum const *bn, unsigned char *dest,
-                  unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size * (64 / 8);
-
-	/* Fill unused leading bytes with 0 */
-	while (s < lsbyte + len)
-		dest[--len] = 0;
-
-	if (len)
-		lbnExtractLittleBytes_64((BNWORD64 *)bn->ptr, dest,
-		                         lsbyte, len);
-	MALLOCDB;
-}
-
-/* The inverse of the above */
-int
-bnInsertLittleBytes_64(struct BigNum *bn, unsigned char const *src,
-                       unsigned lsbyte, unsigned len)
-{
-	unsigned s = bn->size;
-	unsigned words = (len+lsbyte+sizeof(BNWORD64)-1) / sizeof(BNWORD64);
-
-	/* Pad with zeros as required */
-	bnSizeCheck(bn, words);
-
-	if (s < words) {
-		lbnZero_64((BNWORD64 *)bn->ptr BIGLITTLE(-s,+s), words-s);
-		s = words;
-	}
-
-	lbnInsertLittleBytes_64((BNWORD64 *)bn->ptr, src, lsbyte, len);
-
-	bn->size = lbnNorm_64((BNWORD64 *)bn->ptr, s);
-
-	MALLOCDB;
-	return 0;
-}
-
-/* Return the least-significant word of the input. */
-unsigned
-bnLSWord_64(struct BigNum const *bn)
-{
-	return bn->size ? (unsigned)((BNWORD64 *)bn->ptr)[BIGLITTLE(-1,0)]: 0;
-}
-
-/* Return a selected bit of the data */
-int
-bnReadBit_64(struct BigNum const *bn, unsigned bit)
-{
-	BNWORD64 word;
-	if (bit/64 >= bn->size)
-		return 0;
-	word = ((BNWORD64 *)bn->ptr)[BIGLITTLE(-1-bit/64,bit/64)];
-	return (int)(word >> (bit % 64) & 1);
-}
-
-/* Count the number of significant bits. */
-unsigned
-bnBits_64(struct BigNum const *bn)
-{
-	return lbnBits_64((BNWORD64 *)bn->ptr, bn->size);
-}
-
-/* dest += src */
-int
-bnAdd_64(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s = src->size, d = dest->size;
-	BNWORD64 t;
-
-	if (!s)
-		return 0;
-
-	bnSizeCheck(dest, s);
-
-	if (d < s) {
-		lbnZero_64((BNWORD64 *)dest->ptr BIGLITTLE(-d,+d), s-d);
-		dest->size = d = s;
-		MALLOCDB;
-	}
-	t = lbnAddN_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, s);
-	MALLOCDB;
-	if (t) {
-		if (d > s) {
-			t = lbnAdd1_64((BNWORD64 *)dest->ptr BIGLITTLE(-s,+s),
-			               d-s, t);
-			MALLOCDB;
-		}
-		if (t) {
-			bnSizeCheck(dest, d+1);
-			((BNWORD64 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t;
-			dest->size = d+1;
-		}
-	}
-	return 0;
-}
-
-/*
- * dest -= src.
- * If dest goes negative, this produces the absolute value of
- * the difference (the negative of the true value) and returns 1.
- * Otherwise, it returls 0.
- */
-int
-bnSub_64(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s = src->size, d = dest->size;
-	BNWORD64 t;
-
-	if (d < s  &&  d < (s = lbnNorm_64((BNWORD64 *)src->ptr, s))) {
-		bnSizeCheck(dest, s);
-		lbnZero_64((BNWORD64 *)dest->ptr BIGLITTLE(-d,+d), s-d);
-		dest->size = d = s;
-		MALLOCDB;
-	}
-	if (!s)
-		return 0;
-	t = lbnSubN_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, s);
-	MALLOCDB;
-	if (t) {
-		if (d > s) {
-			t = lbnSub1_64((BNWORD64 *)dest->ptr BIGLITTLE(-s,+s),
-			               d-s, t);
-			MALLOCDB;
-		}
-		if (t) {
-			lbnNeg_64((BNWORD64 *)dest->ptr, d);
-			dest->size = lbnNorm_64((BNWORD64 *)dest->ptr,
-			                        dest->size);
-			MALLOCDB;
-			return 1;
-		}
-	}
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, dest->size);
-	return 0;
-}
-
-/*
- * Compare the BigNum to the given value, which must be < 65536.
- * Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmpQ(a,b) <=> 0
- */
-int
-bnCmpQ_64(struct BigNum const *a, unsigned b)
-{
-	unsigned t;
-	BNWORD64 v;
-
-	t = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
-	/* If a is more than one word long or zero, it's easy... */
-	if (t != 1)
-		return (t > 1) ? 1 : (b ? -1 : 0);
-	v = (unsigned)((BNWORD64 *)a->ptr)[BIGLITTLE(-1,0)];
-	return (v > b) ? 1 : ((v < b) ? -1 : 0);
-}
-
-/* Set dest to a small value */
-int
-bnSetQ_64(struct BigNum *dest, unsigned src)
-{
-	if (src) {
-		bnSizeCheck(dest, 1);
-
-		((BNWORD64 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD64)src;
-		dest->size = 1;
-	} else {
-		dest->size = 0;
-	}
-	return 0;
-}
-
-/* dest += src */
-int
-bnAddQ_64(struct BigNum *dest, unsigned src)
-{
-	BNWORD64 t;
-
-	if (!dest->size)
-		return bnSetQ(dest, src);
-
-	t = lbnAdd1_64((BNWORD64 *)dest->ptr, dest->size, (BNWORD64)src);
-	MALLOCDB;
-	if (t) {
-		src = dest->size;
-		bnSizeCheck(dest, src+1);
-		((BNWORD64 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t;
-		dest->size = src+1;
-	}
-	return 0;
-}
-
-/*
- * Return value as for bnSub: 1 if subtract underflowed, in which
- * case the return is the negative of the computed value.
- */
-int
-bnSubQ_64(struct BigNum *dest, unsigned src)
-{
-	BNWORD64 t;
-
-	if (!dest->size)
-		return bnSetQ(dest, src) < 0 ? -1 : (src != 0);
-
-	t = lbnSub1_64((BNWORD64 *)dest->ptr, dest->size, src);
-	MALLOCDB;
-	if (t) {
-		/* Underflow. <= 1 word, so do it simply. */
-		lbnNeg_64((BNWORD64 *)dest->ptr, 1);
-		dest->size = 1;
-		return 1;
-	}
-/* Try to normalize?  Needing this is going to be pretty damn rare. */
-/*		dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, dest->size); */
-	return 0;
-}
-
-/*
- * Compare two BigNums.  Returns -1. 0 or 1 if a<b, a == b or a>b.
- * a <=> b --> bnCmp(a,b) <=> 0
- */
-int
-bnCmp_64(struct BigNum const *a, struct BigNum const *b)
-{
-	unsigned s, t;
-
-	s = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
-	t = lbnNorm_64((BNWORD64 *)b->ptr, b->size);
-
-	if (s != t)
-		return s > t ? 1 : -1;
-	return lbnCmp_64((BNWORD64 *)a->ptr, (BNWORD64 *)b->ptr, s);
-}
-
-/* dest = src*src.  This is more efficient than bnMul. */
-int
-bnSquare_64(struct BigNum *dest, struct BigNum const *src)
-{
-	unsigned s;
-	BNWORD64 *srcbuf;
-
-	s = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
-	if (!s) {
-		dest->size = 0;
-		return 0;
-	}
-	bnSizeCheck(dest, 2*s);
-
-	if (src == dest) {
-		LBNALLOC(srcbuf, BNWORD64, s);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_64(srcbuf, (BNWORD64 *)src->ptr, s);
-		lbnSquare_64((BNWORD64 *)dest->ptr, (BNWORD64 *)srcbuf, s);
-		LBNFREE(srcbuf, s);
-	} else {
-		lbnSquare_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, s);
-	}
-
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, 2*s);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = a * b.  Any overlap between operands is allowed. */
-int
-bnMul_64(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
-	unsigned s, t;
-	BNWORD64 *srcbuf;
-
-	s = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
-	t = lbnNorm_64((BNWORD64 *)b->ptr, b->size);
-
-	if (!s || !t) {
-		dest->size = 0;
-		return 0;
-	}
-
-	if (a == b)
-		return bnSquare_64(dest, a);
-
-	bnSizeCheck(dest, s+t);
-
-	if (dest == a) {
-		LBNALLOC(srcbuf, BNWORD64, s);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_64(srcbuf, (BNWORD64 *)a->ptr, s);
-		lbnMul_64((BNWORD64 *)dest->ptr, srcbuf, s,
-		                                 (BNWORD64 *)b->ptr, t);
-		LBNFREE(srcbuf, s);
-	} else if (dest == b) {
-		LBNALLOC(srcbuf, BNWORD64, t);
-		if (!srcbuf)
-			return -1;
-		lbnCopy_64(srcbuf, (BNWORD64 *)b->ptr, t);
-		lbnMul_64((BNWORD64 *)dest->ptr, (BNWORD64 *)a->ptr, s,
-		                                 srcbuf, t);
-		LBNFREE(srcbuf, t);
-	} else {
-		lbnMul_64((BNWORD64 *)dest->ptr, (BNWORD64 *)a->ptr, s,
-		                                 (BNWORD64 *)b->ptr, t);
-	}
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, s+t);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = a * b */
-int
-bnMulQ_64(struct BigNum *dest, struct BigNum const *a, unsigned b)
-{
-	unsigned s;
-
-	s = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
-	if (!s || !b) {
-		dest->size = 0;
-		return 0;
-	}
-	if (b == 1)
-		return bnCopy_64(dest, a);
-	bnSizeCheck(dest, s+1);
-	lbnMulN1_64((BNWORD64 *)dest->ptr, (BNWORD64 *)a->ptr, s, b);
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, s+1);
-	MALLOCDB;
-	return 0;
-}
-
-/* q = n/d, r = n % d */
-int
-bnDivMod_64(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
-            struct BigNum const *d)
-{
-	unsigned dsize, nsize;
-	BNWORD64 qhigh;
-
-	dsize = lbnNorm_64((BNWORD64 *)d->ptr, d->size);
-	nsize = lbnNorm_64((BNWORD64 *)n->ptr, n->size);
-
-	if (nsize < dsize) {
-		q->size = 0;	/* No quotient */
-		r->size = nsize;
-		return 0;	/* Success */
-	}
-
-	bnSizeCheck(q, nsize-dsize);
-
-	if (r != n) {	/* You are allowed to reduce in place */
-		bnSizeCheck(r, nsize);
-		lbnCopy_64((BNWORD64 *)r->ptr, (BNWORD64 *)n->ptr, nsize);
-	}
-
-	qhigh = lbnDiv_64((BNWORD64 *)q->ptr, (BNWORD64 *)r->ptr, nsize,
-	                  (BNWORD64 *)d->ptr, dsize);
-	nsize -= dsize;
-	if (qhigh) {
-		bnSizeCheck(q, nsize+1);
-		*((BNWORD64 *)q->ptr BIGLITTLE(-nsize-1,+nsize)) = qhigh;
-		q->size = nsize+1;
-	} else {
-		q->size = lbnNorm_64((BNWORD64 *)q->ptr, nsize);
-	}
-	r->size = lbnNorm_64((BNWORD64 *)r->ptr, dsize);
-	MALLOCDB;
-	return 0;
-}
-
-/* det = src % d */
-int
-bnMod_64(struct BigNum *dest, struct BigNum const *src, struct BigNum const *d)
-{
-	unsigned dsize, nsize;
-
-	nsize = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
-	dsize = lbnNorm_64((BNWORD64 *)d->ptr, d->size);
-
-
-	if (dest != src) {
-		bnSizeCheck(dest, nsize);
-		lbnCopy_64((BNWORD64 *)dest->ptr, (BNWORD64 *)src->ptr, nsize);
-	}
-
-	if (nsize < dsize) {
-		dest->size = nsize;	/* No quotient */
-		return 0;
-	}
-
-	(void)lbnDiv_64((BNWORD64 *)dest->ptr BIGLITTLE(-dsize,+dsize),
-	                (BNWORD64 *)dest->ptr, nsize,
-	                (BNWORD64 *)d->ptr, dsize);
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, dsize);
-	MALLOCDB;
-	return 0;
-}
-
-/* return src % d. */
-unsigned
-bnModQ_64(struct BigNum const *src, unsigned d)
-{
-	unsigned s;
-
-	s = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
-	if (!s)
-		return 0;
-
-	if (d & (d-1))	/* Not a power of 2 */
-		d = lbnModQ_64((BNWORD64 *)src->ptr, s, d);
-	else
-		d = (unsigned)((BNWORD64 *)src->ptr)[BIGLITTLE(-1,0)] & (d-1);
-	return d;
-}
-
-/* dest = n^exp (mod mod) */
-int
-bnExpMod_64(struct BigNum *dest, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod)
-{
-	unsigned nsize, esize, msize;
-
-	nsize = lbnNorm_64((BNWORD64 *)n->ptr, n->size);
-	esize = lbnNorm_64((BNWORD64 *)exp->ptr, exp->size);
-	msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(dest, msize);
-
-	/* Special-case base of 2 */
-	if (nsize == 1 && ((BNWORD64 *)n->ptr)[BIGLITTLE(-1,0)] == 2) {
-		if (lbnTwoExpMod_64((BNWORD64 *)dest->ptr,
-				    (BNWORD64 *)exp->ptr, esize,
-				    (BNWORD64 *)mod->ptr, msize) < 0)
-			return -1;
-	} else {
-		if (lbnExpMod_64((BNWORD64 *)dest->ptr,
-		                 (BNWORD64 *)n->ptr, nsize,
-				 (BNWORD64 *)exp->ptr, esize,
-				 (BNWORD64 *)mod->ptr, msize) < 0)
-		return -1;
-	}
-
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/*
- * dest = n1^e1 * n2^e2 (mod mod).  This is more efficient than two
- * separate modular exponentiations, and in fact asymptotically approaches
- * the cost of one.
- */
-int
-bnDoubleExpMod_64(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod)
-{
-	unsigned n1size, e1size, n2size, e2size, msize;
-
-	n1size = lbnNorm_64((BNWORD64 *)n1->ptr, n1->size);
-	e1size = lbnNorm_64((BNWORD64 *)e1->ptr, e1->size);
-	n2size = lbnNorm_64((BNWORD64 *)n2->ptr, n2->size);
-	e2size = lbnNorm_64((BNWORD64 *)e2->ptr, e2->size);
-	msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(dest, msize);
-
-	if (lbnDoubleExpMod_64((BNWORD64 *)dest->ptr,
-		(BNWORD64 *)n1->ptr, n1size, (BNWORD64 *)e1->ptr, e1size,
-		(BNWORD64 *)n2->ptr, n2size, (BNWORD64 *)e2->ptr, e2size,
-		(BNWORD64 *)mod->ptr, msize) < 0)
-		return -1;
-
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/* n = 2^exp (mod mod) */
-int
-bnTwoExpMod_64(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod)
-{
-	unsigned esize, msize;
-
-	esize = lbnNorm_64((BNWORD64 *)exp->ptr, exp->size);
-	msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
-	if (!msize || (((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
-		return -1;	/* Illegal modulus! */
-
-	bnSizeCheck(n, msize);
-
-	if (lbnTwoExpMod_64((BNWORD64 *)n->ptr, (BNWORD64 *)exp->ptr, esize,
-	                    (BNWORD64 *)mod->ptr, msize) < 0)
-		return -1;
-
-	n->size = lbnNorm_64((BNWORD64 *)n->ptr, msize);
-	MALLOCDB;
-	return 0;
-}
-
-/* dest = gcd(a, b) */
-int
-bnGcd_64(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
-{
-	BNWORD64 *tmp;
-	unsigned asize, bsize;
-	int i;
-
-	/* Kind of silly, but we might as well permit it... */
-	if (a == b)
-		return dest == a ? 0 : bnCopy(dest, a);
-
-	/* Ensure a is not the same as "dest" */
-	if (a == dest) {
-		a = b;
-		b = dest;
-	}
-
-	asize = lbnNorm_64((BNWORD64 *)a->ptr, a->size);
-	bsize = lbnNorm_64((BNWORD64 *)b->ptr, b->size);
-
-	bnSizeCheck(dest, bsize+1);
-
-	/* Copy a to tmp */
-	LBNALLOC(tmp, BNWORD64, asize+1);
-	if (!tmp)
-		return -1;
-	lbnCopy_64(tmp, (BNWORD64 *)a->ptr, asize);
-
-	/* Copy b to dest, if necessary */
-	if (dest != b)
-		lbnCopy_64((BNWORD64 *)dest->ptr,
-			   (BNWORD64 *)b->ptr, bsize);
-	if (bsize > asize || (bsize == asize &&
-	        lbnCmp_64((BNWORD64 *)b->ptr, (BNWORD64 *)a->ptr, asize) > 0))
-	{
-		i = lbnGcd_64((BNWORD64 *)dest->ptr, bsize, tmp, asize,
-			&dest->size);
-		if (i > 0)	/* Result in tmp, not dest */
-			lbnCopy_64((BNWORD64 *)dest->ptr, tmp, dest->size);
-	} else {
-		i = lbnGcd_64(tmp, asize, (BNWORD64 *)dest->ptr, bsize,
-			&dest->size);
-		if (i == 0)	/* Result in tmp, not dest */
-			lbnCopy_64((BNWORD64 *)dest->ptr, tmp, dest->size);
-	}
-	LBNFREE(tmp, asize+1);
-	MALLOCDB;
-	return (i < 0) ? i : 0;
-}
-
-/*
- * dest = 1/src (mod mod).  Returns >0 if gcd(src, mod) != 1 (in which case
- * the inverse does not exist).
- */
-int
-bnInv_64(struct BigNum *dest, struct BigNum const *src,
-         struct BigNum const *mod)
-{
-	unsigned s, m;
-	int i;
-
-	s = lbnNorm_64((BNWORD64 *)src->ptr, src->size);
-	m = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-
-	/* lbnInv_64 requires that the input be less than the modulus */
-	if (m < s ||
-	    (m==s && lbnCmp_64((BNWORD64 *)src->ptr, (BNWORD64 *)mod->ptr, s)))
-	{
-		bnSizeCheck(dest, s + (m==s));
-		if (dest != src)
-			lbnCopy_64((BNWORD64 *)dest->ptr,
-			           (BNWORD64 *)src->ptr, s);
-		/* Pre-reduce modulo the modulus */
-		(void)lbnDiv_64((BNWORD64 *)dest->ptr BIGLITTLE(-m,+m),
-			        (BNWORD64 *)dest->ptr, s,
-		                (BNWORD64 *)mod->ptr, m);
-		s = lbnNorm_64((BNWORD64 *)dest->ptr, m);
-		MALLOCDB;
-	} else {
-		bnSizeCheck(dest, m+1);
-		if (dest != src)
-			lbnCopy_64((BNWORD64 *)dest->ptr,
-			           (BNWORD64 *)src->ptr, s);
-	}
-
-	i = lbnInv_64((BNWORD64 *)dest->ptr, s, (BNWORD64 *)mod->ptr, m);
-	if (i == 0)
-		dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, m);
-
-	MALLOCDB;
-	return i;
-}
-
-/*
- * Shift a bignum left the appropriate number of bits,
- * multiplying by 2^amt.
- */
-int
-bnLShift_64(struct BigNum *dest, unsigned amt)
-{
-	unsigned s = dest->size;
-	BNWORD64 carry;
-
-	if (amt % 64) {
-		carry = lbnLshift_64((BNWORD64 *)dest->ptr, s, amt % 64);
-		if (carry) {
-			s++;
-			bnSizeCheck(dest, s);
-			((BNWORD64 *)dest->ptr)[BIGLITTLE(-s,s-1)] = carry;
-		}
-	}
-
-	amt /= 64;
-	if (amt) {
-		bnSizeCheck(dest, s+amt);
-		memmove((BNWORD64 *)dest->ptr BIGLITTLE(-s-amt, +amt),
-		        (BNWORD64 *)dest->ptr BIG(-s),
-			s * sizeof(BNWORD64));
-		lbnZero_64((BNWORD64 *)dest->ptr, amt);
-		s += amt;
-	}
-	dest->size = s;
-	MALLOCDB;
-	return 0;
-}
-
-/*
- * Shift a bignum right the appropriate number of bits,
- * dividing by 2^amt.
- */
-void
-bnRShift_64(struct BigNum *dest, unsigned amt)
-{
-	unsigned s = dest->size;
-
-	if (amt >= 64) {
-		memmove(
-		        (BNWORD64 *)dest->ptr BIG(-s+amt/64),
-			(BNWORD64 *)dest->ptr BIGLITTLE(-s, +amt/64),
-			(s-amt/64) * sizeof(BNWORD64));
-		s -= amt/64;
-		amt %= 64;
-	}
-
-	if (amt)
-		(void)lbnRshift_64((BNWORD64 *)dest->ptr, s, amt);
-
-	dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, s);
-	MALLOCDB;
-}
-
-/*
- * Shift a bignum right until it is odd, and return the number of
- * bits shifted.  n = d * 2^s.  Replaces n with d and returns s.
- * Returns 0 when given 0.  (Another valid answer is infinity.)
- */
-unsigned
-bnMakeOdd_64(struct BigNum *n)
-{
-	unsigned size;
-	unsigned s;	/* shift amount */
-	BNWORD64 *p;
-	BNWORD64 t;
-
-	p = (BNWORD64 *)n->ptr;
-	size = lbnNorm_64(p, n->size);
-	if (!size)
-		return 0;
-
-	t = BIGLITTLE(p[-1],p[0]);
-	s = 0;
-
-	/* See how many words we have to shift */
-	if (!t) {
-		/* Shift by words */
-		do {
-			s++;
-			BIGLITTLE(--p,p++);
-		} while ((t = BIGLITTLE(p[-1],p[0])) == 0);
-		size -= s;
-		s *= 64;
-		memmove((BNWORD64 *)n->ptr BIG(-size), p BIG(-size),
-			size * sizeof(BNWORD64));
-		p = (BNWORD64 *)n->ptr;
-		MALLOCDB;
-	}
-
-	assert(t);
-
-	if (!(t & 1)) {
-		/* Now count the bits */
-		do {
-			t >>= 1;
-			s++;
-		} while ((t & 1) == 0);
-
-		/* Shift the bits */
-		lbnRshift_64(p, size, s & (64-1));
-		/* Renormalize */
-		if (BIGLITTLE(*(p-size),*(p+(size-1))) == 0)
-			--size;
-	}
-	n->size = size;
-
-	MALLOCDB;
-	return s;
-}
-
-/*
- * Do base- and modulus-dependent precomputation for rapid computation of
- * base^exp (mod mod) with various exponents.
- *
- * See lbn64.c for the details on how the algorithm works.  Basically,
- * it involves precomputing a table of powers of base, base^(order^k),
- * for a suitable range 0 <= k < n detemined by the maximum exponent size
- * desired.  To do eht exponentiation, the exponent is expressed in base
- * "order" (sorry for the confusing terminology) and the precomputed powers
- * are combined.
- * 
- * This implementation allows only power-of-2 values for "order".  Using
- * other numbers can be more efficient, but it's more work and for the
- * popular exponent size of 640 bits, an order of 8 is optimal, so it
- * hasn't seemed worth it to implement.
- * 
- * Here's a table of the optimal power-of-2 order for various exponent
- * sizes and the associated (average) cost for an exponentiation.
- * Note that *higher* orders are more memory-efficient; the number
- * of precomputed values required is ceil(ebits/order).  (Ignore the
- * underscores in the middle of numbers; they're harmless.)
- *
- * At     2 bits, order   2 uses    0.000000 multiplies
- * At     4 bits, order   2 uses    1.000000 multiplies
- * At     8 bits, order   2 uses    3.000000 multiplies
- * At   1_6 bits, order   2 uses    7.000000 multiplies
- * At   3_2 bits, order   2 uses   15.000000 multiplies
- * At    34 bits, 15.750000 (order 4) < 1_6.000000 (order 2)
- * At   6_4 bits, order   4 uses   27.000000 multiplies
- * At    99 bits, 39.875000 (order 8) < 40.250000 (order 4)
- * At   128 bits, order   8 uses   48.500000 multiplies
- * At   256 bits, order   8 uses   85.875000 multiplies
- * At   280 bits, 92.625000 (order 1_6) < 92.875000 (order 8)
- * At   512 bits, order 1_6 uses  147.000000 multiplies
- * At   785 bits, 211.093750 (order 3_2) < 211.250000 (order 1_6)
- * At  1024 bits, order 3_2 uses  257.562500 multiplies
- * At  2048 bits, order 3_2 uses  456.093750 multiplies
- * At  2148 bits, 475.406250 (order 6_4) < 475.468750 (order 3_2)
- * At  4096 bits, order 6_4 uses  795.281250 multiplies
- * At  5726 bits, 1062.609375 (order 128) < 1062.843750 (order 6_4)
- * At  8192 bits, order 128 uses 1412.609375 multiplies
- * At 14848 bits, 2355.750000 (order 256) < 2355.929688 (order 128)
- * At 37593 bits, 5187.841797 (order 512) < 5188.144531 (order 256)
- */
-int
-bnBasePrecompBegin_64(struct BnBasePrecomp *pre, struct BigNum const *base,
-	struct BigNum const *mod, unsigned maxebits)
-{
-	int i;
-	BNWORD64 **array;	/* Array of precomputed powers of base */
-	unsigned n;	/* Number of entries in array (needed) */
-	unsigned m;	/* Number of entries in array (non-NULL) */
-	unsigned arraysize; /* Number of entries in array (allocated) */
-	unsigned bits;	/* log2(order) */
-	unsigned msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-	static unsigned const bnBasePrecompThreshTable[] = {
-		33, 98, 279, 784, 2147, 5725, 14847, 37592, (unsigned)-1
-	};
-
-	/* Clear pre in case of failure */
-	pre->array = 0;
-	pre->msize = 0;
-	pre->bits = 0;
-	pre->maxebits = 0;
-	pre->arraysize = 0;
-	pre->entries = 0;
-
-	/* Find the correct bit-window size */
-	bits = 0;
-	do
-		bits++;
-	while (maxebits > bnBasePrecompThreshTable[bits]);
-
-	/* Now the number of precomputed values we need */
-	n = (maxebits+bits-1)/bits;
-	assert(n*bits >= maxebits);
-
-	arraysize = n+1;	/* Add one trailing NULL for safety */
-	array = lbnMemAlloc(arraysize * sizeof(*array));
-	if (!array)
-		return -1;	/* Out of memory */
-
-	/* Now allocate the entries (precomputed powers of base) */
-	for (m = 0; m < n; m++) {
-		BNWORD64 *entry;
-
-		LBNALLOC(entry, BNWORD64, msize);
-		if (!entry)
-			break;
-		array[m] = entry;
-	}
-	
-	/* "m" is the number of successfully allocated entries */
-	if (m < n) {
-		/* Ran out of memory; see if we can use a smaller array */
-		BNWORD64 **newarray;
-
-		if (m < 2) {
-			n = 0;	/* Forget it */
-		} else {
-			/* How few bits can we use with what's allocated? */
-			bits = (maxebits + m - 1) / m;
-retry:
-			n = (maxebits + bits - 1) / bits;
-			if (! (n >> bits) )
-				n = 0; /* Not enough to amount to anything */
-		}
-		/* Free excess allocated array entries */
-		while (m > n) {
-			BNWORD64 *entry = array[--m];
-			LBNFREE(entry, msize);
-		}
-		if (!n) {
-			/* Give it up */
-			lbnMemFree(array, arraysize * sizeof(*array));
-			return -1;
-		}
-		/*
-		 * Try to shrink the pointer array.  This might fail, but
-		 * it's not critical.  lbnMemRealloc isn't guarnateed to
-		 * exist, so we may have to allocate, copy, and free.
-		 */
-#ifdef lbnMemRealloc
-		newarray = lbnMemRealloc(array, arraysize * sizeof(*array),
-			       (n+1) * sizeof(*array));
-		if (newarray) {
-			array = newarray;
-			arraysize = n+1;
-		}
-#else
-		newarray = lbnMemAlloc((n+1) * sizeof(*array));
-		if (newarray) {
-			memcpy(newarray, array, n * sizeof(*array));
-			lbnMemFree(array, arraysize * sizeof(*array));
-			array = newarray;
-			arraysize = n+1;
-		}
-#endif
-	}
-
-	/* Pad with null pointers */
-	while (m < arraysize)
-		array[m++] = 0;
-
-	/* Okay, we have our array, now initialize it */
-	i = lbnBasePrecompBegin_64(array, n, bits,
-		(BNWORD64 *)base->ptr, base->size,
-		(BNWORD64 *)mod->ptr, msize);
-	if (i < 0) {
-		/* Ack, still out of memory */
-		bits++;
-		m = n;
-		goto retry;
-	}
-	/* Finally, totoal success */
-	pre->array = array;
-	pre->bits = bits;
-	pre->msize = msize;
-	pre->maxebits = n * bits;
-	pre->arraysize = arraysize;
-	pre->entries = n;
-	return 0;
-}
-
-/* Free everything preallocated */
-void
-bnBasePrecompEnd_64(struct BnBasePrecomp *pre)
-{
-	BNWORD64 **array = pre->array;
-
-	if (array) {
-		unsigned entries = pre->entries;
-		unsigned msize = pre->msize;
-		unsigned m;
-
-		for (m = 0; m < entries; m++) {
-			BNWORD64 *entry = array[m];
-			if (entry)
-				LBNFREE(entry, msize);
-		}
-		lbnMemFree(array, pre->arraysize * sizeof(array));
-	}
-	pre->array = 0;
-	pre->bits = 0;
-	pre->msize = 0;
-	pre->maxebits = 0;
-	pre->arraysize = 0;
-	pre->entries = 0;
-}
-
-int
-bnBasePrecompExpMod_64(struct BigNum *dest, struct BnBasePrecomp const *pre,
-	struct BigNum const *exp, struct BigNum const *mod)
-{
-	unsigned msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-	unsigned esize = lbnNorm_64((BNWORD64 *)exp->ptr, exp->size);
-	BNWORD64 const * const *array = pre->array;
-	int i;
-
-	assert(msize == pre->msize);
-	assert(((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
-	assert(lbnBits_64((BNWORD64 *)exp->ptr, esize) <= pre->maxebits);
-
-	bnSizeCheck(dest, msize);
-	
-	i = lbnBasePrecompExp_64(dest->ptr, array, pre->bits,
-		       	exp->ptr, esize, mod->ptr, msize);
-	if (i == 0)
-		dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
-	return i;
-}
-
-int
-bnDoubleBasePrecompExpMod_64(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod)
-{
-	unsigned msize = lbnNorm_64((BNWORD64 *)mod->ptr, mod->size);
-	unsigned e1size = lbnNorm_64((BNWORD64 *)exp1->ptr, exp1->size);
-	unsigned e2size = lbnNorm_64((BNWORD64 *)exp1->ptr, exp2->size);
-	BNWORD64 const * const *array1 = pre1->array;
-	BNWORD64 const * const *array2 = pre2->array;
-	int i;
-
-	assert(msize == pre1->msize);
-	assert(msize == pre2->msize);
-	assert(((BNWORD64 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
-	assert(lbnBits_64((BNWORD64 *)exp1->ptr, e1size) <= pre1->maxebits);
-	assert(lbnBits_64((BNWORD64 *)exp2->ptr, e2size) <= pre2->maxebits);
-	assert(pre1->bits == pre2->bits);
-
-	bnSizeCheck(dest, msize);
-	
-	i = lbnDoubleBasePrecompExp_64(dest->ptr, pre1->bits, array1,
-		       	exp1->ptr, e1size, array2, exp2->ptr, e2size,
-			mod->ptr, msize);
-	if (i == 0)
-		dest->size = lbnNorm_64((BNWORD64 *)dest->ptr, msize);
-	return i;
-}
diff --git a/jni/libzrtp/sources/bnlib/bn64.h b/jni/libzrtp/sources/bnlib/bn64.h
deleted file mode 100644
index 1c23721..0000000
--- a/jni/libzrtp/sources/bnlib/bn64.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * bn64.h - interface to 64-bit bignum routines.
- */
-struct BigNum;
-struct BnBasePrecomp;
-
-void bnInit_64(void);
-void bnEnd_64(struct BigNum *bn);
-int bnPrealloc_64(struct BigNum *bn, unsigned bits);
-int bnCopy_64(struct BigNum *dest, struct BigNum const *src);
-int bnSwap_64(struct BigNum *a, struct BigNum *b);
-void bnNorm_64(struct BigNum *bn);
-void bnExtractBigBytes_64(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned dlen);
-int bnInsertBigBytes_64(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-void bnExtractLittleBytes_64(struct BigNum const *bn, unsigned char *dest,
-	unsigned lsbyte, unsigned dlen);
-int bnInsertLittleBytes_64(struct BigNum *bn, unsigned char const *src,
-	unsigned lsbyte, unsigned len);
-unsigned bnLSWord_64(struct BigNum const *src);
-int bnReadBit_64(struct BigNum const *bn, unsigned bit);
-unsigned bnBits_64(struct BigNum const *src);
-int bnAdd_64(struct BigNum *dest, struct BigNum const *src);
-int bnSub_64(struct BigNum *dest, struct BigNum const *src);
-int bnCmpQ_64(struct BigNum const *a, unsigned b);
-int bnSetQ_64(struct BigNum *dest, unsigned src);
-int bnAddQ_64(struct BigNum *dest, unsigned src);
-int bnSubQ_64(struct BigNum *dest, unsigned src);
-int bnCmp_64(struct BigNum const *a, struct BigNum const *b);
-int bnSquare_64(struct BigNum *dest, struct BigNum const *src);
-int bnMul_64(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int bnMulQ_64(struct BigNum *dest, struct BigNum const *a, unsigned b);
-int bnDivMod_64(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
-	struct BigNum const *d);
-int bnMod_64(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *d);
-unsigned bnModQ_64(struct BigNum const *src, unsigned d);
-int bnExpMod_64(struct BigNum *dest, struct BigNum const *n,
-	struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleExpMod_64(struct BigNum *dest,
-	struct BigNum const *n1, struct BigNum const *e1,
-	struct BigNum const *n2, struct BigNum const *e2,
-	struct BigNum const *mod);
-int bnTwoExpMod_64(struct BigNum *n, struct BigNum const *exp,
-	struct BigNum const *mod);
-int bnGcd_64(struct BigNum *dest, struct BigNum const *a,
-	struct BigNum const *b);
-int bnInv_64(struct BigNum *dest, struct BigNum const *src,
-	struct BigNum const *mod);
-int bnLShift_64(struct BigNum *dest, unsigned amt);
-void bnRShift_64(struct BigNum *dest, unsigned amt);
-unsigned bnMakeOdd_64(struct BigNum *n);
-int bnBasePrecompBegin_64(struct BnBasePrecomp *pre, struct BigNum const *base,
-	struct BigNum const *mod, unsigned maxebits);
-void bnBasePrecompEnd_64(struct BnBasePrecomp *pre);
-int bnBasePrecompExpMod_64(struct BigNum *dest, struct BnBasePrecomp const *pre,
-	struct BigNum const *exp, struct BigNum const *mod);
-int bnDoubleBasePrecompExpMod_64(struct BigNum *dest,
-	struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
-	struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
-	struct BigNum const *mod);
diff --git a/jni/libzrtp/sources/bnlib/bnconfig.h.cmake b/jni/libzrtp/sources/bnlib/bnconfig.h.cmake
deleted file mode 100644
index 2571de1..0000000
--- a/jni/libzrtp/sources/bnlib/bnconfig.h.cmake
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * bnconfig.h.cmake -- Configuration file for BigNum library.
- *
- * cmake processes this file.
- */
-#ifndef _BNCONFIG_H
-#define _BNCONFIG_H
-
-/* Checks for the presence and absence of various header files */
-#cmakedefine HAVE_ASSERT_H 1
-#define NO_ASSERT_H !HAVE_ASSERT_H
-
-#cmakedefine HAVE_LIMITS_H 1
-#define NO_LIMITS_H !HAVE_LIMITS_H
-
-#cmakedefine HAVE_STDLIB_H 1
-#define NO_STDLIB_H !HAVE_STDLIB_H
-
-#cmakedefine HAVE_STRING_H 1
-#define NO_STRING_H !HAVE_STRING_H
-
-#cmakedefine HAVE_STRINGS_H 1
-
-#cmakedefine NEED_MEMORY_H 1
-
-/* We go to some trouble to find accurate times... */
-
-/* Define if you have Posix.4 glock_gettime() */
-#cmakedefine HAVE_CLOCK_GETTIME 1
-/* Define if you have Solaris-style gethrvtime() */
-#cmakedefine HAVE_GETHRVTIME 1
-/* Define if you have getrusage() */
-#cmakedefine HAVE_GETRUSAGE 1
-/* Define if you have clock() */
-#cmakedefine HAVE_CLOCK 1
-/* Define if you have time() */
-#cmakedefine HAVE_TIME 1
-
-/*
- * Define as 0 if #including <sys/time.h> automatically
- * #includes <time.h>, and doing so explicitly causes an
- * error.
- */
-#define TIME_WITH_SYS_TIME 0
-
-/* Defines for various kinds of library brokenness */
-
-/* Define if <stdio.h> is missing prototypes (= lots of warnings!) */
-#cmakedefine NO_STDIO_PROTOS 1
-
-/* Define if <assert.h> depends on <stdio.h> and breaks without it */
-#cmakedefine ASSERT_NEEDS_STDIO 1
-/* Define if <assert.h> depends on <stdlib.h> and complains without it */
-#cmakedefine ASSERT_NEEDS_STDLIB 1
-
-/*
- * Define if <string.h> delcares the mem* functions to take char *
- * instead of void * parameters (= lots of warnings)
- */
-#cmakedefine MEM_PROTOS_BROKEN 1
-
-/* If not available, bcopy() is substituted */
-#cmakedefine HAVE_MEMMOVE 1
-#define NO_MEMMOVE !HAVE_MEMMOVE
-#cmakedefine HAVE_MEMCPY 1
-#define NO_MEMCPY !HAVE_MEMCPY
-
-#endif /* _BNCONFIG_H */
diff --git a/jni/libzrtp/sources/bnlib/bninit16.c b/jni/libzrtp/sources/bnlib/bninit16.c
deleted file mode 100644
index 16c6f3e..0000000
--- a/jni/libzrtp/sources/bnlib/bninit16.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * bninit16.c - Provide an init function that sets things up for 16-bit
- * operation.  This is a seaparate tiny file so you can compile two bn
- * packages into the library and write a custom init routine.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bn.h"
-#include "bn16.h"
-
-void
-bnInit(void)
-{
-	bnInit_16();
-}
diff --git a/jni/libzrtp/sources/bnlib/bninit32.c b/jni/libzrtp/sources/bnlib/bninit32.c
deleted file mode 100644
index b27d363..0000000
--- a/jni/libzrtp/sources/bnlib/bninit32.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * bninit32.c - Provide an init function that sets things up for 32-bit
- * operation.  This is a seaparate tiny file so you can compile two bn
- * packages into the library and write a custom init routine.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bn.h"
-#include "bn32.h"
-
-void
-bnInit(void)
-{
-	bnInit_32();
-}
diff --git a/jni/libzrtp/sources/bnlib/bninit64.c b/jni/libzrtp/sources/bnlib/bninit64.c
deleted file mode 100644
index 4abe673..0000000
--- a/jni/libzrtp/sources/bnlib/bninit64.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * bninit64.c - Provide an init function that sets things up for 64-bit
- * operation.  This is a seaparate tiny file so you can compile two bn
- * packages into the library and write a custom init routine.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bn.h"
-#include "bn64.h"
-
-void
-bnInit(void)
-{
-	bnInit_64();
-}
diff --git a/jni/libzrtp/sources/bnlib/bnprint.c b/jni/libzrtp/sources/bnlib/bnprint.c
deleted file mode 100644
index a407248..0000000
--- a/jni/libzrtp/sources/bnlib/bnprint.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * bnprint.c - Print a bignum, for debugging purposes.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include "bnconfig.h"
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-
-#include <stdio.h>
-#include <stdint.h>
-
-#if !NO_STRING_H
-#include <string.h>
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#include "bn.h"
-#include "bnprint.h"
-
-#include "kludge.h"
-
-int
-bnPrint(FILE *f, char const *prefix, struct BigNum const *bn,
-        char const *suffix)
-{
-    unsigned char temp[32];	/* How much to print on one line */
-    unsigned len;
-    size_t i;
-
-    if (prefix && fputs(prefix, f) < 0)
-        return EOF;
-
-    len = (bnBits(bn) + 7)/ 8;
-
-    if (!len) {
-        if (putc('0', f) < 0)
-            return EOF;
-    } else {
-        while (len > sizeof(temp)) {
-            len -= sizeof(temp);
-            bnExtractBigBytes(bn, temp, len, sizeof(temp));
-            for (i = 0; i < sizeof(temp); i++)
-                if (fprintf(f, "%02X", temp[i]) < 0)
-                    return EOF;
-                if (putc('\\', f) < 0 || putc('\n', f) < 0)
-                    return EOF;
-                if (prefix) {
-                    i = strlen(prefix);
-                    while (i--)
-                        if (putc(' ', f) < 0)
-                            return EOF;
-                }
-        }
-        bnExtractBigBytes(bn, temp, 0, len);
-        for (i = 0; i < len; i++)
-            if (fprintf(f, "%02X", temp[i]) < 0)
-                return EOF;
-    }
-    return suffix ? fputs(suffix, f) : 0;
-}
-
-/*
- * Convert an ASCII character to digit value
- */
-static int getAsciiDigit( uint32_t *d, int radix, char c )
-{
-    *d = 255;
-
-    if( c >= 0x30 && c <= 0x39 )
-        *d = c - 0x30;
-    if( c >= 0x41 && c <= 0x46 )
-        *d = c - 0x37;
-    if( c >= 0x61 && c <= 0x66 )
-        *d = c - 0x57;
-
-    if( *d >= (uint32_t)radix )
-        return( -1 );
-
-    return( 0 );
-}
-
-int
-bnReadAscii(struct BigNum *X, char *s, int radix)
-{
-    int slen = strlen(s);
-    int i, neg = 0;
-    uint32_t d;
-
-    bnSetQ(X, 0);
-    for( i = 0; i < slen; i++ ) {
-        if(i == 0 && s[i] == '-') {
-            neg = 1;
-            continue;
-        }
-        getAsciiDigit(&d, radix, s[i]);
-        bnMulQ(X, X, radix);
-
-        bnAddQ(X, d);
-    }
-    return(neg);
-}
diff --git a/jni/libzrtp/sources/bnlib/bnprint.h b/jni/libzrtp/sources/bnlib/bnprint.h
deleted file mode 100644
index b10393a..0000000
--- a/jni/libzrtp/sources/bnlib/bnprint.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#ifndef BNPRINT_H
-#define BNPRINT_H
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-struct BigNum;
-
-#ifndef SWIG
-int bnPrint(FILE *f, char const *prefix, struct BigNum const *bn,
-	char const *suffix);
-#endif
-
-/**
- * Convert an ASCII string into a BigNum.
- *
- * This function converts an ASCII string into a Big number. If the first
- * character of the string is a minus sign the big number is a negative number.
- *
- * @param X the BigNum that stores the result
- *
- * @param s the ASCII string in big-endian format (first digit is most significant)
- *
- * @param radix the function can use radix between 2 and 16
- */
-int bnReadAscii(struct BigNum *X, char *s, int radix);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* BNPRINT_H */
diff --git a/jni/libzrtp/sources/bnlib/bnsize00.h b/jni/libzrtp/sources/bnlib/bnsize00.h
deleted file mode 100644
index 962f486..0000000
--- a/jni/libzrtp/sources/bnlib/bnsize00.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * bnsize00.h - pick the correct machine word size to use.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#include "lbn.h"	/* Get basic information */
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16 && defined(BNWORD64)
-# if defined(BNWORD128) || (defined(lbnMulAdd1_64) && defined(lbnMulSub1_64))
-#  define BNSIZE64 1
-# elif defined(mul64_ppmm) || defined(mul64_ppmma) || defined(mul64_ppmmaa)
-#  define BNSIZE64 1
-# endif
-#endif
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16 && defined(BNWORD32)
-# if defined(BNWORD64) || (defined(lbnMulAdd1_32) && defined(lbnMulSub1_32))
-#  define BNSIZE32 1
-# elif defined(mul32_ppmm) || defined(mul32_ppmma) || defined(mul32_ppmmaa)
-#  define BNSIZE32 1
-# endif
-#endif
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16 && defined(BNWORD16)
-# if defined(BNWORD32) || (defined(lbnMulAdd1_16) && defined(lbnMulSub1_16))
-#  define BNSIZE16 1
-# elif defined(mul16_ppmm) || defined(mul16_ppmma) || defined(mul16_ppmmaa)
-#  define BNSIZE16 1
-# endif
-#endif
-
-#if !BNSIZE64 && !BNSIZE32 && !BNSIZE16
-#error Unable to find a viable word size to compile bignum library.
-#endif
diff --git a/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c b/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c
deleted file mode 100644
index de11280..0000000
--- a/jni/libzrtp/sources/bnlib/ec/curve25519-donna.c
+++ /dev/null
@@ -1,731 +0,0 @@
-/* Copyright 2008, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * 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.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "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 COPYRIGHT
- * OWNER OR CONTRIBUTORS 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.
- *
- * curve25519-donna: Curve25519 elliptic curve, public key function
- *
- * http://code.google.com/p/curve25519-donna/
- *
- * Adam Langley <agl@imperialviolet.org>
- *
- * Derived from public domain C code by Daniel J. Bernstein <djb@cr.yp.to>
- *
- * More information about curve25519 can be found here
- *   http://cr.yp.to/ecdh.html
- *
- * djb's sample implementation of curve25519 is written in a special assembly
- * language called qhasm and uses the floating point registers.
- *
- * This is, almost, a clean room reimplementation from the curve25519 paper. It
- * uses many of the tricks described therein. Only the crecip function is taken
- * from the sample implementation.
- */
-
-#include <string.h>
-#include <stdint.h>
-
-#ifdef _MSC_VER
-#define inline __inline
-#endif
-
-typedef uint8_t u8;
-typedef int32_t s32;
-typedef int64_t limb;
-
-/* Field element representation:
- *
- * Field elements are written as an array of signed, 64-bit limbs, least
- * significant first. The value of the field element is:
- *   x[0] + 2^26·x[1] + x^51·x[2] + 2^102·x[3] + ...
- *
- * i.e. the limbs are 26, 25, 26, 25, ... bits wide.
- */
-
-/* Sum two numbers: output += in */
-static void fsum(limb *output, const limb *in) {
-  unsigned i;
-  for (i = 0; i < 10; i += 2) {
-    output[0+i] = (output[0+i] + in[0+i]);
-    output[1+i] = (output[1+i] + in[1+i]);
-  }
-}
-
-/* Find the difference of two numbers: output = in - output
- * (note the order of the arguments!)
- */
-static void fdifference(limb *output, const limb *in) {
-  unsigned i;
-  for (i = 0; i < 10; ++i) {
-    output[i] = (in[i] - output[i]);
-  }
-}
-
-/* Multiply a number by a scalar: output = in * scalar */
-static void fscalar_product(limb *output, const limb *in, const limb scalar) {
-  unsigned i;
-  for (i = 0; i < 10; ++i) {
-    output[i] = in[i] * scalar;
-  }
-}
-
-/* Multiply two numbers: output = in2 * in
- *
- * output must be distinct to both inputs. The inputs are reduced coefficient
- * form, the output is not.
- */
-static void fproduct(limb *output, const limb *in2, const limb *in) {
-  output[0] =       ((limb) ((s32) in2[0])) * ((s32) in[0]);
-  output[1] =       ((limb) ((s32) in2[0])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[0]);
-  output[2] =  2 *  ((limb) ((s32) in2[1])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[0]);
-  output[3] =       ((limb) ((s32) in2[1])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[0]);
-  output[4] =       ((limb) ((s32) in2[2])) * ((s32) in[2]) +
-               2 * (((limb) ((s32) in2[1])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[0]);
-  output[5] =       ((limb) ((s32) in2[2])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[0]);
-  output[6] =  2 * (((limb) ((s32) in2[3])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[0]);
-  output[7] =       ((limb) ((s32) in2[3])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[0]);
-  output[8] =       ((limb) ((s32) in2[4])) * ((s32) in[4]) +
-               2 * (((limb) ((s32) in2[3])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[0]);
-  output[9] =       ((limb) ((s32) in2[4])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[2]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[1]) +
-                    ((limb) ((s32) in2[0])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[0]);
-  output[10] = 2 * (((limb) ((s32) in2[5])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[1])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[1])) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[2]);
-  output[11] =      ((limb) ((s32) in2[5])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[4]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[3]) +
-                    ((limb) ((s32) in2[2])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[2]);
-  output[12] =      ((limb) ((s32) in2[6])) * ((s32) in[6]) +
-               2 * (((limb) ((s32) in2[5])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[3])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[3])) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[4]);
-  output[13] =      ((limb) ((s32) in2[6])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[7])) * ((s32) in[6]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[5]) +
-                    ((limb) ((s32) in2[4])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[4]);
-  output[14] = 2 * (((limb) ((s32) in2[7])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[5])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[5])) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[6]);
-  output[15] =      ((limb) ((s32) in2[7])) * ((s32) in[8]) +
-                    ((limb) ((s32) in2[8])) * ((s32) in[7]) +
-                    ((limb) ((s32) in2[6])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[6]);
-  output[16] =      ((limb) ((s32) in2[8])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in2[7])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[7]));
-  output[17] =      ((limb) ((s32) in2[8])) * ((s32) in[9]) +
-                    ((limb) ((s32) in2[9])) * ((s32) in[8]);
-  output[18] = 2 *  ((limb) ((s32) in2[9])) * ((s32) in[9]);
-}
-
-/* Reduce a long form to a short form by taking the input mod 2^255 - 19. */
-static void freduce_degree(limb *output) {
-  /* Each of these shifts and adds ends up multiplying the value by 19. */
-  output[8] += output[18] << 4;
-  output[8] += output[18] << 1;
-  output[8] += output[18];
-  output[7] += output[17] << 4;
-  output[7] += output[17] << 1;
-  output[7] += output[17];
-  output[6] += output[16] << 4;
-  output[6] += output[16] << 1;
-  output[6] += output[16];
-  output[5] += output[15] << 4;
-  output[5] += output[15] << 1;
-  output[5] += output[15];
-  output[4] += output[14] << 4;
-  output[4] += output[14] << 1;
-  output[4] += output[14];
-  output[3] += output[13] << 4;
-  output[3] += output[13] << 1;
-  output[3] += output[13];
-  output[2] += output[12] << 4;
-  output[2] += output[12] << 1;
-  output[2] += output[12];
-  output[1] += output[11] << 4;
-  output[1] += output[11] << 1;
-  output[1] += output[11];
-  output[0] += output[10] << 4;
-  output[0] += output[10] << 1;
-  output[0] += output[10];
-}
-
-#if (-1 & 3) != 3
-#error "This code only works on a two's complement system"
-#endif
-
-/* return v / 2^26, using only shifts and adds. */
-static limb div_by_2_26(const limb v)
-{
-  /* High word of v; no shift needed*/
-  const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
-  /* Set to all 1s if v was negative; else set to 0s. */
-  const int32_t sign = ((int32_t) highword) >> 31;
-  /* Set to 0x3ffffff if v was negative; else set to 0. */
-  const int32_t roundoff = ((uint32_t) sign) >> 6;
-  /* Should return v / (1<<26) */
-  return (v + roundoff) >> 26;
-}
-
-/* return v / (2^25), using only shifts and adds. */
-static limb div_by_2_25(const limb v)
-{
-  /* High word of v; no shift needed*/
-  const uint32_t highword = (uint32_t) (((uint64_t) v) >> 32);
-  /* Set to all 1s if v was negative; else set to 0s. */
-  const int32_t sign = ((int32_t) highword) >> 31;
-  /* Set to 0x1ffffff if v was negative; else set to 0. */
-  const int32_t roundoff = ((uint32_t) sign) >> 7;
-  /* Should return v / (1<<25) */
-  return (v + roundoff) >> 25;
-}
-
-static s32 div_s32_by_2_25(const s32 v)
-{
-   const s32 roundoff = ((uint32_t)(v >> 31)) >> 7;
-   return (v + roundoff) >> 25;
-}
-
-/* Reduce all coefficients of the short form input so that |x| < 2^26.
- *
- * On entry: |output[i]| < 2^62
- */
-static void freduce_coefficients(limb *output) {
-  unsigned i;
-
-  output[10] = 0;
-
-  for (i = 0; i < 10; i += 2) {
-    limb over = div_by_2_26(output[i]);
-    output[i] -= over << 26;
-    output[i+1] += over;
-
-    over = div_by_2_25(output[i+1]);
-    output[i+1] -= over << 25;
-    output[i+2] += over;
-  }
-  /* Now |output[10]| < 2 ^ 38 and all other coefficients are reduced. */
-  output[0] += output[10] << 4;
-  output[0] += output[10] << 1;
-  output[0] += output[10];
-
-  output[10] = 0;
-
-  /* Now output[1..9] are reduced, and |output[0]| < 2^26 + 19 * 2^38
-   * So |over| will be no more than 77825  */
-  {
-    limb over = div_by_2_26(output[0]);
-    output[0] -= over << 26;
-    output[1] += over;
-  }
-
-  /* Now output[0,2..9] are reduced, and |output[1]| < 2^25 + 77825
-   * So |over| will be no more than 1. */
-  {
-    /* output[1] fits in 32 bits, so we can use div_s32_by_2_25 here. */
-    s32 over32 = div_s32_by_2_25((s32) output[1]);
-    output[1] -= over32 << 25;
-    output[2] += over32;
-  }
-
-  /* Finally, output[0,1,3..9] are reduced, and output[2] is "nearly reduced":
-   * we have |output[2]| <= 2^26.  This is good enough for all of our math,
-   * but it will require an extra freduce_coefficients before fcontract. */
-}
-
-/* A helpful wrapper around fproduct: output = in * in2.
- *
- * output must be distinct to both inputs. The output is reduced degree and
- * reduced coefficient.
- */
-static void
-fmul(limb *output, const limb *in, const limb *in2) {
-  limb t[19];
-  fproduct(t, in, in2);
-  freduce_degree(t);
-  freduce_coefficients(t);
-  memcpy(output, t, sizeof(limb) * 10);
-}
-
-static void fsquare_inner(limb *output, const limb *in) {
-  output[0] =       ((limb) ((s32) in[0])) * ((s32) in[0]);
-  output[1] =  2 *  ((limb) ((s32) in[0])) * ((s32) in[1]);
-  output[2] =  2 * (((limb) ((s32) in[1])) * ((s32) in[1]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[2]));
-  output[3] =  2 * (((limb) ((s32) in[1])) * ((s32) in[2]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[3]));
-  output[4] =       ((limb) ((s32) in[2])) * ((s32) in[2]) +
-               4 *  ((limb) ((s32) in[1])) * ((s32) in[3]) +
-               2 *  ((limb) ((s32) in[0])) * ((s32) in[4]);
-  output[5] =  2 * (((limb) ((s32) in[2])) * ((s32) in[3]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[4]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[5]));
-  output[6] =  2 * (((limb) ((s32) in[3])) * ((s32) in[3]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[4]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[6]) +
-               2 *  ((limb) ((s32) in[1])) * ((s32) in[5]));
-  output[7] =  2 * (((limb) ((s32) in[3])) * ((s32) in[4]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[5]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[7]));
-  output[8] =       ((limb) ((s32) in[4])) * ((s32) in[4]) +
-               2 * (((limb) ((s32) in[2])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in[1])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[5])));
-  output[9] =  2 * (((limb) ((s32) in[4])) * ((s32) in[5]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[0])) * ((s32) in[9]));
-  output[10] = 2 * (((limb) ((s32) in[5])) * ((s32) in[5]) +
-                    ((limb) ((s32) in[4])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in[3])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[1])) * ((s32) in[9])));
-  output[11] = 2 * (((limb) ((s32) in[5])) * ((s32) in[6]) +
-                    ((limb) ((s32) in[4])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[2])) * ((s32) in[9]));
-  output[12] =      ((limb) ((s32) in[6])) * ((s32) in[6]) +
-               2 * (((limb) ((s32) in[4])) * ((s32) in[8]) +
-               2 * (((limb) ((s32) in[5])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[3])) * ((s32) in[9])));
-  output[13] = 2 * (((limb) ((s32) in[6])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[5])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[4])) * ((s32) in[9]));
-  output[14] = 2 * (((limb) ((s32) in[7])) * ((s32) in[7]) +
-                    ((limb) ((s32) in[6])) * ((s32) in[8]) +
-               2 *  ((limb) ((s32) in[5])) * ((s32) in[9]));
-  output[15] = 2 * (((limb) ((s32) in[7])) * ((s32) in[8]) +
-                    ((limb) ((s32) in[6])) * ((s32) in[9]));
-  output[16] =      ((limb) ((s32) in[8])) * ((s32) in[8]) +
-               4 *  ((limb) ((s32) in[7])) * ((s32) in[9]);
-  output[17] = 2 *  ((limb) ((s32) in[8])) * ((s32) in[9]);
-  output[18] = 2 *  ((limb) ((s32) in[9])) * ((s32) in[9]);
-}
-
-static void
-fsquare(limb *output, const limb *in) {
-  limb t[19];
-  fsquare_inner(t, in);
-  freduce_degree(t);
-  freduce_coefficients(t);
-  memcpy(output, t, sizeof(limb) * 10);
-}
-
-/* Take a little-endian, 32-byte number and expand it into polynomial form */
-static void
-fexpand(limb *output, const u8 *input) {
-#define F(n,start,shift,mask) \
-  output[n] = ((((limb) input[start + 0]) | \
-                ((limb) input[start + 1]) << 8 | \
-                ((limb) input[start + 2]) << 16 | \
-                ((limb) input[start + 3]) << 24) >> shift) & mask;
-  F(0, 0, 0, 0x3ffffff);
-  F(1, 3, 2, 0x1ffffff);
-  F(2, 6, 3, 0x3ffffff);
-  F(3, 9, 5, 0x1ffffff);
-  F(4, 12, 6, 0x3ffffff);
-  F(5, 16, 0, 0x1ffffff);
-  F(6, 19, 1, 0x3ffffff);
-  F(7, 22, 3, 0x1ffffff);
-  F(8, 25, 4, 0x3ffffff);
-  F(9, 28, 6, 0x1ffffff);
-#undef F
-}
-
-#if (-32 >> 1) != -16
-#error "This code only works when >> does sign-extension on negative numbers"
-#endif
-
-/* Take a fully reduced polynomial form number and contract it into a
- * little-endian, 32-byte array
- */
-static void
-fcontract(u8 *output, limb *input) {
-  int i;
-  int j;
-
-  for (j = 0; j < 2; ++j) {
-    for (i = 0; i < 9; ++i) {
-      if ((i & 1) == 1) {
-        /* This calculation is a time-invariant way to make input[i] positive
-           by borrowing from the next-larger limb.
-        */
-        const s32 mask = (s32)(input[i]) >> 31;
-        const s32 carry = -(((s32)(input[i]) & mask) >> 25);
-        input[i] = (s32)(input[i]) + (carry << 25);
-        input[i+1] = (s32)(input[i+1]) - carry;
-      } else {
-        const s32 mask = (s32)(input[i]) >> 31;
-        const s32 carry = -(((s32)(input[i]) & mask) >> 26);
-        input[i] = (s32)(input[i]) + (carry << 26);
-        input[i+1] = (s32)(input[i+1]) - carry;
-      }
-    }
-    {
-      const s32 mask = (s32)(input[9]) >> 31;
-      const s32 carry = -(((s32)(input[9]) & mask) >> 25);
-      input[9] = (s32)(input[9]) + (carry << 25);
-      input[0] = (s32)(input[0]) - (carry * 19);
-    }
-  }
-
-  /* The first borrow-propagation pass above ended with every limb
-     except (possibly) input[0] non-negative.
-
-     Since each input limb except input[0] is decreased by at most 1
-     by a borrow-propagation pass, the second borrow-propagation pass
-     could only have wrapped around to decrease input[0] again if the
-     first pass left input[0] negative *and* input[1] through input[9]
-     were all zero.  In that case, input[1] is now 2^25 - 1, and this
-     last borrow-propagation step will leave input[1] non-negative.
-  */
-  {
-    const s32 mask = (s32)(input[0]) >> 31;
-    const s32 carry = -(((s32)(input[0]) & mask) >> 26);
-    input[0] = (s32)(input[0]) + (carry << 26);
-    input[1] = (s32)(input[1]) - carry;
-  }
-
-  /* Both passes through the above loop, plus the last 0-to-1 step, are
-     necessary: if input[9] is -1 and input[0] through input[8] are 0,
-     negative values will remain in the array until the end.
-   */
-
-  input[1] <<= 2;
-  input[2] <<= 3;
-  input[3] <<= 5;
-  input[4] <<= 6;
-  input[6] <<= 1;
-  input[7] <<= 3;
-  input[8] <<= 4;
-  input[9] <<= 6;
-#define F(i, s) \
-  output[s+0] |=  input[i] & 0xff; \
-  output[s+1]  = (input[i] >> 8) & 0xff; \
-  output[s+2]  = (input[i] >> 16) & 0xff; \
-  output[s+3]  = (input[i] >> 24) & 0xff;
-  output[0] = 0;
-  output[16] = 0;
-  F(0,0);
-  F(1,3);
-  F(2,6);
-  F(3,9);
-  F(4,12);
-  F(5,16);
-  F(6,19);
-  F(7,22);
-  F(8,25);
-  F(9,28);
-#undef F
-}
-
-/* Input: Q, Q', Q-Q'
- * Output: 2Q, Q+Q'
- *
- *   x2 z3: long form
- *   x3 z3: long form
- *   x z: short form, destroyed
- *   xprime zprime: short form, destroyed
- *   qmqp: short form, preserved
- */
-static void fmonty(limb *x2, limb *z2,  /* output 2Q */
-                   limb *x3, limb *z3,  /* output Q + Q' */
-                   limb *x, limb *z,    /* input Q */
-                   limb *xprime, limb *zprime,  /* input Q' */
-                   const limb *qmqp /* input Q - Q' */) {
-  limb origx[10], origxprime[10], zzz[19], xx[19], zz[19], xxprime[19],
-        zzprime[19], zzzprime[19], xxxprime[19];
-
-  memcpy(origx, x, 10 * sizeof(limb));
-  fsum(x, z);
-  fdifference(z, origx);  /* does x - z */
-
-  memcpy(origxprime, xprime, sizeof(limb) * 10);
-  fsum(xprime, zprime);
-  fdifference(zprime, origxprime);
-  fproduct(xxprime, xprime, z);
-  fproduct(zzprime, x, zprime);
-  freduce_degree(xxprime);
-  freduce_coefficients(xxprime);
-  freduce_degree(zzprime);
-  freduce_coefficients(zzprime);
-  memcpy(origxprime, xxprime, sizeof(limb) * 10);
-  fsum(xxprime, zzprime);
-  fdifference(zzprime, origxprime);
-  fsquare(xxxprime, xxprime);
-  fsquare(zzzprime, zzprime);
-  fproduct(zzprime, zzzprime, qmqp);
-  freduce_degree(zzprime);
-  freduce_coefficients(zzprime);
-  memcpy(x3, xxxprime, sizeof(limb) * 10);
-  memcpy(z3, zzprime, sizeof(limb) * 10);
-
-  fsquare(xx, x);
-  fsquare(zz, z);
-  fproduct(x2, xx, zz);
-  freduce_degree(x2);
-  freduce_coefficients(x2);
-  fdifference(zz, xx);         /* does zz = xx - zz */
-  memset(zzz + 10, 0, sizeof(limb) * 9);
-  fscalar_product(zzz, zz, 121665);
-  /* No need to call freduce_degree here:
-     fscalar_product doesn't increase the degree of its input.
-   */
-  freduce_coefficients(zzz);
-  fsum(zzz, xx);
-  fproduct(z2, zz, zzz);
-  freduce_degree(z2);
-  freduce_coefficients(z2);
-}
-
-/* Conditionally swap two reduced-form limb arrays if 'iswap' is 1, but leave
- * them unchanged if 'iswap' is 0.  Runs in data-invariant time to avoid
- * side-channel attacks.
- *
- * NOTE that this function requires that 'iswap' be 1 or 0; other values give
- * wrong results.  Also, the two limb arrays must be in reduced-coefficient,
- * reduced-degree form: the values in a[10..19] or b[10..19] aren't swapped,
- * and all all values in a[0..9],b[0..9] must have magnitude less than
- * INT32_MAX.
- */
-static void
-swap_conditional(limb a[19], limb b[19], limb iswap) {
-  unsigned i;
-  const s32 swap = (s32) -iswap;
-
-  for (i = 0; i < 10; ++i) {
-    const s32 x = swap & ( ((s32)a[i]) ^ ((s32)b[i]) );
-    a[i] = ((s32)a[i]) ^ x;
-    b[i] = ((s32)b[i]) ^ x;
-  }
-}
-
-/* Calculates nQ where Q is the x-coordinate of a point on the curve
- *
- *   resultx/resultz: the x coordinate of the resulting curve point (short form)
- *   n: a little endian, 32-byte number
- *   q: a point of the curve (short form)
- */
-static void
-cmult(limb *resultx, limb *resultz, const u8 *n, const limb *q) {
-  limb a[19] = {0}, b[19] = {1}, c[19] = {1}, d[19] = {0};
-  limb *nqpqx = a, *nqpqz = b, *nqx = c, *nqz = d, *t;
-  limb e[19] = {0}, f[19] = {1}, g[19] = {0}, h[19] = {1};
-  limb *nqpqx2 = e, *nqpqz2 = f, *nqx2 = g, *nqz2 = h;
-
-  unsigned i, j;
-
-  memcpy(nqpqx, q, sizeof(limb) * 10);
-
-  for (i = 0; i < 32; ++i) {
-    u8 byte = n[31 - i];
-    for (j = 0; j < 8; ++j) {
-      const limb bit = byte >> 7;
-
-      swap_conditional(nqx, nqpqx, bit);
-      swap_conditional(nqz, nqpqz, bit);
-      fmonty(nqx2, nqz2,
-             nqpqx2, nqpqz2,
-             nqx, nqz,
-             nqpqx, nqpqz,
-             q);
-      swap_conditional(nqx2, nqpqx2, bit);
-      swap_conditional(nqz2, nqpqz2, bit);
-
-      t = nqx;
-      nqx = nqx2;
-      nqx2 = t;
-      t = nqz;
-      nqz = nqz2;
-      nqz2 = t;
-      t = nqpqx;
-      nqpqx = nqpqx2;
-      nqpqx2 = t;
-      t = nqpqz;
-      nqpqz = nqpqz2;
-      nqpqz2 = t;
-
-      byte <<= 1;
-    }
-  }
-
-  memcpy(resultx, nqx, sizeof(limb) * 10);
-  memcpy(resultz, nqz, sizeof(limb) * 10);
-}
-
-/* -----------------------------------------------------------------------------
- * Shamelessly copied from djb's code
- * ----------------------------------------------------------------------------- */
-static void
-crecip(limb *out, const limb *z) {
-  limb z2[10];
-  limb z9[10];
-  limb z11[10];
-  limb z2_5_0[10];
-  limb z2_10_0[10];
-  limb z2_20_0[10];
-  limb z2_50_0[10];
-  limb z2_100_0[10];
-  limb t0[10];
-  limb t1[10];
-  int i;
-
-  /* 2 */ fsquare(z2,z);
-  /* 4 */ fsquare(t1,z2);
-  /* 8 */ fsquare(t0,t1);
-  /* 9 */ fmul(z9,t0,z);
-  /* 11 */ fmul(z11,z9,z2);
-  /* 22 */ fsquare(t0,z11);
-  /* 2^5 - 2^0 = 31 */ fmul(z2_5_0,t0,z9);
-
-  /* 2^6 - 2^1 */ fsquare(t0,z2_5_0);
-  /* 2^7 - 2^2 */ fsquare(t1,t0);
-  /* 2^8 - 2^3 */ fsquare(t0,t1);
-  /* 2^9 - 2^4 */ fsquare(t1,t0);
-  /* 2^10 - 2^5 */ fsquare(t0,t1);
-  /* 2^10 - 2^0 */ fmul(z2_10_0,t0,z2_5_0);
-
-  /* 2^11 - 2^1 */ fsquare(t0,z2_10_0);
-  /* 2^12 - 2^2 */ fsquare(t1,t0);
-  /* 2^20 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^20 - 2^0 */ fmul(z2_20_0,t1,z2_10_0);
-
-  /* 2^21 - 2^1 */ fsquare(t0,z2_20_0);
-  /* 2^22 - 2^2 */ fsquare(t1,t0);
-  /* 2^40 - 2^20 */ for (i = 2;i < 20;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^40 - 2^0 */ fmul(t0,t1,z2_20_0);
-
-  /* 2^41 - 2^1 */ fsquare(t1,t0);
-  /* 2^42 - 2^2 */ fsquare(t0,t1);
-  /* 2^50 - 2^10 */ for (i = 2;i < 10;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
-  /* 2^50 - 2^0 */ fmul(z2_50_0,t0,z2_10_0);
-
-  /* 2^51 - 2^1 */ fsquare(t0,z2_50_0);
-  /* 2^52 - 2^2 */ fsquare(t1,t0);
-  /* 2^100 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^100 - 2^0 */ fmul(z2_100_0,t1,z2_50_0);
-
-  /* 2^101 - 2^1 */ fsquare(t1,z2_100_0);
-  /* 2^102 - 2^2 */ fsquare(t0,t1);
-  /* 2^200 - 2^100 */ for (i = 2;i < 100;i += 2) { fsquare(t1,t0); fsquare(t0,t1); }
-  /* 2^200 - 2^0 */ fmul(t1,t0,z2_100_0);
-
-  /* 2^201 - 2^1 */ fsquare(t0,t1);
-  /* 2^202 - 2^2 */ fsquare(t1,t0);
-  /* 2^250 - 2^50 */ for (i = 2;i < 50;i += 2) { fsquare(t0,t1); fsquare(t1,t0); }
-  /* 2^250 - 2^0 */ fmul(t0,t1,z2_50_0);
-
-  /* 2^251 - 2^1 */ fsquare(t1,t0);
-  /* 2^252 - 2^2 */ fsquare(t0,t1);
-  /* 2^253 - 2^3 */ fsquare(t1,t0);
-  /* 2^254 - 2^4 */ fsquare(t0,t1);
-  /* 2^255 - 2^5 */ fsquare(t1,t0);
-  /* 2^255 - 21 */ fmul(out,t1,z11);
-}
-
-int curve25519_donna(u8 *, const u8 *, const u8 *);
-
-int curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) {
-  limb bp[10], x[10], z[11], zmone[10];
-  uint8_t e[32];
-  int i;
-
-  for (i = 0; i < 32; ++i) e[i] = secret[i];
-  e[0] &= 248;
-  e[31] &= 127;
-  e[31] |= 64;
-
-  fexpand(bp, basepoint);
-  cmult(x, z, e, bp);
-  crecip(zmone, z);
-  fmul(z, x, zmone);
-  freduce_coefficients(z);
-  fcontract(mypublic, z);
-  return 0;
-}
diff --git a/jni/libzrtp/sources/bnlib/ec/ec.c b/jni/libzrtp/sources/bnlib/ec/ec.c
deleted file mode 100644
index 18e612f..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ec.c
+++ /dev/null
@@ -1,1695 +0,0 @@
-/*
- * Copyright (C) 2012-2013 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <bn.h>
-#include <bnprint.h>
-
-#include <ec/ec.h>
-
-static BigNum _mpiZero;
-static BigNum _mpiOne;
-static BigNum _mpiTwo;
-static BigNum _mpiThree;
-static BigNum _mpiFour;
-static BigNum _mpiEight;
-
-static BigNum* mpiZero  = &_mpiZero;
-static BigNum* mpiOne   = &_mpiOne;
-static BigNum* mpiTwo   = &_mpiTwo;
-static BigNum* mpiThree = &_mpiThree;
-static BigNum* mpiFour  = &_mpiFour;
-static BigNum* mpiEight = &_mpiEight;
-static int initialized = 0;
-
-
-/* The following parameters are given:
- - The prime modulus p
- - The order n
- - The 160-bit input seed SEED to the SHA-1 based algorithm (i.e., the domain parameter seed)
- - The output c of the SHA-1 based algorithm
- - The coefficient b (satisfying b2 c ≡ –27 (mod p))
- - The base point x coordinate Gx
- - The base point y coordinate Gy
-*/
-
-typedef struct _curveData {
-    char *p;
-    char *n;
-    char *SEED;
-    char *c;
-    char *b;
-    char *Gx;
-    char *Gy;
-} curveData;
-
-static curveData nist192 = {
-    "6277101735386680763835789423207666416083908700390324961279",
-    "6277101735386680763835789423176059013767194773182842284081",
-    "3045ae6fc8422f64ed579528d38120eae12196d5",
-    "3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65",
-    "64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
-    "188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
-    "07192b95ffc8da78631011ed6b24cdd573f977a11e794811",
-};
-
-static curveData nist224 = {
-    "26959946667150639794667015087019630673557916260026308143510066298881",
-    "26959946667150639794667015087019625940457807714424391721682722368061",
-    "bd71344799d5c7fcdc45b59fa3b9ab8f6a948bc5",
-    "5b056c7e11dd68f40469ee7f3c7a7d74f7d121116506d031218291fb",
-    "b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
-    "b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
-    "bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34",
-};
-
-static curveData nist256 = {
-    "115792089210356248762697446949407573530086143415290314195533631308867097853951",
-    "115792089210356248762697446949407573529996955224135760342422259061068512044369",
-    "c49d360886e704936a6678e1139d26b7819f7e90",
-    "7efba1662985be9403cb055c75d4f7e0ce8d84a9c5114abcaf3177680104fa0d",
-    "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
-    "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
-    "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
-};
-
-static curveData nist384 = {
-    "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319",
-    "39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643",
-    "a335926aa319a27a1d00896a6773a4827acdac73",
-    "79d1e655f868f02fff48dcdee14151ddb80643c1406d0ca10dfe6fc52009540a495e8042ea5f744f6e184667cc722483",
-    "b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
-    "aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
-    "3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
-};
-
-static curveData nist521 = {
-    "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151",
-    "6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449",
-    "d09e8800291cb85396cc6717393284aaa0da64ba",
-        "0b48bfa5f420a34949539d2bdfc264eeeeb077688e44fbf0ad8f6d0edb37bd6b533281000518e19f1b9ffbe0fe9ed8a3c2200b8f875e523868c70c1e5bf55bad637",
-        "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
-         "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
-        "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
-};
-
-
-/*
- * The data for curve3617 copied from:
- * http://safecurves.cr.yp.to/field.html
- * http://safecurves.cr.yp.to/base.html
- */
-static curveData curve3617 = {
-    "3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffef",  /* Prime */
-    "7ffffffffffffffffffffffffffffffffffffffffffffffffffeb3cc92414cf706022b36f1c0338ad63cf181b0e71a5e106af79",   /* order */
-    "",                                                                                                          /* SEED */
-    "",                                                                                                          /* c */
-    "",                                                                                                          /* b */
-    "1a334905141443300218c0631c326e5fcd46369f44c03ec7f57ff35498a4ab4d6d6ba111301a73faa8537c64c4fd3812f3cbc595",  /* Gx*/
-    "22",                                                                                                        /* Gy (radix 16) */
-};
-
-/*
- * The data for curve25519 copied from:
- * http://safecurves.cr.yp.to/field.html
- * http://safecurves.cr.yp.to/base.html
- * 
- * Note: 
- * The data for Curve25519 is here for the sake of completeness and to have the same
- * set of initialization. One exception if the base point X coordinate (Gx) that we use to
- * compute the DH public value, refer to function ecdhGeneratePublic(...) in ecdh.c.
- * 
- * Otherwise the functions use EcCurve structure only to get the pointers to the Curve25519
- * wrapper functions.
- * 
- */
-static curveData curve25519 = {
-    "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed",   /* Prime */
-    "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed",   /* order */
-    "",                                                                   /* SEED */
-    "",                                                                   /* c */
-    "",                                                                   /* b */
-    "9",                                                                  /* Gx */
-    "20ae19a1b8a086b4e01edd2c7748d14c923d4d7e6d7c61b229e9c5a27eced3d9",   /* Gy */
-};
-
-/*============================================================================*/
-/*    Bignum Shorthand Functions                                              */
-/*============================================================================*/
-
-int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
-{
-    bnAdd (rslt, n1);
-    if (bnCmp (rslt, mod) >= 0) {
-        bnSub (rslt, mod);
-    }
-    return 0;
-}
-
-int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
-{
-    bnAddQ (rslt, n1);
-    if (bnCmp (rslt, mod) >= 0) {
-        bnSub (rslt, mod);
-    }
-    return 0;
-}
-
-int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod)
-{
-    if (bnCmp (rslt, n1) < 0) {
-        bnAdd (rslt, mod);
-    }
-    bnSub (rslt, n1);
-    return 0;
-}
-
-int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod)
-{
-    if (bnCmpQ (rslt, n1) < 0) {
-        bnAdd (rslt, mod);
-    }
-    bnSubQ (rslt, n1);
-    return 0;
-}
-
-int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod, const EcCurve *curve)
-{
-    bnMul (rslt, n1, n2);
-    if (curve)
-        curve->modOp(rslt, rslt, mod);
-    else
-        bnMod(rslt, rslt, mod);
-    return 0;
-}
-
-int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod, const EcCurve *curve)
-{
-    bnMulQ (rslt, n1, n2);
-    if (curve)
-        curve->modOp(rslt, rslt, mod);
-    else
-        bnMod(rslt, rslt, mod);
-   return 0;
-}
-
-int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod, const EcCurve *curve)
-{
-    bnSquare (rslt, n1);
-    if (curve)
-        curve->modOp(rslt, rslt, mod);
-    else
-        bnMod(rslt, rslt, mod);
-    return 0;
-}
-
-/*
- * Note on the Curve25519 functions and usage of BigNumber:
- * In most cases the functions to compute Curve25519 data are small wrapper functions
- * that implement the same API as for the other curve functions. The wrapper functions
- * then call the very specific, high-efficient function in curve25519-donna.c .
- * 
- * For Curve25519 we don't have a real implementation for point add, point doubling, modulo
- * and check public key. Please refer to the actual implementations below.
- */
-
-static int ecGetAffineNist(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecGetAffineEd(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecGetAffine25519(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-static int ecDoublePointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecDoublePointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-static int ecDoublePoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-static int ecAddPointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-static int ecAddPointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-static int ecAddPoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-
-static int ecCheckPubKeyNist(const EcCurve *curve, const EcPoint *pub);
-static int ecCheckPubKey3617(const EcCurve *curve, const EcPoint *pub);
-static int ecCheckPubKey25519(const EcCurve *curve, const EcPoint *pub);
-
-static int ecGenerateRandomNumberNist(const EcCurve *curve, BigNum *d);
-static int ecGenerateRandomNumber3617(const EcCurve *curve, BigNum *d);
-static int ecGenerateRandomNumber25519(const EcCurve *curve, BigNum *d);
-
-static int ecMulPointScalarNormal(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-static int ecMulPointScalar25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-
-/* Forward declaration of new modulo functions for the EC curves */
-static int newMod192(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int newMod256(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int newMod384(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int newMod521(BigNum *r, const BigNum *a, const BigNum *modulo);
-
-static int mod3617(BigNum *r, const BigNum *a, const BigNum *modulo);
-static int mod25519(BigNum *r, const BigNum *a, const BigNum *modulo);
-
-static void commonInit()
-{
-    bnBegin(mpiZero); bnSetQ(mpiZero, 0);
-    bnBegin(mpiOne); bnSetQ(mpiOne, 1);
-    bnBegin(mpiTwo); bnSetQ(mpiTwo, 2);
-    bnBegin(mpiThree); bnSetQ(mpiThree, 3);
-    bnBegin(mpiFour); bnSetQ(mpiFour, 4);
-    bnBegin(mpiEight); bnSetQ(mpiEight, 8);
-}
-
-static void curveCommonInit(EcCurve *curve)
-{
-    /* Initialize scratchpad variables and their pointers */
-    bnBegin(&curve->_S1); curve->S1 = &curve->_S1;
-    bnBegin(&curve->_U1); curve->U1 = &curve->_U1;
-    bnBegin(&curve->_H);  curve->H = &curve->_H;
-    bnBegin(&curve->_R);  curve->R = &curve->_R;
-    bnBegin(&curve->_t0); curve->t0 = &curve->_t0;
-    bnBegin(&curve->_t1); curve->t1 = &curve->_t1;
-    bnBegin(&curve->_t2); curve->t2 = &curve->_t2;
-    bnBegin(&curve->_t3); curve->t3 = &curve->_t3;
-}
-
-static void curveCommonPrealloc(EcCurve *curve)
-{
-    size_t maxBits;
-
-    /* variables must be able to hold p^2, plus one nimb (min. 15 bits) for overflow */
-    maxBits = bnBits(curve->p) * 2 + 15;
-
-    /* The set_bit allocates enough memory to hold maximum values */
-    /* Initialize scratchpad variables before use */
-    bnPrealloc(curve->S1, maxBits);
-    bnPrealloc(curve->U1, maxBits);
-    bnPrealloc(curve->H, maxBits);
-    bnPrealloc(curve->R, maxBits);
-    bnPrealloc(curve->S1, maxBits);
-    bnPrealloc(curve->t1, maxBits);
-    bnPrealloc(curve->t2, maxBits);
-    bnPrealloc(curve->t3, maxBits);
-}
-
-int ecGetCurveNistECp(Curves curveId, EcCurve *curve)
-{
-    curveData *cd;
-
-    if (curveId >= Curve25519 && curveId <= Curve3617)
-        return ecGetCurvesCurve(curveId, curve);
-
-    if (!initialized) {
-        commonInit();
-        initialized = 1;
-    }
-    if (curve == NULL)
-        return -2;
-
-    bnBegin(&curve->_p);    curve->p = &curve->_p;
-    bnBegin(&curve->_n);    curve->n = &curve->_n;
-    bnBegin(&curve->_SEED); curve->SEED = &curve->_SEED;
-    bnBegin(&curve->_c);    curve->c = &curve->_c;
-    bnBegin(&curve->_a);    curve->a = &curve->_a;
-    bnBegin(&curve->_b);    curve->b = &curve->_b;
-    bnBegin(&curve->_Gx);   curve->Gx = &curve->_Gx;
-    bnBegin(&curve->_Gy);   curve->Gy = &curve->_Gy;
-
-    curveCommonInit(curve);
-
-    switch (curveId) {
-    case NIST192P:
-        cd = &nist192;
-        curve->modOp = newMod192;
-        break;
-
-    case NIST224P:
-        cd = &nist224;
-        curve->modOp = bnMod;
-        break;
-
-    case NIST256P:
-        cd = &nist256;
-        curve->modOp = bnMod;
-        break;
-
-    case NIST384P:
-        cd = &nist384;
-        curve->modOp = newMod384;
-        break;
-
-    case NIST521P:
-        cd = &nist521;
-        curve->modOp = newMod521;
-        break;
-
-    default:
-        return -2;
-    }
-
-    curve->affineOp = ecGetAffineNist;
-    curve->doubleOp = ecDoublePointNist;
-    curve->addOp = ecAddPointNist;
-    curve->checkPubOp = ecCheckPubKeyNist;
-    curve->randomOp = ecGenerateRandomNumberNist;
-    curve->mulScalar = ecMulPointScalarNormal;
-
-    bnReadAscii(curve->p, cd->p, 10);
-    bnReadAscii(curve->n, cd->n, 10);
-    bnReadAscii(curve->SEED, cd->SEED, 16);
-    bnReadAscii(curve->c, cd->c, 16);
-    bnCopy(curve->a, curve->p);
-    bnSub(curve->a, mpiThree);
-    bnReadAscii(curve->b, cd->b, 16);
-    bnReadAscii(curve->Gx, cd->Gx, 16);
-    bnReadAscii(curve->Gy, cd->Gy, 16);
-
-    curveCommonPrealloc(curve);
-    curve->id = curveId;
-
-    return 0;
-}
-
-int ecGetCurvesCurve(Curves curveId, EcCurve *curve)
-{
-    curveData *cd;
-
-    if (!initialized) {
-        commonInit();
-        initialized = 1;
-    }
-    if (curve == NULL)
-        return -2;
-
-    /* set-up all bignum structures, simplifies "free" handling */
-    bnBegin(&curve->_p);    curve->p = &curve->_p;
-    bnBegin(&curve->_n);    curve->n = &curve->_n;
-    bnBegin(&curve->_SEED); curve->SEED = &curve->_SEED;
-    bnBegin(&curve->_c);    curve->c = &curve->_c;
-    bnBegin(&curve->_a);    curve->a = &curve->_a;
-    bnBegin(&curve->_b);    curve->b = &curve->_b;
-    bnBegin(&curve->_Gx);   curve->Gx = &curve->_Gx;
-    bnBegin(&curve->_Gy);   curve->Gy = &curve->_Gy;
-
-    curveCommonInit(curve);
-
-    switch (curveId) {
-    case Curve3617:
-        cd = &curve3617;
-        curve->modOp = mod3617;
-        curve->affineOp = ecGetAffineEd;
-        curve->doubleOp = ecDoublePointEd;
-        curve->addOp = ecAddPointEd;
-        curve->checkPubOp = ecCheckPubKey3617;
-        curve->randomOp = ecGenerateRandomNumber3617;
-        curve->mulScalar = ecMulPointScalarNormal;
-
-        bnReadAscii(curve->a, "3617", 10);
-        break;
-
-    case Curve25519:
-        cd = &curve25519;
-        curve->modOp = mod25519;
-        curve->affineOp = ecGetAffine25519;
-        curve->doubleOp = ecDoublePoint25519;
-        curve->addOp = ecAddPoint25519;
-        curve->checkPubOp = ecCheckPubKey25519;
-        curve->randomOp = ecGenerateRandomNumber25519;
-        curve->mulScalar = ecMulPointScalar25519;
-
-        bnReadAscii(curve->a, "486662", 10);
-        break;
-
-    default:
-        return -2;
-    }
-    bnReadAscii(curve->p, cd->p, 16);
-    bnReadAscii(curve->n, cd->n, 16);
-
-    bnReadAscii(curve->Gx, cd->Gx, 16);
-    bnReadAscii(curve->Gy, cd->Gy, 16);
-
-    curveCommonPrealloc(curve);
-    curve->id = curveId;
-    return 0;
-}
-
-void ecFreeCurveNistECp(EcCurve *curve) 
-{
-    if (curve == NULL)
-        return;
-
-    bnEnd(curve->p);
-    bnEnd(curve->n);
-    bnEnd(curve->SEED);
-    bnEnd(curve->c);
-    bnEnd(curve->b);
-    bnEnd(curve->Gx);
-    bnEnd(curve->Gy);
-
-    bnEnd(curve->S1);
-    bnEnd(curve->U1);
-    bnEnd(curve->H);
-    bnEnd(curve->R);
-    bnEnd(curve->t0);
-    bnEnd(curve->t1);
-    bnEnd(curve->t2);
-    bnEnd(curve->t3);
-}
-
-/*
- * EC point helper functions
- */
-
-void ecInitPoint(EcPoint *P)
-{
-    INIT_EC_POINT(P);
-}
-
-void ecFreePoint(EcPoint *P)
-{
-    FREE_EC_POINT(P);
-}
-
-void ecSetBasePoint(EcCurve *C, EcPoint *P)
-{
-    SET_EC_BASE_POINT(C, P);
-}
-
-void ecFreeCurvesCurve(EcCurve *curve)
-{
-    ecFreeCurveNistECp(curve);
-}
-
-/*============================================================================*/
-/*    Elliptic Curve arithmetic                                               */
-/*============================================================================*/
-
-int ecGetAffine(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    return curve->affineOp(curve, R, P);
-}
-
-static int ecGetAffineNist(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    int ret = 0;
-
-    struct BigNum z_1, z_2;
-
-    bnBegin(&z_1);
-    bnBegin(&z_2);
-
-    /* affine x = X / Z^2 */
-    bnInv (&z_1, P->z, curve->p);                 /* z_1 = Z^(-1) */
-    bnMulMod_(&z_2, &z_1, &z_1, curve->p, curve); /* z_2 = Z^(-2) */
-    bnMulMod_(R->x, P->x, &z_2, curve->p, curve);
-
-    /* affine y = Y / Z^3 */
-    bnMulMod_(&z_2, &z_2, &z_1, curve->p, curve); /* z_2 = Z^(-3) */
-    bnMulMod_(R->y, P->y, &z_2, curve->p, curve);
-
-    bnSetQ(R->z, 1);
-
-    bnEnd(&z_1);
-    bnEnd(&z_2);
-    return ret;
-}
-
-static int ecGetAffineEd(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    int ret = 0;
-
-    struct BigNum z_1;
-
-    bnBegin(&z_1);
-
-    /* affine x = X / Z */
-    bnInv (&z_1, P->z, curve->p);                 /* z_1 = Z^(-1) */
-    bnMulMod_(R->x, P->x, &z_1, curve->p, curve);
-
-    /* affine y = Y / Z */
-    bnMulMod_(R->y, P->y, &z_1, curve->p, curve);
-
-    bnSetQ(R->z, 1);
-
-    bnEnd(&z_1);
-    return ret;
-
-}
-
-/* 
- * If the arguments do not point to the same EcPoint then copy P to result.
- * Curve25519 has no specific GetAffine function, it's all inside curve25519-donna
- */
-static int ecGetAffine25519(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    if (R != P) {
-        bnCopy(R->x, P->x);
-        bnCopy(R->y, P->y);
-        bnCopy(R->z, P->z);
-    }
-    return 0;
-}
-
-int ecDoublePoint(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    return curve->doubleOp(curve, R, P);
-}
-
-static int ecDoublePointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    int ret = 0;
-
-    EcPoint tP;
-    const EcPoint *ptP = 0;
-
-    if (!bnCmp(P->y, mpiZero) || !bnCmp(P->z, mpiZero)) {
-        bnSetQ(R->x, 1);
-        bnSetQ(R->y, 1);
-        bnSetQ(R->z, 0);
-        return 0;
-    }
-
-    /* Check for overlapping arguments, copy if necessary and set pointer */
-    if (P == R) {
-        INIT_EC_POINT(&tP);
-        ptP = &tP;
-        bnCopy(tP.x, P->x);
-        bnCopy(tP.y, P->y);
-        bnCopy(tP.z, P->z);
-    }
-    else 
-        ptP = P;
-
-    /* S = 4*X*Y^2, save Y^2 in t1 for later use */
-    bnMulMod_(curve->t1, ptP->y, ptP->y, curve->p, curve);       /* t1 = Y^2 */
-    bnMulMod_(curve->t0, ptP->x, mpiFour, curve->p, curve);      /* t0 = 4 * X */
-    bnMulMod_(curve->S1, curve->t0, curve->t1, curve->p, curve); /* S1 = t0 * t1 */
-
-    /* M = 3*(X + Z^2)*(X - Z^2), use scratch variable U1 to store M value */
-    bnMulMod_(curve->t2, ptP->z, ptP->z, curve->p, curve);       /* t2 = Z^2 */
-    bnCopy(curve->t0, ptP->x);
-    bnAddMod_(curve->t0, curve->t2, curve->p);                   /* t0 = X + t2  */
-    bnMulMod_(curve->t3, curve->t0, mpiThree, curve->p, curve);  /* t3 = 3 * t0 */
-    bnCopy(curve->t0, ptP->x);
-    bnSubMod_(curve->t0, curve->t2, curve->p);                   /* t0 = X - t2 */
-    bnMulMod_(curve->U1, curve->t3, curve->t0, curve->p, curve); /* M = t3 * t0 */
-    
-    /* X' = M^2 - 2*S */
-    bnMulMod_(curve->t2, curve->U1, curve->U1, curve->p, curve); /* t2 = M^2 */
-    bnMulMod_(curve->t0, curve->S1, mpiTwo, curve->p, curve);    /* t0 = S * 2 */
-    bnCopy(R->x, curve->t2);
-    bnSubMod_(R->x, curve->t0, curve->p);                        /* X' = t2 - t0 */
-
-    /* Y' = M*(S - X') - 8*Y^4 */
-    bnMulMod_(curve->t3, curve->t1, curve->t1, curve->p, curve); /* t3 = Y^4 (t1 saved above) */
-    bnMulMod_(curve->t2, curve->t3, mpiEight, curve->p, curve);  /* t2 = t3 * 8 */
-    bnCopy(curve->t3, curve->S1);
-    bnSubMod_(curve->t3, R->x, curve->p);                        /* t3 = S - X' */
-    bnMulMod_(curve->t0, curve->U1, curve->t3, curve->p, curve); /* t0 = M * t3 */
-    bnCopy(R->y, curve->t0);
-    bnSubMod_(R->y, curve->t2, curve->p);                        /* Y' = t0 - t2 */
-
-    /* Z' = 2*Y*Z */
-    bnMulMod_(curve->t0, ptP->y, mpiTwo, curve->p, curve);       /* t0 = 2 * Y */
-    bnMulMod_(R->z, curve->t0, ptP->z, curve->p, curve);         /* Z' = to * Z */
-
-    if (P == R)
-        FREE_EC_POINT(&tP);
-
-    return ret;
-}
-
-static int ecDoublePointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    EcPoint tP;
-    const EcPoint *ptP = 0;
-
-    /* Check for overlapping arguments, copy if necessary and set pointer */
-    if (P == R) {
-        INIT_EC_POINT(&tP);
-        ptP = &tP;
-        bnCopy(tP.x, P->x);
-        bnCopy(tP.y, P->y);
-        bnCopy(tP.z, P->z);
-    }
-    else 
-        ptP = P;
-
-    /* Compute B, C, D, H, E */
-    bnCopy(curve->t1, ptP->x);
-    bnAddMod_(curve->t1, ptP->y, curve->p);
-    bnSquareMod_(curve->t0, curve->t1, curve->p, curve);       /* t0 -> B */
-
-    bnSquareMod_(R->x, ptP->x, curve->p, curve);               /* Rx -> C */
-
-    bnSquareMod_(R->y, ptP->y, curve->p, curve);               /* Ry -> D */
-
-    bnSquareMod_(R->z, ptP->z, curve->p, curve);               /* Rz -> H */
-    bnAddMod_(R->z, R->z, curve->p);                           /* Rz -> 2H */
-
-    bnCopy(curve->t1, R->x);
-    bnAddMod_(curve->t1, R->y, curve->p);                      /* t1 -> E */
-
-    /* Compute Ry */
-    bnCopy(curve->t2, R->x);
-    bnSubMod_(curve->t2, R->y, curve->p);                      /* C - D */
-    bnMulMod_(R->y, curve->t1, curve->t2, curve->p, curve);    /* E * t3; Ry */
-
-    /* Compute Rx */
-    bnSubMod_(curve->t0, curve->t1, curve->p);                 /* B - E; sub result */
-    bnCopy(curve->t2, curve->t1);
-    bnSubMod_(curve->t2, R->z, curve->p);                      /* t2 -> J; (E - 2H) */
-    bnMulMod_(R->x, curve->t2, curve->t0, curve->p, curve);    /* J * t0 */
-
-    /* Compute Rz */
-    bnMulMod_(R->z, curve->t2, curve->t1, curve->p, curve);    /* J * E */
-
-    if (P == R)
-        FREE_EC_POINT(&tP);
-
-    return 0;
-}
-
-/* 
- * Curve25519 has no specific Double Point function, all inside curve25519-donna
- */
-static int ecDoublePoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P)
-{
-    return -2;
-}
-
-/* Add two elliptic curve points. Any of them may be the same object. */
-int ecAddPoint(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
-    return curve->addOp(curve, R, P, Q);
-}
-
-static int ecAddPointNist(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
-    int ret = 0;
-
-    EcPoint tP, tQ;
-    const EcPoint *ptP = 0;
-    const EcPoint *ptQ = 0;
-
-
-    /* Fast check if application called add(R, P, P) */
-    if (!bnCmp(P->x, Q->x) && !bnCmp(P->y, Q->y) && !bnCmp(P->z, Q->z)) {
-        return ecDoublePoint(curve, R, P);
-    }
-
-    /* if P is (@,@), R = Q */
-    if (!bnCmp(P->z, mpiZero)) {
-        bnCopy(R->x, Q->x);
-        bnCopy(R->y, Q->y);
-        bnCopy(R->z, Q->z);
-        return 0;
-    }
-
-    /* if Q is (@,@), R = P */
-    if (!bnCmp(Q->z, mpiZero)) {
-        bnCopy(R->x, P->x);
-        bnCopy(R->y, P->y);
-        bnCopy(R->z, P->z);
-        return 0;
-    }
-
-    /* Check for overlapping arguments, copy if necessary and set pointers */
-    if (P == R) {
-        INIT_EC_POINT(&tP);
-        ptP = &tP;
-        bnCopy(tP.x, P->x);
-        bnCopy(tP.y, P->y);
-        bnCopy(tP.z, P->z);
-    }
-    else 
-        ptP = P;
-
-    if (Q == R) {
-        INIT_EC_POINT(&tQ);
-        ptQ = &tQ;
-        bnCopy(tQ.x, Q->x);
-        bnCopy(tQ.y, Q->y);
-        bnCopy(tQ.z, Q->z);
-    }
-    else
-        ptQ = Q;
-
-    /* U1 = X1*Z2^2, where X1: P->x, Z2: Q->z */
-    bnMulMod_(curve->t1, ptQ->z, ptQ->z, curve->p, curve);    /* t1 = Z2^2 */
-    bnMulMod_(curve->U1, ptP->x, curve->t1, curve->p, curve); /* U1 = X1 * z_2 */
-
-    /* S1 = Y1*Z2^3, where Y1: P->y */
-    bnMulMod_(curve->t1, curve->t1, ptQ->z, curve->p, curve); /* t1 = Z2^3 */
-    bnMulMod_(curve->S1, ptP->y, curve->t1, curve->p, curve); /* S1 = Y1 * z_2 */
-
-    /* U2 = X2*Z1^2, where X2: Q->x, Z1: P->z */
-    bnMulMod_(curve->t1, ptP->z, ptP->z, curve->p, curve);    /* t1 = Z1^2 */
-    bnMulMod_(curve->H, ptQ->x, curve->t1, curve->p, curve);  /* H = X2 * t1 (store U2 in H) */
-
-    /* H = U2 - U1 */
-    bnSubMod_(curve->H, curve->U1, curve->p);
-
-    /* S2 = Y2*Z1^3, where Y2: Q->y */
-    bnMulMod_(curve->t1, curve->t1, ptP->z, curve->p, curve); /* t1 = Z1^3 */
-    bnMulMod_(curve->R, ptQ->y, curve->t1, curve->p, curve);  /* R = Y2 * t1 (store S2 in R) */
-
-    /* R = S2 - S1 */
-    bnSubMod_(curve->R, curve->S1, curve->p);
-
-    /* if (U1 == U2), i.e H is zero */
-    if (!bnCmp(curve->H, mpiZero)) {
-
-        /* if (S1 != S2), i.e. R is _not_ zero: return infinity*/
-        if (bnCmp(curve->R, mpiZero)) {
-            bnSetQ(R->x, 1);
-            bnSetQ(R->y, 1);
-            bnSetQ(R->z, 0);
-            return 0;
-        }
-        return ecDoublePoint(curve, R, P);
-    }
-    /* X3 = R^2 - H^3 - 2*U1*H^2, where X3: R->x */
-    bnMulMod_(curve->t0, curve->H, curve->H, curve->p, curve);   /* t0 = H^2 */
-    bnMulMod_(curve->t1, curve->U1, curve->t0, curve->p, curve); /* t1 = U1 * t0, (hold t1) */
-    bnMulMod_(curve->t0, curve->t0, curve->H, curve->p, curve);  /* t0 = H^3, (hold t0) */
-    bnMulMod_(curve->t2, curve->R, curve->R, curve->p, curve);   /* t2 = R^2 */
-    bnCopy(curve->t3, curve->t2);
-    bnSubMod_(curve->t3, curve->t0, curve->p);                   /* t3 = t2 - t0, (-H^3)*/
-    bnMulMod_(curve->t2, mpiTwo, curve->t1, curve->p, curve);    /* t2 = 2 * t1 */
-    bnCopy(R->x, curve->t3);
-    bnSubMod_(R->x, curve->t2, curve->p);                        /* X3 = t3 - t2 */
-
-    /* Y3 = R*(U1*H^2 - X3) - S1*H^3, where Y3: R->y */
-    bnSubMod_(curve->t1, R->x, curve->p);                        /* t1 = t1 - X3, overwrites t1 now */
-    bnMulMod_(curve->t2, curve->R, curve->t1, curve->p, curve);  /* t2 = R * z_2 */
-    bnMulMod_(curve->S1, curve->S1, curve->t0, curve->p, curve); /* S1 = S1 * t0, (t0 has H^3) */
-    bnCopy(R->y, curve->t2);
-    bnSubMod_(R->y, curve->S1, curve->p);                        /* Y3 = t2 - S1 */
-
-    /* Z3 = H*Z1*Z2, where Z1: P->z, Z2: Q->z, Z3: R->z */
-    bnMulMod_(curve->t2, curve->H, P->z, curve->p, curve);       /* t2 = H * Z1 */
-    bnMulMod_(R->z, curve->t2, Q->z, curve->p, curve);           /* Z3 = t2 * Z2 */
-
-    if (P == R)
-        FREE_EC_POINT(&tP);
-    if (Q == R)
-        FREE_EC_POINT(&tQ);
-    return ret;
-}
-
-/*
- * Refer to the document: Faster addition and doubling on elliptic curves; Daniel J. Bernstein and Tanja Lange
- * section 4.
- *
- * This function is a variant of the 'addition'. The function returns the result in an own curve point
- * and does not overwrite its input parameters.
- */
-static int ecAddPointEd(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
-    EcPoint tP, tQ;
-    const EcPoint *ptP = 0;
-    const EcPoint *ptQ = 0;
-
-    /* if P is (@,@), R = Q */
-    if (!bnCmp(P->z, mpiZero)) {
-        bnCopy(R->x, Q->x);
-        bnCopy(R->y, Q->y);
-        bnCopy(R->z, Q->z);
-        return 0;
-    }
-
-    /* if Q is (@,@), R = P */
-    if (!bnCmp(Q->z, mpiZero)) {
-        bnCopy(R->x, P->x);
-        bnCopy(R->y, P->y);
-        bnCopy(R->z, P->z);
-        return 0;
-    }
-
-    /* Check for overlapping arguments, copy if necessary and set pointers */
-    if (P == R) {
-        INIT_EC_POINT(&tP);
-        ptP = &tP;
-        bnCopy(tP.x, P->x);
-        bnCopy(tP.y, P->y);
-        bnCopy(tP.z, P->z);
-    }
-    else 
-        ptP = P;
-
-    if (Q == R) {
-        INIT_EC_POINT(&tQ);
-        ptQ = &tQ;
-        bnCopy(tQ.x, Q->x);
-        bnCopy(tQ.y, Q->y);
-        bnCopy(tQ.z, Q->z);
-    }
-    else
-        ptQ = Q;
-
-    /* Compute A, C, D first */
-    bnMulMod_(R->z, ptP->z, ptQ->z, curve->p, curve);            /* Rz -> A; (Z1 * z2); Rz becomes R3 */
-    bnMulMod_(R->x, ptP->x, ptQ->x, curve->p, curve);            /* Rx -> C; (X1 * X2); Rx becomes R1 */
-    bnMulMod_(R->y, ptP->y, ptQ->y, curve->p, curve);            /* Ry -> D; (Y1 * Y2); Ry becomes R2 */
-
-    /* Compute large parts of X3 equation, sub result in t0 */
-    bnCopy(curve->t0, ptP->x);
-    bnAddMod_(curve->t0, ptP->y, curve->p);                      /* t0 -> X1 + Y1 */
-    bnCopy(curve->t1, ptQ->x);
-    bnAddMod_(curve->t1, ptQ->y, curve->p);                      /* t1 -> X2 + Y2 */
-    bnMulMod_(curve->t2, curve->t0, curve->t1, curve->p, curve); /* t2 = t0 * t1 */
-    bnSubMod_(curve->t2, R->x, curve->p);                        /* t2 - C */
-    bnSubMod_(curve->t2, R->y, curve->p);                        /* t2 - D */
-    bnMulMod_(curve->t0, curve->t2, R->z, curve->p, curve);      /* t0 -> R7; (t2 * A); sub result */
-
-    /* Compute E */
-    bnMulMod_(curve->t2, R->x, R->y, curve->p, curve);           /* t2 = C * D */
-    bnMulMod_(curve->t1, curve->t2, curve->a, curve->p, curve);  /* t1 -> E; t1 new R8 */
-
-    /* Compute part of Y3 equation, sub result in t2 */
-    bnSubMod_(R->y, R->x, curve->p);                             /* Ry = D - C; sub result */
-    bnMulMod_(curve->t2, R->y, R->z, curve->p, curve);           /* t2 = Ry * A; sub result */
-
-    /* Compute B */
-    bnSquareMod_(R->z, R->z, curve->p, curve);                   /* Rz -> B; (A^2) */
-
-    /* Compute F */
-    bnCopy(curve->t3, R->z);
-    bnSubMod_(curve->t3, curve->t1, curve->p);                   /* t3 -> F; (B - E) */
-
-    /* Compute G */
-    bnAddMod_(R->z, curve->t1, curve->p);                        /* Rz -> G; (B + E) */
-
-    /* Compute, X, Y, Z results */
-    bnMulMod_(R->x, curve->t3, curve->t0, curve->p, curve);      /* Rx = F * t0 */
-    bnMulMod_(R->y, curve->t2, R->z, curve->p, curve);           /* Ry = t2 * G */
-    bnMulMod_(R->z, curve->t3, R->z, curve->p, curve);           /* Rz = F * G */
-
-    if (P == R)
-        FREE_EC_POINT(&tP);
-    if (Q == R)
-        FREE_EC_POINT(&tQ);
-
-    return 0;
-}
-
-/* 
- * Curve25519 has no specific Add Point function, all inside curve25519-donna
- */
-static int ecAddPoint25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q)
-{
-    return -2;
-}
-
-int ecMulPointScalar(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar)
-{
-    return curve->mulScalar(curve, R, P, scalar);
-}
-
-static int ecMulPointScalarNormal(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar)
-{
-    int ret = 0;
-    int i;
-    int bits = bnBits(scalar);
-    EcPoint n;
-
-    INIT_EC_POINT(&n);
-    bnCopy(n.x, P->x);
-    bnCopy(n.y, P->y);
-    bnCopy(n.z, P->z);
-
-    bnSetQ(R->x, 0);
-    bnSetQ(R->y, 0);
-    bnSetQ(R->z, 0);
-
-    for (i = 0; i < bits; i++) {
-        if (bnReadBit(scalar, i))
-            ecAddPoint(curve, R, R, &n);
-
-        /*        ecAddPoint(curve, &n, &n, &n); */
-        ecDoublePoint(curve, &n, &n);
-    }
-    FREE_EC_POINT(&n);
-    return ret;
-}
-
-/* 
- * This function uses BigNumber only as containers to transport the 32 byte data.
- * This makes it compliant to the other functions and thus higher-level API does not change.
- * 
- * curve25519_donna function uses data in little endian format.
- */
-static int ecMulPointScalar25519(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar)
-{
-    uint8_t basepoint[32], secret[32], result[32];
-
-    bnExtractLittleBytes(P->x, basepoint, 0, 32);  /* 25519 function requires the X coordinate only (compressed) */
-    bnExtractLittleBytes(scalar, secret, 0, 32);
-    curve25519_donna(result, secret, basepoint);
-    bnInsertLittleBytes(R->x, result, 0, 32);
-    return 0;
-}
-
-#ifdef WEAKRANDOM
-#include <fcntl.h>
-
-/*
- * A standard random number generator that uses the portable random() system function.
- *
- * This should be enhanced to use a better random generator
- */
-static int _random(unsigned char *output, size_t len)
-{
-    size_t num = 0;
-
-    int rnd = open("/dev/urandom", O_RDONLY);
-    if (rnd >= 0) {
-        num = read(rnd, output, len);
-        close(rnd);
-    }
-    else
-        return num;
-
-    return( 0 );
-}
-#else
-#include <cryptcommon/ZrtpRandom.h>
-static int _random(unsigned char *output, size_t len)
-{
-    return zrtp_getRandomData(output, len);
-}
-#endif
-
-int ecGenerateRandomNumber(const EcCurve *curve, BigNum *d)
-{
-    return curve->randomOp(curve, d);
-}
-
-static int ecGenerateRandomNumberNist(const EcCurve *curve, BigNum *d)
-{
-    BigNum c, nMinusOne;
-
-    size_t randomBytes = ((bnBits(curve->n) + 64) + 7) / 8;
-
-    uint8_t *ran = malloc(randomBytes);
-
-    bnBegin(&c);
-    bnBegin(&nMinusOne);
-
-    bnCopy(&nMinusOne, curve->n);
-    bnSubMod_(&nMinusOne, mpiOne, curve->p);
-
-    bnSetQ(d, 0);
-
-    while (!bnCmpQ(d, 0)) {
-        /* use _random function */
-        _random(ran, randomBytes);
-        bnInsertBigBytes(&c, ran, 0, randomBytes);
-        bnMod(d, &c, &nMinusOne);
-        bnAddMod_(d, mpiOne, curve->p);
-    }
-
-    bnEnd(&c);
-    bnEnd(&nMinusOne);
-    free(ran);
-
-    return 0;
-}
-
-static int ecGenerateRandomNumber3617(const EcCurve *curve, BigNum *d)
-{
-    unsigned char random[52];
-    _random(random, 52);
-
-    /* prepare the secret random data: clear bottom 3 bits. Clearing top 2 bits
-     * makes is a 414 bit value
-     */
-    random[51] &= ~0x7;
-    random[0] &= 0x3f;
-    /* convert the random data into big numbers */
-    bnInsertBigBytes(d, random, 0, 52);
-    return 0;
-}
-
-static int ecGenerateRandomNumber25519(const EcCurve *curve, BigNum *d)
-{
-    unsigned char random[32];
-    _random(random, 32);
-
-    /* No specific preparation. The curve25519_donna functions prepares the data.
-     *
-     * convert the random data into big numbers. the bigNumber is a container only.
-     * we don not use the big number for any arithmetic
-     */
-    bnInsertLittleBytes(d, random, 0, 32);
-    return 0;
-
-}
-
-int ecCheckPubKey(const EcCurve *curve, const EcPoint *pub)
-{
-    return curve->checkPubOp(curve, pub);
-}
-
-static int ecCheckPubKeyNist(const NistECpCurve *curve, const EcPoint *pub)
-{
-    /* Represent point at infinity by (0, 0), make sure it's not that */
-    if (bnCmpQ(pub->x, 0) == 0 && bnCmpQ(pub->y, 0) == 0) {
-        return 0;
-    }
-    /* Check that coordinates are within range */
-    if (bnCmpQ(pub->x, 0) < 0 || bnCmp(pub->x, curve->p) >= 0) {
-        return 0;
-    }
-    if (bnCmpQ(pub->y, 0) < 0 || bnCmp(pub->y, curve->p) >= 0) {
-        return 0;
-    }
-    /* Check that point satisfies EC equation y^2 = x^3 - 3x + b, mod P */
-    bnSquareMod_(curve->t1, pub->y, curve->p, curve);
-    bnSquareMod_(curve->t2, pub->x, curve->p, curve);
-    bnSubQMod_(curve->t2, 3, curve->p);
-    bnMulMod_(curve->t2, curve->t2, pub->x, curve->p, curve);
-    bnAddMod_(curve->t2, curve->b, curve->p);
-    if (bnCmp (curve->t1, curve->t2) != 0) {
-        return 0;
-    }
-    return 1;
-
-}
-
-static int ecCheckPubKey3617(const EcCurve *curve, const EcPoint *pub)
-{
-    /* Represent point at infinity by (0, 0), make sure it's not that */
-    if (bnCmpQ(pub->x, 0) == 0 && bnCmpQ(pub->y, 0) == 0) {
-        return 0;
-    }
-    /* Check that coordinates are within range */
-    if (bnCmpQ(pub->x, 0) < 0 || bnCmp(pub->x, curve->p) >= 0) {
-        return 0;
-    }
-    if (bnCmpQ(pub->y, 0) < 0 || bnCmp(pub->y, curve->p) >= 0) {
-        return 0;
-    }
-    /* Check that point satisfies EC equation x^2+y^2 = 1+3617x^2y^2, mod P */
-    bnSquareMod_(curve->t1, pub->y, curve->p, curve);
-    bnSquareMod_(curve->t2, pub->x, curve->p, curve);
-    bnCopy(curve->t3, curve->t1);                                /* Load t3 */
-    bnAddMod_(curve->t3, curve->t2, curve->p);                   /* t3 = t1 + t2, (x^2+y^2)*/
-
-    bnMulMod_(curve->t0, curve->a, curve->t1, curve->p, curve);  /* t0 = a * t1,  (3617 * x^2) */
-    bnMulMod_(curve->t0, curve->t0, curve->t2, curve->p, curve); /* t0 = t0 * t1, (3617 * x^2 * y^2) */
-    bnAddMod_(curve->t0, mpiOne, curve->p);                      /* t0 = t0 + 1,  (3617 * x^2 * y^2 + 1) */
-
-    if (bnCmp (curve->t0, curve->t3) != 0) {
-        return 0;
-    }
-    return 1;
-}
-
-/**
- * According to http://cr.yp.to/ecdh.html#validate no validation is required if used for Diffie-Hellman
- * thus always return success.
- */
-static int ecCheckPubKey25519(const EcCurve *curve, const EcPoint *pub)
-{
-    return 1;
-}
-
-static int mod3617(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
-    unsigned char buffer[52] = {0};
-    int cmp;
-    BigNum tmp;
-
-    bnBegin(&tmp);
-    cmp = bnCmp(modulo, a);
-    if (cmp == 0) {             /* a is equal modulo, set resul to zero */
-        bnSetQ(r, 0);
-        return 0;
-    }
-    if (cmp > 0) {              /* modulo is greater than a - copy a to r and return it */
-        bnCopy(r, a);
-        return 0;
-    }
-    bnExtractLittleBytes(a, buffer, 0, 52);
-    buffer[51] &= 0x3f;
-
-    bnCopy(&tmp, a);
-    bnRShift(&tmp, 414);
-    bnCopy(r, &tmp);
-    bnLShift(r, 4);
-    bnAdd(r, &tmp);
-
-    bnInsertLittleBytes(&tmp, buffer, 0, 52);
-
-    bnAdd(r, &tmp);
-    while (bnCmp(r, modulo) >= 0) {
-        bnSub(r, modulo);
-    }
-    bnEnd(&tmp);
-    return 0;
-}
-
-/* 
- * Curve25519 has no specific modulo function, all inside curve25519-donna
- */
-static int mod25519(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
-    return -2;
-}
-
-/*
- * Beware: Here are the dragons.
- *
- * The modulo implementations for the NIST curves. For more detailled information see
- * FIPS 186-3, chapter D.2 and other papers about Generailzed Mersenne numbers.
- *
- * I use byte operations to perfom the additions with carry. On a little endian machine
- * this saves conversion from/to big endian format if I would use integers for example. Also
- * using byte addition into a short carry accumulator works on every word size and avoids
- * complex testing and handling of wordsizes and big/little endian stuff.
- *
- */
-
-/* new modulo for 192bit curve */
-static int newMod192(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
-    unsigned char buffer[200] = {0};
-    unsigned char *pt;
-    unsigned char *ps1;
-    unsigned char *ps2;
-    unsigned char *ps3;
-    short ac;
-    int cmp;
-
-    /* Binary big number representation in PolarSSL is always big endian
-     *
-     * the least significant 64bit large word starts at byte offset 40,
-     * the least significant 32bit word starts at byte offset 44
-     * the least significant byte starts at byte offset 47
-     *
-     *           S3    S2   S1          T
-     *                            /-----^------\
-     *           A5    A4   A3    A2    A1    A0
-     * 64bit  0     1     2     3     4     5
-     *        |--+--|--+--|--+--|--+--|--+--|--+--|
-     * 32bit  0  1  2  3  4  5  6  7  8  9 10 11
-     *
-     * perform T + S1 + S2 + S3 mod p
-
-     * where T  = (A2 || A1 || A0)
-     *     + S1 = ( 0 || A3 || A3)
-     *     + S2 = (A4 || A4 ||  0)
-     *     + S3 = (A5 || A5 || A5)
-     *
-     * TODO: error check if input variable is > modulo^2 (do normal mpi_mod_mpi),
-     */
-
-    /* TODO: check if a is > modulo^2 */
-    cmp = bnCmp(modulo, a);
-    if (cmp == 0) {             /* a is equal modulo, set resul to zero */
-        bnSetQ(r, 0);
-        return 0;
-    }
-    if (cmp > 0) {              /* modulo is greater than a - copy a to r and return it */
-        bnCopy(r, a);
-        return 0;
-    }
-    bnExtractBigBytes(a, buffer, 0, bnBytes(modulo)*2);
-
-    /* 6 'A' words, each word is 8 byte. Compute offset to least significant byte of word X */
-#define A(X) buffer + (((6-X)*8)-1)
-
-    ac = 0;
-
-    pt = A(0);      /* pt points to least significant byte of A0  */
-
-    /* Add up first 8 byte word, no need to add ps2 */
-    ps1 = A(3);        /* ps1 points to least significant byte of S1 (A3) */
-    ps3 = A(5);        /* ps3 points to least significant byte of S3 (A5)*/
-
-    /* Each block processes one 32 bit word, big endian, using byte operations */
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
-    /* Add up second 8 byte word, all three S words are used here */
-    ps1 = A(3); ps2 = A(4); ps3 = A(5);
-
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1--; ac += *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
-    /* Add up third 8 byte word, no need to add S1 word */
-    ps2 = A(4); ps3 = A(5);
-
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; *pt-- = ac; ac >>= 8;
-
-    /* In this function we cannot have a negative carry and at most a carry of 2
-     * thus just subtract the modulo until we are less than modulo
-     */
-    bnSetQ(r, 0);
-
-    *(A(3)) = ac;      /* Store the carry */
-    bnInsertBigBytes(r, A(3), 0, 25);  /* 25: 3 * 8 byte words + 1 carry byte */
-    while (bnCmp(r, modulo) >= 0) {
-        bnSub(r, modulo);
-    }
-    return 0;
-}
-#undef A
-
-/* new modulo for 256bit curve */
-static int newMod256(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
-    unsigned char buffer[200] = {0};
-    unsigned char *pt;
-    unsigned char *ps1;
-    unsigned char *ps2;
-    unsigned char *ps3;
-    unsigned char *ps4;
-
-    unsigned char *pd1;
-    unsigned char *pd2;
-    unsigned char *pd3;
-    unsigned char *pd4;
-    short ac;
-    int cmp;
-
-    /* Binary big number representation in PolarSSL is always big endian
-     *
-     * the least significant byte starts at byte offset 63
-     *
-     *                                                                    T
-     *                                                  /-----------------^------------------\
-     *          A15  A14  A13  A12  A11  A10  A9   A8   A7   A6   A5   A4   A3   A2   A1   A0
-     *        |----+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|
-     * offset 0    4    8   12   16   20   24   28   32   36   40   44   48   52   56   60    64
-     *
-     * T  = (  A7 ||  A6 ||  A5 ||  A4 ||  A3 ||  A2 ||  A1 ||  A0 )
-     *
-     * S1 = ( A15 || A14 || A13 || A12 || A11 ||  00 ||  00 ||  00 )
-     * S2 = (  00 || A15 || A14 || A13 || A12 ||  00 ||  00 ||  00 )
-     * S3 = ( A15 || A14 ||  00 ||  00 ||  00 || A10 ||  A9 ||  A8 )
-     * S4 = (  A8 || A13 || A15 || A14 || A13 || A11 || A10 ||  A9 )
-     * D1 = ( A10 ||  A8 ||  00 ||  00 ||  00 || A13 || A12 || A11 )
-     * D2 = ( A11 ||  A9 ||  00 ||  00 || A15 || A14 || A13 || A12 )
-     * D3 = ( A12 ||  00 || A10 ||  A9 ||  A8 || A15 || A14 || A13 )
-     * D4 = ( A13 ||  00 || A11 || A10 ||  A9 ||  00 || A15 || A14 )
-     *
-     * perform B = T + 2*S1 + 2*S2 + S3 + S4 - D1 - D2 - D3 - D4 mod p
-     *
-     * TODO: error check if input variable is > modulo^2 (do normal mpi_mod_mpi),
-     */
-
-    cmp = bnCmp(modulo, a);
-    if (cmp == 0) {             /* a is equal modulo, set resul to zero */
-        bnSetQ(r, 0);
-        return 0;
-    }
-    if (cmp > 0) {              /* modulo is greater than a - copya to r and return it */
-        bnCopy(r, a);
-        return 0;
-    }
-    bnExtractBigBytes(a, buffer, 0, bnBytes(modulo)*2);
-
-    /* 16 'A' words, each word is 4 byte. Compute offset to least significant byte of word X */
-#define A(X) buffer + (((16-X)*4)-1)
-
-    ac = 0;
-
-    pt = A(0);          /* pt points to least significant byte of A0  */
-
-    /* Set up to add up data that goes into A0 (right-most column abover); S1, S2 not used */
-    ps3 = A(8);         /* ps3 points to least significant byte of S3 */
-    ps4 = A(9);         /* ps4 points to least significant byte of S4 */
-    pd1 = A(11);        /* pd1 points to least significant byte of D1 */
-    pd2 = A(12);        /* pd2 points to least significant byte of D2 */
-    pd3 = A(13);        /* pd3 points to least significant byte of D3 */
-    pd4 = A(14);        /* pd4 points to least significant byte of D4 */
-
-    /* Each block processes one 32 bit word, big endian, using byte operations */
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add up data that goes into A1; S1, S2 not used */
-    ps3 = A(9);  ps4 = A(10); pd1 = A(12); pd2 = A(13); pd3 = A(14); pd4 = A(15);
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add up data that goes into A2; S1, S2, D4 not used */
-    ps3 = A(10); ps4 = A(11); pd1 = A(13); pd2 = A(14); pd3 = A(15);
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add up data that goes into A3; S3, D1 not used */
-    ps1 = A(11); ps2 = A(12); ps4 = A(13); pd2 = A(15); pd3 = A(8); pd4 = A(9);
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add up data that goes into A4; S3, D1, D2 not used */
-    ps1 = A(12); ps2 = A(13); ps4 = A(14); pd3 = A(9); pd4 = A(10);
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add up data that goes into A5; S3, D1, D2 not used */
-    ps1 = A(13); ps2 = A(14); ps4 = A(15); pd3 = A(10); pd4 = A(11);
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps4--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add up data that goes into A6; D3, D4 not used */
-    ps1 = A(14); ps2 = A(15); ps3 = A(14); ps4 = A(13); pd1 = A(8); pd2 = A(9);
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps2;ac += *ps2--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add up data that goes into A7; S2 not used */
-    ps1 = A(15); ps3 = A(15); ps4 = A(8); pd1 = A(10); pd2 = A(11); pd3 = A(12); pd4 = A(13);
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--;  ac += *ps3--; ac += *ps4--; ac -= *pd1--; ac -= *pd2--; ac -= *pd3--; ac -= *pd4--; *pt-- = ac; ac >>= 8;
-
-    bnSetQ(r, 0);
-    if (ac > 0) {
-        *(A(8)) = ac;      /* Store the carry */
-        bnInsertBigBytes(r, A(8), 0, 33);  /* 33: 8 * 4 byte words + 1 carry byte */
-    }
-    /* Negative carry requires that we add the modulo (carry * -1) times to make
-     * the result positive. Then get the result mod(256).
-     */
-    else if (ac < 0) {
-        int msb, maxMsb;
-
-        *(A(8)) = 0;
-        bnInsertBigBytes(r, A(8), 0, 33);  /* 33: 8 * 4 byte words + 1 carry byte */
-        ac *= -1;
-        while (ac--) {
-            bnAdd(r, modulo);
-        }
-        maxMsb =  bnBits(modulo);
-        msb = bnBits(r) - maxMsb;
-        /* clear all bits above bit length of modulo. This length is 256 here, thus
-         * we effectiviely doing a mod(256)
-         */
-        if (msb > 0) {
-            BigNum tmp;
-            bnBegin(&tmp);
-            bnSetQ (&tmp, 1);
-            bnLShift (&tmp, maxMsb);
-            bnMod(r, r, &tmp);
-            bnEnd(&tmp);
-        }
-    }
-    else {
-        *(A(8)) = 0;
-        bnInsertBigBytes(r, A(8), 0, 33);  /* 33: 8 * 4 byte words + 1 carry byte */
-    }
-    while (bnCmp(r, modulo) >= 0) {
-        bnSub(r, modulo);
-    }
-    return 0;
-}
-#undef A
-
-
-/* new modulo for 384bit curve */
-static int newMod384(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
-    unsigned char buffer[200] = {0};
-    unsigned char *pt;
-    unsigned char *ps1;
-    unsigned char *ps2;
-    unsigned char *ps3;
-    unsigned char *ps4;
-    unsigned char *ps5;
-    unsigned char *ps6;
-
-    unsigned char *pd1;
-    unsigned char *pd2;
-    unsigned char *pd3;
-    short ac;
-    int cmp;
-
-    /*
-     *
-     * the least significant byte starts at byte offset 97
-     *
-     *                                                                    T
-     *                                        /---------------------------^----------------------------\
-     *      A23 ......... A15  A14  A13  A12  A11  A10  A9   A8   A7   A6   A5   A4   A3   A2   A1   A0
-     *    |----+ ...... |----+----|----+----|----+----|----+----|----+----|----+----|----+----|----+----|
-     *
-     * T  = (A11 || A10 ||  A9 ||  A8 ||  A7 ||  A6 ||  A5 ||  A4 ||  A3 ||  A2 ||  A1 ||  A0)
-
-     * S1 = ( 00 ||  00 ||  00 ||  00 ||  00 || A23 || A22 || A21 ||  00 ||  00 ||  00 ||  00)
-     * S2 = (A23 || A22 || A21 || A20 || A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12)
-     * S3 = (A20 || A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12 || A23 || A22 || A21)
-     * S4 = (A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12 || A20 ||  00 || A23 ||  00)
-     * S5 = ( 00 ||  00 ||  00 ||  00 || A23 || A22 || A21 || A20 ||  00 ||  00 ||  00 ||  00)
-     * S6 = ( 00 ||  00 ||  00 ||  00 ||  00 ||  00 || A23 || A22 || A21 ||  00 ||  00 || A20)
-     * D1 = (A22 || A21 || A20 || A19 || A18 || A17 || A16 || A15 || A14 || A13 || A12 || A23)
-     * D2 = ( 00 ||  00 ||  00 ||  00 ||  00 ||  00 ||  00 || A23 || A22 || A21 || A20 ||  00)
-     * D3 = ( 00 ||  00 ||  00 ||  00 ||  00 ||  00 ||  00 || A23 || A23 ||  00 ||  00 ||  00)
-     *
-     * perform B =  T + 2S1 + S2 + S3 + S4 + S5 + S6 – D1 – D2 – D3 mod p
-     *
-     * TODO: error check if input variable is > modulo^2 (do normal mpi_mod_mpi),
-     *       optimize if input is already < modulo  (just copy over in this case).
-     */
-
-    cmp = bnCmp(modulo, a);
-    if (cmp == 0) {             /* a is equal modulo, set resul to zero */
-        bnSetQ(r, 0);
-        return 0;
-    }
-    if (cmp > 0) {              /* modulo is greater than a - copy a to r and return it */
-        bnCopy(r, a);
-        return 0;
-    }
-
-    bnExtractBigBytes(a, buffer, 0, bnBytes(modulo)*2);
-
-    /* 24 'A' words, each word is 4 byte. Compute offset to least significant byte of word X */
-#define A(X) buffer + (((24-X)*4)-1)
-
-    ac = 0;
-
-    pt = A(0);      /* pt points to least significant byte of A0  */
-
-    /* Set up to add data that goes into A0; S1, S4, S5, D2, D3 not used */
-    ps2 = A(12); ps3 = A(21); ps6 = A(20); pd1 = A(23);
-
-    /* Each block processes one 32 bit word, big endian, using byte operations */
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A1; S1, S5, S6, D3 not used */
-    ps2 = A(13); ps3 = A(22); ps4 = A(23); pd1= A(12); pd2 = A(20);
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A2; S1, S4, S5, S6, D3 not used */
-    ps2 = A(14); ps3 = A(23); pd1 = A(13); pd2 = A(21);
-    ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac -= *pd1--;  ac -= *pd2--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A3; S1, S5, S6 not used */
-    ps2 = A(15); ps3 = A(12); ps4 = A(20); ps6 = A(21); pd1 = A(14); pd2 = A(22); pd3 = A(23);
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A4 */
-    ps1 = A(21); ps2 = A(16); ps3 = A(13); ps4 = A(12); ps5 = A(20); ps6 = A(22); pd1 = A(15); pd2 = A(23), pd3 = A(23);
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--;  ac -= *pd2--; ac -= *pd3--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A5; D2, D3 not used */
-    ps1 = A(22); ps2 = A(17); ps3 = A(14); ps4 = A(13); ps5 = A(21); ps6 = A(23); pd1 = A(16);
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac += *ps6--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A6; S6, D2, D3 not used */
-    ps1 = A(23); ps2 = A(18); ps3 = A(15); ps4 = A(14); ps5 = A(22); pd1 = A(17);
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps1;ac += *ps1--; ac += *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A7; S1, S6, D2, D3 not used */
-    ps2 = A(19); ps3 = A(16); ps4 = A(15); ps5 = A(23); pd1 = A(18);
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac += *ps5--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A8; S1, S5, S6, D2, D3 not used */
-    ps2 = A(20); ps3 = A(17); ps4 = A(16); pd1 = A(19);
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A9; S1, S5, S6, D2, D3 not used */
-    ps2 = A(21); ps3 = A(18); ps4 = A(17); pd1 = A(20);
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A10; S1, S5, S6, D2, D3 not used */
-    ps2 = A(22); ps3 = A(19); ps4 = A(18); pd1 = A(21);
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    /* Set up to add data that goes into A10; S1, S5, S6, D2, D3 not used */
-    ps2 = A(23); ps3 = A(20); ps4 = A(19); pd1 = A(22);
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-    ac += *pt + *ps2--; ac += *ps3--; ac += *ps4--; ac -= *pd1--; *pt-- = ac; ac >>= 8;
-
-    bnSetQ(r, 0);
-    if (ac > 0) {
-        *(A(12)) = ac;      /* Store the carry */
-        bnInsertBigBytes(r, A(12), 0, 49);  /* 49: 12 * 4 byte words + 1 carry byte */
-    }
-    /* Negative carry requires that we add the modulo (carry * -1) times to make
-     * the result positive. Then get the result mod(256).
-     */
-    else if (ac < 0) {
-        int msb, maxMsb;
-
-        *(A(12)) = 0;
-        bnInsertBigBytes(r, A(12), 0, 49);  /* 49: 12 * 4 byte words + 1 carry byte */
-        ac *= -1;
-        while (ac--) {
-            bnAdd(r, modulo);
-        }
-        maxMsb =  bnBits(modulo);
-        msb = bnBits(r) - maxMsb;
-        /* clear all bits above bit length of modulo. This length is 384 here, thus
-         * we effectiviely doing a mod(384)
-         */
-        if (msb > 0) {
-            BigNum tmp;
-            bnBegin(&tmp);
-            bnSetQ (&tmp, 1);
-            bnLShift (&tmp, maxMsb);
-            bnMod(r, r, &tmp);
-            bnEnd(&tmp);
-        }
-    }
-    else {
-        *(A(12)) = 0;
-        bnInsertBigBytes(r, A(12), 0, 49);  /* 49: 12 * 4 byte words + 1 carry byte */
-    }
-    while (bnCmp(r, modulo) >= 0) {
-        bnSub(r, modulo);
-    }
-    return 0;
-}
-#undef A
-
-
-/* new modulo for 521bit curve, much easier because the prime for 521 is a real Mersenne prime */
-static int newMod521(BigNum *r, const BigNum *a, const BigNum *modulo)
-{
-    unsigned char buf1[200] = {0};
-    unsigned char buf2[200] = {0};
-    unsigned char *p1;
-    unsigned char *p2;
-    size_t modSize;
-    short ac = 0;
-    unsigned int i;
-    int cmp;
-
-    /* TODO: check if a is > modulo^2 */
-#if 0
-    if (a->s < 0)               /* is it a negative value? */
-        return bnMod(r, a, modulo);
-#endif
-    cmp = bnCmp(modulo, a);
-    if (cmp == 0) {             /* a is equal modulo, set resul to zero */
-        bnSetQ(r, 0);
-        return 0;
-    }
-    bnCopy(r, a);
-    if (cmp > 0) {              /* modulo is greater than a - return the prepared r */
-        return 0;
-    }
-    modSize = bnBytes(modulo);
-
-    bnExtractBigBytes(a, buf1, 0, modSize*2); /* a must be less modulo^2 */
-    buf1[modSize] &= 1;                   /* clear all bits except least significat */
-
-    bnRShift(r, 521);
-    bnExtractBigBytes(r, buf2, 0, modSize*2);
-    buf2[modSize] &= 1;
-
-    p1 = &buf2[131];            /* p1 is pointer to A0 */
-    p2 = &buf1[131];            /* p2 is pointer to A1 */
-
-    for (i = 0; i < modSize; i++) {
-        ac += *p1 + *p2--; *p1-- = ac; ac >>= 8;
-    }
-    bnSetQ(r, 0);
-    bnInsertBigBytes(r, p1+1, 0, modSize);
-
-    while (bnCmp(r, modulo) >= 0) {
-        bnSub(r, modulo);
-    }
-    return 0;
-}
-
diff --git a/jni/libzrtp/sources/bnlib/ec/ec.h b/jni/libzrtp/sources/bnlib/ec/ec.h
deleted file mode 100644
index 172ffd8..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ec.h
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2012 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-#ifndef _EC_H_
-#define _EC_H_
-
-#include <bn.h>
-
-/**
- * @file ec.h
- * @brief Elliptic curve functions for bnlib
- * @defgroup BNLIB_EC Elliptic curve functions
- * @{
- */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct BigNum BigNum;
-
-typedef enum {
-    NIST192P = 1,
-    NIST224P = 2,
-    NIST256P = 3,
-    NIST384P = 4,
-    NIST521P = 5,
-    Curve25519 = 10,
-    Curve3617  = 11
-} Curves;
-
-/**
- * \brief This structure contains the x, y affine coordinates and the z value if we
- *        use projective coordinates during EC point arithmetic.
- */
-typedef struct _EcPoint {
-    BigNum *x, *y, *z;
-    BigNum tx, ty, tz;
-} EcPoint;
-
-/**
- * @brief This structure contains the value of EC curves over Prime Fields.
- *
- * The for NIST curves the field names correspond to the variable names defined in 
- * NIST FIPS 186-3, E.1.2. The <b>a</b> curve parameter is the constant -3 and is 
- * computed during initialization of the curve structure.
- *
- * For other curves, for example curve3917 we have less parameters to fill in, mostly
- * the prime number, the base point, etc. Refer to the curve's initialization function
- * about the use of the fileds.
- */
-struct EcCurve;
-struct EcCurve {
-    Curves id;
-    BigNum _p;
-    BigNum _n;
-    BigNum _SEED;
-    BigNum _c;
-    BigNum _a;
-    BigNum _b;
-    BigNum _Gx;
-    BigNum _Gy;
-    /* Pointers to the BigNum structures, for better readability mainly */
-    BigNum *p;
-    BigNum *n;
-    BigNum *SEED;
-    BigNum *c;
-    BigNum *a;
-    BigNum *b;
-    BigNum *Gx;
-    BigNum *Gy;
-    /* some scratch pad variables, the EC algorithms use them to 
-       avoid to much memory allocation/deallocatio0n overhead */
-  BigNum _S1, _U1, _H, _R, _t0, _t1, _t2, _t3;
-  BigNum *S1, *U1, *H, *R, *t0, *t1, *t2, *t3;
-  int (*affineOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P);
-  int (*doubleOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P);
-  int (*addOp)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-  int (*modOp)(BigNum *, const BigNum *, const BigNum *);
-  int (*checkPubOp)(const struct EcCurve *curve, const EcPoint *pub);
-  int (*randomOp)(const struct EcCurve *curve, BigNum *d);
-  int (*mulScalar)(const struct EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-
-};
-
-typedef struct EcCurve EcCurve;
-typedef EcCurve NistECpCurve;
-
-/**
- * \brief          Marco to initialize a EC point structure.
- *
- * \param P        Address of the EC point structure
- */
-#define INIT_EC_POINT(P) {EcPoint *e = P; e->x = &e->tx; e->y = &e->ty; e->z = &e->tz; bnBegin(e->x); bnBegin(e->y); bnBegin(e->z);}
-
-/**
- * \brief          Marco to free a EC point structure.
- *
- * \param P        Address of the EC point structure
- */
-#define FREE_EC_POINT(P) {EcPoint *e = P; bnEnd(e->x); bnEnd(e->y); bnEnd(e->z);}
-
-/**
- * \brief          Marco to set a EC point structure to the curve's base point.
- *
- * \param C        Address of the NistECpCurve structure.
- *
- * \param P        Address of the EC point structure.
- */
-#define SET_EC_BASE_POINT(C, P) {EcPoint *e = P;  const EcCurve *c = C; bnCopy(e->x, c->Gx); bnCopy(e->y, c->Gy); bnSetQ(e->z, 1);}
-
-/*
- * EC point helper functions
- */
-extern void ecInitPoint(EcPoint *P);
-
-extern void ecFreePoint(EcPoint *P);
-
-extern void ecSetBasePoint(EcCurve *C, EcPoint *P);
-
-/**
- * \brief          Get NIST EC curve parameters.
- *
- *                 Before reusing a EC curve structure make sure to call ecFreeCurveNistECp
- *                 to return memory.
- *
- * \param curveId  Which curve to initialize
- *
- * \param curve    Pointer to a EcCurve structure
- *
- * \return         0 if successful
- *
- * \note           Call ecFreeCurveNistECp to return allocated memory.
- */
-int ecGetCurveNistECp(Curves curveId, NistECpCurve *curve);
-
-
-/**
- * \brief          Free EC curve parameters.
- *
- * \param curve    Pointer to a EcCurve structure
- *
- * \note           Curve parameters must be initialized calling ecGetCurveNistECp.
- */
-void ecFreeCurveNistECp(EcCurve *curve);
-
-/**
- * \brief          Double an EC point.
- *
- *                 This function uses affine coordinates to perform the computations. For
- *                 further reference see RFC 6090 or the standard work <i>Guide to Elliptic
- *                 Curve Cryptography</i>.
- *
- * \param          curve  Address of EC curve structure
- * \param          R      Address of resulting EC point structure
- * \param          P      Address of the EC point structure
- *
- * \return         0 if successful
- */
-int ecDoublePoint(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-/**
- * \brief          Add two EC points.
- *
- *                 This function uses affine coordinates to perform the computations. For
- *                 further reference see RFC 6090 or the standard work <i>Guide to Elliptic
- *                 Curve Cryptography</i>.
- *
- * \param          curve  Address of EC curve structure
- * \param          R      Address of resulting EC point structure
- * \param          P      Address of the first EC point structure
- * \param          Q      Address of the second EC point structure
- *
- * \return         0 if successful
- */
-int ecAddPoint(const EcCurve *curve, EcPoint *R, const EcPoint *P, const EcPoint *Q);
-
-/**
- * \brief          Mulitply an EC point with a scalar value.
- *
- * \param          curve  Address of EC curve structure
- * \param          R      Address of resulting EC point structure
- * \param          P      Address of the EC point structure
- * \param          scalar Address of the scalar multi-precision integer value
- *
- * \return         0 if successful
- */
-int ecMulPointScalar(const EcCurve *curve, EcPoint *R, const EcPoint *P, const BigNum *scalar);
-
-/**
- * \brief          Convert an EC point from Jacobian projective coordinates to normal affine x/y coordinates.
- *
- * \param          curve  Address of EC curve structure
- * \param          R      Address of EC point structure that receives the x/y coordinates
- * \param          P      Address of the EC point structure that contains the jacobian x/y/z coordinates.
- *
- * \return         0 if successful
- */
-int ecGetAffine(const EcCurve *curve, EcPoint *R, const EcPoint *P);
-
-/**
- * @brief Generate a random number.
- *
- * The method generates a random number and checks if it matches the curve restricitions.
- * Use this number as ECDH private key.
- *
- * @param curve the NIST curve to use.
- *
- * @param d receives the generated random number.
- */
-int ecGenerateRandomNumber(const NistECpCurve *curve, BigNum *d);
-
-/**
- * @brief Check a public key.
- *
- * The method checks if a public key is valid. For NIST curves it uses the
- * ECC Partial Validation, NIST SP800-56A section 5.6.2.6
- * 
- * For other curves it computes the equation and compares the left hand and 
- * the right handresults. If they are equal the point is on the curve.
- *
- * @param curve the curve to use.
- *
- * @param pub the public key to check.
- *
- * @returns true (!0) if the check was ok, false (0) otherwise.
- *
- * @note The function uses some scratch pad variable of the NistECpCurve structure.
- */
-int ecCheckPubKey(const EcCurve *curve, const EcPoint *pub);
-
-int ecGetCurvesCurve(Curves curveId, EcCurve *curve);
-
-void ecFreeCurvesCurve(EcCurve *curve);
-
-/**
- * This is a special function for DJB's curve 25519. Actually it's the scalar multiplication
- * mypublic = basepoint * secret
- */
-int curve25519_donna(unsigned char *mypublic, const unsigned char *secret, const unsigned char *basepoint);
-
-/*
- * Some additional functions that are not available in bnlib
- */
-int bnAddMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
-
-int bnAddQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
-
-int bnSubMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod);
-
-int bnSubQMod_ (struct BigNum *rslt, unsigned n1, struct BigNum *mod);
-
-int bnMulMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *n2, struct BigNum *mod, const EcCurve *curve);
-
-int bnMulQMod_ (struct BigNum *rslt, struct BigNum *n1, unsigned n2, struct BigNum *mod, const EcCurve *curve);
-
-int bnSquareMod_ (struct BigNum *rslt, struct BigNum *n1, struct BigNum *mod, const EcCurve *curve);
-
-#ifdef __cplusplus
-}
-#endif
-
-/**
- * @}
- */
-
-#endif
diff --git a/jni/libzrtp/sources/bnlib/ec/ecdh.c b/jni/libzrtp/sources/bnlib/ec/ecdh.c
deleted file mode 100644
index 8d1bc23..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ecdh.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2012 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-
-#include <ec/ec.h>
-#include <ec/ecdh.h>
-
-int ecdhGeneratePublic(const EcCurve *curve, EcPoint *Q, const BigNum *d)
-{
-    EcPoint G;
-
-    INIT_EC_POINT(&G);
-    SET_EC_BASE_POINT(curve, &G);
-
-    ecMulPointScalar(curve, Q, &G, d);
-    ecGetAffine(curve, Q, Q);
-
-    FREE_EC_POINT(&G);
-
-    return ecCheckPubKey(curve, Q);
-}
-
-int ecdhComputeAgreement(const EcCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d)
-{
-    EcPoint t0;
-
-    INIT_EC_POINT(&t0);
-
-    ecMulPointScalar(curve, &t0, Q, d);
-    ecGetAffine(curve, &t0, &t0);
-    /* TODO: check for infinity here */
-
-    bnCopy(agreement, t0.x);
-
-    FREE_EC_POINT(&t0);
-
-    return 0;
-}
diff --git a/jni/libzrtp/sources/bnlib/ec/ecdh.h b/jni/libzrtp/sources/bnlib/ec/ecdh.h
deleted file mode 100644
index 7ec32ad..0000000
--- a/jni/libzrtp/sources/bnlib/ec/ecdh.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2012 Werner Dittmann
- * All rights reserved. For licensing and other legal details, see the file legal.c.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- *
- */
-#ifndef _ECDH_H_
-#define _ECDH_H_
-/**
- * @file ec.h
- * @brief Elliptic Diffie-Hellman functions for bnlib
- * @defgroup BNLIB_EC Elliptic curve functions
- * @{
- */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @brief Takes a secret large random number and computes the public EC point.
- *
- * @param curve is the curve to use.
- *
- * @param Q the functions writes the computed public point in this parameter.
- *
- * @param d is the secret random number.
- *
- * @return @c true (!0) if public key was computed, @c false otherwise.
- *
- * @sa ecGenerateRandomNumber
- */
-int ecdhGeneratePublic(const EcCurve *curve, EcPoint *Q, const BigNum *d);
-
-/**
- * @brief Computes the key agreement value.
- *
- * Takes the public EC point of the other party and applies the EC DH algorithm
- * to compute the agreed value.
- *
- * @param curve is the curve to use, must be the same curve as used in
- *              @c ecdhGeneratePublic.
- *
- * @param agreemtn the functions writes the computed agreed value in this parameter.
- *
- * @param Q is the other party's public point.
- *
- * @param d is the secret random number.
- */
-int ecdhComputeAgreement(const EcCurve *curve, BigNum *agreement, const EcPoint *Q, const BigNum *d);
-
-#ifdef __cplusplus
-}
-#endif
-/**
- * @}
- */
-
-#endif
\ No newline at end of file
diff --git a/jni/libzrtp/sources/bnlib/germain.c b/jni/libzrtp/sources/bnlib/germain.c
deleted file mode 100644
index 52dbb50..0000000
--- a/jni/libzrtp/sources/bnlib/germain.c
+++ /dev/null
@@ -1,608 +0,0 @@
-/*
- * Sophie Germain prime generation using the bignum library and sieving.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include "bnconfig.h"
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#define BNDEBUG 1
-#ifndef BNDEBUG
-#define BNDEBUG 0
-#endif
-#if BNDEBUG
-#include <stdio.h>
-#endif
-
-#include "bn.h"
-#include "germain.h"
-#include "jacobi.h"
-#include "lbnmem.h"	/* For lbnMemWipe */
-#include "sieve.h"
-
-#include "kludge.h"
-
-/* Size of the sieve area (can be up to 65536/8 = 8192) */
-#define SIEVE 8192
-
-static unsigned const confirm[] = {2, 3, 5, 7, 11, 13, 17};
-#define CONFIRMTESTS (sizeof(confirm)/sizeof(*confirm))
-
-#if BNDEBUG
-/*
- * For sanity checking the sieve, we check for small divisors of the numbers
- * we get back.  This takes "rem", a partially reduced form of the prime,
- * "div" a divisor to check for, and "order", a parameter of the "order"
- * of Sophie Germain primes (0 = normal primes, 1 = Sophie Germain primes,
- * 2 = 4*p+3 is also prime, etc.) and does the check.  It just complains
- * to stdout if the check fails.
- */
-static void
-germainSanity(unsigned rem, unsigned div, unsigned order)
-{
-	unsigned mul = 1;
-
-	rem %= div;
-	if (!rem)
-		printf("bn div by %u!\n", div);
-	while (order--) {
-		rem += rem+1;
-		if (rem >= div)
-			rem -= div;
-		mul += mul;
-		if (!rem)
-			printf("%u*bn+%u div by %u!\n", mul, mul-1, div);
-	}
-}
-#endif /* BNDEBUG */
-
-/*
- * Helper function that does the slow primality test.
- * bn is the input bignum; a, e and bn2 are temporary buffers that are
- * allocated by the caller to save overhead.  bn2 is filled with
- * a copy of 2^order*bn+2^order-1 if bn is found to be prime.
- *
- * Returns 0 if both bn and bn2 are prime, >0 if not prime, and -1 on
- * error (out of memory).  If not prime, the return value is the number
- * of modular exponentiations performed.   Prints a '+' or '-' on the
- * given FILE (if any) for each test that is passed by bn, and a '*'
- * for each test that is passed by bn2.
- *
- * The testing consists of strong pseudoprimality tests, to the bases given
- * in the confirm[] array above.  (Also called Miller-Rabin, although that's
- * not technically correct if we're using fixed bases.)  Some people worry
- * that this might not be enough.  Number theorists may wish to generate
- * primality proofs, but for random inputs, this returns non-primes with
- * a probability which is quite negligible, which is good enough.
- *
- * It has been proved (see Carl Pomerance, "On the Distribution of
- * Pseudoprimes", Math. Comp. v.37 (1981) pp. 587-593) that the number of
- * pseudoprimes (composite numbers that pass a Fermat test to the base 2)
- * less than x is bounded by:
- * exp(ln(x)^(5/14)) <= P_2(x)	### CHECK THIS FORMULA - it looks wrong! ###
- * P_2(x) <= x * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))).
- * Thus, the local density of Pseudoprimes near x is at most
- * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))), and at least
- * exp(ln(x)^(5/14) - ln(x)).  Here are some values of this function
- * for various k-bit numbers x = 2^k:
- * Bits	Density <=	Bit equivalent	Density >=	Bit equivalent
- *  128	3.577869e-07	 21.414396	4.202213e-37	 120.840190
- *  192	4.175629e-10	 31.157288	4.936250e-56	 183.724558
- *  256 5.804314e-13	 40.647940	4.977813e-75	 246.829095
- *  384 1.578039e-18	 59.136573	3.938861e-113	 373.400096
- *  512 5.858255e-24	 77.175803	2.563353e-151	 500.253110
- *  768 1.489276e-34	112.370944	7.872825e-228	 754.422724
- * 1024 6.633188e-45	146.757062	1.882404e-304	1008.953565
- *
- * As you can see, there's quite a bit of slop between these estimates.
- * In fact, the density of pseudoprimes is conjectured to be closer to the
- * square of that upper bound.  E.g. the density of pseudoprimes of size
- * 256 is around 3 * 10^-27.  The density of primes is very high, from
- * 0.005636 at 256 bits to 0.001409 at 1024 bits, i.e.  more than 10^-3.
- *
- * For those people used to cryptographic levels of security where the
- * 56 bits of DES key space is too small because it's exhaustible with
- * custom hardware searching engines, note that you are not generating
- * 50,000,000 primes per second on each of 56,000 custom hardware chips
- * for several hours.  The chances that another Dinosaur Killer asteroid
- * will land today is about 10^-11 or 2^-36, so it would be better to
- * spend your time worrying about *that*.  Well, okay, there should be
- * some derating for the chance that astronomers haven't seen it yet,
- * but I think you get the idea.  For a good feel about the probability
- * of various events, I have heard that a good book is by E'mile Borel,
- * "Les Probabilite's et la vie".  (The 's are accents, not apostrophes.)
- *
- * For more on the subject, try "Finding Four Million Large Random Primes",
- * by Ronald Rivest, in Advancess in Cryptology: Proceedings of Crypto
- * '90.  He used a small-divisor test, then a Fermat test to the base 2,
- * and then 8 iterations of a Miller-Rabin test.  About 718 million random
- * 256-bit integers were generated, 43,741,404 passed the small divisor
- * test, 4,058,000 passed the Fermat test, and all 4,058,000 passed all
- * 8 iterations of the Miller-Rabin test, proving their primality beyond
- * most reasonable doubts.
- *
- * If the probability of getting a pseudoprime is some small p, then the
- * probability of not getting it in t trials is (1-p)^t.  Remember that,
- * for small p, (1-p)^(1/p) ~ 1/e, the base of natural logarithms.
- * (This is more commonly expressed as e = lim_{x\to\infty} (1+1/x)^x.)
- * Thus, (1-p)^t ~ e^(-p*t) = exp(-p*t).  So the odds of being able to
- * do this many tests without seeing a pseudoprime if you assume that
- * p = 10^-6 (one in a million) is one in 57.86.  If you assume that
- * p = 2*10^-6, it's one in 3347.6.  So it's implausible that the density
- * of pseudoprimes is much more than one millionth the density of primes.
- *
- * He also gives a theoretical argument that the chance of finding a
- * 256-bit non-prime which satisfies one Fermat test to the base 2 is
- * less than 10^-22.  The small divisor test improves this number, and
- * if the numbers are 512 bits (as needed for a 1024-bit key) the odds
- * of failure shrink to about 10^-44.  Thus, he concludes, for practical
- * purposes *one* Fermat test to the base 2 is sufficient.
- */
-static int
-germainPrimeTest(struct BigNum const *bn, struct BigNum *bn2, struct BigNum *e,
-	struct BigNum *a, unsigned order, int (*f)(void *arg, int c), void *arg)
-{
-	int err;
-	unsigned i;
-	int j;
-	unsigned k, l, n;
-
-#if BNDEBUG	/* Debugging */
-	/*
-	 * This is debugging code to test the sieving stage.
-	 * If the sieving is wrong, it will let past numbers with
-	 * small divisors.  The prime test here will still work, and
-	 * weed them out, but you'll be doing a lot more slow tests,
-	 * and presumably excluding from consideration some other numbers
-	 * which might be prime.  This check just verifies that none
-	 * of the candidates have any small divisors.  If this
-	 * code is enabled and never triggers, you can feel quite
-	 * confident that the sieving is doing its job.
-	 */
-	i = bnLSWord(bn);
-	if (!(i % 2)) printf("bn div by 2!");
-	i = bnModQ(bn, 51051);	/* 51051 = 3 * 7 * 11 * 13 * 17 */
-	germainSanity(i, 3, order);
-	germainSanity(i, 7, order);
-	germainSanity(i, 11, order);
-	germainSanity(i, 13, order);
-	germainSanity(i, 17, order);
-	i = bnModQ(bn, 63365);	/* 63365 = 5 * 19 * 23 * 29 */
-	germainSanity(i, 5, order);
-	germainSanity(i, 19, order);
-	germainSanity(i, 23, order);
-	germainSanity(i, 29, order);
-	i = bnModQ(bn, 47027);	/* 47027 = 31 * 37 * 41 */
-	germainSanity(i, 31, order);
-	germainSanity(i, 37, order);
-	germainSanity(i, 41, order);
-#endif
-	/*
-	 * First, check whether bn is prime.  This uses a fast primality
-	 * test which usually obviates the need to do one of the
-	 * confirmation tests later.  See prime.c for a full explanation.
-	 * We check bn first because it's one bit smaller, saving one
-	 * modular squaring, and because we might be able to save another
-	 * when testing it.  (1/4 of the time.)  A small speed hack,
-	 * but finding big Sophie Germain primes is *slow*.
-	 */
-	if (bnCopy(e, bn) < 0)
-		return -1;
-	(void)bnSubQ(e, 1);
-	l = bnLSWord(e);
-
-	j = 1;	/* Where to start in prime array for strong prime tests */
-
-	if (l & 7) {
-		bnRShift(e, 1);
-		if (bnTwoExpMod(a, e, bn) < 0)
-			return -1;
-		if ((l & 7) == 6) {
-			/* bn == 7 mod 8, expect +1 */
-			if (bnBits(a) != 1)
-				return 1;	/* Not prime */
-			k = 1;
-		} else {
-			/* bn == 3 or 5 mod 8, expect -1 == bn-1 */
-			if (bnAddQ(a, 1) < 0)
-				return -1;
-			if (bnCmp(a, bn) != 0)
-				return 1;	/* Not prime */
-			k = 1;
-			if (l & 4) {
-				/* bn == 5 mod 8, make odd for strong tests */
-				bnRShift(e, 1);
-				k = 2;
-			}
-		}
-	} else {
-		/* bn == 1 mod 8, expect 2^((bn-1)/4) == +/-1 mod bn */
-		bnRShift(e, 2);
-		if (bnTwoExpMod(a, e, bn) < 0)
-			return -1;
-		if (bnBits(a) == 1) {
-			j = 0;	/* Re-do strong prime test to base 2 */
-		} else {
-			if (bnAddQ(a, 1) < 0)
-				return -1;
-			if (bnCmp(a, bn) != 0)
-				return 1;	/* Not prime */
-		}
-		k = 2 + bnMakeOdd(e);
-	}
-
-
-	/*
-	 * It's prime!  Now check higher-order forms bn2 = 2*bn+1, 4*bn+3,
-	 * etc.  Since bn2 == 3 mod 4, a strong pseudoprimality test boils
-	 * down to looking at a^((bn2-1)/2) mod bn and seeing if it's +/-1.
-	 * (+1 if bn2 is == 7 mod 8, -1 if it's == 3)
-	 * Of course, that exponent is just the previous bn2 or bn...
-	 */
-	if (bnCopy(bn2, bn) < 0)
-			return -1;
-	for (n = 0; n < order; n++) {
-		/*
-		 * Print a success indicator: the sign of Jacobi(2,bn2),
-		 * which is available to us in l.  bn2 = 2*bn + 1.  Since bn
-		 * is odd, bn2 must be == 3 mod 4, so the options modulo 8
-		 * are 3 and 7.  3 if l == 1 mod 4, 7 if l == 3 mod 4.
-		 * The sign of the Jacobi symbol is - and + for these cases,
-		 * respectively.
-		 */
-		if (f && (err = f(arg, "-+"[(l >> 1) & 1])) < 0)
-			return err;
-		/* Exponent is previous bn2 */
-		if (bnCopy(e, bn2) < 0 || bnLShift(bn2, 1) < 0)
-			return -1;
-		(void)bnAddQ(bn2, 1);	/* Can't overflow */
-		if (bnTwoExpMod(a, e, bn2) < 0)
-			return -1;
-		if (n | l) {	/* Expect + */
-			if (bnBits(a) != 1)
-				return 2+n;	/* Not prime */
-		} else {
-			if (bnAddQ(a, 1) < 0)
-				return -1;
-			if (bnCmp(a, bn2) != 0)
-				return 2+n;	/* Not prime */
-		}
-		l = bnLSWord(bn2);
-	}
-
-	/* Final success indicator - it's in the bag. */
-	if (f && (err = f(arg, '*')) < 0)
-		return err;
-	
-	/*
-	 * Success!  We have found a prime!  Now go on to confirmation
-	 * tests...  k is an amount by which we know it's safe to shift
-	 * down e.  j = 1 unless the test to the base 2 could stand to be
-	 * re-done (it wasn't *quite* a strong test), in which case it's 0.
-	 *
-	 * Here, we do the full strong pseudoprimality test.  This proves
-	 * that a number is composite, or says that it's probably prime.
-	 *
-	 * For the given base a, find bn-1 = 2^k * e, then find
-	 * x == a^e (mod bn).
-	 * If x == +1 -> strong pseudoprime to base a
-	 * Otherwise, repeat k times:
-	 *   If x == -1, -> strong pseudoprime
-	 *   x = x^2 (mod bn)
-	 *   If x = +1 -> composite
-	 * If we reach the end of the iteration and x is *not* +1, at the
-	 * end, it is composite.  But it's also composite if the result
-	 * *is* +1.  Which means that the squaring actually only has to
-	 * proceed k-1 times.  If x is not -1 by then, it's composite
-	 * no matter what the result of the squaring is.
-	 *
-	 * For the multiples 2*bn+1, 4*bn+3, etc. then k = 1 (and e is
-	 * the previous multiple of bn) so the squaring loop is never
-	 * actually executed at all.
-	 */
-	for (i = j; i < CONFIRMTESTS; i++) {
-		if (bnCopy(e, bn) < 0)
-				return -1;
-		bnRShift(e, k);
-		k += bnMakeOdd(e);
-		(void)bnSetQ(a, confirm[i]);
-		if (bnExpMod(a, a, e, bn) < 0)
-			return -1;
-
-		if (bnBits(a) != 1) {
-			l = k;
-			for (;;) {
-				if (bnAddQ(a, 1) < 0)
-					return -1;
-				if (bnCmp(a, bn) == 0)	/* Was result bn-1? */
-					break;	/* Prime */
-				if (!--l)
-					return (1+order)*i+2;	/* Fail */
-				/* This part is executed once, on average. */
-				(void)bnSubQ(a, 1);	/* Restore a */
-				if (bnSquare(a, a) < 0 || bnMod(a, a, bn) < 0)
-					return -1;
-				if (bnBits(a) == 1)
-					return (1+order)*i+1;	/* Fail */
-			}
-		}
-
-		if (bnCopy(bn2, bn) < 0)
-			return -1;
-	
-		/* Only do the following if we're not re-doing base 2 */
-		if (i) for (n = 0; n < order; n++) {
-			if (bnCopy(e, bn2) < 0 || bnLShift(bn2, 1) < 0)
-				return -1;
-			(void)bnAddQ(bn2, 1);
-
-			/* Print success indicator for previous test */
-			j = bnJacobiQ(confirm[i], bn2);
-			if (f && (err = f(arg, j < 0 ? '-' : '+')) < 0)
-				return err;
-
-			/* Check that p^e == Jacobi(p,bn2) (mod bn2) */
-			(void)bnSetQ(a, confirm[i]);
-			if (bnExpMod(a, a, e, bn2) < 0)
-				return -1;
-			/*
-			 * FIXME:  Actually, we don't need to compute the
-			 * Jacobi symbol externally... it never happens that
-			 * a = +/-1 but it's the wrong one.  So we can just
-			 * look at a and use its sign.  Find a proof somewhere.
-			 */
-			if (j < 0) {
-				/* Not a Q.R., should have a =  bn2-1 */
-				if (bnAddQ(a, 1) < 0)
-					return -1;
-				if (bnCmp(a, bn2) != 0)	/* Was result bn2-1? */
-					return (1+order)*i+n+2;	/* Fail */
-			} else {
-				/* Quadratic residue, should have a = 1 */
-				if (bnBits(a) != 1)
-					return (1+order)*i+n+2;	/* Fail */
-			}
-		}
-		/* Final success indicator for the base confirm[i]. */
-		if (f && (err = f(arg, '*')) < 0)
-			return err;
-	}
-
-	return 0;	/* Prime! */
-}
-
-/*
- * Add x*y to bn, which is usually (but not always) < 65536.
- * Do it in a simple linear manner.
- */
-static int
-bnAddMult(struct BigNum *bn, unsigned long x, unsigned y)
-{
-	unsigned long z = (unsigned long)x * y;
-
-	while (z > 65535) {
-		if (bnAddQ(bn, 65535) < 0)
-			return -1;
-		z -= 65535;
-	}
-	return bnAddQ(bn, (unsigned)z);
-}
-
-/*
- * Modifies the bignum to return the next Sophie Germain prime >= the
- * input value.  Sohpie Germain primes are number such that p is
- * prime and 2*p+1 is also prime.
- *
- * This is actually parameterized: it generates primes p such that "order"
- * multiples-plus-two are also prime, 2*p+1, 2*(2*p+1)+1 = 4*p+3, etc.
- *
- * Returns >=0 on success or -1 on failure (out of memory).  On success,
- * the return value is the number of modular exponentiations performed
- * (excluding the final confirmations).  This never gives up searching.
- *
- * The FILE *f argument, if non-NULL, has progress indicators written
- * to it.  A dot (.) is written every time a primeality test is failed,
- * a plus (+) or minus (-) when the smaller prime of the pair passes a
- * test, and a star (*) when the larger one does.  Finally, a slash (/)
- * is printed when the sieve was emptied without finding a prime and is
- * being refilled.
- *
- * Apologies to structured programmers for all the GOTOs.
- */
-int
-germainPrimeGen(struct BigNum *bn, unsigned order,
-	int (*f)(void *arg, int c), void *arg)
-{
-	int retval;
-	unsigned p, prev;
-	unsigned inc;
-	struct BigNum a, e, bn2;
-	int modexps = 0;
-#ifdef MSDOS
-	unsigned char *sieve;
-#else
-	unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
-	sieve = lbnMemAlloc(SIEVE);
-	if (!sieve)
-		return -1;
-#endif
-
-	bnBegin(&a);
-	bnBegin(&e);
-	bnBegin(&bn2);
-
-	/*
-	 * Obviously, the prime we find must be odd.  Further, if 2*p+1
-	 * is also to be prime (order > 0) then p != 1 (mod 3), lest
-	 * 2*p+1 == 3 (mod 3).  Added to p != 3 (mod 3), p == 2 (mod 3)
-	 * and p == 5 (mod 6).
-	 * If order > 2 and we care about 4*p+3 and 8*p+7, then similarly
-	 * p == 4 (mod 5), so p == 29 (mod 30).
-	 * So pick the step size for searching based on the order
-	 * and increse bn until it's == -1 (mod inc).
-	 *
-	 * mod 7 doesn't have a unique value for p because 2 -> 5 -> 4 -> 2,
-	 * nor does mod 11, and I don't want to think about things past
-	 * that.  The required order would be impractically high, in any case.
-	 */
-	inc = order ? ((order > 2) ? 30 : 6) : 2;
-	if (bnAddQ(bn, inc-1 - bnModQ(bn, inc)) < 0)
-		goto failed;
-
-	for (;;) {
-		if (sieveBuild(sieve, SIEVE, bn, inc, order) < 0)
-			goto failed;
-
-		p = prev = 0;
-		if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
-			do {
-				/* Adjust bn to have the right value. */
-				assert(p >= prev);
-				if (bnAddMult(bn, p-prev, inc) < 0)
-					goto failed;
-				prev = p;
-
-				/* Okay, do the strong tests. */
-				retval = germainPrimeTest(bn, &bn2, &e, &a,
-				                          order, f, arg);
-				if (retval <= 0)
-					goto done;
-				modexps += retval;
-				if (f && (retval = f(arg, '.')) < 0)
-					goto done;
-
-				/* And try again */
-				p = sieveSearch(sieve, SIEVE, p);
-			} while (p);
-		}
-
-		/* Ran out of sieve space - increase bn and keep trying. */
-		if (bnAddMult(bn, (unsigned long)SIEVE*8-prev, inc) < 0)
-			goto failed;
-		if (f && (retval = f(arg, '/')) < 0)
-			goto done;
-	} /* for (;;) */
-
-failed:
-	retval = -1;
-done:
-	bnEnd(&bn2);
-	bnEnd(&e);
-	bnEnd(&a);
-#ifdef MSDOS
-	lbnMemFree(sieve, SIEVE);
-#else
-	lbnMemWipe(sieve, sizeof(sieve));
-#endif
-	return retval < 0 ? retval : modexps+(order+1)*CONFIRMTESTS;
-}
-
-int
-germainPrimeGenStrong(struct BigNum *bn, struct BigNum const *step,
-	unsigned order, int (*f)(void *arg, int c), void *arg)
-{
-	int retval;
-	unsigned p, prev;
-	struct BigNum a, e, bn2;
-	int modexps = 0;
-#ifdef MSDOS
-	unsigned char *sieve;
-#else
-	unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
-	sieve = lbnMemAlloc(SIEVE);
-	if (!sieve)
-		return -1;
-#endif
-	bnBegin(&a);
-	bnBegin(&e);
-	bnBegin(&bn2);
-
-	for (;;) {
-		if (sieveBuildBig(sieve, SIEVE, bn, step, order) < 0)
-			goto failed;
-
-		p = prev = 0;
-		if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
-			do {
-				/*
-				 * Adjust bn to have the right value,
-				 * adding (p-prev) * 2*step.
-				 */
-				assert(p >= prev);
-				/* Compute delta into a */
-				if (bnMulQ(&a, step, p-prev) < 0)
-					goto failed;
-				if (bnAdd(bn, &a) < 0)
-					goto failed;
-				prev = p;
-
-				/* Okay, do the strong tests. */
-				retval = germainPrimeTest(bn, &bn2, &e, &a,
-				                          order, f, arg);
-				if (retval <= 0)
-					goto done;
-				modexps += retval;
-				if (f && (retval = f(arg, '.')) < 0)
-					goto done;
-
-				/* And try again */
-				p = sieveSearch(sieve, SIEVE, p);
-			} while (p);
-		}
-
-		/* Ran out of sieve space - increase bn and keep trying. */
-#if SIEVE*8 == 65536
-		/* Corner case that will never actually happen */
-		if (!prev) {
-			if (bnAdd(bn, step) < 0)
-				goto failed;
-			p = 65535;
-		} else {
-			p = (unsigned)(SIEVE*8 - prev);
-		}
-#else
-		p = SIEVE*8 - prev;
-#endif
-		if (bnMulQ(&a, step, p) < 0 || bnAdd(bn, &a) < 0)
-			goto failed;
-		if (f && (retval = f(arg, '/')) < 0)
-			goto done;
-	} /* for (;;) */
-
-failed:
-	retval = -1;
-done:
-	bnEnd(&bn2);
-	bnEnd(&e);
-	bnEnd(&a);
-#ifdef MSDOS
-	lbnMemFree(sieve, SIEVE);
-#else
-	lbnMemWipe(sieve, sizeof(sieve));
-#endif
-	return retval < 0 ? retval : modexps+(order+1)*CONFIRMTESTS;
-}
diff --git a/jni/libzrtp/sources/bnlib/germain.h b/jni/libzrtp/sources/bnlib/germain.h
deleted file mode 100644
index f1e018a..0000000
--- a/jni/libzrtp/sources/bnlib/germain.h
+++ /dev/null
@@ -1,8 +0,0 @@
-struct BigNum;
-
-/* Generate a Sophie Germain prime */
-int germainPrimeGen(struct BigNum *bn, unsigned order,
-	int (*f)(void *arg, int c), void *arg);
-/* The same, but search for using the given step size */
-int germainPrimeGenStrong(struct BigNum *bn, struct BigNum const *step,
-	unsigned order, int (*f)(void *arg, int c), void *arg);
diff --git a/jni/libzrtp/sources/bnlib/jacobi.c b/jni/libzrtp/sources/bnlib/jacobi.c
deleted file mode 100644
index 24b7313..0000000
--- a/jni/libzrtp/sources/bnlib/jacobi.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Compute the Jacobi symbol (small prime case only).
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#include "bn.h"
-#include "jacobi.h"
-
-/*
- * For a small (usually prime, but not necessarily) prime p,
- * compute Jacobi(p,bn), which is -1, 0 or +1, using the following rules:
- * Jacobi(x, y) = Jacobi(x mod y, y)
- * Jacobi(0, y) = 0
- * Jacobi(1, y) = 1
- * Jacobi(2, y) = 0 if y is even, +1 if y is +/-1 mod 8, -1 if y = +/-3 mod 8
- * Jacobi(x1*x2, y) = Jacobi(x1, y) * Jacobi(x2, y) (used with x1 = 2 & x1 = 4)
- * If x and y are both odd, then
- * Jacobi(x, y) = Jacobi(y, x) * (-1 if x = y = 3 mod 4, +1 otherwise)
- */
-int
-bnJacobiQ(unsigned p, struct BigNum const *bn)
-{
-	int j = 1;
-	unsigned u = bnLSWord(bn);
-
-	if (!(u & 1))
-		return 0;	/* Don't *do* that */
-
-	/* First, get rid of factors of 2 in p */
-	while ((p & 3) == 0)
-		p >>= 2;
-	if ((p & 1) == 0) {
-		p >>= 1;
-		if ((u ^ u>>1) & 2)
-			j = -j;		/* 3 (011) or 5 (101) mod 8 */
-	}
-	if (p == 1)
-		return j;
-	/* Then, apply quadratic reciprocity */
-	if (p & u & 2)	/* p = u = 3 (mod 4? */
-		j = -j;
-	/* And reduce u mod p */
-	u = bnModQ(bn, p);
-
-	/* Now compute Jacobi(u,p), u < p */
-	while (u) {
-		while ((u & 3) == 0)
-			u >>= 2;
-		if ((u & 1) == 0) {
-			u >>= 1;
-			if ((p ^ p>>1) & 2)
-				j = -j;	/* 3 (011) or 5 (101) mod 8 */
-		}
-		if (u == 1)
-			return j;
-		/* Now both u and p are odd, so use quadratic reciprocity */
-		if (u < p) {
-			unsigned t = u; u = p; p = t;
-			if (u & p & 2)	/* u = p = 3 (mod 4? */
-				j = -j;
-		}
-		/* Now u >= p, so it can be reduced */
-		u %= p;
-	}
-	return 0;
-}
diff --git a/jni/libzrtp/sources/bnlib/jacobi.h b/jni/libzrtp/sources/bnlib/jacobi.h
deleted file mode 100644
index 4dfd1e2..0000000
--- a/jni/libzrtp/sources/bnlib/jacobi.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * For a small (usually prime, but not necessarily) prime p,
- * Return Jacobi(p,bn), which is -1, 0 or +1.
- * bn must be odd.
- */
-struct BigNum;
-int bnJacobiQ(unsigned p, struct BigNum const *bn);
diff --git a/jni/libzrtp/sources/bnlib/kludge.h b/jni/libzrtp/sources/bnlib/kludge.h
deleted file mode 100644
index 023c890..0000000
--- a/jni/libzrtp/sources/bnlib/kludge.h
+++ /dev/null
@@ -1,125 +0,0 @@
-#ifndef KLUDGE_H
-#define KLUDGE_H
-
-/*
- * Kludges for not-quite-ANSI systems.
- * This should always be the last file included, because it may
- * mess up some system header files.
- */
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef ASSERT_NEEDS_STDIO
-#define ASSERT_NEEDS_STDIO 0
-#endif
-#ifndef ASSERT_NEEDS_STDLIB
-#define ASSERT_NEEDS_STDLIB 0
-#endif
-#ifndef NO_STDLIB_H
-#define NO_STDLIB_H 0
-#endif
-
-/* SunOS 4.1.x <assert.h> needs "stderr" defined, and "exit" declared... */
-#ifdef assert
-#if ASSERT_NEEDS_STDIO
-#include <stdio.h>
-#endif
-#if ASSERT_NEEDS_STDLIB
-#if !NO_STDLIB_H
-#include <stdlib.h>
-#endif
-#endif
-#endif
-
-#ifndef NO_MEMMOVE
-#define NO_MEMMOVE 0
-#endif
-#if NO_MEMMOVE	/* memove() not in libraries */
-#define memmove(dest,src,len) bcopy(src,dest,len)
-#endif
-
-#ifndef NO_MEMCPY
-#define NO_MEMCPY 0
-#endif
-#if NO_MEMCPY	/* memcpy() not in libraries */
-#define memcpy(dest,src,len) bcopy(src,dest,len)
-#endif
-
-#ifndef MEM_PROTOS_BROKEN
-#define MEM_PROTOS_BROKEN 0
-#endif
-#if MEM_PROTOS_BROKEN
-#define memcpy(d,s,l) memcpy((void *)(d), (void const *)(s), l)
-#define memmove(d,s,l) memmove((void *)(d), (void const *)(s), l)
-#define memcmp(d,s,l) memcmp((void const *)(d), (void const *)(s), l)
-#define memset(d,v,l) memset((void *)(d), v, l)
-#endif
-
-/*
- * If there are no prototypes for the stdio functions, use these to
- * reduce compiler warnings.  Uses EOF as a giveaway to indicate
- * that <stdio.h> was #included.
- */
-#ifndef NO_STDIO_PROTOS
-#define NO_STDIO_PROTOS 0
-#endif
-#if NO_STDIO_PROTOS	/* Missing prototypes for "simple" functions */
-#ifdef EOF
-#ifdef __cplusplus
-extern "C" {
-#endif
-int (puts)(char const *);
-int (fputs)(char const *, FILE *);
-int (fflush)(FILE *);
-int (printf)(char const *, ...);
-int (fprintf)(FILE *, char const *, ...);
-/* If we have a sufficiently old-fashioned stdio, it probably uses these... */
-int (_flsbuf)(int, FILE *);
-int (_filbuf)(FILE *);
-#ifdef __cplusplus
-}
-#endif
-#endif /* EOF */
-#endif /* NO_STDIO_PROTOS */
-
-/*
- * Borland C seems to think that it's a bad idea to decleare a
- * structure tag and not declare the contents.  I happen to think
- * it's a *good* idea to use such "opaque" structures wherever
- * possible.  So shut up.
- */
-#ifdef __BORLANDC__
-#pragma warn -stu
-#ifndef MSDOS
-#define MSDOS 1
-#endif
-#endif
-
-/* Turn off warning about negation of unsigned values */
-#ifdef _MSC_VER
-#pragma warning(disable:4146)
-#endif
-
-/* Cope with people forgetting to define the OS, if possible... */
-#ifndef MSDOS
-#ifdef __MSDOS
-#define MSDOS 1
-#endif
-#endif
-#ifndef MSDOS
-#ifdef __MSDOS__
-#define MSDOS 1
-#endif
-#endif
-
-/* By MS-DOS, we mean 16-bit brain-dead MS-DOS.  Not GCC & GO32 */
-#ifdef __GO32
-#undef MSDOS
-#endif
-#ifdef __GO32__
-#undef MSDOS
-#endif
-
-#endif /* KLUDGE_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn.h b/jni/libzrtp/sources/bnlib/lbn.h
deleted file mode 100644
index 25f3784..0000000
--- a/jni/libzrtp/sources/bnlib/lbn.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * lbn.h - Low-level bignum header.
- * Defines various word sizes and useful macros.
- * TODO: Rewrite this to use <stdint.h> and/or <inttypes.h>
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef LBN_H
-#define LBN_H
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_LIMITS_H
-#define NO_LIMITS_H 0
-#endif
-
-#include <stdint.h>             /* TODO: protect by configuration ifdef */
-
-/* Make sure we have 8-bit bytes */
-#if !NO_LIMITS_H
-#include <limits.h>
-#if UCHAR_MAX != 0xff || CHAR_BIT != 8
-#error The bignum library requires 8-bit unsigned characters.
-#endif
-#endif /* !NO_LIMITS_H */
-
-#ifdef BNINCLUDE	/* If this is defined as, say, foo.h */
-#define STR(x) #x	/* STR(BNINCLUDE) -> "BNINCLUDE" */
-#define XSTR(x) STR(x)	/* XSTR(BNINCLUDE) -> STR(foo.h) -> "foo.h" */
-#include XSTR(BNINCLUDE)	/* #include "foo.h" */
-#undef XSTR
-#undef STR
-#endif
-
-/* Do we want bnYield()? */
-#ifndef BNYIELD
-#define BNYIELD 0
-#endif
-
-/* Figure out the endianness */
-/* Error if more than one is defined */
-#if defined(BN_BIG_ENDIAN) && defined(BN_LITTLE_ENDIAN)
-#error Only one of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN may be defined
-#endif
-
-/*
- * If no preference is stated, little-endian C code is slightly more
- * efficient, so prefer that.  (The endianness here does NOT have to
- * match the machine's native byte sex; the library's C code will work
- * either way.  The flexibility is allowed for assembly routines
- * that do care.
- */
-#if !defined(BN_BIG_ENDIAN) && !defined(BN_LITTLE_ENDIAN)
-#define BN_LITTLE_ENDIAN 1
-#endif /* !BN_BIG_ENDIAN && !BN_LITTLE_ENDIAN */
-
-/* Macros to choose between big and little endian */
-#if defined(BN_BIG_ENDIAN)
-#define BIG(b) b
-#define LITTLE(l) /*nothing*/
-#define BIGLITTLE(b,l) b
-#elif BN_LITTLE_ENDIAN
-#define BIG(b) /*nothing*/
-#define LITTLE(l) l
-#define BIGLITTLE(b,l) l
-#else
-#error One of BN_BIG_ENDIAN or BN_LITTLE_ENDIAN must be defined as 1
-#endif
-
-
-/*
- * Define a 16-bit unsigned type if available.
- * Unsigned short is preferred over unsigned int to make the type chosen
- * by this file more stable on platforms (such as many 68000 compilers)
- * which support both 16- and 32-bit ints.
- */
-#ifndef BNWORD16
-#if !defined USHRT_MAX || USHRT_MAX == 0xffff ||  UINT_MAX == 0xffff
-#define BNWORD16 uint16_t
-#endif
-#endif /* BNWORD16 */
-
-/*
- * Define a 32-bit unsigned type if available.
- * Unsigned long is preferred over unsigned int to make the type chosen
- * by this file more stable on platforms (such as many 68000 compilers)
- * which support both 16- and 32-bit ints.
- */
-#ifndef BNWORD32
-#if !defined ULONG_MAX || ULONG_MAX == 0xfffffffful || UINT_MAX == 0xffffffff || USHRT_MAX == 0xffffffff
-#define BNWORD32 uint32_t
-#endif
-#endif /* BNWORD32 */
-
-/*
- * Find a 64-bit unsigned type.
- * The conditions here are more complicated to avoid using numbers that
- * will choke lesser preprocessors (like 0xffffffffffffffff) unless
- * we're reasonably certain that they'll be acceptable.
- */
-#if !defined(BNWORD64) && ULONG_MAX > 0xffffffffUL
-#if ULONG_MAX == 0xffffffffffffffff
-#define BNWORD64 uint64_t
-#endif
-#endif
-
-/*
- * I would test the value of unsigned long long, but some *preprocessors*
- * don't constants that long even if the compiler can accept them, so it
- * doesn't work reliably.  So cross our fingers and hope that it's a 64-bit
- * type.
- *
- * GCC uses ULONG_LONG_MAX.  Solaris uses ULLONG_MAX.  IRIX uses ULONGLONG_MAX.
- * Are there any other names for this?
- */
-#if !defined(BNWORD64) && \
-    (defined(ULONG_LONG_MAX) || defined (ULLONG_MAX) || defined(ULONGLONG_MAX))
-#define BNWORD64 uint64_t
-#endif
-
-/* We don't even try to find a 128-bit type at the moment */
-
-#endif /* !LBN_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn00.c b/jni/libzrtp/sources/bnlib/lbn00.c
deleted file mode 100644
index 228ff07..0000000
--- a/jni/libzrtp/sources/bnlib/lbn00.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * lbn00.c - auto-size-detecting lbn??.c file.
- *
- * Written in 1995 by Colin Plumb.
- */
-
-#include "bnsize00.h"
-
-#if BNSIZE64
-
-/* Include all of the C source file by reference */
-#include "lbn64.c"
-
-#elif BNSIZE32
-
-/* Include all of the C source file by reference */
-#include "lbn32.c"
-
-#else /* BNSIZE16 */
-
-/* Include all of the C source file by reference */
-#include "lbn16.c"
-
-#endif
diff --git a/jni/libzrtp/sources/bnlib/lbn16.c b/jni/libzrtp/sources/bnlib/lbn16.c
deleted file mode 100644
index 313094a..0000000
--- a/jni/libzrtp/sources/bnlib/lbn16.c
+++ /dev/null
@@ -1,4073 +0,0 @@
-/*
- * lbn16.c - Low-level bignum routines, 16-bit version.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * NOTE: the magic constants "16" and "32" appear in many places in this
- * file, including inside identifiers.  Because it is not possible to
- * ask "#ifdef" of a macro expansion, it is not possible to use the
- * preprocessor to conditionalize these properly.  Thus, this file is
- * intended to be edited with textual search and replace to produce
- * alternate word size versions.  Any reference to the number of bits
- * in a word must be the string "16", and that string must not appear
- * otherwise.  Any reference to twice this number must appear as "32",
- * which likewise must not appear otherwise.  Is that clear?
- *
- * Remember, when doubling the bit size replace the larger number (32)
- * first, then the smaller (16).  When halving the bit size, do the
- * opposite.  Otherwise, things will get wierd.  Also, be sure to replace
- * every instance that appears.  (:%s/foo/bar/g in vi)
- *
- * These routines work with a pointer to the least-significant end of
- * an array of WORD16s.  The BIG(x), LITTLE(y) and BIGLTTLE(x,y) macros
- * defined in lbn.h (which expand to x on a big-edian machine and y on a
- * little-endian machine) are used to conditionalize the code to work
- * either way.  If you have no assembly primitives, it doesn't matter.
- * Note that on a big-endian machine, the least-significant-end pointer
- * is ONE PAST THE END.  The bytes are ptr[-1] through ptr[-len].
- * On little-endian, they are ptr[0] through ptr[len-1].  This makes
- * perfect sense if you consider pointers to point *between* bytes rather
- * than at them.
- *
- * Because the array index values are unsigned integers, ptr[-i]
- * may not work properly, since the index -i is evaluated as an unsigned,
- * and if pointers are wider, zero-extension will produce a positive
- * number rahter than the needed negative.  The expression used in this
- * code, *(ptr-i) will, however, work.  (The array syntax is equivalent
- * to *(ptr+-i), which is a pretty subtle difference.)
- *
- * Many of these routines will get very unhappy if fed zero-length inputs.
- * They use assert() to enforce this.  An higher layer of code must make
- * sure that these aren't called with zero-length inputs.
- *
- * Any of these routines can be replaced with more efficient versions
- * elsewhere, by just #defining their names.  If one of the names
- * is #defined, the C code is not compiled in and no declaration is
- * made.  Use the BNINCLUDE file to do that.  Typically, you compile
- * asm subroutines with the same name and just, e.g.
- * #define lbnMulAdd1_16 lbnMulAdd1_16
- *
- * If you want to write asm routines, start with lbnMulAdd1_16().
- * This is the workhorse of modular exponentiation.  lbnMulN1_16() is
- * also used a fair bit, although not as much and it's defined in terms
- * of lbnMulAdd1_16 if that has a custom version.  lbnMulSub1_16 and
- * lbnDiv21_16 are used in the usual division and remainder finding.
- * (Not the Montgomery reduction used in modular exponentiation, though.)
- * Once you have lbnMulAdd1_16 defined, writing the other two should
- * be pretty easy.  (Just make sure you get the sign of the subtraction
- * in lbnMulSub1_16 right - it's dest = dest - source * k.)
- *
- * The only definitions that absolutely need a double-word (BNWORD32)
- * type are lbnMulAdd1_16 and lbnMulSub1_16; if those are provided,
- * the rest follows.  lbnDiv21_16, however, is a lot slower unless you
- * have them, and lbnModQ_16 takes after it.  That one is used quite a
- * bit for prime sieving.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h>	/* For memcpy */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "lbn.h"
-#include "lbn16.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef BNWORD16
-#error 16-bit bignum library requires a 16-bit data type
-#endif
-
-/* If this is defined, include bnYield() calls */
-#if BNYIELD
-extern int (*bnYield)(void);	/* From bn.c */
-#endif
-
-/*
- * Most of the multiply (and Montgomery reduce) routines use an outer
- * loop that iterates over one of the operands - a so-called operand
- * scanning approach.  One big advantage of this is that the assembly
- * support routines are simpler.  The loops can be rearranged to have
- * an outer loop that iterates over the product, a so-called product
- * scanning approach.  This has the advantage of writing less data
- * and doing fewer adds to memory, so is supposedly faster.  Some
- * code has been written using a product-scanning approach, but
- * it appears to be slower, so it is turned off by default.  Some
- * experimentation would be appreciated.
- *
- * (The code is also annoying to get right and not very well commented,
- * one of my pet peeves about math libraries.  I'm sorry.)
- */
-#ifndef PRODUCT_SCAN
-#define PRODUCT_SCAN 0
-#endif
-
-/*
- * Copy an array of words.  <Marvin mode on>  Thrilling, isn't it? </Marvin>
- * This is a good example of how the byte offsets and BIGLITTLE() macros work.
- * Another alternative would have been
- * memcpy(dest BIG(-len), src BIG(-len), len*sizeof(BNWORD16)), but I find that
- * putting operators into conditional macros is confusing.
- */
-#ifndef lbnCopy_16
-void
-lbnCopy_16(BNWORD16 *dest, BNWORD16 const *src, unsigned len)
-{
-	memcpy(BIGLITTLE(dest-len,dest), BIGLITTLE(src-len,src),
-	       len * sizeof(*src));
-}
-#endif /* !lbnCopy_16 */
-
-/*
- * Fill n words with zero.  This does it manually rather than calling
- * memset because it can assume alignment to make things faster while
- * memset can't.  Note how big-endian numbers are naturally addressed
- * using predecrement, while little-endian is postincrement.
- */
-#ifndef lbnZero_16
-void
-lbnZero_16(BNWORD16 *num, unsigned len)
-{
-	while (len--)
-		BIGLITTLE(*--num,*num++) = 0;
-}
-#endif /* !lbnZero_16 */
-
-/*
- * Negate an array of words.
- * Negation is subtraction from zero.  Negating low-order words
- * entails doing nothing until a non-zero word is hit.  Once that
- * is negated, a borrow is generated and never dies until the end
- * of the number is hit.  Negation with borrow, -x-1, is the same as ~x.
- * Repeat that until the end of the number.
- *
- * Doesn't return borrow out because that's pretty useless - it's
- * always set unless the input is 0, which is easy to notice in
- * normalized form.
- */
-#ifndef lbnNeg_16
-void
-lbnNeg_16(BNWORD16 *num, unsigned len)
-{
-	assert(len);
-
-	/* Skip low-order zero words */
-	while (BIGLITTLE(*--num,*num) == 0) {
-		if (!--len)
-			return;
-		LITTLE(num++;)
-	}
-	/* Negate the lowest-order non-zero word */
-	*num = -*num;
-	/* Complement all the higher-order words */
-	while (--len) {
-		BIGLITTLE(--num,++num);
-		*num = ~*num;
-	}
-}
-#endif /* !lbnNeg_16 */
-
-
-/*
- * lbnAdd1_16: add the single-word "carry" to the given number.
- * Used for minor increments and propagating the carry after
- * adding in a shorter bignum.
- *
- * Technique: If we have a double-width word, presumably the compiler
- * can add using its carry in inline code, so we just use a larger
- * accumulator to compute the carry from the first addition.
- * If not, it's more complex.  After adding the first carry, which may
- * be > 1, compare the sum and the carry.  If the sum wraps (causing a
- * carry out from the addition), the result will be less than each of the
- * inputs, since the wrap subtracts a number (2^16) which is larger than
- * the other input can possibly be.  If the sum is >= the carry input,
- * return success immediately.
- * In either case, if there is a carry, enter a loop incrementing words
- * until one does not wrap.  Since we are adding 1 each time, the wrap
- * will be to 0 and we can test for equality.
- */
-#ifndef lbnAdd1_16	/* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD32
-BNWORD16
-lbnAdd1_16(BNWORD16 *num, unsigned len, BNWORD16 carry)
-{
-	BNWORD32 t;
-	assert(len > 0);	/* Alternative: if (!len) return carry */
-
-	t = (BNWORD32)BIGLITTLE(*--num,*num) + carry;
-	BIGLITTLE(*num,*num++) = (BNWORD16)t;
-	if ((t >> 16) == 0)
-		return 0;
-	while (--len) {
-		if (++BIGLITTLE(*--num,*num++) != 0)
-			return 0;
-	}
-	return 1;
-}
-#else /* no BNWORD32 */
-BNWORD16
-lbnAdd1_16(BNWORD16 *num, unsigned len, BNWORD16 carry)
-{
-	assert(len > 0);	/* Alternative: if (!len) return carry */
-
-	if ((BIGLITTLE(*--num,*num++) += carry) >= carry)
-		return 0;
-	while (--len) {
-		if (++BIGLITTLE(*--num,*num++) != 0)
-			return 0;
-	}
-	return 1;
-}
-#endif
-#endif/* !lbnAdd1_16 */
-
-/*
- * lbnSub1_16: subtract the single-word "borrow" from the given number.
- * Used for minor decrements and propagating the borrow after
- * subtracting a shorter bignum.
- *
- * Technique: Similar to the add, above.  If there is a double-length type,
- * use that to generate the first borrow.
- * If not, after subtracting the first borrow, which may be > 1, compare
- * the difference and the *negative* of the carry.  If the subtract wraps
- * (causing a borrow out from the subtraction), the result will be at least
- * as large as -borrow.  If the result < -borrow, then no borrow out has
- * appeared and we may return immediately, except when borrow == 0.  To
- * deal with that case, use the identity that -x = ~x+1, and instead of
- * comparing < -borrow, compare for <= ~borrow.
- * Either way, if there is a borrow out, enter a loop decrementing words
- * until a non-zero word is reached.
- *
- * Note the cast of ~borrow to (BNWORD16).  If the size of an int is larger
- * than BNWORD16, C rules say the number is expanded for the arithmetic, so
- * the inversion will be done on an int and the value won't be quite what
- * is expected.
- */
-#ifndef lbnSub1_16	/* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD32
-BNWORD16
-lbnSub1_16(BNWORD16 *num, unsigned len, BNWORD16 borrow)
-{
-	BNWORD32 t;
-	assert(len > 0);	/* Alternative: if (!len) return borrow */
-
-	t = (BNWORD32)BIGLITTLE(*--num,*num) - borrow;
-	BIGLITTLE(*num,*num++) = (BNWORD16)t;
-	if ((t >> 16) == 0)
-		return 0;
-	while (--len) {
-		if ((BIGLITTLE(*--num,*num++))-- != 0)
-			return 0;
-	}
-	return 1;
-}
-#else /* no BNWORD32 */
-BNWORD16
-lbnSub1_16(BNWORD16 *num, unsigned len, BNWORD16 borrow)
-{
-	assert(len > 0);	/* Alternative: if (!len) return borrow */
-
-	if ((BIGLITTLE(*--num,*num++) -= borrow) <= (BNWORD16)~borrow)
-		return 0;
-	while (--len) {
-		if ((BIGLITTLE(*--num,*num++))-- != 0)
-			return 0;
-	}
-	return 1;
-}
-#endif
-#endif /* !lbnSub1_16 */
-
-/*
- * lbnAddN_16: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with lbnAdd1, of adding two bignums of
- * differing lengths.
- *
- * Technique: Maintain a word of carry.  If there is no double-width type,
- * use the same technique as in lbnAdd1, above, to maintain the carry by
- * comparing the inputs.  Adding the carry sources is used as an OR operator;
- * at most one of the two comparisons can possibly be true.  The first can
- * only be true if carry == 1 and x, the result, is 0.  In that case the
- * second can't possibly be true.
- */
-#ifndef lbnAddN_16
-#ifdef BNWORD32
-BNWORD16
-lbnAddN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
-	BNWORD32 t;
-
-	assert(len > 0);
-
-	t = (BNWORD32)BIGLITTLE(*--num1,*num1) + BIGLITTLE(*--num2,*num2++);
-	BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
-	while (--len) {
-		t = (BNWORD32)BIGLITTLE(*--num1,*num1) +
-		    (BNWORD32)BIGLITTLE(*--num2,*num2++) + (t >> 16);
-		BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
-	}
-
-	return (BNWORD16)(t>>16);
-}
-#else /* no BNWORD32 */
-BNWORD16
-lbnAddN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
-	BNWORD16 x, carry = 0;
-
-	assert(len > 0);	/* Alternative: change loop to test at start */
-
-	do {
-		x = BIGLITTLE(*--num2,*num2++);
-		carry = (x += carry) < carry;
-		carry += (BIGLITTLE(*--num1,*num1++) += x) < x;
-	} while (--len);
-
-	return carry;
-}
-#endif
-#endif /* !lbnAddN_16 */
-
-/*
- * lbnSubN_16: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with subn1, of subtracting two bignums of
- * differing lengths.
- *
- * Technique: If no double-width type is availble, maintain a word of borrow.
- * First, add the borrow to the subtrahend (did you have to learn all those
- * awful words in elementary school, too?), and if it overflows, set the
- * borrow again.  Then subtract the modified subtrahend from the next word
- * of input, using the same technique as in subn1, above.
- * Adding the borrows is used as an OR operator; at most one of the two
- * comparisons can possibly be true.  The first can only be true if
- * borrow == 1 and x, the result, is 0.  In that case the second can't
- * possibly be true.
- *
- * In the double-word case, (BNWORD16)-(t>>16) is subtracted, rather than
- * adding t>>16, because the shift would need to sign-extend and that's
- * not guaranteed to happen in ANSI C, even with signed types.
- */
-#ifndef lbnSubN_16
-#ifdef BNWORD32
-BNWORD16
-lbnSubN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
-	BNWORD32 t;
-
-	assert(len > 0);
-
-	t = (BNWORD32)BIGLITTLE(*--num1,*num1) - BIGLITTLE(*--num2,*num2++);
-	BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
-
-	while (--len) {
-		t = (BNWORD32)BIGLITTLE(*--num1,*num1) -
-		    (BNWORD32)BIGLITTLE(*--num2,*num2++) - (BNWORD16)-(t >> 16);
-		BIGLITTLE(*num1,*num1++) = (BNWORD16)t;
-	}
-
-	return -(BNWORD16)(t>>16);
-}
-#else
-BNWORD16
-lbnSubN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len)
-{
-	BNWORD16 x, borrow = 0;
-
-	assert(len > 0);	/* Alternative: change loop to test at start */
-
-	do {
-		x = BIGLITTLE(*--num2,*num2++);
-		borrow = (x += borrow) < borrow;
-		borrow += (BIGLITTLE(*--num1,*num1++) -= x) > (BNWORD16)~x;
-	} while (--len);
-
-	return borrow;
-}
-#endif
-#endif /* !lbnSubN_16 */
-
-#ifndef lbnCmp_16
-/*
- * lbnCmp_16: compare two bignums of equal length, returning the sign of
- * num1 - num2. (-1, 0 or +1).
- * 
- * Technique: Change the little-endian pointers to big-endian pointers
- * and compare from the most-significant end until a difference if found.
- * When it is, figure out the sign of the difference and return it.
- */
-int
-lbnCmp_16(BNWORD16 const *num1, BNWORD16 const *num2, unsigned len)
-{
-	BIGLITTLE(num1 -= len, num1 += len);
-	BIGLITTLE(num2 -= len, num2 += len);
-
-	while (len--) {
-		if (BIGLITTLE(*num1++ != *num2++, *--num1 != *--num2)) {
-			if (BIGLITTLE(num1[-1] < num2[-1], *num1 < *num2))
-				return -1;
-			else
-				return 1;
-		}
-	}
-	return 0;
-}
-#endif /* !lbnCmp_16 */
-
-/*
- * mul16_ppmmaa(ph,pl,x,y,a,b) is an optional routine that
- * computes (ph,pl) = x * y + a + b.  mul16_ppmma and mul16_ppmm
- * are simpler versions.  If you want to be lazy, all of these
- * can be defined in terms of the others, so here we create any
- * that have not been defined in terms of the ones that have been.
- */
-
-/* Define ones with fewer a's in terms of ones with more a's */
-#if !defined(mul16_ppmma) && defined(mul16_ppmmaa)
-#define mul16_ppmma(ph,pl,x,y,a) mul16_ppmmaa(ph,pl,x,y,a,0)
-#endif
-
-#if !defined(mul16_ppmm) && defined(mul16_ppmma)
-#define mul16_ppmm(ph,pl,x,y) mul16_ppmma(ph,pl,x,y,0)
-#endif
-
-/*
- * Use this definition to test the mul16_ppmm-based operations on machines
- * that do not provide mul16_ppmm.  Change the final "0" to a "1" to
- * enable it.
- */
-#if !defined(mul16_ppmm) && defined(BNWORD32) && 0	/* Debugging */
-#define mul16_ppmm(ph,pl,x,y) \
-	({BNWORD32 _ = (BNWORD32)(x)*(y); (pl) = _; (ph) = _>>16;})
-#endif
-
-#if defined(mul16_ppmm) && !defined(mul16_ppmma)
-#define mul16_ppmma(ph,pl,x,y,a) \
-	(mul16_ppmm(ph,pl,x,y), (ph) += ((pl) += (a)) < (a))
-#endif
-
-#if defined(mul16_ppmma) && !defined(mul16_ppmmaa)
-#define mul16_ppmmaa(ph,pl,x,y,a,b) \
-	(mul16_ppmma(ph,pl,x,y,a), (ph) += ((pl) += (b)) < (b))
-#endif
-
-/*
- * lbnMulN1_16: Multiply an n-word input by a 1-word input and store the
- * n+1-word product.  This uses either the mul16_ppmm and mul16_ppmma
- * macros, or C multiplication with the BNWORD32 type.  This uses mul16_ppmma
- * if available, assuming you won't bother defining it unless you can do
- * better than the normal multiplication.
- */
-#ifndef lbnMulN1_16
-#ifdef lbnMulAdd1_16	/* If we have this asm primitive, use it. */
-void
-lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
-	lbnZero_16(out, len);
-	BIGLITTLE(*(out-len-1),*(out+len)) = lbnMulAdd1_16(out, in, len, k);
-}
-#elif defined(mul16_ppmm)
-void
-lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
-	BNWORD16 carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--out;--in;);
-	mul16_ppmm(carry, *out, *in, k);
-	LITTLE(out++;in++;)
-
-	while (--len) {
-		BIG(--out;--in;)
-		carryin = carry;
-		mul16_ppmma(carry, *out, *in, k, carryin);
-		LITTLE(out++;in++;)
-	}
-	BIGLITTLE(*--out,*out) = carry;
-}
-#elif defined(BNWORD32)
-void
-lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
-	BNWORD32 p;
-
-	assert(len > 0);
-
-	p = (BNWORD32)BIGLITTLE(*--in,*in++) * k;
-	BIGLITTLE(*--out,*out++) = (BNWORD16)p;
-
-	while (--len) {
-		p = (BNWORD32)BIGLITTLE(*--in,*in++) * k + (BNWORD16)(p >> 16);
-		BIGLITTLE(*--out,*out++) = (BNWORD16)p;
-	}
-	BIGLITTLE(*--out,*out) = (BNWORD16)(p >> 16);
-}
-#else
-#error No 16x16 -> 32 multiply available for 16-bit bignum package
-#endif
-#endif /* lbnMulN1_16 */
-
-/*
- * lbnMulAdd1_16: Multiply an n-word input by a 1-word input and add the
- * low n words of the product to the destination.  *Returns the n+1st word
- * of the product.*  (That turns out to be more convenient than adding
- * it into the destination and dealing with a possible unit carry out
- * of *that*.)  This uses either the mul16_ppmma and mul16_ppmmaa macros,
- * or C multiplication with the BNWORD32 type.
- *
- * If you're going to write assembly primitives, this is the one to
- * start with.  It is by far the most commonly called function.
- */
-#ifndef lbnMulAdd1_16
-#if defined(mul16_ppmm)
-BNWORD16
-lbnMulAdd1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
-	BNWORD16 prod, carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--out;--in;);
-	carryin = *out;
-	mul16_ppmma(carry, *out, *in, k, carryin);
-	LITTLE(out++;in++;)
-
-	while (--len) {
-		BIG(--out;--in;);
-		carryin = carry;
-		mul16_ppmmaa(carry, prod, *in, k, carryin, *out);
-		*out = prod;
-		LITTLE(out++;in++;)
-	}
-
-	return carry;
-}
-#elif defined(BNWORD32)
-BNWORD16
-lbnMulAdd1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
-	BNWORD32 p;
-
-	assert(len > 0);
-
-	p = (BNWORD32)BIGLITTLE(*--in,*in++) * k + BIGLITTLE(*--out,*out);
-	BIGLITTLE(*out,*out++) = (BNWORD16)p;
-
-	while (--len) {
-		p = (BNWORD32)BIGLITTLE(*--in,*in++) * k +
-		    (BNWORD16)(p >> 16) + BIGLITTLE(*--out,*out);
-		BIGLITTLE(*out,*out++) = (BNWORD16)p;
-	}
-
-	return (BNWORD16)(p >> 16);
-}
-#else
-#error No 16x16 -> 32 multiply available for 16-bit bignum package
-#endif
-#endif /* lbnMulAdd1_16 */
-
-/*
- * lbnMulSub1_16: Multiply an n-word input by a 1-word input and subtract the
- * n-word product from the destination.  Returns the n+1st word of the product.
- * This uses either the mul16_ppmm and mul16_ppmma macros, or
- * C multiplication with the BNWORD32 type.
- *
- * This is rather uglier than adding, but fortunately it's only used in
- * division which is not used too heavily.
- */
-#ifndef lbnMulSub1_16
-#if defined(mul16_ppmm)
-BNWORD16
-lbnMulSub1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
-	BNWORD16 prod, carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--in;)
-	mul16_ppmm(carry, prod, *in, k);
-	LITTLE(in++;)
-	carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD16)~prod;
-
-	while (--len) {
-		BIG(--in;);
-		carryin = carry;
-		mul16_ppmma(carry, prod, *in, k, carryin);
-		LITTLE(in++;)
-		carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD16)~prod;
-	}
-
-	return carry;
-}
-#elif defined(BNWORD32)
-BNWORD16
-lbnMulSub1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k)
-{
-	BNWORD32 p;
-	BNWORD16 carry, t;
-
-	assert(len > 0);
-
-	p = (BNWORD32)BIGLITTLE(*--in,*in++) * k;
-	t = BIGLITTLE(*--out,*out);
-	carry = (BNWORD16)(p>>16) + ((BIGLITTLE(*out,*out++)=t-(BNWORD16)p) > t);
-
-	while (--len) {
-		p = (BNWORD32)BIGLITTLE(*--in,*in++) * k + carry;
-		t = BIGLITTLE(*--out,*out);
-		carry = (BNWORD16)(p>>16) +
-			( (BIGLITTLE(*out,*out++)=t-(BNWORD16)p) > t );
-	}
-
-	return carry;
-}
-#else
-#error No 16x16 -> 32 multiply available for 16-bit bignum package
-#endif
-#endif /* !lbnMulSub1_16 */
-
-/*
- * Shift n words left "shift" bits.  0 < shift < 16.  Returns the
- * carry, any bits shifted off the left-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnLshift_16
-BNWORD16
-lbnLshift_16(BNWORD16 *num, unsigned len, unsigned shift)
-{
-	BNWORD16 x, carry;
-
-	assert(shift > 0);
-	assert(shift < 16);
-
-	carry = 0;
-	while (len--) {
-		BIG(--num;)
-		x = *num;
-		*num = (x<<shift) | carry;
-		LITTLE(num++;)
-		carry = x >> (16-shift);
-	}
-	return carry;
-}
-#endif /* !lbnLshift_16 */
-
-/*
- * An optimized version of the above, for shifts of 1.
- * Some machines can use add-with-carry tricks for this.
- */
-#ifndef lbnDouble_16
-BNWORD16
-lbnDouble_16(BNWORD16 *num, unsigned len)
-{
-	BNWORD16 x, carry;
-
-	carry = 0;
-	while (len--) {
-		BIG(--num;)
-		x = *num;
-		*num = (x<<1) | carry;
-		LITTLE(num++;)
-		carry = x >> (16-1);
-	}
-	return carry;
-}
-#endif /* !lbnDouble_16 */
-
-/*
- * Shift n words right "shift" bits.  0 < shift < 16.  Returns the
- * carry, any bits shifted off the right-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnRshift_16
-BNWORD16
-lbnRshift_16(BNWORD16 *num, unsigned len, unsigned shift)
-{
-	BNWORD16 x, carry = 0;
-
-	assert(shift > 0);
-	assert(shift < 16);
-
-	BIGLITTLE(num -= len, num += len);
-
-	while (len--) {
-		LITTLE(--num;)
-		x = *num;
-		*num = (x>>shift) | carry;
-		BIG(num++;)
-		carry = x << (16-shift);
-	}
-	return carry >> (16-shift);
-}
-#endif /* !lbnRshift_16 */
-
-/* 
- * Multiply two numbers of the given lengths.  prod and num2 may overlap,
- * provided that the low len1 bits of prod are free.  (This corresponds
- * nicely to the place the result is returned from lbnMontReduce_16.)
- *
- * TODO: Use Karatsuba multiply.  The overlap constraints may have
- * to get rewhacked.
- */
-#ifndef lbnMul_16
-void
-lbnMul_16(BNWORD16 *prod, BNWORD16 const *num1, unsigned len1,
-                          BNWORD16 const *num2, unsigned len2)
-{
-	/* Special case of zero */
-	if (!len1 || !len2) {
-		lbnZero_16(prod, len1+len2);
-		return;
-	}
-
-	/* Multiply first word */
-	lbnMulN1_16(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-
-	/*
-	 * Add in subsequent words, storing the most significant word,
-	 * which is new each time.
-	 */
-	while (--len2) {
-		BIGLITTLE(--prod,prod++);
-		BIGLITTLE(*(prod-len1-1),*(prod+len1)) =
-		    lbnMulAdd1_16(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-	}
-}
-#endif /* !lbnMul_16 */
-
-/*
- * lbnMulX_16 is a square multiply - both inputs are the same length.
- * It's normally just a macro wrapper around the general multiply,
- * but might be implementable in assembly more efficiently (such as
- * when product scanning).
- */
-#ifndef lbnMulX_16
-#if defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Test code to see whether product scanning is any faster.  It seems
- * to make the C code slower, so PRODUCT_SCAN is not defined.
- */
-static void
-lbnMulX_16(BNWORD16 *prod, BNWORD16 const *num1, BNWORD16 const *num2,
-	unsigned len)
-{
-	BNWORD32 x, y;
-	BNWORD16 const *p1, *p2;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	x = (BNWORD32)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
-	BIGLITTLE(*--prod, *prod++) = (BNWORD16)x;
-	x >>= 16;
-
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = num1;
-		p2 = BIGLITTLE(num2-i-1,num2+i+1);
-		for (j = 0; j <= i; j++) {
-			BIG(y = (BNWORD32)*--p1 * *p2++;)
-			LITTLE(y = (BNWORD32)*p1++ * *--p2;)
-			x += y;
-			carry += (x < y);
-		}
-		BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
-		x = (x >> 16) | (BNWORD32)carry << 16;
-	}
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = BIGLITTLE(num1-i,num1+i);
-		p2 = BIGLITTLE(num2-len,num2+len);
-		for (j = i; j < len; j++) {
-			BIG(y = (BNWORD32)*--p1 * *p2++;)
-			LITTLE(y = (BNWORD32)*p1++ * *--p2;)
-			x += y;
-			carry += (x < y);
-		}
-		BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
-		x = (x >> 16) | (BNWORD32)carry << 16;
-	}
-	
-	BIGLITTLE(*--prod,*prod) = (BNWORD16)x;
-}
-#else /* !defined(BNWORD32) || !PRODUCT_SCAN */
-/* Default trivial macro definition */
-#define lbnMulX_16(prod, num1, num2, len) lbnMul_16(prod, num1, len, num2, len)
-#endif /* !defined(BNWORD32) || !PRODUCT_SCAN */
-#endif /* !lbmMulX_16 */
-
-#if !defined(lbnMontMul_16) && defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Test code for product-scanning multiply.  This seems to slow the C
- * code down rather than speed it up.
- * This does a multiply and Montgomery reduction together, using the
- * same loops.  The outer loop scans across the product, twice.
- * The first pass computes the low half of the product and the
- * Montgomery multipliers.  These are stored in the product array,
- * which contains no data as of yet.  x and carry add up the columns
- * and propagate carries forward.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers.  The results of this multiply
- * are stored.
- */
-static void
-lbnMontMul_16(BNWORD16 *prod, BNWORD16 const *num1, BNWORD16 const *num2,
-	BNWORD16 const *mod, unsigned len, BNWORD16 inv)
-{
-	BNWORD32 x, y;
-	BNWORD16 const *p1, *p2, *pm;
-	BNWORD16 *pp;
-	BNWORD16 t;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	/*
-	 * This computes directly into the high half of prod, so just
-	 * shift the pointer and consider prod only "len" elements long
-	 * for the rest of the code.
-	 */
-	BIGLITTLE(prod -= len, prod += len);
-
-	/* Pass 1 - compute Montgomery multipliers */
-	/* First iteration can have certain simplifications. */
-	x = (BNWORD32)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
-	BIGLITTLE(prod[-1], prod[0]) = t = inv * (BNWORD16)x;
-	y = (BNWORD32)t * BIGLITTLE(mod[-1],mod[0]);
-	x += y;
-	/* Note: GCC 2.6.3 has a bug if you try to eliminate "carry" */
-	carry = (x < y);
-	assert((BNWORD16)x == 0);
-	x = x >> 16 | (BNWORD32)carry << 16;
-
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = num1;
-		p2 = BIGLITTLE(num2-i-1,num2+i+1);
-		pp = prod;
-		pm = BIGLITTLE(mod-i-1,mod+i+1);
-		for (j = 0; j < i; j++) {
-			y = (BNWORD32)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
-			x += y;
-			carry += (x < y);
-			y = (BNWORD32)BIGLITTLE(*--pp * *pm++, *pp++ * *--pm);
-			x += y;
-			carry += (x < y);
-		}
-		y = (BNWORD32)BIGLITTLE(p1[-1] * p2[0], p1[0] * p2[-1]);
-		x += y;
-		carry += (x < y);
-		assert(BIGLITTLE(pp == prod-i, pp == prod+i));
-		BIGLITTLE(pp[-1], pp[0]) = t = inv * (BNWORD16)x;
-		assert(BIGLITTLE(pm == mod-1, pm == mod+1));
-		y = (BNWORD32)t * BIGLITTLE(pm[0],pm[-1]);
-		x += y;
-		carry += (x < y);
-		assert((BNWORD16)x == 0);
-		x = x >> 16 | (BNWORD32)carry << 16;
-	}
-
-	/* Pass 2 - compute reduced product and store */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = BIGLITTLE(num1-i,num1+i);
-		p2 = BIGLITTLE(num2-len,num2+len);
-		pm = BIGLITTLE(mod-i,mod+i);
-		pp = BIGLITTLE(prod-len,prod+len);
-		for (j = i; j < len; j++) {
-			y = (BNWORD32)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
-			x += y;
-			carry += (x < y);
-			y = (BNWORD32)BIGLITTLE(*--pm * *pp++, *pm++ * *--pp);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pm == mod-len, pm == mod+len));
-		assert(BIGLITTLE(pp == prod-i, pp == prod+i));
-		BIGLITTLE(pp[0],pp[-1]) = (BNWORD16)x;
-		x = (x >> 16) | (BNWORD32)carry << 16;
-	}
-
-	/* Last round of second half, simplified. */
-	BIGLITTLE(*(prod-len),*(prod+len-1)) = (BNWORD16)x;
-	carry = (x >> 16);
-
-	while (carry)
-		carry -= lbnSubN_16(prod, mod, len);
-	while (lbnCmp_16(prod, mod, len) >= 0)
-		(void)lbnSubN_16(prod, mod, len);
-}
-/* Suppress later definition */
-#define lbnMontMul_16 lbnMontMul_16
-#endif
-
-#if !defined(lbnSquare_16) && defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Trial code for product-scanning squaring.  This seems to slow the C
- * code down rather than speed it up.
- */
-void
-lbnSquare_16(BNWORD16 *prod, BNWORD16 const *num, unsigned len)
-{
-	BNWORD32 x, y, z;
-	BNWORD16 const *p1, *p2;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	/* Word 0 of product */
-	x = (BNWORD32)BIGLITTLE(num[-1] * num[-1], num[0] * num[0]);
-	BIGLITTLE(*--prod, *prod++) = (BNWORD16)x;
-	x >>= 16;
-
-	/* Words 1 through len-1 */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		y = 0;
-		p1 = num;
-		p2 = BIGLITTLE(num-i-1,num+i+1);
-		for (j = 0; j < (i+1)/2; j++) {
-			BIG(z = (BNWORD32)*--p1 * *p2++;)
-			LITTLE(z = (BNWORD32)*p1++ * *--p2;)
-			y += z;
-			carry += (y < z);
-		}
-		y += z = y;
-		carry += carry + (y < z);
-		if ((i & 1) == 0) {
-			assert(BIGLITTLE(--p1 == p2, p1 == --p2));
-			BIG(z = (BNWORD32)*p2 * *p2;)
-			LITTLE(z = (BNWORD32)*p1 * *p1;)
-			y += z;
-			carry += (y < z);
-		}
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
-		x = (x >> 16) | (BNWORD32)carry << 16;
-	}
-	/* Words len through 2*len-2 */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		y = 0;
-		p1 = BIGLITTLE(num-i,num+i);
-		p2 = BIGLITTLE(num-len,num+len);
-		for (j = 0; j < (len-i)/2; j++) {
-			BIG(z = (BNWORD32)*--p1 * *p2++;)
-			LITTLE(z = (BNWORD32)*p1++ * *--p2;)
-			y += z;
-			carry += (y < z);
-		}
-		y += z = y;
-		carry += carry + (y < z);
-		if ((len-i) & 1) {
-			assert(BIGLITTLE(--p1 == p2, p1 == --p2));
-			BIG(z = (BNWORD32)*p2 * *p2;)
-			LITTLE(z = (BNWORD32)*p1 * *p1;)
-			y += z;
-			carry += (y < z);
-		}
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*--prod,*prod++) = (BNWORD16)x;
-		x = (x >> 16) | (BNWORD32)carry << 16;
-	}
-	
-	/* Word 2*len-1 */
-	BIGLITTLE(*--prod,*prod) = (BNWORD16)x;
-}
-/* Suppress later definition */
-#define lbnSquare_16 lbnSquare_16
-#endif
-
-/*
- * Square a number, using optimized squaring to reduce the number of
- * primitive multiples that are executed.  There may not be any
- * overlap of the input and output.
- *
- * Technique: Consider the partial products in the multiplication
- * of "abcde" by itself:
- *
- *               a  b  c  d  e
- *            *  a  b  c  d  e
- *          ==================
- *              ae be ce de ee
- *           ad bd cd dd de
- *        ac bc cc cd ce
- *     ab bb bc bd be
- *  aa ab ac ad ae
- *
- * Note that everything above the main diagonal:
- *              ae be ce de = (abcd) * e
- *           ad bd cd       = (abc) * d
- *        ac bc             = (ab) * c
- *     ab                   = (a) * b
- *
- * is a copy of everything below the main diagonal:
- *                       de
- *                 cd ce
- *           bc bd be
- *     ab ac ad ae
- *
- * Thus, the sum is 2 * (off the diagonal) + diagonal.
- *
- * This is accumulated beginning with the diagonal (which
- * consist of the squares of the digits of the input), which is then
- * divided by two, the off-diagonal added, and multiplied by two
- * again.  The low bit is simply a copy of the low bit of the
- * input, so it doesn't need special care.
- *
- * TODO: Merge the shift by 1 with the squaring loop.
- * TODO: Use Karatsuba.  (a*W+b)^2 = a^2 * (W^2+W) + b^2 * (W+1) - (a-b)^2 * W.
- */
-#ifndef lbnSquare_16
-void
-lbnSquare_16(BNWORD16 *prod, BNWORD16 const *num, unsigned len)
-{
-	BNWORD16 t;
-	BNWORD16 *prodx = prod;		/* Working copy of the argument */
-	BNWORD16 const *numx = num;	/* Working copy of the argument */
-	unsigned lenx = len;		/* Working copy of the argument */
-
-	if (!len)
-		return;
-
-	/* First, store all the squares */
-	while (lenx--) {
-#ifdef mul16_ppmm
-		BNWORD16 ph, pl;
-		t = BIGLITTLE(*--numx,*numx++);
-		mul16_ppmm(ph,pl,t,t);
-		BIGLITTLE(*--prodx,*prodx++) = pl;
-		BIGLITTLE(*--prodx,*prodx++) = ph;
-#elif defined(BNWORD32) /* use BNWORD32 */
-		BNWORD32 p;
-		t = BIGLITTLE(*--numx,*numx++);
-		p = (BNWORD32)t * t;
-		BIGLITTLE(*--prodx,*prodx++) = (BNWORD16)p;
-		BIGLITTLE(*--prodx,*prodx++) = (BNWORD16)(p>>16);
-#else	/* Use lbnMulN1_16 */
-		t = BIGLITTLE(numx[-1],*numx);
-		lbnMulN1_16(prodx, numx, 1, t);
-		BIGLITTLE(--numx,numx++);
-		BIGLITTLE(prodx -= 2, prodx += 2);
-#endif
-	}
-	/* Then, shift right 1 bit */
-	(void)lbnRshift_16(prod, 2*len, 1);
-
-	/* Then, add in the off-diagonal sums */
-	lenx = len;
-	numx = num;
-	prodx = prod;
-	while (--lenx) {
-		t = BIGLITTLE(*--numx,*numx++);
-		BIGLITTLE(--prodx,prodx++);
-		t = lbnMulAdd1_16(prodx, numx, lenx, t);
-		lbnAdd1_16(BIGLITTLE(prodx-lenx,prodx+lenx), lenx+1, t);
-		BIGLITTLE(--prodx,prodx++);
-	}
-
-	/* Shift it back up */
-	lbnDouble_16(prod, 2*len);
-
-	/* And set the low bit appropriately */
-	BIGLITTLE(prod[-1],prod[0]) |= BIGLITTLE(num[-1],num[0]) & 1;
-}
-#endif /* !lbnSquare_16 */
-
-/*
- * lbnNorm_16 - given a number, return a modified length such that the
- * most significant digit is non-zero.  Zero-length input is okay.
- */
-#ifndef lbnNorm_16
-unsigned
-lbnNorm_16(BNWORD16 const *num, unsigned len)
-{
-	BIGLITTLE(num -= len,num += len);
-	while (len && BIGLITTLE(*num++,*--num) == 0)
-		--len;
-	return len;
-}
-#endif /* lbnNorm_16 */
-
-/*
- * lbnBits_16 - return the number of significant bits in the array.
- * It starts by normalizing the array.  Zero-length input is okay.
- * Then assuming there's anything to it, it fetches the high word,
- * generates a bit length by multiplying the word length by 16, and
- * subtracts off 16/2, 16/4, 16/8, ... bits if the high bits are clear.
- */
-#ifndef lbnBits_16
-unsigned
-lbnBits_16(BNWORD16 const *num, unsigned len)
-{
-	BNWORD16 t;
-	unsigned i;
-
-	len = lbnNorm_16(num, len);
-	if (len) {
-		t = BIGLITTLE(*(num-len),*(num+(len-1)));
-		assert(t);
-		len *= 16;
-		i = 16/2;
-		do {
-			if (t >> i)
-				t >>= i;
-			else
-				len -= i;
-		} while ((i /= 2) != 0);
-	}
-	return len;
-}
-#endif /* lbnBits_16 */
-
-/*
- * If defined, use hand-rolled divide rather than compiler's native.
- * If the machine doesn't do it in line, the manual code is probably
- * faster, since it can assume normalization and the fact that the
- * quotient will fit into 16 bits, which a general 32-bit divide
- * in a compiler's run-time library can't do.
- */
-#ifndef BN_SLOW_DIVIDE_32
-/* Assume that divisors of more than thirty-two bits are slow */
-#define BN_SLOW_DIVIDE_32 (32 > 0x20)
-#endif
-
-/*
- * Return (nh<<16|nl) % d, and place the quotient digit into *q.
- * It is guaranteed that nh < d, and that d is normalized (with its high
- * bit set).  If we have a double-width type, it's easy.  If not, ooh,
- * yuk!
- */
-#ifndef lbnDiv21_16
-#if defined(BNWORD32) && !BN_SLOW_DIVIDE_32
-BNWORD16
-lbnDiv21_16(BNWORD16 *q, BNWORD16 nh, BNWORD16 nl, BNWORD16 d)
-{
-	BNWORD32 n = (BNWORD32)nh << 16 | nl;
-
-	/* Divisor must be normalized */
-	assert(d >> (16-1) == 1);
-
-	*q = n / d;
-	return n % d;
-}
-#else
-/*
- * This is where it gets ugly.
- *
- * Do the division in two halves, using Algorithm D from section 4.3.1
- * of Knuth.  Note Theorem B from that section, that the quotient estimate
- * is never more than the true quotient, and is never more than two
- * too low.
- *
- * The mapping onto conventional long division is (everything a half word):
- *        _____________qh___ql_
- * dh dl ) nh.h nh.l nl.h nl.l
- *             - (qh * d)
- *            -----------
- *              rrrr rrrr nl.l
- *                  - (ql * d)
- *                -----------
- *                  rrrr rrrr
- *
- * The implicit 3/2-digit d*qh and d*ql subtractors are computed this way:
- *   First, estimate a q digit so that nh/dh works.  Subtracting qh*dh from
- *   the (nh.h nh.l) list leaves a 1/2-word remainder r.  Then compute the
- *   low part of the subtractor, qh * dl.   This also needs to be subtracted
- *   from (nh.h nh.l nl.h) to get the final remainder.  So we take the
- *   remainder, which is (nh.h nh.l) - qh*dl, shift it and add in nl.h, and
- *   try to subtract qh * dl from that.  Since the remainder is 1/2-word
- *   long, shifting and adding nl.h results in a single word r.
- *   It is possible that the remainder we're working with, r, is less than
- *   the product qh * dl, if we estimated qh too high.  The estimation
- *   technique can produce a qh that is too large (never too small), leading
- *   to r which is too small.  In that case, decrement the digit qh, add
- *   shifted dh to r (to correct for that error), and subtract dl from the
- *   product we're comparing r with.  That's the "correct" way to do it, but
- *   just adding dl to r instead of subtracting it from the product is
- *   equivalent and a lot simpler.  You just have to watch out for overflow.
- *
- *   The process is repeated with (rrrr rrrr nl.l) for the low digit of the
- *   quotient ql.
- *
- * The various uses of 16/2 for shifts are because of the note about
- * automatic editing of this file at the very top of the file.
- */
-#define highhalf(x) ( (x) >> 16/2 )
-#define lowhalf(x) ( (x) & (((BNWORD16)1 << 16/2)-1) )
-BNWORD16
-lbnDiv21_16(BNWORD16 *q, BNWORD16 nh, BNWORD16 nl, BNWORD16 d)
-{
-	BNWORD16 dh = highhalf(d), dl = lowhalf(d);
-	BNWORD16 qh, ql, prod, r;
-
-	/* Divisor must be normalized */
-	assert((d >> (16-1)) == 1);
-
-	/* Do first half-word of division */
-	qh = nh / dh;
-	r = nh % dh;
-	prod = qh * dl;
-
-	/*
-	 * Add next half-word of numerator to remainder and correct.
-	 * qh may be up to two too large.
-	 */
-	r = (r << (16/2)) | highhalf(nl);
-	if (r < prod) {
-		--qh; r += d;
-		if (r >= d && r < prod) {
-			--qh; r += d; 
-		}
-	}
-	r -= prod;
-
-	/* Do second half-word of division */
-	ql = r / dh;
-	r = r % dh;
-	prod = ql * dl;
-
-	r = (r << (16/2)) | lowhalf(nl);
-	if (r < prod) {
-		--ql; r += d;
-		if (r >= d && r < prod) {
-			--ql; r += d;
-		}
-	}
-	r -= prod;
-
-	*q = (qh << (16/2)) | ql;
-
-	return r;
-}
-#endif
-#endif /* lbnDiv21_16 */
-
-
-/*
- * In the division functions, the dividend and divisor are referred to
- * as "n" and "d", which stand for "numerator" and "denominator".
- *
- * The quotient is (nlen-dlen+1) digits long.  It may be overlapped with
- * the high (nlen-dlen) words of the dividend, but one extra word is needed
- * on top to hold the top word.
- */
-
-/*
- * Divide an n-word number by a 1-word number, storing the remainder
- * and n-1 words of the n-word quotient.  The high word is returned.
- * It IS legal for rem to point to the same address as n, and for
- * q to point one word higher.
- *
- * TODO: If BN_SLOW_DIVIDE_32, add a divnhalf_16 which uses 16-bit
- *       dividends if the divisor is half that long.
- * TODO: Shift the dividend on the fly to avoid the last division and
- *       instead have a remainder that needs shifting.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef lbnDiv1_16
-BNWORD16
-lbnDiv1_16(BNWORD16 *q, BNWORD16 *rem, BNWORD16 const *n, unsigned len,
-	BNWORD16 d)
-{
-	unsigned shift;
-	unsigned xlen;
-	BNWORD16 r;
-	BNWORD16 qhigh;
-
-	assert(len > 0);
-	assert(d);
-
-	if (len == 1) {
-		r = *n;
-		*rem = r%d;
-		return r/d;
-	}
-
-	shift = 0;
-	r = d;
-	xlen = 16/2;
-	do {
-		if (r >> xlen)
-			r >>= xlen;
-		else
-			shift += xlen;
-	} while ((xlen /= 2) != 0);
-	assert((d >> (16-1-shift)) == 1);
-	d <<= shift;
-
-	BIGLITTLE(q -= len-1,q += len-1);
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	if (r < d) {
-		qhigh = 0;
-	} else {
-		qhigh = r/d;
-		r %= d;
-	}
-
-	xlen = len;
-	while (--xlen)
-		r = lbnDiv21_16(BIGLITTLE(q++,--q), r, BIGLITTLE(*n++,*--n), d);
-
-	/*
-	 * Final correction for shift - shift the quotient up "shift"
-	 * bits, and merge in the extra bits of quotient.  Then reduce
-	 * the final remainder mod the real d.
-	 */
-	if (shift) {
-		d >>= shift;
-		qhigh = (qhigh << shift) | lbnLshift_16(q, len-1, shift);
-		BIGLITTLE(q[-1],*q) |= r/d;
-		r %= d;
-	}
-	*rem = r;
-
-	return qhigh;
-}
-#endif
-
-/*
- * This function performs a "quick" modulus of a number with a divisor
- * d which is guaranteed to be at most sixteen bits, i.e. less than 65536.
- * This applies regardless of the word size the library is compiled with.
- *
- * This function is important to prime generation, for sieving.
- */
-#ifndef lbnModQ_16
-/* If there's a custom lbnMod21_16, no normalization needed */
-#ifdef lbnMod21_16
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
-	unsigned i, shift;
-	BNWORD16 r;
-
-	assert(len > 0);
-
-	BIGLITTLE(n -= len,n += len);
-
-	/* Try using a compare to avoid the first divide */
-	r = BIGLITTLE(*n++,*--n);
-	if (r >= d)
-		r %= d;
-	while (--len)
-		r = lbnMod21_16(r, BIGLITTLE(*n++,*--n), d);
-
-	return r;
-}
-#elif defined(BNWORD32) && !BN_SLOW_DIVIDE_32
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
-	BNWORD16 r;
-
-	if (!--len)
-		return BIGLITTLE(n[-1],n[0]) % d;
-
-	BIGLITTLE(n -= len,n += len);
-	r = BIGLITTLE(n[-1],n[0]);
-
-	do {
-		r = (BNWORD16)((((BNWORD32)r<<16) | BIGLITTLE(*n++,*--n)) % d);
-	} while (--len);
-
-	return r;
-}
-#elif 16 >= 0x20
-/*
- * If the single word size can hold 65535*65536, then this function
- * is avilable.
- */
-#ifndef highhalf
-#define highhalf(x) ( (x) >> 16/2 )
-#define lowhalf(x) ( (x) & ((1 << 16/2)-1) )
-#endif
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
-	BNWORD16 r, x;
-
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	while (--len) {
-		x = BIGLITTLE(*n++,*--n);
-		r = (r%d << 16/2) | highhalf(x);
-		r = (r%d << 16/2) | lowhalf(x);
-	}
-
-	return r%d;
-}
-#else
-/* Default case - use lbnDiv21_16 */
-unsigned
-lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d)
-{
-	unsigned i, shift;
-	BNWORD16 r;
-	BNWORD16 q;
-
-	assert(len > 0);
-
-	shift = 0;
-	r = d;
-	i = 16;
-	while (i /= 2) {
-		if (r >> i)
-			r >>= i;
-		else
-			shift += i;
-	}
-	assert(d >> (16-1-shift) == 1);
-	d <<= shift;
-
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	if (r >= d)
-		r %= d;
-
-	while (--len)
-		r = lbnDiv21_16(&q, r, BIGLITTLE(*n++,*--n), d);
-
-	/*
-	 * Final correction for shift - shift the quotient up "shift"
-	 * bits, and merge in the extra bits of quotient.  Then reduce
-	 * the final remainder mod the real d.
-	 */
-	if (shift)
-		r %= d >> shift;
-
-	return r;
-}
-#endif
-#endif /* lbnModQ_16 */
-
-/*
- * Reduce n mod d and return the quotient.  That is, find:
- * q = n / d;
- * n = n % d;
- * d is altered during the execution of this subroutine by normalizing it.
- * It must already have its most significant word non-zero; it is shifted
- * so its most significant bit is non-zero.
- *
- * The quotient q is nlen-dlen+1 words long.  To make it possible to
- * overlap the quptient with the input (you can store it in the high dlen
- * words), the high word of the quotient is *not* stored, but is returned.
- * (If all you want is the remainder, you don't care about it, anyway.)
- *
- * This uses algorithm D from Knuth (4.3.1), except that we do binary
- * (shift) normalization of the divisor.  WARNING: This is hairy!
- *
- * This function is used for some modular reduction, but it is not used in
- * the modular exponentiation loops; they use Montgomery form and the
- * corresponding, more efficient, Montgomery reduction.  This code
- * is needed for the conversion to Montgomery form, however, so it
- * has to be here and it might as well be reasonably efficient.
- *
- * The overall operation is as follows ("top" and "up" refer to the
- * most significant end of the number; "bottom" and "down", the least):
- *
- * - Shift the divisor up until the most significant bit is set.
- * - Shift the dividend up the same amount.  This will produce the
- *   correct quotient, and the remainder can be recovered by shifting
- *   it back down the same number of bits.  This may produce an overflow
- *   word, but the word is always strictly less than the most significant
- *   divisor word.
- * - Estimate the first quotient digit qhat:
- *   - First take the top two words (one of which is the overflow) of the
- *     dividend and divide by the top word of the divisor:
- *     qhat = (nh,nm)/dh.  This qhat is >= the correct quotient digit
- *     and, since dh is normalized, it is at most two over.
- *   - Second, correct by comparing the top three words.  If
- *     (dh,dl) * qhat > (nh,nm,ml), decrease qhat and try again.
- *     The second iteration can be simpler because there can't be a third.
- *     The computation can be simplified by subtracting dh*qhat from
- *     both sides, suitably shifted.  This reduces the left side to
- *     dl*qhat.  On the right, (nh,nm)-dh*qhat is simply the
- *     remainder r from (nh,nm)%dh, so the right is (r,nl).
- *     This produces qhat that is almost always correct and at
- *     most (prob ~ 2/2^16) one too high.
- * - Subtract qhat times the divisor (suitably shifted) from the dividend.
- *   If there is a borrow, qhat was wrong, so decrement it
- *   and add the divisor back in (once).
- * - Store the final quotient digit qhat in the quotient array q.
- *
- * Repeat the quotient digit computation for successive digits of the
- * quotient until the whole quotient has been computed.  Then shift the
- * divisor and the remainder down to correct for the normalization.
- *
- * TODO: Special case 2-word divisors.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef divn_16
-BNWORD16
-lbnDiv_16(BNWORD16 *q, BNWORD16 *n, unsigned nlen, BNWORD16 *d, unsigned dlen)
-{
-	BNWORD16 nh,nm,nl;	/* Top three words of the dividend */
-	BNWORD16 dh,dl;	/* Top two words of the divisor */
-	BNWORD16 qhat;	/* Extimate of quotient word */
-	BNWORD16 r;	/* Remainder from quotient estimate division */
-	BNWORD16 qhigh;	/* High word of quotient */
-	unsigned i;	/* Temp */
-	unsigned shift;	/* Bits shifted by normalization */
-	unsigned qlen = nlen-dlen; /* Size of quotient (less 1) */
-#ifdef mul16_ppmm
-	BNWORD16 t16;
-#elif defined(BNWORD32)
-	BNWORD32 t32;
-#else /* use lbnMulN1_16 */
-	BNWORD16 t2[2];
-#define t2high BIGLITTLE(t2[0],t2[1])
-#define t2low BIGLITTLE(t2[1],t2[0])
-#endif
-
-	assert(dlen);
-	assert(nlen >= dlen);
-
-	/*
-	 * Special cases for short divisors.  The general case uses the
-	 * top top 2 digits of the divisor (d) to estimate a quotient digit,
-	 * so it breaks if there are fewer digits available.  Thus, we need
-	 * special cases for a divisor of length 1.  A divisor of length
-	 * 2 can have a *lot* of administrivia overhead removed removed,
-	 * so it's probably worth special-casing that case, too.
-	 */
-	if (dlen == 1)
-		return lbnDiv1_16(q, BIGLITTLE(n-1,n), n, nlen,
-		                  BIGLITTLE(d[-1],d[0]));
-
-#if 0
-	/*
-	 * @@@ This is not yet written...  The general loop will do,
-	 * albeit less efficiently
-	 */
-	if (dlen == 2) {
-		/*
-		 * divisor two digits long:
-		 * use the 3/2 technique from Knuth, but we know
-		 * it's exact.
-		 */
-		dh = BIGLITTLE(d[-1],d[0]);
-		dl = BIGLITTLE(d[-2],d[1]);
-		shift = 0;
-		if ((sh & ((BNWORD16)1 << 16-1-shift)) == 0) {
-			do {
-				shift++;
-			} while (dh & (BNWORD16)1<<16-1-shift) == 0);
-			dh = dh << shift | dl >> (16-shift);
-			dl <<= shift;
-
-
-		}
-
-
-		for (shift = 0; (dh & (BNWORD16)1 << 16-1-shift)) == 0; shift++)
-			;
-		if (shift) {
-		}
-		dh = dh << shift | dl >> (16-shift);
-		shift = 0;
-		while (dh
-	}
-#endif
-
-	dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
-	assert(dh);
-
-	/* Normalize the divisor */
-	shift = 0;
-	r = dh;
-	i = 16/2;
-	do {
-		if (r >> i)
-			r >>= i;
-		else
-			shift += i;
-	} while ((i /= 2) != 0);
-
-	nh = 0;
-	if (shift) {
-		lbnLshift_16(d, dlen, shift);
-		dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
-		nh = lbnLshift_16(n, nlen, shift);
-	}
-
-	/* Assert that dh is now normalized */
-	assert(dh >> (16-1));
-
-	/* Also get the second-most significant word of the divisor */
-	dl = BIGLITTLE(*(d-(dlen-1)),*(d+(dlen-2)));
-
-	/*
-	 * Adjust pointers: n to point to least significant end of first
-	 * first subtract, and q to one the most-significant end of the
-	 * quotient array.
-	 */
-	BIGLITTLE(n -= qlen,n += qlen);
-	BIGLITTLE(q -= qlen,q += qlen);
-
-	/* Fetch the most significant stored word of the dividend */
-	nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
-	/*
-	 * Compute the first digit of the quotient, based on the
-	 * first two words of the dividend (the most significant of which
-	 * is the overflow word h).
-	 */
-	if (nh) {
-		assert(nh < dh);
-		r = lbnDiv21_16(&qhat, nh, nm, dh);
-	} else if (nm >= dh) {
-		qhat = nm/dh;
-		r = nm % dh;
-	} else {	/* Quotient is zero */
-		qhigh = 0;
-		goto divloop;
-	}
-
-	/* Now get the third most significant word of the dividend */
-	nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-
-	/*
-	 * Correct qhat, the estimate of quotient digit.
-	 * qhat can only be high, and at most two words high,
-	 * so the loop can be unrolled and abbreviated.
-	 */
-#ifdef mul16_ppmm
-	mul16_ppmm(nm, t16, qhat, dl);
-	if (nm > r || (nm == r && t16 > nl)) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) >= dh) {
-			nm -= (t16 < dl);
-			t16 -= dl;
-			if (nm > r || (nm == r && t16 > nl))
-				qhat--;
-		}
-	}
-#elif defined(BNWORD32)
-	t32 = (BNWORD32)qhat * dl;
-	if (t32 > ((BNWORD32)r << 16) + nl) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) > dh) {
-			t32 -= dl;
-			if (t32 > ((BNWORD32)r << 16) + nl)
-				qhat--;
-		}
-	}
-#else /* Use lbnMulN1_16 */
-	lbnMulN1_16(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
-	if (t2high > r || (t2high == r && t2low > nl)) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) >= dh) {
-			t2high -= (t2low < dl);
-			t2low -= dl;
-			if (t2high > r || (t2high == r && t2low > nl))
-				qhat--;
-		}
-	}
-#endif
-
-	/* Do the multiply and subtract */
-	r = lbnMulSub1_16(n, d, dlen, qhat);
-	/* If there was a borrow, add back once. */
-	if (r > nh) {	/* Borrow? */
-		(void)lbnAddN_16(n, d, dlen);
-		qhat--;
-	}
-
-	/* Remember the first quotient digit. */
-	qhigh = qhat;
-
-	/* Now, the main division loop: */
-divloop:
-	while (qlen--) {
-
-		/* Advance n */
-		nh = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-		BIGLITTLE(++n,--n);
-		nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
-		if (nh == dh) {
-			qhat = ~(BNWORD16)0;
-			/* Optimized computation of r = (nh,nm) - qhat * dh */
-			r = nh + nm;
-			if (r < nh)
-				goto subtract;
-		} else {
-			assert(nh < dh);
-			r = lbnDiv21_16(&qhat, nh, nm, dh);
-		}
-
-		nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-#ifdef mul16_ppmm
-		mul16_ppmm(nm, t16, qhat, dl);
-		if (nm > r || (nm == r && t16 > nl)) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				nm -= (t16 < dl);
-				t16 -= dl;
-				if (nm > r || (nm == r && t16 > nl))
-					qhat--;
-			}
-		}
-#elif defined(BNWORD32)
-		t32 = (BNWORD32)qhat * dl;
-		if (t32 > ((BNWORD32)r<<16) + nl) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				t32 -= dl;
-				if (t32 > ((BNWORD32)r << 16) + nl)
-					qhat--;
-			}
-		}
-#else /* Use lbnMulN1_16 */
-		lbnMulN1_16(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
-		if (t2high > r || (t2high == r && t2low > nl)) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				t2high -= (t2low < dl);
-				t2low -= dl;
-				if (t2high > r || (t2high == r && t2low > nl))
-					qhat--;
-			}
-		}
-#endif
-
-		/*
-		 * As a point of interest, note that it is not worth checking
-		 * for qhat of 0 or 1 and installing special-case code.  These
-		 * occur with probability 2^-16, so spending 1 cycle to check
-		 * for them is only worth it if we save more than 2^15 cycles,
-		 * and a multiply-and-subtract for numbers in the 1024-bit
-		 * range just doesn't take that long.
-		 */
-subtract:
-		/*
-		 * n points to the least significant end of the substring
-		 * of n to be subtracted from.  qhat is either exact or
-		 * one too large.  If the subtract gets a borrow, it was
-		 * one too large and the divisor is added back in.  It's
-		 * a dlen+1 word add which is guaranteed to produce a
-		 * carry out, so it can be done very simply.
-		 */
-		r = lbnMulSub1_16(n, d, dlen, qhat);
-		if (r > nh) {	/* Borrow? */
-			(void)lbnAddN_16(n, d, dlen);
-			qhat--;
-		}
-		/* Store the quotient digit */
-		BIGLITTLE(*q++,*--q) = qhat;
-	}
-	/* Tah dah! */
-
-	if (shift) {
-		lbnRshift_16(d, dlen, shift);
-		lbnRshift_16(n, dlen, shift);
-	}
-
-	return qhigh;
-}
-#endif
-
-/*
- * Find the negative multiplicative inverse of x (x must be odd!) modulo 2^16.
- *
- * This just performs Newton's iteration until it gets the
- * inverse.  The initial estimate is always correct to 3 bits, and
- * sometimes 4.  The number of valid bits doubles each iteration.
- * (To prove it, assume x * y == 1 (mod 2^n), and introduce a variable
- * for the error mod 2^2n.  x * y == 1 + k*2^n (mod 2^2n) and follow
- * the iteration through.)
- */
-#ifndef lbnMontInv1_16
-BNWORD16
-lbnMontInv1_16(BNWORD16 const x)
-{
-        BNWORD16 y = x, z;
-
-	assert(x & 1);
- 
-        while ((z = x*y) != 1)
-                y *= 2 - z;
-        return -y;
-}
-#endif /* !lbnMontInv1_16 */
-
-#if defined(BNWORD32) && PRODUCT_SCAN
-/*
- * Test code for product-scanning Montgomery reduction.
- * This seems to slow the C code down rather than speed it up.
- *
- * The first loop computes the Montgomery multipliers, storing them over
- * the low half of the number n.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers.  The results of this multiply
- * are stored.
- */
-void
-lbnMontReduce_16(BNWORD16 *n, BNWORD16 const *mod, unsigned mlen, BNWORD16 inv)
-{
-	BNWORD32 x, y;
-	BNWORD16 const *pm;
-	BNWORD16 *pn;
-	BNWORD16 t;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!mlen)
-		return;
-
-	/* Pass 1 - compute Montgomery multipliers */
-	/* First iteration can have certain simplifications. */
-	t = BIGLITTLE(n[-1],n[0]);
-	x = t;
-	t *= inv;
-	BIGLITTLE(n[-1], n[0]) = t;
-	x += (BNWORD32)t * BIGLITTLE(mod[-1],mod[0]); /* Can't overflow */
-	assert((BNWORD16)x == 0);
-	x = x >> 16;
-
-	for (i = 1; i < mlen; i++) {
-		carry = 0;
-		pn = n;
-		pm = BIGLITTLE(mod-i-1,mod+i+1);
-		for (j = 0; j < i; j++) {
-			y = (BNWORD32)BIGLITTLE(*--pn * *pm++, *pn++ * *--pm);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pn == n-i, pn == n+i));
-		y = t = BIGLITTLE(pn[-1], pn[0]);
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(pn[-1], pn[0]) = t = inv * (BNWORD16)x;
-		assert(BIGLITTLE(pm == mod-1, pm == mod+1));
-		y = (BNWORD32)t * BIGLITTLE(pm[0],pm[-1]);
-		x += y;
-		carry += (x < y);
-		assert((BNWORD16)x == 0);
-		x = x >> 16 | (BNWORD32)carry << 16;
-	}
-
-	BIGLITTLE(n -= mlen, n += mlen);
-
-	/* Pass 2 - compute upper words and add to n */
-	for (i = 1; i < mlen; i++) {
-		carry = 0;
-		pm = BIGLITTLE(mod-i,mod+i);
-		pn = n;
-		for (j = i; j < mlen; j++) {
-			y = (BNWORD32)BIGLITTLE(*--pm * *pn++, *pm++ * *--pn);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pm == mod-mlen, pm == mod+mlen));
-		assert(BIGLITTLE(pn == n+mlen-i, pn == n-mlen+i));
-		y = t = BIGLITTLE(*(n-i),*(n+i-1));
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*(n-i),*(n+i-1)) = (BNWORD16)x;
-		x = (x >> 16) | (BNWORD32)carry << 16;
-	}
-
-	/* Last round of second half, simplified. */
-	t = BIGLITTLE(*(n-mlen),*(n+mlen-1));
-	x += t;
-	BIGLITTLE(*(n-mlen),*(n+mlen-1)) = (BNWORD16)x;
-	carry = (unsigned)(x >> 16);
-
-	while (carry)
-		carry -= lbnSubN_16(n, mod, mlen);
-	while (lbnCmp_16(n, mod, mlen) >= 0)
-		(void)lbnSubN_16(n, mod, mlen);
-}
-#define lbnMontReduce_16 lbnMontReduce_16
-#endif
-
-/*
- * Montgomery reduce n, modulo mod.  This reduces modulo mod and divides by
- * 2^(16*mlen).  Returns the result in the *top* mlen words of the argument n.
- * This is ready for another multiplication using lbnMul_16.
- *
- * Montgomery representation is a very useful way to encode numbers when
- * you're doing lots of modular reduction.  What you do is pick a multiplier
- * R which is relatively prime to the modulus and very easy to divide by.
- * Since the modulus is odd, R is closen as a power of 2, so the division
- * is a shift.  In fact, it's a shift of an integral number of words,
- * so the shift can be implicit - just drop the low-order words.
- *
- * Now, choose R *larger* than the modulus m, 2^(16*mlen).  Then convert
- * all numbers a, b, etc. to Montgomery form M(a), M(b), etc using the
- * relationship M(a) = a*R mod m, M(b) = b*R mod m, etc.  Note that:
- * - The Montgomery form of a number depends on the modulus m.
- *   A fixed modulus m is assumed throughout this discussion.
- * - Since R is relaitvely prime to m, multiplication by R is invertible;
- *   no information about the numbers is lost, they're just scrambled.
- * - Adding (and subtracting) numbers in this form works just as usual.
- *   M(a+b) = (a+b)*R mod m = (a*R + b*R) mod m = (M(a) + M(b)) mod m
- * - Multiplying numbers in this form produces a*b*R*R.  The problem
- *   is to divide out the excess factor of R, modulo m as well as to
- *   reduce to the given length mlen.  It turns out that this can be
- *   done *faster* than a normal divide, which is where the speedup
- *   in Montgomery division comes from.
- *
- * Normal reduction chooses a most-significant quotient digit q and then
- * subtracts q*m from the number to be reduced.  Choosing q is tricky
- * and involved (just look at lbnDiv_16 to see!) and is usually
- * imperfect, requiring a check for correction after the subtraction.
- *
- * Montgomery reduction *adds* a multiple of m to the *low-order* part
- * of the number to be reduced.  This multiple is chosen to make the
- * low-order part of the number come out to zero.  This can be done
- * with no trickery or error using a precomputed inverse of the modulus.
- * In this code, the "part" is one word, but any width can be used.
- *
- * Repeating this step sufficiently often results in a value which
- * is a multiple of R (a power of two, remember) but is still (since
- * the additions were to the low-order part and thus did not increase
- * the value of the number being reduced very much) still not much
- * larger than m*R.  Then implicitly divide by R and subtract off
- * m until the result is in the correct range.
- *
- * Since the low-order part being cancelled is less than R, the
- * multiple of m added must have a multiplier which is at most R-1.
- * Assuming that the input is at most m*R-1, the final number is
- * at most m*(2*R-1)-1 = 2*m*R - m - 1, so subtracting m once from
- * the high-order part, equivalent to subtracting m*R from the
- * while number, produces a result which is at most m*R - m - 1,
- * which divided by R is at most m-1.
- *
- * To convert *to* Montgomery form, you need a regular remainder
- * routine, although you can just compute R*R (mod m) and do the
- * conversion using Montgomery multiplication.  To convert *from*
- * Montgomery form, just Montgomery reduce the number to
- * remove the extra factor of R.
- * 
- * TODO: Change to a full inverse and use Karatsuba's multiplication
- * rather than this word-at-a-time.
- */
-#ifndef lbnMontReduce_16
-void
-lbnMontReduce_16(BNWORD16 *n, BNWORD16 const *mod, unsigned const mlen,
-                BNWORD16 inv)
-{
-	BNWORD16 t;
-	BNWORD16 c = 0;
-	unsigned len = mlen;
-
-	/* inv must be the negative inverse of mod's least significant word */
-	assert((BNWORD16)(inv * BIGLITTLE(mod[-1],mod[0])) == (BNWORD16)-1);
-
-	assert(len);
-
-	do {
-		t = lbnMulAdd1_16(n, mod, mlen, inv * BIGLITTLE(n[-1],n[0]));
-		c += lbnAdd1_16(BIGLITTLE(n-mlen,n+mlen), len, t);
-		BIGLITTLE(--n,++n);
-	} while (--len);
-
-	/*
-	 * All that adding can cause an overflow past the modulus size,
-	 * but it's unusual, and never by much, so a subtraction loop
-	 * is the right way to deal with it.
-	 * This subtraction happens infrequently - I've only ever seen it
-	 * invoked once per reduction, and then just under 22.5% of the time.
-	 */
-	while (c)
-		c -= lbnSubN_16(n, mod, mlen);
-	while (lbnCmp_16(n, mod, mlen) >= 0)
-		(void)lbnSubN_16(n, mod, mlen);
-}
-#endif /* !lbnMontReduce_16 */
-
-/*
- * A couple of helpers that you might want to implement atomically
- * in asm sometime.
- */
-#ifndef lbnMontMul_16
-/*
- * Multiply "num1" by "num2", modulo "mod", all of length "len", and
- * place the result in the high half of "prod".  "inv" is the inverse
- * of the least-significant word of the modulus, modulo 2^16.
- * This uses numbers in Montgomery form.  Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontMul_16(prod, n1, n2, mod, len, inv) \
-	(lbnMulX_16(prod, n1, n2, len), lbnMontReduce_16(prod, mod, len, inv))
-#endif /* !lbnMontMul_16 */
-
-#ifndef lbnMontSquare_16
-/*
- * Square "n", modulo "mod", both of length "len", and place the result
- * in the high half of "prod".  "inv" is the inverse of the least-significant
- * word of the modulus, modulo 2^16.
- * This uses numbers in Montgomery form.  Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontSquare_16(prod, n, mod, len, inv) \
-	(lbnSquare_16(prod, n, len), lbnMontReduce_16(prod, mod, len, inv))
-	
-#endif /* !lbnMontSquare_16 */
-
-/*
- * Convert a number to Montgomery form - requires mlen + nlen words
- * of memory in "n".
- */
-void
-lbnToMont_16(BNWORD16 *n, unsigned nlen, BNWORD16 *mod, unsigned mlen)
-{
-	/* Move n up "mlen" words */
-	lbnCopy_16(BIGLITTLE(n-mlen,n+mlen), n, nlen);
-	lbnZero_16(n, mlen);
-	/* Do the division - dump the quotient in the high-order words */
-	(void)lbnDiv_16(BIGLITTLE(n-mlen,n+mlen), n, mlen+nlen, mod, mlen);
-}
-
-/*
- * Convert from Montgomery form.  Montgomery reduction is all that is
- * needed.
- */
-void
-lbnFromMont_16(BNWORD16 *n, BNWORD16 *mod, unsigned len)
-{
-	/* Zero the high words of n */
-	lbnZero_16(BIGLITTLE(n-len,n+len), len);
-	lbnMontReduce_16(n, mod, len, lbnMontInv1_16(mod[BIGLITTLE(-1,0)]));
-	/* Move n down len words */
-	lbnCopy_16(n, BIGLITTLE(n-len,n+len), len);
-}
-
-/*
- * The windowed exponentiation algorithm, precomputes a table of odd
- * powers of n up to 2^k.  See the comment in bnExpMod_16 below for
- * an explanation of how it actually works works.
- *
- * It takes 2^(k-1)-1 multiplies to compute the table, and (e-1)/(k+1)
- * multiplies (on average) to perform the exponentiation.  To minimize
- * the sum, k must vary with e.  The optimal window sizes vary with the
- * exponent length.  Here are some selected values and the boundary cases.
- * (An underscore _ has been inserted into some of the numbers to ensure
- * that magic strings like 16 do not appear in this table.  It should be
- * ignored.)
- *
- * At e =    1 bits, k=1   (0.000000) is best
- * At e =    2 bits, k=1   (0.500000) is best
- * At e =    4 bits, k=1   (1.500000) is best
- * At e =    8 bits, k=2   (3.333333) < k=1   (3.500000)
- * At e =  1_6 bits, k=2   (6.000000) is best
- * At e =   26 bits, k=3   (9.250000) < k=2   (9.333333)
- * At e =  3_2 bits, k=3  (10.750000) is best
- * At e =  6_4 bits, k=3  (18.750000) is best
- * At e =   82 bits, k=4  (23.200000) < k=3  (23.250000)
- * At e =  128 bits, k=4 (3_2.400000) is best
- * At e =  242 bits, k=5  (55.1_66667) < k=4 (55.200000)
- * At e =  256 bits, k=5  (57.500000) is best
- * At e =  512 bits, k=5 (100.1_66667) is best
- * At e =  674 bits, k=6 (127.142857) < k=5 (127.1_66667)
- * At e = 1024 bits, k=6 (177.142857) is best
- * At e = 1794 bits, k=7 (287.125000) < k=6 (287.142857)
- * At e = 2048 bits, k=7 (318.875000) is best
- * At e = 4096 bits, k=7 (574.875000) is best
- *
- * The numbers in parentheses are the expected number of multiplications
- * needed to do the computation.  The normal russian-peasant modular
- * exponentiation technique always uses (e-1)/2.  For exponents as
- * small as 192 bits (below the range of current factoring algorithms),
- * half of the multiplies are eliminated, 45.2 as opposed to the naive
- * 95.5.  Counting the 191 squarings as 3/4 a multiply each (squaring
- * proper is just over half of multiplying, but the Montgomery
- * reduction in each case is also a multiply), that's 143.25
- * multiplies, for totals of 188.45 vs. 238.75 - a 21% savings.
- * For larger exponents (like 512 bits), it's 483.92 vs. 639.25, a
- * 24.3% savings.  It asymptotically approaches 25%.
- *
- * Um, actually there's a slightly more accurate way to count, which
- * really is the average number of multiplies required, averaged
- * uniformly over all 2^(e-1) e-bit numbers, from 2^(e-1) to (2^e)-1.
- * It's based on the recurrence that for the last b bits, b <= k, at
- * most one multiply is needed (and none at all 1/2^b of the time),
- * while when b > k, the odds are 1/2 each way that the bit will be
- * 0 (meaning no multiplies to reduce it to the b-1-bit case) and
- * 1/2 that the bit will be 1, starting a k-bit window and requiring
- * 1 multiply beyond the b-k-bit case.  Since the most significant
- * bit is always 1, a k-bit window always starts there, and that
- * multiply is by 1, so it isn't a multiply at all.  Thus, the
- * number of multiplies is simply that needed for the last e-k bits.
- * This recurrence produces:
- *
- * At e =    1 bits, k=1   (0.000000) is best
- * At e =    2 bits, k=1   (0.500000) is best
- * At e =    4 bits, k=1   (1.500000) is best
- * At e =    6 bits, k=2   (2.437500) < k=1   (2.500000)
- * At e =    8 bits, k=2   (3.109375) is best
- * At e =  1_6 bits, k=2   (5.777771) is best
- * At e =   24 bits, k=3   (8.437629) < k=2   (8.444444)
- * At e =  3_2 bits, k=3  (10.437492) is best
- * At e =  6_4 bits, k=3  (18.437500) is best
- * At e =   81 bits, k=4  (22.6_40000) < k=3  (22.687500)
- * At e =  128 bits, k=4 (3_2.040000) is best
- * At e =  241 bits, k=5  (54.611111) < k=4  (54.6_40000)
- * At e =  256 bits, k=5  (57.111111) is best
- * At e =  512 bits, k=5  (99.777778) is best
- * At e =  673 bits, k=6 (126.591837) < k=5 (126.611111)
- * At e = 1024 bits, k=6 (176.734694) is best
- * At e = 1793 bits, k=7 (286.578125) < k=6 (286.591837)
- * At e = 2048 bits, k=7 (318.453125) is best
- * At e = 4096 bits, k=7 (574.453125) is best
- *
- * This has the rollover points at 6, 24, 81, 241, 673 and 1793 instead
- * of 8, 26, 82, 242, 674, and 1794.  Not a very big difference.
- * (The numbers past that are k=8 at 4609 and k=9 at 11521,
- * vs. one more in each case for the approximation.)
- *
- * Given that exponents for which k>7 are useful are uncommon,
- * a fixed size table for k <= 7 is used for simplicity.
- *
- * The basic number of squarings needed is e-1, although a k-bit
- * window (for k > 1) can save, on average, k-2 of those, too.
- * That savings currently isn't counted here.  It would drive the
- * crossover points slightly lower.
- * (Actually, this win is also reduced in the DoubleExpMod case,
- * meaning we'd have to split the tables.  Except for that, the
- * multiplies by powers of the two bases are independent, so
- * the same logic applies to each as the single case.)
- *
- * Table entry i is the largest number of bits in an exponent to
- * process with a window size of i+1.  Entry 6 is the largest
- * possible unsigned number, so the window will never be more
- * than 7 bits, requiring 2^6 = 0x40 slots.
- */
-#define BNEXPMOD_MAX_WINDOW	7
-static unsigned const bnExpModThreshTable[BNEXPMOD_MAX_WINDOW] = {
-	5, 23, 80, 240, 672, 1792, (unsigned)-1
-/*	7, 25, 81, 241, 673, 1793, (unsigned)-1	 ### The old approximations */
-};
-
-/*
- * Perform modular exponentiation, as fast as possible!  This uses
- * Montgomery reduction, optimized squaring, and windowed exponentiation.
- * The modulus "mod" MUST be odd!
- *
- * This returns 0 on success, -1 on out of memory.
- *
- * The window algorithm:
- * The idea is to keep a running product of b1 = n^(high-order bits of exp),
- * and then keep appending exponent bits to it.  The following patterns
- * apply to a 3-bit window (k = 3):
- * To append   0: square
- * To append   1: square, multiply by n^1
- * To append  10: square, multiply by n^1, square
- * To append  11: square, square, multiply by n^3
- * To append 100: square, multiply by n^1, square, square
- * To append 101: square, square, square, multiply by n^5
- * To append 110: square, square, multiply by n^3, square
- * To append 111: square, square, square, multiply by n^7
- *
- * Since each pattern involves only one multiply, the longer the pattern
- * the better, except that a 0 (no multiplies) can be appended directly.
- * We precompute a table of odd powers of n, up to 2^k, and can then
- * multiply k bits of exponent at a time.  Actually, assuming random
- * exponents, there is on average one zero bit between needs to
- * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
- * 1/8 of the time, there's 2, 1/16 of the time, there's 3, etc.), so
- * you have to do one multiply per k+1 bits of exponent.
- *
- * The loop walks down the exponent, squaring the result buffer as
- * it goes.  There is a wbits+1 bit lookahead buffer, buf, that is
- * filled with the upcoming exponent bits.  (What is read after the
- * end of the exponent is unimportant, but it is filled with zero here.)
- * When the most-significant bit of this buffer becomes set, i.e.
- * (buf & tblmask) != 0, we have to decide what pattern to multiply
- * by, and when to do it.  We decide, remember to do it in future
- * after a suitable number of squarings have passed (e.g. a pattern
- * of "100" in the buffer requires that we multiply by n^1 immediately;
- * a pattern of "110" calls for multiplying by n^3 after one more
- * squaring), clear the buffer, and continue.
- *
- * When we start, there is one more optimization: the result buffer
- * is implcitly one, so squaring it or multiplying by it can be
- * optimized away.  Further, if we start with a pattern like "100"
- * in the lookahead window, rather than placing n into the buffer
- * and then starting to square it, we have already computed n^2
- * to compute the odd-powers table, so we can place that into
- * the buffer and save a squaring.
- *
- * This means that if you have a k-bit window, to compute n^z,
- * where z is the high k bits of the exponent, 1/2 of the time
- * it requires no squarings.  1/4 of the time, it requires 1
- * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
- * And the remaining 1/2^(k-1) of the time, the top k bits are a
- * 1 followed by k-1 0 bits, so it again only requires k-2
- * squarings, not k-1.  The average of these is 1.  Add that
- * to the one squaring we have to do to compute the table,
- * and you'll see that a k-bit window saves k-2 squarings
- * as well as reducing the multiplies.  (It actually doesn't
- * hurt in the case k = 1, either.)
- *
- * n must have mlen words allocated.  Although fewer may be in use
- * when n is passed in, all are in use on exit.
- */
-int
-lbnExpMod_16(BNWORD16 *result, BNWORD16 const *n, unsigned nlen,
-	BNWORD16 const *e, unsigned elen, BNWORD16 *mod, unsigned mlen)
-{
-	BNWORD16 *table[1 << (BNEXPMOD_MAX_WINDOW-1)];
-				/* Table of odd powers of n */
-	unsigned ebits;		/* Exponent bits */
-	unsigned wbits;		/* Window size */
-	unsigned tblmask;	/* Mask of exponentiation window */
-	BNWORD16 bitpos;	/* Mask of current look-ahead bit */
-	unsigned buf;		/* Buffer of exponent bits */
-	unsigned multpos;	/* Where to do pending multiply */
-	BNWORD16 const *mult;	/* What to multiply by */
-	unsigned i;		/* Loop counter */
-	int isone;		/* Flag: accum. is implicitly one */
-	BNWORD16 *a, *b;	/* Working buffers/accumulators */
-	BNWORD16 *t;		/* Pointer into the working buffers */
-	BNWORD16 inv;		/* mod^-1 modulo 2^16 */
-	int y;			/* bnYield() result */
-
-	assert(mlen);
-	assert(nlen <= mlen);
-
-	/* First, a couple of trivial cases. */
-	elen = lbnNorm_16(e, elen);
-	if (!elen) {
-		/* x ^ 0 == 1 */
-		lbnZero_16(result, mlen);
-		BIGLITTLE(result[-1],result[0]) = 1;
-		return 0;
-	}
-	ebits = lbnBits_16(e, elen);
-	if (ebits == 1) {
-		/* x ^ 1 == x */
-		if (n != result)
-			lbnCopy_16(result, n, nlen);
-		if (mlen > nlen)
-			lbnZero_16(BIGLITTLE(result-nlen,result+nlen),
-			           mlen-nlen);
-		return 0;
-	}
-
-	/* Okay, now move the exponent pointer to the most-significant word */
-	e = BIGLITTLE(e-elen, e+elen-1);
-
-	/* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
-	wbits = 0;
-	while (ebits > bnExpModThreshTable[wbits])
-		wbits++;
-
-	/* Allocate working storage: two product buffers and the tables. */
-	LBNALLOC(a, BNWORD16, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD16, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert to the appropriate table size: tblmask = 1<<(k-1) */
-	tblmask = 1u << wbits;
-
-	/* We have the result buffer available, so use it. */
-	table[0] = result;
-
-	/*
-	 * Okay, we now have a minimal-sized table - expand it.
-	 * This is allowed to fail!  If so, scale back the table size
-	 * and proceed.
-	 */
-	for (i = 1; i < tblmask; i++) {
-		LBNALLOC(t, BNWORD16, mlen);
-		if (!t)	/* Out of memory!  Quit the loop. */
-			break;
-		table[i] = t;
-	}
-
-	/* If we stopped, with i < tblmask, shrink the tables appropriately */
-	while (tblmask > i) {
-		wbits--;
-		tblmask >>= 1;
-	}
-	/* Free up our overallocations */
-	while (--i > tblmask)
-		LBNFREE(table[i], mlen);
-
-	/* Okay, fill in the table */
-
-	/* Compute the necessary modular inverse */
-	inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	/* Convert n to Montgomery form */
-
-	/* Move n up "mlen" words into a */
-	t = BIGLITTLE(a-mlen, a+mlen);
-	lbnCopy_16(t, n, nlen);
-	lbnZero_16(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_16(t, a, mlen+nlen, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_16(table[0], a, mlen);
-
-	/* Square a into b */
-	lbnMontSquare_16(b, a, mod, mlen, inv);
-
-	/* Use high half of b to initialize the table */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	for (i = 1; i < tblmask; i++) {
-		lbnMontMul_16(a, t, table[i-1], mod, mlen, inv);
-		lbnCopy_16(table[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* We might use b = n^2 later... */
-
-	/* Initialze the fetch pointer */
-	bitpos = (BNWORD16)1 << ((ebits-1) & (16-1));	/* Initialize mask */
-
-	/* This should point to the msbit of e */
-	assert((*e & bitpos) != 0);
-
-	/*
-	 * Pre-load the window.  Becuase the window size is
-	 * never larger than the exponent size, there is no need to
-	 * detect running off the end of e in here.
-	 *
-	 * The read-ahead is controlled by elen and the bitpos mask.
-	 * Note that this is *ahead* of ebits, which tracks the
-	 * most significant end of the window.  The purpose of this
-	 * initialization is to get the two wbits+1 bits apart,
-	 * like they should be.
-	 *
-	 * Note that bitpos and e1len together keep track of the
-	 * lookahead read pointer in the exponent that is used here.
-	 */
-	buf = 0;
-	for (i = 0; i <= wbits; i++) {
-		buf = (buf << 1) | ((*e & bitpos) != 0);
-		bitpos >>= 1;
-		if (!bitpos) {
-			BIGLITTLE(e++,e--);
-			bitpos = (BNWORD16)1 << (16-1);
-			elen--;
-		}
-	}
-	assert(buf & tblmask);
-
-	/*
-	 * Set the pending multiply positions to a location that will
-	 * never be encountered, thus ensuring that nothing will happen
-	 * until the need for a multiply appears and one is scheduled.
-	 */
-	multpos = ebits;	/* A NULL value */
-	mult = 0;	/* Force a crash if we use these */
-
-	/*
-	 * Okay, now begins the real work.  The first step is
-	 * slightly magic, so it's done outside the main loop,
-	 * but it's very similar to what's inside.
-	 */
-	ebits--;	/* Start processing the first bit... */
-	isone = 1;
-
-	/*
-	 * This is just like the multiply in the loop, except that
-	 * - We know the msbit of buf is set, and
-	 * - We have the extra value n^2 floating around.
-	 * So, do the usual computation, and if the result is that
-	 * the buffer should be multiplied by n^1 immediately
-	 * (which we'd normally then square), we multiply it
-	 * (which reduces to a copy, which reduces to setting a flag)
-	 * by n^2 and skip the squaring.  Thus, we do the
-	 * multiply and the squaring in one step.
-	 */
-	assert(buf & tblmask);
-	multpos = ebits - wbits;
-	while ((buf & 1) == 0) {
-		buf >>= 1;
-		multpos++;
-	}
-	/* Intermediates can wrap, but final must NOT */
-	assert(multpos <= ebits);
-	mult = table[buf>>1];
-	buf = 0;
-
-	/* Special case: use already-computed value sitting in buffer */
-	if (multpos == ebits)
-		isone = 0;
-
-	/*
-	 * At this point, the buffer (which is the high half of b) holds
-	 * either 1 (implicitly, as the "isone" flag is set), or n^2.
-	 */
-
-	/*
-	 * The main loop.  The procedure is:
-	 * - Advance the window
-	 * - If the most-significant bit of the window is set,
-	 *   schedule a multiply for the appropriate time in the
-	 *   future (may be immediately)
-	 * - Perform any pending multiples
-	 * - Check for termination
-	 * - Square the buffer
-	 *
-	 * At any given time, the acumulated product is held in
-	 * the high half of b.
-	 */
-	for (;;) {
-		ebits--;
-
-		/* Advance the window */
-		assert(buf < tblmask);
-		buf <<= 1;
-		/*
-		 * This reads ahead of the current exponent position
-		 * (controlled by ebits), so we have to be able to read
-		 * past the lsb of the exponents without error.
-		 */
-		if (elen) {
-			buf |= ((*e & bitpos) != 0);
-			bitpos >>= 1;
-			if (!bitpos) {
-				BIGLITTLE(e++,e--);
-				bitpos = (BNWORD16)1 << (16-1);
-				elen--;
-			}
-		}
-
-		/* Examine the window for pending multiplies */
-		if (buf & tblmask) {
-			multpos = ebits - wbits;
-			while ((buf & 1) == 0) {
-				buf >>= 1;
-				multpos++;
-			}
-			/* Intermediates can wrap, but final must NOT */
-			assert(multpos <= ebits);
-			mult = table[buf>>1];
-			buf = 0;
-		}
-
-		/* If we have a pending multiply, do it */
-		if (ebits == multpos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_16(t, mult, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_16(a, t, mult, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* Are we done? */
-		if (!ebits)
-			break;
-
-		/* Square the input */
-		if (!isone) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			lbnMontSquare_16(a, t, mod, mlen, inv);
-			/* Swap a and b */
-			t = a; a = b; b = t;
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	} /* for (;;) */
-
-	assert(!isone);
-	assert(!buf);
-
-	/* DONE! */
-
-	/* Convert result out of Montgomery form */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	lbnCopy_16(b, t, mlen);
-	lbnZero_16(t, mlen);
-	lbnMontReduce_16(b, mod, mlen, inv);
-	lbnCopy_16(result, t, mlen);
-	/*
-	 * Clean up - free intermediate storage.
-	 * Do NOT free table[0], which is the result
-	 * buffer.
-	 */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	while (--tblmask)
-		LBNFREE(table[tblmask], mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-/*
- * Compute and return n1^e1 * n2^e2 mod "mod".
- * result may be either input buffer, or something separate.
- * It must be "mlen" words long.
- *
- * There is a current position in the exponents, which is kept in e1bits.
- * (The exponents are swapped if necessary so e1 is the longer of the two.)
- * At any given time, the value in the accumulator is
- * n1^(e1>>e1bits) * n2^(e2>>e1bits) mod "mod".
- * As e1bits is counted down, this is updated, by squaring it and doing
- * any necessary multiplies.
- * To decide on the necessary multiplies, two windows, each w1bits+1 bits
- * wide, are maintained in buf1 and buf2, which read *ahead* of the
- * e1bits position (with appropriate handling of the case when e1bits
- * drops below w1bits+1).  When the most-significant bit of either window
- * becomes set, indicating that something needs to be multiplied by
- * the accumulator or it will get out of sync, the window is examined
- * to see which power of n1 or n2 to multiply by, and when (possibly
- * later, if the power is greater than 1) the multiply should take
- * place.  Then the multiply and its location are remembered and the
- * window is cleared.
- *
- * If we had every power of n1 in the table, the multiply would always
- * be w1bits steps in the future.  But we only keep the odd powers,
- * so instead of waiting w1bits squarings and then multiplying
- * by n1^k, we wait w1bits-k squarings and multiply by n1.
- *
- * Actually, w2bits can be less than w1bits, but the window is the same
- * size, to make it easier to keep track of where we're reading.  The
- * appropriate number of low-order bits of the window are just ignored.
- */
-int
-lbnDoubleExpMod_16(BNWORD16 *result,
-                   BNWORD16 const *n1, unsigned n1len,
-                   BNWORD16 const *e1, unsigned e1len,
-                   BNWORD16 const *n2, unsigned n2len,
-                   BNWORD16 const *e2, unsigned e2len,
-                   BNWORD16 *mod, unsigned mlen)
-{
-	BNWORD16 *table1[1 << (BNEXPMOD_MAX_WINDOW-1)];
-					/* Table of odd powers of n1 */
-	BNWORD16 *table2[1 << (BNEXPMOD_MAX_WINDOW-1)];
-					/* Table of odd powers of n2 */
-	unsigned e1bits, e2bits;	/* Exponent bits */
-	unsigned w1bits, w2bits;	/* Window sizes */
-	unsigned tblmask;		/* Mask of exponentiation window */
-	BNWORD16 bitpos;		/* Mask of current look-ahead bit */
-	unsigned buf1, buf2;		/* Buffer of exponent bits */
-	unsigned mult1pos, mult2pos;	/* Where to do pending multiply */
-	BNWORD16 const *mult1, *mult2;	/* What to multiply by */
-	unsigned i;			/* Loop counter */
-	int isone;			/* Flag: accum. is implicitly one */
-	BNWORD16 *a, *b;		/* Working buffers/accumulators */
-	BNWORD16 *t;			/* Pointer into the working buffers */
-	BNWORD16 inv;			/* mod^-1 modulo 2^16 */
-	int y;				/* bnYield() result */
-
-	assert(mlen);
-	assert(n1len <= mlen);
-	assert(n2len <= mlen);
-
-	/* First, a couple of trivial cases. */
-	e1len = lbnNorm_16(e1, e1len);
-	e2len = lbnNorm_16(e2, e2len);
-
-	/* Ensure that the first exponent is the longer */
-	e1bits = lbnBits_16(e1, e1len);
-	e2bits = lbnBits_16(e2, e2len);
-	if (e1bits < e2bits) {
-		i = e1len; e1len = e2len; e2len = i;
-		i = e1bits; e1bits = e2bits; e2bits = i;
-		t = (BNWORD16 *)n1; n1 = n2; n2 = t; 
-		t = (BNWORD16 *)e1; e1 = e2; e2 = t; 
-	}
-	assert(e1bits >= e2bits);
-
-	/* Handle a trivial case */
-	if (!e2len)
-		return lbnExpMod_16(result, n1, n1len, e1, e1len, mod, mlen);
-	assert(e2bits);
-
-	/* The code below fucks up if the exponents aren't at least 2 bits */
-	if (e1bits == 1) {
-		assert(e2bits == 1);
-
-		LBNALLOC(a, BNWORD16, n1len+n2len);
-		if (!a)
-			return -1;
-
-		lbnMul_16(a, n1, n1len, n2, n2len);
-		/* Do a direct modular reduction */
-		if (n1len + n2len >= mlen)
-			(void)lbnDiv_16(a+mlen, a, n1len+n2len, mod, mlen);
-		lbnCopy_16(result, a, mlen);
-		LBNFREE(a, n1len+n2len);
-		return 0;
-	}
-
-	/* Okay, now move the exponent pointers to the most-significant word */
-	e1 = BIGLITTLE(e1-e1len, e1+e1len-1);
-	e2 = BIGLITTLE(e2-e2len, e2+e2len-1);
-
-	/* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
-	w1bits = 0;
-	while (e1bits > bnExpModThreshTable[w1bits])
-		w1bits++;
-	w2bits = 0;
-	while (e2bits > bnExpModThreshTable[w2bits])
-		w2bits++;
-
-	assert(w1bits >= w2bits);
-
-	/* Allocate working storage: two product buffers and the tables. */
-	LBNALLOC(a, BNWORD16, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD16, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert to the appropriate table size: tblmask = 1<<(k-1) */
-	tblmask = 1u << w1bits;
-	/* Use buf2 for its size, temporarily */
-	buf2 = 1u << w2bits;
-
-	LBNALLOC(t, BNWORD16, mlen);
-	if (!t) {
-		LBNFREE(b, 2*mlen);
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-	table1[0] = t;
-	table2[0] = result;
-
-	/*
-	 * Okay, we now have some minimal-sized tables - expand them.
-	 * This is allowed to fail!  If so, scale back the table sizes
-	 * and proceed.  We allocate both tables at the same time
-	 * so if it fails partway through, they'll both be a reasonable
-	 * size rather than one huge and one tiny.
-	 * When i passes buf2 (the number of entries in the e2 window,
-	 * which may be less than the number of entries in the e1 window),
-	 * stop allocating e2 space.
-	 */
-	for (i = 1; i < tblmask; i++) {
-		LBNALLOC(t, BNWORD16, mlen);
-		if (!t)	/* Out of memory!  Quit the loop. */
-			break;
-		table1[i] = t;
-		if (i < buf2) {
-			LBNALLOC(t, BNWORD16, mlen);
-			if (!t) {
-				LBNFREE(table1[i], mlen);
-				break;
-			}
-			table2[i] = t;
-		}
-	}
-
-	/* If we stopped, with i < tblmask, shrink the tables appropriately */
-	while (tblmask > i) {
-		w1bits--;
-		tblmask >>= 1;
-	}
-	/* Free up our overallocations */
-	while (--i > tblmask) {
-		if (i < buf2)
-			LBNFREE(table2[i], mlen);
-		LBNFREE(table1[i], mlen);
-	}
-	/* And shrink the second window too, if needed */
-	if (w2bits > w1bits) {
-		w2bits = w1bits;
-		buf2 = tblmask;
-	}
-
-	/*
-	 * From now on, use the w2bits variable for the difference
-	 * between w1bits and w2bits.
-	 */
-	w2bits = w1bits-w2bits;
-
-	/* Okay, fill in the tables */
-
-	/* Compute the necessary modular inverse */
-	inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	/* Convert n1 to Montgomery form */
-
-	/* Move n1 up "mlen" words into a */
-	t = BIGLITTLE(a-mlen, a+mlen);
-	lbnCopy_16(t, n1, n1len);
-	lbnZero_16(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_16(t, a, mlen+n1len, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_16(table1[0], a, mlen);
-
-	/* Square a into b */
-	lbnMontSquare_16(b, a, mod, mlen, inv);
-
-	/* Use high half of b to initialize the first table */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	for (i = 1; i < tblmask; i++) {
-		lbnMontMul_16(a, t, table1[i-1], mod, mlen, inv);
-		lbnCopy_16(table1[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* Convert n2 to Montgomery form */
-
-	t = BIGLITTLE(a-mlen, a+mlen);
-	/* Move n2 up "mlen" words into a */
-	lbnCopy_16(t, n2, n2len);
-	lbnZero_16(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_16(t, a, mlen+n2len, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_16(table2[0], a, mlen);
-
-	/* Square it into a */
-	lbnMontSquare_16(a, table2[0], mod, mlen, inv);
-	/* Copy to b, low half */
-	lbnCopy_16(b, t, mlen);
-
-	/* Use b to initialize the second table */
-	for (i = 1; i < buf2; i++) {
-		lbnMontMul_16(a, b, table2[i-1], mod, mlen, inv);
-		lbnCopy_16(table2[i], t, mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/*
-	 * Okay, a recap: at this point, the low part of b holds
-	 * n2^2, the high part holds n1^2, and the tables are
-	 * initialized with the odd powers of n1 and n2 from 1
-	 * through 2*tblmask-1 and 2*buf2-1.
-	 *
-	 * We might use those squares in b later, or we might not.
-	 */
-
-	/* Initialze the fetch pointer */
-	bitpos = (BNWORD16)1 << ((e1bits-1) & (16-1));	/* Initialize mask */
-
-	/* This should point to the msbit of e1 */
-	assert((*e1 & bitpos) != 0);
-
-	/*
-	 * Pre-load the windows.  Becuase the window size is
-	 * never larger than the exponent size, there is no need to
-	 * detect running off the end of e1 in here.
-	 *
-	 * The read-ahead is controlled by e1len and the bitpos mask.
-	 * Note that this is *ahead* of e1bits, which tracks the
-	 * most significant end of the window.  The purpose of this
-	 * initialization is to get the two w1bits+1 bits apart,
-	 * like they should be.
-	 *
-	 * Note that bitpos and e1len together keep track of the
-	 * lookahead read pointer in the exponent that is used here.
-	 * e2len is not decremented, it is only ever compared with
-	 * e1len as *that* is decremented.
-	 */
-	buf1 = buf2 = 0;
-	for (i = 0; i <= w1bits; i++) {
-		buf1 = (buf1 << 1) | ((*e1 & bitpos) != 0);
-		if (e1len <= e2len)
-			buf2 = (buf2 << 1) | ((*e2 & bitpos) != 0);
-		bitpos >>= 1;
-		if (!bitpos) {
-			BIGLITTLE(e1++,e1--);
-			if (e1len <= e2len)
-				BIGLITTLE(e2++,e2--);
-			bitpos = (BNWORD16)1 << (16-1);
-			e1len--;
-		}
-	}
-	assert(buf1 & tblmask);
-
-	/*
-	 * Set the pending multiply positions to a location that will
-	 * never be encountered, thus ensuring that nothing will happen
-	 * until the need for a multiply appears and one is scheduled.
-	 */
-	mult1pos = mult2pos = e1bits;	/* A NULL value */
-	mult1 = mult2 = 0;	/* Force a crash if we use these */
-
-	/*
-	 * Okay, now begins the real work.  The first step is
-	 * slightly magic, so it's done outside the main loop,
-	 * but it's very similar to what's inside.
-	 */
-	isone = 1;	/* Buffer is implicitly 1, so replace * by copy */
-	e1bits--;	/* Start processing the first bit... */
-
-	/*
-	 * This is just like the multiply in the loop, except that
-	 * - We know the msbit of buf1 is set, and
-	 * - We have the extra value n1^2 floating around.
-	 * So, do the usual computation, and if the result is that
-	 * the buffer should be multiplied by n1^1 immediately
-	 * (which we'd normally then square), we multiply it
-	 * (which reduces to a copy, which reduces to setting a flag)
-	 * by n1^2 and skip the squaring.  Thus, we do the
-	 * multiply and the squaring in one step.
-	 */
-	assert(buf1 & tblmask);
-	mult1pos = e1bits - w1bits;
-	while ((buf1 & 1) == 0) {
-		buf1 >>= 1;
-		mult1pos++;
-	}
-	/* Intermediates can wrap, but final must NOT */
-	assert(mult1pos <= e1bits);
-	mult1 = table1[buf1>>1];
-	buf1 = 0;
-
-	/* Special case: use already-computed value sitting in buffer */
-	if (mult1pos == e1bits)
-		isone = 0;
-
-	/*
-	 * The first multiply by a power of n2.  Similar, but
-	 * we might not even want to schedule a multiply if e2 is
-	 * shorter than e1, and the window might be shorter so
-	 * we have to leave the low w2bits bits alone.
-	 */
-	if (buf2 & tblmask) {
-		/* Remember low-order bits for later */
-		i = buf2 & ((1u << w2bits) - 1);
-		buf2 >>= w2bits;
-		mult2pos = e1bits - w1bits + w2bits;
-		while ((buf2 & 1) == 0) {
-			buf2 >>= 1;
-			mult2pos++;
-		}
-		assert(mult2pos <= e1bits);
-		mult2 = table2[buf2>>1];
-		buf2 = i;
-
-		if (mult2pos == e1bits) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				lbnCopy_16(t, b, mlen);	/* Copy low to high */
-				isone = 0;
-			} else {
-				lbnMontMul_16(a, t, b, mod, mlen, inv);
-				t = a; a = b; b = t;
-			}
-		}
-	}
-
-	/*
-	 * At this point, the buffer (which is the high half of b)
-	 * holds either 1 (implicitly, as the "isone" flag is set),
-	 * n1^2, n2^2 or n1^2 * n2^2.
-	 */
-
-	/*
-	 * The main loop.  The procedure is:
-	 * - Advance the windows
-	 * - If the most-significant bit of a window is set,
-	 *   schedule a multiply for the appropriate time in the
-	 *   future (may be immediately)
-	 * - Perform any pending multiples
-	 * - Check for termination
-	 * - Square the buffers
-	 *
-	 * At any given time, the acumulated product is held in
-	 * the high half of b.
-	 */
-	for (;;) {
-		e1bits--;
-
-		/* Advance the windows */
-		assert(buf1 < tblmask);
-		buf1 <<= 1;
-		assert(buf2 < tblmask);
-		buf2 <<= 1;
-		/*
-		 * This reads ahead of the current exponent position
-		 * (controlled by e1bits), so we have to be able to read
-		 * past the lsb of the exponents without error.
-		 */
-		if (e1len) {
-			buf1 |= ((*e1 & bitpos) != 0);
-			if (e1len <= e2len)
-				buf2 |= ((*e2 & bitpos) != 0);
-			bitpos >>= 1;
-			if (!bitpos) {
-				BIGLITTLE(e1++,e1--);
-				if (e1len <= e2len)
-					BIGLITTLE(e2++,e2--);
-				bitpos = (BNWORD16)1 << (16-1);
-				e1len--;
-			}
-		}
-
-		/* Examine the first window for pending multiplies */
-		if (buf1 & tblmask) {
-			mult1pos = e1bits - w1bits;
-			while ((buf1 & 1) == 0) {
-				buf1 >>= 1;
-				mult1pos++;
-			}
-			/* Intermediates can wrap, but final must NOT */
-			assert(mult1pos <= e1bits);
-			mult1 = table1[buf1>>1];
-			buf1 = 0;
-		}
-
-		/*
-		 * Examine the second window for pending multiplies.
-		 * Window 2 can be smaller than window 1, but we
-		 * keep the same number of bits in buf2, so we need
-		 * to ignore any low-order bits in the buffer when
-		 * computing what to multiply by, and recompute them
-		 * later.
-		 */
-		if (buf2 & tblmask) {
-			/* Remember low-order bits for later */
-			i = buf2 & ((1u << w2bits) - 1);
-			buf2 >>= w2bits;
-			mult2pos = e1bits - w1bits + w2bits;
-			while ((buf2 & 1) == 0) {
-				buf2 >>= 1;
-				mult2pos++;
-			}
-			assert(mult2pos <= e1bits);
-			mult2 = table2[buf2>>1];
-			buf2 = i;
-		}
-
-
-		/* If we have a pending multiply for e1, do it */
-		if (e1bits == mult1pos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_16(t, mult1, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_16(a, t, mult1, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* If we have a pending multiply for e2, do it */
-		if (e1bits == mult2pos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_16(t, mult2, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_16(a, t, mult2, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* Are we done? */
-		if (!e1bits)
-			break;
-
-		/* Square the buffer */
-		if (!isone) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			lbnMontSquare_16(a, t, mod, mlen, inv);
-			/* Swap a and b */
-			t = a; a = b; b = t;
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	} /* for (;;) */
-
-	assert(!isone);
-	assert(!buf1);
-	assert(!buf2);
-
-	/* DONE! */
-
-	/* Convert result out of Montgomery form */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	lbnCopy_16(b, t, mlen);
-	lbnZero_16(t, mlen);
-	lbnMontReduce_16(b, mod, mlen, inv);
-	lbnCopy_16(result, t, mlen);
-
-	/* Clean up - free intermediate storage */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	buf2 = tblmask >> w2bits;
-	while (--tblmask) {
-		if (tblmask < buf2)
-			LBNFREE(table2[tblmask], mlen);
-		LBNFREE(table1[tblmask], mlen);
-	}
-	t = table1[0];
-	LBNFREE(t, mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-/*
- * 2^exp (mod mod).  This is an optimized version for use in Fermat
- * tests.  The input value of n is ignored; it is returned with
- * "mlen" words valid.
- */
-int
-lbnTwoExpMod_16(BNWORD16 *n, BNWORD16 const *exp, unsigned elen,
-	BNWORD16 *mod, unsigned mlen)
-{
-	unsigned e;	/* Copy of high words of the exponent */
-	unsigned bits;	/* Assorted counter of bits */
-	BNWORD16 const *bitptr;
-	BNWORD16 bitword, bitpos;
-	BNWORD16 *a, *b, *a1;
-	BNWORD16 inv;
-	int y;		/* Result of bnYield() */
-
-	assert(mlen);
-
-	bitptr = BIGLITTLE(exp-elen, exp+elen-1);
-	bitword = *bitptr;
-	assert(bitword);
-
-	/* Clear n for future use. */
-	lbnZero_16(n, mlen);
-
-	bits = lbnBits_16(exp, elen);
-	
-	/* First, a couple of trivial cases. */
-	if (bits <= 1) {
-		/* 2 ^ 0 == 1,  2 ^ 1 == 2 */
-		BIGLITTLE(n[-1],n[0]) = (BNWORD16)1<<elen;
-		return 0;
-	}
-
-	/* Set bitpos to the most significant bit */
-	bitpos = (BNWORD16)1 << ((bits-1) & (16-1));
-
-	/* Now, count the bits in the modulus. */
-	bits = lbnBits_16(mod, mlen);
-	assert(bits > 1);	/* a 1-bit modulus is just stupid... */
-
-	/*
-	 * We start with 1<<e, where "e" is as many high bits of the
-	 * exponent as we can manage without going over the modulus.
-	 * This first loop finds "e".
-	 */
-	e = 1;
-	while (elen) {
-		/* Consume the first bit */
-		bitpos >>= 1;
-		if (!bitpos) {
-			if (!--elen)
-				break;
-			bitword = BIGLITTLE(*++bitptr,*--bitptr);
-			bitpos = (BNWORD16)1<<(16-1);
-		}
-		e = (e << 1) | ((bitpos & bitword) != 0);
-		if (e >= bits) {	/* Overflow!  Back out. */
-			e >>= 1;
-			break;
-		}
-	}
-	/*
-	 * The bit in "bitpos" being examined by the bit buffer has NOT
-	 * been consumed yet.  This may be past the end of the exponent,
-	 * in which case elen == 1.
-	 */
-
-	/* Okay, now, set bit "e" in n.  n is already zero. */
-	inv = (BNWORD16)1 << (e & (16-1));
-	e /= 16;
-	BIGLITTLE(n[-e-1],n[e]) = inv;
-	/*
-	 * The effective length of n in words is now "e+1".
-	 * This is used a little bit later.
-	 */
-
-	if (!elen)
-		return 0;	/* That was easy! */
-
-	/*
-	 * We have now processed the first few bits.  The next step
-	 * is to convert this to Montgomery form for further squaring.
-	 */
-
-	/* Allocate working storage: two product buffers */
-	LBNALLOC(a, BNWORD16, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD16, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert n to Montgomery form */
-	inv = BIGLITTLE(mod[-1],mod[0]);	/* LSW of modulus */
-	assert(inv & 1);	/* Modulus must be odd */
-	inv = lbnMontInv1_16(inv);
-	/* Move n (length e+1, remember?) up "mlen" words into b */
-	/* Note that we lie about a1 for a bit - it's pointing to b */
-	a1 = BIGLITTLE(b-mlen,b+mlen);
-	lbnCopy_16(a1, n, e+1);
-	lbnZero_16(b, mlen);
-	/* Do the division - dump the quotient into the high-order words */
-	(void)lbnDiv_16(a1, b, mlen+e+1, mod, mlen);
-	/*
-	 * Now do the first squaring and modular reduction to put
-	 * the number up in a1 where it belongs.
-	 */
-	lbnMontSquare_16(a, b, mod, mlen, inv);
-	/* Fix up a1 to point to where it should go. */
-	a1 = BIGLITTLE(a-mlen,a+mlen);
-
-	/*
-	 * Okay, now, a1 holds the number being accumulated, and
-	 * b is a scratch register.  Start working:
-	 */
-	for (;;) {
-		/*
-		 * Is the bit set?  If so, double a1 as well.
-		 * A modular doubling like this is very cheap.
-		 */
-		if (bitpos & bitword) {
-			/*
-			 * Double the number.  If there was a carry out OR
-			 * the result is greater than the modulus, subract
-			 * the modulus.
-			 */
-			if (lbnDouble_16(a1, mlen) ||
-			    lbnCmp_16(a1, mod, mlen) > 0)
-				(void)lbnSubN_16(a1, mod, mlen);
-		}
-
-		/* Advance to the next exponent bit */
-		bitpos >>= 1;
-		if (!bitpos) {
-			if (!--elen)
-				break;	/* Done! */
-			bitword = BIGLITTLE(*++bitptr,*--bitptr);
-			bitpos = (BNWORD16)1<<(16-1);
-		}
-
-		/*
-		 * The elen/bitword/bitpos bit buffer is known to be
-		 * non-empty, i.e. there is at least one more unconsumed bit.
-		 * Thus, it's safe to square the number.
-		 */
-		lbnMontSquare_16(b, a1, mod, mlen, inv);
-		/* Rename result (in b) back to a (a1, really). */
-		a1 = b; b = a; a = a1;
-		a1 = BIGLITTLE(a-mlen,a+mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* DONE!  Just a little bit of cleanup... */
-
-	/*
-	 * Convert result out of Montgomery form... this is
-	 * just a Montgomery reduction.
-	 */
-	lbnCopy_16(a, a1, mlen);
-	lbnZero_16(a1, mlen);
-	lbnMontReduce_16(a, mod, mlen, inv);
-	lbnCopy_16(n, a1, mlen);
-
-	/* Clean up - free intermediate storage */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-
-/*
- * Returns a substring of the big-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length.  I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence 
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractBigBytes_16(BNWORD16 const *n, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen)
-{
-	BNWORD16 t = 0;	/* Needed to shut up uninitialized var warnings */
-	unsigned shift;
-
-	lsbyte += buflen;
-
-	shift = (8 * lsbyte) % 16;
-	lsbyte /= (16/8);	/* Convert to word offset */
-	BIGLITTLE(n -= lsbyte, n += lsbyte);
-
-	if (shift)
-		t = BIGLITTLE(n[-1],n[0]);
-
-	while (buflen--) {
-		if (!shift) {
-			t = BIGLITTLE(*n++,*--n);
-			shift = 16;
-		}
-		shift -= 8;
-		*buf++ = (unsigned char)(t>>shift);
-	}
-}
-
-/*
- * Merge a big-endian array of bytes into a bignum array.
- * The array had better be big enough.  This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its *last* byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right.  Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertBigBytes_16(BNWORD16 *n, unsigned char const *buf,
-                  unsigned lsbyte,  unsigned buflen)
-{
-	BNWORD16 t = 0;	/* Shut up uninitialized varibale warnings */
-
-	lsbyte += buflen;
-
-	BIGLITTLE(n -= lsbyte/(16/8), n += lsbyte/(16/8));
-
-	/* Load up leading odd bytes */
-	if (lsbyte % (16/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte * 8) % 16;
-	}
-
-	/* The main loop - merge into t, storing at each word boundary. */
-	while (buflen--) {
-		t = (t << 8) | *buf++;
-		if ((--lsbyte % (16/8)) == 0)
-			BIGLITTLE(*n++,*--n) = t;
-	}
-
-	/* Merge odd bytes in t into last word */
-	lsbyte = (lsbyte * 8) % 16;
-	if (lsbyte) {
-		t <<= lsbyte;
-		t |= (((BNWORD16)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
-		BIGLITTLE(n[0],n[-1]) = t;
-	}
-
-	return;
-}
-
-/*
- * Returns a substring of the little-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length.  I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence 
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractLittleBytes_16(BNWORD16 const *n, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen)
-{
-	BNWORD16 t = 0;	/* Needed to shut up uninitialized var warnings */
-
-	BIGLITTLE(n -= lsbyte/(16/8), n += lsbyte/(16/8));
-
-	if (lsbyte % (16/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte % (16/8)) * 8 ;
-	}
-
-	while (buflen--) {
-		if ((lsbyte++ % (16/8)) == 0)
-			t = BIGLITTLE(*--n,*n++);
-		*buf++ = (unsigned char)t;
-		t >>= 8;
-	}
-}
-
-/*
- * Merge a little-endian array of bytes into a bignum array.
- * The array had better be big enough.  This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its first byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right.  Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertLittleBytes_16(BNWORD16 *n, unsigned char const *buf,
-                  unsigned lsbyte,  unsigned buflen)
-{
-	BNWORD16 t = 0;	/* Shut up uninitialized varibale warnings */
-
-	/* Move to most-significant end */
-	lsbyte += buflen;
-	buf += buflen;
-
-	BIGLITTLE(n -= lsbyte/(16/8), n += lsbyte/(16/8));
-
-	/* Load up leading odd bytes */
-	if (lsbyte % (16/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte * 8) % 16;
-	}
-
-	/* The main loop - merge into t, storing at each word boundary. */
-	while (buflen--) {
-		t = (t << 8) | *--buf;
-		if ((--lsbyte % (16/8)) == 0)
-			BIGLITTLE(*n++,*--n) = t;
-	}
-
-	/* Merge odd bytes in t into last word */
-	lsbyte = (lsbyte * 8) % 16;
-	if (lsbyte) {
-		t <<= lsbyte;
-		t |= (((BNWORD16)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
-		BIGLITTLE(n[0],n[-1]) = t;
-	}
-
-	return;
-}
-
-#ifdef DEADCODE	/* This was a precursor to the more flexible lbnExtractBytes */
-/*
- * Convert a big-endian array of bytes to a bignum.
- * Returns the number of words in the bignum.
- * Note the expression "16/8" for the number of bytes per word.
- * This is so the word-size adjustment will work.
- */
-unsigned
-lbnFromBytes_16(BNWORD16 *a, unsigned char const *b, unsigned blen)
-{
-	BNWORD16 t;
-	unsigned alen = (blen + (16/8-1))/(16/8);
-	BIGLITTLE(a -= alen, a += alen);
-
-	while (blen) {
-		t = 0;
-		do {
-			t = t << 8 | *b++;
-		} while (--blen & (16/8-1));
-		BIGLITTLE(*a++,*--a) = t;
-	}
-	return alen;
-}
-#endif
-
-/*
- * Computes the GCD of a and b.  Modifies both arguments; when it returns,
- * one of them is the GCD and the other is trash.  The return value
- * indicates which: 0 for a, and 1 for b.  The length of the retult is
- * returned in rlen.  Both inputs must have one extra word of precision.
- * alen must be >= blen.
- *
- * TODO: use the binary algorithm (Knuth section 4.5.2, algorithm B).
- * This is based on taking out common powers of 2, then repeatedly:
- * gcd(2*u,v) = gcd(u,2*v) = gcd(u,v) - isolated powers of 2 can be deleted.
- * gcd(u,v) = gcd(u-v,v) - the numbers can be easily reduced.
- * It gets less reduction per step, but the steps are much faster than
- * the division case.
- */
-int
-lbnGcd_16(BNWORD16 *a, unsigned alen, BNWORD16 *b, unsigned blen,
-	unsigned *rlen)
-{
-#if BNYIELD
-	int y;
-#endif
-	assert(alen >= blen);
-
-	while (blen != 0) {
-		(void)lbnDiv_16(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
-		alen = lbnNorm_16(a, blen);
-		if (alen == 0) {
-			*rlen = blen;
-			return 1;
-		}
-		(void)lbnDiv_16(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
-		blen = lbnNorm_16(b, alen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			return y;
-#endif
-	}
-	*rlen = alen;
-	return 0;
-}
-
-/*
- * Invert "a" modulo "mod" using the extended Euclidean algorithm.
- * Note that this only computes one of the cosequences, and uses the
- * theorem that the signs flip every step and the absolute value of
- * the cosequence values are always bounded by the modulus to avoid
- * having to work with negative numbers.
- * gcd(a,mod) had better equal 1.  Returns 1 if the GCD is NOT 1.
- * a must be one word longer than "mod".  It is overwritten with the
- * result.
- * TODO: Use Richard Schroeppel's *much* faster algorithm.
- */
-int
-lbnInv_16(BNWORD16 *a, unsigned alen, BNWORD16 const *mod, unsigned mlen)
-{
-	BNWORD16 *b;	/* Hold a copy of mod during GCD reduction */
-	BNWORD16 *p;	/* Temporary for products added to t0 and t1 */
-	BNWORD16 *t0, *t1;	/* Inverse accumulators */
-	BNWORD16 cy;
-	unsigned blen, t0len, t1len, plen;
-	int y;
-
-	alen = lbnNorm_16(a, alen);
-	if (!alen)
-		return 1;	/* No inverse */
-
-	mlen = lbnNorm_16(mod, mlen);
-
-	assert (alen <= mlen);
-
-	/* Inverse of 1 is 1 */
-	if (alen == 1 && BIGLITTLE(a[-1],a[0]) == 1) {
-		lbnZero_16(BIGLITTLE(a-alen,a+alen), mlen-alen);
-		return 0;
-	}
-
-	/* Allocate a pile of space */
-	LBNALLOC(b, BNWORD16, mlen+1);
-	if (b) {
-		/*
-		 * Although products are guaranteed to always be less than the
-		 * modulus, it can involve multiplying two 3-word numbers to
-		 * get a 5-word result, requiring a 6th word to store a 0
-		 * temporarily.  Thus, mlen + 1.
-		 */
-		LBNALLOC(p, BNWORD16, mlen+1);
-		if (p) {
-			LBNALLOC(t0, BNWORD16, mlen);
-			if (t0) {
-				LBNALLOC(t1, BNWORD16, mlen);
-				if (t1)
-						goto allocated;
-				LBNFREE(t0, mlen);
-			}
-			LBNFREE(p, mlen+1);
-		}
-		LBNFREE(b, mlen+1);
-	}
-	return -1;
-
-allocated:
-
-	/* Set t0 to 1 */
-	t0len = 1;
-	BIGLITTLE(t0[-1],t0[0]) = 1;
-	
-	/* b = mod */
-	lbnCopy_16(b, mod, mlen);
-	/* blen = mlen (implicitly) */
-	
-	/* t1 = b / a; b = b % a */
-	cy = lbnDiv_16(t1, b, mlen, a, alen);
-	*(BIGLITTLE(t1-(mlen-alen)-1,t1+(mlen-alen))) = cy;
-	t1len = lbnNorm_16(t1, mlen-alen+1);
-	blen = lbnNorm_16(b, alen);
-
-	/* while (b > 1) */
-	while (blen > 1 || BIGLITTLE(b[-1],b[0]) != (BNWORD16)1) {
-		/* q = a / b; a = a % b; */
-		if (alen < blen || (alen == blen && lbnCmp_16(a, a, alen) < 0))
-			assert(0);
-		cy = lbnDiv_16(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
-		*(BIGLITTLE(a-alen-1,a+alen)) = cy;
-		plen = lbnNorm_16(BIGLITTLE(a-blen,a+blen), alen-blen+1);
-		assert(plen);
-		alen = lbnNorm_16(a, blen);
-		if (!alen)
-			goto failure;	/* GCD not 1 */
-
-		/* t0 += q * t1; */
-		assert(plen+t1len <= mlen+1);
-		lbnMul_16(p, BIGLITTLE(a-blen,a+blen), plen, t1, t1len);
-		plen = lbnNorm_16(p, plen + t1len);
-		assert(plen <= mlen);
-		if (plen > t0len) {
-			lbnZero_16(BIGLITTLE(t0-t0len,t0+t0len), plen-t0len);
-			t0len = plen;
-		}
-		cy = lbnAddN_16(t0, p, plen);
-		if (cy) {
-			if (t0len > plen) {
-				cy = lbnAdd1_16(BIGLITTLE(t0-plen,t0+plen),
-						t0len-plen, cy);
-			}
-			if (cy) {
-				BIGLITTLE(t0[-t0len-1],t0[t0len]) = cy;
-				t0len++;
-			}
-		}
-
-		/* if (a <= 1) return a ? t0 : FAIL; */
-		if (alen <= 1 && BIGLITTLE(a[-1],a[0]) == (BNWORD16)1) {
-			if (alen == 0)
-				goto failure;	/* FAIL */
-			assert(t0len <= mlen);
-			lbnCopy_16(a, t0, t0len);
-			lbnZero_16(BIGLITTLE(a-t0len, a+t0len), mlen-t0len);
-			goto success;
-		}
-
-		/* q = b / a; b = b % a; */
-		if (blen < alen || (blen == alen && lbnCmp_16(b, a, alen) < 0))
-			assert(0);
-		cy = lbnDiv_16(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
-		*(BIGLITTLE(b-blen-1,b+blen)) = cy;
-		plen = lbnNorm_16(BIGLITTLE(b-alen,b+alen), blen-alen+1);
-		assert(plen);
-		blen = lbnNorm_16(b, alen);
-		if (!blen)
-			goto failure;	/* GCD not 1 */
-
-		/* t1 += q * t0; */
-		assert(plen+t0len <= mlen+1);
-		lbnMul_16(p, BIGLITTLE(b-alen,b+alen), plen, t0, t0len);
-		plen = lbnNorm_16(p, plen + t0len);
-		assert(plen <= mlen);
-		if (plen > t1len) {
-			lbnZero_16(BIGLITTLE(t1-t1len,t1+t1len), plen-t1len);
-			t1len = plen;
-		}
-		cy = lbnAddN_16(t1, p, plen);
-		if (cy) {
-			if (t1len > plen) {
-				cy = lbnAdd1_16(BIGLITTLE(t1-plen,t0+plen),
-						t1len-plen, cy);
-			}
-			if (cy) {
-				BIGLITTLE(t1[-t1len-1],t1[t1len]) = cy;
-				t1len++;
-			}
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield() < 0))
-			goto yield;
-#endif
-	}
-
-	if (!blen)
-		goto failure;	/* gcd(a, mod) != 1 -- FAIL */
-
-	/* return mod-t1 */
-	lbnCopy_16(a, mod, mlen);
-	assert(t1len <= mlen);
-	cy = lbnSubN_16(a, t1, t1len);
-	if (cy) {
-		assert(mlen > t1len);
-		cy = lbnSub1_16(BIGLITTLE(a-t1len, a+t1len), mlen-t1len, cy);
-		assert(!cy);
-	}
-
-success:
-	LBNFREE(t1, mlen);
-	LBNFREE(t0, mlen);
-	LBNFREE(p, mlen+1);
-	LBNFREE(b, mlen+1);
-	
-	return 0;
-
-failure:		/* GCD is not 1 - no inverse exists! */
-	y = 1;
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(t1, mlen);
-	LBNFREE(t0, mlen);
-	LBNFREE(p, mlen+1);
-	LBNFREE(b, mlen+1);
-	
-	return y;
-}
-
-/*
- * Precompute powers of "a" mod "mod".  Compute them every "bits"
- * for "n" steps.  This is sufficient to compute powers of g with
- * exponents up to n*bits bits long, i.e. less than 2^(n*bits).
- * 
- * This assumes that the caller has already initialized "array" to point
- * to "n" buffers of size "mlen".
- */
-int
-lbnBasePrecompBegin_16(BNWORD16 **array, unsigned n, unsigned bits,
-	BNWORD16 const *g, unsigned glen, BNWORD16 *mod, unsigned mlen)
-{
-	BNWORD16 *a, *b;	/* Temporary double-width accumulators */
-	BNWORD16 *a1;	/* Pointer to high half of a*/
-	BNWORD16 inv;	/* Montgomery inverse of LSW of mod */
-	BNWORD16 *t;
-	unsigned i;
-
-	glen = lbnNorm_16(g, glen);
-	assert(glen);
-
-	assert (mlen == lbnNorm_16(mod, mlen));
-	assert (glen <= mlen);
-
-	/* Allocate two temporary buffers, and the array slots */
-	LBNALLOC(a, BNWORD16, mlen*2);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD16, mlen*2);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Okay, all ready */
-
-	/* Convert n to Montgomery form */
-	inv = BIGLITTLE(mod[-1],mod[0]);	/* LSW of modulus */
-	assert(inv & 1);	/* Modulus must be odd */
-	inv = lbnMontInv1_16(inv);
-	/* Move g up "mlen" words into a (clearing the low mlen words) */
-	a1 = BIGLITTLE(a-mlen,a+mlen);
-	lbnCopy_16(a1, g, glen);
-	lbnZero_16(a, mlen);
-
-	/* Do the division - dump the quotient into the high-order words */
-	(void)lbnDiv_16(a1, a, mlen+glen, mod, mlen);
-
-	/* Copy the first value into the array */
-	t = *array;
-	lbnCopy_16(t, a, mlen);
-	a1 = a;	/* This first value is *not* shifted up */
-	
-	/* Now compute the remaining n-1 array entries */
-	assert(bits);
-	assert(n);
-	while (--n) {
-		i = bits;
-		do {
-			/* Square a1 into b1 */
-			lbnMontSquare_16(b, a1, mod, mlen, inv);
-			t = b; b = a; a = t;
-			a1 = BIGLITTLE(a-mlen, a+mlen);
-		} while (--i);
-		t = *++array;
-		lbnCopy_16(t, a1, mlen);
-	}
-
-	/* Hooray, we're done. */
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-	return 0;
-}
-
-/*
- * result = base^exp (mod mod).  "array" is a an array of pointers
- * to procomputed powers of base, each 2^bits apart.  (I.e. array[i]
- * is base^(2^(i*bits))).
- * 
- * The algorithm consists of:
- * a  = b  = (powers of g to be raised to the power 2^bits-1)
- * a *= b *= (powers of g to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of g to be raised to the power 1)
- * 
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnBasePrecompExp_16(BNWORD16 *result, BNWORD16 const * const *array,
-       unsigned bits, BNWORD16 const *exp, unsigned elen,
-       BNWORD16 const *mod, unsigned mlen)
-{
-	BNWORD16 *a, *b, *c, *t;
-	BNWORD16 *a1, *b1;
-	int anull, bnull;	/* Null flags: values are implicitly 1 */
-	unsigned i, j;				/* Loop counters */
-	unsigned mask;				/* Exponent bits to examime */
-	BNWORD16 const *eptr;			/* Pointer into exp */
-	BNWORD16 buf, curbits, nextword;	/* Bit-buffer varaibles */
-	BNWORD16 inv;				/* Inverse of LSW of modulus */
-	unsigned ewords;			/* Words of exponent left */
-	int bufbits;				/* Number of valid bits */
-	int y = 0;
-
-	mlen = lbnNorm_16(mod, mlen);
-	assert (mlen);
-
-	elen = lbnNorm_16(exp, elen);
-	if (!elen) {
-		lbnZero_16(result, mlen);
-		BIGLITTLE(result[-1],result[0]) = 1;
-		return 0;
-	}
-	/*
-	 * This could be precomputed, but it's so cheap, and it would require
-	 * making the precomputation structure word-size dependent.
-	 */
-	inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	assert(elen);
-
-	/*
-	 * Allocate three temporary buffers.  The current numbers generally
-	 * live in the upper halves of these buffers.
-	 */
-	LBNALLOC(a, BNWORD16, mlen*2);
-	if (a) {
-		LBNALLOC(b, BNWORD16, mlen*2);
-		if (b) {
-			LBNALLOC(c, BNWORD16, mlen*2);
-			if (c)
-				goto allocated;
-			LBNFREE(b, 2*mlen);
-		}
-		LBNFREE(a, 2*mlen);
-	}
-	return -1;
-
-allocated:
-
-	anull = bnull = 1;
-
-	mask = (1u<<bits) - 1;
-	for (i = mask; i; --i) {
-		/* Set up bit buffer for walking the exponent */
-		eptr = exp;
-		buf = BIGLITTLE(*--eptr, *eptr++);
-		ewords = elen-1;
-		bufbits = 16;
-		for (j = 0; ewords || buf; j++) {
-			/* Shift down current buffer */
-			curbits = buf;
-			buf >>= bits;
-			/* If necessary, add next word */
-			bufbits -= bits;
-			if (bufbits < 0 && ewords > 0) {
-				nextword = BIGLITTLE(*--eptr, *eptr++);
-				ewords--;
-				curbits |= nextword << (bufbits+bits);
-				buf = nextword >> -bufbits;
-				bufbits += 16;
-			}
-			/* If appropriate, multiply b *= array[j] */
-			if ((curbits & mask) == i) {
-				BNWORD16 const *d = array[j];
-
-				b1 = BIGLITTLE(b-mlen-1,b+mlen);
-				if (bnull) {
-					lbnCopy_16(b1, d, mlen);
-					bnull = 0;
-				} else {
-					lbnMontMul_16(c, b1, d, mod, mlen, inv);
-					t = c; c = b; b = t;
-				}
-#if BNYIELD
-				if (bnYield && (y = bnYield() < 0))
-					goto yield;
-#endif
-			}
-		}
-
-		/* Multiply a *= b */
-		if (!bnull) {
-			a1 = BIGLITTLE(a-mlen-1,a+mlen);
-			b1 = BIGLITTLE(b-mlen-1,b+mlen);
-			if (anull) {
-				lbnCopy_16(a1, b1, mlen);
-				anull = 0;
-			} else {
-				lbnMontMul_16(c, a1, b1, mod, mlen, inv);
-				t = c; c = a; a = t;
-			}
-		}
-	}
-
-	assert(!anull);	/* If it were, elen would have been 0 */
-
-	/* Convert out of Montgomery form and return */
-	a1 = BIGLITTLE(a-mlen-1,a+mlen);
-	lbnCopy_16(a, a1, mlen);
-	lbnZero_16(a1, mlen);
-	lbnMontReduce_16(a, mod, mlen, inv);
-	lbnCopy_16(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(c, 2*mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;
-}
-
-/*
- * result = base1^exp1 *base2^exp2 (mod mod).  "array1" and "array2" are
- * arrays of pointers to procomputed powers of the corresponding bases,
- * each 2^bits apart.  (I.e. array1[i] is base1^(2^(i*bits))).
- * 
- * Bits must be the same in both.  (It could be made adjustable, but it's
- * a bit of a pain.  Just make them both equal to the larger one.)
- * 
- * The algorithm consists of:
- * a  = b  = (powers of base1 and base2  to be raised to the power 2^bits-1)
- * a *= b *= (powers of base1 and base2 to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of base1 and base2 to be raised to the power 1)
- * 
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnDoubleBasePrecompExp_16(BNWORD16 *result, unsigned bits,
-       BNWORD16 const * const *array1, BNWORD16 const *exp1, unsigned elen1,
-       BNWORD16 const * const *array2, BNWORD16 const *exp2,
-       unsigned elen2, BNWORD16 const *mod, unsigned mlen)
-{
-	BNWORD16 *a, *b, *c, *t;
-	BNWORD16 *a1, *b1;
-	int anull, bnull;	/* Null flags: values are implicitly 1 */
-	unsigned i, j, k;				/* Loop counters */
-	unsigned mask;				/* Exponent bits to examime */
-	BNWORD16 const *eptr;			/* Pointer into exp */
-	BNWORD16 buf, curbits, nextword;	/* Bit-buffer varaibles */
-	BNWORD16 inv;				/* Inverse of LSW of modulus */
-	unsigned ewords;			/* Words of exponent left */
-	int bufbits;				/* Number of valid bits */
-	int y = 0;
-	BNWORD16 const * const *array;
-
-	mlen = lbnNorm_16(mod, mlen);
-	assert (mlen);
-
-	elen1 = lbnNorm_16(exp1, elen1);
-	if (!elen1) {
-		return lbnBasePrecompExp_16(result, array2, bits, exp2, elen2,
-		                            mod, mlen);
-	}
-	elen2 = lbnNorm_16(exp2, elen2);
-	if (!elen2) {
-		return lbnBasePrecompExp_16(result, array1, bits, exp1, elen1,
-		                            mod, mlen);
-	}
-	/*
-	 * This could be precomputed, but it's so cheap, and it would require
-	 * making the precomputation structure word-size dependent.
-	 */
-	inv = lbnMontInv1_16(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	assert(elen1);
-	assert(elen2);
-
-	/*
-	 * Allocate three temporary buffers.  The current numbers generally
-	 * live in the upper halves of these buffers.
-	 */
-	LBNALLOC(a, BNWORD16, mlen*2);
-	if (a) {
-		LBNALLOC(b, BNWORD16, mlen*2);
-		if (b) {
-			LBNALLOC(c, BNWORD16, mlen*2);
-			if (c)
-				goto allocated;
-			LBNFREE(b, 2*mlen);
-		}
-		LBNFREE(a, 2*mlen);
-	}
-	return -1;
-
-allocated:
-
-	anull = bnull = 1;
-
-	mask = (1u<<bits) - 1;
-	for (i = mask; i; --i) {
-		/* Walk each exponent in turn */
-		for (k = 0; k < 2; k++) {
-			/* Set up the exponent for walking */
-			array = k ? array2 : array1;
-			eptr = k ? exp2 : exp1;
-			ewords = (k ? elen2 : elen1) - 1;
-			/* Set up bit buffer for walking the exponent */
-			buf = BIGLITTLE(*--eptr, *eptr++);
-			bufbits = 16;
-			for (j = 0; ewords || buf; j++) {
-				/* Shift down current buffer */
-				curbits = buf;
-				buf >>= bits;
-				/* If necessary, add next word */
-				bufbits -= bits;
-				if (bufbits < 0 && ewords > 0) {
-					nextword = BIGLITTLE(*--eptr, *eptr++);
-					ewords--;
-					curbits |= nextword << (bufbits+bits);
-					buf = nextword >> -bufbits;
-					bufbits += 16;
-				}
-				/* If appropriate, multiply b *= array[j] */
-				if ((curbits & mask) == i) {
-					BNWORD16 const *d = array[j];
-
-					b1 = BIGLITTLE(b-mlen-1,b+mlen);
-					if (bnull) {
-						lbnCopy_16(b1, d, mlen);
-						bnull = 0;
-					} else {
-						lbnMontMul_16(c, b1, d, mod, mlen, inv);
-						t = c; c = b; b = t;
-					}
-#if BNYIELD
-					if (bnYield && (y = bnYield() < 0))
-						goto yield;
-#endif
-				}
-			}
-		}
-
-		/* Multiply a *= b */
-		if (!bnull) {
-			a1 = BIGLITTLE(a-mlen-1,a+mlen);
-			b1 = BIGLITTLE(b-mlen-1,b+mlen);
-			if (anull) {
-				lbnCopy_16(a1, b1, mlen);
-				anull = 0;
-			} else {
-				lbnMontMul_16(c, a1, b1, mod, mlen, inv);
-				t = c; c = a; a = t;
-			}
-		}
-	}
-
-	assert(!anull);	/* If it were, elen would have been 0 */
-
-	/* Convert out of Montgomery form and return */
-	a1 = BIGLITTLE(a-mlen-1,a+mlen);
-	lbnCopy_16(a, a1, mlen);
-	lbnZero_16(a1, mlen);
-	lbnMontReduce_16(a, mod, mlen, inv);
-	lbnCopy_16(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(c, 2*mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;
-}
diff --git a/jni/libzrtp/sources/bnlib/lbn16.h b/jni/libzrtp/sources/bnlib/lbn16.h
deleted file mode 100644
index f2237ce..0000000
--- a/jni/libzrtp/sources/bnlib/lbn16.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef LBN16_H
-#define LBN16_H
-
-#include "lbn.h"
-
-#ifndef BNWORD16
-#error 16-bit bignum library requires a 16-bit data type
-#endif
-
-#ifndef lbnCopy_16
-void lbnCopy_16(BNWORD16 *dest, BNWORD16 const *src, unsigned len);
-#endif
-#ifndef lbnZero_16
-void lbnZero_16(BNWORD16 *num, unsigned len);
-#endif
-#ifndef lbnNeg_16
-void lbnNeg_16(BNWORD16 *num, unsigned len);
-#endif
-
-#ifndef lbnAdd1_16
-BNWORD16 lbnAdd1_16(BNWORD16 *num, unsigned len, BNWORD16 carry);
-#endif
-#ifndef lbnSub1_16
-BNWORD16 lbnSub1_16(BNWORD16 *num, unsigned len, BNWORD16 borrow);
-#endif
-
-#ifndef lbnAddN_16
-BNWORD16 lbnAddN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len);
-#endif
-#ifndef lbnSubN_16
-BNWORD16 lbnSubN_16(BNWORD16 *num1, BNWORD16 const *num2, unsigned len);
-#endif
-
-#ifndef lbnCmp_16
-int lbnCmp_16(BNWORD16 const *num1, BNWORD16 const *num2, unsigned len);
-#endif
-
-#ifndef lbnMulN1_16
-void lbnMulN1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k);
-#endif
-#ifndef lbnMulAdd1_16
-BNWORD16
-lbnMulAdd1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k);
-#endif
-#ifndef lbnMulSub1_16
-BNWORD16 lbnMulSub1_16(BNWORD16 *out, BNWORD16 const *in, unsigned len, BNWORD16 k);
-#endif
-
-#ifndef lbnLshift_16
-BNWORD16 lbnLshift_16(BNWORD16 *num, unsigned len, unsigned shift);
-#endif
-#ifndef lbnDouble_16
-BNWORD16 lbnDouble_16(BNWORD16 *num, unsigned len);
-#endif
-#ifndef lbnRshift_16
-BNWORD16 lbnRshift_16(BNWORD16 *num, unsigned len, unsigned shift);
-#endif
-
-#ifndef lbnMul_16
-void lbnMul_16(BNWORD16 *prod, BNWORD16 const *num1, unsigned len1,
-	BNWORD16 const *num2, unsigned len2);
-#endif
-#ifndef lbnSquare_16
-void lbnSquare_16(BNWORD16 *prod, BNWORD16 const *num, unsigned len);
-#endif
-
-#ifndef lbnNorm_16
-unsigned lbnNorm_16(BNWORD16 const *num, unsigned len);
-#endif
-#ifndef lbnBits_16
-unsigned lbnBits_16(BNWORD16 const *num, unsigned len);
-#endif
-
-#ifndef lbnExtractBigBytes_16
-void lbnExtractBigBytes_16(BNWORD16 const *bn, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertBigytes_16
-void lbnInsertBigBytes_16(BNWORD16 *n, unsigned char const *buf,
-	unsigned lsbyte,  unsigned buflen);
-#endif
-#ifndef lbnExtractLittleBytes_16
-void lbnExtractLittleBytes_16(BNWORD16 const *bn, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertLittleBytes_16
-void lbnInsertLittleBytes_16(BNWORD16 *n, unsigned char const *buf,
-	unsigned lsbyte,  unsigned buflen);
-#endif
-
-#ifndef lbnDiv21_16
-BNWORD16 lbnDiv21_16(BNWORD16 *q, BNWORD16 nh, BNWORD16 nl, BNWORD16 d);
-#endif
-#ifndef lbnDiv1_16
-BNWORD16 lbnDiv1_16(BNWORD16 *q, BNWORD16 *rem,
-	BNWORD16 const *n, unsigned len, BNWORD16 d);
-#endif
-#ifndef lbnModQ_16
-unsigned lbnModQ_16(BNWORD16 const *n, unsigned len, unsigned d);
-#endif
-#ifndef lbnDiv_16
-BNWORD16
-lbnDiv_16(BNWORD16 *q, BNWORD16 *n, unsigned nlen, BNWORD16 *d, unsigned dlen);
-#endif
-
-#ifndef lbnMontInv1_16
-BNWORD16 lbnMontInv1_16(BNWORD16 const x);
-#endif
-#ifndef lbnMontReduce_16
-void lbnMontReduce_16(BNWORD16 *n, BNWORD16 const *mod, unsigned const mlen,
-                BNWORD16 inv);
-#endif
-#ifndef lbnToMont_16
-void lbnToMont_16(BNWORD16 *n, unsigned nlen, BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnFromMont_16
-void lbnFromMont_16(BNWORD16 *n, BNWORD16 *mod, unsigned len);
-#endif
-
-#ifndef lbnExpMod_16
-int lbnExpMod_16(BNWORD16 *result, BNWORD16 const *n, unsigned nlen,
-	BNWORD16 const *exp, unsigned elen, BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnDoubleExpMod_16
-int lbnDoubleExpMod_16(BNWORD16 *result,
-	BNWORD16 const *n1, unsigned n1len, BNWORD16 const *e1, unsigned e1len,
-	BNWORD16 const *n2, unsigned n2len, BNWORD16 const *e2, unsigned e2len,
-	BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnTwoExpMod_16
-int lbnTwoExpMod_16(BNWORD16 *n, BNWORD16 const *exp, unsigned elen,
-	BNWORD16 *mod, unsigned mlen);
-#endif
-#ifndef lbnGcd_16
-int lbnGcd_16(BNWORD16 *a, unsigned alen, BNWORD16 *b, unsigned blen,
-	unsigned *rlen);
-#endif
-#ifndef lbnInv_16
-int lbnInv_16(BNWORD16 *a, unsigned alen, BNWORD16 const *mod, unsigned mlen);
-#endif
-
-int lbnBasePrecompBegin_16(BNWORD16 **array, unsigned n, unsigned bits,
-	BNWORD16 const *g, unsigned glen, BNWORD16 *mod, unsigned mlen);
-int lbnBasePrecompExp_16(BNWORD16 *result, BNWORD16 const * const *array,
-       unsigned bits, BNWORD16 const *exp, unsigned elen,
-       BNWORD16 const *mod, unsigned mlen);
-int lbnDoubleBasePrecompExp_16(BNWORD16 *result, unsigned bits,
-       BNWORD16 const * const *array1, BNWORD16 const *exp1, unsigned elen1,
-       BNWORD16 const * const *array2, BNWORD16 const *exp2,
-       unsigned elen2, BNWORD16 const *mod, unsigned mlen);
-
-#endif /* LBN16_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn32.c b/jni/libzrtp/sources/bnlib/lbn32.c
deleted file mode 100644
index 73fedcb..0000000
--- a/jni/libzrtp/sources/bnlib/lbn32.c
+++ /dev/null
@@ -1,4073 +0,0 @@
-/*
- * lbn32.c - Low-level bignum routines, 32-bit version.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * NOTE: the magic constants "32" and "64" appear in many places in this
- * file, including inside identifiers.  Because it is not possible to
- * ask "#ifdef" of a macro expansion, it is not possible to use the
- * preprocessor to conditionalize these properly.  Thus, this file is
- * intended to be edited with textual search and replace to produce
- * alternate word size versions.  Any reference to the number of bits
- * in a word must be the string "32", and that string must not appear
- * otherwise.  Any reference to twice this number must appear as "64",
- * which likewise must not appear otherwise.  Is that clear?
- *
- * Remember, when doubling the bit size replace the larger number (64)
- * first, then the smaller (32).  When halving the bit size, do the
- * opposite.  Otherwise, things will get wierd.  Also, be sure to replace
- * every instance that appears.  (:%s/foo/bar/g in vi)
- *
- * These routines work with a pointer to the least-significant end of
- * an array of WORD32s.  The BIG(x), LITTLE(y) and BIGLTTLE(x,y) macros
- * defined in lbn.h (which expand to x on a big-edian machine and y on a
- * little-endian machine) are used to conditionalize the code to work
- * either way.  If you have no assembly primitives, it doesn't matter.
- * Note that on a big-endian machine, the least-significant-end pointer
- * is ONE PAST THE END.  The bytes are ptr[-1] through ptr[-len].
- * On little-endian, they are ptr[0] through ptr[len-1].  This makes
- * perfect sense if you consider pointers to point *between* bytes rather
- * than at them.
- *
- * Because the array index values are unsigned integers, ptr[-i]
- * may not work properly, since the index -i is evaluated as an unsigned,
- * and if pointers are wider, zero-extension will produce a positive
- * number rahter than the needed negative.  The expression used in this
- * code, *(ptr-i) will, however, work.  (The array syntax is equivalent
- * to *(ptr+-i), which is a pretty subtle difference.)
- *
- * Many of these routines will get very unhappy if fed zero-length inputs.
- * They use assert() to enforce this.  An higher layer of code must make
- * sure that these aren't called with zero-length inputs.
- *
- * Any of these routines can be replaced with more efficient versions
- * elsewhere, by just #defining their names.  If one of the names
- * is #defined, the C code is not compiled in and no declaration is
- * made.  Use the BNINCLUDE file to do that.  Typically, you compile
- * asm subroutines with the same name and just, e.g.
- * #define lbnMulAdd1_32 lbnMulAdd1_32
- *
- * If you want to write asm routines, start with lbnMulAdd1_32().
- * This is the workhorse of modular exponentiation.  lbnMulN1_32() is
- * also used a fair bit, although not as much and it's defined in terms
- * of lbnMulAdd1_32 if that has a custom version.  lbnMulSub1_32 and
- * lbnDiv21_32 are used in the usual division and remainder finding.
- * (Not the Montgomery reduction used in modular exponentiation, though.)
- * Once you have lbnMulAdd1_32 defined, writing the other two should
- * be pretty easy.  (Just make sure you get the sign of the subtraction
- * in lbnMulSub1_32 right - it's dest = dest - source * k.)
- *
- * The only definitions that absolutely need a double-word (BNWORD64)
- * type are lbnMulAdd1_32 and lbnMulSub1_32; if those are provided,
- * the rest follows.  lbnDiv21_32, however, is a lot slower unless you
- * have them, and lbnModQ_32 takes after it.  That one is used quite a
- * bit for prime sieving.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h>	/* For memcpy */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "lbn.h"
-#include "lbn32.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef BNWORD32
-#error 32-bit bignum library requires a 32-bit data type
-#endif
-
-/* If this is defined, include bnYield() calls */
-#if BNYIELD
-extern int (*bnYield)(void);	/* From bn.c */
-#endif
-
-/*
- * Most of the multiply (and Montgomery reduce) routines use an outer
- * loop that iterates over one of the operands - a so-called operand
- * scanning approach.  One big advantage of this is that the assembly
- * support routines are simpler.  The loops can be rearranged to have
- * an outer loop that iterates over the product, a so-called product
- * scanning approach.  This has the advantage of writing less data
- * and doing fewer adds to memory, so is supposedly faster.  Some
- * code has been written using a product-scanning approach, but
- * it appears to be slower, so it is turned off by default.  Some
- * experimentation would be appreciated.
- *
- * (The code is also annoying to get right and not very well commented,
- * one of my pet peeves about math libraries.  I'm sorry.)
- */
-#ifndef PRODUCT_SCAN
-#define PRODUCT_SCAN 0
-#endif
-
-/*
- * Copy an array of words.  <Marvin mode on>  Thrilling, isn't it? </Marvin>
- * This is a good example of how the byte offsets and BIGLITTLE() macros work.
- * Another alternative would have been
- * memcpy(dest BIG(-len), src BIG(-len), len*sizeof(BNWORD32)), but I find that
- * putting operators into conditional macros is confusing.
- */
-#ifndef lbnCopy_32
-void
-lbnCopy_32(BNWORD32 *dest, BNWORD32 const *src, unsigned len)
-{
-	memcpy(BIGLITTLE(dest-len,dest), BIGLITTLE(src-len,src),
-	       len * sizeof(*src));
-}
-#endif /* !lbnCopy_32 */
-
-/*
- * Fill n words with zero.  This does it manually rather than calling
- * memset because it can assume alignment to make things faster while
- * memset can't.  Note how big-endian numbers are naturally addressed
- * using predecrement, while little-endian is postincrement.
- */
-#ifndef lbnZero_32
-void
-lbnZero_32(BNWORD32 *num, unsigned len)
-{
-	while (len--)
-		BIGLITTLE(*--num,*num++) = 0;
-}
-#endif /* !lbnZero_32 */
-
-/*
- * Negate an array of words.
- * Negation is subtraction from zero.  Negating low-order words
- * entails doing nothing until a non-zero word is hit.  Once that
- * is negated, a borrow is generated and never dies until the end
- * of the number is hit.  Negation with borrow, -x-1, is the same as ~x.
- * Repeat that until the end of the number.
- *
- * Doesn't return borrow out because that's pretty useless - it's
- * always set unless the input is 0, which is easy to notice in
- * normalized form.
- */
-#ifndef lbnNeg_32
-void
-lbnNeg_32(BNWORD32 *num, unsigned len)
-{
-	assert(len);
-
-	/* Skip low-order zero words */
-	while (BIGLITTLE(*--num,*num) == 0) {
-		if (!--len)
-			return;
-		LITTLE(num++;)
-	}
-	/* Negate the lowest-order non-zero word */
-	*num = -*num;
-	/* Complement all the higher-order words */
-	while (--len) {
-		BIGLITTLE(--num,++num);
-		*num = ~*num;
-	}
-}
-#endif /* !lbnNeg_32 */
-
-
-/*
- * lbnAdd1_32: add the single-word "carry" to the given number.
- * Used for minor increments and propagating the carry after
- * adding in a shorter bignum.
- *
- * Technique: If we have a double-width word, presumably the compiler
- * can add using its carry in inline code, so we just use a larger
- * accumulator to compute the carry from the first addition.
- * If not, it's more complex.  After adding the first carry, which may
- * be > 1, compare the sum and the carry.  If the sum wraps (causing a
- * carry out from the addition), the result will be less than each of the
- * inputs, since the wrap subtracts a number (2^32) which is larger than
- * the other input can possibly be.  If the sum is >= the carry input,
- * return success immediately.
- * In either case, if there is a carry, enter a loop incrementing words
- * until one does not wrap.  Since we are adding 1 each time, the wrap
- * will be to 0 and we can test for equality.
- */
-#ifndef lbnAdd1_32	/* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD64
-BNWORD32
-lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry)
-{
-	BNWORD64 t;
-	assert(len > 0);	/* Alternative: if (!len) return carry */
-
-	t = (BNWORD64)BIGLITTLE(*--num,*num) + carry;
-	BIGLITTLE(*num,*num++) = (BNWORD32)t;
-	if ((t >> 32) == 0)
-		return 0;
-	while (--len) {
-		if (++BIGLITTLE(*--num,*num++) != 0)
-			return 0;
-	}
-	return 1;
-}
-#else /* no BNWORD64 */
-BNWORD32
-lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry)
-{
-	assert(len > 0);	/* Alternative: if (!len) return carry */
-
-	if ((BIGLITTLE(*--num,*num++) += carry) >= carry)
-		return 0;
-	while (--len) {
-		if (++BIGLITTLE(*--num,*num++) != 0)
-			return 0;
-	}
-	return 1;
-}
-#endif
-#endif/* !lbnAdd1_32 */
-
-/*
- * lbnSub1_32: subtract the single-word "borrow" from the given number.
- * Used for minor decrements and propagating the borrow after
- * subtracting a shorter bignum.
- *
- * Technique: Similar to the add, above.  If there is a double-length type,
- * use that to generate the first borrow.
- * If not, after subtracting the first borrow, which may be > 1, compare
- * the difference and the *negative* of the carry.  If the subtract wraps
- * (causing a borrow out from the subtraction), the result will be at least
- * as large as -borrow.  If the result < -borrow, then no borrow out has
- * appeared and we may return immediately, except when borrow == 0.  To
- * deal with that case, use the identity that -x = ~x+1, and instead of
- * comparing < -borrow, compare for <= ~borrow.
- * Either way, if there is a borrow out, enter a loop decrementing words
- * until a non-zero word is reached.
- *
- * Note the cast of ~borrow to (BNWORD32).  If the size of an int is larger
- * than BNWORD32, C rules say the number is expanded for the arithmetic, so
- * the inversion will be done on an int and the value won't be quite what
- * is expected.
- */
-#ifndef lbnSub1_32	/* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD64
-BNWORD32
-lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow)
-{
-	BNWORD64 t;
-	assert(len > 0);	/* Alternative: if (!len) return borrow */
-
-	t = (BNWORD64)BIGLITTLE(*--num,*num) - borrow;
-	BIGLITTLE(*num,*num++) = (BNWORD32)t;
-	if ((t >> 32) == 0)
-		return 0;
-	while (--len) {
-		if ((BIGLITTLE(*--num,*num++))-- != 0)
-			return 0;
-	}
-	return 1;
-}
-#else /* no BNWORD64 */
-BNWORD32
-lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow)
-{
-	assert(len > 0);	/* Alternative: if (!len) return borrow */
-
-	if ((BIGLITTLE(*--num,*num++) -= borrow) <= (BNWORD32)~borrow)
-		return 0;
-	while (--len) {
-		if ((BIGLITTLE(*--num,*num++))-- != 0)
-			return 0;
-	}
-	return 1;
-}
-#endif
-#endif /* !lbnSub1_32 */
-
-/*
- * lbnAddN_32: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with lbnAdd1, of adding two bignums of
- * differing lengths.
- *
- * Technique: Maintain a word of carry.  If there is no double-width type,
- * use the same technique as in lbnAdd1, above, to maintain the carry by
- * comparing the inputs.  Adding the carry sources is used as an OR operator;
- * at most one of the two comparisons can possibly be true.  The first can
- * only be true if carry == 1 and x, the result, is 0.  In that case the
- * second can't possibly be true.
- */
-#ifndef lbnAddN_32
-#ifdef BNWORD64
-BNWORD32
-lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
-	BNWORD64 t;
-
-	assert(len > 0);
-
-	t = (BNWORD64)BIGLITTLE(*--num1,*num1) + BIGLITTLE(*--num2,*num2++);
-	BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
-	while (--len) {
-		t = (BNWORD64)BIGLITTLE(*--num1,*num1) +
-		    (BNWORD64)BIGLITTLE(*--num2,*num2++) + (t >> 32);
-		BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
-	}
-
-	return (BNWORD32)(t>>32);
-}
-#else /* no BNWORD64 */
-BNWORD32
-lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
-	BNWORD32 x, carry = 0;
-
-	assert(len > 0);	/* Alternative: change loop to test at start */
-
-	do {
-		x = BIGLITTLE(*--num2,*num2++);
-		carry = (x += carry) < carry;
-		carry += (BIGLITTLE(*--num1,*num1++) += x) < x;
-	} while (--len);
-
-	return carry;
-}
-#endif
-#endif /* !lbnAddN_32 */
-
-/*
- * lbnSubN_32: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with subn1, of subtracting two bignums of
- * differing lengths.
- *
- * Technique: If no double-width type is availble, maintain a word of borrow.
- * First, add the borrow to the subtrahend (did you have to learn all those
- * awful words in elementary school, too?), and if it overflows, set the
- * borrow again.  Then subtract the modified subtrahend from the next word
- * of input, using the same technique as in subn1, above.
- * Adding the borrows is used as an OR operator; at most one of the two
- * comparisons can possibly be true.  The first can only be true if
- * borrow == 1 and x, the result, is 0.  In that case the second can't
- * possibly be true.
- *
- * In the double-word case, (BNWORD32)-(t>>32) is subtracted, rather than
- * adding t>>32, because the shift would need to sign-extend and that's
- * not guaranteed to happen in ANSI C, even with signed types.
- */
-#ifndef lbnSubN_32
-#ifdef BNWORD64
-BNWORD32
-lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
-	BNWORD64 t;
-
-	assert(len > 0);
-
-	t = (BNWORD64)BIGLITTLE(*--num1,*num1) - BIGLITTLE(*--num2,*num2++);
-	BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
-
-	while (--len) {
-		t = (BNWORD64)BIGLITTLE(*--num1,*num1) -
-		    (BNWORD64)BIGLITTLE(*--num2,*num2++) - (BNWORD32)-(t >> 32);
-		BIGLITTLE(*num1,*num1++) = (BNWORD32)t;
-	}
-
-	return -(BNWORD32)(t>>32);
-}
-#else
-BNWORD32
-lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len)
-{
-	BNWORD32 x, borrow = 0;
-
-	assert(len > 0);	/* Alternative: change loop to test at start */
-
-	do {
-		x = BIGLITTLE(*--num2,*num2++);
-		borrow = (x += borrow) < borrow;
-		borrow += (BIGLITTLE(*--num1,*num1++) -= x) > (BNWORD32)~x;
-	} while (--len);
-
-	return borrow;
-}
-#endif
-#endif /* !lbnSubN_32 */
-
-#ifndef lbnCmp_32
-/*
- * lbnCmp_32: compare two bignums of equal length, returning the sign of
- * num1 - num2. (-1, 0 or +1).
- * 
- * Technique: Change the little-endian pointers to big-endian pointers
- * and compare from the most-significant end until a difference if found.
- * When it is, figure out the sign of the difference and return it.
- */
-int
-lbnCmp_32(BNWORD32 const *num1, BNWORD32 const *num2, unsigned len)
-{
-	BIGLITTLE(num1 -= len, num1 += len);
-	BIGLITTLE(num2 -= len, num2 += len);
-
-	while (len--) {
-		if (BIGLITTLE(*num1++ != *num2++, *--num1 != *--num2)) {
-			if (BIGLITTLE(num1[-1] < num2[-1], *num1 < *num2))
-				return -1;
-			else
-				return 1;
-		}
-	}
-	return 0;
-}
-#endif /* !lbnCmp_32 */
-
-/*
- * mul32_ppmmaa(ph,pl,x,y,a,b) is an optional routine that
- * computes (ph,pl) = x * y + a + b.  mul32_ppmma and mul32_ppmm
- * are simpler versions.  If you want to be lazy, all of these
- * can be defined in terms of the others, so here we create any
- * that have not been defined in terms of the ones that have been.
- */
-
-/* Define ones with fewer a's in terms of ones with more a's */
-#if !defined(mul32_ppmma) && defined(mul32_ppmmaa)
-#define mul32_ppmma(ph,pl,x,y,a) mul32_ppmmaa(ph,pl,x,y,a,0)
-#endif
-
-#if !defined(mul32_ppmm) && defined(mul32_ppmma)
-#define mul32_ppmm(ph,pl,x,y) mul32_ppmma(ph,pl,x,y,0)
-#endif
-
-/*
- * Use this definition to test the mul32_ppmm-based operations on machines
- * that do not provide mul32_ppmm.  Change the final "0" to a "1" to
- * enable it.
- */
-#if !defined(mul32_ppmm) && defined(BNWORD64) && 0	/* Debugging */
-#define mul32_ppmm(ph,pl,x,y) \
-	({BNWORD64 _ = (BNWORD64)(x)*(y); (pl) = _; (ph) = _>>32;})
-#endif
-
-#if defined(mul32_ppmm) && !defined(mul32_ppmma)
-#define mul32_ppmma(ph,pl,x,y,a) \
-	(mul32_ppmm(ph,pl,x,y), (ph) += ((pl) += (a)) < (a))
-#endif
-
-#if defined(mul32_ppmma) && !defined(mul32_ppmmaa)
-#define mul32_ppmmaa(ph,pl,x,y,a,b) \
-	(mul32_ppmma(ph,pl,x,y,a), (ph) += ((pl) += (b)) < (b))
-#endif
-
-/*
- * lbnMulN1_32: Multiply an n-word input by a 1-word input and store the
- * n+1-word product.  This uses either the mul32_ppmm and mul32_ppmma
- * macros, or C multiplication with the BNWORD64 type.  This uses mul32_ppmma
- * if available, assuming you won't bother defining it unless you can do
- * better than the normal multiplication.
- */
-#ifndef lbnMulN1_32
-#ifdef lbnMulAdd1_32	/* If we have this asm primitive, use it. */
-void
-lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
-	lbnZero_32(out, len);
-	BIGLITTLE(*(out-len-1),*(out+len)) = lbnMulAdd1_32(out, in, len, k);
-}
-#elif defined(mul32_ppmm)
-void
-lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
-	BNWORD32 carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--out;--in;);
-	mul32_ppmm(carry, *out, *in, k);
-	LITTLE(out++;in++;)
-
-	while (--len) {
-		BIG(--out;--in;)
-		carryin = carry;
-		mul32_ppmma(carry, *out, *in, k, carryin);
-		LITTLE(out++;in++;)
-	}
-	BIGLITTLE(*--out,*out) = carry;
-}
-#elif defined(BNWORD64)
-void
-lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
-	BNWORD64 p;
-
-	assert(len > 0);
-
-	p = (BNWORD64)BIGLITTLE(*--in,*in++) * k;
-	BIGLITTLE(*--out,*out++) = (BNWORD32)p;
-
-	while (--len) {
-		p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + (BNWORD32)(p >> 32);
-		BIGLITTLE(*--out,*out++) = (BNWORD32)p;
-	}
-	BIGLITTLE(*--out,*out) = (BNWORD32)(p >> 32);
-}
-#else
-#error No 32x32 -> 64 multiply available for 32-bit bignum package
-#endif
-#endif /* lbnMulN1_32 */
-
-/*
- * lbnMulAdd1_32: Multiply an n-word input by a 1-word input and add the
- * low n words of the product to the destination.  *Returns the n+1st word
- * of the product.*  (That turns out to be more convenient than adding
- * it into the destination and dealing with a possible unit carry out
- * of *that*.)  This uses either the mul32_ppmma and mul32_ppmmaa macros,
- * or C multiplication with the BNWORD64 type.
- *
- * If you're going to write assembly primitives, this is the one to
- * start with.  It is by far the most commonly called function.
- */
-#ifndef lbnMulAdd1_32
-#if defined(mul32_ppmm)
-BNWORD32
-lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
-	BNWORD32 prod, carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--out;--in;);
-	carryin = *out;
-	mul32_ppmma(carry, *out, *in, k, carryin);
-	LITTLE(out++;in++;)
-
-	while (--len) {
-		BIG(--out;--in;);
-		carryin = carry;
-		mul32_ppmmaa(carry, prod, *in, k, carryin, *out);
-		*out = prod;
-		LITTLE(out++;in++;)
-	}
-
-	return carry;
-}
-#elif defined(BNWORD64)
-BNWORD32
-lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
-	BNWORD64 p;
-
-	assert(len > 0);
-
-	p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + BIGLITTLE(*--out,*out);
-	BIGLITTLE(*out,*out++) = (BNWORD32)p;
-
-	while (--len) {
-		p = (BNWORD64)BIGLITTLE(*--in,*in++) * k +
-		    (BNWORD32)(p >> 32) + BIGLITTLE(*--out,*out);
-		BIGLITTLE(*out,*out++) = (BNWORD32)p;
-	}
-
-	return (BNWORD32)(p >> 32);
-}
-#else
-#error No 32x32 -> 64 multiply available for 32-bit bignum package
-#endif
-#endif /* lbnMulAdd1_32 */
-
-/*
- * lbnMulSub1_32: Multiply an n-word input by a 1-word input and subtract the
- * n-word product from the destination.  Returns the n+1st word of the product.
- * This uses either the mul32_ppmm and mul32_ppmma macros, or
- * C multiplication with the BNWORD64 type.
- *
- * This is rather uglier than adding, but fortunately it's only used in
- * division which is not used too heavily.
- */
-#ifndef lbnMulSub1_32
-#if defined(mul32_ppmm)
-BNWORD32
-lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
-	BNWORD32 prod, carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--in;)
-	mul32_ppmm(carry, prod, *in, k);
-	LITTLE(in++;)
-	carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD32)~prod;
-
-	while (--len) {
-		BIG(--in;);
-		carryin = carry;
-		mul32_ppmma(carry, prod, *in, k, carryin);
-		LITTLE(in++;)
-		carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD32)~prod;
-	}
-
-	return carry;
-}
-#elif defined(BNWORD64)
-BNWORD32
-lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k)
-{
-	BNWORD64 p;
-	BNWORD32 carry, t;
-
-	assert(len > 0);
-
-	p = (BNWORD64)BIGLITTLE(*--in,*in++) * k;
-	t = BIGLITTLE(*--out,*out);
-	carry = (BNWORD32)(p>>32) + ((BIGLITTLE(*out,*out++)=t-(BNWORD32)p) > t);
-
-	while (--len) {
-		p = (BNWORD64)BIGLITTLE(*--in,*in++) * k + carry;
-		t = BIGLITTLE(*--out,*out);
-		carry = (BNWORD32)(p>>32) +
-			( (BIGLITTLE(*out,*out++)=t-(BNWORD32)p) > t );
-	}
-
-	return carry;
-}
-#else
-#error No 32x32 -> 64 multiply available for 32-bit bignum package
-#endif
-#endif /* !lbnMulSub1_32 */
-
-/*
- * Shift n words left "shift" bits.  0 < shift < 32.  Returns the
- * carry, any bits shifted off the left-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnLshift_32
-BNWORD32
-lbnLshift_32(BNWORD32 *num, unsigned len, unsigned shift)
-{
-	BNWORD32 x, carry;
-
-	assert(shift > 0);
-	assert(shift < 32);
-
-	carry = 0;
-	while (len--) {
-		BIG(--num;)
-		x = *num;
-		*num = (x<<shift) | carry;
-		LITTLE(num++;)
-		carry = x >> (32-shift);
-	}
-	return carry;
-}
-#endif /* !lbnLshift_32 */
-
-/*
- * An optimized version of the above, for shifts of 1.
- * Some machines can use add-with-carry tricks for this.
- */
-#ifndef lbnDouble_32
-BNWORD32
-lbnDouble_32(BNWORD32 *num, unsigned len)
-{
-	BNWORD32 x, carry;
-
-	carry = 0;
-	while (len--) {
-		BIG(--num;)
-		x = *num;
-		*num = (x<<1) | carry;
-		LITTLE(num++;)
-		carry = x >> (32-1);
-	}
-	return carry;
-}
-#endif /* !lbnDouble_32 */
-
-/*
- * Shift n words right "shift" bits.  0 < shift < 32.  Returns the
- * carry, any bits shifted off the right-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnRshift_32
-BNWORD32
-lbnRshift_32(BNWORD32 *num, unsigned len, unsigned shift)
-{
-	BNWORD32 x, carry = 0;
-
-	assert(shift > 0);
-	assert(shift < 32);
-
-	BIGLITTLE(num -= len, num += len);
-
-	while (len--) {
-		LITTLE(--num;)
-		x = *num;
-		*num = (x>>shift) | carry;
-		BIG(num++;)
-		carry = x << (32-shift);
-	}
-	return carry >> (32-shift);
-}
-#endif /* !lbnRshift_32 */
-
-/* 
- * Multiply two numbers of the given lengths.  prod and num2 may overlap,
- * provided that the low len1 bits of prod are free.  (This corresponds
- * nicely to the place the result is returned from lbnMontReduce_32.)
- *
- * TODO: Use Karatsuba multiply.  The overlap constraints may have
- * to get rewhacked.
- */
-#ifndef lbnMul_32
-void
-lbnMul_32(BNWORD32 *prod, BNWORD32 const *num1, unsigned len1,
-                          BNWORD32 const *num2, unsigned len2)
-{
-	/* Special case of zero */
-	if (!len1 || !len2) {
-		lbnZero_32(prod, len1+len2);
-		return;
-	}
-
-	/* Multiply first word */
-	lbnMulN1_32(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-
-	/*
-	 * Add in subsequent words, storing the most significant word,
-	 * which is new each time.
-	 */
-	while (--len2) {
-		BIGLITTLE(--prod,prod++);
-		BIGLITTLE(*(prod-len1-1),*(prod+len1)) =
-		    lbnMulAdd1_32(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-	}
-}
-#endif /* !lbnMul_32 */
-
-/*
- * lbnMulX_32 is a square multiply - both inputs are the same length.
- * It's normally just a macro wrapper around the general multiply,
- * but might be implementable in assembly more efficiently (such as
- * when product scanning).
- */
-#ifndef lbnMulX_32
-#if defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Test code to see whether product scanning is any faster.  It seems
- * to make the C code slower, so PRODUCT_SCAN is not defined.
- */
-static void
-lbnMulX_32(BNWORD32 *prod, BNWORD32 const *num1, BNWORD32 const *num2,
-	unsigned len)
-{
-	BNWORD64 x, y;
-	BNWORD32 const *p1, *p2;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	x = (BNWORD64)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
-	BIGLITTLE(*--prod, *prod++) = (BNWORD32)x;
-	x >>= 32;
-
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = num1;
-		p2 = BIGLITTLE(num2-i-1,num2+i+1);
-		for (j = 0; j <= i; j++) {
-			BIG(y = (BNWORD64)*--p1 * *p2++;)
-			LITTLE(y = (BNWORD64)*p1++ * *--p2;)
-			x += y;
-			carry += (x < y);
-		}
-		BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
-		x = (x >> 32) | (BNWORD64)carry << 32;
-	}
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = BIGLITTLE(num1-i,num1+i);
-		p2 = BIGLITTLE(num2-len,num2+len);
-		for (j = i; j < len; j++) {
-			BIG(y = (BNWORD64)*--p1 * *p2++;)
-			LITTLE(y = (BNWORD64)*p1++ * *--p2;)
-			x += y;
-			carry += (x < y);
-		}
-		BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
-		x = (x >> 32) | (BNWORD64)carry << 32;
-	}
-	
-	BIGLITTLE(*--prod,*prod) = (BNWORD32)x;
-}
-#else /* !defined(BNWORD64) || !PRODUCT_SCAN */
-/* Default trivial macro definition */
-#define lbnMulX_32(prod, num1, num2, len) lbnMul_32(prod, num1, len, num2, len)
-#endif /* !defined(BNWORD64) || !PRODUCT_SCAN */
-#endif /* !lbmMulX_32 */
-
-#if !defined(lbnMontMul_32) && defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Test code for product-scanning multiply.  This seems to slow the C
- * code down rather than speed it up.
- * This does a multiply and Montgomery reduction together, using the
- * same loops.  The outer loop scans across the product, twice.
- * The first pass computes the low half of the product and the
- * Montgomery multipliers.  These are stored in the product array,
- * which contains no data as of yet.  x and carry add up the columns
- * and propagate carries forward.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers.  The results of this multiply
- * are stored.
- */
-static void
-lbnMontMul_32(BNWORD32 *prod, BNWORD32 const *num1, BNWORD32 const *num2,
-	BNWORD32 const *mod, unsigned len, BNWORD32 inv)
-{
-	BNWORD64 x, y;
-	BNWORD32 const *p1, *p2, *pm;
-	BNWORD32 *pp;
-	BNWORD32 t;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	/*
-	 * This computes directly into the high half of prod, so just
-	 * shift the pointer and consider prod only "len" elements long
-	 * for the rest of the code.
-	 */
-	BIGLITTLE(prod -= len, prod += len);
-
-	/* Pass 1 - compute Montgomery multipliers */
-	/* First iteration can have certain simplifications. */
-	x = (BNWORD64)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
-	BIGLITTLE(prod[-1], prod[0]) = t = inv * (BNWORD32)x;
-	y = (BNWORD64)t * BIGLITTLE(mod[-1],mod[0]);
-	x += y;
-	/* Note: GCC 2.6.3 has a bug if you try to eliminate "carry" */
-	carry = (x < y);
-	assert((BNWORD32)x == 0);
-	x = x >> 32 | (BNWORD64)carry << 32;
-
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = num1;
-		p2 = BIGLITTLE(num2-i-1,num2+i+1);
-		pp = prod;
-		pm = BIGLITTLE(mod-i-1,mod+i+1);
-		for (j = 0; j < i; j++) {
-			y = (BNWORD64)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
-			x += y;
-			carry += (x < y);
-			y = (BNWORD64)BIGLITTLE(*--pp * *pm++, *pp++ * *--pm);
-			x += y;
-			carry += (x < y);
-		}
-		y = (BNWORD64)BIGLITTLE(p1[-1] * p2[0], p1[0] * p2[-1]);
-		x += y;
-		carry += (x < y);
-		assert(BIGLITTLE(pp == prod-i, pp == prod+i));
-		BIGLITTLE(pp[-1], pp[0]) = t = inv * (BNWORD32)x;
-		assert(BIGLITTLE(pm == mod-1, pm == mod+1));
-		y = (BNWORD64)t * BIGLITTLE(pm[0],pm[-1]);
-		x += y;
-		carry += (x < y);
-		assert((BNWORD32)x == 0);
-		x = x >> 32 | (BNWORD64)carry << 32;
-	}
-
-	/* Pass 2 - compute reduced product and store */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = BIGLITTLE(num1-i,num1+i);
-		p2 = BIGLITTLE(num2-len,num2+len);
-		pm = BIGLITTLE(mod-i,mod+i);
-		pp = BIGLITTLE(prod-len,prod+len);
-		for (j = i; j < len; j++) {
-			y = (BNWORD64)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
-			x += y;
-			carry += (x < y);
-			y = (BNWORD64)BIGLITTLE(*--pm * *pp++, *pm++ * *--pp);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pm == mod-len, pm == mod+len));
-		assert(BIGLITTLE(pp == prod-i, pp == prod+i));
-		BIGLITTLE(pp[0],pp[-1]) = (BNWORD32)x;
-		x = (x >> 32) | (BNWORD64)carry << 32;
-	}
-
-	/* Last round of second half, simplified. */
-	BIGLITTLE(*(prod-len),*(prod+len-1)) = (BNWORD32)x;
-	carry = (x >> 32);
-
-	while (carry)
-		carry -= lbnSubN_32(prod, mod, len);
-	while (lbnCmp_32(prod, mod, len) >= 0)
-		(void)lbnSubN_32(prod, mod, len);
-}
-/* Suppress later definition */
-#define lbnMontMul_32 lbnMontMul_32
-#endif
-
-#if !defined(lbnSquare_32) && defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Trial code for product-scanning squaring.  This seems to slow the C
- * code down rather than speed it up.
- */
-void
-lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len)
-{
-	BNWORD64 x, y, z;
-	BNWORD32 const *p1, *p2;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	/* Word 0 of product */
-	x = (BNWORD64)BIGLITTLE(num[-1] * num[-1], num[0] * num[0]);
-	BIGLITTLE(*--prod, *prod++) = (BNWORD32)x;
-	x >>= 32;
-
-	/* Words 1 through len-1 */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		y = 0;
-		p1 = num;
-		p2 = BIGLITTLE(num-i-1,num+i+1);
-		for (j = 0; j < (i+1)/2; j++) {
-			BIG(z = (BNWORD64)*--p1 * *p2++;)
-			LITTLE(z = (BNWORD64)*p1++ * *--p2;)
-			y += z;
-			carry += (y < z);
-		}
-		y += z = y;
-		carry += carry + (y < z);
-		if ((i & 1) == 0) {
-			assert(BIGLITTLE(--p1 == p2, p1 == --p2));
-			BIG(z = (BNWORD64)*p2 * *p2;)
-			LITTLE(z = (BNWORD64)*p1 * *p1;)
-			y += z;
-			carry += (y < z);
-		}
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
-		x = (x >> 32) | (BNWORD64)carry << 32;
-	}
-	/* Words len through 2*len-2 */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		y = 0;
-		p1 = BIGLITTLE(num-i,num+i);
-		p2 = BIGLITTLE(num-len,num+len);
-		for (j = 0; j < (len-i)/2; j++) {
-			BIG(z = (BNWORD64)*--p1 * *p2++;)
-			LITTLE(z = (BNWORD64)*p1++ * *--p2;)
-			y += z;
-			carry += (y < z);
-		}
-		y += z = y;
-		carry += carry + (y < z);
-		if ((len-i) & 1) {
-			assert(BIGLITTLE(--p1 == p2, p1 == --p2));
-			BIG(z = (BNWORD64)*p2 * *p2;)
-			LITTLE(z = (BNWORD64)*p1 * *p1;)
-			y += z;
-			carry += (y < z);
-		}
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*--prod,*prod++) = (BNWORD32)x;
-		x = (x >> 32) | (BNWORD64)carry << 32;
-	}
-	
-	/* Word 2*len-1 */
-	BIGLITTLE(*--prod,*prod) = (BNWORD32)x;
-}
-/* Suppress later definition */
-#define lbnSquare_32 lbnSquare_32
-#endif
-
-/*
- * Square a number, using optimized squaring to reduce the number of
- * primitive multiples that are executed.  There may not be any
- * overlap of the input and output.
- *
- * Technique: Consider the partial products in the multiplication
- * of "abcde" by itself:
- *
- *               a  b  c  d  e
- *            *  a  b  c  d  e
- *          ==================
- *              ae be ce de ee
- *           ad bd cd dd de
- *        ac bc cc cd ce
- *     ab bb bc bd be
- *  aa ab ac ad ae
- *
- * Note that everything above the main diagonal:
- *              ae be ce de = (abcd) * e
- *           ad bd cd       = (abc) * d
- *        ac bc             = (ab) * c
- *     ab                   = (a) * b
- *
- * is a copy of everything below the main diagonal:
- *                       de
- *                 cd ce
- *           bc bd be
- *     ab ac ad ae
- *
- * Thus, the sum is 2 * (off the diagonal) + diagonal.
- *
- * This is accumulated beginning with the diagonal (which
- * consist of the squares of the digits of the input), which is then
- * divided by two, the off-diagonal added, and multiplied by two
- * again.  The low bit is simply a copy of the low bit of the
- * input, so it doesn't need special care.
- *
- * TODO: Merge the shift by 1 with the squaring loop.
- * TODO: Use Karatsuba.  (a*W+b)^2 = a^2 * (W^2+W) + b^2 * (W+1) - (a-b)^2 * W.
- */
-#ifndef lbnSquare_32
-void
-lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len)
-{
-	BNWORD32 t;
-	BNWORD32 *prodx = prod;		/* Working copy of the argument */
-	BNWORD32 const *numx = num;	/* Working copy of the argument */
-	unsigned lenx = len;		/* Working copy of the argument */
-
-	if (!len)
-		return;
-
-	/* First, store all the squares */
-	while (lenx--) {
-#ifdef mul32_ppmm
-		BNWORD32 ph, pl;
-		t = BIGLITTLE(*--numx,*numx++);
-		mul32_ppmm(ph,pl,t,t);
-		BIGLITTLE(*--prodx,*prodx++) = pl;
-		BIGLITTLE(*--prodx,*prodx++) = ph;
-#elif defined(BNWORD64) /* use BNWORD64 */
-		BNWORD64 p;
-		t = BIGLITTLE(*--numx,*numx++);
-		p = (BNWORD64)t * t;
-		BIGLITTLE(*--prodx,*prodx++) = (BNWORD32)p;
-		BIGLITTLE(*--prodx,*prodx++) = (BNWORD32)(p>>32);
-#else	/* Use lbnMulN1_32 */
-		t = BIGLITTLE(numx[-1],*numx);
-		lbnMulN1_32(prodx, numx, 1, t);
-		BIGLITTLE(--numx,numx++);
-		BIGLITTLE(prodx -= 2, prodx += 2);
-#endif
-	}
-	/* Then, shift right 1 bit */
-	(void)lbnRshift_32(prod, 2*len, 1);
-
-	/* Then, add in the off-diagonal sums */
-	lenx = len;
-	numx = num;
-	prodx = prod;
-	while (--lenx) {
-		t = BIGLITTLE(*--numx,*numx++);
-		BIGLITTLE(--prodx,prodx++);
-		t = lbnMulAdd1_32(prodx, numx, lenx, t);
-		lbnAdd1_32(BIGLITTLE(prodx-lenx,prodx+lenx), lenx+1, t);
-		BIGLITTLE(--prodx,prodx++);
-	}
-
-	/* Shift it back up */
-	lbnDouble_32(prod, 2*len);
-
-	/* And set the low bit appropriately */
-	BIGLITTLE(prod[-1],prod[0]) |= BIGLITTLE(num[-1],num[0]) & 1;
-}
-#endif /* !lbnSquare_32 */
-
-/*
- * lbnNorm_32 - given a number, return a modified length such that the
- * most significant digit is non-zero.  Zero-length input is okay.
- */
-#ifndef lbnNorm_32
-unsigned
-lbnNorm_32(BNWORD32 const *num, unsigned len)
-{
-	BIGLITTLE(num -= len,num += len);
-	while (len && BIGLITTLE(*num++,*--num) == 0)
-		--len;
-	return len;
-}
-#endif /* lbnNorm_32 */
-
-/*
- * lbnBits_32 - return the number of significant bits in the array.
- * It starts by normalizing the array.  Zero-length input is okay.
- * Then assuming there's anything to it, it fetches the high word,
- * generates a bit length by multiplying the word length by 32, and
- * subtracts off 32/2, 32/4, 32/8, ... bits if the high bits are clear.
- */
-#ifndef lbnBits_32
-unsigned
-lbnBits_32(BNWORD32 const *num, unsigned len)
-{
-	BNWORD32 t;
-	unsigned i;
-
-	len = lbnNorm_32(num, len);
-	if (len) {
-		t = BIGLITTLE(*(num-len),*(num+(len-1)));
-		assert(t);
-		len *= 32;
-		i = 32/2;
-		do {
-			if (t >> i)
-				t >>= i;
-			else
-				len -= i;
-		} while ((i /= 2) != 0);
-	}
-	return len;
-}
-#endif /* lbnBits_32 */
-
-/*
- * If defined, use hand-rolled divide rather than compiler's native.
- * If the machine doesn't do it in line, the manual code is probably
- * faster, since it can assume normalization and the fact that the
- * quotient will fit into 32 bits, which a general 64-bit divide
- * in a compiler's run-time library can't do.
- */
-#ifndef BN_SLOW_DIVIDE_64
-/* Assume that divisors of more than thirty-two bits are slow */
-#define BN_SLOW_DIVIDE_64 (64 > 0x20)
-#endif
-
-/*
- * Return (nh<<32|nl) % d, and place the quotient digit into *q.
- * It is guaranteed that nh < d, and that d is normalized (with its high
- * bit set).  If we have a double-width type, it's easy.  If not, ooh,
- * yuk!
- */
-#ifndef lbnDiv21_32
-#if defined(BNWORD64) && !BN_SLOW_DIVIDE_64
-BNWORD32
-lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d)
-{
-	BNWORD64 n = (BNWORD64)nh << 32 | nl;
-
-	/* Divisor must be normalized */
-	assert(d >> (32-1) == 1);
-
-	*q = n / d;
-	return n % d;
-}
-#else
-/*
- * This is where it gets ugly.
- *
- * Do the division in two halves, using Algorithm D from section 4.3.1
- * of Knuth.  Note Theorem B from that section, that the quotient estimate
- * is never more than the true quotient, and is never more than two
- * too low.
- *
- * The mapping onto conventional long division is (everything a half word):
- *        _____________qh___ql_
- * dh dl ) nh.h nh.l nl.h nl.l
- *             - (qh * d)
- *            -----------
- *              rrrr rrrr nl.l
- *                  - (ql * d)
- *                -----------
- *                  rrrr rrrr
- *
- * The implicit 3/2-digit d*qh and d*ql subtractors are computed this way:
- *   First, estimate a q digit so that nh/dh works.  Subtracting qh*dh from
- *   the (nh.h nh.l) list leaves a 1/2-word remainder r.  Then compute the
- *   low part of the subtractor, qh * dl.   This also needs to be subtracted
- *   from (nh.h nh.l nl.h) to get the final remainder.  So we take the
- *   remainder, which is (nh.h nh.l) - qh*dl, shift it and add in nl.h, and
- *   try to subtract qh * dl from that.  Since the remainder is 1/2-word
- *   long, shifting and adding nl.h results in a single word r.
- *   It is possible that the remainder we're working with, r, is less than
- *   the product qh * dl, if we estimated qh too high.  The estimation
- *   technique can produce a qh that is too large (never too small), leading
- *   to r which is too small.  In that case, decrement the digit qh, add
- *   shifted dh to r (to correct for that error), and subtract dl from the
- *   product we're comparing r with.  That's the "correct" way to do it, but
- *   just adding dl to r instead of subtracting it from the product is
- *   equivalent and a lot simpler.  You just have to watch out for overflow.
- *
- *   The process is repeated with (rrrr rrrr nl.l) for the low digit of the
- *   quotient ql.
- *
- * The various uses of 32/2 for shifts are because of the note about
- * automatic editing of this file at the very top of the file.
- */
-#define highhalf(x) ( (x) >> 32/2 )
-#define lowhalf(x) ( (x) & (((BNWORD32)1 << 32/2)-1) )
-BNWORD32
-lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d)
-{
-	BNWORD32 dh = highhalf(d), dl = lowhalf(d);
-	BNWORD32 qh, ql, prod, r;
-
-	/* Divisor must be normalized */
-	assert((d >> (32-1)) == 1);
-
-	/* Do first half-word of division */
-	qh = nh / dh;
-	r = nh % dh;
-	prod = qh * dl;
-
-	/*
-	 * Add next half-word of numerator to remainder and correct.
-	 * qh may be up to two too large.
-	 */
-	r = (r << (32/2)) | highhalf(nl);
-	if (r < prod) {
-		--qh; r += d;
-		if (r >= d && r < prod) {
-			--qh; r += d; 
-		}
-	}
-	r -= prod;
-
-	/* Do second half-word of division */
-	ql = r / dh;
-	r = r % dh;
-	prod = ql * dl;
-
-	r = (r << (32/2)) | lowhalf(nl);
-	if (r < prod) {
-		--ql; r += d;
-		if (r >= d && r < prod) {
-			--ql; r += d;
-		}
-	}
-	r -= prod;
-
-	*q = (qh << (32/2)) | ql;
-
-	return r;
-}
-#endif
-#endif /* lbnDiv21_32 */
-
-
-/*
- * In the division functions, the dividend and divisor are referred to
- * as "n" and "d", which stand for "numerator" and "denominator".
- *
- * The quotient is (nlen-dlen+1) digits long.  It may be overlapped with
- * the high (nlen-dlen) words of the dividend, but one extra word is needed
- * on top to hold the top word.
- */
-
-/*
- * Divide an n-word number by a 1-word number, storing the remainder
- * and n-1 words of the n-word quotient.  The high word is returned.
- * It IS legal for rem to point to the same address as n, and for
- * q to point one word higher.
- *
- * TODO: If BN_SLOW_DIVIDE_64, add a divnhalf_32 which uses 32-bit
- *       dividends if the divisor is half that long.
- * TODO: Shift the dividend on the fly to avoid the last division and
- *       instead have a remainder that needs shifting.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef lbnDiv1_32
-BNWORD32
-lbnDiv1_32(BNWORD32 *q, BNWORD32 *rem, BNWORD32 const *n, unsigned len,
-	BNWORD32 d)
-{
-	unsigned shift;
-	unsigned xlen;
-	BNWORD32 r;
-	BNWORD32 qhigh;
-
-	assert(len > 0);
-	assert(d);
-
-	if (len == 1) {
-		r = *n;
-		*rem = r%d;
-		return r/d;
-	}
-
-	shift = 0;
-	r = d;
-	xlen = 32/2;
-	do {
-		if (r >> xlen)
-			r >>= xlen;
-		else
-			shift += xlen;
-	} while ((xlen /= 2) != 0);
-	assert((d >> (32-1-shift)) == 1);
-	d <<= shift;
-
-	BIGLITTLE(q -= len-1,q += len-1);
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	if (r < d) {
-		qhigh = 0;
-	} else {
-		qhigh = r/d;
-		r %= d;
-	}
-
-	xlen = len;
-	while (--xlen)
-		r = lbnDiv21_32(BIGLITTLE(q++,--q), r, BIGLITTLE(*n++,*--n), d);
-
-	/*
-	 * Final correction for shift - shift the quotient up "shift"
-	 * bits, and merge in the extra bits of quotient.  Then reduce
-	 * the final remainder mod the real d.
-	 */
-	if (shift) {
-		d >>= shift;
-		qhigh = (qhigh << shift) | lbnLshift_32(q, len-1, shift);
-		BIGLITTLE(q[-1],*q) |= r/d;
-		r %= d;
-	}
-	*rem = r;
-
-	return qhigh;
-}
-#endif
-
-/*
- * This function performs a "quick" modulus of a number with a divisor
- * d which is guaranteed to be at most sixteen bits, i.e. less than 65536.
- * This applies regardless of the word size the library is compiled with.
- *
- * This function is important to prime generation, for sieving.
- */
-#ifndef lbnModQ_32
-/* If there's a custom lbnMod21_32, no normalization needed */
-#ifdef lbnMod21_32
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
-	unsigned i, shift;
-	BNWORD32 r;
-
-	assert(len > 0);
-
-	BIGLITTLE(n -= len,n += len);
-
-	/* Try using a compare to avoid the first divide */
-	r = BIGLITTLE(*n++,*--n);
-	if (r >= d)
-		r %= d;
-	while (--len)
-		r = lbnMod21_32(r, BIGLITTLE(*n++,*--n), d);
-
-	return r;
-}
-#elif defined(BNWORD64) && !BN_SLOW_DIVIDE_64
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
-	BNWORD32 r;
-
-	if (!--len)
-		return BIGLITTLE(n[-1],n[0]) % d;
-
-	BIGLITTLE(n -= len,n += len);
-	r = BIGLITTLE(n[-1],n[0]);
-
-	do {
-		r = (BNWORD32)((((BNWORD64)r<<32) | BIGLITTLE(*n++,*--n)) % d);
-	} while (--len);
-
-	return r;
-}
-#elif 32 >= 0x20
-/*
- * If the single word size can hold 65535*65536, then this function
- * is avilable.
- */
-#ifndef highhalf
-#define highhalf(x) ( (x) >> 32/2 )
-#define lowhalf(x) ( (x) & ((1 << 32/2)-1) )
-#endif
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
-	BNWORD32 r, x;
-
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	while (--len) {
-		x = BIGLITTLE(*n++,*--n);
-		r = (r%d << 32/2) | highhalf(x);
-		r = (r%d << 32/2) | lowhalf(x);
-	}
-
-	return r%d;
-}
-#else
-/* Default case - use lbnDiv21_32 */
-unsigned
-lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d)
-{
-	unsigned i, shift;
-	BNWORD32 r;
-	BNWORD32 q;
-
-	assert(len > 0);
-
-	shift = 0;
-	r = d;
-	i = 32;
-	while (i /= 2) {
-		if (r >> i)
-			r >>= i;
-		else
-			shift += i;
-	}
-	assert(d >> (32-1-shift) == 1);
-	d <<= shift;
-
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	if (r >= d)
-		r %= d;
-
-	while (--len)
-		r = lbnDiv21_32(&q, r, BIGLITTLE(*n++,*--n), d);
-
-	/*
-	 * Final correction for shift - shift the quotient up "shift"
-	 * bits, and merge in the extra bits of quotient.  Then reduce
-	 * the final remainder mod the real d.
-	 */
-	if (shift)
-		r %= d >> shift;
-
-	return r;
-}
-#endif
-#endif /* lbnModQ_32 */
-
-/*
- * Reduce n mod d and return the quotient.  That is, find:
- * q = n / d;
- * n = n % d;
- * d is altered during the execution of this subroutine by normalizing it.
- * It must already have its most significant word non-zero; it is shifted
- * so its most significant bit is non-zero.
- *
- * The quotient q is nlen-dlen+1 words long.  To make it possible to
- * overlap the quptient with the input (you can store it in the high dlen
- * words), the high word of the quotient is *not* stored, but is returned.
- * (If all you want is the remainder, you don't care about it, anyway.)
- *
- * This uses algorithm D from Knuth (4.3.1), except that we do binary
- * (shift) normalization of the divisor.  WARNING: This is hairy!
- *
- * This function is used for some modular reduction, but it is not used in
- * the modular exponentiation loops; they use Montgomery form and the
- * corresponding, more efficient, Montgomery reduction.  This code
- * is needed for the conversion to Montgomery form, however, so it
- * has to be here and it might as well be reasonably efficient.
- *
- * The overall operation is as follows ("top" and "up" refer to the
- * most significant end of the number; "bottom" and "down", the least):
- *
- * - Shift the divisor up until the most significant bit is set.
- * - Shift the dividend up the same amount.  This will produce the
- *   correct quotient, and the remainder can be recovered by shifting
- *   it back down the same number of bits.  This may produce an overflow
- *   word, but the word is always strictly less than the most significant
- *   divisor word.
- * - Estimate the first quotient digit qhat:
- *   - First take the top two words (one of which is the overflow) of the
- *     dividend and divide by the top word of the divisor:
- *     qhat = (nh,nm)/dh.  This qhat is >= the correct quotient digit
- *     and, since dh is normalized, it is at most two over.
- *   - Second, correct by comparing the top three words.  If
- *     (dh,dl) * qhat > (nh,nm,ml), decrease qhat and try again.
- *     The second iteration can be simpler because there can't be a third.
- *     The computation can be simplified by subtracting dh*qhat from
- *     both sides, suitably shifted.  This reduces the left side to
- *     dl*qhat.  On the right, (nh,nm)-dh*qhat is simply the
- *     remainder r from (nh,nm)%dh, so the right is (r,nl).
- *     This produces qhat that is almost always correct and at
- *     most (prob ~ 2/2^32) one too high.
- * - Subtract qhat times the divisor (suitably shifted) from the dividend.
- *   If there is a borrow, qhat was wrong, so decrement it
- *   and add the divisor back in (once).
- * - Store the final quotient digit qhat in the quotient array q.
- *
- * Repeat the quotient digit computation for successive digits of the
- * quotient until the whole quotient has been computed.  Then shift the
- * divisor and the remainder down to correct for the normalization.
- *
- * TODO: Special case 2-word divisors.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef divn_32
-BNWORD32
-lbnDiv_32(BNWORD32 *q, BNWORD32 *n, unsigned nlen, BNWORD32 *d, unsigned dlen)
-{
-	BNWORD32 nh,nm,nl;	/* Top three words of the dividend */
-	BNWORD32 dh,dl;	/* Top two words of the divisor */
-	BNWORD32 qhat;	/* Extimate of quotient word */
-	BNWORD32 r;	/* Remainder from quotient estimate division */
-	BNWORD32 qhigh;	/* High word of quotient */
-	unsigned i;	/* Temp */
-	unsigned shift;	/* Bits shifted by normalization */
-	unsigned qlen = nlen-dlen; /* Size of quotient (less 1) */
-#ifdef mul32_ppmm
-	BNWORD32 t32;
-#elif defined(BNWORD64)
-	BNWORD64 t64;
-#else /* use lbnMulN1_32 */
-	BNWORD32 t2[2];
-#define t2high BIGLITTLE(t2[0],t2[1])
-#define t2low BIGLITTLE(t2[1],t2[0])
-#endif
-
-	assert(dlen);
-	assert(nlen >= dlen);
-
-	/*
-	 * Special cases for short divisors.  The general case uses the
-	 * top top 2 digits of the divisor (d) to estimate a quotient digit,
-	 * so it breaks if there are fewer digits available.  Thus, we need
-	 * special cases for a divisor of length 1.  A divisor of length
-	 * 2 can have a *lot* of administrivia overhead removed removed,
-	 * so it's probably worth special-casing that case, too.
-	 */
-	if (dlen == 1)
-		return lbnDiv1_32(q, BIGLITTLE(n-1,n), n, nlen,
-		                  BIGLITTLE(d[-1],d[0]));
-
-#if 0
-	/*
-	 * @@@ This is not yet written...  The general loop will do,
-	 * albeit less efficiently
-	 */
-	if (dlen == 2) {
-		/*
-		 * divisor two digits long:
-		 * use the 3/2 technique from Knuth, but we know
-		 * it's exact.
-		 */
-		dh = BIGLITTLE(d[-1],d[0]);
-		dl = BIGLITTLE(d[-2],d[1]);
-		shift = 0;
-		if ((sh & ((BNWORD32)1 << 32-1-shift)) == 0) {
-			do {
-				shift++;
-			} while (dh & (BNWORD32)1<<32-1-shift) == 0);
-			dh = dh << shift | dl >> (32-shift);
-			dl <<= shift;
-
-
-		}
-
-
-		for (shift = 0; (dh & (BNWORD32)1 << 32-1-shift)) == 0; shift++)
-			;
-		if (shift) {
-		}
-		dh = dh << shift | dl >> (32-shift);
-		shift = 0;
-		while (dh
-	}
-#endif
-
-	dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
-	assert(dh);
-
-	/* Normalize the divisor */
-	shift = 0;
-	r = dh;
-	i = 32/2;
-	do {
-		if (r >> i)
-			r >>= i;
-		else
-			shift += i;
-	} while ((i /= 2) != 0);
-
-	nh = 0;
-	if (shift) {
-		lbnLshift_32(d, dlen, shift);
-		dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
-		nh = lbnLshift_32(n, nlen, shift);
-	}
-
-	/* Assert that dh is now normalized */
-	assert(dh >> (32-1));
-
-	/* Also get the second-most significant word of the divisor */
-	dl = BIGLITTLE(*(d-(dlen-1)),*(d+(dlen-2)));
-
-	/*
-	 * Adjust pointers: n to point to least significant end of first
-	 * first subtract, and q to one the most-significant end of the
-	 * quotient array.
-	 */
-	BIGLITTLE(n -= qlen,n += qlen);
-	BIGLITTLE(q -= qlen,q += qlen);
-
-	/* Fetch the most significant stored word of the dividend */
-	nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
-	/*
-	 * Compute the first digit of the quotient, based on the
-	 * first two words of the dividend (the most significant of which
-	 * is the overflow word h).
-	 */
-	if (nh) {
-		assert(nh < dh);
-		r = lbnDiv21_32(&qhat, nh, nm, dh);
-	} else if (nm >= dh) {
-		qhat = nm/dh;
-		r = nm % dh;
-	} else {	/* Quotient is zero */
-		qhigh = 0;
-		goto divloop;
-	}
-
-	/* Now get the third most significant word of the dividend */
-	nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-
-	/*
-	 * Correct qhat, the estimate of quotient digit.
-	 * qhat can only be high, and at most two words high,
-	 * so the loop can be unrolled and abbreviated.
-	 */
-#ifdef mul32_ppmm
-	mul32_ppmm(nm, t32, qhat, dl);
-	if (nm > r || (nm == r && t32 > nl)) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) >= dh) {
-			nm -= (t32 < dl);
-			t32 -= dl;
-			if (nm > r || (nm == r && t32 > nl))
-				qhat--;
-		}
-	}
-#elif defined(BNWORD64)
-	t64 = (BNWORD64)qhat * dl;
-	if (t64 > ((BNWORD64)r << 32) + nl) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) > dh) {
-			t64 -= dl;
-			if (t64 > ((BNWORD64)r << 32) + nl)
-				qhat--;
-		}
-	}
-#else /* Use lbnMulN1_32 */
-	lbnMulN1_32(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
-	if (t2high > r || (t2high == r && t2low > nl)) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) >= dh) {
-			t2high -= (t2low < dl);
-			t2low -= dl;
-			if (t2high > r || (t2high == r && t2low > nl))
-				qhat--;
-		}
-	}
-#endif
-
-	/* Do the multiply and subtract */
-	r = lbnMulSub1_32(n, d, dlen, qhat);
-	/* If there was a borrow, add back once. */
-	if (r > nh) {	/* Borrow? */
-		(void)lbnAddN_32(n, d, dlen);
-		qhat--;
-	}
-
-	/* Remember the first quotient digit. */
-	qhigh = qhat;
-
-	/* Now, the main division loop: */
-divloop:
-	while (qlen--) {
-
-		/* Advance n */
-		nh = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-		BIGLITTLE(++n,--n);
-		nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
-		if (nh == dh) {
-			qhat = ~(BNWORD32)0;
-			/* Optimized computation of r = (nh,nm) - qhat * dh */
-			r = nh + nm;
-			if (r < nh)
-				goto subtract;
-		} else {
-			assert(nh < dh);
-			r = lbnDiv21_32(&qhat, nh, nm, dh);
-		}
-
-		nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-#ifdef mul32_ppmm
-		mul32_ppmm(nm, t32, qhat, dl);
-		if (nm > r || (nm == r && t32 > nl)) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				nm -= (t32 < dl);
-				t32 -= dl;
-				if (nm > r || (nm == r && t32 > nl))
-					qhat--;
-			}
-		}
-#elif defined(BNWORD64)
-		t64 = (BNWORD64)qhat * dl;
-		if (t64 > ((BNWORD64)r<<32) + nl) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				t64 -= dl;
-				if (t64 > ((BNWORD64)r << 32) + nl)
-					qhat--;
-			}
-		}
-#else /* Use lbnMulN1_32 */
-		lbnMulN1_32(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
-		if (t2high > r || (t2high == r && t2low > nl)) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				t2high -= (t2low < dl);
-				t2low -= dl;
-				if (t2high > r || (t2high == r && t2low > nl))
-					qhat--;
-			}
-		}
-#endif
-
-		/*
-		 * As a point of interest, note that it is not worth checking
-		 * for qhat of 0 or 1 and installing special-case code.  These
-		 * occur with probability 2^-32, so spending 1 cycle to check
-		 * for them is only worth it if we save more than 2^15 cycles,
-		 * and a multiply-and-subtract for numbers in the 1024-bit
-		 * range just doesn't take that long.
-		 */
-subtract:
-		/*
-		 * n points to the least significant end of the substring
-		 * of n to be subtracted from.  qhat is either exact or
-		 * one too large.  If the subtract gets a borrow, it was
-		 * one too large and the divisor is added back in.  It's
-		 * a dlen+1 word add which is guaranteed to produce a
-		 * carry out, so it can be done very simply.
-		 */
-		r = lbnMulSub1_32(n, d, dlen, qhat);
-		if (r > nh) {	/* Borrow? */
-			(void)lbnAddN_32(n, d, dlen);
-			qhat--;
-		}
-		/* Store the quotient digit */
-		BIGLITTLE(*q++,*--q) = qhat;
-	}
-	/* Tah dah! */
-
-	if (shift) {
-		lbnRshift_32(d, dlen, shift);
-		lbnRshift_32(n, dlen, shift);
-	}
-
-	return qhigh;
-}
-#endif
-
-/*
- * Find the negative multiplicative inverse of x (x must be odd!) modulo 2^32.
- *
- * This just performs Newton's iteration until it gets the
- * inverse.  The initial estimate is always correct to 3 bits, and
- * sometimes 4.  The number of valid bits doubles each iteration.
- * (To prove it, assume x * y == 1 (mod 2^n), and introduce a variable
- * for the error mod 2^2n.  x * y == 1 + k*2^n (mod 2^2n) and follow
- * the iteration through.)
- */
-#ifndef lbnMontInv1_32
-BNWORD32
-lbnMontInv1_32(BNWORD32 const x)
-{
-        BNWORD32 y = x, z;
-
-	assert(x & 1);
- 
-        while ((z = x*y) != 1)
-                y *= 2 - z;
-        return -y;
-}
-#endif /* !lbnMontInv1_32 */
-
-#if defined(BNWORD64) && PRODUCT_SCAN
-/*
- * Test code for product-scanning Montgomery reduction.
- * This seems to slow the C code down rather than speed it up.
- *
- * The first loop computes the Montgomery multipliers, storing them over
- * the low half of the number n.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers.  The results of this multiply
- * are stored.
- */
-void
-lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned mlen, BNWORD32 inv)
-{
-	BNWORD64 x, y;
-	BNWORD32 const *pm;
-	BNWORD32 *pn;
-	BNWORD32 t;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!mlen)
-		return;
-
-	/* Pass 1 - compute Montgomery multipliers */
-	/* First iteration can have certain simplifications. */
-	t = BIGLITTLE(n[-1],n[0]);
-	x = t;
-	t *= inv;
-	BIGLITTLE(n[-1], n[0]) = t;
-	x += (BNWORD64)t * BIGLITTLE(mod[-1],mod[0]); /* Can't overflow */
-	assert((BNWORD32)x == 0);
-	x = x >> 32;
-
-	for (i = 1; i < mlen; i++) {
-		carry = 0;
-		pn = n;
-		pm = BIGLITTLE(mod-i-1,mod+i+1);
-		for (j = 0; j < i; j++) {
-			y = (BNWORD64)BIGLITTLE(*--pn * *pm++, *pn++ * *--pm);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pn == n-i, pn == n+i));
-		y = t = BIGLITTLE(pn[-1], pn[0]);
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(pn[-1], pn[0]) = t = inv * (BNWORD32)x;
-		assert(BIGLITTLE(pm == mod-1, pm == mod+1));
-		y = (BNWORD64)t * BIGLITTLE(pm[0],pm[-1]);
-		x += y;
-		carry += (x < y);
-		assert((BNWORD32)x == 0);
-		x = x >> 32 | (BNWORD64)carry << 32;
-	}
-
-	BIGLITTLE(n -= mlen, n += mlen);
-
-	/* Pass 2 - compute upper words and add to n */
-	for (i = 1; i < mlen; i++) {
-		carry = 0;
-		pm = BIGLITTLE(mod-i,mod+i);
-		pn = n;
-		for (j = i; j < mlen; j++) {
-			y = (BNWORD64)BIGLITTLE(*--pm * *pn++, *pm++ * *--pn);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pm == mod-mlen, pm == mod+mlen));
-		assert(BIGLITTLE(pn == n+mlen-i, pn == n-mlen+i));
-		y = t = BIGLITTLE(*(n-i),*(n+i-1));
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*(n-i),*(n+i-1)) = (BNWORD32)x;
-		x = (x >> 32) | (BNWORD64)carry << 32;
-	}
-
-	/* Last round of second half, simplified. */
-	t = BIGLITTLE(*(n-mlen),*(n+mlen-1));
-	x += t;
-	BIGLITTLE(*(n-mlen),*(n+mlen-1)) = (BNWORD32)x;
-	carry = (unsigned)(x >> 32);
-
-	while (carry)
-		carry -= lbnSubN_32(n, mod, mlen);
-	while (lbnCmp_32(n, mod, mlen) >= 0)
-		(void)lbnSubN_32(n, mod, mlen);
-}
-#define lbnMontReduce_32 lbnMontReduce_32
-#endif
-
-/*
- * Montgomery reduce n, modulo mod.  This reduces modulo mod and divides by
- * 2^(32*mlen).  Returns the result in the *top* mlen words of the argument n.
- * This is ready for another multiplication using lbnMul_32.
- *
- * Montgomery representation is a very useful way to encode numbers when
- * you're doing lots of modular reduction.  What you do is pick a multiplier
- * R which is relatively prime to the modulus and very easy to divide by.
- * Since the modulus is odd, R is closen as a power of 2, so the division
- * is a shift.  In fact, it's a shift of an integral number of words,
- * so the shift can be implicit - just drop the low-order words.
- *
- * Now, choose R *larger* than the modulus m, 2^(32*mlen).  Then convert
- * all numbers a, b, etc. to Montgomery form M(a), M(b), etc using the
- * relationship M(a) = a*R mod m, M(b) = b*R mod m, etc.  Note that:
- * - The Montgomery form of a number depends on the modulus m.
- *   A fixed modulus m is assumed throughout this discussion.
- * - Since R is relaitvely prime to m, multiplication by R is invertible;
- *   no information about the numbers is lost, they're just scrambled.
- * - Adding (and subtracting) numbers in this form works just as usual.
- *   M(a+b) = (a+b)*R mod m = (a*R + b*R) mod m = (M(a) + M(b)) mod m
- * - Multiplying numbers in this form produces a*b*R*R.  The problem
- *   is to divide out the excess factor of R, modulo m as well as to
- *   reduce to the given length mlen.  It turns out that this can be
- *   done *faster* than a normal divide, which is where the speedup
- *   in Montgomery division comes from.
- *
- * Normal reduction chooses a most-significant quotient digit q and then
- * subtracts q*m from the number to be reduced.  Choosing q is tricky
- * and involved (just look at lbnDiv_32 to see!) and is usually
- * imperfect, requiring a check for correction after the subtraction.
- *
- * Montgomery reduction *adds* a multiple of m to the *low-order* part
- * of the number to be reduced.  This multiple is chosen to make the
- * low-order part of the number come out to zero.  This can be done
- * with no trickery or error using a precomputed inverse of the modulus.
- * In this code, the "part" is one word, but any width can be used.
- *
- * Repeating this step sufficiently often results in a value which
- * is a multiple of R (a power of two, remember) but is still (since
- * the additions were to the low-order part and thus did not increase
- * the value of the number being reduced very much) still not much
- * larger than m*R.  Then implicitly divide by R and subtract off
- * m until the result is in the correct range.
- *
- * Since the low-order part being cancelled is less than R, the
- * multiple of m added must have a multiplier which is at most R-1.
- * Assuming that the input is at most m*R-1, the final number is
- * at most m*(2*R-1)-1 = 2*m*R - m - 1, so subtracting m once from
- * the high-order part, equivalent to subtracting m*R from the
- * while number, produces a result which is at most m*R - m - 1,
- * which divided by R is at most m-1.
- *
- * To convert *to* Montgomery form, you need a regular remainder
- * routine, although you can just compute R*R (mod m) and do the
- * conversion using Montgomery multiplication.  To convert *from*
- * Montgomery form, just Montgomery reduce the number to
- * remove the extra factor of R.
- * 
- * TODO: Change to a full inverse and use Karatsuba's multiplication
- * rather than this word-at-a-time.
- */
-#ifndef lbnMontReduce_32
-void
-lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned const mlen,
-                BNWORD32 inv)
-{
-	BNWORD32 t;
-	BNWORD32 c = 0;
-	unsigned len = mlen;
-
-	/* inv must be the negative inverse of mod's least significant word */
-	assert((BNWORD32)(inv * BIGLITTLE(mod[-1],mod[0])) == (BNWORD32)-1);
-
-	assert(len);
-
-	do {
-		t = lbnMulAdd1_32(n, mod, mlen, inv * BIGLITTLE(n[-1],n[0]));
-		c += lbnAdd1_32(BIGLITTLE(n-mlen,n+mlen), len, t);
-		BIGLITTLE(--n,++n);
-	} while (--len);
-
-	/*
-	 * All that adding can cause an overflow past the modulus size,
-	 * but it's unusual, and never by much, so a subtraction loop
-	 * is the right way to deal with it.
-	 * This subtraction happens infrequently - I've only ever seen it
-	 * invoked once per reduction, and then just under 22.5% of the time.
-	 */
-	while (c)
-		c -= lbnSubN_32(n, mod, mlen);
-	while (lbnCmp_32(n, mod, mlen) >= 0)
-		(void)lbnSubN_32(n, mod, mlen);
-}
-#endif /* !lbnMontReduce_32 */
-
-/*
- * A couple of helpers that you might want to implement atomically
- * in asm sometime.
- */
-#ifndef lbnMontMul_32
-/*
- * Multiply "num1" by "num2", modulo "mod", all of length "len", and
- * place the result in the high half of "prod".  "inv" is the inverse
- * of the least-significant word of the modulus, modulo 2^32.
- * This uses numbers in Montgomery form.  Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontMul_32(prod, n1, n2, mod, len, inv) \
-	(lbnMulX_32(prod, n1, n2, len), lbnMontReduce_32(prod, mod, len, inv))
-#endif /* !lbnMontMul_32 */
-
-#ifndef lbnMontSquare_32
-/*
- * Square "n", modulo "mod", both of length "len", and place the result
- * in the high half of "prod".  "inv" is the inverse of the least-significant
- * word of the modulus, modulo 2^32.
- * This uses numbers in Montgomery form.  Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontSquare_32(prod, n, mod, len, inv) \
-	(lbnSquare_32(prod, n, len), lbnMontReduce_32(prod, mod, len, inv))
-	
-#endif /* !lbnMontSquare_32 */
-
-/*
- * Convert a number to Montgomery form - requires mlen + nlen words
- * of memory in "n".
- */
-void
-lbnToMont_32(BNWORD32 *n, unsigned nlen, BNWORD32 *mod, unsigned mlen)
-{
-	/* Move n up "mlen" words */
-	lbnCopy_32(BIGLITTLE(n-mlen,n+mlen), n, nlen);
-	lbnZero_32(n, mlen);
-	/* Do the division - dump the quotient in the high-order words */
-	(void)lbnDiv_32(BIGLITTLE(n-mlen,n+mlen), n, mlen+nlen, mod, mlen);
-}
-
-/*
- * Convert from Montgomery form.  Montgomery reduction is all that is
- * needed.
- */
-void
-lbnFromMont_32(BNWORD32 *n, BNWORD32 *mod, unsigned len)
-{
-	/* Zero the high words of n */
-	lbnZero_32(BIGLITTLE(n-len,n+len), len);
-	lbnMontReduce_32(n, mod, len, lbnMontInv1_32(mod[BIGLITTLE(-1,0)]));
-	/* Move n down len words */
-	lbnCopy_32(n, BIGLITTLE(n-len,n+len), len);
-}
-
-/*
- * The windowed exponentiation algorithm, precomputes a table of odd
- * powers of n up to 2^k.  See the comment in bnExpMod_32 below for
- * an explanation of how it actually works works.
- *
- * It takes 2^(k-1)-1 multiplies to compute the table, and (e-1)/(k+1)
- * multiplies (on average) to perform the exponentiation.  To minimize
- * the sum, k must vary with e.  The optimal window sizes vary with the
- * exponent length.  Here are some selected values and the boundary cases.
- * (An underscore _ has been inserted into some of the numbers to ensure
- * that magic strings like 32 do not appear in this table.  It should be
- * ignored.)
- *
- * At e =    1 bits, k=1   (0.000000) is best
- * At e =    2 bits, k=1   (0.500000) is best
- * At e =    4 bits, k=1   (1.500000) is best
- * At e =    8 bits, k=2   (3.333333) < k=1   (3.500000)
- * At e =  1_6 bits, k=2   (6.000000) is best
- * At e =   26 bits, k=3   (9.250000) < k=2   (9.333333)
- * At e =  3_2 bits, k=3  (10.750000) is best
- * At e =  6_4 bits, k=3  (18.750000) is best
- * At e =   82 bits, k=4  (23.200000) < k=3  (23.250000)
- * At e =  128 bits, k=4 (3_2.400000) is best
- * At e =  242 bits, k=5  (55.1_66667) < k=4 (55.200000)
- * At e =  256 bits, k=5  (57.500000) is best
- * At e =  512 bits, k=5 (100.1_66667) is best
- * At e =  674 bits, k=6 (127.142857) < k=5 (127.1_66667)
- * At e = 1024 bits, k=6 (177.142857) is best
- * At e = 1794 bits, k=7 (287.125000) < k=6 (287.142857)
- * At e = 2048 bits, k=7 (318.875000) is best
- * At e = 4096 bits, k=7 (574.875000) is best
- *
- * The numbers in parentheses are the expected number of multiplications
- * needed to do the computation.  The normal russian-peasant modular
- * exponentiation technique always uses (e-1)/2.  For exponents as
- * small as 192 bits (below the range of current factoring algorithms),
- * half of the multiplies are eliminated, 45.2 as opposed to the naive
- * 95.5.  Counting the 191 squarings as 3/4 a multiply each (squaring
- * proper is just over half of multiplying, but the Montgomery
- * reduction in each case is also a multiply), that's 143.25
- * multiplies, for totals of 188.45 vs. 238.75 - a 21% savings.
- * For larger exponents (like 512 bits), it's 483.92 vs. 639.25, a
- * 24.3% savings.  It asymptotically approaches 25%.
- *
- * Um, actually there's a slightly more accurate way to count, which
- * really is the average number of multiplies required, averaged
- * uniformly over all 2^(e-1) e-bit numbers, from 2^(e-1) to (2^e)-1.
- * It's based on the recurrence that for the last b bits, b <= k, at
- * most one multiply is needed (and none at all 1/2^b of the time),
- * while when b > k, the odds are 1/2 each way that the bit will be
- * 0 (meaning no multiplies to reduce it to the b-1-bit case) and
- * 1/2 that the bit will be 1, starting a k-bit window and requiring
- * 1 multiply beyond the b-k-bit case.  Since the most significant
- * bit is always 1, a k-bit window always starts there, and that
- * multiply is by 1, so it isn't a multiply at all.  Thus, the
- * number of multiplies is simply that needed for the last e-k bits.
- * This recurrence produces:
- *
- * At e =    1 bits, k=1   (0.000000) is best
- * At e =    2 bits, k=1   (0.500000) is best
- * At e =    4 bits, k=1   (1.500000) is best
- * At e =    6 bits, k=2   (2.437500) < k=1   (2.500000)
- * At e =    8 bits, k=2   (3.109375) is best
- * At e =  1_6 bits, k=2   (5.777771) is best
- * At e =   24 bits, k=3   (8.437629) < k=2   (8.444444)
- * At e =  3_2 bits, k=3  (10.437492) is best
- * At e =  6_4 bits, k=3  (18.437500) is best
- * At e =   81 bits, k=4  (22.6_40000) < k=3  (22.687500)
- * At e =  128 bits, k=4 (3_2.040000) is best
- * At e =  241 bits, k=5  (54.611111) < k=4  (54.6_40000)
- * At e =  256 bits, k=5  (57.111111) is best
- * At e =  512 bits, k=5  (99.777778) is best
- * At e =  673 bits, k=6 (126.591837) < k=5 (126.611111)
- * At e = 1024 bits, k=6 (176.734694) is best
- * At e = 1793 bits, k=7 (286.578125) < k=6 (286.591837)
- * At e = 2048 bits, k=7 (318.453125) is best
- * At e = 4096 bits, k=7 (574.453125) is best
- *
- * This has the rollover points at 6, 24, 81, 241, 673 and 1793 instead
- * of 8, 26, 82, 242, 674, and 1794.  Not a very big difference.
- * (The numbers past that are k=8 at 4609 and k=9 at 11521,
- * vs. one more in each case for the approximation.)
- *
- * Given that exponents for which k>7 are useful are uncommon,
- * a fixed size table for k <= 7 is used for simplicity.
- *
- * The basic number of squarings needed is e-1, although a k-bit
- * window (for k > 1) can save, on average, k-2 of those, too.
- * That savings currently isn't counted here.  It would drive the
- * crossover points slightly lower.
- * (Actually, this win is also reduced in the DoubleExpMod case,
- * meaning we'd have to split the tables.  Except for that, the
- * multiplies by powers of the two bases are independent, so
- * the same logic applies to each as the single case.)
- *
- * Table entry i is the largest number of bits in an exponent to
- * process with a window size of i+1.  Entry 6 is the largest
- * possible unsigned number, so the window will never be more
- * than 7 bits, requiring 2^6 = 0x40 slots.
- */
-#define BNEXPMOD_MAX_WINDOW	7
-static unsigned const bnExpModThreshTable[BNEXPMOD_MAX_WINDOW] = {
-	5, 23, 80, 240, 672, 1792, (unsigned)-1
-/*	7, 25, 81, 241, 673, 1793, (unsigned)-1	 ### The old approximations */
-};
-
-/*
- * Perform modular exponentiation, as fast as possible!  This uses
- * Montgomery reduction, optimized squaring, and windowed exponentiation.
- * The modulus "mod" MUST be odd!
- *
- * This returns 0 on success, -1 on out of memory.
- *
- * The window algorithm:
- * The idea is to keep a running product of b1 = n^(high-order bits of exp),
- * and then keep appending exponent bits to it.  The following patterns
- * apply to a 3-bit window (k = 3):
- * To append   0: square
- * To append   1: square, multiply by n^1
- * To append  10: square, multiply by n^1, square
- * To append  11: square, square, multiply by n^3
- * To append 100: square, multiply by n^1, square, square
- * To append 101: square, square, square, multiply by n^5
- * To append 110: square, square, multiply by n^3, square
- * To append 111: square, square, square, multiply by n^7
- *
- * Since each pattern involves only one multiply, the longer the pattern
- * the better, except that a 0 (no multiplies) can be appended directly.
- * We precompute a table of odd powers of n, up to 2^k, and can then
- * multiply k bits of exponent at a time.  Actually, assuming random
- * exponents, there is on average one zero bit between needs to
- * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
- * 1/8 of the time, there's 2, 1/32 of the time, there's 3, etc.), so
- * you have to do one multiply per k+1 bits of exponent.
- *
- * The loop walks down the exponent, squaring the result buffer as
- * it goes.  There is a wbits+1 bit lookahead buffer, buf, that is
- * filled with the upcoming exponent bits.  (What is read after the
- * end of the exponent is unimportant, but it is filled with zero here.)
- * When the most-significant bit of this buffer becomes set, i.e.
- * (buf & tblmask) != 0, we have to decide what pattern to multiply
- * by, and when to do it.  We decide, remember to do it in future
- * after a suitable number of squarings have passed (e.g. a pattern
- * of "100" in the buffer requires that we multiply by n^1 immediately;
- * a pattern of "110" calls for multiplying by n^3 after one more
- * squaring), clear the buffer, and continue.
- *
- * When we start, there is one more optimization: the result buffer
- * is implcitly one, so squaring it or multiplying by it can be
- * optimized away.  Further, if we start with a pattern like "100"
- * in the lookahead window, rather than placing n into the buffer
- * and then starting to square it, we have already computed n^2
- * to compute the odd-powers table, so we can place that into
- * the buffer and save a squaring.
- *
- * This means that if you have a k-bit window, to compute n^z,
- * where z is the high k bits of the exponent, 1/2 of the time
- * it requires no squarings.  1/4 of the time, it requires 1
- * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
- * And the remaining 1/2^(k-1) of the time, the top k bits are a
- * 1 followed by k-1 0 bits, so it again only requires k-2
- * squarings, not k-1.  The average of these is 1.  Add that
- * to the one squaring we have to do to compute the table,
- * and you'll see that a k-bit window saves k-2 squarings
- * as well as reducing the multiplies.  (It actually doesn't
- * hurt in the case k = 1, either.)
- *
- * n must have mlen words allocated.  Although fewer may be in use
- * when n is passed in, all are in use on exit.
- */
-int
-lbnExpMod_32(BNWORD32 *result, BNWORD32 const *n, unsigned nlen,
-	BNWORD32 const *e, unsigned elen, BNWORD32 *mod, unsigned mlen)
-{
-	BNWORD32 *table[1 << (BNEXPMOD_MAX_WINDOW-1)];
-				/* Table of odd powers of n */
-	unsigned ebits;		/* Exponent bits */
-	unsigned wbits;		/* Window size */
-	unsigned tblmask;	/* Mask of exponentiation window */
-	BNWORD32 bitpos;	/* Mask of current look-ahead bit */
-	unsigned buf;		/* Buffer of exponent bits */
-	unsigned multpos;	/* Where to do pending multiply */
-	BNWORD32 const *mult;	/* What to multiply by */
-	unsigned i;		/* Loop counter */
-	int isone;		/* Flag: accum. is implicitly one */
-	BNWORD32 *a, *b;	/* Working buffers/accumulators */
-	BNWORD32 *t;		/* Pointer into the working buffers */
-	BNWORD32 inv;		/* mod^-1 modulo 2^32 */
-	int y;			/* bnYield() result */
-
-	assert(mlen);
-	assert(nlen <= mlen);
-
-	/* First, a couple of trivial cases. */
-	elen = lbnNorm_32(e, elen);
-	if (!elen) {
-		/* x ^ 0 == 1 */
-		lbnZero_32(result, mlen);
-		BIGLITTLE(result[-1],result[0]) = 1;
-		return 0;
-	}
-	ebits = lbnBits_32(e, elen);
-	if (ebits == 1) {
-		/* x ^ 1 == x */
-		if (n != result)
-			lbnCopy_32(result, n, nlen);
-		if (mlen > nlen)
-			lbnZero_32(BIGLITTLE(result-nlen,result+nlen),
-			           mlen-nlen);
-		return 0;
-	}
-
-	/* Okay, now move the exponent pointer to the most-significant word */
-	e = BIGLITTLE(e-elen, e+elen-1);
-
-	/* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
-	wbits = 0;
-	while (ebits > bnExpModThreshTable[wbits])
-		wbits++;
-
-	/* Allocate working storage: two product buffers and the tables. */
-	LBNALLOC(a, BNWORD32, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD32, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert to the appropriate table size: tblmask = 1<<(k-1) */
-	tblmask = 1u << wbits;
-
-	/* We have the result buffer available, so use it. */
-	table[0] = result;
-
-	/*
-	 * Okay, we now have a minimal-sized table - expand it.
-	 * This is allowed to fail!  If so, scale back the table size
-	 * and proceed.
-	 */
-	for (i = 1; i < tblmask; i++) {
-		LBNALLOC(t, BNWORD32, mlen);
-		if (!t)	/* Out of memory!  Quit the loop. */
-			break;
-		table[i] = t;
-	}
-
-	/* If we stopped, with i < tblmask, shrink the tables appropriately */
-	while (tblmask > i) {
-		wbits--;
-		tblmask >>= 1;
-	}
-	/* Free up our overallocations */
-	while (--i > tblmask)
-		LBNFREE(table[i], mlen);
-
-	/* Okay, fill in the table */
-
-	/* Compute the necessary modular inverse */
-	inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	/* Convert n to Montgomery form */
-
-	/* Move n up "mlen" words into a */
-	t = BIGLITTLE(a-mlen, a+mlen);
-	lbnCopy_32(t, n, nlen);
-	lbnZero_32(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_32(t, a, mlen+nlen, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_32(table[0], a, mlen);
-
-	/* Square a into b */
-	lbnMontSquare_32(b, a, mod, mlen, inv);
-
-	/* Use high half of b to initialize the table */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	for (i = 1; i < tblmask; i++) {
-		lbnMontMul_32(a, t, table[i-1], mod, mlen, inv);
-		lbnCopy_32(table[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* We might use b = n^2 later... */
-
-	/* Initialze the fetch pointer */
-	bitpos = (BNWORD32)1 << ((ebits-1) & (32-1));	/* Initialize mask */
-
-	/* This should point to the msbit of e */
-	assert((*e & bitpos) != 0);
-
-	/*
-	 * Pre-load the window.  Becuase the window size is
-	 * never larger than the exponent size, there is no need to
-	 * detect running off the end of e in here.
-	 *
-	 * The read-ahead is controlled by elen and the bitpos mask.
-	 * Note that this is *ahead* of ebits, which tracks the
-	 * most significant end of the window.  The purpose of this
-	 * initialization is to get the two wbits+1 bits apart,
-	 * like they should be.
-	 *
-	 * Note that bitpos and e1len together keep track of the
-	 * lookahead read pointer in the exponent that is used here.
-	 */
-	buf = 0;
-	for (i = 0; i <= wbits; i++) {
-		buf = (buf << 1) | ((*e & bitpos) != 0);
-		bitpos >>= 1;
-		if (!bitpos) {
-			BIGLITTLE(e++,e--);
-			bitpos = (BNWORD32)1 << (32-1);
-			elen--;
-		}
-	}
-	assert(buf & tblmask);
-
-	/*
-	 * Set the pending multiply positions to a location that will
-	 * never be encountered, thus ensuring that nothing will happen
-	 * until the need for a multiply appears and one is scheduled.
-	 */
-	multpos = ebits;	/* A NULL value */
-	mult = 0;	/* Force a crash if we use these */
-
-	/*
-	 * Okay, now begins the real work.  The first step is
-	 * slightly magic, so it's done outside the main loop,
-	 * but it's very similar to what's inside.
-	 */
-	ebits--;	/* Start processing the first bit... */
-	isone = 1;
-
-	/*
-	 * This is just like the multiply in the loop, except that
-	 * - We know the msbit of buf is set, and
-	 * - We have the extra value n^2 floating around.
-	 * So, do the usual computation, and if the result is that
-	 * the buffer should be multiplied by n^1 immediately
-	 * (which we'd normally then square), we multiply it
-	 * (which reduces to a copy, which reduces to setting a flag)
-	 * by n^2 and skip the squaring.  Thus, we do the
-	 * multiply and the squaring in one step.
-	 */
-	assert(buf & tblmask);
-	multpos = ebits - wbits;
-	while ((buf & 1) == 0) {
-		buf >>= 1;
-		multpos++;
-	}
-	/* Intermediates can wrap, but final must NOT */
-	assert(multpos <= ebits);
-	mult = table[buf>>1];
-	buf = 0;
-
-	/* Special case: use already-computed value sitting in buffer */
-	if (multpos == ebits)
-		isone = 0;
-
-	/*
-	 * At this point, the buffer (which is the high half of b) holds
-	 * either 1 (implicitly, as the "isone" flag is set), or n^2.
-	 */
-
-	/*
-	 * The main loop.  The procedure is:
-	 * - Advance the window
-	 * - If the most-significant bit of the window is set,
-	 *   schedule a multiply for the appropriate time in the
-	 *   future (may be immediately)
-	 * - Perform any pending multiples
-	 * - Check for termination
-	 * - Square the buffer
-	 *
-	 * At any given time, the acumulated product is held in
-	 * the high half of b.
-	 */
-	for (;;) {
-		ebits--;
-
-		/* Advance the window */
-		assert(buf < tblmask);
-		buf <<= 1;
-		/*
-		 * This reads ahead of the current exponent position
-		 * (controlled by ebits), so we have to be able to read
-		 * past the lsb of the exponents without error.
-		 */
-		if (elen) {
-			buf |= ((*e & bitpos) != 0);
-			bitpos >>= 1;
-			if (!bitpos) {
-				BIGLITTLE(e++,e--);
-				bitpos = (BNWORD32)1 << (32-1);
-				elen--;
-			}
-		}
-
-		/* Examine the window for pending multiplies */
-		if (buf & tblmask) {
-			multpos = ebits - wbits;
-			while ((buf & 1) == 0) {
-				buf >>= 1;
-				multpos++;
-			}
-			/* Intermediates can wrap, but final must NOT */
-			assert(multpos <= ebits);
-			mult = table[buf>>1];
-			buf = 0;
-		}
-
-		/* If we have a pending multiply, do it */
-		if (ebits == multpos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_32(t, mult, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_32(a, t, mult, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* Are we done? */
-		if (!ebits)
-			break;
-
-		/* Square the input */
-		if (!isone) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			lbnMontSquare_32(a, t, mod, mlen, inv);
-			/* Swap a and b */
-			t = a; a = b; b = t;
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	} /* for (;;) */
-
-	assert(!isone);
-	assert(!buf);
-
-	/* DONE! */
-
-	/* Convert result out of Montgomery form */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	lbnCopy_32(b, t, mlen);
-	lbnZero_32(t, mlen);
-	lbnMontReduce_32(b, mod, mlen, inv);
-	lbnCopy_32(result, t, mlen);
-	/*
-	 * Clean up - free intermediate storage.
-	 * Do NOT free table[0], which is the result
-	 * buffer.
-	 */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	while (--tblmask)
-		LBNFREE(table[tblmask], mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-/*
- * Compute and return n1^e1 * n2^e2 mod "mod".
- * result may be either input buffer, or something separate.
- * It must be "mlen" words long.
- *
- * There is a current position in the exponents, which is kept in e1bits.
- * (The exponents are swapped if necessary so e1 is the longer of the two.)
- * At any given time, the value in the accumulator is
- * n1^(e1>>e1bits) * n2^(e2>>e1bits) mod "mod".
- * As e1bits is counted down, this is updated, by squaring it and doing
- * any necessary multiplies.
- * To decide on the necessary multiplies, two windows, each w1bits+1 bits
- * wide, are maintained in buf1 and buf2, which read *ahead* of the
- * e1bits position (with appropriate handling of the case when e1bits
- * drops below w1bits+1).  When the most-significant bit of either window
- * becomes set, indicating that something needs to be multiplied by
- * the accumulator or it will get out of sync, the window is examined
- * to see which power of n1 or n2 to multiply by, and when (possibly
- * later, if the power is greater than 1) the multiply should take
- * place.  Then the multiply and its location are remembered and the
- * window is cleared.
- *
- * If we had every power of n1 in the table, the multiply would always
- * be w1bits steps in the future.  But we only keep the odd powers,
- * so instead of waiting w1bits squarings and then multiplying
- * by n1^k, we wait w1bits-k squarings and multiply by n1.
- *
- * Actually, w2bits can be less than w1bits, but the window is the same
- * size, to make it easier to keep track of where we're reading.  The
- * appropriate number of low-order bits of the window are just ignored.
- */
-int
-lbnDoubleExpMod_32(BNWORD32 *result,
-                   BNWORD32 const *n1, unsigned n1len,
-                   BNWORD32 const *e1, unsigned e1len,
-                   BNWORD32 const *n2, unsigned n2len,
-                   BNWORD32 const *e2, unsigned e2len,
-                   BNWORD32 *mod, unsigned mlen)
-{
-	BNWORD32 *table1[1 << (BNEXPMOD_MAX_WINDOW-1)];
-					/* Table of odd powers of n1 */
-	BNWORD32 *table2[1 << (BNEXPMOD_MAX_WINDOW-1)];
-					/* Table of odd powers of n2 */
-	unsigned e1bits, e2bits;	/* Exponent bits */
-	unsigned w1bits, w2bits;	/* Window sizes */
-	unsigned tblmask;		/* Mask of exponentiation window */
-	BNWORD32 bitpos;		/* Mask of current look-ahead bit */
-	unsigned buf1, buf2;		/* Buffer of exponent bits */
-	unsigned mult1pos, mult2pos;	/* Where to do pending multiply */
-	BNWORD32 const *mult1, *mult2;	/* What to multiply by */
-	unsigned i;			/* Loop counter */
-	int isone;			/* Flag: accum. is implicitly one */
-	BNWORD32 *a, *b;		/* Working buffers/accumulators */
-	BNWORD32 *t;			/* Pointer into the working buffers */
-	BNWORD32 inv;			/* mod^-1 modulo 2^32 */
-	int y;				/* bnYield() result */
-
-	assert(mlen);
-	assert(n1len <= mlen);
-	assert(n2len <= mlen);
-
-	/* First, a couple of trivial cases. */
-	e1len = lbnNorm_32(e1, e1len);
-	e2len = lbnNorm_32(e2, e2len);
-
-	/* Ensure that the first exponent is the longer */
-	e1bits = lbnBits_32(e1, e1len);
-	e2bits = lbnBits_32(e2, e2len);
-	if (e1bits < e2bits) {
-		i = e1len; e1len = e2len; e2len = i;
-		i = e1bits; e1bits = e2bits; e2bits = i;
-		t = (BNWORD32 *)n1; n1 = n2; n2 = t; 
-		t = (BNWORD32 *)e1; e1 = e2; e2 = t; 
-	}
-	assert(e1bits >= e2bits);
-
-	/* Handle a trivial case */
-	if (!e2len)
-		return lbnExpMod_32(result, n1, n1len, e1, e1len, mod, mlen);
-	assert(e2bits);
-
-	/* The code below fucks up if the exponents aren't at least 2 bits */
-	if (e1bits == 1) {
-		assert(e2bits == 1);
-
-		LBNALLOC(a, BNWORD32, n1len+n2len);
-		if (!a)
-			return -1;
-
-		lbnMul_32(a, n1, n1len, n2, n2len);
-		/* Do a direct modular reduction */
-		if (n1len + n2len >= mlen)
-			(void)lbnDiv_32(a+mlen, a, n1len+n2len, mod, mlen);
-		lbnCopy_32(result, a, mlen);
-		LBNFREE(a, n1len+n2len);
-		return 0;
-	}
-
-	/* Okay, now move the exponent pointers to the most-significant word */
-	e1 = BIGLITTLE(e1-e1len, e1+e1len-1);
-	e2 = BIGLITTLE(e2-e2len, e2+e2len-1);
-
-	/* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
-	w1bits = 0;
-	while (e1bits > bnExpModThreshTable[w1bits])
-		w1bits++;
-	w2bits = 0;
-	while (e2bits > bnExpModThreshTable[w2bits])
-		w2bits++;
-
-	assert(w1bits >= w2bits);
-
-	/* Allocate working storage: two product buffers and the tables. */
-	LBNALLOC(a, BNWORD32, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD32, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert to the appropriate table size: tblmask = 1<<(k-1) */
-	tblmask = 1u << w1bits;
-	/* Use buf2 for its size, temporarily */
-	buf2 = 1u << w2bits;
-
-	LBNALLOC(t, BNWORD32, mlen);
-	if (!t) {
-		LBNFREE(b, 2*mlen);
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-	table1[0] = t;
-	table2[0] = result;
-
-	/*
-	 * Okay, we now have some minimal-sized tables - expand them.
-	 * This is allowed to fail!  If so, scale back the table sizes
-	 * and proceed.  We allocate both tables at the same time
-	 * so if it fails partway through, they'll both be a reasonable
-	 * size rather than one huge and one tiny.
-	 * When i passes buf2 (the number of entries in the e2 window,
-	 * which may be less than the number of entries in the e1 window),
-	 * stop allocating e2 space.
-	 */
-	for (i = 1; i < tblmask; i++) {
-		LBNALLOC(t, BNWORD32, mlen);
-		if (!t)	/* Out of memory!  Quit the loop. */
-			break;
-		table1[i] = t;
-		if (i < buf2) {
-			LBNALLOC(t, BNWORD32, mlen);
-			if (!t) {
-				LBNFREE(table1[i], mlen);
-				break;
-			}
-			table2[i] = t;
-		}
-	}
-
-	/* If we stopped, with i < tblmask, shrink the tables appropriately */
-	while (tblmask > i) {
-		w1bits--;
-		tblmask >>= 1;
-	}
-	/* Free up our overallocations */
-	while (--i > tblmask) {
-		if (i < buf2)
-			LBNFREE(table2[i], mlen);
-		LBNFREE(table1[i], mlen);
-	}
-	/* And shrink the second window too, if needed */
-	if (w2bits > w1bits) {
-		w2bits = w1bits;
-		buf2 = tblmask;
-	}
-
-	/*
-	 * From now on, use the w2bits variable for the difference
-	 * between w1bits and w2bits.
-	 */
-	w2bits = w1bits-w2bits;
-
-	/* Okay, fill in the tables */
-
-	/* Compute the necessary modular inverse */
-	inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	/* Convert n1 to Montgomery form */
-
-	/* Move n1 up "mlen" words into a */
-	t = BIGLITTLE(a-mlen, a+mlen);
-	lbnCopy_32(t, n1, n1len);
-	lbnZero_32(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_32(t, a, mlen+n1len, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_32(table1[0], a, mlen);
-
-	/* Square a into b */
-	lbnMontSquare_32(b, a, mod, mlen, inv);
-
-	/* Use high half of b to initialize the first table */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	for (i = 1; i < tblmask; i++) {
-		lbnMontMul_32(a, t, table1[i-1], mod, mlen, inv);
-		lbnCopy_32(table1[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* Convert n2 to Montgomery form */
-
-	t = BIGLITTLE(a-mlen, a+mlen);
-	/* Move n2 up "mlen" words into a */
-	lbnCopy_32(t, n2, n2len);
-	lbnZero_32(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_32(t, a, mlen+n2len, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_32(table2[0], a, mlen);
-
-	/* Square it into a */
-	lbnMontSquare_32(a, table2[0], mod, mlen, inv);
-	/* Copy to b, low half */
-	lbnCopy_32(b, t, mlen);
-
-	/* Use b to initialize the second table */
-	for (i = 1; i < buf2; i++) {
-		lbnMontMul_32(a, b, table2[i-1], mod, mlen, inv);
-		lbnCopy_32(table2[i], t, mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/*
-	 * Okay, a recap: at this point, the low part of b holds
-	 * n2^2, the high part holds n1^2, and the tables are
-	 * initialized with the odd powers of n1 and n2 from 1
-	 * through 2*tblmask-1 and 2*buf2-1.
-	 *
-	 * We might use those squares in b later, or we might not.
-	 */
-
-	/* Initialze the fetch pointer */
-	bitpos = (BNWORD32)1 << ((e1bits-1) & (32-1));	/* Initialize mask */
-
-	/* This should point to the msbit of e1 */
-	assert((*e1 & bitpos) != 0);
-
-	/*
-	 * Pre-load the windows.  Becuase the window size is
-	 * never larger than the exponent size, there is no need to
-	 * detect running off the end of e1 in here.
-	 *
-	 * The read-ahead is controlled by e1len and the bitpos mask.
-	 * Note that this is *ahead* of e1bits, which tracks the
-	 * most significant end of the window.  The purpose of this
-	 * initialization is to get the two w1bits+1 bits apart,
-	 * like they should be.
-	 *
-	 * Note that bitpos and e1len together keep track of the
-	 * lookahead read pointer in the exponent that is used here.
-	 * e2len is not decremented, it is only ever compared with
-	 * e1len as *that* is decremented.
-	 */
-	buf1 = buf2 = 0;
-	for (i = 0; i <= w1bits; i++) {
-		buf1 = (buf1 << 1) | ((*e1 & bitpos) != 0);
-		if (e1len <= e2len)
-			buf2 = (buf2 << 1) | ((*e2 & bitpos) != 0);
-		bitpos >>= 1;
-		if (!bitpos) {
-			BIGLITTLE(e1++,e1--);
-			if (e1len <= e2len)
-				BIGLITTLE(e2++,e2--);
-			bitpos = (BNWORD32)1 << (32-1);
-			e1len--;
-		}
-	}
-	assert(buf1 & tblmask);
-
-	/*
-	 * Set the pending multiply positions to a location that will
-	 * never be encountered, thus ensuring that nothing will happen
-	 * until the need for a multiply appears and one is scheduled.
-	 */
-	mult1pos = mult2pos = e1bits;	/* A NULL value */
-	mult1 = mult2 = 0;	/* Force a crash if we use these */
-
-	/*
-	 * Okay, now begins the real work.  The first step is
-	 * slightly magic, so it's done outside the main loop,
-	 * but it's very similar to what's inside.
-	 */
-	isone = 1;	/* Buffer is implicitly 1, so replace * by copy */
-	e1bits--;	/* Start processing the first bit... */
-
-	/*
-	 * This is just like the multiply in the loop, except that
-	 * - We know the msbit of buf1 is set, and
-	 * - We have the extra value n1^2 floating around.
-	 * So, do the usual computation, and if the result is that
-	 * the buffer should be multiplied by n1^1 immediately
-	 * (which we'd normally then square), we multiply it
-	 * (which reduces to a copy, which reduces to setting a flag)
-	 * by n1^2 and skip the squaring.  Thus, we do the
-	 * multiply and the squaring in one step.
-	 */
-	assert(buf1 & tblmask);
-	mult1pos = e1bits - w1bits;
-	while ((buf1 & 1) == 0) {
-		buf1 >>= 1;
-		mult1pos++;
-	}
-	/* Intermediates can wrap, but final must NOT */
-	assert(mult1pos <= e1bits);
-	mult1 = table1[buf1>>1];
-	buf1 = 0;
-
-	/* Special case: use already-computed value sitting in buffer */
-	if (mult1pos == e1bits)
-		isone = 0;
-
-	/*
-	 * The first multiply by a power of n2.  Similar, but
-	 * we might not even want to schedule a multiply if e2 is
-	 * shorter than e1, and the window might be shorter so
-	 * we have to leave the low w2bits bits alone.
-	 */
-	if (buf2 & tblmask) {
-		/* Remember low-order bits for later */
-		i = buf2 & ((1u << w2bits) - 1);
-		buf2 >>= w2bits;
-		mult2pos = e1bits - w1bits + w2bits;
-		while ((buf2 & 1) == 0) {
-			buf2 >>= 1;
-			mult2pos++;
-		}
-		assert(mult2pos <= e1bits);
-		mult2 = table2[buf2>>1];
-		buf2 = i;
-
-		if (mult2pos == e1bits) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				lbnCopy_32(t, b, mlen);	/* Copy low to high */
-				isone = 0;
-			} else {
-				lbnMontMul_32(a, t, b, mod, mlen, inv);
-				t = a; a = b; b = t;
-			}
-		}
-	}
-
-	/*
-	 * At this point, the buffer (which is the high half of b)
-	 * holds either 1 (implicitly, as the "isone" flag is set),
-	 * n1^2, n2^2 or n1^2 * n2^2.
-	 */
-
-	/*
-	 * The main loop.  The procedure is:
-	 * - Advance the windows
-	 * - If the most-significant bit of a window is set,
-	 *   schedule a multiply for the appropriate time in the
-	 *   future (may be immediately)
-	 * - Perform any pending multiples
-	 * - Check for termination
-	 * - Square the buffers
-	 *
-	 * At any given time, the acumulated product is held in
-	 * the high half of b.
-	 */
-	for (;;) {
-		e1bits--;
-
-		/* Advance the windows */
-		assert(buf1 < tblmask);
-		buf1 <<= 1;
-		assert(buf2 < tblmask);
-		buf2 <<= 1;
-		/*
-		 * This reads ahead of the current exponent position
-		 * (controlled by e1bits), so we have to be able to read
-		 * past the lsb of the exponents without error.
-		 */
-		if (e1len) {
-			buf1 |= ((*e1 & bitpos) != 0);
-			if (e1len <= e2len)
-				buf2 |= ((*e2 & bitpos) != 0);
-			bitpos >>= 1;
-			if (!bitpos) {
-				BIGLITTLE(e1++,e1--);
-				if (e1len <= e2len)
-					BIGLITTLE(e2++,e2--);
-				bitpos = (BNWORD32)1 << (32-1);
-				e1len--;
-			}
-		}
-
-		/* Examine the first window for pending multiplies */
-		if (buf1 & tblmask) {
-			mult1pos = e1bits - w1bits;
-			while ((buf1 & 1) == 0) {
-				buf1 >>= 1;
-				mult1pos++;
-			}
-			/* Intermediates can wrap, but final must NOT */
-			assert(mult1pos <= e1bits);
-			mult1 = table1[buf1>>1];
-			buf1 = 0;
-		}
-
-		/*
-		 * Examine the second window for pending multiplies.
-		 * Window 2 can be smaller than window 1, but we
-		 * keep the same number of bits in buf2, so we need
-		 * to ignore any low-order bits in the buffer when
-		 * computing what to multiply by, and recompute them
-		 * later.
-		 */
-		if (buf2 & tblmask) {
-			/* Remember low-order bits for later */
-			i = buf2 & ((1u << w2bits) - 1);
-			buf2 >>= w2bits;
-			mult2pos = e1bits - w1bits + w2bits;
-			while ((buf2 & 1) == 0) {
-				buf2 >>= 1;
-				mult2pos++;
-			}
-			assert(mult2pos <= e1bits);
-			mult2 = table2[buf2>>1];
-			buf2 = i;
-		}
-
-
-		/* If we have a pending multiply for e1, do it */
-		if (e1bits == mult1pos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_32(t, mult1, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_32(a, t, mult1, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* If we have a pending multiply for e2, do it */
-		if (e1bits == mult2pos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_32(t, mult2, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_32(a, t, mult2, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* Are we done? */
-		if (!e1bits)
-			break;
-
-		/* Square the buffer */
-		if (!isone) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			lbnMontSquare_32(a, t, mod, mlen, inv);
-			/* Swap a and b */
-			t = a; a = b; b = t;
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	} /* for (;;) */
-
-	assert(!isone);
-	assert(!buf1);
-	assert(!buf2);
-
-	/* DONE! */
-
-	/* Convert result out of Montgomery form */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	lbnCopy_32(b, t, mlen);
-	lbnZero_32(t, mlen);
-	lbnMontReduce_32(b, mod, mlen, inv);
-	lbnCopy_32(result, t, mlen);
-
-	/* Clean up - free intermediate storage */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	buf2 = tblmask >> w2bits;
-	while (--tblmask) {
-		if (tblmask < buf2)
-			LBNFREE(table2[tblmask], mlen);
-		LBNFREE(table1[tblmask], mlen);
-	}
-	t = table1[0];
-	LBNFREE(t, mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-/*
- * 2^exp (mod mod).  This is an optimized version for use in Fermat
- * tests.  The input value of n is ignored; it is returned with
- * "mlen" words valid.
- */
-int
-lbnTwoExpMod_32(BNWORD32 *n, BNWORD32 const *exp, unsigned elen,
-	BNWORD32 *mod, unsigned mlen)
-{
-	unsigned e;	/* Copy of high words of the exponent */
-	unsigned bits;	/* Assorted counter of bits */
-	BNWORD32 const *bitptr;
-	BNWORD32 bitword, bitpos;
-	BNWORD32 *a, *b, *a1;
-	BNWORD32 inv;
-	int y;		/* Result of bnYield() */
-
-	assert(mlen);
-
-	bitptr = BIGLITTLE(exp-elen, exp+elen-1);
-	bitword = *bitptr;
-	assert(bitword);
-
-	/* Clear n for future use. */
-	lbnZero_32(n, mlen);
-
-	bits = lbnBits_32(exp, elen);
-	
-	/* First, a couple of trivial cases. */
-	if (bits <= 1) {
-		/* 2 ^ 0 == 1,  2 ^ 1 == 2 */
-		BIGLITTLE(n[-1],n[0]) = (BNWORD32)1<<elen;
-		return 0;
-	}
-
-	/* Set bitpos to the most significant bit */
-	bitpos = (BNWORD32)1 << ((bits-1) & (32-1));
-
-	/* Now, count the bits in the modulus. */
-	bits = lbnBits_32(mod, mlen);
-	assert(bits > 1);	/* a 1-bit modulus is just stupid... */
-
-	/*
-	 * We start with 1<<e, where "e" is as many high bits of the
-	 * exponent as we can manage without going over the modulus.
-	 * This first loop finds "e".
-	 */
-	e = 1;
-	while (elen) {
-		/* Consume the first bit */
-		bitpos >>= 1;
-		if (!bitpos) {
-			if (!--elen)
-				break;
-			bitword = BIGLITTLE(*++bitptr,*--bitptr);
-			bitpos = (BNWORD32)1<<(32-1);
-		}
-		e = (e << 1) | ((bitpos & bitword) != 0);
-		if (e >= bits) {	/* Overflow!  Back out. */
-			e >>= 1;
-			break;
-		}
-	}
-	/*
-	 * The bit in "bitpos" being examined by the bit buffer has NOT
-	 * been consumed yet.  This may be past the end of the exponent,
-	 * in which case elen == 1.
-	 */
-
-	/* Okay, now, set bit "e" in n.  n is already zero. */
-	inv = (BNWORD32)1 << (e & (32-1));
-	e /= 32;
-	BIGLITTLE(n[-e-1],n[e]) = inv;
-	/*
-	 * The effective length of n in words is now "e+1".
-	 * This is used a little bit later.
-	 */
-
-	if (!elen)
-		return 0;	/* That was easy! */
-
-	/*
-	 * We have now processed the first few bits.  The next step
-	 * is to convert this to Montgomery form for further squaring.
-	 */
-
-	/* Allocate working storage: two product buffers */
-	LBNALLOC(a, BNWORD32, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD32, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert n to Montgomery form */
-	inv = BIGLITTLE(mod[-1],mod[0]);	/* LSW of modulus */
-	assert(inv & 1);	/* Modulus must be odd */
-	inv = lbnMontInv1_32(inv);
-	/* Move n (length e+1, remember?) up "mlen" words into b */
-	/* Note that we lie about a1 for a bit - it's pointing to b */
-	a1 = BIGLITTLE(b-mlen,b+mlen);
-	lbnCopy_32(a1, n, e+1);
-	lbnZero_32(b, mlen);
-	/* Do the division - dump the quotient into the high-order words */
-	(void)lbnDiv_32(a1, b, mlen+e+1, mod, mlen);
-	/*
-	 * Now do the first squaring and modular reduction to put
-	 * the number up in a1 where it belongs.
-	 */
-	lbnMontSquare_32(a, b, mod, mlen, inv);
-	/* Fix up a1 to point to where it should go. */
-	a1 = BIGLITTLE(a-mlen,a+mlen);
-
-	/*
-	 * Okay, now, a1 holds the number being accumulated, and
-	 * b is a scratch register.  Start working:
-	 */
-	for (;;) {
-		/*
-		 * Is the bit set?  If so, double a1 as well.
-		 * A modular doubling like this is very cheap.
-		 */
-		if (bitpos & bitword) {
-			/*
-			 * Double the number.  If there was a carry out OR
-			 * the result is greater than the modulus, subract
-			 * the modulus.
-			 */
-			if (lbnDouble_32(a1, mlen) ||
-			    lbnCmp_32(a1, mod, mlen) > 0)
-				(void)lbnSubN_32(a1, mod, mlen);
-		}
-
-		/* Advance to the next exponent bit */
-		bitpos >>= 1;
-		if (!bitpos) {
-			if (!--elen)
-				break;	/* Done! */
-			bitword = BIGLITTLE(*++bitptr,*--bitptr);
-			bitpos = (BNWORD32)1<<(32-1);
-		}
-
-		/*
-		 * The elen/bitword/bitpos bit buffer is known to be
-		 * non-empty, i.e. there is at least one more unconsumed bit.
-		 * Thus, it's safe to square the number.
-		 */
-		lbnMontSquare_32(b, a1, mod, mlen, inv);
-		/* Rename result (in b) back to a (a1, really). */
-		a1 = b; b = a; a = a1;
-		a1 = BIGLITTLE(a-mlen,a+mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* DONE!  Just a little bit of cleanup... */
-
-	/*
-	 * Convert result out of Montgomery form... this is
-	 * just a Montgomery reduction.
-	 */
-	lbnCopy_32(a, a1, mlen);
-	lbnZero_32(a1, mlen);
-	lbnMontReduce_32(a, mod, mlen, inv);
-	lbnCopy_32(n, a1, mlen);
-
-	/* Clean up - free intermediate storage */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-
-/*
- * Returns a substring of the big-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length.  I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence 
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractBigBytes_32(BNWORD32 const *n, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen)
-{
-	BNWORD32 t = 0;	/* Needed to shut up uninitialized var warnings */
-	unsigned shift;
-
-	lsbyte += buflen;
-
-	shift = (8 * lsbyte) % 32;
-	lsbyte /= (32/8);	/* Convert to word offset */
-	BIGLITTLE(n -= lsbyte, n += lsbyte);
-
-	if (shift)
-		t = BIGLITTLE(n[-1],n[0]);
-
-	while (buflen--) {
-		if (!shift) {
-			t = BIGLITTLE(*n++,*--n);
-			shift = 32;
-		}
-		shift -= 8;
-		*buf++ = (unsigned char)(t>>shift);
-	}
-}
-
-/*
- * Merge a big-endian array of bytes into a bignum array.
- * The array had better be big enough.  This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its *last* byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right.  Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertBigBytes_32(BNWORD32 *n, unsigned char const *buf,
-                  unsigned lsbyte,  unsigned buflen)
-{
-	BNWORD32 t = 0;	/* Shut up uninitialized varibale warnings */
-
-	lsbyte += buflen;
-
-	BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
-
-	/* Load up leading odd bytes */
-	if (lsbyte % (32/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte * 8) % 32;
-	}
-
-	/* The main loop - merge into t, storing at each word boundary. */
-	while (buflen--) {
-		t = (t << 8) | *buf++;
-		if ((--lsbyte % (32/8)) == 0)
-			BIGLITTLE(*n++,*--n) = t;
-	}
-
-	/* Merge odd bytes in t into last word */
-	lsbyte = (lsbyte * 8) % 32;
-	if (lsbyte) {
-		t <<= lsbyte;
-		t |= (((BNWORD32)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
-		BIGLITTLE(n[0],n[-1]) = t;
-	}
-
-	return;
-}
-
-/*
- * Returns a substring of the little-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length.  I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence 
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractLittleBytes_32(BNWORD32 const *n, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen)
-{
-	BNWORD32 t = 0;	/* Needed to shut up uninitialized var warnings */
-
-	BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
-
-	if (lsbyte % (32/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte % (32/8)) * 8 ;
-	}
-
-	while (buflen--) {
-		if ((lsbyte++ % (32/8)) == 0)
-			t = BIGLITTLE(*--n,*n++);
-		*buf++ = (unsigned char)t;
-		t >>= 8;
-	}
-}
-
-/*
- * Merge a little-endian array of bytes into a bignum array.
- * The array had better be big enough.  This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its first byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right.  Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertLittleBytes_32(BNWORD32 *n, unsigned char const *buf,
-                  unsigned lsbyte,  unsigned buflen)
-{
-	BNWORD32 t = 0;	/* Shut up uninitialized varibale warnings */
-
-	/* Move to most-significant end */
-	lsbyte += buflen;
-	buf += buflen;
-
-	BIGLITTLE(n -= lsbyte/(32/8), n += lsbyte/(32/8));
-
-	/* Load up leading odd bytes */
-	if (lsbyte % (32/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte * 8) % 32;
-	}
-
-	/* The main loop - merge into t, storing at each word boundary. */
-	while (buflen--) {
-		t = (t << 8) | *--buf;
-		if ((--lsbyte % (32/8)) == 0)
-			BIGLITTLE(*n++,*--n) = t;
-	}
-
-	/* Merge odd bytes in t into last word */
-	lsbyte = (lsbyte * 8) % 32;
-	if (lsbyte) {
-		t <<= lsbyte;
-		t |= (((BNWORD32)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
-		BIGLITTLE(n[0],n[-1]) = t;
-	}
-
-	return;
-}
-
-#ifdef DEADCODE	/* This was a precursor to the more flexible lbnExtractBytes */
-/*
- * Convert a big-endian array of bytes to a bignum.
- * Returns the number of words in the bignum.
- * Note the expression "32/8" for the number of bytes per word.
- * This is so the word-size adjustment will work.
- */
-unsigned
-lbnFromBytes_32(BNWORD32 *a, unsigned char const *b, unsigned blen)
-{
-	BNWORD32 t;
-	unsigned alen = (blen + (32/8-1))/(32/8);
-	BIGLITTLE(a -= alen, a += alen);
-
-	while (blen) {
-		t = 0;
-		do {
-			t = t << 8 | *b++;
-		} while (--blen & (32/8-1));
-		BIGLITTLE(*a++,*--a) = t;
-	}
-	return alen;
-}
-#endif
-
-/*
- * Computes the GCD of a and b.  Modifies both arguments; when it returns,
- * one of them is the GCD and the other is trash.  The return value
- * indicates which: 0 for a, and 1 for b.  The length of the retult is
- * returned in rlen.  Both inputs must have one extra word of precision.
- * alen must be >= blen.
- *
- * TODO: use the binary algorithm (Knuth section 4.5.2, algorithm B).
- * This is based on taking out common powers of 2, then repeatedly:
- * gcd(2*u,v) = gcd(u,2*v) = gcd(u,v) - isolated powers of 2 can be deleted.
- * gcd(u,v) = gcd(u-v,v) - the numbers can be easily reduced.
- * It gets less reduction per step, but the steps are much faster than
- * the division case.
- */
-int
-lbnGcd_32(BNWORD32 *a, unsigned alen, BNWORD32 *b, unsigned blen,
-	unsigned *rlen)
-{
-#if BNYIELD
-	int y;
-#endif
-	assert(alen >= blen);
-
-	while (blen != 0) {
-		(void)lbnDiv_32(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
-		alen = lbnNorm_32(a, blen);
-		if (alen == 0) {
-			*rlen = blen;
-			return 1;
-		}
-		(void)lbnDiv_32(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
-		blen = lbnNorm_32(b, alen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			return y;
-#endif
-	}
-	*rlen = alen;
-	return 0;
-}
-
-/*
- * Invert "a" modulo "mod" using the extended Euclidean algorithm.
- * Note that this only computes one of the cosequences, and uses the
- * theorem that the signs flip every step and the absolute value of
- * the cosequence values are always bounded by the modulus to avoid
- * having to work with negative numbers.
- * gcd(a,mod) had better equal 1.  Returns 1 if the GCD is NOT 1.
- * a must be one word longer than "mod".  It is overwritten with the
- * result.
- * TODO: Use Richard Schroeppel's *much* faster algorithm.
- */
-int
-lbnInv_32(BNWORD32 *a, unsigned alen, BNWORD32 const *mod, unsigned mlen)
-{
-	BNWORD32 *b;	/* Hold a copy of mod during GCD reduction */
-	BNWORD32 *p;	/* Temporary for products added to t0 and t1 */
-	BNWORD32 *t0, *t1;	/* Inverse accumulators */
-	BNWORD32 cy;
-	unsigned blen, t0len, t1len, plen;
-	int y;
-
-	alen = lbnNorm_32(a, alen);
-	if (!alen)
-		return 1;	/* No inverse */
-
-	mlen = lbnNorm_32(mod, mlen);
-
-	assert (alen <= mlen);
-
-	/* Inverse of 1 is 1 */
-	if (alen == 1 && BIGLITTLE(a[-1],a[0]) == 1) {
-		lbnZero_32(BIGLITTLE(a-alen,a+alen), mlen-alen);
-		return 0;
-	}
-
-	/* Allocate a pile of space */
-	LBNALLOC(b, BNWORD32, mlen+1);
-	if (b) {
-		/*
-		 * Although products are guaranteed to always be less than the
-		 * modulus, it can involve multiplying two 3-word numbers to
-		 * get a 5-word result, requiring a 6th word to store a 0
-		 * temporarily.  Thus, mlen + 1.
-		 */
-		LBNALLOC(p, BNWORD32, mlen+1);
-		if (p) {
-			LBNALLOC(t0, BNWORD32, mlen);
-			if (t0) {
-				LBNALLOC(t1, BNWORD32, mlen);
-				if (t1)
-						goto allocated;
-				LBNFREE(t0, mlen);
-			}
-			LBNFREE(p, mlen+1);
-		}
-		LBNFREE(b, mlen+1);
-	}
-	return -1;
-
-allocated:
-
-	/* Set t0 to 1 */
-	t0len = 1;
-	BIGLITTLE(t0[-1],t0[0]) = 1;
-	
-	/* b = mod */
-	lbnCopy_32(b, mod, mlen);
-	/* blen = mlen (implicitly) */
-	
-	/* t1 = b / a; b = b % a */
-	cy = lbnDiv_32(t1, b, mlen, a, alen);
-	*(BIGLITTLE(t1-(mlen-alen)-1,t1+(mlen-alen))) = cy;
-	t1len = lbnNorm_32(t1, mlen-alen+1);
-	blen = lbnNorm_32(b, alen);
-
-	/* while (b > 1) */
-	while (blen > 1 || BIGLITTLE(b[-1],b[0]) != (BNWORD32)1) {
-		/* q = a / b; a = a % b; */
-		if (alen < blen || (alen == blen && lbnCmp_32(a, a, alen) < 0))
-			assert(0);
-		cy = lbnDiv_32(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
-		*(BIGLITTLE(a-alen-1,a+alen)) = cy;
-		plen = lbnNorm_32(BIGLITTLE(a-blen,a+blen), alen-blen+1);
-		assert(plen);
-		alen = lbnNorm_32(a, blen);
-		if (!alen)
-			goto failure;	/* GCD not 1 */
-
-		/* t0 += q * t1; */
-		assert(plen+t1len <= mlen+1);
-		lbnMul_32(p, BIGLITTLE(a-blen,a+blen), plen, t1, t1len);
-		plen = lbnNorm_32(p, plen + t1len);
-		assert(plen <= mlen);
-		if (plen > t0len) {
-			lbnZero_32(BIGLITTLE(t0-t0len,t0+t0len), plen-t0len);
-			t0len = plen;
-		}
-		cy = lbnAddN_32(t0, p, plen);
-		if (cy) {
-			if (t0len > plen) {
-				cy = lbnAdd1_32(BIGLITTLE(t0-plen,t0+plen),
-						t0len-plen, cy);
-			}
-			if (cy) {
-				BIGLITTLE(t0[-t0len-1],t0[t0len]) = cy;
-				t0len++;
-			}
-		}
-
-		/* if (a <= 1) return a ? t0 : FAIL; */
-		if (alen <= 1 && BIGLITTLE(a[-1],a[0]) == (BNWORD32)1) {
-			if (alen == 0)
-				goto failure;	/* FAIL */
-			assert(t0len <= mlen);
-			lbnCopy_32(a, t0, t0len);
-			lbnZero_32(BIGLITTLE(a-t0len, a+t0len), mlen-t0len);
-			goto success;
-		}
-
-		/* q = b / a; b = b % a; */
-		if (blen < alen || (blen == alen && lbnCmp_32(b, a, alen) < 0))
-			assert(0);
-		cy = lbnDiv_32(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
-		*(BIGLITTLE(b-blen-1,b+blen)) = cy;
-		plen = lbnNorm_32(BIGLITTLE(b-alen,b+alen), blen-alen+1);
-		assert(plen);
-		blen = lbnNorm_32(b, alen);
-		if (!blen)
-			goto failure;	/* GCD not 1 */
-
-		/* t1 += q * t0; */
-		assert(plen+t0len <= mlen+1);
-		lbnMul_32(p, BIGLITTLE(b-alen,b+alen), plen, t0, t0len);
-		plen = lbnNorm_32(p, plen + t0len);
-		assert(plen <= mlen);
-		if (plen > t1len) {
-			lbnZero_32(BIGLITTLE(t1-t1len,t1+t1len), plen-t1len);
-			t1len = plen;
-		}
-		cy = lbnAddN_32(t1, p, plen);
-		if (cy) {
-			if (t1len > plen) {
-				cy = lbnAdd1_32(BIGLITTLE(t1-plen,t0+plen),
-						t1len-plen, cy);
-			}
-			if (cy) {
-				BIGLITTLE(t1[-t1len-1],t1[t1len]) = cy;
-				t1len++;
-			}
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield() < 0))
-			goto yield;
-#endif
-	}
-
-	if (!blen)
-		goto failure;	/* gcd(a, mod) != 1 -- FAIL */
-
-	/* return mod-t1 */
-	lbnCopy_32(a, mod, mlen);
-	assert(t1len <= mlen);
-	cy = lbnSubN_32(a, t1, t1len);
-	if (cy) {
-		assert(mlen > t1len);
-		cy = lbnSub1_32(BIGLITTLE(a-t1len, a+t1len), mlen-t1len, cy);
-		assert(!cy);
-	}
-
-success:
-	LBNFREE(t1, mlen);
-	LBNFREE(t0, mlen);
-	LBNFREE(p, mlen+1);
-	LBNFREE(b, mlen+1);
-	
-	return 0;
-
-failure:		/* GCD is not 1 - no inverse exists! */
-	y = 1;
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(t1, mlen);
-	LBNFREE(t0, mlen);
-	LBNFREE(p, mlen+1);
-	LBNFREE(b, mlen+1);
-	
-	return y;
-}
-
-/*
- * Precompute powers of "a" mod "mod".  Compute them every "bits"
- * for "n" steps.  This is sufficient to compute powers of g with
- * exponents up to n*bits bits long, i.e. less than 2^(n*bits).
- * 
- * This assumes that the caller has already initialized "array" to point
- * to "n" buffers of size "mlen".
- */
-int
-lbnBasePrecompBegin_32(BNWORD32 **array, unsigned n, unsigned bits,
-	BNWORD32 const *g, unsigned glen, BNWORD32 *mod, unsigned mlen)
-{
-	BNWORD32 *a, *b;	/* Temporary double-width accumulators */
-	BNWORD32 *a1;	/* Pointer to high half of a*/
-	BNWORD32 inv;	/* Montgomery inverse of LSW of mod */
-	BNWORD32 *t;
-	unsigned i;
-
-	glen = lbnNorm_32(g, glen);
-	assert(glen);
-
-	assert (mlen == lbnNorm_32(mod, mlen));
-	assert (glen <= mlen);
-
-	/* Allocate two temporary buffers, and the array slots */
-	LBNALLOC(a, BNWORD32, mlen*2);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD32, mlen*2);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Okay, all ready */
-
-	/* Convert n to Montgomery form */
-	inv = BIGLITTLE(mod[-1],mod[0]);	/* LSW of modulus */
-	assert(inv & 1);	/* Modulus must be odd */
-	inv = lbnMontInv1_32(inv);
-	/* Move g up "mlen" words into a (clearing the low mlen words) */
-	a1 = BIGLITTLE(a-mlen,a+mlen);
-	lbnCopy_32(a1, g, glen);
-	lbnZero_32(a, mlen);
-
-	/* Do the division - dump the quotient into the high-order words */
-	(void)lbnDiv_32(a1, a, mlen+glen, mod, mlen);
-
-	/* Copy the first value into the array */
-	t = *array;
-	lbnCopy_32(t, a, mlen);
-	a1 = a;	/* This first value is *not* shifted up */
-	
-	/* Now compute the remaining n-1 array entries */
-	assert(bits);
-	assert(n);
-	while (--n) {
-		i = bits;
-		do {
-			/* Square a1 into b1 */
-			lbnMontSquare_32(b, a1, mod, mlen, inv);
-			t = b; b = a; a = t;
-			a1 = BIGLITTLE(a-mlen, a+mlen);
-		} while (--i);
-		t = *++array;
-		lbnCopy_32(t, a1, mlen);
-	}
-
-	/* Hooray, we're done. */
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-	return 0;
-}
-
-/*
- * result = base^exp (mod mod).  "array" is a an array of pointers
- * to procomputed powers of base, each 2^bits apart.  (I.e. array[i]
- * is base^(2^(i*bits))).
- * 
- * The algorithm consists of:
- * a  = b  = (powers of g to be raised to the power 2^bits-1)
- * a *= b *= (powers of g to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of g to be raised to the power 1)
- * 
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnBasePrecompExp_32(BNWORD32 *result, BNWORD32 const * const *array,
-       unsigned bits, BNWORD32 const *exp, unsigned elen,
-       BNWORD32 const *mod, unsigned mlen)
-{
-	BNWORD32 *a, *b, *c, *t;
-	BNWORD32 *a1, *b1;
-	int anull, bnull;	/* Null flags: values are implicitly 1 */
-	unsigned i, j;				/* Loop counters */
-	unsigned mask;				/* Exponent bits to examime */
-	BNWORD32 const *eptr;			/* Pointer into exp */
-	BNWORD32 buf, curbits, nextword;	/* Bit-buffer varaibles */
-	BNWORD32 inv;				/* Inverse of LSW of modulus */
-	unsigned ewords;			/* Words of exponent left */
-	int bufbits;				/* Number of valid bits */
-	int y = 0;
-
-	mlen = lbnNorm_32(mod, mlen);
-	assert (mlen);
-
-	elen = lbnNorm_32(exp, elen);
-	if (!elen) {
-		lbnZero_32(result, mlen);
-		BIGLITTLE(result[-1],result[0]) = 1;
-		return 0;
-	}
-	/*
-	 * This could be precomputed, but it's so cheap, and it would require
-	 * making the precomputation structure word-size dependent.
-	 */
-	inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	assert(elen);
-
-	/*
-	 * Allocate three temporary buffers.  The current numbers generally
-	 * live in the upper halves of these buffers.
-	 */
-	LBNALLOC(a, BNWORD32, mlen*2);
-	if (a) {
-		LBNALLOC(b, BNWORD32, mlen*2);
-		if (b) {
-			LBNALLOC(c, BNWORD32, mlen*2);
-			if (c)
-				goto allocated;
-			LBNFREE(b, 2*mlen);
-		}
-		LBNFREE(a, 2*mlen);
-	}
-	return -1;
-
-allocated:
-
-	anull = bnull = 1;
-
-	mask = (1u<<bits) - 1;
-	for (i = mask; i; --i) {
-		/* Set up bit buffer for walking the exponent */
-		eptr = exp;
-		buf = BIGLITTLE(*--eptr, *eptr++);
-		ewords = elen-1;
-		bufbits = 32;
-		for (j = 0; ewords || buf; j++) {
-			/* Shift down current buffer */
-			curbits = buf;
-			buf >>= bits;
-			/* If necessary, add next word */
-			bufbits -= bits;
-			if (bufbits < 0 && ewords > 0) {
-				nextword = BIGLITTLE(*--eptr, *eptr++);
-				ewords--;
-				curbits |= nextword << (bufbits+bits);
-				buf = nextword >> -bufbits;
-				bufbits += 32;
-			}
-			/* If appropriate, multiply b *= array[j] */
-			if ((curbits & mask) == i) {
-				BNWORD32 const *d = array[j];
-
-				b1 = BIGLITTLE(b-mlen-1,b+mlen);
-				if (bnull) {
-					lbnCopy_32(b1, d, mlen);
-					bnull = 0;
-				} else {
-					lbnMontMul_32(c, b1, d, mod, mlen, inv);
-					t = c; c = b; b = t;
-				}
-#if BNYIELD
-				if (bnYield && (y = bnYield() < 0))
-					goto yield;
-#endif
-			}
-		}
-
-		/* Multiply a *= b */
-		if (!bnull) {
-			a1 = BIGLITTLE(a-mlen-1,a+mlen);
-			b1 = BIGLITTLE(b-mlen-1,b+mlen);
-			if (anull) {
-				lbnCopy_32(a1, b1, mlen);
-				anull = 0;
-			} else {
-				lbnMontMul_32(c, a1, b1, mod, mlen, inv);
-				t = c; c = a; a = t;
-			}
-		}
-	}
-
-	assert(!anull);	/* If it were, elen would have been 0 */
-
-	/* Convert out of Montgomery form and return */
-	a1 = BIGLITTLE(a-mlen-1,a+mlen);
-	lbnCopy_32(a, a1, mlen);
-	lbnZero_32(a1, mlen);
-	lbnMontReduce_32(a, mod, mlen, inv);
-	lbnCopy_32(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(c, 2*mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;
-}
-
-/*
- * result = base1^exp1 *base2^exp2 (mod mod).  "array1" and "array2" are
- * arrays of pointers to procomputed powers of the corresponding bases,
- * each 2^bits apart.  (I.e. array1[i] is base1^(2^(i*bits))).
- * 
- * Bits must be the same in both.  (It could be made adjustable, but it's
- * a bit of a pain.  Just make them both equal to the larger one.)
- * 
- * The algorithm consists of:
- * a  = b  = (powers of base1 and base2  to be raised to the power 2^bits-1)
- * a *= b *= (powers of base1 and base2 to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of base1 and base2 to be raised to the power 1)
- * 
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnDoubleBasePrecompExp_32(BNWORD32 *result, unsigned bits,
-       BNWORD32 const * const *array1, BNWORD32 const *exp1, unsigned elen1,
-       BNWORD32 const * const *array2, BNWORD32 const *exp2,
-       unsigned elen2, BNWORD32 const *mod, unsigned mlen)
-{
-	BNWORD32 *a, *b, *c, *t;
-	BNWORD32 *a1, *b1;
-	int anull, bnull;	/* Null flags: values are implicitly 1 */
-	unsigned i, j, k;				/* Loop counters */
-	unsigned mask;				/* Exponent bits to examime */
-	BNWORD32 const *eptr;			/* Pointer into exp */
-	BNWORD32 buf, curbits, nextword;	/* Bit-buffer varaibles */
-	BNWORD32 inv;				/* Inverse of LSW of modulus */
-	unsigned ewords;			/* Words of exponent left */
-	int bufbits;				/* Number of valid bits */
-	int y = 0;
-	BNWORD32 const * const *array;
-
-	mlen = lbnNorm_32(mod, mlen);
-	assert (mlen);
-
-	elen1 = lbnNorm_32(exp1, elen1);
-	if (!elen1) {
-		return lbnBasePrecompExp_32(result, array2, bits, exp2, elen2,
-		                            mod, mlen);
-	}
-	elen2 = lbnNorm_32(exp2, elen2);
-	if (!elen2) {
-		return lbnBasePrecompExp_32(result, array1, bits, exp1, elen1,
-		                            mod, mlen);
-	}
-	/*
-	 * This could be precomputed, but it's so cheap, and it would require
-	 * making the precomputation structure word-size dependent.
-	 */
-	inv = lbnMontInv1_32(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	assert(elen1);
-	assert(elen2);
-
-	/*
-	 * Allocate three temporary buffers.  The current numbers generally
-	 * live in the upper halves of these buffers.
-	 */
-	LBNALLOC(a, BNWORD32, mlen*2);
-	if (a) {
-		LBNALLOC(b, BNWORD32, mlen*2);
-		if (b) {
-			LBNALLOC(c, BNWORD32, mlen*2);
-			if (c)
-				goto allocated;
-			LBNFREE(b, 2*mlen);
-		}
-		LBNFREE(a, 2*mlen);
-	}
-	return -1;
-
-allocated:
-
-	anull = bnull = 1;
-
-	mask = (1u<<bits) - 1;
-	for (i = mask; i; --i) {
-		/* Walk each exponent in turn */
-		for (k = 0; k < 2; k++) {
-			/* Set up the exponent for walking */
-			array = k ? array2 : array1;
-			eptr = k ? exp2 : exp1;
-			ewords = (k ? elen2 : elen1) - 1;
-			/* Set up bit buffer for walking the exponent */
-			buf = BIGLITTLE(*--eptr, *eptr++);
-			bufbits = 32;
-			for (j = 0; ewords || buf; j++) {
-				/* Shift down current buffer */
-				curbits = buf;
-				buf >>= bits;
-				/* If necessary, add next word */
-				bufbits -= bits;
-				if (bufbits < 0 && ewords > 0) {
-					nextword = BIGLITTLE(*--eptr, *eptr++);
-					ewords--;
-					curbits |= nextword << (bufbits+bits);
-					buf = nextword >> -bufbits;
-					bufbits += 32;
-				}
-				/* If appropriate, multiply b *= array[j] */
-				if ((curbits & mask) == i) {
-					BNWORD32 const *d = array[j];
-
-					b1 = BIGLITTLE(b-mlen-1,b+mlen);
-					if (bnull) {
-						lbnCopy_32(b1, d, mlen);
-						bnull = 0;
-					} else {
-						lbnMontMul_32(c, b1, d, mod, mlen, inv);
-						t = c; c = b; b = t;
-					}
-#if BNYIELD
-					if (bnYield && (y = bnYield() < 0))
-						goto yield;
-#endif
-				}
-			}
-		}
-
-		/* Multiply a *= b */
-		if (!bnull) {
-			a1 = BIGLITTLE(a-mlen-1,a+mlen);
-			b1 = BIGLITTLE(b-mlen-1,b+mlen);
-			if (anull) {
-				lbnCopy_32(a1, b1, mlen);
-				anull = 0;
-			} else {
-				lbnMontMul_32(c, a1, b1, mod, mlen, inv);
-				t = c; c = a; a = t;
-			}
-		}
-	}
-
-	assert(!anull);	/* If it were, elen would have been 0 */
-
-	/* Convert out of Montgomery form and return */
-	a1 = BIGLITTLE(a-mlen-1,a+mlen);
-	lbnCopy_32(a, a1, mlen);
-	lbnZero_32(a1, mlen);
-	lbnMontReduce_32(a, mod, mlen, inv);
-	lbnCopy_32(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(c, 2*mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;
-}
diff --git a/jni/libzrtp/sources/bnlib/lbn32.h b/jni/libzrtp/sources/bnlib/lbn32.h
deleted file mode 100644
index e975550..0000000
--- a/jni/libzrtp/sources/bnlib/lbn32.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef LBN32_H
-#define LBN32_H
-
-#include "lbn.h"
-
-#ifndef BNWORD32
-#error 32-bit bignum library requires a 32-bit data type
-#endif
-
-#ifndef lbnCopy_32
-void lbnCopy_32(BNWORD32 *dest, BNWORD32 const *src, unsigned len);
-#endif
-#ifndef lbnZero_32
-void lbnZero_32(BNWORD32 *num, unsigned len);
-#endif
-#ifndef lbnNeg_32
-void lbnNeg_32(BNWORD32 *num, unsigned len);
-#endif
-
-#ifndef lbnAdd1_32
-BNWORD32 lbnAdd1_32(BNWORD32 *num, unsigned len, BNWORD32 carry);
-#endif
-#ifndef lbnSub1_32
-BNWORD32 lbnSub1_32(BNWORD32 *num, unsigned len, BNWORD32 borrow);
-#endif
-
-#ifndef lbnAddN_32
-BNWORD32 lbnAddN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len);
-#endif
-#ifndef lbnSubN_32
-BNWORD32 lbnSubN_32(BNWORD32 *num1, BNWORD32 const *num2, unsigned len);
-#endif
-
-#ifndef lbnCmp_32
-int lbnCmp_32(BNWORD32 const *num1, BNWORD32 const *num2, unsigned len);
-#endif
-
-#ifndef lbnMulN1_32
-void lbnMulN1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k);
-#endif
-#ifndef lbnMulAdd1_32
-BNWORD32
-lbnMulAdd1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k);
-#endif
-#ifndef lbnMulSub1_32
-BNWORD32 lbnMulSub1_32(BNWORD32 *out, BNWORD32 const *in, unsigned len, BNWORD32 k);
-#endif
-
-#ifndef lbnLshift_32
-BNWORD32 lbnLshift_32(BNWORD32 *num, unsigned len, unsigned shift);
-#endif
-#ifndef lbnDouble_32
-BNWORD32 lbnDouble_32(BNWORD32 *num, unsigned len);
-#endif
-#ifndef lbnRshift_32
-BNWORD32 lbnRshift_32(BNWORD32 *num, unsigned len, unsigned shift);
-#endif
-
-#ifndef lbnMul_32
-void lbnMul_32(BNWORD32 *prod, BNWORD32 const *num1, unsigned len1,
-	BNWORD32 const *num2, unsigned len2);
-#endif
-#ifndef lbnSquare_32
-void lbnSquare_32(BNWORD32 *prod, BNWORD32 const *num, unsigned len);
-#endif
-
-#ifndef lbnNorm_32
-unsigned lbnNorm_32(BNWORD32 const *num, unsigned len);
-#endif
-#ifndef lbnBits_32
-unsigned lbnBits_32(BNWORD32 const *num, unsigned len);
-#endif
-
-#ifndef lbnExtractBigBytes_32
-void lbnExtractBigBytes_32(BNWORD32 const *bn, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertBigytes_32
-void lbnInsertBigBytes_32(BNWORD32 *n, unsigned char const *buf,
-	unsigned lsbyte,  unsigned buflen);
-#endif
-#ifndef lbnExtractLittleBytes_32
-void lbnExtractLittleBytes_32(BNWORD32 const *bn, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertLittleBytes_32
-void lbnInsertLittleBytes_32(BNWORD32 *n, unsigned char const *buf,
-	unsigned lsbyte,  unsigned buflen);
-#endif
-
-#ifndef lbnDiv21_32
-BNWORD32 lbnDiv21_32(BNWORD32 *q, BNWORD32 nh, BNWORD32 nl, BNWORD32 d);
-#endif
-#ifndef lbnDiv1_32
-BNWORD32 lbnDiv1_32(BNWORD32 *q, BNWORD32 *rem,
-	BNWORD32 const *n, unsigned len, BNWORD32 d);
-#endif
-#ifndef lbnModQ_32
-unsigned lbnModQ_32(BNWORD32 const *n, unsigned len, unsigned d);
-#endif
-#ifndef lbnDiv_32
-BNWORD32
-lbnDiv_32(BNWORD32 *q, BNWORD32 *n, unsigned nlen, BNWORD32 *d, unsigned dlen);
-#endif
-
-#ifndef lbnMontInv1_32
-BNWORD32 lbnMontInv1_32(BNWORD32 const x);
-#endif
-#ifndef lbnMontReduce_32
-void lbnMontReduce_32(BNWORD32 *n, BNWORD32 const *mod, unsigned const mlen,
-                BNWORD32 inv);
-#endif
-#ifndef lbnToMont_32
-void lbnToMont_32(BNWORD32 *n, unsigned nlen, BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnFromMont_32
-void lbnFromMont_32(BNWORD32 *n, BNWORD32 *mod, unsigned len);
-#endif
-
-#ifndef lbnExpMod_32
-int lbnExpMod_32(BNWORD32 *result, BNWORD32 const *n, unsigned nlen,
-	BNWORD32 const *exp, unsigned elen, BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnDoubleExpMod_32
-int lbnDoubleExpMod_32(BNWORD32 *result,
-	BNWORD32 const *n1, unsigned n1len, BNWORD32 const *e1, unsigned e1len,
-	BNWORD32 const *n2, unsigned n2len, BNWORD32 const *e2, unsigned e2len,
-	BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnTwoExpMod_32
-int lbnTwoExpMod_32(BNWORD32 *n, BNWORD32 const *exp, unsigned elen,
-	BNWORD32 *mod, unsigned mlen);
-#endif
-#ifndef lbnGcd_32
-int lbnGcd_32(BNWORD32 *a, unsigned alen, BNWORD32 *b, unsigned blen,
-	unsigned *rlen);
-#endif
-#ifndef lbnInv_32
-int lbnInv_32(BNWORD32 *a, unsigned alen, BNWORD32 const *mod, unsigned mlen);
-#endif
-
-int lbnBasePrecompBegin_32(BNWORD32 **array, unsigned n, unsigned bits,
-	BNWORD32 const *g, unsigned glen, BNWORD32 *mod, unsigned mlen);
-int lbnBasePrecompExp_32(BNWORD32 *result, BNWORD32 const * const *array,
-       unsigned bits, BNWORD32 const *exp, unsigned elen,
-       BNWORD32 const *mod, unsigned mlen);
-int lbnDoubleBasePrecompExp_32(BNWORD32 *result, unsigned bits,
-       BNWORD32 const * const *array1, BNWORD32 const *exp1, unsigned elen1,
-       BNWORD32 const * const *array2, BNWORD32 const *exp2,
-       unsigned elen2, BNWORD32 const *mod, unsigned mlen);
-
-#endif /* LBN32_H */
diff --git a/jni/libzrtp/sources/bnlib/lbn64.c b/jni/libzrtp/sources/bnlib/lbn64.c
deleted file mode 100644
index e930652..0000000
--- a/jni/libzrtp/sources/bnlib/lbn64.c
+++ /dev/null
@@ -1,4073 +0,0 @@
-/*
- * lbn64.c - Low-level bignum routines, 64-bit version.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * NOTE: the magic constants "64" and "128" appear in many places in this
- * file, including inside identifiers.  Because it is not possible to
- * ask "#ifdef" of a macro expansion, it is not possible to use the
- * preprocessor to conditionalize these properly.  Thus, this file is
- * intended to be edited with textual search and replace to produce
- * alternate word size versions.  Any reference to the number of bits
- * in a word must be the string "64", and that string must not appear
- * otherwise.  Any reference to twice this number must appear as "128",
- * which likewise must not appear otherwise.  Is that clear?
- *
- * Remember, when doubling the bit size replace the larger number (128)
- * first, then the smaller (64).  When halving the bit size, do the
- * opposite.  Otherwise, things will get wierd.  Also, be sure to replace
- * every instance that appears.  (:%s/foo/bar/g in vi)
- *
- * These routines work with a pointer to the least-significant end of
- * an array of WORD64s.  The BIG(x), LITTLE(y) and BIGLTTLE(x,y) macros
- * defined in lbn.h (which expand to x on a big-edian machine and y on a
- * little-endian machine) are used to conditionalize the code to work
- * either way.  If you have no assembly primitives, it doesn't matter.
- * Note that on a big-endian machine, the least-significant-end pointer
- * is ONE PAST THE END.  The bytes are ptr[-1] through ptr[-len].
- * On little-endian, they are ptr[0] through ptr[len-1].  This makes
- * perfect sense if you consider pointers to point *between* bytes rather
- * than at them.
- *
- * Because the array index values are unsigned integers, ptr[-i]
- * may not work properly, since the index -i is evaluated as an unsigned,
- * and if pointers are wider, zero-extension will produce a positive
- * number rahter than the needed negative.  The expression used in this
- * code, *(ptr-i) will, however, work.  (The array syntax is equivalent
- * to *(ptr+-i), which is a pretty subtle difference.)
- *
- * Many of these routines will get very unhappy if fed zero-length inputs.
- * They use assert() to enforce this.  An higher layer of code must make
- * sure that these aren't called with zero-length inputs.
- *
- * Any of these routines can be replaced with more efficient versions
- * elsewhere, by just #defining their names.  If one of the names
- * is #defined, the C code is not compiled in and no declaration is
- * made.  Use the BNINCLUDE file to do that.  Typically, you compile
- * asm subroutines with the same name and just, e.g.
- * #define lbnMulAdd1_64 lbnMulAdd1_64
- *
- * If you want to write asm routines, start with lbnMulAdd1_64().
- * This is the workhorse of modular exponentiation.  lbnMulN1_64() is
- * also used a fair bit, although not as much and it's defined in terms
- * of lbnMulAdd1_64 if that has a custom version.  lbnMulSub1_64 and
- * lbnDiv21_64 are used in the usual division and remainder finding.
- * (Not the Montgomery reduction used in modular exponentiation, though.)
- * Once you have lbnMulAdd1_64 defined, writing the other two should
- * be pretty easy.  (Just make sure you get the sign of the subtraction
- * in lbnMulSub1_64 right - it's dest = dest - source * k.)
- *
- * The only definitions that absolutely need a double-word (BNWORD128)
- * type are lbnMulAdd1_64 and lbnMulSub1_64; if those are provided,
- * the rest follows.  lbnDiv21_64, however, is a lot slower unless you
- * have them, and lbnModQ_64 takes after it.  That one is used quite a
- * bit for prime sieving.
- */
-
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_STRING_H
-#include <string.h>	/* For memcpy */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "lbn.h"
-#include "lbn64.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef BNWORD64
-#error 64-bit bignum library requires a 64-bit data type
-#endif
-
-/* If this is defined, include bnYield() calls */
-#if BNYIELD
-extern int (*bnYield)(void);	/* From bn.c */
-#endif
-
-/*
- * Most of the multiply (and Montgomery reduce) routines use an outer
- * loop that iterates over one of the operands - a so-called operand
- * scanning approach.  One big advantage of this is that the assembly
- * support routines are simpler.  The loops can be rearranged to have
- * an outer loop that iterates over the product, a so-called product
- * scanning approach.  This has the advantage of writing less data
- * and doing fewer adds to memory, so is supposedly faster.  Some
- * code has been written using a product-scanning approach, but
- * it appears to be slower, so it is turned off by default.  Some
- * experimentation would be appreciated.
- *
- * (The code is also annoying to get right and not very well commented,
- * one of my pet peeves about math libraries.  I'm sorry.)
- */
-#ifndef PRODUCT_SCAN
-#define PRODUCT_SCAN 0
-#endif
-
-/*
- * Copy an array of words.  <Marvin mode on>  Thrilling, isn't it? </Marvin>
- * This is a good example of how the byte offsets and BIGLITTLE() macros work.
- * Another alternative would have been
- * memcpy(dest BIG(-len), src BIG(-len), len*sizeof(BNWORD64)), but I find that
- * putting operators into conditional macros is confusing.
- */
-#ifndef lbnCopy_64
-void
-lbnCopy_64(BNWORD64 *dest, BNWORD64 const *src, unsigned len)
-{
-	memcpy(BIGLITTLE(dest-len,dest), BIGLITTLE(src-len,src),
-	       len * sizeof(*src));
-}
-#endif /* !lbnCopy_64 */
-
-/*
- * Fill n words with zero.  This does it manually rather than calling
- * memset because it can assume alignment to make things faster while
- * memset can't.  Note how big-endian numbers are naturally addressed
- * using predecrement, while little-endian is postincrement.
- */
-#ifndef lbnZero_64
-void
-lbnZero_64(BNWORD64 *num, unsigned len)
-{
-	while (len--)
-		BIGLITTLE(*--num,*num++) = 0;
-}
-#endif /* !lbnZero_64 */
-
-/*
- * Negate an array of words.
- * Negation is subtraction from zero.  Negating low-order words
- * entails doing nothing until a non-zero word is hit.  Once that
- * is negated, a borrow is generated and never dies until the end
- * of the number is hit.  Negation with borrow, -x-1, is the same as ~x.
- * Repeat that until the end of the number.
- *
- * Doesn't return borrow out because that's pretty useless - it's
- * always set unless the input is 0, which is easy to notice in
- * normalized form.
- */
-#ifndef lbnNeg_64
-void
-lbnNeg_64(BNWORD64 *num, unsigned len)
-{
-	assert(len);
-
-	/* Skip low-order zero words */
-	while (BIGLITTLE(*--num,*num) == 0) {
-		if (!--len)
-			return;
-		LITTLE(num++;)
-	}
-	/* Negate the lowest-order non-zero word */
-	*num = -*num;
-	/* Complement all the higher-order words */
-	while (--len) {
-		BIGLITTLE(--num,++num);
-		*num = ~*num;
-	}
-}
-#endif /* !lbnNeg_64 */
-
-
-/*
- * lbnAdd1_64: add the single-word "carry" to the given number.
- * Used for minor increments and propagating the carry after
- * adding in a shorter bignum.
- *
- * Technique: If we have a double-width word, presumably the compiler
- * can add using its carry in inline code, so we just use a larger
- * accumulator to compute the carry from the first addition.
- * If not, it's more complex.  After adding the first carry, which may
- * be > 1, compare the sum and the carry.  If the sum wraps (causing a
- * carry out from the addition), the result will be less than each of the
- * inputs, since the wrap subtracts a number (2^64) which is larger than
- * the other input can possibly be.  If the sum is >= the carry input,
- * return success immediately.
- * In either case, if there is a carry, enter a loop incrementing words
- * until one does not wrap.  Since we are adding 1 each time, the wrap
- * will be to 0 and we can test for equality.
- */
-#ifndef lbnAdd1_64	/* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD128
-BNWORD64
-lbnAdd1_64(BNWORD64 *num, unsigned len, BNWORD64 carry)
-{
-	BNWORD128 t;
-	assert(len > 0);	/* Alternative: if (!len) return carry */
-
-	t = (BNWORD128)BIGLITTLE(*--num,*num) + carry;
-	BIGLITTLE(*num,*num++) = (BNWORD64)t;
-	if ((t >> 64) == 0)
-		return 0;
-	while (--len) {
-		if (++BIGLITTLE(*--num,*num++) != 0)
-			return 0;
-	}
-	return 1;
-}
-#else /* no BNWORD128 */
-BNWORD64
-lbnAdd1_64(BNWORD64 *num, unsigned len, BNWORD64 carry)
-{
-	assert(len > 0);	/* Alternative: if (!len) return carry */
-
-	if ((BIGLITTLE(*--num,*num++) += carry) >= carry)
-		return 0;
-	while (--len) {
-		if (++BIGLITTLE(*--num,*num++) != 0)
-			return 0;
-	}
-	return 1;
-}
-#endif
-#endif/* !lbnAdd1_64 */
-
-/*
- * lbnSub1_64: subtract the single-word "borrow" from the given number.
- * Used for minor decrements and propagating the borrow after
- * subtracting a shorter bignum.
- *
- * Technique: Similar to the add, above.  If there is a double-length type,
- * use that to generate the first borrow.
- * If not, after subtracting the first borrow, which may be > 1, compare
- * the difference and the *negative* of the carry.  If the subtract wraps
- * (causing a borrow out from the subtraction), the result will be at least
- * as large as -borrow.  If the result < -borrow, then no borrow out has
- * appeared and we may return immediately, except when borrow == 0.  To
- * deal with that case, use the identity that -x = ~x+1, and instead of
- * comparing < -borrow, compare for <= ~borrow.
- * Either way, if there is a borrow out, enter a loop decrementing words
- * until a non-zero word is reached.
- *
- * Note the cast of ~borrow to (BNWORD64).  If the size of an int is larger
- * than BNWORD64, C rules say the number is expanded for the arithmetic, so
- * the inversion will be done on an int and the value won't be quite what
- * is expected.
- */
-#ifndef lbnSub1_64	/* If defined, it's provided as an asm subroutine */
-#ifdef BNWORD128
-BNWORD64
-lbnSub1_64(BNWORD64 *num, unsigned len, BNWORD64 borrow)
-{
-	BNWORD128 t;
-	assert(len > 0);	/* Alternative: if (!len) return borrow */
-
-	t = (BNWORD128)BIGLITTLE(*--num,*num) - borrow;
-	BIGLITTLE(*num,*num++) = (BNWORD64)t;
-	if ((t >> 64) == 0)
-		return 0;
-	while (--len) {
-		if ((BIGLITTLE(*--num,*num++))-- != 0)
-			return 0;
-	}
-	return 1;
-}
-#else /* no BNWORD128 */
-BNWORD64
-lbnSub1_64(BNWORD64 *num, unsigned len, BNWORD64 borrow)
-{
-	assert(len > 0);	/* Alternative: if (!len) return borrow */
-
-	if ((BIGLITTLE(*--num,*num++) -= borrow) <= (BNWORD64)~borrow)
-		return 0;
-	while (--len) {
-		if ((BIGLITTLE(*--num,*num++))-- != 0)
-			return 0;
-	}
-	return 1;
-}
-#endif
-#endif /* !lbnSub1_64 */
-
-/*
- * lbnAddN_64: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with lbnAdd1, of adding two bignums of
- * differing lengths.
- *
- * Technique: Maintain a word of carry.  If there is no double-width type,
- * use the same technique as in lbnAdd1, above, to maintain the carry by
- * comparing the inputs.  Adding the carry sources is used as an OR operator;
- * at most one of the two comparisons can possibly be true.  The first can
- * only be true if carry == 1 and x, the result, is 0.  In that case the
- * second can't possibly be true.
- */
-#ifndef lbnAddN_64
-#ifdef BNWORD128
-BNWORD64
-lbnAddN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
-	BNWORD128 t;
-
-	assert(len > 0);
-
-	t = (BNWORD128)BIGLITTLE(*--num1,*num1) + BIGLITTLE(*--num2,*num2++);
-	BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
-	while (--len) {
-		t = (BNWORD128)BIGLITTLE(*--num1,*num1) +
-		    (BNWORD128)BIGLITTLE(*--num2,*num2++) + (t >> 64);
-		BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
-	}
-
-	return (BNWORD64)(t>>64);
-}
-#else /* no BNWORD128 */
-BNWORD64
-lbnAddN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
-	BNWORD64 x, carry = 0;
-
-	assert(len > 0);	/* Alternative: change loop to test at start */
-
-	do {
-		x = BIGLITTLE(*--num2,*num2++);
-		carry = (x += carry) < carry;
-		carry += (BIGLITTLE(*--num1,*num1++) += x) < x;
-	} while (--len);
-
-	return carry;
-}
-#endif
-#endif /* !lbnAddN_64 */
-
-/*
- * lbnSubN_64: add two bignums of the same length, returning the carry (0 or 1).
- * One of the building blocks, along with subn1, of subtracting two bignums of
- * differing lengths.
- *
- * Technique: If no double-width type is availble, maintain a word of borrow.
- * First, add the borrow to the subtrahend (did you have to learn all those
- * awful words in elementary school, too?), and if it overflows, set the
- * borrow again.  Then subtract the modified subtrahend from the next word
- * of input, using the same technique as in subn1, above.
- * Adding the borrows is used as an OR operator; at most one of the two
- * comparisons can possibly be true.  The first can only be true if
- * borrow == 1 and x, the result, is 0.  In that case the second can't
- * possibly be true.
- *
- * In the double-word case, (BNWORD64)-(t>>64) is subtracted, rather than
- * adding t>>64, because the shift would need to sign-extend and that's
- * not guaranteed to happen in ANSI C, even with signed types.
- */
-#ifndef lbnSubN_64
-#ifdef BNWORD128
-BNWORD64
-lbnSubN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
-	BNWORD128 t;
-
-	assert(len > 0);
-
-	t = (BNWORD128)BIGLITTLE(*--num1,*num1) - BIGLITTLE(*--num2,*num2++);
-	BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
-
-	while (--len) {
-		t = (BNWORD128)BIGLITTLE(*--num1,*num1) -
-		    (BNWORD128)BIGLITTLE(*--num2,*num2++) - (BNWORD64)-(t >> 64);
-		BIGLITTLE(*num1,*num1++) = (BNWORD64)t;
-	}
-
-	return -(BNWORD64)(t>>64);
-}
-#else
-BNWORD64
-lbnSubN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len)
-{
-	BNWORD64 x, borrow = 0;
-
-	assert(len > 0);	/* Alternative: change loop to test at start */
-
-	do {
-		x = BIGLITTLE(*--num2,*num2++);
-		borrow = (x += borrow) < borrow;
-		borrow += (BIGLITTLE(*--num1,*num1++) -= x) > (BNWORD64)~x;
-	} while (--len);
-
-	return borrow;
-}
-#endif
-#endif /* !lbnSubN_64 */
-
-#ifndef lbnCmp_64
-/*
- * lbnCmp_64: compare two bignums of equal length, returning the sign of
- * num1 - num2. (-1, 0 or +1).
- * 
- * Technique: Change the little-endian pointers to big-endian pointers
- * and compare from the most-significant end until a difference if found.
- * When it is, figure out the sign of the difference and return it.
- */
-int
-lbnCmp_64(BNWORD64 const *num1, BNWORD64 const *num2, unsigned len)
-{
-	BIGLITTLE(num1 -= len, num1 += len);
-	BIGLITTLE(num2 -= len, num2 += len);
-
-	while (len--) {
-		if (BIGLITTLE(*num1++ != *num2++, *--num1 != *--num2)) {
-			if (BIGLITTLE(num1[-1] < num2[-1], *num1 < *num2))
-				return -1;
-			else
-				return 1;
-		}
-	}
-	return 0;
-}
-#endif /* !lbnCmp_64 */
-
-/*
- * mul64_ppmmaa(ph,pl,x,y,a,b) is an optional routine that
- * computes (ph,pl) = x * y + a + b.  mul64_ppmma and mul64_ppmm
- * are simpler versions.  If you want to be lazy, all of these
- * can be defined in terms of the others, so here we create any
- * that have not been defined in terms of the ones that have been.
- */
-
-/* Define ones with fewer a's in terms of ones with more a's */
-#if !defined(mul64_ppmma) && defined(mul64_ppmmaa)
-#define mul64_ppmma(ph,pl,x,y,a) mul64_ppmmaa(ph,pl,x,y,a,0)
-#endif
-
-#if !defined(mul64_ppmm) && defined(mul64_ppmma)
-#define mul64_ppmm(ph,pl,x,y) mul64_ppmma(ph,pl,x,y,0)
-#endif
-
-/*
- * Use this definition to test the mul64_ppmm-based operations on machines
- * that do not provide mul64_ppmm.  Change the final "0" to a "1" to
- * enable it.
- */
-#if !defined(mul64_ppmm) && defined(BNWORD128) && 0	/* Debugging */
-#define mul64_ppmm(ph,pl,x,y) \
-	({BNWORD128 _ = (BNWORD128)(x)*(y); (pl) = _; (ph) = _>>64;})
-#endif
-
-#if defined(mul64_ppmm) && !defined(mul64_ppmma)
-#define mul64_ppmma(ph,pl,x,y,a) \
-	(mul64_ppmm(ph,pl,x,y), (ph) += ((pl) += (a)) < (a))
-#endif
-
-#if defined(mul64_ppmma) && !defined(mul64_ppmmaa)
-#define mul64_ppmmaa(ph,pl,x,y,a,b) \
-	(mul64_ppmma(ph,pl,x,y,a), (ph) += ((pl) += (b)) < (b))
-#endif
-
-/*
- * lbnMulN1_64: Multiply an n-word input by a 1-word input and store the
- * n+1-word product.  This uses either the mul64_ppmm and mul64_ppmma
- * macros, or C multiplication with the BNWORD128 type.  This uses mul64_ppmma
- * if available, assuming you won't bother defining it unless you can do
- * better than the normal multiplication.
- */
-#ifndef lbnMulN1_64
-#ifdef lbnMulAdd1_64	/* If we have this asm primitive, use it. */
-void
-lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
-	lbnZero_64(out, len);
-	BIGLITTLE(*(out-len-1),*(out+len)) = lbnMulAdd1_64(out, in, len, k);
-}
-#elif defined(mul64_ppmm)
-void
-lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
-	BNWORD64 carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--out;--in;);
-	mul64_ppmm(carry, *out, *in, k);
-	LITTLE(out++;in++;)
-
-	while (--len) {
-		BIG(--out;--in;)
-		carryin = carry;
-		mul64_ppmma(carry, *out, *in, k, carryin);
-		LITTLE(out++;in++;)
-	}
-	BIGLITTLE(*--out,*out) = carry;
-}
-#elif defined(BNWORD128)
-void
-lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
-	BNWORD128 p;
-
-	assert(len > 0);
-
-	p = (BNWORD128)BIGLITTLE(*--in,*in++) * k;
-	BIGLITTLE(*--out,*out++) = (BNWORD64)p;
-
-	while (--len) {
-		p = (BNWORD128)BIGLITTLE(*--in,*in++) * k + (BNWORD64)(p >> 64);
-		BIGLITTLE(*--out,*out++) = (BNWORD64)p;
-	}
-	BIGLITTLE(*--out,*out) = (BNWORD64)(p >> 64);
-}
-#else
-#error No 64x64 -> 128 multiply available for 64-bit bignum package
-#endif
-#endif /* lbnMulN1_64 */
-
-/*
- * lbnMulAdd1_64: Multiply an n-word input by a 1-word input and add the
- * low n words of the product to the destination.  *Returns the n+1st word
- * of the product.*  (That turns out to be more convenient than adding
- * it into the destination and dealing with a possible unit carry out
- * of *that*.)  This uses either the mul64_ppmma and mul64_ppmmaa macros,
- * or C multiplication with the BNWORD128 type.
- *
- * If you're going to write assembly primitives, this is the one to
- * start with.  It is by far the most commonly called function.
- */
-#ifndef lbnMulAdd1_64
-#if defined(mul64_ppmm)
-BNWORD64
-lbnMulAdd1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
-	BNWORD64 prod, carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--out;--in;);
-	carryin = *out;
-	mul64_ppmma(carry, *out, *in, k, carryin);
-	LITTLE(out++;in++;)
-
-	while (--len) {
-		BIG(--out;--in;);
-		carryin = carry;
-		mul64_ppmmaa(carry, prod, *in, k, carryin, *out);
-		*out = prod;
-		LITTLE(out++;in++;)
-	}
-
-	return carry;
-}
-#elif defined(BNWORD128)
-BNWORD64
-lbnMulAdd1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
-	BNWORD128 p;
-
-	assert(len > 0);
-
-	p = (BNWORD128)BIGLITTLE(*--in,*in++) * k + BIGLITTLE(*--out,*out);
-	BIGLITTLE(*out,*out++) = (BNWORD64)p;
-
-	while (--len) {
-		p = (BNWORD128)BIGLITTLE(*--in,*in++) * k +
-		    (BNWORD64)(p >> 64) + BIGLITTLE(*--out,*out);
-		BIGLITTLE(*out,*out++) = (BNWORD64)p;
-	}
-
-	return (BNWORD64)(p >> 64);
-}
-#else
-#error No 64x64 -> 128 multiply available for 64-bit bignum package
-#endif
-#endif /* lbnMulAdd1_64 */
-
-/*
- * lbnMulSub1_64: Multiply an n-word input by a 1-word input and subtract the
- * n-word product from the destination.  Returns the n+1st word of the product.
- * This uses either the mul64_ppmm and mul64_ppmma macros, or
- * C multiplication with the BNWORD128 type.
- *
- * This is rather uglier than adding, but fortunately it's only used in
- * division which is not used too heavily.
- */
-#ifndef lbnMulSub1_64
-#if defined(mul64_ppmm)
-BNWORD64
-lbnMulSub1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
-	BNWORD64 prod, carry, carryin;
-
-	assert(len > 0);
-
-	BIG(--in;)
-	mul64_ppmm(carry, prod, *in, k);
-	LITTLE(in++;)
-	carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD64)~prod;
-
-	while (--len) {
-		BIG(--in;);
-		carryin = carry;
-		mul64_ppmma(carry, prod, *in, k, carryin);
-		LITTLE(in++;)
-		carry += (BIGLITTLE(*--out,*out++) -= prod) > (BNWORD64)~prod;
-	}
-
-	return carry;
-}
-#elif defined(BNWORD128)
-BNWORD64
-lbnMulSub1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k)
-{
-	BNWORD128 p;
-	BNWORD64 carry, t;
-
-	assert(len > 0);
-
-	p = (BNWORD128)BIGLITTLE(*--in,*in++) * k;
-	t = BIGLITTLE(*--out,*out);
-	carry = (BNWORD64)(p>>64) + ((BIGLITTLE(*out,*out++)=t-(BNWORD64)p) > t);
-
-	while (--len) {
-		p = (BNWORD128)BIGLITTLE(*--in,*in++) * k + carry;
-		t = BIGLITTLE(*--out,*out);
-		carry = (BNWORD64)(p>>64) +
-			( (BIGLITTLE(*out,*out++)=t-(BNWORD64)p) > t );
-	}
-
-	return carry;
-}
-#else
-#error No 64x64 -> 128 multiply available for 64-bit bignum package
-#endif
-#endif /* !lbnMulSub1_64 */
-
-/*
- * Shift n words left "shift" bits.  0 < shift < 64.  Returns the
- * carry, any bits shifted off the left-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnLshift_64
-BNWORD64
-lbnLshift_64(BNWORD64 *num, unsigned len, unsigned shift)
-{
-	BNWORD64 x, carry;
-
-	assert(shift > 0);
-	assert(shift < 64);
-
-	carry = 0;
-	while (len--) {
-		BIG(--num;)
-		x = *num;
-		*num = (x<<shift) | carry;
-		LITTLE(num++;)
-		carry = x >> (64-shift);
-	}
-	return carry;
-}
-#endif /* !lbnLshift_64 */
-
-/*
- * An optimized version of the above, for shifts of 1.
- * Some machines can use add-with-carry tricks for this.
- */
-#ifndef lbnDouble_64
-BNWORD64
-lbnDouble_64(BNWORD64 *num, unsigned len)
-{
-	BNWORD64 x, carry;
-
-	carry = 0;
-	while (len--) {
-		BIG(--num;)
-		x = *num;
-		*num = (x<<1) | carry;
-		LITTLE(num++;)
-		carry = x >> (64-1);
-	}
-	return carry;
-}
-#endif /* !lbnDouble_64 */
-
-/*
- * Shift n words right "shift" bits.  0 < shift < 64.  Returns the
- * carry, any bits shifted off the right-hand side (0 <= carry < 2^shift).
- */
-#ifndef lbnRshift_64
-BNWORD64
-lbnRshift_64(BNWORD64 *num, unsigned len, unsigned shift)
-{
-	BNWORD64 x, carry = 0;
-
-	assert(shift > 0);
-	assert(shift < 64);
-
-	BIGLITTLE(num -= len, num += len);
-
-	while (len--) {
-		LITTLE(--num;)
-		x = *num;
-		*num = (x>>shift) | carry;
-		BIG(num++;)
-		carry = x << (64-shift);
-	}
-	return carry >> (64-shift);
-}
-#endif /* !lbnRshift_64 */
-
-/* 
- * Multiply two numbers of the given lengths.  prod and num2 may overlap,
- * provided that the low len1 bits of prod are free.  (This corresponds
- * nicely to the place the result is returned from lbnMontReduce_64.)
- *
- * TODO: Use Karatsuba multiply.  The overlap constraints may have
- * to get rewhacked.
- */
-#ifndef lbnMul_64
-void
-lbnMul_64(BNWORD64 *prod, BNWORD64 const *num1, unsigned len1,
-                          BNWORD64 const *num2, unsigned len2)
-{
-	/* Special case of zero */
-	if (!len1 || !len2) {
-		lbnZero_64(prod, len1+len2);
-		return;
-	}
-
-	/* Multiply first word */
-	lbnMulN1_64(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-
-	/*
-	 * Add in subsequent words, storing the most significant word,
-	 * which is new each time.
-	 */
-	while (--len2) {
-		BIGLITTLE(--prod,prod++);
-		BIGLITTLE(*(prod-len1-1),*(prod+len1)) =
-		    lbnMulAdd1_64(prod, num1, len1, BIGLITTLE(*--num2,*num2++));
-	}
-}
-#endif /* !lbnMul_64 */
-
-/*
- * lbnMulX_64 is a square multiply - both inputs are the same length.
- * It's normally just a macro wrapper around the general multiply,
- * but might be implementable in assembly more efficiently (such as
- * when product scanning).
- */
-#ifndef lbnMulX_64
-#if defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Test code to see whether product scanning is any faster.  It seems
- * to make the C code slower, so PRODUCT_SCAN is not defined.
- */
-static void
-lbnMulX_64(BNWORD64 *prod, BNWORD64 const *num1, BNWORD64 const *num2,
-	unsigned len)
-{
-	BNWORD128 x, y;
-	BNWORD64 const *p1, *p2;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	x = (BNWORD128)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
-	BIGLITTLE(*--prod, *prod++) = (BNWORD64)x;
-	x >>= 64;
-
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = num1;
-		p2 = BIGLITTLE(num2-i-1,num2+i+1);
-		for (j = 0; j <= i; j++) {
-			BIG(y = (BNWORD128)*--p1 * *p2++;)
-			LITTLE(y = (BNWORD128)*p1++ * *--p2;)
-			x += y;
-			carry += (x < y);
-		}
-		BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
-		x = (x >> 64) | (BNWORD128)carry << 64;
-	}
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = BIGLITTLE(num1-i,num1+i);
-		p2 = BIGLITTLE(num2-len,num2+len);
-		for (j = i; j < len; j++) {
-			BIG(y = (BNWORD128)*--p1 * *p2++;)
-			LITTLE(y = (BNWORD128)*p1++ * *--p2;)
-			x += y;
-			carry += (x < y);
-		}
-		BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
-		x = (x >> 64) | (BNWORD128)carry << 64;
-	}
-	
-	BIGLITTLE(*--prod,*prod) = (BNWORD64)x;
-}
-#else /* !defined(BNWORD128) || !PRODUCT_SCAN */
-/* Default trivial macro definition */
-#define lbnMulX_64(prod, num1, num2, len) lbnMul_64(prod, num1, len, num2, len)
-#endif /* !defined(BNWORD128) || !PRODUCT_SCAN */
-#endif /* !lbmMulX_64 */
-
-#if !defined(lbnMontMul_64) && defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Test code for product-scanning multiply.  This seems to slow the C
- * code down rather than speed it up.
- * This does a multiply and Montgomery reduction together, using the
- * same loops.  The outer loop scans across the product, twice.
- * The first pass computes the low half of the product and the
- * Montgomery multipliers.  These are stored in the product array,
- * which contains no data as of yet.  x and carry add up the columns
- * and propagate carries forward.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers.  The results of this multiply
- * are stored.
- */
-static void
-lbnMontMul_64(BNWORD64 *prod, BNWORD64 const *num1, BNWORD64 const *num2,
-	BNWORD64 const *mod, unsigned len, BNWORD64 inv)
-{
-	BNWORD128 x, y;
-	BNWORD64 const *p1, *p2, *pm;
-	BNWORD64 *pp;
-	BNWORD64 t;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	/*
-	 * This computes directly into the high half of prod, so just
-	 * shift the pointer and consider prod only "len" elements long
-	 * for the rest of the code.
-	 */
-	BIGLITTLE(prod -= len, prod += len);
-
-	/* Pass 1 - compute Montgomery multipliers */
-	/* First iteration can have certain simplifications. */
-	x = (BNWORD128)BIGLITTLE(num1[-1] * num2[-1], num1[0] * num2[0]);
-	BIGLITTLE(prod[-1], prod[0]) = t = inv * (BNWORD64)x;
-	y = (BNWORD128)t * BIGLITTLE(mod[-1],mod[0]);
-	x += y;
-	/* Note: GCC 2.6.3 has a bug if you try to eliminate "carry" */
-	carry = (x < y);
-	assert((BNWORD64)x == 0);
-	x = x >> 64 | (BNWORD128)carry << 64;
-
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = num1;
-		p2 = BIGLITTLE(num2-i-1,num2+i+1);
-		pp = prod;
-		pm = BIGLITTLE(mod-i-1,mod+i+1);
-		for (j = 0; j < i; j++) {
-			y = (BNWORD128)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
-			x += y;
-			carry += (x < y);
-			y = (BNWORD128)BIGLITTLE(*--pp * *pm++, *pp++ * *--pm);
-			x += y;
-			carry += (x < y);
-		}
-		y = (BNWORD128)BIGLITTLE(p1[-1] * p2[0], p1[0] * p2[-1]);
-		x += y;
-		carry += (x < y);
-		assert(BIGLITTLE(pp == prod-i, pp == prod+i));
-		BIGLITTLE(pp[-1], pp[0]) = t = inv * (BNWORD64)x;
-		assert(BIGLITTLE(pm == mod-1, pm == mod+1));
-		y = (BNWORD128)t * BIGLITTLE(pm[0],pm[-1]);
-		x += y;
-		carry += (x < y);
-		assert((BNWORD64)x == 0);
-		x = x >> 64 | (BNWORD128)carry << 64;
-	}
-
-	/* Pass 2 - compute reduced product and store */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		p1 = BIGLITTLE(num1-i,num1+i);
-		p2 = BIGLITTLE(num2-len,num2+len);
-		pm = BIGLITTLE(mod-i,mod+i);
-		pp = BIGLITTLE(prod-len,prod+len);
-		for (j = i; j < len; j++) {
-			y = (BNWORD128)BIGLITTLE(*--p1 * *p2++, *p1++ * *--p2);
-			x += y;
-			carry += (x < y);
-			y = (BNWORD128)BIGLITTLE(*--pm * *pp++, *pm++ * *--pp);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pm == mod-len, pm == mod+len));
-		assert(BIGLITTLE(pp == prod-i, pp == prod+i));
-		BIGLITTLE(pp[0],pp[-1]) = (BNWORD64)x;
-		x = (x >> 64) | (BNWORD128)carry << 64;
-	}
-
-	/* Last round of second half, simplified. */
-	BIGLITTLE(*(prod-len),*(prod+len-1)) = (BNWORD64)x;
-	carry = (x >> 64);
-
-	while (carry)
-		carry -= lbnSubN_64(prod, mod, len);
-	while (lbnCmp_64(prod, mod, len) >= 0)
-		(void)lbnSubN_64(prod, mod, len);
-}
-/* Suppress later definition */
-#define lbnMontMul_64 lbnMontMul_64
-#endif
-
-#if !defined(lbnSquare_64) && defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Trial code for product-scanning squaring.  This seems to slow the C
- * code down rather than speed it up.
- */
-void
-lbnSquare_64(BNWORD64 *prod, BNWORD64 const *num, unsigned len)
-{
-	BNWORD128 x, y, z;
-	BNWORD64 const *p1, *p2;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!len)
-		return;
-
-	/* Word 0 of product */
-	x = (BNWORD128)BIGLITTLE(num[-1] * num[-1], num[0] * num[0]);
-	BIGLITTLE(*--prod, *prod++) = (BNWORD64)x;
-	x >>= 64;
-
-	/* Words 1 through len-1 */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		y = 0;
-		p1 = num;
-		p2 = BIGLITTLE(num-i-1,num+i+1);
-		for (j = 0; j < (i+1)/2; j++) {
-			BIG(z = (BNWORD128)*--p1 * *p2++;)
-			LITTLE(z = (BNWORD128)*p1++ * *--p2;)
-			y += z;
-			carry += (y < z);
-		}
-		y += z = y;
-		carry += carry + (y < z);
-		if ((i & 1) == 0) {
-			assert(BIGLITTLE(--p1 == p2, p1 == --p2));
-			BIG(z = (BNWORD128)*p2 * *p2;)
-			LITTLE(z = (BNWORD128)*p1 * *p1;)
-			y += z;
-			carry += (y < z);
-		}
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
-		x = (x >> 64) | (BNWORD128)carry << 64;
-	}
-	/* Words len through 2*len-2 */
-	for (i = 1; i < len; i++) {
-		carry = 0;
-		y = 0;
-		p1 = BIGLITTLE(num-i,num+i);
-		p2 = BIGLITTLE(num-len,num+len);
-		for (j = 0; j < (len-i)/2; j++) {
-			BIG(z = (BNWORD128)*--p1 * *p2++;)
-			LITTLE(z = (BNWORD128)*p1++ * *--p2;)
-			y += z;
-			carry += (y < z);
-		}
-		y += z = y;
-		carry += carry + (y < z);
-		if ((len-i) & 1) {
-			assert(BIGLITTLE(--p1 == p2, p1 == --p2));
-			BIG(z = (BNWORD128)*p2 * *p2;)
-			LITTLE(z = (BNWORD128)*p1 * *p1;)
-			y += z;
-			carry += (y < z);
-		}
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*--prod,*prod++) = (BNWORD64)x;
-		x = (x >> 64) | (BNWORD128)carry << 64;
-	}
-	
-	/* Word 2*len-1 */
-	BIGLITTLE(*--prod,*prod) = (BNWORD64)x;
-}
-/* Suppress later definition */
-#define lbnSquare_64 lbnSquare_64
-#endif
-
-/*
- * Square a number, using optimized squaring to reduce the number of
- * primitive multiples that are executed.  There may not be any
- * overlap of the input and output.
- *
- * Technique: Consider the partial products in the multiplication
- * of "abcde" by itself:
- *
- *               a  b  c  d  e
- *            *  a  b  c  d  e
- *          ==================
- *              ae be ce de ee
- *           ad bd cd dd de
- *        ac bc cc cd ce
- *     ab bb bc bd be
- *  aa ab ac ad ae
- *
- * Note that everything above the main diagonal:
- *              ae be ce de = (abcd) * e
- *           ad bd cd       = (abc) * d
- *        ac bc             = (ab) * c
- *     ab                   = (a) * b
- *
- * is a copy of everything below the main diagonal:
- *                       de
- *                 cd ce
- *           bc bd be
- *     ab ac ad ae
- *
- * Thus, the sum is 2 * (off the diagonal) + diagonal.
- *
- * This is accumulated beginning with the diagonal (which
- * consist of the squares of the digits of the input), which is then
- * divided by two, the off-diagonal added, and multiplied by two
- * again.  The low bit is simply a copy of the low bit of the
- * input, so it doesn't need special care.
- *
- * TODO: Merge the shift by 1 with the squaring loop.
- * TODO: Use Karatsuba.  (a*W+b)^2 = a^2 * (W^2+W) + b^2 * (W+1) - (a-b)^2 * W.
- */
-#ifndef lbnSquare_64
-void
-lbnSquare_64(BNWORD64 *prod, BNWORD64 const *num, unsigned len)
-{
-	BNWORD64 t;
-	BNWORD64 *prodx = prod;		/* Working copy of the argument */
-	BNWORD64 const *numx = num;	/* Working copy of the argument */
-	unsigned lenx = len;		/* Working copy of the argument */
-
-	if (!len)
-		return;
-
-	/* First, store all the squares */
-	while (lenx--) {
-#ifdef mul64_ppmm
-		BNWORD64 ph, pl;
-		t = BIGLITTLE(*--numx,*numx++);
-		mul64_ppmm(ph,pl,t,t);
-		BIGLITTLE(*--prodx,*prodx++) = pl;
-		BIGLITTLE(*--prodx,*prodx++) = ph;
-#elif defined(BNWORD128) /* use BNWORD128 */
-		BNWORD128 p;
-		t = BIGLITTLE(*--numx,*numx++);
-		p = (BNWORD128)t * t;
-		BIGLITTLE(*--prodx,*prodx++) = (BNWORD64)p;
-		BIGLITTLE(*--prodx,*prodx++) = (BNWORD64)(p>>64);
-#else	/* Use lbnMulN1_64 */
-		t = BIGLITTLE(numx[-1],*numx);
-		lbnMulN1_64(prodx, numx, 1, t);
-		BIGLITTLE(--numx,numx++);
-		BIGLITTLE(prodx -= 2, prodx += 2);
-#endif
-	}
-	/* Then, shift right 1 bit */
-	(void)lbnRshift_64(prod, 2*len, 1);
-
-	/* Then, add in the off-diagonal sums */
-	lenx = len;
-	numx = num;
-	prodx = prod;
-	while (--lenx) {
-		t = BIGLITTLE(*--numx,*numx++);
-		BIGLITTLE(--prodx,prodx++);
-		t = lbnMulAdd1_64(prodx, numx, lenx, t);
-		lbnAdd1_64(BIGLITTLE(prodx-lenx,prodx+lenx), lenx+1, t);
-		BIGLITTLE(--prodx,prodx++);
-	}
-
-	/* Shift it back up */
-	lbnDouble_64(prod, 2*len);
-
-	/* And set the low bit appropriately */
-	BIGLITTLE(prod[-1],prod[0]) |= BIGLITTLE(num[-1],num[0]) & 1;
-}
-#endif /* !lbnSquare_64 */
-
-/*
- * lbnNorm_64 - given a number, return a modified length such that the
- * most significant digit is non-zero.  Zero-length input is okay.
- */
-#ifndef lbnNorm_64
-unsigned
-lbnNorm_64(BNWORD64 const *num, unsigned len)
-{
-	BIGLITTLE(num -= len,num += len);
-	while (len && BIGLITTLE(*num++,*--num) == 0)
-		--len;
-	return len;
-}
-#endif /* lbnNorm_64 */
-
-/*
- * lbnBits_64 - return the number of significant bits in the array.
- * It starts by normalizing the array.  Zero-length input is okay.
- * Then assuming there's anything to it, it fetches the high word,
- * generates a bit length by multiplying the word length by 64, and
- * subtracts off 64/2, 64/4, 64/8, ... bits if the high bits are clear.
- */
-#ifndef lbnBits_64
-unsigned
-lbnBits_64(BNWORD64 const *num, unsigned len)
-{
-	BNWORD64 t;
-	unsigned i;
-
-	len = lbnNorm_64(num, len);
-	if (len) {
-		t = BIGLITTLE(*(num-len),*(num+(len-1)));
-		assert(t);
-		len *= 64;
-		i = 64/2;
-		do {
-			if (t >> i)
-				t >>= i;
-			else
-				len -= i;
-		} while ((i /= 2) != 0);
-	}
-	return len;
-}
-#endif /* lbnBits_64 */
-
-/*
- * If defined, use hand-rolled divide rather than compiler's native.
- * If the machine doesn't do it in line, the manual code is probably
- * faster, since it can assume normalization and the fact that the
- * quotient will fit into 64 bits, which a general 128-bit divide
- * in a compiler's run-time library can't do.
- */
-#ifndef BN_SLOW_DIVIDE_128
-/* Assume that divisors of more than thirty-two bits are slow */
-#define BN_SLOW_DIVIDE_128 (128 > 0x20)
-#endif
-
-/*
- * Return (nh<<64|nl) % d, and place the quotient digit into *q.
- * It is guaranteed that nh < d, and that d is normalized (with its high
- * bit set).  If we have a double-width type, it's easy.  If not, ooh,
- * yuk!
- */
-#ifndef lbnDiv21_64
-#if defined(BNWORD128) && !BN_SLOW_DIVIDE_128
-BNWORD64
-lbnDiv21_64(BNWORD64 *q, BNWORD64 nh, BNWORD64 nl, BNWORD64 d)
-{
-	BNWORD128 n = (BNWORD128)nh << 64 | nl;
-
-	/* Divisor must be normalized */
-	assert(d >> (64-1) == 1);
-
-	*q = n / d;
-	return n % d;
-}
-#else
-/*
- * This is where it gets ugly.
- *
- * Do the division in two halves, using Algorithm D from section 4.3.1
- * of Knuth.  Note Theorem B from that section, that the quotient estimate
- * is never more than the true quotient, and is never more than two
- * too low.
- *
- * The mapping onto conventional long division is (everything a half word):
- *        _____________qh___ql_
- * dh dl ) nh.h nh.l nl.h nl.l
- *             - (qh * d)
- *            -----------
- *              rrrr rrrr nl.l
- *                  - (ql * d)
- *                -----------
- *                  rrrr rrrr
- *
- * The implicit 3/2-digit d*qh and d*ql subtractors are computed this way:
- *   First, estimate a q digit so that nh/dh works.  Subtracting qh*dh from
- *   the (nh.h nh.l) list leaves a 1/2-word remainder r.  Then compute the
- *   low part of the subtractor, qh * dl.   This also needs to be subtracted
- *   from (nh.h nh.l nl.h) to get the final remainder.  So we take the
- *   remainder, which is (nh.h nh.l) - qh*dl, shift it and add in nl.h, and
- *   try to subtract qh * dl from that.  Since the remainder is 1/2-word
- *   long, shifting and adding nl.h results in a single word r.
- *   It is possible that the remainder we're working with, r, is less than
- *   the product qh * dl, if we estimated qh too high.  The estimation
- *   technique can produce a qh that is too large (never too small), leading
- *   to r which is too small.  In that case, decrement the digit qh, add
- *   shifted dh to r (to correct for that error), and subtract dl from the
- *   product we're comparing r with.  That's the "correct" way to do it, but
- *   just adding dl to r instead of subtracting it from the product is
- *   equivalent and a lot simpler.  You just have to watch out for overflow.
- *
- *   The process is repeated with (rrrr rrrr nl.l) for the low digit of the
- *   quotient ql.
- *
- * The various uses of 64/2 for shifts are because of the note about
- * automatic editing of this file at the very top of the file.
- */
-#define highhalf(x) ( (x) >> 64/2 )
-#define lowhalf(x) ( (x) & (((BNWORD64)1 << 64/2)-1) )
-BNWORD64
-lbnDiv21_64(BNWORD64 *q, BNWORD64 nh, BNWORD64 nl, BNWORD64 d)
-{
-	BNWORD64 dh = highhalf(d), dl = lowhalf(d);
-	BNWORD64 qh, ql, prod, r;
-
-	/* Divisor must be normalized */
-	assert((d >> (64-1)) == 1);
-
-	/* Do first half-word of division */
-	qh = nh / dh;
-	r = nh % dh;
-	prod = qh * dl;
-
-	/*
-	 * Add next half-word of numerator to remainder and correct.
-	 * qh may be up to two too large.
-	 */
-	r = (r << (64/2)) | highhalf(nl);
-	if (r < prod) {
-		--qh; r += d;
-		if (r >= d && r < prod) {
-			--qh; r += d; 
-		}
-	}
-	r -= prod;
-
-	/* Do second half-word of division */
-	ql = r / dh;
-	r = r % dh;
-	prod = ql * dl;
-
-	r = (r << (64/2)) | lowhalf(nl);
-	if (r < prod) {
-		--ql; r += d;
-		if (r >= d && r < prod) {
-			--ql; r += d;
-		}
-	}
-	r -= prod;
-
-	*q = (qh << (64/2)) | ql;
-
-	return r;
-}
-#endif
-#endif /* lbnDiv21_64 */
-
-
-/*
- * In the division functions, the dividend and divisor are referred to
- * as "n" and "d", which stand for "numerator" and "denominator".
- *
- * The quotient is (nlen-dlen+1) digits long.  It may be overlapped with
- * the high (nlen-dlen) words of the dividend, but one extra word is needed
- * on top to hold the top word.
- */
-
-/*
- * Divide an n-word number by a 1-word number, storing the remainder
- * and n-1 words of the n-word quotient.  The high word is returned.
- * It IS legal for rem to point to the same address as n, and for
- * q to point one word higher.
- *
- * TODO: If BN_SLOW_DIVIDE_128, add a divnhalf_64 which uses 64-bit
- *       dividends if the divisor is half that long.
- * TODO: Shift the dividend on the fly to avoid the last division and
- *       instead have a remainder that needs shifting.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef lbnDiv1_64
-BNWORD64
-lbnDiv1_64(BNWORD64 *q, BNWORD64 *rem, BNWORD64 const *n, unsigned len,
-	BNWORD64 d)
-{
-	unsigned shift;
-	unsigned xlen;
-	BNWORD64 r;
-	BNWORD64 qhigh;
-
-	assert(len > 0);
-	assert(d);
-
-	if (len == 1) {
-		r = *n;
-		*rem = r%d;
-		return r/d;
-	}
-
-	shift = 0;
-	r = d;
-	xlen = 64/2;
-	do {
-		if (r >> xlen)
-			r >>= xlen;
-		else
-			shift += xlen;
-	} while ((xlen /= 2) != 0);
-	assert((d >> (64-1-shift)) == 1);
-	d <<= shift;
-
-	BIGLITTLE(q -= len-1,q += len-1);
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	if (r < d) {
-		qhigh = 0;
-	} else {
-		qhigh = r/d;
-		r %= d;
-	}
-
-	xlen = len;
-	while (--xlen)
-		r = lbnDiv21_64(BIGLITTLE(q++,--q), r, BIGLITTLE(*n++,*--n), d);
-
-	/*
-	 * Final correction for shift - shift the quotient up "shift"
-	 * bits, and merge in the extra bits of quotient.  Then reduce
-	 * the final remainder mod the real d.
-	 */
-	if (shift) {
-		d >>= shift;
-		qhigh = (qhigh << shift) | lbnLshift_64(q, len-1, shift);
-		BIGLITTLE(q[-1],*q) |= r/d;
-		r %= d;
-	}
-	*rem = r;
-
-	return qhigh;
-}
-#endif
-
-/*
- * This function performs a "quick" modulus of a number with a divisor
- * d which is guaranteed to be at most sixteen bits, i.e. less than 65536.
- * This applies regardless of the word size the library is compiled with.
- *
- * This function is important to prime generation, for sieving.
- */
-#ifndef lbnModQ_64
-/* If there's a custom lbnMod21_64, no normalization needed */
-#ifdef lbnMod21_64
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
-	unsigned i, shift;
-	BNWORD64 r;
-
-	assert(len > 0);
-
-	BIGLITTLE(n -= len,n += len);
-
-	/* Try using a compare to avoid the first divide */
-	r = BIGLITTLE(*n++,*--n);
-	if (r >= d)
-		r %= d;
-	while (--len)
-		r = lbnMod21_64(r, BIGLITTLE(*n++,*--n), d);
-
-	return r;
-}
-#elif defined(BNWORD128) && !BN_SLOW_DIVIDE_128
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
-	BNWORD64 r;
-
-	if (!--len)
-		return BIGLITTLE(n[-1],n[0]) % d;
-
-	BIGLITTLE(n -= len,n += len);
-	r = BIGLITTLE(n[-1],n[0]);
-
-	do {
-		r = (BNWORD64)((((BNWORD128)r<<64) | BIGLITTLE(*n++,*--n)) % d);
-	} while (--len);
-
-	return r;
-}
-#elif 64 >= 0x20
-/*
- * If the single word size can hold 65535*65536, then this function
- * is avilable.
- */
-#ifndef highhalf
-#define highhalf(x) ( (x) >> 64/2 )
-#define lowhalf(x) ( (x) & ((1 << 64/2)-1) )
-#endif
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
-	BNWORD64 r, x;
-
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	while (--len) {
-		x = BIGLITTLE(*n++,*--n);
-		r = (r%d << 64/2) | highhalf(x);
-		r = (r%d << 64/2) | lowhalf(x);
-	}
-
-	return r%d;
-}
-#else
-/* Default case - use lbnDiv21_64 */
-unsigned
-lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d)
-{
-	unsigned i, shift;
-	BNWORD64 r;
-	BNWORD64 q;
-
-	assert(len > 0);
-
-	shift = 0;
-	r = d;
-	i = 64;
-	while (i /= 2) {
-		if (r >> i)
-			r >>= i;
-		else
-			shift += i;
-	}
-	assert(d >> (64-1-shift) == 1);
-	d <<= shift;
-
-	BIGLITTLE(n -= len,n += len);
-
-	r = BIGLITTLE(*n++,*--n);
-	if (r >= d)
-		r %= d;
-
-	while (--len)
-		r = lbnDiv21_64(&q, r, BIGLITTLE(*n++,*--n), d);
-
-	/*
-	 * Final correction for shift - shift the quotient up "shift"
-	 * bits, and merge in the extra bits of quotient.  Then reduce
-	 * the final remainder mod the real d.
-	 */
-	if (shift)
-		r %= d >> shift;
-
-	return r;
-}
-#endif
-#endif /* lbnModQ_64 */
-
-/*
- * Reduce n mod d and return the quotient.  That is, find:
- * q = n / d;
- * n = n % d;
- * d is altered during the execution of this subroutine by normalizing it.
- * It must already have its most significant word non-zero; it is shifted
- * so its most significant bit is non-zero.
- *
- * The quotient q is nlen-dlen+1 words long.  To make it possible to
- * overlap the quptient with the input (you can store it in the high dlen
- * words), the high word of the quotient is *not* stored, but is returned.
- * (If all you want is the remainder, you don't care about it, anyway.)
- *
- * This uses algorithm D from Knuth (4.3.1), except that we do binary
- * (shift) normalization of the divisor.  WARNING: This is hairy!
- *
- * This function is used for some modular reduction, but it is not used in
- * the modular exponentiation loops; they use Montgomery form and the
- * corresponding, more efficient, Montgomery reduction.  This code
- * is needed for the conversion to Montgomery form, however, so it
- * has to be here and it might as well be reasonably efficient.
- *
- * The overall operation is as follows ("top" and "up" refer to the
- * most significant end of the number; "bottom" and "down", the least):
- *
- * - Shift the divisor up until the most significant bit is set.
- * - Shift the dividend up the same amount.  This will produce the
- *   correct quotient, and the remainder can be recovered by shifting
- *   it back down the same number of bits.  This may produce an overflow
- *   word, but the word is always strictly less than the most significant
- *   divisor word.
- * - Estimate the first quotient digit qhat:
- *   - First take the top two words (one of which is the overflow) of the
- *     dividend and divide by the top word of the divisor:
- *     qhat = (nh,nm)/dh.  This qhat is >= the correct quotient digit
- *     and, since dh is normalized, it is at most two over.
- *   - Second, correct by comparing the top three words.  If
- *     (dh,dl) * qhat > (nh,nm,ml), decrease qhat and try again.
- *     The second iteration can be simpler because there can't be a third.
- *     The computation can be simplified by subtracting dh*qhat from
- *     both sides, suitably shifted.  This reduces the left side to
- *     dl*qhat.  On the right, (nh,nm)-dh*qhat is simply the
- *     remainder r from (nh,nm)%dh, so the right is (r,nl).
- *     This produces qhat that is almost always correct and at
- *     most (prob ~ 2/2^64) one too high.
- * - Subtract qhat times the divisor (suitably shifted) from the dividend.
- *   If there is a borrow, qhat was wrong, so decrement it
- *   and add the divisor back in (once).
- * - Store the final quotient digit qhat in the quotient array q.
- *
- * Repeat the quotient digit computation for successive digits of the
- * quotient until the whole quotient has been computed.  Then shift the
- * divisor and the remainder down to correct for the normalization.
- *
- * TODO: Special case 2-word divisors.
- * TODO: Use reciprocals rather than dividing.
- */
-#ifndef divn_64
-BNWORD64
-lbnDiv_64(BNWORD64 *q, BNWORD64 *n, unsigned nlen, BNWORD64 *d, unsigned dlen)
-{
-	BNWORD64 nh,nm,nl;	/* Top three words of the dividend */
-	BNWORD64 dh,dl;	/* Top two words of the divisor */
-	BNWORD64 qhat;	/* Extimate of quotient word */
-	BNWORD64 r;	/* Remainder from quotient estimate division */
-	BNWORD64 qhigh;	/* High word of quotient */
-	unsigned i;	/* Temp */
-	unsigned shift;	/* Bits shifted by normalization */
-	unsigned qlen = nlen-dlen; /* Size of quotient (less 1) */
-#ifdef mul64_ppmm
-	BNWORD64 t64;
-#elif defined(BNWORD128)
-	BNWORD128 t128;
-#else /* use lbnMulN1_64 */
-	BNWORD64 t2[2];
-#define t2high BIGLITTLE(t2[0],t2[1])
-#define t2low BIGLITTLE(t2[1],t2[0])
-#endif
-
-	assert(dlen);
-	assert(nlen >= dlen);
-
-	/*
-	 * Special cases for short divisors.  The general case uses the
-	 * top top 2 digits of the divisor (d) to estimate a quotient digit,
-	 * so it breaks if there are fewer digits available.  Thus, we need
-	 * special cases for a divisor of length 1.  A divisor of length
-	 * 2 can have a *lot* of administrivia overhead removed removed,
-	 * so it's probably worth special-casing that case, too.
-	 */
-	if (dlen == 1)
-		return lbnDiv1_64(q, BIGLITTLE(n-1,n), n, nlen,
-		                  BIGLITTLE(d[-1],d[0]));
-
-#if 0
-	/*
-	 * @@@ This is not yet written...  The general loop will do,
-	 * albeit less efficiently
-	 */
-	if (dlen == 2) {
-		/*
-		 * divisor two digits long:
-		 * use the 3/2 technique from Knuth, but we know
-		 * it's exact.
-		 */
-		dh = BIGLITTLE(d[-1],d[0]);
-		dl = BIGLITTLE(d[-2],d[1]);
-		shift = 0;
-		if ((sh & ((BNWORD64)1 << 64-1-shift)) == 0) {
-			do {
-				shift++;
-			} while (dh & (BNWORD64)1<<64-1-shift) == 0);
-			dh = dh << shift | dl >> (64-shift);
-			dl <<= shift;
-
-
-		}
-
-
-		for (shift = 0; (dh & (BNWORD64)1 << 64-1-shift)) == 0; shift++)
-			;
-		if (shift) {
-		}
-		dh = dh << shift | dl >> (64-shift);
-		shift = 0;
-		while (dh
-	}
-#endif
-
-	dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
-	assert(dh);
-
-	/* Normalize the divisor */
-	shift = 0;
-	r = dh;
-	i = 64/2;
-	do {
-		if (r >> i)
-			r >>= i;
-		else
-			shift += i;
-	} while ((i /= 2) != 0);
-
-	nh = 0;
-	if (shift) {
-		lbnLshift_64(d, dlen, shift);
-		dh = BIGLITTLE(*(d-dlen),*(d+(dlen-1)));
-		nh = lbnLshift_64(n, nlen, shift);
-	}
-
-	/* Assert that dh is now normalized */
-	assert(dh >> (64-1));
-
-	/* Also get the second-most significant word of the divisor */
-	dl = BIGLITTLE(*(d-(dlen-1)),*(d+(dlen-2)));
-
-	/*
-	 * Adjust pointers: n to point to least significant end of first
-	 * first subtract, and q to one the most-significant end of the
-	 * quotient array.
-	 */
-	BIGLITTLE(n -= qlen,n += qlen);
-	BIGLITTLE(q -= qlen,q += qlen);
-
-	/* Fetch the most significant stored word of the dividend */
-	nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
-	/*
-	 * Compute the first digit of the quotient, based on the
-	 * first two words of the dividend (the most significant of which
-	 * is the overflow word h).
-	 */
-	if (nh) {
-		assert(nh < dh);
-		r = lbnDiv21_64(&qhat, nh, nm, dh);
-	} else if (nm >= dh) {
-		qhat = nm/dh;
-		r = nm % dh;
-	} else {	/* Quotient is zero */
-		qhigh = 0;
-		goto divloop;
-	}
-
-	/* Now get the third most significant word of the dividend */
-	nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-
-	/*
-	 * Correct qhat, the estimate of quotient digit.
-	 * qhat can only be high, and at most two words high,
-	 * so the loop can be unrolled and abbreviated.
-	 */
-#ifdef mul64_ppmm
-	mul64_ppmm(nm, t64, qhat, dl);
-	if (nm > r || (nm == r && t64 > nl)) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) >= dh) {
-			nm -= (t64 < dl);
-			t64 -= dl;
-			if (nm > r || (nm == r && t64 > nl))
-				qhat--;
-		}
-	}
-#elif defined(BNWORD128)
-	t128 = (BNWORD128)qhat * dl;
-	if (t128 > ((BNWORD128)r << 64) + nl) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) > dh) {
-			t128 -= dl;
-			if (t128 > ((BNWORD128)r << 64) + nl)
-				qhat--;
-		}
-	}
-#else /* Use lbnMulN1_64 */
-	lbnMulN1_64(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
-	if (t2high > r || (t2high == r && t2low > nl)) {
-		/* Decrement qhat and adjust comparison parameters */
-		qhat--;
-		if ((r += dh) >= dh) {
-			t2high -= (t2low < dl);
-			t2low -= dl;
-			if (t2high > r || (t2high == r && t2low > nl))
-				qhat--;
-		}
-	}
-#endif
-
-	/* Do the multiply and subtract */
-	r = lbnMulSub1_64(n, d, dlen, qhat);
-	/* If there was a borrow, add back once. */
-	if (r > nh) {	/* Borrow? */
-		(void)lbnAddN_64(n, d, dlen);
-		qhat--;
-	}
-
-	/* Remember the first quotient digit. */
-	qhigh = qhat;
-
-	/* Now, the main division loop: */
-divloop:
-	while (qlen--) {
-
-		/* Advance n */
-		nh = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-		BIGLITTLE(++n,--n);
-		nm = BIGLITTLE(*(n-dlen),*(n+(dlen-1)));
-
-		if (nh == dh) {
-			qhat = ~(BNWORD64)0;
-			/* Optimized computation of r = (nh,nm) - qhat * dh */
-			r = nh + nm;
-			if (r < nh)
-				goto subtract;
-		} else {
-			assert(nh < dh);
-			r = lbnDiv21_64(&qhat, nh, nm, dh);
-		}
-
-		nl = BIGLITTLE(*(n-(dlen-1)),*(n+(dlen-2)));
-#ifdef mul64_ppmm
-		mul64_ppmm(nm, t64, qhat, dl);
-		if (nm > r || (nm == r && t64 > nl)) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				nm -= (t64 < dl);
-				t64 -= dl;
-				if (nm > r || (nm == r && t64 > nl))
-					qhat--;
-			}
-		}
-#elif defined(BNWORD128)
-		t128 = (BNWORD128)qhat * dl;
-		if (t128 > ((BNWORD128)r<<64) + nl) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				t128 -= dl;
-				if (t128 > ((BNWORD128)r << 64) + nl)
-					qhat--;
-			}
-		}
-#else /* Use lbnMulN1_64 */
-		lbnMulN1_64(BIGLITTLE(t2+2,t2), &dl, 1, qhat);
-		if (t2high > r || (t2high == r && t2low > nl)) {
-			/* Decrement qhat and adjust comparison parameters */
-			qhat--;
-			if ((r += dh) >= dh) {
-				t2high -= (t2low < dl);
-				t2low -= dl;
-				if (t2high > r || (t2high == r && t2low > nl))
-					qhat--;
-			}
-		}
-#endif
-
-		/*
-		 * As a point of interest, note that it is not worth checking
-		 * for qhat of 0 or 1 and installing special-case code.  These
-		 * occur with probability 2^-64, so spending 1 cycle to check
-		 * for them is only worth it if we save more than 2^15 cycles,
-		 * and a multiply-and-subtract for numbers in the 1024-bit
-		 * range just doesn't take that long.
-		 */
-subtract:
-		/*
-		 * n points to the least significant end of the substring
-		 * of n to be subtracted from.  qhat is either exact or
-		 * one too large.  If the subtract gets a borrow, it was
-		 * one too large and the divisor is added back in.  It's
-		 * a dlen+1 word add which is guaranteed to produce a
-		 * carry out, so it can be done very simply.
-		 */
-		r = lbnMulSub1_64(n, d, dlen, qhat);
-		if (r > nh) {	/* Borrow? */
-			(void)lbnAddN_64(n, d, dlen);
-			qhat--;
-		}
-		/* Store the quotient digit */
-		BIGLITTLE(*q++,*--q) = qhat;
-	}
-	/* Tah dah! */
-
-	if (shift) {
-		lbnRshift_64(d, dlen, shift);
-		lbnRshift_64(n, dlen, shift);
-	}
-
-	return qhigh;
-}
-#endif
-
-/*
- * Find the negative multiplicative inverse of x (x must be odd!) modulo 2^64.
- *
- * This just performs Newton's iteration until it gets the
- * inverse.  The initial estimate is always correct to 3 bits, and
- * sometimes 4.  The number of valid bits doubles each iteration.
- * (To prove it, assume x * y == 1 (mod 2^n), and introduce a variable
- * for the error mod 2^2n.  x * y == 1 + k*2^n (mod 2^2n) and follow
- * the iteration through.)
- */
-#ifndef lbnMontInv1_64
-BNWORD64
-lbnMontInv1_64(BNWORD64 const x)
-{
-        BNWORD64 y = x, z;
-
-	assert(x & 1);
- 
-        while ((z = x*y) != 1)
-                y *= 2 - z;
-        return -y;
-}
-#endif /* !lbnMontInv1_64 */
-
-#if defined(BNWORD128) && PRODUCT_SCAN
-/*
- * Test code for product-scanning Montgomery reduction.
- * This seems to slow the C code down rather than speed it up.
- *
- * The first loop computes the Montgomery multipliers, storing them over
- * the low half of the number n.
- *
- * The second half multiplies the upper half, adding in the modulus
- * times the Montgomery multipliers.  The results of this multiply
- * are stored.
- */
-void
-lbnMontReduce_64(BNWORD64 *n, BNWORD64 const *mod, unsigned mlen, BNWORD64 inv)
-{
-	BNWORD128 x, y;
-	BNWORD64 const *pm;
-	BNWORD64 *pn;
-	BNWORD64 t;
-	unsigned carry;
-	unsigned i, j;
-
-	/* Special case of zero */
-	if (!mlen)
-		return;
-
-	/* Pass 1 - compute Montgomery multipliers */
-	/* First iteration can have certain simplifications. */
-	t = BIGLITTLE(n[-1],n[0]);
-	x = t;
-	t *= inv;
-	BIGLITTLE(n[-1], n[0]) = t;
-	x += (BNWORD128)t * BIGLITTLE(mod[-1],mod[0]); /* Can't overflow */
-	assert((BNWORD64)x == 0);
-	x = x >> 64;
-
-	for (i = 1; i < mlen; i++) {
-		carry = 0;
-		pn = n;
-		pm = BIGLITTLE(mod-i-1,mod+i+1);
-		for (j = 0; j < i; j++) {
-			y = (BNWORD128)BIGLITTLE(*--pn * *pm++, *pn++ * *--pm);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pn == n-i, pn == n+i));
-		y = t = BIGLITTLE(pn[-1], pn[0]);
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(pn[-1], pn[0]) = t = inv * (BNWORD64)x;
-		assert(BIGLITTLE(pm == mod-1, pm == mod+1));
-		y = (BNWORD128)t * BIGLITTLE(pm[0],pm[-1]);
-		x += y;
-		carry += (x < y);
-		assert((BNWORD64)x == 0);
-		x = x >> 64 | (BNWORD128)carry << 64;
-	}
-
-	BIGLITTLE(n -= mlen, n += mlen);
-
-	/* Pass 2 - compute upper words and add to n */
-	for (i = 1; i < mlen; i++) {
-		carry = 0;
-		pm = BIGLITTLE(mod-i,mod+i);
-		pn = n;
-		for (j = i; j < mlen; j++) {
-			y = (BNWORD128)BIGLITTLE(*--pm * *pn++, *pm++ * *--pn);
-			x += y;
-			carry += (x < y);
-		}
-		assert(BIGLITTLE(pm == mod-mlen, pm == mod+mlen));
-		assert(BIGLITTLE(pn == n+mlen-i, pn == n-mlen+i));
-		y = t = BIGLITTLE(*(n-i),*(n+i-1));
-		x += y;
-		carry += (x < y);
-		BIGLITTLE(*(n-i),*(n+i-1)) = (BNWORD64)x;
-		x = (x >> 64) | (BNWORD128)carry << 64;
-	}
-
-	/* Last round of second half, simplified. */
-	t = BIGLITTLE(*(n-mlen),*(n+mlen-1));
-	x += t;
-	BIGLITTLE(*(n-mlen),*(n+mlen-1)) = (BNWORD64)x;
-	carry = (unsigned)(x >> 64);
-
-	while (carry)
-		carry -= lbnSubN_64(n, mod, mlen);
-	while (lbnCmp_64(n, mod, mlen) >= 0)
-		(void)lbnSubN_64(n, mod, mlen);
-}
-#define lbnMontReduce_64 lbnMontReduce_64
-#endif
-
-/*
- * Montgomery reduce n, modulo mod.  This reduces modulo mod and divides by
- * 2^(64*mlen).  Returns the result in the *top* mlen words of the argument n.
- * This is ready for another multiplication using lbnMul_64.
- *
- * Montgomery representation is a very useful way to encode numbers when
- * you're doing lots of modular reduction.  What you do is pick a multiplier
- * R which is relatively prime to the modulus and very easy to divide by.
- * Since the modulus is odd, R is closen as a power of 2, so the division
- * is a shift.  In fact, it's a shift of an integral number of words,
- * so the shift can be implicit - just drop the low-order words.
- *
- * Now, choose R *larger* than the modulus m, 2^(64*mlen).  Then convert
- * all numbers a, b, etc. to Montgomery form M(a), M(b), etc using the
- * relationship M(a) = a*R mod m, M(b) = b*R mod m, etc.  Note that:
- * - The Montgomery form of a number depends on the modulus m.
- *   A fixed modulus m is assumed throughout this discussion.
- * - Since R is relaitvely prime to m, multiplication by R is invertible;
- *   no information about the numbers is lost, they're just scrambled.
- * - Adding (and subtracting) numbers in this form works just as usual.
- *   M(a+b) = (a+b)*R mod m = (a*R + b*R) mod m = (M(a) + M(b)) mod m
- * - Multiplying numbers in this form produces a*b*R*R.  The problem
- *   is to divide out the excess factor of R, modulo m as well as to
- *   reduce to the given length mlen.  It turns out that this can be
- *   done *faster* than a normal divide, which is where the speedup
- *   in Montgomery division comes from.
- *
- * Normal reduction chooses a most-significant quotient digit q and then
- * subtracts q*m from the number to be reduced.  Choosing q is tricky
- * and involved (just look at lbnDiv_64 to see!) and is usually
- * imperfect, requiring a check for correction after the subtraction.
- *
- * Montgomery reduction *adds* a multiple of m to the *low-order* part
- * of the number to be reduced.  This multiple is chosen to make the
- * low-order part of the number come out to zero.  This can be done
- * with no trickery or error using a precomputed inverse of the modulus.
- * In this code, the "part" is one word, but any width can be used.
- *
- * Repeating this step sufficiently often results in a value which
- * is a multiple of R (a power of two, remember) but is still (since
- * the additions were to the low-order part and thus did not increase
- * the value of the number being reduced very much) still not much
- * larger than m*R.  Then implicitly divide by R and subtract off
- * m until the result is in the correct range.
- *
- * Since the low-order part being cancelled is less than R, the
- * multiple of m added must have a multiplier which is at most R-1.
- * Assuming that the input is at most m*R-1, the final number is
- * at most m*(2*R-1)-1 = 2*m*R - m - 1, so subtracting m once from
- * the high-order part, equivalent to subtracting m*R from the
- * while number, produces a result which is at most m*R - m - 1,
- * which divided by R is at most m-1.
- *
- * To convert *to* Montgomery form, you need a regular remainder
- * routine, although you can just compute R*R (mod m) and do the
- * conversion using Montgomery multiplication.  To convert *from*
- * Montgomery form, just Montgomery reduce the number to
- * remove the extra factor of R.
- * 
- * TODO: Change to a full inverse and use Karatsuba's multiplication
- * rather than this word-at-a-time.
- */
-#ifndef lbnMontReduce_64
-void
-lbnMontReduce_64(BNWORD64 *n, BNWORD64 const *mod, unsigned const mlen,
-                BNWORD64 inv)
-{
-	BNWORD64 t;
-	BNWORD64 c = 0;
-	unsigned len = mlen;
-
-	/* inv must be the negative inverse of mod's least significant word */
-	assert((BNWORD64)(inv * BIGLITTLE(mod[-1],mod[0])) == (BNWORD64)-1);
-
-	assert(len);
-
-	do {
-		t = lbnMulAdd1_64(n, mod, mlen, inv * BIGLITTLE(n[-1],n[0]));
-		c += lbnAdd1_64(BIGLITTLE(n-mlen,n+mlen), len, t);
-		BIGLITTLE(--n,++n);
-	} while (--len);
-
-	/*
-	 * All that adding can cause an overflow past the modulus size,
-	 * but it's unusual, and never by much, so a subtraction loop
-	 * is the right way to deal with it.
-	 * This subtraction happens infrequently - I've only ever seen it
-	 * invoked once per reduction, and then just under 22.5% of the time.
-	 */
-	while (c)
-		c -= lbnSubN_64(n, mod, mlen);
-	while (lbnCmp_64(n, mod, mlen) >= 0)
-		(void)lbnSubN_64(n, mod, mlen);
-}
-#endif /* !lbnMontReduce_64 */
-
-/*
- * A couple of helpers that you might want to implement atomically
- * in asm sometime.
- */
-#ifndef lbnMontMul_64
-/*
- * Multiply "num1" by "num2", modulo "mod", all of length "len", and
- * place the result in the high half of "prod".  "inv" is the inverse
- * of the least-significant word of the modulus, modulo 2^64.
- * This uses numbers in Montgomery form.  Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontMul_64(prod, n1, n2, mod, len, inv) \
-	(lbnMulX_64(prod, n1, n2, len), lbnMontReduce_64(prod, mod, len, inv))
-#endif /* !lbnMontMul_64 */
-
-#ifndef lbnMontSquare_64
-/*
- * Square "n", modulo "mod", both of length "len", and place the result
- * in the high half of "prod".  "inv" is the inverse of the least-significant
- * word of the modulus, modulo 2^64.
- * This uses numbers in Montgomery form.  Reduce using "len" and "inv".
- *
- * This is implemented as a macro to win on compilers that don't do
- * inlining, since it's so trivial.
- */
-#define lbnMontSquare_64(prod, n, mod, len, inv) \
-	(lbnSquare_64(prod, n, len), lbnMontReduce_64(prod, mod, len, inv))
-	
-#endif /* !lbnMontSquare_64 */
-
-/*
- * Convert a number to Montgomery form - requires mlen + nlen words
- * of memory in "n".
- */
-void
-lbnToMont_64(BNWORD64 *n, unsigned nlen, BNWORD64 *mod, unsigned mlen)
-{
-	/* Move n up "mlen" words */
-	lbnCopy_64(BIGLITTLE(n-mlen,n+mlen), n, nlen);
-	lbnZero_64(n, mlen);
-	/* Do the division - dump the quotient in the high-order words */
-	(void)lbnDiv_64(BIGLITTLE(n-mlen,n+mlen), n, mlen+nlen, mod, mlen);
-}
-
-/*
- * Convert from Montgomery form.  Montgomery reduction is all that is
- * needed.
- */
-void
-lbnFromMont_64(BNWORD64 *n, BNWORD64 *mod, unsigned len)
-{
-	/* Zero the high words of n */
-	lbnZero_64(BIGLITTLE(n-len,n+len), len);
-	lbnMontReduce_64(n, mod, len, lbnMontInv1_64(mod[BIGLITTLE(-1,0)]));
-	/* Move n down len words */
-	lbnCopy_64(n, BIGLITTLE(n-len,n+len), len);
-}
-
-/*
- * The windowed exponentiation algorithm, precomputes a table of odd
- * powers of n up to 2^k.  See the comment in bnExpMod_64 below for
- * an explanation of how it actually works works.
- *
- * It takes 2^(k-1)-1 multiplies to compute the table, and (e-1)/(k+1)
- * multiplies (on average) to perform the exponentiation.  To minimize
- * the sum, k must vary with e.  The optimal window sizes vary with the
- * exponent length.  Here are some selected values and the boundary cases.
- * (An underscore _ has been inserted into some of the numbers to ensure
- * that magic strings like 64 do not appear in this table.  It should be
- * ignored.)
- *
- * At e =    1 bits, k=1   (0.000000) is best
- * At e =    2 bits, k=1   (0.500000) is best
- * At e =    4 bits, k=1   (1.500000) is best
- * At e =    8 bits, k=2   (3.333333) < k=1   (3.500000)
- * At e =  1_6 bits, k=2   (6.000000) is best
- * At e =   26 bits, k=3   (9.250000) < k=2   (9.333333)
- * At e =  3_2 bits, k=3  (10.750000) is best
- * At e =  6_4 bits, k=3  (18.750000) is best
- * At e =   82 bits, k=4  (23.200000) < k=3  (23.250000)
- * At e =  128 bits, k=4 (3_2.400000) is best
- * At e =  242 bits, k=5  (55.1_66667) < k=4 (55.200000)
- * At e =  256 bits, k=5  (57.500000) is best
- * At e =  512 bits, k=5 (100.1_66667) is best
- * At e =  674 bits, k=6 (127.142857) < k=5 (127.1_66667)
- * At e = 1024 bits, k=6 (177.142857) is best
- * At e = 1794 bits, k=7 (287.125000) < k=6 (287.142857)
- * At e = 2048 bits, k=7 (318.875000) is best
- * At e = 4096 bits, k=7 (574.875000) is best
- *
- * The numbers in parentheses are the expected number of multiplications
- * needed to do the computation.  The normal russian-peasant modular
- * exponentiation technique always uses (e-1)/2.  For exponents as
- * small as 192 bits (below the range of current factoring algorithms),
- * half of the multiplies are eliminated, 45.2 as opposed to the naive
- * 95.5.  Counting the 191 squarings as 3/4 a multiply each (squaring
- * proper is just over half of multiplying, but the Montgomery
- * reduction in each case is also a multiply), that's 143.25
- * multiplies, for totals of 188.45 vs. 238.75 - a 21% savings.
- * For larger exponents (like 512 bits), it's 483.92 vs. 639.25, a
- * 24.3% savings.  It asymptotically approaches 25%.
- *
- * Um, actually there's a slightly more accurate way to count, which
- * really is the average number of multiplies required, averaged
- * uniformly over all 2^(e-1) e-bit numbers, from 2^(e-1) to (2^e)-1.
- * It's based on the recurrence that for the last b bits, b <= k, at
- * most one multiply is needed (and none at all 1/2^b of the time),
- * while when b > k, the odds are 1/2 each way that the bit will be
- * 0 (meaning no multiplies to reduce it to the b-1-bit case) and
- * 1/2 that the bit will be 1, starting a k-bit window and requiring
- * 1 multiply beyond the b-k-bit case.  Since the most significant
- * bit is always 1, a k-bit window always starts there, and that
- * multiply is by 1, so it isn't a multiply at all.  Thus, the
- * number of multiplies is simply that needed for the last e-k bits.
- * This recurrence produces:
- *
- * At e =    1 bits, k=1   (0.000000) is best
- * At e =    2 bits, k=1   (0.500000) is best
- * At e =    4 bits, k=1   (1.500000) is best
- * At e =    6 bits, k=2   (2.437500) < k=1   (2.500000)
- * At e =    8 bits, k=2   (3.109375) is best
- * At e =  1_6 bits, k=2   (5.777771) is best
- * At e =   24 bits, k=3   (8.437629) < k=2   (8.444444)
- * At e =  3_2 bits, k=3  (10.437492) is best
- * At e =  6_4 bits, k=3  (18.437500) is best
- * At e =   81 bits, k=4  (22.6_40000) < k=3  (22.687500)
- * At e =  128 bits, k=4 (3_2.040000) is best
- * At e =  241 bits, k=5  (54.611111) < k=4  (54.6_40000)
- * At e =  256 bits, k=5  (57.111111) is best
- * At e =  512 bits, k=5  (99.777778) is best
- * At e =  673 bits, k=6 (126.591837) < k=5 (126.611111)
- * At e = 1024 bits, k=6 (176.734694) is best
- * At e = 1793 bits, k=7 (286.578125) < k=6 (286.591837)
- * At e = 2048 bits, k=7 (318.453125) is best
- * At e = 4096 bits, k=7 (574.453125) is best
- *
- * This has the rollover points at 6, 24, 81, 241, 673 and 1793 instead
- * of 8, 26, 82, 242, 674, and 1794.  Not a very big difference.
- * (The numbers past that are k=8 at 4609 and k=9 at 11521,
- * vs. one more in each case for the approximation.)
- *
- * Given that exponents for which k>7 are useful are uncommon,
- * a fixed size table for k <= 7 is used for simplicity.
- *
- * The basic number of squarings needed is e-1, although a k-bit
- * window (for k > 1) can save, on average, k-2 of those, too.
- * That savings currently isn't counted here.  It would drive the
- * crossover points slightly lower.
- * (Actually, this win is also reduced in the DoubleExpMod case,
- * meaning we'd have to split the tables.  Except for that, the
- * multiplies by powers of the two bases are independent, so
- * the same logic applies to each as the single case.)
- *
- * Table entry i is the largest number of bits in an exponent to
- * process with a window size of i+1.  Entry 6 is the largest
- * possible unsigned number, so the window will never be more
- * than 7 bits, requiring 2^6 = 0x40 slots.
- */
-#define BNEXPMOD_MAX_WINDOW	7
-static unsigned const bnExpModThreshTable[BNEXPMOD_MAX_WINDOW] = {
-	5, 23, 80, 240, 672, 1792, (unsigned)-1
-/*	7, 25, 81, 241, 673, 1793, (unsigned)-1	 ### The old approximations */
-};
-
-/*
- * Perform modular exponentiation, as fast as possible!  This uses
- * Montgomery reduction, optimized squaring, and windowed exponentiation.
- * The modulus "mod" MUST be odd!
- *
- * This returns 0 on success, -1 on out of memory.
- *
- * The window algorithm:
- * The idea is to keep a running product of b1 = n^(high-order bits of exp),
- * and then keep appending exponent bits to it.  The following patterns
- * apply to a 3-bit window (k = 3):
- * To append   0: square
- * To append   1: square, multiply by n^1
- * To append  10: square, multiply by n^1, square
- * To append  11: square, square, multiply by n^3
- * To append 100: square, multiply by n^1, square, square
- * To append 101: square, square, square, multiply by n^5
- * To append 110: square, square, multiply by n^3, square
- * To append 111: square, square, square, multiply by n^7
- *
- * Since each pattern involves only one multiply, the longer the pattern
- * the better, except that a 0 (no multiplies) can be appended directly.
- * We precompute a table of odd powers of n, up to 2^k, and can then
- * multiply k bits of exponent at a time.  Actually, assuming random
- * exponents, there is on average one zero bit between needs to
- * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
- * 1/8 of the time, there's 2, 1/64 of the time, there's 3, etc.), so
- * you have to do one multiply per k+1 bits of exponent.
- *
- * The loop walks down the exponent, squaring the result buffer as
- * it goes.  There is a wbits+1 bit lookahead buffer, buf, that is
- * filled with the upcoming exponent bits.  (What is read after the
- * end of the exponent is unimportant, but it is filled with zero here.)
- * When the most-significant bit of this buffer becomes set, i.e.
- * (buf & tblmask) != 0, we have to decide what pattern to multiply
- * by, and when to do it.  We decide, remember to do it in future
- * after a suitable number of squarings have passed (e.g. a pattern
- * of "100" in the buffer requires that we multiply by n^1 immediately;
- * a pattern of "110" calls for multiplying by n^3 after one more
- * squaring), clear the buffer, and continue.
- *
- * When we start, there is one more optimization: the result buffer
- * is implcitly one, so squaring it or multiplying by it can be
- * optimized away.  Further, if we start with a pattern like "100"
- * in the lookahead window, rather than placing n into the buffer
- * and then starting to square it, we have already computed n^2
- * to compute the odd-powers table, so we can place that into
- * the buffer and save a squaring.
- *
- * This means that if you have a k-bit window, to compute n^z,
- * where z is the high k bits of the exponent, 1/2 of the time
- * it requires no squarings.  1/4 of the time, it requires 1
- * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
- * And the remaining 1/2^(k-1) of the time, the top k bits are a
- * 1 followed by k-1 0 bits, so it again only requires k-2
- * squarings, not k-1.  The average of these is 1.  Add that
- * to the one squaring we have to do to compute the table,
- * and you'll see that a k-bit window saves k-2 squarings
- * as well as reducing the multiplies.  (It actually doesn't
- * hurt in the case k = 1, either.)
- *
- * n must have mlen words allocated.  Although fewer may be in use
- * when n is passed in, all are in use on exit.
- */
-int
-lbnExpMod_64(BNWORD64 *result, BNWORD64 const *n, unsigned nlen,
-	BNWORD64 const *e, unsigned elen, BNWORD64 *mod, unsigned mlen)
-{
-	BNWORD64 *table[1 << (BNEXPMOD_MAX_WINDOW-1)];
-				/* Table of odd powers of n */
-	unsigned ebits;		/* Exponent bits */
-	unsigned wbits;		/* Window size */
-	unsigned tblmask;	/* Mask of exponentiation window */
-	BNWORD64 bitpos;	/* Mask of current look-ahead bit */
-	unsigned buf;		/* Buffer of exponent bits */
-	unsigned multpos;	/* Where to do pending multiply */
-	BNWORD64 const *mult;	/* What to multiply by */
-	unsigned i;		/* Loop counter */
-	int isone;		/* Flag: accum. is implicitly one */
-	BNWORD64 *a, *b;	/* Working buffers/accumulators */
-	BNWORD64 *t;		/* Pointer into the working buffers */
-	BNWORD64 inv;		/* mod^-1 modulo 2^64 */
-	int y;			/* bnYield() result */
-
-	assert(mlen);
-	assert(nlen <= mlen);
-
-	/* First, a couple of trivial cases. */
-	elen = lbnNorm_64(e, elen);
-	if (!elen) {
-		/* x ^ 0 == 1 */
-		lbnZero_64(result, mlen);
-		BIGLITTLE(result[-1],result[0]) = 1;
-		return 0;
-	}
-	ebits = lbnBits_64(e, elen);
-	if (ebits == 1) {
-		/* x ^ 1 == x */
-		if (n != result)
-			lbnCopy_64(result, n, nlen);
-		if (mlen > nlen)
-			lbnZero_64(BIGLITTLE(result-nlen,result+nlen),
-			           mlen-nlen);
-		return 0;
-	}
-
-	/* Okay, now move the exponent pointer to the most-significant word */
-	e = BIGLITTLE(e-elen, e+elen-1);
-
-	/* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
-	wbits = 0;
-	while (ebits > bnExpModThreshTable[wbits])
-		wbits++;
-
-	/* Allocate working storage: two product buffers and the tables. */
-	LBNALLOC(a, BNWORD64, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD64, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert to the appropriate table size: tblmask = 1<<(k-1) */
-	tblmask = 1u << wbits;
-
-	/* We have the result buffer available, so use it. */
-	table[0] = result;
-
-	/*
-	 * Okay, we now have a minimal-sized table - expand it.
-	 * This is allowed to fail!  If so, scale back the table size
-	 * and proceed.
-	 */
-	for (i = 1; i < tblmask; i++) {
-		LBNALLOC(t, BNWORD64, mlen);
-		if (!t)	/* Out of memory!  Quit the loop. */
-			break;
-		table[i] = t;
-	}
-
-	/* If we stopped, with i < tblmask, shrink the tables appropriately */
-	while (tblmask > i) {
-		wbits--;
-		tblmask >>= 1;
-	}
-	/* Free up our overallocations */
-	while (--i > tblmask)
-		LBNFREE(table[i], mlen);
-
-	/* Okay, fill in the table */
-
-	/* Compute the necessary modular inverse */
-	inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	/* Convert n to Montgomery form */
-
-	/* Move n up "mlen" words into a */
-	t = BIGLITTLE(a-mlen, a+mlen);
-	lbnCopy_64(t, n, nlen);
-	lbnZero_64(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_64(t, a, mlen+nlen, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_64(table[0], a, mlen);
-
-	/* Square a into b */
-	lbnMontSquare_64(b, a, mod, mlen, inv);
-
-	/* Use high half of b to initialize the table */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	for (i = 1; i < tblmask; i++) {
-		lbnMontMul_64(a, t, table[i-1], mod, mlen, inv);
-		lbnCopy_64(table[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* We might use b = n^2 later... */
-
-	/* Initialze the fetch pointer */
-	bitpos = (BNWORD64)1 << ((ebits-1) & (64-1));	/* Initialize mask */
-
-	/* This should point to the msbit of e */
-	assert((*e & bitpos) != 0);
-
-	/*
-	 * Pre-load the window.  Becuase the window size is
-	 * never larger than the exponent size, there is no need to
-	 * detect running off the end of e in here.
-	 *
-	 * The read-ahead is controlled by elen and the bitpos mask.
-	 * Note that this is *ahead* of ebits, which tracks the
-	 * most significant end of the window.  The purpose of this
-	 * initialization is to get the two wbits+1 bits apart,
-	 * like they should be.
-	 *
-	 * Note that bitpos and e1len together keep track of the
-	 * lookahead read pointer in the exponent that is used here.
-	 */
-	buf = 0;
-	for (i = 0; i <= wbits; i++) {
-		buf = (buf << 1) | ((*e & bitpos) != 0);
-		bitpos >>= 1;
-		if (!bitpos) {
-			BIGLITTLE(e++,e--);
-			bitpos = (BNWORD64)1 << (64-1);
-			elen--;
-		}
-	}
-	assert(buf & tblmask);
-
-	/*
-	 * Set the pending multiply positions to a location that will
-	 * never be encountered, thus ensuring that nothing will happen
-	 * until the need for a multiply appears and one is scheduled.
-	 */
-	multpos = ebits;	/* A NULL value */
-	mult = 0;	/* Force a crash if we use these */
-
-	/*
-	 * Okay, now begins the real work.  The first step is
-	 * slightly magic, so it's done outside the main loop,
-	 * but it's very similar to what's inside.
-	 */
-	ebits--;	/* Start processing the first bit... */
-	isone = 1;
-
-	/*
-	 * This is just like the multiply in the loop, except that
-	 * - We know the msbit of buf is set, and
-	 * - We have the extra value n^2 floating around.
-	 * So, do the usual computation, and if the result is that
-	 * the buffer should be multiplied by n^1 immediately
-	 * (which we'd normally then square), we multiply it
-	 * (which reduces to a copy, which reduces to setting a flag)
-	 * by n^2 and skip the squaring.  Thus, we do the
-	 * multiply and the squaring in one step.
-	 */
-	assert(buf & tblmask);
-	multpos = ebits - wbits;
-	while ((buf & 1) == 0) {
-		buf >>= 1;
-		multpos++;
-	}
-	/* Intermediates can wrap, but final must NOT */
-	assert(multpos <= ebits);
-	mult = table[buf>>1];
-	buf = 0;
-
-	/* Special case: use already-computed value sitting in buffer */
-	if (multpos == ebits)
-		isone = 0;
-
-	/*
-	 * At this point, the buffer (which is the high half of b) holds
-	 * either 1 (implicitly, as the "isone" flag is set), or n^2.
-	 */
-
-	/*
-	 * The main loop.  The procedure is:
-	 * - Advance the window
-	 * - If the most-significant bit of the window is set,
-	 *   schedule a multiply for the appropriate time in the
-	 *   future (may be immediately)
-	 * - Perform any pending multiples
-	 * - Check for termination
-	 * - Square the buffer
-	 *
-	 * At any given time, the acumulated product is held in
-	 * the high half of b.
-	 */
-	for (;;) {
-		ebits--;
-
-		/* Advance the window */
-		assert(buf < tblmask);
-		buf <<= 1;
-		/*
-		 * This reads ahead of the current exponent position
-		 * (controlled by ebits), so we have to be able to read
-		 * past the lsb of the exponents without error.
-		 */
-		if (elen) {
-			buf |= ((*e & bitpos) != 0);
-			bitpos >>= 1;
-			if (!bitpos) {
-				BIGLITTLE(e++,e--);
-				bitpos = (BNWORD64)1 << (64-1);
-				elen--;
-			}
-		}
-
-		/* Examine the window for pending multiplies */
-		if (buf & tblmask) {
-			multpos = ebits - wbits;
-			while ((buf & 1) == 0) {
-				buf >>= 1;
-				multpos++;
-			}
-			/* Intermediates can wrap, but final must NOT */
-			assert(multpos <= ebits);
-			mult = table[buf>>1];
-			buf = 0;
-		}
-
-		/* If we have a pending multiply, do it */
-		if (ebits == multpos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_64(t, mult, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_64(a, t, mult, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* Are we done? */
-		if (!ebits)
-			break;
-
-		/* Square the input */
-		if (!isone) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			lbnMontSquare_64(a, t, mod, mlen, inv);
-			/* Swap a and b */
-			t = a; a = b; b = t;
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	} /* for (;;) */
-
-	assert(!isone);
-	assert(!buf);
-
-	/* DONE! */
-
-	/* Convert result out of Montgomery form */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	lbnCopy_64(b, t, mlen);
-	lbnZero_64(t, mlen);
-	lbnMontReduce_64(b, mod, mlen, inv);
-	lbnCopy_64(result, t, mlen);
-	/*
-	 * Clean up - free intermediate storage.
-	 * Do NOT free table[0], which is the result
-	 * buffer.
-	 */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	while (--tblmask)
-		LBNFREE(table[tblmask], mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-/*
- * Compute and return n1^e1 * n2^e2 mod "mod".
- * result may be either input buffer, or something separate.
- * It must be "mlen" words long.
- *
- * There is a current position in the exponents, which is kept in e1bits.
- * (The exponents are swapped if necessary so e1 is the longer of the two.)
- * At any given time, the value in the accumulator is
- * n1^(e1>>e1bits) * n2^(e2>>e1bits) mod "mod".
- * As e1bits is counted down, this is updated, by squaring it and doing
- * any necessary multiplies.
- * To decide on the necessary multiplies, two windows, each w1bits+1 bits
- * wide, are maintained in buf1 and buf2, which read *ahead* of the
- * e1bits position (with appropriate handling of the case when e1bits
- * drops below w1bits+1).  When the most-significant bit of either window
- * becomes set, indicating that something needs to be multiplied by
- * the accumulator or it will get out of sync, the window is examined
- * to see which power of n1 or n2 to multiply by, and when (possibly
- * later, if the power is greater than 1) the multiply should take
- * place.  Then the multiply and its location are remembered and the
- * window is cleared.
- *
- * If we had every power of n1 in the table, the multiply would always
- * be w1bits steps in the future.  But we only keep the odd powers,
- * so instead of waiting w1bits squarings and then multiplying
- * by n1^k, we wait w1bits-k squarings and multiply by n1.
- *
- * Actually, w2bits can be less than w1bits, but the window is the same
- * size, to make it easier to keep track of where we're reading.  The
- * appropriate number of low-order bits of the window are just ignored.
- */
-int
-lbnDoubleExpMod_64(BNWORD64 *result,
-                   BNWORD64 const *n1, unsigned n1len,
-                   BNWORD64 const *e1, unsigned e1len,
-                   BNWORD64 const *n2, unsigned n2len,
-                   BNWORD64 const *e2, unsigned e2len,
-                   BNWORD64 *mod, unsigned mlen)
-{
-	BNWORD64 *table1[1 << (BNEXPMOD_MAX_WINDOW-1)];
-					/* Table of odd powers of n1 */
-	BNWORD64 *table2[1 << (BNEXPMOD_MAX_WINDOW-1)];
-					/* Table of odd powers of n2 */
-	unsigned e1bits, e2bits;	/* Exponent bits */
-	unsigned w1bits, w2bits;	/* Window sizes */
-	unsigned tblmask;		/* Mask of exponentiation window */
-	BNWORD64 bitpos;		/* Mask of current look-ahead bit */
-	unsigned buf1, buf2;		/* Buffer of exponent bits */
-	unsigned mult1pos, mult2pos;	/* Where to do pending multiply */
-	BNWORD64 const *mult1, *mult2;	/* What to multiply by */
-	unsigned i;			/* Loop counter */
-	int isone;			/* Flag: accum. is implicitly one */
-	BNWORD64 *a, *b;		/* Working buffers/accumulators */
-	BNWORD64 *t;			/* Pointer into the working buffers */
-	BNWORD64 inv;			/* mod^-1 modulo 2^64 */
-	int y;				/* bnYield() result */
-
-	assert(mlen);
-	assert(n1len <= mlen);
-	assert(n2len <= mlen);
-
-	/* First, a couple of trivial cases. */
-	e1len = lbnNorm_64(e1, e1len);
-	e2len = lbnNorm_64(e2, e2len);
-
-	/* Ensure that the first exponent is the longer */
-	e1bits = lbnBits_64(e1, e1len);
-	e2bits = lbnBits_64(e2, e2len);
-	if (e1bits < e2bits) {
-		i = e1len; e1len = e2len; e2len = i;
-		i = e1bits; e1bits = e2bits; e2bits = i;
-		t = (BNWORD64 *)n1; n1 = n2; n2 = t; 
-		t = (BNWORD64 *)e1; e1 = e2; e2 = t; 
-	}
-	assert(e1bits >= e2bits);
-
-	/* Handle a trivial case */
-	if (!e2len)
-		return lbnExpMod_64(result, n1, n1len, e1, e1len, mod, mlen);
-	assert(e2bits);
-
-	/* The code below fucks up if the exponents aren't at least 2 bits */
-	if (e1bits == 1) {
-		assert(e2bits == 1);
-
-		LBNALLOC(a, BNWORD64, n1len+n2len);
-		if (!a)
-			return -1;
-
-		lbnMul_64(a, n1, n1len, n2, n2len);
-		/* Do a direct modular reduction */
-		if (n1len + n2len >= mlen)
-			(void)lbnDiv_64(a+mlen, a, n1len+n2len, mod, mlen);
-		lbnCopy_64(result, a, mlen);
-		LBNFREE(a, n1len+n2len);
-		return 0;
-	}
-
-	/* Okay, now move the exponent pointers to the most-significant word */
-	e1 = BIGLITTLE(e1-e1len, e1+e1len-1);
-	e2 = BIGLITTLE(e2-e2len, e2+e2len-1);
-
-	/* Look up appropriate k-1 for the exponent - tblmask = 1<<(k-1) */
-	w1bits = 0;
-	while (e1bits > bnExpModThreshTable[w1bits])
-		w1bits++;
-	w2bits = 0;
-	while (e2bits > bnExpModThreshTable[w2bits])
-		w2bits++;
-
-	assert(w1bits >= w2bits);
-
-	/* Allocate working storage: two product buffers and the tables. */
-	LBNALLOC(a, BNWORD64, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD64, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert to the appropriate table size: tblmask = 1<<(k-1) */
-	tblmask = 1u << w1bits;
-	/* Use buf2 for its size, temporarily */
-	buf2 = 1u << w2bits;
-
-	LBNALLOC(t, BNWORD64, mlen);
-	if (!t) {
-		LBNFREE(b, 2*mlen);
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-	table1[0] = t;
-	table2[0] = result;
-
-	/*
-	 * Okay, we now have some minimal-sized tables - expand them.
-	 * This is allowed to fail!  If so, scale back the table sizes
-	 * and proceed.  We allocate both tables at the same time
-	 * so if it fails partway through, they'll both be a reasonable
-	 * size rather than one huge and one tiny.
-	 * When i passes buf2 (the number of entries in the e2 window,
-	 * which may be less than the number of entries in the e1 window),
-	 * stop allocating e2 space.
-	 */
-	for (i = 1; i < tblmask; i++) {
-		LBNALLOC(t, BNWORD64, mlen);
-		if (!t)	/* Out of memory!  Quit the loop. */
-			break;
-		table1[i] = t;
-		if (i < buf2) {
-			LBNALLOC(t, BNWORD64, mlen);
-			if (!t) {
-				LBNFREE(table1[i], mlen);
-				break;
-			}
-			table2[i] = t;
-		}
-	}
-
-	/* If we stopped, with i < tblmask, shrink the tables appropriately */
-	while (tblmask > i) {
-		w1bits--;
-		tblmask >>= 1;
-	}
-	/* Free up our overallocations */
-	while (--i > tblmask) {
-		if (i < buf2)
-			LBNFREE(table2[i], mlen);
-		LBNFREE(table1[i], mlen);
-	}
-	/* And shrink the second window too, if needed */
-	if (w2bits > w1bits) {
-		w2bits = w1bits;
-		buf2 = tblmask;
-	}
-
-	/*
-	 * From now on, use the w2bits variable for the difference
-	 * between w1bits and w2bits.
-	 */
-	w2bits = w1bits-w2bits;
-
-	/* Okay, fill in the tables */
-
-	/* Compute the necessary modular inverse */
-	inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	/* Convert n1 to Montgomery form */
-
-	/* Move n1 up "mlen" words into a */
-	t = BIGLITTLE(a-mlen, a+mlen);
-	lbnCopy_64(t, n1, n1len);
-	lbnZero_64(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_64(t, a, mlen+n1len, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_64(table1[0], a, mlen);
-
-	/* Square a into b */
-	lbnMontSquare_64(b, a, mod, mlen, inv);
-
-	/* Use high half of b to initialize the first table */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	for (i = 1; i < tblmask; i++) {
-		lbnMontMul_64(a, t, table1[i-1], mod, mlen, inv);
-		lbnCopy_64(table1[i], BIGLITTLE(a-mlen, a+mlen), mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* Convert n2 to Montgomery form */
-
-	t = BIGLITTLE(a-mlen, a+mlen);
-	/* Move n2 up "mlen" words into a */
-	lbnCopy_64(t, n2, n2len);
-	lbnZero_64(a, mlen);
-	/* Do the division - lose the quotient into the high-order words */
-	(void)lbnDiv_64(t, a, mlen+n2len, mod, mlen);
-	/* Copy into first table entry */
-	lbnCopy_64(table2[0], a, mlen);
-
-	/* Square it into a */
-	lbnMontSquare_64(a, table2[0], mod, mlen, inv);
-	/* Copy to b, low half */
-	lbnCopy_64(b, t, mlen);
-
-	/* Use b to initialize the second table */
-	for (i = 1; i < buf2; i++) {
-		lbnMontMul_64(a, b, table2[i-1], mod, mlen, inv);
-		lbnCopy_64(table2[i], t, mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/*
-	 * Okay, a recap: at this point, the low part of b holds
-	 * n2^2, the high part holds n1^2, and the tables are
-	 * initialized with the odd powers of n1 and n2 from 1
-	 * through 2*tblmask-1 and 2*buf2-1.
-	 *
-	 * We might use those squares in b later, or we might not.
-	 */
-
-	/* Initialze the fetch pointer */
-	bitpos = (BNWORD64)1 << ((e1bits-1) & (64-1));	/* Initialize mask */
-
-	/* This should point to the msbit of e1 */
-	assert((*e1 & bitpos) != 0);
-
-	/*
-	 * Pre-load the windows.  Becuase the window size is
-	 * never larger than the exponent size, there is no need to
-	 * detect running off the end of e1 in here.
-	 *
-	 * The read-ahead is controlled by e1len and the bitpos mask.
-	 * Note that this is *ahead* of e1bits, which tracks the
-	 * most significant end of the window.  The purpose of this
-	 * initialization is to get the two w1bits+1 bits apart,
-	 * like they should be.
-	 *
-	 * Note that bitpos and e1len together keep track of the
-	 * lookahead read pointer in the exponent that is used here.
-	 * e2len is not decremented, it is only ever compared with
-	 * e1len as *that* is decremented.
-	 */
-	buf1 = buf2 = 0;
-	for (i = 0; i <= w1bits; i++) {
-		buf1 = (buf1 << 1) | ((*e1 & bitpos) != 0);
-		if (e1len <= e2len)
-			buf2 = (buf2 << 1) | ((*e2 & bitpos) != 0);
-		bitpos >>= 1;
-		if (!bitpos) {
-			BIGLITTLE(e1++,e1--);
-			if (e1len <= e2len)
-				BIGLITTLE(e2++,e2--);
-			bitpos = (BNWORD64)1 << (64-1);
-			e1len--;
-		}
-	}
-	assert(buf1 & tblmask);
-
-	/*
-	 * Set the pending multiply positions to a location that will
-	 * never be encountered, thus ensuring that nothing will happen
-	 * until the need for a multiply appears and one is scheduled.
-	 */
-	mult1pos = mult2pos = e1bits;	/* A NULL value */
-	mult1 = mult2 = 0;	/* Force a crash if we use these */
-
-	/*
-	 * Okay, now begins the real work.  The first step is
-	 * slightly magic, so it's done outside the main loop,
-	 * but it's very similar to what's inside.
-	 */
-	isone = 1;	/* Buffer is implicitly 1, so replace * by copy */
-	e1bits--;	/* Start processing the first bit... */
-
-	/*
-	 * This is just like the multiply in the loop, except that
-	 * - We know the msbit of buf1 is set, and
-	 * - We have the extra value n1^2 floating around.
-	 * So, do the usual computation, and if the result is that
-	 * the buffer should be multiplied by n1^1 immediately
-	 * (which we'd normally then square), we multiply it
-	 * (which reduces to a copy, which reduces to setting a flag)
-	 * by n1^2 and skip the squaring.  Thus, we do the
-	 * multiply and the squaring in one step.
-	 */
-	assert(buf1 & tblmask);
-	mult1pos = e1bits - w1bits;
-	while ((buf1 & 1) == 0) {
-		buf1 >>= 1;
-		mult1pos++;
-	}
-	/* Intermediates can wrap, but final must NOT */
-	assert(mult1pos <= e1bits);
-	mult1 = table1[buf1>>1];
-	buf1 = 0;
-
-	/* Special case: use already-computed value sitting in buffer */
-	if (mult1pos == e1bits)
-		isone = 0;
-
-	/*
-	 * The first multiply by a power of n2.  Similar, but
-	 * we might not even want to schedule a multiply if e2 is
-	 * shorter than e1, and the window might be shorter so
-	 * we have to leave the low w2bits bits alone.
-	 */
-	if (buf2 & tblmask) {
-		/* Remember low-order bits for later */
-		i = buf2 & ((1u << w2bits) - 1);
-		buf2 >>= w2bits;
-		mult2pos = e1bits - w1bits + w2bits;
-		while ((buf2 & 1) == 0) {
-			buf2 >>= 1;
-			mult2pos++;
-		}
-		assert(mult2pos <= e1bits);
-		mult2 = table2[buf2>>1];
-		buf2 = i;
-
-		if (mult2pos == e1bits) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				lbnCopy_64(t, b, mlen);	/* Copy low to high */
-				isone = 0;
-			} else {
-				lbnMontMul_64(a, t, b, mod, mlen, inv);
-				t = a; a = b; b = t;
-			}
-		}
-	}
-
-	/*
-	 * At this point, the buffer (which is the high half of b)
-	 * holds either 1 (implicitly, as the "isone" flag is set),
-	 * n1^2, n2^2 or n1^2 * n2^2.
-	 */
-
-	/*
-	 * The main loop.  The procedure is:
-	 * - Advance the windows
-	 * - If the most-significant bit of a window is set,
-	 *   schedule a multiply for the appropriate time in the
-	 *   future (may be immediately)
-	 * - Perform any pending multiples
-	 * - Check for termination
-	 * - Square the buffers
-	 *
-	 * At any given time, the acumulated product is held in
-	 * the high half of b.
-	 */
-	for (;;) {
-		e1bits--;
-
-		/* Advance the windows */
-		assert(buf1 < tblmask);
-		buf1 <<= 1;
-		assert(buf2 < tblmask);
-		buf2 <<= 1;
-		/*
-		 * This reads ahead of the current exponent position
-		 * (controlled by e1bits), so we have to be able to read
-		 * past the lsb of the exponents without error.
-		 */
-		if (e1len) {
-			buf1 |= ((*e1 & bitpos) != 0);
-			if (e1len <= e2len)
-				buf2 |= ((*e2 & bitpos) != 0);
-			bitpos >>= 1;
-			if (!bitpos) {
-				BIGLITTLE(e1++,e1--);
-				if (e1len <= e2len)
-					BIGLITTLE(e2++,e2--);
-				bitpos = (BNWORD64)1 << (64-1);
-				e1len--;
-			}
-		}
-
-		/* Examine the first window for pending multiplies */
-		if (buf1 & tblmask) {
-			mult1pos = e1bits - w1bits;
-			while ((buf1 & 1) == 0) {
-				buf1 >>= 1;
-				mult1pos++;
-			}
-			/* Intermediates can wrap, but final must NOT */
-			assert(mult1pos <= e1bits);
-			mult1 = table1[buf1>>1];
-			buf1 = 0;
-		}
-
-		/*
-		 * Examine the second window for pending multiplies.
-		 * Window 2 can be smaller than window 1, but we
-		 * keep the same number of bits in buf2, so we need
-		 * to ignore any low-order bits in the buffer when
-		 * computing what to multiply by, and recompute them
-		 * later.
-		 */
-		if (buf2 & tblmask) {
-			/* Remember low-order bits for later */
-			i = buf2 & ((1u << w2bits) - 1);
-			buf2 >>= w2bits;
-			mult2pos = e1bits - w1bits + w2bits;
-			while ((buf2 & 1) == 0) {
-				buf2 >>= 1;
-				mult2pos++;
-			}
-			assert(mult2pos <= e1bits);
-			mult2 = table2[buf2>>1];
-			buf2 = i;
-		}
-
-
-		/* If we have a pending multiply for e1, do it */
-		if (e1bits == mult1pos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_64(t, mult1, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_64(a, t, mult1, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* If we have a pending multiply for e2, do it */
-		if (e1bits == mult2pos) {
-			/* Multiply by the table entry remembered previously */
-			t = BIGLITTLE(b-mlen, b+mlen);
-			if (isone) {
-				/* Multiply by 1 is a trivial case */
-				lbnCopy_64(t, mult2, mlen);
-				isone = 0;
-			} else {
-				lbnMontMul_64(a, t, mult2, mod, mlen, inv);
-				/* Swap a and b */
-				t = a; a = b; b = t;
-			}
-		}
-
-		/* Are we done? */
-		if (!e1bits)
-			break;
-
-		/* Square the buffer */
-		if (!isone) {
-			t = BIGLITTLE(b-mlen, b+mlen);
-			lbnMontSquare_64(a, t, mod, mlen, inv);
-			/* Swap a and b */
-			t = a; a = b; b = t;
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	} /* for (;;) */
-
-	assert(!isone);
-	assert(!buf1);
-	assert(!buf2);
-
-	/* DONE! */
-
-	/* Convert result out of Montgomery form */
-	t = BIGLITTLE(b-mlen, b+mlen);
-	lbnCopy_64(b, t, mlen);
-	lbnZero_64(t, mlen);
-	lbnMontReduce_64(b, mod, mlen, inv);
-	lbnCopy_64(result, t, mlen);
-
-	/* Clean up - free intermediate storage */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	buf2 = tblmask >> w2bits;
-	while (--tblmask) {
-		if (tblmask < buf2)
-			LBNFREE(table2[tblmask], mlen);
-		LBNFREE(table1[tblmask], mlen);
-	}
-	t = table1[0];
-	LBNFREE(t, mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-/*
- * 2^exp (mod mod).  This is an optimized version for use in Fermat
- * tests.  The input value of n is ignored; it is returned with
- * "mlen" words valid.
- */
-int
-lbnTwoExpMod_64(BNWORD64 *n, BNWORD64 const *exp, unsigned elen,
-	BNWORD64 *mod, unsigned mlen)
-{
-	unsigned e;	/* Copy of high words of the exponent */
-	unsigned bits;	/* Assorted counter of bits */
-	BNWORD64 const *bitptr;
-	BNWORD64 bitword, bitpos;
-	BNWORD64 *a, *b, *a1;
-	BNWORD64 inv;
-	int y;		/* Result of bnYield() */
-
-	assert(mlen);
-
-	bitptr = BIGLITTLE(exp-elen, exp+elen-1);
-	bitword = *bitptr;
-	assert(bitword);
-
-	/* Clear n for future use. */
-	lbnZero_64(n, mlen);
-
-	bits = lbnBits_64(exp, elen);
-	
-	/* First, a couple of trivial cases. */
-	if (bits <= 1) {
-		/* 2 ^ 0 == 1,  2 ^ 1 == 2 */
-		BIGLITTLE(n[-1],n[0]) = (BNWORD64)1<<elen;
-		return 0;
-	}
-
-	/* Set bitpos to the most significant bit */
-	bitpos = (BNWORD64)1 << ((bits-1) & (64-1));
-
-	/* Now, count the bits in the modulus. */
-	bits = lbnBits_64(mod, mlen);
-	assert(bits > 1);	/* a 1-bit modulus is just stupid... */
-
-	/*
-	 * We start with 1<<e, where "e" is as many high bits of the
-	 * exponent as we can manage without going over the modulus.
-	 * This first loop finds "e".
-	 */
-	e = 1;
-	while (elen) {
-		/* Consume the first bit */
-		bitpos >>= 1;
-		if (!bitpos) {
-			if (!--elen)
-				break;
-			bitword = BIGLITTLE(*++bitptr,*--bitptr);
-			bitpos = (BNWORD64)1<<(64-1);
-		}
-		e = (e << 1) | ((bitpos & bitword) != 0);
-		if (e >= bits) {	/* Overflow!  Back out. */
-			e >>= 1;
-			break;
-		}
-	}
-	/*
-	 * The bit in "bitpos" being examined by the bit buffer has NOT
-	 * been consumed yet.  This may be past the end of the exponent,
-	 * in which case elen == 1.
-	 */
-
-	/* Okay, now, set bit "e" in n.  n is already zero. */
-	inv = (BNWORD64)1 << (e & (64-1));
-	e /= 64;
-	BIGLITTLE(n[-e-1],n[e]) = inv;
-	/*
-	 * The effective length of n in words is now "e+1".
-	 * This is used a little bit later.
-	 */
-
-	if (!elen)
-		return 0;	/* That was easy! */
-
-	/*
-	 * We have now processed the first few bits.  The next step
-	 * is to convert this to Montgomery form for further squaring.
-	 */
-
-	/* Allocate working storage: two product buffers */
-	LBNALLOC(a, BNWORD64, 2*mlen);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD64, 2*mlen);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Convert n to Montgomery form */
-	inv = BIGLITTLE(mod[-1],mod[0]);	/* LSW of modulus */
-	assert(inv & 1);	/* Modulus must be odd */
-	inv = lbnMontInv1_64(inv);
-	/* Move n (length e+1, remember?) up "mlen" words into b */
-	/* Note that we lie about a1 for a bit - it's pointing to b */
-	a1 = BIGLITTLE(b-mlen,b+mlen);
-	lbnCopy_64(a1, n, e+1);
-	lbnZero_64(b, mlen);
-	/* Do the division - dump the quotient into the high-order words */
-	(void)lbnDiv_64(a1, b, mlen+e+1, mod, mlen);
-	/*
-	 * Now do the first squaring and modular reduction to put
-	 * the number up in a1 where it belongs.
-	 */
-	lbnMontSquare_64(a, b, mod, mlen, inv);
-	/* Fix up a1 to point to where it should go. */
-	a1 = BIGLITTLE(a-mlen,a+mlen);
-
-	/*
-	 * Okay, now, a1 holds the number being accumulated, and
-	 * b is a scratch register.  Start working:
-	 */
-	for (;;) {
-		/*
-		 * Is the bit set?  If so, double a1 as well.
-		 * A modular doubling like this is very cheap.
-		 */
-		if (bitpos & bitword) {
-			/*
-			 * Double the number.  If there was a carry out OR
-			 * the result is greater than the modulus, subract
-			 * the modulus.
-			 */
-			if (lbnDouble_64(a1, mlen) ||
-			    lbnCmp_64(a1, mod, mlen) > 0)
-				(void)lbnSubN_64(a1, mod, mlen);
-		}
-
-		/* Advance to the next exponent bit */
-		bitpos >>= 1;
-		if (!bitpos) {
-			if (!--elen)
-				break;	/* Done! */
-			bitword = BIGLITTLE(*++bitptr,*--bitptr);
-			bitpos = (BNWORD64)1<<(64-1);
-		}
-
-		/*
-		 * The elen/bitword/bitpos bit buffer is known to be
-		 * non-empty, i.e. there is at least one more unconsumed bit.
-		 * Thus, it's safe to square the number.
-		 */
-		lbnMontSquare_64(b, a1, mod, mlen, inv);
-		/* Rename result (in b) back to a (a1, really). */
-		a1 = b; b = a; a = a1;
-		a1 = BIGLITTLE(a-mlen,a+mlen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			goto yield;
-#endif
-	}
-
-	/* DONE!  Just a little bit of cleanup... */
-
-	/*
-	 * Convert result out of Montgomery form... this is
-	 * just a Montgomery reduction.
-	 */
-	lbnCopy_64(a, a1, mlen);
-	lbnZero_64(a1, mlen);
-	lbnMontReduce_64(a, mod, mlen, inv);
-	lbnCopy_64(n, a1, mlen);
-
-	/* Clean up - free intermediate storage */
-	y = 0;
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;	/* Success */
-}
-
-
-/*
- * Returns a substring of the big-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length.  I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence 
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractBigBytes_64(BNWORD64 const *n, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen)
-{
-	BNWORD64 t = 0;	/* Needed to shut up uninitialized var warnings */
-	unsigned shift;
-
-	lsbyte += buflen;
-
-	shift = (8 * lsbyte) % 64;
-	lsbyte /= (64/8);	/* Convert to word offset */
-	BIGLITTLE(n -= lsbyte, n += lsbyte);
-
-	if (shift)
-		t = BIGLITTLE(n[-1],n[0]);
-
-	while (buflen--) {
-		if (!shift) {
-			t = BIGLITTLE(*n++,*--n);
-			shift = 64;
-		}
-		shift -= 8;
-		*buf++ = (unsigned char)(t>>shift);
-	}
-}
-
-/*
- * Merge a big-endian array of bytes into a bignum array.
- * The array had better be big enough.  This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its *last* byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right.  Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertBigBytes_64(BNWORD64 *n, unsigned char const *buf,
-                  unsigned lsbyte,  unsigned buflen)
-{
-	BNWORD64 t = 0;	/* Shut up uninitialized varibale warnings */
-
-	lsbyte += buflen;
-
-	BIGLITTLE(n -= lsbyte/(64/8), n += lsbyte/(64/8));
-
-	/* Load up leading odd bytes */
-	if (lsbyte % (64/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte * 8) % 64;
-	}
-
-	/* The main loop - merge into t, storing at each word boundary. */
-	while (buflen--) {
-		t = (t << 8) | *buf++;
-		if ((--lsbyte % (64/8)) == 0)
-			BIGLITTLE(*n++,*--n) = t;
-	}
-
-	/* Merge odd bytes in t into last word */
-	lsbyte = (lsbyte * 8) % 64;
-	if (lsbyte) {
-		t <<= lsbyte;
-		t |= (((BNWORD64)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
-		BIGLITTLE(n[0],n[-1]) = t;
-	}
-
-	return;
-}
-
-/*
- * Returns a substring of the little-endian array of bytes representation
- * of the bignum array based on two parameters, the least significant
- * byte number (0 to start with the least significant byte) and the
- * length.  I.e. the number returned is a representation of
- * (bn / 2^(8*lsbyte)) % 2 ^ (8*buflen).
- *
- * It is an error if the bignum is not at least buflen + lsbyte bytes
- * long.
- *
- * This code assumes that the compiler has the minimal intelligence 
- * neded to optimize divides and modulo operations on an unsigned data
- * type with a power of two.
- */
-void
-lbnExtractLittleBytes_64(BNWORD64 const *n, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen)
-{
-	BNWORD64 t = 0;	/* Needed to shut up uninitialized var warnings */
-
-	BIGLITTLE(n -= lsbyte/(64/8), n += lsbyte/(64/8));
-
-	if (lsbyte % (64/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte % (64/8)) * 8 ;
-	}
-
-	while (buflen--) {
-		if ((lsbyte++ % (64/8)) == 0)
-			t = BIGLITTLE(*--n,*n++);
-		*buf++ = (unsigned char)t;
-		t >>= 8;
-	}
-}
-
-/*
- * Merge a little-endian array of bytes into a bignum array.
- * The array had better be big enough.  This is
- * equivalent to extracting the entire bignum into a
- * large byte array, copying the input buffer into the
- * middle of it, and converting back to a bignum.
- *
- * The buf is "len" bytes long, and its first byte is at
- * position "lsbyte" from the end of the bignum.
- *
- * Note that this is a pain to get right.  Fortunately, it's hardly
- * critical for efficiency.
- */
-void
-lbnInsertLittleBytes_64(BNWORD64 *n, unsigned char const *buf,
-                  unsigned lsbyte,  unsigned buflen)
-{
-	BNWORD64 t = 0;	/* Shut up uninitialized varibale warnings */
-
-	/* Move to most-significant end */
-	lsbyte += buflen;
-	buf += buflen;
-
-	BIGLITTLE(n -= lsbyte/(64/8), n += lsbyte/(64/8));
-
-	/* Load up leading odd bytes */
-	if (lsbyte % (64/8)) {
-		t = BIGLITTLE(*--n,*n++);
-		t >>= (lsbyte * 8) % 64;
-	}
-
-	/* The main loop - merge into t, storing at each word boundary. */
-	while (buflen--) {
-		t = (t << 8) | *--buf;
-		if ((--lsbyte % (64/8)) == 0)
-			BIGLITTLE(*n++,*--n) = t;
-	}
-
-	/* Merge odd bytes in t into last word */
-	lsbyte = (lsbyte * 8) % 64;
-	if (lsbyte) {
-		t <<= lsbyte;
-		t |= (((BNWORD64)1 << lsbyte) - 1) & BIGLITTLE(n[0],n[-1]);
-		BIGLITTLE(n[0],n[-1]) = t;
-	}
-
-	return;
-}
-
-#ifdef DEADCODE	/* This was a precursor to the more flexible lbnExtractBytes */
-/*
- * Convert a big-endian array of bytes to a bignum.
- * Returns the number of words in the bignum.
- * Note the expression "64/8" for the number of bytes per word.
- * This is so the word-size adjustment will work.
- */
-unsigned
-lbnFromBytes_64(BNWORD64 *a, unsigned char const *b, unsigned blen)
-{
-	BNWORD64 t;
-	unsigned alen = (blen + (64/8-1))/(64/8);
-	BIGLITTLE(a -= alen, a += alen);
-
-	while (blen) {
-		t = 0;
-		do {
-			t = t << 8 | *b++;
-		} while (--blen & (64/8-1));
-		BIGLITTLE(*a++,*--a) = t;
-	}
-	return alen;
-}
-#endif
-
-/*
- * Computes the GCD of a and b.  Modifies both arguments; when it returns,
- * one of them is the GCD and the other is trash.  The return value
- * indicates which: 0 for a, and 1 for b.  The length of the retult is
- * returned in rlen.  Both inputs must have one extra word of precision.
- * alen must be >= blen.
- *
- * TODO: use the binary algorithm (Knuth section 4.5.2, algorithm B).
- * This is based on taking out common powers of 2, then repeatedly:
- * gcd(2*u,v) = gcd(u,2*v) = gcd(u,v) - isolated powers of 2 can be deleted.
- * gcd(u,v) = gcd(u-v,v) - the numbers can be easily reduced.
- * It gets less reduction per step, but the steps are much faster than
- * the division case.
- */
-int
-lbnGcd_64(BNWORD64 *a, unsigned alen, BNWORD64 *b, unsigned blen,
-	unsigned *rlen)
-{
-#if BNYIELD
-	int y;
-#endif
-	assert(alen >= blen);
-
-	while (blen != 0) {
-		(void)lbnDiv_64(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
-		alen = lbnNorm_64(a, blen);
-		if (alen == 0) {
-			*rlen = blen;
-			return 1;
-		}
-		(void)lbnDiv_64(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
-		blen = lbnNorm_64(b, alen);
-#if BNYIELD
-		if (bnYield && (y = bnYield()) < 0)
-			return y;
-#endif
-	}
-	*rlen = alen;
-	return 0;
-}
-
-/*
- * Invert "a" modulo "mod" using the extended Euclidean algorithm.
- * Note that this only computes one of the cosequences, and uses the
- * theorem that the signs flip every step and the absolute value of
- * the cosequence values are always bounded by the modulus to avoid
- * having to work with negative numbers.
- * gcd(a,mod) had better equal 1.  Returns 1 if the GCD is NOT 1.
- * a must be one word longer than "mod".  It is overwritten with the
- * result.
- * TODO: Use Richard Schroeppel's *much* faster algorithm.
- */
-int
-lbnInv_64(BNWORD64 *a, unsigned alen, BNWORD64 const *mod, unsigned mlen)
-{
-	BNWORD64 *b;	/* Hold a copy of mod during GCD reduction */
-	BNWORD64 *p;	/* Temporary for products added to t0 and t1 */
-	BNWORD64 *t0, *t1;	/* Inverse accumulators */
-	BNWORD64 cy;
-	unsigned blen, t0len, t1len, plen;
-	int y;
-
-	alen = lbnNorm_64(a, alen);
-	if (!alen)
-		return 1;	/* No inverse */
-
-	mlen = lbnNorm_64(mod, mlen);
-
-	assert (alen <= mlen);
-
-	/* Inverse of 1 is 1 */
-	if (alen == 1 && BIGLITTLE(a[-1],a[0]) == 1) {
-		lbnZero_64(BIGLITTLE(a-alen,a+alen), mlen-alen);
-		return 0;
-	}
-
-	/* Allocate a pile of space */
-	LBNALLOC(b, BNWORD64, mlen+1);
-	if (b) {
-		/*
-		 * Although products are guaranteed to always be less than the
-		 * modulus, it can involve multiplying two 3-word numbers to
-		 * get a 5-word result, requiring a 6th word to store a 0
-		 * temporarily.  Thus, mlen + 1.
-		 */
-		LBNALLOC(p, BNWORD64, mlen+1);
-		if (p) {
-			LBNALLOC(t0, BNWORD64, mlen);
-			if (t0) {
-				LBNALLOC(t1, BNWORD64, mlen);
-				if (t1)
-						goto allocated;
-				LBNFREE(t0, mlen);
-			}
-			LBNFREE(p, mlen+1);
-		}
-		LBNFREE(b, mlen+1);
-	}
-	return -1;
-
-allocated:
-
-	/* Set t0 to 1 */
-	t0len = 1;
-	BIGLITTLE(t0[-1],t0[0]) = 1;
-	
-	/* b = mod */
-	lbnCopy_64(b, mod, mlen);
-	/* blen = mlen (implicitly) */
-	
-	/* t1 = b / a; b = b % a */
-	cy = lbnDiv_64(t1, b, mlen, a, alen);
-	*(BIGLITTLE(t1-(mlen-alen)-1,t1+(mlen-alen))) = cy;
-	t1len = lbnNorm_64(t1, mlen-alen+1);
-	blen = lbnNorm_64(b, alen);
-
-	/* while (b > 1) */
-	while (blen > 1 || BIGLITTLE(b[-1],b[0]) != (BNWORD64)1) {
-		/* q = a / b; a = a % b; */
-		if (alen < blen || (alen == blen && lbnCmp_64(a, a, alen) < 0))
-			assert(0);
-		cy = lbnDiv_64(BIGLITTLE(a-blen,a+blen), a, alen, b, blen);
-		*(BIGLITTLE(a-alen-1,a+alen)) = cy;
-		plen = lbnNorm_64(BIGLITTLE(a-blen,a+blen), alen-blen+1);
-		assert(plen);
-		alen = lbnNorm_64(a, blen);
-		if (!alen)
-			goto failure;	/* GCD not 1 */
-
-		/* t0 += q * t1; */
-		assert(plen+t1len <= mlen+1);
-		lbnMul_64(p, BIGLITTLE(a-blen,a+blen), plen, t1, t1len);
-		plen = lbnNorm_64(p, plen + t1len);
-		assert(plen <= mlen);
-		if (plen > t0len) {
-			lbnZero_64(BIGLITTLE(t0-t0len,t0+t0len), plen-t0len);
-			t0len = plen;
-		}
-		cy = lbnAddN_64(t0, p, plen);
-		if (cy) {
-			if (t0len > plen) {
-				cy = lbnAdd1_64(BIGLITTLE(t0-plen,t0+plen),
-						t0len-plen, cy);
-			}
-			if (cy) {
-				BIGLITTLE(t0[-t0len-1],t0[t0len]) = cy;
-				t0len++;
-			}
-		}
-
-		/* if (a <= 1) return a ? t0 : FAIL; */
-		if (alen <= 1 && BIGLITTLE(a[-1],a[0]) == (BNWORD64)1) {
-			if (alen == 0)
-				goto failure;	/* FAIL */
-			assert(t0len <= mlen);
-			lbnCopy_64(a, t0, t0len);
-			lbnZero_64(BIGLITTLE(a-t0len, a+t0len), mlen-t0len);
-			goto success;
-		}
-
-		/* q = b / a; b = b % a; */
-		if (blen < alen || (blen == alen && lbnCmp_64(b, a, alen) < 0))
-			assert(0);
-		cy = lbnDiv_64(BIGLITTLE(b-alen,b+alen), b, blen, a, alen);
-		*(BIGLITTLE(b-blen-1,b+blen)) = cy;
-		plen = lbnNorm_64(BIGLITTLE(b-alen,b+alen), blen-alen+1);
-		assert(plen);
-		blen = lbnNorm_64(b, alen);
-		if (!blen)
-			goto failure;	/* GCD not 1 */
-
-		/* t1 += q * t0; */
-		assert(plen+t0len <= mlen+1);
-		lbnMul_64(p, BIGLITTLE(b-alen,b+alen), plen, t0, t0len);
-		plen = lbnNorm_64(p, plen + t0len);
-		assert(plen <= mlen);
-		if (plen > t1len) {
-			lbnZero_64(BIGLITTLE(t1-t1len,t1+t1len), plen-t1len);
-			t1len = plen;
-		}
-		cy = lbnAddN_64(t1, p, plen);
-		if (cy) {
-			if (t1len > plen) {
-				cy = lbnAdd1_64(BIGLITTLE(t1-plen,t0+plen),
-						t1len-plen, cy);
-			}
-			if (cy) {
-				BIGLITTLE(t1[-t1len-1],t1[t1len]) = cy;
-				t1len++;
-			}
-		}
-#if BNYIELD
-		if (bnYield && (y = bnYield() < 0))
-			goto yield;
-#endif
-	}
-
-	if (!blen)
-		goto failure;	/* gcd(a, mod) != 1 -- FAIL */
-
-	/* return mod-t1 */
-	lbnCopy_64(a, mod, mlen);
-	assert(t1len <= mlen);
-	cy = lbnSubN_64(a, t1, t1len);
-	if (cy) {
-		assert(mlen > t1len);
-		cy = lbnSub1_64(BIGLITTLE(a-t1len, a+t1len), mlen-t1len, cy);
-		assert(!cy);
-	}
-
-success:
-	LBNFREE(t1, mlen);
-	LBNFREE(t0, mlen);
-	LBNFREE(p, mlen+1);
-	LBNFREE(b, mlen+1);
-	
-	return 0;
-
-failure:		/* GCD is not 1 - no inverse exists! */
-	y = 1;
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(t1, mlen);
-	LBNFREE(t0, mlen);
-	LBNFREE(p, mlen+1);
-	LBNFREE(b, mlen+1);
-	
-	return y;
-}
-
-/*
- * Precompute powers of "a" mod "mod".  Compute them every "bits"
- * for "n" steps.  This is sufficient to compute powers of g with
- * exponents up to n*bits bits long, i.e. less than 2^(n*bits).
- * 
- * This assumes that the caller has already initialized "array" to point
- * to "n" buffers of size "mlen".
- */
-int
-lbnBasePrecompBegin_64(BNWORD64 **array, unsigned n, unsigned bits,
-	BNWORD64 const *g, unsigned glen, BNWORD64 *mod, unsigned mlen)
-{
-	BNWORD64 *a, *b;	/* Temporary double-width accumulators */
-	BNWORD64 *a1;	/* Pointer to high half of a*/
-	BNWORD64 inv;	/* Montgomery inverse of LSW of mod */
-	BNWORD64 *t;
-	unsigned i;
-
-	glen = lbnNorm_64(g, glen);
-	assert(glen);
-
-	assert (mlen == lbnNorm_64(mod, mlen));
-	assert (glen <= mlen);
-
-	/* Allocate two temporary buffers, and the array slots */
-	LBNALLOC(a, BNWORD64, mlen*2);
-	if (!a)
-		return -1;
-	LBNALLOC(b, BNWORD64, mlen*2);
-	if (!b) {
-		LBNFREE(a, 2*mlen);
-		return -1;
-	}
-
-	/* Okay, all ready */
-
-	/* Convert n to Montgomery form */
-	inv = BIGLITTLE(mod[-1],mod[0]);	/* LSW of modulus */
-	assert(inv & 1);	/* Modulus must be odd */
-	inv = lbnMontInv1_64(inv);
-	/* Move g up "mlen" words into a (clearing the low mlen words) */
-	a1 = BIGLITTLE(a-mlen,a+mlen);
-	lbnCopy_64(a1, g, glen);
-	lbnZero_64(a, mlen);
-
-	/* Do the division - dump the quotient into the high-order words */
-	(void)lbnDiv_64(a1, a, mlen+glen, mod, mlen);
-
-	/* Copy the first value into the array */
-	t = *array;
-	lbnCopy_64(t, a, mlen);
-	a1 = a;	/* This first value is *not* shifted up */
-	
-	/* Now compute the remaining n-1 array entries */
-	assert(bits);
-	assert(n);
-	while (--n) {
-		i = bits;
-		do {
-			/* Square a1 into b1 */
-			lbnMontSquare_64(b, a1, mod, mlen, inv);
-			t = b; b = a; a = t;
-			a1 = BIGLITTLE(a-mlen, a+mlen);
-		} while (--i);
-		t = *++array;
-		lbnCopy_64(t, a1, mlen);
-	}
-
-	/* Hooray, we're done. */
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-	return 0;
-}
-
-/*
- * result = base^exp (mod mod).  "array" is a an array of pointers
- * to procomputed powers of base, each 2^bits apart.  (I.e. array[i]
- * is base^(2^(i*bits))).
- * 
- * The algorithm consists of:
- * a  = b  = (powers of g to be raised to the power 2^bits-1)
- * a *= b *= (powers of g to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of g to be raised to the power 1)
- * 
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnBasePrecompExp_64(BNWORD64 *result, BNWORD64 const * const *array,
-       unsigned bits, BNWORD64 const *exp, unsigned elen,
-       BNWORD64 const *mod, unsigned mlen)
-{
-	BNWORD64 *a, *b, *c, *t;
-	BNWORD64 *a1, *b1;
-	int anull, bnull;	/* Null flags: values are implicitly 1 */
-	unsigned i, j;				/* Loop counters */
-	unsigned mask;				/* Exponent bits to examime */
-	BNWORD64 const *eptr;			/* Pointer into exp */
-	BNWORD64 buf, curbits, nextword;	/* Bit-buffer varaibles */
-	BNWORD64 inv;				/* Inverse of LSW of modulus */
-	unsigned ewords;			/* Words of exponent left */
-	int bufbits;				/* Number of valid bits */
-	int y = 0;
-
-	mlen = lbnNorm_64(mod, mlen);
-	assert (mlen);
-
-	elen = lbnNorm_64(exp, elen);
-	if (!elen) {
-		lbnZero_64(result, mlen);
-		BIGLITTLE(result[-1],result[0]) = 1;
-		return 0;
-	}
-	/*
-	 * This could be precomputed, but it's so cheap, and it would require
-	 * making the precomputation structure word-size dependent.
-	 */
-	inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	assert(elen);
-
-	/*
-	 * Allocate three temporary buffers.  The current numbers generally
-	 * live in the upper halves of these buffers.
-	 */
-	LBNALLOC(a, BNWORD64, mlen*2);
-	if (a) {
-		LBNALLOC(b, BNWORD64, mlen*2);
-		if (b) {
-			LBNALLOC(c, BNWORD64, mlen*2);
-			if (c)
-				goto allocated;
-			LBNFREE(b, 2*mlen);
-		}
-		LBNFREE(a, 2*mlen);
-	}
-	return -1;
-
-allocated:
-
-	anull = bnull = 1;
-
-	mask = (1u<<bits) - 1;
-	for (i = mask; i; --i) {
-		/* Set up bit buffer for walking the exponent */
-		eptr = exp;
-		buf = BIGLITTLE(*--eptr, *eptr++);
-		ewords = elen-1;
-		bufbits = 64;
-		for (j = 0; ewords || buf; j++) {
-			/* Shift down current buffer */
-			curbits = buf;
-			buf >>= bits;
-			/* If necessary, add next word */
-			bufbits -= bits;
-			if (bufbits < 0 && ewords > 0) {
-				nextword = BIGLITTLE(*--eptr, *eptr++);
-				ewords--;
-				curbits |= nextword << (bufbits+bits);
-				buf = nextword >> -bufbits;
-				bufbits += 64;
-			}
-			/* If appropriate, multiply b *= array[j] */
-			if ((curbits & mask) == i) {
-				BNWORD64 const *d = array[j];
-
-				b1 = BIGLITTLE(b-mlen-1,b+mlen);
-				if (bnull) {
-					lbnCopy_64(b1, d, mlen);
-					bnull = 0;
-				} else {
-					lbnMontMul_64(c, b1, d, mod, mlen, inv);
-					t = c; c = b; b = t;
-				}
-#if BNYIELD
-				if (bnYield && (y = bnYield() < 0))
-					goto yield;
-#endif
-			}
-		}
-
-		/* Multiply a *= b */
-		if (!bnull) {
-			a1 = BIGLITTLE(a-mlen-1,a+mlen);
-			b1 = BIGLITTLE(b-mlen-1,b+mlen);
-			if (anull) {
-				lbnCopy_64(a1, b1, mlen);
-				anull = 0;
-			} else {
-				lbnMontMul_64(c, a1, b1, mod, mlen, inv);
-				t = c; c = a; a = t;
-			}
-		}
-	}
-
-	assert(!anull);	/* If it were, elen would have been 0 */
-
-	/* Convert out of Montgomery form and return */
-	a1 = BIGLITTLE(a-mlen-1,a+mlen);
-	lbnCopy_64(a, a1, mlen);
-	lbnZero_64(a1, mlen);
-	lbnMontReduce_64(a, mod, mlen, inv);
-	lbnCopy_64(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(c, 2*mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;
-}
-
-/*
- * result = base1^exp1 *base2^exp2 (mod mod).  "array1" and "array2" are
- * arrays of pointers to procomputed powers of the corresponding bases,
- * each 2^bits apart.  (I.e. array1[i] is base1^(2^(i*bits))).
- * 
- * Bits must be the same in both.  (It could be made adjustable, but it's
- * a bit of a pain.  Just make them both equal to the larger one.)
- * 
- * The algorithm consists of:
- * a  = b  = (powers of base1 and base2  to be raised to the power 2^bits-1)
- * a *= b *= (powers of base1 and base2 to be raised to the power 2^bits-2)
- * ...
- * a *= b *= (powers of base1 and base2 to be raised to the power 1)
- * 
- * All we do is walk the exponent 2^bits-1 times in groups of "bits" bits,
- */
-int
-lbnDoubleBasePrecompExp_64(BNWORD64 *result, unsigned bits,
-       BNWORD64 const * const *array1, BNWORD64 const *exp1, unsigned elen1,
-       BNWORD64 const * const *array2, BNWORD64 const *exp2,
-       unsigned elen2, BNWORD64 const *mod, unsigned mlen)
-{
-	BNWORD64 *a, *b, *c, *t;
-	BNWORD64 *a1, *b1;
-	int anull, bnull;	/* Null flags: values are implicitly 1 */
-	unsigned i, j, k;				/* Loop counters */
-	unsigned mask;				/* Exponent bits to examime */
-	BNWORD64 const *eptr;			/* Pointer into exp */
-	BNWORD64 buf, curbits, nextword;	/* Bit-buffer varaibles */
-	BNWORD64 inv;				/* Inverse of LSW of modulus */
-	unsigned ewords;			/* Words of exponent left */
-	int bufbits;				/* Number of valid bits */
-	int y = 0;
-	BNWORD64 const * const *array;
-
-	mlen = lbnNorm_64(mod, mlen);
-	assert (mlen);
-
-	elen1 = lbnNorm_64(exp1, elen1);
-	if (!elen1) {
-		return lbnBasePrecompExp_64(result, array2, bits, exp2, elen2,
-		                            mod, mlen);
-	}
-	elen2 = lbnNorm_64(exp2, elen2);
-	if (!elen2) {
-		return lbnBasePrecompExp_64(result, array1, bits, exp1, elen1,
-		                            mod, mlen);
-	}
-	/*
-	 * This could be precomputed, but it's so cheap, and it would require
-	 * making the precomputation structure word-size dependent.
-	 */
-	inv = lbnMontInv1_64(mod[BIGLITTLE(-1,0)]);	/* LSW of modulus */
-
-	assert(elen1);
-	assert(elen2);
-
-	/*
-	 * Allocate three temporary buffers.  The current numbers generally
-	 * live in the upper halves of these buffers.
-	 */
-	LBNALLOC(a, BNWORD64, mlen*2);
-	if (a) {
-		LBNALLOC(b, BNWORD64, mlen*2);
-		if (b) {
-			LBNALLOC(c, BNWORD64, mlen*2);
-			if (c)
-				goto allocated;
-			LBNFREE(b, 2*mlen);
-		}
-		LBNFREE(a, 2*mlen);
-	}
-	return -1;
-
-allocated:
-
-	anull = bnull = 1;
-
-	mask = (1u<<bits) - 1;
-	for (i = mask; i; --i) {
-		/* Walk each exponent in turn */
-		for (k = 0; k < 2; k++) {
-			/* Set up the exponent for walking */
-			array = k ? array2 : array1;
-			eptr = k ? exp2 : exp1;
-			ewords = (k ? elen2 : elen1) - 1;
-			/* Set up bit buffer for walking the exponent */
-			buf = BIGLITTLE(*--eptr, *eptr++);
-			bufbits = 64;
-			for (j = 0; ewords || buf; j++) {
-				/* Shift down current buffer */
-				curbits = buf;
-				buf >>= bits;
-				/* If necessary, add next word */
-				bufbits -= bits;
-				if (bufbits < 0 && ewords > 0) {
-					nextword = BIGLITTLE(*--eptr, *eptr++);
-					ewords--;
-					curbits |= nextword << (bufbits+bits);
-					buf = nextword >> -bufbits;
-					bufbits += 64;
-				}
-				/* If appropriate, multiply b *= array[j] */
-				if ((curbits & mask) == i) {
-					BNWORD64 const *d = array[j];
-
-					b1 = BIGLITTLE(b-mlen-1,b+mlen);
-					if (bnull) {
-						lbnCopy_64(b1, d, mlen);
-						bnull = 0;
-					} else {
-						lbnMontMul_64(c, b1, d, mod, mlen, inv);
-						t = c; c = b; b = t;
-					}
-#if BNYIELD
-					if (bnYield && (y = bnYield() < 0))
-						goto yield;
-#endif
-				}
-			}
-		}
-
-		/* Multiply a *= b */
-		if (!bnull) {
-			a1 = BIGLITTLE(a-mlen-1,a+mlen);
-			b1 = BIGLITTLE(b-mlen-1,b+mlen);
-			if (anull) {
-				lbnCopy_64(a1, b1, mlen);
-				anull = 0;
-			} else {
-				lbnMontMul_64(c, a1, b1, mod, mlen, inv);
-				t = c; c = a; a = t;
-			}
-		}
-	}
-
-	assert(!anull);	/* If it were, elen would have been 0 */
-
-	/* Convert out of Montgomery form and return */
-	a1 = BIGLITTLE(a-mlen-1,a+mlen);
-	lbnCopy_64(a, a1, mlen);
-	lbnZero_64(a1, mlen);
-	lbnMontReduce_64(a, mod, mlen, inv);
-	lbnCopy_64(result, a1, mlen);
-
-#if BNYIELD
-yield:
-#endif
-	LBNFREE(c, 2*mlen);
-	LBNFREE(b, 2*mlen);
-	LBNFREE(a, 2*mlen);
-
-	return y;
-}
diff --git a/jni/libzrtp/sources/bnlib/lbn64.h b/jni/libzrtp/sources/bnlib/lbn64.h
deleted file mode 100644
index 283e248..0000000
--- a/jni/libzrtp/sources/bnlib/lbn64.h
+++ /dev/null
@@ -1,152 +0,0 @@
-#ifndef LBN64_H
-#define LBN64_H
-
-#include "lbn.h"
-
-#ifndef BNWORD64
-#error 64-bit bignum library requires a 64-bit data type
-#endif
-
-#ifndef lbnCopy_64
-void lbnCopy_64(BNWORD64 *dest, BNWORD64 const *src, unsigned len);
-#endif
-#ifndef lbnZero_64
-void lbnZero_64(BNWORD64 *num, unsigned len);
-#endif
-#ifndef lbnNeg_64
-void lbnNeg_64(BNWORD64 *num, unsigned len);
-#endif
-
-#ifndef lbnAdd1_64
-BNWORD64 lbnAdd1_64(BNWORD64 *num, unsigned len, BNWORD64 carry);
-#endif
-#ifndef lbnSub1_64
-BNWORD64 lbnSub1_64(BNWORD64 *num, unsigned len, BNWORD64 borrow);
-#endif
-
-#ifndef lbnAddN_64
-BNWORD64 lbnAddN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len);
-#endif
-#ifndef lbnSubN_64
-BNWORD64 lbnSubN_64(BNWORD64 *num1, BNWORD64 const *num2, unsigned len);
-#endif
-
-#ifndef lbnCmp_64
-int lbnCmp_64(BNWORD64 const *num1, BNWORD64 const *num2, unsigned len);
-#endif
-
-#ifndef lbnMulN1_64
-void lbnMulN1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k);
-#endif
-#ifndef lbnMulAdd1_64
-BNWORD64
-lbnMulAdd1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k);
-#endif
-#ifndef lbnMulSub1_64
-BNWORD64 lbnMulSub1_64(BNWORD64 *out, BNWORD64 const *in, unsigned len, BNWORD64 k);
-#endif
-
-#ifndef lbnLshift_64
-BNWORD64 lbnLshift_64(BNWORD64 *num, unsigned len, unsigned shift);
-#endif
-#ifndef lbnDouble_64
-BNWORD64 lbnDouble_64(BNWORD64 *num, unsigned len);
-#endif
-#ifndef lbnRshift_64
-BNWORD64 lbnRshift_64(BNWORD64 *num, unsigned len, unsigned shift);
-#endif
-
-#ifndef lbnMul_64
-void lbnMul_64(BNWORD64 *prod, BNWORD64 const *num1, unsigned len1,
-	BNWORD64 const *num2, unsigned len2);
-#endif
-#ifndef lbnSquare_64
-void lbnSquare_64(BNWORD64 *prod, BNWORD64 const *num, unsigned len);
-#endif
-
-#ifndef lbnNorm_64
-unsigned lbnNorm_64(BNWORD64 const *num, unsigned len);
-#endif
-#ifndef lbnBits_64
-unsigned lbnBits_64(BNWORD64 const *num, unsigned len);
-#endif
-
-#ifndef lbnExtractBigBytes_64
-void lbnExtractBigBytes_64(BNWORD64 const *bn, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertBigytes_64
-void lbnInsertBigBytes_64(BNWORD64 *n, unsigned char const *buf,
-	unsigned lsbyte,  unsigned buflen);
-#endif
-#ifndef lbnExtractLittleBytes_64
-void lbnExtractLittleBytes_64(BNWORD64 const *bn, unsigned char *buf,
-	unsigned lsbyte, unsigned buflen);
-#endif
-#ifndef lbnInsertLittleBytes_64
-void lbnInsertLittleBytes_64(BNWORD64 *n, unsigned char const *buf,
-	unsigned lsbyte,  unsigned buflen);
-#endif
-
-#ifndef lbnDiv21_64
-BNWORD64 lbnDiv21_64(BNWORD64 *q, BNWORD64 nh, BNWORD64 nl, BNWORD64 d);
-#endif
-#ifndef lbnDiv1_64
-BNWORD64 lbnDiv1_64(BNWORD64 *q, BNWORD64 *rem,
-	BNWORD64 const *n, unsigned len, BNWORD64 d);
-#endif
-#ifndef lbnModQ_64
-unsigned lbnModQ_64(BNWORD64 const *n, unsigned len, unsigned d);
-#endif
-#ifndef lbnDiv_64
-BNWORD64
-lbnDiv_64(BNWORD64 *q, BNWORD64 *n, unsigned nlen, BNWORD64 *d, unsigned dlen);
-#endif
-
-#ifndef lbnMontInv1_64
-BNWORD64 lbnMontInv1_64(BNWORD64 const x);
-#endif
-#ifndef lbnMontReduce_64
-void lbnMontReduce_64(BNWORD64 *n, BNWORD64 const *mod, unsigned const mlen,
-                BNWORD64 inv);
-#endif
-#ifndef lbnToMont_64
-void lbnToMont_64(BNWORD64 *n, unsigned nlen, BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnFromMont_64
-void lbnFromMont_64(BNWORD64 *n, BNWORD64 *mod, unsigned len);
-#endif
-
-#ifndef lbnExpMod_64
-int lbnExpMod_64(BNWORD64 *result, BNWORD64 const *n, unsigned nlen,
-	BNWORD64 const *exp, unsigned elen, BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnDoubleExpMod_64
-int lbnDoubleExpMod_64(BNWORD64 *result,
-	BNWORD64 const *n1, unsigned n1len, BNWORD64 const *e1, unsigned e1len,
-	BNWORD64 const *n2, unsigned n2len, BNWORD64 const *e2, unsigned e2len,
-	BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnTwoExpMod_64
-int lbnTwoExpMod_64(BNWORD64 *n, BNWORD64 const *exp, unsigned elen,
-	BNWORD64 *mod, unsigned mlen);
-#endif
-#ifndef lbnGcd_64
-int lbnGcd_64(BNWORD64 *a, unsigned alen, BNWORD64 *b, unsigned blen,
-	unsigned *rlen);
-#endif
-#ifndef lbnInv_64
-int lbnInv_64(BNWORD64 *a, unsigned alen, BNWORD64 const *mod, unsigned mlen);
-#endif
-
-int lbnBasePrecompBegin_64(BNWORD64 **array, unsigned n, unsigned bits,
-	BNWORD64 const *g, unsigned glen, BNWORD64 *mod, unsigned mlen);
-int lbnBasePrecompExp_64(BNWORD64 *result, BNWORD64 const * const *array,
-       unsigned bits, BNWORD64 const *exp, unsigned elen,
-       BNWORD64 const *mod, unsigned mlen);
-int lbnDoubleBasePrecompExp_64(BNWORD64 *result, unsigned bits,
-       BNWORD64 const * const *array1, BNWORD64 const *exp1, unsigned elen1,
-       BNWORD64 const * const *array2, BNWORD64 const *exp2,
-       unsigned elen2, BNWORD64 const *mod, unsigned mlen);
-
-#endif /* LBN64_H */
diff --git a/jni/libzrtp/sources/bnlib/lbnmem.c b/jni/libzrtp/sources/bnlib/lbnmem.c
deleted file mode 100644
index 56d2002..0000000
--- a/jni/libzrtp/sources/bnlib/lbnmem.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * lbnmem.c - low-level bignum memory handling.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * Note that in all cases, the pointers passed around
- * are pointers to the *least* significant end of the word.
- * On big-endian machines, these are pointers to the *end*
- * of the allocated range.
- *
- * BNSECURE is a simple level of security; for more security
- * change these function to use locked unswappable memory.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_STDLIB_H
-#define NO_STDLIB_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_STDLIB_H
-#include <stdlib.h>	/* For malloc() & co. */
-#else
-void *malloc();
-void *realloc();
-void free();
-#endif
-
-#if !NO_STRING_H
-#include <string.h>	/* For memset */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#ifndef DBMALLOC
-#define DBMALLOC 0
-#endif
-#if DBMALLOC
-/* Development debugging */
-#include "../dbmalloc/malloc.h"
-#endif
-
-#include "lbn.h"
-#include "lbnmem.h"
-
-#include "kludge.h"
-
-#ifndef lbnMemWipe
-void
-lbnMemWipe(void *ptr, unsigned bytes)
-{
-	memset(ptr, 0, bytes);
-}
-#define lbnMemWipe(ptr, bytes) memset(ptr, 0, bytes)
-#endif
-
-#ifndef lbnMemAlloc
-void *
-lbnMemAlloc(unsigned bytes)
-{
-	return malloc(bytes);
-}
-#define lbnMemAlloc(bytes) malloc(bytes)
-#endif
-
-#ifndef lbnMemFree
-void
-lbnMemFree(void *ptr, unsigned bytes)
-{
-	lbnMemWipe(ptr, bytes);
-	free(ptr);
-}
-#endif
-
-#ifndef lbnRealloc
-#if defined(lbnMemRealloc) || !BNSECURE
-void *
-lbnRealloc(void *ptr, unsigned oldbytes, unsigned newbytes)
-{
-	if (ptr) {
-		BIG(ptr = (char *)ptr - oldbytes;)
-		if (newbytes < oldbytes)
-			memmove(ptr, (char *)ptr + oldbytes-newbytes, oldbytes);
-	}
-#ifdef lbnMemRealloc
-	ptr = lbnMemRealloc(ptr, oldbytes, newbytes);
-#else
-	ptr = realloc(ptr, newbytes);
-#endif
-	if (ptr) {
-		if (newbytes > oldbytes)
-			memmove((char *)ptr + newbytes-oldbytes, ptr, oldbytes);
-		BIG(ptr = (char *)ptr + newbytes;)
-	}
-
-	return ptr;
-}
-
-#else /* BNSECURE */
-
-void *
-lbnRealloc(void *oldptr, unsigned oldbytes, unsigned newbytes)
-{
-	void *newptr = lbnMemAlloc(newbytes);
-
-	if (!newptr)
-		return newptr;
-	if (!oldptr)
-		return BIGLITTLE((char *)newptr+newbytes, newptr);
-
-	/*
-	 * The following copies are a bit non-obvious in the big-endian case
-	 * because one of the pointers points to the *end* of allocated memory.
-	 */
-	if (newbytes > oldbytes) {	/* Copy all of old into part of new */
-		BIG(newptr = (char *)newptr + newbytes;)
-		BIG(oldptr = (char *)oldptr - oldbytes;)
-		memcpy(BIGLITTLE((char *)newptr-oldbytes, newptr), oldptr,
-		       oldbytes);
-	} else {	/* Copy part of old into all of new */
-		memcpy(newptr, BIGLITTLE((char *)oldptr-newbytes, oldptr),
-		       newbytes);
-		BIG(newptr = (char *)newptr + newbytes;)
-		BIG(oldptr = (char *)oldptr - oldbytes;)
-	}
-
-	lbnMemFree(oldptr, oldbytes);
-
-	return newptr;
-}
-#endif /* BNSECURE */
-#endif /* !lbnRealloc */
diff --git a/jni/libzrtp/sources/bnlib/lbnmem.h b/jni/libzrtp/sources/bnlib/lbnmem.h
deleted file mode 100644
index f77298b..0000000
--- a/jni/libzrtp/sources/bnlib/lbnmem.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Operations on the usual buffers of bytes
- */
-#ifndef BNSECURE
-#define BNSECURE 1
-#endif
-
-/*
- * These operations act on buffers of memory, just like malloc & free.
- * One exception: it is not legal to pass a NULL pointer to lbnMemFree.
- */
-
-#ifndef lbnMemAlloc
-void *lbnMemAlloc(unsigned bytes);
-#endif
-
-#ifndef lbnMemFree
-void lbnMemFree(void *ptr, unsigned bytes);
-#endif
-
-/* This wipes out a buffer of bytes if necessary needed. */
-
-#ifndef lbnMemWipe
-#if BNSECURE
-void lbnMemWipe(void *ptr, unsigned bytes);
-#else
-#define lbnMemWipe(ptr, bytes) (void)(ptr,bytes)
-#endif
-#endif /* !lbnMemWipe */
-
-/*
- * lbnRealloc is NOT like realloc(); it's endian-sensitive!
- * If lbnMemRealloc is #defined, lbnRealloc will be defined in terms of it.
- * It is legal to pass a NULL pointer to lbnRealloc, although oldbytes
- * will always be sero.
- */
-#ifndef lbnRealloc
-void *lbnRealloc(void *ptr, unsigned oldbytes, unsigned newbytes);
-#endif
-
-
-/*
- * These macros are the ones actually used most often in the math library.
- * They take and return pointers to the *end* of the given buffer, and
- * take sizes in terms of words, not bytes.
- *
- * Note that LBNALLOC takes the pointer as an argument instead of returning
- * the value.
- *
- * Note also that these macros are only useable if you have included
- * lbn.h (for the BIG and BIGLITTLE macros), which this file does NOT include.
- */
-
-#define LBNALLOC(p,type,words) BIGLITTLE( \
-	if ( ((p) = (type *)lbnMemAlloc((words)*sizeof*(p))) != 0) \
-		(p) += (words), \
-	(p) = (type *)lbnMemAlloc((words) * sizeof*(p)) \
-	)
-#define LBNFREE(p,words) lbnMemFree((p) BIG(-(words)), (words) * sizeof*(p))
-#define LBNREALLOC(p,old,new) \
-	lbnRealloc(p, (old) * sizeof*(p), (new) * sizeof*(p))
-#define LBNWIPE(p,words) lbnMemWipe((p) BIG(-(words)), (words) * sizeof*(p))
-
diff --git a/jni/libzrtp/sources/bnlib/legal.c b/jni/libzrtp/sources/bnlib/legal.c
deleted file mode 100644
index 343db14..0000000
--- a/jni/libzrtp/sources/bnlib/legal.c
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * bnlib - BigNum multiprecision integer math library.
- * Copyright (c) 1995, 2005 Colin Plumb.  All rights reserved.
- * For licensing information, please contact
- * Philip R. Zimmermann <prz@mit.edu>, http://philzimmermann.com
- *
- * This subroutine library is licensed to the general public under
- * the GNU GPL, version 2.  Any software that uses code under a GPL 
- * license is itself subject to the same GPL licensing terms.
- * 
- * For licensing bnlib under alternate terms, so that you can use it without 
- * your own product becoming infected with the obligations of the GPL, 
- * you should contact Philip Zimmermann, who has unlimited sublicensing 
- * rights under non-GPL terms.
- *
- * This module must be packaged together with the rest of the bnlib 
- * source code.  That's why it's in a .c file.
- *
- * Lawyers have requested that the following information be included:
- *
- * Warranties:
- *   This software is provided "as is," with no warranty expressed
- *   or implied.
- *
- * Export controls:
- *   This software may be subject to export controls by the US Commerce
- *   Department's Bureau of Industry and Security.
- *
- */
-
-/* Force inclusion of this copyright string.  It may be commented out only 
- * if necessary in order to squeeze bnlib into memory-starved environments. */
-#include "legal.h"
-volatile const char bnCopyright[] =
-	"\0bnlib Copyright (c) 1995, 2005 Colin Plumb.";
-
-
-/****************************************************************************
-
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    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.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along
-    with this program; if not, write to the Free Software Foundation, Inc.,
-    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
-
-****************************************************************************/
diff --git a/jni/libzrtp/sources/bnlib/legal.h b/jni/libzrtp/sources/bnlib/legal.h
deleted file mode 100644
index e28cd91..0000000
--- a/jni/libzrtp/sources/bnlib/legal.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * We want the copyright string to be accessable to the unix strings command 
- * in the final linked binary, and we don't want the linker to remove it if 
- * it's not referenced, so we do that by using the volatile qualifier.
- * 
- * ANSI C standard, section 3.5.3: "An object that has volatile-qualified
- * type may be modified in ways unknown to the implementation or have
- * other unknown side effects."  Yes, we can't expect a compiler to
- * understand law...
- */
-extern volatile const char bnCopyright[];
diff --git a/jni/libzrtp/sources/bnlib/prime.c b/jni/libzrtp/sources/bnlib/prime.c
deleted file mode 100644
index adf17d6..0000000
--- a/jni/libzrtp/sources/bnlib/prime.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/*
- * Prime generation using the bignum library and sieving.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#include <stdarg.h>	/* We just can't live without this... */
-
-#ifndef BNDEBUG
-#define BNDEBUG 1
-#endif
-#if BNDEBUG
-#include <stdio.h>
-#endif
-
-#include "bn.h"
-#include "lbnmem.h"
-#include "prime.h"
-#include "sieve.h"
-
-#include "kludge.h"
-
-/* Size of the shuffle table */
-#define SHUFFLE	256
-/* Size of the sieve area */
-#define SIEVE 32768u/16
-
-/* Confirmation tests.  The first one *must* be 2 */
-static unsigned const confirm[] = {2, 3, 5, 7, 11, 13, 17};
-#define CONFIRMTESTS (sizeof(confirm)/sizeof(*confirm))
-
-/*
- * Helper function that does the slow primality test.
- * bn is the input bignum; a and e are temporary buffers that are
- * allocated by the caller to save overhead.
- *
- * Returns 0 if prime, >0 if not prime, and -1 on error (out of memory).
- * If not prime, returns the number of modular exponentiations performed.
- * Calls the given progress function with a '*' for each primality test
- * that is passed.
- *
- * The testing consists of strong pseudoprimality tests, to the bases given
- * in the confirm[] array above.  (Also called Miller-Rabin, although that's
- * not technically correct if we're using fixed bases.)  Some people worry
- * that this might not be enough.  Number theorists may wish to generate
- * primality proofs, but for random inputs, this returns non-primes with
- * a probability which is quite negligible, which is good enough.
- *
- * It has been proved (see Carl Pomerance, "On the Distribution of
- * Pseudoprimes", Math. Comp. v.37 (1981) pp. 587-593) that the number of
- * pseudoprimes (composite numbers that pass a Fermat test to the base 2)
- * less than x is bounded by:
- * exp(ln(x)^(5/14)) <= P_2(x)	### CHECK THIS FORMULA - it looks wrong! ###
- * P_2(x) <= x * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))).
- * Thus, the local density of Pseudoprimes near x is at most
- * exp(-1/2 * ln(x) * ln(ln(ln(x))) / ln(ln(x))), and at least
- * exp(ln(x)^(5/14) - ln(x)).  Here are some values of this function
- * for various k-bit numbers x = 2^k:
- * Bits	Density <=	Bit equivalent	Density >=	Bit equivalent
- *  128	3.577869e-07	 21.414396	4.202213e-37	 120.840190
- *  192	4.175629e-10	 31.157288	4.936250e-56	 183.724558
- *  256 5.804314e-13	 40.647940	4.977813e-75	 246.829095
- *  384 1.578039e-18	 59.136573	3.938861e-113	 373.400096
- *  512 5.858255e-24	 77.175803	2.563353e-151	 500.253110
- *  768 1.489276e-34	112.370944	7.872825e-228	 754.422724
- * 1024 6.633188e-45	146.757062	1.882404e-304	1008.953565
- *
- * As you can see, there's quite a bit of slop between these estimates.
- * In fact, the density of pseudoprimes is conjectured to be closer to the
- * square of that upper bound.  E.g. the density of pseudoprimes of size
- * 256 is around 3 * 10^-27.  The density of primes is very high, from
- * 0.005636 at 256 bits to 0.001409 at 1024 bits, i.e.  more than 10^-3.
- *
- * For those people used to cryptographic levels of security where the
- * 56 bits of DES key space is too small because it's exhaustible with
- * custom hardware searching engines, note that you are not generating
- * 50,000,000 primes per second on each of 56,000 custom hardware chips
- * for several hours.  The chances that another Dinosaur Killer asteroid
- * will land today is about 10^-11 or 2^-36, so it would be better to
- * spend your time worrying about *that*.  Well, okay, there should be
- * some derating for the chance that astronomers haven't seen it yet,
- * but I think you get the idea.  For a good feel about the probability
- * of various events, I have heard that a good book is by E'mile Borel,
- * "Les Probabilite's et la vie".  (The 's are accents, not apostrophes.)
- *
- * For more on the subject, try "Finding Four Million Large Random Primes",
- * by Ronald Rivest, in Advancess in Cryptology: Proceedings of Crypto
- * '90.  He used a small-divisor test, then a Fermat test to the base 2,
- * and then 8 iterations of a Miller-Rabin test.  About 718 million random
- * 256-bit integers were generated, 43,741,404 passed the small divisor
- * test, 4,058,000 passed the Fermat test, and all 4,058,000 passed all
- * 8 iterations of the Miller-Rabin test, proving their primality beyond
- * most reasonable doubts.
- *
- * If the probability of getting a pseudoprime is some small p, then the
- * probability of not getting it in t trials is (1-p)^t.  Remember that,
- * for small p, (1-p)^(1/p) ~ 1/e, the base of natural logarithms.
- * (This is more commonly expressed as e = lim_{x\to\infty} (1+1/x)^x.)
- * Thus, (1-p)^t ~ e^(-p*t) = exp(-p*t).  So the odds of being able to
- * do this many tests without seeing a pseudoprime if you assume that
- * p = 10^-6 (one in a million) is one in 57.86.  If you assume that
- * p = 2*10^-6, it's one in 3347.6.  So it's implausible that the density
- * of pseudoprimes is much more than one millionth the density of primes.
- *
- * He also gives a theoretical argument that the chance of finding a
- * 256-bit non-prime which satisfies one Fermat test to the base 2 is
- * less than 10^-22.  The small divisor test improves this number, and
- * if the numbers are 512 bits (as needed for a 1024-bit key) the odds
- * of failure shrink to about 10^-44.  Thus, he concludes, for practical
- * purposes *one* Fermat test to the base 2 is sufficient.
- */
-static int
-primeTest(struct BigNum const *bn, struct BigNum *e, struct BigNum *a,
-	int (*f)(void *arg, int c), void *arg)
-{
-	unsigned i, j;
-	unsigned k, l;
-	int err;
-
-#if BNDEBUG	/* Debugging */
-	/*
-	 * This is debugging code to test the sieving stage.
-	 * If the sieving is wrong, it will let past numbers with
-	 * small divisors.  The prime test here will still work, and
-	 * weed them out, but you'll be doing a lot more slow tests,
-	 * and presumably excluding from consideration some other numbers
-	 * which might be prime.  This check just verifies that none
-	 * of the candidates have any small divisors.  If this
-	 * code is enabled and never triggers, you can feel quite
-	 * confident that the sieving is doing its job.
-	 */
-	i = bnLSWord(bn);
-	if (!(i % 2)) printf("bn div by 2!");
-	i = bnModQ(bn, 51051);	/* 51051 = 3 * 7 * 11 * 13 * 17 */
-	if (!(i % 3)) printf("bn div by 3!");
-	if (!(i % 7)) printf("bn div by 7!");
-	if (!(i % 11)) printf("bn div by 11!");
-	if (!(i % 13)) printf("bn div by 13!");
-	if (!(i % 17)) printf("bn div by 17!");
-	i = bnModQ(bn, 63365);	/* 63365 = 5 * 19 * 23 * 29 */
-	if (!(i % 5)) printf("bn div by 5!");
-	if (!(i % 19)) printf("bn div by 19!");
-	if (!(i % 23)) printf("bn div by 23!");
-	if (!(i % 29)) printf("bn div by 29!");
-	i = bnModQ(bn, 47027);	/* 47027 = 31 * 37 * 41 */
-	if (!(i % 31)) printf("bn div by 31!");
-	if (!(i % 37)) printf("bn div by 37!");
-	if (!(i % 41)) printf("bn div by 41!");
-#endif
-
-	/*
-	 * Now, check that bn is prime.  If it passes to the base 2,
-	 * it's prime beyond all reasonable doubt, and everything else
-	 * is just gravy, but it gives people warm fuzzies to do it.
-	 *
-	 * This starts with verifying Euler's criterion for a base of 2.
-	 * This is the fastest pseudoprimality test that I know of,
-	 * saving a modular squaring over a Fermat test, as well as
-	 * being stronger.  7/8 of the time, it's as strong as a strong
-	 * pseudoprimality test, too.  (The exception being when bn ==
-	 * 1 mod 8 and 2 is a quartic residue, i.e. bn is of the form
-	 * a^2 + (8*b)^2.)  The precise series of tricks used here is
-	 * not documented anywhere, so here's an explanation.
-	 * Euler's criterion states that if p is prime then a^((p-1)/2)
-	 * is congruent to Jacobi(a,p), modulo p.  Jacobi(a,p) is
-	 * a function which is +1 if a is a square modulo p, and -1 if
-	 * it is not.  For a = 2, this is particularly simple.  It's
-	 * +1 if p == +/-1 (mod 8), and -1 if m == +/-3 (mod 8).
-	 * If p == 3 mod 4, then all a strong test does is compute
-	 * 2^((p-1)/2). and see if it's +1 or -1.  (Euler's criterion
-	 * says *which* it should be.)  If p == 5 (mod 8), then
-	 * 2^((p-1)/2) is -1, so the initial step in a strong test,
-	 * looking at 2^((p-1)/4), is wasted - you're not going to
-	 * find a +/-1 before then if it *is* prime, and it shouldn't
-	 * have either of those values if it isn't.  So don't bother.
-	 *
-	 * The remaining case is p == 1 (mod 8).  In this case, we
-	 * expect 2^((p-1)/2) == 1 (mod p), so we expect that the
-	 * square root of this, 2^((p-1)/4), will be +/-1 (mod p).
-	 * Evaluating this saves us a modular squaring 1/4 of the time.
-	 * If it's -1, a strong pseudoprimality test would call p
-	 * prime as well.  Only if the result is +1, indicating that
-	 * 2 is not only a quadratic residue, but a quartic one as well,
-	 * does a strong pseudoprimality test verify more things than
-	 * this test does.  Good enough.
-	 *
-	 * We could back that down another step, looking at 2^((p-1)/8)
-	 * if there was a cheap way to determine if 2 were expected to
-	 * be a quartic residue or not.  Dirichlet proved that 2 is
-	 * a quartic residue iff p is of the form a^2 + (8*b^2).
-	 * All primes == 1 (mod 4) can be expressed as a^2 + (2*b)^2,
-	 * but I see no cheap way to evaluate this condition.
-	 */
-	if (bnCopy(e, bn) < 0)
-		return -1;
-	(void)bnSubQ(e, 1);
-	l = bnLSWord(e);
-
-	j = 1;	/* Where to start in prime array for strong prime tests */
-
-	if (l & 7) {
-		bnRShift(e, 1);
-		if (bnTwoExpMod(a, e, bn) < 0)
-			return -1;
-		if ((l & 7) == 6) {
-			/* bn == 7 mod 8, expect +1 */
-			if (bnBits(a) != 1)
-				return 1;	/* Not prime */
-			k = 1;
-		} else {
-			/* bn == 3 or 5 mod 8, expect -1 == bn-1 */
-			if (bnAddQ(a, 1) < 0)
-				return -1;
-			if (bnCmp(a, bn) != 0)
-				return 1;	/* Not prime */
-			k = 1;
-			if (l & 4) {
-				/* bn == 5 mod 8, make odd for strong tests */
-				bnRShift(e, 1);
-				k = 2;
-			}
-		}
-	} else {
-		/* bn == 1 mod 8, expect 2^((bn-1)/4) == +/-1 mod bn */
-		bnRShift(e, 2);
-		if (bnTwoExpMod(a, e, bn) < 0)
-			return -1;
-		if (bnBits(a) == 1) {
-			j = 0;	/* Re-do strong prime test to base 2 */
-		} else {
-			if (bnAddQ(a, 1) < 0)
-				return -1;
-			if (bnCmp(a, bn) != 0)
-				return 1;	/* Not prime */
-		}
-		k = 2 + bnMakeOdd(e);
-	}
-	/* It's prime!  Now go on to confirmation tests */
-
-	/*
-	 * Now, e = (bn-1)/2^k is odd.  k >= 1, and has a given value
-	 * with probability 2^-k, so its expected value is 2.
-	 * j = 1 in the usual case when the previous test was as good as
-	 * a strong prime test, but 1/8 of the time, j = 0 because
-	 * the strong prime test to the base 2 needs to be re-done.
-	 */
-	for (i = j; i < CONFIRMTESTS; i++) {
-		if (f && (err = f(arg, '*')) < 0)
-			return err;
-		(void)bnSetQ(a, confirm[i]);
-		if (bnExpMod(a, a, e, bn) < 0)
-			return -1;
-		if (bnBits(a) == 1)
-			continue;	/* Passed this test */
-
-		l = k;
-		for (;;) {
-			if (bnAddQ(a, 1) < 0)
-				return -1;
-			if (bnCmp(a, bn) == 0)	/* Was result bn-1? */
-				break;	/* Prime */
-			if (!--l)	/* Reached end, not -1? luck? */
-				return i+2-j;	/* Failed, not prime */
-			/* This portion is executed, on average, once. */
-			(void)bnSubQ(a, 1);	/* Put a back where it was. */
-			if (bnSquare(a, a) < 0 || bnMod(a, a, bn) < 0)
-				return -1;
-			if (bnBits(a) == 1)
-				return i+2-j;	/* Failed, not prime */
-		}
-		/* It worked (to the base confirm[i]) */
-	}
-	
-	/* Yes, we've decided that it's prime. */
-	if (f && (err = f(arg, '*')) < 0)
-		return err;
-	return 0;	/* Prime! */
-}
-
-/*
- * Add x*y to bn, which is usually (but not always) < 65536.
- * Do it in a simple linear manner.
- */
-static int
-bnAddMult(struct BigNum *bn, unsigned x, unsigned y)
-{
-	unsigned long z = (unsigned long)x * y;
-
-	while (z > 65535) {
-		if (bnAddQ(bn, 65535) < 0)
-			return -1;
-		z -= 65535;
-	}
-	return bnAddQ(bn, (unsigned)z);
-}
-
-static int
-bnSubMult(struct BigNum *bn, unsigned x, unsigned y)
-{
-	unsigned long z = (unsigned long)x * y;
-
-	while (z > 65535) {
-		if (bnSubQ(bn, 65535) < 0)
-			return -1;
-		z -= 65535;
-	}
-	return bnSubQ(bn, (unsigned)z);
-}
-
-/*
- * Modifies the bignum to return a nearby (slightly larger) number which
- * is a probable prime.  Returns >=0 on success or -1 on failure (out of
- * memory).  The return value is the number of unsuccessful modular
- * exponentiations performed.  This never gives up searching.
- *
- * All other arguments are optional.  They may be NULL.  They are:
- *
- * unsigned (*rand)(unsigned limit)
- * For better distributed numbers, supply a non-null pointer to a
- * function which returns a random x, 0 <= x < limit.  (It may make it
- * simpler to know that 0 < limit <= SHUFFLE, so you need at most a byte.)
- * The program generates a large window of sieve data and then does
- * pseudoprimality tests on the data.  If a rand function is supplied,
- * the candidates which survive sieving are shuffled with a window of
- * size SHUFFLE before testing to increase the uniformity of the prime
- * selection.  This isn't perfect, but it reduces the correlation between
- * the size of the prime-free gap before a prime and the probability
- * that that prime will be found by a sequential search.
- *
- * If rand is NULL, sequential search is used.  If you want sequential
- * search, note that the search begins with the given number; if you're
- * trying to generate consecutive primes, you must increment the previous
- * one by two before calling this again.
- *
- * int (*f)(void *arg, int c), void *arg
- * The function f argument, if non-NULL, is called with progress indicator
- * characters for printing.  A dot (.) is written every time a primality test
- * is failed, a star (*) every time one is passed, and a slash (/) in the
- * (very rare) case that the sieve was emptied without finding a prime
- * and is being refilled.  f is also passed the void *arg argument for
- * private context storage.  If f returns < 0, the test aborts and returns
- * that value immediately.  (bn is set to the last value tested, so you
- * can increment bn and continue.)
- *
- * The "exponent" argument, and following unsigned numbers, are exponents
- * for which an inverse is desired, modulo p.  For a d to exist such that
- * (x^e)^d == x (mod p), then d*e == 1 (mod p-1), so gcd(e,p-1) must be 1.
- * The prime returned is constrained to not be congruent to 1 modulo
- * any of the zero-terminated list of 16-bit numbers.  Note that this list
- * should contain all the small prime factors of e.  (You'll have to test
- * for large prime factors of e elsewhere, but the chances of needing to
- * generate another prime are low.)
- *
- * The list is terminated by a 0, and may be empty.
- */
-int
-primeGen(struct BigNum *bn, unsigned (*rand)(unsigned),
-         int (*f)(void *arg, int c), void *arg, unsigned exponent, ...)
-{
-	int retval;
-	int modexps = 0;
-	unsigned short offsets[SHUFFLE];
-	unsigned i, j;
-	unsigned p, q, prev;
-	struct BigNum a, e;
-#ifdef MSDOS
-	unsigned char *sieve;
-#else
-	unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
-	sieve = lbnMemAlloc(SIEVE);
-	if (!sieve)
-		return -1;
-#endif
-
-	bnBegin(&a);
-	bnBegin(&e);
-
-#if 0	/* Self-test (not used for production) */
-{
-	struct BigNum t;
-	static unsigned char const prime1[] = {5};
-	static unsigned char const prime2[] = {7};
-	static unsigned char const prime3[] = {11};
-	static unsigned char const prime4[] = {1, 1}; /* 257 */
-	static unsigned char const prime5[] = {0xFF, 0xF1}; /* 65521 */
-	static unsigned char const prime6[] = {1, 0, 1}; /* 65537 */
-	static unsigned char const prime7[] = {1, 0, 3}; /* 65539 */
-	/* A small prime: 1234567891 */
-	static unsigned char const prime8[] = {0x49, 0x96, 0x02, 0xD3};
-	/* A slightly larger prime: 12345678901234567891 */
-	static unsigned char const prime9[] = {
-		0xAB, 0x54, 0xA9, 0x8C, 0xEB, 0x1F, 0x0A, 0xD3 };
-	/*
-	 * No, 123456789012345678901234567891 isn't prime; it's just a
-	 * lucky, easy-to-remember conicidence.  (You have to go to
-	 * ...4567907 for a prime.)
-	 */
-	static struct {
-		unsigned char const *prime;
-		unsigned size;
-	} const primelist[] = {
-		{ prime1, sizeof(prime1) },
-		{ prime2, sizeof(prime2) },
-		{ prime3, sizeof(prime3) },
-		{ prime4, sizeof(prime4) },
-		{ prime5, sizeof(prime5) },
-		{ prime6, sizeof(prime6) },
-		{ prime7, sizeof(prime7) },
-		{ prime8, sizeof(prime8) },
-		{ prime9, sizeof(prime9) } };
-
-	bnBegin(&t);
-
-	for (i = 0; i < sizeof(primelist)/sizeof(primelist[0]); i++) {
-			bnInsertBytes(&t, primelist[i].prime, 0,
-				      primelist[i].size);
-			bnCopy(&e, &t);
-			(void)bnSubQ(&e, 1);
-			bnTwoExpMod(&a, &e, &t);
-			p = bnBits(&a);
-			if (p != 1) {
-				printf(
-			"Bug: Fermat(2) %u-bit output (1 expected)\n", p);
-				fputs("Prime = 0x", stdout);
-				for (j = 0; j < primelist[i].size; j++)
-					printf("%02X", primelist[i].prime[j]);
-				putchar('\n');
-			}
-			bnSetQ(&a, 3);
-			bnExpMod(&a, &a, &e, &t);
-			p = bnBits(&a);
-			if (p != 1) {
-				printf(
-			"Bug: Fermat(3) %u-bit output (1 expected)\n", p);
-				fputs("Prime = 0x", stdout);
-				for (j = 0; j < primelist[i].size; j++)
-					printf("%02X", primelist[i].prime[j]);
-				putchar('\n');
-			}
-		}
-
-	bnEnd(&t);
-}
-#endif
-
-	/* First, make sure that bn is odd. */
-	if ((bnLSWord(bn) & 1) == 0)
-		(void)bnAddQ(bn, 1);
-
-retry:
-	/* Then build a sieve starting at bn. */
-	sieveBuild(sieve, SIEVE, bn, 2, 0);
-
-	/* Do the extra exponent sieving */
-	if (exponent) {
-		va_list ap;
-		unsigned t = exponent;
-
-		va_start(ap, exponent);
-
-		do {
-			/* The exponent had better be odd! */
-			assert(t & 1);
-
-			i = bnModQ(bn, t);
-			/* Find 1-i */
-			if (i == 0)
-				i = 1;
-			else if (--i)
-				i = t - i;
-
-			/* Divide by 2, modulo the exponent */
-			i = (i & 1) ? i/2 + t/2 + 1 : i/2;
-
-			/* Remove all following multiples from the sieve. */
-			sieveSingle(sieve, SIEVE, i, t);
-
-			/* Get the next exponent value */
-			t = va_arg(ap, unsigned);
-		} while (t);
-
-		va_end(ap);
-	}
-
-	/* Fill up the offsets array with the first SHUFFLE candidates */
-	i = p = 0;
-	/* Get first prime */
-	if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
-		offsets[i++] = p;
-		p = sieveSearch(sieve, SIEVE, p);
-	}
-	/*
-	 * Okay, from this point onwards, p is always the next entry
-	 * from the sieve, that has not been added to the shuffle table,
-	 * and is 0 iff the sieve has been exhausted.
-	 *
-	 * If we want to shuffle, then fill the shuffle table until the
-	 * sieve is exhausted or the table is full.
-	 */
-	if (rand && p) {
-		do {
-			offsets[i++] = p;
-			p = sieveSearch(sieve, SIEVE, p);
-		} while (p && i < SHUFFLE);
-	}
-
-	/* Choose a random candidate for experimentation */
-	prev = 0;
-	while (i) {
-		/* Pick a random entry from the shuffle table */
-		j = rand ? rand(i) : 0;
-		q = offsets[j];	/* The entry to use */
-
-		/* Replace the entry with some more data, if possible */
-		if (p) {
-			offsets[j] = p;
-			p = sieveSearch(sieve, SIEVE, p);
-		} else {
-			offsets[j] = offsets[--i];
-			offsets[i] = 0;
-		}
-
-		/* Adjust bn to have the right value */
-		if ((q > prev ? bnAddMult(bn, q-prev, 2)
-		              : bnSubMult(bn, prev-q, 2)) < 0)
-			goto failed;
-		prev = q;
-
-		/* Now do the Fermat tests */
-		retval = primeTest(bn, &e, &a, f, arg);
-		if (retval <= 0)
-			goto done;	/* Success or error */
-		modexps += retval;
-		if (f && (retval = f(arg, '.')) < 0)
-			goto done;
-	}
-
-	/* Ran out of sieve space - increase bn and keep trying. */
-	if (bnAddMult(bn, SIEVE*8-prev, 2) < 0)
-		goto failed;
-	if (f && (retval = f(arg, '/')) < 0)
-		goto done;
-	goto retry;
-
-failed:
-	retval = -1;
-done:
-	bnEnd(&e);
-	bnEnd(&a);
-	lbnMemWipe(offsets, sizeof(offsets));
-#ifdef MSDOS
-	lbnMemFree(sieve, SIEVE);
-#else
-	lbnMemWipe(sieve, sizeof(sieve));
-#endif
-
-	return retval < 0 ? retval : modexps + CONFIRMTESTS;
-}
-
-/*
- * Similar, but searches forward from the given starting value in steps of
- * "step" rather than 1.  The step size must be even, and bn must be odd.
- * Among other possibilities, this can be used to generate "strong"
- * primes, where p-1 has a large prime factor.
- */
-int
-primeGenStrong(struct BigNum *bn, struct BigNum const *step,
-	int (*f)(void *arg, int c), void *arg)
-{
-	int retval;
-	unsigned p, prev;
-	struct BigNum a, e;
-	int modexps = 0;
-#ifdef MSDOS
-	unsigned char *sieve;
-#else
-	unsigned char sieve[SIEVE];
-#endif
-
-#ifdef MSDOS
-	sieve = lbnMemAlloc(SIEVE);
-	if (!sieve)
-		return -1;
-#endif
-
-	/* Step must be even and bn must be odd */
-	assert((bnLSWord(step) & 1) == 0);
-	assert((bnLSWord(bn) & 1) == 1);
-
-	bnBegin(&a);
-	bnBegin(&e);
-
-	for (;;) {
-		if (sieveBuildBig(sieve, SIEVE, bn, step, 0) < 0)
-			goto failed;
-
-		p = prev = 0;
-		if (sieve[0] & 1 || (p = sieveSearch(sieve, SIEVE, p)) != 0) {
-			do {
-				/*
-				 * Adjust bn to have the right value,
-				 * adding (p-prev) * 2*step.
-				 */
-				assert(p >= prev);
-				/* Compute delta into a */
-				if (bnMulQ(&a, step, p-prev) < 0)
-					goto failed;
-				if (bnAdd(bn, &a) < 0)
-					goto failed;
-				prev = p;
-
-				retval = primeTest(bn, &e, &a, f, arg);
-				if (retval <= 0)
-					goto done;	/* Success! */
-				modexps += retval;
-				if (f && (retval = f(arg, '.')) < 0)
-					goto done;
-
-				/* And try again */
-				p = sieveSearch(sieve, SIEVE, p);
-			} while (p);
-		}
-
-		/* Ran out of sieve space - increase bn and keep trying. */
-#if SIEVE*8 == 65536
-		/* Corner case that will never actually happen */
-		if (!prev) {
-			if (bnAdd(bn, step) < 0)
-				goto failed;
-			p = 65535;
-		} else {
-			p = (unsigned)(SIEVE*8 - prev);
-		}
-#else
-		p = SIEVE*8 - prev;
-#endif
-		if (bnMulQ(&a, step, p) < 0 || bnAdd(bn, &a) < 0)
-			goto failed;
-		if (f && (retval = f(arg, '/')) < 0)
-			goto done;
-	} /* for (;;) */
-
-failed:
-	retval = -1;
-
-done:
-
-	bnEnd(&e);
-	bnEnd(&a);
-#ifdef MSDOS
-	lbnMemFree(sieve, SIEVE);
-#else
-	lbnMemWipe(sieve, sizeof(sieve));
-#endif
-	return retval < 0 ? retval : modexps + CONFIRMTESTS;
-}
diff --git a/jni/libzrtp/sources/bnlib/prime.h b/jni/libzrtp/sources/bnlib/prime.h
deleted file mode 100644
index faff722..0000000
--- a/jni/libzrtp/sources/bnlib/prime.h
+++ /dev/null
@@ -1,12 +0,0 @@
-struct BigNum;
-
-/* Generate a prime >= bn. leaving the result in bn. */
-int primeGen(struct BigNum *bn, unsigned (*randfunc)(unsigned),
-	int (*f)(void *arg, int c), void *arg, unsigned exponent, ...);
-
-/*
- * Generate a prime of the form bn + k*step.  Step must be even and
- * bn must be odd.
- */
-int primeGenStrong(struct BigNum *bn, struct BigNum const *step,
-	int (*f)(void *arg, int c), void *arg);
diff --git a/jni/libzrtp/sources/bnlib/sieve.c b/jni/libzrtp/sources/bnlib/sieve.c
deleted file mode 100644
index 7362ff5..0000000
--- a/jni/libzrtp/sources/bnlib/sieve.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * sieve.c - Trial division for prime finding.
- *
- * Copyright (c) 1995  Colin Plumb.  All rights reserved.
- * For licensing and other legal details, see the file legal.c.
- *
- * Finding primes:
- * - Sieve 1 to find the small primes for
- * - Sieve 2 to find the candidate large primes, then
- * - Pseudo-primality test.
- *
- * An important question is how much trial division by small primes
- * should we do?  The answer is a LOT.  Even a heavily optimized
- * Fermat test to the base 2 (the simplest pseudoprimality test)
- * is much more expensive than a division.
- *
- * For an prime of n k-bit words, a Fermat test to the base 2 requires n*k
- * modular squarings, each of which involves n*(n+1)/2 signle-word multiplies
- * in the squaring and n*(n+1) multiplies in the modular reduction, plus
- * some overhead to get into and out of Montgomery form.  This is a total
- * of 3/2 * k * n^2 * (n+1).  Equivalently, if n*k = b bits, it's
- * 3/2 * (b/k+1) * b^2 / k.
- *
- * A modulo operation requires n single-word divides.  Let's assume that
- * a divide is 4 times the cost of a multiply.  That's 4*n multiplies.
- * However, you only have to do the division once for your entire
- * search.  It can be amortized over 10-15 primes.  So it's
- * really more like n/3 multiplies.  This is b/3k.
- *
- * Now, let's suppose you have a candidate prime t.  Your options
- * are to a) do trial division by a prime p, then do a Fermat test,
- * or to do the Fermat test directly.  Doing the trial division
- * costs b/3k multiplies, but a certain fraction of the time (1/p), it
- * saves you 3/2 b^3 / k^2 multiplies.  Thus, it's worth it doing the
- * division as long as b/3k < 3/2 * (b/k+1) * b^2 / k / p.
- * I.e. p < 9/2 * (b/k + 1) * b = 9/2 * (b^2/k + b).
- * E.g. for k=16 and b=256, p < 9/2 * 17 * 256 = 19584.
- * Solving for k=16 and k=32 at a few interesting value of b:
- *
- * k=16, b=256: p <  19584	k=32, b=256: p <  10368
- * k=16, b=384: p <  43200	k=32, b=384; p <  22464
- * k=16, b=512: p <  76032	k=32, b=512: p <  39168
- * k=16, b=640: p < 118080	k=32, b=640: p <  60480
- *
- * H'm... before using the highly-optimized Fermat test, I got much larger
- * numbers (64K to 256K), and designed the sieve for that.  Maybe it needs
- * to be reduced.  It *is* true that the desirable sieve size increases
- * rapidly with increasing prime size, and it's the larger primes that are
- * worrisome in any case.  I'll leave it as is (64K) for now while I
- * think about it.
- *
- * A bit of tweaking the division (we can compute a reciprocal and do
- * multiplies instead, turning 4*n into 4 + 2*n) would increase all the
- * numbers by a factor of 2 or so.
- *
- *
- * Bit k in a sieve corresponds to the number a + k*b.
- * For a given a and b, the sieve's job is to find the values of
- * k for which a + k*b == 0 (mod p).  Multiplying by b^-1 and
- * isolating k, you get k == -a*b^-1 (mod p).  So the values of
- * k which should be worked on are k = (-a*b^-1 mod p) + i * p,
- * for i = 0, 1, 2,...
- *
- * Note how this is still easy to use with very large b, if you need it.
- * It just requires computing (b mod p) and then finding the multiplicative
- * inverse of that.
- *
- *
- * How large a space to search to ensure that one will hit a prime?
- * The average density is known, but the primes behave oddly, and sometimes
- * there are large gaps.  It is conjectured by shanks that the first gap
- * of size "delta" will occur at approximately exp(sqrt(delta)), so a delta
- * of 65536 is conjectured to be to contain a prime up to e^256.
- * Remembering the handy 2<->e conversion ratios:
- * ln(2) = 0.693147   log2(e) = 1.442695
- * This covers up to 369 bits.  Damn, not enough!  Still, it'll have to do.
- *
- * Cramer's conjecture (he proved it for "most" cases) is that in the limit,
- * as p goes to infinity, the largest gap after a prime p tends to (ln(p))^2.
- * So, for a 1024-bit p, the interval to the next prime is expected to be
- * about 709.78^2, or 503791.  We'd need to enlarge our space by a factor of
- * 8 to be sure.  It isn't worth the hassle.
- *
- * Note that a span of this size is expected to contain 92 primes even
- * in the vicinity of 2^1024 (it's 369 at 256 bits and 492 at 192 bits).
- * So the probability of failure is pretty low.
- */
-#ifndef HAVE_CONFIG_H
-#define HAVE_CONFIG_H 0
-#endif
-#if HAVE_CONFIG_H
-#include <bnconfig.h>
-#endif
-
-/*
- * Some compilers complain about #if FOO if FOO isn't defined,
- * so do the ANSI-mandated thing explicitly...
- */
-#ifndef NO_ASSERT_H
-#define NO_ASSERT_H 0
-#endif
-#ifndef NO_LIMITS_H
-#define NO_LIMITS_H 0
-#endif
-#ifndef NO_STRING_H
-#define NO_STRING_H 0
-#endif
-#ifndef HAVE_STRINGS_H
-#define HAVE_STRINGS_H 0
-#endif
-#ifndef NEED_MEMORY_H
-#define NEED_MEMORY_H 0
-#endif
-
-#if !NO_ASSERT_H
-#include <assert.h>
-#else
-#define assert(x) (void)0
-#endif
-
-#if !NO_LIMITS_H
-#include <limits.h>	/* For UINT_MAX */
-#endif			/* If not avail, default value of 0 is safe */
-
-#if !NO_STRING_H
-#include <string.h>	/* for memset() */
-#elif HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#if NEED_MEMORY_H
-#include <memory.h>
-#endif
-
-#include "bn.h"
-#include "sieve.h"
-#ifdef MSDOS
-#include "lbnmem.h"
-#endif
-
-#include "kludge.h"
-
-/*
- * Each array stores potential primes as 1 bits in little-endian bytes.
- * Bit k in an array represents a + k*b, for some parameters a and b
- * of the sieve.  Currently, b is hardcoded to 2.
- *
- * Various factors of 16 arise because these are all *byte* sizes, and
- * skipping even numbers, 16 numbers fit into a byte's worth of bitmap.
- */
-
-/*
- * The first number in the small prime sieve.  This could be raised to
- * 3 if you want to squeeze bytes out aggressively for a smaller SMALL
- * table, and doing so would let one more prime into the end of the array,
- * but there is no sense making it larger if you're generating small
- * primes up to the limit if 2^16, since it doesn't save any memory and
- * would require extra code to ignore 65537 in the last byte, which is
- * over the 16-bit limit.
- */
-#define SMALLSTART 1
-
-/*
- * Size of sieve used to find large primes, in bytes.  For compatibility
- * with 16-bit-int systems, the largest prime that can appear in it,
- * SMALL * 16 + SMALLSTART - 2, must be < 65536.  Since 65537 is a prime,
- * this is the absolute maximum table size.
- */
-#define SMALL (65536/16)
-
-/*
- * Compute the multiplicative inverse of x, modulo mod, using the extended
- * Euclidean algorithm.  The classical EEA returns two results, traditionally
- * named s and t, but only one (t) is needed or computed here.
- * It is unrolled twice to avoid some variable-swapping, and because negating
- * t every other round makes all the number positive and less than the
- * modulus, which makes fixed-length arithmetic easier.
- *
- * If gcd(x, mod) != 1, then this will return 0.
- */
-static unsigned
-sieveModInvert(unsigned x, unsigned mod)
-{
-	unsigned y;
-	unsigned t0, t1;
-	unsigned q;
-
-	if (x <= 1)
-		return x;	/* 0 and 1 are self-inverse */
-	/*
-	 * The first round is simplified based on the
-	 * initial conditions t0 = 1 and t1 = 0.
-	 */
-	t1 = mod / x;
-	y = mod % x;
-	if (y <= 1)
-		return y ? mod - t1 : 0;
-	t0 = 1;
-
-	do {
-		q = x / y;
-		x = x % y;
-		t0 += q * t1;
-		if (x <= 1)
-			return x ? t0 : 0;
-		q = y / x;
-		y = y % x;
-		t1 += q * t0;
-	} while (y > 1);
-	return y ? mod - t1 : 0;
-}
-
-
-/*
- * Perform a single sieving operation on an array.  Clear bits "start",
- * "start+step", "start+2*step", etc. from the array, up to the size
- * limit (in BYTES) "size".  All of the arguments must fit into 16 bits
- * for portability.
- *
- * This is the core of the sieving operation.  In addition to being
- * called from the sieving functions, it is useful to call directly if,
- * say, you want to exclude primes congruent to 1 mod 3, or whatever.
- * (Although in that case, it would be better to change the sieving to
- * use a step size of 6 and start == 5 (mod 6).)
- *
- * Originally, this was inlined in the code below (with various checks
- * turned off where they could be inferred from the environment), but it
- * turns out that all the sieving is so fast that it makes a negligible
- * speed difference and smaller, cleaner code was preferred.
- *
- * Rather than increment a bit index through the array and clear
- * the corresponding bit, this code takes advantage of the fact that
- * every eighth increment must use the same bit position in a byte.
- * I.e. start + k*step == start + (k+8)*step (mod 8).  Thus, a bitmask
- * can be computed only eight times and used for all multiples.  Thus, the
- * outer loop is over (k mod 8) while the inner loop is over (k div 8).
- *
- * The only further trickiness is that this code is designed to accept
- * start, step, and size up to 65535 on 16-bit machines.  On such a
- * machine, the computation "start+step" can overflow, so we need to
- * insert an extra check for that situation.
- */
-void
-sieveSingle(unsigned char *array, unsigned size, unsigned start, unsigned step)
-{
-	unsigned bit;
-	unsigned char mask;
-	unsigned i;
-
-#if UINT_MAX < 0x1ffff
-	/* Unsigned is small; add checks for wrap */
-	for (bit = 0; bit < 8; bit++) {
-		i = start/8;
-		if (i >= size)
-			break;
-		mask = ~(1 << (start & 7));
-		do {
-			array[i] &= mask;
-			i += step;
-		} while (i >= step && i < size);
-		start += step;
-		if (start < step)	/* Overflow test */
-			break;
-	}
-#else
-	/* Unsigned has the range - no overflow possible */
-	for (bit = 0; bit < 8; bit++) {
-		i = start/8;
-		if (i >= size)
-			break;
-		mask = ~(1 << (start & 7));
-		do {
-			array[i] &= mask;
-			i += step;
-		} while (i < size);
-		start += step;
-	}
-#endif
-}
-
-/*
- * Returns the index of the next bit set in the given array.  The search
- * begins after the specified bit, so if you care about bit 0, you need
- * to check it explicitly yourself.  This returns 0 if no bits are found.
- *
- * Note that the size is in bytes, and that it takes and returns BIT
- * positions.  If the array represents odd numbers only, as usual, the
- * returned values must be doubled to turn them into offsets from the
- * initial number.
- */
-unsigned
-sieveSearch(unsigned char const *array, unsigned size, unsigned start)
-{
-	unsigned i;	/* Loop index */
-	unsigned char t;	/* Temp */
-
-	if (!++start)
-		return 0;
-	i = start/8;
-	if (i >= size)
-		return 0;	/* Done! */
-
-	/* Deal with odd-bit beginnings => search the first byte */
-	if (start & 7) {
-		t = array[i++] >> (start & 7);
-		if (t) {
-			if (!(t & 15)) {
-				t >>= 4;
-				start += 4;
-			}
-			if (!(t & 3)) {
-				t >>= 2;
-				start += 2;
-			}
-			if (!(t & 1))
-				start += 1;
-			return start;
-		} else if (i == size) {
-			return 0;	/* Done */
-		}
-	}
-
-	/* Now the main search loop */
-
-	do {
-		if ((t = array[i]) != 0) {
-			start = 8*i;
-			if (!(t & 15)) {
-				t >>= 4;
-				start += 4;
-			}
-			if (!(t & 3)) {
-				t >>= 2;
-				start += 2;
-			}
-			if (!(t & 1))
-				start += 1;
-			return start;
-		}
-	} while (++i < size);
-
-	/* Failed */
-	return 0;
-}
-
-/*
- * Build a table of small primes for sieving larger primes with.  This
- * could be cached between calls to sieveBuild, but it's so fast that
- * it's really not worth it.  This code takes a few milliseconds to run.
- */
-static void
-sieveSmall(unsigned char *array, unsigned size)
-{
-	unsigned i;		/* Loop index */
-	unsigned p;		/* The current prime */
-
-	/* Initialize to all 1s */
-	memset(array, 0xFF, size);
-
-#if SMALLSTART == 1
-	/* Mark 1 as NOT prime */
-	array[0] = 0xfe;
-	i = 1;	/* Index of first prime */
-#else
-	i = 0;	/* Index of first prime */
-#endif
-
-	/*
-	 * Okay, now sieve via the primes up to 256, obtained from the
-	 * table itself.  We know the maximum possible table size is
-	 * 65536, and sieveSingle() can cope with out-of-range inputs
-	 * safely, and the time required is trivial, so it isn't adaptive
-	 * based on the array size.
-	 *
-	 * Convert each bit position into a prime, compute a starting
-	 * sieve position (the square of the prime), and remove multiples
-	 * from the table, using sieveSingle().  I used to have that
-	 * code in line here, but the speed difference was so small it
-	 * wasn't worth it.  If a compiler really wants to waste memory,
-	 * it can inline it.
-	 */
-	do {
-		p = 2 * i + SMALLSTART;
-		if (p > 256)
-			break;
-		/* Start at square of p */
-		sieveSingle(array, size, (p*p-SMALLSTART)/2, p);
-
-		/* And find the next prime */
-		i = sieveSearch(array, 16, i);
-	} while (i);
-}
-
-
-/*
- * This is the primary sieving function.  It fills in the array with
- * a sieve (multiples of small primes removed) beginning at bn and
- * proceeding in steps of "step".
- *
- * It generates a small array to get the primes to sieve by.  It's
- * generated on the fly - sieveSmall is fast enough to make that
- * perfectly acceptable.
- *
- * The caller should take the array, walk it with sieveSearch, and
- * apply a stronger primality test to the numbers that are returned.
- *
- * If the "dbl" flag non-zero (at least 1), this also sieves 2*bn+1, in
- * steps of 2*step.  If dbl is 2 or more, this also sieve 4*bn+3,
- * in steps of 4*step, and so on for arbitrarily high values of "dbl".
- * This is convenient for finding primes such that (p-1)/2 is also prime.
- * This is particularly efficient because sieveSingle is controlled by the
- * parameter s = -n/step (mod p).  (In fact, we find t = -1/step (mod p)
- * and multiply that by n (mod p).)  If you have -n/step (mod p), then
- * finding -(2*n+1)/(2*step) (mod p), which is -n/step - 1/(2*step) (mod p),
- * reduces to finding -1/(2*step) (mod p), or t/2 (mod p), and adding that
- * to s = -n/step (mod p).  Dividing by 2 modulo an odd p is easy -
- * if even, divide directly.  Otherwise, add p (which produces an even
- * sum), and divide by 2.  Very simple.  And this produces s' and t'
- * for step' = 2*step.  It can be repeated for step'' = 4*step and so on.
- *
- * Note that some of the math is complicated by the fact that 2*p might
- * not fit into an unsigned, so rather than if (odd(x)) x = (x+p)/2,
- * we do if (odd(x)) x = x/2 + p/2 + 1;
- *
- * TODO: Do the double-sieving by sieving the larger number, and then
- * just subtract one from the remainder to get the other parameter.
- * (bn-1)/2 is divisible by an odd p iff bn-1 is divisible, which is
- * true iff bn == 1 mod p.  This requires using a step size of 4.
- */
-int
-sieveBuild(unsigned char *array, unsigned size, struct BigNum const *bn,
-	unsigned step, unsigned dbl)
-{
-	unsigned i, j;	/* Loop index */
-	unsigned p;	/* Current small prime */
-	unsigned s;	/* Where to start operations in the big sieve */
-	unsigned t;	/* Step modulo p, the current prime */
-#ifdef MSDOS	/* Use dynamic allocation rather than on the stack */
-	unsigned char *small;
-#else
-	unsigned char small[SMALL];
-#endif
-
-	assert(array);
-
-#ifdef MSDOS
-	small = lbnMemAlloc(SMALL);	/* Which allocator?  Not secure. */
-	if (!small)
-		return -1;	/* Failed */
-#endif
-
-	/*
-	 * An odd step is a special case, since we must sieve by 2,
-	 * which isn't in the small prime array and has a few other
-	 * special properties.  These are:
-	 * - Since the numbers are stored in binary, we don't need to
-	 *   use bnModQ to find the remainder.
-	 * - If step is odd, then t = step % 2 is 1, which allows
-	 *   the elimination of a lot of math.  Inverting and negating
-	 *   t don't change it, and multiplying s by 1 is a no-op,
-	 *   so t isn't actually mentioned.
-	 * - Since this is the first sieving, instead of calling
-	 *   sieveSingle, we can just use memset to fill the array
-	 *   with 0x55 or 0xAA.  Since a 1 bit means possible prime
-	 *   (i.e. NOT divisible by 2), and the least significant bit
-	 *   is first, if bn % 2 == 0, we use 0xAA (bit 0 = bn is NOT
-	 *   prime), while if bn % 2 == 1, use 0x55.
-	 *   (If step is even, bn must be odd, so fill the array with 0xFF.)
-	 * - Any doublings need not be considered, since 2*bn+1 is odd, and
-	 *   2*step is even, so none of these numbers are divisible by 2.
-	 */
-	if (step & 1) {
-		s = bnLSWord(bn) & 1;
-		memset(array, 0xAA >> s, size);
-	} else {
-		/* Initialize the array to all 1's */
-		memset(array, 255, size);
-		assert(bnLSWord(bn) & 1);
-	}
-
-	/*
-	 * This could be cached between calls to sieveBuild, but
-	 * it's really not worth it; sieveSmall is *very* fast.
-	 * sieveSmall returns a sieve of odd primes.
-	 */
-	sieveSmall(small, SMALL);
-
-	/*
-	 * Okay, now sieve via the primes up to ssize*16+SMALLSTART-1,
-	 * obtained from the small table.
-	 */
-	i = (small[0] & 1) ? 0 : sieveSearch(small, SMALL, 0);
-	do {
-		p = 2 * i + SMALLSTART;
-
-		/*
-		 * Modulo is usually very expensive, but step is usually
-		 * small, so this conditional is worth it.
-		 */
-		t = (step < p) ? step : step % p;
-		if (!t) {
-			/*
-			 * Instead of assert failing, returning all zero
-			 * bits is the "correct" thing to do, but I think
-			 * that the caller should take care of that
-			 * themselves before starting.
-			 */
-			assert(bnModQ(bn, p) != 0);
-			continue;
-		}
-		/*
-		 * Get inverse of step mod p.  0 < t < p, and p is prime,
-		 * so it has an inverse and sieveModInvert can't return 0.
-		 */
-		t = sieveModInvert(t, p);
-		assert(t);
-		/* Negate t, so now t == -1/step (mod p) */
-		t = p - t;
-
-		/* Now get the bignum modulo the prime. */
-		s = bnModQ(bn, p);
-
-		/* Multiply by t, the negative inverse of step size */
-#if UINT_MAX/0xffff < 0xffff
-		s = (unsigned)(((unsigned long)s * t) % p);
-#else
-		s = (s * t) % p;
-#endif
-
-		/* s is now the starting bit position, so sieve */
-		sieveSingle(array, size, s, p);
-
-		/* Now do the double sieves as desired. */
-		for (j = 0; j < dbl; j++) {
-			/* Halve t modulo p */
-#if UINT_MAX < 0x1ffff
-			t = (t & 1) ? p/2 + t/2 + 1 : t/2;
-			/* Add t to s, modulo p with overflow checks. */
-			s += t;
-			if (s >= p || s < t)
-				s -= p;
-#else
-			if (t & 1)
-				t += p;
-			t /= 2;
-			/* Add t to s, modulo p */
-			s += t;
-			if (s >= p)
-				s -= p;
-#endif
-			sieveSingle(array, size, s, p);
-		}
-
-		/* And find the next prime */
-	} while ((i = sieveSearch(small, SMALL, i)) != 0);
-
-#ifdef MSDOS
-	lbnMemFree(small, SMALL);
-#endif
-	return 0;	/* Success */
-}
-
-/*
- * Similar to the above, but use "step" (which must be even) as a step
- * size rather than a fixed value of 2.  If "step" has any small divisors
- * other than 2, this will blow up.
- *
- * Returns -1 on out of memory (MSDOS only, actually), and -2
- * if step is found to be non-prime.
- */
-int
-sieveBuildBig(unsigned char *array, unsigned size, struct BigNum const *bn,
-	struct BigNum const *step, unsigned dbl)
-{
-	unsigned i, j;	/* Loop index */
-	unsigned p;	/* Current small prime */
-	unsigned s;	/* Where to start operations in the big sieve */
-	unsigned t;	/* step modulo p, the current prime */
-#ifdef MSDOS	/* Use dynamic allocation rather than on the stack */
-	unsigned char *small;
-#else
-	unsigned char small[SMALL];
-#endif
-
-	assert(array);
-
-#ifdef MSDOS
-	small = lbnMemAlloc(SMALL);	/* Which allocator?  Not secure. */
-	if (!small)
-		return -1;	/* Failed */
-#endif
-	/*
-	 * An odd step is a special case, since we must sieve by 2,
-	 * which isn't in the small prime array and has a few other
-	 * special properties.  These are:
-	 * - Since the numbers are stored in binary, we don't need to
-	 *   use bnModQ to find the remainder.
-	 * - If step is odd, then t = step % 2 is 1, which allows
-	 *   the elimination of a lot of math.  Inverting and negating
-	 *   t don't change it, and multiplying s by 1 is a no-op,
-	 *   so t isn't actually mentioned.
-	 * - Since this is the first sieving, instead of calling
-	 *   sieveSingle, we can just use memset to fill the array
-	 *   with 0x55 or 0xAA.  Since a 1 bit means possible prime
-	 *   (i.e. NOT divisible by 2), and the least significant bit
-	 *   is first, if bn % 2 == 0, we use 0xAA (bit 0 = bn is NOT
-	 *   prime), while if bn % 2 == 1, use 0x55.
-	 *   (If step is even, bn must be odd, so fill the array with 0xFF.)
-	 * - Any doublings need not be considered, since 2*bn+1 is odd, and
-	 *   2*step is even, so none of these numbers are divisible by 2.
-	 */
-	if (bnLSWord(step) & 1) {
-		s = bnLSWord(bn) & 1;
-		memset(array, 0xAA >> s, size);
-	} else {
-		/* Initialize the array to all 1's */
-		memset(array, 255, size);
-		assert(bnLSWord(bn) & 1);
-	}
-
-	/*
-	 * This could be cached between calls to sieveBuild, but
-	 * it's really not worth it; sieveSmall is *very* fast.
-	 * sieveSmall returns a sieve of the odd primes.
-	 */
-	sieveSmall(small, SMALL);
-
-	/*
-	 * Okay, now sieve via the primes up to ssize*16+SMALLSTART-1,
-	 * obtained from the small table.
-	 */
-	i = (small[0] & 1) ? 0 : sieveSearch(small, SMALL, 0);
-	do {
-		p = 2 * i + SMALLSTART;
-
-		t = bnModQ(step, p);
-		if (!t) {
-			assert(bnModQ(bn, p) != 0);
-			continue;
-		}
-		/* Get negative inverse of step */
-		t = sieveModInvert(bnModQ(step, p), p);
-		assert(t);
-		t = p-t;
-
-		/* Okay, we have a prime - get the remainder */
-		s = bnModQ(bn, p);
-
-		/* Now multiply s by the negative inverse of step (mod p) */
-#if UINT_MAX/0xffff < 0xffff
-		s = (unsigned)(((unsigned long)s * t) % p);
-#else
-		s = (s * t) % p;
-#endif
-		/* We now have the starting bit pos */
-		sieveSingle(array, size, s, p);
-
-		/* Now do the double sieves as desired. */
-		for (j = 0; j < dbl; j++) {
-			/* Halve t modulo p */
-#if UINT_MAX < 0x1ffff
-			t = (t & 1) ? p/2 + t/2 + 1 : t/2;
-			/* Add t to s, modulo p with overflow checks. */
-			s += t;
-			if (s >= p || s < t)
-				s -= p;
-#else
-			if (t & 1)
-				t += p;
-			t /= 2;
-			/* Add t to s, modulo p */
-			s += t;
-			if (s >= p)
-				s -= p;
-#endif
-			sieveSingle(array, size, s, p);
-		}
-
-		/* And find the next prime */
-	} while ((i = sieveSearch(small, SMALL, i)) != 0);
-
-#ifdef MSDOS
-	lbnMemFree(small, SMALL);
-#endif
-	return 0;	/* Success */
-}
diff --git a/jni/libzrtp/sources/bnlib/sieve.h b/jni/libzrtp/sources/bnlib/sieve.h
deleted file mode 100644
index 22ed6ce..0000000
--- a/jni/libzrtp/sources/bnlib/sieve.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * sieve.h - Trial division for prime finding.
- *
- * This is generally not intended for direct use by a user of the library;
- * the prime.c and dhprime.c functions. are more likely to be used.
- * However, a special application may need these.
- */
-struct BigNum;
-
-/* Remove multiples of a single number from the sieve */
-void
-sieveSingle(unsigned char *array, unsigned size, unsigned start, unsigned step);
-
-/* Build a sieve starting at the number and incrementing by "step". */
-int sieveBuild(unsigned char *array, unsigned size, struct BigNum const *bn,
-	unsigned step, unsigned dbl);
-
-/* Similar, but uses a >16-bit step size */
-int sieveBuildBig(unsigned char *array, unsigned size, struct BigNum const *bn,
-	struct BigNum const *step, unsigned dbl);
-
-/* Return the next bit set in the sieve (or 0 on failure) */
-unsigned sieveSearch(unsigned char const *array, unsigned size, unsigned start);
diff --git a/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake b/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake
index 506b224..43a3d11 100644
--- a/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake
+++ b/jni/libzrtp/sources/cmake/Modules/GeneratePackage.cmake
@@ -23,7 +23,7 @@
   # others
   "\\\\.#"
   "/#"
-  "/build*"
+  "/build/"
   "/autom4te\\\\.cache/"
   "/_build/"
   "/doc/html/"
@@ -37,9 +37,6 @@
   "\\\\.la$"
   "\\\\.sh$"
   "Makefile\\\\.in$"
-  "\\\\.directory$"
-  "\\\\._.DS_Store$"
-  "\\\\._buildmac$"
   )
 
   SET(CPACK_PACKAGE_VENDOR "Werner Dittmann")
@@ -55,20 +52,24 @@
 
 #  SPECFILE()
 
-  ADD_CUSTOM_TARGET(svncheck
-    COMMAND cd $(CMAKE_SOURCE_DIR) && LC_ALL=C git status | grep -q "nothing to commit .working directory clean.")
+  ADD_CUSTOM_TARGET( svncheck
+    COMMAND cd $(CMAKE_SOURCE_DIR) && LC_ALL=C git status | grep -q "nothing to commit .working directory clean."
+  )
 
-  SET(AUTOBUILD_COMMAND
-    COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/*.tar.bz2
+  SET( AUTOBUILD_COMMAND
+    COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/package/*.tar.bz2
     COMMAND ${CMAKE_MAKE_PROGRAM} package_source
+    COMMAND ${CMAKE_COMMAND} -E copy ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.bz2 ${CMAKE_BINARY_DIR}/package
+    COMMAND ${CMAKE_COMMAND} -E remove ${CPACK_SOURCE_PACKAGE_FILE_NAME}.tar.bz2
 #    COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_SOURCE_DIR}/package/${PACKAGE}.changes" "${CMAKE_BINARY_DIR}/package/${PACKAGE}.changes"
   )
 
-  ADD_CUSTOM_TARGET(srcpackage_local
-      ${AUTOBUILD_COMMAND})
+  ADD_CUSTOM_TARGET( srcpackage_local
+    ${AUTOBUILD_COMMAND}
+  )
 
-  ADD_CUSTOM_TARGET(srcpackage
-     COMMAND ${CMAKE_MAKE_PROGRAM} svncheck
-     ${AUTOBUILD_COMMAND})
-
-  ENDMACRO(GENERATE_PACKAGING)
+  ADD_CUSTOM_TARGET( srcpackage
+    COMMAND ${CMAKE_MAKE_PROGRAM} svncheck
+    ${AUTOBUILD_COMMAND}
+  )
+ENDMACRO(GENERATE_PACKAGING)
diff --git a/jni/libzrtp/sources/common/EventClass.cpp b/jni/libzrtp/sources/common/EventClass.cpp
deleted file mode 100644
index bfe117f9..0000000
--- a/jni/libzrtp/sources/common/EventClass.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-//
-// EventClass.cpp: implementation file
-//
-// Copyright (C) Walter E. Capers.  All rights reserved
-//
-// This source is free to use as you like.  If you make
-// any changes please keep me in the loop.  Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-//  To implement event signals as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07        
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date: 11/02/07
-// Name: Walter E. Capers
-// Description: removed unnessary code identified by On Freund from Code Project
-//
-//
-#include "Thread.h"
-
-#ifndef WINDOWS
-#include <sys/time.h>
-#endif
-
-#include <iostream>
-using namespace std;
-
-CEventClass::CEventClass(void)
-:m_bCreated(TRUE)
-{
-	memset(&m_owner,0,sizeof(ThreadId_t));
-#ifdef WINDOWS
-	m_event = CreateEvent(NULL,FALSE,FALSE,NULL);
-	if( !m_event )
-	{
-		m_bCreated = FALSE;
-	}
-#else
-	pthread_mutexattr_t mattr;
-	
-	pthread_mutexattr_init(&mattr);
-	pthread_mutex_init(&m_lock,&mattr);
-	pthread_cond_init(&m_ready,NULL);
-
-#endif	
-}
-
-CEventClass::~CEventClass(void)
-{
-#ifdef WINDOWS
-	CloseHandle(m_event);
-#else
-	pthread_cond_destroy(&m_ready);
-	pthread_mutex_destroy(&m_lock);
-#endif
-}
-
-
-/**
- *
- * Set
- * set an event to signaled
- *
- **/
-void
-CEventClass::Set()
-{
-#ifdef WINDOWS
-	SetEvent(m_event);
-#else
-	pthread_cond_signal(&m_ready);
-#endif
-}
-
-/**
- *
- * Wait
- * wait for an event -- wait for an event object
- * to be set to signaled.  must be paired with a
- * call to reset within the same thread.
- *
- **/
-BOOL
-CEventClass::Wait(DWORD tmout)
-{
-
-	try
-	{
-		ThreadId_t id = CThread::ThreadId();
-		if( CThread::ThreadIdsEqual(&id,&m_owner) )
-		{
-			throw "\n\tinvalid Wait call, Wait can not be called more than once"
-				"\n\twithout a corresponding call to Reset!\n";
-		}
-		ThreadId_t zero;
-		memset(&zero,0,sizeof(ThreadId_t));
-
-		if( memcmp(&zero,&m_owner,sizeof(ThreadId_t)) != 0 )
-		{
-			throw "\n\tanother thread is already waiting on this event!\n";
-		}
-
-		m_owner = CThread::ThreadId();
-#ifdef WINDOWS
-        tmout = tmout == 0 ? INFINITE : tmout;
-        DWORD rc = WaitForSingleObject(m_event, tmout);
-        e_timeout = FALSE;
-        if (rc ==  WAIT_OBJECT_0) {
-            return TRUE;
-        }
-        else if (rc == WAIT_TIMEOUT) {
-            e_timeout = TRUE;
-            return TRUE;
-        }
-        else
-            return FALSE;
-#else
-		pthread_mutex_lock(&m_lock);
-        e_timeout = FALSE;
-        if (tmout == 0) {
-            pthread_cond_wait(&m_ready,&m_lock);
-            return TRUE;
-        }
-        struct timespec ts;
-        timeval tv;
-        gettimeofday(&tv, NULL);
-        ts.tv_sec = tv.tv_sec;
-        ts.tv_nsec = tv.tv_usec * 1000l;
-        ts.tv_sec += tmout / 1000;
-        ts.tv_nsec += (tmout % 1000) * 1000000l;
-        while(ts.tv_nsec > 1000000000l) {
-            ++ts.tv_sec;
-            ts.tv_nsec -= 1000000000l;
-        }
-        int rc = pthread_cond_timedwait(&m_ready, &m_lock, &ts);
-        if (rc == ETIMEDOUT)
-            e_timeout = TRUE;
-        return TRUE;
-#endif
-	}
-	catch( char *psz )
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CEventClass::Wait",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CEventClass::Wait: " << psz;
-#endif
-
-	}
-	return TRUE;
-}
-
-
-/**
- *
- * Reset
- * reset an event flag to unsignaled
- * wait must be paired with reset within the same thread.
- *
- **/
-void
-CEventClass::Reset()
-{
-	try 
-	{
-		ThreadId_t id = CThread::ThreadId();
-		if( !CThread::ThreadIdsEqual(&id,&m_owner) )
-		{
-			throw "\n\tunbalanced call to Reset, Reset must be called from\n"
-				  "\n\tthe same Wait-Reset pair!\n";
-		}
-
-		memset(&m_owner,0,sizeof(ThreadId_t));
-
-#ifndef WINDOWS
-		pthread_mutex_unlock(&m_lock);
-#endif
-	}
-	catch( char *psz )
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CEventClass::Reset",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CEventClass::Reset: " << psz;
-#endif
-
-	}
-}
-
diff --git a/jni/libzrtp/sources/common/EventClass.h b/jni/libzrtp/sources/common/EventClass.h
deleted file mode 100644
index d9a15e7..0000000
--- a/jni/libzrtp/sources/common/EventClass.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// EventClass.h: header file
-//
-// Copyright (C) Walter E. Capers.  All rights reserved
-//
-// This source is free to use as you like.  If you make
-// any changes please keep me in the loop.  Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-//  To implement event signals as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07        
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date:
-// Name:
-// Description:
-//
-//
-#ifndef EVENT_CLASS
-#define EVENT_CLASS
-
-class CEventClass
-{
-private:
-	ThreadId_t m_owner;
-#ifdef WINDOWS
-	HANDLE m_event;
-#else
-	pthread_cond_t m_ready;
-	pthread_mutex_t m_lock;
-#endif
-public:
-    BOOL e_timeout;
-	BOOL m_bCreated;
-	void Set();
-	BOOL Wait(DWORD tmout =0);
-	void Reset();
-	CEventClass(void);
-	~CEventClass(void);
-};
-
-#endif
-
diff --git a/jni/libzrtp/sources/common/MutexClass.cpp b/jni/libzrtp/sources/common/MutexClass.cpp
deleted file mode 100644
index ebf8e4e..0000000
--- a/jni/libzrtp/sources/common/MutexClass.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-//
-// MutexClass.cpp: implementation file
-//
-// Copyright (C) Walter E. Capers.  All rights reserved
-//
-// This source is free to use as you like.  If you make
-// any changes please keep me in the loop.  Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-//  To implement mutexes as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07        
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date:
-// Name:
-// Description:
-//
-//
-#include "Thread.h"
-
-#include <iostream>
-using namespace std;
-
-CMutexClass::CMutexClass(void)
-:m_bCreated(TRUE)
-{
-#ifdef WINDOWS
-   m_mutex = CreateMutex(NULL,FALSE,NULL);
-   if( !m_mutex ) m_bCreated = FALSE;
-#else
-   pthread_mutexattr_t mattr;
-
-   pthread_mutexattr_init( &mattr );
-   pthread_mutex_init(&m_mutex,&mattr);
-
-#endif
-   memset(&m_owner,0,sizeof(ThreadId_t));
-
-}
-
-CMutexClass::~CMutexClass(void)
-{
-#ifdef WINDOWS
-	WaitForSingleObject(m_mutex,INFINITE);
-	CloseHandle(m_mutex);
-#else
-	pthread_mutex_lock(&m_mutex);
-	pthread_mutex_unlock(&m_mutex); 
-	pthread_mutex_destroy(&m_mutex);
-#endif
-}
-
-/**
- *
- * Lock
- * the same thread can not lock the same mutex
- * more than once
- *
- **/
-void
-CMutexClass::Lock()
-{
-	ThreadId_t id = CThread::ThreadId();
-	try {
-		if(CThread::ThreadIdsEqual(&m_owner,&id) )
-		    throw "\n\tthe same thread can not acquire a mutex twice!\n"; // the mutex is already locked by this thread
-#ifdef WINDOWS
-		WaitForSingleObject(m_mutex,INFINITE);
-#else
-		pthread_mutex_lock(&m_mutex);
-#endif
-		m_owner = CThread::ThreadId();
-	}
-	catch( char *psz )
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CMutexClass::Lock",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CMutexClass::Lock : " << psz;
-#endif
-
-
-	}
-
-}
-
-/**
- *
- * Unlock
- * releases a mutex.  only the thread that acquires
- * the mutex can release it.
- *
- **/
-void 
-CMutexClass::Unlock()
-{
-	ThreadId_t id = CThread::ThreadId();
-	try 
-	{
-	  if( ! CThread::ThreadIdsEqual(&id,&m_owner) )
-		throw "\n\tonly the thread that acquires a mutex can release it!"; 
-
-	   memset(&m_owner,0,sizeof(ThreadId_t));
-#ifdef WINDOWS
-	   ReleaseMutex(m_mutex);
-#else
-	   pthread_mutex_unlock(&m_mutex);
-#endif
-	}
-	catch ( char *psz)
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CMutexClass::Unlock",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CMutexClass::Unlock : " << psz;
-#endif
-
-	}
-}
-
diff --git a/jni/libzrtp/sources/common/MutexClass.h b/jni/libzrtp/sources/common/MutexClass.h
deleted file mode 100644
index a3600f4..0000000
--- a/jni/libzrtp/sources/common/MutexClass.h
+++ /dev/null
@@ -1,57 +0,0 @@
-//
-// MutexClass.h: header file
-//
-// Copyright (C) Walter E. Capers.  All rights reserved
-//
-// This source is free to use as you like.  If you make
-// any changes please keep me in the loop.  Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-//  To implement mutexes as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.25.07        
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date:
-// Name:
-// Description:
-//
-//
-
-#ifndef MUTEX_CLASS
-#define MUTEX_CLASS
-
-#ifndef WINDOWS
-#if defined(WIN32) || defined(WIN64)
-#define WINDOWS
-#endif
-#endif
-
-#ifndef WINDOWS
-#include <pthread.h>
-#endif
-#include <common/Thread.h>
-
-class CMutexClass
-{
-private:
-#ifdef WINDOWS
-	HANDLE m_mutex;
-#else
-	pthread_mutex_t m_mutex;
-#endif
-	ThreadId_t m_owner;
-public:
-	BOOL m_bCreated;
-	void Lock();
-	void Unlock();
-	CMutexClass(void);
-	~CMutexClass(void);
-};
-#endif
-
diff --git a/jni/libzrtp/sources/common/Thread.cpp b/jni/libzrtp/sources/common/Thread.cpp
deleted file mode 100644
index 1bec1f0..0000000
--- a/jni/libzrtp/sources/common/Thread.cpp
+++ /dev/null
@@ -1,1129 +0,0 @@
-//
-// Thread.cpp: implementation file
-//
-// Copyright (C) Walter E. Capers.  All rights reserved
-//
-// This source is free to use as you like.  If you make
-// any changes please keep me in the loop.  Email your changes
-// to walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-//  To implement threading as a C++ object
-//
-// NOTES:
-//  This object supports two types of thread models, event driven and
-//  interval driven.  Under the event driven model, a thread waits
-//  in a paused state until the member function Event is called.  When
-//  the Event function is called the thread wakes up and calls OnTask.
-//  Under the interval driven model, the thread wakes up every
-//  m_dwIdle milli-seconds and calls OnTask.
-//
-//  You can switch between the two models from within the same object.
-//
-// COMPILER NOTES:
-// On Unix you must use -lpthread a -lrt
-// On Windows you must specify threaded under C++ code generation
-//
-// REVISIONS
-// =======================================================
-// Date: 10.24.07        
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date: 10.24.07 11:49 am
-// Name: Walter E. Capers
-// Description: Added SetIdle function to allow the idle time to be altered
-//              independent of the SetThreadType member function.
-//              Added sleep interval to Stop function.
-//
-// Date: 10.25.07
-// Name: Walter E. Capers
-// Description: Added support for other non-windows platforms.
-//
-//              Added static functions: ThreadIdsEqual and ThreadId.
-//
-//              Added que for handling multiple events.
-//
-//              Created the CEventClass and CMutexClass classes to facilitate
-//              platform independence.
-//
-// Date: 10.26.07
-// Name: Walter E. Capers
-// Description: Made object production ready...
-//              Added more comments
-//
-//              Addressed various issues with threads on UNIX systems.
-//                -- there was a defect in the Sleep function
-//                -- there was a defect in the main thread function THKERNEL
-//                   , when transitioning between thread models the CEvent::Reset
-//                   function was not being called when it was necessary resulting
-//                   in a lock up.
-//              
-//				 Transition between thread types also failed on WINDOWS since the Event
-//               member function was being called from within SetThreadType.  This
-//               resulted in an Event usage error.  To correct the problem m_event.Set
-//               is called instead.  Also, eliminated unecessary logic.
-//
-//               Got rid of OnStart, OnStop, OnDestroy... Could not override with a derived
-//				 class, not sure why I will come back to in a later release.
-//
-//				 Changed default behavior of thread.  If OnTask is not redefined in the derived
-//               class the default version now expects a CTask object.  The Class for CTask 
-//               is defined in thread.h.  A class must be derived from CTask to use it in
-//               the default version of OnTask(LPVOID).
-//
-// Date: 11.01.07
-// Name: Walter E. Capers
-// Description: I introduced more logic and ASSERTIONS to insure the integrity of CThread objects.  
-//              Both the Homogeneous and Specialized thread types can be physically set using the 
-//              SetThreadType member function.  If the thread type is not set, the thread will
-//              determine its type based on calls to member functions; however, this does not
-//              apply to interval-based threads.  Interval-based threads must be implicitly
-//              identified using the SetThreadType member function.  The new integrity tests
-//              are implemented to insure usage consistency with a CThread object.   
-//
-//              New member functions AtCapacity and PercentCapacity were added to determine
-//              if a thread is truly busy.  AtCapacity will return TRUE under one of two 
-//              conditions: the thread is processing an event and its stack is full, the thread
-//              is not running.  These new functions allow thread objects to be placed in arrays
-//              and tasked based on their workloads.
-//
-//              The Event member function has been modified to verify that a thread is running
-//              before posting an event.  This resolved a problem on SunOS were threads did not
-//              start right away; there was a small delay of a few milliseconds.    
-//
-//              Error flags are automatically reset when certain member functions are called this
-//              isolates error occurrences to specific call sequences.
-//
-//
-// Date: 11.01.07
-// Name: Walter E. Capers
-// Description: In THKernel, changed how events are released.  Events are now released right after
-//              They are recieved.
-
-#include "Thread.h"
-#ifdef USE_BEGIN_THREAD
-#include <process.h>
-#endif
-
-
-
-#ifndef WINDOWS
-
-#include <unistd.h>
-#include <pthread.h>
-
-extern "C"
-{
- //int	usleep(useconds_t useconds);
-#ifdef NANO_SECOND_SLEEP
- int 	nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
-#endif
-}
-
-void Sleep( unsigned int milli )
-{
-#ifdef NANO_SECOND_SLEEP
-	struct timespec interval, remainder;
-	milli = milli * 1000000;
-	interval.tv_sec= 0;
-	interval.tv_nsec=milli;
-	nanosleep(&interval,&remainder);
-#else
-	usleep(milli*1000);
-#endif	
-}
-#endif
-
-#include <iostream>
-using namespace std;
-
-/**
- * 
- * _THKERNEL
- * thread callback function used by CreateThread
- *
- *
- **/
-#ifdef WINDOWS
-#ifdef USE_BEGIN_THREAD
-unsigned __stdcall
-#else
-DWORD WINAPI
-#endif
-#else
-LPVOID
-#endif
-_THKERNEL( LPVOID lpvData /* CThread Object */ 
-		  )
-{
-	CThread *pThread = (CThread *)lpvData;
-	ThreadType_t lastType;
-	/*
-	 *
-	 * initialization
-	 *
-	 */
-
-
-    pThread->m_mutex.Lock();
-		pThread->m_state = ThreadStateWaiting;
-		pThread->m_bRunning = TRUE;
-#ifndef WINDOWS
-		pThread->m_dwId = CThread::ThreadId();
-#endif
-	pThread->m_mutex.Unlock();
-	
-	while( TRUE )
-	{
-		lastType = pThread->m_type;
-
-		if( lastType == ThreadTypeHomogeneous ||
-			lastType == ThreadTypeSpecialized ||
-			lastType == ThreadTypeNotDefined )
-		{
-			if( ! pThread->m_event.Wait()  )  // wait for a message
-					break;
-			pThread->m_event.Reset(); // message recieved
-		}
-	
-		if( ! pThread->KernelProcess() ) 
-				break;
-
-
-		/*if( lastType == ThreadTypeHomogeneous ||
-			lastType == ThreadTypeSpecialized ||
-			lastType == ThreadTypeNotDefined )
-		{
-			pThread->m_event.Reset();
-		} */
-
-		if( pThread->m_type == ThreadTypeIntervalDriven )
-			Sleep(pThread->m_dwIdle);
-
-	}
-
-
-	pThread->m_mutex.Lock();
-		pThread->m_state = ThreadStateDown;
-		pThread->m_bRunning = FALSE;
-	pThread->m_mutex.Unlock();
-
-
-#ifdef WINDOWS
-	return 0;
-#else
-	return (LPVOID)0;
-#endif
-}
-
-/**
- *
- * FromSameThread
- * determines if the calling thread is the same
- * as the thread assoicated with the object
- *
- **/
-BOOL
-CThread::FromSameThread()
-{
-	ThreadId_t id = ThreadId();
-	if( ThreadIdsEqual(&id,&m_dwId) ) return TRUE;
-	return FALSE;
-}
-
-/**
- *
- * OnTask
- * called when a thread is tasked using the Event
- * member function
- *
- **/
-BOOL 
-CThread::OnTask( LPVOID lpvData /*data passed from thread*/ 
-					   )
-{
-    ASSERT(lpvData && m_type == ThreadTypeHomogeneous);
-
-	if( m_type != ThreadTypeHomogeneous )
-	{
-		cerr << "Warning CThread::OnTask:\n\tOnTask(LPVOID) called for a non-homogeneous thread!\n";
-		return FALSE;
-	}
-
-	((CTask *)lpvData)->SetTaskStatus(TaskStatusBeingProcessed);
-	BOOL bReturn = ((CTask *)lpvData)->Task();
-	((CTask *)lpvData)->SetTaskStatus(TaskStatusCompleted);
-
-	return bReturn; 
-} 
-
-
-
-/**
- *
- * OnTask
- * overloaded implementation of OnTask that
- * takes no arguments
- *
- **/
-BOOL
-CThread::OnTask()
-{
-	ASSERT(m_type == ThreadTypeIntervalDriven);
-	if( m_type != ThreadTypeIntervalDriven )
-	{
-		cerr << "Warning CThread::OnTask:\n\tOnTask() called for a non-event driven thread!\n";
-		return FALSE;
-	}
-
-	printf("\nthread is alive\n");
-
-	return TRUE;
-}
-
-/**
- *
- * CEvent
- * used to place tasks on the threads event queue
- * wakes up thread.
- *
- **/
-BOOL
-CThread::Event(CTask *pvTask /* data to be processed by thread */
-			   )
-{
-	m_mutex.Lock();
-
-	ASSERT(m_type == ThreadTypeHomogeneous ||
-	       m_type == ThreadTypeNotDefined );
-
-	try 
-	{
-		if( FromSameThread() )
-		{
-			throw "\n\tit is illegal for a thread to place an event on its own event stack!\n";
-		}
-
-
-		// make sure that the thread is running 
-		if( !m_bRunning && m_dwObjectCondition == NO_ERRORS )
-		{
-			m_mutex.Unlock();
-			PingThread(m_dwIdle*2); // wait two idle cycles for it to start
-			m_mutex.Lock();
-		}
-		if( !m_bRunning ) // if it is not running return FALSE;
-		{
-			m_mutex.Unlock();
-			return FALSE;
-		}
-
-
-		if( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )
-			m_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;
-		if( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH)
-			m_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;
-
-		if( m_type != ThreadTypeHomogeneous &&
-			m_type != ThreadTypeNotDefined    )
-		{
-			m_mutex.Unlock();
-			m_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;
-			m_dwObjectCondition |= EVENT_AND_TYPE_DONT_MATCH;
-			m_state = ThreadStateFault;
-			cerr << "Warning: invalid call to CEvent::Event(CTask *), thread type is not specialized\n";
-
-			return FALSE;
-		}
-
-		m_type = ThreadTypeHomogeneous;
-		m_mutex.Unlock();
-
-		pvTask->SetId(&m_dwId);
-		if( ! Push((LPVOID)pvTask) )
-			return FALSE;
-
-		pvTask->SetTaskStatus(TaskStatusWaitingOnQueue);
-		m_event.Set();
-
-	}
-	catch (char *psz)
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CThread::CEvent",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CThread::CEvent(CTask *pvTask):" << psz;
-#endif
-
-	}
-	return TRUE;
-}
-
-/**
- *
- * Event
- * used to place tasks on the threads event queue
- * wakes up thread.
- *
- **/
-BOOL
-CThread::Event(LPVOID lpvData /* data to be processed by thread */
-			   )
-{
-
-	m_mutex.Lock();
-	ASSERT( m_type == ThreadTypeSpecialized ||
-		    m_type == ThreadTypeNotDefined );
-	try 
-	{
-		if( FromSameThread() )
-		{
-			throw "\n\tit is illegal for a thread to place an event on its own event stack!\n";
-		}
-	}
-	catch (char *psz)
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CThread::CEvent",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CThread::CEvent(LPVOID lpvData):" << psz;
-#endif
-
-	}
-
-	// make sure that the thread is running 
-	if( !m_bRunning && m_dwObjectCondition == NO_ERRORS )
-	{
-		m_mutex.Unlock();
-		  PingThread(m_dwIdle*2); // wait two idle cycles for it to start
-		m_mutex.Lock();
-	}
-	if( !m_bRunning ) // if it is not running return FALSE;
-	{
-		m_mutex.Unlock();
-		return FALSE;
-	}
-
-	if( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )
-		m_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;
-	if( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH)
-		m_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;
-
-	if( m_type != ThreadTypeSpecialized && 
-		m_type != ThreadTypeNotDefined )
-	{
-		m_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;
-		m_dwObjectCondition |= EVENT_AND_TYPE_DONT_MATCH;
-		cerr << "Warning: invalid call to CEvent::Event(LPVOID), thread type is not specialized\n";
-		m_mutex.Unlock();
-		return FALSE;
-	}
-	m_type = ThreadTypeSpecialized;
-
-	m_mutex.Unlock();
-	if( ! Push(lpvData) )
-	{
-		return FALSE;
-	}
-
-	m_event.Set();
-
-	return TRUE;
-}
-
-
-/**
- *
- * SetPriority
- * sets a threads run priority, see SetThreadPriority
- * Note: only works for Windows family of operating systems
- *
- *
- **/
-void
-CThread::SetPriority(DWORD dwPriority)
-{
-
-#ifdef WINDOWS
-	SetThreadPriority(m_thread,dwPriority);
-#endif
-}
-
-	  
-/**
- *
- * KernelProcess
- * routes thread activity
- *
- **/
-BOOL
-CThread::KernelProcess()
-{
-
-	m_mutex.Lock();
-	m_state = ThreadStateBusy;
-	if( !m_bRunning )
-	{
-		m_state = ThreadStateShuttingDown;
-		m_mutex.Unlock();
-		return FALSE;
-	}
-	m_mutex.Unlock();
-
-	if( !Empty() )
-	{
-		while( !Empty() )
-		{
-			Pop();
-			if( !OnTask(m_lpvProcessor) )
-			{
-				m_mutex.Lock();
-				m_lpvProcessor = NULL;
-				m_state = ThreadStateShuttingDown;
-				m_mutex.Unlock();
-				return FALSE;
-			}
-		}
-		m_mutex.Lock();
-		m_lpvProcessor = NULL;
-		m_state = ThreadStateWaiting;
-	}
-	else {
-		if( !OnTask() )
-		{
-			m_mutex.Lock();
-			m_state = ThreadStateShuttingDown;
-			m_mutex.Unlock();
-			return FALSE;
-		}
-		m_mutex.Lock();
-		m_state = ThreadStateWaiting;
-	}
-
-	m_mutex.Unlock();
-
-	return TRUE;
-}
-
-
-/**
- * 
- * GetEventsPending
- * returns the total number of vents waiting
- * in the event que
- * 
- **/
-unsigned int
-CThread::GetEventsPending()
-{
-	unsigned int chEventsWaiting;
-
-	m_mutex.Lock();
-	  chEventsWaiting = m_queuePos;
-    m_mutex.Unlock();
-
-	return chEventsWaiting;
-}
-
-
-/**
- *
- * CThread
- * instanciates thread object and
- * starts thread.
- *
- **/
-CThread::CThread(void)
-:m_bRunning(FALSE)
-#ifdef WINDOWS
-,m_thread(NULL)
-#endif
-,m_dwId(0L)
-,m_state(ThreadStateDown)
-,m_dwIdle(100)
-,m_lppvQueue(NULL)
-,m_lpvProcessor(NULL)
-,m_chQueue(QUEUE_SIZE)
-,m_type(ThreadTypeNotDefined)
-,m_stackSize(DEFAULT_STACK_SIZE)
-,m_queuePos(0)
-,m_StopTimeout(30)
-{
-
-	m_dwObjectCondition = NO_ERRORS;
-
-	m_lppvQueue = new LPVOID [QUEUE_SIZE];
-
-	if( !m_lppvQueue ) 
-	{
-		m_dwObjectCondition |= MEMORY_FAULT;
-		m_state = ThreadStateFault;
-		return;
-	}
-
-	if( !m_mutex.m_bCreated )
-	{
-		perror("mutex creation failed");
-		m_dwObjectCondition |= MUTEX_CREATION;
-		m_state = ThreadStateFault;
-		return;
-	}
-
-
-	if( !m_event.m_bCreated )
-	{
-		perror("event creation failed");
-		m_dwObjectCondition |= EVENT_CREATION;
-		m_state = ThreadStateFault;
-		return;
-	}
-
-
-	Start();
-
-}
-
-
-/**
- *
- * PercentCapacity
- * returns a floating point value identifying
- * the current workload of the thread
- *
- **/
-float
-CThread::PercentCapacity()
-{
-	float fValue = 0;
-	m_mutex.Lock();
-		fValue = (float)m_queuePos/m_chQueue;
-	m_mutex.Unlock();
-	return fValue;
-}
-
-/**
- *
- * SetQueueSize
- * changes the threads queue size
- *
- **/
-BOOL
-CThread::SetQueueSize( unsigned int ch )
-{
-	LPVOID * newQueue = NULL;
-
-	m_mutex.Lock();
-	    ASSERT(ch > m_queuePos);
-
-	    if( ch <= m_queuePos )
-		{
-			cerr << "Warning CThread::SetQueueSize:\n\tthe new queue size is less than the number of tasks on a non-empty queue! Request ignored.\n";
-			m_mutex.Unlock();
-			return FALSE;
-		}
-
-		newQueue = new LPVOID [ch];
-		if(  !newQueue )
-		{
-			cerr << "Warning CThread::SetQueueSize:\n\ta low memory, could not reallocate queue!\n";
-			m_mutex.Unlock();
-			return FALSE;
-		}
-
-		for( unsigned int i=0;i<m_queuePos; i++ )
-		{
-			newQueue[i] = m_lppvQueue[i];
-		}
-
-		delete [] m_lppvQueue;
-
-		m_chQueue = ch;
-		m_lppvQueue = newQueue;
-
-	m_mutex.Unlock();
-
-	return TRUE;
-}
-
-
-
-/**
- *
- * Empty
- * returns a value of TRUE if there are no items on the threads que
- * otherwise a value of FALSE is returned.
- *
- **/
-BOOL
-CThread::Empty()
-{
-	m_mutex.Lock();
-	if( m_queuePos <= 0 )
-	{
-		m_mutex.Unlock();
-		return TRUE;
-	}
-	m_mutex.Unlock();
-	return FALSE;
-}
-
-
-
-/**
- *
- * Push
- * place a data object in the threads que
- *
- **/
-BOOL
-CThread::Push( LPVOID lpv )
-{
-	if( !lpv ) return TRUE;
-
-	m_mutex.Lock();
-
-	if( m_queuePos+1 >= m_chQueue ) {
-		m_dwObjectCondition |= STACK_OVERFLOW;
-		m_mutex.Unlock();
-		return FALSE;
-	}
-	if( m_dwObjectCondition & STACK_EMPTY    )
-		m_dwObjectCondition = m_dwObjectCondition ^ STACK_EMPTY;
-
-	if( m_dwObjectCondition & STACK_OVERFLOW ) 
-		m_dwObjectCondition = m_dwObjectCondition ^ STACK_OVERFLOW;
-
-	m_lppvQueue[m_queuePos++] = lpv;
-	if( m_queuePos+1 >= m_chQueue )
-		m_dwObjectCondition |= STACK_FULL;
-
-	m_mutex.Unlock();
-	return TRUE;
-}
-
-
-/**
- *
- * Pop
- * move an object from the input que to the processor
- *
- **/
-BOOL
-CThread::Pop()
-{
-
-	m_mutex.Lock();
-	if( m_queuePos-1 < 0 )
-	{
-		m_queuePos = 0;
-		m_dwObjectCondition |= STACK_EMPTY;
-		m_mutex.Unlock();
-		return FALSE;
-	}
-	if( m_dwObjectCondition & STACK_EMPTY )
-		m_dwObjectCondition = m_dwObjectCondition ^ STACK_EMPTY;
-	if( m_dwObjectCondition & STACK_OVERFLOW )
-		m_dwObjectCondition = m_dwObjectCondition ^ STACK_OVERFLOW;
-	if( m_dwObjectCondition & STACK_FULL )
-		m_dwObjectCondition = m_dwObjectCondition ^ STACK_FULL;
-
-	m_queuePos--;
-	m_lpvProcessor = m_lppvQueue[m_queuePos];
-	m_mutex.Unlock();
-	return TRUE;
-}
-
-
-/**
- *
- * SetThreadType
- * specifies the type of threading that is to be performed.
- *
- * ThreadTypeEventDriven (default): an event must be physically sent
- *									to the thread using the Event member
- *									function.
- *
- * ThreadTypeIntervalDriven       : an event occurs automatically every 
- *                                  dwIdle milli seconds.
- *
- **/
-void
-CThread::SetThreadType(ThreadType_t typ,
-              DWORD dwIdle)
-{
-
-	try 
-	{
-		if( FromSameThread() )
-		{
-			throw "\n\tit is illegal for a thread to change its own type!\n";
-		}
-
-
-		m_mutex.Lock();
-		m_dwIdle = dwIdle;
-
-
-		if( m_type == typ ) {
-			m_mutex.Unlock();
-			return;
-		}
-		if( m_dwObjectCondition & ILLEGAL_USE_OF_EVENT )
-			m_dwObjectCondition = m_dwObjectCondition ^ ILLEGAL_USE_OF_EVENT;
-		if( m_dwObjectCondition & EVENT_AND_TYPE_DONT_MATCH )
-			m_dwObjectCondition = m_dwObjectCondition ^ EVENT_AND_TYPE_DONT_MATCH;
-
-		m_type = typ;
-
-
-		m_mutex.Unlock();
-		m_event.Set();
-	}
-	catch (char *psz)
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CThread::SetThreadType",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CThread::SetThreadType(ThreadType_t typ):" << psz;
-#endif
-
-	}
-}
-
-
-/**
- *
- * Stop
- * stop thread 
- *
- **/
-BOOL
-CThread::Stop()
-{
-	try 
-	{
-		if( FromSameThread() )
-		{
-			throw "\n\tit is illegal for a thread to attempt to signal itself to stop!\n";
-		}
-
-		m_mutex.Lock();
-		m_bRunning = FALSE;
-		m_mutex.Unlock();
-		m_event.Set();
-
-		int ticks = (m_StopTimeout*1000)/100;
-
-		for( int i=0; i<ticks; i++ )
-		{
-			Sleep(100);
-
-			m_mutex.Lock();
-			if( m_state == ThreadStateDown )
-			{
-				m_mutex.Unlock();
-				return TRUE;
-			}
-			m_mutex.Unlock();
-
-		} 
-	}
-	catch (char *psz)
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CThread::Stop",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CThread::Stop():" << psz;
-#endif
-
-	}
-	return FALSE;
-}
-
-
-/**
- *
- * SetIdle
- * changes the threads idle interval
- *
- **/
-void
-CThread::SetIdle(DWORD dwIdle)
-{
-	m_mutex.Lock();
-		m_dwIdle = dwIdle;
-	m_mutex.Unlock();
-}
-
-/**
- *
- * Start
- * start thread
- *
- **/
-BOOL
-CThread::Start()
-{
-	try 
-	{
-		if( FromSameThread() )
-		{
-			throw "\n\tit is illegal for a thread to attempt to start itself!\n";
-		}
-
-
-		m_mutex.Lock();
-		if( m_bRunning ) 
-		{
-			m_mutex.Unlock();
-			return TRUE;
-		}
-
-		m_mutex.Unlock();
-
-
-		if( m_dwObjectCondition & THREAD_CREATION )
-			m_dwObjectCondition = m_dwObjectCondition ^ THREAD_CREATION;
-
-#ifdef WINDOWS
-		if( m_thread ) CloseHandle(m_thread);
-#ifdef USE_BEGIN_THREAD
-		m_thread = (HANDLE )_beginthreadex(NULL,(unsigned int)m_stackSize,_THKERNEL,(LPVOID)this,0,&m_dwId);
-#else
-		m_thread = CreateThread(NULL,m_stackSize ,_THKERNEL,(LPVOID)this,0,&m_dwId);
-#endif
-		if( !m_thread )
-		{
-			perror("thread creation failed");
-			m_dwObjectCondition |= THREAD_CREATION;
-			m_state = ThreadStateFault;
-			return FALSE;
-		}
-#else
-		pthread_attr_t attr;
-
-		pthread_attr_init(&attr);
-
-#ifdef VMS
-		if( m_stackSize == 0 )
-			pthread_attr_setstacksize(&attr,PTHREAD_STACK_MIN*10);
-#endif
-		if( m_stackSize != 0 )
-			pthread_attr_setstacksize(&attr,m_stackSize);
-
-		int error = pthread_create(&m_thread,&attr,_THKERNEL,(LPVOID)this);
-
-		if( error != 0 )
-		{
-			m_dwObjectCondition |= THREAD_CREATION;
-			m_state = ThreadStateFault;
-
-#if defined(HPUX) || defined(SUNOS) || defined(LINUX)
-			switch(error)/* show the thread error */
-			{
-
-			case EINVAL:
-				cerr << "error: attr in an invalid thread attributes object\n";
-				break;
-			case EAGAIN:
-				cerr << "error: the necessary resources to create a thread are not\n";
-				cerr << "available.\n";
-				break;
-			case EPERM:
-				cerr << "error: the caller does not have the privileges to create\n";
-				cerr << "the thread with the specified attr object.\n";
-				break;
-#if defined(HPUX)
-			case ENOSYS:
-
-				cerr << "error: pthread_create not implemented!\n";
-				if( __is_threadlib_linked()==0 )
-				{
-					cerr << "error: threaded library not being used, improper linkage \"-lpthread -lc\"!\n";
-				}
-				break;
-#endif
-			default:
-				cerr << "error: an unknown error was encountered attempting to create\n";
-				cerr << "the requested thread.\n";
-				break;
-			}
-#else
-			cerr << "error: could not create thread, pthread_create failed (" << error << ")!\n";
-#endif
-			return FALSE;	
-		}
-#endif
-	}
-	catch (char *psz)
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CThread::Start",MB_ICONHAND);
-#else
-		cerr << "Fatal exception CThread::Start():" << psz;
-#endif
-		exit(-1);
-	}
-	return TRUE;
-}
-
-/**
- *
- * AtCapacity
- * returns TRUE if the threads queue is full, and the thread
- * is busy processing an event or the thread is not running
- *
- **/
-BOOL
-CThread::AtCapacity()
-{
-	m_mutex.Lock();
-		if( ((m_dwObjectCondition & STACK_OVERFLOW ||
-			  m_dwObjectCondition & STACK_FULL ) &&
-			  m_state == ThreadStateBusy) || !m_bRunning)
-		{
-			m_mutex.Unlock();
-			return TRUE;
-		}
-	m_mutex.Unlock();
-	return FALSE;
-}
-
-/**
- *
- * ThreadState
- * return the current state of the thread
- *
- **/
-ThreadState_t 
-CThread::ThreadState()
-{
-	ThreadState_t currentState;
-	m_mutex.Lock();
-		currentState = m_state;
-	m_mutex.Unlock();
-	return currentState;
-}
-
-/**
- *
- * ~CThread
- * destructor.  Stop should be called prior to destruction to
- * allow for gracefull thread termination.
- *
- **/
-CThread::~CThread(void)
-{
-	if( m_bRunning ) // gracefull termination
-	{
-		try 
-		{
-			if( !Stop() )
-			{
-				throw "\n\tthread failed to stop in a timely manner!\n";
-			}
-		}
-		catch( char *psz )
-		{
-#ifdef WINDOWS
-		    MessageBoxA(NULL,&psz[2],"Fatal exception CThread::Stop",MB_ICONHAND);
-		    exit(-1);
-#else
-			cerr << "Fatal exception CThread::Stop: " << psz;
-#endif
-		}
-	}
-#ifdef WINDOWS
-	CloseHandle(m_thread);
-#endif
-
-	delete [] m_lppvQueue;
-}
-
-
-/**
- *
- * PingThread
- * used to determine if a thread is running
- *
- **/
-BOOL
-CThread::PingThread(DWORD dwTimeout /* timeout in milli-seconds */
-				 )
-{
-    DWORD dwTotal = 0;
-
-	while(TRUE)
-	{
-		if( dwTotal > dwTimeout && dwTimeout > 0 )
-			return FALSE;
-		m_mutex.Lock();
-			if( m_bRunning )
-			{
-				m_mutex.Unlock();
-				return TRUE;
-			}
-		dwTotal += m_dwIdle;
-		m_mutex.Unlock();
-		Sleep(m_dwIdle);
-	}
-
-	return FALSE;
-}
-
-/**
- *
- * WaitTillExit
- * blocks caller until thread exits
- *
- **/
-void
-CThread::WaitTillExit()
-{
-
-	/*
-	 *
-	 * prevent users from calling this function from within the same thread
-	 * of execution
-	 *
-	 */
-	try 
-	{
-		if( FromSameThread() )
-			throw "\n\tthis function can not be called from within the same thread!\n";
-
-
-
-
-		if( !m_bRunning ) return;
-
-
-#ifdef WINDOWS
-		WaitForSingleObject(m_thread,INFINITE);
-#else
-		LPVOID lpv;
-
-		pthread_join(m_thread,&lpv);
-#endif
-	}
-	catch( char *psz )
-	{
-#ifdef WINDOWS
-		MessageBoxA(NULL,&psz[2],"Fatal exception CThread::WaitTillExit",MB_ICONHAND);
-		exit(-1);
-#else
-		cerr << "Fatal exception CThread::WaitTillExit: " << psz;
-#endif
-
-	}
-}
-
-
-
-
diff --git a/jni/libzrtp/sources/common/Thread.h b/jni/libzrtp/sources/common/Thread.h
deleted file mode 100644
index ca77255..0000000
--- a/jni/libzrtp/sources/common/Thread.h
+++ /dev/null
@@ -1,315 +0,0 @@
-//
-// Thread.h: header file
-//
-// Copyright (C) Walter E. Capers.  All rights reserved
-//
-// This source is free to use as you like.  If you make
-// any changes please keep me in the loop.  Email them to
-// walt.capers@comcast.net.
-//
-// PURPOSE:
-//
-//  To implement Win32 threading as a C++ object
-//
-// REVISIONS
-// =======================================================
-// Date: 10.24.07        
-// Name: Walter E. Capers
-// Description: File creation
-//
-// Date: 10.24.07 11:49 am
-// Name: Walter E. Capers
-// Description: Added SetIdle function to allow the idle time to be altered
-//              independent of the SetThreadType member function.
-// Date: 10.31.07
-// Name: Walter E. Capers
-// Description: Added support for beginthreadex
-//              To use compile with -DUSE_BEGIN_THREAD
-//
-//
-
-#ifndef THREAD_CLASS
-#define THREAD_CLASS
-
-#ifndef WINDOWS
-#if defined(_WIN32) || defined(_WIN64)
-#define WINDOWS
-#endif
-#endif
-#ifdef __APPLE__
-#define VMS
-#endif
-
-#ifndef WINDOWS
-#include <stdio.h>
-#include <string.h>
-//#include <malloc.h>
-#include <memory.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <time.h>
-#include <errno.h>
-typedef unsigned char BOOL;
-#define TRUE 1
-#define FALSE 0
-typedef long DWORD;
-typedef void *LPVOID;
-#else
-#include "afx.h"
-/* #include <windows.h> */
-#include <stdio.h>
-#endif
-
-#if defined(AS400) || defined(OS400)
-typedef pthread_id_np_t ThreadId_t;
-#elif defined(VMS) || defined(__NetBSD__)
-typedef pthread_t ThreadId_t;
-#else
-#ifdef USE_BEGIN_THREAD
-typedef unsigned ThreadId_t;
-#else
-typedef DWORD ThreadId_t;
-#endif
-#endif
-
-#include <common/MutexClass.h>
-#include <common/EventClass.h>
-
-#define QUEUE_SIZE 100
-#define DEFAULT_STACK_SIZE 0
-#ifndef WINDOWS
-void Sleep( unsigned int mseconds);
-#endif
-
-#ifndef ASSERT
-#if defined(DEBUG) || defined(_DEBUG)
-#define ASSERT(test) if( !(test) ) { \
-	fprintf(stderr,"\nASSERT(%s) FAILS, %s line %d\n",#test,__FILE__, __LINE__); exit(0);}
-#else
-#define ASSERT(test)
-#endif
-#endif
-
-
-typedef enum {
-	ThreadStateBusy,               // thread is currently handling a task
-	ThreadStateWaiting,            // thread is waiting for something to do
-    ThreadStateDown,               // thread is not running
-    ThreadStateShuttingDown,       // thread is in the process of shutting down
-    ThreadStateFault               // an error has occured and the thread could not
-	                               // be launched
-} ThreadState_t;
-
-typedef enum {
-	ThreadTypeHomogeneous,
-	ThreadTypeSpecialized,
-    ThreadTypeIntervalDriven,
-    ThreadTypeNotDefined } ThreadType_t;
-
-
-typedef enum {
-	TaskStatusNotSubmitted,
-	TaskStatusWaitingOnQueue,
-	TaskStatusBeingProcessed,
-	TaskStatusCompleted } TaskStatus_t;
-
-class CTask
-{
-private:
-	TaskStatus_t m_state;
-	ThreadId_t m_dwThread;
-public:
-	CMutexClass m_mutex;
-
-	void SetTaskStatus(TaskStatus_t state) 
-	{
-		m_mutex.Lock();
-			m_state=state;
-		m_mutex.Unlock();
-	}
-
-	void SetId(ThreadId_t *pid)
-	{
-		memcpy(&m_dwThread,pid,sizeof(ThreadId_t));
-	}
-
-	/**
-	 *
-	 * Wait
-	 * waits for upto timeoutSeconds for a task
-	 * to complete
-	 *
-	 **/
-	BOOL Wait(int timeoutSeconds)
-	{
-        timeoutSeconds = timeoutSeconds * 1000;
-		if( Status() != TaskStatusCompleted &&
-			timeoutSeconds > 0 )
-		{
-			Sleep(100);
-			timeoutSeconds = timeoutSeconds - 100;
-		}
-		if( Status() == TaskStatusCompleted ) return TRUE;
-		return FALSE;
-	}
-
-	/**
-	 *
-	 * Status
-	 * returns current state of a task
-	 *
-	 **/
-	TaskStatus_t Status()
-	{
-		TaskStatus_t state ;
-
-		m_mutex.Lock();
-		  state = m_state;
-		m_mutex.Unlock();
-	    return state;
-	}
-
-	void Thread(ThreadId_t *pId)
-	{
-		memcpy(pId,&m_dwThread,sizeof(ThreadId_t));
-	}
-
-	CTask(){m_state=TaskStatusNotSubmitted; memset(&m_dwThread,0,sizeof(ThreadId_t)); }
-	~CTask(){}
-	virtual BOOL Task()=0;
-};
-
-
-class CThread 
-#ifdef WINDOWS
-	: public CObject // use CObject as a base class so object can be used in lists and
-	               // object arrays
-#endif
-{
-private:
-	CEventClass   m_event;         // event controller
-	int           m_StopTimeout;   // specifies a timeout value for stop
-	                               // if a thread fails to stop within m_StopTimeout
-	                               // seconds an exception is thrown
-
-	BOOL		  m_bRunning;      // set to TRUE if thread is running
-#ifdef WINDOWS
-	HANDLE		  m_thread;		   // thread handle
-#else
-	pthread_t     m_thread;        // thread handle
-#endif
-	ThreadId_t	  m_dwId;          // id of this thread
-	LPVOID        *m_lppvQueue;    // task que
-	unsigned int  m_chQueue;       // que depth
-	unsigned int  m_queuePos;      // current que possition
-	LPVOID        m_lpvProcessor;  // data which is currently being processed
-	ThreadState_t m_state;         // current state of thread see thread state data
-	                               // structure.
-	DWORD         m_dwIdle;        // used for Sleep periods
-	ThreadType_t  m_type;
-	DWORD		  m_stackSize;     // thread stack size
-#define NO_ERRORS			       0
-#define MUTEX_CREATION		       0x01
-#define EVENT_CREATION		       0x02
-#define THREAD_CREATION		       0x04
-#define UNKNOWN					   0x08
-#define ILLEGAL_USE_OF_EVENT       0x10
-#define MEMORY_FAULT               0x20
-#define EVENT_AND_TYPE_DONT_MATCH  0x40
-#define STACK_OVERFLOW             0x80
-#define STACK_EMPTY                0x100
-#define STACK_FULL                 0x200
-
-	DWORD         m_dwObjectCondition;
-	BOOL		  Push(LPVOID lpv);
-	BOOL		  Pop();
-	BOOL		  Empty();
-public:
-	/**
-	 *
-	 * user definable member functions
-	 *
-	 **/
-	CMutexClass	  m_mutex;         // mutex that protects threads internal data
-
-	virtual BOOL OnTask(LPVOID lpvData);     // called when an event occurs
-	virtual BOOL OnTask();                   // called when a time interval has elapsed
-
-	CThread(void);
-	~CThread(void);
-#ifdef WINDOWS
-#ifdef USE_BEGIN_THREAD
-	friend unsigned __stdcall _THKERNEL(LPVOID lpvData);
-#else
-	friend DWORD WINAPI _THKERNEL( LPVOID lpvData );
-#endif
-#else
-	friend LPVOID _THKERNEL(LPVOID lpvData);
-#endif
-	BOOL        FromSameThread();
-	float		PercentCapacity();
-	void        WaitTillExit();
-	BOOL		KernelProcess();
-	BOOL		Event(LPVOID lpvData=NULL);
-	BOOL        Event(CTask *pvTask);
-	void		SetOnStopTimeout(int seconds ) { m_StopTimeout = seconds; }
-    BOOL        SetQueueSize( unsigned int ch );
-	BOOL		Stop();
-	BOOL		Start();
-	void		GetId(ThreadId_t *pId) { memcpy(pId,&m_dwId,sizeof(ThreadId_t)); }      // returns thread id
-	ThreadState_t ThreadState();
-	BOOL		PingThread(DWORD dwTimeout=0);
-	BOOL        AtCapacity();
-#ifdef WINDOWS
-	void		SetPriority(DWORD dwPriority=THREAD_PRIORITY_NORMAL);
-#else
-	void		SetPriority(DWORD dwPriority=0);
-#endif
-	DWORD		GetErrorFlags() { return m_dwObjectCondition; } // returns state of object
-	void		SetThreadType(ThreadType_t typ=ThreadTypeNotDefined,DWORD dwIdle=100);
-	void		SetIdle(DWORD dwIdle=100);
-    unsigned int GetEventsPending();
-    static BOOL ThreadIdsEqual(ThreadId_t *p1,
-						       ThreadId_t *p2)
-	{
-#if defined(AS400)||defined(OS400)
-		return(( memcmp(p1,p2,sizeof(ThreadId_t))==0)?TRUE:FALSE);
-#elif defined(VMS) || defined(__NetBSD__)
-		return (( pthread_equal(*p1,*p2) )?TRUE:FALSE );
-#else
-		return ((*p1 == *p2)?TRUE:FALSE);
-#endif
-
-	}
-
-	static ThreadId_t ThreadId()
-	{
-		ThreadId_t thisThreadsId ;
-#if defined(AS400) || defined(OS400)
-		pthread_t thread;
-#endif
-
-#ifdef WINDOWS
-		thisThreadsId = (ThreadId_t)GetCurrentThreadId();
-#else
-
-#if defined(AS400) || defined(OS400)
-		thread = pthread_self();
-		pthread_getunique_np(&thread,&thisThreadsId);
-#elif defined(ALPHA) || defined(DEC) || defined(VMS)
-#ifdef VMS
-		thisThreadsId = pthread_self();
-#else
-		thisThreadsId = pthread_getsequence_np(pthread_self());
-#endif
-#else
-		thisThreadsId = pthread_self();
-#endif
-#endif
-		return thisThreadsId;
-	}
-
-
-};
-#endif
-
diff --git a/jni/libzrtp/sources/common/osSpecifics.c b/jni/libzrtp/sources/common/osSpecifics.c
deleted file mode 100644
index 3345363..0000000
--- a/jni/libzrtp/sources/common/osSpecifics.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
-  Copyright (C) 2012-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include <stdint.h>
-#include <common/osSpecifics.h>
-
-
-#if defined(_WIN32) || defined(_WIN64)
-
-#else
-
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-# include <WinSock2.h>
-# include <time.h>
-
-uint64_t  zrtpGetTickCount()
-{
-   // return GetTickCount64();  //works only on 64bit OS
-   unsigned long long ret;
-   FILETIME ft;
-   GetSystemTimeAsFileTime(&ft);
-   ret = ft.dwHighDateTime;
-   ret <<= 32;
-   ret |= ft.dwLowDateTime;
-
-   return ret / 10;             //return msec
-}
-#else
-# include <netinet/in.h>
-# include <sys/time.h>
-
-uint64_t zrtpGetTickCount()
-{
-   struct timeval tv;
-   gettimeofday(&tv, 0);
-
-   return ((uint64_t)tv.tv_sec) * (uint64_t)1000 + ((uint64_t)tv.tv_usec) / (uint64_t)1000;
-}
-
-#endif
-
-uint32_t zrtpNtohl (uint32_t net)
-{
-    return ntohl(net);
-}
-
-uint16_t zrtpNtohs (uint16_t net)
-{
-    return ntohs(net);
-}
-
-uint32_t zrtpHtonl (uint32_t host)
-{
-    return htonl(host);
-}
-uint16_t zrtpHtons (uint16_t host)
-{
-    return htons(host);
-}
-
diff --git a/jni/libzrtp/sources/common/osSpecifics.h b/jni/libzrtp/sources/common/osSpecifics.h
deleted file mode 100644
index 5030688..0000000
--- a/jni/libzrtp/sources/common/osSpecifics.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
-  Copyright (C) 2012-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _OSSPECIFICS_H_
-#define _OSSPECIFICS_H_
-
-/**
- * @file osSpecifics.h
- * @brief Some functions to adapt to OS and/or compiler specific handling
- * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
- * @{
- *
- * This modules contains some functions that are either specific for a particular
- * OS or use include files that are not common.
- *
- * This header file shall not #include system specific header files and shall also
- * not use specific #ifdef stuff. Refer to @c osSpecifics.c for the OS specific
- * #include, #ifdef and implementations.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef __EXPORT
-  #if (defined _WIN32 || defined __CYGWIN__) && defined(_DLL)
-    #define __EXPORT    __declspec(dllimport)
-    #define __LOCAL
-  #elif __GNUC__ >= 4
-    #define __EXPORT    __attribute__ ((visibility("default")))
-    #define __LOCAL     __attribute__ ((visibility("hidden")))
-  #else
-    #define __EXPORT
-    #define __LOCAL
-  #endif
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-# define snprintf _snprintf
-#endif
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-/**
- * Get surrent system time in milli-second.
- *
- * @return current time in ms.
- */
-extern uint64_t zrtpGetTickCount();
-
-/**
- * Convert a 32bit variable from network to host order.
- *
- * Replaces the macros found in @c inet.h or @c WinSock2.h. Use this function
- * to avoid different includes freamed with @c #idef in the sources. Including
- * @c WinSock2 will increase compile time and may lead to other subtle problems
- * because @c WinSock2 also includes @c windows.h.
- *
- * @param net 32bit variable in network byte order.
- *
- * @return 32bit variable in host byte order.
- */
-extern uint32_t zrtpNtohl (uint32_t net);
-
-/**
- * Convert a 16bit variable from network to host order.
- *
- * @param net 16bit variable in network byte order.
- *
- * @return 16bit variable in host byte order.
- *
- * @sa zrtpNtohl()
- */
-extern uint16_t zrtpNtohs (uint16_t net);
-
-/**
- * Convert a 32bit variable from host to network order.
- *
- * @param host 32bit variable in host byte order.
- *
- * @return 32bit variable in network byte order.
- *
- * @sa zrtpNtohl()
- */
-extern uint32_t zrtpHtonl (uint32_t host);
-
-/**
- * Convert a 16bit variable from host to network order.
- *
- * @param host 16bit variable in host byte order.
- *
- * @return 16bit variable in network byte order.
- *
- * @sa zrtpNtohl()
- */
-extern uint16_t zrtpHtons (uint16_t host);
-
-#if defined(__cplusplus)
-}
-#endif
-
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp
deleted file mode 100644
index c19fa82..0000000
--- a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- *  Copyright (C) 2006-2013 Werner Dittmann
- *
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Lesser General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  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.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <fcntl.h>
-
-#include <cryptcommon/ZrtpRandom.h>
-#include <cryptcommon/aescpp.h>
-#include <common/Thread.h>
-#include <zrtp/crypto/sha2.h>
-
-static sha512_ctx mainCtx;
-
-static CMutexClass lockRandom;
-
-static bool initialized = false;
-
-/*
- * Random bits are produced as follows.
- * First stir new entropy into the random state (zrtp->rand_ctx).
- * Then make a copy of the random context and finalize it.
- * Use the digest to seed an AES-256 context and, if space remains, to
- * initialize a counter.
- * Then encrypt the counter with the AES-256 context, incrementing it
- * per block, until we have produced the desired quantity of data.
- */
-/*----------------------------------------------------------------------------*/
-int ZrtpRandom::getRandomData(uint8_t* buffer, uint32_t length) {
-
-    AESencrypt aesCtx;
-    sha512_ctx randCtx2;
-    uint8_t    md[SHA512_DIGEST_SIZE];
-    uint8_t    ctr[AES_BLOCK_SIZE];
-    uint8_t    rdata[AES_BLOCK_SIZE];
-    uint32_t   generated = length;
-
-    /*
-     * Add entropy from system state
-     * We will include whatever happens to be in the buffer, it can't hurt
-     */
-    ZrtpRandom::addEntropy(buffer, length);
-
-    lockRandom.Lock();
-
-    /* Copy the mainCtx and finalize it into the md buffer */
-    memcpy(&randCtx2, &mainCtx, sizeof(sha512_ctx));
-    sha512_end(md, &randCtx2);
-
-    lockRandom.Unlock();
-
-    /* Key an AES context from this buffer */
-    aesCtx.key256(md);
-
-    /* Initialize counter, using excess from md if available */
-    memset (ctr, 0, sizeof(ctr));
-    if (SHA512_DIGEST_SIZE > (256/8)) {
-        uint32_t ctrbytes = SHA512_DIGEST_SIZE - (256/8);
-        if (ctrbytes > AES_BLOCK_SIZE)
-            ctrbytes = AES_BLOCK_SIZE;
-        memcpy(ctr + sizeof(ctr) - ctrbytes, md + (256/8), ctrbytes);
-    }
-
-    /* Encrypt counter, copy to destination buffer, increment counter */
-    while (length) {
-        uint8_t *ctrptr;
-        uint32_t copied;
-        aesCtx.encrypt(ctr, rdata);
-        copied = (sizeof(rdata) < length) ? sizeof(rdata) : length;
-        memcpy (buffer, rdata, copied);
-        buffer += copied;
-        length -= copied;
-
-        /* Increment counter */
-        ctrptr = ctr + sizeof(ctr) - 1;
-        while (ctrptr >= ctr) {
-            if ((*ctrptr-- += 1) != 0) {
-                break;
-            }
-        }
-    }
-    memset(&randCtx2, 0, sizeof(randCtx2));
-    memset(md, 0, sizeof(md));
-    memset(&aesCtx, 0, sizeof(aesCtx));
-    memset(ctr, 0, sizeof(ctr));
-    memset(rdata, 0, sizeof(rdata));
-
-    return generated;
-}
-
-
-int ZrtpRandom::addEntropy(const uint8_t *buffer, uint32_t length)
-{
-
-    uint8_t newSeed[64];
-    size_t len = getSystemSeed(newSeed, sizeof(newSeed));
-
-    lockRandom.Lock();
-    initialize();
-
-    if (buffer && length) {
-        sha512_hash(buffer, length, &mainCtx);
-    }
-    if (len > 0) {
-        sha512_hash(newSeed, len, &mainCtx);
-        length += len;
-    }
-    lockRandom.Unlock();
-    return length;
-}
-
-
-void ZrtpRandom::initialize() {
-    if (initialized)
-        return;
-
-    sha512_begin(&mainCtx);
-    initialized = true;
-}
-
-/*
- * This works for Linux and similar systems. For other systems add
- * other functions (using #ifdef conditional compile) to get some
- * random data that we can use as seed for the internal PRNG below.
- */
-
-size_t ZrtpRandom::getSystemSeed(uint8_t *seed, size_t length)
-{
-    size_t num = 0;
-
-#if !(defined(_WIN32) || defined(_WIN64))
-    int rnd = open("/dev/urandom", O_RDONLY);
-    if (rnd >= 0) {
-        num = read(rnd, seed, length);
-        close(rnd);
-    }
-    else
-        return num;
-#endif
-    return num;
-}
-
-int zrtp_AddEntropy(const uint8_t *buffer, uint32_t length) {
-    return ZrtpRandom::addEntropy(buffer, length);
-}
-
-int zrtp_getRandomData(uint8_t *buffer, uint32_t length) {
-    return ZrtpRandom::getRandomData(buffer, length);
-}
diff --git a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h b/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h
deleted file mode 100644
index d3eedf7..0000000
--- a/jni/libzrtp/sources/cryptcommon/ZrtpRandom.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZRTPRANDOM_H_
-#define _ZRTPRANDOM_H_
-
-/**
- * @file ZrtpCommon.h
- * @brief ZRTP standalone random number generator
- * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
- * @{
- */
-
-#include <string.h>
-#if !(defined(_WIN32) || defined(_WIN64))
-#include <unistd.h>
-#endif
-#include <stdint.h>
-#include <sys/types.h>
-
-#ifdef __cplusplus
-class ZrtpRandom {
-public:
-    /**
-     * @brief This method adds entropy to the PRNG.
-     *
-     * An application may seed some entropy data to the PRNG. If the @c buffer is
-     * @c NULL or the @c length is zero then the method adds at least some system
-     * entropy.
-     *
-     * @param buffer some entropy data to add
-     *
-     * @param length length of entropy data in bytes
-     *
-     * @return on success: number of entropy bytes added, on failure: -1. Number of
-     *         bytes added may be bigger then @c length because of added system
-     *         entropy.
-     */
-    static int addEntropy(const uint8_t *buffer, uint32_t length);
-
-    /**
-     * @brief Get some random data.
-     *
-     * @param buffer that will contain the random data
-     *
-     * @param length how many bytes of random data to generate
-     *
-     * @return the number of generated random data bytes
-     */
-    static int getRandomData(uint8_t *buffer, uint32_t length);
-
-private:
-    static void initialize();
-    static size_t getSystemSeed(uint8_t *seed, size_t length);
-
-};
-#endif
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-int zrtp_AddEntropy(const uint8_t *buffer, uint32_t length);
-
-int zrtp_getRandomData(uint8_t *buffer, uint32_t length);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ZRTPRANDOM */
\ No newline at end of file
diff --git a/jni/libzrtp/sources/cryptcommon/aes.h b/jni/libzrtp/sources/cryptcommon/aes.h
deleted file mode 100644
index 40927fb..0000000
--- a/jni/libzrtp/sources/cryptcommon/aes.h
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the definitions required to use AES in C. See aesopt.h
- for optimisation details.
-*/
-
-#ifndef _AES_H
-#define _AES_H
-
-#include <stdlib.h>
-
-/*  This include is used to find 8 & 32 bit unsigned integer types  */
-#include "brg_types.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define AES_128     /* if a fast 128 bit key scheduler is needed    */
-#define AES_192     /* if a fast 192 bit key scheduler is needed    */
-#define AES_256     /* if a fast 256 bit key scheduler is needed    */
-#define AES_VAR     /* if variable key size scheduler is needed     */
-#define AES_MODES   /* if support is needed for modes               */
-
-/* The following must also be set in assembler files if being used  */
-
-#define AES_ENCRYPT /* if support for encryption is needed          */
-#define AES_DECRYPT /* if support for decryption is needed          */
-#define AES_REV_DKS /* define to reverse decryption key schedule    */
-
-#define AES_BLOCK_SIZE  16  /* the AES block size in bytes          */
-#define N_COLS           4  /* the number of columns in the state   */
-
-/* The key schedule length is 11, 13 or 15 16-byte blocks for 128,  */
-/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes  */
-/* or 44, 52 or 60 32-bit words.                                    */
-
-#if defined( AES_VAR ) || defined( AES_256 )
-#define KS_LENGTH       60
-#elif defined( AES_192 )
-#define KS_LENGTH       52
-#else
-#define KS_LENGTH       44
-#endif
-
-#define AES_RETURN INT_RETURN
-
-/* the character array 'inf' in the following structures is used    */
-/* to hold AES context information. This AES code uses cx->inf.b[0] */
-/* to hold the number of rounds multiplied by 16. The other three   */
-/* elements can be used by code that implements additional modes    */
-
-typedef union
-{   uint_32t l;
-    uint_8t b[4];
-} aes_inf;
-
-typedef struct
-{   uint_32t ks[KS_LENGTH];
-    aes_inf inf;
-} aes_encrypt_ctx;
-
-typedef struct
-{   uint_32t ks[KS_LENGTH];
-    aes_inf inf;
-} aes_decrypt_ctx;
-
-/* This routine must be called before first use if non-static       */
-/* tables are being used                                            */
-
-AES_RETURN aes_init(void);
-
-/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
-/* those in the range 128 <= key_len <= 256 are given in bits       */
-
-#if defined( AES_ENCRYPT )
-
-#if defined( AES_128 ) || defined( AES_VAR)
-AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_192 ) || defined( AES_VAR)
-AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_256 ) || defined( AES_VAR)
-AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_VAR )
-AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
-#endif
-
-AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
-
-#endif
-
-#if defined( AES_DECRYPT )
-
-#if defined( AES_128 ) || defined( AES_VAR)
-AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_192 ) || defined( AES_VAR)
-AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_256 ) || defined( AES_VAR)
-AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
-#endif
-
-#if defined( AES_VAR )
-AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
-#endif
-
-AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
-
-#endif
-
-#if defined( AES_MODES )
-
-/* Multiple calls to the following subroutines for multiple block   */
-/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
-/* long messages incremantally provided that the context AND the iv */
-/* are preserved between all such calls.  For the ECB and CBC modes */
-/* each individual call within a series of incremental calls must   */
-/* process only full blocks (i.e. len must be a multiple of 16) but */
-/* the CFB, OFB and CTR mode calls can handle multiple incremental  */
-/* calls of any length. Each mode is reset when a new AES key is    */
-/* set but ECB and CBC operations can be reset without setting a    */
-/* new key by setting a new IV value.  To reset CFB, OFB and CTR    */
-/* without setting the key, aes_mode_reset() must be called and the */
-/* IV must be set.  NOTE: All these calls update the IV on exit so  */
-/* this has to be reset if a new operation with the same IV as the  */
-/* previous one is required (or decryption follows encryption with  */
-/* the same IV array).                                              */
-
-AES_RETURN aes_test_alignment_detection(unsigned int n);
-
-AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, const aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, const aes_decrypt_ctx cx[1]);
-
-AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
-
-AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
-
-AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
-
-#define aes_ofb_encrypt aes_ofb_crypt
-#define aes_ofb_decrypt aes_ofb_crypt
-
-AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
-
-typedef void cbuf_inc(unsigned char *cbuf);
-
-#define aes_ctr_encrypt aes_ctr_crypt
-#define aes_ctr_decrypt aes_ctr_crypt
-
-AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
-            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aes_modes.c b/jni/libzrtp/sources/cryptcommon/aes_modes.c
deleted file mode 100644
index 2ffa783..0000000
--- a/jni/libzrtp/sources/cryptcommon/aes_modes.c
+++ /dev/null
@@ -1,946 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- These subroutines implement multiple block AES modes for ECB, CBC, CFB,
- OFB and CTR encryption,  The code provides support for the VIA Advanced
- Cryptography Engine (ACE).
-
- NOTE: In the following subroutines, the AES contexts (ctx) must be
- 16 byte aligned if VIA ACE is being used
-*/
-
-#include <string.h>
-#include <assert.h>
-
-#include "aesopt.h"
-
-#if defined( AES_MODES )
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
-#pragma intrinsic(memcpy)
-#endif
-
-#define BFR_BLOCKS      8
-
-/* These values are used to detect long word alignment in order to */
-/* speed up some buffer operations. This facility may not work on  */
-/* some machines so this define can be commented out if necessary  */
-
-#define FAST_BUFFER_OPERATIONS
-
-#define lp32(x)         ((uint_32t*)(x))
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-#include "aes_via_ace.h"
-
-#pragma pack(16)
-
-aligned_array(unsigned long,    enc_gen_table, 12, 16) =    NEH_ENC_GEN_DATA;
-aligned_array(unsigned long,   enc_load_table, 12, 16) =   NEH_ENC_LOAD_DATA;
-aligned_array(unsigned long, enc_hybrid_table, 12, 16) = NEH_ENC_HYBRID_DATA;
-aligned_array(unsigned long,    dec_gen_table, 12, 16) =    NEH_DEC_GEN_DATA;
-aligned_array(unsigned long,   dec_load_table, 12, 16) =   NEH_DEC_LOAD_DATA;
-aligned_array(unsigned long, dec_hybrid_table, 12, 16) = NEH_DEC_HYBRID_DATA;
-
-/* NOTE: These control word macros must only be used after  */
-/* a key has been set up because they depend on key size    */
-/* See the VIA ACE documentation for key type information   */
-/* and aes_via_ace.h for non-default NEH_KEY_TYPE values    */
-
-#ifndef NEH_KEY_TYPE
-#  define NEH_KEY_TYPE NEH_HYBRID
-#endif
-
-#if NEH_KEY_TYPE == NEH_LOAD
-#define kd_adr(c)   ((uint_8t*)(c)->ks)
-#elif NEH_KEY_TYPE == NEH_GENERATE
-#define kd_adr(c)   ((uint_8t*)(c)->ks + (c)->inf.b[0])
-#elif NEH_KEY_TYPE == NEH_HYBRID
-#define kd_adr(c)   ((uint_8t*)(c)->ks + ((c)->inf.b[0] == 160 ? 160 : 0))
-#else
-#error no key type defined for VIA ACE 
-#endif
-
-#else
-
-#define aligned_array(type, name, no, stride) type name[no]
-#define aligned_auto(type, name, no, stride)  type name[no]
-
-#endif
-
-#if defined( _MSC_VER ) && _MSC_VER > 1200
-
-#define via_cwd(cwd, ty, dir, len) \
-    unsigned long* cwd = (dir##_##ty##_table + ((len - 128) >> 4))
-
-#else
-
-#define via_cwd(cwd, ty, dir, len)              \
-    aligned_auto(unsigned long, cwd, 4, 16);    \
-    cwd[1] = cwd[2] = cwd[3] = 0;               \
-    cwd[0] = neh_##dir##_##ty##_key(len)
-
-#endif
-
-/* test the code for detecting and setting pointer alignment */
-
-AES_RETURN aes_test_alignment_detection(unsigned int n)	/* 4 <= n <= 16 */
-{	uint_8t	p[16];
-    uint_32t i, count_eq = 0, count_neq = 0;
-
-    if(n < 4 || n > 16)
-        return EXIT_FAILURE;
-
-    for(i = 0; i < n; ++i)
-    {
-        uint_8t *qf = ALIGN_FLOOR(p + i, n),
-                *qh =  ALIGN_CEIL(p + i, n);
-        
-        if(qh == qf)
-            ++count_eq;
-        else if(qh == qf + n)
-            ++count_neq;
-        else
-            return EXIT_FAILURE;
-    }
-    return (count_eq != 1 || count_neq != n - 1 ? EXIT_FAILURE : EXIT_SUCCESS);
-}
-
-AES_RETURN aes_mode_reset(aes_encrypt_ctx ctx[1])
-{
-    ctx->inf.b[2] = 0;
-    return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, const aes_encrypt_ctx ctx[1])
-{   int nb = len >> 4;
-
-    if(len & (AES_BLOCK_SIZE - 1))
-        return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-    if(ctx->inf.b[1] == 0xff)
-    {   uint_8t *ksp = (uint_8t*)(ctx->ks);
-        via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
-        if(ALIGN_OFFSET( ctx, 16 ))
-            return EXIT_FAILURE;
-
-        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
-        {
-            via_ecb_op5(ksp, cwd, ibuf, obuf, nb);
-        }
-        else
-        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
-            uint_8t *ip, *op;
-
-            while(nb)
-            {
-                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
-                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
-                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
-                if(ip != ibuf)
-                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
-                via_ecb_op5(ksp, cwd, ip, op, m);
-
-                if(op != obuf)
-                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
-                ibuf += m * AES_BLOCK_SIZE;
-                obuf += m * AES_BLOCK_SIZE;
-                nb -= m;
-            }
-        }
-
-        return EXIT_SUCCESS;
-    }
-
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
-    while(nb--)
-    {
-        if(aes_encrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-        ibuf += AES_BLOCK_SIZE;
-        obuf += AES_BLOCK_SIZE;
-    }
-#endif
-    return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, const aes_decrypt_ctx ctx[1])
-{   int nb = len >> 4;
-
-    if(len & (AES_BLOCK_SIZE - 1))
-        return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-    if(ctx->inf.b[1] == 0xff)
-    {   uint_8t *ksp = kd_adr(ctx);
-        via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
-
-        if(ALIGN_OFFSET( ctx, 16 ))
-            return EXIT_FAILURE;
-
-        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
-        {
-            via_ecb_op5(ksp, cwd, ibuf, obuf, nb);
-        }
-        else
-        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
-            uint_8t *ip, *op;
-
-            while(nb)
-            {
-                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
-                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
-                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
-                if(ip != ibuf)
-                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
-                via_ecb_op5(ksp, cwd, ip, op, m);
-
-                if(op != obuf)
-                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
-                ibuf += m * AES_BLOCK_SIZE;
-                obuf += m * AES_BLOCK_SIZE;
-                nb -= m;
-            }
-        }
-
-        return EXIT_SUCCESS;
-    }
-
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
-    while(nb--)
-    {
-        if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-        ibuf += AES_BLOCK_SIZE;
-        obuf += AES_BLOCK_SIZE;
-    }
-#endif
-    return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, const aes_encrypt_ctx ctx[1])
-{   int nb = len >> 4;
-
-    if(len & (AES_BLOCK_SIZE - 1))
-        return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-    if(ctx->inf.b[1] == 0xff)
-    {   uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
-        aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
-        via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
-        if(ALIGN_OFFSET( ctx, 16 ))
-            return EXIT_FAILURE;
-
-        if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */
-        {
-            ivp = liv;
-            memcpy(liv, iv, AES_BLOCK_SIZE);
-        }
-
-        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 ))
-        {
-            via_cbc_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);
-        }
-        else
-        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
-            uint_8t *ip, *op;
-
-            while(nb)
-            {
-                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
-                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
-                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
-                if(ip != ibuf)
-                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
-                via_cbc_op7(ksp, cwd, ip, op, m, ivp, ivp);
-
-                if(op != obuf)
-                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
-                ibuf += m * AES_BLOCK_SIZE;
-                obuf += m * AES_BLOCK_SIZE;
-                nb -= m;
-            }
-        }
-
-        if(iv != ivp)
-            memcpy(iv, ivp, AES_BLOCK_SIZE);
-
-        return EXIT_SUCCESS;
-    }
-
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
-# ifdef FAST_BUFFER_OPERATIONS
-    if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
-        while(nb--)
-        {
-            lp32(iv)[0] ^= lp32(ibuf)[0];
-            lp32(iv)[1] ^= lp32(ibuf)[1];
-            lp32(iv)[2] ^= lp32(ibuf)[2];
-            lp32(iv)[3] ^= lp32(ibuf)[3];
-            if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                return EXIT_FAILURE;
-            memcpy(obuf, iv, AES_BLOCK_SIZE);
-            ibuf += AES_BLOCK_SIZE;
-            obuf += AES_BLOCK_SIZE;
-        }
-    else
-# endif
-        while(nb--)
-        {
-            iv[ 0] ^= ibuf[ 0]; iv[ 1] ^= ibuf[ 1];
-            iv[ 2] ^= ibuf[ 2]; iv[ 3] ^= ibuf[ 3];
-            iv[ 4] ^= ibuf[ 4]; iv[ 5] ^= ibuf[ 5];
-            iv[ 6] ^= ibuf[ 6]; iv[ 7] ^= ibuf[ 7];
-            iv[ 8] ^= ibuf[ 8]; iv[ 9] ^= ibuf[ 9];
-            iv[10] ^= ibuf[10]; iv[11] ^= ibuf[11];
-            iv[12] ^= ibuf[12]; iv[13] ^= ibuf[13];
-            iv[14] ^= ibuf[14]; iv[15] ^= ibuf[15];
-            if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                return EXIT_FAILURE;
-            memcpy(obuf, iv, AES_BLOCK_SIZE);
-            ibuf += AES_BLOCK_SIZE;
-            obuf += AES_BLOCK_SIZE;
-        }
-#endif
-    return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, const aes_decrypt_ctx ctx[1])
-{   unsigned char tmp[AES_BLOCK_SIZE];
-    int nb = len >> 4;
-
-    if(len & (AES_BLOCK_SIZE - 1))
-        return EXIT_FAILURE;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-    if(ctx->inf.b[1] == 0xff)
-    {   uint_8t *ksp = kd_adr(ctx), *ivp = iv;
-        aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
-        via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
-
-        if(ALIGN_OFFSET( ctx, 16 ))
-            return EXIT_FAILURE;
-
-        if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */
-        {
-            ivp = liv;
-            memcpy(liv, iv, AES_BLOCK_SIZE);
-        }
-
-        if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ) && !ALIGN_OFFSET( iv, 16 ))
-        {
-            via_cbc_op6(ksp, cwd, ibuf, obuf, nb, ivp);
-        }
-        else
-        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
-            uint_8t *ip, *op;
-
-            while(nb)
-            {
-                int m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb);
-
-                ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
-                op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
-                if(ip != ibuf)
-                    memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
-                via_cbc_op6(ksp, cwd, ip, op, m, ivp);
-
-                if(op != obuf)
-                    memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
-                ibuf += m * AES_BLOCK_SIZE;
-                obuf += m * AES_BLOCK_SIZE;
-                nb -= m;
-            }
-        }
-
-        if(iv != ivp)
-            memcpy(iv, ivp, AES_BLOCK_SIZE);
-
-        return EXIT_SUCCESS;
-    }
-#endif
-
-#if !defined( ASSUME_VIA_ACE_PRESENT )
-# ifdef FAST_BUFFER_OPERATIONS
-    if(!ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
-        while(nb--)
-        {
-            memcpy(tmp, ibuf, AES_BLOCK_SIZE);
-            if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
-                return EXIT_FAILURE;
-            lp32(obuf)[0] ^= lp32(iv)[0];
-            lp32(obuf)[1] ^= lp32(iv)[1];
-            lp32(obuf)[2] ^= lp32(iv)[2];
-            lp32(obuf)[3] ^= lp32(iv)[3];
-            memcpy(iv, tmp, AES_BLOCK_SIZE);
-            ibuf += AES_BLOCK_SIZE;
-            obuf += AES_BLOCK_SIZE;
-        }
-    else
-# endif
-        while(nb--)
-        {
-            memcpy(tmp, ibuf, AES_BLOCK_SIZE);
-            if(aes_decrypt(ibuf, obuf, ctx) != EXIT_SUCCESS)
-                return EXIT_FAILURE;
-            obuf[ 0] ^= iv[ 0]; obuf[ 1] ^= iv[ 1];
-            obuf[ 2] ^= iv[ 2]; obuf[ 3] ^= iv[ 3];
-            obuf[ 4] ^= iv[ 4]; obuf[ 5] ^= iv[ 5];
-            obuf[ 6] ^= iv[ 6]; obuf[ 7] ^= iv[ 7];
-            obuf[ 8] ^= iv[ 8]; obuf[ 9] ^= iv[ 9];
-            obuf[10] ^= iv[10]; obuf[11] ^= iv[11];
-            obuf[12] ^= iv[12]; obuf[13] ^= iv[13];
-            obuf[14] ^= iv[14]; obuf[15] ^= iv[15];
-            memcpy(iv, tmp, AES_BLOCK_SIZE);
-            ibuf += AES_BLOCK_SIZE;
-            obuf += AES_BLOCK_SIZE;
-        }
-#endif
-    return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
-{   int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
-
-    if(b_pos)           /* complete any partial block   */
-    {
-        while(b_pos < AES_BLOCK_SIZE && cnt < len)
-        {
-            *obuf++ = (iv[b_pos++] ^= *ibuf++);
-            cnt++;
-        }
-
-        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
-    }
-
-    if((nb = (len - cnt) >> 4) != 0)    /* process whole blocks */
-    {
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-        if(ctx->inf.b[1] == 0xff)
-        {   int m;
-            uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
-            aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
-            via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
-            if(ALIGN_OFFSET( ctx, 16 ))
-                return EXIT_FAILURE;
-
-            if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */
-            {
-                ivp = liv;
-                memcpy(liv, iv, AES_BLOCK_SIZE);
-            }
-
-            if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
-            {
-                via_cfb_op7(ksp, cwd, ibuf, obuf, nb, ivp, ivp);
-                ibuf += nb * AES_BLOCK_SIZE;
-                obuf += nb * AES_BLOCK_SIZE;
-                cnt  += nb * AES_BLOCK_SIZE;
-            }
-            else    /* input, output or both are unaligned  */
-            {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
-                uint_8t *ip, *op;
-
-                while(nb)
-                {
-                    m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;
-
-                    ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
-                    op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
-                    if(ip != ibuf)
-                        memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
-                    via_cfb_op7(ksp, cwd, ip, op, m, ivp, ivp);
-
-                    if(op != obuf)
-                        memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
-                    ibuf += m * AES_BLOCK_SIZE;
-                    obuf += m * AES_BLOCK_SIZE;
-                    cnt  += m * AES_BLOCK_SIZE;
-                }
-            }
-
-            if(ivp != iv)
-                memcpy(iv, ivp, AES_BLOCK_SIZE);
-        }
-#else
-# ifdef FAST_BUFFER_OPERATIONS
-        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
-            while(cnt + AES_BLOCK_SIZE <= len)
-            {
-                assert(b_pos == 0);
-                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                    return EXIT_FAILURE;
-                lp32(obuf)[0] = lp32(iv)[0] ^= lp32(ibuf)[0];
-                lp32(obuf)[1] = lp32(iv)[1] ^= lp32(ibuf)[1];
-                lp32(obuf)[2] = lp32(iv)[2] ^= lp32(ibuf)[2];
-                lp32(obuf)[3] = lp32(iv)[3] ^= lp32(ibuf)[3];
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-                cnt  += AES_BLOCK_SIZE;
-            }
-        else
-# endif
-            while(cnt + AES_BLOCK_SIZE <= len)
-            {
-                assert(b_pos == 0);
-                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                    return EXIT_FAILURE;
-                obuf[ 0] = iv[ 0] ^= ibuf[ 0]; obuf[ 1] = iv[ 1] ^= ibuf[ 1];
-                obuf[ 2] = iv[ 2] ^= ibuf[ 2]; obuf[ 3] = iv[ 3] ^= ibuf[ 3];
-                obuf[ 4] = iv[ 4] ^= ibuf[ 4]; obuf[ 5] = iv[ 5] ^= ibuf[ 5];
-                obuf[ 6] = iv[ 6] ^= ibuf[ 6]; obuf[ 7] = iv[ 7] ^= ibuf[ 7];
-                obuf[ 8] = iv[ 8] ^= ibuf[ 8]; obuf[ 9] = iv[ 9] ^= ibuf[ 9];
-                obuf[10] = iv[10] ^= ibuf[10]; obuf[11] = iv[11] ^= ibuf[11];
-                obuf[12] = iv[12] ^= ibuf[12]; obuf[13] = iv[13] ^= ibuf[13];
-                obuf[14] = iv[14] ^= ibuf[14]; obuf[15] = iv[15] ^= ibuf[15];
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-                cnt  += AES_BLOCK_SIZE;
-            }
-#endif
-    }
-
-    while(cnt < len)
-    {
-        if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-
-        while(cnt < len && b_pos < AES_BLOCK_SIZE)
-        {
-            *obuf++ = (iv[b_pos++] ^= *ibuf++);
-            cnt++;
-        }
-
-        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
-    }
-
-    ctx->inf.b[2] = (uint_8t)b_pos;
-    return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
-{   int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
-
-    if(b_pos)           /* complete any partial block   */
-    {   uint_8t t;
-
-        while(b_pos < AES_BLOCK_SIZE && cnt < len)
-        {
-            t = *ibuf++;
-            *obuf++ = t ^ iv[b_pos];
-            iv[b_pos++] = t;
-            cnt++;
-        }
-
-        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
-    }
-
-    if((nb = (len - cnt) >> 4) != 0)    /* process whole blocks */
-    {
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-        if(ctx->inf.b[1] == 0xff)
-        {   int m;
-            uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
-            aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
-            via_cwd(cwd, hybrid, dec, 2 * ctx->inf.b[0] - 192);
-
-            if(ALIGN_OFFSET( ctx, 16 ))
-                return EXIT_FAILURE;
-
-            if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */
-            {
-                ivp = liv;
-                memcpy(liv, iv, AES_BLOCK_SIZE);
-            }
-
-            if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
-            {
-                via_cfb_op6(ksp, cwd, ibuf, obuf, nb, ivp);
-                ibuf += nb * AES_BLOCK_SIZE;
-                obuf += nb * AES_BLOCK_SIZE;
-                cnt  += nb * AES_BLOCK_SIZE;
-            }
-            else    /* input, output or both are unaligned  */
-            {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
-                uint_8t *ip, *op;
-
-                while(nb)
-                {
-                    m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;
-
-                    ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
-                    op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
-                    if(ip != ibuf)  /* input buffer is not aligned */
-                        memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
-                    via_cfb_op6(ksp, cwd, ip, op, m, ivp);
-
-                    if(op != obuf)  /* output buffer is not aligned */
-                        memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
-                    ibuf += m * AES_BLOCK_SIZE;
-                    obuf += m * AES_BLOCK_SIZE;
-                    cnt  += m * AES_BLOCK_SIZE;
-                }
-            }
-
-            if(ivp != iv)
-                memcpy(iv, ivp, AES_BLOCK_SIZE);
-        }
-#else
-# ifdef FAST_BUFFER_OPERATIONS
-        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) &&!ALIGN_OFFSET( iv, 4 ))
-            while(cnt + AES_BLOCK_SIZE <= len)
-            {   uint_32t t;
-
-                assert(b_pos == 0);
-                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                    return EXIT_FAILURE;
-                t = lp32(ibuf)[0], lp32(obuf)[0] = t ^ lp32(iv)[0], lp32(iv)[0] = t;
-                t = lp32(ibuf)[1], lp32(obuf)[1] = t ^ lp32(iv)[1], lp32(iv)[1] = t;
-                t = lp32(ibuf)[2], lp32(obuf)[2] = t ^ lp32(iv)[2], lp32(iv)[2] = t;
-                t = lp32(ibuf)[3], lp32(obuf)[3] = t ^ lp32(iv)[3], lp32(iv)[3] = t;
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-                cnt  += AES_BLOCK_SIZE;
-            }
-        else
-# endif
-            while(cnt + AES_BLOCK_SIZE <= len)
-            {   uint_8t t;
-
-                assert(b_pos == 0);
-                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                    return EXIT_FAILURE;
-                t = ibuf[ 0], obuf[ 0] = t ^ iv[ 0], iv[ 0] = t;
-                t = ibuf[ 1], obuf[ 1] = t ^ iv[ 1], iv[ 1] = t;
-                t = ibuf[ 2], obuf[ 2] = t ^ iv[ 2], iv[ 2] = t;
-                t = ibuf[ 3], obuf[ 3] = t ^ iv[ 3], iv[ 3] = t;
-                t = ibuf[ 4], obuf[ 4] = t ^ iv[ 4], iv[ 4] = t;
-                t = ibuf[ 5], obuf[ 5] = t ^ iv[ 5], iv[ 5] = t;
-                t = ibuf[ 6], obuf[ 6] = t ^ iv[ 6], iv[ 6] = t;
-                t = ibuf[ 7], obuf[ 7] = t ^ iv[ 7], iv[ 7] = t;
-                t = ibuf[ 8], obuf[ 8] = t ^ iv[ 8], iv[ 8] = t;
-                t = ibuf[ 9], obuf[ 9] = t ^ iv[ 9], iv[ 9] = t;
-                t = ibuf[10], obuf[10] = t ^ iv[10], iv[10] = t;
-                t = ibuf[11], obuf[11] = t ^ iv[11], iv[11] = t;
-                t = ibuf[12], obuf[12] = t ^ iv[12], iv[12] = t;
-                t = ibuf[13], obuf[13] = t ^ iv[13], iv[13] = t;
-                t = ibuf[14], obuf[14] = t ^ iv[14], iv[14] = t;
-                t = ibuf[15], obuf[15] = t ^ iv[15], iv[15] = t;
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-                cnt  += AES_BLOCK_SIZE;
-            }
-#endif
-    }
-
-    while(cnt < len)
-    {   uint_8t t;
-
-        if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-
-        while(cnt < len && b_pos < AES_BLOCK_SIZE)
-        {
-            t = *ibuf++;
-            *obuf++ = t ^ iv[b_pos];
-            iv[b_pos++] = t;
-            cnt++;
-        }
-
-        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
-    }
-
-    ctx->inf.b[2] = (uint_8t)b_pos;
-    return EXIT_SUCCESS;
-}
-
-AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
-                    int len, unsigned char *iv, aes_encrypt_ctx ctx[1])
-{   int cnt = 0, b_pos = (int)ctx->inf.b[2], nb;
-
-    if(b_pos)           /* complete any partial block   */
-    {
-        while(b_pos < AES_BLOCK_SIZE && cnt < len)
-        {
-            *obuf++ = iv[b_pos++] ^ *ibuf++;
-            cnt++;
-        }
-
-        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
-    }
-
-    if((nb = (len - cnt) >> 4) != 0)   /* process whole blocks */
-    {
-#if defined( USE_VIA_ACE_IF_PRESENT )
-
-        if(ctx->inf.b[1] == 0xff)
-        {   int m;
-            uint_8t *ksp = (uint_8t*)(ctx->ks), *ivp = iv;
-            aligned_auto(uint_8t, liv, AES_BLOCK_SIZE, 16);
-            via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-
-            if(ALIGN_OFFSET( ctx, 16 ))
-                return EXIT_FAILURE;
-
-            if(ALIGN_OFFSET( iv, 16 ))   /* ensure an aligned iv */
-            {
-                ivp = liv;
-                memcpy(liv, iv, AES_BLOCK_SIZE);
-            }
-
-            if(!ALIGN_OFFSET( ibuf, 16 ) && !ALIGN_OFFSET( obuf, 16 ))
-            {
-                via_ofb_op6(ksp, cwd, ibuf, obuf, nb, ivp);
-                ibuf += nb * AES_BLOCK_SIZE;
-                obuf += nb * AES_BLOCK_SIZE;
-                cnt  += nb * AES_BLOCK_SIZE;
-            }
-            else    /* input, output or both are unaligned  */
-        {   aligned_auto(uint_8t, buf, BFR_BLOCKS * AES_BLOCK_SIZE, 16);
-            uint_8t *ip, *op;
-
-                while(nb)
-                {
-                    m = (nb > BFR_BLOCKS ? BFR_BLOCKS : nb), nb -= m;
-
-                    ip = (ALIGN_OFFSET( ibuf, 16 ) ? buf : ibuf);
-                    op = (ALIGN_OFFSET( obuf, 16 ) ? buf : obuf);
-
-                    if(ip != ibuf)
-                        memcpy(buf, ibuf, m * AES_BLOCK_SIZE);
-
-                    via_ofb_op6(ksp, cwd, ip, op, m, ivp);
-
-                    if(op != obuf)
-                        memcpy(obuf, buf, m * AES_BLOCK_SIZE);
-
-                    ibuf += m * AES_BLOCK_SIZE;
-                    obuf += m * AES_BLOCK_SIZE;
-                    cnt  += m * AES_BLOCK_SIZE;
-                }
-            }
-
-            if(ivp != iv)
-                memcpy(iv, ivp, AES_BLOCK_SIZE);
-        }
-#else
-# ifdef FAST_BUFFER_OPERATIONS
-        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( iv, 4 ))
-            while(cnt + AES_BLOCK_SIZE <= len)
-            {
-                assert(b_pos == 0);
-                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                    return EXIT_FAILURE;
-                lp32(obuf)[0] = lp32(iv)[0] ^ lp32(ibuf)[0];
-                lp32(obuf)[1] = lp32(iv)[1] ^ lp32(ibuf)[1];
-                lp32(obuf)[2] = lp32(iv)[2] ^ lp32(ibuf)[2];
-                lp32(obuf)[3] = lp32(iv)[3] ^ lp32(ibuf)[3];
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-                cnt  += AES_BLOCK_SIZE;
-            }
-        else
-# endif
-            while(cnt + AES_BLOCK_SIZE <= len)
-            {
-                assert(b_pos == 0);
-                if(aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-                    return EXIT_FAILURE;
-                obuf[ 0] = iv[ 0] ^ ibuf[ 0]; obuf[ 1] = iv[ 1] ^ ibuf[ 1];
-                obuf[ 2] = iv[ 2] ^ ibuf[ 2]; obuf[ 3] = iv[ 3] ^ ibuf[ 3];
-                obuf[ 4] = iv[ 4] ^ ibuf[ 4]; obuf[ 5] = iv[ 5] ^ ibuf[ 5];
-                obuf[ 6] = iv[ 6] ^ ibuf[ 6]; obuf[ 7] = iv[ 7] ^ ibuf[ 7];
-                obuf[ 8] = iv[ 8] ^ ibuf[ 8]; obuf[ 9] = iv[ 9] ^ ibuf[ 9];
-                obuf[10] = iv[10] ^ ibuf[10]; obuf[11] = iv[11] ^ ibuf[11];
-                obuf[12] = iv[12] ^ ibuf[12]; obuf[13] = iv[13] ^ ibuf[13];
-                obuf[14] = iv[14] ^ ibuf[14]; obuf[15] = iv[15] ^ ibuf[15];
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-                cnt  += AES_BLOCK_SIZE;
-            }
-#endif
-    }
-
-    while(cnt < len)
-    {
-        if(!b_pos && aes_encrypt(iv, iv, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-
-        while(cnt < len && b_pos < AES_BLOCK_SIZE)
-        {
-            *obuf++ = iv[b_pos++] ^ *ibuf++;
-            cnt++;
-        }
-
-        b_pos = (b_pos == AES_BLOCK_SIZE ? 0 : b_pos);
-    }
-
-    ctx->inf.b[2] = (uint_8t)b_pos;
-    return EXIT_SUCCESS;
-}
-
-#define BFR_LENGTH  (BFR_BLOCKS * AES_BLOCK_SIZE)
-
-AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
-            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx ctx[1])
-{   unsigned char   *ip;
-    int             i, blen, b_pos = (int)(ctx->inf.b[2]);
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-    aligned_auto(uint_8t, buf, BFR_LENGTH, 16);
-    if(ctx->inf.b[1] == 0xff && ALIGN_OFFSET( ctx, 16 ))
-        return EXIT_FAILURE;
-#else
-    uint_8t buf[BFR_LENGTH];
-#endif
-
-    if(b_pos)
-    {
-        memcpy(buf, cbuf, AES_BLOCK_SIZE);
-        if(aes_ecb_encrypt(buf, buf, AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-
-        while(b_pos < AES_BLOCK_SIZE && len)
-        {
-            *obuf++ = *ibuf++ ^ buf[b_pos++];
-            --len;
-        }
-
-        if(len)
-            ctr_inc(cbuf), b_pos = 0;
-    }
-
-    while(len)
-    {
-        blen = (len > BFR_LENGTH ? BFR_LENGTH : len), len -= blen;
-
-        for(i = 0, ip = buf; i < (blen >> 4); ++i)
-        {
-            memcpy(ip, cbuf, AES_BLOCK_SIZE);
-            ctr_inc(cbuf);
-            ip += AES_BLOCK_SIZE;
-        }
-
-        if(blen & (AES_BLOCK_SIZE - 1))
-            memcpy(ip, cbuf, AES_BLOCK_SIZE), i++;
-
-#if defined( USE_VIA_ACE_IF_PRESENT )
-        if(ctx->inf.b[1] == 0xff)
-        {
-            via_cwd(cwd, hybrid, enc, 2 * ctx->inf.b[0] - 192);
-            via_ecb_op5((ctx->ks), cwd, buf, buf, i);
-        }
-        else
-#endif
-        if(aes_ecb_encrypt(buf, buf, i * AES_BLOCK_SIZE, ctx) != EXIT_SUCCESS)
-            return EXIT_FAILURE;
-
-        i = 0; ip = buf;
-# ifdef FAST_BUFFER_OPERATIONS
-        if(!ALIGN_OFFSET( ibuf, 4 ) && !ALIGN_OFFSET( obuf, 4 ) && !ALIGN_OFFSET( ip, 4 ))
-            while(i + AES_BLOCK_SIZE <= blen)
-            {
-                lp32(obuf)[0] = lp32(ibuf)[0] ^ lp32(ip)[0];
-                lp32(obuf)[1] = lp32(ibuf)[1] ^ lp32(ip)[1];
-                lp32(obuf)[2] = lp32(ibuf)[2] ^ lp32(ip)[2];
-                lp32(obuf)[3] = lp32(ibuf)[3] ^ lp32(ip)[3];
-                i += AES_BLOCK_SIZE;
-                ip += AES_BLOCK_SIZE;
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-            }
-        else
-#endif
-            while(i + AES_BLOCK_SIZE <= blen)
-            {
-                obuf[ 0] = ibuf[ 0] ^ ip[ 0]; obuf[ 1] = ibuf[ 1] ^ ip[ 1];
-                obuf[ 2] = ibuf[ 2] ^ ip[ 2]; obuf[ 3] = ibuf[ 3] ^ ip[ 3];
-                obuf[ 4] = ibuf[ 4] ^ ip[ 4]; obuf[ 5] = ibuf[ 5] ^ ip[ 5];
-                obuf[ 6] = ibuf[ 6] ^ ip[ 6]; obuf[ 7] = ibuf[ 7] ^ ip[ 7];
-                obuf[ 8] = ibuf[ 8] ^ ip[ 8]; obuf[ 9] = ibuf[ 9] ^ ip[ 9];
-                obuf[10] = ibuf[10] ^ ip[10]; obuf[11] = ibuf[11] ^ ip[11];
-                obuf[12] = ibuf[12] ^ ip[12]; obuf[13] = ibuf[13] ^ ip[13];
-                obuf[14] = ibuf[14] ^ ip[14]; obuf[15] = ibuf[15] ^ ip[15];
-                i += AES_BLOCK_SIZE;
-                ip += AES_BLOCK_SIZE;
-                ibuf += AES_BLOCK_SIZE;
-                obuf += AES_BLOCK_SIZE;
-            }
-
-        while(i++ < blen)
-            *obuf++ = *ibuf++ ^ ip[b_pos++];
-    }
-
-    ctx->inf.b[2] = (uint_8t)b_pos;
-    return EXIT_SUCCESS;
-}
-
-#if defined(__cplusplus)
-}
-#endif
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aescpp.h b/jni/libzrtp/sources/cryptcommon/aescpp.h
deleted file mode 100644
index 9e2e24c..0000000
--- a/jni/libzrtp/sources/cryptcommon/aescpp.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the definitions required to use AES (Rijndael) in C++.
-*/
-
-#ifndef _AESCPP_H
-#define _AESCPP_H
-
-#include "aes.h"
-
-#if defined( AES_ENCRYPT )
-
-class AESencrypt
-{
-public:
-    aes_encrypt_ctx cx[1];
-    AESencrypt(void) { aes_init(); };
-#if defined(AES_128)
-    AESencrypt(const unsigned char key[])
-        {   aes_encrypt_key128(key, cx); }
-    AES_RETURN key128(const unsigned char key[])
-        {   return aes_encrypt_key128(key, cx); }
-#endif
-#if defined(AES_192)
-    AES_RETURN key192(const unsigned char key[])
-        {   return aes_encrypt_key192(key, cx); }
-#endif
-#if defined(AES_256)
-    AES_RETURN key256(const unsigned char key[])
-        {   return aes_encrypt_key256(key, cx); }
-#endif
-#if defined(AES_VAR)
-    AES_RETURN key(const unsigned char key[], int key_len)
-        {   return aes_encrypt_key(key, key_len, cx); }
-#endif
-    AES_RETURN encrypt(const unsigned char in[], unsigned char out[]) const
-        {   return aes_encrypt(in, out, cx);  }
-#ifndef AES_MODES
-    AES_RETURN ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const
-        {   while(nb--)
-            {   aes_encrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; }
-        }
-#endif
-#ifdef AES_MODES
-    AES_RETURN mode_reset(void)   { return aes_mode_reset(cx); }
-
-    AES_RETURN ecb_encrypt(const unsigned char in[], unsigned char out[], int nb) const
-        {   return aes_ecb_encrypt(in, out, nb, cx);  }
-
-    AES_RETURN cbc_encrypt(const unsigned char in[], unsigned char out[], int nb,
-                                    unsigned char iv[]) const
-        {   return aes_cbc_encrypt(in, out, nb, iv, cx);  }
-
-    AES_RETURN cfb_encrypt(const unsigned char in[], unsigned char out[], int nb,
-                                    unsigned char iv[])
-        {   return aes_cfb_encrypt(in, out, nb, iv, cx);  }
-
-    AES_RETURN cfb_decrypt(const unsigned char in[], unsigned char out[], int nb,
-                                    unsigned char iv[])
-        {   return aes_cfb_decrypt(in, out, nb, iv, cx);  }
-
-    AES_RETURN ofb_crypt(const unsigned char in[], unsigned char out[], int nb,
-                                    unsigned char iv[])
-        {   return aes_ofb_crypt(in, out, nb, iv, cx);  }
-
-    typedef void ctr_fn(unsigned char ctr[]);
-
-    AES_RETURN ctr_crypt(const unsigned char in[], unsigned char out[], int nb,
-                                    unsigned char iv[], ctr_fn cf)
-        {   return aes_ctr_crypt(in, out, nb, iv, cf, cx);  }
-
-#endif
-
-};
-
-#endif
-
-#if defined( AES_DECRYPT )
-
-class AESdecrypt
-{
-public:
-    aes_decrypt_ctx cx[1];
-    AESdecrypt(void) { aes_init(); };
-#if defined(AES_128)
-    AESdecrypt(const unsigned char key[])
-            { aes_decrypt_key128(key, cx); }
-    AES_RETURN key128(const unsigned char key[])
-            { return aes_decrypt_key128(key, cx); }
-#endif
-#if defined(AES_192)
-    AES_RETURN key192(const unsigned char key[])
-            { return aes_decrypt_key192(key, cx); }
-#endif
-#if defined(AES_256)
-    AES_RETURN key256(const unsigned char key[])
-            { return aes_decrypt_key256(key, cx); }
-#endif
-#if defined(AES_VAR)
-    AES_RETURN key(const unsigned char key[], int key_len)
-            { return aes_decrypt_key(key, key_len, cx); }
-#endif
-    AES_RETURN decrypt(const unsigned char in[], unsigned char out[]) const
-        {   return aes_decrypt(in, out, cx);  }
-#ifndef AES_MODES
-    AES_RETURN ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const
-        {   while(nb--)
-            {   aes_decrypt(in, out, cx), in += AES_BLOCK_SIZE, out += AES_BLOCK_SIZE; }
-        }
-#endif
-#ifdef AES_MODES
-
-    AES_RETURN ecb_decrypt(const unsigned char in[], unsigned char out[], int nb) const
-        {   return aes_ecb_decrypt(in, out, nb, cx);  }
-
-    AES_RETURN cbc_decrypt(const unsigned char in[], unsigned char out[], int nb,
-                                    unsigned char iv[]) const
-        {   return aes_cbc_decrypt(in, out, nb, iv, cx);  }
-#endif
-};
-
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aescrypt.c b/jni/libzrtp/sources/cryptcommon/aescrypt.c
deleted file mode 100644
index 6095f41..0000000
--- a/jni/libzrtp/sources/cryptcommon/aescrypt.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-*/
-
-#include "aesopt.h"
-#include "aestab.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
-#define so(y,x,c)   word_out(y, c, s(x,c))
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[4],y[4]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
-#endif
-
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
-
-/* Visual C++ .Net v7.1 provides the fastest encryption code when using
-   Pentium optimiation with small code but this is poor for decryption
-   so we need to control this with the following VC++ pragmas
-*/
-
-#if defined( _MSC_VER ) && !defined( _WIN64 )
-#pragma optimize( "s", on )
-#endif
-
-/* Given the column (c) of the output state variable, the following
-   macros give the input state variables which are needed in its
-   computation for each row (r) of the state. All the alternative
-   macros give the same end values but expand into different ways
-   of calculating these values.  In particular the complex macro
-   used for dynamically variable block sizes is designed to expand
-   to a compile time constant whenever possible but will expand to
-   conditional clauses on some branches (I am grateful to Frank
-   Yellin for this construction)
-*/
-
-#define fwd_var(x,r,c)\
- ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
- : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
- : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
- :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
-
-#if defined(FT4_SET)
-#undef  dec_fmvars
-#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
-#elif defined(FT1_SET)
-#undef  dec_fmvars
-#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
-#else
-#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
-#endif
-
-#if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
-#elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
-#else
-#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
-#endif
-
-AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
-{   uint_32t         locals(b0, b1);
-    const uint_32t   *kp;
-#if defined( dec_fmvars )
-    dec_fmvars; /* declare variables for fwd_mcol() if needed */
-#endif
-
-    if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
-        return EXIT_FAILURE;
-
-    kp = cx->ks;
-    state_in(b0, in, kp);
-
-#if (ENC_UNROLL == FULL)
-
-    switch(cx->inf.b[0])
-    {
-    case 14 * 16:
-        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
-        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
-        kp += 2 * N_COLS;
-    case 12 * 16:
-        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
-        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
-        kp += 2 * N_COLS;
-    case 10 * 16:
-        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
-        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
-        round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
-        round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
-        round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
-        round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
-        round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
-        round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
-        round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
-        round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
-    }
-
-#else
-
-#if (ENC_UNROLL == PARTIAL)
-    {   uint_32t    rnd;
-        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
-        {
-            kp += N_COLS;
-            round(fwd_rnd, b1, b0, kp);
-            kp += N_COLS;
-            round(fwd_rnd, b0, b1, kp);
-        }
-        kp += N_COLS;
-        round(fwd_rnd,  b1, b0, kp);
-#else
-    {   uint_32t    rnd;
-        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
-        {
-            kp += N_COLS;
-            round(fwd_rnd, b1, b0, kp);
-            l_copy(b0, b1);
-        }
-#endif
-        kp += N_COLS;
-        round(fwd_lrnd, b0, b1, kp);
-    }
-#endif
-
-    state_out(out, b0);
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if ( FUNCS_IN_C & DECRYPTION_IN_C)
-
-/* Visual C++ .Net v7.1 provides the fastest encryption code when using
-   Pentium optimiation with small code but this is poor for decryption
-   so we need to control this with the following VC++ pragmas
-*/
-
-#if defined( _MSC_VER ) && !defined( _WIN64 )
-#pragma optimize( "t", on )
-#endif
-
-/* Given the column (c) of the output state variable, the following
-   macros give the input state variables which are needed in its
-   computation for each row (r) of the state. All the alternative
-   macros give the same end values but expand into different ways
-   of calculating these values.  In particular the complex macro
-   used for dynamically variable block sizes is designed to expand
-   to a compile time constant whenever possible but will expand to
-   conditional clauses on some branches (I am grateful to Frank
-   Yellin for this construction)
-*/
-
-#define inv_var(x,r,c)\
- ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
- : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
- : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
- :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
-
-#if defined(IT4_SET)
-#undef  dec_imvars
-#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
-#elif defined(IT1_SET)
-#undef  dec_imvars
-#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
-#else
-#define inv_rnd(y,x,k,c)    (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
-#endif
-
-#if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
-#elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
-#else
-#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
-#endif
-
-/* This code can work with the decryption key schedule in the   */
-/* order that is used for encrytpion (where the 1st decryption  */
-/* round key is at the high end ot the schedule) or with a key  */
-/* schedule that has been reversed to put the 1st decryption    */
-/* round key at the low end of the schedule in memory (when     */
-/* AES_REV_DKS is defined)                                      */
-
-#ifdef AES_REV_DKS
-#define key_ofs     0
-#define rnd_key(n)  (kp + n * N_COLS)
-#else
-#define key_ofs     1
-#define rnd_key(n)  (kp - n * N_COLS)
-#endif
-
-AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
-{   uint_32t        locals(b0, b1);
-#if defined( dec_imvars )
-    dec_imvars; /* declare variables for inv_mcol() if needed */
-#endif
-    const uint_32t *kp;
-
-    if( cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16 )
-        return EXIT_FAILURE;
-
-    kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
-    state_in(b0, in, kp);
-
-#if (DEC_UNROLL == FULL)
-
-    kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
-    switch(cx->inf.b[0])
-    {
-    case 14 * 16:
-        round(inv_rnd,  b1, b0, rnd_key(-13));
-        round(inv_rnd,  b0, b1, rnd_key(-12));
-    case 12 * 16:
-        round(inv_rnd,  b1, b0, rnd_key(-11));
-        round(inv_rnd,  b0, b1, rnd_key(-10));
-    case 10 * 16:
-        round(inv_rnd,  b1, b0, rnd_key(-9));
-        round(inv_rnd,  b0, b1, rnd_key(-8));
-        round(inv_rnd,  b1, b0, rnd_key(-7));
-        round(inv_rnd,  b0, b1, rnd_key(-6));
-        round(inv_rnd,  b1, b0, rnd_key(-5));
-        round(inv_rnd,  b0, b1, rnd_key(-4));
-        round(inv_rnd,  b1, b0, rnd_key(-3));
-        round(inv_rnd,  b0, b1, rnd_key(-2));
-        round(inv_rnd,  b1, b0, rnd_key(-1));
-        round(inv_lrnd, b0, b1, rnd_key( 0));
-    }
-
-#else
-
-#if (DEC_UNROLL == PARTIAL)
-    {   uint_32t    rnd;
-        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd)
-        {
-            kp = rnd_key(1);
-            round(inv_rnd, b1, b0, kp);
-            kp = rnd_key(1);
-            round(inv_rnd, b0, b1, kp);
-        }
-        kp = rnd_key(1);
-        round(inv_rnd, b1, b0, kp);
-#else
-    {   uint_32t    rnd;
-        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd)
-        {
-            kp = rnd_key(1);
-            round(inv_rnd, b1, b0, kp);
-            l_copy(b0, b1);
-        }
-#endif
-        kp = rnd_key(1);
-        round(inv_lrnd, b0, b1, kp);
-        }
-#endif
-
-    state_out(out, b0);
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aeskey.c b/jni/libzrtp/sources/cryptcommon/aeskey.c
deleted file mode 100644
index 10d3324..0000000
--- a/jni/libzrtp/sources/cryptcommon/aeskey.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-*/
-
-#include "aesopt.h"
-#include "aestab.h"
-
-/*
-#ifdef USE_VIA_ACE_IF_PRESENT
-#  include "aes_via_ace.h"
-#endif
-*/
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Initialise the key schedule from the user supplied key. The key
-   length can be specified in bytes, with legal values of 16, 24
-   and 32, or in bits, with legal values of 128, 192 and 256. These
-   values correspond with Nk values of 4, 6 and 8 respectively.
-
-   The following macros implement a single cycle in the key
-   schedule generation process. The number of cycles needed
-   for each cx->n_col and nk value is:
-
-    nk =             4  5  6  7  8
-    ------------------------------
-    cx->n_col = 4   10  9  8  7  7
-    cx->n_col = 5   14 11 10  9  9
-    cx->n_col = 6   19 15 12 11 11
-    cx->n_col = 7   21 19 16 13 14
-    cx->n_col = 8   29 23 19 17 14
-*/
-
-#if defined( REDUCE_CODE_SIZE )
-#  define ls_box ls_sub
-   uint_32t ls_sub(const uint_32t t, const uint_32t n);
-#  define inv_mcol im_sub
-   uint_32t im_sub(const uint_32t x);
-#  ifdef ENC_KS_UNROLL
-#    undef ENC_KS_UNROLL
-#  endif
-#  ifdef DEC_KS_UNROLL
-#    undef DEC_KS_UNROLL
-#  endif
-#endif
-
-#if (FUNCS_IN_C & ENC_KEYING_IN_C)
-
-#if defined(AES_128) || defined( AES_VAR )
-
-#define ke4(k,i) \
-{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
-    k[4*(i)+5] = ss[1] ^= ss[0]; \
-    k[4*(i)+6] = ss[2] ^= ss[1]; \
-    k[4*(i)+7] = ss[3] ^= ss[2]; \
-}
-
-AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
-{   uint_32t    ss[4];
-
-    cx->ks[0] = ss[0] = word_in(key, 0);
-    cx->ks[1] = ss[1] = word_in(key, 1);
-    cx->ks[2] = ss[2] = word_in(key, 2);
-    cx->ks[3] = ss[3] = word_in(key, 3);
-
-#ifdef ENC_KS_UNROLL
-    ke4(cx->ks, 0);  ke4(cx->ks, 1);
-    ke4(cx->ks, 2);  ke4(cx->ks, 3);
-    ke4(cx->ks, 4);  ke4(cx->ks, 5);
-    ke4(cx->ks, 6);  ke4(cx->ks, 7);
-    ke4(cx->ks, 8);
-#else
-    {   uint_32t i;
-        for(i = 0; i < 9; ++i)
-            ke4(cx->ks, i);
-    }
-#endif
-    ke4(cx->ks, 9);
-    cx->inf.l = 0;
-    cx->inf.b[0] = 10 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
-    if(VIA_ACE_AVAILABLE)
-        cx->inf.b[1] = 0xff;
-#endif
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_192) || defined( AES_VAR )
-
-#define kef6(k,i) \
-{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
-    k[6*(i)+ 7] = ss[1] ^= ss[0]; \
-    k[6*(i)+ 8] = ss[2] ^= ss[1]; \
-    k[6*(i)+ 9] = ss[3] ^= ss[2]; \
-}
-
-#define ke6(k,i) \
-{   kef6(k,i); \
-    k[6*(i)+10] = ss[4] ^= ss[3]; \
-    k[6*(i)+11] = ss[5] ^= ss[4]; \
-}
-
-AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
-{   uint_32t    ss[6];
-
-    cx->ks[0] = ss[0] = word_in(key, 0);
-    cx->ks[1] = ss[1] = word_in(key, 1);
-    cx->ks[2] = ss[2] = word_in(key, 2);
-    cx->ks[3] = ss[3] = word_in(key, 3);
-    cx->ks[4] = ss[4] = word_in(key, 4);
-    cx->ks[5] = ss[5] = word_in(key, 5);
-
-#ifdef ENC_KS_UNROLL
-    ke6(cx->ks, 0);  ke6(cx->ks, 1);
-    ke6(cx->ks, 2);  ke6(cx->ks, 3);
-    ke6(cx->ks, 4);  ke6(cx->ks, 5);
-    ke6(cx->ks, 6);
-#else
-    {   uint_32t i;
-        for(i = 0; i < 7; ++i)
-            ke6(cx->ks, i);
-    }
-#endif
-    kef6(cx->ks, 7);
-    cx->inf.l = 0;
-    cx->inf.b[0] = 12 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
-    if(VIA_ACE_AVAILABLE)
-        cx->inf.b[1] = 0xff;
-#endif
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_256) || defined( AES_VAR )
-
-#define kef8(k,i) \
-{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
-    k[8*(i)+ 9] = ss[1] ^= ss[0]; \
-    k[8*(i)+10] = ss[2] ^= ss[1]; \
-    k[8*(i)+11] = ss[3] ^= ss[2]; \
-}
-
-#define ke8(k,i) \
-{   kef8(k,i); \
-    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
-    k[8*(i)+13] = ss[5] ^= ss[4]; \
-    k[8*(i)+14] = ss[6] ^= ss[5]; \
-    k[8*(i)+15] = ss[7] ^= ss[6]; \
-}
-
-AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
-{   uint_32t    ss[8];
-
-    cx->ks[0] = ss[0] = word_in(key, 0);
-    cx->ks[1] = ss[1] = word_in(key, 1);
-    cx->ks[2] = ss[2] = word_in(key, 2);
-    cx->ks[3] = ss[3] = word_in(key, 3);
-    cx->ks[4] = ss[4] = word_in(key, 4);
-    cx->ks[5] = ss[5] = word_in(key, 5);
-    cx->ks[6] = ss[6] = word_in(key, 6);
-    cx->ks[7] = ss[7] = word_in(key, 7);
-
-#ifdef ENC_KS_UNROLL
-    ke8(cx->ks, 0); ke8(cx->ks, 1);
-    ke8(cx->ks, 2); ke8(cx->ks, 3);
-    ke8(cx->ks, 4); ke8(cx->ks, 5);
-#else
-    {   uint_32t i;
-        for(i = 0; i < 6; ++i)
-            ke8(cx->ks,  i);
-    }
-#endif
-    kef8(cx->ks, 6);
-    cx->inf.l = 0;
-    cx->inf.b[0] = 14 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
-    if(VIA_ACE_AVAILABLE)
-        cx->inf.b[1] = 0xff;
-#endif
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined( AES_VAR )
-
-AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
-{   
-    switch(key_len)
-    {
-    case 16: case 128: return aes_encrypt_key128(key, cx);
-    case 24: case 192: return aes_encrypt_key192(key, cx);
-    case 32: case 256: return aes_encrypt_key256(key, cx);
-    default: return EXIT_FAILURE;
-    }
-}
-
-#endif
-
-#endif
-
-#if (FUNCS_IN_C & DEC_KEYING_IN_C)
-
-/* this is used to store the decryption round keys  */
-/* in forward or reverse order                      */
-
-#ifdef AES_REV_DKS
-#define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
-#else
-#define v(n,i)  (i)
-#endif
-
-#if DEC_ROUND == NO_TABLES
-#define ff(x)   (x)
-#else
-#define ff(x)   inv_mcol(x)
-#if defined( dec_imvars )
-#define d_vars  dec_imvars
-#endif
-#endif
-
-#if defined(AES_128) || defined( AES_VAR )
-
-#define k4e(k,i) \
-{   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
-    k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
-    k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
-    k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
-}
-
-#if 1
-
-#define kdf4(k,i) \
-{   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
-    ss[1] = ss[1] ^ ss[3]; \
-    ss[2] = ss[2] ^ ss[3]; \
-    ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
-    ss[i % 4] ^= ss[4]; \
-    ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \
-    ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
-    ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
-    ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
-}
-
-#define kd4(k,i) \
-{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
-    ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
-    k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
-    k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
-    k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
-    k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
-}
-
-#define kdl4(k,i) \
-{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
-    k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
-    k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
-    k[v(40,(4*(i))+6)] = ss[0]; \
-    k[v(40,(4*(i))+7)] = ss[1]; \
-}
-
-#else
-
-#define kdf4(k,i) \
-{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
-    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
-    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
-}
-
-#define kd4(k,i) \
-{   ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
-    ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
-    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
-    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
-    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
-}
-
-#define kdl4(k,i) \
-{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
-    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
-    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
-    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
-}
-
-#endif
-
-AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
-{   uint_32t    ss[5];
-#if defined( d_vars )
-        d_vars;
-#endif
-    cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
-    cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
-    cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
-    cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
-
-#ifdef DEC_KS_UNROLL
-     kdf4(cx->ks, 0); kd4(cx->ks, 1);
-     kd4(cx->ks, 2);  kd4(cx->ks, 3);
-     kd4(cx->ks, 4);  kd4(cx->ks, 5);
-     kd4(cx->ks, 6);  kd4(cx->ks, 7);
-     kd4(cx->ks, 8);  kdl4(cx->ks, 9);
-#else
-    {   uint_32t i;
-        for(i = 0; i < 10; ++i)
-            k4e(cx->ks, i);
-#if !(DEC_ROUND == NO_TABLES)
-        for(i = N_COLS; i < 10 * N_COLS; ++i)
-            cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
-    }
-#endif
-    cx->inf.l = 0;
-    cx->inf.b[0] = 10 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
-    if(VIA_ACE_AVAILABLE)
-        cx->inf.b[1] = 0xff;
-#endif
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_192) || defined( AES_VAR )
-
-#define k6ef(k,i) \
-{   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
-    k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
-    k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
-    k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
-}
-
-#define k6e(k,i) \
-{   k6ef(k,i); \
-    k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
-    k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
-}
-
-#define kdf6(k,i) \
-{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
-    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
-    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
-    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
-    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
-}
-
-#define kd6(k,i) \
-{   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
-    ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
-    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
-    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
-    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
-    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
-    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
-}
-
-#define kdl6(k,i) \
-{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
-    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
-    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
-    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
-}
-
-AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
-{   uint_32t    ss[7];
-#if defined( d_vars )
-        d_vars;
-#endif
-    cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
-    cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
-    cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
-    cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
-
-#ifdef DEC_KS_UNROLL
-    cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
-    cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5));
-    kdf6(cx->ks, 0); kd6(cx->ks, 1);
-    kd6(cx->ks, 2);  kd6(cx->ks, 3);
-    kd6(cx->ks, 4);  kd6(cx->ks, 5);
-    kd6(cx->ks, 6);  kdl6(cx->ks, 7);
-#else
-    cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
-    cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
-    {   uint_32t i;
-
-        for(i = 0; i < 7; ++i)
-            k6e(cx->ks, i);
-        k6ef(cx->ks, 7);
-#if !(DEC_ROUND == NO_TABLES)
-        for(i = N_COLS; i < 12 * N_COLS; ++i)
-            cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
-    }
-#endif
-    cx->inf.l = 0;
-    cx->inf.b[0] = 12 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
-    if(VIA_ACE_AVAILABLE)
-        cx->inf.b[1] = 0xff;
-#endif
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(AES_256) || defined( AES_VAR )
-
-#define k8ef(k,i) \
-{   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
-    k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
-    k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
-    k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
-}
-
-#define k8e(k,i) \
-{   k8ef(k,i); \
-    k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
-    k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
-    k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
-    k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
-}
-
-#define kdf8(k,i) \
-{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
-    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
-    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
-    ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
-    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
-    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
-    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
-}
-
-#define kd8(k,i) \
-{   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
-    ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
-    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
-    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
-    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
-    ss[8] = ls_box(ss[3],0); \
-    ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
-    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
-    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
-    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
-}
-
-#define kdl8(k,i) \
-{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
-    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
-    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
-    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
-}
-
-AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
-{   uint_32t    ss[9];
-#if defined( d_vars )
-        d_vars;
-#endif
-    cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
-    cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
-    cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
-    cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
-
-#ifdef DEC_KS_UNROLL
-    cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4));
-    cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5));
-    cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6));
-    cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
-    kdf8(cx->ks, 0); kd8(cx->ks, 1);
-    kd8(cx->ks, 2);  kd8(cx->ks, 3);
-    kd8(cx->ks, 4);  kd8(cx->ks, 5);
-    kdl8(cx->ks, 6);
-#else
-    cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);
-    cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
-    cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
-    cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
-    {   uint_32t i;
-
-        for(i = 0; i < 6; ++i)
-            k8e(cx->ks,  i);
-        k8ef(cx->ks,  6);
-#if !(DEC_ROUND == NO_TABLES)
-        for(i = N_COLS; i < 14 * N_COLS; ++i)
-            cx->ks[i] = inv_mcol(cx->ks[i]);
-#endif
-    }
-#endif
-    cx->inf.l = 0;
-    cx->inf.b[0] = 14 * 16;
-
-#ifdef USE_VIA_ACE_IF_PRESENT
-    if(VIA_ACE_AVAILABLE)
-        cx->inf.b[1] = 0xff;
-#endif
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined( AES_VAR )
-
-AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
-{
-    switch(key_len)
-    {
-    case 16: case 128: return aes_decrypt_key128(key, cx);
-    case 24: case 192: return aes_decrypt_key192(key, cx);
-    case 32: case 256: return aes_decrypt_key256(key, cx);
-    default: return EXIT_FAILURE;
-    }
-}
-
-#endif
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aesopt.h b/jni/libzrtp/sources/cryptcommon/aesopt.h
deleted file mode 100644
index 471e0c9..0000000
--- a/jni/libzrtp/sources/cryptcommon/aesopt.h
+++ /dev/null
@@ -1,742 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the compilation options for AES (Rijndael) and code
- that is common across encryption, key scheduling and table generation.
-
- OPERATION
-
- These source code files implement the AES algorithm Rijndael designed by
- Joan Daemen and Vincent Rijmen. This version is designed for the standard
- block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
- and 32 bytes).
-
- This version is designed for flexibility and speed using operations on
- 32-bit words rather than operations on bytes.  It can be compiled with
- either big or little endian internal byte order but is faster when the
- native byte order for the processor is used.
-
- THE CIPHER INTERFACE
-
- The cipher interface is implemented as an array of bytes in which lower
- AES bit sequence indexes map to higher numeric significance within bytes.
-
-  uint_8t                 (an unsigned  8-bit type)
-  uint_32t                (an unsigned 32-bit type)
-  struct aes_encrypt_ctx  (structure for the cipher encryption context)
-  struct aes_decrypt_ctx  (structure for the cipher decryption context)
-  AES_RETURN                the function return type
-
-  C subroutine calls:
-
-  AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
-  AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
-  AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
-  AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
-                                                  const aes_encrypt_ctx cx[1]);
-
-  AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
-  AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
-  AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
-  AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
-                                                  const aes_decrypt_ctx cx[1]);
-
- IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
- you call aes_init() before AES is used so that the tables are initialised.
-
- C++ aes class subroutines:
-
-     Class AESencrypt  for encryption
-
-      Construtors:
-          AESencrypt(void)
-          AESencrypt(const unsigned char *key) - 128 bit key
-      Members:
-          AES_RETURN key128(const unsigned char *key)
-          AES_RETURN key192(const unsigned char *key)
-          AES_RETURN key256(const unsigned char *key)
-          AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
-
-      Class AESdecrypt  for encryption
-      Construtors:
-          AESdecrypt(void)
-          AESdecrypt(const unsigned char *key) - 128 bit key
-      Members:
-          AES_RETURN key128(const unsigned char *key)
-          AES_RETURN key192(const unsigned char *key)
-          AES_RETURN key256(const unsigned char *key)
-          AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
-*/
-
-#if !defined( _AESOPT_H )
-#define _AESOPT_H
-
-#if defined( __cplusplus )
-#include "aescpp.h"
-#else
-#include "aes.h"
-#endif
-
-/*  PLATFORM SPECIFIC INCLUDES */
-
-#include "brg_endian.h"
-
-/*  CONFIGURATION - THE USE OF DEFINES
-
-    Later in this section there are a number of defines that control the
-    operation of the code.  In each section, the purpose of each define is
-    explained so that the relevant form can be included or excluded by
-    setting either 1's or 0's respectively on the branches of the related
-    #if clauses.  The following local defines should not be changed.
-*/
-
-#define ENCRYPTION_IN_C     1
-#define DECRYPTION_IN_C     2
-#define ENC_KEYING_IN_C     4
-#define DEC_KEYING_IN_C     8
-
-#define NO_TABLES           0
-#define ONE_TABLE           1
-#define FOUR_TABLES         4
-#define NONE                0
-#define PARTIAL             1
-#define FULL                2
-
-/*  --- START OF USER CONFIGURED OPTIONS --- */
-
-/*  1. BYTE ORDER WITHIN 32 BIT WORDS
-
-    The fundamental data processing units in Rijndael are 8-bit bytes. The
-    input, output and key input are all enumerated arrays of bytes in which
-    bytes are numbered starting at zero and increasing to one less than the
-    number of bytes in the array in question. This enumeration is only used
-    for naming bytes and does not imply any adjacency or order relationship
-    from one byte to another. When these inputs and outputs are considered
-    as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to
-    byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte.
-    In this implementation bits are numbered from 0 to 7 starting at the
-    numerically least significant end of each byte (bit n represents 2^n).
-
-    However, Rijndael can be implemented more efficiently using 32-bit
-    words by packing bytes into words so that bytes 4*n to 4*n+3 are placed
-    into word[n]. While in principle these bytes can be assembled into words
-    in any positions, this implementation only supports the two formats in
-    which bytes in adjacent positions within words also have adjacent byte
-    numbers. This order is called big-endian if the lowest numbered bytes
-    in words have the highest numeric significance and little-endian if the
-    opposite applies.
-
-    This code can work in either order irrespective of the order used by the
-    machine on which it runs. Normally the internal byte order will be set
-    to the order of the processor on which the code is to be run but this
-    define can be used to reverse this in special situations
-
-    WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
-    This define will hence be redefined later (in section 4) if necessary
-*/
-
-#if 1
-#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
-#elif 0
-#  define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
-#elif 0
-#  define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
-#else
-#  error The algorithm byte order is not defined
-#endif
-
-/*  2. VIA ACE SUPPORT */
-
-#if defined( __GNUC__ ) && defined( __i386__ ) \
- || defined( _WIN32   ) && defined( _M_IX86  ) \
- && !(defined( _WIN64 ) || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
-#  define VIA_ACE_POSSIBLE
-#endif
-
-/*  Define this option if support for the VIA ACE is required. This uses
-    inline assembler instructions and is only implemented for the Microsoft,
-    Intel and GCC compilers.  If VIA ACE is known to be present, then defining
-    ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
-    code.  If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
-    it is detected (both present and enabled) but the normal AES code will
-    also be present.
-
-    When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
-    aligned; other input/output buffers do not need to be 16 byte aligned
-    but there are very large performance gains if this can be arranged.
-    VIA ACE also requires the decryption key schedule to be in reverse
-    order (which later checks below ensure).
-*/
-
-#if 1 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
-#  define USE_VIA_ACE_IF_PRESENT
-#endif
-
-#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )
-#  define ASSUME_VIA_ACE_PRESENT
-#  endif
-
-/*  3. ASSEMBLER SUPPORT
-
-    This define (which can be on the command line) enables the use of the
-    assembler code routines for encryption, decryption and key scheduling
-    as follows:
-
-    ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
-                encryption and decryption and but with key scheduling in C
-    ASM_X86_V2  uses assembler (aes_x86_v2.asm) with compressed tables for
-                encryption, decryption and key scheduling
-    ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
-                encryption and decryption and but with key scheduling in C
-    ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
-                encryption and decryption and but with key scheduling in C
-
-    Change one 'if 0' below to 'if 1' to select the version or define
-    as a compilation option.
-*/
-
-#if 0 && !defined( ASM_X86_V1C )
-#  define ASM_X86_V1C
-#elif 0 && !defined( ASM_X86_V2  )
-#  define ASM_X86_V2
-#elif 0 && !defined( ASM_X86_V2C )
-#  define ASM_X86_V2C
-#elif 0 && !defined( ASM_AMD64_C )
-#  define ASM_AMD64_C
-#endif
-
-#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
-      && !defined( _M_IX86 ) || defined( ASM_AMD64_C ) && !defined( _M_X64 )
-#  error Assembler code is only available for x86 and AMD64 systems
-#endif
-
-/*  4. FAST INPUT/OUTPUT OPERATIONS.
-
-    On some machines it is possible to improve speed by transferring the
-    bytes in the input and output arrays to and from the internal 32-bit
-    variables by addressing these arrays as if they are arrays of 32-bit
-    words.  On some machines this will always be possible but there may
-    be a large performance penalty if the byte arrays are not aligned on
-    the normal word boundaries. On other machines this technique will
-    lead to memory access errors when such 32-bit word accesses are not
-    properly aligned. The option SAFE_IO avoids such problems but will
-    often be slower on those machines that support misaligned access
-    (especially so if care is taken to align the input  and output byte
-    arrays on 32-bit word boundaries). If SAFE_IO is not defined it is
-    assumed that access to byte arrays as if they are arrays of 32-bit
-    words will not cause problems when such accesses are misaligned.
-*/
-#if 1 && !defined( _MSC_VER )
-#  define SAFE_IO
-#endif
-
-/*  5. LOOP UNROLLING
-
-    The code for encryption and decrytpion cycles through a number of rounds
-    that can be implemented either in a loop or by expanding the code into a
-    long sequence of instructions, the latter producing a larger program but
-    one that will often be much faster. The latter is called loop unrolling.
-    There are also potential speed advantages in expanding two iterations in
-    a loop with half the number of iterations, which is called partial loop
-    unrolling.  The following options allow partial or full loop unrolling
-    to be set independently for encryption and decryption
-*/
-#if 1
-#  define ENC_UNROLL  FULL
-#elif 0
-#  define ENC_UNROLL  PARTIAL
-#else
-#  define ENC_UNROLL  NONE
-#endif
-
-#if 1
-#  define DEC_UNROLL  FULL
-#elif 0
-#  define DEC_UNROLL  PARTIAL
-#else
-#  define DEC_UNROLL  NONE
-#endif
-
-#if 1
-#  define ENC_KS_UNROLL
-#endif
-
-#if 1
-#  define DEC_KS_UNROLL
-#endif
-
-/*  6. FAST FINITE FIELD OPERATIONS
-
-    If this section is included, tables are used to provide faster finite
-    field arithmetic (this has no effect if FIXED_TABLES is defined).
-*/
-#if 1
-#  define FF_TABLES
-#endif
-
-/*  7. INTERNAL STATE VARIABLE FORMAT
-
-    The internal state of Rijndael is stored in a number of local 32-bit
-    word varaibles which can be defined either as an array or as individual
-    names variables. Include this section if you want to store these local
-    varaibles in arrays. Otherwise individual local variables will be used.
-*/
-#if 1
-#  define ARRAYS
-#endif
-
-/*  8. FIXED OR DYNAMIC TABLES
-
-    When this section is included the tables used by the code are compiled
-    statically into the binary file.  Otherwise the subroutine aes_init()
-    must be called to compute them before the code is first used.
-*/
-#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
-#  define FIXED_TABLES
-#endif
-
-/*  9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
-
-    In some systems it is better to mask longer values to extract bytes 
-    rather than using a cast. This option allows this choice.
-*/
-#if 0
-#  define to_byte(x)  ((uint_8t)(x))
-#else
-#  define to_byte(x)  ((x) & 0xff)
-#endif
-
-/*  10. TABLE ALIGNMENT
-
-    On some sytsems speed will be improved by aligning the AES large lookup
-    tables on particular boundaries. This define should be set to a power of
-    two giving the desired alignment. It can be left undefined if alignment
-    is not needed.  This option is specific to the Microsft VC++ compiler -
-    it seems to sometimes cause trouble for the VC++ version 6 compiler.
-*/
-
-#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
-#  define TABLE_ALIGN 32
-#endif
-
-/*  11.  REDUCE CODE AND TABLE SIZE
-
-    This replaces some expanded macros with function calls if AES_ASM_V2 or
-    AES_ASM_V2C are defined
-*/
-
-#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))
-#  define REDUCE_CODE_SIZE
-#endif
-
-/*  12. TABLE OPTIONS
-
-    This cipher proceeds by repeating in a number of cycles known as 'rounds'
-    which are implemented by a round function which can optionally be speeded
-    up using tables.  The basic tables are each 256 32-bit words, with either
-    one or four tables being required for each round function depending on
-    how much speed is required. The encryption and decryption round functions
-    are different and the last encryption and decrytpion round functions are
-    different again making four different round functions in all.
-
-    This means that:
-      1. Normal encryption and decryption rounds can each use either 0, 1
-         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
-      2. The last encryption and decryption rounds can also use either 0, 1
-         or 4 tables and table spaces of 0, 1024 or 4096 bytes each.
-
-    Include or exclude the appropriate definitions below to set the number
-    of tables used by this implementation.
-*/
-
-#if 1   /* set tables for the normal encryption round */
-#  define ENC_ROUND   FOUR_TABLES
-#elif 0
-#  define ENC_ROUND   ONE_TABLE
-#else
-#  define ENC_ROUND   NO_TABLES
-#endif
-
-#if 1   /* set tables for the last encryption round */
-#  define LAST_ENC_ROUND  FOUR_TABLES
-#elif 0
-#  define LAST_ENC_ROUND  ONE_TABLE
-#else
-#  define LAST_ENC_ROUND  NO_TABLES
-#endif
-
-#if 1   /* set tables for the normal decryption round */
-#  define DEC_ROUND   FOUR_TABLES
-#elif 0
-#  define DEC_ROUND   ONE_TABLE
-#else
-#  define DEC_ROUND   NO_TABLES
-#endif
-
-#if 1   /* set tables for the last decryption round */
-#  define LAST_DEC_ROUND  FOUR_TABLES
-#elif 0
-#  define LAST_DEC_ROUND  ONE_TABLE
-#else
-#  define LAST_DEC_ROUND  NO_TABLES
-#endif
-
-/*  The decryption key schedule can be speeded up with tables in the same
-    way that the round functions can.  Include or exclude the following
-    defines to set this requirement.
-*/
-#if 1
-#  define KEY_SCHED   FOUR_TABLES
-#elif 0
-#  define KEY_SCHED   ONE_TABLE
-#else
-#  define KEY_SCHED   NO_TABLES
-#endif
-
-/*  ---- END OF USER CONFIGURED OPTIONS ---- */
-
-/* VIA ACE support is only available for VC++ and GCC */
-
-#if !defined( _MSC_VER ) && !defined( __GNUC__ )
-#  if defined( ASSUME_VIA_ACE_PRESENT )
-#    undef ASSUME_VIA_ACE_PRESENT
-#  endif
-#  if defined( USE_VIA_ACE_IF_PRESENT )
-#    undef USE_VIA_ACE_IF_PRESENT
-#  endif
-#endif
-
-#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )
-#  define USE_VIA_ACE_IF_PRESENT
-#endif
-
-#if defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
-#  define AES_REV_DKS
-#endif
-
-/* ********** UNDEF - we don't use VIA stuff ****************** */
-#undef USE_VIA_ACE_IF_PRESENT
-
-/* Assembler support requires the use of platform byte order */
-
-#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
-    && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)
-#  undef  ALGORITHM_BYTE_ORDER
-#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
-#endif
-
-/* In this implementation the columns of the state array are each held in
-   32-bit words. The state array can be held in various ways: in an array
-   of words, in a number of individual word variables or in a number of
-   processor registers. The following define maps a variable name x and
-   a column number c to the way the state array variable is to be held.
-   The first define below maps the state into an array x[c] whereas the
-   second form maps the state into a number of individual variables x0,
-   x1, etc.  Another form could map individual state colums to machine
-   register names.
-*/
-
-#if defined( ARRAYS )
-#  define s(x,c) x[c]
-#else
-#  define s(x,c) x##c
-#endif
-
-/*  This implementation provides subroutines for encryption, decryption
-    and for setting the three key lengths (separately) for encryption
-    and decryption. Since not all functions are needed, masks are set
-    up here to determine which will be implemented in C
-*/
-
-#if !defined( AES_ENCRYPT )
-#  define EFUNCS_IN_C   0
-#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
-    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
-#  define EFUNCS_IN_C   ENC_KEYING_IN_C
-#elif !defined( ASM_X86_V2 )
-#  define EFUNCS_IN_C   ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )
-#else
-#  define EFUNCS_IN_C   0
-#endif
-
-#if !defined( AES_DECRYPT )
-#  define DFUNCS_IN_C   0
-#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
-    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
-#  define DFUNCS_IN_C   DEC_KEYING_IN_C
-#elif !defined( ASM_X86_V2 )
-#  define DFUNCS_IN_C   ( DECRYPTION_IN_C | DEC_KEYING_IN_C )
-#else
-#  define DFUNCS_IN_C   0
-#endif
-
-#define FUNCS_IN_C  ( EFUNCS_IN_C | DFUNCS_IN_C )
-
-/* END OF CONFIGURATION OPTIONS */
-
-#define RC_LENGTH   (5 * (AES_BLOCK_SIZE / 4 - 2))
-
-/* Disable or report errors on some combinations of options */
-
-#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
-#  undef  LAST_ENC_ROUND
-#  define LAST_ENC_ROUND  NO_TABLES
-#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
-#  undef  LAST_ENC_ROUND
-#  define LAST_ENC_ROUND  ONE_TABLE
-#endif
-
-#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
-#  undef  ENC_UNROLL
-#  define ENC_UNROLL  NONE
-#endif
-
-#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
-#  undef  LAST_DEC_ROUND
-#  define LAST_DEC_ROUND  NO_TABLES
-#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
-#  undef  LAST_DEC_ROUND
-#  define LAST_DEC_ROUND  ONE_TABLE
-#endif
-
-#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
-#  undef  DEC_UNROLL
-#  define DEC_UNROLL  NONE
-#endif
-
-#if defined( bswap32 )
-#  define aes_sw32    bswap32
-#elif defined( bswap_32 )
-#  define aes_sw32    bswap_32
-#else
-#  define brot(x,n)   (((uint_32t)(x) <<  n) | ((uint_32t)(x) >> (32 - n)))
-#  define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
-#endif
-
-/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to
-               higher index positions with wrap around into low positions
-    ups(x,n):  moves bytes by n positions to higher index positions in
-               words but without wrap around
-    bval(x,n): extracts a byte from a word
-
-    WARNING:   The definitions given here are intended only for use with
-               unsigned variables and with shift counts that are compile
-               time constants
-*/
-
-#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
-#  define upr(x,n)      (((uint_32t)(x) << (8 * (n))) | ((uint_32t)(x) >> (32 - 8 * (n))))
-#  define ups(x,n)      ((uint_32t) (x) << (8 * (n)))
-#  define bval(x,n)     to_byte((x) >> (8 * (n)))
-#  define bytes2word(b0, b1, b2, b3)  \
-        (((uint_32t)(b3) << 24) | ((uint_32t)(b2) << 16) | ((uint_32t)(b1) << 8) | (b0))
-#endif
-
-#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
-#  define upr(x,n)      (((uint_32t)(x) >> (8 * (n))) | ((uint_32t)(x) << (32 - 8 * (n))))
-#  define ups(x,n)      ((uint_32t) (x) >> (8 * (n)))
-#  define bval(x,n)     to_byte((x) >> (24 - 8 * (n)))
-#  define bytes2word(b0, b1, b2, b3)  \
-        (((uint_32t)(b0) << 24) | ((uint_32t)(b1) << 16) | ((uint_32t)(b2) << 8) | (b3))
-#endif
-
-#if defined( SAFE_IO )
-#  define word_in(x,c)    bytes2word(((const uint_8t*)(x)+4*c)[0], ((const uint_8t*)(x)+4*c)[1], \
-                                   ((const uint_8t*)(x)+4*c)[2], ((const uint_8t*)(x)+4*c)[3])
-#  define word_out(x,c,v) { ((uint_8t*)(x)+4*c)[0] = bval(v,0); ((uint_8t*)(x)+4*c)[1] = bval(v,1); \
-                          ((uint_8t*)(x)+4*c)[2] = bval(v,2); ((uint_8t*)(x)+4*c)[3] = bval(v,3); }
-#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
-#  define word_in(x,c)    (*((uint_32t*)(x)+(c)))
-#  define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = (v))
-#else
-#  define word_in(x,c)    aes_sw32(*((uint_32t*)(x)+(c)))
-#  define word_out(x,c,v) (*((uint_32t*)(x)+(c)) = aes_sw32(v))
-#endif
-
-/* the finite field modular polynomial and elements */
-
-#define WPOLY   0x011b
-#define BPOLY     0x1b
-
-/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
-
-#define gf_c1  0x80808080
-#define gf_c2  0x7f7f7f7f
-#define gf_mulx(x)  ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))
-
-/* The following defines provide alternative definitions of gf_mulx that might
-   give improved performance if a fast 32-bit multiply is not available. Note
-   that a temporary variable u needs to be defined where gf_mulx is used.
-
-#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
-#define gf_c4  (0x01010101 * BPOLY)
-#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
-*/
-
-/* Work out which tables are needed for the different options   */
-
-#if defined( ASM_X86_V1C )
-#  if defined( ENC_ROUND )
-#    undef  ENC_ROUND
-#  endif
-#  define ENC_ROUND   FOUR_TABLES
-#  if defined( LAST_ENC_ROUND )
-#    undef  LAST_ENC_ROUND
-#  endif
-#  define LAST_ENC_ROUND  FOUR_TABLES
-#  if defined( DEC_ROUND )
-#    undef  DEC_ROUND
-#  endif
-#  define DEC_ROUND   FOUR_TABLES
-#  if defined( LAST_DEC_ROUND )
-#    undef  LAST_DEC_ROUND
-#  endif
-#  define LAST_DEC_ROUND  FOUR_TABLES
-#  if defined( KEY_SCHED )
-#    undef  KEY_SCHED
-#    define KEY_SCHED   FOUR_TABLES
-#  endif
-#endif
-
-#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )
-#  if ENC_ROUND == ONE_TABLE
-#    define FT1_SET
-#  elif ENC_ROUND == FOUR_TABLES
-#    define FT4_SET
-#  else
-#    define SBX_SET
-#  endif
-#  if LAST_ENC_ROUND == ONE_TABLE
-#    define FL1_SET
-#  elif LAST_ENC_ROUND == FOUR_TABLES
-#    define FL4_SET
-#  elif !defined( SBX_SET )
-#    define SBX_SET
-#  endif
-#endif
-
-#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )
-#  if DEC_ROUND == ONE_TABLE
-#    define IT1_SET
-#  elif DEC_ROUND == FOUR_TABLES
-#    define IT4_SET
-#  else
-#    define ISB_SET
-#  endif
-#  if LAST_DEC_ROUND == ONE_TABLE
-#    define IL1_SET
-#  elif LAST_DEC_ROUND == FOUR_TABLES
-#    define IL4_SET
-#  elif !defined(ISB_SET)
-#    define ISB_SET
-#  endif
-#endif
-
-#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
-#  if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))
-#    if KEY_SCHED == ONE_TABLE
-#      if !defined( FL1_SET )  && !defined( FL4_SET ) 
-#        define LS1_SET
-#      endif
-#    elif KEY_SCHED == FOUR_TABLES
-#      if !defined( FL4_SET )
-#        define LS4_SET
-#      endif
-#    elif !defined( SBX_SET )
-#      define SBX_SET
-#    endif
-#  endif
-#  if (FUNCS_IN_C & DEC_KEYING_IN_C)
-#    if KEY_SCHED == ONE_TABLE
-#      define IM1_SET
-#    elif KEY_SCHED == FOUR_TABLES
-#      define IM4_SET
-#    elif !defined( SBX_SET )
-#      define SBX_SET
-#    endif
-#  endif
-#endif
-
-/* generic definitions of Rijndael macros that use tables    */
-
-#define no_table(x,box,vf,rf,c) bytes2word( \
-    box[bval(vf(x,0,c),rf(0,c))], \
-    box[bval(vf(x,1,c),rf(1,c))], \
-    box[bval(vf(x,2,c),rf(2,c))], \
-    box[bval(vf(x,3,c),rf(3,c))])
-
-#define one_table(x,op,tab,vf,rf,c) \
- (     tab[bval(vf(x,0,c),rf(0,c))] \
-  ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
-  ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
-  ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-
-#define four_tables(x,tab,vf,rf,c) \
- (  tab[0][bval(vf(x,0,c),rf(0,c))] \
-  ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
-  ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
-  ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-
-#define vf1(x,r,c)  (x)
-#define rf1(r,c)    (r)
-#define rf2(r,c)    ((8+r-c)&3)
-
-/* perform forward and inverse column mix operation on four bytes in long word x in */
-/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros.  */
-
-#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) 
-
-#if defined( FM4_SET )      /* not currently used */
-#  define fwd_mcol(x)       four_tables(x,t_use(f,m),vf1,rf1,0)
-#elif defined( FM1_SET )    /* not currently used */
-#  define fwd_mcol(x)       one_table(x,upr,t_use(f,m),vf1,rf1,0)
-#else
-#  define dec_fmvars        uint_32t g2
-#  define fwd_mcol(x)       (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
-#endif
-
-#if defined( IM4_SET )
-#  define inv_mcol(x)       four_tables(x,t_use(i,m),vf1,rf1,0)
-#elif defined( IM1_SET )
-#  define inv_mcol(x)       one_table(x,upr,t_use(i,m),vf1,rf1,0)
-#else
-#  define dec_imvars        uint_32t g2, g4, g9
-#  define inv_mcol(x)       (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
-                            (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
-#endif
-
-#if defined( FL4_SET )
-#  define ls_box(x,c)       four_tables(x,t_use(f,l),vf1,rf2,c)
-#elif defined( LS4_SET )
-#  define ls_box(x,c)       four_tables(x,t_use(l,s),vf1,rf2,c)
-#elif defined( FL1_SET )
-#  define ls_box(x,c)       one_table(x,upr,t_use(f,l),vf1,rf2,c)
-#elif defined( LS1_SET )
-#  define ls_box(x,c)       one_table(x,upr,t_use(l,s),vf1,rf2,c)
-#else
-#  define ls_box(x,c)       no_table(x,t_use(s,box),vf1,rf2,c)
-#endif
-
-#endif
-
-#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )
-#  define ISB_SET
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/aestab.c b/jni/libzrtp/sources/cryptcommon/aestab.c
deleted file mode 100644
index e2bdb9a..0000000
--- a/jni/libzrtp/sources/cryptcommon/aestab.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-*/
-
-#define DO_TABLES
-
-#include "aes.h"
-#include "aesopt.h"
-
-#if defined(FIXED_TABLES)
-
-#define sb_data(w) {\
-    w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
-    w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
-    w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
-    w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\
-    w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\
-    w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\
-    w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\
-    w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\
-    w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\
-    w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\
-    w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\
-    w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\
-    w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\
-    w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\
-    w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\
-    w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\
-    w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\
-    w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\
-    w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\
-    w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\
-    w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\
-    w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\
-    w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\
-    w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\
-    w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\
-    w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\
-    w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\
-    w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\
-    w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
-    w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
-    w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
-    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
-
-#define isb_data(w) {\
-    w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
-    w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
-    w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
-    w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\
-    w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\
-    w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\
-    w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\
-    w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\
-    w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\
-    w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\
-    w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\
-    w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\
-    w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\
-    w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\
-    w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\
-    w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\
-    w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\
-    w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\
-    w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\
-    w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\
-    w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\
-    w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\
-    w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\
-    w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\
-    w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\
-    w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\
-    w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\
-    w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\
-    w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
-    w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
-    w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
-    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
-
-#define mm_data(w) {\
-    w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
-    w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
-    w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
-    w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\
-    w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\
-    w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\
-    w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\
-    w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\
-    w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\
-    w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\
-    w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\
-    w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\
-    w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\
-    w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\
-    w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\
-    w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\
-    w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\
-    w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\
-    w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\
-    w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\
-    w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\
-    w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\
-    w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\
-    w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\
-    w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\
-    w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\
-    w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\
-    w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\
-    w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
-    w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
-    w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
-    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
-
-#define rc_data(w) {\
-    w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
-    w(0x1b), w(0x36) }
-
-#define h0(x)   (x)
-
-#define w0(p)   bytes2word(p, 0, 0, 0)
-#define w1(p)   bytes2word(0, p, 0, 0)
-#define w2(p)   bytes2word(0, 0, p, 0)
-#define w3(p)   bytes2word(0, 0, 0, p)
-
-#define u0(p)   bytes2word(f2(p), p, p, f3(p))
-#define u1(p)   bytes2word(f3(p), f2(p), p, p)
-#define u2(p)   bytes2word(p, f3(p), f2(p), p)
-#define u3(p)   bytes2word(p, p, f3(p), f2(p))
-
-#define v0(p)   bytes2word(fe(p), f9(p), fd(p), fb(p))
-#define v1(p)   bytes2word(fb(p), fe(p), f9(p), fd(p))
-#define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))
-#define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))
-
-#endif
-
-#if defined(FIXED_TABLES) || !defined(FF_TABLES)
-
-#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))
-#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
-#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
-                        ^ (((x>>5) & 4) * WPOLY))
-#define f3(x)   (f2(x) ^ x)
-#define f9(x)   (f8(x) ^ x)
-#define fb(x)   (f8(x) ^ f2(x) ^ x)
-#define fd(x)   (f8(x) ^ f4(x) ^ x)
-#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
-
-#else
-
-#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
-#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
-#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
-#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
-#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
-#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
-
-#endif
-
-#include "aestab.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined(FIXED_TABLES)
-
-/* implemented in case of wrong call for fixed tables */
-
-AES_RETURN aes_init(void)
-{
-    return EXIT_SUCCESS;
-}
-
-#else   /*  Generate the tables for the dynamic table option */
-
-#if defined(FF_TABLES)
-
-#define gf_inv(x)   ((x) ? pow[ 255 - log[x]] : 0)
-
-#else 
-
-/*  It will generally be sensible to use tables to compute finite
-    field multiplies and inverses but where memory is scarse this
-    code might sometimes be better. But it only has effect during
-    initialisation so its pretty unimportant in overall terms.
-*/
-
-/*  return 2 ^ (n - 1) where n is the bit number of the highest bit
-    set in x with x in the range 1 < x < 0x00000200.   This form is
-    used so that locals within fi can be bytes rather than words
-*/
-
-static uint_8t hibit(const uint_32t x)
-{   uint_8t r = (uint_8t)((x >> 1) | (x >> 2));
-
-    r |= (r >> 2);
-    r |= (r >> 4);
-    return (r + 1) >> 1;
-}
-
-/* return the inverse of the finite field element x */
-
-static uint_8t gf_inv(const uint_8t x)
-{   uint_8t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
-    if(x < 2) 
-        return x;
-
-    for( ; ; )
-    {
-        if(n1)
-            while(n2 >= n1)             /* divide polynomial p2 by p1    */
-            {
-                n2 /= n1;               /* shift smaller polynomial left */ 
-                p2 ^= (p1 * n2) & 0xff; /* and remove from larger one    */
-                v2 ^= v1 * n2;          /* shift accumulated value and   */ 
-                n2 = hibit(p2);         /* add into result               */
-            }
-        else
-            return v1;
-
-        if(n2)                          /* repeat with values swapped    */ 
-            while(n1 >= n2)
-            {
-                n1 /= n2; 
-                p1 ^= p2 * n1; 
-                v1 ^= v2 * n1; 
-                n1 = hibit(p1);
-            }
-        else
-            return v2;
-    }
-}
-
-#endif
-
-/* The forward and inverse affine transformations used in the S-box */
-uint_8t fwd_affine(const uint_8t x)
-{   uint_32t w = x;
-    w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
-    return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
-}
-
-uint_8t inv_affine(const uint_8t x)
-{   uint_32t w = x;
-    w = (w << 1) ^ (w << 3) ^ (w << 6);
-    return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
-}
-
-static int init = 0;
-
-AES_RETURN aes_init(void)
-{   uint_32t  i, w;
-
-#if defined(FF_TABLES)
-
-    uint_8t  pow[512], log[256];
-
-    if(init)
-        return EXIT_SUCCESS;
-    /*  log and power tables for GF(2^8) finite field with
-        WPOLY as modular polynomial - the simplest primitive
-        root is 0x03, used here to generate the tables
-    */
-
-    i = 0; w = 1;
-    do
-    {
-        pow[i] = (uint_8t)w;
-        pow[i + 255] = (uint_8t)w;
-        log[w] = (uint_8t)i++;
-        w ^=  (w << 1) ^ (w & 0x80 ? WPOLY : 0);
-    }
-    while (w != 1);
-
-#else
-    if(init)
-        return EXIT_SUCCESS;
-#endif
-
-    for(i = 0, w = 1; i < RC_LENGTH; ++i)
-    {
-        t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
-        w = f2(w);
-    }
-
-    for(i = 0; i < 256; ++i)
-    {   uint_8t    b;
-
-        b = fwd_affine(gf_inv((uint_8t)i));
-        w = bytes2word(f2(b), b, b, f3(b));
-
-#if defined( SBX_SET )
-        t_set(s,box)[i] = b;
-#endif
-
-#if defined( FT1_SET )                 /* tables for a normal encryption round */
-        t_set(f,n)[i] = w;
-#endif
-#if defined( FT4_SET )
-        t_set(f,n)[0][i] = w;
-        t_set(f,n)[1][i] = upr(w,1);
-        t_set(f,n)[2][i] = upr(w,2);
-        t_set(f,n)[3][i] = upr(w,3);
-#endif
-        w = bytes2word(b, 0, 0, 0);
-
-#if defined( FL1_SET )            /* tables for last encryption round (may also   */
-        t_set(f,l)[i] = w;        /* be used in the key schedule)                 */
-#endif
-#if defined( FL4_SET )
-        t_set(f,l)[0][i] = w;
-        t_set(f,l)[1][i] = upr(w,1);
-        t_set(f,l)[2][i] = upr(w,2);
-        t_set(f,l)[3][i] = upr(w,3);
-#endif
-
-#if defined( LS1_SET )			/* table for key schedule if t_set(f,l) above is*/
-        t_set(l,s)[i] = w;      /* not of the required form                     */
-#endif
-#if defined( LS4_SET )
-        t_set(l,s)[0][i] = w;
-        t_set(l,s)[1][i] = upr(w,1);
-        t_set(l,s)[2][i] = upr(w,2);
-        t_set(l,s)[3][i] = upr(w,3);
-#endif
-
-        b = gf_inv(inv_affine((uint_8t)i));
-        w = bytes2word(fe(b), f9(b), fd(b), fb(b));
-
-#if defined( IM1_SET )			/* tables for the inverse mix column operation  */
-        t_set(i,m)[b] = w;
-#endif
-#if defined( IM4_SET )
-        t_set(i,m)[0][b] = w;
-        t_set(i,m)[1][b] = upr(w,1);
-        t_set(i,m)[2][b] = upr(w,2);
-        t_set(i,m)[3][b] = upr(w,3);
-#endif
-
-#if defined( ISB_SET )
-        t_set(i,box)[i] = b;
-#endif
-#if defined( IT1_SET )			/* tables for a normal decryption round */
-        t_set(i,n)[i] = w;
-#endif
-#if defined( IT4_SET )
-        t_set(i,n)[0][i] = w;
-        t_set(i,n)[1][i] = upr(w,1);
-        t_set(i,n)[2][i] = upr(w,2);
-        t_set(i,n)[3][i] = upr(w,3);
-#endif
-        w = bytes2word(b, 0, 0, 0);
-#if defined( IL1_SET )			/* tables for last decryption round */
-        t_set(i,l)[i] = w;
-#endif
-#if defined( IL4_SET )
-        t_set(i,l)[0][i] = w;
-        t_set(i,l)[1][i] = upr(w,1);
-        t_set(i,l)[2][i] = upr(w,2);
-        t_set(i,l)[3][i] = upr(w,3);
-#endif
-    }
-    init = 1;
-    return EXIT_SUCCESS;
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
diff --git a/jni/libzrtp/sources/cryptcommon/aestab.h b/jni/libzrtp/sources/cryptcommon/aestab.h
deleted file mode 100644
index de68567..0000000
--- a/jni/libzrtp/sources/cryptcommon/aestab.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
----------------------------------------------------------------------------
-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.
-
-The redistribution and use of this software (with or without changes)
-is allowed without the payment of fees or royalties provided that:
-
-  source code distributions include the above copyright notice, this
-  list of conditions and the following disclaimer;
-
-  binary distributions include the above copyright notice, this list
-  of conditions and the following disclaimer in their documentation.
-
-This software is provided 'as is' with no explicit or implied warranties
-in respect of its operation, including, but not limited to, correctness
-and fitness for purpose.
----------------------------------------------------------------------------
-Issue Date: 20/12/2007
-
- This file contains the code for declaring the tables needed to implement
- AES. The file aesopt.h is assumed to be included before this header file.
- If there are no global variables, the definitions here can be used to put
- the AES tables in a structure so that a pointer can then be added to the
- AES context to pass them to the AES routines that need them.   If this
- facility is used, the calling program has to ensure that this pointer is
- managed appropriately.  In particular, the value of the t_dec(in,it) item
- in the table structure must be set to zero in order to ensure that the
- tables are initialised. In practice the three code sequences in aeskey.c
- that control the calls to aes_init() and the aes_init() routine itself will
- have to be changed for a specific implementation. If global variables are
- available it will generally be preferable to use them with the precomputed
- FIXED_TABLES option that uses static global tables.
-
- The following defines can be used to control the way the tables
- are defined, initialised and used in embedded environments that
- require special features for these purposes
-
-    the 't_dec' construction is used to declare fixed table arrays
-    the 't_set' construction is used to set fixed table values
-    the 't_use' construction is used to access fixed table values
-
-    256 byte tables:
-
-        t_xxx(s,box)    => forward S box
-        t_xxx(i,box)    => inverse S box
-
-    256 32-bit word OR 4 x 256 32-bit word tables:
-
-        t_xxx(f,n)      => forward normal round
-        t_xxx(f,l)      => forward last round
-        t_xxx(i,n)      => inverse normal round
-        t_xxx(i,l)      => inverse last round
-        t_xxx(l,s)      => key schedule table
-        t_xxx(i,m)      => key schedule table
-
-    Other variables and tables:
-
-        t_xxx(r,c)      => the rcon table
-*/
-
-#if !defined( _AESTAB_H )
-#define _AESTAB_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#define t_dec(m,n) t_##m##n
-#define t_set(m,n) t_##m##n
-#define t_use(m,n) t_##m##n
-
-#if defined(FIXED_TABLES)
-#  if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))
-/*   make tables far data to avoid using too much DGROUP space (PG) */
-#    define CONST const far
-#  else
-#    define CONST const
-#  endif
-#else
-#  define CONST
-#endif
-
-#if defined(DO_TABLES)
-#  define EXTERN
-#else
-#  define EXTERN extern
-#endif
-
-#if defined(_MSC_VER) && defined(TABLE_ALIGN)
-#define ALIGN __declspec(align(TABLE_ALIGN))
-#else
-#define ALIGN
-#endif
-
-#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
-#  define XP_DIR __cdecl
-#else
-#  define XP_DIR
-#endif
-
-#if defined(DO_TABLES) && defined(FIXED_TABLES)
-#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]    =   b(e)
-#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
-EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
-#else
-#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]
-#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]
-EXTERN ALIGN CONST uint_32t t_dec(r,c)[RC_LENGTH];
-#endif
-
-#if defined( SBX_SET )
-    d_1(uint_8t, t_dec(s,box), sb_data, h0);
-#endif
-#if defined( ISB_SET )
-    d_1(uint_8t, t_dec(i,box), isb_data, h0);
-#endif
-
-#if defined( FT1_SET )
-    d_1(uint_32t, t_dec(f,n), sb_data, u0);
-#endif
-#if defined( FT4_SET )
-    d_4(uint_32t, t_dec(f,n), sb_data, u0, u1, u2, u3);
-#endif
-
-#if defined( FL1_SET )
-    d_1(uint_32t, t_dec(f,l), sb_data, w0);
-#endif
-#if defined( FL4_SET )
-    d_4(uint_32t, t_dec(f,l), sb_data, w0, w1, w2, w3);
-#endif
-
-#if defined( IT1_SET )
-    d_1(uint_32t, t_dec(i,n), isb_data, v0);
-#endif
-#if defined( IT4_SET )
-    d_4(uint_32t, t_dec(i,n), isb_data, v0, v1, v2, v3);
-#endif
-
-#if defined( IL1_SET )
-    d_1(uint_32t, t_dec(i,l), isb_data, w0);
-#endif
-#if defined( IL4_SET )
-    d_4(uint_32t, t_dec(i,l), isb_data, w0, w1, w2, w3);
-#endif
-
-#if defined( LS1_SET )
-#if defined( FL1_SET )
-#undef  LS1_SET
-#else
-    d_1(uint_32t, t_dec(l,s), sb_data, w0);
-#endif
-#endif
-
-#if defined( LS4_SET )
-#if defined( FL4_SET )
-#undef  LS4_SET
-#else
-    d_4(uint_32t, t_dec(l,s), sb_data, w0, w1, w2, w3);
-#endif
-#endif
-
-#if defined( IM1_SET )
-    d_1(uint_32t, t_dec(i,m), mm_data, v0);
-#endif
-#if defined( IM4_SET )
-    d_4(uint_32t, t_dec(i,m), mm_data, v0, v1, v2, v3);
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/brg_types.h b/jni/libzrtp/sources/cryptcommon/brg_types.h
deleted file mode 100644
index 40d4af5..0000000
--- a/jni/libzrtp/sources/cryptcommon/brg_types.h
+++ /dev/null
@@ -1,219 +0,0 @@
-/*

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

-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.

-

-The redistribution and use of this software (with or without changes)

-is allowed without the payment of fees or royalties provided that:

-

-  source code distributions include the above copyright notice, this

-  list of conditions and the following disclaimer;

-

-  binary distributions include the above copyright notice, this list

-  of conditions and the following disclaimer in their documentation.

-

-This software is provided 'as is' with no explicit or implied warranties

-in respect of its operation, including, but not limited to, correctness

-and fitness for purpose.

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

-Issue Date: 20/12/2007

-

- The unsigned integer types defined here are of the form uint_<nn>t where

- <nn> is the length of the type; for example, the unsigned 32-bit type is

- 'uint_32t'.  These are NOT the same as the 'C99 integer types' that are

- defined in the inttypes.h and stdint.h headers since attempts to use these

- types have shown that support for them is still highly variable.  However,

- since the latter are of the form uint<nn>_t, a regular expression search

- and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')

- can be used to convert the types used here to the C99 standard types.

-*/

-

-#ifndef _BRG_TYPES_H

-#define _BRG_TYPES_H

-

-#if defined(__cplusplus)

-extern "C" {

-#endif

-

-#include <limits.h>

-

-#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )

-#  include <stddef.h>

-#  define ptrint_t intptr_t

-#elif defined( __ECOS__ )

-#  define intptr_t unsigned int

-#  define ptrint_t intptr_t

-#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 )

-#  include <stdint.h>

-#  define ptrint_t intptr_t

-#else

-#  define ptrint_t int

-#endif

-

-#ifndef BRG_UI8

-#  define BRG_UI8

-#  if UCHAR_MAX == 255u

-     typedef unsigned char uint_8t;

-#  else

-#    error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h

-#  endif

-#endif

-

-#ifndef BRG_UI16

-#  define BRG_UI16

-#  if USHRT_MAX == 65535u

-     typedef unsigned short uint_16t;

-#  else

-#    error Please define uint_16t as a 16-bit unsigned short type in brg_types.h

-#  endif

-#endif

-

-#ifndef BRG_UI32

-#  define BRG_UI32

-#  if UINT_MAX == 4294967295u

-#    define li_32(h) 0x##h##u

-     typedef unsigned int uint_32t;

-#  elif ULONG_MAX == 4294967295u

-#    define li_32(h) 0x##h##ul

-     typedef unsigned long uint_32t;

-#  elif defined( _CRAY )

-#    error This code needs 32-bit data types, which Cray machines do not provide

-#  else

-#    error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h

-#  endif

-#endif

-

-#ifndef BRG_UI64

-#  if defined( __BORLANDC__ ) && !defined( __MSDOS__ )

-#    define BRG_UI64

-#    define li_64(h) 0x##h##ui64

-     typedef unsigned __int64 uint_64t;

-#  elif defined( _MSC_VER ) && ( _MSC_VER < 1300 )    /* 1300 == VC++ 7.0 */

-#    define BRG_UI64

-#    define li_64(h) 0x##h##ui64

-     typedef unsigned __int64 uint_64t;

-#  elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful

-#    define BRG_UI64

-#    define li_64(h) 0x##h##ull

-     typedef unsigned long long uint_64t;

-#  elif defined( __MVS__ )

-#    define BRG_UI64

-#    define li_64(h) 0x##h##ull

-     typedef unsigned int long long uint_64t;

-#  elif defined( UINT_MAX ) && UINT_MAX > 4294967295u

-#    if UINT_MAX == 18446744073709551615u

-#      define BRG_UI64

-#      define li_64(h) 0x##h##u

-       typedef unsigned int uint_64t;

-#    endif

-#  elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u

-#    if ULONG_MAX == 18446744073709551615ul

-#      define BRG_UI64

-#      define li_64(h) 0x##h##ul

-       typedef unsigned long uint_64t;

-#    endif

-#  elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u

-#    if ULLONG_MAX == 18446744073709551615ull

-#      define BRG_UI64

-#      define li_64(h) 0x##h##ull

-       typedef unsigned long long uint_64t;

-#    endif

-#  elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u

-#    if ULONG_LONG_MAX == 18446744073709551615ull

-#      define BRG_UI64

-#      define li_64(h) 0x##h##ull

-       typedef unsigned long long uint_64t;

-#    endif

-#  endif

-#endif

-

-#if !defined( BRG_UI64 )

-#  if defined( NEED_UINT_64T )

-#    error Please define uint_64t as an unsigned 64 bit type in brg_types.h

-#  endif

-#endif

-

-#ifndef RETURN_VALUES

-#  define RETURN_VALUES

-#  if defined( DLL_EXPORT )

-#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )

-#      define VOID_RETURN    __declspec( dllexport ) void __stdcall

-#      define INT_RETURN     __declspec( dllexport ) int  __stdcall

-#    elif defined( __GNUC__ )

-#      define VOID_RETURN    __declspec( __dllexport__ ) void

-#      define INT_RETURN     __declspec( __dllexport__ ) int

-#    else

-#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers

-#    endif

-#  elif defined( DLL_IMPORT )

-#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )

-#      define VOID_RETURN    __declspec( dllimport ) void __stdcall

-#      define INT_RETURN     __declspec( dllimport ) int  __stdcall

-#    elif defined( __GNUC__ )

-#      define VOID_RETURN    __declspec( __dllimport__ ) void

-#      define INT_RETURN     __declspec( __dllimport__ ) int

-#    else

-#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers

-#    endif

-#  elif defined( __WATCOMC__ )

-#    define VOID_RETURN  void __cdecl

-#    define INT_RETURN   int  __cdecl

-#  else

-#    define VOID_RETURN  void

-#    define INT_RETURN   int

-#  endif

-#endif

-

-/*	These defines are used to detect and set the memory alignment of pointers.

-    Note that offsets are in bytes.

-

-    ALIGN_OFFSET(x,n)			return the positive or zero offset of 

-                                the memory addressed by the pointer 'x' 

-                                from an address that is aligned on an 

-                                'n' byte boundary ('n' is a power of 2)

-

-    ALIGN_FLOOR(x,n)			return a pointer that points to memory

-                                that is aligned on an 'n' byte boundary 

-                                and is not higher than the memory address

-                                pointed to by 'x' ('n' is a power of 2)

-

-    ALIGN_CEIL(x,n)				return a pointer that points to memory

-                                that is aligned on an 'n' byte boundary 

-                                and is not lower than the memory address

-                                pointed to by 'x' ('n' is a power of 2)

-*/

-

-#define ALIGN_OFFSET(x,n)	(((ptrint_t)(x)) & ((n) - 1))

-#define ALIGN_FLOOR(x,n)	((uint_8t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))

-#define ALIGN_CEIL(x,n)		((uint_8t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))

-

-/*  These defines are used to declare buffers in a way that allows

-    faster operations on longer variables to be used.  In all these

-    defines 'size' must be a power of 2 and >= 8. NOTE that the 

-    buffer size is in bytes but the type length is in bits

-

-    UNIT_TYPEDEF(x,size)        declares a variable 'x' of length 

-                                'size' bits

-

-    BUFR_TYPEDEF(x,size,bsize)  declares a buffer 'x' of length 'bsize' 

-                                bytes defined as an array of variables

-                                each of 'size' bits (bsize must be a 

-                                multiple of size / 8)

-

-    UNIT_CAST(x,size)           casts a variable to a type of 

-                                length 'size' bits

-

-    UPTR_CAST(x,size)           casts a pointer to a pointer to a 

-                                varaiable of length 'size' bits

-*/

-

-#define UI_TYPE(size)               uint_##size##t

-#define UNIT_TYPEDEF(x,size)        typedef UI_TYPE(size) x

-#define BUFR_TYPEDEF(x,size,bsize)  typedef UI_TYPE(size) x[bsize / (size >> 3)]

-#define UNIT_CAST(x,size)           ((UI_TYPE(size) )(x))  

-#define UPTR_CAST(x,size)           ((UI_TYPE(size)*)(x))

-

-#if defined(__cplusplus)

-}

-#endif

-

-#endif

diff --git a/jni/libzrtp/sources/demo/CMakeLists.txt b/jni/libzrtp/sources/demo/CMakeLists.txt
index c253d9f..8db3c63 100755
--- a/jni/libzrtp/sources/demo/CMakeLists.txt
+++ b/jni/libzrtp/sources/demo/CMakeLists.txt
@@ -1,27 +1,15 @@
+########### next target ###############
 
-#to make sure includes are first taken - it contains config.h
-include_directories(BEFORE ${CMAKE_BINARY_DIR})
-include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
-                     ${CMAKE_SOURCE_DIR}/zrtp
-                     ${CMAKE_SOURCE_DIR}/clients/ccrtp)
+add_executable(zrtptest zrtptest.cpp)
+target_link_libraries(zrtptest zrtpcpp)
+add_dependencies(zrtptest zrtpcpp)
 
-if (CCRTP)
-    ########### next target ###############
+########### next target ###############
 
-    add_executable(zrtptest zrtptest.cpp)
-    target_link_libraries(zrtptest ${zrtplibName})
-    add_dependencies(zrtptest ${zrtplibName})
+add_executable(zrtptestMulti zrtptestMulti.cpp)
+target_link_libraries(zrtptestMulti zrtpcpp)
+add_dependencies(zrtptestMulti zrtpcpp)
 
-    ########### next target ###############
-
-    add_executable(zrtptestMulti zrtptestMulti.cpp)
-    target_link_libraries(zrtptestMulti ${zrtplibName})
-    add_dependencies(zrtptestMulti ${zrtplibName})
-else()
-    add_executable(sdestest sdestest.cpp)
-    target_link_libraries(sdestest ${zrtplibName})
-    add_dependencies(sdestest ${zrtplibName})
-endif()
 ########### next target ###############
 
 #add_executable(wrappertest wrappertest.c)
diff --git a/jni/libzrtp/sources/demo/sdestest.cpp b/jni/libzrtp/sources/demo/sdestest.cpp
deleted file mode 100644
index a329e8d..0000000
--- a/jni/libzrtp/sources/demo/sdestest.cpp
+++ /dev/null
@@ -1,231 +0,0 @@
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <crypto/hmac256.h>
-
-/*
-HKDF-Expand(PRK, info, L)
-
-Description in RFC 5869
-
-   HKDF-Expand(PRK, info, L) -> OKM
-
-   Options:
-      Hash     a hash function; HashLen denotes the length of the
-               hash function output in octets
-   Inputs:
-      PRK      a pseudorandom key of at least HashLen octets
-               (usually, the output from the extract step)
-      info     optional context and application specific information
-               (can be a zero-length string)
-      L        length of output keying material in octets
-               (<= 255*HashLen)
-
-   Output:
-      OKM      output keying material (of L octets)
-
-   The output OKM is calculated as follows:
-
-   N = ceil(L/HashLen)
-   T = T(1) | T(2) | T(3) | ... | T(N)
-   OKM = first L octets of T
-
-   where:
-   T(0) = empty string (zero length)
-   T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
-   T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
-   T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
-   ...
-
-   (where the constant concatenated to the end of each T(n) is a
-   single octet.)
-
-
-   A.1.  Test Case 1
-
-   Basic test case with SHA-256
-
-   Hash = SHA-256
-   IKM  = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b (22 octets)
-   salt = 0x000102030405060708090a0b0c (13 octets)
-   info = 0xf0f1f2f3f4f5f6f7f8f9 (10 octets)
-   L    = 42
-
-   PRK  = 0x077709362c2e32df0ddc3f0dc47bba63
-          90b6c73bb50f9c3122ec844ad7c2b3e5 (32 octets)
-   OKM  = 0x3cb25f25faacd57a90434f64d0362f2a
-          2d2d0a90cf1a5a4c5db02d56ecc4c5bf
-          34007208d5b887185865 (42 octets)
-
-A.2.  Test Case 2
-
-   Test with SHA-256 and longer inputs/outputs
-
-   Hash = SHA-256
-   IKM  = 0x000102030405060708090a0b0c0d0e0f
-          101112131415161718191a1b1c1d1e1f
-          202122232425262728292a2b2c2d2e2f
-          303132333435363738393a3b3c3d3e3f
-          404142434445464748494a4b4c4d4e4f (80 octets)
-   salt = 0x606162636465666768696a6b6c6d6e6f
-          707172737475767778797a7b7c7d7e7f
-          808182838485868788898a8b8c8d8e8f
-          909192939495969798999a9b9c9d9e9f
-          a0a1a2a3a4a5a6a7a8a9aaabacadaeaf (80 octets)
-   info = 0xb0b1b2b3b4b5b6b7b8b9babbbcbdbebf
-          c0c1c2c3c4c5c6c7c8c9cacbcccdcecf
-          d0d1d2d3d4d5d6d7d8d9dadbdcdddedf
-          e0e1e2e3e4e5e6e7e8e9eaebecedeeef
-          f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff (80 octets)
-   L    = 82
-
-   PRK  = 0x06a6b88c5853361a06104c9ceb35b45c
-          ef760014904671014a193f40c15fc244 (32 octets)
-   OKM  = 0xb11e398dc80327a1c8e7f78c596a4934
-          4f012eda2d4efad8a050cc4c19afa97c
-          59045a99cac7827271cb41c65e590e09
-          da3275600c2f09b8367793a9aca3db71
-          cc30c58179ec3e87c14c01d5c1f3434f
-          1d87 (82 octets)
-
-A.3.  Test Case 3
-
-   Test with SHA-256 and zero-length salt/info
-
-   Hash = SHA-256
-   IKM  = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b (22 octets)
-   salt = (0 octets)
-   info = (0 octets)
-   L    = 42
-
-   PRK  = 0x19ef24a32c717b167f33a91d6f648bdf
-          96596776afdb6377ac434c1c293ccb04 (32 octets)
-   OKM  = 0x8da4e775a563c18f715f802a063c5a31
-          b8a11f5c5ee1879ec3454e5f3c738d2d
-          9d201395faa4b61a96c8 (42 octets)
-
-*/
-
-static void hexdump(const char* title, const unsigned char *s, int l)
-{
-    int n=0;
-
-    if (s == NULL) return;
-
-    fprintf(stderr, "%s",title);
-    for( ; n < l ; ++n) {
-        if((n%16) == 0)
-            fprintf(stderr, "\n%04x",n);
-        fprintf(stderr, " %02x",s[n]);
-    }
-    fprintf(stderr, "\n");
-}
-
-
-static uint8_t info_A1[] = {
-    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9};
-
-static int32_t L_A1 = 42;
-
-static uint8_t PRK_A1[] = {
-    0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f, 0x0d, 0xc4, 0x7b, 0xba, 0x63,
-    0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31, 0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5};
-
-static uint8_t OKM_A1[] = {
-    0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64, 0xd0, 0x36, 0x2f, 0x2a,
-    0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c, 0x5d, 0xb0, 0x2d, 0x56, 0xec, 0xc4, 0xc5, 0xbf,
-    0x34, 0x00, 0x72, 0x08, 0xd5, 0xb8, 0x87, 0x18, 0x58, 0x65}; // (42 octets)
-
-
-static int32_t L_A3 = 42;
-
-static uint8_t PRK_A3[] = {
-    0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9, 0x1d, 0x6f, 0x64, 0x8b, 0xdf,
-    0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77, 0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04};   // (32 octets)
-
-static uint8_t OKM_A3[] = {
-    0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31,
-    0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d,
-    0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8};  // (42 octets)
-
-
-    
-void* createSha256HmacContext(uint8_t* key, int32_t keyLength);
-void freeSha256HmacContext(void* ctx);
-void hmacSha256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength );
-
-
-static int expand(uint8_t* prk, uint32_t prkLen, uint8_t* info, int32_t infoLen, int32_t L, uint32_t hashLen, uint8_t* outbuffer)
-{
-    int32_t n;
-    uint8_t *T;
-    void* hmacCtx;
-
-    const uint8_t* data[4];      // Data pointers for HMAC data, max. 3 plus terminating NULL
-    uint32_t dataLen[4];
-    int32_t dataIdx = 0;
-
-    uint8_t counter;
-    int32_t macLength;
-
-    if (prkLen < hashLen)
-        return -1;
-
-    n = (L + (hashLen-1)) / hashLen;
-
-    // T points to buffer that holds concatenated T(1) || T(2) || ... T(N))
-    T = reinterpret_cast<uint8_t*>(malloc(n * hashLen));
-
-    // Prepare the HMAC
-    hmacCtx = createSha256HmacContext(prk, prkLen);
-
-    // Prepare first HMAC. T(0) has zero length, thus we ignore it in first run.
-    // After first run use its output (T(1)) as first data in next HMAC run.
-    for (int i = 1; i <= n; i++) {
-        if (infoLen > 0 && info != NULL) {
-            data[dataIdx] = info;
-            dataLen[dataIdx++] = infoLen;
-        }
-        counter = i & 0xff;
-        data[dataIdx] = &counter;
-        dataLen[dataIdx++] = 1;
-
-        data[dataIdx] = NULL;
-        dataLen[dataIdx++] = 0;
-
-        hmacSha256Ctx(hmacCtx, data, dataLen, T + ((i-1) * hashLen), &macLength);
-
-        dataIdx = 0;
-        data[dataIdx] = T + ((i-1) * hashLen);
-        dataLen[dataIdx++] = hashLen;
-    }
-    freeSha256HmacContext(hmacCtx);
-    memcpy(outbuffer, T, L);
-    free(T);
-    return 0;
-}
-
-int main(int argc, char *argv[])
-{
-    uint8_t buffer[500];
-    expand(PRK_A1, sizeof(PRK_A1), info_A1, sizeof(info_A1), L_A1, SHA256_DIGEST_LENGTH, buffer);
-    if (memcmp(buffer, OKM_A1, L_A1) != 0) {
-        fprintf(stderr, "ERROR: Test result A1 mismatch");
-        hexdump("Computed result of expand A1", buffer, L_A1);
-        hexdump("Expected result of expand A1", OKM_A1, L_A1);
-        return 1;
-    }
-
-    expand(PRK_A3, sizeof(PRK_A3), NULL, 0, L_A3, SHA256_DIGEST_LENGTH, buffer);
-    if (memcmp(buffer, OKM_A3, L_A3) != 0) {
-        fprintf(stderr, "ERROR: Test result A3 mismatch");
-        hexdump("Computed result of expand A3", buffer, L_A3);
-        hexdump("Expected result of expand A3", OKM_A3, L_A3);
-        return 1;
-    }
-
-    printf("Done\n");
-    return 0;
-}
diff --git a/jni/libzrtp/sources/demo/zrtptest.cpp b/jni/libzrtp/sources/demo/zrtptest.cpp
index 0595543..394d31c 100644
--- a/jni/libzrtp/sources/demo/zrtptest.cpp
+++ b/jni/libzrtp/sources/demo/zrtptest.cpp
@@ -18,7 +18,7 @@
 
 #include <cstdlib>
 #include <map>
-#include <zrtpccrtp.h>
+#include <libzrtpcpp/zrtpccrtp.h>
 #include <libzrtpcpp/ZrtpUserCallback.h>
 
 using namespace ost;
@@ -28,36 +28,40 @@
 class PacketsPattern
 {
 public:
-    inline const InetHostAddress& getReceiverAddress() const { return *receiverAddress; }
-    inline const InetHostAddress& getSenderAddress()   const { return *senderAddress; }
+    inline const InetHostAddress&
+    getDestinationAddress() const
+    { return destinationAddress; }
 
-    inline void setReceiverAddress(InetHostAddress *addr) const { delete receiverAddress; receiverAddress = addr; }
-    inline void setSenderAddress(InetHostAddress *addr)   const { delete senderAddress; senderAddress = addr; }
+    inline const tpport_t
+    getDestinationPort() const
+    { return destinationPort; }
 
-    inline const tpport_t getReceiverPort() const { return receiverPort; }
-    inline const tpport_t getSenderPort()   const { return senderPort; }
+    uint32
+    getPacketsNumber() const
+    { return packetsNumber; }
 
-    uint32 getPacketsNumber() const  { return packetsNumber; }
+    uint32
+    getSsrc() const
+    { return 0xdeadbeef; }
 
-    uint32 getSsrc() const  { return 0xdeadbeef; }
+    const unsigned char*
+    getPacketData(uint32 i)
+    { return data[i%2]; }
 
-    const unsigned char*getPacketData(uint32 i) { return data[i%2]; }
-
-    const size_t getPacketSize(uint32 i) { return strlen((char*)data[i%2]) + 1 ; }
+    const size_t
+    getPacketSize(uint32 i)
+    { return strlen((char*)data[i%2]) + 1 ; }
 
 private:
-    static const InetHostAddress *receiverAddress;
-    static const InetHostAddress *senderAddress;
-
-    static const uint16 receiverPort = 5002;
-    static const uint16 senderPort = 5004;
+    static const InetHostAddress destinationAddress;
+    static const uint16 destinationPort = 5002;
     static const uint32 packetsNumber = 10;
     static const uint32 packetsSize = 12;
     static const unsigned char* data[];
 };
 
-const InetHostAddress *PacketsPattern::receiverAddress = new InetHostAddress("localhost");
-const InetHostAddress *PacketsPattern::senderAddress = new InetHostAddress("localhost");
+const InetHostAddress PacketsPattern::destinationAddress =
+    InetHostAddress("localhost");
 
 const unsigned char* PacketsPattern::data[] = {
     (unsigned char*)"0123456789\n",
@@ -111,13 +115,6 @@
 };
 
 
-/*
- * The following classes use:
- * - localAddress and destination port+2 for the sender classes
- * - destinationAddress and destination port for the receiver classes.
- * 
- */
-
 /**
  * SymmetricZRTPSession in non-security mode (RTPSession compatible).
  *
@@ -135,7 +132,7 @@
     int doTest() {
         // should be valid?
         //RTPSession tx();
-        ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
+        ExtZrtpSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
 //        SymmetricZRTPSession tx(pattern.getSsrc(), InetHostAddress("localhost"));
         tx.setSchedulingTimeout(10000);
         tx.setExpireTimeout(1000000);
@@ -143,9 +140,8 @@
         tx.startRunning();
 
         tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
-
-        // We are sender:
-        if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
+        if (!tx.addDestination(pattern.getDestinationAddress(),
+                               pattern.getDestinationPort()) ) {
             return 1;
         }
 
@@ -178,7 +174,8 @@
 
     int
     doTest() {
-        ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
+        ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
+                                pattern.getDestinationPort());
 
 //         SymmetricZRTPSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
 //                                 pattern.getDestinationPort());
@@ -188,7 +185,8 @@
         rx.startRunning();
         rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
         // arbitrary number of loops to provide time to start transmitter
-        if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
+        if (!rx.addDestination(pattern.getDestinationAddress(),
+                               pattern.getDestinationPort()+2) ) {
             return 1;
         }
         for ( int i = 0; i < 5000 ; i++ ) {
@@ -227,8 +225,8 @@
     int doTest() {
         // should be valid?
         //RTPSession tx();
-        // Initialize with local address and Local port is detination port +2 - keep RTP/RTCP port pairs
-        ExtZrtpSession tx(pattern.getSsrc(), pattern.getSenderAddress(), pattern.getSenderPort());
+        ExtZrtpSession tx(pattern.getSsrc(), pattern.getDestinationAddress(),
+                                pattern.getDestinationPort()+2);
         tx.initialize("test_t.zid");
 
         tx.setSchedulingTimeout(10000);
@@ -237,7 +235,8 @@
         tx.startRunning();
 
         tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
-        if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
+        if (!tx.addDestination(pattern.getDestinationAddress(),
+                               pattern.getDestinationPort()) ) {
             return 1;
         }
         tx.startZrtp();
@@ -269,7 +268,8 @@
 
     int
     doTest() {
-        ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getReceiverAddress(), pattern.getReceiverPort());
+        ExtZrtpSession rx(pattern.getSsrc()+1, pattern.getDestinationAddress(),
+                                pattern.getDestinationPort());
 
         rx.initialize("test_r.zid");
 
@@ -279,7 +279,8 @@
         rx.startRunning();
         rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
         // arbitrary number of loops to provide time to start transmitter
-        if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
+        if (!rx.addDestination(pattern.getDestinationAddress(),
+                               pattern.getDestinationPort()+2) ) {
             return 1;
         }
         rx.startZrtp();
@@ -344,8 +345,6 @@
         warningMap.insert(pair<int32, std::string*>(WarningCRCmismatch, new string("Internal ZRTP packet checksum mismatch - packet dropped")));
         warningMap.insert(pair<int32, std::string*>(WarningSRTPauthError, new string("Dropping packet because SRTP authentication failed!")));
         warningMap.insert(pair<int32, std::string*>(WarningSRTPreplayError, new string("Dropping packet because SRTP replay check failed!")));
-        warningMap.insert(pair<int32, std::string*>(WarningNoExpectedRSMatch, new string("No RS match found - but ZRTP expected a match.")));
-        warningMap.insert(pair<int32, std::string*>(WarningNoExpectedAuxMatch, new string("The auxlliary secrets do not match.")));
 
         severeMap.insert(pair<int32, std::string*>(SevereHelloHMACFailed, new string("Hash HMAC check of Hello failed!")));
         severeMap.insert(pair<int32, std::string*>(SevereCommitHMACFailed, new string("Hash HMAC check of Commit failed!")));
@@ -451,8 +450,6 @@
 
 bool MyUserCallback::initialized = false;
 
-static unsigned char transmAuxSecret[] = {1,2,3,4,5,6,7,8,9,0};
-
 /**
  * SymmetricZRTPSession in security mode and using a callback class.
  *
@@ -468,55 +465,26 @@
 ZrtpSendPacketTransmissionTestCB : public Thread, public TimerPort
 {
 public:
-
-    ZrtpConfigure config;
-
-    void run() {
+    void
+    run()
+    {
         doTest();
     }
 
-    int doTest() {
+    int doTest()
+    {
         // should be valid?
         //RTPSession tx();
-        ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getSenderAddress(), pattern.getSenderPort());
-        config.clear();
-//        config.setStandardConfig();
-//         config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH2k"));
-//         config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
-
-        // This ordering prefers NIST
-        config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
-        config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
-
-        config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC25"));
-        config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E255"));
-
-        config.addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
-        config.addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
-
-        config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
-        config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
-
-        config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
-
-        config.addAlgo(AuthLength, zrtpAuthLengths.getByName("HS32"));
-        config.addAlgo(AuthLength, zrtpAuthLengths.getByName("HS80"));
-        config.addAlgo(AuthLength, zrtpAuthLengths.getByName("SK32"));
-        config.addAlgo(AuthLength, zrtpAuthLengths.getByName("SK64"));
-
-        tx.initialize("test_t.zid", true, &config);
+        ExtZrtpSession tx(/*pattern.getSsrc(),*/ pattern.getDestinationAddress(),
+                                pattern.getDestinationPort()+2);
+        tx.initialize("test_t.zid");
         // At this point the Hello hash is available. See ZRTP specification
         // chapter 9.1 for further information when an how to use the Hello
         // hash.
-        int numSupportedVersion = tx.getNumberSupportedVersions();
-        cout << "TX Hello hash 0: " << tx.getHelloHash(0) << endl;
-        cout << "TX Hello hash 0 length: " << tx.getHelloHash(0).length() << endl;
-        if (numSupportedVersion > 1) {
-            cout << "TX Hello hash 1: " << tx.getHelloHash(1) << endl;
-            cout << "TX Hello hash 1 length: " << tx.getHelloHash(1).length() << endl;
-        }
+        cout << "TX Hello hash: " << tx.getHelloHash() << endl;
+        cout << "TX Hello hash length: " << tx.getHelloHash().length() << endl;
+
         tx.setUserCallback(new MyUserCallback(&tx));
-        tx.setAuxSecret(transmAuxSecret, sizeof(transmAuxSecret));
 
         tx.setSchedulingTimeout(10000);
         tx.setExpireTimeout(1000000);
@@ -524,8 +492,8 @@
         tx.startRunning();
 
         tx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
-
-        if (!tx.addDestination(pattern.getReceiverAddress(), pattern.getReceiverPort()) ) {
+        if (!tx.addDestination(pattern.getDestinationAddress(),
+                               pattern.getDestinationPort()) ) {
             return 1;
         }
         tx.startZrtp();
@@ -549,49 +517,29 @@
     }
 };
 
-static unsigned char recvAuxSecret[] = {1,2,3,4,5,6,7,8,9,9};
 
 class
 ZrtpRecvPacketTransmissionTestCB: public Thread
 {
 public:
-    ZrtpConfigure config;
-
-    void run() {
+    void
+    run() {
         doTest();
     }
 
-    int doTest() {
-        ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getReceiverAddress(), pattern.getReceiverPort());
-        config.clear();
-//        config.setStandardConfig();
-//         config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("DH3k"));
+    int
+    doTest() {
+        ExtZrtpSession rx( /*pattern.getSsrc()+1,*/ pattern.getDestinationAddress(),
+                                pattern.getDestinationPort());
 
-         config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("E414"));
-         config.addAlgo(PubKeyAlgorithm, zrtpPubKeys.getByName("EC38"));
-
-         config.addAlgo(HashAlgorithm, zrtpHashes.getByName("S384"));
-         config.addAlgo(HashAlgorithm, zrtpHashes.getByName("SKN3"));
-
-//          config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("2FS3"));
-//          config.addAlgo(CipherAlgorithm, zrtpSymCiphers.getByName("AES3"));
-
-        config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
-
-
-        rx.initialize("test_r.zid", true, &config);
+        rx.initialize("test_r.zid");
         // At this point the Hello hash is available. See ZRTP specification
         // chapter 9.1 for further information when an how to use the Hello
         // hash.
-        int numSupportedVersion = rx.getNumberSupportedVersions();
-        cout << "RX Hello hash 0: " << rx.getHelloHash(0) << endl;
-        cout << "RX Hello hash 0 length: " << rx.getHelloHash(0).length() << endl;
-        if (numSupportedVersion > 1) {
-            cout << "RX Hello hash 1: " << rx.getHelloHash(1) << endl;
-            cout << "RX Hello hash 1 length: " << rx.getHelloHash(1).length() << endl;
-        }
+        cout << "RX Hello hash: " << rx.getHelloHash() << endl;
+        cout << "RX Hello hash length: " << rx.getHelloHash().length() << endl;
+
         rx.setUserCallback(new MyUserCallback(&rx));
-        rx.setAuxSecret(recvAuxSecret, sizeof(recvAuxSecret));
 
         rx.setSchedulingTimeout(10000);
         rx.setExpireTimeout(1000000);
@@ -599,7 +547,8 @@
         rx.startRunning();
         rx.setPayloadFormat(StaticPayloadFormat(sptPCMU));
         // arbitrary number of loops to provide time to start transmitter
-        if (!rx.addDestination(pattern.getSenderAddress(), pattern.getSenderPort()) ) {
+        if (!rx.addDestination(pattern.getDestinationAddress(),
+                               pattern.getDestinationPort()+2) ) {
             return 1;
         }
         rx.startZrtp();
@@ -631,7 +580,7 @@
 
     /* check args */
     while (1) {
-        c = getopt(argc, argv, "rsR:S:");
+        c = getopt(argc, argv, "rs");
         if (c == -1) {
             break;
         }
@@ -642,12 +591,6 @@
         case 's':
             send = true;
             break;
-        case 'R':
-            pattern.setReceiverAddress(new InetHostAddress(optarg));
-            break;
-        case 'S':
-            pattern.setSenderAddress(new InetHostAddress(optarg));
-            break;
         default:
             cerr << "Wrong Arguments, only -s and -r are accepted" << endl;
         }
diff --git a/jni/libzrtp/sources/demo/zrtptestMulti.cpp b/jni/libzrtp/sources/demo/zrtptestMulti.cpp
index d7042ed..39e20a7 100644
--- a/jni/libzrtp/sources/demo/zrtptestMulti.cpp
+++ b/jni/libzrtp/sources/demo/zrtptestMulti.cpp
@@ -18,7 +18,7 @@
 
 #include <cstdlib>
 #include <map>
-#include <zrtpccrtp.h>
+#include <libzrtpcpp/zrtpccrtp.h>
 #include <libzrtpcpp/ZrtpUserCallback.h>
 #include <libzrtpcpp/ZrtpConfigure.h>
 
@@ -488,8 +488,7 @@
     if (!multiParams.empty()) {
         tx = new SymmetricZRTPSession(pattern.getDestinationAddress(),
                                       pattern.getDestinationPort()+2+10);
-
-        //            tx->initialize("test_t.zid", true, &config);
+//            tx->initialize("test_t.zid", true, &config);
         tx->initialize("test_t.zid", true);
         tx->setMultiStrParams(multiParams);
 
@@ -500,12 +499,13 @@
     else {
         tx = new SymmetricZRTPSession(pattern.getDestinationAddress(),
                                       pattern.getDestinationPort()+2);
+        //config.addHashAlgo(Sha384);
+//            tx->initialize("test_t.zid", true, &config);
         if (mitm) {                      // Act as trusted MitM - could be enrolled
             tx->setMitmMode(true);
         }
 
         tx->setSignSas(signsas);
-//            tx->initialize("test_t.zid", true, &config);
         tx->initialize("test_t.zid", true);
 
         if (enroll)                     // act as PBX enrollement service
@@ -518,13 +518,8 @@
     // At this point the Hello hash is available. See ZRTP specification
     // chapter 9.1 for further information when an how to use the Hello
     // hash.
-    int numSupportedVersion = tx->getNumberSupportedVersions();
-    cout << "TX Hello hash 0: " << tx->getHelloHash(0) << endl;
-    cout << "TX Hello hash 0 length: " << tx->getHelloHash(0).length() << endl;
-    if (numSupportedVersion > 1) {
-        cout << "TX Hello hash 1: " << tx->getHelloHash(1) << endl;
-        cout << "TX Hello hash 1 length: " << tx->getHelloHash(1).length() << endl;
-    }
+    cout << prefix << "Hello hash: " << tx->getHelloHash() << endl;
+    cout << prefix << "Hello hash length: " << tx->getHelloHash().length() << endl;
     tx->setUserCallback(mcb);
     tx->setSchedulingTimeout(10000);
     tx->setExpireTimeout(1000000);
@@ -588,14 +583,12 @@
         rx = new SymmetricZRTPSession(pattern.getDestinationAddress(),
                                       pattern.getDestinationPort());
         config.setStandardConfig();
-//        config.clear();
-//        config.addAlgo(SasType, zrtpSasTypes.getByName("B256"));
-
         if (enroll)
             config.setTrustedMitM(true);                // allow a trusted MitM to start enrollment process
 
         rx->setSignSas(signsas);
 
+        // config.addHashAlgo(Sha384);
         rx->initialize("test_r.zid", true, &config);
 //            rx->initialize("test_r.zid", true);
 
@@ -606,13 +599,8 @@
     // At this point the Hello hash is available. See ZRTP specification
     // chapter 9.1 for further information when an how to use the Hello
     // hash.
-    int numSupportedVersion = rx->getNumberSupportedVersions();
-    cout << "RX Hello hash 0: " << rx->getHelloHash(0) << endl;
-    cout << "RX Hello hash 0 length: " << rx->getHelloHash(0).length() << endl;
-    if (numSupportedVersion > 1) {
-        cout << "RX Hello hash 1: " << rx->getHelloHash(1) << endl;
-        cout << "RX Hello hash 1 length: " << rx->getHelloHash(1).length() << endl;
-    }
+    cout << prefix << "Hello hash: " << rx->getHelloHash() << endl;
+    cout << prefix << "Hello hash length: " << rx->getHelloHash().length() << endl;
     rx->setUserCallback(mcb);
     rx->setSchedulingTimeout(10000);
     rx->setExpireTimeout(1000000);
diff --git a/jni/libzrtp/sources/doc/Doxymini b/jni/libzrtp/sources/doc/Doxymini
index 245ff07..2685d6e 100644
--- a/jni/libzrtp/sources/doc/Doxymini
+++ b/jni/libzrtp/sources/doc/Doxymini
@@ -1,243 +1,211 @@
-# Doxyfile 1.7.5.1
+# Doxyfile 1.5.3
 
 # This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project.
+# doxygen (www.doxygen.org) for a project
 #
-# All text after a hash (#) is considered a comment and will be ignored.
+# All text after a hash (#) is considered a comment and will be ignored
 # The format is:
 #       TAG = value [value, ...]
 # For lists items can also be appended using:
 #       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ").
+# Values that contain spaces should be placed between quotes (" ")
 
 #---------------------------------------------------------------------------
 # Project related configuration options
 #---------------------------------------------------------------------------
 
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
+# This tag specifies the encoding used for all characters in the config file that 
+# follow. The default is UTF-8 which is also the encoding used for all text before 
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into 
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of 
+# possible encodings.
 
 DOXYFILE_ENCODING      = UTF-8
 
-# The PROJECT_NAME tag is a single word (or sequence of words) that should
-# identify the project. Note that if you do not use Doxywizard you need
-# to put quotes around the project name if it contains spaces.
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
 
-PROJECT_NAME           = "ZRTP and SRTP implementation"
+PROJECT_NAME           = "ZRTP for ccRTP "
 
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
 # if some version control system is used.
 
-PROJECT_NUMBER         =
+PROJECT_NUMBER         = 
 
-# Using the PROJECT_BRIEF tag one can provide an optional one line description
-# for a project that appears at the top of each page and should give viewer
-# a quick idea about the purpose of the project. Keep the description short.
-
-PROJECT_BRIEF          =
-
-# With the PROJECT_LOGO tag one can specify an logo or icon that is
-# included in the documentation. The maximum height of the logo should not
-# exceed 55 pixels and the maximum width should not exceed 200 pixels.
-# Doxygen will copy the logo to the output directory.
-
-PROJECT_LOGO           =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
 # where doxygen was started. If left blank the current directory will be used.
 
 OUTPUT_DIRECTORY       = .
 
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
 # otherwise cause performance problems for the file system.
 
 CREATE_SUBDIRS         = NO
 
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
 
 OUTPUT_LANGUAGE        = English
 
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
 # Set to NO to disable this.
 
 BRIEF_MEMBER_DESC      = YES
 
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
 # brief descriptions will be completely suppressed.
 
 REPEAT_BRIEF           = YES
 
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
 # "represents" "a" "an" "the"
 
-ABBREVIATE_BRIEF       =
+ABBREVIATE_BRIEF       = 
 
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
 # description.
 
 ALWAYS_DETAILED_SEC    = NO
 
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
 # operators of the base classes will not be shown.
 
 INLINE_INHERITED_MEMB  = NO
 
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
 # to NO the shortest path that makes the file name unique will be used.
 
 FULL_PATH_NAMES        = NO
 
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
 # path to strip.
 
-STRIP_FROM_PATH        =
+STRIP_FROM_PATH        = 
 
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
 # are normally passed to the compiler using the -I flag.
 
-STRIP_FROM_INC_PATH    =
+STRIP_FROM_INC_PATH    = 
 
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful if your file system
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
 # doesn't support long names like on DOS, Mac, or CD-ROM.
 
 SHORT_NAMES            = NO
 
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
 # (thus requiring an explicit @brief command for a brief description.)
 
 JAVADOC_AUTOBRIEF      = YES
 
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
 # an explicit \brief command for a brief description.)
 
 QT_AUTOBRIEF           = NO
 
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
 # description. Set this tag to YES if you prefer the old behaviour instead.
 
 MULTILINE_CPP_IS_BRIEF = NO
 
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
 # re-implements.
 
 INHERIT_DOCS           = NO
 
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
 # be part of the file/class/namespace that contains it.
 
 SEPARATE_MEMBER_PAGES  = NO
 
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
 # Doxygen uses this value to replace tabs by spaces in code fragments.
 
-TAB_SIZE               = 4
+TAB_SIZE               = 8
 
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
 # You can put \n's in the value part of an alias to insert newlines.
 
-ALIASES                =
+ALIASES                = 
 
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
 # of all members will be omitted, etc.
 
 OPTIMIZE_OUTPUT_FOR_C  = NO
 
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for
-# Java. For instance, namespaces will be presented as packages, qualified
-# scopes will look different, etc.
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
 
 OPTIMIZE_OUTPUT_JAVA   = NO
 
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources only. Doxygen will then generate output that is more tailored for
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN   = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL   = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given extension.
-# Doxygen has a built-in mapping, but you can override or extend it using this
-# tag. The format is ext=language, where ext is a file extension, and language
-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
-
-EXTENSION_MAPPING      =
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also makes the inheritance and collaboration
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
 # diagrams that involve STL classes more complete and accurate.
 
 BUILTIN_STL_SUPPORT    = NO
@@ -247,542 +215,406 @@
 
 CPP_CLI_SUPPORT        = NO
 
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
-# Doxygen will parse them like normal C++ but will assume all classes use public
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT            = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate getter
-# and setter methods for a property. Setting this option to YES (the default)
-# will make doxygen replace the get and set methods by a property in the
-# documentation. This will only work if the methods are indeed getting or
-# setting a simple type. If this is not the case, or you want to show the
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT   = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
 # all members of a group must be documented explicitly.
 
 DISTRIBUTE_GROUP_DOC   = NO
 
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
 # the \nosubgrouping command.
 
 SUBGROUPING            = YES
 
-# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and
-# unions are shown inside the group in which they are included (e.g. using
-# @ingroup) instead of on a separate page (for HTML and Man pages) or
-# section (for LaTeX and RTF).
-
-INLINE_GROUPED_CLASSES = NO
-
-# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and
-# unions with only public data fields will be shown inline in the documentation
-# of the scope in which they are defined (i.e. file, namespace, or group
-# documentation), provided this scope is documented. If set to NO (the default),
-# structs, classes, and unions are shown on a separate page (for HTML and Man
-# pages) or section (for LaTeX and RTF).
-
-INLINE_SIMPLE_STRUCTS  = NO
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
-# is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically
-# be useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT   = NO
-
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penalty.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will roughly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE      = 0
-
 #---------------------------------------------------------------------------
 # Build related configuration options
 #---------------------------------------------------------------------------
 
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
 # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
 
 EXTRACT_ALL            = YES
 
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
 # will be included in the documentation.
 
 EXTRACT_PRIVATE        = NO
 
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
 # will be included in the documentation.
 
-EXTRACT_STATIC         = YES
+EXTRACT_STATIC         = NO
 
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
 # If set to NO only classes defined in header files are included.
 
 EXTRACT_LOCAL_CLASSES  = YES
 
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
 # If set to NO (the default) only methods in the interface are included.
 
 EXTRACT_LOCAL_METHODS  = NO
 
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base
-# name of the file that contains the anonymous namespace. By default
-# anonymous namespaces are hidden.
+# If this flag is set to YES, the members of anonymous namespaces will be extracted 
+# and appear in the documentation as a namespace called 'anonymous_namespace{file}', 
+# where file will be replaced with the base name of the file that contains the anonymous 
+# namespace. By default anonymous namespace are hidden.
 
 EXTRACT_ANON_NSPACES   = NO
 
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
 # This option has no effect if EXTRACT_ALL is enabled.
 
 HIDE_UNDOC_MEMBERS     = NO
 
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
 # overviews. This option has no effect if EXTRACT_ALL is enabled.
 
 HIDE_UNDOC_CLASSES     = NO
 
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
 # documentation.
 
 HIDE_FRIEND_COMPOUNDS  = NO
 
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
 # function's detailed documentation block.
 
 HIDE_IN_BODY_DOCS      = NO
 
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
 # Set it to YES to include the internal documentation.
 
 INTERNAL_DOCS          = NO
 
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
 # and Mac users are advised to set this option to NO.
 
 CASE_SENSE_NAMES       = NO
 
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
 # documentation. If set to YES the scope will be hidden.
 
 HIDE_SCOPE_NAMES       = NO
 
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
 # of that file.
 
 SHOW_INCLUDE_FILES     = YES
 
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
-# will list include files with double quotes in the documentation
-# rather than with sharp brackets.
-
-FORCE_LOCAL_INCLUDES   = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
 # is inserted in the documentation for inline members.
 
 INLINE_INFO            = YES
 
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
 # declaration order.
 
 SORT_MEMBER_DOCS       = YES
 
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
 # declaration order.
 
 SORT_BRIEF_DOCS        = NO
 
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
-# will sort the (brief and detailed) documentation of class members so that
-# constructors and destructors are listed first. If set to NO (the default)
-# the constructors will appear in the respective orders defined by
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
-# hierarchy of group names into alphabetical order. If set to NO (the default)
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES       = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
 # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
+# Note: This option applies only to the class list, not to the 
 # alphabetical list.
 
 SORT_BY_SCOPE_NAME     = NO
 
-# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to
-# do proper type resolution of all parameters of a function it will reject a
-# match between the prototype and the implementation of a member function even
-# if there is only one candidate or it is obvious which candidate to choose
-# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen
-# will still accept a match between prototype and implementation in such cases.
-
-STRICT_PROTO_MATCHING  = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
 # commands in the documentation.
 
 GENERATE_TODOLIST      = YES
 
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
 # commands in the documentation.
 
 GENERATE_TESTLIST      = YES
 
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
 # commands in the documentation.
 
 GENERATE_BUGLIST       = YES
 
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
 # \deprecated commands in the documentation.
 
 GENERATE_DEPRECATEDLIST= YES
 
-# The ENABLED_SECTIONS tag can be used to enable conditional
+# The ENABLED_SECTIONS tag can be used to enable conditional 
 # documentation sections, marked by \if sectionname ... \endif.
 
-ENABLED_SECTIONS       =
+ENABLED_SECTIONS       = 
 
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or macro consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and macros in the
-# documentation can be controlled using \showinitializer or \hideinitializer
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
 # command in the documentation regardless of this setting.
 
 MAX_INITIALIZER_LINES  = 30
 
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
 # list will mention the files that were used to generate the documentation.
 
 SHOW_USED_FILES        = YES
 
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
 # in the documentation. The default is NO.
 
 SHOW_DIRECTORIES       = NO
 
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES             = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
-# Namespaces page.
-# This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES        = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
 # is used as the file version. See the manual for examples.
 
-FILE_VERSION_FILTER    =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. The create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option.
-# You can optionally specify a file name after the option, if omitted
-# DoxygenLayout.xml will be used as the name of the layout file.
-
-LAYOUT_FILE            =
-
-# The CITE_BIB_FILES tag can be used to specify one or more bib files
-# containing the references data. This must be a list of .bib files. The
-# .bib extension is automatically appended if omitted. Using this command
-# requires the bibtex tool to be installed. See also
-# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style
-# of the bibliography can be controlled using LATEX_BIB_STYLE.
-
-CITE_BIB_FILES         =
+FILE_VERSION_FILTER    = 
 
 #---------------------------------------------------------------------------
 # configuration options related to warning and progress messages
 #---------------------------------------------------------------------------
 
-# The QUIET tag can be used to turn on/off the messages that are generated
+# The QUIET tag can be used to turn on/off the messages that are generated 
 # by doxygen. Possible values are YES and NO. If left blank NO is used.
 
 QUIET                  = NO
 
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
 # NO is used.
 
 WARNINGS               = YES
 
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
 # automatically be disabled.
 
 WARN_IF_UNDOCUMENTED   = YES
 
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
 # don't exist or using markup commands wrongly.
 
 WARN_IF_DOC_ERROR      = YES
 
-# The WARN_NO_PARAMDOC option can be enabled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
 # documentation.
 
 WARN_NO_PARAMDOC       = NO
 
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
 # be obtained via FILE_VERSION_FILTER)
 
 WARN_FORMAT            = "$file:$line: $text"
 
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
 # to stderr.
 
-WARN_LOGFILE           =
+WARN_LOGFILE           = 
 
 #---------------------------------------------------------------------------
 # configuration options related to the input files
 #---------------------------------------------------------------------------
 
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
 # with spaces.
 
-INPUT                  = ../zrtp \
-                         ../zrtp/libzrtpcpp \
-                         ../zrtp/crypto \
-                         ../srtp \
-                         ../srtp/crypto \
-                         ../clients/ccrtp
+INPUT                  = ../src \
+                         ../src/libzrtpcpp \
+                         ../src/libzrtpcpp/crypto
 
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
-# also the default input encoding. Doxygen uses libiconv (or the iconv built
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
-# the list of possible encodings.
+# This tag can be used to specify the character encoding of the source files that 
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default 
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding. 
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
 
 INPUT_ENCODING         = UTF-8
 
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh
-# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py
-# *.f90 *.f *.for *.vhd *.vhdl
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
 
 FILE_PATTERNS          = *.h
 
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
 # If left blank NO is used.
 
 RECURSIVE              = NO
 
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
 # subdirectory from a directory tree whose root is specified with the INPUT tag.
-# Note that relative paths are relative to directory from which doxygen is run.
 
-EXCLUDE                =
+EXCLUDE                = 
 
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix file system feature) are excluded
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
 # from the input.
 
 EXCLUDE_SYMLINKS       = NO
 
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
 # for example use the pattern */test/*
 
 EXCLUDE_PATTERNS       = config.h \
                          macros.h \
                          namespace.h
 
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the output. 
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used, 
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
 
-EXCLUDE_SYMBOLS        =
+EXCLUDE_SYMBOLS        = 
 
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
 # the \include command).
 
-EXAMPLE_PATH           =
+EXAMPLE_PATH           = 
 
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
 # blank all files are included.
 
-EXAMPLE_PATTERNS       =
+EXAMPLE_PATTERNS       = 
 
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
 # Possible values are YES and NO. If left blank NO is used.
 
 EXAMPLE_RECURSIVE      = NO
 
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
 # the \image command).
 
-IMAGE_PATH             =
+IMAGE_PATH             = 
 
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-# If FILTER_PATTERNS is specified, this tag will be
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
 # ignored.
 
-INPUT_FILTER           =
+INPUT_FILTER           = 
 
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis.
-# Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match.
-# The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty or if
-# non of the patterns match the file name, INPUT_FILTER is applied.
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
 
-FILTER_PATTERNS        =
+FILTER_PATTERNS        = 
 
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
 # files to browse (i.e. when SOURCE_BROWSER is set to YES).
 
 FILTER_SOURCE_FILES    = NO
 
-# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
-# pattern. A pattern will override the setting for FILTER_PATTERN (if any)
-# and it is also possible to disable source filtering for a specific pattern
-# using *.ext= (so without naming a filter). This option only has effect when
-# FILTER_SOURCE_FILES is enabled.
-
-FILTER_SOURCE_PATTERNS =
-
 #---------------------------------------------------------------------------
 # configuration options related to source browsing
 #---------------------------------------------------------------------------
 
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH 
+# then you must also enable this option. If you don't then doxygen will produce 
+# a warning and turn it on anyway
 
 SOURCE_BROWSER         = NO
 
-# Setting the INLINE_SOURCES tag to YES will include the body
+# Setting the INLINE_SOURCES tag to YES will include the body 
 # of functions and classes directly in the documentation.
 
 INLINE_SOURCES         = NO
 
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
 # fragments. Normal C and C++ comments will always remain visible.
 
 STRIP_CODE_COMMENTS    = YES
 
-# If the REFERENCED_BY_RELATION tag is set to YES
-# then for each documented function all documented
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
 # functions referencing it will be listed.
 
 REFERENCED_BY_RELATION = YES
 
-# If the REFERENCES_RELATION tag is set to YES
-# then for each documented function all documented entities
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
 # called/used by that function will be listed.
 
 REFERENCES_RELATION    = YES
@@ -790,21 +622,20 @@
 # If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
 # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
 # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.
-# Otherwise they will link to the documentation.
+# link to the source code.  Otherwise they will link to the documentstion.
 
 REFERENCES_LINK_SOURCE = YES
 
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
 # will need version 4.8.6 or higher.
 
 USE_HTAGS              = NO
 
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
 # which an include is specified. Set to NO to disable this.
 
 VERBATIM_HEADERS       = YES
@@ -813,544 +644,287 @@
 # configuration options related to the alphabetical class index
 #---------------------------------------------------------------------------
 
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
 # contains a lot of classes, structs, unions or interfaces.
 
 ALPHABETICAL_INDEX     = YES
 
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
 # in which this list will be split (can be a number in the range [1..20])
 
 COLS_IN_ALPHA_INDEX    = 5
 
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
 # should be ignored while generating the index headers.
 
-IGNORE_PREFIX          =
+IGNORE_PREFIX          = 
 
 #---------------------------------------------------------------------------
 # configuration options related to the HTML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
 # generate HTML output.
 
 GENERATE_HTML          = YES
 
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
 # put in front of it. If left blank `html' will be used as the default path.
 
-HTML_OUTPUT            =
+HTML_OUTPUT            = 
 
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
 # doxygen will generate files with .html extension.
 
 HTML_FILE_EXTENSION    = .html
 
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header. Note that when using a custom header you are responsible
-#  for the proper inclusion of any scripts and style sheets that doxygen
-# needs, which is dependent on the configuration options used.
-# It is adviced to generate a default header using "doxygen -w html
-# header.html footer.html stylesheet.css YourConfigFile" and then modify
-# that header. Note that the header is subject to change so you typically
-# have to redo this when upgrading to a newer version of doxygen or when
-# changing the value of configuration settings such as GENERATE_TREEVIEW!
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
 
-HTML_HEADER            =
+HTML_HEADER            = 
 
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
 # standard footer.
 
-HTML_FOOTER            =
+HTML_FOOTER            = 
 
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
 # stylesheet in the HTML output directory as well, or it will be erased!
 
-HTML_STYLESHEET        =
+HTML_STYLESHEET        = 
 
-# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
-# other source files which should be copied to the HTML output directory. Note
-# that these files will be copied to the base HTML output directory. Use the
-# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
-# files. In the HTML_STYLESHEET file, use the file name only. Also note that
-# the files will be copied as-is; there are no commands or markers available.
-
-HTML_EXTRA_FILES       =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
-# Doxygen will adjust the colors in the stylesheet and background images
-# according to this color. Hue is specified as an angle on a colorwheel,
-# see http://en.wikipedia.org/wiki/Hue for more information.
-# For instance the value 0 represents red, 60 is yellow, 120 is green,
-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
-# The allowed range is 0 to 359.
-
-HTML_COLORSTYLE_HUE    = 220
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
-# the colors in the HTML output. For a value of 0 the output will use
-# grayscales only. A value of 255 will produce the most vivid colors.
-
-HTML_COLORSTYLE_SAT    = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
-# the luminance component of the colors in the HTML output. Values below
-# 100 gradually make the output lighter, whereas values above 100 make
-# the output darker. The value divided by 100 is the actual gamma applied,
-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
-# and 100 does not change the gamma.
-
-HTML_COLORSTYLE_GAMMA  = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting
-# this to NO can help when comparing the output of multiple runs.
-
-HTML_TIMESTAMP         = NO
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
 # NO a bullet list will be used.
 
 HTML_ALIGN_MEMBERS     = YES
 
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded. For this to work a browser that supports
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS  = NO
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files
-# will be generated that can be used as input for Apple's Xcode 3
-# integrated development environment, introduced with OSX 10.5 (Leopard).
-# To create a documentation set, doxygen will generate a Makefile in the
-# HTML output directory. Running make will produce the docset in that
-# directory and running "make install" will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
-# it at startup.
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-
-GENERATE_DOCSET        = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
-# feed. A documentation feed provides an umbrella under which multiple
-# documentation sets from a single provider (such as a company or product suite)
-# can be grouped.
-
-DOCSET_FEEDNAME        = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
-# should uniquely identify the documentation set bundle. This should be a
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID       = org.doxygen.Project
-
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-
-DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
-
-# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
-
-DOCSET_PUBLISHER_NAME  = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
 # of the generated HTML documentation.
 
 GENERATE_HTMLHELP      = YES
 
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
 # written to the html output directory.
 
-CHM_FILE               =
+CHM_FILE               = 
 
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
 # the HTML help compiler on the generated index.hhp.
 
-HHC_LOCATION           =
+HHC_LOCATION           = 
 
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
 # it should be included in the master .chm file (NO).
 
 GENERATE_CHI           = NO
 
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
-
-CHM_INDEX_ENCODING     =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
 # normal table of contents (NO) in the .chm file.
 
 BINARY_TOC             = NO
 
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
 # to the contents of the HTML help documentation and to the tree view.
 
 TOC_EXPAND             = NO
 
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
-# that can be used as input for Qt's qhelpgenerator to generate a
-# Qt Compressed Help (.qch) of the generated HTML documentation.
-
-GENERATE_QHP           = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
-# be used to specify the file name of the resulting .qch file.
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE               =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#namespace
-
-QHP_NAMESPACE          = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
-
-QHP_VIRTUAL_FOLDER     = doc
-
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
-# add. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
-
-QHP_CUST_FILTER_NAME   =
-
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
-# Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS  =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
-# Qt Help Project / Filter Attributes</a>.
-
-QHP_SECT_FILTER_ATTRS  =
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
-# be used to specify the location of Qt's qhelpgenerator.
-# If non-empty doxygen will try to run qhelpgenerator on the generated
-# .qhp file.
-
-QHG_LOCATION           =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
-#  will be generated, which together with the HTML files, form an Eclipse help
-# plugin. To install this plugin and make it available under the help contents
-# menu in Eclipse, the contents of the directory containing the HTML and XML
-# files needs to be copied into the plugins directory of eclipse. The name of
-# the directory within the plugins directory should be the same as
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
-# the help appears.
-
-GENERATE_ECLIPSEHELP   = NO
-
-# A unique identifier for the eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have
-# this name.
-
-ECLIPSE_DOC_ID         = org.doxygen.Project
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
 # the value YES disables it.
 
 DISABLE_INDEX          = NO
 
-# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values
-# (range [0,1..20]) that doxygen will group on one line in the generated HTML
-# documentation. Note that a value of 0 will completely suppress the enum
-# values from appearing in the overview section.
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
 
 ENUM_VALUES_PER_LINE   = 4
 
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to YES, a side panel will be generated
-# containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
-# Windows users are probably better off using the HTML help feature.
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
 
 GENERATE_TREEVIEW      = NO
 
-# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
-# and Class Hierarchy pages using a tree view instead of an ordered list.
-
-USE_INLINE_TREES       = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
 # is shown.
 
 TREEVIEW_WIDTH         = 250
 
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
-# links to external symbols imported via tag files in a separate window.
-
-EXT_LINKS_IN_WINDOW    = NO
-
-# Use this tag to change the font size of Latex formulas included
-# as images in the HTML documentation. The default is 10. Note that
-# when you change the font size after a successful doxygen run you need
-# to manually remove any form_*.png images from the HTML output directory
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE       = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are
-# not supported properly for IE 6.0, but are supported on all modern browsers.
-# Note that when changing this option you need to delete any form_*.png files
-# in the HTML output before the changes have effect.
-
-FORMULA_TRANSPARENT    = YES
-
-# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax
-# (see http://www.mathjax.org) which uses client side Javascript for the
-# rendering instead of using prerendered bitmaps. Use this if you do not
-# have LaTeX installed or if you want to formulas look prettier in the HTML
-# output. When enabled you also need to install MathJax separately and
-# configure the path to it using the MATHJAX_RELPATH option.
-
-USE_MATHJAX            = NO
-
-# When MathJax is enabled you need to specify the location relative to the
-# HTML output directory using the MATHJAX_RELPATH option. The destination
-# directory should contain the MathJax.js script. For instance, if the mathjax
-# directory is located at the same level as the HTML output directory, then
-# MATHJAX_RELPATH should be ../mathjax. The default value points to the
-# mathjax.org site, so you can quickly see the result without installing
-# MathJax, but it is strongly recommended to install a local copy of MathJax
-# before deployment.
-
-MATHJAX_RELPATH        = http://www.mathjax.org/mathjax
-
-# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension
-# names that should be enabled during MathJax rendering.
-
-MATHJAX_EXTENSIONS     =
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box
-# for the HTML output. The underlying search engine uses javascript
-# and DHTML and should work on any modern browser. Note that when using
-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
-# (GENERATE_DOCSET) there is already a search function so this one should
-# typically be disabled. For large projects the javascript based search engine
-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
-
-SEARCHENGINE           = NO
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a PHP enabled web server instead of at the web client
-# using Javascript. Doxygen will generate the search PHP script and index
-# file to put on the web server. The advantage of the server
-# based approach is that it scales better to large projects and allows
-# full text search. The disadvantages are that it is more difficult to setup
-# and does not have live searching capabilities.
-
-SERVER_BASED_SEARCH    = NO
-
 #---------------------------------------------------------------------------
 # configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
 # generate Latex output.
 
 GENERATE_LATEX         = NO
 
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
 # put in front of it. If left blank `latex' will be used as the default path.
 
-LATEX_OUTPUT           =
+LATEX_OUTPUT           = 
 
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
 # invoked. If left blank `latex' will be used as the default command name.
-# Note that when enabling USE_PDFLATEX this option is only used for
-# generating bitmaps for formulas in the HTML output, but not in the
-# Makefile that is written to the output directory.
 
 LATEX_CMD_NAME         = latex
 
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
 # default command name.
 
 MAKEINDEX_CMD_NAME     = makeindex
 
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
 # save some trees in general.
 
 COMPACT_LATEX          = NO
 
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, letter, legal and
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
 # executive. If left blank a4wide will be used.
 
 PAPER_TYPE             = a4
 
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
 # packages that should be included in the LaTeX output.
 
-EXTRA_PACKAGES         =
+EXTRA_PACKAGES         = 
 
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
 # standard header. Notice: only use this tag if you know what you are doing!
 
-LATEX_HEADER           =
+LATEX_HEADER           = 
 
-# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for
-# the generated latex document. The footer should contain everything after
-# the last chapter. If it is left blank doxygen will generate a
-# standard footer. Notice: only use this tag if you know what you are doing!
-
-LATEX_FOOTER           =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
 # This makes the output suitable for online browsing using a pdf viewer.
 
 PDF_HYPERLINKS         = NO
 
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
 # higher quality PDF documentation.
 
 USE_PDFLATEX           = NO
 
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
 # This option is also used when generating formulas in HTML.
 
 LATEX_BATCHMODE        = NO
 
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
 # in the output.
 
 LATEX_HIDE_INDICES     = NO
 
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include
-# source code with syntax highlighting in the LaTeX output.
-# Note that which sources are shown also depends on other settings
-# such as SOURCE_BROWSER.
-
-LATEX_SOURCE_CODE      = NO
-
-# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
-# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See
-# http://en.wikipedia.org/wiki/BibTeX for more info.
-
-LATEX_BIB_STYLE        = plain
-
 #---------------------------------------------------------------------------
 # configuration options related to the RTF output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
 # other RTF readers or editors.
 
 GENERATE_RTF           = NO
 
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
 # put in front of it. If left blank `rtf' will be used as the default path.
 
 RTF_OUTPUT             = rtf
 
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
 # save some trees in general.
 
 COMPACT_RTF            = NO
 
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
 # Note: wordpad (write) and others do not support links.
 
 RTF_HYPERLINKS         = NO
 
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
 # replacements, missing definitions are set to their default value.
 
-RTF_STYLESHEET_FILE    =
+RTF_STYLESHEET_FILE    = 
 
-# Set optional variables used in the generation of an rtf document.
+# Set optional variables used in the generation of an rtf document. 
 # Syntax is similar to doxygen's config file.
 
-RTF_EXTENSIONS_FILE    =
+RTF_EXTENSIONS_FILE    = 
 
 #---------------------------------------------------------------------------
 # configuration options related to the man page output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
 # generate man pages
 
 GENERATE_MAN           = NO
 
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
 # put in front of it. If left blank `man' will be used as the default path.
 
-MAN_OUTPUT             =
+MAN_OUTPUT             = 
 
-# The MAN_EXTENSION tag determines the extension that is added to
+# The MAN_EXTENSION tag determines the extension that is added to 
 # the generated man pages (default is the subroutine's section .3)
 
 MAN_EXTENSION          = .3
 
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
 # would be unable to find the correct page. The default is NO.
 
 MAN_LINKS              = NO
@@ -1359,33 +933,33 @@
 # configuration options related to the XML output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
 # the code including all documentation.
 
 GENERATE_XML           = NO
 
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
 # put in front of it. If left blank `xml' will be used as the default path.
 
 XML_OUTPUT             = xml
 
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
 # syntax of the XML files.
 
-XML_SCHEMA             =
+XML_SCHEMA             = 
 
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
 # syntax of the XML files.
 
-XML_DTD                =
+XML_DTD                = 
 
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
 # enabling this will significantly increase the size of the XML output.
 
 XML_PROGRAMLISTING     = YES
@@ -1394,10 +968,10 @@
 # configuration options for the AutoGen Definitions output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
 # and incomplete at the moment.
 
 GENERATE_AUTOGEN_DEF   = NO
@@ -1406,359 +980,319 @@
 # configuration options related to the Perl module output
 #---------------------------------------------------------------------------
 
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
 # moment.
 
 GENERATE_PERLMOD       = NO
 
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
 # to generate PDF and DVI output from the Perl module output.
 
 PERLMOD_LATEX          = NO
 
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader.
-# This is useful
-# if you want to understand what is going on.
-# On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
 # and Perl will parse it just the same.
 
 PERLMOD_PRETTY         = YES
 
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
 # Makefile don't overwrite each other's variables.
 
-PERLMOD_MAKEVAR_PREFIX =
+PERLMOD_MAKEVAR_PREFIX = 
 
 #---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
+# Configuration options related to the preprocessor   
 #---------------------------------------------------------------------------
 
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
 # files.
 
 ENABLE_PREPROCESSING   = YES
 
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
 # way by setting EXPAND_ONLY_PREDEF to YES.
 
 MACRO_EXPANSION        = YES
 
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
 # PREDEFINED and EXPAND_AS_DEFINED tags.
 
 EXPAND_ONLY_PREDEF     = NO
 
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# pointed to by INCLUDE_PATH will be searched when a #include is found.
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
 
 SEARCH_INCLUDES        = YES
 
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
 # the preprocessor.
 
 INCLUDE_PATH           = .
 
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
 # be used.
 
-INCLUDE_FILE_PATTERNS  =
+INCLUDE_FILE_PATTERNS  = 
 
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
 # instead of the = operator.
 
-PREDEFINED             =
+PREDEFINED             = 
 
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition that
-# overrules the definition found in the source code.
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
 
-EXPAND_AS_DEFINED      =
+EXPAND_AS_DEFINED      = 
 
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all references to function-like macros
-# that are alone on a line, have an all uppercase name, and do not end with a
-# semicolon, because these will confuse the parser if not removed.
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
 
 SKIP_FUNCTION_MACROS   = YES
 
 #---------------------------------------------------------------------------
-# Configuration::additions related to external references
+# Configuration::additions related to external references   
 #---------------------------------------------------------------------------
 
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-#
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-#
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
 # does not have to be run to correct the links.
 # Note that each tag file must have a unique name
 # (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
+# If a tag file is not located in the directory in which doxygen 
 # is run, you must also specify the path to the tagfile here.
 
-TAGFILES               =
+TAGFILES               = 
 
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
 # a tag file that is based on the input files it reads.
 
-GENERATE_TAGFILE       =
+GENERATE_TAGFILE       = 
 
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
 # will be listed.
 
 ALLEXTERNALS           = NO
 
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
 # be listed.
 
 EXTERNAL_GROUPS        = YES
 
-# The PERL_PATH should be the absolute path and name of the perl script
+# The PERL_PATH should be the absolute path and name of the perl script 
 # interpreter (i.e. the result of `which perl').
 
 PERL_PATH              = /usr/bin/perl
 
 #---------------------------------------------------------------------------
-# Configuration options related to the dot tool
+# Configuration options related to the dot tool   
 #---------------------------------------------------------------------------
 
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option also works with HAVE_DOT disabled, but it is recommended to
-# install and use dot, since it yields more powerful graphs.
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
 
 CLASS_DIAGRAMS         = YES
 
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to 
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to 
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to 
+# be found in the default search path.
 
-MSCGEN_PATH            =
+MSCGEN_PATH            = 
 
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
 # or is not a class.
 
 HIDE_UNDOC_RELATIONS   = YES
 
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
 # have no effect if this option is set to NO (the default)
 
 HAVE_DOT               = YES
 
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
-# allowed to run in parallel. When set to 0 (the default) doxygen will
-# base this on the number of processors available in the system. You can set it
-# explicitly to a value larger than 0 to get control over the balance
-# between CPU load and processing speed.
-
-DOT_NUM_THREADS        = 0
-
-# By default doxygen will use the Helvetica font for all dot files that
-# doxygen generates. When you want a differently looking font you can specify
-# the font name using DOT_FONTNAME. You need to make sure dot is able to find
-# the font, which can be done by putting it in a standard location or by setting
-# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
-# directory containing the font.
-
-DOT_FONTNAME           = Helvetica
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
-
-DOT_FONTSIZE           = 10
-
-# By default doxygen will tell dot to use the Helvetica font.
-# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to
-# set the path where dot can find it.
-
-DOT_FONTPATH           =
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
 # the CLASS_DIAGRAMS tag to NO.
 
 CLASS_GRAPH            = YES
 
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
 # class references variables) of the class with other documented classes.
 
 COLLABORATION_GRAPH    = YES
 
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
 # will generate a graph for groups, showing the direct groups dependencies
 
 GROUP_GRAPHS           = YES
 
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
 # Language.
 
 UML_LOOK               = YES
 
-# If set to YES, the inheritance and collaboration graphs will show the
+# If set to YES, the inheritance and collaboration graphs will show the 
 # relations between templates and their instances.
 
 TEMPLATE_RELATIONS     = YES
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
 # other documented files.
 
 INCLUDE_GRAPH          = YES
 
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
 # indirectly include this file.
 
 INCLUDED_BY_GRAPH      = YES
 
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
+# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
 
 CALL_GRAPH             = NO
 
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
+# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
 
 CALLER_GRAPH           = NO
 
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will generate a graphical hierarchy of all classes instead of a textual one.
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
 
 GRAPHICAL_HIERARCHY    = YES
 
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
 # in a graphical way. The dependency relations are determined by the #include
 # relations between the files in the directories.
 
 DIRECTORY_GRAPH        = YES
 
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are svg, png, jpg, or gif.
-# If left blank png will be used. If you choose svg you need to set
-# HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible in IE 9+ (other browsers do not have this requirement).
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
 
 DOT_IMAGE_FORMAT       = png
 
-# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
-# enable generation of interactive SVG images that allow zooming and panning.
-# Note that this requires a modern browser other than Internet Explorer.
-# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you
-# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files
-# visible. Older versions of IE do not have SVG support.
-
-INTERACTIVE_SVG        = NO
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
 # found. If left blank, it is assumed the dot tool can be found in the path.
 
-DOT_PATH               =
+DOT_PATH               = 
 
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
 # \dotfile command).
 
-DOTFILE_DIRS           =
+DOTFILE_DIRS           = 
 
-# The MSCFILE_DIRS tag can be used to specify one or more directories that
-# contain msc files that are included in the documentation (see the
-# \mscfile command).
-
-MSCFILE_DIRS           =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the number 
+# of direct children of the root node in a graph is already larger than 
+# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note 
 # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
 
 DOT_GRAPH_MAX_NODES    = 50
 
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
 # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
 
 MAX_DOT_GRAPH_DEPTH    = 0
 
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
 
 DOT_TRANSPARENT        = NO
 
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
 # support this, this feature is disabled by default.
 
 DOT_MULTI_TARGETS      = NO
 
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
 # arrows in the dot generated graphs.
 
 GENERATE_LEGEND        = YES
 
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
 # the various graphs.
 
 DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/jni/libzrtp/sources/libzrtpcpp.pc.cmake b/jni/libzrtp/sources/libzrtpcpp.pc.cmake
index 655bd30..f9f5541 100644
--- a/jni/libzrtp/sources/libzrtpcpp.pc.cmake
+++ b/jni/libzrtp/sources/libzrtpcpp.pc.cmake
@@ -9,7 +9,7 @@
 Description: GNU ZRTP core library
 Version: @VERSION@
 Requires: @CRYPTOBACKEND@
-Libs:  -L${libdir} -l@zrtplibName@
+Libs:  -L${libdir} -l@zrtplib@
 Cflags: -I${includedir}
 
 
diff --git a/jni/libzrtp/sources/zrtp/Base32.cpp b/jni/libzrtp/sources/src/Base32.cpp
similarity index 100%
rename from jni/libzrtp/sources/zrtp/Base32.cpp
rename to jni/libzrtp/sources/src/Base32.cpp
diff --git a/jni/libzrtp/sources/src/CMakeLists.txt b/jni/libzrtp/sources/src/CMakeLists.txt
new file mode 100755
index 0000000..05e57ff
--- /dev/null
+++ b/jni/libzrtp/sources/src/CMakeLists.txt
@@ -0,0 +1,87 @@
+cmake_minimum_required (VERSION 2.6)
+
+# add_subdirectory(libzrtpcpp)
+# add_subdirectory(libzrtpcpp/crypto)
+
+include_directories (${CMAKE_CURRENT_SOURCE_DIR})
+
+set(gcrypt_src
+    libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
+    libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
+    libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
+    libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
+    libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
+    libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
+    libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp)
+
+set(openssl_src
+    libzrtpcpp/crypto/openssl/ZrtpDH.cpp
+    libzrtpcpp/crypto/openssl/hmac256.cpp
+    libzrtpcpp/crypto/openssl/sha256.cpp
+    libzrtpcpp/crypto/openssl/hmac384.cpp
+    libzrtpcpp/crypto/openssl/sha384.cpp
+    libzrtpcpp/crypto/openssl/AesCFB.cpp
+    libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp)
+
+if (GCRYPT_FOUND)
+    set(crypto_src ${gcrypt_src})
+endif()
+
+if (OPENSSL_FOUND)
+    set(crypto_src ${openssl_src})
+endif()
+
+if(enable_ccrtp)
+  set(ccrtp_src ZrtpQueue.cpp)
+endif()
+
+set(twofish_srcs libzrtpcpp/crypto/twofish.c
+         libzrtpcpp/crypto/twofish_cfb.c
+         libzrtpcpp/crypto/TwoCFB.cpp)
+
+set(zrtp_src
+    ZrtpCallbackWrapper.cpp
+    ZIDFile.cpp
+    ZIDRecord.cpp
+    ZRtp.cpp
+    ZrtpCrc32.cpp
+    ZrtpPacketCommit.cpp
+    ZrtpPacketConf2Ack.cpp
+    ZrtpPacketConfirm.cpp
+    ZrtpPacketDHPart.cpp
+    ZrtpPacketGoClear.cpp
+    ZrtpPacketClearAck.cpp
+    ZrtpPacketHelloAck.cpp
+    ZrtpPacketHello.cpp
+    ZrtpPacketError.cpp
+    ZrtpPacketErrorAck.cpp
+    ZrtpPacketPingAck.cpp
+    ZrtpPacketPing.cpp
+    ZrtpPacketSASrelay.cpp
+    ZrtpPacketRelayAck.cpp
+    ZrtpStateClass.cpp
+    ZrtpTextData.cpp
+    ZrtpConfigure.cpp
+    ZrtpCWrapper.cpp
+    Base32.cpp)
+
+set(zrtpcpp_src ${zrtp_src} ${ccrtp_src} ${crypto_src} ${twofish_srcs})
+
+if(BUILD_STATIC AND NOT BUILD_SHARED)
+    set(LIBRARY_BUILD_TYPE STATIC)
+else()
+    set(LIBRARY_BUILD_TYPE SHARED)
+endif()
+
+add_library(${zrtplib} ${LIBRARY_BUILD_TYPE} ${zrtpcpp_src})
+set_target_properties(${zrtplib} PROPERTIES VERSION ${VERSION} SOVERSION ${SOVERSION})
+target_link_libraries(${zrtplib} ${LIBS})
+
+if(enable_ccrtp)
+    add_dependencies(${zrtplib} ccrtp)
+endif()
+
+add_subdirectory(libzrtpcpp)
+
+install(TARGETS ${zrtplib} DESTINATION ${LIBDIRNAME})
+
diff --git a/jni/libzrtp/sources/src/ZIDFile.cpp b/jni/libzrtp/sources/src/ZIDFile.cpp
new file mode 100644
index 0000000..69b43eb
--- /dev/null
+++ b/jni/libzrtp/sources/src/ZIDFile.cpp
@@ -0,0 +1,430 @@
+/*
+  Copyright (C) 2006-2008 Werner Dittmann
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  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.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+// #define UNIT_TEST
+
+#include <string>
+#include <time.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <libzrtpcpp/ZIDFile.h>
+
+
+static ZIDFile* instance;
+static int errors = 0;  // maybe we will use as member of ZIDFile later...
+
+void ZIDFile::createZIDFile(char* name) {
+    zidFile = fopen(name, "wb+");
+    // New file, generate an associated random ZID and save
+    // it as first record
+    if (zidFile != NULL) {
+        unsigned int* ip;
+        ip = (unsigned int*) associatedZid;
+        srand(time(NULL));
+        *ip++ = rand();
+        *ip++ = rand();
+        *ip = rand();
+
+        ZIDRecord rec(associatedZid);
+        rec.setOwnZIDRecord();
+        fseek(zidFile, 0L, SEEK_SET);
+        if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
+            ++errors;
+        fflush(zidFile);
+    }
+}
+
+/**
+ * Migrate old ZID file format to new one.
+ *
+ * If ZID file is old format:
+ * - close it, rename it, then re-open
+ * - create ZID file for new format
+ * - copy over contents and flags.
+ */
+void ZIDFile::checkDoMigration(char* name) {
+    FILE* fdOld;
+    unsigned char inb[2];
+    zidrecord1_t recOld;
+
+    fseek(zidFile, 0L, SEEK_SET);
+    if (fread(inb, 2, 1, zidFile) < 1) {
+        ++errors;
+        inb[0] = 0;
+    }
+
+    if (inb[0] > 0) {           // if it's new format just return
+        return;
+    }
+    fclose(zidFile);            // close old ZID file
+    zidFile = NULL;
+
+    // create save file name, rename and re-open
+    // if rename fails, just unlink old ZID file and create a brand new file
+    // just a little inconvenience for the user, need to verify new SAS
+    std::string fn = std::string(name) + std::string(".save");
+    if (rename(name, fn.c_str()) < 0) {
+	unlink(name);
+        createZIDFile(name);
+        return;
+    }
+    fdOld = fopen(fn.c_str(), "rb");    // reopen old format in read only mode
+
+    // Get first record from old file - is the own ZID
+    fseek(fdOld, 0L, SEEK_SET);
+    if (fread(&recOld, sizeof(zidrecord1_t), 1, fdOld) != 1) {
+        fclose(fdOld);
+        return;
+    }
+    if (recOld.ownZid != 1) {
+        fclose(fdOld);
+        return;
+    }
+    zidFile = fopen(name, "wb+");    // create new format file in binary r/w mode
+    if (zidFile == NULL) {
+        return;
+    }
+    // create ZIDRecord in new format, copy over own ZID and write the record
+    ZIDRecord rec(recOld.identifier);
+    rec.setOwnZIDRecord();
+    if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
+        ++errors;
+
+    // now copy over all valid records from old ZID file format.
+    // Sequentially read old records, sequentially write new records
+    int numRead;
+    do {
+        numRead = fread(&recOld, sizeof(zidrecord1_t), 1, fdOld);
+        if (numRead == 0) {     // all old records processed
+            break;
+        }
+        // skip own ZID record and invalid records
+        if (recOld.ownZid == 1 || recOld.recValid == 0) {
+            continue;
+        }
+        ZIDRecord rec2(recOld.identifier);
+        rec2.setValid();
+        if (recOld.rs1Valid & SASVerified) {
+            rec2.setSasVerified();
+        }
+        rec2.setNewRs1(recOld.rs2Data);
+        rec2.setNewRs1(recOld.rs1Data);
+        if (fwrite(rec2.getRecordData(), rec2.getRecordLength(), 1, zidFile) < 1)
+            ++errors;
+
+    } while (numRead == 1);
+    fflush(zidFile);
+}
+
+ZIDFile::~ZIDFile() {
+    close();
+}
+
+ZIDFile* ZIDFile::getInstance() {
+
+    if (instance == NULL) {
+        instance = new ZIDFile();
+    }
+    return instance;
+}
+
+int ZIDFile::open(char* name) {
+
+    // check for an already active ZID file
+    if (zidFile != NULL) {
+        return 0;
+    }
+    if ((zidFile = fopen(name, "rb+")) == NULL) {
+        createZIDFile(name);
+    } else {
+        checkDoMigration(name);
+        if (zidFile != NULL) {
+            ZIDRecord rec;
+            fseek(zidFile, 0L, SEEK_SET);
+            if (fread(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) != 1) {
+                fclose(zidFile);
+                zidFile = NULL;
+                return -1;
+            }
+            if (!rec.isOwnZIDRecord()) {
+                fclose(zidFile);
+                zidFile = NULL;
+                return -1;
+            }
+            memcpy(associatedZid, rec.getIdentifier(), IDENTIFIER_LEN);
+        }
+    }
+    return ((zidFile == NULL) ? -1 : 1);
+}
+
+void ZIDFile::close() {
+
+    if (zidFile != NULL) {
+        fclose(zidFile);
+        zidFile = NULL;
+    }
+}
+
+unsigned int ZIDFile::getRecord(ZIDRecord* zidRecord) {
+    unsigned long pos;
+    ZIDRecord rec;
+    int numRead;
+
+    // set read pointer behind first record (
+    fseek(zidFile, rec.getRecordLength(), SEEK_SET);
+
+    do {
+        pos = ftell(zidFile);
+        numRead = fread(rec.getRecordData(), rec.getRecordLength(), 1, zidFile);
+        if (numRead == 0) {
+            break;
+        }
+
+        // skip own ZID record and invalid records
+        if (rec.isOwnZIDRecord() || !rec.isValid()) {
+            continue;
+        }
+
+    } while (numRead == 1 &&
+             memcmp(zidRecord->getIdentifier(), rec.getIdentifier(), IDENTIFIER_LEN) != 0);
+
+    // If we reached end of file, then no record with the ZID
+    // found. We need to create a new ZID record.
+    if (numRead == 0) {
+        // create new record
+        ZIDRecord rec1(zidRecord->getIdentifier());
+        rec1.setValid();
+        if (fwrite(rec1.getRecordData(), rec1.getRecordLength(), 1, zidFile) < 1)
+            ++errors;
+        memcpy(zidRecord->getRecordData(), rec1.getRecordData(), rec1.getRecordLength());
+    } else {
+        // Copy the read data into caller's the record storage
+        memcpy(zidRecord->getRecordData(), rec.getRecordData(), rec.getRecordLength());
+    }
+
+    //  remember position of record in file for save operation
+    zidRecord->setPosition(pos);
+    return 1;
+}
+
+unsigned int ZIDFile::saveRecord(ZIDRecord *zidRecord) {
+
+    fseek(zidFile, zidRecord->getPosition(), SEEK_SET);
+    if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)
+        ++errors;
+    fflush(zidFile);
+    return 1;
+}
+
+
+#ifdef UNIT_TEST
+
+#include <iostream>
+#include <unistd.h>
+using namespace std;
+
+static void hexdump(const char* title, const unsigned char *s, int l) {
+    int n=0;
+
+    if (s == NULL) return;
+
+    fprintf(stderr, "%s",title);
+    for (; n < l ; ++n) {
+        if ((n%16) == 0)
+            fprintf(stderr, "\n%04x",n);
+        fprintf(stderr, " %02x",s[n]);
+    }
+    fprintf(stderr, "\n");
+}
+
+int main(int argc, char *argv[]) {
+
+    unsigned char myId[IDENTIFIER_LEN];
+    ZIDFile *zid = ZIDFile::getInstance();
+
+    unlink("testzid2");
+    zid->open("testzid2");
+    hexdump("My ZID: ", zid->getZid(), IDENTIFIER_LEN);
+    memcpy(myId, zid->getZid(), IDENTIFIER_LEN);
+    zid->close();
+
+    zid->open("testzid2");
+    if (memcmp(myId, zid->getZid(), IDENTIFIER_LEN) != 0) {
+        cerr << "Wrong ZID in testfile" << endl;
+        return 1;
+    }
+
+    // Create a new ZID record for peer ZID "123456789012"
+    ZIDRecord zr3((unsigned char*) "123456789012");
+    zid->getRecord(&zr3);
+    if (!zr3.isValid()) {
+        cerr << "New ZID record '123456789012' not set to valid" << endl;
+        return 1;
+    }
+    zid->saveRecord(&zr3);
+
+    // create a second record with peer ZID "210987654321"
+    ZIDRecord zr4((unsigned char*) "210987654321");
+    zid->getRecord(&zr4);
+    if (!zr4.isValid()) {
+        cerr << "New ZID record '210987654321' not set to valid" << endl;
+        return 1;
+    }
+    zid->saveRecord(&zr4);
+
+    // now set a first RS1 with default expiration interval, check
+    // if set correctly, valid flag and expiration interval
+    zr3.setNewRs1((unsigned char*) "11122233344455566677788899900012");
+    if (memcmp(zr3.getRs1(), "11122233344455566677788899900012", RS_LENGTH) != 0) {
+        cerr << "RS1 was not set (111...012)" << endl;
+        return 1;
+    }
+    if (!zr3.isRs1Valid()) {
+        cerr << "RS1 was not set to valid state (111...012)" << endl;
+        return 1;
+    }
+    if (!zr3.isRs1NotExpired()) {
+        cerr << "RS1 expired (111...012)" << endl;
+        return 1;
+    }
+    if (zr3.isRs2Valid()) {
+        cerr << "RS2 was set to valid state (111...012)" << endl;
+        return 1;
+    }
+    zid->saveRecord(&zr3);
+
+    // create a second RS1, RS2 will become the first RS1,  check
+    // if set correctly, valid flag and expiration interval for both
+    // RS1 and RS2
+    zr3.setNewRs1((unsigned char*) "00099988877766655544433322211121");
+    if (memcmp(zr3.getRs1(), "00099988877766655544433322211121", RS_LENGTH) != 0) {
+        cerr << "RS1 was not set (000...121)" << endl;
+        return 1;
+    }
+    if (!zr3.isRs1Valid()) {
+        cerr << "RS1 was not set to valid state (000...121)" << endl;
+        return 1;
+    }
+    if (!zr3.isRs1NotExpired()) {
+        cerr << "RS1 expired (000...121)" << endl;
+        return 1;
+    }
+    if (memcmp(zr3.getRs2(), "11122233344455566677788899900012", RS_LENGTH) != 0) {
+        cerr << "RS2 was not set (111...012)" << endl;
+        return 1;
+    }
+    if (!zr3.isRs2Valid()) {
+        cerr << "RS2 was not set to valid state (111...012)" << endl;
+        return 1;
+    }
+    if (!zr3.isRs2NotExpired()) {
+        cerr << "RS2 expired (111...012)" << endl;
+        return 1;
+    }
+    zid->saveRecord(&zr3);
+
+    zid->close();
+
+    // Reopen, check if first record is still valid, RSx vaild and
+    // not expired. Then manipulate 2nd record.
+    zid->open("testzid2");
+
+    ZIDRecord zr3a((unsigned char*) "123456789012");
+    zid->getRecord(&zr3a);
+    if (!zr3a.isValid()) {
+        cerr << "Re-read ZID record '123456789012' not set to valid" << endl;
+        return 1;
+    }
+    if (memcmp(zr3a.getRs1(), "00099988877766655544433322211121", RS_LENGTH) != 0) {
+        cerr << "re-read RS1 was not set (000...121)" << endl;
+        return 1;
+    }
+    if (!zr3a.isRs1Valid()) {
+        cerr << "Re-read RS1 was not set to valid state (000...121)" << endl;
+        return 1;
+    }
+    if (!zr3a.isRs1NotExpired()) {
+        cerr << "re-read RS1 expired (000...121)" << endl;
+        return 1;
+    }
+    if (memcmp(zr3a.getRs2(), "11122233344455566677788899900012", RS_LENGTH) != 0) {
+        cerr << "re-read RS2 was not set (111...012)" << endl;
+        return 1;
+    }
+    if (!zr3a.isRs2Valid()) {
+        cerr << "Re-read RS2 was not set to valid state (111...012)" << endl;
+        return 1;
+    }
+    if (!zr3a.isRs2NotExpired()) {
+        cerr << "Re-read RS2 expired (111...012)" << endl;
+        return 1;
+    }
+
+    ZIDRecord zr5((unsigned char*) "210987654321");
+    zid->getRecord(&zr5);
+
+
+    // set new RS1 with expire interval of 5 second, then check immediatly
+    zr5.setNewRs1((unsigned char*) "aaa22233344455566677788899900012", 5);
+    if (!zr5.isValid()) {
+        cerr << "Re-read ZID record '210987654321' not set to valid" << endl;
+        return 1;
+    }
+    if (memcmp(zr5.getRs1(), "aaa22233344455566677788899900012", RS_LENGTH) != 0) {
+        cerr << "RS1 (2) was not set (aaa...012)" << endl;
+        return 1;
+    }
+    if (!zr5.isRs1Valid()) {
+        cerr << "RS1 (2) was not set to valid state (aaa...012)" << endl;
+        return 1;
+    }
+    if (!zr5.isRs1NotExpired()) {
+        cerr << "RS1 (2) expired (aaa...012)" << endl;
+        return 1;
+    }
+
+    // wait for 6 second, now the expire check shall fail
+    sleep(6);
+    if (zr5.isRs1NotExpired()) {
+        cerr << "RS1 (2) is not expired after defined interval (aaa...012)" << endl;
+        return 1;
+    }
+
+    zr5.setNewRs1((unsigned char*) "bbb99988877766655544433322211121", 256);
+    zid->saveRecord(&zr5);
+
+    zid->close();
+
+    // Test migration
+    zid->open("testzidOld");
+    zid->close();
+
+}
+
+#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/src/ZIDRecord.cpp b/jni/libzrtp/sources/src/ZIDRecord.cpp
new file mode 100644
index 0000000..d62c2e3
--- /dev/null
+++ b/jni/libzrtp/sources/src/ZIDRecord.cpp
@@ -0,0 +1,113 @@
+/*
+  Copyright (C) 2006-2007 Werner Dittmann
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  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.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+#include <time.h>
+
+#include <libzrtpcpp/ZIDRecord.h>
+
+void ZIDRecord::setNewRs1(const unsigned char* data, int32_t expire) {
+
+    // shift RS1 data into RS2 position
+    memcpy(record.rs2Data, record.rs1Data, RS_LENGTH);
+    memcpy(record.rs2Interval, record.rs1Interval, TIME_LENGTH);
+
+    // now propagate flags as well
+    if (isRs1Valid()) {
+	setRs2Valid();
+    }
+
+    // set new RS1 data
+    memcpy(record.rs1Data, data, RS_LENGTH);
+
+    time_t validThru;
+    if (expire == -1) {
+	validThru = -1;
+    }
+    else if (expire <= 0) {
+	validThru = 0;
+    }
+    else {
+	validThru = time(NULL) + expire;
+    }
+
+    if (sizeof(time_t) == 4) {
+	long long temp = validThru;
+	memcpy(record.rs1Interval, (unsigned char*)&temp, TIME_LENGTH);
+    }
+    else {
+	memcpy(record.rs1Interval, (unsigned char*)&validThru, TIME_LENGTH);
+    }
+    setRs1Valid();
+}
+
+
+const bool ZIDRecord::isRs1NotExpired() {
+    time_t current = time(NULL);
+    time_t validThru;
+
+    if (sizeof(time_t) == 4) {
+	long long temp;
+	memcpy((unsigned char*)&temp, record.rs1Interval, TIME_LENGTH);
+	validThru = temp;
+    }
+    else {
+	memcpy((unsigned char*)&validThru, record.rs1Interval, TIME_LENGTH);
+    }
+
+    if (validThru == -1)
+	return true;
+    if (validThru == 0)
+	return false;
+    return (current <= validThru) ? true : false;
+}
+
+const bool ZIDRecord::isRs2NotExpired() {
+    time_t current = time(NULL);
+    time_t validThru;
+
+    if (sizeof(time_t) == 4) {
+	long long temp;
+	memcpy((unsigned char*)&temp, record.rs2Interval, TIME_LENGTH);
+	validThru = temp;
+    }
+    else {
+	memcpy((unsigned char*)&validThru, record.rs2Interval, TIME_LENGTH);
+    }
+
+    if (validThru == -1)
+	return true;
+    if (validThru == 0)
+	return false;
+    return (current <= validThru) ? true : false;
+}
+
+void ZIDRecord::setMiTMData(const unsigned char* data) {
+    memcpy(record.mitmKey, data, RS_LENGTH);
+    setMITMKeyAvailable();
+}
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/ZRtp.cpp b/jni/libzrtp/sources/src/ZRtp.cpp
similarity index 69%
rename from jni/libzrtp/sources/zrtp/ZRtp.cpp
rename to jni/libzrtp/sources/src/ZRtp.cpp
index c7d2a46..50c29a9 100755
--- a/jni/libzrtp/sources/zrtp/ZRtp.cpp
+++ b/jni/libzrtp/sources/src/ZRtp.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -15,28 +15,23 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-/*
+/*F
  * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
  */
 #include <sstream>
 
-#include <crypto/zrtpDH.h>
-#include <crypto/hmac256.h>
-#include <crypto/sha256.h>
-#include <crypto/hmac384.h>
-#include <crypto/sha384.h>
-
-#include <crypto/skeinMac256.h>
-#include <crypto/skein256.h>
-#include <crypto/skeinMac384.h>
-#include <crypto/skein384.h>
-
-#include <crypto/aesCFB.h>
-#include <crypto/twoCFB.h>
+#include <libzrtpcpp/crypto/ZrtpDH.h>
+#include <libzrtpcpp/crypto/hmac256.h>
+#include <libzrtpcpp/crypto/sha256.h>
+#include <libzrtpcpp/crypto/hmac384.h>
+#include <libzrtpcpp/crypto/sha384.h>
+#include <libzrtpcpp/crypto/aesCFB.h>
+#include <libzrtpcpp/crypto/twoCFB.h>
 
 #include <libzrtpcpp/ZRtp.h>
 #include <libzrtpcpp/ZrtpStateClass.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZIDFile.h>
+#include <libzrtpcpp/ZIDRecord.h>
 #include <libzrtpcpp/Base32.h>
 
 using namespace GnuZrtpCodes;
@@ -58,7 +53,7 @@
     }
     fprintf(stderr, "\n");
 }
- * */
+ */
 
 /*
  * This method simplifies detection of libzrtpcpp inside Automake, configure
@@ -77,12 +72,10 @@
 
 ZRtp::ZRtp(uint8_t *myZid, ZrtpCallback *cb, std::string id, ZrtpConfigure* config, bool mitmm, bool sasSignSupport):
         callback(cb), dhContext(NULL), DHss(NULL), auxSecret(NULL), auxSecretLength(0), rs1Valid(false),
-        rs2Valid(false), msgShaContext(NULL), hash(NULL), cipher(NULL), pubKey(NULL), sasType(NULL), authLength(NULL),
-        multiStream(false), multiStreamAvailable(false), peerIsEnrolled(false), mitmSeen(false), pbxSecretTmp(NULL),
-        enrollmentMode(false), configureAlgos(*config), zidRec(NULL), saveZidRecord(true) {
+        rs2Valid(false), msgShaContext(NULL), multiStream(false), multiStreamAvailable(false), pbxSecretTmp(NULL),
+        configureAlgos(*config) {
 
     enableMitmEnrollment = config->isTrustedMitM();
-    signatureData = NULL;
     paranoidMode = config->isParanoidMode();
 
     // setup the implicit hash function pointers and length
@@ -93,8 +86,6 @@
     hmacFunctionImpl = hmac_sha256;
     hmacListFunctionImpl = hmac_sha256;
 
-    memcpy(ownZid, myZid, ZID_SIZE);        // save the ZID
-
     /*
      * Generate H0 as a random number (256 bits, 32 bytes) and then
      * the hash chain, refer to chapter 9. Use the implicit hash function.
@@ -104,39 +95,19 @@
     sha256(H1, HASH_IMAGE_SIZE, H2);        // H2
     sha256(H2, HASH_IMAGE_SIZE, H3);        // H3
 
-    // configure all supported Hello packet versions
-    zrtpHello_11.configureHello(&configureAlgos);
-    zrtpHello_11.setH3(H3);                    // set H3 in Hello, included in helloHash
-    zrtpHello_11.setZid(ownZid);
-    zrtpHello_11.setVersion((uint8_t*)zrtpVersion_11);
+    zrtpHello.configureHello(&configureAlgos);
+    zrtpHello.setH3(H3);                    // set H3 in Hello, included in helloHash
 
+    memcpy(zid, myZid, ZID_SIZE);
+    zrtpHello.setZid(zid);
 
-    zrtpHello_12.configureHello(&configureAlgos);
-    zrtpHello_12.setH3(H3);                 // set H3 in Hello, included in helloHash
-    zrtpHello_12.setZid(ownZid);
-    zrtpHello_12.setVersion((uint8_t*)zrtpVersion_12);
+    if (mitmm)                              // this session acts for a trusted MitM (PBX)
+        zrtpHello.setMitmMode();
 
-    if (mitmm) {                            // this session acts for a trusted MitM (PBX)
-        zrtpHello_11.setMitmMode();
-        zrtpHello_12.setMitmMode();
-    }
-    if (sasSignSupport) {                   // the application supports SAS signing
-        zrtpHello_11.setSasSign();
-        zrtpHello_12.setSasSign();
-    }
+    if (sasSignSupport)                     // the application supports SAS signing
+        zrtpHello.setSasSign();
 
-    // Keep array in ascending order (greater index -> greater version)
-    helloPackets[0].packet = &zrtpHello_11;
-    helloPackets[0].version = zrtpHello_11.getVersionInt();
-    setClientId(id, &helloPackets[0]);      // set id, compute HMAC and final helloHash
-
-    helloPackets[1].packet = &zrtpHello_12;
-    helloPackets[1].version = zrtpHello_12.getVersionInt();
-    setClientId(id, &helloPackets[1]);      // set id, compute HMAC and final helloHash
- 
-    currentHelloPacket = helloPackets[SUPPORTED_ZRTP_VERSIONS-1].packet;  // start with highest supported version
-    helloPackets[SUPPORTED_ZRTP_VERSIONS].packet = NULL;
-    peerHelloVersion[0] = 0;
+    setClientId(id);                        // set id, compute HMAC and final helloHash
 
     stateEngine = new ZrtpStateClass(this);
 }
@@ -164,10 +135,6 @@
         auxSecret = NULL;
         auxSecretLength = 0;
     }
-    if (zidRec != NULL) {
-        delete zidRec;
-        zidRec = NULL;
-    }
     memset(hmacKeyI, 0, MAX_DIGEST_LENGTH);
     memset(hmacKeyR, 0, MAX_DIGEST_LENGTH);
 
@@ -187,12 +154,11 @@
     memset(zrtpSession, 0, MAX_DIGEST_LENGTH);
 }
 
-void ZRtp::processZrtpMessage(uint8_t *message, uint32_t pSSRC, size_t length) {
+void ZRtp::processZrtpMessage(uint8_t *message, uint32_t pSSRC) {
     Event_t ev;
 
     peerSSRC = pSSRC;
     ev.type = ZrtpPacket;
-    ev.length = length;
     ev.packet = message;
 
     if (stateEngine != NULL) {
@@ -263,7 +229,7 @@
 }
 
 ZrtpPacketHello* ZRtp::prepareHello() {
-    return currentHelloPacket;
+    return &zrtpHello;
 }
 
 ZrtpPacketHelloAck* ZRtp::prepareHelloAck() {
@@ -277,33 +243,20 @@
  */
 ZrtpPacketCommit* ZRtp::prepareCommit(ZrtpPacketHello *hello, uint32_t* errMsg) {
 
-    myRole = Initiator;
+    sendInfo(Info, InfoHelloReceived);
 
-    if (!hello->isLengthOk()) {
-        *errMsg = CriticalSWError;
+    if (memcmp(hello->getVersion(), zrtpVersion, ZRTP_WORD_SIZE-1) != 0) {
+        *errMsg = UnsuppZRTPVersion;
         return NULL;
     }
-    // Save data before detailed checks - may aid in analysing problems
-    peerClientId.assign((char*)hello->getClientId(), ZRTP_WORD_SIZE * 4);
-    memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
-    peerHelloVersion[ZRTP_WORD_SIZE] = 0;
-
     // Save our peer's (presumably the Responder) ZRTP id
     memcpy(peerZid, hello->getZid(), ZID_SIZE);
-    if (memcmp(peerZid, ownZid, ZID_SIZE) == 0) {       // peers have same ZID????
+    if (memcmp(peerZid, zid, ZID_SIZE) == 0) {       // peers have same ZID????
         *errMsg = EqualZIDHello;
         return NULL;
     }
     memcpy(peerH3, hello->getH3(), HASH_IMAGE_SIZE);
 
-    int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
-
-    // calculate hash over the received Hello packet - is peer's hello hash.
-    // Use implicit hash algorithm
-    hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
-
-    sendInfo(Info, InfoHelloReceived);
-
     /*
      * The Following section extracts the algorithm from the peer's Hello
      * packet. Always the preferend offered algorithms are
@@ -320,15 +273,10 @@
     sasType = findBestSASType(hello);
 
     if (!multiStream) {
-        pubKey = findBestPubkey(hello);                 // Check for public key algorithm first, must set 'hash' as well
-        if (hash == NULL) {
-            *errMsg = UnsuppHashType;
-            return NULL;
-        }
-        if (cipher == NULL)                             // public key selection may have set the cipher already
-            cipher = findBestCipher(hello, pubKey);
-        if (authLength == NULL)                         // public key selection may have set the SRTP authLen already
-            authLength = findBestAuthLen(hello);
+        authLength = findBestAuthLen(hello);
+        pubKey = findBestPubkey(hello);
+        cipher = findBestCipher(hello, pubKey);
+        hash = findBestHash(hello);
         multiStreamAvailable = checkMultiStream(hello);
     }
     else {
@@ -358,16 +306,22 @@
     /*
      * Prepare our DHPart2 packet here. Required to compute HVI. If we stay
      * in Initiator role then we reuse this packet later in prepareDHPart2().
-     * To create this DH packet we have to compute the retained secret ids,
-     * thus get our peer's retained secret data first.
+     * To create this DH packet we have to compute the retained secret ids
+     * first. Thus get our peer's retained secret data first.
      */
-    zidRec = getZidCacheInstance()->getRecord(peerZid);
+    ZIDRecord zidRec(peerZid);
+    ZIDFile *zidFile = ZIDFile::getInstance();
+    zidFile->getRecord(&zidRec);
 
     //Compute the Initator's and Responder's retained secret ids.
     computeSharedSecretSet(zidRec);
 
     // Check if a PBX application set the MitM flag.
-    mitmSeen = hello->isMitmMode();
+    if (hello->isMitmMode()) {
+        mitmSeen = true;
+    }
+    // Flag to record that fact that we have a MitM key of the other peer.
+    peerIsEnrolled = zidRec.isMITMKeyAvailable();
 
     signSasSeen = hello->isSasSign();
     // Construct a DHPart2 message (Initiator's DH message). This packet
@@ -397,7 +351,7 @@
     // Compute the HVI, refer to chapter 5.4.1.1 of the specification
     computeHvi(&zrtpDH2, hello);
 
-    zrtpCommit.setZid(ownZid);
+    zrtpCommit.setZid(zid);
     zrtpCommit.setHashType((uint8_t*)hash->getName());
     zrtpCommit.setCipherType((uint8_t*)cipher->getName());
     zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
@@ -417,6 +371,7 @@
     // hash first messages to produce overall message hash
     // First the Responder's Hello message, second the Commit (always Initator's).
     // Must use negotiated hash.
+    int32_t helloLen = hello->getLength() * ZRTP_WORD_SIZE;
     msgShaContext = createHashCtx();
     hashCtxFunction(msgShaContext, (unsigned char*)hello->getHeaderBase(), helloLen);
     hashCtxFunction(msgShaContext, (unsigned char*)zrtpCommit.getHeaderBase(), len);
@@ -425,6 +380,12 @@
     // Responder or DHPart1 as Initiator
     storeMsgTemp(hello);
 
+    // calculate hash over the received Hello packet - is peer's hello hash.
+    // Use implicit hash algorithm
+    hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
+    memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
+    peerHelloVersion[ZRTP_WORD_SIZE] = 0;
+
     return &zrtpCommit;
 }
 
@@ -432,11 +393,11 @@
 
     randomZRTP(hvi, ZRTP_WORD_SIZE*4);  // This is the Multi-Stream NONCE size
 
-    zrtpCommit.setZid(ownZid);
+    zrtpCommit.setZid(zid);
     zrtpCommit.setHashType((uint8_t*)hash->getName());
     zrtpCommit.setCipherType((uint8_t*)cipher->getName());
     zrtpCommit.setAuthLen((uint8_t*)authLength->getName());
-    zrtpCommit.setPubKeyType((uint8_t*)mult);  // this is fixed because of Multi Stream mode
+    zrtpCommit.setPubKeyType((uint8_t*)"Mult");  // this is fixed because of Multi Stream mode
     zrtpCommit.setSasType((uint8_t*)sasType->getName());
     zrtpCommit.setNonce(hvi);
     zrtpCommit.setH2(H2);
@@ -466,11 +427,17 @@
     // Responder or DHPart1 as Initiator
     storeMsgTemp(hello);
 
+    // calculate hash over the received Hello packet - is peer's hello hash.
+    // Use implicit hash algorithm
+    hashFunctionImpl((unsigned char*)hello->getHeaderBase(), helloLen, peerHelloHash);
+    memcpy(peerHelloVersion, hello->getVersion(), ZRTP_WORD_SIZE);
+    peerHelloVersion[ZRTP_WORD_SIZE] = 0;
+
     return &zrtpCommit;
 }
 
 /*
- * At this point we will take the role of the Responder. We have been in
+ * At this point we will take the role of the Responder. We may have been in
  * the role of the Initiator before and already sent a commit packet that
  * clashed with a commit packet from our peer. If our HVI was lower than our
  * peer's HVI then we switched to Responder and handle our peer's commit packet
@@ -482,21 +449,8 @@
 
     sendInfo(Info, InfoRespCommitReceived);
 
-    if (!commit->isLengthOk(ZrtpPacketCommit::DhExchange)) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
-
-    // Check if ZID in Commit is the same as we got in Hello
-    uint8_t tmpZid[ZID_SIZE];
-    memcpy(tmpZid, commit->getZid(), ZID_SIZE);
-    if (memcmp(peerZid, tmpZid, ZID_SIZE) != 0) {       // ZIDs do not match????
-        sendInfo(Severe, SevereProtocolError);
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
-
-    // The following code checks the hash chain according chapter 10 to detect false ZRTP packets.
+    // The following code check the hash chain according chapter 10 to detect
+    // false ZRTP packets.
     // Must use the implicit hash function.
     uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
     memcpy(peerH2, commit->getH2(), HASH_IMAGE_SIZE);
@@ -544,22 +498,22 @@
     if (*(int32_t*)(hash->getName()) != *(int32_t*)(cp->getName())) {
         hash = cp;
         setNegotiatedHash(hash);
+
+        ZIDRecord zidRec(peerZid);
+        ZIDFile *zidFile = ZIDFile::getInstance();
+        zidFile->getRecord(&zidRec);
+
         // Compute the Initator's and Responder's retained secret ids
         // with the committed hash.
         computeSharedSecretSet(zidRec);
     }
+
     // check if we support the commited pub key type
     cp = &zrtpPubKeys.getByName((const char*)commit->getPubKeysType());
     if (!cp->isValid()) { // no match - something went wrong
         *errMsg = UnsuppPKExchange;
         return NULL;
     }
-    if (*(int32_t*)(cp->getName()) == *(int32_t*)ec38 || *(int32_t*)(cp->getName()) == *(int32_t*)e414) {
-        if (!(*(int32_t*)(hash->getName()) == *(int32_t*)s384 || *(int32_t*)(hash->getName()) == *(int32_t*)skn3)) {
-            *errMsg = UnsuppHashType;
-            return NULL;
-        }
-    }
     pubKey = cp;
 
     // check if we support the commited SAS type
@@ -571,7 +525,7 @@
     sasType = cp;
 
     // dhContext cannot be NULL - always setup during prepareCommit()
-    // check if we can use the dhContext prepared by prepareCommit(),
+    // check if we can use the dhContext prepared by prepareCOmmit(),
     // if not delete old DH context and generate new one
     // The algorithm names are 4 chars only, thus we can cast to int32_t
     if (*(int32_t*)(dhContext->getDHtype()) != *(int32_t*)(pubKey->getName())) {
@@ -583,11 +537,7 @@
 
     dhContext->getPubKeyBytes(pubKeyBytes);
 
-    // Re-compute auxSecretIDr because we changed roles *IDr with my H3, *IDi with peer's H3
     // Setup a DHPart1 packet.
-    myRole = Responder;
-    computeAuxSecretIds();                 // recompute AUX secret ids because we are now Responder, use different H3
-
     zrtpDH1.setPubKeyType(pubKey->getName());
     zrtpDH1.setMessageType((uint8_t*)DHPart1Msg);
     zrtpDH1.setRs1Id(rs1IDr);
@@ -608,20 +558,22 @@
     zrtpDH1.setHMAC(hmac);
 
     // We are definitly responder. Save the peer's hvi for later compare.
+    myRole = Responder;
     memcpy(peerHvi, commit->getHvi(), HVI_SIZE);
 
-    // We are responder. Release the pre-computed SHA context because it was prepared for Initiator.
-    // Setup and compute for Responder.
+    // We are responder. Release a possibly pre-computed SHA context
+    // because this was prepared for Initiator. Then create a new one.
     if (msgShaContext != NULL) {
         closeHashCtx(msgShaContext, NULL);
     }
     msgShaContext = createHashCtx();
 
     // Hash messages to produce overall message hash:
-    // First the Responder's (my) Hello message, second the Commit (always Initator's), 
-    // then the DH1 message (which is always a Responder's message).
-    // Must use negotiated hash.
-    hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);
+    // First the Responder's (my) Hello message, second the Commit
+    // (always Initator's), then the DH1 message (which is always a
+    // Responder's message).
+    // Must use negotiated hash
+    hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
     hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
     hashCtxFunction(msgShaContext, (unsigned char*)zrtpDH1.getHeaderBase(), zrtpDH1.getLength() * ZRTP_WORD_SIZE);
 
@@ -640,10 +592,6 @@
 
     sendInfo(Info, InfoInitDH1Received);
 
-    if (!dhPart1->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     // Because we are initiator the protocol engine didn't receive Commit
     // thus could not store a peer's H2. A two step SHA256 is required to
     // re-compute H3. Then compare with peer's H3 from peer's Hello packet.
@@ -682,6 +630,8 @@
     }
     dhContext->computeSecretKey(pvr, DHss);
 
+    myRole = Initiator;
+
     // We are Initiator: the Responder's Hello and the Initiator's (our) Commit
     // are already hashed in the context. Now hash the Responder's DH1 and then
     // the Initiator's (our) DH2 in that order.
@@ -692,9 +642,17 @@
     // Compute the message Hash
     closeHashCtx(msgShaContext, messageHash);
     msgShaContext = NULL;
+
+    // To compute the keys for the Initiator we need the retained secrets of our
+    // peer. Get them from the storage.
+    ZIDRecord zidRec(peerZid);
+    ZIDFile *zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
     // Now compute the S0, all dependend keys and the new RS1. The function
     // also performs sign SAS callback if it's active.
     generateKeysInitiator(dhPart1, zidRec);
+    zid->saveRecord(&zidRec);
 
     delete dhContext;
     dhContext = NULL;
@@ -714,10 +672,6 @@
 
     sendInfo(Info, InfoRespDH2Received);
 
-    if (!dhPart2->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     // Because we are responder we received a Commit and stored its H2.
     // Now re-compute H2 from received H1 and compare with stored peer's H2.
     // Use implicit hash function
@@ -740,7 +694,7 @@
     // using my Hello packet and the Initiator's DHPart2 and compare with
     // hvi sent in commit packet. If it doesn't macht then a MitM attack
     // may have occured.
-    computeHvi(dhPart2, currentHelloPacket);
+    computeHvi(dhPart2, &zrtpHello);
     if (memcmp(hvi, peerHvi, HVI_SIZE) != 0) {
         *errMsg = DHErrorWrongHVI;
         return NULL;
@@ -757,20 +711,27 @@
         return NULL;
     }
     dhContext->computeSecretKey(pvi, DHss);
-
-    // Hash the Initiator's DH2 into the message Hash (other messages already prepared, see method prepareDHPart1().
+    // Hash the Initiator's DH2 into the message Hash (other messages already
+    // prepared, see method prepareDHPart1().
     // Use neotiated hash function
     hashCtxFunction(msgShaContext, (unsigned char*)dhPart2->getHeaderBase(), dhPart2->getLength() * ZRTP_WORD_SIZE);
 
     closeHashCtx(msgShaContext, messageHash);
     msgShaContext = NULL;
+
+    // To compute the Keys for the Initiator we need the retained secrets of our
+    // peer. Get them from the storage.
+    ZIDRecord zidRec(peerZid);
+    ZIDFile *zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
     /*
      * The expected shared secret Ids were already computed when we built the
      * DHPart1 packet. Generate s0, all depended keys, and the new RS1 value
-     * for the ZID record. The functions also performs sign SAS callback if it's
-     * active. May reset the verify flag in ZID record.
+     * for the ZID record. The functions also performs sign SAS callback if it's active.
      */
     generateKeysResponder(dhPart2, zidRec);
+    zid->saveRecord(&zidRec);
 
     delete dhContext;
     dhContext = NULL;
@@ -780,24 +741,19 @@
 
     // Check if user verfied the SAS in a previous call and thus verfied
     // the retained secret. Don't set the verified flag if paranoidMode is true.
-    if (zidRec->isSasVerified() && !paranoidMode) {
+    if (zidRec.isSasVerified() && !paranoidMode) {
         zrtpConfirm1.setSASFlag();
     }
     zrtpConfirm1.setExpTime(0xFFFFFFFF);
     zrtpConfirm1.setIv(randomIV);
     zrtpConfirm1.setHashH0(H0);
 
-    // if this runs at PBX user agent enrollment service then set flag in confirm
+    // if this run at PBX user agent enrollment service then set flag in confirm
     // packet and store the MitM key
     if (enrollmentMode) {
-        // As clarification to RFC6189: store new PBX secret only if we don't have
-        // a matching PBX secret for the peer's ZID.
-        if (!peerIsEnrolled) {
-            computePBXSecret();
-            zidRec->setMiTMData(pbxSecretTmp);
-        }
-        // Set flag to enable user's client to ask for confirmation or re-confirmation.
+        computePBXSecret();
         zrtpConfirm1.setPBXEnrollment();
+        writeEnrollmentPBX();
     }
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
@@ -821,10 +777,6 @@
 
     sendInfo(Info, InfoRespCommitReceived);
 
-    if (!commit->isLengthOk(ZrtpPacketCommit::MultiStream)) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     // The following code checks the hash chain according chapter 10 to detect
     // false ZRTP packets.
     // Use implicit hash function
@@ -895,7 +847,7 @@
     // First the Responder's (my) Hello message, second the Commit
     // (always Initator's)
     // use negotiated hash
-    hashCtxFunction(msgShaContext, (unsigned char*)currentHelloPacket->getHeaderBase(), currentHelloPacket->getLength() * ZRTP_WORD_SIZE);
+    hashCtxFunction(msgShaContext, (unsigned char*)zrtpHello.getHeaderBase(), zrtpHello.getLength() * ZRTP_WORD_SIZE);
     hashCtxFunction(msgShaContext, (unsigned char*)commit->getHeaderBase(), commit->getLength() * ZRTP_WORD_SIZE);
 
     closeHashCtx(msgShaContext, messageHash);
@@ -933,10 +885,6 @@
 
     sendInfo(Info, InfoInitConf1Received);
 
-    if (!confirm1->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
 
@@ -951,7 +899,10 @@
         *errMsg = ConfirmHMACWrong;
         return NULL;
     }
-    cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);
+    cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), confirm1->getIv(), confirm1->getHashH0(), hmlen);
+
+    std::string cs(cipher->getReadable());
+    cs.append("/").append(pubKey->getName());
 
     // Check HMAC of DHPart1 packet stored in temporary buffer. The
     // HMAC key of the DHPart1 packet is peer's H0 that is contained in
@@ -962,7 +913,7 @@
         return NULL;
     }
     signatureLength = confirm1->getSignatureLength();
-    if (signSasSeen && signatureLength > 0 && confirm1->isSignatureLengthOk()) {
+    if (signSasSeen && signatureLength > 0) {
         signatureData = confirm1->getSignatureData();
         callback->checkSASSignature(sasHash);
         // TODO: error handling if checkSASSignature returns false.
@@ -973,18 +924,27 @@
      */
     bool sasFlag = confirm1->isSASFlag();
 
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+
+    ZIDFile *zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
     // Our peer did not confirm the SAS in last session, thus reset
     // our SAS flag too. Reset the flag also if paranoidMode is true.
     if (!sasFlag || paranoidMode) {
-        zidRec->resetSasVerified();
+        zidRec.resetSasVerified();
     }
     // get verified flag from current RS1 before set a new RS1. This
     // may not be set even if peer's flag is set in confirm1 message.
-    sasFlag = zidRec->isSasVerified();
+    sasFlag = zidRec.isSasVerified();
+
+    callback->srtpSecretsOn(cs, SAS, sasFlag);
 
     // now we are ready to save the new RS1 which inherits the verified
     // flag from old RS1
-    zidRec->setNewRs1((const uint8_t*)newRs1);
+    zidRec.setNewRs1((const uint8_t*)newRs1);
+    zid->saveRecord(&zidRec);
 
     // now generate my Confirm2 message
     zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
@@ -1005,19 +965,10 @@
         // packet and store the MitM key. The PBX user agent service always stores
         // its MitM key.
         if (enrollmentMode) {
-            // As clarification to RFC6189: store new PBX secret only if we don't have
-            // a matching PBX secret for the peer's ZID.
-            if (!peerIsEnrolled) {
-                computePBXSecret();
-                zidRec->setMiTMData(pbxSecretTmp);
-            }
-            // Set flag to enable user's client to ask for confirmation or re-confirmation.
             zrtpConfirm2.setPBXEnrollment();
+            writeEnrollmentPBX();
         }
     }
-    if (saveZidRecord)
-        getZidCacheInstance()->saveRecord(zidRec);
-
     // Encrypt and HMAC with Initiator's key - we are Initiator here
     hmlen = (zrtpConfirm2.getLength() - 9) * ZRTP_WORD_SIZE;
     cipher->getEncrypt()(zrtpKeyI, cipher->getKeylen(), randomIV, zrtpConfirm2.getHashH0(), hmlen);
@@ -1032,18 +983,27 @@
     // agent stores the MitM key only if the user accepts the enrollment
     // request.
     if (enableMitmEnrollment && confirm1->isPBXEnrollment()) {
-        // As clarification to RFC6189: if already enrolled (having a matching PBX secret)
-        // ask for reconfirmation.
-        if (!peerIsEnrolled) {
-            callback->zrtpAskEnrollment(EnrollmentRequest);
-        }
-        else {
-            callback->zrtpAskEnrollment(EnrollmentReconfirm);
-        }
+        callback->zrtpAskEnrollment(EnrollmentRequest);
     }
     return &zrtpConfirm2;
 }
 
+/**
+ * Save the computed MitM secret to the ZID record of the peer
+ */
+void ZRtp::writeEnrollmentPBX() {
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+
+    ZIDFile *zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
+    if (pbxSecretTmp != NULL) {
+        zidRec.setMiTMData(pbxSecretTmp);
+    }
+    zid->saveRecord(&zidRec);
+}
+
 /*
  * At this point we are Initiator.
  */
@@ -1054,10 +1014,6 @@
     // don't update SAS, RS
     sendInfo(Info, InfoInitConf1Received);
 
-    if (!confirm1->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
 
@@ -1078,8 +1034,8 @@
         *errMsg = ConfirmHMACWrong;
         return NULL;
     }
-    // Cast away the const for the IV - the standalone AES CFB modifies IV on return
-    cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), (uint8_t*)confirm1->getIv(), confirm1->getHashH0(), hmlen);
+    cipher->getDecrypt()(zrtpKeyR, cipher->getKeylen(), confirm1->getIv(), confirm1->getHashH0(), hmlen);
+    std::string cs(cipher->getReadable());
 
     // Because we are initiator the protocol engine didn't receive Commit and
     // because we are using multi-stream mode here we also did not receive a DHPart1 and
@@ -1099,6 +1055,12 @@
         *errMsg = CriticalSWError;
         return NULL;
     }
+    // TODO: here we have a SAS signature from reponder, call checkSASsignature (save / compare in case of resend)
+
+    // Inform GUI about security state, don't show SAS and its state
+    std::string cs1("");
+    callback->srtpSecretsOn(cs, cs1, true);
+
     // now generate my Confirm2 message
     zrtpConfirm2.setMessageType((uint8_t*)Confirm2Msg);
     zrtpConfirm2.setHashH0(H0);
@@ -1123,10 +1085,6 @@
 
     sendInfo(Info, InfoRespConf2Received);
 
-    if (!confirm2->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
 
@@ -1143,8 +1101,9 @@
         *errMsg = ConfirmHMACWrong;
         return NULL;
     }
-    // Cast away the const for the IV - the standalone AES CFB modifies IV on return
-    cipher->getDecrypt()(zrtpKeyI, cipher->getKeylen(), (uint8_t*)confirm2->getIv(), confirm2->getHashH0(), hmlen);
+    cipher->getDecrypt()(zrtpKeyI, cipher->getKeylen(), confirm2->getIv(), confirm2->getHashH0(), hmlen);
+
+    std::string cs(cipher->getReadable());
 
     if (!multiStream) {
         // Check HMAC of DHPart2 packet stored in temporary buffer. The
@@ -1156,7 +1115,7 @@
             return NULL;
         }
         signatureLength = confirm2->getSignatureLength();
-        if (signSasSeen && signatureLength > 0 && confirm2->isSignatureLengthOk() ) {
+        if (signSasSeen && signatureLength > 0) {
             signatureData = confirm2->getSignatureData();
             callback->checkSASSignature(sasHash);
             // TODO: error handling if checkSASSignature returns false.
@@ -1166,16 +1125,29 @@
         * GUI about state.
         */
         bool sasFlag = confirm2->isSASFlag();
+
+        // Initialize a ZID record to get peer's retained secrets
+        ZIDRecord zidRec(peerZid);
+
+        ZIDFile *zid = ZIDFile::getInstance();
+        zid->getRecord(&zidRec);
+
         // Our peer did not confirm the SAS in last session, thus reset
         // our SAS flag too. Reset the flag also if paranoidMode is true.
         if (!sasFlag || paranoidMode) {
-            zidRec->resetSasVerified();
+            zidRec.resetSasVerified();
         }
 
+        // Now get the resulting SAS verified flag from current RS1 before setting a new RS1.
+        // It's a combination of our SAS verfied flag and peer's verified flag. Only if both
+        // were set (true) then sasFlag becomes true.
+        sasFlag = zidRec.isSasVerified();
+        cs.append("/").append(pubKey->getName());
+        callback->srtpSecretsOn(cs, SAS, sasFlag);
+
         // save new RS1, this inherits the verified flag from old RS1
-        zidRec->setNewRs1((const uint8_t*)newRs1);
-        if (saveZidRecord)
-            getZidCacheInstance()->saveRecord(zidRec);
+        zidRec.setNewRs1((const uint8_t*)newRs1);
+        zid->saveRecord(&zidRec);
 
         // Ask for enrollment only if enabled via configuration and the
         // confirm packet contains the enrollment flag. The enrolling user
@@ -1183,14 +1155,7 @@
         // request.
         if (enableMitmEnrollment && confirm2->isPBXEnrollment()) {
             computePBXSecret();
-            // As clarification to RFC6189: if already enrolled (having a matching PBX secret)
-            // ask for reconfirmation.
-            if (!peerIsEnrolled) {
-                callback->zrtpAskEnrollment(EnrollmentRequest);
-            }
-            else {
-                callback->zrtpAskEnrollment(EnrollmentReconfirm);
-            }
+            callback->zrtpAskEnrollment(EnrollmentRequest);
         }
     }
     else {
@@ -1205,15 +1170,16 @@
             *errMsg = CriticalSWError;
             return NULL;
         }
+        std::string cs1("");
+
+        // Inform GUI about security state, don't show SAS and its state
+        callback->srtpSecretsOn(cs, cs1, true);
     }
     return &zrtpConf2Ack;
 }
 
 ZrtpPacketErrorAck* ZRtp::prepareErrorAck(ZrtpPacketError* epkt) {
-    if (epkt->getLength() < 4)
-        sendInfo(ZrtpError, CriticalSWError * -1);
-    else
-        sendInfo(ZrtpError, epkt->getErrorCode() * -1);
+    sendInfo(ZrtpError, epkt->getErrorCode() * -1);
     return &zrtpErrorAck;
 }
 
@@ -1223,12 +1189,11 @@
 }
 
 ZrtpPacketPingAck* ZRtp::preparePingAck(ZrtpPacketPing* ppkt) {
-    if (ppkt->getLength() != 6)                    // A PING packet must have a length of 6 words
-        return NULL;
+
     // Because we do not support ZRTP proxy mode use the truncated ZID.
     // If this code shall be used in ZRTP proxy implementation the computation
     // of the endpoint hash must be enhanced (see chaps 5.15ff and 5.16)
-    zrtpPingAck.setLocalEpHash(ownZid);
+    zrtpPingAck.setLocalEpHash(zid);
     zrtpPingAck.setRemoteEpHash(ppkt->getEpHash());
     zrtpPingAck.setSSRC(peerSSRC);
     return &zrtpPingAck;
@@ -1240,10 +1205,6 @@
     if (!mitmSeen || paranoidMode)
         return &zrtpRelayAck;
 
-    if (!srly->isLengthOk()) {
-        *errMsg = CriticalSWError;
-        return NULL;
-    }
     uint8_t* hkey, *ekey;
     // If we are responder then the PBX used it's Initiator keys
     if (myRole == Responder) {
@@ -1258,6 +1219,8 @@
     uint8_t confMac[MAX_DIGEST_LENGTH];
     uint32_t macLen;
 
+    // Use the Initiator's keys here because we are Responder here and
+    // reveice packets from Initiator
     int16_t hmlen = (srly->getLength() - 9) * ZRTP_WORD_SIZE;
 
     // Use negotiated HMAC (hash)
@@ -1267,10 +1230,11 @@
         *errMsg = ConfirmHMACWrong;
         return NULL;                // TODO - check error handling
     }
-    // Cast away the const for the IV - the standalone AES CFB modifies IV on return
-    cipher->getDecrypt()(ekey, cipher->getKeylen(), (uint8_t*)srly->getIv(), (uint8_t*)srly->getFiller(), hmlen);
+    cipher->getDecrypt()(ekey, cipher->getKeylen(), srly->getIv(), (uint8_t*)srly->getFiller(), hmlen);
 
+    const uint8_t* render = srly->getSas();
     const uint8_t* newSasHash = srly->getTrustedSas();
+
     bool sasHashNull = true;
     for (int i = 0; i < HASH_IMAGE_SIZE; i++) {
         if (newSasHash[i] != 0) {
@@ -1278,38 +1242,27 @@
             break;
         }
     }
-    std::string cs(cipher->getReadable());
-    cs.append("/").append(pubKey->getName());
-
     // Check if new SAS is null or a trusted MitM relationship doesn't exist.
     // If this is the case then don't render and don't show the new SAS - use
-    // our computed SAS hash but we may use a different SAS rendering algorithm to
+    // the computed SAS hash but we may use a different SAS rendering algorithm to
     // render the computed SAS.
     if (sasHashNull || !peerIsEnrolled) {
-        cs.append("/MitM");
         newSasHash = sasHash;
     }
-    else {
-        cs.append("/SASviaMitM");
-    }
     // If other SAS schemes required - check here and use others
-    const uint8_t* render = srly->getSasAlgo();
     AlgorithmEnum* renderAlgo = &zrtpSasTypes.getByName((const char*)render);
-    uint8_t sasBytes[4];
+    uint8_t sasBytes[4];;
     if (renderAlgo->isValid()) {
         sasBytes[0] = newSasHash[0];
         sasBytes[1] = newSasHash[1];
         sasBytes[2] = newSasHash[2] & 0xf0;
         sasBytes[3] = 0;
-        if (*(int32_t*)b32 == *(int32_t*)(renderAlgo->getName())) {
-            SAS = Base32(sasBytes, 20).getEncoded();
-        }
-        else {
-            SAS.assign(sas256WordsEven[sasBytes[0]]).append(":").append(sas256WordsOdd[sasBytes[1]]);
-        }
     }
-    bool verify = zidRec->isSasVerified() && srly->isSASFlag();
-    callback->srtpSecretsOn(cs, SAS, verify);
+    SAS = Base32(sasBytes, 20).getEncoded();
+    std::string cs(cipher->getReadable());
+    cs.append("/").append(pubKey->getName()).append("/MitM");
+
+    callback->srtpSecretsOn(cs, SAS, false);
     return &zrtpRelayAck;
 }
 
@@ -1359,26 +1312,42 @@
     int numAlgosConf;
     AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
 
+    bool mandatoryFound = false;
+
     // If Hello does not contain any hash names return Sha256, its mandatory
     int num = hello->getNumHashes();
     if (num == 0) {
         return &zrtpHashes.getByName(mandatoryHash);
     }
-    // Build list of configured hash algorithm names.
+    // Build list of configured hash algorithm names, append mandatory algos
+    // if necessary.
     numAlgosConf = configureAlgos.getNumConfiguredAlgos(HashAlgorithm);
     for (i = 0; i < numAlgosConf; i++) {
         algosConf[i] = &configureAlgos.getAlgoAt(HashAlgorithm, i);
+        if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryHash) {
+            mandatoryFound = true;
+        }
+    }
+    if (!mandatoryFound) {
+        algosConf[numAlgosConf++] = &zrtpHashes.getByName(mandatoryHash);
     }
 
     // Build list of offered known algos in Hello, append mandatory algos if necessary
+    mandatoryFound = false;
     for (numAlgosOffered = 0, i = 0; i < num; i++) {
         algosOffered[numAlgosOffered] = &zrtpHashes.getByName((const char*)hello->getHashType(i));
         if (!algosOffered[numAlgosOffered]->isValid())
             continue;
-        numAlgosOffered++;
+        if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryHash) {
+            mandatoryFound = true;
+        }
+    }
+    if (!mandatoryFound) {
+        algosOffered[numAlgosOffered++] = &zrtpHashes.getByName(mandatoryHash);
     }
 
-    // Lookup offered algos in configured algos.
+    // Lookup offered algos in configured algos. Because of appended
+    // mandatory algorithms at least one match will happen
     for (i = 0; i < numAlgosOffered; i++) {
         for (ii = 0; ii < numAlgosConf; ii++) {
             if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1389,7 +1358,6 @@
     return &zrtpHashes.getByName(mandatoryHash);
 }
 
-
 AlgorithmEnum* ZRtp::findBestCipher(ZrtpPacketHello *hello, AlgorithmEnum* pk) {
 
     int i;
@@ -1400,24 +1368,44 @@
     int numAlgosConf;
     AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
 
+    bool mandatoryFound = false;
+
     int num = hello->getNumCiphers();
     if (num == 0 || (*(int32_t*)(pk->getName()) == *(int32_t*)dh2k)) {
         return &zrtpSymCiphers.getByName(aes1);
     }
 
-    // Build list of configured cipher algorithm names.
+    // Build list of configured cipher algorithm names, append mandatory algos
+    // if necessary.
     numAlgosConf = configureAlgos.getNumConfiguredAlgos(CipherAlgorithm);
     for (i = 0; i < numAlgosConf; i++) {
         algosConf[i] = &configureAlgos.getAlgoAt(CipherAlgorithm, i);
+        if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryCipher) {
+            mandatoryFound = true;
+        }
     }
-    // Build list of offered known algos names in Hello.
+    if (!mandatoryFound) {
+        algosConf[numAlgosConf++] = &zrtpSymCiphers.getByName(mandatoryCipher);
+    }
+
+    // Build list of offered known algos names in Hello, append mandatory algos if
+    // necessary
+    mandatoryFound = false;
     for (numAlgosOffered = 0, i = 0; i < num; i++) {
         algosOffered[numAlgosOffered] = &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
         if (!algosOffered[numAlgosOffered]->isValid())
             continue;
-        numAlgosOffered++;
+        if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryCipher) {
+            mandatoryFound = true;
+        }
     }
-    // Lookup offered algos in configured algos.  Prefer algorithms that appear first in Hello packet (offered).
+
+    if (!mandatoryFound) {
+        algosOffered[numAlgosOffered++] = &zrtpSymCiphers.getByName(mandatoryCipher);
+    }
+
+    // Lookup offered algos in configured algos. Because of appended
+    // mandatory algorithms at least one match will happen
     for (i = 0; i < numAlgosOffered; i++) {
         for (ii = 0; ii < numAlgosConf; ii++) {
             if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1425,106 +1413,70 @@
             }
         }
     }
-    // If we don't have a match - use the mandatory algorithm
     return &zrtpSymCiphers.getByName(mandatoryCipher);
 }
 
-// We can have the non-NIST in the list of orderedAlgos even if they are not available
-// in the code (refer to ZrtpConfigure.cpp). If they are not build in they cannot appear
-// in'configureAlgos' and thus not in the intersection lists. Thus a ZRTP build that
-// does not include the non-NIST curves also works without problems.
-//
 AlgorithmEnum* ZRtp::findBestPubkey(ZrtpPacketHello *hello) {
 
-    AlgorithmEnum* peerIntersect[ZrtpConfigure::maxNoOfAlgos+1];
-    AlgorithmEnum* ownIntersect[ZrtpConfigure::maxNoOfAlgos+1];
+    int i;
+    int ii;
+    int numAlgosOffered;
+    AlgorithmEnum* algosOffered[ZrtpConfigure::maxNoOfAlgos+1];
 
-    // Build list of own pubkey algorithm names, must follow the order
-    // defined in RFC 6189, chapter 4.1.2.
-    const char *orderedAlgos[] = {dh2k, e255, ec25, dh3k, e414, ec38};
-    int numOrderedAlgos = sizeof(orderedAlgos) / sizeof(const char*);
+    int numAlgosConf;
+    AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
 
-    int numAlgosPeer = hello->getNumPubKeys();
-    if (numAlgosPeer == 0) {
-        hash = findBestHash(hello);                    // find a hash algorithm
+    bool mandatoryFound = false;
+
+    int num = hello->getNumPubKeys();
+    if (num == 0) {
         return &zrtpPubKeys.getByName(mandatoryPubKey);
     }
-    // Build own list of intersecting algos, keep own order or algorithms
-    // The list must include real public key algorithms only, so skip mult-stream mode, 
-    // preshared and alike.
-    int numAlgosOwn = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
-    int numOwnIntersect = 0;
-    for (int i = 0; i < numAlgosOwn; i++) {
-        ownIntersect[numOwnIntersect] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, i);
-        if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)mult) {
+    // Build list of configured pubkey algorithm names, append mandatory algos
+    // if necessary.
+    // The list must include real public key algorithms only, so skip
+    // mult-stream mode, preshared and alike.
+    numAlgosConf = configureAlgos.getNumConfiguredAlgos(PubKeyAlgorithm);
+    for (i = 0, ii = 0; i < numAlgosConf; i++) {
+        algosConf[ii] = &configureAlgos.getAlgoAt(PubKeyAlgorithm, ii);
+        if (*(int32_t*)(algosConf[ii]->getName()) == *(int32_t*)mult) {
             continue;                               // skip multi-stream mode
         }
-        for (int ii = 0; ii < numAlgosPeer; ii++) {
-            if (*(int32_t*)(ownIntersect[numOwnIntersect]->getName()) == *(int32_t*)(zrtpPubKeys.getByName((const char*)hello->getPubKeyType(ii)).getName())) {
-                numOwnIntersect++;
-                break;
+        if (*(int32_t*)(algosConf[ii++]->getName()) == *(int32_t*)mandatoryPubKey) {
+            mandatoryFound = true;
+        }
+    }
+
+    numAlgosConf = ii;
+    if (!mandatoryFound) {
+        algosConf[numAlgosConf++] = &zrtpPubKeys.getByName(mandatoryPubKey);
+    }
+
+    // Build list of offered known algos in Hello, append mandatory algos if necessary
+    mandatoryFound = false;
+    for (numAlgosOffered = 0, i = 0; i < num; i++) {
+        algosOffered[numAlgosOffered] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));
+        if (!algosOffered[numAlgosOffered]->isValid())
+            continue;
+        if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryPubKey) {
+            mandatoryFound = true;
+        }
+    }
+
+    if (!mandatoryFound) {
+        algosOffered[numAlgosOffered++] = &zrtpPubKeys.getByName(mandatoryPubKey);
+    }
+
+    // Lookup offered algos in configured algos. Because of appended
+    // mandatory algorithms at least one match will happen
+    for (i = 0; i < numAlgosOffered; i++) {
+        for (ii = 0; ii < numAlgosConf; ii++) {
+            if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
+                return algosConf[ii];
             }
         }
     }
-    // Build list of peer's intersecting algos: take own list as input and build a 
-    // list of algorithms that we have in common. The order of the list is according
-    // to peer's Hello packet (peer's preferences). 
-    int numPeerIntersect = 0;
-    for (int i = 0; i < numAlgosPeer; i++) {
-        peerIntersect[numPeerIntersect] = &zrtpPubKeys.getByName((const char*)hello->getPubKeyType(i));
-        for (int ii = 0; ii < numOwnIntersect; ii++) {
-            if (*(int32_t*)(ownIntersect[ii]->getName()) == *(int32_t*)(peerIntersect[numPeerIntersect]->getName())) {
-                numPeerIntersect++;
-                break;
-            }
-        }
-    }
-    if (numPeerIntersect == 0) {       // If we don't have a common algorithm - use mandatory algorithms
-        hash = findBestHash(hello);
-        return &zrtpPubKeys.getByName(mandatoryPubKey);
-    }
-
-    // If we have only one algorithm in common or if the first entry matches - take it.
-    // Otherwise determine which algorithm from the intersection lists is first in the 
-    // list of ordered algorithms and select it (RFC6189, section 4.1.2).
-    AlgorithmEnum* useAlgo;
-    if (numPeerIntersect > 1 && *(int32_t*)(ownIntersect[0]->getName()) != *(int32_t*)(peerIntersect[0]->getName())) {
-        int own, peer;
-
-        const int32_t *name = (int32_t*)ownIntersect[0]->getName();
-        for (own = 0; own < numOrderedAlgos; own++) {
-            if (*name == *(int32_t*)orderedAlgos[own])
-                break;
-        }
-        name = (int32_t*)peerIntersect[0]->getName();
-        for (peer = 0; peer < numOrderedAlgos; peer++) {
-            if (*name == *(int32_t*)orderedAlgos[peer])
-                break;
-        }
-        if (own < peer) {
-            useAlgo = ownIntersect[0];
-        }
-        else {
-            useAlgo = peerIntersect[0];
-        }
-        // find fastest of conf vs intersecting
-    }
-    else {
-        useAlgo = peerIntersect[0];
-    }
-    int32_t algoName = *(int32_t*)(useAlgo->getName());
-
-    // select a corresponding strong hash if necessary.
-    if (algoName == *(int32_t*)ec38 || algoName == *(int32_t*)e414) {
-        hash = getStrongHashOffered(hello, algoName);
-        cipher = getStrongCipherOffered(hello, algoName);
-    }
-    else {
-        hash = getHashOffered(hello, algoName);;
-        cipher = getCipherOffered(hello, algoName);
-    }
-    authLength = getAuthLenOffered(hello, algoName);
-    return useAlgo;
+    return &zrtpPubKeys.getByName(mandatoryPubKey);
 }
 
 AlgorithmEnum* ZRtp::findBestSASType(ZrtpPacketHello *hello) {
@@ -1537,23 +1489,42 @@
     int numAlgosConf;
     AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+1];
 
+    bool mandatoryFound = false;
+
     int num = hello->getNumSas();
     if (num == 0) {
         return &zrtpSasTypes.getByName(mandatorySasType);
     }
-    // Build list of configured SAS algorithm names
+    // Buildlist of configured SAS algorithm names, append mandatory algos
+    // if necessary.
     numAlgosConf = configureAlgos.getNumConfiguredAlgos(SasType);
     for (i = 0; i < numAlgosConf; i++) {
         algosConf[i] = &configureAlgos.getAlgoAt(SasType, i);
+        if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatorySasType) {
+            mandatoryFound = true;
+        }
     }
-    // Build list of offered known algos in Hello,
+
+    if (!mandatoryFound) {
+        algosConf[numAlgosConf++] = &zrtpSasTypes.getByName(mandatorySasType);
+    }
+
+    // Build list of offered known algos in Hello, append mandatory algos if necessary
     for (numAlgosOffered = 0, i = 0; i < num; i++) {
-        algosOffered[numAlgosOffered] = &zrtpSasTypes.getByName((const char*)hello->getSasType(i));
+        algosOffered[numAlgosOffered] = &zrtpSasTypes.getByName((const char*)hello->getSasType(i++));
         if (!algosOffered[numAlgosOffered]->isValid())
             continue;
-        numAlgosOffered++;
+        if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatorySasType) {
+            mandatoryFound = true;
+        }
     }
-    // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
+
+    if (!mandatoryFound) {
+        algosOffered[numAlgosOffered++] = &zrtpSasTypes.getByName(mandatorySasType);
+    }
+
+    // Lookup offered algos in configured algos. Because of appended
+    // mandatory algorithms at least one match will happen
     for (i = 0; i < numAlgosOffered; i++) {
         for (ii = 0; ii < numAlgosConf; ii++) {
             if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1561,7 +1532,6 @@
             }
         }
     }
-    // If we don't have a match - use the mandatory algorithm
     return &zrtpSasTypes.getByName(mandatorySasType);
 }
 
@@ -1575,26 +1545,55 @@
     int numAlgosConf;
     AlgorithmEnum* algosConf[ZrtpConfigure::maxNoOfAlgos+2];
 
+    bool mandatoryFound_1 = false;
+    bool mandatoryFound_2 = false;
+
     int num = hello->getNumAuth();
     if (num == 0) {
         return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
     }
 
-    // Build list of configured Authentication tag length algorithm names.
+    // Build list of configured SAS algorithm names, append mandatory algos
+    // if necessary.
     numAlgosConf = configureAlgos.getNumConfiguredAlgos(AuthLength);
     for (i = 0; i < numAlgosConf; i++) {
         algosConf[i] = &configureAlgos.getAlgoAt(AuthLength, i);
+        if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryAuthLen_1) {
+            mandatoryFound_1 = true;
+        }
+        if (*(int32_t*)(algosConf[i]->getName()) == *(int32_t*)mandatoryAuthLen_2) {
+            mandatoryFound_2 = true;
+        }
     }
 
-    // Build list of offered known algos in Hello.
+    if (!mandatoryFound_1) {
+        algosConf[numAlgosConf++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
+    }
+
+    if (!mandatoryFound_2) {
+        algosConf[numAlgosConf++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_2);
+    }
+
+    // Build list of offered known algos in Hello, append mandatory algos if necessary
     for (numAlgosOffered = 0, i = 0; i < num; i++) {
         algosOffered[numAlgosOffered] = &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));
         if (!algosOffered[numAlgosOffered]->isValid())
             continue;
-        numAlgosOffered++;
+        if (*(int32_t*)(algosOffered[numAlgosOffered]->getName()) == *(int32_t*)mandatoryAuthLen_1) {
+            mandatoryFound_1 = true;
+        }
+        if (*(int32_t*)(algosOffered[numAlgosOffered++]->getName()) == *(int32_t*)mandatoryAuthLen_2) {
+            mandatoryFound_2 = true;
+        }
     }
-
-    // Lookup offered algos in configured algos. Prefer algorithms that appear first in Hello packet (offered).
+    if (!mandatoryFound_1) {
+        algosOffered[numAlgosOffered++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
+    }
+    if (!mandatoryFound_2) {
+        algosOffered[numAlgosOffered++] = &zrtpAuthLengths.getByName(mandatoryAuthLen_2);
+    }
+    // Lookup offered algos in configured algos. Because of appended
+    // mandatory algorithms at least one match will happen
     for (i = 0; i < numAlgosOffered; i++) {
         for (ii = 0; ii < numAlgosConf; ii++) {
             if (*(int32_t*)(algosOffered[i]->getName()) == *(int32_t*)(algosConf[ii]->getName())) {
@@ -1602,115 +1601,9 @@
             }
         }
     }
-    // If we don't have a match - use the mandatory algorithm
     return &zrtpAuthLengths.getByName(mandatoryAuthLen_1);
 }
 
-// The following set of functions implement a 'non-NIST first policy' if nonNist computes 
-// to true. They prefer nonNist algorithms if these are available. Otherwise they use the NIST
-// counterpart or simply call the according findBest*(...) function.
-//
-// Only the findBestPubkey(...) function calls them after it selected the public key algorithm.
-// If the public key algorithm is non-NIST and if the policy is set to PreferNonNist then
-// nonNist becomes true.
-//
-// The functions work according to the RFC6189 spec: the initiator can select every algorithm
-// that both parties support. Thus the Initiator can even select an algorithm the wasn't offered
-// in its own Hello packet but that the Initiator found in the peer's Hello and that is available
-// for it.
-//
-AlgorithmEnum* ZRtp::getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int numHash = hello->getNumHashes();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < numHash; i++) {
-            int32_t nm = *(int32_t*)(hello->getHashType(i));
-            if (nm == *(int32_t*)skn3) {
-                return &zrtpHashes.getByName((const char*)hello->getHashType(i));
-            }
-        }
-    }
-    for (int i = 0; i < numHash; i++) {
-        int32_t nm = *(int32_t*)(hello->getHashType(i));
-        if (nm == *(int32_t*)s384 || nm == *(int32_t*)skn3) {
-            return &zrtpHashes.getByName((const char*)hello->getHashType(i));
-        }
-    }
-    return NULL;         // returning NULL -> prepareCommit(...) terminates ZRTP, missing strong hash is an error
-}
-
-AlgorithmEnum* ZRtp::getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int num = hello->getNumCiphers();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getCipherType(i));
-            if (nm == *(int32_t*)two3) {
-                return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
-            }
-        }
-    }
-    for (int i = 0; i < num; i++) {
-        int32_t nm = *(int32_t*)(hello->getCipherType(i));
-        if (nm == *(int32_t*)aes3 || nm == *(int32_t*)two3) {
-            return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
-        }
-    }
-    return NULL;       // returning NULL -> prepareCommit(...) finds the best cipher
-}
-
-AlgorithmEnum* ZRtp::getHashOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int num = hello->getNumHashes();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getHashType(i));
-            if (nm == *(int32_t*)skn2 || nm == *(int32_t*)skn3) {
-                return &zrtpHashes.getByName((const char*)hello->getHashType(i));
-            }
-        }
-    }
-    return findBestHash(hello);
-}
-
-AlgorithmEnum* ZRtp::getCipherOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int num = hello->getNumCiphers();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getCipherType(i));
-            if (nm == *(int32_t*)two2 || nm == *(int32_t*)two3) {
-                return &zrtpSymCiphers.getByName((const char*)hello->getCipherType(i));
-            }
-        }
-    }
-    return NULL;       // returning NULL -> prepareCommit(...) finds the best cipher
-}
-
-AlgorithmEnum* ZRtp::getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName) {
-
-    int num = hello->getNumAuth();
-    bool nonNist = (algoName == *(int32_t*)e414 || algoName == *(int32_t*)e255) && configureAlgos.getSelectionPolicy() == ZrtpConfigure::PreferNonNist;
-
-    if (nonNist) {
-        for (int i = 0; i < num; i++) {
-            int32_t nm = *(int32_t*)(hello->getAuthLen(i));
-            if (nm == *(int32_t*)sk32 || nm == *(int32_t*)sk64) {
-                return &zrtpAuthLengths.getByName((const char*)hello->getAuthLen(i));
-            }
-        }
-    }
-    return findBestAuthLen(hello);
-}
-
 bool ZRtp::checkMultiStream(ZrtpPacketHello *hello) {
 
     int  i;
@@ -1731,10 +1624,6 @@
 bool ZRtp::verifyH2(ZrtpPacketCommit *commit) {
     uint8_t tmpH3[IMPL_MAX_DIGEST_LENGTH];
 
-    // packet does not have the correct size, treat H2 verfication as failed.
-    if (!commit->isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange))
-        return false;
-
     sha256(commit->getH2(), HASH_IMAGE_SIZE, tmpH3);
     if (memcmp(tmpH3, peerH3, HASH_IMAGE_SIZE) != 0) {
         return false;
@@ -1761,7 +1650,7 @@
     return;
 }
 
-void ZRtp:: computeSharedSecretSet(ZIDRecord *zidRec) {
+void ZRtp:: computeSharedSecretSet(ZIDRecord &zidRec) {
 
     /*
      * Compute the Initiator's and Reponder's retained shared secret Ids.
@@ -1770,64 +1659,45 @@
     uint8_t randBuf[RS_LENGTH];
     uint32_t macLen;
 
-    fprintf(stderr, "Compute shared secrets\n");
-    detailInfo.secretsCached = 0;
-    if (!zidRec->isRs1Valid()) {
+    if (!zidRec.isRs1Valid()) {
         randomZRTP(randBuf, RS_LENGTH);
         hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
         hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
     }
     else {
         rs1Valid = true;
-        hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
-        hmacFunction((unsigned char*)zidRec->getRs1(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
-        detailInfo.secretsCached = Rs1;
+        hmacFunction((unsigned char*)zidRec.getRs1(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs1IDi, &macLen);
+        hmacFunction((unsigned char*)zidRec.getRs1(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs1IDr, &macLen);
     }
 
-    if (!zidRec->isRs2Valid()) {
+    if (!zidRec.isRs2Valid()) {
         randomZRTP(randBuf, RS_LENGTH);
         hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
         hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
     }
     else {
         rs2Valid = true;
-        hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
-        hmacFunction((unsigned char*)zidRec->getRs2(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
-        detailInfo.secretsCached |= Rs2;
+        hmacFunction((unsigned char*)zidRec.getRs2(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), rs2IDi, &macLen);
+        hmacFunction((unsigned char*)zidRec.getRs2(), RS_LENGTH, (unsigned char*)responder, strlen(responder), rs2IDr, &macLen);
     }
 
-    if (!zidRec->isMITMKeyAvailable()) {
+    /*
+    * For the time being we don't support this types of shared secrect. Could be
+    * easily done: somebody sets some data into our ZRtp object, check it here
+    * and use it. Otherwise use the random data.
+    */
+    randomZRTP(randBuf, RS_LENGTH);
+    hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), auxSecretIDi, &macLen);
+    hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), auxSecretIDr, &macLen);
+
+    if (!zidRec.isMITMKeyAvailable()) {
         randomZRTP(randBuf, RS_LENGTH);
         hmacFunction(randBuf, RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
         hmacFunction(randBuf, RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
-
     }
     else {
-        hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
-        hmacFunction((unsigned char*)zidRec->getMiTMData(), RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
-        detailInfo.secretsCached |= Pbx;
-    }
-    computeAuxSecretIds();
-}
-
-void ZRtp::computeAuxSecretIds() {
-    uint8_t randBuf[RS_LENGTH];
-    uint32_t macLen;
-
-    if (auxSecret == NULL) {
-        randomZRTP(randBuf, RS_LENGTH);
-        hmacFunction(randBuf, RS_LENGTH, H3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);
-        hmacFunction(randBuf, RS_LENGTH, H3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);
-    }
-    else {
-        if (myRole == Initiator) {  // I'm initiator thus use my H3 for initiator's IDi, peerH3 for respnder's IDr
-            hmacFunction(auxSecret, auxSecretLength, H3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);
-            hmacFunction(auxSecret, auxSecretLength, peerH3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);
-        }
-        else {
-            hmacFunction(auxSecret, auxSecretLength, peerH3, HASH_IMAGE_SIZE, auxSecretIDi, &macLen);
-            hmacFunction(auxSecret, auxSecretLength, H3, HASH_IMAGE_SIZE, auxSecretIDr, &macLen);
-        }
+        hmacFunction((unsigned char*)zidRec.getMiTMData(), RS_LENGTH, (unsigned char*)initiator, strlen(initiator), pbxSecretIDi, &macLen);
+        hmacFunction((unsigned char*)zidRec.getMiTMData(), RS_LENGTH, (unsigned char*)responder, strlen(responder), pbxSecretIDr, &macLen);
     }
 }
 
@@ -1837,70 +1707,49 @@
  * to chapter 5.3 in the specification).
  * When using this method then we are in Initiator role.
  */
-void ZRtp::generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {
+void ZRtp::generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
     const uint8_t* setD[3];
     int32_t rsFound = 0;
 
     setD[0] = setD[1] = setD[2] = NULL;
 
-    detailInfo.secretsMatchedDH = 0;
-    if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)
-        detailInfo.secretsMatchedDH |= Rs1;
-    if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0)
-        detailInfo.secretsMatchedDH |= Rs2;
     /*
      * Select the real secrets into setD. The dhPart is DHpart1 message
      * received from responder. rs1IDr and rs2IDr are the expected ids using
      * the initator's cached retained secrets.
      */
-    // Check which RS we shall use for first place (s1)
-    detailInfo.secretsMatched = 0;
+    int matchingSecrets = 0;
     if (memcmp(rs1IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs1();
+        setD[matchingSecrets++] = zidRec.getRs1();
         rsFound = 0x1;
-        detailInfo.secretsMatched = Rs1;
     }
     else if (memcmp(rs1IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs1();
+        setD[matchingSecrets++] = zidRec.getRs1();
         rsFound = 0x2;
-        detailInfo.secretsMatched = Rs1;
     }
     else if (memcmp(rs2IDr, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs2();
+        setD[matchingSecrets++] = zidRec.getRs2();
         rsFound = 0x4;
-        detailInfo.secretsMatched = Rs2;
     }
     else if (memcmp(rs2IDr, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs2();
+        setD[matchingSecrets++] = zidRec.getRs2();
         rsFound = 0x8;
-        detailInfo.secretsMatched = Rs2;
     }
-
+    /* *** Not yet supported
     if (memcmp(auxSecretIDr, dhPart->getAuxSecretId(), 8) == 0) {
-        DEBUGOUT((fprintf(stdout, "Initiator: Match for aux secret found\n")));
-        setD[1] = auxSecret;
-        detailInfo.secretsMatched |= Aux;
-        detailInfo.secretsMatchedDH |= Aux;
+    DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
+        setD[matchingSecrets++] = auxSecret;
     }
-    if (auxSecret != NULL && (detailInfo.secretsMatched & Aux) == 0) {
-        sendInfo(Warning, WarningNoExpectedAuxMatch);
-    }
-
-    // check if we have a matching PBX secret and place it third (s3)
-    if (memcmp(pbxSecretIDr, dhPart->getPbxSecretId(), HMAC_SIZE) == 0) {
+    */
+    if (memcmp(pbxSecretIDr, dhPart->getPbxSecretId(), 8) == 0) {
         DEBUGOUT((fprintf(stdout, "%c: Match for Other_secret found\n", zid[0])));
-        setD[2] = zidRec->getMiTMData();
-        detailInfo.secretsMatched |= Pbx;
-        detailInfo.secretsMatchedDH |= Pbx;
-        // Flag to record that fact that we have a MitM key of the other peer.
-        peerIsEnrolled = true;
+        setD[matchingSecrets++] = zidRec.getMiTMData();
     }
     // Check if some retained secrets found
     if (rsFound == 0) {                        // no RS matches found
         if (rs1Valid || rs2Valid) {            // but valid RS records in cache
             sendInfo(Warning, WarningNoExpectedRSMatch);
-            zidRec->resetSasVerified();
-            saveZidRecord = false;             // Don't save RS until user verfied/confirmed SAS
+            zidRec.resetSasVerified();
         }
         else {                                 // No valid RS record in cache
             sendInfo(Warning, WarningNoRSMatch);
@@ -1934,7 +1783,7 @@
 
     //Very first element is a fixed counter, big endian
     counter = 1;
-    counter = zrtpHtonl(counter);
+    counter = htonl(counter);
     data[pos] = (unsigned char*)&counter;
     length[pos++] = sizeof(uint32_t);
 
@@ -1948,7 +1797,7 @@
 
     // Next is Initiator's id (ZIDi), in this case as Initiator
     // it is zid
-    data[pos] = ownZid;
+    data[pos] = zid;
     length[pos++] = ZID_SIZE;
 
     // Next is Responder's id (ZIDr), in this case our peer's id
@@ -1969,7 +1818,7 @@
      * this length stuff again.
      */
     int secretHashLen = RS_LENGTH;
-    secretHashLen = zrtpHtonl(secretHashLen);        // prepare 32 bit big-endian number
+    secretHashLen = htonl(secretHashLen);        // prepare 32 bit big-endian number
 
     for (int32_t i = 0; i < 3; i++) {
         if (setD[i] != NULL) {           // a matching secret, set length, then secret
@@ -1977,7 +1826,7 @@
             data[pos] = (unsigned char*)&sLen[i];
             length[pos++] = sizeof(uint32_t);
             data[pos] = (unsigned char*)setD[i];
-            length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
+            length[pos++] = RS_LENGTH;
         }
         else {                           // no machting secret, set length 0, skip secret
             sLen[i] = 0;
@@ -2002,68 +1851,47 @@
  * retained secret ids. Compare them with the expected secret ids (refer
  * to chapter 5.3.1 in the specification).
  */
-void ZRtp::generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec) {
+void ZRtp::generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec) {
     const uint8_t* setD[3];
     int32_t rsFound = 0;
 
     setD[0] = setD[1] = setD[2] = NULL;
 
-    detailInfo.secretsMatchedDH = 0;
-    if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)
-        detailInfo.secretsMatchedDH |= Rs1;
-    if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0 || memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0)
-        detailInfo.secretsMatchedDH |= Rs2;
-
     /*
      * Select the real secrets into setD
      */
-    // Check which RS we shall use for first place (s1)
-    detailInfo.secretsMatched = 0;
+    int matchingSecrets = 0;
     if (memcmp(rs1IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs1();
+        setD[matchingSecrets++] = zidRec.getRs1();
         rsFound = 0x1;
-        detailInfo.secretsMatched = Rs1;
     }
     else if (memcmp(rs1IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs1();
+        setD[matchingSecrets++] = zidRec.getRs1();
         rsFound = 0x2;
-        detailInfo.secretsMatched = Rs1;
-    }
-    else if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs2();
-        rsFound |= 0x4;
-        detailInfo.secretsMatched = Rs2;
     }
     else if (memcmp(rs2IDi, dhPart->getRs2Id(), HMAC_SIZE) == 0) {
-        setD[0] = zidRec->getRs2();
+        setD[matchingSecrets++] = zidRec.getRs2();
+        rsFound |= 0x4;
+    }
+    else if (memcmp(rs2IDi, dhPart->getRs1Id(), HMAC_SIZE) == 0) {
+        setD[matchingSecrets++] = zidRec.getRs2();
         rsFound |= 0x8;
-        detailInfo.secretsMatched = Rs2;
     }
-
-    if (memcmp(auxSecretIDi, dhPart->getAuxSecretId(), 8) == 0) {
-        DEBUGOUT((fprintf(stdout, "Responder: Match for aux secret found\n")));
-        setD[1] = auxSecret;
-        detailInfo.secretsMatched |= Aux;
-        detailInfo.secretsMatchedDH |= Aux;
+    /* ***** not yet supported
+    if (memcmp(auxSecretIDi, dhPart->getauxSecretId(), 8) == 0) {
+    DEBUGOUT((fprintf(stdout, "%c: Match for aux secret found\n", zid[0])));
+        setD[matchingSecrets++] = ;
     }
-    // If we have an auxSecret but no match from peer - report this.
-    if (auxSecret != NULL && (detailInfo.secretsMatched & Aux) == 0) {
-        sendInfo(Warning, WarningNoExpectedAuxMatch);
-    }
-
+    */
     if (memcmp(pbxSecretIDi, dhPart->getPbxSecretId(), 8) == 0) {
-        DEBUGOUT((fprintf(stdout, "%c: Match for PBX secret found\n", ownZid[0])));
-        setD[2] = zidRec->getMiTMData();
-        detailInfo.secretsMatched |= Pbx;
-        detailInfo.secretsMatchedDH |= Pbx;
-        peerIsEnrolled = true;
+        DEBUGOUT((fprintf(stdout, "%c: Match for PBX secret found\n", zid[0])));
+        setD[matchingSecrets++] = zidRec.getMiTMData();
     }
     // Check if some retained secrets found
     if (rsFound == 0) {                        // no RS matches found
         if (rs1Valid || rs2Valid) {            // but valid RS records in cache
             sendInfo(Warning, WarningNoExpectedRSMatch);
-            zidRec->resetSasVerified();
-            saveZidRecord = false;             // Don't save RS until user verfied/confirmed SAS
+            zidRec.resetSasVerified();
         }
         else {                                 // No valid RS record in cache
             sendInfo(Warning, WarningNoRSMatch);
@@ -2099,7 +1927,7 @@
 
     //Very first element is a fixed counter, big endian
     counter = 1;
-    counter = zrtpHtonl(counter);
+    counter = htonl(counter);
     data[pos] = (unsigned char*)&counter;
     length[pos++] = sizeof(uint32_t);
 
@@ -2117,7 +1945,7 @@
     length[pos++] = ZID_SIZE;
 
     // Next is Responder's id (ZIDr), in this case our own zid
-    data[pos] = ownZid;
+    data[pos] = zid;
     length[pos++] = ZID_SIZE;
 
     // Next ist total hash (messageHash) itself
@@ -2134,7 +1962,7 @@
      * this length stuff again.
      */
     int secretHashLen = RS_LENGTH;
-    secretHashLen = zrtpHtonl(secretHashLen);        // prepare 32 bit big-endian number
+    secretHashLen = htonl(secretHashLen);        // prepare 32 bit big-endian number
 
     for (int32_t i = 0; i < 3; i++) {
         if (setD[i] != NULL) {           // a matching secret, set length, then secret
@@ -2142,7 +1970,7 @@
             data[pos] = (unsigned char*)&sLen[i];
             length[pos++] = sizeof(uint32_t);
             data[pos] = (unsigned char*)setD[i];
-            length[pos++] = (i != 1) ? RS_LENGTH : auxSecretLength;
+            length[pos++] = RS_LENGTH;
         }
         else {                           // no machting secret, set length 0, skip secret
             sLen[i] = 0;
@@ -2174,7 +2002,7 @@
 
     // Very first element is a fixed counter, big endian
     uint32_t counter = 1;
-    counter = zrtpHtonl(counter);
+    counter = htonl(counter);
     data[pos] = (unsigned char*)&counter;
     length[pos++] = sizeof(uint32_t);
 
@@ -2187,7 +2015,7 @@
     length[pos++] = contextLength;
 
     // last element is HMAC length in bits, big endian
-    uint32_t len = zrtpHtonl(L);
+    uint32_t len = htonl(L);
     data[pos] = (unsigned char*)&len;
     length[pos++] = sizeof(uint32_t);
 
@@ -2201,18 +2029,18 @@
 void ZRtp::generateKeysMultiStream() {
 
     // allocate the maximum size, compute real size to use
-    uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];
-    int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;
+    uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)+sizeof(messageHash)];
+    int32_t kdfSize = sizeof(peerZid)+sizeof(zid)+hashLength;
 
     if (myRole == Responder) {
         memcpy(KDFcontext, peerZid, sizeof(peerZid));
-        memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
+        memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
     }
     else {
-        memcpy(KDFcontext, ownZid, sizeof(ownZid));
-        memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
+        memcpy(KDFcontext, zid, sizeof(zid));
+        memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
     }
-    memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);
+    memcpy(KDFcontext+sizeof(zid)+sizeof(peerZid), messageHash, hashLength);
 
     KDF(zrtpSession, hashLength, (unsigned char*)zrtpMsk, strlen(zrtpMsk)+1, KDFcontext, kdfSize, hashLength*8, s0);
 
@@ -2224,16 +2052,16 @@
 void ZRtp::computePBXSecret() {
     // Construct the KDF context as per ZRTP specification chap 7.3.1:
     // ZIDi || ZIDr
-    uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)];
-    int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid);
+    uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)];
+    int32_t kdfSize = sizeof(peerZid)+sizeof(zid);
 
     if (myRole == Responder) {
         memcpy(KDFcontext, peerZid, sizeof(peerZid));
-        memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
+        memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
     }
     else {
-        memcpy(KDFcontext, ownZid, sizeof(ownZid));
-        memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
+        memcpy(KDFcontext, zid, sizeof(zid));
+        memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
     }
 
     KDF(zrtpSession, hashLength, (unsigned char*)zrtpTrustedMitm, strlen(zrtpTrustedMitm)+1, KDFcontext,
@@ -2246,20 +2074,20 @@
 void ZRtp::computeSRTPKeys() {
 
     // allocate the maximum size, compute real size to use
-    uint8_t KDFcontext[sizeof(peerZid)+sizeof(ownZid)+sizeof(messageHash)];
-    int32_t kdfSize = sizeof(peerZid)+sizeof(ownZid)+hashLength;
+    uint8_t KDFcontext[sizeof(peerZid)+sizeof(zid)+sizeof(messageHash)];
+    int32_t kdfSize = sizeof(peerZid)+sizeof(zid)+hashLength;
 
     int32_t keyLen = cipher->getKeylen() * 8;
 
     if (myRole == Responder) {
         memcpy(KDFcontext, peerZid, sizeof(peerZid));
-        memcpy(KDFcontext+sizeof(peerZid), ownZid, sizeof(ownZid));
+        memcpy(KDFcontext+sizeof(peerZid), zid, sizeof(zid));
     }
     else {
-        memcpy(KDFcontext, ownZid, sizeof(ownZid));
-        memcpy(KDFcontext+sizeof(ownZid), peerZid, sizeof(peerZid));
+        memcpy(KDFcontext, zid, sizeof(zid));
+        memcpy(KDFcontext+sizeof(zid), peerZid, sizeof(peerZid));
     }
-    memcpy(KDFcontext+sizeof(ownZid)+sizeof(peerZid), messageHash, hashLength);
+    memcpy(KDFcontext+sizeof(zid)+sizeof(peerZid), messageHash, hashLength);
 
     // Inititiator key and salt
     KDF(s0, hashLength, (unsigned char*)iniMasterKey, strlen(iniMasterKey)+1, KDFcontext, kdfSize, keyLen, srtpKeyI);
@@ -2271,13 +2099,13 @@
 
     // The HMAC keys for GoClear
     KDF(s0, hashLength, (unsigned char*)iniHmacKey, strlen(iniHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyI);
+
     KDF(s0, hashLength, (unsigned char*)respHmacKey, strlen(respHmacKey)+1, KDFcontext, kdfSize, hashLength*8, hmacKeyR);
 
     // The keys for Confirm messages
     KDF(s0, hashLength, (unsigned char*)iniZrtpKey, strlen(iniZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyI);
     KDF(s0, hashLength, (unsigned char*)respZrtpKey, strlen(respZrtpKey)+1, KDFcontext, kdfSize, keyLen, zrtpKeyR);
 
-    detailInfo.pubKey = detailInfo.sasType = NULL;
     if (!multiStream) {
         // Compute the new Retained Secret
         KDF(s0, hashLength, (unsigned char*)retainedSec, strlen(retainedSec)+1, KDFcontext, kdfSize, SHA256_DIGEST_LENGTH*8, newRs1);
@@ -2285,7 +2113,7 @@
         // Compute the ZRTP Session Key
         KDF(s0, hashLength, (unsigned char*)zrtpSessionKey, strlen(zrtpSessionKey)+1, KDFcontext, kdfSize, hashLength*8, zrtpSession);
 
-        // perform  generation according to chapter 5.5 and 8.
+        // perform SAS generation according to chapter 5.5 and 8.
         // we don't need a speciai sasValue filed. sasValue are the first
         // (leftmost) 32 bits (4 bytes) of sasHash
         uint8_t sasBytes[4];
@@ -2298,24 +2126,10 @@
         sasBytes[1] = sasHash[1];
         sasBytes[2] = sasHash[2] & 0xf0;
         sasBytes[3] = 0;
-        if (*(int32_t*)b32 == *(int32_t*)(sasType->getName())) {
-            SAS = Base32(sasBytes, 20).getEncoded();
-        }
-        else {
-            SAS.assign(sas256WordsEven[sasBytes[0]]).append(":").append(sas256WordsOdd[sasBytes[1]]);
-        }
-
+        SAS = Base32(sasBytes, 20).getEncoded();
         if (signSasSeen)
             callback->signSAS(sasHash);
-
-        detailInfo.pubKey = pubKey->getReadable();
-        detailInfo.sasType = sasType->getReadable();
     }
-    // set algorithm names into detailInfo structure
-    detailInfo.authLength = authLength->getReadable();
-    detailInfo.cipher = cipher->getReadable();
-    detailInfo.hash = hash->getReadable();
-
     memset(KDFcontext, 0, sizeof(KDFcontext));
 }
 
@@ -2341,25 +2155,7 @@
     sec.sas = SAS;
     sec.role = myRole;
 
-    bool rc = callback->srtpSecretsReady(&sec, part);
-
-    // The call state engine calls ForSender always after ForReceiver.
-    if (part == ForSender) {
-        std::string cs(cipher->getReadable());
-        if (!multiStream) {
-            cs.append("/").append(pubKey->getName());
-            if (mitmSeen)
-                cs.append("/EndAtMitM");
-            callback->srtpSecretsOn(cs, SAS, zidRec->isSasVerified());
-        }
-        else {
-            std::string cs1("");
-            if (mitmSeen)
-                cs.append("/EndAtMitM");
-            callback->srtpSecretsOn(cs, cs1, true);
-        }
-    }
-    return rc;
+    return callback->srtpSecretsReady(&sec, part);
 }
 
 
@@ -2392,34 +2188,6 @@
         hashCtxFunction = sha384Ctx;
         hashCtxListFunction = sha384Ctx;
         break;
-
-    case 2:
-        hashLength = SKEIN256_DIGEST_LENGTH;
-        hashFunction = skein256;
-        hashListFunction = skein256;
-
-        hmacFunction = macSkein256;
-        hmacListFunction = macSkein256;
-
-        createHashCtx = createSkein256Context;
-        closeHashCtx = closeSkein256Context;
-        hashCtxFunction = skein256Ctx;
-        hashCtxListFunction = skein256Ctx;
-        break;
-
-    case 3:
-        hashLength = SKEIN384_DIGEST_LENGTH;
-        hashFunction = skein384;
-        hashListFunction = skein384;
-
-        hmacFunction = macSkein384;
-        hmacListFunction = macSkein384;
-
-        createHashCtx = createSkein384Context;
-        closeHashCtx = closeSkein384Context;
-        hashCtxFunction = skein384Ctx;
-        hashCtxListFunction = skein384Ctx;
-        break;
     }
 }
 
@@ -2432,25 +2200,25 @@
     if (paranoidMode)
         return;
 
-    zidRec->setSasVerified();
-    saveZidRecord = true;
-    getZidCacheInstance()->saveRecord(zidRec);
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+    ZIDFile *zid = ZIDFile::getInstance();
+
+    zid->getRecord(&zidRec);
+    zidRec.setSasVerified();
+    zid->saveRecord(&zidRec);
 }
 
 void ZRtp::resetSASVerified() {
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+    ZIDFile *zid = ZIDFile::getInstance();
 
-    zidRec->resetSasVerified();
-    getZidCacheInstance()->saveRecord(zidRec);
+    zid->getRecord(&zidRec);
+    zidRec.resetSasVerified();
+    zid->saveRecord(&zidRec);
 }
 
-void ZRtp::setRs2Valid() {
-
-    if (zidRec != NULL) {
-        zidRec->setRs2Valid();
-        if (saveZidRecord)
-            getZidCacheInstance()->saveRecord(zidRec);
-    }
-}
 
 void ZRtp::sendInfo(GnuZrtpCodes::MessageSeverity severity, int32_t subCode) {
 
@@ -2502,32 +2270,33 @@
     }
 }
 
-void ZRtp::setClientId(std::string id, HelloPacketVersion* hpv) {
+void ZRtp::setClientId(std::string id) {
+    if (id.size() < CLIENT_ID_SIZE) {
+        unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
+        memcpy(tmp, id.c_str(), id.size());
+        tmp[CLIENT_ID_SIZE] = 0;
+        zrtpHello.setClientId(tmp);
+    } else {
+        zrtpHello.setClientId((unsigned char*)id.c_str());
+    }
 
-    unsigned char tmp[CLIENT_ID_SIZE +1] = {' '};
-    memcpy(tmp, id.c_str(), id.size() > CLIENT_ID_SIZE ? CLIENT_ID_SIZE : id.size());
-    tmp[CLIENT_ID_SIZE] = 0;
+    int32_t len = zrtpHello.getLength() * ZRTP_WORD_SIZE;
 
-    hpv->packet->setClientId(tmp);
-
-    int32_t len = hpv->packet->getLength() * ZRTP_WORD_SIZE;
-
-    // Hello packets are ready now, compute its HMAC
+    // Hello packet is ready now, compute its HMAC
     // (excluding the HMAC field (2*ZTP_WORD_SIZE)) and store in Hello
     // use the implicit hash function
     uint8_t hmac[IMPL_MAX_DIGEST_LENGTH];
     uint32_t macLen;
-    hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)hpv->packet->getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
-    hpv->packet->setHMAC(hmac);
+    hmacFunctionImpl(H2, HASH_IMAGE_SIZE, (uint8_t*)zrtpHello.getHeaderBase(), len-(2*ZRTP_WORD_SIZE), hmac, &macLen);
+    zrtpHello.setHMAC(hmac);
 
     // calculate hash over the final Hello packet, refer to chap 9.1 how to
     // use this hash in SIP/SDP.
-    hashFunctionImpl((uint8_t*)hpv->packet->getHeaderBase(), len, hpv->helloHash);
+    hashFunctionImpl((uint8_t*)zrtpHello.getHeaderBase(), len, helloHash);
 }
 
 void ZRtp::storeMsgTemp(ZrtpPacketBase* pkt) {
-    uint32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
-    length = (length > sizeof(tempMsgBuffer)) ? sizeof(tempMsgBuffer) : length;
+    int32_t length = pkt->getLength() * ZRTP_WORD_SIZE;
     memset(tempMsgBuffer, 0, sizeof(tempMsgBuffer));
     memcpy(tempMsgBuffer, (uint8_t*)pkt->getHeaderBase(), length);
     lengthOfMsgData = length;
@@ -2543,18 +2312,12 @@
     return (memcmp(hmac, tempMsgBuffer+len, (HMAC_SIZE)) == 0 ? true : false);
 }
 
-std::string ZRtp::getHelloHash(int32_t index) {
+std::string ZRtp::getHelloHash() {
     std::ostringstream stm;
 
-    if (index < 0 || index >= MAX_ZRTP_VERSIONS)
-        return std::string();
+    uint8_t* hp = helloHash;
 
-    uint8_t* hp = helloPackets[index].helloHash;
-
-    char version[5] = {'\0'};
-    strncpy(version, (const char*)helloPackets[index].packet->getVersion(), ZRTP_WORD_SIZE);
-
-    stm << version;
+    stm << zrtpVersion;
     stm << " ";
     stm.fill('0');
     stm << hex;
@@ -2634,19 +2397,24 @@
 
 void ZRtp::acceptEnrollment(bool accepted) {
     if (!accepted) {
-        zidRec->resetMITMKeyAvailable();
         callback->zrtpInformEnrollment(EnrollmentCanceled);
-        getZidCacheInstance()->saveRecord(zidRec);
         return;
     }
+    // Get peer's zid record to store the pbx (MitM) secret
+    // Initialize a ZID record to get peer's retained secrets
+    ZIDRecord zidRec(peerZid);
+    ZIDFile* zid = ZIDFile::getInstance();
+    zid->getRecord(&zidRec);
+
     if (pbxSecretTmp != NULL) {
-        zidRec->setMiTMData(pbxSecretTmp);
-        getZidCacheInstance()->saveRecord(zidRec);
+        zidRec.setMiTMData(pbxSecretTmp);
         callback->zrtpInformEnrollment(EnrollmentOk);
     }
     else {
         callback->zrtpInformEnrollment(EnrollmentFailed);
+        return;
     }
+    zid->saveRecord(&zidRec);
     return;
 }
 
@@ -2671,8 +2439,7 @@
     Event_t ev;
 
     ev.type = ZrtpPacket;
-    ev.packet = (uint8_t*)zrtpConf2Ack.getHeaderBase();
-    ev.length = sizeof (Conf2AckPacket_t) + 12;  // 12 is fixed ZRTP (RTP) header size
+    ev.packet = (uint8_t*)&zrtpConf2Ack;
 
     if (stateEngine != NULL) {
         stateEngine->processEvent(&ev);
@@ -2680,8 +2447,7 @@
 }
 
 int32_t ZRtp::compareCommit(ZrtpPacketCommit *commit) {
-    // TODO: enhance to compare according to rules defined in chapter 4.2,
-    // but we don't support Preshared.
+    // TODO: enhance to compare according to rules defined in chapter 4.2
     int32_t len = 0;
     len = !multiStream ? HVI_SIZE : (4 * ZRTP_WORD_SIZE);
     return (memcmp(hvi, commit->getHvi(), len));
@@ -2720,8 +2486,9 @@
     randomZRTP(randomIV, sizeof(randomIV));
     zrtpSasRelay.setIv(randomIV);
     zrtpSasRelay.setTrustedSas(sh);
-    zrtpSasRelay.setSasAlgo((uint8_t*)render.c_str());
+    zrtpSasRelay.setSas((uint8_t*)render.c_str());
 
+    // Encrypt and HMAC with Initiator's key - we are Initiator here
     int16_t hmlen = (zrtpSasRelay.getLength() - 9) * ZRTP_WORD_SIZE;
     cipher->getEncrypt()(ekey, cipher->getKeylen(), randomIV, (uint8_t*)zrtpSasRelay.getFiller(), hmlen);
 
@@ -2748,22 +2515,6 @@
     return IDENTIFIER_LEN;
 }
 
-const ZRtp::zrtpInfo* ZRtp::getDetailInfo() {
-    return &detailInfo;
-}
-
-std::string ZRtp::getPeerClientId() {
-    if (peerClientId.empty())
-        return std::string();
-    return peerClientId;
-}
-
-std::string ZRtp::getPeerProtcolVersion() {
-    if (peerHelloVersion[0] == 0)
-        return std::string();
-    return std::string((char*)peerHelloVersion);
-}
-
 /** EMACS **
  * Local variables:
  * mode: c++
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp b/jni/libzrtp/sources/src/ZrtpCWrapper.cpp
similarity index 94%
rename from jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
rename to jni/libzrtp/sources/src/ZrtpCWrapper.cpp
index 7f7c3dd..1e1d2c8 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpCWrapper.cpp
+++ b/jni/libzrtp/sources/src/ZrtpCWrapper.cpp
@@ -1,9 +1,9 @@
 /*
     This class maps the ZRTP C calls to ZRTP C++ methods.
-    Copyright (C) 2010-2013  Werner Dittmann
+    Copyright (C) 2010  Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
@@ -19,7 +19,7 @@
 
 #include <libzrtpcpp/ZrtpCallback.h>
 #include <libzrtpcpp/ZrtpConfigure.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZIDFile.h>
 #include <libzrtpcpp/ZRtp.h>
 #include <libzrtpcpp/ZrtpCallbackWrapper.h>
 #include <libzrtpcpp/ZrtpCWrapper.h>
@@ -55,7 +55,8 @@
 
     // Initialize ZID file (cache) and get my own ZID
     zrtp_initZidFile(zidFilename);
-    const unsigned char* myZid = getZidCacheInstance()->getZid();
+    ZIDFile* zf = ZIDFile::getInstance();
+    const unsigned char* myZid = zf->getZid();
 
     zrtpContext->zrtpEngine = new ZRtp((uint8_t*)myZid, zrtpContext->zrtpCallback,
                               clientIdString, zrtpContext->configure, mitmMode == 0 ? false : true);
@@ -79,7 +80,7 @@
 }
 
 static int32_t zrtp_initZidFile(const char* zidFilename) {
-    ZIDCache* zf = getZidCacheInstance();
+    ZIDFile* zf = ZIDFile::getInstance();
 
     if (!zf->isOpen()) {
         std::string fname;
@@ -124,9 +125,9 @@
         zrtpContext->zrtpEngine->stopZrtp();
 }
 
-void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC, size_t length) {
+void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC) {
     if (zrtpContext && zrtpContext->zrtpEngine)
-        zrtpContext->zrtpEngine->processZrtpMessage(extHeader, peerSSRC, length);
+        zrtpContext->zrtpEngine->processZrtpMessage(extHeader, peerSSRC);
 }
 
 void zrtp_processTimeout(ZrtpContext* zrtpContext) {
@@ -164,10 +165,10 @@
         zrtpContext->zrtpEngine->resetSASVerified();
 }
 
-char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index) {
+char* zrtp_getHelloHash(ZrtpContext* zrtpContext) {
     std::string ret;
     if (zrtpContext && zrtpContext->zrtpEngine)
-        ret = zrtpContext->zrtpEngine->getHelloHash(index);
+        ret = zrtpContext->zrtpEngine->getHelloHash();
     else
         return NULL;
 
@@ -324,13 +325,6 @@
     return 0;
 }
 
-int32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext) {
-    return zrtpContext->zrtpEngine->getNumberSupportedVersions();
-}
-
-int32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext) {
-    return zrtpContext->zrtpEngine->getCurrentProtocolVersion();
-}
 /*
  * The following methods wrap the ZRTP Configure functions
  */
diff --git a/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp b/jni/libzrtp/sources/src/ZrtpCallbackWrapper.cpp
similarity index 96%
rename from jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp
rename to jni/libzrtp/sources/src/ZrtpCallbackWrapper.cpp
index fed2c04..ca2dce6 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpCallbackWrapper.cpp
+++ b/jni/libzrtp/sources/src/ZrtpCallbackWrapper.cpp
@@ -1,9 +1,9 @@
 /*
     This class maps the ZRTP C++ callback methods to C callback methods.
-    Copyright (C) 2010-2013  Werner Dittmann
+    Copyright (C) 2010  Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp b/jni/libzrtp/sources/src/ZrtpConfigure.cpp
similarity index 85%
rename from jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
rename to jni/libzrtp/sources/src/ZrtpConfigure.cpp
index 6a22983..560466f 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpConfigure.cpp
+++ b/jni/libzrtp/sources/src/ZrtpConfigure.cpp
@@ -1,26 +1,5 @@
-/*

-  Copyright (C) 2006-2013 Werner Dittmann

-

-  This program is free software: you can redistribute it and/or modify

-  it under the terms of the GNU Lesser General Public License as published by

-  the Free Software Foundation, either version 3 of the License, or

-  (at your option) any later version.

-

-  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.  See the

-  GNU General Public License for more details.

-

-  You should have received a copy of the GNU General Public License

-  along with this program.  If not, see <http://www.gnu.org/licenses/>.

-*/

-

-/*

- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>

- */

-

-#include <crypto/aesCFB.h>

-#include <crypto/twoCFB.h>

+#include <libzrtpcpp/crypto/aesCFB.h>

+#include <libzrtpcpp/crypto/twoCFB.h>

 #include <libzrtpcpp/ZrtpConfigure.h>

 #include <libzrtpcpp/ZrtpTextData.h>

 

@@ -154,10 +133,8 @@
  * Set up the enumeration list for available hash algorithms

  */

 HashEnum::HashEnum() : EnumBase(HashAlgorithm) {

-    insert(s256, 0, "SHA-256", NULL, NULL, None);

-    insert(s384, 0, "SHA-384", NULL, NULL, None);

-    insert(skn2, 0, "Skein-256", NULL, NULL, None);

-    insert(skn3, 0, "Skein-384", NULL, NULL, None);

+    insert(s256);

+    insert(s384);

 }

 

 HashEnum::~HashEnum() {}

@@ -166,10 +143,10 @@
  * Set up the enumeration list for available symmetric cipher algorithms

  */

 SymCipherEnum::SymCipherEnum() : EnumBase(CipherAlgorithm) {

-    insert(aes3, 32, "AES-256", aesCfbEncrypt, aesCfbDecrypt, Aes);

-    insert(aes1, 16, "AES-128", aesCfbEncrypt, aesCfbDecrypt, Aes);

-    insert(two3, 32, "Twofish-256", twoCfbEncrypt, twoCfbDecrypt, TwoFish);

-    insert(two1, 16, "TwoFish-128", twoCfbEncrypt, twoCfbDecrypt, TwoFish);

+    insert(aes3, 32, "AES-CM-256", aesCfbEncrypt, aesCfbDecrypt, Aes);

+    insert(aes1, 16, "AES-CM-128", aesCfbEncrypt, aesCfbDecrypt, Aes);

+    insert(two3, 32, "TWO-CM-256", twoCfbEncrypt, twoCfbDecrypt, TwoFish);

+    insert(two1, 16, "TWO-CM-128", twoCfbEncrypt, twoCfbDecrypt, TwoFish);

 }

 

 SymCipherEnum::~SymCipherEnum() {}

@@ -178,15 +155,11 @@
  * Set up the enumeration list for available public key algorithms

  */

 PubKeyEnum::PubKeyEnum() : EnumBase(PubKeyAlgorithm) {

-    insert(dh2k, 0, "DH-2048", NULL, NULL, None);

-    insert(ec25, 0, "NIST ECDH-256", NULL, NULL, None);

-    insert(dh3k, 0, "DH-3072", NULL, NULL, None);

-    insert(ec38, 0, "NIST ECDH-384", NULL, NULL, None);

-    insert(mult, 0, "Multi-stream",  NULL, NULL, None);

-#ifdef SUPPORT_NON_NIST

-    insert(e255, 0, "ECDH-255", NULL, NULL, None);

-    insert(e414, 0, "ECDH-414", NULL, NULL, None);

-#endif

+    insert(dh2k);

+    insert(dh3k);

+    insert(mult);

+    insert(ec25);

+    insert(ec38);

 }

 

 PubKeyEnum::~PubKeyEnum() {}

@@ -196,7 +169,6 @@
  */

 SasTypeEnum::SasTypeEnum() : EnumBase(SasType) {

     insert(b32);

-    insert(b256);

 }

 

 SasTypeEnum::~SasTypeEnum() {}

@@ -205,10 +177,10 @@
  * Set up the enumeration list for available SRTP authentications

  */

 AuthLengthEnum::AuthLengthEnum() : EnumBase(AuthLength) {

-    insert(hs32, 32, "HMAC-SHA1 32 bit", NULL, NULL, Sha1);

-    insert(hs80, 80, "HMAC-SHA1 80 bit", NULL, NULL, Sha1);

-    insert(sk32, 32, "Skein-MAC 32 bit", NULL, NULL, Skein);

-    insert(sk64, 64, "Skein-MAC 64 bit", NULL, NULL, Skein);

+    insert(hs32, 32, "", NULL, NULL, Sha1);

+    insert(hs80, 80, "", NULL, NULL, Sha1);

+    insert(sk32, 32, "", NULL, NULL, Skein);

+    insert(sk64, 64, "", NULL, NULL, Skein);

 }

 

 AuthLengthEnum::~AuthLengthEnum() {}

@@ -225,8 +197,7 @@
 /*

  * The public methods are mainly a facade to the private methods.

  */

-ZrtpConfigure::ZrtpConfigure(): enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false),

-selectionPolicy(Standard){}

+ZrtpConfigure::ZrtpConfigure() : enableTrustedMitM(false), enableSasSignature(false), enableParanoidMode(false) {}

 

 ZrtpConfigure::~ZrtpConfigure() {}

 

diff --git a/jni/libzrtp/sources/zrtp/ZrtpCrc32.cpp b/jni/libzrtp/sources/src/ZrtpCrc32.cpp
similarity index 74%
rename from jni/libzrtp/sources/zrtp/ZrtpCrc32.cpp
rename to jni/libzrtp/sources/src/ZrtpCrc32.cpp
index 0606561..c65b19a 100755
--- a/jni/libzrtp/sources/zrtp/ZrtpCrc32.cpp
+++ b/jni/libzrtp/sources/src/ZrtpCrc32.cpp
@@ -1,7 +1,46 @@
+/* SCTP kernel reference Implementation
+ * Copyright (c) 1999-2001 Motorola, Inc.
+ * Copyright (c) 2001-2003 International Business Machines, Corp.
+ *
+ * SCTP Checksum functions
+ *
+ * The SCTP reference implementation is free software;
+ * you can redistribute it and/or modify it under the terms of
+ * the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * The SCTP reference implementation 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.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU CC; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Please send any bug reports or fixes you make to the
+ * email address(es):
+ *    lksctp developers <lksctp-developers@lists.sourceforge.net>
+ *
+ * Or submit a bug report through the following website:
+ *    http://www.sf.net/projects/lksctp
+ *
+ * Written or modified by:
+ *    Dinakaran Joseph
+ *    Jon Grimm <jgrimm@us.ibm.com>
+ *    Sridhar Samudrala <sri@us.ibm.com>
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorporated into the next SCTP release.
+ */
+
 /* The following code has been taken directly from
  * draft-ietf-tsvwg-sctpcsum-03.txt
  *
- * The code has now been modified by Werner.Dittmann@t-online.de for use
+ * The code has now been modified by Werner.Dittmann@t-online.de for use 
  * inside the ZRTP implementation.
  */
 
@@ -145,10 +184,40 @@
     byte3 = (result>>24) & 0xff;
 
     crc32 = ((byte0 << 24) |
-    (byte1 << 16) |
-    (byte2 << 8)  |
-    byte3);
+	     (byte1 << 16) |
+	     (byte2 << 8)  |
+	     byte3);
     // fprintf(stderr, "Computed crc32: %x\n", crc32);
     return crc32;
 }
 
+#ifdef UNIT_TEST
+uint8_t test_data[48] = {
+    0x01, 0xC0, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x01, 0xFE, 0x60, 0xAC,
+    0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x09,
+    0x25, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00,
+};
+    
+int main( int argc, char * argv[] )
+{
+    crc32c =  sctp_update_cksum(test_data, 48);
+    printf("Hello World, expected result: 0x664f75eb\n");
+    printf("Result is: 0x%x\n", crc32c);
+}
+#endif
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketClearAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketClearAck.cpp
index 5a96f52..85f1484 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketClearAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketClearAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp b/jni/libzrtp/sources/src/ZrtpPacketCommit.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketCommit.cpp
index b582777..af4bb09 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketCommit.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketCommit.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp b/jni/libzrtp/sources/src/ZrtpPacketConf2Ack.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketConf2Ack.cpp
index 67a51ee..f35dc82 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConf2Ack.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketConf2Ack.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp b/jni/libzrtp/sources/src/ZrtpPacketConfirm.cpp
similarity index 83%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketConfirm.cpp
index 6f13cae..f558759 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketConfirm.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketConfirm.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -66,17 +66,6 @@
     return true;
 }
 
-bool ZrtpPacketConfirm::isSignatureLengthOk() {
-    int32_t actualLen = getLength();
-    int32_t expectedLen = 19;                  // Confirm packet fixed part is 19 ZRTP words
-    int32_t sigLen = getSignatureLength();
-
-    if (sigLen > 0) {                          // We have a signature
-        expectedLen += sigLen + 1;             // +1 for the signature length field
-    }
-    return (expectedLen == actualLen);
-}
-
 int32_t ZrtpPacketConfirm::getSignatureLength() {
     int32_t sl = confirmHeader->sigLength & 0xff;
     if (confirmHeader->filler[1] == 1) {                              // do we have a 9th bit
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp b/jni/libzrtp/sources/src/ZrtpPacketDHPart.cpp
similarity index 83%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketDHPart.cpp
index 1a89e16..8c59233 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketDHPart.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketDHPart.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -59,12 +59,6 @@
     else if (*(int32_t*)pkt == *(int32_t*)ec38) {
         dhLength = 96;
     }
-    else if (*(int32_t*)pkt == *(int32_t*)e255) {
-        dhLength = 32;
-    }
-    else if (*(int32_t*)pkt == *(int32_t*)e414) {
-        dhLength = 104;
-    }
     else
         return;
 
@@ -80,24 +74,18 @@
 
     int16_t len = getLength();
     DEBUGOUT((fprintf(stdout, "DHPart length: %d\n", len)));
-    if (len == 85) {         // Dh2k
+    if (len == 85) {
         dhLength = 256;
     }
-    else if (len == 117) {   // Dh3k
+    else if (len == 117) {
         dhLength = 384;
     }
-    else if (len == 37) {    // EC256
+    else if (len == 37) {
         dhLength = 64;
     }
-    else if (len == 45) {    // EC384
+    else if (len == 45) {
         dhLength = 96;
     }
-    else if (len == 29) {    // E255
-        dhLength = 32;
-    }
-    else if (len == 47) {    // E414
-        dhLength = 104;
-    }
     else {
         pv = NULL;
         return;
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp b/jni/libzrtp/sources/src/ZrtpPacketError.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketError.cpp
index 94d4dc1..a9d881e 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketError.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketError.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketErrorAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketErrorAck.cpp
index d0d0f33..3a30977 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketErrorAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketErrorAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketGoClear.cpp b/jni/libzrtp/sources/src/ZrtpPacketGoClear.cpp
similarity index 100%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketGoClear.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketGoClear.cpp
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp b/jni/libzrtp/sources/src/ZrtpPacketHello.cpp
similarity index 81%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketHello.cpp
index bc885ef..1a0b701 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHello.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketHello.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -19,7 +19,6 @@
  * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
  */
 
-#include <ctype.h>
 #include <libzrtpcpp/ZrtpPacketHello.h>
 
 
@@ -63,6 +62,8 @@
     setLength(length / ZRTP_WORD_SIZE);
     setMessageType((uint8_t*)HelloMsg);
 
+    setVersion((uint8_t*)zrtpVersion);
+
     uint32_t lenField = nHash << 16;
     for (int32_t i = 0; i < nHash; i++) {
         AlgorithmEnum& hash = config->getAlgoAt(HashAlgorithm, i);
@@ -92,7 +93,7 @@
         AlgorithmEnum& sas = config->getAlgoAt(SasType, i);
         setSasType(i, (int8_t*)sas.getName());
     }
-    *((uint32_t*)&helloHeader->flags) = zrtpHtonl(lenField);
+    *((uint32_t*)&helloHeader->flags) = htonl(lenField);
 }
 
 ZrtpPacketHello::ZrtpPacketHello(uint8_t *data) {
@@ -101,28 +102,14 @@
     zrtpHeader = (zrtpPacketHeader_t *)&((HelloPacket_t *)data)->hdr;	// the standard header
     helloHeader = (Hello_t *)&((HelloPacket_t *)data)->hello;
 
-    // Force the isLengthOk() check to fail when we process the packet.
-    if (getLength() < HELLO_FIXED_PART_LEN) {
-        computedLength = 0;
-        return;
-    }
-
     uint32_t t = *((uint32_t*)&helloHeader->flags);
-    uint32_t temp = zrtpNtohl(t);
+    uint32_t temp = ntohl(t);
 
     nHash = (temp & (0xf << 16)) >> 16;
-    nHash &= 0x7;                              // restrict to max 7 algorithms
     nCipher = (temp & (0xf << 12)) >> 12;
-    nCipher &= 0x7;
     nAuth = (temp & (0xf << 8)) >> 8;
-    nAuth &= 0x7;
     nPubkey = (temp & (0xf << 4)) >> 4;
-    nPubkey &= 0x7;
     nSas = temp & 0xf;
-    nSas &= 0x7;
-
-    // +2 : the MAC at the end of the packet
-    computedLength = nHash + nCipher + nAuth + nPubkey + nSas + sizeof(HelloPacket_t)/ZRTP_WORD_SIZE + 2;
 
     oHash = sizeof(Hello_t);
     oCipher = oHash + (nHash * ZRTP_WORD_SIZE);
@@ -135,14 +122,3 @@
 ZrtpPacketHello::~ZrtpPacketHello() {
     DEBUGOUT((fprintf(stdout, "Deleting Hello packet: alloc: %x\n", allocated)));
 }
-
-int32_t ZrtpPacketHello::getVersionInt() {
-    uint8_t* vp = getVersion();
-    int32_t version = 0;
-
-    if (isdigit(*vp) && isdigit(*vp+2)) {
-        version = (*vp - '0') * 10;
-        version += *(vp+2) - '0';
-    }
-    return version;
-}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketHelloAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketHelloAck.cpp
index 2849f2d..2d752b7 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketHelloAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketHelloAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp b/jni/libzrtp/sources/src/ZrtpPacketPing.cpp
similarity index 86%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketPing.cpp
index b79e4ac..9a1f90f 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPing.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketPing.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -30,7 +30,7 @@
     setZrtpId();
     setLength((sizeof(PingPacket_t) / ZRTP_WORD_SIZE) - 1);
     setMessageType((uint8_t*)PingMsg);
-    setVersion((uint8_t*)zrtpVersion_11);  // TODO: fix version string after clarification
+    setVersion((uint8_t*)zrtpVersion);
 }
 
 ZrtpPacketPing::ZrtpPacketPing(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketPingAck.cpp
similarity index 86%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketPingAck.cpp
index 0bee991..2331640 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketPingAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketPingAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -30,7 +30,7 @@
     setZrtpId();
     setLength((sizeof(PingAckPacket_t) / ZRTP_WORD_SIZE) - 1);
     setMessageType((uint8_t*)PingAckMsg);
-    setVersion((uint8_t*)zrtpVersion_11);  // TODO: fix version string after clarification
+    setVersion((uint8_t*)zrtpVersion);
 }
 
 ZrtpPacketPingAck::ZrtpPacketPingAck(uint8_t *data) {
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp b/jni/libzrtp/sources/src/ZrtpPacketRelayAck.cpp
similarity index 91%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketRelayAck.cpp
index a531e2f..6ff0c7a 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketRelayAck.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketRelayAck.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-20013 Werner Dittmann
+  Copyright (C) 2006-20011 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp b/jni/libzrtp/sources/src/ZrtpPacketSASrelay.cpp
similarity index 95%
rename from jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
rename to jni/libzrtp/sources/src/ZrtpPacketSASrelay.cpp
index c8b7f54..d132e28 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpPacketSASrelay.cpp
+++ b/jni/libzrtp/sources/src/ZrtpPacketSASrelay.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp b/jni/libzrtp/sources/src/ZrtpQueue.cpp
similarity index 96%
rename from jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
rename to jni/libzrtp/sources/src/ZrtpQueue.cpp
index fef847e..73cb228 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpQueue.cpp
+++ b/jni/libzrtp/sources/src/ZrtpQueue.cpp
@@ -22,8 +22,8 @@
 #include <string>
 #include <stdio.h>
 
-#include <ZrtpQueue.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZrtpQueue.h>
+#include <libzrtpcpp/ZIDFile.h>
 #include <libzrtpcpp/ZRtp.h>
 #include <libzrtpcpp/ZrtpStateClass.h>
 #include <libzrtpcpp/ZrtpUserCallback.h>
@@ -90,7 +90,7 @@
         staticTimeoutProvider = new TimeoutProvider<std::string, ZrtpQueue*>();
         staticTimeoutProvider->start();
     }
-    ZIDCache* zf = getZidCacheInstance();
+    ZIDFile* zf = ZIDFile::getInstance();
     if (!zf->isOpen()) {
         std::string fname;
         if (zidFilename == NULL) {
@@ -119,15 +119,12 @@
 void ZrtpQueue::startZrtp() {
     if (zrtpEngine != NULL) {
         zrtpEngine->startZrtpEngine();
-        zrtpUnprotect = 0;
         started = true;
     }
 }
 
 void ZrtpQueue::stopZrtp() {
     if (zrtpEngine != NULL) {
-        if (zrtpUnprotect < 50 && !zrtpEngine->isMultiStream())
-            zrtpEngine->setRs2Valid();
         delete zrtpEngine;
         zrtpEngine = NULL;
         started = false;
@@ -161,10 +158,6 @@
     // if ZRTP processing is enabled. Because valid RTP packets are
     // already handled we delete any packets here after processing.
     if (enableZrtp && zrtpEngine != NULL) {
-        // Fixed header length + smallest ZRTP packet (includes CRC)
-        if (rtn < (int32)(12 + sizeof(HelloAckPacket_t))) // data too small, dismiss
-            return 0;
-
         // Get CRC value into crc (see above how to compute the offset)
         uint16_t temp = rtn - CRC_SIZE;
         uint32_t crc = *(uint32_t*)(buffer + temp);
@@ -199,7 +192,7 @@
 
         // store peer's SSRC, used when creating the CryptoContext
         peerSSRC = packet->getSSRC();
-        zrtpEngine->processZrtpMessage(extHeader, peerSSRC, rtn);
+        zrtpEngine->processZrtpMessage(extHeader, peerSSRC);
     }
     delete packet;
     return 0;
@@ -686,9 +679,9 @@
     clientIdString = id;
 }
 
-std::string ZrtpQueue::getHelloHash(int32_t index)  {
+std::string ZrtpQueue::getHelloHash()  {
     if (zrtpEngine != NULL)
-        return zrtpEngine->getHelloHash(index);
+        return zrtpEngine->getHelloHash();
     else
         return std::string();
 }
@@ -818,21 +811,6 @@
     return 0;
 }
 
-int32_t ZrtpQueue::getNumberSupportedVersions() {
-    if (zrtpEngine != NULL)
-        return zrtpEngine->getNumberSupportedVersions();
-
-    return 0;
-}
-
-int32_t ZrtpQueue::getCurrentProtocolVersion() {
-    if (zrtpEngine != NULL)
-        return zrtpEngine->getCurrentProtocolVersion();
-
-    return 0;
-}
-
-
 IncomingZRTPPkt::IncomingZRTPPkt(const unsigned char* const block, size_t len) :
         IncomingRTPPkt(block,len) {
 }
diff --git a/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp b/jni/libzrtp/sources/src/ZrtpStateClass.cpp
similarity index 85%
rename from jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
rename to jni/libzrtp/sources/src/ZrtpStateClass.cpp
index 2c46a4f..f77f9f9 100644
--- a/jni/libzrtp/sources/zrtp/ZrtpStateClass.cpp
+++ b/jni/libzrtp/sources/src/ZrtpStateClass.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2008 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -46,9 +46,14 @@
 };
 
 
-ZrtpStateClass::ZrtpStateClass(ZRtp *p) : parent(p), commitPkt(NULL), multiStream(false), secSubstate(Normal), sentVersion(0) {
+ZrtpStateClass::ZrtpStateClass(ZRtp *p) {
+    parent = p;
+    secSubstate = Normal;
     engine = new ZrtpStates(states, numberOfStates, Initial);
 
+    commitPkt = NULL;
+    multiStream = false;
+
     // Set up timers according to ZRTP spec
     T1.start = 50;
     T1.maxResend = 20;
@@ -77,35 +82,21 @@
 
 void ZrtpStateClass::processEvent(Event_t *ev) {
 
+    event = ev;
     char *msg, first, middle, last;
     uint8_t *pkt;
 
     parent->synchEnter();
 
-    event = ev;
     if (event->type == ZrtpPacket) {
-        pkt = event->packet;
-        msg = (char *)pkt + 4;
-        first = tolower(*msg);
-        middle = tolower(*(msg+4));
+	pkt = event->packet;
+	msg = (char *)pkt + 4;
+	first = tolower(*msg);
+	middle = tolower(*(msg+4));
         last = tolower(*(msg+7));
 
-        // Sanity check of packet size for all states except WaitErrorAck.
-        if (!inState(WaitErrorAck)) {
-            uint16_t totalLength = *(uint16_t*)(pkt+2);
-            totalLength = zrtpNtohs(totalLength) * ZRTP_WORD_SIZE;
-            totalLength += 12 + sizeof(uint32_t);           // 12 bytes is fixed header, uint32_t is CRC
-
-            if (totalLength != ev->length) {
-                fprintf(stderr, "Total length does not match received length: %d - %ld\n", totalLength, (long int)(ev->length & 0xffff));
-                sendErrorPacket(MalformedPacket);
-                parent->synchLeave();
-                return;
-            }
-        }
-
         // Check if this is an Error packet.
-        if (first == 'e' && middle =='r' && last == ' ') {
+	if (first == 'e' && middle =='r' && last == ' ') {
             /*
              * Process a received Error packet.
              *
@@ -123,9 +114,7 @@
         else if (first == 'p' && middle == ' ' && last == ' ') {
             ZrtpPacketPing ppkt(pkt);
             ZrtpPacketPingAck* ppktAck = parent->preparePingAck(&ppkt);
-            if (ppktAck != NULL) {          // ACK only to valid PING packet, otherwise ignore it
-                parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
-            }
+            parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(ppktAck));
             parent->synchLeave();
             return;
         }
@@ -137,6 +126,7 @@
             parent->synchLeave();
             return;
         }
+
     }
     /*
      * Shut down protocol state engine: cancel outstanding timer, further
@@ -154,11 +144,10 @@
     DEBUGOUT((cout << "Checking for match in Initial.\n"));
 
     if (event->type == ZrtpInitial) {
-        ZrtpPacketHello* hello = parent->prepareHello();
-        sentVersion = hello->getVersionInt();
+	ZrtpPacketHello* hello = parent->prepareHello();
 
-        // remember packet for easy resend in case timer triggers
-        sentPacket = static_cast<ZrtpPacketBase *>(hello);
+	// remember packet for easy resend in case timer triggers
+	sentPacket = static_cast<ZrtpPacketBase *>(hello);
 
         if (!parent->sendPacketZRTP(sentPacket)) {
             sendFailed();                 // returns to state Initial
@@ -168,7 +157,7 @@
             timerFailed(SevereNoTimer);      // returns to state Initial
             return;
         }
-        nextState(Detect);
+	nextState(Detect);
     }
 }
 
@@ -236,8 +225,6 @@
          * - our peer acknowledged our Hello packet, we have not seen the peer's Hello yet
          * - cancel timer T1 to stop resending Hello
          * - switch to state AckDetected, wait for peer's Hello (F3)
-         * 
-         * When we receive an HelloAck this also means that out partner accepted our protocol version.
          */
         if (first == 'h' && last =='k') {
             cancelTimer();
@@ -247,8 +234,7 @@
         }
         /*
          * Hello:
-         * - send HelloAck packet to acknowledge the received Hello packet if versions match.
-         *   Otherweise negotiate ZRTP versions.
+         * - send HelloAck packet to acknowledge the received Hello packet 
          * - use received Hello packet to prepare own Commit packet. We need to
          *   do it at this point because we need the hash value computed from
          *   peer's Hello packet. Follwing states my use the prepared Commit.
@@ -257,58 +243,7 @@
          * - Don't clear sentPacket, points to Hello
          */
         if (first == 'h' && last ==' ') {
-            ZrtpPacketHello hpkt(pkt);
-
             cancelTimer();
-
-            /*
-             * Check and negotiate the ZRTP protocol version first.
-             *
-             * This selection mechanism relies on the fact that we sent the highest supported protocol version in
-             * the initial Hello packet with as stated in RFC6189, section 4.1.1
-             */
-            int32_t recvVersion = hpkt.getVersionInt();
-            if (recvVersion > sentVersion) {   // We don't support this version, stay in state with timer active
-                if (startTimer(&T1) <= 0) {
-                    timerFailed(SevereNoTimer);      // returns to state Initial
-                }
-                return;
-            }
-
-            /*
-             * The versions don't match. Start negotiating versions. This negotiation stays in the Detect state.
-             * Only if the received version matches our own sent version we start to send a HelloAck.
-             */
-            if (recvVersion != sentVersion) {
-                ZRtp::HelloPacketVersion* hpv = parent->helloPackets;
-
-                int32_t index;
-                for (index = 0; hpv->packet && hpv->packet != parent->currentHelloPacket; hpv++, index++)   // Find current sent Hello
-                    ;
-
-                for(; index >= 0 && hpv->version > recvVersion; hpv--, index--)   // find a supported version less-equal to received version
-                    ;
-
-                if (index < 0) {
-                    sendErrorPacket(UnsuppZRTPVersion);
-                    return;
-                }
-                parent->currentHelloPacket = hpv->packet;
-                sentVersion = parent->currentHelloPacket->getVersionInt();
-
-                // remember packet for easy resend in case timer triggers
-                sentPacket = static_cast<ZrtpPacketBase *>(parent->currentHelloPacket);
-
-                if (!parent->sendPacketZRTP(sentPacket)) {
-                    sendFailed();                 // returns to state Initial
-                    return;
-                }
-                if (startTimer(&T1) <= 0) {
-                    timerFailed(SevereNoTimer);      // returns to state Initial
-                    return;
-                }
-                return;
-            }
             ZrtpPacketHelloAck* helloAck = parent->prepareHelloAck();
 
             if (!parent->sendPacketZRTP(static_cast<ZrtpPacketBase *>(helloAck))) {
@@ -317,6 +252,7 @@
             }
             // Use peer's Hello packet to create my commit packet, store it 
             // for possible later usage in state AckSent
+            ZrtpPacketHello hpkt(pkt);
             commitPkt = parent->prepareCommit(&hpkt, &errorCode);
 
             nextState(AckSent);
@@ -343,7 +279,7 @@
             nextState(Detect);
         }
     }
-    // If application calls zrtpStart() to restart discovery
+    // If application call zrtpStart() to restart discovery
     else if (event->type == ZrtpInitial) {
         cancelTimer();
         if (!parent->sendPacketZRTP(sentPacket)) {
@@ -368,7 +304,7 @@
  *
  * The protocol engine got a Hello packet from peer and answered with a
  * HelloAck response.  According to the protocol we must also send a 
- * Hello after HelloAck (refer to figure 1 in ZRTP RFC 6189, message
+ * Hello after HelloAck (refer to figure 1 in ZRTP RFC xxxx, message 
  * HelloACK (F2) must be followed by Hello (F3)). We use the timeout in 
  * this state to send the required Hello (F3).
  *
@@ -411,36 +347,36 @@
      */
     if (event->type == ZrtpPacket) {
         pkt = event->packet;
-        msg = (char *)pkt + 4;
+	msg = (char *)pkt + 4;
 
-        first = tolower(*msg);
-        last = tolower(*(msg+7));
+	first = tolower(*msg);
+	last = tolower(*(msg+7));
 
-        /*
+	/*
          * HelloAck:
          * The peer answers with HelloAck to own HelloAck/Hello. Send Commit
          * and try Initiator mode. The requirement defined in chapter 4.1 to
          * have a complete Hello/HelloAck is fulfilled.
-         * - stop Hello timer T1
-         * - send own Commit message
-         * - switch state to CommitSent, start Commit timer, assume Initiator
-         */
-        if (first == 'h' && last =='k') {
-            cancelTimer();
+	 * - stop Hello timer T1
+	 * - send own Commit message
+	 * - switch state to CommitSent, start Commit timer, assume Initiator
+	 */
+	if (first == 'h' && last =='k') {
+	    cancelTimer();
 
             // remember packet for easy resend in case timer triggers
             // Timer trigger received in new state CommitSend
             sentPacket = static_cast<ZrtpPacketBase *>(commitPkt);
             commitPkt = NULL;                    // now stored in sentPacket
-            nextState(CommitSent);
+	    nextState(CommitSent);
             if (!parent->sendPacketZRTP(sentPacket)) {
                 sendFailed();             // returns to state Initial
                 return;
             }
             if (startTimer(&T2) <= 0) {
                 timerFailed(SevereNoTimer);  // returns to state Initial
-            }
-            return;
+	    }
+	    return;
         }
         /*
          * Hello:
@@ -472,7 +408,7 @@
          * - switch to state WaitDHPart2 and wait for peer's DHPart2
          * - don't start timer, we are responder
          */
-        if (first == 'c' && last == ' ') {
+        if (first == 'c') {
             cancelTimer();
             ZrtpPacketCommit cpkt(pkt);
 
@@ -510,7 +446,7 @@
     }
     /*
      * Timer:
-     * - resend Hello packet, stay in state, restart timer until repeat
+     * - resend Hello packet, stay in state, restart timer until repeat 
      *   counter triggers
      * - if repeat counter triggers switch to state Detect, con't clear
      *   sentPacket, Detect requires it to point to own Hello message
@@ -540,7 +476,7 @@
  * AckDetected state.
  *
  * The protocol engine received a HelloAck in state Detect, thus the peer 
- * acknowledged our the Hello. According to ZRT RFC 6189 our peer must send
+ * acknowledged our the Hello. According to ZRT RFC xxxx our peer must send
  * its Hello until our protocol engine sees it (refer also to comment for
  * state AckSent). This protocol sequence gurantees that both peers got at
  * least one Hello. 
@@ -575,7 +511,7 @@
         /*
          * Implementation for choice 1)
          * Hello:
-         * - Acknowledge peer's Hello, sending HelloACK (F4)
+         * - Acknowledge peers Hello, sending HelloACK (F4)
          * - switch to state WaitCommit, wait for peer's Commit
          * - we are going to be in the Responder role
          */
@@ -606,13 +542,13 @@
         /*
          * Implementation for choice 2)
          * Hello:
-         * - Acknowledge peer's Hello by sending Commit (F5)
+         * - Acknowledge peers Hello by sending Commit (F5)
          *   instead of HelloAck (F4)
          * - switch to state CommitSent
          * - Initiator role, thus start timer T2 to monitor timeout for Commit
          */
 
-        if (first == 'h' && last == ' ') {
+        if (first == 'h') {
             // Parse peer's packet data into a Hello packet
             ZrtpPacketHello hpkt(pkt);
             ZrtpPacketCommit* commit = parent->prepareCommit(&hpkt, &errorCode);
@@ -662,7 +598,7 @@
 
     DEBUGOUT((cout << "Checking for match in WaitCommit.\n"));
 
-    char *msg, first, last;
+    char *msg, first;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -671,13 +607,12 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        last = tolower(*(msg+7));
         /*
          * Hello:
          * - resend HelloAck
          * - stay in WaitCommit
          */
-        if (first == 'h' && last == ' ') {
+        if (first == 'h') {
             if (!parent->sendPacketZRTP(sentPacket)) {
                 sendFailed();       // returns to state Initial
             }
@@ -690,7 +625,7 @@
          * - switch state to WaitDHPart2 or WaitConfirm2 if multi stream mode
          * - don't start timer, we are responder
          */
-        if (first == 'c' && last == ' ') {
+        if (first == 'c') {
             ZrtpPacketCommit cpkt(pkt);
 
             if (!multiStream) {
@@ -758,7 +693,7 @@
 
     DEBUGOUT((cout << "Checking for match in CommitSend.\n"));
 
-    char *msg, first, middle, last, secondLast;
+    char *msg, first, last;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -767,9 +702,7 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        middle = tolower(*(msg+4));
         last = tolower(*(msg+7));
-        secondLast = tolower(*(msg+6));
 
         /*
          * HelloAck or Hello:
@@ -777,7 +710,7 @@
          *   ignore it
          * - no switch in state, leave timer as it is
          */
-        if (first == 'h' && middle == 'o' && (last =='k' || last == ' ')) {
+        if (first == 'h' && (last =='k' || last == ' ')) {
             return;
         }
 
@@ -802,11 +735,6 @@
             }
             cancelTimer();         // this cancels the Commit timer T2
 
-            if (!zpCo.isLengthOk(multiStream ? ZrtpPacketCommit::MultiStream : ZrtpPacketCommit::DhExchange)) {
-                sendErrorPacket(CriticalSWError);
-                return;
-            }
-
             // if our hvi is less than peer's hvi: switch to Responder mode and
             // send DHPart1 or Confirm1 packet. Peer (as Initiator) will retrigger if
             // necessary
@@ -859,7 +787,7 @@
          * - switch to WaitConfirm1
          * - start timer to resend DHPart2 if necessary, we are Initiator
          */
-        if (first == 'd' && secondLast == '1') {
+        if (first == 'd') {
             cancelTimer();
             sentPacket = NULL;
             ZrtpPacketDHPart dpkt(pkt);
@@ -891,11 +819,6 @@
             return;
         }
 
-        /*
-         * Confirm1 and multi-stream mode
-         * - switch off resending commit
-         * - prepare Confirm2
-         */
         if (multiStream && (first == 'c' && last == '1')) {
             cancelTimer();
             ZrtpPacketConfirm cpkt(pkt);
@@ -966,7 +889,7 @@
 
     DEBUGOUT((cout << "Checking for match in DHPart2.\n"));
 
-    char *msg, first, secondLast, last;
+    char *msg, first;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -975,14 +898,12 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        last = tolower(*(msg+7));
-        secondLast = tolower(*(msg+6));
         /*
          * Commit:
          * - resend DHPart1
          * - stay in state
          */
-        if (first == 'c' && last == ' ') {
+        if (first == 'c') {
             if (!parent->sendPacketZRTP(sentPacket)) {
                 return sendFailed();       // returns to state Initial
             }
@@ -994,7 +915,7 @@
          * - switch to WaitConfirm2
          * - No timer, we are responder
          */
-        if (first == 'd' && secondLast == '2') {
+        if (first == 'd') {
             ZrtpPacketDHPart dpkt(pkt);
             ZrtpPacketConfirm* confirm = parent->prepareConfirm1(&dpkt, &errorCode);
 
@@ -1073,14 +994,6 @@
                 sendErrorPacket(errorCode);
                 return;
             }
-            // according to chap 5.8: after sending Confirm2 the Initiator must
-            // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck
-            // state.
-            if (!parent->srtpSecretsReady(ForReceiver)) {
-                parent->sendInfo(Severe, CriticalSWError);
-                sendErrorPacket(CriticalSWError);
-                return;
-            }
             nextState(WaitConfAck);
             sentPacket = static_cast<ZrtpPacketBase *>(confirm);
 
@@ -1089,7 +1002,15 @@
                 return;
             }
             if (startTimer(&T2) <= 0) {
-                timerFailed(SevereNoTimer);  // returns to state Initial
+                timerFailed(SevereNoTimer);  // returns to state Initial TODO check for return following this line
+            }
+            // according to chap 5.8: after sending Confirm2 the Initiator must
+            // be ready to receive SRTP data. SRTP sender will be enabled in WaitConfAck
+            // state.
+            if (!parent->srtpSecretsReady(ForReceiver)) {
+                parent->sendInfo(Severe, CriticalSWError);
+                sendErrorPacket(CriticalSWError);
+                return;
             }
         }
     }
@@ -1135,7 +1056,7 @@
 
     DEBUGOUT((cout << "Checking for match in WaitConfirm2.\n"));
 
-    char *msg, first, secondLast, last;
+    char *msg, first, last;
     uint8_t *pkt;
     uint32_t errorCode = 0;
 
@@ -1144,7 +1065,6 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        secondLast = tolower(*(msg+6));
         last = tolower(*(msg+7));
 
         /*
@@ -1152,7 +1072,7 @@
          * - resend Confirm1 packet
          * - stay in state
          */
-        if ((first == 'd' && secondLast == '2') || (multiStream && (first == 'c' && last == ' '))) {
+        if (first == 'd' || (multiStream && (first == 'c' && last == ' '))) {
             if (!parent->sendPacketZRTP(sentPacket)) {
                 sendFailed();             // returns to state Initial
             }
@@ -1179,7 +1099,8 @@
                 sendFailed();             // returns to state Initial
                 return;
             }
-            if (!parent->srtpSecretsReady(ForReceiver) || !parent->srtpSecretsReady(ForSender))  {
+            if (!parent->srtpSecretsReady(ForSender) ||
+                !parent->srtpSecretsReady(ForReceiver)) {
                 parent->sendInfo(Severe, CriticalSWError);
                 sendErrorPacket(CriticalSWError);
                 return;
@@ -1218,7 +1139,7 @@
 
     DEBUGOUT((cout << "Checking for match in WaitConfAck.\n"));
 
-    char *msg, first, last;
+    char *msg, first;
     uint8_t *pkt;
 
     if (event->type == ZrtpPacket) {
@@ -1226,13 +1147,12 @@
         msg = (char *)pkt + 4;
 
         first = tolower(*msg);
-        last = tolower(*(msg+7));
          /*
          * ConfAck:
          * - Switch off resending Confirm2
          * - switch to SecureState
          */
-        if (first == 'c' && last == 'k') {
+        if (first == 'c') {
             cancelTimer();
             sentPacket = NULL;
             // Receiver was already enabled after sending Confirm2 packet
@@ -1276,45 +1196,44 @@
 void ZrtpStateClass::evWaitClearAck(void) {
     DEBUGOUT((cout << "Checking for match in ClearAck.\n"));
 
-//     char *msg, first, last, middle;
-//     uint8_t *pkt;
-// 
-//     if (event->type == ZrtpPacket) {
-// 	pkt = event->packet;
-// 	msg = (char *)pkt + 4;
-// 
-// 	first = tolower(*msg);
-//     middle = tolower(*(msg+4));
-// 	last = tolower(*(msg+7));
-// 
-// 	/*
-// 	 * ClearAck:
-// 	 * - stop resending GoClear,
-// 	 * - switch to state AckDetected, wait for peer's Hello
-// 	 */
-// 	if (first == 'c' && middle == 'r' && last =='k') {
-// 	    cancelTimer();
-// 	    sentPacket = NULL;
-// 	    nextState(Initial);
-// 	}
-//     }
-//     // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC
-//     else if (event->type == Timer) {
-//         if (!parent->sendPacketZRTP(sentPacket)) {
-//             sendFailed();                 // returns to state Initial
-//             return;
-//         }
-//         if (nextTimer(&T2) <= 0) {
-//             timerFailed(SevereTooMuchRetries);     // returns to state Initial
-//         }
-//     }
-//     else {  // unknown Event type for this state (covers Error and ZrtpClose)
-//         if (event->type != ZrtpClose) {
-//             parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
-//         }
-// 	sentPacket = NULL;
-// 	nextState(Initial);
-//     }
+    char *msg, first, last;
+    uint8_t *pkt;
+
+    if (event->type == ZrtpPacket) {
+	pkt = event->packet;
+	msg = (char *)pkt + 4;
+
+	first = tolower(*msg);
+	last = tolower(*(msg+7));
+
+	/*
+	 * ClearAck:
+	 * - stop resending GoClear,
+	 * - switch to state AckDetected, wait for peer's Hello
+	 */
+	if (first == 'c' && last =='k') {
+	    cancelTimer();
+	    sentPacket = NULL;
+	    nextState(Initial);
+	}
+    }
+    // Timer event triggered - this is Timer T2 to resend GoClear w/o HMAC
+    else if (event->type == Timer) {
+        if (!parent->sendPacketZRTP(sentPacket)) {
+            sendFailed();                 // returns to state Initial
+            return;
+        }
+        if (nextTimer(&T2) <= 0) {
+            timerFailed(SevereTooMuchRetries);     // returns to state Initial
+        }
+    }
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
+        if (event->type != ZrtpClose) {
+            parent->zrtpNegotiationFailed(Severe, SevereProtocolError);
+        }
+	sentPacket = NULL;
+	nextState(Initial);
+    }
 }
 
 
@@ -1418,7 +1337,7 @@
         }
         /*
          * GoClear received, handle it. TODO fix go clear handling
-         *
+         */
         if (first == 'g' && last == 'r') {
             ZrtpPacketGoClear gpkt(pkt);
             ZrtpPacketClearAck* clearAck = parent->prepareClearAck(&gpkt);
@@ -1428,18 +1347,8 @@
             }
         // TODO Timeout to resend clear ack until user user confirmation
         }
-        */
     }
-    else if (event->type == Timer) {
-        // Ignore stray timeout in this state
-        ;
-    }
-    // unknown Event type for this state (covers Error and ZrtpClose)
-    else  {
-        // If in secure state ingnore error events to avoid Error packet injection
-        // attack - found by Dmitry Monakhov (dmonakhov@openvz.org)
-        if (event->type == ErrorPkt)
-            return;
+    else {  // unknown Event type for this state (covers Error and ZrtpClose)
         sentPacket = NULL;
         parent->srtpSecretsOff(ForSender);
         parent->srtpSecretsOff(ForReceiver);
diff --git a/jni/libzrtp/sources/src/ZrtpTextData.cpp b/jni/libzrtp/sources/src/ZrtpTextData.cpp
new file mode 100644
index 0000000..5861099
--- /dev/null
+++ b/jni/libzrtp/sources/src/ZrtpTextData.cpp
@@ -0,0 +1,97 @@
+/*
+  Copyright (C) 2006-2008 Werner Dittmann
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  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.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+ * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+#include <stdint.h>
+#include <libzrtpcpp/ZrtpConfigure.h>
+//                             1
+//                    1234567890123456
+char clientId[] =    "GNU ZRTP 2.1.0  "; // 16 chars max.
+char zrtpVersion[] = "1.10";             // must be 4 chars
+/**
+ *
+ */
+char HelloMsg[]    = "Hello   ";
+char HelloAckMsg[] = "HelloACK";
+char CommitMsg[]   = "Commit  ";
+char DHPart1Msg[]  = "DHPart1 ";
+char DHPart2Msg[]  = "DHPart2 ";
+char Confirm1Msg[] = "Confirm1";
+char Confirm2Msg[] = "Confirm2";
+char Conf2AckMsg[] = "Conf2ACK";
+char ErrorMsg[]    = "Error   ";
+char ErrorAckMsg[] = "ErrorACK";
+char GoClearMsg[]  = "GoClear ";
+char ClearAckMsg[] = "ClearACK";
+char PingMsg[]     = "Ping    ";
+char PingAckMsg[]  = "PingACK ";
+char SasRelayMsg[] = "SASrelay";
+char RelayAckMsg[] = "RelayACK";
+
+char responder[]      = "Responder";
+char initiator[]      = "Initiator";
+char iniMasterKey[]   = "Initiator SRTP master key";
+char iniMasterSalt[]  = "Initiator SRTP master salt";
+char respMasterKey[]  = "Responder SRTP master key";
+char respMasterSalt[] = "Responder SRTP master salt";
+
+char iniHmacKey[]  = "Initiator HMAC key";
+char respHmacKey[] = "Responder HMAC key";
+char retainedSec[] = "retained secret";
+
+char iniZrtpKey[]  = "Initiator ZRTP key";
+char respZrtpKey[] = "Responder ZRTP key";
+
+char sasString[] = "SAS";
+
+char KDFString[] = "ZRTP-HMAC-KDF";
+
+char zrtpSessionKey[] = "ZRTP Session Key";
+
+char zrtpMsk[] = "ZRTP MSK";
+char zrtpTrustedMitm[] = "Trusted MiTM key";
+
+char s256[] = "S256";
+char s384[] = "S384";
+const char* mandatoryHash = s256;
+
+char aes3[] = "AES3";
+char aes2[] = "AES2";
+char aes1[] = "AES1";
+char two3[] = "2FS3";
+char two2[] = "2FS2";
+char two1[] = "2FS1";
+const char* mandatoryCipher = aes1;
+
+char dh2k[] = "DH2k";
+char ec25[] = "EC25";
+char dh3k[] = "DH3k";
+char ec38[] = "EC38";
+char mult[] = "Mult";
+const char* mandatoryPubKey = dh3k;
+
+char b32[] = "B32 ";
+const char* mandatorySasType = b32;
+
+char hs32[] = "HS32";
+char hs80[] = "HS80";
+char sk32[] = "SK32";
+char sk64[] = "SK64";
+const char* mandatoryAuthLen_1 = hs32;
+const char* mandatoryAuthLen_2 = hs80;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/Base32.h b/jni/libzrtp/sources/src/libzrtpcpp/Base32.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/Base32.h
rename to jni/libzrtp/sources/src/libzrtpcpp/Base32.h
diff --git a/jni/libzrtp/sources/src/libzrtpcpp/CMakeLists.txt b/jni/libzrtp/sources/src/libzrtpcpp/CMakeLists.txt
new file mode 100755
index 0000000..099a233
--- /dev/null
+++ b/jni/libzrtp/sources/src/libzrtpcpp/CMakeLists.txt
@@ -0,0 +1,9 @@
+
+if(enable_ccrtp)
+  set(ccrtp_inst ZrtpQueue.h zrtpccrtp.h ZrtpUserCallback.h TimeoutProvider.h)
+endif()
+
+install(FILES 
+    ZrtpCodes.h ZrtpConfigure.h ZrtpCallback.h ZrtpCWrapper.h 
+    ${ccrtp_inst} DESTINATION include/libzrtpcpp)
+
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h b/jni/libzrtp/sources/src/libzrtpcpp/TimeoutProvider.h
similarity index 71%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h
rename to jni/libzrtp/sources/src/libzrtpcpp/TimeoutProvider.h
index 7aa3405..9f0edf7 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/CcrtpTimeoutProvider.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/TimeoutProvider.h
@@ -55,14 +55,14 @@
 public:
 
     TPRequest( TOSubscriber tsi, int timeoutMs, const TOCommand &command):
-        subscriber(tsi)
+    subscriber(tsi)
     {
         struct timeval tv;
         gettimeofday(&tv, NULL );
 
         when_ms = ((uint64)tv.tv_sec) * (uint64)1000 + ((uint64)tv.tv_usec) / (uint64)1000;
-        when_ms += timeoutMs;
-        this->command = command;
+    when_ms += timeoutMs;
+    this->command = command;
     }
 
     /**
@@ -70,18 +70,18 @@
      */
     bool happensBefore(uint64 t)
     {
-        if (when_ms < t) {
-            return true;
-        }
-        if (when_ms > t) {
-            return false;
-        }
-        return false; // if equal it does not "happens_before"
+    if (when_ms < t) {
+        return true;
+    }
+    if (when_ms > t) {
+        return false;
+    }
+    return false; // if equal it does not "happens_before"
 
     }
 
     bool happensBefore(const TPRequest *req){
-        return happensBefore(req->when_ms);
+    return happensBefore(req->when_ms);
     }
 
     /**
@@ -95,22 +95,22 @@
 
         uint64 now = ((uint64)tv.tv_sec) * (uint64)1000 + ((uint64)tv.tv_usec) / (uint64)1000;
 
-        if (happensBefore(now)) {
-            return 0;
-        }
-        else {
-            return (int)(when_ms - now);
-        }
+    if (happensBefore(now)) {
+        return 0;
+    }
+    else {
+        return (int)(when_ms - now);
+    }
     }
 
     TOCommand getCommand()
     {
-        return command;
+    return command;
     }
 
     TOSubscriber getSubscriber()
     {
-        return subscriber;
+    return subscriber;
     }
 
     /**
@@ -121,9 +121,9 @@
      */
     bool operator==(const TPRequest<TOCommand, TOSubscriber> &req)
     {
-        if (req.subscriber == subscriber &&
-            req.command == command &&
-            req.when_ms == when_ms) {
+    if (req.subscriber == subscriber &&
+               req.command == command &&
+               req.when_ms == when_ms) {
             return true;
         }
         return false;
@@ -132,10 +132,10 @@
 private:
     TOSubscriber subscriber;
     uint64 when_ms;     // Time since Epoch in ms when the timeout
-    // will happen
+                // will happen
 
     TOCommand command;      // Command that will be delivered to the
-    // receiver (subscriber) of the timeout.
+                // receiver (subscriber) of the timeout.
 };
 
 /**
@@ -145,7 +145,7 @@
  * @author Werner Dittmann
  */
 template<class TOCommand, class TOSubscriber>
-class TimeoutProvider : public ost::Thread, ost::Event {
+        class TimeoutProvider : public ost::Thread, ost::Event {
 
 public:
 
@@ -158,15 +158,15 @@
      * Destructor also terminates the Timeout thread.
      */
     ~TimeoutProvider() {
-        terminate();
+    terminate();
     }
 
     /**
      * Terminates the Timeout provider thread.
      */
     void stopThread(){
-        stop = true;
-        signal();       // signal event to waiting thread
+    stop = true;
+    signal();       // signal event to waiting thread
     }
 
     /**
@@ -183,28 +183,28 @@
     void requestTimeout(int32_t time_ms, TOSubscriber subscriber, const TOCommand &command)
     {
         TPRequest<TOCommand, TOSubscriber>* request =
-            new TPRequest<TOCommand, TOSubscriber>(subscriber, time_ms, command);
+                new TPRequest<TOCommand, TOSubscriber>(subscriber, time_ms, command);
 
         synchLock.enter();
 
-        if (requests.size()==0) {
-            requests.push_front(request);
-            signal();
-            synchLock.leave();
-            return;
-        }
+    if (requests.size()==0) {
+        requests.push_front(request);
+        signal();
+        synchLock.leave();
+        return;
+    }
         if (request->happensBefore(requests.front())) {
-            requests.push_front(request);
-            signal();
+        requests.push_front(request);
+        signal();
             synchLock.leave();
-            return;
-        }
+        return;
+    }
         if (requests.back()->happensBefore(request)){
-            requests.push_back(request);
-            signal();
+        requests.push_back(request);
+        signal();
             synchLock.leave();
-            return;
-        }
+        return;
+    }
 
         typename std::list<TPRequest<TOCommand, TOSubscriber>* >::iterator i;
         for(i = requests.begin(); i != requests.end(); i++ ) {
@@ -213,8 +213,8 @@
                 break;
             }
         }
-        signal();
-        synchLock.leave();
+    signal();
+    synchLock.leave();
     }
 
     /**
@@ -234,48 +234,48 @@
             }
             i++;
         }
-        synchLock.leave();
+    synchLock.leave();
     }
 
 protected:
 
     void run()
     {
-        do {
-            synchLock.enter();
-            int32_t time = 3600000;
-            int32_t size = 0;
-            if ((size = requests.size()) > 0) {
+    do {
+        synchLock.enter();
+        int32_t time = 3600000;
+        int32_t size = 0;
+        if ((size = requests.size()) > 0) {
                 time = requests.front()->getMsToTimeout();
             }
-            if (time == 0 && size > 0) {
-                if (stop){  // This must be checked so that we will
-                    // stop even if we have timeouts to deliver.
+        if (time == 0 && size > 0) {
+        if (stop){  // This must be checked so that we will
+                // stop even if we have timeouts to deliver.
                     synchLock.leave();
-                    return;
-                }
+            return;
+        }
                 TPRequest<TOCommand, TOSubscriber>* req = requests.front();
-                TOSubscriber subs = req->getSubscriber();
-                TOCommand command = req->getCommand();
+        TOSubscriber subs = req->getSubscriber();
+        TOCommand command = req->getCommand();
 
                 requests.pop_front();
 
-                synchLock.leave(); // call the command with free Mutex
-                subs->handleTimeout(command);
-                continue;
-            }
-            synchLock.leave();
-            if (stop) {     // If we were told to stop while delivering
-                // a timeout we will exit here
-                return;
-            }
-            reset();        // ready to receive triggers again
+        synchLock.leave(); // call the command with free Mutex
+        subs->handleTimeout(command);
+        continue;
+        }
+        synchLock.leave();
+        if (stop) {     // If we were told to stop while delivering
+                                // a timeout we will exit here
+        return;
+        }
+        reset();        // ready to receive triggers again
             wait(time);
-            if (stop) {     // If we are told to exit while waiting we
-                // will exit
-                return;
-            }
-        } while(true);
+        if (stop) {     // If we are told to exit while waiting we
+                                // will exit
+        return;
+        }
+    } while(true);
     }
 
 private:
@@ -287,9 +287,17 @@
     ost::Mutex synchLock;   // Protects the internal data structures
 
     bool stop;      // Flag to tell the worker thread
-    // to terminate. Set to true and
-    // wake the worker thread to
-    // terminate it.
+                        // to terminate. Set to true and
+                        // wake the worker thread to
+                        // terminate it.
 };
 
 #endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/src/libzrtpcpp/ZIDFile.h b/jni/libzrtp/sources/src/libzrtpcpp/ZIDFile.h
new file mode 100644
index 0000000..0637c27
--- /dev/null
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZIDFile.h
@@ -0,0 +1,157 @@
+/*
+  Copyright (C) 2006-2010 Werner Dittmann
+
+  This program is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  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.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+#include <libzrtpcpp/ZIDRecord.h>
+
+#ifndef _ZIDFILE_H_
+#define _ZIDFILE_H_
+/**
+ * @file ZIDFile.h
+ * @brief ZID file management
+ *
+ * A ZID file stores (caches) some data that helps ZRTP to achives its
+ * key continuity feature. See @c ZIDRecord for further info which data
+ * the ZID file contains.
+ *
+ * @ingroup GNU_ZRTP
+ * @{
+ */
+
+/**
+ * This class implements a ZID (ZRTP Identifiers) file.
+ *
+ * The ZID file holds information about peers.
+ *
+ * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
+ */
+
+class __EXPORT ZIDFile {
+
+private:
+
+    FILE* zidFile;
+    unsigned char associatedZid[IDENTIFIER_LEN];
+    /**
+     * The private ZID file constructor.
+     *
+     */
+    ZIDFile(): zidFile(NULL) {};
+    ~ZIDFile();
+    void createZIDFile(char* name);
+    void checkDoMigration(char* name);
+
+public:
+
+    /**
+     * Get the an instance of ZIDFile.
+     *
+     * This method just creates an instance an store a pointer to it
+     * in a static variable. The ZIDFile is a singleton, thus only
+     * <em>one</em> ZID file can be open at one time.
+     *
+     * @return
+     *    A pointer to the global ZIDFile singleton instance.
+     */
+    static ZIDFile* getInstance();
+    /**
+     * Open the named ZID file and return a ZID file class.
+     *
+     * This static function either opens an existing ZID file or
+     * creates a new ZID file with the given name. The ZIDFile is a
+     * singleton, thus only <em>one</em> ZID file can be open at one
+     * time.
+     *
+     * To open another ZID file you must close the active ZID file
+     * first.
+     *
+     * @param name
+     *    The name of the ZID file to open or create
+     * @return
+     *    1 if file could be opened/created, 0 if the ZID instance
+     *    already has an open file, -1 if open/creation of file failed.
+     */
+    int open(char *name);
+
+    /**
+     * Check if ZIDFile has an active (open) file.
+     *
+     * @return
+     *    True if ZIDFile has an active file, false otherwise
+     */
+    bool isOpen() { return (zidFile != NULL); };
+
+     /**
+     * Close the ZID file.
+     * Closes the ZID file, and prepares to open a new ZID file.
+     */
+    void close();
+
+    /**
+     * Get a ZID record from the active ZID file.
+     *
+     * The method get the identifier data from the ZID record parameter,
+     * locates the record in the ZID file and fills in the RS1, RS2, and
+     * other data.
+     *
+     * If no matching record exists in the ZID file the method creates
+     * it and fills it with default values.
+     *
+     * @param zidRecord
+     *    The ZID record that contains the identifier data. The method
+     *    fills in data .
+     * @return
+     *    Currently always 1 to indicate sucess
+     */
+    unsigned int getRecord(ZIDRecord* zidRecord);
+
+    /**
+     * Save a ZID record into the active ZID file.
+     *
+     * This method saves the content of a ZID record into the ZID file. Before
+     * you can save the ZID record you must have performed a getRecord()
+     * first.
+     *
+     * @param zidRecord
+     *    The ZID record to save.
+     * @return
+     *    1 on success
+     */
+    unsigned int saveRecord(ZIDRecord *zidRecord);
+
+    /**
+     * Get the ZID associated with this ZID file.
+     *
+     * @return
+     *    Pointer to the ZID
+     */
+    const unsigned char* getZid() { return associatedZid; };
+};
+
+/**
+ * @}
+ */
+#endif
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h b/jni/libzrtp/sources/src/libzrtpcpp/ZIDRecord.h
similarity index 81%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZIDRecord.h
index 74cc8a0..dc4691f 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordFile.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZIDRecord.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -15,13 +15,13 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _ZIDRECORDFILE_H_
-#define _ZIDRECORDFILE_H_
+#ifndef _ZIDRECORD_H_
+#define _ZIDRECORD_H_
 
 
 /**
- * @file ZIDRecordFile.h
- * @brief ZID cache record management
+ * @file ZIDRecord.h
+ * @brief ZID record management
  *
  * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP
  * to achives its key continuity feature. Please refer to the ZRTP
@@ -33,8 +33,9 @@
 
 #include <string.h>
 #include <stdint.h>
-#include <libzrtpcpp/ZIDRecord.h>
 
+#define IDENTIFIER_LEN  12
+#define RS_LENGTH       32
 #define TIME_LENGTH      8      // 64 bit, can hold time on 64 bit systems
 
 /**
@@ -67,6 +68,21 @@
     unsigned char mitmKey[RS_LENGTH];         ///< MiTM key if available
 } zidrecord2_t;
 
+
+#ifndef __EXPORT
+  #if defined _WIN32 || defined __CYGWIN__
+    #define __EXPORT    __declspec(dllimport)
+    #define __LOCAL
+  #endif
+  #if __GNUC__ >= 4
+    #define __EXPORT    __attribute__ ((visibility("default")))
+    #define __LOCAL     __attribute__ ((visibility("hidden")))
+  #else
+    #define __EXPORT
+    #define __LOCAL
+  #endif
+#endif
+
 static const int Valid            = 0x1;
 static const int SASVerified      = 0x2;
 static const int RS1Valid         = 0x4;
@@ -86,13 +102,20 @@
  *
  * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
  */
-class __EXPORT ZIDRecordFile: public ZIDRecord {
-    friend class ZIDCacheFile;
+class __EXPORT ZIDRecord {
+    friend class ZIDFile;
 
 private:
     zidrecord2_t record;
     unsigned long position;
 
+    /*
+     * The default constructor is private
+     */
+    ZIDRecord() {
+    record.version = 2;
+    }
+
     /**
      * Functions for I/O availabe for ZID file handling
      *
@@ -108,21 +131,25 @@
     void setValid()   { record.flags |= Valid; }
 
 public:
-    /*
-     * @brief The default constructor,
-     */
-    ZIDRecordFile() {
-        memset(&record, 0, sizeof(zidrecord2_t));
-        record.version = 2;
-    }
-
     /**
-     * Set the @c ZID in the record.
+     * Create a ZID Record with given ZID data
      *
-     * Set the ZID in this record before calling read or save.
+     * The method creates a new ZID record and initializes its ZID
+     * data field. All other fields are set to null.
+     *
+     * An application can use this pre-initialized record to look
+     * up the associated record in the ZID file. If the record is
+     * available, the ZID record fields are filled with the stored
+     * data.
+     *
+     * @param idData
+     *     Pointer to the fixed length ZID data
+     * @see ZIDFile::getRecord
      */
-    void setZid(const unsigned char *zid) {
-        memcpy(record.identifier, zid, IDENTIFIER_LEN);
+    ZIDRecord(const unsigned char *idData) {
+    memset(&record, 0, sizeof(zidrecord2_t));
+    memcpy(record.identifier, idData, IDENTIFIER_LEN);
+    record.version = 2;
     }
 
     /**
@@ -211,7 +238,7 @@
      * @return
      *    Returns true is RS1 is not expired (valid), false otherwise.
      */
-    bool isRs1NotExpired();
+    const bool isRs1NotExpired();
 
     /**
      * Returns pointer to RS1 data.
@@ -226,7 +253,7 @@
      * @return
      *    Returns true is RS2 is not expired (valid), false otherwise.
      */
-    bool isRs2NotExpired();
+    const bool isRs2NotExpired();
 
     /**
      * Returns pointer to RS1 data.
@@ -269,5 +296,13 @@
     const unsigned char* getMiTMData() {return record.mitmKey; }
 };
 
-#endif // ZIDRECORDSMALL
+#endif // ZIDRECORD
 
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h b/jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
similarity index 82%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
index a20b599..4e03f28 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZRtp.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZRtp.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -41,7 +41,7 @@
 #include <libzrtpcpp/ZrtpPacketSASrelay.h>
 #include <libzrtpcpp/ZrtpPacketRelayAck.h>
 #include <libzrtpcpp/ZrtpCallback.h>
-#include <libzrtpcpp/ZIDCache.h>
+#include <libzrtpcpp/ZIDRecord.h>
 
 #ifndef SHA256_DIGEST_LENGTH
 #define SHA256_DIGEST_LENGTH 32
@@ -51,15 +51,6 @@
 #define MAX_DIGEST_LENGTH       64
 #define IMPL_MAX_DIGEST_LENGTH  64
 
-// max. number of parallel supported ZRTP protocol versions.
-#define MAX_ZRTP_VERSIONS       2
-
-// currently only 1.10 supported
-#define SUPPORTED_ZRTP_VERSIONS       1
-
-// Integer representation of highest supported ZRTP protocol version
-#define HIGHEST_ZRTP_VERION    12
-
 class __EXPORT ZrtpStateClass;
 class ZrtpDH;
 
@@ -99,33 +90,6 @@
 
     public:
 
-    typedef enum _secrets {
-        Rs1 = 1,
-        Rs2 = 2,
-        Pbx = 4,
-        Aux = 8
-    } secrets;
-
-    typedef struct _zrtpInfo {
-        int32_t secretsCached;
-        int32_t secretsMatched;
-        int32_t secretsMatchedDH;
-        const char *hash;
-        const char *cipher;
-        const char *pubKey;
-        const char *sasType;
-        const char *authLength;
-    } zrtpInfo;
-
-    /**
-     * Faster access to Hello packets with different versions.
-     */
-    typedef struct _HelloPacketVersion {
-        int32_t version;
-        ZrtpPacketHello* packet;
-        uint8_t helloHash[IMPL_MAX_DIGEST_LENGTH];
-    } HelloPacketVersion;
-
     /**
      * Constructor intializes all relevant data but does not start the
      * engine.
@@ -154,24 +118,26 @@
     void stopZrtp();
 
     /**
-     * Process ZRTP message.
+     * Process RTP extension header.
      *
-     * The method takes the data and forwards it to the ZRTP state engine for further
-     * processing. It's the caller's duty to check the ZRTP CRC and the ZRTP magic
-     * cookie before calling this function.
+     * This method expects to get a pointer to the extension header of
+     * a RTP packet. The method checks if this is really a ZRTP
+     * packet. If this check fails the method returns 0 (false) in
+     * case this is not a ZRTP packet. We return a 1 if we processed
+     * the ZRTP extension header and the caller may process RTP data
+     * after the extension header as usual.  The method return -1 the
+     * call shall dismiss the packet and shall not forward it to
+     * further RTP processing.
      *
      * @param extHeader
-     *    A pointer to the first byte of the ZRTP message. Refer to RFC6189.
+     *    A pointer to the first byte of the extension header. Refer to
+     *    RFC3550.
      * @param peerSSRC
      *    The peer's SSRC.
-     * @param length
-     *     of the received data packet, this includes the RTP like header
-     *     and the ZRTP CRC field - used to do santity checks.
-     *
      * @return
      *    Code indicating further packet handling, see description above.
      */
-    void processZrtpMessage(uint8_t *extHeader, uint32_t peerSSRC, size_t length);
+    void processZrtpMessage(uint8_t *extHeader, uint32_t peerSSRC);
 
     /**
      * Process a timeout event.
@@ -236,25 +202,17 @@
     /**
      * Get the ZRTP Hello Hash data.
      *
-     * Use this method to get the ZRTP Hello hash data. The method
+     * Use this method to get the ZRTP Hello Hash data. The method
      * returns the data as a string containing the ZRTP protocol version and
      * hex-digits.
-     * 
-     * The index defines which Hello packet to use. Each supported ZRTP procol version
-     * uses a different Hello packet and thus computes different hashes.
      *
      * Refer to ZRTP specification, chapter 8.
-     * 
-     * @param index
-     *     Hello hash of the Hello packet identfied by index. Index must be 0 <= index < MAX_ZRTP_VERSIONS.
      *
      * @return
-     *    a std::string formatted according to RFC6189 section 8 without the leading 'a=zrtp-hash:'
-     *    SDP attribute identifier. The hello hash is available immediately after class instantiation.
-     * 
-     * @see getNumberSupportedVersions()
+     *    a std:string containing the Hello hash value as hex-digits. The
+     *    hello hash is available immediately after class instantiation.
      */
-    std::string getHelloHash(int index);
+    std::string getHelloHash();
 
     /**
      * Get the peer's ZRTP Hello Hash data.
@@ -493,50 +451,6 @@
       */
      int32_t getPeerZid(uint8_t* data);
 
-     /**
-      * Returns a pointer to the gather detailed information structure.
-      *
-      * This structure contains some detailed information about the negotiated
-      * algorithms, the chached and matched shared secrets.
-      */
-     const zrtpInfo *getDetailInfo();
-
-     /**
-      * Get peer's client id.
-      *
-      * @return the peer's client id or an empty @c string if not set.
-      */
-     std::string getPeerClientId();
-
-     /**
-      * Get peer's protocl version string.
-      *
-      * @return the peer's protocol version or an empty @c string if not set.
-      */
-     std::string getPeerProtcolVersion();
-
-     /**
-      * Get number of supported ZRTP protocol versions.
-      *
-      * @return the number of supported ZRTP protocol versions.
-      */
-     int32_t getNumberSupportedVersions() {return SUPPORTED_ZRTP_VERSIONS;}
-
-     /**
-      * Get negotiated ZRTP protocol version.
-      *
-      * @return the integer representation of the negotiated ZRTP protocol version.
-      */
-     int32_t getCurrentProtocolVersion() {return currentHelloPacket->getVersionInt();}
-
-     /**
-      * Validate the RS2 data if necessary.
-      *
-      * The cache functions stores the RS2 data but does not set its valid flag. The
-      * application may decide to set this flag.
-      */
-     void setRs2Valid();
-
 private:
      friend class ZrtpStateClass;
 
@@ -548,7 +462,7 @@
     /**
      * This is my ZID that I send to the peer.
      */
-    uint8_t ownZid[IDENTIFIER_LEN];
+    uint8_t zid[IDENTIFIER_LEN];
 
     /**
      * The peer's ZID
@@ -659,6 +573,7 @@
     uint8_t H1[IMPL_MAX_DIGEST_LENGTH];
     uint8_t H2[IMPL_MAX_DIGEST_LENGTH];
     uint8_t H3[IMPL_MAX_DIGEST_LENGTH];
+    uint8_t helloHash[IMPL_MAX_DIGEST_LENGTH];
 
     uint8_t peerHelloHash[IMPL_MAX_DIGEST_LENGTH];
     uint8_t peerHelloVersion[ZRTP_WORD_SIZE + 1];   // +1 for nul byte
@@ -816,9 +731,7 @@
     /**
      * Pre-initialized packets.
      */
-    ZrtpPacketHello    zrtpHello_11;
-    ZrtpPacketHello    zrtpHello_12;   // Prepare for ZRTP protocol version 1.2
-
+    ZrtpPacketHello    zrtpHello;
     ZrtpPacketHelloAck zrtpHelloAck;
     ZrtpPacketConf2Ack zrtpConf2Ack;
     ZrtpPacketClearAck zrtpClearAck;
@@ -834,23 +747,6 @@
     ZrtpPacketSASrelay zrtpSasRelay;
     ZrtpPacketRelayAck zrtpRelayAck;
 
-    HelloPacketVersion helloPackets[MAX_ZRTP_VERSIONS + 1];
-    int32_t highestZrtpVersion;
-
-    /// Pointer to Hello packet sent to partner, initialized in ZRtp, modified by ZrtpStateClass
-    ZrtpPacketHello* currentHelloPacket;
-
-    /**
-     * ZID cache record
-     */
-    ZIDRecord *zidRec;
-
-    /**
-     * Save record
-     * 
-     * If false don't save record until user vrified and confirmed the SAS.
-     */
-    bool saveZidRecord;
     /**
      * Random IV data to encrypt the confirm data, 128 bit for AES
      */
@@ -870,11 +766,7 @@
      */
     bool signSasSeen;
 
-    uint32_t peerSSRC;           // peer's SSRC, required to setup PingAck packet
-
-    zrtpInfo detailInfo;         // filled with some more detailded information if application would like to know
-
-    std::string peerClientId;    // store the peer's client Id
+    uint32_t peerSSRC;            // peer's SSRC, required to setup PingAck packet
 
     /**
      * Enable or disable paranoid mode.
@@ -917,8 +809,9 @@
      *    The Hello packet.
      * @return
      *    The Enum that identifies the best offered Hash algortihm. Return
-     *    mandatory algorithm if no match was found.
-     */
+     *    <code>NumSupportedHashes</code> to signal that no matching Hash algorithm
+     *     was found at all.
+    */
     AlgorithmEnum* findBestHash(ZrtpPacketHello *hello);
 
     /**
@@ -932,8 +825,9 @@
      * @param pk
      *    The id of the selected public key algorithm
      * @return
-     *    The Enum that identifies the best offered Cipher algorithm. Return
-     *    mandatory algorithm if no match was found.
+     *    The Enum that identifies the best offered Cipher algortihm. Return
+     *    <code>NumSupportedSymCiphers</code> to signal that no matching Cipher algorithm
+     *    was found at all.
      */
     AlgorithmEnum* findBestCipher(ZrtpPacketHello *hello,  AlgorithmEnum* pk);
 
@@ -946,8 +840,9 @@
      * @param hello
      *    The Hello packet.
      * @return
-     *    The Enum that identifies the best offered Public Key algorithm. Return
-     *    mandatory algorithm if no match was found.
+     *    The Enum that identifies the best offered Public Key algortihm. Return
+     *    <code>NumSupportedPubKeys</code> to signal that no matching Public Key algorithm
+     *    was found at all.
      */
     AlgorithmEnum* findBestPubkey(ZrtpPacketHello *hello);
 
@@ -955,18 +850,14 @@
      * Find the best SAS algorithm that is offered in Hello.
      *
      * Find the best, that is the strongest, SAS algorithm that our peer
-     * offers in its Hello packet. The method works as definied in RFC 6189,
-     * chapter 4.1.2.
-     *
-     * The list of own supported public key algorithms must follow the rules
-     * defined in RFC 6189, chapter 4.1.2, thus the order in the list must go
-     * from fastest to slowest.
+     * offers in its Hello packet.
      *
      * @param hello
      *    The Hello packet.
      * @return
-     *    The Enum that identifies the best offered SAS algorithm. Return
-     *    mandatory algorithm if no match was found.
+     *    The Enum that identifies the best offered SAS algortihm. Return
+     *    <code>NumSupportedSASTypes</code> to signal that no matching SAS algorithm
+     *    was found at all.
      */
     AlgorithmEnum* findBestSASType(ZrtpPacketHello* hello);
 
@@ -980,7 +871,8 @@
      *    The Hello packet.
      * @return
      *    The Enum that identifies the best offered authentication length. Return
-     *    mandatory algorithm if no match was found.
+     *    <code>NumSupportedAuthLenghts</code> to signal that no matching length
+     *    was found at all.
      */
     AlgorithmEnum* findBestAuthLen(ZrtpPacketHello* hello);
 
@@ -998,77 +890,6 @@
     bool checkMultiStream(ZrtpPacketHello* hello);
 
     /**
-     * Checks if Hello packet contains a strong (384bit) hash based on selection policy.
-     * 
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST HASH algorithms (Skein etc).
-     * 
-     * If Hello packet does not contain a strong hash then this functions returns @c NULL.
-     *
-     * @param hello The Hello packet.
-     * @param algoName name of selected PK algorithm
-     * @return @c hash algorithm if found in Hello packet, @c NULL otherwise.
-     */
-    AlgorithmEnum* getStrongHashOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
-     * Checks if Hello packet offers a strong (256bit) symmetric cipher based on selection policy.
-     *
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST symmetric cipher algorithms (Twofish etc).
-     *
-     * If Hello packet does not contain a symmetric cipher then this functions returns @c NULL.
-
-     * @param hello The Hello packet.
-     * @param algoName name of selected PK algorithm
-     * @return @c hash algorithm if found in Hello packet, @c NULL otherwise.
-     *
-     * @return @c cipher algorithm if found in Hello packet, @c NULL otherwise.
-     */
-    AlgorithmEnum* getStrongCipherOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
-     * Checks if Hello packet contains a hash based on selection policy.
-     *
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST HASH algorithms (Skein etc).
-     *
-     * @param hello The Hello packet.
-     * @param algoName name of selected PK algorithm
-     * @return @c hash algorithm found in Hello packet.
-     */
-    AlgorithmEnum* getHashOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
-     * Checks if Hello packet offers a symmetric cipher based on selection policy.
-     *
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST symmetric cipher algorithms (Twofish etc).
-     *
-     * @param hello The Hello packet.
-     * @param algoName name of selected PK algorithm
-     * @return non-NIST @c cipher algorithm if found in Hello packet, @c NULL otherwise
-     */
-    AlgorithmEnum* getCipherOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
-     * Checks if Hello packet offers a SRTP authentication length based on selection policy.
-     *
-     * The function currently implements the nonNist policy only:
-     * If the public key algorithm is a non-NIST ECC algorithm this function prefers
-     * non-NIST algorithms (Skein etc).
-     *
-     * @param hello The Hello packet.
-     * @param algoName algoName name of selected PK algorithm
-     * @return @c authLen algorithm found in Hello packet
-     */
-    AlgorithmEnum* getAuthLenOffered(ZrtpPacketHello *hello, int32_t algoName);
-
-    /**
      * Save the computed MitM secret to the ZID record of the peer
      */
     void writeEnrollmentPBX();
@@ -1078,18 +899,16 @@
      */
     void computeHvi(ZrtpPacketDHPart* dh, ZrtpPacketHello *hello);
 
-    void computeSharedSecretSet(ZIDRecord *zidRec);
-
-    void computeAuxSecretIds();
+    void computeSharedSecretSet(ZIDRecord& zidRec);
 
     void computeSRTPKeys();
 
     void KDF(uint8_t* key, uint32_t keyLength, uint8_t* label, int32_t labelLength,
                uint8_t* context, int32_t contextLength, int32_t L, uint8_t* output);
 
-    void generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec);
+    void generateKeysInitiator(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec);
 
-    void generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord *zidRec);
+    void generateKeysResponder(ZrtpPacketDHPart *dhPart, ZIDRecord& zidRec);
 
     void generateKeysMultiStream();
 
@@ -1462,10 +1281,8 @@
       *
       * @param id
       *     The client's id
-      * @param hpv
-      *     Pointer to hello packet version structure.
       */
-     void setClientId(std::string id, HelloPacketVersion* hpv);
+     void setClientId(std::string id);
 };
 
 /**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCWrapper.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCWrapper.h
index 0ad5b95..0126545 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCWrapper.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCWrapper.h
@@ -1,9 +1,9 @@
 /*
     This file defines the GNU ZRTP C-to-C++ wrapper.
-    Copyright (C) 2013  Werner Dittmann
+    Copyright (C) 2010  Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
@@ -565,7 +565,7 @@
      * @returns
      *      Pointer to the ZrtpContext
      */
-    ZrtpContext* zrtp_CreateWrapper(void);
+    ZrtpContext* zrtp_CreateWrapper();
 
     /**
      * Initialize the ZRTP protocol engine.
@@ -690,12 +690,10 @@
      *    A pointer to the first byte of the ZRTP message part.
      * @param peerSSRC
      *    The peer's SSRC.
-     * @param length of the received data packet - used to do santity checks.
-     *
      * @return
      *    Code indicating further packet handling, see description above.
      */
-    void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC, size_t length);
+    void zrtp_processZrtpMessage(ZrtpContext* zrtpContext, uint8_t *extHeader, uint32_t peerSSRC);
 
     /**
      * Process a timeout event.
@@ -782,28 +780,21 @@
      *
      * Use this method to get the ZRTP Hello Hash data. The method
      * returns the data as a string containing the ZRTP protocol version and
-     * hex-digits. 
-
-     * The index defines which Hello packet to use. Each supported ZRTP procol version
-     * uses a different Hello packet and thus computes different hashes.
+     * hex-digits. Refer to ZRTP specification, chapter 8.
      *
-     * Refer to ZRTP specification, chapter 8.
-     *
-     * @param index
-     *     Hello hash of the Hello packet identfied by index. Index must be 0 <= index < zrtp_getNumberSupportedVersions().
+     * <b>NOTE: An application may call this method if it needs this information.
+     * Usually it is not necessary.</b>
      *
      * @param zrtpContext
      *    Pointer to the opaque ZrtpContext structure.
-     *
      * @return
-     *    a pointer to a C-string that contains the Hello hash formatted according to RFC6189 section 8 
-     *    without the leading 'a=zrtp-hash:' SDP attribute identifier. The hello hash is available 
-     *    immediately after @c zrtp_CreateWrapper. The caller must @c free() if it does not use the
+     *    a pointer to a C-string that contains the Hello hash value as
+     *    hex-digits. The hello hash is available immediately after
+     *    @c zrtp_CreateWrapper .
+     *    The caller must @c free() if it does not use the
      *    hello hash C-string anymore.
-     *
-     * @see zrtp_getNumberSupportedVersions()
      */
-    char* zrtp_getHelloHash(ZrtpContext* zrtpContext, int32_t index);
+    char* zrtp_getHelloHash(ZrtpContext* zrtpContext);
 
     /**
      * Get the peer's ZRTP Hello Hash data.
@@ -1077,27 +1068,7 @@
     int32_t zrtp_getPeerZid(ZrtpContext* zrtpContext, uint8_t* data);
 
 
-     /**
-      * Get number of supported ZRTP protocol versions.
-      *
-      * @param zrtpContext
-      *    Pointer to the opaque ZrtpContext structure.
-      *
-      * @return the number of supported ZRTP protocol versions.
-      */
-     int32_t zrtp_getNumberSupportedVersions(ZrtpContext* zrtpContext);
-
-     /**
-      * Get negotiated ZRTP protocol versions.
-      *
-      * @param zrtpContext
-      *    Pointer to the opaque ZrtpContext structure.
-      *
-      * @return the integer representation of the negotiated ZRTP protocol version.
-      */
-     int32_t zrtp_getCurrentProtocolVersion(ZrtpContext* zrtpContext);
-
-     /**
+    /**
      * This enumerations list all configurable algorithm types.
      */
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallback.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallback.h
index 0ad18a9..23e9ca3 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallback.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallback.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -28,7 +28,20 @@
 #include <string>
 #include <stdint.h>
 #include <libzrtpcpp/ZrtpCodes.h>
-#include <common/osSpecifics.h>
+
+#ifndef __EXPORT
+  #if defined _WIN32 || defined __CYGWIN__
+    #define __EXPORT    __declspec(dllimport)
+    #define __LOCAL
+  #endif
+  #if __GNUC__ >= 4
+    #define __EXPORT    __attribute__ ((visibility("default")))
+    #define __LOCAL     __attribute__ ((visibility("hidden")))
+  #else
+    #define __EXPORT
+    #define __LOCAL
+  #endif
+#endif
 
 /**
  * This enum defines which role a ZRTP peer has.
@@ -46,7 +59,6 @@
  * </ul>
  */
 typedef enum  {
-    NoRole = 0,     ///< ZRTP role not yet set
     Responder = 1,  ///< This client is in ZRTP Responder mode
     Initiator       ///< This client is in ZRTP Initiator mode
 } Role;
@@ -118,10 +130,9 @@
      * ZRTP calls this method to send a ZRTP packet via the RTP session.
      *
      * @param data
-     *    Points to ZRTP packet to send. The packet already contains a 4 bytes
-     *    storage at the end to store CRC.
+     *    Points to ZRTP packet to send.
      * @param length
-     *    The length in bytes of the data, including the CRC storage.
+     *    The length in bytes of the data
      * @return
      *    zero if sending failed, one if packet was send
      */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallbackWrapper.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallbackWrapper.h
index 098ec06..dd739e0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCallbackWrapper.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCallbackWrapper.h
@@ -1,9 +1,9 @@
 /*
     This class maps the ZRTP C++ callback methods to C callback methods.
-    Copyright (C) 2010-2013 Werner Dittmann
+    Copyright (C) 2010 Werner Dittmann
 
     This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Lesser General Public License as published by
+    it under the terms of the GNU General Public License as published by
     the Free Software Foundation, either version 3 of the License, or
     (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCodes.h
similarity index 90%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCodes.h
index 1a7dd5f..a1bb6fc 100755
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCodes.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCodes.h
@@ -1,10 +1,10 @@
 /** @file ZrtpCodes.h
  */
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the Lesser GNU General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -73,7 +73,7 @@
  * Sub-codes for Info
  */
 enum InfoCodes {
-    InfoHelloReceived = 1,          //!< Hello received and prepared a Commit, ready to get peer's hello hash
+    InfoHelloReceived = 1,          //!< Hello received, preparing a Commit
     InfoCommitDHGenerated,          //!< Commit: Generated a public DH key
     InfoRespCommitReceived,         //!< Responder: Commit received, preparing DHPart1
     InfoDH1DHGenerated,             //!< DH1Part: Generated a public DH key
@@ -90,15 +90,14 @@
  * Sub-codes for Warning
  */
 enum WarningCodes {
-    WarningDHAESmismatch = 1,       //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096 - not used DH4096 was discarded
+    WarningDHAESmismatch = 1,       //!< Commit contains an AES256 cipher but does not offer a Diffie-Helman 4096
     WarningGoClearReceived,         //!< Received a GoClear message
-    WarningDHShort,                 //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096- not used DH4096 was discarded
+    WarningDHShort,                 //!< Hello offers an AES256 cipher but does not offer a Diffie-Helman 4096
     WarningNoRSMatch,               //!< No retained shared secrets available - must verify SAS
     WarningCRCmismatch,             //!< Internal ZRTP packet checksum mismatch - packet dropped
     WarningSRTPauthError,           //!< Dropping packet because SRTP authentication failed!
     WarningSRTPreplayError,         //!< Dropping packet because SRTP replay check failed!
-    WarningNoExpectedRSMatch,       //!< Valid retained shared secrets availabe but no matches found - must verify SAS
-    WarningNoExpectedAuxMatch       //!< Our AUX secret was set but the other peer's AUX secret does not match ours
+    WarningNoExpectedRSMatch        //!< Valid retained shared secrets availabe but no matches found - must verify SAS
 };
 
 /**
@@ -151,8 +150,7 @@
  * Information codes for the Enrollment user callbacks.
  */
 enum InfoEnrollment {
-    EnrollmentRequest = 0,          //!< Aks user to confirm or deny an Enrollemnt request
-    EnrollmentReconfirm,            //!< User already enrolled, ask re-confirmation
+    EnrollmentRequest,              //!< Aks user to confirm or deny an Enrollemnt request
     EnrollmentCanceled,             //!< User did not confirm the PBX enrollement
     EnrollmentFailed,               //!< Enrollment process failed, no PBX secret available
     EnrollmentOk                    //!< Enrollment process for this PBX was ok
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpConfigure.h
similarity index 93%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpConfigure.h
index bb78cef..33a824f 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpConfigure.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpConfigure.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2009 - 2013 Werner Dittmann
+  Copyright (C) 2009 - 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -47,7 +47,7 @@
 };
 
 typedef void(*encrypt_t)(uint8_t*, int32_t, uint8_t*, uint8_t*, int32_t);
-typedef void(*decrypt_t)(uint8_t*, int32_t, uint8_t*, uint8_t*, int32_t);
+typedef void(*decrypt_t)(uint8_t*, int32_t, const uint8_t*, uint8_t*, int32_t);
 
 /**
  * The algorithm enumration class.
@@ -182,7 +182,7 @@
  * @see zrtpSasTypes
  * @see zrtpAuthLengths
  */
-class __EXPORT EnumBase {
+class EnumBase {
 public:
     /**
      * Get an AlgorithmEnum by its name
@@ -257,41 +257,41 @@
 /**
  * The enumaration subclasses that contain the supported algorithm enumerations.
  */
-class __EXPORT HashEnum : public EnumBase {
+class HashEnum : public EnumBase {
 public:
     HashEnum();
     ~HashEnum();
 };
 
-class __EXPORT SymCipherEnum : public EnumBase {
+class SymCipherEnum : public EnumBase {
 public:
     SymCipherEnum();
     ~SymCipherEnum();
 };
 
-class __EXPORT PubKeyEnum : public EnumBase {
+class PubKeyEnum : public EnumBase {
 public:
     PubKeyEnum();
     ~PubKeyEnum();
 };
 
-class __EXPORT SasTypeEnum : public EnumBase {
+class SasTypeEnum : public EnumBase {
 public:
     SasTypeEnum();
     ~SasTypeEnum();
 };
 
-class __EXPORT AuthLengthEnum : public EnumBase {
+class AuthLengthEnum : public EnumBase {
 public:
     AuthLengthEnum();
     ~AuthLengthEnum();
 };
 
-extern __EXPORT HashEnum zrtpHashes;
-extern __EXPORT SymCipherEnum zrtpSymCiphers;
-extern __EXPORT PubKeyEnum zrtpPubKeys;
-extern __EXPORT SasTypeEnum zrtpSasTypes;
-extern __EXPORT AuthLengthEnum zrtpAuthLengths;
+extern HashEnum zrtpHashes;
+extern SymCipherEnum zrtpSymCiphers;
+extern PubKeyEnum zrtpPubKeys;
+extern SasTypeEnum zrtpSasTypes;
+extern AuthLengthEnum zrtpAuthLengths;
 
 /**
  * ZRTP configuration data.
@@ -315,14 +315,6 @@
     ~ZrtpConfigure();
 
     /**
-     * Define the algorithm selection policies.
-     */
-    typedef enum _policies {
-        Standard = 1,
-        PreferNonNist = 2
-    } Policy;
-
-    /**
      * Set the maximum number of algorithms per algorithm type that an application can
      * configure.
      */
@@ -518,9 +510,6 @@
     /// Helper function to print some internal data
     void printConfiguredAlgos(AlgoTypes algoTyp);
 
-    Policy getSelectionPolicy()         {return selectionPolicy;}
-    void setSelectionPolicy(Policy pol) {selectionPolicy = pol;}
-
   private:
     std::vector<AlgorithmEnum* > hashes;
     std::vector<AlgorithmEnum* > symCiphers;
@@ -543,8 +532,6 @@
 
     void printConfiguredAlgos(std::vector<AlgorithmEnum* >& a);
 
-    Policy selectionPolicy;
-
   protected:
 
   public:
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCrc32.h
similarity index 93%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpCrc32.h
index 49eec83..ad57edd 100755
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpCrc32.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpCrc32.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketBase.h
similarity index 87%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketBase.h
index a5826c7..8beab7e 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketBase.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketBase.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -37,8 +37,7 @@
 #include <stdint.h>
 #include <string.h>
 #include <stdlib.h>
-
-#include <common/osSpecifics.h>
+#include <netinet/in.h>
 
 #include <libzrtpcpp/zrtpPacket.h>
 #include <libzrtpcpp/ZrtpTextData.h>
@@ -96,7 +95,7 @@
      * @return
      *     @c true if check was ok
      */
-    bool isZrtpPacket()            { return (zrtpNtohs(zrtpHeader->zrtpId) == zrtpId); };
+    bool isZrtpPacket()            { return (ntohs(zrtpHeader->zrtpId) == zrtpId); };
 
     /**
      * Get the length in words of the ZRTP message
@@ -104,7 +103,7 @@
      * @return
      *     The length in words
      */
-    uint16_t getLength()           { return zrtpNtohs(zrtpHeader->length); };
+    uint16_t getLength()           { return ntohs(zrtpHeader->length); };
 
     /**
      * Return pointer to fixed length message type ASCII data
@@ -120,7 +119,7 @@
      * @param len
      *     The length of the ZRTP message in words, host order
      */
-    void setLength(uint16_t len)  { zrtpHeader->length = zrtpHtons(len); };
+    void setLength(uint16_t len)  { zrtpHeader->length = htons(len); };
 
     /**
      * Copy the message type ASCII data to ZRTP message type field
@@ -134,7 +133,7 @@
     /**
      * Initializes the ZRTP Id field
      */
-    void setZrtpId()              { zrtpHeader->zrtpId = zrtpHtons(zrtpId); }
+    void setZrtpId()              { zrtpHeader->zrtpId = htons(zrtpId); }
 };
 
 /**
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketClearAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketClearAck.h
index 91ca4c4..992f6d8 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketClearAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketClearAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketCommit.h
similarity index 88%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketCommit.h
index 4b6e1eb..b23b23d 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketCommit.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketCommit.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -31,11 +31,6 @@
 
 #include <libzrtpcpp/ZrtpPacketBase.h>
 
-// PRSH here only for completeness. We don't support PRSH in the other ZRTP parts.
-#define COMMIT_DH_EX      29
-#define COMMIT_MULTI      25
-#define COMMIT_PRSH       27
-
 /**
  * Implement the Commit packet.
  *
@@ -53,11 +48,6 @@
     Commit_t* commitHeader;     ///< Points to Commit message part
 
  public:
-    typedef enum _commitType {
-        DhExchange =  1,
-        MultiStream = 2
-    } commitType;
-
     /// Creates a Commit packet with default data
     ZrtpPacketCommit();
 
@@ -100,10 +90,6 @@
     /// Get pointer to MAC field during multi-stream mode, a fixed length byte array
     uint8_t* getHMACMulti()   { return commitHeader->hmac-4*ZRTP_WORD_SIZE; };
 
-    /// Check if packet length makes sense.
-    bool isLengthOk(commitType type)   {int32_t len = getLength(); 
-                                        return ((type == DhExchange) ? len == COMMIT_DH_EX : len == COMMIT_MULTI);}
-
     /// Set hash algorithm type field, fixed length character field
     void setHashType(uint8_t* text)    { memcpy(commitHeader->hash, text, ZRTP_WORD_SIZE); };
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConf2Ack.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConf2Ack.h
index a6f85f5..a7c2567 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConf2Ack.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConf2Ack.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConfirm.h
similarity index 90%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConfirm.h
index 283861d..b2dfbf4 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketConfirm.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketConfirm.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -73,7 +73,7 @@
         const uint8_t* getHmac()          { return confirmHeader->hmac; }
 
         /// Get Expiration time data
-        const uint32_t getExpTime()       { return zrtpNtohl(confirmHeader->expTime); }
+        const uint32_t getExpTime()       { return ntohl(confirmHeader->expTime); }
 
         /// Get pointer to initial hash chain (H0) data, fixed byte array
         uint8_t* getHashH0()              { return confirmHeader->hashH0; }
@@ -84,11 +84,6 @@
         /// get the signature length in words
         int32_t getSignatureLength();
 
-        /// Check if packet length makes sense. Confirm packets are 19 words at minumum
-        bool isLengthOk()             {return (getLength() >= 19); }
-
-        bool isSignatureLengthOk();
-
         /// set SAS verified flag
         void setSASFlag()            { confirmHeader->flags |= 0x4; }
 
@@ -102,7 +97,7 @@
         void setIv(uint8_t* text)    { memcpy(confirmHeader->iv, text, sizeof(confirmHeader->iv)); }
 
         /// Set expiration time data
-        void setExpTime(uint32_t t)  { confirmHeader->expTime = zrtpHtonl(t); }
+        void setExpTime(uint32_t t)  { confirmHeader->expTime = htonl(t); }
 
         /// Set initial hash chain (H0) data, fixed length byte array
         void setHashH0(uint8_t* t)   { memcpy(confirmHeader->hashH0, t, sizeof(confirmHeader->hashH0)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketDHPart.h
similarity index 93%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketDHPart.h
index 08737a5..d0ea4ba 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketDHPart.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketDHPart.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -79,9 +79,6 @@
     /// Get pointer to HMAC, fixed length byte array
     uint8_t* getHMAC()           { return pv+dhLength; };
 
-    /// Check if packet length makes sense. DHPart packets are 29 words at minumum, using E255
-    bool isLengthOk()            {return (getLength() >= 29);}
-
     /// Setpublic key value, variable length byte array
     void setPv(uint8_t* text)         { memcpy(pv, text, dhLength); };
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketError.h
similarity index 83%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketError.h
index 679a803..d775801 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketError.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketError.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -52,10 +52,10 @@
     virtual ~ZrtpPacketError();
 
     /// Get the error code from Error message
-    uint32_t getErrorCode() { return zrtpNtohl(errorHeader->errorCode); };
+    uint32_t getErrorCode() { return ntohl(errorHeader->errorCode); };
 
     /// Set error code in Error message
-    void setErrorCode(uint32_t code) {errorHeader->errorCode = zrtpHtonl(code); };
+    void setErrorCode(uint32_t code) {errorHeader->errorCode = htonl(code); };
 
  private:
      ErrorPacket_t data;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketErrorAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketErrorAck.h
index cfd435c..e64c8a6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketErrorAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketErrorAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2007-2013 Werner Dittmann
+  Copyright (C) 2007 - 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketGoClear.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketGoClear.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketGoClear.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketGoClear.h
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHello.h
similarity index 90%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHello.h
index f5394af..0cc7403 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHello.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHello.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -28,8 +28,6 @@
 
 #include <libzrtpcpp/ZrtpPacketBase.h>
 
-#define HELLO_FIXED_PART_LEN  22
-
 /**
  * Implement the Hello packet.
  *
@@ -85,9 +83,6 @@
     /// Get version number from Hello message, fixed ASCII character array
     uint8_t* getVersion()  { return helloHeader->version; };
 
-     /// Get version number from Hello message as integer, only relvant digits converted
-    int32_t getVersionInt();
-
     /// Get client id from Hello message, fixed ASCII character array
     uint8_t* getClientId() { return helloHeader->clientId; };
 
@@ -98,7 +93,7 @@
     uint8_t* getZid()      { return helloHeader->zid; };
 
     /// Set version sting in Hello message, fixed ASCII character array
-    void setVersion(const uint8_t *text)     { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
+    void setVersion(uint8_t *text)     { memcpy(helloHeader->version, text,ZRTP_WORD_SIZE ); }
 
     /// Set client id in Hello message, fixed ASCII character array
     void setClientId(const uint8_t *t) { memcpy(helloHeader->clientId, t, sizeof(helloHeader->clientId)); }
@@ -176,20 +171,16 @@
     int32_t getNumAuth()     {return nAuth; }
 
     /// set MitM flag
-    void setMitmMode()       {helloHeader->flags |= 0x20; }
+    void setMitmMode()            { helloHeader->flags |= 0x20; }
 
     /// set SAS sign flag
-    void setSasSign()        {helloHeader->flags |= 0x40; }
-
-    /// Check if packet length matches
-    bool isLengthOk()        {return (computedLength == getLength());}
+    void setSasSign()            { helloHeader->flags |= 0x40; }
 
  private:
-     uint32_t computedLength;
      // Hello packet is of variable length. It maximum size is 46 words:
-     // - 20 words fixed sizze
+     // - 11 words fixed sizze
      // - up to 35 words variable part, depending on number of algorithms
-     // leads to a maximum of 4*55=220 bytes.
+     // leads to a maximum of 4*46=184 bytes.
      uint8_t data[256];       // large enough to hold a full blown Hello packet
 };
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHelloAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHelloAck.h
index d3e138e..345a071 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketHelloAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketHelloAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPing.h
similarity index 92%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPing.h
index 32fb2f9..840df62 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPing.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPing.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPingAck.h
similarity index 87%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPingAck.h
index eb2924f..51ad8c8 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketPingAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketPingAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -49,13 +49,13 @@
     virtual ~ZrtpPacketPingAck();
 
     /// Get SSRC from PingAck message
-    uint32_t getSSRC() { return zrtpNtohl(pingAckHeader->ssrc); };
+    uint32_t getSSRC() { return ntohl(pingAckHeader->ssrc); };
 
     /// Set ZRTP protocol version field, fixed ASCII character array
     void setVersion(uint8_t *text)      { memcpy(pingAckHeader->version, text, ZRTP_WORD_SIZE ); }
 
     /// Set SSRC in PingAck message
-    void setSSRC(uint32_t data)         {pingAckHeader->ssrc = zrtpHtonl(data); };
+    void setSSRC(uint32_t data)         {pingAckHeader->ssrc = htonl(data); };
 
     /// Set remote endpoint hash, fixed byte array
     void setRemoteEpHash(uint8_t *hash) { memcpy(pingAckHeader->remoteEpHash, hash, sizeof(pingAckHeader->remoteEpHash)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketRelayAck.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketRelayAck.h
index 7fe373b..93437e6 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketRelayAck.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketRelayAck.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2007-2013 Werner Dittmann
+  Copyright (C) 2007 - 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketSASrelay.h
similarity index 86%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketSASrelay.h
index 22739ff..427ac28 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpPacketSASrelay.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpPacketSASrelay.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2011 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -70,17 +70,14 @@
         const uint8_t* getHmac()          { return sasRelayHeader->hmac; }
 
         /// Get pointer to new SAS rendering algorithm, fixed byte array
-        const uint8_t* getSasAlgo() {return sasRelayHeader->sas; }
+        const uint8_t* getSas() {return sasRelayHeader->sas; }
 
         /// Get pointer to new SAS hash data, fixed byte array
-        const uint8_t* getTrustedSas()    { return sasRelayHeader->trustedSasHash; }
+        const uint8_t* getTrustedSas() { return sasRelayHeader->trustedSasHash; }
 
         /// get the signature length in words
         uint32_t getSignatureLength();
 
-        /// Check if packet length makes sense. SAS rely packets are 19 words at minumum, they are similar to Confirm
-        bool isLengthOk()                 {return (getLength() >= 19);}
-
         /// set SAS verified flag
         void setSASFlag()            { sasRelayHeader->flags |= 0x4; }
 
@@ -91,7 +88,7 @@
         void setIv(uint8_t* text)    { memcpy(sasRelayHeader->iv, text, sizeof(sasRelayHeader->iv)); }
 
         /// Set SAS rendering algorithm, fixed length byte array
-        void setSasAlgo(uint8_t* text) { memcpy(sasRelayHeader->sas, text, sizeof(sasRelayHeader->sas)); }
+        void setSas(uint8_t* text)    { memcpy(sasRelayHeader->sas, text, sizeof(sasRelayHeader->sas)); }
 
         /// Set SAS hash data, fixed length byte array
         void setTrustedSas(uint8_t* text)    { memcpy(sasRelayHeader->trustedSasHash, text, sizeof(sasRelayHeader->trustedSasHash)); }
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpQueue.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpQueue.h
index 512d8c8..b979ada 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpQueue.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpQueue.h
@@ -21,8 +21,8 @@
 #include <ccrtp/cqueue.h>
 #include <ccrtp/rtppkt.h>
 #include <libzrtpcpp/ZrtpCallback.h>
+#include <libzrtpcpp/TimeoutProvider.h>
 #include <libzrtpcpp/ZrtpConfigure.h>
-#include <CcrtpTimeoutProvider.h>
 
 class __EXPORT ZrtpUserCallback;
 class __EXPORT ZRtp;
@@ -368,28 +368,20 @@
      */
     void setClientId(std::string id);
 
-   /**
+    /**
      * Get the ZRTP Hello Hash data.
      *
-     * Use this method to get the ZRTP Hello hash data. The method
-     * returns the data as a string containing the ZRTP protocol version and
-     * hex-digits.
-     * 
-     * The index defines which Hello packet to use. Each supported ZRTP procol version
-     * uses a different Hello packet and thus computes different hashes.
-     *
-     * Refer to ZRTP specification, chapter 8.
-     *
-     * @param index
-     *     Hello hash of the Hello packet identfied by index. Index must be 0 <= index < getNumberSupportedVersions().
+     * Use this method to get the ZRTP Hello Hash data. The method
+     * returns the data as a string containing hex-digits. Refer
+     * to ZRTP specification, chapter 9.1.
      *
      * @return
-     *    a std::string formatted according to RFC6189 section 8 without the leading 'a=zrtp-hash:'
-     *    SDP attribute identifier. The hello hash is available immediatly after class instantiation.
-     * 
-     * @see getNumberSupportedVersions()
+     *    a std:string containing the Hello hash value as hex-digits. The
+     *    hello hash is available immediatly after calling
+     *    ZrtpQueue#startZrtp. If ZRTP was not started the method returns
+     *    an empty string.
      */
-    std::string getHelloHash(int32_t index);
+    std::string getHelloHash();
 
     /**
      * Get the peer's ZRTP Hello Hash data.
@@ -751,20 +743,6 @@
      */
     int32 getPeerZid(uint8* data);
 
-    /**
-      * Get number of supported ZRTP protocol versions.
-      *
-      * @return the number of supported ZRTP protocol versions.
-      */
-     int32_t getNumberSupportedVersions();
-
-     /**
-      * Get negotiated ZRTP protocol version.
-      *
-      * @return the integer representation of the negotiated ZRTP protocol version.
-      */
-     int32_t getCurrentProtocolVersion();
-
 protected:
     friend class TimeoutProvider<std::string, ost::ZrtpQueue*>;
 
@@ -873,7 +851,6 @@
     int16 senderZrtpSeqNo;
     ost::Mutex synchLock;   // Mutex for ZRTP (used by ZrtpStateClass)
     uint32 peerSSRC;
-    uint64 zrtpUnprotect;
     bool started;
     bool mitmMode;
     bool signSas;
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStateClass.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpStateClass.h
index 5c16313..fba061d 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStateClass.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStateClass.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -74,7 +74,6 @@
 /// A ZRTP state event
 typedef struct Event {
     EventDataType type; ///< Type of event
-    size_t   length;    ///< length of the message data
     uint8_t* packet;    ///< Event data if availabe, usually a ZRTP message
 } Event_t;
 
@@ -161,11 +160,6 @@
      */
     bool subEvWaitRelayAck();
 
-    /**
-     * Hello packet version sent to other partner
-     */
-    int32_t sentVersion;
-
 public:
     /// Create a ZrtpStateClass
     ZrtpStateClass(ZRtp *p);
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStates.h
similarity index 94%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpStates.h
index e90a543..44662a0 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpStates.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpStates.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpTextData.h
similarity index 86%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpTextData.h
index 0be1e56..e79cb98 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpTextData.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpTextData.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -37,12 +37,8 @@
  *
  * @author Werner Dittmann <Werner.Dittmann@t-online.de>
  */
-
-extern char zrtpBuildInfo[];
-
 extern char clientId[];
-extern char zrtpVersion_11[];
-extern char zrtpVersion_12[];
+extern char zrtpVersion[];
 
 /**
  *
@@ -91,8 +87,6 @@
 
 extern char s256[];
 extern char s384[];
-extern char skn2[];
-extern char skn3[];
 extern const char* mandatoryHash;
 
 extern char aes3[];
@@ -108,15 +102,12 @@
 extern char dh3k[];
 extern char ec25[];
 extern char ec38[];
-extern char e255[];
-extern char e414[];
 
 extern char mult[];
 
 extern const char* mandatoryPubKey;
 
 extern char b32[];
-extern char b256[];
 extern const char* mandatorySasType;
 
 extern char hs32[];
@@ -126,9 +117,6 @@
 extern const char* mandatoryAuthLen_1;
 extern const char* mandatoryAuthLen_2;
 
-extern const char* sas256WordsOdd[];
-extern const char* sas256WordsEven[];
-
 /**
  * @}
  */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpUserCallback.h
similarity index 98%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
rename to jni/libzrtp/sources/src/libzrtpcpp/ZrtpUserCallback.h
index d3c9f9d..3e4871c 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpUserCallback.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/ZrtpUserCallback.h
@@ -1,8 +1,8 @@
 /*

-  Copyright (C) 2006-2013 Werner Dittmann

+  Copyright (C) 2006-2008 Werner Dittmann

 

   This program is free software: you can redistribute it and/or modify

-  it under the terms of the GNU Lesser General Public License as published by

+  it under the terms of the GNU General Public License as published by

   the Free Software Foundation, either version 3 of the License, or

   (at your option) any later version.

 

diff --git a/jni/libzrtp/sources/zrtp/crypto/twoCFB.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/TwoCFB.cpp
similarity index 90%
rename from jni/libzrtp/sources/zrtp/crypto/twoCFB.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/TwoCFB.cpp
index d4f7042..be3dda4 100755
--- a/jni/libzrtp/sources/zrtp/crypto/twoCFB.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/TwoCFB.cpp
@@ -36,12 +36,13 @@
 
 #include <string.h>
 
-#include <zrtp/crypto/twoCFB.h>
-#include <cryptcommon/twofish.h>
+#include <libzrtpcpp/crypto/twoCFB.h>
+#include <libzrtpcpp/crypto/twofish.h>
 
 static int initialized = 0;
 
-void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
+void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+                   int32_t dataLength)
 {
     Twofish_key keyCtx;
     int usedBytes = 0;
@@ -59,7 +60,8 @@
 }
 
 
-void twoCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
+void twoCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
+                   int32_t dataLength)
 {
     Twofish_key keyCtx;
     int usedBytes = 0;
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/ZrtpDH.h
similarity index 95%
rename from jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/ZrtpDH.h
index d2a3a40..bd32f7f 100644
--- a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/ZrtpDH.h
@@ -23,9 +23,10 @@
 #define _ZRTPDH_H__
 
 #include <stdint.h>
+#include <libzrtpcpp/ZrtpConfigure.h>
 
 /**
- * @file zrtpDH.h
+ * @file ZrtpDH.h
  * @brief Class that implemets Diffie-Helman key agreement for ZRTP
  * 
  * @ingroup GNU_ZRTP
@@ -42,25 +43,12 @@
  * @param length
  *    Number of random bytes to produce.
  */
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
 void randomZRTP(uint8_t *buf, int32_t length);
-#if defined(__cplusplus)
-}
-#endif
-
-#if defined(__cplusplus)
-
-#include <libzrtpcpp/ZrtpConfigure.h>
 
 const int32_t DH2K = 0;
 const int32_t DH3K = 1;
 const int32_t EC25 = 2;
 const int32_t EC38 = 3;
-const int32_t E255 = 4;
-const int32_t E414 = 5;
 
 
 /**
@@ -164,8 +152,8 @@
      */
     const char* getDHtype();
 };
-#endif /*__cpluscplus */
-#endif
+
+#endif // ZRTPDH_H
 
 /**
  * @}
diff --git a/jni/libzrtp/sources/zrtp/crypto/aesCFB.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/aesCFB.h
similarity index 91%
rename from jni/libzrtp/sources/zrtp/crypto/aesCFB.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/aesCFB.h
index 7223bdf..6b4ab6e 100644
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/aesCFB.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -79,7 +79,7 @@
  *    Length of the data in bytes
  */
 
-void aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+void aesCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
                    int32_t dataLength);
 /**
  * @}
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp
similarity index 95%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp
index 1c743d2..78fad51 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/InitializeGcrypt.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/InitializeGcrypt.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -17,7 +17,7 @@
 
 #include <stdio.h>
 
-#include <string.h>
+#include <malloc.h>
 #include <pthread.h>
 #include <errno.h>
 #include <gcrypt.h>
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
similarity index 88%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
index 066035f..8d06a89 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptAesCFB.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptAesCFB.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -21,7 +21,7 @@
  */
 
 #include <gcrypt.h>
-#include <crypto/aesCFB.h>
+#include <libzrtpcpp/crypto/aesCFB.h>
 
 
 extern void initializeGcrypt();
@@ -51,7 +51,7 @@
     gcry_cipher_close(tmp);
 }
 
-void aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+void aesCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
                    int32_t dataLength);
 {
     gcry_error_t err = 0;
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
index bc8897a..1aba680 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptZrtpDH.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptZrtpDH.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006, 2013 Werner Dittmann
+  Copyright (C) 2006, 2009 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -21,8 +21,8 @@
  */
 
 #include <gcrypt.h>
-#include <zrtp/crypto/zrtpDH.h>
-#include <zrtp/libzrtpcpp/ZrtpTextData.h>
+#include <libzrtpcpp/crypto/ZrtpDH.h>
+#include <libzrtpcpp/ZrtpTextData.h>
 #include <sstream>
 
 struct gcryptCtx {
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
index a0ecc65..3a44504 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac256.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -21,7 +21,7 @@
  */
 
 #include <gcrypt.h>
-#include <crypto/hmac256.h>
+#include <libzrtpcpp/crypto/hmac256.h>
 
 void hmac_sha256(uint8_t* key, uint32_t keyLength,
 		uint8_t* data, int32_t dataLength,
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
similarity index 97%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
index aa852c4..c48813c 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcrypthmac384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcrypthmac384.cpp
@@ -21,7 +21,7 @@
  */
 
 #include <gcrypt.h>
-#include <crypto/hmac384.h>
+#include <libzrtpcpp/crypto/hmac384.h>
 
 void hmac_sha384(uint8_t* key, uint32_t keyLength,
 		uint8_t* data, int32_t dataLength,
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
similarity index 93%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
index b20bfe6..0c32bd8 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha256.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -22,7 +22,7 @@
  */
 
 #include <gcrypt.h>
-#include <crypto/sha256.h>
+#include <libzrtpcpp/crypto/sha256.h>
 
 void sha256(unsigned char* data, unsigned int dataLength,
             unsigned char* mac)
diff --git a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
similarity index 93%
rename from jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
index c26a23c..19c8c5b 100644
--- a/jni/libzrtp/sources/zrtp/crypto/gcrypt/gcryptsha384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/gcrypt/gcryptsha384.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -22,7 +22,7 @@
  */
 
 #include <gcrypt.h>
-#include <crypto/sha384.h>
+#include <libzrtpcpp/crypto/sha384.h>
 
 void sha384(unsigned char* data, unsigned int dataLength,
             unsigned char* mac)
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac256.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac256.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/crypto/hmac256.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac256.h
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac384.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac384.h
similarity index 100%
rename from jni/libzrtp/sources/zrtp/crypto/hmac384.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/hmac384.h
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/aesCFB.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/AesCFB.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/aesCFB.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/AesCFB.cpp
index bac29f5..595d1ff 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/aesCFB.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/AesCFB.cpp
@@ -38,7 +38,7 @@
 #include <openssl/aes.h>
 #include <string.h>
 
-#include <zrtp/crypto/aesCFB.h>
+#include <libzrtpcpp/crypto/aesCFB.h>
 
 // extern void initializeOpenSSL();
 
@@ -66,7 +66,7 @@
 }
 
 
-void aesCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+void aesCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
                    int32_t dataLength)
 {
     AES_KEY aesKey;
@@ -85,5 +85,5 @@
         return;
     }
     AES_cfb128_encrypt(data, data, dataLength, &aesKey,
-                       IV, &usedBytes, AES_DECRYPT);
+                       (unsigned char*)IV, &usedBytes, AES_DECRYPT);
 }
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp
similarity index 97%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp
index 2c5c8de..ef0c926 100755
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/InitializeOpenSSL.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/InitializeOpenSSL.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006 Werner Dittmann
 
   This program is free software; you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/zrtpDH.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/ZrtpDH.cpp
similarity index 99%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/zrtpDH.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/ZrtpDH.cpp
index d5b8cc9..fbd623c 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/zrtpDH.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/ZrtpDH.cpp
@@ -46,8 +46,8 @@
 #include <openssl/ec.h>
 #include <openssl/ecdh.h>
 
-#include <zrtp/crypto/zrtpDH.h>
-#include <zrtp/libzrtpcpp/ZrtpTextData.h>
+#include <libzrtpcpp/crypto/ZrtpDH.h>
+#include <libzrtpcpp/ZrtpTextData.h>
 
 // extern void initializeOpenSSL();
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac256.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/hmac256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac256.cpp
index 40e4e82..a054c02 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac256.cpp
@@ -36,7 +36,7 @@
  */
 
 #include <openssl/hmac.h>
-#include <crypto/hmac256.h>
+#include <libzrtpcpp/crypto/hmac256.h>
 
 void hmac_sha256(uint8_t* key, uint32_t key_length,
 		uint8_t* data, int32_t data_length,
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac384.cpp
similarity index 92%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/hmac384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac384.cpp
index 8181cd6..10d6fbc 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/hmac384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/hmac384.cpp
@@ -36,9 +36,11 @@
  */
 
 #include <openssl/hmac.h>
-#include <zrtp/crypto/hmac256.h>
+#include <libzrtpcpp/crypto/hmac256.h>
 
-void hmac_sha384(uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length)
+void hmac_sha384(uint8_t* key, uint32_t key_length,
+		uint8_t* data, int32_t data_length,
+                uint8_t* mac, uint32_t* mac_length)
 {
     unsigned int tmp;
     HMAC( EVP_sha384(), key, key_length, data, data_length, mac, &tmp );
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/sha256.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha256.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/sha256.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha256.cpp
index bc2e222..2163a6d 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/sha256.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha256.cpp
@@ -38,7 +38,7 @@
 #include <openssl/crypto.h>
 #include <openssl/sha.h>
 
-#include <crypto/sha256.h>
+#include <libzrtpcpp/crypto/sha256.h>
 
 void sha256(unsigned char *data, unsigned int data_length,
 	    unsigned char *digest )
diff --git a/jni/libzrtp/sources/zrtp/crypto/openssl/sha384.cpp b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha384.cpp
similarity index 98%
rename from jni/libzrtp/sources/zrtp/crypto/openssl/sha384.cpp
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha384.cpp
index 9fcf316..9d166e7 100644
--- a/jni/libzrtp/sources/zrtp/crypto/openssl/sha384.cpp
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/openssl/sha384.cpp
@@ -38,7 +38,7 @@
 #include <openssl/crypto.h>
 #include <openssl/sha.h>
 
-#include <crypto/sha384.h>
+#include <libzrtpcpp/crypto/sha384.h>
 
 void sha384(unsigned char *data, unsigned int data_length,
 	    unsigned char *digest )
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha256.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha256.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/crypto/sha256.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/sha256.h
index 36127b9..959a620 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha256.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha256.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha384.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha384.h
similarity index 96%
rename from jni/libzrtp/sources/zrtp/crypto/sha384.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/sha384.h
index d4ccce5..6cb7a70 100644
--- a/jni/libzrtp/sources/zrtp/crypto/sha384.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/sha384.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/crypto/twoCFB.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twoCFB.h
similarity index 87%
rename from jni/libzrtp/sources/zrtp/crypto/twoCFB.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twoCFB.h
index 595d19d..593a59c 100755
--- a/jni/libzrtp/sources/zrtp/crypto/twoCFB.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twoCFB.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -56,7 +56,8 @@
  *    Length of the data in bytes
  */
 
-void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength);
+void twoCfbEncrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data,
+                   int32_t dataLength);
 
 /**
  * Decrypt data with Twofish CFB mode, full block feedback size.
@@ -78,7 +79,8 @@
  *    Length of the data in bytes
  */
 
-void twoCfbDecrypt(uint8_t* key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength);
+void twoCfbDecrypt(uint8_t* key, int32_t keyLength, const uint8_t* IV, uint8_t *data,
+                   int32_t dataLength);
 /**
  * @}
  */
diff --git a/jni/libzrtp/sources/cryptcommon/twofish.c b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/twofish.c
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.c
index 03d2770..3d390ea 100644
--- a/jni/libzrtp/sources/cryptcommon/twofish.c
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.c
@@ -1,1742 +1,1733 @@
-/* 
- * Fast, portable, and easy-to-use Twofish implementation,  
- * Version 0.3. 
- * Copyright (c) 2002 by Niels Ferguson.  
- * (See further down for the almost-unrestricted licensing terms.) 
- * 
- * -------------------------------------------------------------------------- 
- * There are two files for this implementation: 
- * - twofish.h, the header file. 
- * - twofish.c, the code file. 
- * 
- * To incorporate this code into your program you should: 
- * - Check the licensing terms further down in this comment. 
- * - Fix the two type definitions in twofish.h to suit your platform. 
- * - Fix a few definitions in twofish.c in the section marked  
- *   PLATFORM FIXES. There is one important ones that affects  
- *   functionality, and then a few definitions that you can optimise  
- *   for efficiency but those have no effect on the functionality.  
- *   Don't change anything else. 
- * - Put the code in your project and compile it. 
- * 
- * To use this library you should: 
- * - Call Twofish_initialise() in your program before any other function in 
- *   this library. 
- * - Use Twofish_prepare_key(...) to convert a key to internal form. 
- * - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt 
- *   data. 
- * See the comments in the header file for details on these functions. 
- * -------------------------------------------------------------------------- 
- *  
- * There are many Twofish implementation available for free on the web. 
- * Most of them are hard to integrate into your own program. 
- * As we like people to use our cipher, I thought I would make it easier.  
- * Here is a free and easy-to-integrate Twofish implementation in C. 
- * The latest version is always available from my personal home page at 
- *    http://niels.ferguson.net/ 
- * 
- * Integrating library code into a project is difficult because the library 
- * header files interfere with the project's header files and code.  
- * And of course the project's header files interfere with the library code. 
- * I've tried to resolve these problems here.  
- * The header file of this implementation is very light-weight.  
- * It contains two typedefs, a structure, and a few function declarations. 
- * All names it defines start with "Twofish_".  
- * The header file is therefore unlikely to cause problems in your project. 
- * The code file of this implementation doesn't need to include the header 
- * files of the project. There is thus no danger of the project interfering 
- * with all the definitions and macros of the Twofish code. 
- * In most situations, all you need to do is fill in a few platform-specific 
- * definitions in the header file and code file,  
- * and you should be able to run the Twofish code in your project. 
- * I estimate it should take you less than an hour to integrate this code 
- * into your project, most of it spent reading the comments telling you what 
- * to do. 
- * 
- * For people using C++: it is very easy to wrap this library into a 
- * TwofishKey class. One of the big advantages is that you can automate the 
- * wiping of the key material in the destructor. I have not provided a C++ 
- * class because the interface depends too much on the abstract base class  
- * you use for block ciphers in your program, which I don't know about. 
- * 
- * This implementation is designed for use on PC-class machines. It uses the  
- * Twofish 'full' keying option which uses large tables. Total table size is  
- * around 5-6 kB for static tables plus 4.5 kB for each pre-processed key. 
- * If you need an implementation that uses less memory, 
- * take a look at Brian Gladman's code on his web site: 
- *     http://fp.gladman.plus.com/cryptography_technology/aes/ 
- * He has code for all AES candidates. 
- * His Twofish code has lots of options trading off table size vs. speed. 
- * You can also take a look at the optimised code by Doug Whiting on the 
- * Twofish web site 
- *      http://www.counterpane.com/twofish.html 
- * which has loads of options. 
- * I believe these existing implementations are harder to re-use because they 
- * are not clean libraries and they impose requirements on the environment.  
- * This implementation is very careful to minimise those,  
- * and should be easier to integrate into any larger program. 
- * 
- * The default mode of this implementation is fully portable as it uses no 
- * behaviour not defined in the C standard. (This is harder than you think.) 
- * If you have any problems porting the default mode, please let me know 
- * so that I can fix the problem. (But only if this code is at fault, I  
- * don't fix compilers.) 
- * Most of the platform fixes are related to non-portable but faster ways  
- * of implementing certain functions. 
- * 
- * In general I've tried to make the code as fast as possible, at the expense 
- * of memory and code size. However, C does impose limits, and this  
- * implementation will be slower than an optimised assembler implementation. 
- * But beware of assembler implementations: a good Pentium implementation 
- * uses completely different code than a good Pentium II implementation. 
- * You basically have to re-write the assembly code for every generation of 
- * processor. Unless you are severely pressed for speed, stick with C. 
- * 
- * The initialisation routine of this implementation contains a self-test. 
- * If initialisation succeeds without calling the fatal routine, then 
- * the implementation works. I don't think you can break the implementation 
- * in such a way that it still passes the tests, unless you are malicious. 
- * In other words: if the initialisation routine returns,  
- * you have successfully ported the implementation.  
- * (Or not implemented the fatal routine properly, but that is your problem.) 
- * 
- * I'm indebted to many people who helped me in one way or another to write 
- * this code. During the design of Twofish and the AES process I had very  
- * extensive discussions of all implementation issues with various people. 
- * Doug Whiting in particular provided a wealth of information. The Twofish  
- * team spent untold hours discussion various cipher features, and their  
- * implementation. Brian Gladman implemented all AES candidates in C,  
- * and we had some fruitful discussions on how to implement Twofish in C. 
- * Jan Nieuwenhuizen tested this code on Linux using GCC. 
- * 
- * Now for the license: 
- * The author hereby grants a perpetual license to everybody to 
- * use this code for any purpose as long as the copyright message is included 
- * in the source code of this or any derived work. 
- *  
- * Yes, this means that you, your company, your club, and anyone else 
- * can use this code anywhere you want. You can change it and distribute it 
- * under the GPL, include it in your commercial product without releasing 
- * the source code, put it on the web, etc.  
- * The only thing you cannot do is remove my copyright message,  
- * or distribute any source code based on this implementation that does not  
- * include my copyright message.  
- *  
- * I appreciate a mention in the documentation or credits,  
- * but I understand if that is difficult to do. 
- * I also appreciate it if you tell me where and why you used my code. 
- * 
- * Please send any questions or comments to niels@ferguson.net 
- * 
- * Have Fun! 
- * 
- * Niels 
- */ 
- 
-/* 
- * DISCLAIMER: As I'm giving away my work for free, I'm of course not going 
- * to accept any liability of any form. This code, or the Twofish cipher, 
- * might very well be flawed; you have been warned. 
- * This software is provided as-is, without any kind of warrenty or 
- * guarantee. And that is really all you can expect when you download  
- * code for free from the Internet.  
- * 
- * I think it is really sad that disclaimers like this seem to be necessary. 
- * If people only had a little bit more common sense, and didn't come 
- * whining like little children every time something happens.... 
- */ 
-  
-/* 
- * Version history: 
- * Version 0.0, 2002-08-30 
- *      First written. 
- * Version 0.1, 2002-09-03 
- *      Added disclaimer. Improved self-tests. 
- * Version 0.2, 2002-09-09 
- *      Removed last non-portabilities. Default now works completely within 
- *      the C standard. UInt32 can be larger than 32 bits without problems. 
- * Version 0.3, 2002-09-28 
- *      Bugfix: use  instead of  to adhere to ANSI/ISO. 
- *      Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library  
- *      header  already defines BIG_ENDIAN, even though it is not  
- *      supposed to. 
- */ 
- 
- 
-/*  
- * Minimum set of include files. 
- * You should not need any application-specific include files for this code.  
- * In fact, adding you own header files could break one of the many macros or 
- * functions in this file. Be very careful. 
- * Standard include files will probably be ok. 
- */ 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-/* #include      * for memset(), memcpy(), and memcmp() */ 
-#include "twofish.h" 
- 
- 
-/* 
- * PLATFORM FIXES 
- * ============== 
- * 
- * Fix the type definitions in twofish.h first! 
- *  
- * The following definitions have to be fixed for each particular platform  
- * you work on. If you have a multi-platform program, you no doubt have  
- * portable definitions that you can substitute here without changing the  
- * rest of the code. 
- */ 
- 
- 
-/*  
- * Function called if something is fatally wrong with the implementation.  
- * This fatal function is called when a coding error is detected in the 
- * Twofish implementation, or when somebody passes an obviously erroneous 
- * parameter to this implementation. There is not much you can do when 
- * the code contains bugs, so we just stop. 
- *  
- * The argument is a string. Ideally the fatal function prints this string 
- * as an error message. Whatever else this function does, it should never 
- * return. A typical implementation would stop the program completely after 
- * printing the error message. 
- * 
- * This default implementation is not very useful,  
- * but does not assume anything about your environment.  
- * It will at least let you know something is wrong.... 
- * I didn't want to include any libraries to print and error or so, 
- * as this makes the code much harder to integrate in a project. 
- * 
- * Note that the Twofish_fatal function may not return to the caller. 
- * Unfortunately this is not something the self-test can test for, 
- * so you have to make sure of this yourself. 
- * 
- * If you want to call an external function, be careful about including 
- * your own header files here. This code uses a lot of macros, and your 
- * header file could easily break it. Maybe the best solution is to use 
- * a separate extern statement for your fatal function. 
- */ 
-/* #define Twofish_fatal(pmsgx) { fprintf(stderr, pmsgx); exit(1); } */
-#define Twofish_fatal(pmsgx, code) { return(code); } 
- 
- 
-/* 
- * The rest of the settings are not important for the functionality 
- * of this Twofish implementation. That is, their default settings 
- * work on all platforms. You can change them to improve the  
- * speed of the implementation on your platform. Erroneous settings 
- * will result in erroneous implementations, but the self-test should 
- * catch those. 
- */ 
- 
- 
-/*  
- * Macros to rotate a Twofish_UInt32 value left or right by the  
- * specified number of bits. This should be a 32-bit rotation,  
- * and not rotation of, say, 64-bit values. 
- * 
- * Every encryption or decryption operation uses 32 of these rotations, 
- * so it is a good idea to make these macros efficient. 
- * 
- * This fully portable definition has one piece of tricky stuff. 
- * The UInt32 might be larger than 32 bits, so we have to mask 
- * any higher bits off. The simplest way to do this is to 'and' the 
- * value first with 0xffffffff and then shift it right. An optimising 
- * compiler that has a 32-bit type can optimise this 'and' away. 
- *  
- * Unfortunately there is no portable way of writing the constant 
- * 0xffffffff. You don't know which suffix to use (U, or UL?) 
- * The UINT32_MASK definition uses a bit of trickery. Shift-left 
- * is only defined if the shift amount is strictly less than the size 
- * of the UInt32, so we can't use (1<<32). The answer it to take the value 
- * 2, cast it to a UInt32, shift it left 31 positions, and subtract one. 
- * Another example of how to make something very simple extremely difficult. 
- * I hate C. 
- *  
- * The rotation macros are straightforward. 
- * They are only applied to UInt32 values, which are _unsigned_ 
- * so the >> operator must do a logical shift that brings in zeroes. 
- * On most platforms you will only need to optimise the ROL32 macro; the 
- * ROR32 macro is not inefficient on an optimising compiler as all rotation 
- * amounts in this code are known at compile time. 
- * 
- * On many platforms there is a faster solution. 
- * For example, MS compilers have the __rotl and __rotr functions 
- * that generate x86 rotation instructions. 
- */ 
-#define UINT32_MASK    ( (((Twofish_UInt32)2)<<31) - 1 ) 
- 
-#ifndef _MSC_VER 
-#define ROL32(x,n) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) ) 
-#define ROR32(x,n) ( (x)>>(n) | ((x) & UINT32_MASK) << (32-(n)) ) 
-#else 
-#define ROL32(x,n) (_lrotl((x), (n))) 
-#define ROR32(x,n) (_lrotr((x), (n))) 
-#endif 
- 
-/* 
- * Select data type for q-table entries.  
- * 
- * Larger entry types cost more memory (1.5 kB), and might be faster  
- * or slower depending on the CPU and compiler details. 
- * 
- * This choice only affects the static data size and the key setup speed. 
- * Functionality, expanded key size, or encryption speed are not affected. 
- * Define to 1 to get large q-table entries. 
- */ 
-#define LARGE_Q_TABLE   0    /* default = 0 */ 
- 
- 
-/* 
- * Method to select a single byte from a UInt32. 
- * WARNING: non-portable code if set; might not work on all platforms. 
- * 
- * Inside the inner loop of Twofish it is necessary to access the 4  
- * individual bytes of a UInt32. This can be done using either shifts 
- * and masks, or memory accesses. 
- * 
- * Set to 0 to use shift and mask operations for the byte selection. 
- * This is more ALU intensive. It is also fully portable.  
- *  
- * Set to 1 to use memory accesses. The UInt32 is stored in memory and 
- * the individual bytes are read from memory one at a time. 
- * This solution is more memory-intensive, and not fully portable. 
- * It might be faster on your platform, or not. If you use this option, 
- * make sure you set the CPU_IS_BIG_ENDIAN flag appropriately. 
- *  
- * This macro does not affect the conversion of the inputs and outputs 
- * of the cipher. See the CONVERT_USING_CASTS macro for that. 
- */ 
-#define SELECT_BYTE_FROM_UINT32_IN_MEMORY    0    /* default = 0 */ 
- 
- 
-/* 
- * Method used to read the input and write the output. 
- * WARNING: non-portable code if set; might not work on all platforms. 
- * 
- * Twofish operates on 32-bit words. The input to the cipher is 
- * a byte array, as is the output. The portable method of doing the 
- * conversion is a bunch of rotate and mask operations, but on many  
- * platforms it can be done faster using a cast. 
- * This only works if your CPU allows UInt32 accesses to arbitrary Byte 
- * addresses. 
- *  
- * Set to 0 to use the shift and mask operations. This is fully 
- * portable. . 
- * 
- * Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a 
- * UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN  
- * macro) the byte order in the UInt32 is swapped. The reverse is done 
- * to write the output of the encryption/decryption. Make sure you set 
- * the CPU_IS_BIG_ENDIAN flag appropriately. 
- * This option does not work unless a UInt32 is exactly 32 bits. 
- * 
- * This macro only changes the reading/writing of the plaintext/ciphertext. 
- * See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which 
- * a UInt32 is split into 4 bytes for the S-box selection. 
- */ 
-#define CONVERT_USING_CASTS    0    /* default = 0 */ 
- 
- 
-/*  
- * Endianness switch. 
- * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or 
- * CONVERT_USING_CASTS is set. 
- * 
- * Set to 1 on a big-endian machine, and to 0 on a little-endian machine.  
- * Twofish uses the little-endian convention (least significant byte first) 
- * and big-endian machines (using most significant byte first)  
- * have to do a few conversions.  
- * 
- * CAUTION: This code has never been tested on a big-endian machine,  
- * because I don't have access to one. Feedback appreciated. 
- */ 
-#define CPU_IS_BIG_ENDIAN    0 
- 
- 
-/*  
- * Macro to reverse the order of the bytes in a UInt32. 
- * Used to convert to little-endian on big-endian machines. 
- * This macro is always tested, but only used in the encryption and 
- * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN 
- * are both set. In other words: this macro is only speed-critical if 
- * both these flags have been set. 
- * 
- * This default definition of SWAP works, but on many platforms there is a  
- * more efficient implementation.  
- */ 
-#define BSWAP(x) ((ROL32((x),8)&0x00ff00ff) | (ROR32((x),8) & 0xff00ff00)) 
- 
- 
-/* 
- * END OF PLATFORM FIXES 
- * ===================== 
- *  
- * You should not have to touch the rest of this file. 
- */ 
- 
- 
-/* 
- * Convert the external type names to some that are easier to use inside 
- * this file. I didn't want to use the names Byte and UInt32 in the 
- * header file, because many programs already define them and using two 
- * conventions at once can be very difficult. 
- * Don't change these definitions! Change the originals  
- * in twofish.h instead.  
- */ 
-/* A Byte must be an unsigned integer, 8 bits long. */ 
-/* typedef Twofish_Byte    Byte; */
-/* A UInt32 must be an unsigned integer at least 32 bits long. */ 
-/* typedef Twofish_UInt32  UInt32; */
- 
- 
-/*  
- * Define a macro ENDIAN_CONVERT. 
- * 
- * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian 
- * machines, and is the identity function on little-endian machines. 
- * The code then uses this macro without considering the endianness. 
- */ 
- 
-#if CPU_IS_BIG_ENDIAN 
-#define ENDIAN_CONVERT(x)    BSWAP(x) 
-#else 
-#define ENDIAN_CONVERT(x)    (x) 
-#endif 
- 
- 
-/*  
- * Compute byte offset within a UInt32 stored in memory. 
- * 
- * This is only used when SELECT_BYTE_FROM_UINT32_IN_MEMORY is set. 
- *  
- * The input is the byte number 0..3, 0 for least significant. 
- * Note the use of sizeof() to support UInt32 types that are larger 
- * than 4 bytes. 
- */ 
-#if CPU_IS_BIG_ENDIAN 
-#define BYTE_OFFSET( n )  (sizeof(Twofish_UInt32) - 1 - (n) ) 
-#else 
-#define BYTE_OFFSET( n )  (n) 
-#endif 
- 
- 
-/* 
- * Macro to get Byte no. b from UInt32 value X. 
- * We use two different definition, depending on the settings. 
- */ 
-#if SELECT_BYTE_FROM_UINT32_IN_MEMORY 
-    /* Pick the byte from the memory in which X is stored. */ 
-#define SELECT_BYTE( X, b ) (((Twofish_Byte *)(&(X)))[BYTE_OFFSET(b)]) 
-#else 
-    /* Portable solution: Pick the byte directly from the X value. */ 
-#define SELECT_BYTE( X, b ) (((X) >> (8*(b))) & 0xff) 
-#endif 
- 
- 
-/* Some shorthands because we use byte selection in large formulae. */ 
-#define b0(X)   SELECT_BYTE((X),0) 
-#define b1(X)   SELECT_BYTE((X),1) 
-#define b2(X)   SELECT_BYTE((X),2) 
-#define b3(X)   SELECT_BYTE((X),3) 
- 
- 
-/* 
- * We need macros to load and store UInt32 from/to byte arrays 
- * using the least-significant-byte-first convention. 
- * 
- * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to 
- * by p. 
- * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form. 
- */ 
-#if CONVERT_USING_CASTS 
- 
-    /* Get UInt32 from four bytes pointed to by p. */ 
-#define GET32( p )    ENDIAN_CONVERT( *((Twofish_UInt32 *)(p)) ) 
-    /* Put UInt32 into four bytes pointed to by p */ 
-#define PUT32( v, p ) *((Twofish_UInt32 *)(p)) = ENDIAN_CONVERT(v) 
- 
-#else 
- 
-    /* Get UInt32 from four bytes pointed to by p. */ 
-#define GET32( p ) \
-    ( \
-      (Twofish_UInt32)((p)[0])     \
-    | (Twofish_UInt32)((p)[1])<< 8 \
-    | (Twofish_UInt32)((p)[2])<<16 \
-    | (Twofish_UInt32)((p)[3])<<24 \
-    ) 
-    /* Put UInt32 into four bytes pointed to by p */ 
-#define PUT32( v, p ) \
-    (p)[0] = (Twofish_Byte)(((v)      ) & 0xff); \
-    (p)[1] = (Twofish_Byte)(((v) >>  8) & 0xff); \
-    (p)[2] = (Twofish_Byte)(((v) >> 16) & 0xff); \
-    (p)[3] = (Twofish_Byte)(((v) >> 24) & 0xff)
- 
-#endif 
-
-#ifdef ANDROID
-/**
- * Dummy function to disable some compiler optimizations.
- * 
- * See comment in Twofish_cfb128_encrypt().
- */
-void Two_debugDummy(Twofish_Byte* in, Twofish_Byte* out, Twofish_Byte* ivec)
-{
-}
-#endif
-/* 
- * Test the platform-specific macros. 
- * This function tests the macros defined so far to make sure the  
- * definitions are appropriate for this platform. 
- * If you make any mistake in the platform configuration, this should detect 
- * that and inform you what went wrong. 
- * Somewhere, someday, this is going to save somebody a lot of time, 
- * because misbehaving macros are hard to debug. 
- */ 
-static int test_platform() 
-    { 
-    /* Buffer with test values. */ 
-    Twofish_Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0}; 
-    Twofish_UInt32 C; 
-    Twofish_UInt32 x,y; 
-    int i; 
- 
-    /*  
-     * Some sanity checks on the types that can't be done in compile time.  
-     * A smart compiler will just optimise these tests away. 
-     * The pre-processor doesn't understand different types, so we cannot 
-     * do these checks in compile-time. 
-     * 
-     * I hate C. 
-     * 
-     * The first check in each case is to make sure the size is correct. 
-     * The second check is to ensure that it is an unsigned type. 
-     */ 
-    if( ((Twofish_UInt32)((Twofish_UInt32)1 << 31) == 0) || ((Twofish_UInt32)-1 < 0 ))  
-        { 
-	  Twofish_fatal( "Twofish code: Twofish_UInt32 type not suitable", ERR_UINT32 ); 
-        } 
-    if( (sizeof( Twofish_Byte ) != 1) || (((Twofish_Byte)-1) < 0) )  
-        { 
-	  Twofish_fatal( "Twofish code: Twofish_Byte type not suitable", ERR_BYTE ); 
-        } 
- 
-    /*  
-     * Sanity-check the endianness conversions.  
-     * This is just an aid to find problems. If you do the endianness 
-     * conversion macros wrong you will fail the full cipher test, 
-     * but that does not help you find the error. 
-     * Always make it easy to find the bugs!  
-     * 
-     * Detail: There is no fully portable way of writing UInt32 constants, 
-     * as you don't know whether to use the U or UL suffix. Using only U you 
-     * might only be allowed 16-bit constants. Using UL you might get 64-bit 
-     * constants which cannot be stored in a UInt32 without warnings, and 
-     * which generally behave subtly different from a true UInt32. 
-     * As long as we're just comparing with the constant,  
-     * we can always use the UL suffix and at worst lose some efficiency.  
-     * I use a separate '32-bit constant' macro in most of my other code. 
-     * 
-     * I hate C. 
-     * 
-     * Start with testing GET32. We test it on all positions modulo 4  
-     * to make sure we can handly any position of inputs. (Some CPUs 
-     * do not allow non-aligned accesses which we would do if you used 
-     * the CONVERT_USING_CASTS option. 
-     */ 
-    if( (GET32( buf ) != 0x78563412UL) || (GET32(buf+1) != 0x9a785634UL)  
-        || (GET32( buf+2 ) != 0xbc9a7856UL) || (GET32(buf+3) != 0xdebc9a78UL) ) 
-        { 
-	  Twofish_fatal( "Twofish code: GET32 not implemented properly", ERR_GET32 ); 
-        } 
- 
-    /*  
-     * We can now use GET32 to test PUT32. 
-     * We don't test the shifted versions. If GET32 can do that then 
-     * so should PUT32. 
-     */ 
-    C = GET32( buf ); 
-    PUT32( 3*C, buf ); 
-    if( GET32( buf ) != 0x69029c36UL ) 
-        { 
-	  Twofish_fatal( "Twofish code: PUT32 not implemented properly", ERR_PUT32 ); 
-        } 
- 
- 
-    /* Test ROL and ROR */ 
-    for( i=1; i<32; i++ )  
-        { 
-        /* Just a simple test. */ 
-        x = ROR32( C, i ); 
-        y = ROL32( C, i ); 
-        x ^= (C>>i) ^ (C<<(32-i)); 
-        /*y ^= (C<>(32-i));  */
-        y ^= (C<<i) ^ (C>>(32-i));
-        x |= y; 
-        /*  
-         * Now all we check is that x is zero in the least significant 
-         * 32 bits. Using the UL suffix is safe here, as it doesn't matter 
-         * if we get a larger type. 
-         */ 
-	if( (x & 0xffffffffUL) != 0 ) 
-            { 
-	      Twofish_fatal( "Twofish ROL or ROR not properly defined.", ERR_ROLR ); 
-            } 
-        } 
- 
-    /* Test the BSWAP macro */ 
-    if( BSWAP(C) != 0x12345678UL ) 
-        { 
-        /* 
-         * The BSWAP macro should always work, even if you are not using it. 
-         * A smart optimising compiler will just remove this entire test. 
-         */ 
-	  Twofish_fatal( "BSWAP not properly defined.", ERR_BSWAP ); 
-        } 
- 
-    /* And we can test the b macros which use SELECT_BYTE. */ 
-    if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) ) 
-        { 
-        /* 
-         * There are many reasons why this could fail. 
-         * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value.  
-         */ 
-	  Twofish_fatal( "Twofish code: SELECT_BYTE not implemented properly", ERR_SELECTB ); 
-        }
-    return SUCCESS;
-    } 
- 
- 
-/* 
- * Finally, we can start on the Twofish-related code. 
- * You really need the Twofish specifications to understand this code. The 
- * best source is the Twofish book: 
- *     "The Twofish Encryption Algorithm", by Bruce Schneier, John Kelsey, 
- *     Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson. 
- * you can also use the AES submission document of Twofish, which is  
- * available from my list of publications on my personal web site at  
- *    http://niels.ferguson.net/. 
- * 
- * The first thing we do is write the testing routines. This is what the  
- * implementation has to satisfy in the end. We only test the external 
- * behaviour of the implementation of course. 
- */ 
- 
- 
-/* 
- * Perform a single self test on a (plaintext,ciphertext,key) triple. 
- * Arguments: 
- *  key     array of key bytes 
- *  key_len length of key in bytes 
- *  p       plaintext 
- *  c       ciphertext 
- */ 
-static int test_vector( Twofish_Byte key[], int key_len, Twofish_Byte p[16], Twofish_Byte c[16] ) 
-    { 
-    Twofish_Byte tmp[16];               /* scratch pad. */ 
-    Twofish_key xkey;           /* The expanded key */ 
-    int i; 
- 
- 
-    /* Prepare the key */ 
-    if ((i = Twofish_prepare_key( key, key_len, &xkey)) < 0)
-	return i; 
- 
-    /*  
-     * We run the test twice to ensure that the xkey structure 
-     * is not damaged by the first encryption.  
-     * Those are hideous bugs to find if you get them in an application. 
-     */ 
-    for( i=0; i<2; i++ )  
-        { 
-        /* Encrypt and test */ 
-        Twofish_encrypt( &xkey, p, tmp ); 
-        if( memcmp( c, tmp, 16 ) != 0 )  
-            { 
-	      Twofish_fatal( "Twofish encryption failure", ERR_TEST_ENC ); 
-            } 
- 
-        /* Decrypt and test */ 
-        Twofish_decrypt( &xkey, c, tmp ); 
-        if( memcmp( p, tmp, 16 ) != 0 )  
-            { 
-	      Twofish_fatal( "Twofish decryption failure", ERR_TEST_DEC ); 
-            } 
-        } 
- 
-    /* The test keys are not secret, so we don't need to wipe xkey. */
-    return SUCCESS;
-    }
- 
- 
-/* 
- * Check implementation using three (key,plaintext,ciphertext) 
- * test vectors, one for each major key length. 
- *  
- * This is an absolutely minimal self-test.  
- * This routine does not test odd-sized keys. 
- */ 
-static int test_vectors() 
-    { 
-    /* 
-     * We run three tests, one for each major key length. 
-     * These test vectors come from the Twofish specification. 
-     * One encryption and one decryption using randomish data and key 
-     * will detect almost any error, especially since we generate the 
-     * tables ourselves, so we don't have the problem of a single 
-     * damaged table entry in the source. 
-     */ 
- 
-    /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */ 
-    static Twofish_Byte k128[] = { 
-        0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,  
-        0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A, 
-        }; 
-    static Twofish_Byte p128[] = { 
-        0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,  
-        0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 
-        }; 
-    static Twofish_Byte c128[] = { 
-        0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,  
-        0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 
-        }; 
- 
-    /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */ 
-    static Twofish_Byte k192[] = { 
-        0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,  
-        0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,  
-        0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 
-        }; 
-    static Twofish_Byte p192[] = { 
-        0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 
-        0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 
-        }; 
-    static Twofish_Byte c192[] = { 
-        0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 
-        0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 
-        }; 
- 
-    /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */ 
-    static Twofish_Byte k256[] = { 
-        0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,  
-        0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 
-        0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 
-        0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F 
-        }; 
-    static Twofish_Byte p256[] = { 
-        0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 
-        0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 
-        }; 
-    static Twofish_Byte c256[] = { 
-        0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 
-        0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA 
-        }; 
-
-    int ret;
-
-    /* Run the actual tests. */ 
-    if ((ret = test_vector( k128, 16, p128, c128 )) < 0)
-      return ret; 
-    if ((ret = test_vector( k192, 24, p192, c192 )) < 0)
-      return ret; 
-    if ((ret = test_vector( k256, 32, p256, c256 )) < 0)
-      return ret;
-    return SUCCESS;
-    }    
- 
- 
-/* 
- * Perform extensive test for a single key size. 
- *  
- * Test a single key size against the test vectors from section 
- * B.2 in the Twofish book. This is a sequence of 49 encryptions 
- * and decryptions. Each plaintext is equal to the ciphertext of 
- * the previous encryption. The key is made up from the ciphertext 
- * two and three encryptions ago. Both plaintext and key start 
- * at the zero value.  
- * We should have designed a cleaner recurrence relation for 
- * these tests, but it is too late for that now. At least we learned 
- * how to do it better next time. 
- * For details see appendix B of the book. 
- * 
- * Arguments: 
- * key_len      Number of bytes of key 
- * final_value  Final plaintext value after 49 iterations 
- */ 
-static int test_sequence( int key_len, Twofish_Byte final_value[] ) 
-    { 
-    Twofish_Byte buf[ (50+3)*16 ];      /* Buffer to hold our computation values. */ 
-    Twofish_Byte tmp[16];               /* Temp for testing the decryption. */ 
-    Twofish_key xkey;           /* The expanded key */ 
-    int i, ret;
-    Twofish_Byte * p; 
- 
-    /* Wipe the buffer */ 
-    memset( buf, 0, sizeof( buf ) ); 
- 
-    /* 
-     * Because the recurrence relation is done in an inconvenient manner 
-     * we end up looping backwards over the buffer. 
-     */ 
- 
-    /* Pointer in buffer points to current plaintext. */ 
-    p = &buf[50*16]; 
-    for( i=1; i<50; i++ ) 
-        { 
-        /*  
-         * Prepare a key. 
-         * This automatically checks that key_len is valid. 
-         */ 
-	  if ((ret = Twofish_prepare_key( p+16, key_len, &xkey)) < 0)
-	    return ret; 
- 
-        /* Compute the next 16 bytes in the buffer */ 
-        Twofish_encrypt( &xkey, p, p-16 ); 
- 
-        /* Check that the decryption is correct. */ 
-        Twofish_decrypt( &xkey, p-16, tmp ); 
-        if( memcmp( tmp, p, 16 ) != 0 ) 
-            { 
-	      Twofish_fatal( "Twofish decryption failure in sequence", ERR_SEQ_DEC ); 
-            } 
-        /* Move on to next 16 bytes in the buffer. */ 
-        p -= 16; 
-        } 
- 
-    /* And check the final value. */ 
-    if( memcmp( p, final_value, 16 ) != 0 )  
-        { 
-	  Twofish_fatal( "Twofish encryption failure in sequence", ERR_SEQ_ENC ); 
-        } 
- 
-    /* None of the data was secret, so there is no need to wipe anything. */
-    return SUCCESS;
-    } 
- 
- 
-/*  
- * Run all three sequence tests from the Twofish test vectors.  
- * 
- * This checks the most extensive test vectors currently available  
- * for Twofish. The data is from the Twofish book, appendix B.2. 
- */ 
-static int test_sequences() 
-    { 
-    static Twofish_Byte r128[] = { 
-        0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57, 
-        0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0 
-        }; 
-    static Twofish_Byte r192[] = { 
-        0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4, 
-        0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41 
-        }; 
-    static Twofish_Byte r256[] = { 
-        0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75, 
-        0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05 
-        }; 
- 
-    /* Run the three sequence test vectors */
-    int ret;
-    if ((ret = test_sequence( 16, r128)) < 0)
-      return ret; 
-    if ((ret = test_sequence( 24, r192)) < 0)
-      return ret; 
-    if ((ret = test_sequence( 32, r256)) < 0)
-      return ret;
-    return SUCCESS;
-    } 
- 
- 
-/* 
- * Test the odd-sized keys. 
- * 
- * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits. 
- * The equivalent key is found by padding at the end with zero bytes 
- * until a regular key size is reached. 
- * 
- * We just test that the key expansion routine behaves properly. 
- * If the expanded keys are identical, then the encryptions and decryptions 
- * will behave the same. 
- */ 
-static int test_odd_sized_keys() 
-    { 
-    Twofish_Byte buf[32]; 
-    Twofish_key xkey; 
-    Twofish_key xkey_two; 
-    int i, ret;
- 
-    /*  
-     * We first create an all-zero key to use as PRNG key.  
-     * Normally we would not have to fill the buffer with zeroes, as we could 
-     * just pass a zero key length to the Twofish_prepare_key function. 
-     * However, this relies on using odd-sized keys, and those are just the 
-     * ones we are testing here. We can't use an untested function to test  
-     * itself.  
-     */ 
-    memset( buf, 0, sizeof( buf ) ); 
-    if ((ret = Twofish_prepare_key( buf, 16, &xkey)) < 0)
-      return ret; 
- 
-    /* Fill buffer with pseudo-random data derived from two encryptions */ 
-    Twofish_encrypt( &xkey, buf, buf ); 
-    Twofish_encrypt( &xkey, buf, buf+16 ); 
- 
-    /* Create all possible shorter keys that are prefixes of the buffer. */ 
-    for( i=31; i>=0; i-- ) 
-        { 
-        /* Set a byte to zero. This is the new padding byte */ 
-        buf[i] = 0; 
- 
-        /* Expand the key with only i bytes of length */ 
-        if ((ret = Twofish_prepare_key( buf, i, &xkey)) < 0)
-	  return ret; 
- 
-        /* Expand the corresponding padded key of regular length */ 
-        if ((ret = Twofish_prepare_key( buf, i<=16 ? 16 : (i<= 24 ? 24 : 32), &xkey_two )) < 0)
-	  return ret; 
- 
-        /* Compare the two */ 
-        if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 ) 
-            { 
-	      Twofish_fatal( "Odd sized keys do not expand properly", ERR_ODD_KEY ); 
-            } 
-        } 
- 
-    /* None of the key values are secret, so we don't need to wipe them. */
-    return SUCCESS;
-    } 
- 
- 
-/* 
- * Test the Twofish implementation. 
- * 
- * This routine runs all the self tests, in order of importance. 
- * It is called by the Twofish_initialise routine. 
- *  
- * In almost all applications the cost of running the self tests during 
- * initialisation is insignificant, especially 
- * compared to the time it takes to load the application from disk.  
- * If you are very pressed for initialisation performance,  
- * you could remove some of the tests. Make sure you did run them 
- * once in the software and hardware configuration you are using. 
- */ 
-static int self_test() 
-    {
-      int ret;
-    /* The three test vectors form an absolute minimal test set. */ 
-      if ((ret = test_vectors()) < 0)
-	return ret;
- 
-    /*  
-     * If at all possible you should run these tests too. They take 
-     * more time, but provide a more thorough coverage. 
-     */ 
-      if ((ret = test_sequences()) < 0)
-	return ret;
- 
-    /* Test the odd-sized keys. */ 
-      if ((ret = test_odd_sized_keys()) < 0)
-	return ret;
-      return SUCCESS;
-    } 
- 
- 
-/* 
- * And now, the actual Twofish implementation. 
- * 
- * This implementation generates all the tables during initialisation.  
- * I don't like large tables in the code, especially since they are easily  
- * damaged in the source without anyone noticing it. You need code to  
- * generate them anyway, and this way all the code is close together. 
- * Generating them in the application leads to a smaller executable  
- * (the code is smaller than the tables it generates) and a  
- * larger static memory footprint. 
- * 
- * Twofish can be implemented in many ways. I have chosen to  
- * use large tables with a relatively long key setup time. 
- * If you encrypt more than a few blocks of data it pays to pre-compute  
- * as much as possible. This implementation is relatively inefficient for  
- * applications that need to re-key every block or so. 
- */ 
- 
-/*  
- * We start with the t-tables, directly from the Twofish definition.  
- * These are nibble-tables, but merging them and putting them two nibbles  
- * in one byte is more work than it is worth. 
- */ 
-static Twofish_Byte t_table[2][4][16] = { 
-    { 
-        {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4}, 
-        {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD}, 
-        {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1}, 
-        {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA} 
-    }, 
-    { 
-        {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5}, 
-        {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8}, 
-        {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF}, 
-        {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA} 
-    } 
-}; 
- 
- 
-/* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */ 
-#define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) ) 
- 
-/* 
- * The q-boxes are only used during the key schedule computations.  
- * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit  
- * lookup tables as it is faster to load a 32-bit value than to load an  
- * 8-bit value and zero the rest of the register. 
- * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in  
- * the q-tables. Here we just define the Qtype which is used to store  
- * the entries of the q-tables. 
- */ 
-#if LARGE_Q_TABLE 
-typedef Twofish_UInt32      Qtype; 
-#else 
-typedef Twofish_Byte        Qtype; 
-#endif 
- 
-/*  
- * The actual q-box tables.  
- * There are two q-boxes, each having 256 entries. 
- */ 
-static Qtype q_table[2][256]; 
- 
- 
-/* 
- * Now the function that converts a single t-table into a q-table. 
- * 
- * Arguments: 
- * t[4][16] : four 4->4bit lookup tables that define the q-box 
- * q[256]   : output parameter: the resulting q-box as a lookup table. 
- */ 
-static void make_q_table( Twofish_Byte t[4][16], Qtype q[256] ) 
-    { 
-    int ae,be,ao,bo;        /* Some temporaries. */ 
-    int i; 
-    /* Loop over all input values and compute the q-box result. */ 
-    for( i=0; i<256; i++ ) { 
-        /*  
-         * This is straight from the Twofish specifications.  
-         *  
-         * The ae variable is used for the a_i values from the specs 
-         * with even i, and ao for the odd i's. Similarly for the b's. 
-         */ 
-        ae = i>>4; be = i&0xf; 
-        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); 
-        ae = t[0][ao]; be = t[1][bo]; 
-        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); 
-        ae = t[2][ao]; be = t[3][bo]; 
- 
-        /* Store the result in the q-box table, the cast avoids a warning. */ 
-        q[i] = (Qtype) ((be<<4) | ae); 
-        } 
-    } 
- 
- 
-/*  
- * Initialise both q-box tables.  
- */ 
-static void initialise_q_boxes() { 
-    /* Initialise each of the q-boxes using the t-tables */ 
-    make_q_table( t_table[0], q_table[0] ); 
-    make_q_table( t_table[1], q_table[1] ); 
-    } 
- 
- 
-/* 
- * Next up is the MDS matrix multiplication. 
- * The MDS matrix multiplication operates in the field 
- * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1. 
- * If you don't understand this, read a book on finite fields. You cannot 
- * follow the finite-field computations without some background. 
- *  
- * In this field, multiplication by x is easy: shift left one bit  
- * and if bit 8 is set then xor the result with 0x169.  
- * 
- * The MDS coefficients use a multiplication by 1/x, 
- * or rather a division by x. This is easy too: first make the 
- * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary,  
- * and then shift right one position.  
- * Even easier: shift right and xor with 0xb4 if the lsbit was set. 
- * 
- * The MDS coefficients are 1, EF, and 5B, and we use the fact that 
- *   EF = 1 + 1/x + 1/x^2 
- *   5B = 1       + 1/x^2 
- * in this field. This makes multiplication by EF and 5B relatively easy. 
- * 
- * This property is no accident, the MDS matrix was designed to allow 
- * this implementation technique to be used. 
- * 
- * We have four MDS tables, each mapping 8 bits to 32 bits. 
- * Each table performs one column of the matrix multiplication.  
- * As the MDS is always preceded by q-boxes, each of these tables 
- * also implements the q-box just previous to that column. 
- */ 
- 
-/* The actual MDS tables. */ 
-static Twofish_UInt32 MDS_table[4][256]; 
- 
-/* A small table to get easy conditional access to the 0xb4 constant. */ 
-static Twofish_UInt32 mds_poly_divx_const[] = {0,0xb4}; 
- 
-/* Function to initialise the MDS tables. */ 
-static void initialise_mds_tables() 
-    { 
-    int i; 
-    Twofish_UInt32 q,qef,q5b;       /* Temporary variables. */ 
- 
-    /* Loop over all 8-bit input values */ 
-    for( i=0; i<256; i++ )  
-        { 
-        /*  
-         * To save some work during the key expansion we include the last 
-         * of the q-box layers from the h() function in these MDS tables. 
-         */ 
- 
-        /* We first do the inputs that are mapped through the q0 table. */ 
-        q = q_table[0][i]; 
-        /* 
-         * Here we divide by x, note the table to get 0xb4 only if the  
-         * lsbit is set.  
-         * This sets qef = (1/x)*q in the finite field 
-         */ 
-        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; 
-        /* 
-         * Divide by x again, and add q to get (1+1/x^2)*q.  
-         * Note that (1+1/x^2) =  5B in the field, and addition in the field 
-         * is exclusive or on the bits. 
-         */ 
-        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; 
-        /*  
-         * Add q5b to qef to set qef = (1+1/x+1/x^2)*q. 
-         * Again, (1+1/x+1/x^2) = EF in the field. 
-         */ 
-        qef ^= q5b; 
- 
-        /*  
-         * Now that we have q5b = 5B * q and qef = EF * q  
-         * we can fill two of the entries in the MDS matrix table.  
-         * See the Twofish specifications for the order of the constants. 
-         */ 
-        MDS_table[1][i] = (q  <<24) | (q5b<<16) | (qef<<8) | qef; 
-        MDS_table[3][i] = (q5b<<24) | (qef<<16) | (q  <<8) | q5b; 
- 
-        /* Now we do it all again for the two columns that have a q1 box. */ 
-        q = q_table[1][i]; 
-        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; 
-        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; 
-        qef ^= q5b; 
- 
-        /* The other two columns use the coefficient in a different order. */ 
-        MDS_table[0][i] = (qef<<24) | (qef<<16) | (q5b<<8) | q  ; 
-        MDS_table[2][i] = (qef<<24) | (q  <<16) | (qef<<8) | q5b; 
-        } 
-    } 
- 
- 
-/* 
- * The h() function is the heart of the Twofish cipher.  
- * It is a complicated sequence of q-box lookups, key material xors,  
- * and finally the MDS matrix. 
- * We use lots of macros to make this reasonably fast. 
- */ 
- 
-/* First a shorthand for the two q-tables */ 
-#define q0  q_table[0] 
-#define q1  q_table[1] 
- 
-/* 
- * Each macro computes one column of the h for either 2, 3, or 4 stages. 
- * As there are 4 columns, we have 12 macros in all. 
- *  
- * The key bytes are stored in the Byte array L at offset  
- * 0,1,2,3,  8,9,10,11,  [16,17,18,19,   [24,25,26,27]] as this is the 
- * order we get the bytes from the user. If you look at the Twofish  
- * specs, you'll see that h() is applied to the even key words or the 
- * odd key words. The bytes of the even words appear in this spacing, 
- * and those of the odd key words too. 
- * 
- * These macros are the only place where the q-boxes and the MDS table 
- * are used. 
- */ 
-#define H02( y, L )  MDS_table[0][q0[q0[y]^L[ 8]]^L[0]] 
-#define H12( y, L )  MDS_table[1][q0[q1[y]^L[ 9]]^L[1]] 
-#define H22( y, L )  MDS_table[2][q1[q0[y]^L[10]]^L[2]] 
-#define H32( y, L )  MDS_table[3][q1[q1[y]^L[11]]^L[3]] 
-#define H03( y, L )  H02( q1[y]^L[16], L ) 
-#define H13( y, L )  H12( q1[y]^L[17], L ) 
-#define H23( y, L )  H22( q0[y]^L[18], L ) 
-#define H33( y, L )  H32( q0[y]^L[19], L ) 
-#define H04( y, L )  H03( q1[y]^L[24], L ) 
-#define H14( y, L )  H13( q0[y]^L[25], L ) 
-#define H24( y, L )  H23( q0[y]^L[26], L ) 
-#define H34( y, L )  H33( q1[y]^L[27], L ) 
- 
-/* 
- * Now we can define the h() function given an array of key bytes.  
- * This function is only used in the key schedule, and not to pre-compute 
- * the keyed S-boxes. 
- * 
- * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24) 
- * so we only provide k as an argument. 
- * 
- * Arguments: 
- * k        input to the h() function. 
- * L        pointer to array of key bytes at  
- *          offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]] 
- * kCycles  # key cycles, 2, 3, or 4. 
- */ 
-static Twofish_UInt32 h( int k, Twofish_Byte L[], int kCycles ) 
-    { 
-    switch( kCycles ) { 
-        /* We code all 3 cases separately for speed reasons. */ 
-    case 2: 
-        return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L); 
-    case 3: 
-        return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L); 
-    case 4: 
-        return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L); 
-    default:  
-        /* This is always a coding error, which is fatal. */ 
-      Twofish_fatal( "Twofish h(): Illegal argument", ERR_ILL_ARG ); 
-      return ERR_ILL_ARG;
-        } 
-    } 
- 
- 
-/* 
- * Pre-compute the keyed S-boxes. 
- * Fill the pre-computed S-box array in the expanded key structure. 
- * Each pre-computed S-box maps 8 bits to 32 bits. 
- * 
- * The S argument contains half the number of bytes of the full key, but is 
- * derived from the full key. (See Twofish specifications for details.) 
- * S has the weird byte input order used by the Hxx macros. 
- * 
- * This function takes most of the time of a key expansion. 
- * 
- * Arguments: 
- * S        pointer to array of 8*kCycles Bytes containing the S vector. 
- * kCycles  number of key words, must be in the set {2,3,4} 
- * xkey     pointer to Twofish_key structure that will contain the S-boxes. 
- */ 
-static int fill_keyed_sboxes( Twofish_Byte S[], int kCycles, Twofish_key * xkey ) 
-    { 
-    int i; 
-    switch( kCycles ) { 
-        /* We code all 3 cases separately for speed reasons. */ 
-    case 2: 
-        for( i=0; i<256; i++ ) 
-            { 
-            xkey->s[0][i]= H02( i, S ); 
-            xkey->s[1][i]= H12( i, S ); 
-            xkey->s[2][i]= H22( i, S ); 
-            xkey->s[3][i]= H32( i, S ); 
-            } 
-        break; 
-    case 3: 
-        for( i=0; i<256; i++ ) 
-            { 
-            xkey->s[0][i]= H03( i, S ); 
-            xkey->s[1][i]= H13( i, S ); 
-            xkey->s[2][i]= H23( i, S ); 
-            xkey->s[3][i]= H33( i, S ); 
-            } 
-        break; 
-    case 4: 
-        for( i=0; i<256; i++ ) 
-            { 
-            xkey->s[0][i]= H04( i, S ); 
-            xkey->s[1][i]= H14( i, S ); 
-            xkey->s[2][i]= H24( i, S ); 
-            xkey->s[3][i]= H34( i, S ); 
-            } 
-        break; 
-    default:  
-        /* This is always a coding error, which is fatal. */ 
-      Twofish_fatal( "Twofish fill_keyed_sboxes(): Illegal argument", ERR_ILL_ARG ); 
-        }
-    return SUCCESS;
-    }
- 
- 
-/* A flag to keep track of whether we have been initialised or not. */ 
-static int Twofish_initialised = 0; 
- 
-/* 
- * Initialise the Twofish implementation. 
- * This function must be called before any other function in the 
- * Twofish implementation is called. 
- * This routine also does some sanity checks, to make sure that 
- * all the macros behave, and it tests the whole cipher. 
- */ 
-int Twofish_initialise() 
-    {
-      int ret;
-    /* First test the various platform-specific definitions. */ 
-      if ((ret = test_platform()) < 0)
-	return ret;
- 
-    /* We can now generate our tables, in the right order of course. */ 
-    initialise_q_boxes(); 
-    initialise_mds_tables(); 
- 
-    /* We're finished with the initialisation itself. */ 
-    Twofish_initialised = 1; 
- 
-    /*  
-     * And run some tests on the whole cipher.  
-     * Yes, you need to do this every time you start your program.  
-     * It is called assurance; you have to be certain that your program 
-     * still works properly.  
-     */ 
-    return self_test(); 
-    } 
- 
- 
-/* 
- * The Twofish key schedule uses an Reed-Solomon code matrix multiply. 
- * Just like the MDS matrix, the RS-matrix is designed to be easy 
- * to implement. Details are below in the code.  
- * 
- * These constants make it easy to compute in the finite field used  
- * for the RS code. 
- * 
- * We use Bytes for the RS computation, but these are automatically 
- * widened to unsigned integers in the expressions. Having unsigned 
- * ints in these tables therefore provides the fastest access. 
- */ 
-static unsigned int rs_poly_const[] = {0, 0x14d}; 
-static unsigned int rs_poly_div_const[] = {0, 0xa6 }; 
- 
- 
-/* 
- * Prepare a key for use in encryption and decryption. 
- * Like most block ciphers, Twofish allows the key schedule  
- * to be pre-computed given only the key.  
- * Twofish has a fairly 'heavy' key schedule that takes a lot of time  
- * to compute. The main work is pre-computing the S-boxes used in the  
- * encryption and decryption. We feel that this makes the cipher much  
- * harder to attack. The attacker doesn't even know what the S-boxes  
- * contain without including the entire key schedule in the analysis.  
- * 
- * Unlike most Twofish implementations, this one allows any key size from 
- * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the  
- * specifications); the key is simply padded with zeroes to the next real  
- * key size of 16, 24, or 32 bytes. 
- * Each odd-sized key is thus equivalent to a single normal-sized key. 
- * 
- * Arguments: 
- * key      array of key bytes 
- * key_len  number of bytes in the key, must be in the range 0,...,32. 
- * xkey     Pointer to an Twofish_key structure that will be filled  
- *             with the internal form of the cipher key. 
- */ 
-int Twofish_prepare_key( Twofish_Byte key[], int key_len, Twofish_key * xkey ) 
-    { 
-    /* We use a single array to store all key material in,  
-     * to simplify the wiping of the key material at the end. 
-     * The first 32 bytes contain the actual (padded) cipher key. 
-     * The next 32 bytes contain the S-vector in its weird format, 
-     * and we have 4 bytes of overrun necessary for the RS-reduction. 
-     */ 
-    Twofish_Byte K[32+32+4];  
- 
-    int kCycles;        /* # key cycles, 2,3, or 4. */ 
- 
-    int i; 
-    Twofish_UInt32 A, B;        /* Used to compute the round keys. */ 
- 
-    Twofish_Byte * kptr;        /* Three pointers for the RS computation. */ 
-    Twofish_Byte * sptr; 
-    Twofish_Byte * t; 
- 
-    Twofish_Byte b,bx,bxx;      /* Some more temporaries for the RS computation. */ 
- 
-    /* Check that the Twofish implementation was initialised. */ 
-    if( Twofish_initialised == 0 ) 
-        { 
-        /*  
-         * You didn't call Twofish_initialise before calling this routine. 
-         * This is a programming error, and therefore we call the fatal 
-         * routine.  
-         * 
-         * I could of course call the initialisation routine here, 
-         * but there are a few reasons why I don't. First of all, the  
-         * self-tests have to be done at startup. It is no good to inform 
-         * the user that the cipher implementation fails when he wants to 
-         * write his data to disk in encrypted form. You have to warn him 
-         * before he spends time typing his data. Second, the initialisation 
-         * and self test are much slower than a single key expansion. 
-         * Calling the initialisation here makes the performance of the 
-         * cipher unpredictable. This can lead to really weird problems  
-         * if you use the cipher for a real-time task. Suddenly it fails  
-         * once in a while the first time you try to use it. Things like  
-         * that are almost impossible to debug. 
-         */ 
-	  /* Twofish_fatal( "Twofish implementation was not initialised.", ERR_INIT ); */
-         
-        /* 
-         * There is always a danger that the Twofish_fatal routine returns, 
-         * in spite of the specifications that it should not.  
-         * (A good programming rule: don't trust the rest of the code.) 
-         * This would be disasterous. If the q-tables and MDS-tables have 
-         * not been initialised, they are probably still filled with zeroes. 
-         * Suppose the MDS-tables are all zero. The key expansion would then 
-         * generate all-zero round keys, and all-zero s-boxes. The danger 
-         * is that nobody would notice as the encry
-         * mangles the input, and the decryption still 'decrypts' it, 
-         * but now in a completely key-independent manner.  
-         * To stop such security disasters, we use blunt force. 
-         * If your program hangs here: fix the fatal routine! 
-         */ 
-        for(;;);        /* Infinite loop, which beats being insecure. */ 
-        } 
- 
-    /* Check for valid key length. */ 
-    if( key_len < 0 || key_len > 32 ) 
-        { 
-        /*  
-         * This can only happen if a programmer didn't read the limitations 
-         * on the key size.  
-         */ 
-	  Twofish_fatal( "Twofish_prepare_key: illegal key length", ERR_KEY_LEN ); 
-        /*  
-         * A return statement just in case the fatal macro returns. 
-         * The rest of the code assumes that key_len is in range, and would 
-         * buffer-overflow if it wasn't.  
-         * 
-         * Why do we still use a programming language that has problems like 
-         * buffer overflows, when these problems were solved in 1960 with 
-         * the development of Algol? Have we not leared anything? 
-         */ 
-        return ERR_KEY_LEN; 
-        } 
- 
-    /* Pad the key with zeroes to the next suitable key length. */ 
-    memcpy( K, key, key_len ); 
-    memset( K+key_len, 0, sizeof(K)-key_len ); 
- 
-    /*  
-     * Compute kCycles: the number of key cycles used in the cipher.  
-     * 2 for 128-bit keys, 3 for 192-bit keys, and 4 for 256-bit keys. 
-     */ 
-    kCycles = (key_len + 7) >> 3; 
-    /* Handle the special case of very short keys: minimum 2 cycles. */ 
-    if( kCycles < 2 ) 
-        { 
-        kCycles = 2; 
-        } 
- 
-    /*  
-     * From now on we just pretend to have 8*kCycles bytes of  
-     * key material in K. This handles all the key size cases.  
-     */ 
- 
-    /*  
-     * We first compute the 40 expanded key words,  
-     * formulas straight from the Twofish specifications. 
-     */ 
-    for( i=0; i<40; i+=2 ) 
-        { 
-        /*  
-         * Due to the byte spacing expected by the h() function  
-         * we can pick the bytes directly from the key K. 
-         * As we use bytes, we never have the little/big endian 
-         * problem. 
-         * 
-         * Note that we apply the rotation function only to simple 
-         * variables, as the rotation macro might evaluate its argument 
-         * more than once. 
-         */ 
-        A = h( i  , K  , kCycles ); 
-        B = h( i+1, K+4, kCycles ); 
-        B = ROL32( B, 8 ); 
- 
-        /* Compute and store the round keys. */ 
-        A += B; 
-        B += A; 
-        xkey->K[i]   = A; 
-        xkey->K[i+1] = ROL32( B, 9 ); 
-        } 
- 
-    /* Wipe variables that contained key material. */ 
-    A=B=0; 
- 
-    /*  
-     * And now the dreaded RS multiplication that few seem to understand. 
-     * The RS matrix is not random, and is specially designed to compute the 
-     * RS matrix multiplication in a simple way. 
-     * 
-     * We work in the field GF(2)[x]/x^8+x^6+x^3+x^2+1. Note that this is a 
-     * different field than used for the MDS matrix.  
-     * (At least, it is a different representation because all GF(2^8)  
-     * representations are equivalent in some form.) 
-     *  
-     * We take 8 consecutive bytes of the key and interpret them as  
-     * a polynomial k_0 + k_1 y + k_2 y^2 + ... + k_7 y^7 where  
-     * the k_i bytes are the key bytes and are elements of the finite field. 
-     * We multiply this polynomial by y^4 and reduce it modulo 
-     *     y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1.  
-     * using straightforward polynomial modulo reduction. 
-     * The coefficients of the result are the result of the RS 
-     * matrix multiplication. When we wrote the Twofish specification,  
-     * the original RS definition used the polynomials,  
-     * but that requires much more mathematical knowledge.  
-     * We were already using matrix multiplication in a finite field for  
-     * the MDS matrix, so I re-wrote the RS operation as a matrix  
-     * multiplication to reduce the difficulty of understanding it.  
-     * Some implementors have not picked up on this simpler method of 
-     * computing the RS operation, even though it is mentioned in the 
-     * specifications. 
-     * 
-     * It is possible to perform these computations faster by using 32-bit  
-     * word operations, but that is not portable and this is not a speed- 
-     * critical area. 
-     * 
-     * We explained the 1/x computation when we did the MDS matrix.  
-     * 
-     * The S vector is stored in K[32..64]. 
-     * The S vector has to be reversed, so we loop cross-wise. 
-     * 
-     * Note the weird byte spacing of the S-vector, to match the even  
-     * or odd key words arrays. See the discussion at the Hxx macros for 
-     * details. 
-     */ 
-    kptr = K + 8*kCycles;           /* Start at end of key */ 
-    sptr = K + 32;                  /* Start at start of S */ 
- 
-    /* Loop over all key material */ 
-    while( kptr > K )  
-        { 
-        kptr -= 8; 
-        /*  
-         * Initialise the polynimial in sptr[0..12] 
-         * The first four coefficients are 0 as we have to multiply by y^4. 
-         * The next 8 coefficients are from the key material. 
-         */ 
-        memset( sptr, 0, 4 ); 
-        memcpy( sptr+4, kptr, 8 ); 
- 
-        /*  
-         * The 12 bytes starting at sptr are now the coefficients of 
-         * the polynomial we need to reduce. 
-         */ 
- 
-        /* Loop over the polynomial coefficients from high to low */ 
-        t = sptr+11; 
-        /* Keep looping until polynomial is degree 3; */ 
-        while( t > sptr+3 ) 
-            { 
-            /* Pick up the highest coefficient of the poly. */ 
-            b = *t; 
- 
-            /*  
-             * Compute x and (x+1/x) times this coefficient.  
-             * See the MDS matrix implementation for a discussion of  
-             * multiplication by x and 1/x. We just use different  
-             * constants here as we are in a  
-             * different finite field representation. 
-             * 
-             * These two statements set  
-             * bx = (x) * b  
-             * bxx= (x + 1/x) * b 
-             */ 
-            bx = (Twofish_Byte)((b<<1) ^ rs_poly_const[ b>>7 ]); 
-            bxx= (Twofish_Byte)((b>>1) ^ rs_poly_div_const[ b&1 ] ^ bx); 
- 
-            /* 
-             * Subtract suitable multiple of  
-             * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1  
-             * from the polynomial, except that we don't bother 
-             * updating t[0] as it will become zero anyway. 
-             */ 
-            t[-1] ^= bxx; 
-            t[-2] ^= bx; 
-            t[-3] ^= bxx; 
-            t[-4] ^= b; 
-             
-            /* Go to the next coefficient. */ 
-            t--; 
-            } 
- 
-        /* Go to next S-vector word, obeying the weird spacing rules. */ 
-        sptr += 8; 
-        } 
- 
-    /* Wipe variables that contained key material. */ 
-    b = bx = bxx = 0; 
- 
-    /* And finally, we can compute the key-dependent S-boxes. */ 
-    fill_keyed_sboxes( &K[32], kCycles, xkey ); 
- 
-    /* Wipe array that contained key material. */ 
-    memset( K, 0, sizeof( K ) );
-    return SUCCESS;
-    } 
- 
- 
-/* 
- * We can now start on the actual encryption and decryption code. 
- * As these are often speed-critical we will use a lot of macros. 
- */ 
- 
-/* 
- * The g() function is the heart of the round function. 
- * We have two versions of the g() function, one without an input 
- * rotation and one with. 
- * The pre-computed S-boxes make this pretty simple. 
- */ 
-#define g0(X,xkey) \
- (xkey->s[0][b0(X)]^xkey->s[1][b1(X)]^xkey->s[2][b2(X)]^xkey->s[3][b3(X)]) 
- 
-#define g1(X,xkey) \
- (xkey->s[0][b3(X)]^xkey->s[1][b0(X)]^xkey->s[2][b1(X)]^xkey->s[3][b2(X)]) 
- 
-/* 
- * A single round of Twofish. The A,B,C,D are the four state variables, 
- * T0 and T1 are temporaries, xkey is the expanded key, and r the  
- * round number. 
- * 
- * Note that this macro does not implement the swap at the end of the round. 
- */ 
-#define ENCRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \
-    T0 = g0(A,xkey); T1 = g1(B,xkey);\
-    C ^= T0+T1+xkey->K[8+2*(r)]; C = ROR32(C,1);\
-    D = ROL32(D,1); D ^= T0+2*T1+xkey->K[8+2*(r)+1] 
- 
-/* 
- * Encrypt a single cycle, consisting of two rounds. 
- * This avoids the swapping of the two halves.  
- * Parameter r is now the cycle number. 
- */ 
-#define ENCRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \
-    ENCRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)   );\
-    ENCRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)+1 )
- 
-/* Full 16-round encryption */ 
-#define ENCRYPT( A,B,C,D,T0,T1,xkey ) \
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 );\
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\
-    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 )
- 
-/* 
- * A single round of Twofish for decryption. It differs from 
- * ENCRYTP_RND only because of the 1-bit rotations. 
- */ 
-#define DECRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \
-    T0 = g0(A,xkey); T1 = g1(B,xkey);\
-    C = ROL32(C,1); C ^= T0+T1+xkey->K[8+2*(r)];\
-    D ^= T0+2*T1+xkey->K[8+2*(r)+1]; D = ROR32(D,1)
- 
-/* 
- * Decrypt a single cycle, consisting of two rounds.  
- * This avoids the swapping of the two halves.  
- * Parameter r is now the cycle number. 
- */ 
-#define DECRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \
-    DECRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)+1 );\
-    DECRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)   )
- 
-/* Full 16-round decryption. */ 
-#define DECRYPT( A,B,C,D,T0,T1, xkey ) \
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 );\
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\
-    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 ) 
-
-/* 
- * A macro to read the state from the plaintext and do the initial key xors. 
- * The koff argument allows us to use the same macro  
- * for the decryption which uses different key words at the start. 
- */ 
-#define GET_INPUT( src, A,B,C,D, xkey, koff ) \
-    A = GET32(src   )^xkey->K[  koff]; B = GET32(src+ 4)^xkey->K[1+koff]; \
-    C = GET32(src+ 8)^xkey->K[2+koff]; D = GET32(src+12)^xkey->K[3+koff]
- 
-/* 
- * Similar macro to put the ciphertext in the output buffer. 
- * We xor the keys into the state variables before we use the PUT32  
- * macro as the macro might use its argument multiple times. 
- */ 
-#define PUT_OUTPUT( A,B,C,D, dst, xkey, koff ) \
-    A ^= xkey->K[  koff]; B ^= xkey->K[1+koff]; \
-    C ^= xkey->K[2+koff]; D ^= xkey->K[3+koff]; \
-    PUT32( A, dst   ); PUT32( B, dst+ 4 ); \
-    PUT32( C, dst+8 ); PUT32( D, dst+12 )
- 
- 
-/* 
- * Twofish block encryption 
- * 
- * Arguments: 
- * xkey         expanded key array 
- * p            16 bytes of plaintext 
- * c            16 bytes in which to store the ciphertext 
- */ 
-void Twofish_encrypt( Twofish_key * xkey, Twofish_Byte p[16], Twofish_Byte c[16]) 
-    { 
-    Twofish_UInt32 A,B,C,D,T0,T1;       /* Working variables */ 
- 
-    /* Get the four plaintext words xorred with the key */ 
-    GET_INPUT( p, A,B,C,D, xkey, 0 ); 
- 
-    /* Do 8 cycles (= 16 rounds) */ 
-    ENCRYPT( A,B,C,D,T0,T1,xkey ); 
- 
-    /* Store them with the final swap and the output whitening. */ 
-    PUT_OUTPUT( C,D,A,B, c, xkey, 4 ); 
-    } 
- 
- 
-/* 
- * Twofish block decryption. 
- * 
- * Arguments: 
- * xkey         expanded key array 
- * p            16 bytes of plaintext 
- * c            16 bytes in which to store the ciphertext 
- */ 
-void Twofish_decrypt( Twofish_key * xkey, Twofish_Byte c[16], Twofish_Byte p[16]) 
-    { 
-    Twofish_UInt32 A,B,C,D,T0,T1;       /* Working variables */ 
- 
-    /* Get the four plaintext words xorred with the key */ 
-    GET_INPUT( c, A,B,C,D, xkey, 4 ); 
- 
-    /* Do 8 cycles (= 16 rounds) */ 
-    DECRYPT( A,B,C,D,T0,T1,xkey ); 
- 
-    /* Store them with the final swap and the output whitening. */ 
-    PUT_OUTPUT( C,D,A,B, p, xkey, 0 ); 
-    } 
- 
-/* 
- * Using the macros it is easy to make special routines for 
- * CBC mode, CTR mode etc. The only thing you might want to 
- * add is a XOR_PUT_OUTPUT which xors the outputs into the 
- * destinationa instead of overwriting the data. This requires 
- * a XOR_PUT32 macro as well, but that should all be trivial. 
- * 
- * I thought about including routines for the separate cipher 
- * modes here, but it is unclear which modes should be included, 
- * and each encryption or decryption routine takes up a lot of code space. 
- * Also, I don't have any test vectors for any cipher modes 
- * with Twofish. 
- */ 
-
-
+/* 

+ * Fast, portable, and easy-to-use Twofish implementation,  

+ * Version 0.3. 

+ * Copyright (c) 2002 by Niels Ferguson.  

+ * (See further down for the almost-unrestricted licensing terms.) 

+ * 

+ * -------------------------------------------------------------------------- 

+ * There are two files for this implementation: 

+ * - twofish.h, the header file. 

+ * - twofish.c, the code file. 

+ * 

+ * To incorporate this code into your program you should: 

+ * - Check the licensing terms further down in this comment. 

+ * - Fix the two type definitions in twofish.h to suit your platform. 

+ * - Fix a few definitions in twofish.c in the section marked  

+ *   PLATFORM FIXES. There is one important ones that affects  

+ *   functionality, and then a few definitions that you can optimise  

+ *   for efficiency but those have no effect on the functionality.  

+ *   Don't change anything else. 

+ * - Put the code in your project and compile it. 

+ * 

+ * To use this library you should: 

+ * - Call Twofish_initialise() in your program before any other function in 

+ *   this library. 

+ * - Use Twofish_prepare_key(...) to convert a key to internal form. 

+ * - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt 

+ *   data. 

+ * See the comments in the header file for details on these functions. 

+ * -------------------------------------------------------------------------- 

+ *  

+ * There are many Twofish implementation available for free on the web. 

+ * Most of them are hard to integrate into your own program. 

+ * As we like people to use our cipher, I thought I would make it easier.  

+ * Here is a free and easy-to-integrate Twofish implementation in C. 

+ * The latest version is always available from my personal home page at 

+ *    http://niels.ferguson.net/ 

+ * 

+ * Integrating library code into a project is difficult because the library 

+ * header files interfere with the project's header files and code.  

+ * And of course the project's header files interfere with the library code. 

+ * I've tried to resolve these problems here.  

+ * The header file of this implementation is very light-weight.  

+ * It contains two typedefs, a structure, and a few function declarations. 

+ * All names it defines start with "Twofish_".  

+ * The header file is therefore unlikely to cause problems in your project. 

+ * The code file of this implementation doesn't need to include the header 

+ * files of the project. There is thus no danger of the project interfering 

+ * with all the definitions and macros of the Twofish code. 

+ * In most situations, all you need to do is fill in a few platform-specific 

+ * definitions in the header file and code file,  

+ * and you should be able to run the Twofish code in your project. 

+ * I estimate it should take you less than an hour to integrate this code 

+ * into your project, most of it spent reading the comments telling you what 

+ * to do. 

+ * 

+ * For people using C++: it is very easy to wrap this library into a 

+ * TwofishKey class. One of the big advantages is that you can automate the 

+ * wiping of the key material in the destructor. I have not provided a C++ 

+ * class because the interface depends too much on the abstract base class  

+ * you use for block ciphers in your program, which I don't know about. 

+ * 

+ * This implementation is designed for use on PC-class machines. It uses the  

+ * Twofish 'full' keying option which uses large tables. Total table size is  

+ * around 5-6 kB for static tables plus 4.5 kB for each pre-processed key. 

+ * If you need an implementation that uses less memory, 

+ * take a look at Brian Gladman's code on his web site: 

+ *     http://fp.gladman.plus.com/cryptography_technology/aes/ 

+ * He has code for all AES candidates. 

+ * His Twofish code has lots of options trading off table size vs. speed. 

+ * You can also take a look at the optimised code by Doug Whiting on the 

+ * Twofish web site 

+ *      http://www.counterpane.com/twofish.html 

+ * which has loads of options. 

+ * I believe these existing implementations are harder to re-use because they 

+ * are not clean libraries and they impose requirements on the environment.  

+ * This implementation is very careful to minimise those,  

+ * and should be easier to integrate into any larger program. 

+ * 

+ * The default mode of this implementation is fully portable as it uses no 

+ * behaviour not defined in the C standard. (This is harder than you think.) 

+ * If you have any problems porting the default mode, please let me know 

+ * so that I can fix the problem. (But only if this code is at fault, I  

+ * don't fix compilers.) 

+ * Most of the platform fixes are related to non-portable but faster ways  

+ * of implementing certain functions. 

+ * 

+ * In general I've tried to make the code as fast as possible, at the expense 

+ * of memory and code size. However, C does impose limits, and this  

+ * implementation will be slower than an optimised assembler implementation. 

+ * But beware of assembler implementations: a good Pentium implementation 

+ * uses completely different code than a good Pentium II implementation. 

+ * You basically have to re-write the assembly code for every generation of 

+ * processor. Unless you are severely pressed for speed, stick with C. 

+ * 

+ * The initialisation routine of this implementation contains a self-test. 

+ * If initialisation succeeds without calling the fatal routine, then 

+ * the implementation works. I don't think you can break the implementation 

+ * in such a way that it still passes the tests, unless you are malicious. 

+ * In other words: if the initialisation routine returns,  

+ * you have successfully ported the implementation.  

+ * (Or not implemented the fatal routine properly, but that is your problem.) 

+ * 

+ * I'm indebted to many people who helped me in one way or another to write 

+ * this code. During the design of Twofish and the AES process I had very  

+ * extensive discussions of all implementation issues with various people. 

+ * Doug Whiting in particular provided a wealth of information. The Twofish  

+ * team spent untold hours discussion various cipher features, and their  

+ * implementation. Brian Gladman implemented all AES candidates in C,  

+ * and we had some fruitful discussions on how to implement Twofish in C. 

+ * Jan Nieuwenhuizen tested this code on Linux using GCC. 

+ * 

+ * Now for the license: 

+ * The author hereby grants a perpetual license to everybody to 

+ * use this code for any purpose as long as the copyright message is included 

+ * in the source code of this or any derived work. 

+ *  

+ * Yes, this means that you, your company, your club, and anyone else 

+ * can use this code anywhere you want. You can change it and distribute it 

+ * under the GPL, include it in your commercial product without releasing 

+ * the source code, put it on the web, etc.  

+ * The only thing you cannot do is remove my copyright message,  

+ * or distribute any source code based on this implementation that does not  

+ * include my copyright message.  

+ *  

+ * I appreciate a mention in the documentation or credits,  

+ * but I understand if that is difficult to do. 

+ * I also appreciate it if you tell me where and why you used my code. 

+ * 

+ * Please send any questions or comments to niels@ferguson.net 

+ * 

+ * Have Fun! 

+ * 

+ * Niels 

+ */ 

+ 

+/* 

+ * DISCLAIMER: As I'm giving away my work for free, I'm of course not going 

+ * to accept any liability of any form. This code, or the Twofish cipher, 

+ * might very well be flawed; you have been warned. 

+ * This software is provided as-is, without any kind of warrenty or 

+ * guarantee. And that is really all you can expect when you download  

+ * code for free from the Internet.  

+ * 

+ * I think it is really sad that disclaimers like this seem to be necessary. 

+ * If people only had a little bit more common sense, and didn't come 

+ * whining like little children every time something happens.... 

+ */ 

+  

+/* 

+ * Version history: 

+ * Version 0.0, 2002-08-30 

+ *      First written. 

+ * Version 0.1, 2002-09-03 

+ *      Added disclaimer. Improved self-tests. 

+ * Version 0.2, 2002-09-09 

+ *      Removed last non-portabilities. Default now works completely within 

+ *      the C standard. UInt32 can be larger than 32 bits without problems. 

+ * Version 0.3, 2002-09-28 

+ *      Bugfix: use  instead of  to adhere to ANSI/ISO. 

+ *      Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library  

+ *      header  already defines BIG_ENDIAN, even though it is not  

+ *      supposed to. 

+ */ 

+ 

+ 

+/*  

+ * Minimum set of include files. 

+ * You should not need any application-specific include files for this code.  

+ * In fact, adding you own header files could break one of the many macros or 

+ * functions in this file. Be very careful. 

+ * Standard include files will probably be ok. 

+ */ 

+#include <stdio.h>

+#include <string.h>

+#include <stdlib.h>

+/* #include      * for memset(), memcpy(), and memcmp() */ 

+#include "twofish.h" 

+ 

+ 

+/* 

+ * PLATFORM FIXES 

+ * ============== 

+ * 

+ * Fix the type definitions in twofish.h first! 

+ *  

+ * The following definitions have to be fixed for each particular platform  

+ * you work on. If you have a multi-platform program, you no doubt have  

+ * portable definitions that you can substitute here without changing the  

+ * rest of the code. 

+ */ 

+ 

+ 

+/*  

+ * Function called if something is fatally wrong with the implementation.  

+ * This fatal function is called when a coding error is detected in the 

+ * Twofish implementation, or when somebody passes an obviously erroneous 

+ * parameter to this implementation. There is not much you can do when 

+ * the code contains bugs, so we just stop. 

+ *  

+ * The argument is a string. Ideally the fatal function prints this string 

+ * as an error message. Whatever else this function does, it should never 

+ * return. A typical implementation would stop the program completely after 

+ * printing the error message. 

+ * 

+ * This default implementation is not very useful,  

+ * but does not assume anything about your environment.  

+ * It will at least let you know something is wrong.... 

+ * I didn't want to include any libraries to print and error or so, 

+ * as this makes the code much harder to integrate in a project. 

+ * 

+ * Note that the Twofish_fatal function may not return to the caller. 

+ * Unfortunately this is not something the self-test can test for, 

+ * so you have to make sure of this yourself. 

+ * 

+ * If you want to call an external function, be careful about including 

+ * your own header files here. This code uses a lot of macros, and your 

+ * header file could easily break it. Maybe the best solution is to use 

+ * a separate extern statement for your fatal function. 

+ */ 

+/* #define Twofish_fatal(pmsgx) { fprintf(stderr, pmsgx); exit(1); } */

+#define Twofish_fatal(pmsgx, code) { return(code); } 

+ 

+ 

+/* 

+ * The rest of the settings are not important for the functionality 

+ * of this Twofish implementation. That is, their default settings 

+ * work on all platforms. You can change them to improve the  

+ * speed of the implementation on your platform. Erroneous settings 

+ * will result in erroneous implementations, but the self-test should 

+ * catch those. 

+ */ 

+ 

+ 

+/*  

+ * Macros to rotate a Twofish_UInt32 value left or right by the  

+ * specified number of bits. This should be a 32-bit rotation,  

+ * and not rotation of, say, 64-bit values. 

+ * 

+ * Every encryption or decryption operation uses 32 of these rotations, 

+ * so it is a good idea to make these macros efficient. 

+ * 

+ * This fully portable definition has one piece of tricky stuff. 

+ * The UInt32 might be larger than 32 bits, so we have to mask 

+ * any higher bits off. The simplest way to do this is to 'and' the 

+ * value first with 0xffffffff and then shift it right. An optimising 

+ * compiler that has a 32-bit type can optimise this 'and' away. 

+ *  

+ * Unfortunately there is no portable way of writing the constant 

+ * 0xffffffff. You don't know which suffix to use (U, or UL?) 

+ * The UINT32_MASK definition uses a bit of trickery. Shift-left 

+ * is only defined if the shift amount is strictly less than the size 

+ * of the UInt32, so we can't use (1<<32). The answer it to take the value 

+ * 2, cast it to a UInt32, shift it left 31 positions, and subtract one. 

+ * Another example of how to make something very simple extremely difficult. 

+ * I hate C. 

+ *  

+ * The rotation macros are straightforward. 

+ * They are only applied to UInt32 values, which are _unsigned_ 

+ * so the >> operator must do a logical shift that brings in zeroes. 

+ * On most platforms you will only need to optimise the ROL32 macro; the 

+ * ROR32 macro is not inefficient on an optimising compiler as all rotation 

+ * amounts in this code are known at compile time. 

+ * 

+ * On many platforms there is a faster solution. 

+ * For example, MS compilers have the __rotl and __rotr functions 

+ * that generate x86 rotation instructions. 

+ */ 

+#define UINT32_MASK    ( (((Twofish_UInt32)2)<<31) - 1 ) 

+ 

+#ifndef _MSC_VER 

+#define ROL32(x,n) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) ) 

+#define ROR32(x,n) ( (x)>>(n) | ((x) & UINT32_MASK) << (32-(n)) ) 

+#else 

+#define ROL32(x,n) (_lrotl((x), (n))) 

+#define ROR32(x,n) (_lrotr((x), (n))) 

+#endif 

+ 

+/* 

+ * Select data type for q-table entries.  

+ * 

+ * Larger entry types cost more memory (1.5 kB), and might be faster  

+ * or slower depending on the CPU and compiler details. 

+ * 

+ * This choice only affects the static data size and the key setup speed. 

+ * Functionality, expanded key size, or encryption speed are not affected. 

+ * Define to 1 to get large q-table entries. 

+ */ 

+#define LARGE_Q_TABLE   0    /* default = 0 */ 

+ 

+ 

+/* 

+ * Method to select a single byte from a UInt32. 

+ * WARNING: non-portable code if set; might not work on all platforms. 

+ * 

+ * Inside the inner loop of Twofish it is necessary to access the 4  

+ * individual bytes of a UInt32. This can be done using either shifts 

+ * and masks, or memory accesses. 

+ * 

+ * Set to 0 to use shift and mask operations for the byte selection. 

+ * This is more ALU intensive. It is also fully portable.  

+ *  

+ * Set to 1 to use memory accesses. The UInt32 is stored in memory and 

+ * the individual bytes are read from memory one at a time. 

+ * This solution is more memory-intensive, and not fully portable. 

+ * It might be faster on your platform, or not. If you use this option, 

+ * make sure you set the CPU_IS_BIG_ENDIAN flag appropriately. 

+ *  

+ * This macro does not affect the conversion of the inputs and outputs 

+ * of the cipher. See the CONVERT_USING_CASTS macro for that. 

+ */ 

+#define SELECT_BYTE_FROM_UINT32_IN_MEMORY    0    /* default = 0 */ 

+ 

+ 

+/* 

+ * Method used to read the input and write the output. 

+ * WARNING: non-portable code if set; might not work on all platforms. 

+ * 

+ * Twofish operates on 32-bit words. The input to the cipher is 

+ * a byte array, as is the output. The portable method of doing the 

+ * conversion is a bunch of rotate and mask operations, but on many  

+ * platforms it can be done faster using a cast. 

+ * This only works if your CPU allows UInt32 accesses to arbitrary Byte 

+ * addresses. 

+ *  

+ * Set to 0 to use the shift and mask operations. This is fully 

+ * portable. . 

+ * 

+ * Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a 

+ * UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN  

+ * macro) the byte order in the UInt32 is swapped. The reverse is done 

+ * to write the output of the encryption/decryption. Make sure you set 

+ * the CPU_IS_BIG_ENDIAN flag appropriately. 

+ * This option does not work unless a UInt32 is exactly 32 bits. 

+ * 

+ * This macro only changes the reading/writing of the plaintext/ciphertext. 

+ * See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which 

+ * a UInt32 is split into 4 bytes for the S-box selection. 

+ */ 

+#define CONVERT_USING_CASTS    0    /* default = 0 */ 

+ 

+ 

+/*  

+ * Endianness switch. 

+ * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or 

+ * CONVERT_USING_CASTS is set. 

+ * 

+ * Set to 1 on a big-endian machine, and to 0 on a little-endian machine.  

+ * Twofish uses the little-endian convention (least significant byte first) 

+ * and big-endian machines (using most significant byte first)  

+ * have to do a few conversions.  

+ * 

+ * CAUTION: This code has never been tested on a big-endian machine,  

+ * because I don't have access to one. Feedback appreciated. 

+ */ 

+#define CPU_IS_BIG_ENDIAN    0 

+ 

+ 

+/*  

+ * Macro to reverse the order of the bytes in a UInt32. 

+ * Used to convert to little-endian on big-endian machines. 

+ * This macro is always tested, but only used in the encryption and 

+ * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN 

+ * are both set. In other words: this macro is only speed-critical if 

+ * both these flags have been set. 

+ * 

+ * This default definition of SWAP works, but on many platforms there is a  

+ * more efficient implementation.  

+ */ 

+#define BSWAP(x) ((ROL32((x),8)&0x00ff00ff) | (ROR32((x),8) & 0xff00ff00)) 

+ 

+ 

+/* 

+ * END OF PLATFORM FIXES 

+ * ===================== 

+ *  

+ * You should not have to touch the rest of this file. 

+ */ 

+ 

+ 

+/* 

+ * Convert the external type names to some that are easier to use inside 

+ * this file. I didn't want to use the names Byte and UInt32 in the 

+ * header file, because many programs already define them and using two 

+ * conventions at once can be very difficult. 

+ * Don't change these definitions! Change the originals  

+ * in twofish.h instead.  

+ */ 

+/* A Byte must be an unsigned integer, 8 bits long. */ 

+/* typedef Twofish_Byte    Byte; */

+/* A UInt32 must be an unsigned integer at least 32 bits long. */ 

+/* typedef Twofish_UInt32  UInt32; */

+ 

+ 

+/*  

+ * Define a macro ENDIAN_CONVERT. 

+ * 

+ * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian 

+ * machines, and is the identity function on little-endian machines. 

+ * The code then uses this macro without considering the endianness. 

+ */ 

+ 

+#if CPU_IS_BIG_ENDIAN 

+#define ENDIAN_CONVERT(x)    BSWAP(x) 

+#else 

+#define ENDIAN_CONVERT(x)    (x) 

+#endif 

+ 

+ 

+/*  

+ * Compute byte offset within a UInt32 stored in memory. 

+ * 

+ * This is only used when SELECT_BYTE_FROM_UINT32_IN_MEMORY is set. 

+ *  

+ * The input is the byte number 0..3, 0 for least significant. 

+ * Note the use of sizeof() to support UInt32 types that are larger 

+ * than 4 bytes. 

+ */ 

+#if CPU_IS_BIG_ENDIAN 

+#define BYTE_OFFSET( n )  (sizeof(Twofish_UInt32) - 1 - (n) ) 

+#else 

+#define BYTE_OFFSET( n )  (n) 

+#endif 

+ 

+ 

+/* 

+ * Macro to get Byte no. b from UInt32 value X. 

+ * We use two different definition, depending on the settings. 

+ */ 

+#if SELECT_BYTE_FROM_UINT32_IN_MEMORY 

+    /* Pick the byte from the memory in which X is stored. */ 

+#define SELECT_BYTE( X, b ) (((Twofish_Byte *)(&(X)))[BYTE_OFFSET(b)]) 

+#else 

+    /* Portable solution: Pick the byte directly from the X value. */ 

+#define SELECT_BYTE( X, b ) (((X) >> (8*(b))) & 0xff) 

+#endif 

+ 

+ 

+/* Some shorthands because we use byte selection in large formulae. */ 

+#define b0(X)   SELECT_BYTE((X),0) 

+#define b1(X)   SELECT_BYTE((X),1) 

+#define b2(X)   SELECT_BYTE((X),2) 

+#define b3(X)   SELECT_BYTE((X),3) 

+ 

+ 

+/* 

+ * We need macros to load and store UInt32 from/to byte arrays 

+ * using the least-significant-byte-first convention. 

+ * 

+ * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to 

+ * by p. 

+ * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form. 

+ */ 

+#if CONVERT_USING_CASTS 

+ 

+    /* Get UInt32 from four bytes pointed to by p. */ 

+#define GET32( p )    ENDIAN_CONVERT( *((Twofish_UInt32 *)(p)) ) 

+    /* Put UInt32 into four bytes pointed to by p */ 

+#define PUT32( v, p ) *((Twofish_UInt32 *)(p)) = ENDIAN_CONVERT(v) 

+ 

+#else 

+ 

+    /* Get UInt32 from four bytes pointed to by p. */ 

+#define GET32( p ) \

+    ( \

+      (Twofish_UInt32)((p)[0])     \

+    | (Twofish_UInt32)((p)[1])<< 8 \

+    | (Twofish_UInt32)((p)[2])<<16 \

+    | (Twofish_UInt32)((p)[3])<<24 \

+    ) 

+    /* Put UInt32 into four bytes pointed to by p */ 

+#define PUT32( v, p ) \

+    (p)[0] = (Twofish_Byte)(((v)      ) & 0xff); \

+    (p)[1] = (Twofish_Byte)(((v) >>  8) & 0xff); \

+    (p)[2] = (Twofish_Byte)(((v) >> 16) & 0xff); \

+    (p)[3] = (Twofish_Byte)(((v) >> 24) & 0xff)

+ 

+#endif 

+ 

+ 

+/* 

+ * Test the platform-specific macros. 

+ * This function tests the macros defined so far to make sure the  

+ * definitions are appropriate for this platform. 

+ * If you make any mistake in the platform configuration, this should detect 

+ * that and inform you what went wrong. 

+ * Somewhere, someday, this is going to save somebody a lot of time, 

+ * because misbehaving macros are hard to debug. 

+ */ 

+static int test_platform() 

+    { 

+    /* Buffer with test values. */ 

+    Twofish_Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0}; 

+    Twofish_UInt32 C; 

+    Twofish_UInt32 x,y; 

+    int i; 

+ 

+    /*  

+     * Some sanity checks on the types that can't be done in compile time.  

+     * A smart compiler will just optimise these tests away. 

+     * The pre-processor doesn't understand different types, so we cannot 

+     * do these checks in compile-time. 

+     * 

+     * I hate C. 

+     * 

+     * The first check in each case is to make sure the size is correct. 

+     * The second check is to ensure that it is an unsigned type. 

+     */ 

+    if( ((Twofish_UInt32)((Twofish_UInt32)1 << 31) == 0) || ((Twofish_UInt32)-1 < 0 ))  

+        { 

+	  Twofish_fatal( "Twofish code: Twofish_UInt32 type not suitable", ERR_UINT32 ); 

+        } 

+    if( (sizeof( Twofish_Byte ) != 1) || (((Twofish_Byte)-1) < 0) )  

+        { 

+	  Twofish_fatal( "Twofish code: Twofish_Byte type not suitable", ERR_BYTE ); 

+        } 

+ 

+    /*  

+     * Sanity-check the endianness conversions.  

+     * This is just an aid to find problems. If you do the endianness 

+     * conversion macros wrong you will fail the full cipher test, 

+     * but that does not help you find the error. 

+     * Always make it easy to find the bugs!  

+     * 

+     * Detail: There is no fully portable way of writing UInt32 constants, 

+     * as you don't know whether to use the U or UL suffix. Using only U you 

+     * might only be allowed 16-bit constants. Using UL you might get 64-bit 

+     * constants which cannot be stored in a UInt32 without warnings, and 

+     * which generally behave subtly different from a true UInt32. 

+     * As long as we're just comparing with the constant,  

+     * we can always use the UL suffix and at worst lose some efficiency.  

+     * I use a separate '32-bit constant' macro in most of my other code. 

+     * 

+     * I hate C. 

+     * 

+     * Start with testing GET32. We test it on all positions modulo 4  

+     * to make sure we can handly any position of inputs. (Some CPUs 

+     * do not allow non-aligned accesses which we would do if you used 

+     * the CONVERT_USING_CASTS option. 

+     */ 

+    if( (GET32( buf ) != 0x78563412UL) || (GET32(buf+1) != 0x9a785634UL)  

+        || (GET32( buf+2 ) != 0xbc9a7856UL) || (GET32(buf+3) != 0xdebc9a78UL) ) 

+        { 

+	  Twofish_fatal( "Twofish code: GET32 not implemented properly", ERR_GET32 ); 

+        } 

+ 

+    /*  

+     * We can now use GET32 to test PUT32. 

+     * We don't test the shifted versions. If GET32 can do that then 

+     * so should PUT32. 

+     */ 

+    C = GET32( buf ); 

+    PUT32( 3*C, buf ); 

+    if( GET32( buf ) != 0x69029c36UL ) 

+        { 

+	  Twofish_fatal( "Twofish code: PUT32 not implemented properly", ERR_PUT32 ); 

+        } 

+ 

+ 

+    /* Test ROL and ROR */ 

+    for( i=1; i<32; i++ )  

+        { 

+        /* Just a simple test. */ 

+        x = ROR32( C, i ); 

+        y = ROL32( C, i ); 

+        x ^= (C>>i) ^ (C<<(32-i)); 

+        /*y ^= (C<>(32-i));  */

+        y ^= (C<<i) ^ (C>>(32-i));

+        x |= y; 

+        /*  

+         * Now all we check is that x is zero in the least significant 

+         * 32 bits. Using the UL suffix is safe here, as it doesn't matter 

+         * if we get a larger type. 

+         */ 

+	if( (x & 0xffffffffUL) != 0 ) 

+            { 

+	      Twofish_fatal( "Twofish ROL or ROR not properly defined.", ERR_ROLR ); 

+            } 

+        } 

+ 

+    /* Test the BSWAP macro */ 

+    if( BSWAP(C) != 0x12345678UL ) 

+        { 

+        /* 

+         * The BSWAP macro should always work, even if you are not using it. 

+         * A smart optimising compiler will just remove this entire test. 

+         */ 

+	  Twofish_fatal( "BSWAP not properly defined.", ERR_BSWAP ); 

+        } 

+ 

+    /* And we can test the b macros which use SELECT_BYTE. */ 

+    if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) ) 

+        { 

+        /* 

+         * There are many reasons why this could fail. 

+         * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value.  

+         */ 

+	  Twofish_fatal( "Twofish code: SELECT_BYTE not implemented properly", ERR_SELECTB ); 

+        }

+    return SUCCESS;

+    } 

+ 

+ 

+/* 

+ * Finally, we can start on the Twofish-related code. 

+ * You really need the Twofish specifications to understand this code. The 

+ * best source is the Twofish book: 

+ *     "The Twofish Encryption Algorithm", by Bruce Schneier, John Kelsey, 

+ *     Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson. 

+ * you can also use the AES submission document of Twofish, which is  

+ * available from my list of publications on my personal web site at  

+ *    http://niels.ferguson.net/. 

+ * 

+ * The first thing we do is write the testing routines. This is what the  

+ * implementation has to satisfy in the end. We only test the external 

+ * behaviour of the implementation of course. 

+ */ 

+ 

+ 

+/* 

+ * Perform a single self test on a (plaintext,ciphertext,key) triple. 

+ * Arguments: 

+ *  key     array of key bytes 

+ *  key_len length of key in bytes 

+ *  p       plaintext 

+ *  c       ciphertext 

+ */ 

+static int test_vector( Twofish_Byte key[], int key_len, Twofish_Byte p[16], Twofish_Byte c[16] ) 

+    { 

+    Twofish_Byte tmp[16];               /* scratch pad. */ 

+    Twofish_key xkey;           /* The expanded key */ 

+    int i; 

+ 

+ 

+    /* Prepare the key */ 

+    if ((i = Twofish_prepare_key( key, key_len, &xkey)) < 0)

+	return i; 

+ 

+    /*  

+     * We run the test twice to ensure that the xkey structure 

+     * is not damaged by the first encryption.  

+     * Those are hideous bugs to find if you get them in an application. 

+     */ 

+    for( i=0; i<2; i++ )  

+        { 

+        /* Encrypt and test */ 

+        Twofish_encrypt( &xkey, p, tmp ); 

+        if( memcmp( c, tmp, 16 ) != 0 )  

+            { 

+	      Twofish_fatal( "Twofish encryption failure", ERR_TEST_ENC ); 

+            } 

+ 

+        /* Decrypt and test */ 

+        Twofish_decrypt( &xkey, c, tmp ); 

+        if( memcmp( p, tmp, 16 ) != 0 )  

+            { 

+	      Twofish_fatal( "Twofish decryption failure", ERR_TEST_DEC ); 

+            } 

+        } 

+ 

+    /* The test keys are not secret, so we don't need to wipe xkey. */

+    return SUCCESS;

+    }

+ 

+ 

+/* 

+ * Check implementation using three (key,plaintext,ciphertext) 

+ * test vectors, one for each major key length. 

+ *  

+ * This is an absolutely minimal self-test.  

+ * This routine does not test odd-sized keys. 

+ */ 

+static int test_vectors() 

+    { 

+    /* 

+     * We run three tests, one for each major key length. 

+     * These test vectors come from the Twofish specification. 

+     * One encryption and one decryption using randomish data and key 

+     * will detect almost any error, especially since we generate the 

+     * tables ourselves, so we don't have the problem of a single 

+     * damaged table entry in the source. 

+     */ 

+ 

+    /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */ 

+    static Twofish_Byte k128[] = { 

+        0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,  

+        0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A, 

+        }; 

+    static Twofish_Byte p128[] = { 

+        0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,  

+        0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 

+        }; 

+    static Twofish_Byte c128[] = { 

+        0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,  

+        0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 

+        }; 

+ 

+    /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */ 

+    static Twofish_Byte k192[] = { 

+        0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,  

+        0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,  

+        0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 

+        }; 

+    static Twofish_Byte p192[] = { 

+        0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, 

+        0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 

+        }; 

+    static Twofish_Byte c192[] = { 

+        0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, 

+        0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 

+        }; 

+ 

+    /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */ 

+    static Twofish_Byte k256[] = { 

+        0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,  

+        0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, 

+        0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, 

+        0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F 

+        }; 

+    static Twofish_Byte p256[] = { 

+        0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, 

+        0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 

+        }; 

+    static Twofish_Byte c256[] = { 

+        0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, 

+        0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA 

+        }; 

+

+    int ret;

+

+    /* Run the actual tests. */ 

+    if ((ret = test_vector( k128, 16, p128, c128 )) < 0)

+      return ret; 

+    if ((ret = test_vector( k192, 24, p192, c192 )) < 0)

+      return ret; 

+    if ((ret = test_vector( k256, 32, p256, c256 )) < 0)

+      return ret;

+    return SUCCESS;

+    }    

+ 

+ 

+/* 

+ * Perform extensive test for a single key size. 

+ *  

+ * Test a single key size against the test vectors from section 

+ * B.2 in the Twofish book. This is a sequence of 49 encryptions 

+ * and decryptions. Each plaintext is equal to the ciphertext of 

+ * the previous encryption. The key is made up from the ciphertext 

+ * two and three encryptions ago. Both plaintext and key start 

+ * at the zero value.  

+ * We should have designed a cleaner recurrence relation for 

+ * these tests, but it is too late for that now. At least we learned 

+ * how to do it better next time. 

+ * For details see appendix B of the book. 

+ * 

+ * Arguments: 

+ * key_len      Number of bytes of key 

+ * final_value  Final plaintext value after 49 iterations 

+ */ 

+static int test_sequence( int key_len, Twofish_Byte final_value[] ) 

+    { 

+    Twofish_Byte buf[ (50+3)*16 ];      /* Buffer to hold our computation values. */ 

+    Twofish_Byte tmp[16];               /* Temp for testing the decryption. */ 

+    Twofish_key xkey;           /* The expanded key */ 

+    int i, ret;

+    Twofish_Byte * p; 

+ 

+    /* Wipe the buffer */ 

+    memset( buf, 0, sizeof( buf ) ); 

+ 

+    /* 

+     * Because the recurrence relation is done in an inconvenient manner 

+     * we end up looping backwards over the buffer. 

+     */ 

+ 

+    /* Pointer in buffer points to current plaintext. */ 

+    p = &buf[50*16]; 

+    for( i=1; i<50; i++ ) 

+        { 

+        /*  

+         * Prepare a key. 

+         * This automatically checks that key_len is valid. 

+         */ 

+	  if ((ret = Twofish_prepare_key( p+16, key_len, &xkey)) < 0)

+	    return ret; 

+ 

+        /* Compute the next 16 bytes in the buffer */ 

+        Twofish_encrypt( &xkey, p, p-16 ); 

+ 

+        /* Check that the decryption is correct. */ 

+        Twofish_decrypt( &xkey, p-16, tmp ); 

+        if( memcmp( tmp, p, 16 ) != 0 ) 

+            { 

+	      Twofish_fatal( "Twofish decryption failure in sequence", ERR_SEQ_DEC ); 

+            } 

+        /* Move on to next 16 bytes in the buffer. */ 

+        p -= 16; 

+        } 

+ 

+    /* And check the final value. */ 

+    if( memcmp( p, final_value, 16 ) != 0 )  

+        { 

+	  Twofish_fatal( "Twofish encryption failure in sequence", ERR_SEQ_ENC ); 

+        } 

+ 

+    /* None of the data was secret, so there is no need to wipe anything. */

+    return SUCCESS;

+    } 

+ 

+ 

+/*  

+ * Run all three sequence tests from the Twofish test vectors.  

+ * 

+ * This checks the most extensive test vectors currently available  

+ * for Twofish. The data is from the Twofish book, appendix B.2. 

+ */ 

+static int test_sequences() 

+    { 

+    static Twofish_Byte r128[] = { 

+        0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57, 

+        0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0 

+        }; 

+    static Twofish_Byte r192[] = { 

+        0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4, 

+        0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41 

+        }; 

+    static Twofish_Byte r256[] = { 

+        0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75, 

+        0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05 

+        }; 

+ 

+    /* Run the three sequence test vectors */

+    int ret;

+    if ((ret = test_sequence( 16, r128)) < 0)

+      return ret; 

+    if ((ret = test_sequence( 24, r192)) < 0)

+      return ret; 

+    if ((ret = test_sequence( 32, r256)) < 0)

+      return ret;

+    return SUCCESS;

+    } 

+ 

+ 

+/* 

+ * Test the odd-sized keys. 

+ * 

+ * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits. 

+ * The equivalent key is found by padding at the end with zero bytes 

+ * until a regular key size is reached. 

+ * 

+ * We just test that the key expansion routine behaves properly. 

+ * If the expanded keys are identical, then the encryptions and decryptions 

+ * will behave the same. 

+ */ 

+static int test_odd_sized_keys() 

+    { 

+    Twofish_Byte buf[32]; 

+    Twofish_key xkey; 

+    Twofish_key xkey_two; 

+    int i, ret;

+ 

+    /*  

+     * We first create an all-zero key to use as PRNG key.  

+     * Normally we would not have to fill the buffer with zeroes, as we could 

+     * just pass a zero key length to the Twofish_prepare_key function. 

+     * However, this relies on using odd-sized keys, and those are just the 

+     * ones we are testing here. We can't use an untested function to test  

+     * itself.  

+     */ 

+    memset( buf, 0, sizeof( buf ) ); 

+    if ((ret = Twofish_prepare_key( buf, 16, &xkey)) < 0)

+      return ret; 

+ 

+    /* Fill buffer with pseudo-random data derived from two encryptions */ 

+    Twofish_encrypt( &xkey, buf, buf ); 

+    Twofish_encrypt( &xkey, buf, buf+16 ); 

+ 

+    /* Create all possible shorter keys that are prefixes of the buffer. */ 

+    for( i=31; i>=0; i-- ) 

+        { 

+        /* Set a byte to zero. This is the new padding byte */ 

+        buf[i] = 0; 

+ 

+        /* Expand the key with only i bytes of length */ 

+        if ((ret = Twofish_prepare_key( buf, i, &xkey)) < 0)

+	  return ret; 

+ 

+        /* Expand the corresponding padded key of regular length */ 

+        if ((ret = Twofish_prepare_key( buf, i<=16 ? 16 : (i<= 24 ? 24 : 32), &xkey_two )) < 0)

+	  return ret; 

+ 

+        /* Compare the two */ 

+        if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 ) 

+            { 

+	      Twofish_fatal( "Odd sized keys do not expand properly", ERR_ODD_KEY ); 

+            } 

+        } 

+ 

+    /* None of the key values are secret, so we don't need to wipe them. */

+    return SUCCESS;

+    } 

+ 

+ 

+/* 

+ * Test the Twofish implementation. 

+ * 

+ * This routine runs all the self tests, in order of importance. 

+ * It is called by the Twofish_initialise routine. 

+ *  

+ * In almost all applications the cost of running the self tests during 

+ * initialisation is insignificant, especially 

+ * compared to the time it takes to load the application from disk.  

+ * If you are very pressed for initialisation performance,  

+ * you could remove some of the tests. Make sure you did run them 

+ * once in the software and hardware configuration you are using. 

+ */ 

+static int self_test() 

+    {

+      int ret;

+    /* The three test vectors form an absolute minimal test set. */ 

+      if ((ret = test_vectors()) < 0)

+	return ret;

+ 

+    /*  

+     * If at all possible you should run these tests too. They take 

+     * more time, but provide a more thorough coverage. 

+     */ 

+      if ((ret = test_sequences()) < 0)

+	return ret;

+ 

+    /* Test the odd-sized keys. */ 

+      if ((ret = test_odd_sized_keys()) < 0)

+	return ret;

+      return SUCCESS;

+    } 

+ 

+ 

+/* 

+ * And now, the actual Twofish implementation. 

+ * 

+ * This implementation generates all the tables during initialisation.  

+ * I don't like large tables in the code, especially since they are easily  

+ * damaged in the source without anyone noticing it. You need code to  

+ * generate them anyway, and this way all the code is close together. 

+ * Generating them in the application leads to a smaller executable  

+ * (the code is smaller than the tables it generates) and a  

+ * larger static memory footprint. 

+ * 

+ * Twofish can be implemented in many ways. I have chosen to  

+ * use large tables with a relatively long key setup time. 

+ * If you encrypt more than a few blocks of data it pays to pre-compute  

+ * as much as possible. This implementation is relatively inefficient for  

+ * applications that need to re-key every block or so. 

+ */ 

+ 

+/*  

+ * We start with the t-tables, directly from the Twofish definition.  

+ * These are nibble-tables, but merging them and putting them two nibbles  

+ * in one byte is more work than it is worth. 

+ */ 

+static Twofish_Byte t_table[2][4][16] = { 

+    { 

+        {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4}, 

+        {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD}, 

+        {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1}, 

+        {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA} 

+    }, 

+    { 

+        {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5}, 

+        {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8}, 

+        {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF}, 

+        {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA} 

+    } 

+}; 

+ 

+ 

+/* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */ 

+#define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) ) 

+ 

+/* 

+ * The q-boxes are only used during the key schedule computations.  

+ * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit  

+ * lookup tables as it is faster to load a 32-bit value than to load an  

+ * 8-bit value and zero the rest of the register. 

+ * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in  

+ * the q-tables. Here we just define the Qtype which is used to store  

+ * the entries of the q-tables. 

+ */ 

+#if LARGE_Q_TABLE 

+typedef Twofish_UInt32      Qtype; 

+#else 

+typedef Twofish_Byte        Qtype; 

+#endif 

+ 

+/*  

+ * The actual q-box tables.  

+ * There are two q-boxes, each having 256 entries. 

+ */ 

+static Qtype q_table[2][256]; 

+ 

+ 

+/* 

+ * Now the function that converts a single t-table into a q-table. 

+ * 

+ * Arguments: 

+ * t[4][16] : four 4->4bit lookup tables that define the q-box 

+ * q[256]   : output parameter: the resulting q-box as a lookup table. 

+ */ 

+static void make_q_table( Twofish_Byte t[4][16], Qtype q[256] ) 

+    { 

+    int ae,be,ao,bo;        /* Some temporaries. */ 

+    int i; 

+    /* Loop over all input values and compute the q-box result. */ 

+    for( i=0; i<256; i++ ) { 

+        /*  

+         * This is straight from the Twofish specifications.  

+         *  

+         * The ae variable is used for the a_i values from the specs 

+         * with even i, and ao for the odd i's. Similarly for the b's. 

+         */ 

+        ae = i>>4; be = i&0xf; 

+        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); 

+        ae = t[0][ao]; be = t[1][bo]; 

+        ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); 

+        ae = t[2][ao]; be = t[3][bo]; 

+ 

+        /* Store the result in the q-box table, the cast avoids a warning. */ 

+        q[i] = (Qtype) ((be<<4) | ae); 

+        } 

+    } 

+ 

+ 

+/*  

+ * Initialise both q-box tables.  

+ */ 

+static void initialise_q_boxes() { 

+    /* Initialise each of the q-boxes using the t-tables */ 

+    make_q_table( t_table[0], q_table[0] ); 

+    make_q_table( t_table[1], q_table[1] ); 

+    } 

+ 

+ 

+/* 

+ * Next up is the MDS matrix multiplication. 

+ * The MDS matrix multiplication operates in the field 

+ * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1. 

+ * If you don't understand this, read a book on finite fields. You cannot 

+ * follow the finite-field computations without some background. 

+ *  

+ * In this field, multiplication by x is easy: shift left one bit  

+ * and if bit 8 is set then xor the result with 0x169.  

+ * 

+ * The MDS coefficients use a multiplication by 1/x, 

+ * or rather a division by x. This is easy too: first make the 

+ * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary,  

+ * and then shift right one position.  

+ * Even easier: shift right and xor with 0xb4 if the lsbit was set. 

+ * 

+ * The MDS coefficients are 1, EF, and 5B, and we use the fact that 

+ *   EF = 1 + 1/x + 1/x^2 

+ *   5B = 1       + 1/x^2 

+ * in this field. This makes multiplication by EF and 5B relatively easy. 

+ * 

+ * This property is no accident, the MDS matrix was designed to allow 

+ * this implementation technique to be used. 

+ * 

+ * We have four MDS tables, each mapping 8 bits to 32 bits. 

+ * Each table performs one column of the matrix multiplication.  

+ * As the MDS is always preceded by q-boxes, each of these tables 

+ * also implements the q-box just previous to that column. 

+ */ 

+ 

+/* The actual MDS tables. */ 

+static Twofish_UInt32 MDS_table[4][256]; 

+ 

+/* A small table to get easy conditional access to the 0xb4 constant. */ 

+static Twofish_UInt32 mds_poly_divx_const[] = {0,0xb4}; 

+ 

+/* Function to initialise the MDS tables. */ 

+static void initialise_mds_tables() 

+    { 

+    int i; 

+    Twofish_UInt32 q,qef,q5b;       /* Temporary variables. */ 

+ 

+    /* Loop over all 8-bit input values */ 

+    for( i=0; i<256; i++ )  

+        { 

+        /*  

+         * To save some work during the key expansion we include the last 

+         * of the q-box layers from the h() function in these MDS tables. 

+         */ 

+ 

+        /* We first do the inputs that are mapped through the q0 table. */ 

+        q = q_table[0][i]; 

+        /* 

+         * Here we divide by x, note the table to get 0xb4 only if the  

+         * lsbit is set.  

+         * This sets qef = (1/x)*q in the finite field 

+         */ 

+        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; 

+        /* 

+         * Divide by x again, and add q to get (1+1/x^2)*q.  

+         * Note that (1+1/x^2) =  5B in the field, and addition in the field 

+         * is exclusive or on the bits. 

+         */ 

+        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; 

+        /*  

+         * Add q5b to qef to set qef = (1+1/x+1/x^2)*q. 

+         * Again, (1+1/x+1/x^2) = EF in the field. 

+         */ 

+        qef ^= q5b; 

+ 

+        /*  

+         * Now that we have q5b = 5B * q and qef = EF * q  

+         * we can fill two of the entries in the MDS matrix table.  

+         * See the Twofish specifications for the order of the constants. 

+         */ 

+        MDS_table[1][i] = (q  <<24) | (q5b<<16) | (qef<<8) | qef; 

+        MDS_table[3][i] = (q5b<<24) | (qef<<16) | (q  <<8) | q5b; 

+ 

+        /* Now we do it all again for the two columns that have a q1 box. */ 

+        q = q_table[1][i]; 

+        qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; 

+        q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; 

+        qef ^= q5b; 

+ 

+        /* The other two columns use the coefficient in a different order. */ 

+        MDS_table[0][i] = (qef<<24) | (qef<<16) | (q5b<<8) | q  ; 

+        MDS_table[2][i] = (qef<<24) | (q  <<16) | (qef<<8) | q5b; 

+        } 

+    } 

+ 

+ 

+/* 

+ * The h() function is the heart of the Twofish cipher.  

+ * It is a complicated sequence of q-box lookups, key material xors,  

+ * and finally the MDS matrix. 

+ * We use lots of macros to make this reasonably fast. 

+ */ 

+ 

+/* First a shorthand for the two q-tables */ 

+#define q0  q_table[0] 

+#define q1  q_table[1] 

+ 

+/* 

+ * Each macro computes one column of the h for either 2, 3, or 4 stages. 

+ * As there are 4 columns, we have 12 macros in all. 

+ *  

+ * The key bytes are stored in the Byte array L at offset  

+ * 0,1,2,3,  8,9,10,11,  [16,17,18,19,   [24,25,26,27]] as this is the 

+ * order we get the bytes from the user. If you look at the Twofish  

+ * specs, you'll see that h() is applied to the even key words or the 

+ * odd key words. The bytes of the even words appear in this spacing, 

+ * and those of the odd key words too. 

+ * 

+ * These macros are the only place where the q-boxes and the MDS table 

+ * are used. 

+ */ 

+#define H02( y, L )  MDS_table[0][q0[q0[y]^L[ 8]]^L[0]] 

+#define H12( y, L )  MDS_table[1][q0[q1[y]^L[ 9]]^L[1]] 

+#define H22( y, L )  MDS_table[2][q1[q0[y]^L[10]]^L[2]] 

+#define H32( y, L )  MDS_table[3][q1[q1[y]^L[11]]^L[3]] 

+#define H03( y, L )  H02( q1[y]^L[16], L ) 

+#define H13( y, L )  H12( q1[y]^L[17], L ) 

+#define H23( y, L )  H22( q0[y]^L[18], L ) 

+#define H33( y, L )  H32( q0[y]^L[19], L ) 

+#define H04( y, L )  H03( q1[y]^L[24], L ) 

+#define H14( y, L )  H13( q0[y]^L[25], L ) 

+#define H24( y, L )  H23( q0[y]^L[26], L ) 

+#define H34( y, L )  H33( q1[y]^L[27], L ) 

+ 

+/* 

+ * Now we can define the h() function given an array of key bytes.  

+ * This function is only used in the key schedule, and not to pre-compute 

+ * the keyed S-boxes. 

+ * 

+ * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24) 

+ * so we only provide k as an argument. 

+ * 

+ * Arguments: 

+ * k        input to the h() function. 

+ * L        pointer to array of key bytes at  

+ *          offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]] 

+ * kCycles  # key cycles, 2, 3, or 4. 

+ */ 

+static Twofish_UInt32 h( int k, Twofish_Byte L[], int kCycles ) 

+    { 

+    switch( kCycles ) { 

+        /* We code all 3 cases separately for speed reasons. */ 

+    case 2: 

+        return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L); 

+    case 3: 

+        return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L); 

+    case 4: 

+        return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L); 

+    default:  

+        /* This is always a coding error, which is fatal. */ 

+      Twofish_fatal( "Twofish h(): Illegal argument", ERR_ILL_ARG ); 

+      return ERR_ILL_ARG;

+        } 

+    } 

+ 

+ 

+/* 

+ * Pre-compute the keyed S-boxes. 

+ * Fill the pre-computed S-box array in the expanded key structure. 

+ * Each pre-computed S-box maps 8 bits to 32 bits. 

+ * 

+ * The S argument contains half the number of bytes of the full key, but is 

+ * derived from the full key. (See Twofish specifications for details.) 

+ * S has the weird byte input order used by the Hxx macros. 

+ * 

+ * This function takes most of the time of a key expansion. 

+ * 

+ * Arguments: 

+ * S        pointer to array of 8*kCycles Bytes containing the S vector. 

+ * kCycles  number of key words, must be in the set {2,3,4} 

+ * xkey     pointer to Twofish_key structure that will contain the S-boxes. 

+ */ 

+static int fill_keyed_sboxes( Twofish_Byte S[], int kCycles, Twofish_key * xkey ) 

+    { 

+    int i; 

+    switch( kCycles ) { 

+        /* We code all 3 cases separately for speed reasons. */ 

+    case 2: 

+        for( i=0; i<256; i++ ) 

+            { 

+            xkey->s[0][i]= H02( i, S ); 

+            xkey->s[1][i]= H12( i, S ); 

+            xkey->s[2][i]= H22( i, S ); 

+            xkey->s[3][i]= H32( i, S ); 

+            } 

+        break; 

+    case 3: 

+        for( i=0; i<256; i++ ) 

+            { 

+            xkey->s[0][i]= H03( i, S ); 

+            xkey->s[1][i]= H13( i, S ); 

+            xkey->s[2][i]= H23( i, S ); 

+            xkey->s[3][i]= H33( i, S ); 

+            } 

+        break; 

+    case 4: 

+        for( i=0; i<256; i++ ) 

+            { 

+            xkey->s[0][i]= H04( i, S ); 

+            xkey->s[1][i]= H14( i, S ); 

+            xkey->s[2][i]= H24( i, S ); 

+            xkey->s[3][i]= H34( i, S ); 

+            } 

+        break; 

+    default:  

+        /* This is always a coding error, which is fatal. */ 

+      Twofish_fatal( "Twofish fill_keyed_sboxes(): Illegal argument", ERR_ILL_ARG ); 

+        }

+    return SUCCESS;

+    }

+ 

+ 

+/* A flag to keep track of whether we have been initialised or not. */ 

+static int Twofish_initialised = 0; 

+ 

+/* 

+ * Initialise the Twofish implementation. 

+ * This function must be called before any other function in the 

+ * Twofish implementation is called. 

+ * This routine also does some sanity checks, to make sure that 

+ * all the macros behave, and it tests the whole cipher. 

+ */ 

+int Twofish_initialise() 

+    {

+      int ret;

+    /* First test the various platform-specific definitions. */ 

+      if ((ret = test_platform()) < 0)

+	return ret;

+ 

+    /* We can now generate our tables, in the right order of course. */ 

+    initialise_q_boxes(); 

+    initialise_mds_tables(); 

+ 

+    /* We're finished with the initialisation itself. */ 

+    Twofish_initialised = 1; 

+ 

+    /*  

+     * And run some tests on the whole cipher.  

+     * Yes, you need to do this every time you start your program.  

+     * It is called assurance; you have to be certain that your program 

+     * still works properly.  

+     */ 

+    return self_test(); 

+    } 

+ 

+ 

+/* 

+ * The Twofish key schedule uses an Reed-Solomon code matrix multiply. 

+ * Just like the MDS matrix, the RS-matrix is designed to be easy 

+ * to implement. Details are below in the code.  

+ * 

+ * These constants make it easy to compute in the finite field used  

+ * for the RS code. 

+ * 

+ * We use Bytes for the RS computation, but these are automatically 

+ * widened to unsigned integers in the expressions. Having unsigned 

+ * ints in these tables therefore provides the fastest access. 

+ */ 

+static unsigned int rs_poly_const[] = {0, 0x14d}; 

+static unsigned int rs_poly_div_const[] = {0, 0xa6 }; 

+ 

+ 

+/* 

+ * Prepare a key for use in encryption and decryption. 

+ * Like most block ciphers, Twofish allows the key schedule  

+ * to be pre-computed given only the key.  

+ * Twofish has a fairly 'heavy' key schedule that takes a lot of time  

+ * to compute. The main work is pre-computing the S-boxes used in the  

+ * encryption and decryption. We feel that this makes the cipher much  

+ * harder to attack. The attacker doesn't even know what the S-boxes  

+ * contain without including the entire key schedule in the analysis.  

+ * 

+ * Unlike most Twofish implementations, this one allows any key size from 

+ * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the  

+ * specifications); the key is simply padded with zeroes to the next real  

+ * key size of 16, 24, or 32 bytes. 

+ * Each odd-sized key is thus equivalent to a single normal-sized key. 

+ * 

+ * Arguments: 

+ * key      array of key bytes 

+ * key_len  number of bytes in the key, must be in the range 0,...,32. 

+ * xkey     Pointer to an Twofish_key structure that will be filled  

+ *             with the internal form of the cipher key. 

+ */ 

+int Twofish_prepare_key( Twofish_Byte key[], int key_len, Twofish_key * xkey ) 

+    { 

+    /* We use a single array to store all key material in,  

+     * to simplify the wiping of the key material at the end. 

+     * The first 32 bytes contain the actual (padded) cipher key. 

+     * The next 32 bytes contain the S-vector in its weird format, 

+     * and we have 4 bytes of overrun necessary for the RS-reduction. 

+     */ 

+    Twofish_Byte K[32+32+4];  

+ 

+    int kCycles;        /* # key cycles, 2,3, or 4. */ 

+ 

+    int i; 

+    Twofish_UInt32 A, B;        /* Used to compute the round keys. */ 

+ 

+    Twofish_Byte * kptr;        /* Three pointers for the RS computation. */ 

+    Twofish_Byte * sptr; 

+    Twofish_Byte * t; 

+ 

+    Twofish_Byte b,bx,bxx;      /* Some more temporaries for the RS computation. */ 

+ 

+    /* Check that the Twofish implementation was initialised. */ 

+    if( Twofish_initialised == 0 ) 

+        { 

+        /*  

+         * You didn't call Twofish_initialise before calling this routine. 

+         * This is a programming error, and therefore we call the fatal 

+         * routine.  

+         * 

+         * I could of course call the initialisation routine here, 

+         * but there are a few reasons why I don't. First of all, the  

+         * self-tests have to be done at startup. It is no good to inform 

+         * the user that the cipher implementation fails when he wants to 

+         * write his data to disk in encrypted form. You have to warn him 

+         * before he spends time typing his data. Second, the initialisation 

+         * and self test are much slower than a single key expansion. 

+         * Calling the initialisation here makes the performance of the 

+         * cipher unpredictable. This can lead to really weird problems  

+         * if you use the cipher for a real-time task. Suddenly it fails  

+         * once in a while the first time you try to use it. Things like  

+         * that are almost impossible to debug. 

+         */ 

+	  /* Twofish_fatal( "Twofish implementation was not initialised.", ERR_INIT ); */

+         

+        /* 

+         * There is always a danger that the Twofish_fatal routine returns, 

+         * in spite of the specifications that it should not.  

+         * (A good programming rule: don't trust the rest of the code.) 

+         * This would be disasterous. If the q-tables and MDS-tables have 

+         * not been initialised, they are probably still filled with zeroes. 

+         * Suppose the MDS-tables are all zero. The key expansion would then 

+         * generate all-zero round keys, and all-zero s-boxes. The danger 

+         * is that nobody would notice as the encry

+         * mangles the input, and the decryption still 'decrypts' it, 

+         * but now in a completely key-independent manner.  

+         * To stop such security disasters, we use blunt force. 

+         * If your program hangs here: fix the fatal routine! 

+         */ 

+        for(;;);        /* Infinite loop, which beats being insecure. */ 

+        } 

+ 

+    /* Check for valid key length. */ 

+    if( key_len < 0 || key_len > 32 ) 

+        { 

+        /*  

+         * This can only happen if a programmer didn't read the limitations 

+         * on the key size.  

+         */ 

+	  Twofish_fatal( "Twofish_prepare_key: illegal key length", ERR_KEY_LEN ); 

+        /*  

+         * A return statement just in case the fatal macro returns. 

+         * The rest of the code assumes that key_len is in range, and would 

+         * buffer-overflow if it wasn't.  

+         * 

+         * Why do we still use a programming language that has problems like 

+         * buffer overflows, when these problems were solved in 1960 with 

+         * the development of Algol? Have we not leared anything? 

+         */ 

+        return ERR_KEY_LEN; 

+        } 

+ 

+    /* Pad the key with zeroes to the next suitable key length. */ 

+    memcpy( K, key, key_len ); 

+    memset( K+key_len, 0, sizeof(K)-key_len ); 

+ 

+    /*  

+     * Compute kCycles: the number of key cycles used in the cipher.  

+     * 2 for 128-bit keys, 3 for 192-bit keys, and 4 for 256-bit keys. 

+     */ 

+    kCycles = (key_len + 7) >> 3; 

+    /* Handle the special case of very short keys: minimum 2 cycles. */ 

+    if( kCycles < 2 ) 

+        { 

+        kCycles = 2; 

+        } 

+ 

+    /*  

+     * From now on we just pretend to have 8*kCycles bytes of  

+     * key material in K. This handles all the key size cases.  

+     */ 

+ 

+    /*  

+     * We first compute the 40 expanded key words,  

+     * formulas straight from the Twofish specifications. 

+     */ 

+    for( i=0; i<40; i+=2 ) 

+        { 

+        /*  

+         * Due to the byte spacing expected by the h() function  

+         * we can pick the bytes directly from the key K. 

+         * As we use bytes, we never have the little/big endian 

+         * problem. 

+         * 

+         * Note that we apply the rotation function only to simple 

+         * variables, as the rotation macro might evaluate its argument 

+         * more than once. 

+         */ 

+        A = h( i  , K  , kCycles ); 

+        B = h( i+1, K+4, kCycles ); 

+        B = ROL32( B, 8 ); 

+ 

+        /* Compute and store the round keys. */ 

+        A += B; 

+        B += A; 

+        xkey->K[i]   = A; 

+        xkey->K[i+1] = ROL32( B, 9 ); 

+        } 

+ 

+    /* Wipe variables that contained key material. */ 

+    A=B=0; 

+ 

+    /*  

+     * And now the dreaded RS multiplication that few seem to understand. 

+     * The RS matrix is not random, and is specially designed to compute the 

+     * RS matrix multiplication in a simple way. 

+     * 

+     * We work in the field GF(2)[x]/x^8+x^6+x^3+x^2+1. Note that this is a 

+     * different field than used for the MDS matrix.  

+     * (At least, it is a different representation because all GF(2^8)  

+     * representations are equivalent in some form.) 

+     *  

+     * We take 8 consecutive bytes of the key and interpret them as  

+     * a polynomial k_0 + k_1 y + k_2 y^2 + ... + k_7 y^7 where  

+     * the k_i bytes are the key bytes and are elements of the finite field. 

+     * We multiply this polynomial by y^4 and reduce it modulo 

+     *     y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1.  

+     * using straightforward polynomial modulo reduction. 

+     * The coefficients of the result are the result of the RS 

+     * matrix multiplication. When we wrote the Twofish specification,  

+     * the original RS definition used the polynomials,  

+     * but that requires much more mathematical knowledge.  

+     * We were already using matrix multiplication in a finite field for  

+     * the MDS matrix, so I re-wrote the RS operation as a matrix  

+     * multiplication to reduce the difficulty of understanding it.  

+     * Some implementors have not picked up on this simpler method of 

+     * computing the RS operation, even though it is mentioned in the 

+     * specifications. 

+     * 

+     * It is possible to perform these computations faster by using 32-bit  

+     * word operations, but that is not portable and this is not a speed- 

+     * critical area. 

+     * 

+     * We explained the 1/x computation when we did the MDS matrix.  

+     * 

+     * The S vector is stored in K[32..64]. 

+     * The S vector has to be reversed, so we loop cross-wise. 

+     * 

+     * Note the weird byte spacing of the S-vector, to match the even  

+     * or odd key words arrays. See the discussion at the Hxx macros for 

+     * details. 

+     */ 

+    kptr = K + 8*kCycles;           /* Start at end of key */ 

+    sptr = K + 32;                  /* Start at start of S */ 

+ 

+    /* Loop over all key material */ 

+    while( kptr > K )  

+        { 

+        kptr -= 8; 

+        /*  

+         * Initialise the polynimial in sptr[0..12] 

+         * The first four coefficients are 0 as we have to multiply by y^4. 

+         * The next 8 coefficients are from the key material. 

+         */ 

+        memset( sptr, 0, 4 ); 

+        memcpy( sptr+4, kptr, 8 ); 

+ 

+        /*  

+         * The 12 bytes starting at sptr are now the coefficients of 

+         * the polynomial we need to reduce. 

+         */ 

+ 

+        /* Loop over the polynomial coefficients from high to low */ 

+        t = sptr+11; 

+        /* Keep looping until polynomial is degree 3; */ 

+        while( t > sptr+3 ) 

+            { 

+            /* Pick up the highest coefficient of the poly. */ 

+            b = *t; 

+ 

+            /*  

+             * Compute x and (x+1/x) times this coefficient.  

+             * See the MDS matrix implementation for a discussion of  

+             * multiplication by x and 1/x. We just use different  

+             * constants here as we are in a  

+             * different finite field representation. 

+             * 

+             * These two statements set  

+             * bx = (x) * b  

+             * bxx= (x + 1/x) * b 

+             */ 

+            bx = (Twofish_Byte)((b<<1) ^ rs_poly_const[ b>>7 ]); 

+            bxx= (Twofish_Byte)((b>>1) ^ rs_poly_div_const[ b&1 ] ^ bx); 

+ 

+            /* 

+             * Subtract suitable multiple of  

+             * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1  

+             * from the polynomial, except that we don't bother 

+             * updating t[0] as it will become zero anyway. 

+             */ 

+            t[-1] ^= bxx; 

+            t[-2] ^= bx; 

+            t[-3] ^= bxx; 

+            t[-4] ^= b; 

+             

+            /* Go to the next coefficient. */ 

+            t--; 

+            } 

+ 

+        /* Go to next S-vector word, obeying the weird spacing rules. */ 

+        sptr += 8; 

+        } 

+ 

+    /* Wipe variables that contained key material. */ 

+    b = bx = bxx = 0; 

+ 

+    /* And finally, we can compute the key-dependent S-boxes. */ 

+    fill_keyed_sboxes( &K[32], kCycles, xkey ); 

+ 

+    /* Wipe array that contained key material. */ 

+    memset( K, 0, sizeof( K ) );

+    return SUCCESS;

+    } 

+ 

+ 

+/* 

+ * We can now start on the actual encryption and decryption code. 

+ * As these are often speed-critical we will use a lot of macros. 

+ */ 

+ 

+/* 

+ * The g() function is the heart of the round function. 

+ * We have two versions of the g() function, one without an input 

+ * rotation and one with. 

+ * The pre-computed S-boxes make this pretty simple. 

+ */ 

+#define g0(X,xkey) \

+ (xkey->s[0][b0(X)]^xkey->s[1][b1(X)]^xkey->s[2][b2(X)]^xkey->s[3][b3(X)]) 

+ 

+#define g1(X,xkey) \

+ (xkey->s[0][b3(X)]^xkey->s[1][b0(X)]^xkey->s[2][b1(X)]^xkey->s[3][b2(X)]) 

+ 

+/* 

+ * A single round of Twofish. The A,B,C,D are the four state variables, 

+ * T0 and T1 are temporaries, xkey is the expanded key, and r the  

+ * round number. 

+ * 

+ * Note that this macro does not implement the swap at the end of the round. 

+ */ 

+#define ENCRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \

+    T0 = g0(A,xkey); T1 = g1(B,xkey);\

+    C ^= T0+T1+xkey->K[8+2*(r)]; C = ROR32(C,1);\

+    D = ROL32(D,1); D ^= T0+2*T1+xkey->K[8+2*(r)+1] 

+ 

+/* 

+ * Encrypt a single cycle, consisting of two rounds. 

+ * This avoids the swapping of the two halves.  

+ * Parameter r is now the cycle number. 

+ */ 

+#define ENCRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \

+    ENCRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)   );\

+    ENCRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)+1 )

+ 

+/* Full 16-round encryption */ 

+#define ENCRYPT( A,B,C,D,T0,T1,xkey ) \

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 );\

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\

+    ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 )

+ 

+/* 

+ * A single round of Twofish for decryption. It differs from 

+ * ENCRYTP_RND only because of the 1-bit rotations. 

+ */ 

+#define DECRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \

+    T0 = g0(A,xkey); T1 = g1(B,xkey);\

+    C = ROL32(C,1); C ^= T0+T1+xkey->K[8+2*(r)];\

+    D ^= T0+2*T1+xkey->K[8+2*(r)+1]; D = ROR32(D,1)

+ 

+/* 

+ * Decrypt a single cycle, consisting of two rounds.  

+ * This avoids the swapping of the two halves.  

+ * Parameter r is now the cycle number. 

+ */ 

+#define DECRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \

+    DECRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)+1 );\

+    DECRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)   )

+ 

+/* Full 16-round decryption. */ 

+#define DECRYPT( A,B,C,D,T0,T1, xkey ) \

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 );\

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\

+    DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 ) 

+

+/* 

+ * A macro to read the state from the plaintext and do the initial key xors. 

+ * The koff argument allows us to use the same macro  

+ * for the decryption which uses different key words at the start. 

+ */ 

+#define GET_INPUT( src, A,B,C,D, xkey, koff ) \

+    A = GET32(src   )^xkey->K[  koff]; B = GET32(src+ 4)^xkey->K[1+koff]; \

+    C = GET32(src+ 8)^xkey->K[2+koff]; D = GET32(src+12)^xkey->K[3+koff]

+ 

+/* 

+ * Similar macro to put the ciphertext in the output buffer. 

+ * We xor the keys into the state variables before we use the PUT32  

+ * macro as the macro might use its argument multiple times. 

+ */ 

+#define PUT_OUTPUT( A,B,C,D, dst, xkey, koff ) \

+    A ^= xkey->K[  koff]; B ^= xkey->K[1+koff]; \

+    C ^= xkey->K[2+koff]; D ^= xkey->K[3+koff]; \

+    PUT32( A, dst   ); PUT32( B, dst+ 4 ); \

+    PUT32( C, dst+8 ); PUT32( D, dst+12 )

+ 

+ 

+/* 

+ * Twofish block encryption 

+ * 

+ * Arguments: 

+ * xkey         expanded key array 

+ * p            16 bytes of plaintext 

+ * c            16 bytes in which to store the ciphertext 

+ */ 

+void Twofish_encrypt( Twofish_key * xkey, Twofish_Byte p[16], Twofish_Byte c[16]) 

+    { 

+    Twofish_UInt32 A,B,C,D,T0,T1;       /* Working variables */ 

+ 

+    /* Get the four plaintext words xorred with the key */ 

+    GET_INPUT( p, A,B,C,D, xkey, 0 ); 

+ 

+    /* Do 8 cycles (= 16 rounds) */ 

+    ENCRYPT( A,B,C,D,T0,T1,xkey ); 

+ 

+    /* Store them with the final swap and the output whitening. */ 

+    PUT_OUTPUT( C,D,A,B, c, xkey, 4 ); 

+    } 

+ 

+ 

+/* 

+ * Twofish block decryption. 

+ * 

+ * Arguments: 

+ * xkey         expanded key array 

+ * p            16 bytes of plaintext 

+ * c            16 bytes in which to store the ciphertext 

+ */ 

+void Twofish_decrypt( Twofish_key * xkey, Twofish_Byte c[16], Twofish_Byte p[16]) 

+    { 

+    Twofish_UInt32 A,B,C,D,T0,T1;       /* Working variables */ 

+ 

+    /* Get the four plaintext words xorred with the key */ 

+    GET_INPUT( c, A,B,C,D, xkey, 4 ); 

+ 

+    /* Do 8 cycles (= 16 rounds) */ 

+    DECRYPT( A,B,C,D,T0,T1,xkey ); 

+ 

+    /* Store them with the final swap and the output whitening. */ 

+    PUT_OUTPUT( C,D,A,B, p, xkey, 0 ); 

+    } 

+ 

+/* 

+ * Using the macros it is easy to make special routines for 

+ * CBC mode, CTR mode etc. The only thing you might want to 

+ * add is a XOR_PUT_OUTPUT which xors the outputs into the 

+ * destinationa instead of overwriting the data. This requires 

+ * a XOR_PUT32 macro as well, but that should all be trivial. 

+ * 

+ * I thought about including routines for the separate cipher 

+ * modes here, but it is unclear which modes should be included, 

+ * and each encryption or decryption routine takes up a lot of code space. 

+ * Also, I don't have any test vectors for any cipher modes 

+ * with Twofish. 

+ */ 

+

+

diff --git a/jni/libzrtp/sources/cryptcommon/twofish.h b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.h
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/twofish.h
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.h
index 21d7e96..0c8b0d7 100755
--- a/jni/libzrtp/sources/cryptcommon/twofish.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish.h
@@ -1,265 +1,265 @@
-/* 
- * Fast, portable, and easy-to-use Twofish implementation,  
- * Version 0.3. 
- * Copyright (c) 2002 by Niels Ferguson. 
- * 
- * See the twofish.c file for the details of the how and why of this code. 
- * 
- * The author hereby grants a perpetual license to everybody to 
- * use this code for any purpose as long as the copyright message is included 
- * in the source code of this or any derived work. 
- */ 
- 
- 
-/* 
- * PLATFORM FIXES 
- * ============== 
- * 
- * The following definitions have to be fixed for each particular platform  
- * you work on. If you have a multi-platform program, you no doubt have  
- * portable definitions that you can substitute here without changing  
- * the rest of the code. 
- * 
- * The defaults provided here should work on most PC compilers. 
- */ 
- 
-#ifndef TWOFISH_H
-#define TWOFISH_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @file twofish.h
- * @brief Function that provide basic Twofish crypto support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
- 
-/**
- * A Twofish_Byte must be an unsigned 8-bit integer.
- *
- * It must also be the elementary data size of your C platform, 
- * i.e. sizeof( Twofish_Byte ) == 1. 
- */ 
-typedef unsigned char   Twofish_Byte; 
- 
-/**
- * A Twofish_UInt32 must be an unsigned integer of at least 32 bits.  
- *  
- * This type is used only internally in the implementation, so ideally it 
- * would not appear in the header file, but it is used inside the 
- * Twofish_key structure which means it has to be included here. 
- */ 
-typedef unsigned int    Twofish_UInt32; 
- 
- 
-/* 
- * END OF PLATFORM FIXES 
- * ===================== 
- *  
- * You should not have to touch the rest of this file, but the code 
- * in twofish.c has a few things you need to fix too. 
- */ 
-
-/**
- * Return  codes
- */
-#define SUCCESS          1
-#define ERR_UINT32      -2
-#define ERR_BYTE        -3
-#define ERR_GET32       -4
-#define ERR_PUT32       -5
-#define ERR_ROLR        -6
-#define ERR_BSWAP       -7
-#define ERR_SELECTB     -8
-#define ERR_TEST_ENC    -9
-#define ERR_TEST_DEC   -10
-#define ERR_SEQ_ENC    -11
-#define ERR_SEQ_DEC    -12
-#define ERR_ODD_KEY    -13
-#define ERR_INIT       -14
-#define ERR_KEY_LEN    -15
-#define ERR_ILL_ARG    -16
-
-
-/**
- * Structure that contains a prepared Twofish key.
- *
- * A cipher key is used in two stages. In the first stage it is converted 
- * form the original form to an internal representation.  
- * This internal form is then used to encrypt and decrypt data.  
- * This structure contains the internal form. It is rather large: 4256 bytes 
- * on a platform with 32-bit unsigned values. 
- * 
- * Treat this as an opague structure, and don't try to manipulate the 
- * elements in it. I wish I could hide the inside of the structure, 
- * but C doesn't allow that. 
- */ 
-typedef 
-    struct
-        {
-        Twofish_UInt32 s[4][256];   /* pre-computed S-boxes */ 
-        Twofish_UInt32 K[40];       /* Round key words */ 
-        }
-    Twofish_key; 
-
-
-/**
- * Initialise and test the Twofish implementation.  
- *  
- * This function MUST be called before any other function in the  
- * Twofish implementation is called. 
- * It only needs to be called once. 
- *  
- * Apart from initialising the implementation it performs a self test. 
- * If the Twofish_fatal function is not called, the code passed the test. 
- * (See the twofish.c file for details on the Twofish_fatal function.)
- *
- * @returns a negative number if an error happend, +1 otherwise
- */ 
-extern int Twofish_initialise(); 
- 
- 
-/**
- * Convert a cipher key to the internal form used for  
- * encryption and decryption. 
- *  
- * The cipher key is an array of bytes; the Twofish_Byte type is  
- * defined above to a type suitable on your platform.  
- * 
- * Any key must be converted to an internal form in the Twofisk_key structure 
- * before it can be used. 
- * The encryption and decryption functions only work with the internal form. 
- * The conversion to internal form need only be done once for each key value. 
- * 
- * Be sure to wipe all key storage, including the Twofish_key structure,  
- * once you are done with the key data.  
- * A simple memset( TwofishKey, 0, sizeof( TwofishKey ) ) will do just fine. 
- * 
- * Unlike most implementations, this one allows any key size from 0 bytes  
- * to 32 bytes. According to the Twofish specifications,  
- * irregular key sizes are handled by padding the key with zeroes at the end  
- * until the key size is 16, 24, or 32 bytes, whichever 
- * comes first. Note that each key of irregular size is equivalent to exactly 
- * one key of 16, 24, or 32 bytes. 
- * 
- * WARNING: Short keys have low entropy, and result in low security. 
- * Anything less than 8 bytes is utterly insecure. For good security 
- * use at least 16 bytes. I prefer to use 32-byte keys to prevent 
- * any collision attacks on the key. 
- * 
- * The key length argument key_len must be in the proper range. 
- * If key_len is not in the range 0,...,32 this routine attempts to generate  
- * a fatal error (depending on the code environment),  
- * and at best (or worst) returns without having done anything. 
- * 
- * @param key      Array of key bytes 
- * @param key_len  Number of key bytes, must be in the range 0,1,...,32.  
- * @param xkey     Pointer to an Twofish_key structure that will be filled  
- *                 with the internal form of the cipher key.
- * @returns a negative number if an error happend, +1 otherwise
- */ 
-extern int Twofish_prepare_key(
-                                Twofish_Byte key[],
-                                int key_len,
-                                Twofish_key * xkey
-                                );
-
-
-/**
- * Encrypt a single block of data. 
- * 
- * This function encrypts a single block of 16 bytes of data. 
- * If you want to encrypt a larger or variable-length message,  
- * you will have to use a cipher mode, such as CBC or CTR.  
- * These are outside the scope of this implementation. 
- * 
- * The xkey structure is not modified by this routine, and can be 
- * used for further encryption and decryption operations. 
- * 
- * @param xkey     pointer to Twofish_key, internal form of the key 
- *                 produces by Twofish_prepare_key() 
- * @param p        Plaintext to be encrypted 
- * @param c        Place to store the ciphertext 
- */ 
-extern void Twofish_encrypt(
-                            Twofish_key * xkey,
-                            Twofish_Byte p[16],
-                            Twofish_Byte c[16]
-                            ); 
-
-
-/**
- * Decrypt a single block of data. 
- * 
- * This function decrypts a single block of 16 bytes of data. 
- * If you want to decrypt a larger or variable-length message,  
- * you will have to use a cipher mode, such as CBC or CTR.  
- * These are outside the scope of this implementation. 
- * 
- * The xkey structure is not modified by this routine, and can be 
- * used for further encryption and decryption operations. 
- * 
- * @param xkey     pointer to Twofish_key, internal form of the key 
- *                 produces by Twofish_prepare_key() 
- * @param c        Ciphertext to be decrypted 
- * @param p        Place to store the plaintext 
- */ 
-extern void Twofish_decrypt(
-                            Twofish_key * xkey,
-                            Twofish_Byte c[16],
-                            Twofish_Byte p[16]
-                            ); 
-
-
-/**
- * Encrypt data in CFB mode. 
- * 
- * This function encrypts data in CFB mode.
- *
- * The key structure is not modified by this routine, and can be 
- * used for further encryption and decryption operations. 
- * 
- * @param keyCtx   pointer to Twofish_key, internal form of the key 
- *                 produced by Twofish_prepare_key() 
- * @param in       Plaintext to be encrypted 
- * @param out      Place to store the ciphertext 
- * @param len      number of bytes to encrypt.
- * @param ivec     initialization vector for this CFB mode encryption.
- * @param num      pointer to integer that holds number of available crypto bytes.
- */
-void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in,
-                            Twofish_Byte* out, size_t len,
-                            Twofish_Byte* ivec, int *num);
-
-/**
- * Decrypt data in CFB mode. 
- * 
- * This function decrypts data in CFB. 
- *
- * The key structure is not modified by this routine, and can be 
- * used for further encryption and decryption operations. 
- * 
- * @param keyCtx   pointer to Twofish_key, internal form of the key 
- *                 produced by Twofish_prepare_key() 
- * @param in       Ciphertext to be decrypted 
- * @param out      Place to store the plaintext 
- * @param len      number of bytes to decrypt.
- * @param ivec     initialization vector for this CFB mode encryption.
- * @param num      pointer to integer that holds number of available crypto bytes.
- */ 
-void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in,
-                            Twofish_Byte* out, size_t len,
-                            Twofish_Byte* ivec, int *num);
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/* 

+ * Fast, portable, and easy-to-use Twofish implementation,  

+ * Version 0.3. 

+ * Copyright (c) 2002 by Niels Ferguson. 

+ * 

+ * See the twofish.c file for the details of the how and why of this code. 

+ * 

+ * The author hereby grants a perpetual license to everybody to 

+ * use this code for any purpose as long as the copyright message is included 

+ * in the source code of this or any derived work. 

+ */ 

+ 

+ 

+/* 

+ * PLATFORM FIXES 

+ * ============== 

+ * 

+ * The following definitions have to be fixed for each particular platform  

+ * you work on. If you have a multi-platform program, you no doubt have  

+ * portable definitions that you can substitute here without changing  

+ * the rest of the code. 

+ * 

+ * The defaults provided here should work on most PC compilers. 

+ */ 

+ 

+#ifndef TWOFISH_H

+#define TWOFISH_H

+

+#ifdef __cplusplus

+extern "C"

+{

+#endif

+

+/**

+ * @file twofish.h

+ * @brief Function that provide basic Twofish crypto support

+ * 

+ * @ingroup GNU_ZRTP

+ * @{

+ */

+ 

+/**

+ * A Twofish_Byte must be an unsigned 8-bit integer.

+ *

+ * It must also be the elementary data size of your C platform, 

+ * i.e. sizeof( Twofish_Byte ) == 1. 

+ */ 

+typedef unsigned char   Twofish_Byte; 

+ 

+/**

+ * A Twofish_UInt32 must be an unsigned integer of at least 32 bits.  

+ *  

+ * This type is used only internally in the implementation, so ideally it 

+ * would not appear in the header file, but it is used inside the 

+ * Twofish_key structure which means it has to be included here. 

+ */ 

+typedef unsigned int    Twofish_UInt32; 

+ 

+ 

+/* 

+ * END OF PLATFORM FIXES 

+ * ===================== 

+ *  

+ * You should not have to touch the rest of this file, but the code 

+ * in twofish.c has a few things you need to fix too. 

+ */ 

+

+/**

+ * Return  codes

+ */

+#define SUCCESS          1

+#define ERR_UINT32      -2

+#define ERR_BYTE        -3

+#define ERR_GET32       -4

+#define ERR_PUT32       -5

+#define ERR_ROLR        -6

+#define ERR_BSWAP       -7

+#define ERR_SELECTB     -8

+#define ERR_TEST_ENC    -9

+#define ERR_TEST_DEC   -10

+#define ERR_SEQ_ENC    -11

+#define ERR_SEQ_DEC    -12

+#define ERR_ODD_KEY    -13

+#define ERR_INIT       -14

+#define ERR_KEY_LEN    -15

+#define ERR_ILL_ARG    -16

+

+

+/**

+ * Structure that contains a prepared Twofish key.

+ *

+ * A cipher key is used in two stages. In the first stage it is converted 

+ * form the original form to an internal representation.  

+ * This internal form is then used to encrypt and decrypt data.  

+ * This structure contains the internal form. It is rather large: 4256 bytes 

+ * on a platform with 32-bit unsigned values. 

+ * 

+ * Treat this as an opague structure, and don't try to manipulate the 

+ * elements in it. I wish I could hide the inside of the structure, 

+ * but C doesn't allow that. 

+ */ 

+typedef 

+    struct

+        {

+        Twofish_UInt32 s[4][256];   /* pre-computed S-boxes */ 

+        Twofish_UInt32 K[40];       /* Round key words */ 

+        }

+    Twofish_key; 

+

+

+/**

+ * Initialise and test the Twofish implementation.  

+ *  

+ * This function MUST be called before any other function in the  

+ * Twofish implementation is called. 

+ * It only needs to be called once. 

+ *  

+ * Apart from initialising the implementation it performs a self test. 

+ * If the Twofish_fatal function is not called, the code passed the test. 

+ * (See the twofish.c file for details on the Twofish_fatal function.)

+ *

+ * @returns a negative number if an error happend, +1 otherwise

+ */ 

+extern int Twofish_initialise(); 

+ 

+ 

+/**

+ * Convert a cipher key to the internal form used for  

+ * encryption and decryption. 

+ *  

+ * The cipher key is an array of bytes; the Twofish_Byte type is  

+ * defined above to a type suitable on your platform.  

+ * 

+ * Any key must be converted to an internal form in the Twofisk_key structure 

+ * before it can be used. 

+ * The encryption and decryption functions only work with the internal form. 

+ * The conversion to internal form need only be done once for each key value. 

+ * 

+ * Be sure to wipe all key storage, including the Twofish_key structure,  

+ * once you are done with the key data.  

+ * A simple memset( TwofishKey, 0, sizeof( TwofishKey ) ) will do just fine. 

+ * 

+ * Unlike most implementations, this one allows any key size from 0 bytes  

+ * to 32 bytes. According to the Twofish specifications,  

+ * irregular key sizes are handled by padding the key with zeroes at the end  

+ * until the key size is 16, 24, or 32 bytes, whichever 

+ * comes first. Note that each key of irregular size is equivalent to exactly 

+ * one key of 16, 24, or 32 bytes. 

+ * 

+ * WARNING: Short keys have low entropy, and result in low security. 

+ * Anything less than 8 bytes is utterly insecure. For good security 

+ * use at least 16 bytes. I prefer to use 32-byte keys to prevent 

+ * any collision attacks on the key. 

+ * 

+ * The key length argument key_len must be in the proper range. 

+ * If key_len is not in the range 0,...,32 this routine attempts to generate  

+ * a fatal error (depending on the code environment),  

+ * and at best (or worst) returns without having done anything. 

+ * 

+ * @param key      Array of key bytes 

+ * @param key_len  Number of key bytes, must be in the range 0,1,...,32.  

+ * @param xkey     Pointer to an Twofish_key structure that will be filled  

+ *                 with the internal form of the cipher key.

+ * @returns a negative number if an error happend, +1 otherwise

+ */ 

+extern int Twofish_prepare_key(

+                                Twofish_Byte key[],

+                                int key_len,

+                                Twofish_key * xkey

+                                );

+

+

+/**

+ * Encrypt a single block of data. 

+ * 

+ * This function encrypts a single block of 16 bytes of data. 

+ * If you want to encrypt a larger or variable-length message,  

+ * you will have to use a cipher mode, such as CBC or CTR.  

+ * These are outside the scope of this implementation. 

+ * 

+ * The xkey structure is not modified by this routine, and can be 

+ * used for further encryption and decryption operations. 

+ * 

+ * @param xkey     pointer to Twofish_key, internal form of the key 

+ *                 produces by Twofish_prepare_key() 

+ * @param p        Plaintext to be encrypted 

+ * @param c        Place to store the ciphertext 

+ */ 

+extern void Twofish_encrypt(

+                            Twofish_key * xkey,

+                            Twofish_Byte p[16],

+                            Twofish_Byte c[16]

+                            ); 

+

+

+/**

+ * Decrypt a single block of data. 

+ * 

+ * This function decrypts a single block of 16 bytes of data. 

+ * If you want to decrypt a larger or variable-length message,  

+ * you will have to use a cipher mode, such as CBC or CTR.  

+ * These are outside the scope of this implementation. 

+ * 

+ * The xkey structure is not modified by this routine, and can be 

+ * used for further encryption and decryption operations. 

+ * 

+ * @param xkey     pointer to Twofish_key, internal form of the key 

+ *                 produces by Twofish_prepare_key() 

+ * @param c        Ciphertext to be decrypted 

+ * @param p        Place to store the plaintext 

+ */ 

+extern void Twofish_decrypt(

+                            Twofish_key * xkey,

+                            Twofish_Byte c[16],

+                            Twofish_Byte p[16]

+                            ); 

+

+

+/**

+ * Encrypt data in CFB mode. 

+ * 

+ * This function encrypts data in CFB mode.

+ *

+ * The key structure is not modified by this routine, and can be 

+ * used for further encryption and decryption operations. 

+ * 

+ * @param keyCtx   pointer to Twofish_key, internal form of the key 

+ *                 produced by Twofish_prepare_key() 

+ * @param in       Plaintext to be encrypted 

+ * @param out      Place to store the ciphertext 

+ * @param len      number of bytes to encrypt.

+ * @param ivec     initialization vector for this CFB mode encryption.

+ * @param num      pointer to integer that holds number of available crypto bytes.

+ */

+void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in,

+                            Twofish_Byte* out, size_t len,

+                            Twofish_Byte* ivec, int *num);

+

+/**

+ * Decrypt data in CFB mode. 

+ * 

+ * This function decrypts data in CFB. 

+ *

+ * The key structure is not modified by this routine, and can be 

+ * used for further encryption and decryption operations. 

+ * 

+ * @param keyCtx   pointer to Twofish_key, internal form of the key 

+ *                 produced by Twofish_prepare_key() 

+ * @param in       Ciphertext to be decrypted 

+ * @param out      Place to store the plaintext 

+ * @param len      number of bytes to decrypt.

+ * @param ivec     initialization vector for this CFB mode encryption.

+ * @param num      pointer to integer that holds number of available crypto bytes.

+ */ 

+void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in,

+                            Twofish_Byte* out, size_t len,

+                            Twofish_Byte* ivec, int *num);

+/**

+ * @}

+ */

+#ifdef __cplusplus

+}

+#endif

+

+#endif

diff --git a/jni/libzrtp/sources/cryptcommon/twofish_cfb.c b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish_cfb.c
similarity index 66%
rename from jni/libzrtp/sources/cryptcommon/twofish_cfb.c
rename to jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish_cfb.c
index 241b956..7540738 100755
--- a/jni/libzrtp/sources/cryptcommon/twofish_cfb.c
+++ b/jni/libzrtp/sources/src/libzrtpcpp/crypto/twofish_cfb.c
@@ -1,94 +1,82 @@
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "twofish.h"
-
-void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in, 
-			    Twofish_Byte* out, size_t len,
-			    Twofish_Byte* ivec, int32_t *num)
-{
-  uint32_t n;
-
-  n = *num;
-
-  do {
-    while (n && len) {
-      *(out++) = ivec[n] ^= *(in++);
-      --len;
-      n = (n+1) % 16;
-    }
-    while (len>=16) {
-      Twofish_encrypt(keyCtx, ivec, ivec);
-      for (n=0; n<16; n+=sizeof(size_t)) {
-
-/*
- * Some GCC version(s) of Android's NDK produce code that leads to a crash (SIGBUS). The
- * offending line if the line that produces the output by xor'ing the ivec. Somehow the
- * compiler/optimizer seems to incorrectly setup the pointers. Adding a call to an
- * external function that uses the pointer disabled or modifies this optimzing
- * behaviour. This debug functions as such does nothing, it just disables some
- * optimization. Don't use a local (static) function - the compiler sees that it does
- * nothing and optimizes again :-) .
- */
-#ifdef ANDROID
-          Two_debugDummy(in, out, ivec);
-#endif
-          *(size_t*)(out+n) = *(size_t*)(ivec+n) ^= *(size_t*)(in+n);;
-      }
-      len -= 16;
-      out += 16;
-      in  += 16;
-    }
-    n = 0;
-    if (len) {
-      Twofish_encrypt(keyCtx, ivec, ivec);
-      while (len--) {
-          out[n] = ivec[n] ^= in[n];
-          ++n;
-      }
-    }
-    *num = n;
-    return;
-  } while (0);
-}
-
-
-void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in, 
-			    Twofish_Byte* out, size_t len,
-			    Twofish_Byte* ivec, int32_t *num)
-{
-  uint32_t n;
-
-  n = *num;
-
-  do {
-    while (n && len) {
-      unsigned char c;
-      *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
-      --len;
-      n = (n+1) % 16;
-    }
-    while (len>=16) {
-      Twofish_encrypt(keyCtx, ivec, ivec);
-      for (n=0; n<16; n+=sizeof(size_t)) {
-	size_t t = *(size_t*)(in+n);
-	*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
-	*(size_t*)(ivec+n) = t;
-      }
-      len -= 16;
-      out += 16;
-      in  += 16;
-    }
-    n = 0;
-    if (len) {
-      Twofish_encrypt(keyCtx, ivec, ivec);
-      while (len--) {
-	unsigned char c;
-	out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;
-	++n;
-      }
-    }
-    *num = n;
-    return;
-  } while (0);
-}
+#include <stdint.h>

+#include <stdlib.h>

+

+#include "twofish.h"

+

+void Twofish_cfb128_encrypt(Twofish_key* keyCtx, Twofish_Byte* in, 

+			    Twofish_Byte* out, size_t len,

+			    Twofish_Byte* ivec, int32_t *num)

+{

+  uint32_t n;

+

+  n = *num;

+

+  do {

+    while (n && len) {

+      *(out++) = ivec[n] ^= *(in++);

+      --len;

+      n = (n+1) % 16;

+    }

+    while (len>=16) {

+      Twofish_encrypt(keyCtx, ivec, ivec);

+      for (n=0; n<16; n+=sizeof(size_t)) {

+	*(size_t*)(out+n) =

+	  *(size_t*)(ivec+n) ^= *(size_t*)(in+n);

+      }

+      len -= 16;

+      out += 16;

+      in  += 16;

+    }

+    n = 0;

+    if (len) {

+      Twofish_encrypt(keyCtx, ivec, ivec);

+      while (len--) {

+	out[n] = ivec[n] ^= in[n];

+	++n;

+      }

+    }

+    *num = n;

+    return;

+  } while (0);

+}

+

+

+void Twofish_cfb128_decrypt(Twofish_key* keyCtx, Twofish_Byte* in, 

+			    Twofish_Byte* out, size_t len,

+			    Twofish_Byte* ivec, int32_t *num)

+{

+  uint32_t n;

+

+  n = *num;

+

+  do {

+    while (n && len) {

+      unsigned char c;

+      *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;

+      --len;

+      n = (n+1) % 16;

+    }

+    while (len>=16) {

+      Twofish_encrypt(keyCtx, ivec, ivec);

+      for (n=0; n<16; n+=sizeof(size_t)) {

+	size_t t = *(size_t*)(in+n);

+	*(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;

+	*(size_t*)(ivec+n) = t;

+      }

+      len -= 16;

+      out += 16;

+      in  += 16;

+    }

+    n = 0;

+    if (len) {

+      Twofish_encrypt(keyCtx, ivec, ivec);

+      while (len--) {

+	unsigned char c;

+	out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c;

+	++n;

+      }

+    }

+    *num = n;

+    return;

+  } while (0);

+}

diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h b/jni/libzrtp/sources/src/libzrtpcpp/zrtpPacket.h
similarity index 98%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
rename to jni/libzrtp/sources/src/libzrtpcpp/zrtpPacket.h
index f01fb52..18ba7a1 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpPacket.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/zrtpPacket.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h b/jni/libzrtp/sources/src/libzrtpcpp/zrtpccrtp.h
similarity index 98%
rename from jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h
rename to jni/libzrtp/sources/src/libzrtpcpp/zrtpccrtp.h
index 3eae183..d94ca5a 100644
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpccrtp.h
+++ b/jni/libzrtp/sources/src/libzrtpcpp/zrtpccrtp.h
@@ -19,7 +19,7 @@
 #define _ZRTPCCRTP_H_
 
 #include <ccrtp/rtp.h>
-#include <ZrtpQueue.h>
+#include <libzrtpcpp/ZrtpQueue.h>
 
 NAMESPACE_COMMONCPP
 
diff --git a/jni/libzrtp/sources/srtp/CryptoContext.cpp b/jni/libzrtp/sources/srtp/CryptoContext.cpp
index 89eb699..d486f86 100644
--- a/jni/libzrtp/sources/srtp/CryptoContext.cpp
+++ b/jni/libzrtp/sources/srtp/CryptoContext.cpp
@@ -1,6 +1,4 @@
 /*
-  Copyright (C) 2006 - 2012 Werner Dittmann
-
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
@@ -16,20 +14,22 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
 
-/*
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+/* Copyright (C) 2004-2012
+ *
+ * Authors: Israel Abad <i_abad@terra.es>
+ *          Erik Eliasson <eliasson@it.kth.se>
+ *          Johan Bilien <jobi@via.ecp.fr>
+ *          Joachim Orrblad <joachim@orrblad.com>
+ *          Werner Dittmann <Werner.Dittmann@t-online.de>
  */
 
 #include <string.h>
+#include <arpa/inet.h>
 #include <stdio.h>
-#include <stdint.h>
-
-#include <common/osSpecifics.h>
 
 #include <CryptoContext.h>
-#include <crypto/SrtpSymCrypto.h>
 #include <crypto/hmac.h>
-#include <cryptcommon/macSkein.h>
+#include <crypto/macSkein.h>
 
 CryptoContext::CryptoContext( uint32_t ssrc,
                               int32_t roc,
@@ -45,10 +45,11 @@
                               int32_t skeyl,
                               int32_t tagLength):
 
-        ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL), roc(roc),guessed_roc(0),
-        s_l(0),key_deriv_rate(key_deriv_rate), replay_window(0), master_key_srtp_use_nb(0),
-        master_key_srtcp_use_nb(0), labelBase(0), seqNumSet(false), macCtx(NULL), cipher(NULL),
-        f8Cipher(NULL)
+        ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL),
+        roc(roc),guessed_roc(0),s_l(0),key_deriv_rate(key_deriv_rate),
+        replay_window(0),
+        master_key_srtp_use_nb(0), master_key_srtcp_use_nb(0), seqNumSet(false),
+        macCtx(NULL), cipher(NULL), f8Cipher(NULL)
 {
     this->ealg = ealg;
     this->aalg = aalg;
@@ -188,7 +189,7 @@
             iv[i] = (0xFF & (ssrc >> ((7-i)*8))) ^ k_s[i];
         }
         for (i = 8; i < 14; i++ ) {
-            iv[i] = (0xFF & (unsigned char)(index >> ((13-i)*8) ) ) ^ k_s[i];
+            iv[i] = (0xFF & (unsigned char)( index >> ((13-i)*8) ) ) ^ k_s[i];
         }
         iv[14] = iv[15] = 0;
 
@@ -212,7 +213,7 @@
         iv[0] = 0;
 
         // set ROC in network order into IV
-        ui32p[3] = zrtpHtonl(roc);
+        ui32p[3] = htonl(roc);
 
         cipher->f8_encrypt(payload, paylen, iv, f8Cipher);
     }
@@ -230,7 +231,7 @@
     unsigned char temp[20];
     const unsigned char* chunks[3];
     unsigned int chunkLength[3];
-    uint32_t beRoc = zrtpHtonl(roc);
+    uint32_t beRoc = htonl(roc);
 
     chunks[0] = pkt;
     chunkLength[0] = pktlen;
@@ -288,8 +289,10 @@
     }
 
     for (i = 7; i < 14 ; i++ ) {
-        iv[i] = (unsigned char)(0xFF & (key_id >> (8*(13-i)))) ^  master_salt[i];
+        iv[i] = (unsigned char)(0xFF & (key_id >> (8*(13-i)))) ^
+                master_salt[i];
     }
+
     iv[14] = iv[15] = 0;
 }
 
@@ -298,17 +301,17 @@
 {
     uint8_t iv[16];
 
-    // prepare cipher to compute derived keys.
+    // prepare AES cipher to compute derived keys.
     cipher->setNewKey(master_key, master_key_length);
     memset(master_key, 0, master_key_length);
 
     // compute the session encryption key
-    uint64_t label = labelBase + 0;
+    uint64_t label = 0;
     computeIv(iv, label, index, key_deriv_rate, master_salt);
     cipher->get_ctr_cipher_stream(k_e, n_e, iv);
 
     // compute the session authentication key
-    label = labelBase + 0x01;
+    label = 0x01;
     computeIv(iv, label, index, key_deriv_rate, master_salt);
     cipher->get_ctr_cipher_stream(k_a, n_a, iv);
 
@@ -325,12 +328,12 @@
     memset(k_a, 0, n_a);
 
     // compute the session salt
-    label = labelBase + 0x02;
+    label = 0x02;
     computeIv(iv, label, index, key_deriv_rate, master_salt);
     cipher->get_ctr_cipher_stream(k_s, n_s, iv);
     memset(master_salt, 0, master_salt_length);
 
-    // as last step prepare cipher with derived key.
+    // as last step prepare AES cipher with derived key.
     cipher->setNewKey(k_e, n_e);
     if (f8Cipher != NULL)
         cipher->f8_deriveForIV(f8Cipher, k_e, n_e, k_s, n_s);
@@ -388,18 +391,22 @@
 
     int64_t delta = guessed_index - local_index;
     if (delta > 0) {
-        return true;           /* Packet not yet received*/
+        /* Packet not yet received*/
+        return true;
     }
     else {
-        if ( -delta >= REPLAY_WINDOW_SIZE ) {
-            return false;      /* Packet too old */
+        if ( -delta > REPLAY_WINDOW_SIZE ) {
+            /* Packet too old */
+            return false;
         }
         else {
             if ((replay_window >> (-delta)) & 0x1) {
-                return false;  /* Packet already received ! */
+                /* Packet already received ! */
+                return false;
             }
             else {
-                return true;  /* Packet not yet received */
+                /* Packet not yet received */
+                return true;
             }
         }
     }
@@ -447,3 +454,12 @@
 
     return pcc;
 }
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/CryptoContext.h b/jni/libzrtp/sources/srtp/CryptoContext.h
index 25c3a08..3075bf5 100644
--- a/jni/libzrtp/sources/srtp/CryptoContext.h
+++ b/jni/libzrtp/sources/srtp/CryptoContext.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2006 - 2012 Werner Dittmann
+  Copyright (C) 2004-2006 the Minisip Team
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -16,6 +16,8 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
 
+
+
 #ifndef CRYPTOCONTEXT_H
 #define CRYPTOCONTEXT_H
 
@@ -38,21 +40,21 @@
 const int SrtpEncryptionTWOCM = 3;
 const int SrtpEncryptionTWOF8 = 4;
 
-// Check if included via CryptoContextCtrl.cpp - avoid double definitions
 #ifndef CRYPTOCONTEXTCTRL_H
 
 #include <stdint.h>
+#include <crypto/SrtpSymCrypto.h>
 
 class SrtpSymCrypto;
 
 /**
- * @brief Implementation for a SRTP cryptographic context.
+ * The implementation for a SRTP cryptographic context.
  *
  * This class holds data and provides functions that implement a
- * cryptographic context for SRTP. Refer to RFC 3711, chapter 3.2 for some
+ * cryptographic context for SRTP, Refer to RFC 3711, chapter 3.2 for some
  * more detailed information about the SRTP cryptographic context.
  *
- * Each SRTP cryptographic context uses a RTP source identified by
+ * Each SRTP cryptographic context maintains a RTP source identified by
  * its SSRC. Thus you can independently protect each source inside a RTP
  * session.
  *
@@ -60,93 +62,35 @@
  * cryptographic context, such as master key, key length, authentication
  * length and so on. The key management mechanisms are not part of
  * SRTP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
- * (RFC6189). After key management negotiated the data the application can
- * setup the SRTP cryptographic context and enable SRTP processing.
+ * (draft-zimmermann-avt-zrtp-01). After key management negotiated the
+ * data the application can setup the SRTP cryptographic context and
+ * enable SRTP processing.
  *
- * This SRTP context implementation supports RTP only.
+ * Currently this implementation supports RTP only, not RTCP.
  *
- * A short eample how to setup a SRTP CryptoContext:
- @verbatim
-
- // First some key and salt data - this data is just for demo purposes
- uint8 masterKey[] = {   0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-                        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
-
- uint8 masterSalt[] = {  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-                        0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d };
-
- ...
-
- CryptoContext* cryptoCtxSend =
-     new CryptoContext(0xfeedbacc,
-     0,                           // roc,
-     0L,                          // keyderivation rate << 48,
-     SrtpEncryptionAESCM,         // encryption algo
-     SrtpAuthenticationSha1Hmac,  // authtication algo
-     masterKey,                   // Master Key data
-     128 / 8,                     // Master Key length in bytes
-     masterSalt,                  // Master Salt data
-     112 / 8,                     // Master Salt length in bytes
-     128 / 8,                     // encryption keylength in bytes
-     160 / 8,                     // authentication key length in bytes (SHA1)
-     112 / 8,                     // session salt length in bytes
-      80 / 8);                     // authentication tag length in bytes
-
- cryptoCtxSend->deriveSrtpKeys(0);
-
- ....
-
- // To protect a RTP packet
- // buffer: pointer to the RTP packet, length of the RTP data, newLength is a
- // pointer to a size_t that gets the updated length.
- bool rc = SrtpHandler::protect(cryptoCtxSend, buffer, length, newLength);
-
- // To unprotect a SRTP packet:
- // buffer: pointer to the RTP packet, length of the SRTP data, newLength is a
- // pointer to a size_t that gets the updated length.
- int32_t rc = SrtpHandler::unprotect(cryptoCtxRecv, buffer, length, newLength);
-
- @endverbatim
- *
- * @note You need two CryptoContext instances - one for the sending channel the
- * other one for the receiving channel. 
- *
- * Before an appliction can use a CryptoContext it must call the key derivation
- * function deriveSrtpKeys() first. Only then this SRTP cryptographic context is ready
- * to protect or unprotect a RTP SSRC stream.
- *
- * Together with the newCryptoContextForSSRC() function an application can prepare a
- * CryptoContext and save it as template. Once it needs a new CryptoContext, say
- * for a new SSRC, it calls newCryptoContextForSSRC() on the saved context to get an
- * initialized copy and then call deriveSrtpKeys() to compute and process the keys.
- *
- * @note A saved, pre-initialized template contains the non-processed keys. Only
- * the method deriveSrtpKeys() processes the keys and cleares them. Thus don't store
- * CryptoContext templates if the application cannot protect the templates against
- * reading from other possibly rogue applications.
- *
- * @sa SrtpHandler
- * 
+ * @author Israel Abad <i_abad@terra.es>
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
+ * @author Joachim Orrblad <joachim@orrblad.com>
  * @author Werner Dittmann <Werner.Dittmann@t-online.de>
  */
+
 class CryptoContext {
 public:
     /**
-     * @brief Constructor for an active SRTP cryptographic context.
+     * Constructor for an active SRTP cryptographic context.
      *
-     * This constructor creates an pre-initialized SRTP cryptographic context were
-     * algorithms are allocated, keys are stored and so on. An application can
-     * call newCryptoContextForSSRC() to get a full copy of this pre-initialized
-     * CryptoContext.
-     *
+     * This constructor creates an active SRTP cryptographic context were
+     * algorithms are enabled, keys are computed and so on. This SRTP
+     * cryptographic context can protect a RTP SSRC stream.
      *
      * @param ssrc
-     *    The RTP SSRC that this SRTP cryptographic context belongs to.
+     *    The RTP SSRC that this SRTP cryptographic context protects.
      *
      * @param roc
      *    The initial Roll-Over-Counter according to RFC 3711. These are the
-     *    upper 32 bit of the overall 48 bit SRTP packet index. Usually set to zero.
-     *    Refer to chapter 3.2.1 of the RFC.
+     *    upper 32 bit of the overall 48 bit SRTP packet index. Refer to
+     *    chapter 3.2.1 of the RFC.
      *
      * @param keyDerivRate
      *    The key derivation rate defines when to recompute the SRTP session
@@ -154,14 +98,15 @@
      *
      * @param ealg
      *    The encryption algorithm to use. Possible values are <code>
-     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,
-     *    SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1
-     *    for AESCM (Counter mode) and 4.1.2 for AES F8 mode.
+     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8
+     *    </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2
+     *    for AES F8 mode.
      *
      * @param aalg
      *    The authentication algorithm to use. Possible values are <code>
-     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac
-     *    </code>.
+     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac</code>. The only
+     *    active algorithm here is SHA1 HMAC, a SHA1 based hashed message
+     *    authentication code as defined in RFC 2104.
      *
      * @param masterKey
      *    Pointer to the master key for this SRTP cryptographic context.
@@ -175,26 +120,27 @@
      *    bytes (128 or 256 bit master key)
      *
      * @param masterSalt
-     *    SRTP uses the master salt to generate the initialization vector
+     *    SRTP uses the master salt to computer the initialization vector
      *    that in turn is input to compute the session key, session
      *    authentication key and the session salt.
      *
      * @param masterSaltLength
-     *    The length in bytes of the master salt data in bytes. According to
-     *    RFC3711 the standard value for the master salt length should
-     *    be 14 bytes (112 bit).
+     *    The length in bytes of the master salt data in bytes. SRTP uses
+     *    AES as encryption algorithm. AES encrypts 16 byte blocks
+     *    (independent of the key length). According to RFC3711 the standard
+     *    value for the master salt length should be 112 bit (14 bytes).
      *
      * @param ekeyl
      *    The length in bytes of the session encryption key that SRTP shall
-     *    generate and use. Usually the same length as for the master key
-     *    length, however you may use a different length as well.
+     *    compute and use. Usually the same length as for the master key
+     *    length. But you may use a different length as well. Be carefull
+     *    that the key management mechanisms supports different key lengths.
      *
      * @param akeyl
      *    The length in bytes of the session authentication key. SRTP
      *    computes this key and uses it as input to the authentication
      *    algorithm.
-     *    This is usually 160 bits (20 bytes) for @c SrtpAuthenticationSha1Hmac
-     *    and 256 bits (32 bytes) for @c SrtpAuthenticationSkeinHmac.
+     *    The standard value is 160 bits (20 bytes).
      *
      * @param skeyl
      *    The length in bytes of the session salt. SRTP computes this salt
@@ -203,11 +149,9 @@
      *
      * @param tagLength
      *    The length is bytes of the authentication tag that SRTP appends
-     *    to the RTP packet. The @c CryptoContext supports @c SrtpAuthenticationSha1Hmac
-     *    with 4 and 10 byte (32 and 80 bits) and @c SrtpAuthenticationSkeinHmac
-     *    with 4 and 8 bytes (32 and 64 bits) tag length. Refer to chapter 4.2. in RFC 3711.
+     *    to the RTP packet. Refer to chapter 4.2. in the RFC 3711.
      */
-    CryptoContext(uint32_t ssrc, int32_t roc,
+    CryptoContext( uint32_t ssrc, int32_t roc,
                    int64_t  keyDerivRate,
                    const  int32_t ealg,
                    const  int32_t aalg,
@@ -218,17 +162,16 @@
                    int32_t  ekeyl,
                    int32_t  akeyl,
                    int32_t  skeyl,
-                   int32_t  tagLength);
-
+                   int32_t  tagLength );
     /**
-     * @brief Destructor.
+     * Destructor.
      *
      * Cleans the SRTP cryptographic context.
      */
     ~CryptoContext();
 
     /**
-     * @brief Set the Roll-Over-Counter.
+     * Set the Roll-Over-Counter.
      *
      * Ths method sets the upper 32 bit of the 48 bit SRTP packet index
      * (the roll-over-part)
@@ -236,20 +179,28 @@
      * @param r
      *   The roll-over-counter
      */
-    inline void setRoc(uint32_t r) { roc = r; }
+    inline void
+    setRoc(uint32_t r)
+    {
+        roc = r;
+    }
 
     /**
-     * @brief Get the Roll-Over-Counter.
+     * Get the Roll-Over-Counter.
      *
      * Ths method get the upper 32 bit of the 48 bit SRTP packet index
      * (the roll-over-part)
      *
      * @return The roll-over-counter
      */
-    inline uint32_t getRoc() const { return roc; }
+    inline uint32_t
+    getRoc() const
+    {
+        return roc;
+    }
 
     /**
-     * @brief Perform SRTP encryption.
+     * Perform SRTP encryption.
      *
      * This method encrypts <em>and</em> decrypts SRTP payload data. Plain
      * data gets encrypted, encrypted data get decrypted.
@@ -270,10 +221,10 @@
      * @param ssrc
      *    The RTP SSRC data in <em>host</em> order.
      */
-    void srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc);
+    void srtpEncrypt(uint8_t* pkt, uint8_t* payload, uint32_t paylen, uint64_t index, uint32_t ssrc );
 
     /**
-     * @brief Compute the authentication tag.
+     * Compute the authentication tag.
      *
      * Compute the authentication tag according the the paramters in the
      * SRTP Cryptograhic context.
@@ -291,26 +242,23 @@
      *    Points to a buffer that hold the computed tag. This buffer must
      *    be able to hold <code>tagLength</code> bytes.
      */
-    void srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag);
+    void srtpAuthenticate(uint8_t* pkt, uint32_t pktlen, uint32_t roc, uint8_t* tag );
 
     /**
-     * @brief Perform key derivation according to SRTP specification
+     * Perform key derivation according to SRTP specification
      *
      * This method computes the session key, session authentication key and the
      * session salt key. This method must be called at least once after the
      * SRTP Cryptograhic context was set up.
      *
-     * This method clears the key data once it was processed by the encryptions'
-     * set key functions.
-     *
      * @param index
      *    The 48 bit SRTP packet index. See the <code>guessIndex</code>
-     *    method. Usually 0.
+     *    method.
      */
     void deriveSrtpKeys(uint64_t index);
 
     /**
-     * @brief Compute (guess) the new SRTP index based on the sequence number of
+     * Compute (guess) the new SRTP index based on the sequence number of
      * a received RTP packet.
      *
      * The method uses the algorithm show in RFC3711, Appendix A, to compute
@@ -324,7 +272,7 @@
     uint64_t guessIndex(uint16_t newSeqNumber);
 
     /**
-     * @brief Check for packet replay.
+     * Check for packet replay.
      *
      * The method check if a received packet is either to old or was already
      * received.
@@ -341,7 +289,7 @@
     bool checkReplay(uint16_t newSeqNumber);
 
     /**
-     * @brief Update the SRTP packet index.
+     * Update the SRTP packet index.
      *
      * Call this method after all checks were successful. See chapter
      * 3.3.1 in the RFC when to update the ROC and ROC processing.
@@ -349,67 +297,64 @@
      * @param newSeqNumber
      *    The sequence number of the received RTP packet in host order.
      */
-    void update(uint16_t newSeqNumber);
+    void update( uint16_t newSeqNumber );
 
     /**
-     * @brief Get the length of the SRTP authentication tag in bytes.
+     * Get the length of the SRTP authentication tag in bytes.
      *
      * @return the length of the authentication tag.
      */
-    int32_t getTagLength() const { return tagLength; }
+    inline int32_t
+    getTagLength() const
+    {
+        return tagLength;
+    }
+
 
     /**
-     * @brief Get the length of the MKI in bytes.
+     * Get the length of the MKI in bytes.
      *
      * @return the length of the MKI.
      */
-    int32_t getMkiLength() const { return mkiLength; }
+    inline int32_t
+    getMkiLength() const
+    {
+        return mkiLength;
+    }
 
     /**
-     * @brief Get the SSRC of this SRTP Cryptograhic context.
+     * Get the SSRC of this SRTP Cryptograhic context.
      *
      * @return the SSRC.
      */
-    uint32_t getSsrc() const { return ssrcCtx; }
+    inline uint32_t
+    getSsrc() const
+    {
+        return ssrcCtx;
+    }
 
     /**
-     * @brief Set the start (base) number to compute the PRF labels.
-     *
-     * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.
-     * CryptoContext computes the labes as follows:
-     *
-     * - labelBase + 0 -> encryption label
-     * - labelBase + 1 -> authentication label
-     * - labelBase + 2 -> salting key label
-     *
-     * The CryptoContext constructor initializes CryptoContext::labelBase
-     * with 0 to comply with RFC 3711 label values.
-     *
-     * Applications may set the #labelBase to other values to use the CryptoContext
-     * for other purposes.
-     */
-    void setLabelbase(uint8_t base) { labelBase = base; }
-
-    /**
-     * @brief Derive a new Crypto Context for use with a new SSRC
+     * Derive a new Crypto Context for use with a new SSRC
      *
      * This method returns a new Crypto Context initialized with the data
      * of this crypto context. Replacing the SSRC, Roll-over-Counter, and
-     * the key derivation rate the application can use this Crypto Context
+     * the key derivation rate the application cab use this Crypto Context
      * to encrypt / decrypt a new stream (Synchronization source) inside
      * one RTP session.
      *
-     * Before the application can use this crypto context it must call deriveSrtpKeys().
+     * Before the application can use this crypto context it must call
+     * the <code>deriveSrtpKeys</code> method.
      *
      * @param ssrc
      *     The SSRC for this context
      * @param roc
-     *     The Roll-Over-Counter for this context, usually 0
+     *     The Roll-Over-Counter for this context
      * @param keyDerivRate
-     *     The key derivation rate for this context, usally 0
+     *     The key derivation rate for this context
      * @return
      *     a new CryptoContext with all relevant data set.
      */
+
     CryptoContext* newCryptoContextForSSRC(uint32_t ssrc, int roc, int64_t keyDerivRate);
 
 private:
@@ -448,7 +393,6 @@
     int32_t akeyl;
     int32_t skeyl;
     int32_t tagLength;
-    uint8_t labelBase;
     bool  seqNumSet;
 
     void*   macCtx;
@@ -464,3 +408,11 @@
  */
 #endif
 
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp b/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
index 952a823..caf5746 100644
--- a/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
+++ b/jni/libzrtp/sources/srtp/CryptoContextCtrl.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2011 - 2012 Werner Dittmann
+  Copyright (C) 2004-2006 the Minisip Team
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -16,22 +16,24 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
 
-/* 
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+/* Copyright (C) 2004-2012
+ *
+ * Authors: Israel Abad <i_abad@terra.es>
+ *          Erik Eliasson <eliasson@it.kth.se>
+ *          Johan Bilien <jobi@via.ecp.fr>
+ *          Joachim Orrblad <joachim@orrblad.com>
+ *          Werner Dittmann <Werner.Dittmann@t-online.de>
  */
 
 #include <string.h>
+#include <arpa/inet.h>
 #include <stdio.h>
-#include <stdint.h>
-
-#include <common/osSpecifics.h>
 
 #include <CryptoContextCtrl.h>
 #include <CryptoContext.h>
 
-#include <crypto/SrtpSymCrypto.h>
 #include <crypto/hmac.h>
-#include <cryptcommon/macSkein.h>
+#include <crypto/macSkein.h>
 
 
 CryptoContextCtrl::CryptoContextCtrl(uint32_t ssrc,
@@ -45,9 +47,8 @@
                                 int32_t akeyl,
                                 int32_t skeyl,
                                 int32_t tagLength):
-ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL), replay_window(0), srtcpIndex(0),
-labelBase(3), macCtx(NULL), cipher(NULL), f8Cipher(NULL)        // SRTCP labels start at 3
-
+ssrcCtx(ssrc),using_mki(false),mkiLength(0),mki(NULL),
+replay_window(0), macCtx(NULL), cipher(NULL), f8Cipher(NULL)
 {
     this->ealg = ealg;
     this->aalg = aalg;
@@ -163,7 +164,7 @@
     aalg = SrtpAuthenticationNull;
 }
 
-void CryptoContextCtrl::srtcpEncrypt( uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc )
+void CryptoContextCtrl::srtcpEncrypt( uint8_t* rtp, int32_t len, uint64_t index, uint32_t ssrc )
 {
     if (ealg == SrtpEncryptionNull) {
         return;
@@ -243,7 +244,7 @@
     unsigned char temp[20];
     const unsigned char* chunks[3];
     unsigned int chunkLength[3];
-    uint32_t beIndex = zrtpHtonl(index);
+    uint32_t beIndex = htonl(index);
 
     chunks[0] = rtp;
     chunkLength[0] = len;
@@ -295,17 +296,17 @@
 {
     uint8_t iv[16];
 
-    // prepare cipher to compute derived keys.
+    // prepare AES cipher to compute derived keys.
     cipher->setNewKey(master_key, master_key_length);
     memset(master_key, 0, master_key_length);
 
     // compute the session encryption key
-    uint8_t label = labelBase;
+    uint8_t label = 3;
     computeIv(iv, label, master_salt);
     cipher->get_ctr_cipher_stream(k_e, n_e, iv);
 
     // compute the session authentication key
-    label = labelBase + 1;
+    label = 4;
     computeIv(iv, label, master_salt);
     cipher->get_ctr_cipher_stream(k_a, n_a, iv);
 
@@ -322,12 +323,12 @@
     memset(k_a, 0, n_a);
 
     // compute the session salt
-    label = labelBase + 2;
+    label = 5;
     computeIv(iv, label, master_salt);
     cipher->get_ctr_cipher_stream(k_s, n_s, iv);
     memset(master_salt, 0, master_salt_length);
 
-    // as last step prepare cipher with derived key.
+    // as last step prepare AES cipher with derived key.
     cipher->setNewKey(k_e, n_e);
     if (f8Cipher != NULL)
         cipher->f8_deriveForIV(f8Cipher, k_e, n_e, k_s, n_s);
@@ -341,21 +342,24 @@
         return true;
     }
 
-    int64_t delta = index - s_l;
+    int64_t delta = s_l - index;
     if (delta > 0) {
         /* Packet not yet received*/
         return true;
     }
     else {
-        if( -delta >= REPLAY_WINDOW_SIZE ) {
-            return false;       /* Packet too old */
+        if( -delta > REPLAY_WINDOW_SIZE ) {
+            /* Packet too old */
+            return false;
         }
         else {
             if((replay_window >> (-delta)) & 0x1) {
-                return false;   /* Packet already received ! */
+                /* Packet already received ! */
+                return false;
             }
             else {
-                return true;    /* Packet not yet received */
+                /* Packet not yet received */
+                return true;
             }
         }
     }
@@ -373,8 +377,7 @@
     else {
         replay_window |= ( 1 << delta );
     }
-    if (index > s_l)
-        s_l = index;
+    s_l = index;
 }
 
 CryptoContextCtrl* CryptoContextCtrl::newCryptoContextForSSRC(uint32_t ssrc)
@@ -394,3 +397,12 @@
 
     return pcc;
 }
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/CryptoContextCtrl.h b/jni/libzrtp/sources/srtp/CryptoContextCtrl.h
index 3adcd8d..456e58f 100644
--- a/jni/libzrtp/sources/srtp/CryptoContextCtrl.h
+++ b/jni/libzrtp/sources/srtp/CryptoContextCtrl.h
@@ -1,6 +1,7 @@
 /*
-  Copyright (C) 2011 - 2012 Werner Dittmann
-
+  Copyright (C) 2004-2006 the Minisip Team
+  Copyright (C) 2011 Werner Dittmann for the SRTCP support
+  
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
@@ -16,110 +17,117 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
 
+
+
 #ifndef CRYPTOCONTEXTCTRL_H
 #define CRYPTOCONTEXTCTRL_H
 
 /**
- * @file CryptoContextCtrl.h
- * @brief The C++ SRTCP implementation
+ * @file CryptoContext.h
+ * @brief The C++ SRTP implementation
  * @ingroup Z_SRTP
  * @{
  */
 
+#include <crypto/SrtpSymCrypto.h>
+
 class SrtpSymCrypto;
 
-/**
- * The implementation for a SRTCP cryptographic context.
- *
- * This class holds data and provides functions that implement a
- * cryptographic context for SRTCP, Refer to RFC 3711, chapter 3.2 for some
- * more detailed information about the SRTCP cryptographic context.
- *
- * Each SRTCP cryptographic context maintains a RTCP source identified by
- * its SSRC. Thus you can independently protect each source inside a RTP
- * session.
- *
- * Key management mechanisms negotiate the parameters for the SRTCP
- * cryptographic context, such as master key, key length, authentication
- * length and so on. The key management mechanisms are not part of
- * SRTCP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
- * (RFC6189). After key management negotiated the data the application
- * can setup the SRTCP cryptographic context and enable SRTCP processing.
- *
- * @sa CryptoContext
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
+    /**
+     * The implementation for a SRTCP cryptographic context.
+     *
+     * This class holds data and provides functions that implement a
+     * cryptographic context for SRTP, Refer to RFC 3711, chapter 3.2 for some
+     * more detailed information about the SRTP cryptographic context.
+     *
+     * Each SRTP cryptographic context maintains a RTP source identified by
+     * its SSRC. Thus you can independently protect each source inside a RTP
+     * session.
+     *
+     * Key management mechanisms negotiate the parameters for the SRTP
+     * cryptographic context, such as master key, key length, authentication
+     * length and so on. The key management mechanisms are not part of
+     * SRTP. Refer to MIKEY (RFC 3880) or to Phil Zimmermann's ZRTP protocol
+     * (draft-zimmermann-avt-zrtp-01). After key management negotiated the
+     * data the application can setup the SRTCP cryptographic context and
+     * enable SRTCP processing.
+     *
+     *
+     * @author Israel Abad <i_abad@terra.es>
+     * @author Erik Eliasson <eliasson@it.kth.se>
+     * @author Johan Bilien <jobi@via.ecp.fr>
+     * @author Joachim Orrblad <joachim@orrblad.com>
+     * @author Werner Dittmann <Werner.Dittmann@t-online.de>
+     */
+
 class CryptoContextCtrl {
     public:
     /**
-     * @brief Constructor for an active SRTCP cryptographic context.
+     * Constructor for an active SRTP cryptographic context.
      *
-     * This constructor creates an active SRTCP cryptographic context were
-     * algorithms are enabled, keys are computed and so on. This SRTCP
-     * cryptographic context can protect a RTCP SSRC stream.
-     *
-     * See the notes in CryptoContext documentation regarding the handling
-     * of key data.
+     * This constructor creates an active SRTP cryptographic context were
+     * algorithms are enabled, keys are computed and so on. This SRTP
+     * cryptographic context can protect a RTP SSRC stream.
      *
      * @param ssrc
-     *    The RTP SSRC that this SRTCP cryptographic context protects.
+     *    The RTP SSRC that this SRTP cryptographic context protects.
      *
      * @param ealg
      *    The encryption algorithm to use. Possible values are <code>
-     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8,
+     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8
      *    </code>. See chapter 4.1.1 for AESCM (Counter mode) and 4.1.2
      *    for AES F8 mode.
      *
      * @param aalg
      *    The authentication algorithm to use. Possible values are <code>
-     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac, SrtpAuthenticationSkeinHmac
-     *    </code>.
+     *    SrtpEncryptionNull, SrtpAuthenticationSha1Hmac</code>. The only
+     *    active algorithm here is SHA1 HMAC, a SHA1 based hashed message
+     *    authentication code as defined in RFC 2104.
      *
      * @param masterKey
-     *    Pointer to the master key for this SRTCP cryptographic context.
+     *    Pointer to the master key for this SRTP cryptographic context.
      *    Must point to <code>masterKeyLength</code> bytes. Refer to chapter
      *    3.2.1 of the RFC about the role of the master key.
      *
      * @param masterKeyLength
      *    The length in bytes of the master key in bytes. The length must
-     *    match the selected encryption algorithm. Because SRTCP uses AES
+     *    match the selected encryption algorithm. Because SRTP uses AES
      *    based  encryption only, then master key length may be 16 or 32
      *    bytes (128 or 256 bit master key)
      *
      * @param masterSalt
-     *    SRTCP uses the master salt to computer the initialization vector
+     *    SRTP uses the master salt to computer the initialization vector
      *    that in turn is input to compute the session key, session
      *    authentication key and the session salt.
      *
      * @param masterSaltLength
-     *    The length in bytes of the master salt data in bytes. SRTCP uses
+     *    The length in bytes of the master salt data in bytes. SRTP uses
      *    AES as encryption algorithm. AES encrypts 16 byte blocks
      *    (independent of the key length). According to RFC3711 the standard
      *    value for the master salt length should be 112 bit (14 bytes).
      *
      * @param ekeyl
-     *    The length in bytes of the session encryption key that SRTCP shall
+     *    The length in bytes of the session encryption key that SRTP shall
      *    compute and use. Usually the same length as for the master key
      *    length. But you may use a different length as well. Be carefull
      *    that the key management mechanisms supports different key lengths.
      *
      * @param akeyl
-     *    The length in bytes of the session authentication key. SRTCP
+     *    The length in bytes of the session authentication key. SRTP
      *    computes this key and uses it as input to the authentication
      *    algorithm.
      *    The standard value is 160 bits (20 bytes).
      *
      * @param skeyl
-     *    The length in bytes of the session salt. SRTCP computes this salt
+     *    The length in bytes of the session salt. SRTP computes this salt
      *    key and uses it as input during encryption. The length usually
      *    is the same as the master salt length.
      *
      * @param tagLength
-     *    The length is bytes of the authentication tag that SRTCP appends
+     *    The length is bytes of the authentication tag that SRTP appends
      *    to the RTP packet. Refer to chapter 4.2. in the RFC 3711.
      */
-    CryptoContextCtrl(uint32_t ssrc,
+    CryptoContextCtrl( uint32_t ssrc,
                const  int32_t ealg,
                const  int32_t aalg,
                uint8_t* masterKey,
@@ -129,71 +137,65 @@
                int32_t  ekeyl,
                int32_t  akeyl,
                int32_t  skeyl,
-               int32_t  tagLength);
-
+               int32_t  tagLength );
     /**
-     * @brief Destructor.
+     * Destructor.
      *
-     * Cleans the SRTCP cryptographic context.
+     * Cleans the SRTP cryptographic context.
      */
     ~CryptoContextCtrl();
 
     /**
-     * @brief Perform SRTCP encryption.
+     * Perform SRTP encryption.
      *
-     * This method encrypts <em>and</em> decrypts SRTCP payload data. Plain
+     * This method encrypts <em>and</em> decrypts SRTP payload data. Plain
      * data gets encrypted, encrypted data get decrypted.
      *
      * @param rtp
      *    The RTP packet that contains the data to encrypt.
      *
-     * @param len
-     *    Length of the RTCP packet
-     *
      * @param index
-     *    The 31 bit SRTCP packet index.
+     *    The 48 bit SRTP packet index. See the <code>guessIndex</code>
+     *    method.
      *
      * @param ssrc
-     *    The RTCP SSRC data in <em>host</em> order.
+     *    The RTP SSRC data in <em>host</em> order.
      */
-    void srtcpEncrypt(uint8_t* rtp, int32_t len, uint32_t index, uint32_t ssrc);
+    void srtcpEncrypt( uint8_t* rtp, int32_t len, uint64_t index, uint32_t ssrc );
 
     /**
-     * @brief Compute the authentication tag.
+     * Compute the authentication tag.
      *
      * Compute the authentication tag according the the paramters in the
-     * SRTCP Cryptograhic context.
+     * SRTP Cryptograhic context.
      *
      * @param rtp
-     *    The RTCP packet that contains the data to authenticate.
+     *    The RTP packet that contains the data to authenticate.
      *
-     * @param len
-     *    Length of the RTCP packet
-     *
-     * @param index
-     *    The 31 bit SRTCP index.
+     * @param roc
+     *    The 32 bit SRTP roll-over-counter.
      *
      * @param tag
      *    Points to a buffer that hold the computed tag. This buffer must
      *    be able to hold <code>tagLength</code> bytes.
      */
-    void srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t index, uint8_t* tag);
+    void srtcpAuthenticate(uint8_t* rtp, int32_t len, uint32_t roc, uint8_t* tag );
 
     /**
-     * @brief Perform key derivation according to SRTCP specification
+     * Perform key derivation according to SRTP specification
      *
      * This method computes the session key, session authentication key and the
      * session salt key. This method must be called at least once after the
-     * SRTCP cryptograhic context was set up.
+     * SRTP Cryptograhic context was set up.
      *
-     * This method clears the key data once it was processed by the encryptions'
-     * set key functions.
-     *
+     * @param index
+     *    The 48 bit SRTP packet index. See the <code>guessIndex</code>
+     *    method.
      */
      void deriveSrtcpKeys();
 
     /**
-     * @brief Check for packet replay.
+     * Check for packet replay.
      *
      * The method check if a received packet is either to old or was already
      * received.
@@ -210,7 +212,7 @@
      bool checkReplay(uint32_t newSeqNumber);
 
     /**
-     * @brief Update the SRTCP packet index.
+     * Update the SRTP packet index.
      *
      * Call this method after all checks were successful. See chapter
      * 3.3.1 in the RFC when to update the ROC and ROC processing.
@@ -218,77 +220,56 @@
      * @param newSeqNumber
      *    The sequence number of the received RTCP packet in host order.
      */
-    void update(uint32_t newSeqNumber);
+    void update( uint32_t newSeqNumber );
 
     /**
-     * @brief Get the length of the SRTCP authentication tag in bytes.
+     * Get the length of the SRTP authentication tag in bytes.
      *
      * @return the length of the authentication tag.
      */
-    inline int32_t getTagLength() const { return tagLength; }
+    inline int32_t
+    getTagLength() const
+        {return tagLength;}
+
 
     /**
-     * @brief Get the length of the MKI in bytes.
+     * Get the length of the MKI in bytes.
      *
      * @return the length of the MKI.
      */
-    inline int32_t getMkiLength() const { return mkiLength; }
+    inline int32_t
+    getMkiLength() const
+        {return mkiLength;}
 
     /**
-     * @brief Get the SSRC of this SRTCP Cryptograhic context.
+     * Get the SSRC of this SRTP Cryptograhic context.
      *
      * @return the SSRC.
      */
-    inline uint32_t getSsrc() const { return ssrcCtx; }
+    inline uint32_t
+    getSsrc() const
+        {return ssrcCtx;}
 
     /**
-     * @brief Get the SRTCP index field of this SRTCP Cryptograhic context.
+     * Derive a new Crypto Context for use with a new SSRC
      *
-     * @return the SRTCP.
-     */
-    uint32_t getSrtcpIndex() const { return srtcpIndex; }
-
-    /**
-     * @brief Set the SRTCP index field of this SRTCP Cryptograhic context.
+     * This method returns a new Crypto Context initialized with the data
+     * of this crypto context. Replacing the SSRC, Roll-over-Counter, and
+     * the key derivation rate the application cab use this Crypto Context
+     * to encrypt / decrypt a new stream (Synchronization source) inside
+     * one RTP session.
      *
-     * @param index the new SRTCP index value.
-     *
-     */
-    void setSrtcpIndex(uint32_t index) { srtcpIndex = index; }
-
-    /**
-     * @brief Set the start (base) number to compute the PRF labels.
-     *
-     * Refer to RFC3711, chapters 4.3.1 and 4.3.2 about values for labels.
-     * CryptoContextCtrl computes the labes as follows:
-     *
-     * - labelBase + 0 -> encryption label
-     * - labelBase + 1 -> authentication label
-     * - labelBase + 2 -> salting key label
-     *
-     * The CryptoContextCtrl constructor initializes CryptoContextCtrl#labelBase
-     * with 3 to comply with RFC 3711 label values.
-     *
-     * Applications may set #labelBase to other values to use CryptoContextCtrl
-     * for other purposes.
-     */
-    void setLabelbase(uint8_t base) { labelBase = base; }
-
-    /**
-     * @brief Derive a new Crypto Context for use with a new SSRC
-     *
-     * This method returns a new CryptoContextCtrl initialized with the data
-     * of this crypto context. The application can use this CryptoContextCtrl
-     * instance to encrypt / decrypt a new stream (Synchronization source) inside
-     * one RTCP session.
-     *
-     * Before the application can use this crypto context it must call deriveSrtcpKeys().
+     * Before the application can use this crypto context it must call
+     * the <code>deriveSrtpKeys</code> method.
      *
      * @param ssrc
      *     The SSRC for this context
-     *
+     * @param roc
+     *     The Roll-Over-Counter for this context
+     * @param keyDerivRate
+     *     The key derivation rate for this context
      * @return
-     *     a new CryptoContextCtrl with all relevant data set.
+     *     a new CryptoContext with all relevant data set.
      */
     CryptoContextCtrl* newCryptoContextForSSRC(uint32_t ssrc);
 
@@ -323,8 +304,6 @@
         int32_t akeyl;
         int32_t skeyl;
         int32_t tagLength;
-        uint32_t srtcpIndex;
-        uint8_t labelBase;
 
         void*   macCtx;
 
@@ -338,3 +317,11 @@
 
 #endif
 
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/SrtpHandler.cpp b/jni/libzrtp/sources/srtp/SrtpHandler.cpp
deleted file mode 100644
index 621e25a..0000000
--- a/jni/libzrtp/sources/srtp/SrtpHandler.cpp
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
-  Copyright (C) 2012 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-*/
-
-/*
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-#include <common/osSpecifics.h>
-
-#include <SrtpHandler.h>
-#include <CryptoContext.h>
-#include <CryptoContextCtrl.h>
-
-#define RTP_HEADER_LENGTH 12
-
-bool SrtpHandler::decodeRtp(uint8_t* buffer, int32_t length, uint32_t *ssrc, uint16_t *seq, uint8_t** payload, int32_t *payloadlen)
-{
-    int offset;
-    uint16_t *pus;
-    uint32_t *pui;
-
-    /* Assume RTP header at the start of buffer. */
-
-    if ((*buffer & 0xC0) != 0x80) {         // check version bits
-        return false;
-    }
-    if (length < RTP_HEADER_LENGTH)
-        return false;
-
-    /* Get some handy pointers */
-    pus = (uint16_t*)buffer;
-    pui = (uint32_t*)buffer;
-
-    uint16_t tmp16 = pus[1];                    // get seq number
-    *seq = zrtpNtohs(tmp16);                        // and return in host oder
-
-    uint32_t tmp32 = pui[2];                    // get SSRC
-    *ssrc = zrtpNtohl(tmp32);                       // and return in host order
-
-    /* Payload is located right after header plus CSRC */
-    int32_t numCC = buffer[0] & 0x0f;           // lower 4 bits in first byte is num of contrib SSRC
-    offset = RTP_HEADER_LENGTH + (numCC * sizeof(uint32_t));
-
-    // Sanity check
-    if (offset > length)
-        return false;
-
-    /* Adjust payload offset if RTP extension is used. */
-    if ((*buffer & 0x10) == 0x10) {             // packet contains RTP extension
-        pus = (uint16_t*)(buffer + offset);     // pus points to extension as 16bit pointer
-        tmp16 = pus[1];                         // the second 16 bit word is the length
-        tmp16 = zrtpNtohs(tmp16);                   // to host order
-        offset += (tmp16 + 1) * sizeof(uint32_t);
-    }
-    /* Sanity check */
-    if (offset > length)
-        return false;
-
-    /* Set payload and payload length. */
-    *payload = buffer + offset;
-    *payloadlen = length - offset;
-
-    return true;
-}
-
-bool SrtpHandler::protect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
-    uint8_t* payload = NULL;
-    int32_t payloadlen = 0;
-    uint16_t seqnum;
-    uint32_t ssrc;
-
-
-    if (pcc == NULL) {
-        return false;
-    }
-    if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen))
-        return false;
-
-    /* Encrypt the packet */
-    uint64_t index = ((uint64_t)pcc->getRoc() << 16) | (uint64_t)seqnum;
-
-    pcc->srtpEncrypt(buffer, payload, payloadlen, index, ssrc);
-
-    // NO MKI support yet - here we assume MKI is zero. To build in MKI
-    // take MKI length into account when storing the authentication tag.
-
-    /* Compute MAC and store at end of RTP packet data */
-    if (pcc->getTagLength() > 0) {
-        pcc->srtpAuthenticate(buffer, length, pcc->getRoc(), buffer+length);
-    }
-    *newLength = length + pcc->getTagLength();
-
-    /* Update the ROC if necessary */
-    if (seqnum == 0xFFFF ) {
-        pcc->setRoc(pcc->getRoc() + 1);
-    }
-    return true;
-}
-
-int32_t SrtpHandler::unprotect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
-    uint8_t* payload = NULL;
-    int32_t payloadlen = 0;
-    uint16_t seqnum;
-    uint32_t ssrc;
-
-    if (pcc == NULL) {
-        return 0;
-    }
-
-    if (!decodeRtp(buffer, length, &ssrc, &seqnum, &payload, &payloadlen))
-        return 0;
-    /*
-     * This is the setting of the packet data when we come to this point:
-     *
-     * length:      complete length of received data
-     * buffer:      points to data as received from network
-     * payloadlen:  length of data excluding hdrSize and padding
-     *
-     * Because this is an SRTP packet we need to adjust some values here.
-     * The SRTP MKI and authentication data is always at the end of a
-     * packet. Thus compute the position of this data.
-     */
-    uint32_t srtpDataIndex = length - (pcc->getTagLength() + pcc->getMkiLength());
-
-    // Compute new length
-    length -= pcc->getTagLength() + pcc->getMkiLength();
-    *newLength = length;
-
-    // recompute payloadlen by subtracting SRTP data
-    payloadlen -= pcc->getTagLength() + pcc->getMkiLength();
-
-    // MKI is unused, so just skip it
-    // const uint8* mki = buffer + srtpDataIndex;
-    uint8_t* tag = buffer + srtpDataIndex + pcc->getMkiLength();
-
-    /* Replay control */
-    if (!pcc->checkReplay(seqnum)) {
-        return -2;
-    }
-    /* Guess the index */
-    uint64_t guessedIndex = pcc->guessIndex(seqnum);
-
-    if (pcc->getTagLength() > 0) {
-        uint32_t guessedRoc = guessedIndex >> 16;
-        uint8_t mac[20];
-
-        pcc->srtpAuthenticate(buffer, (uint32_t)length, guessedRoc, mac);
-        if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
-            return -1;
-        }
-    }
-    /* Decrypt the content */
-    pcc->srtpEncrypt(buffer, payload, payloadlen, guessedIndex, ssrc);
-
-    /* Update the Crypto-context */
-    pcc->update(seqnum);
-
-    return 1;
-}
-
-
-bool SrtpHandler::protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
-
-    if (pcc == NULL) {
-        return false;
-    }
-    /* Encrypt the packet */
-    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender
-    ssrc = zrtpNtohl(ssrc);
-
-    uint32_t encIndex = pcc->getSrtcpIndex();
-    pcc->srtcpEncrypt(buffer + 8, length - 8, encIndex, ssrc);
-
-    encIndex |= 0x80000000;                                     // set the E flag
-
-    // Fill SRTCP index as last word
-    uint32_t* ip = reinterpret_cast<uint32_t*>(buffer+length);
-    *ip = zrtpHtonl(encIndex);
-
-    // NO MKI support yet - here we assume MKI is zero. To build in MKI
-    // take MKI length into account when storing the authentication tag.
-
-    // Compute MAC and store in packet after the SRTCP index field
-    pcc->srtcpAuthenticate(buffer, length, encIndex, buffer + length + sizeof(uint32_t));
-
-    encIndex++;
-    encIndex &= ~0x80000000;                                // clear the E-flag and modulo 2^31
-    pcc->setSrtcpIndex(encIndex);
-    *newLength = length + pcc->getTagLength() + sizeof(uint32_t);
-
-    return true;
-}
-
-int32_t SrtpHandler::unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-{
-
-    if (pcc == NULL) {
-        return 0;
-    }
-
-    // Compute the total length of the payload
-    int32_t payloadLen = length - (pcc->getTagLength() + pcc->getMkiLength() + 4);
-    *newLength = payloadLen;
-
-    // point to the SRTCP index field just after the real payload
-    const uint32_t* index = reinterpret_cast<uint32_t*>(buffer + payloadLen);
-
-    uint32_t encIndex = zrtpNtohl(*index);
-    uint32_t remoteIndex = encIndex & ~0x80000000;    // get index without Encryption flag
-
-    if (!pcc->checkReplay(remoteIndex)) {
-       return -2;
-    }
-
-    uint8_t mac[20];
-
-    // Now get a pointer to the authentication tag field
-    const uint8_t* tag = buffer + (length - pcc->getTagLength());
-
-    // Authenticate includes the index, but not MKI and not (obviously) the tag itself
-    pcc->srtcpAuthenticate(buffer, payloadLen, encIndex, mac);
-    if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
-        return -1;
-    }
-
-    uint32_t ssrc = *(reinterpret_cast<uint32_t*>(buffer + 4)); // always SSRC of sender
-    ssrc = zrtpNtohl(ssrc);
-
-    // Decrypt the content, exclude the very first SRTCP header (fixed, 8 bytes)
-    if (encIndex & 0x80000000)
-        pcc->srtcpEncrypt(buffer + 8, payloadLen - 8, remoteIndex, ssrc);
-
-    // Update the Crypto-context
-    pcc->update(remoteIndex);
-
-    return 1;
-}
-
diff --git a/jni/libzrtp/sources/srtp/SrtpHandler.h b/jni/libzrtp/sources/srtp/SrtpHandler.h
deleted file mode 100644
index 1cc420b..0000000
--- a/jni/libzrtp/sources/srtp/SrtpHandler.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
-  Copyright (C) 2012 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-*/
-
-#include <stdint.h>
-
-class CryptoContext;
-class CryptoContextCtrl;
-
-/**
- * @brief SRTP and SRTCP protect and unprotect functions.
- *
- * The static methods take SRTP or SRTCP crypto contexts, a pointer uint8_t buffer
- * that must contain an RTP/SRTP packet and perform the actions necessary to protect
- * the RTP/RTCP packet or to unprotect the SRTP/SRTCP packet.
- * 
- * The methods assume that the buffer contains all protocol relevant fields (SSRC,
- * sequence number etc.) in network order.
- *
- * When encrypting the buffer must be big enough to store additional data, usually
- * 4 - 14 bytes, depending on how the application configured the authentication parameters.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-class SrtpHandler
-{
-public:
-    /**
-     * @brief Protect an RTP packet.
-     *
-     * @param pcc the SRTP CryptoContext instance
-     *
-     * @param buffer the RTP packet to protect
-     *
-     * @param length the length of the RTP packet data in bytes
-     *
-     * @param newLength the length of the resulting SRTP packet data in bytes
-     *
-     * @return @c true if protection was successful, @c false otherwise
-     */
-    static bool protect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
-    /**
-     * @brief Unprotect a SRTP packet.
-     *
-     * @param pcc the SRTP CryptoContext instance
-     *
-     * @param buffer the SRTP packet to unprotect
-     *
-     * @param length the length of the SRTP packet data in bytes
-     *
-     * @param newLength the length of the resulting RTP packet data in bytes
-     *
-     * @return an integer value
-     *         - 1 - success
-     *         - -1 - SRTP authentication failed
-     *         - -2 - SRTP replay check failed
-     */
-    static int32_t unprotect(CryptoContext* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
-    /**
-     * @brief Protect an RTCP packet.
-     *
-     * @param pcc the SRTCP CryptoContextCtrl instance
-     *
-     * @param buffer the RTCP packet to protect
-     *
-     * @param length the length of the RTCP packet data in bytes
-     *
-     * @param newLength the length of the resulting SRTCP packet data in bytes
-     *
-     * @return @c true if protection was successful, @c false otherwise
-     */
-    static bool protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
-    /**
-     * @brief Unprotect a SRTCP packet.
-     *
-     * @param pcc the SRTCP CryptoContextCtrl instance
-     *
-     * @param buffer the SRTCP packet to unprotect
-     *
-     * @param length the length of the SRTCP packet data in bytes
-     *
-     * @param newLength the length of the resulting RTCP packet data in bytes
-     *
-     * @return an integer value
-     *         - 0 - illegal packet (too short, not a valid RTP header byte), dismiss it
-     *         - 1 - success
-     *         - -1 - SRTCP authentication failed
-     *         - -2 - SRTCP replay check failed
-     */
-    static int32_t unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength);
-
-private:
-    static bool decodeRtp(uint8_t* buffer, int32_t length, uint32_t *ssrc, uint16_t *seq, uint8_t** payload, int32_t *payloadlen);
-
-};
\ No newline at end of file
diff --git a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.cpp b/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.cpp
deleted file mode 100644
index f92514d..0000000
--- a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
-  Copyright (C) 2012 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-  * In addition, as a special exception, the copyright holders give
-  * permission to link the code of portions of this program with the
-  * OpenSSL library under certain conditions as described in each
-  * individual source file, and distribute linked combinations
-  * including the two.
-  * You must obey the GNU General Public License in all respects
-  * for all of the code used other than OpenSSL.  If you modify
-  * file(s) with this exception, you may extend this exception to your
-  * version of the file(s), but you are not obligated to do so.  If you
-  * do not wish to do so, delete this exception statement from your
-  * version.  If you delete this exception statement from all source
-  * files in the program, then also delete it here.
-  */
-
-/**
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#define MAKE_F8_TEST
-
-#include <stdlib.h>
-#include <crypto/SrtpSymCrypto.h>
-#include <cryptcommon/twofish.h>
-#include <cryptcommon/aesopt.h>
-#include <string.h>
-#include <stdio.h>
-#include <common/osSpecifics.h>
-
-SrtpSymCrypto::SrtpSymCrypto(int algo):key(NULL), algorithm(algo) {
-}
-
-SrtpSymCrypto::SrtpSymCrypto( uint8_t* k, int32_t keyLength, int algo):
-    key(NULL), algorithm(algo) {
-
-    setNewKey(k, keyLength);
-}
-
-SrtpSymCrypto::~SrtpSymCrypto() {
-    if (key != NULL) {
-        if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
-            AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);
-            memset(saAes->cx, 0, sizeof(aes_encrypt_ctx));
-            delete saAes;
-        }
-        else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
-            memset(key, 0, sizeof(Twofish_key));
-            delete[] (uint8_t*)key;
-        }
-        key = NULL;
-    }
-}
-
-static int twoFishInit = 0;
-
-bool SrtpSymCrypto::setNewKey(const uint8_t* k, int32_t keyLength) {
-    // release an existing key before setting a new one
-    if (key != NULL) {
-        if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
-            AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);
-            memset(saAes->cx, 0, sizeof(aes_encrypt_ctx));
-            delete saAes;
-        }
-        else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
-            memset(key, 0, sizeof(Twofish_key));
-            delete[] (uint8_t*)key;
-        }
-        key = NULL;
-    }
-
-    if (!(keyLength == 16 || keyLength == 32)) {
-        return false;
-    }
-    if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
-        AESencrypt *saAes = new AESencrypt();
-        if (keyLength == 16)
-            saAes->key128(k);
-        else
-            saAes->key256(k);
-        key = saAes;
-    }
-    else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
-        if (!twoFishInit) {
-            Twofish_initialise();
-            twoFishInit = 1;
-        }
-        key = new uint8_t[sizeof(Twofish_key)];
-        memset(key, 0, sizeof(Twofish_key));
-        Twofish_prepare_key((Twofish_Byte*)k, keyLength,  (Twofish_key*)key);
-    }
-    else
-        return false;
-
-    return true;
-}
-
-void SrtpSymCrypto::encrypt(const uint8_t* input, uint8_t* output) {
-    if (algorithm == SrtpEncryptionAESCM || algorithm == SrtpEncryptionAESF8) {
-        AESencrypt *saAes = reinterpret_cast<AESencrypt*>(key);
-        saAes->encrypt(input, output);
-    }
-    else if (algorithm == SrtpEncryptionTWOCM || algorithm == SrtpEncryptionTWOF8) {
-        Twofish_encrypt((Twofish_key*)key, (Twofish_Byte*)input,
-                        (Twofish_Byte*)output); 
-    }
-}
-
-void SrtpSymCrypto::get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv) {
-    uint16_t ctr = 0;
-    unsigned char temp[SRTP_BLOCK_SIZE];
-
-    for(ctr = 0; ctr < length/SRTP_BLOCK_SIZE; ctr++) {
-        //compute the cipher stream
-        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);
-        iv[15] = (uint8_t)((ctr & 0x00FF));
-
-        encrypt(iv, &output[ctr*SRTP_BLOCK_SIZE]);
-    }
-    if ((length % SRTP_BLOCK_SIZE) > 0) {
-        // Treat the last bytes:
-        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);
-        iv[15] = (uint8_t)((ctr & 0x00FF));
-
-        encrypt(iv, temp);
-        memcpy(&output[ctr*SRTP_BLOCK_SIZE], temp, length % SRTP_BLOCK_SIZE );
-    }
-}
-
-void SrtpSymCrypto::ctr_encrypt(const uint8_t* input, uint32_t input_length, uint8_t* output, uint8_t* iv) {
-
-    if (key == NULL)
-        return;
-
-    uint16_t ctr = 0;
-    unsigned char temp[SRTP_BLOCK_SIZE];
-
-    int l = input_length/SRTP_BLOCK_SIZE;
-    for (ctr = 0; ctr < l; ctr++ ) {
-        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);
-        iv[15] = (uint8_t)((ctr & 0x00FF));
-
-        encrypt(iv, temp);
-        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {
-            *output++ = temp[i] ^ *input++;
-        }
-
-    }
-    l = input_length % SRTP_BLOCK_SIZE;
-    if (l > 0) {
-        // Treat the last bytes:
-        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);
-        iv[15] = (uint8_t)((ctr & 0x00FF));
-
-        encrypt(iv, temp);
-        for (int i = 0; i < l; i++ ) {
-            *output++ = temp[i] ^ *input++;
-        }
-    }
-}
-
-void SrtpSymCrypto::ctr_encrypt( uint8_t* data, uint32_t data_length, uint8_t* iv ) {
-
-    if (key == NULL)
-        return;
-
-    uint16_t ctr = 0;
-    unsigned char temp[SRTP_BLOCK_SIZE];
-
-    int l = data_length/SRTP_BLOCK_SIZE;
-    for (ctr = 0; ctr < l; ctr++ ) {
-        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);
-        iv[15] = (uint8_t)((ctr & 0x00FF));
-
-        encrypt(iv, temp);
-        for (int i = 0; i < SRTP_BLOCK_SIZE; i++ ) {
-            *data++ ^= temp[i];
-        }
-
-    }
-    l = data_length % SRTP_BLOCK_SIZE;
-    if (l > 0) {
-        // Treat the last bytes:
-        iv[14] = (uint8_t)((ctr & 0xFF00) >>  8);
-        iv[15] = (uint8_t)((ctr & 0x00FF));
-
-        encrypt(iv, temp);
-        for (int i = 0; i < l; i++ ) {
-            *data++ ^= temp[i];
-        }
-    }
-}
-
-void SrtpSymCrypto::f8_encrypt(const uint8_t* data, uint32_t data_length,
-                         uint8_t* iv, SrtpSymCrypto* f8Cipher ) {
-
-    f8_encrypt(data, data_length, const_cast<uint8_t*>(data), iv, f8Cipher);
-}
-
-#define MAX_KEYLEN 32
-
-void SrtpSymCrypto::f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen,
-             uint8_t* salt, int32_t saltLen) {
-
-    unsigned char *cp_in, *cp_in1, *cp_out;
-
-    unsigned char maskedKey[MAX_KEYLEN];
-    unsigned char saltMask[MAX_KEYLEN];
-
-    if (keyLen > MAX_KEYLEN)
-        return;
-
-    if (saltLen > keyLen)
-        return;
-    /*
-     * First copy the salt into the mask field, then fill with 0x55 to
-     * get a full key.
-     */
-    memcpy(saltMask, salt, saltLen);
-    memset(saltMask+saltLen, 0x55, keyLen-saltLen);
-
-    /*
-     * XOR the original key with the above created mask to
-     * get the special key.
-     */
-    cp_out = maskedKey;
-    cp_in = key;
-    cp_in1 = saltMask;
-    for (int i = 0; i < keyLen; i++) {
-        *cp_out++ = *cp_in++ ^ *cp_in1++;
-    }
-    /*
-     * Prepare the a new AES cipher with the special key to compute IV'
-     */
-    f8Cipher->setNewKey(maskedKey, keyLen);
-}
-
-void SrtpSymCrypto::f8_encrypt(const uint8_t* in, uint32_t in_length, uint8_t* out,
-                         uint8_t* iv, SrtpSymCrypto* f8Cipher ) {
-
-
-    int offset = 0;
-
-    unsigned char ivAccent[SRTP_BLOCK_SIZE];
-    unsigned char S[SRTP_BLOCK_SIZE];
-
-    F8_CIPHER_CTX f8ctx;
-
-    if (key == NULL)
-        return;
-    /*
-     * Get memory for the derived IV (IV')
-     */
-    f8ctx.ivAccent = ivAccent;
-    /*
-     * Use the derived IV encryption setup to encrypt the original IV to produce IV'.
-     */
-    f8Cipher->encrypt(iv, f8ctx.ivAccent);
-
-    f8ctx.J = 0;                       // initialize the counter
-    f8ctx.S = S;               // get the key stream buffer
-
-    memset(f8ctx.S, 0, SRTP_BLOCK_SIZE); // initial value for key stream
-
-    while (in_length >= SRTP_BLOCK_SIZE) {
-        processBlock(&f8ctx, in+offset, SRTP_BLOCK_SIZE, out+offset);
-        in_length -= SRTP_BLOCK_SIZE;
-        offset += SRTP_BLOCK_SIZE;
-    }
-    if (in_length > 0) {
-        processBlock(&f8ctx, in+offset, in_length, out+offset);
-    }
-}
-
-int SrtpSymCrypto::processBlock(F8_CIPHER_CTX *f8ctx, const uint8_t* in, int32_t length, uint8_t* out) {
-
-    int i;
-    const uint8_t *cp_in;
-    uint8_t* cp_in1, *cp_out;
-    uint32_t *ui32p;
-
-    /*
-     * XOR the previous key stream with IV'
-     * ( S(-1) xor IV' )
-     */
-    cp_in = f8ctx->ivAccent;
-    cp_out = f8ctx->S;
-    for (i = 0; i < SRTP_BLOCK_SIZE; i++) {
-        *cp_out++ ^= *cp_in++;
-    }
-    /*
-     * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter
-     */
-    ui32p = (uint32_t *)f8ctx->S;
-    ui32p[3] ^= zrtpHtonl(f8ctx->J);
-    f8ctx->J++;
-    /*
-     * Now compute the new key stream using AES encrypt
-     */
-    encrypt(f8ctx->S, f8ctx->S);
-    /*
-     * as the last step XOR the plain text with the key stream to produce
-     * the ciphertext.
-     */
-    cp_out = out;
-    cp_in = in;
-    cp_in1 = f8ctx->S;
-    for (i = 0; i < length; i++) {
-        *cp_out++ = *cp_in++ ^ *cp_in1++;
-    }
-    return length;
-}
-
diff --git a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h b/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h
index 09bdcab..1b596c8 100644
--- a/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h
+++ b/jni/libzrtp/sources/srtp/crypto/SrtpSymCrypto.h
@@ -1,5 +1,5 @@
 /*

-  Copyright (C) 2008-2012 Werner Dittmann

+  Copyright (C) 2005, 2004, 2010, 2012 Erik Eliasson, Johan Bilien, Werner Dittmann

 

   This library is free software; you can redistribute it and/or

   modify it under the terms of the GNU Lesser General Public

@@ -36,7 +36,7 @@
 

 /**

  * @file SrtpSymCrypto.h

- * @brief Class which implements SRTP cryptographic functions

+ * @brief Class which implements SRTP AES cryptographic functions

  * 

  * @ingroup GNU_ZRTP

  * @{

@@ -56,7 +56,7 @@
 } F8_CIPHER_CTX;

 

 /**

- * @brief Implments the SRTP encryption modes as defined in RFC3711

+ * Implments the SRTP encryption modes as defined in RFC3711

  *

  * The SRTP specification defines two encryption modes, AES-CTR

  * (AES Counter mode) and AES-F8 mode. The AES-CTR is required,

@@ -70,43 +70,31 @@
  * The implementation uses the openSSL library as its cryptographic

  * backend.

  *

+ * @author Erik Eliasson <eliasson@it.kth.se>

+ * @author Johan Bilien <jobi@via.ecp.fr>

  * @author Werner Dittmann <Werner.Dittmann@t-online.de>

  */

 class SrtpSymCrypto {

 public:

-    /**

-     * @brief Constructor that does not initialize key data

-     *

-     * @param algo

-     *    The Encryption algorithm to use.Possible values are <code>

-     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8

-     *    SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1

-     *    for CM (Counter mode) and 4.1.2 for F8 mode.

-     */

     SrtpSymCrypto(int algo = SrtpEncryptionAESCM);

 

     /**

-     * @brief Constructor that initializes key data

+     * Constructor that initializes key data

      * 

      * @param key

      *     Pointer to key bytes.

      * @param key_length

      *     Number of key bytes.

-     * @param algo

-     *    The Encryption algorithm to use.Possible values are <code>

-     *    SrtpEncryptionNull, SrtpEncryptionAESCM, SrtpEncryptionAESF8

-     *    SrtpEncryptionTWOCM, SrtpEncryptionTWOF8</code>. See chapter 4.1.1

-     *    for CM (Counter mode) and 4.1.2 for F8 mode.

      */

     SrtpSymCrypto(uint8_t* key, int32_t key_length, int algo = SrtpEncryptionAESCM);

 

     ~SrtpSymCrypto();

 

     /**

-     * @brief Encrypts the input to the output.

+     * Encrypts the inpout to the output.

      *

      * Encrypts one input block to one output block. Each block

-     * is 16 bytes according to the encryption algorithms used.

+     * is 16 bytes according to the AES encryption algorithm used.

      *

      * @param input

      *    Pointer to input block, must be 16 bytes

@@ -117,7 +105,7 @@
     void encrypt( const uint8_t* input, uint8_t* output );

 

     /**

-     * @brief Set new key

+     * Set new key

      *

      * @param key

      *   Pointer to key data, must have at least a size of keyLength 

@@ -131,7 +119,7 @@
     bool setNewKey(const uint8_t* key, int32_t keyLength);

 

     /**

-     * @brief Computes the cipher stream for AES CM mode.

+     * Computes the cipher stream for AES CM mode.

      *

      * @param output

      *    Pointer to a buffer that receives the cipher stream. Must be

@@ -148,9 +136,9 @@
     void get_ctr_cipher_stream(uint8_t* output, uint32_t length, uint8_t* iv);

 

     /**

-     * @brief Counter-mode encryption.

+     * Counter-mode encryption.

      *

-     * This method performs the CM encryption.

+     * This method performs the AES CM encryption.

      *

      * @param input

      *    Pointer to input buffer, must be <code>inputLen</code> bytes.

@@ -168,9 +156,9 @@
     void ctr_encrypt(const uint8_t* input, uint32_t inputLen, uint8_t* output, uint8_t* iv );

 

     /**

-     * @brief Counter-mode encryption, in place.

+     * Counter-mode encryption, in place.

      *

-     * This method performs the CM encryption.

+     * This method performs the AES CM encryption.

      *

      * @param data

      *    Pointer to input and output block, must be <code>dataLen</code>

@@ -186,12 +174,12 @@
     void ctr_encrypt(uint8_t* data, uint32_t data_length, uint8_t* iv );

 

     /**

-     * @brief Derive a cipher context to compute the IV'.

+     * Derive a AES context to compute the IV'.

      *

      * See chapter 4.1.2.1 in RFC 3711.

      *

      * @param f8Cipher

-     *    Pointer to the cipher context that will be used to encrypt IV to IV'

+     *    Pointer to the AES context that will be used to encrypt IV to IV'

      *

      * @param key

      *    The master key

@@ -208,9 +196,10 @@
     void f8_deriveForIV(SrtpSymCrypto* f8Cipher, uint8_t* key, int32_t keyLen, uint8_t* salt, int32_t saltLen);

 

     /**

-     * @brief F8 mode encryption, in place.

+     * AES F8 mode encryption, in place.

      *

-     * This method performs the F8 encryption, see chapter 4.1.2 in RFC 3711.

+     * This method performs the AES F8 encryption, see chapter 4.1.2

+     * in RFC 3711.

      *

      * @param data

      *    Pointer to input and output block, must be <code>dataLen</code>

@@ -229,9 +218,10 @@
     void f8_encrypt(const uint8_t* data, uint32_t dataLen, uint8_t* iv, SrtpSymCrypto* f8Cipher);

 

     /**

-     * @brief F8 mode encryption.

+     * AES F8 mode encryption.

      *

-     * This method performs the F8 encryption, see chapter 4.1.2 in RFC 3711.

+     * This method performs the AES F8 encryption, see chapter 4.1.2

+     * in RFC 3711.

      *

      * @param data

      *    Pointer to input and output block, must be <code>dataLen</code>

@@ -262,13 +252,13 @@
 int testF8();

 #pragma GCC visibility pop

 

-/* Only SrtpSymCrypto functions defines the MAKE_F8_TEST */

+/* Only SrtpSymCrypto functions define the MAKE_F8_TEST */

 #ifdef MAKE_F8_TEST

 

 #include <cstring>

 #include <iostream>

 #include <cstdio>

-#include <common/osSpecifics.h>

+#include <arpa/inet.h>

 

 using namespace std;

 

@@ -348,7 +338,7 @@
     derivedIv[0] = 0;

 

     // set ROC in network order into IV

-    ui32p[3] = zrtpHtonl(ROC);

+    ui32p[3] = htonl(ROC);

 

     int32_t pad = 0;

 

@@ -393,3 +383,11 @@
 

 #endif

 

+/** EMACS **

+ * Local variables:

+ * mode: c++

+ * c-default-style: ellemtel

+ * c-basic-offset: 4

+ * End:

+ */

+

diff --git a/jni/libzrtp/sources/cryptcommon/brg_endian.h b/jni/libzrtp/sources/srtp/crypto/brg_endian.h
similarity index 66%
rename from jni/libzrtp/sources/cryptcommon/brg_endian.h
rename to jni/libzrtp/sources/srtp/crypto/brg_endian.h
index 82e48f0..c03c7c5 100644
--- a/jni/libzrtp/sources/cryptcommon/brg_endian.h
+++ b/jni/libzrtp/sources/srtp/crypto/brg_endian.h
@@ -1,39 +1,49 @@
 /*

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

-Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved.

+ ---------------------------------------------------------------------------

+ Copyright (c) 2003, Dr Brian Gladman, Worcester, UK.   All rights reserved.

 

-The redistribution and use of this software (with or without changes)

-is allowed without the payment of fees or royalties provided that:

+ LICENSE TERMS

 

-  source code distributions include the above copyright notice, this

-  list of conditions and the following disclaimer;

+ The free distribution and use of this software in both source and binary

+ form is allowed (with or without changes) provided that:

 

-  binary distributions include the above copyright notice, this list

-  of conditions and the following disclaimer in their documentation.

+   1. distributions of this source code include the above copyright

+      notice, this list of conditions and the following disclaimer;

 

-This software is provided 'as is' with no explicit or implied warranties

-in respect of its operation, including, but not limited to, correctness

-and fitness for purpose.

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

-Issue Date: 20/12/2007

+   2. distributions in binary form include the above copyright

+      notice, this list of conditions and the following disclaimer

+      in the documentation and/or other associated materials;

+

+   3. the copyright holder's name is not used to endorse products

+      built using this software without specific written permission.

+

+ ALTERNATIVELY, provided that this notice is retained in full, this product

+ may be distributed under the terms of the GNU General Public License (GPL),

+ in which case the provisions of the GPL apply INSTEAD OF those given above.

+

+ DISCLAIMER

+

+ This software is provided 'as is' with no explicit or implied warranties

+ in respect of its properties, including, but not limited to, correctness

+ and/or fitness for purpose.

+ ---------------------------------------------------------------------------

+ Issue 20/10/2006

 */

 

-#ifndef _BRG_ENDIAN_H

-#define _BRG_ENDIAN_H

+#ifndef BRG_ENDIAN_H

+#define BRG_ENDIAN_H

 

 #define IS_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */

 #define IS_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */

 

 /* Include files where endian defines and byteswap functions may reside */

-#if defined( __sun )

-#  include <sys/isa_defs.h>

-#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )

+#if defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )

 #  include <sys/endian.h>

 #elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \

       defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )

 #  include <machine/endian.h>

 #elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )

-#  if !defined( __MINGW32__ ) && !defined( _AIX )

+#  if !defined( __MINGW32__ ) && !defined(AVR)

 #    include <endian.h>

 #    if !defined( __BEOS__ )

 #      include <byteswap.h>

@@ -101,7 +111,7 @@
       defined( __i386__ )  || defined( _M_I86 )  || defined( _M_IX86 )    || \

       defined( __OS2__ )   || defined( sun386 )  || defined( __TURBOC__ ) || \

       defined( vax )       || defined( vms )     || defined( VMS )        || \

-      defined( __VMS )     || defined( _M_X64 )

+      defined( __VMS )     || defined( _M_X64 )  || defined( AVR )

 #  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN

 

 #elif defined( AMIGA )   || defined( applec )    || defined( __AS400__ )  || \

@@ -110,7 +120,7 @@
       defined( __MRC__ ) || defined( __MVS__ )   || defined( __MWERKS__ ) || \

       defined( sparc )   || defined( __sparc)    || defined( SYMANTEC_C ) || \

       defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM )   || \

-      defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )

+      defined( THINK_C ) || defined( __VMCMS__ )

 #  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN

 

 #elif 0     /* **** EDIT HERE IF NECESSARY **** */

@@ -120,7 +130,19 @@
 #else

 #  error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order

 #endif

-

 #endif

 

+/* special handler for IA64, which may be either endianness (?)  */

+/* here we assume little-endian, but this may need to be changed */

+#if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)

+#  define PLATFORM_MUST_ALIGN (1)

+#ifndef PLATFORM_BYTE_ORDER

+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN

 #endif

+#endif

+

+#ifndef   PLATFORM_MUST_ALIGN

+#  define PLATFORM_MUST_ALIGN (0)

+#endif

+

+#endif  /* ifndef BRG_ENDIAN_H */

diff --git a/jni/libzrtp/sources/srtp/crypto/brg_types.h b/jni/libzrtp/sources/srtp/crypto/brg_types.h
new file mode 100644
index 0000000..6db737d
--- /dev/null
+++ b/jni/libzrtp/sources/srtp/crypto/brg_types.h
@@ -0,0 +1,188 @@
+/*

+ ---------------------------------------------------------------------------

+ Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.

+

+ LICENSE TERMS

+

+ The free distribution and use of this software in both source and binary

+ form is allowed (with or without changes) provided that:

+

+   1. distributions of this source code include the above copyright

+      notice, this list of conditions and the following disclaimer;

+

+   2. distributions in binary form include the above copyright

+      notice, this list of conditions and the following disclaimer

+      in the documentation and/or other associated materials;

+

+   3. the copyright holder's name is not used to endorse products

+      built using this software without specific written permission.

+

+ ALTERNATIVELY, provided that this notice is retained in full, this product

+ may be distributed under the terms of the GNU General Public License (GPL),

+ in which case the provisions of the GPL apply INSTEAD OF those given above.

+

+ DISCLAIMER

+

+ This software is provided 'as is' with no explicit or implied warranties

+ in respect of its properties, including, but not limited to, correctness

+ and/or fitness for purpose.

+ ---------------------------------------------------------------------------

+ Issue 09/09/2006

+

+ The unsigned integer types defined here are of the form uint_<nn>t where

+ <nn> is the length of the type; for example, the unsigned 32-bit type is

+ 'uint_32t'.  These are NOT the same as the 'C99 integer types' that are

+ defined in the inttypes.h and stdint.h headers since attempts to use these

+ types have shown that support for them is still highly variable.  However,

+ since the latter are of the form uint<nn>_t, a regular expression search

+ and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')

+ can be used to convert the types used here to the C99 standard types.

+*/

+

+#ifndef BRG_TYPES_H

+#define BRG_TYPES_H

+

+#if defined(__cplusplus)

+extern "C" {

+#endif

+

+#include <limits.h>

+

+#ifndef BRG_UI8

+#  define BRG_UI8

+#  if UCHAR_MAX == 255u

+     typedef unsigned char uint_8t;

+#  else

+#    error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h

+#  endif

+#endif

+

+#ifndef BRG_UI16

+#  define BRG_UI16

+#  if USHRT_MAX == 65535u

+     typedef unsigned short uint_16t;

+#  else

+#    error Please define uint_16t as a 16-bit unsigned short type in brg_types.h

+#  endif

+#endif

+

+#ifndef BRG_UI32

+#  define BRG_UI32

+#  if UINT_MAX == 4294967295u

+#    define li_32(h) 0x##h##u

+     typedef unsigned int uint_32t;

+#  elif ULONG_MAX == 4294967295u

+#    define li_32(h) 0x##h##ul

+     typedef unsigned long uint_32t;

+#  elif defined( _CRAY )

+#    error This code needs 32-bit data types, which Cray machines do not provide

+#  else

+#    error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h

+#  endif

+#endif

+

+#ifndef BRG_UI64

+#  if defined( __BORLANDC__ ) && !defined( __MSDOS__ )

+#    define BRG_UI64

+#    define li_64(h) 0x##h##ui64

+     typedef unsigned __int64 uint_64t;

+#  elif defined( _MSC_VER ) && ( _MSC_VER < 1300 )    /* 1300 == VC++ 7.0 */

+#    define BRG_UI64

+#    define li_64(h) 0x##h##ui64

+     typedef unsigned __int64 uint_64t;

+#  elif defined( __sun ) && defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful

+#    define BRG_UI64

+#    define li_64(h) 0x##h##ull

+     typedef unsigned long long uint_64t;

+#  elif defined( UINT_MAX ) && UINT_MAX > 4294967295u

+#    if UINT_MAX == 18446744073709551615u

+#      define BRG_UI64

+#      define li_64(h) 0x##h##u

+       typedef unsigned int uint_64t;

+#    endif

+#  elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u

+#    if ULONG_MAX == 18446744073709551615ul

+#      define BRG_UI64

+#      define li_64(h) 0x##h##ul

+       typedef unsigned long uint_64t;

+#    endif

+#  elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u

+#    if ULLONG_MAX == 18446744073709551615ull

+#      define BRG_UI64

+#      define li_64(h) 0x##h##ull

+       typedef unsigned long long uint_64t;

+#    endif

+#  elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u

+#    if ULONG_LONG_MAX == 18446744073709551615ull

+#      define BRG_UI64

+#      define li_64(h) 0x##h##ull

+       typedef unsigned long long uint_64t;

+#    endif

+#  elif defined(__GNUC__)  /* DLW: avoid mingw problem with -ansi */

+#      define BRG_UI64

+#      define li_64(h) 0x##h##ull

+       typedef unsigned long long uint_64t;

+#  endif

+#endif

+

+#if defined( NEED_UINT_64T ) && !defined( BRG_UI64 )

+#  error Please define uint_64t as an unsigned 64 bit type in brg_types.h

+#endif

+

+#ifndef RETURN_VALUES

+#  define RETURN_VALUES

+#  if defined( DLL_EXPORT )

+#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )

+#      define VOID_RETURN    __declspec( dllexport ) void __stdcall

+#      define INT_RETURN     __declspec( dllexport ) int  __stdcall

+#    elif defined( __GNUC__ )

+#      define VOID_RETURN    __declspec( __dllexport__ ) void

+#      define INT_RETURN     __declspec( __dllexport__ ) int

+#    else

+#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers

+#    endif

+#  elif defined( DLL_IMPORT )

+#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )

+#      define VOID_RETURN    __declspec( dllimport ) void __stdcall

+#      define INT_RETURN     __declspec( dllimport ) int  __stdcall

+#    elif defined( __GNUC__ )

+#      define VOID_RETURN    __declspec( __dllimport__ ) void

+#      define INT_RETURN     __declspec( __dllimport__ ) int

+#    else

+#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers

+#    endif

+#  elif defined( __WATCOMC__ )

+#    define VOID_RETURN  void __cdecl

+#    define INT_RETURN   int  __cdecl

+#  else

+#    define VOID_RETURN  void

+#    define INT_RETURN   int

+#  endif

+#endif

+

+/*  These defines are used to declare buffers in a way that allows

+    faster operations on longer variables to be used.  In all these

+    defines 'size' must be a power of 2 and >= 8

+

+    dec_unit_type(size,x)       declares a variable 'x' of length 

+                                'size' bits

+

+    dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize' 

+                                bytes defined as an array of variables

+                                each of 'size' bits (bsize must be a 

+                                multiple of size / 8)

+

+    ptr_cast(x,size)            casts a pointer to a pointer to a 

+                                varaiable of length 'size' bits

+*/

+

+#define ui_type(size)               uint_##size##t

+#define dec_unit_type(size,x)       typedef ui_type(size) x

+#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)]

+#define ptr_cast(x,size)            ((ui_type(size)*)(x))

+

+#if defined(__cplusplus)

+}

+#endif

+

+#endif

diff --git a/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp b/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp
index 1c743d2..78fad51 100644
--- a/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/gcrypt/InitializeGcrypt.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2006-2013 Werner Dittmann
+  Copyright (C) 2006-2007 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -17,7 +17,7 @@
 
 #include <stdio.h>
 
-#include <string.h>
+#include <malloc.h>
 #include <pthread.h>
 #include <errno.h>
 #include <gcrypt.h>
diff --git a/jni/libzrtp/sources/srtp/crypto/hmac.cpp b/jni/libzrtp/sources/srtp/crypto/hmac.cpp
deleted file mode 100644
index 38028a3..0000000
--- a/jni/libzrtp/sources/srtp/crypto/hmac.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
-  Copyright (C) 2012 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include "crypto/sha1.h"
-#include "crypto/hmac.h"
-
-typedef struct _hmacSha1Context {
-    sha1_ctx ctx;
-    sha1_ctx innerCtx;
-    sha1_ctx outerCtx;
-} hmacSha1Context;
-
-static int32_t hmacSha1Init(hmacSha1Context *ctx, const uint8_t *key, uint32_t kLength)
-{
-    int32_t i;
-    uint8_t localPad[SHA1_BLOCK_SIZE] = {0};
-    uint8_t localKey[SHA1_BLOCK_SIZE] = {0};
-
-    if (key == NULL)
-        return 0;
-
-    memset(ctx, 0, sizeof(hmacSha1Context));
-
-    /* check key length and reduce it if necessary */
-    if (kLength > SHA1_BLOCK_SIZE) {
-        sha1_begin(&ctx->ctx);
-        sha1_hash(key, kLength, &ctx->ctx);
-        sha1_end(localKey, &ctx->ctx);
-    }
-    else {
-        memcpy(localKey, key, kLength);
-    }
-    /* prepare inner hash and hold the context */
-    for (i = 0; i < SHA1_BLOCK_SIZE; i++)
-        localPad[i] = localKey[i] ^ 0x36;
-
-    sha1_begin(&ctx->innerCtx);
-    sha1_hash(localPad, SHA1_BLOCK_SIZE, &ctx->innerCtx);
-
-    /* prepare outer hash and hold the context */
-    for (i = 0; i < SHA1_BLOCK_SIZE; i++)
-        localPad[i] = localKey[i] ^ 0x5c;
-
-    sha1_begin(&ctx->outerCtx);
-    sha1_hash(localPad, SHA1_BLOCK_SIZE, &ctx->outerCtx);
-
-    /* copy prepared inner hash to work hash - ready to process data */
-    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha1_ctx));
-
-    memset(localKey, 0, sizeof(localKey));
-
-    return 1;
-}
-
-static void hmacSha1Reset(hmacSha1Context *ctx)
-{
-    /* copy prepared inner hash to work hash context */
-    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha1_ctx));
-}
-
-static void hmacSha1Update(hmacSha1Context *ctx, const uint8_t *data, uint32_t dLength)
-{
-    /* hash new data to work hash context */
-    sha1_hash(data, dLength, &ctx->ctx);
-}
-
-static void hmacSha1Final(hmacSha1Context *ctx, uint8_t *mac)
-{
-    uint8_t tmpDigest[SHA1_DIGEST_SIZE];
-
-    /* finalize work hash context */
-    sha1_end(tmpDigest, &ctx->ctx);
-
-    /* copy prepared outer hash to work hash */
-    memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha1_ctx));
-
-    /* hash inner digest to work (outer) hash context */
-    sha1_hash(tmpDigest, SHA1_DIGEST_SIZE, &ctx->ctx);
-
-    /* finalize work hash context to get the hmac*/
-    sha1_end(mac, &ctx->ctx);
-}
-
-
-void hmac_sha1(uint8_t *key, int32_t keyLength, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
-    hmacSha1Context ctx;
-
-    hmacSha1Init(&ctx, key, keyLength);
-    hmacSha1Update(&ctx, data, dataLength);
-    hmacSha1Final(&ctx, mac);
-    *macLength = SHA1_BLOCK_SIZE;
-}
-
-void hmac_sha1( uint8_t* key, int32_t keyLength, const uint8_t* dataChunks[], uint32_t dataChunckLength[],
-                uint8_t* mac, int32_t* macLength )
-{
-    hmacSha1Context ctx;
-
-    hmacSha1Init(&ctx, key, keyLength);
-
-    while (*dataChunks) {
-        hmacSha1Update(&ctx, *dataChunks, *dataChunckLength);
-        dataChunks ++;
-        dataChunckLength ++;
-    }
-    hmacSha1Final(&ctx, mac);
-    *macLength = SHA1_BLOCK_SIZE;
-}
-
-void* createSha1HmacContext(uint8_t* key, int32_t keyLength)
-{
-    hmacSha1Context *ctx = reinterpret_cast<hmacSha1Context*>(malloc(sizeof(hmacSha1Context)));
-
-    hmacSha1Init(ctx, key, keyLength);
-    return ctx;
-}
-
-void hmacSha1Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,
-                uint8_t* mac, int32_t* macLength)
-{
-    hmacSha1Context *pctx = (hmacSha1Context*)ctx;
-
-    hmacSha1Reset(pctx);
-    hmacSha1Update(pctx, data, dataLength);
-    hmacSha1Final(pctx, mac);
-    *macLength = SHA1_BLOCK_SIZE;
-}
-
-void hmacSha1Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
-                uint8_t* mac, int32_t* macLength )
-{
-    hmacSha1Context *pctx = (hmacSha1Context*)ctx;
-
-    hmacSha1Reset(pctx);
-    while (*data) {
-        hmacSha1Update(pctx, *data, *dataLength);
-        data++;
-        dataLength++;
-    }
-    hmacSha1Final(pctx, mac);
-    *macLength = SHA1_BLOCK_SIZE;
-}
-
-void freeSha1HmacContext(void* ctx)
-{
-    if (ctx) {
-        memset(ctx, 0, sizeof(hmacSha1Context));
-        free(ctx);
-    }
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/srtp/crypto/hmac.h b/jni/libzrtp/sources/srtp/crypto/hmac.h
index 6d99f92..4abfa8f 100644
--- a/jni/libzrtp/sources/srtp/crypto/hmac.h
+++ b/jni/libzrtp/sources/srtp/crypto/hmac.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2010 Werner Dittmann
+  Copyright (C) 2005, 2004, 2010 Erik Eliasson, Johan Bilien, Werner Dittmann
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -32,6 +32,8 @@
 /**
  * Functions to compute SHA1 HAMAC.
  *
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
  * @author Werner Dittmann
  */
 
diff --git a/jni/libzrtp/sources/cryptcommon/macSkein.cpp b/jni/libzrtp/sources/srtp/crypto/macSkein.cpp
similarity index 93%
rename from jni/libzrtp/sources/cryptcommon/macSkein.cpp
rename to jni/libzrtp/sources/srtp/crypto/macSkein.cpp
index 9da946f..ba4c260 100644
--- a/jni/libzrtp/sources/cryptcommon/macSkein.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/macSkein.cpp
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2010-2013 Werner Dittmann
+  Copyright (C) 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -15,7 +15,7 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <cryptcommon/macSkein.h>
+#include <crypto/macSkein.h>
 #include <stdlib.h>
 
 void macSkein(uint8_t* key, int32_t key_length,
diff --git a/jni/libzrtp/sources/cryptcommon/macSkein.h b/jni/libzrtp/sources/srtp/crypto/macSkein.h
similarity index 96%
rename from jni/libzrtp/sources/cryptcommon/macSkein.h
rename to jni/libzrtp/sources/srtp/crypto/macSkein.h
index ce5d380..71c2ad9 100644
--- a/jni/libzrtp/sources/cryptcommon/macSkein.h
+++ b/jni/libzrtp/sources/srtp/crypto/macSkein.h
@@ -1,8 +1,8 @@
 /*
-  Copyright (C) 2010-2013 Werner Dittmann
+  Copyright (C) 2010 Werner Dittmann
 
   This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
+  it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
@@ -19,7 +19,7 @@
 #ifndef MAC_SKEIN_H
 #define MAC_SKEIN_H
 
-#include <cryptcommon/skeinApi.h>
+#include <crypto/skeinApi.h>
 /**
  * @file macSkein.h
  * @brief Function that provide Skein MAC support
diff --git a/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp b/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp
index 00d4476..3d6747d 100644
--- a/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/openssl/SrtpSymCrypto.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2012 Werner Dittmann
+  Copyright (C) 2005, 2004, 2012 Erik Eliasson, Johan Bilien, Werner Dittmann
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -30,6 +30,8 @@
   */
 
 /**
+ * @author Erik Eliasson <eliasson@it.kth.se>
+ * @author Johan Bilien <jobi@via.ecp.fr>
  * @author Werner Dittmann <Werner.Dittmann@t-online.de>
  */
 
@@ -38,10 +40,10 @@
 #include <stdlib.h>
 #include <openssl/aes.h>                // the include of openSSL
 #include <crypto/SrtpSymCrypto.h>
-#include <cryptcommon/twofish.h>
+#include <crypto/twofish.h>
 #include <string.h>
 #include <stdio.h>
-#include <common/osSpecifics.h>
+#include <arpa/inet.h>
 
 SrtpSymCrypto::SrtpSymCrypto(int algo):key(NULL), algorithm(algo) {
 }
@@ -294,7 +296,7 @@
      * Now XOR (S(n-1) xor IV') with the current counter, then increment the counter
      */
     ui32p = (uint32_t *)f8ctx->S;
-    ui32p[3] ^= zrtpHtonl(f8ctx->J);
+    ui32p[3] ^= htonl(f8ctx->J);
     f8ctx->J++;
     /*
      * Now compute the new key stream using AES encrypt
@@ -313,3 +315,12 @@
     return length;
 }
 
+
+/** EMACS **
+ * Local variables:
+ * mode: c++
+ * c-default-style: ellemtel
+ * c-basic-offset: 4
+ * End:
+ */
+
diff --git a/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp b/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp
index cfe73c3..88d33a1 100644
--- a/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp
+++ b/jni/libzrtp/sources/srtp/crypto/openssl/hmac.cpp
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2010 Werner Dittmann
+  Copyright (C) 2005, 2004, 2010, Erik Eliasson, Johan Bilien, Werner Dittmann
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -30,7 +30,9 @@
  */
 
 /*
- * Authors: Werner Dittmann
+ * Authors: Erik Eliasson <eliasson@it.kth.se>
+ *          Johan Bilien <jobi@via.ecp.fr>
+ *          Werner Dittmann
  */
 
 #include <stdint.h>
@@ -65,7 +67,7 @@
 void* createSha1HmacContext(uint8_t* key, int32_t key_length)
 {
     HMAC_CTX* ctx = (HMAC_CTX*)malloc(sizeof(HMAC_CTX));
-
+    
     HMAC_CTX_init(ctx);
     HMAC_Init_ex(ctx, key, key_length, EVP_sha1(), NULL);
     return ctx;
diff --git a/jni/libzrtp/sources/srtp/crypto/sha1.c b/jni/libzrtp/sources/srtp/crypto/sha1.c
deleted file mode 100644
index 31cee60..0000000
--- a/jni/libzrtp/sources/srtp/crypto/sha1.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products
-      built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-
- This is a byte oriented version of SHA1 that operates on arrays of bytes
- stored in memory.
-*/
-
-#include <string.h>     /* for memcpy() etc.        */
-
-#include "sha1.h"
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
-#pragma intrinsic(memcpy)
-#endif
-
-#if 0 && defined(_MSC_VER)
-#define rotl32  _lrotl
-#define rotr32  _lrotr
-#else
-#define rotl32(x,n)   (((x) << n) | ((x) >> (32 - n)))
-#define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))
-#endif
-
-#if !defined(bswap_32)
-#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
-#endif
-
-#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
-#define SWAP_BYTES
-#else
-#undef  SWAP_BYTES
-#endif
-
-#if defined(SWAP_BYTES)
-#define bsw_32(p,n) \
-    { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
-#else
-#define bsw_32(p,n)
-#endif
-
-#define SHA1_MASK   (SHA1_BLOCK_SIZE - 1)
-
-#if 0
-
-#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))
-#define parity(x,y,z)   ((x) ^ (y) ^ (z))
-#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-#else   /* Discovered by Rich Schroeppel and Colin Plumb   */
-
-#define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
-#define parity(x,y,z)   ((x) ^ (y) ^ (z))
-#define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))
-
-#endif
-
-/* Compile 64 bytes of hash data into SHA1 context. Note    */
-/* that this routine assumes that the byte order in the     */
-/* ctx->wbuf[] at this point is in such an order that low   */
-/* address bytes in the ORIGINAL byte stream will go in     */
-/* this buffer to the high end of 32-bit words on BOTH big  */
-/* and little endian systems                                */
-
-#ifdef ARRAY
-#define q(v,n)  v[n]
-#else
-#define q(v,n)  v##n
-#endif
-
-#define one_cycle(v,a,b,c,d,e,f,k,h)            \
-    q(v,e) += rotr32(q(v,a),27) +               \
-              f(q(v,b),q(v,c),q(v,d)) + k + h;  \
-    q(v,b)  = rotr32(q(v,b), 2)
-
-#define five_cycle(v,f,k,i)                 \
-    one_cycle(v, 0,1,2,3,4, f,k,hf(i  ));   \
-    one_cycle(v, 4,0,1,2,3, f,k,hf(i+1));   \
-    one_cycle(v, 3,4,0,1,2, f,k,hf(i+2));   \
-    one_cycle(v, 2,3,4,0,1, f,k,hf(i+3));   \
-    one_cycle(v, 1,2,3,4,0, f,k,hf(i+4))
-
-VOID_RETURN sha1_compile(sha1_ctx ctx[1])
-{   uint_32t    *w = ctx->wbuf;
-
-#ifdef ARRAY
-    uint_32t    v[5];
-    memcpy(v, ctx->hash, 5 * sizeof(uint_32t));
-#else
-    uint_32t    v0, v1, v2, v3, v4;
-    v0 = ctx->hash[0]; v1 = ctx->hash[1];
-    v2 = ctx->hash[2]; v3 = ctx->hash[3];
-    v4 = ctx->hash[4];
-#endif
-
-#define hf(i)   w[i]
-
-    five_cycle(v, ch, 0x5a827999,  0);
-    five_cycle(v, ch, 0x5a827999,  5);
-    five_cycle(v, ch, 0x5a827999, 10);
-    one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \
-
-#undef  hf
-#define hf(i) (w[(i) & 15] = rotl32(                    \
-                 w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \
-               ^ w[((i) +  2) & 15] ^ w[(i) & 15], 1))
-
-    one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16));
-    one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17));
-    one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18));
-    one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19));
-
-    five_cycle(v, parity, 0x6ed9eba1,  20);
-    five_cycle(v, parity, 0x6ed9eba1,  25);
-    five_cycle(v, parity, 0x6ed9eba1,  30);
-    five_cycle(v, parity, 0x6ed9eba1,  35);
-
-    five_cycle(v, maj, 0x8f1bbcdc,  40);
-    five_cycle(v, maj, 0x8f1bbcdc,  45);
-    five_cycle(v, maj, 0x8f1bbcdc,  50);
-    five_cycle(v, maj, 0x8f1bbcdc,  55);
-
-    five_cycle(v, parity, 0xca62c1d6,  60);
-    five_cycle(v, parity, 0xca62c1d6,  65);
-    five_cycle(v, parity, 0xca62c1d6,  70);
-    five_cycle(v, parity, 0xca62c1d6,  75);
-
-#ifdef ARRAY
-    ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
-    ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
-    ctx->hash[4] += v[4];
-#else
-    ctx->hash[0] += v0; ctx->hash[1] += v1;
-    ctx->hash[2] += v2; ctx->hash[3] += v3;
-    ctx->hash[4] += v4;
-#endif
-}
-
-VOID_RETURN sha1_begin(sha1_ctx ctx[1])
-{
-    ctx->count[0] = ctx->count[1] = 0;
-    ctx->hash[0] = 0x67452301;
-    ctx->hash[1] = 0xefcdab89;
-    ctx->hash[2] = 0x98badcfe;
-    ctx->hash[3] = 0x10325476;
-    ctx->hash[4] = 0xc3d2e1f0;
-}
-
-/* SHA1 hash data in an array of bytes into hash buffer and */
-/* call the hash_compile function as required.              */
-
-VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1])
-{   
-	uint_32t pos = (uint_32t)(ctx->count[0] & SHA1_MASK),
-            space = SHA1_BLOCK_SIZE - pos;
-    const unsigned char *sp = data;
-
-    if((ctx->count[0] += len) < len)
-        ++(ctx->count[1]);
-
-    while(len >= space)     /* tranfer whole blocks if possible  */
-    {
-        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
-        sp += space; len -= space; space = SHA1_BLOCK_SIZE; pos = 0;
-        bsw_32(ctx->wbuf, SHA1_BLOCK_SIZE >> 2);
-        sha1_compile(ctx);
-    }
-
-    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
-}
-
-/* SHA1 final padding and digest calculation  */
-
-VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1])
-{   uint_32t    i = (uint_32t)(ctx->count[0] & SHA1_MASK);
-
-    /* put bytes in the buffer in an order in which references to   */
-    /* 32-bit words will put bytes with lower addresses into the    */
-    /* top of 32 bit words on BOTH big and little endian machines   */
-    bsw_32(ctx->wbuf, (i + 3) >> 2);
-
-    /* we now need to mask valid bytes and add the padding which is */
-    /* a single 1 bit and as many zero bits as necessary. Note that */
-    /* we can always add the first padding byte here because the    */
-    /* buffer always has at least one empty slot                    */
-    ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
-    ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
-
-    /* we need 9 or more empty positions, one for the padding byte  */
-    /* (above) and eight for the length count. If there is not      */
-    /* enough space, pad and empty the buffer                       */
-    if(i > SHA1_BLOCK_SIZE - 9)
-    {
-        if(i < 60) ctx->wbuf[15] = 0;
-        sha1_compile(ctx);
-        i = 0;
-    }
-    else    /* compute a word index for the empty buffer positions  */
-        i = (i >> 2) + 1;
-
-    while(i < 14) /* and zero pad all but last two positions        */
-        ctx->wbuf[i++] = 0;
-
-    /* the following 32-bit length fields are assembled in the      */
-    /* wrong byte order on little endian machines but this is       */
-    /* corrected later since they are only ever used as 32-bit      */
-    /* word values.                                                 */
-    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
-    ctx->wbuf[15] = ctx->count[0] << 3;
-    sha1_compile(ctx);
-
-    /* extract the hash value as bytes in case the hash buffer is   */
-    /* misaligned for 32-bit words                                  */
-    for(i = 0; i < SHA1_DIGEST_SIZE; ++i)
-        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
-}
-
-VOID_RETURN bg_sha1(unsigned char hval[], const unsigned char data[], unsigned long len)
-{   sha1_ctx    cx[1];
-
-    sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx);
-}
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/srtp/crypto/sha1.h b/jni/libzrtp/sources/srtp/crypto/sha1.h
deleted file mode 100644
index 79fb680..0000000
--- a/jni/libzrtp/sources/srtp/crypto/sha1.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products
-      built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-*/
-
-#ifndef _SHA1_H
-#define _SHA1_H
-
-#include <stdlib.h>
-#include <cryptcommon/brg_types.h>
-
-#define SHA1_BLOCK_SIZE  64
-#define SHA1_DIGEST_SIZE 20
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* type to hold the SHA256 context  */
-
-typedef struct
-{   uint_32t count[2];
-    uint_32t hash[5];
-    uint_32t wbuf[16];
-} sha1_ctx;
-
-/* Note that these prototypes are the same for both bit and */
-/* byte oriented implementations. However the length fields */
-/* are in bytes or bits as appropriate for the version used */
-/* and bit sequences are input as arrays of bytes in which  */
-/* bit sequences run from the most to the least significant */
-/* end of each byte                                         */
-
-VOID_RETURN sha1_compile(sha1_ctx ctx[1]);
-
-VOID_RETURN sha1_begin(sha1_ctx ctx[1]);
-VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]);
-VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]);
-VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/cryptcommon/skein.c b/jni/libzrtp/sources/srtp/crypto/skein.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skein.c
rename to jni/libzrtp/sources/srtp/crypto/skein.c
index 9c6451d..5935a2a 100644
--- a/jni/libzrtp/sources/cryptcommon/skein.c
+++ b/jni/libzrtp/sources/srtp/crypto/skein.c
@@ -11,8 +11,8 @@
 #define  SKEIN_PORT_CODE /* instantiate any code in skein_port.h */

 

 #include <string.h>       /* get the memcpy/memset functions */

-#include <cryptcommon/skein.h> /* get the Skein API definitions   */

-#include <cryptcommon/skein_iv.h>    /* get precomputed IVs */

+#include <crypto/skein.h> /* get the Skein API definitions   */

+#include <crypto/skein_iv.h>    /* get precomputed IVs */

 

 /*****************************************************************/

 /* External function to process blkCnt (nonzero) full block(s) of data. */

diff --git a/jni/libzrtp/sources/cryptcommon/skein.h b/jni/libzrtp/sources/srtp/crypto/skein.h
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skein.h
rename to jni/libzrtp/sources/srtp/crypto/skein.h
index 135aeb3..345a112 100644
--- a/jni/libzrtp/sources/cryptcommon/skein.h
+++ b/jni/libzrtp/sources/srtp/crypto/skein.h
@@ -33,7 +33,7 @@
 #endif

 

 #include <stddef.h>                          /* get size_t definition */

-#include <cryptcommon/skein_port.h>          /* get platform-specific definitions */

+#include <crypto/skein_port.h>               /* get platform-specific definitions */

 

 enum

     {

diff --git a/jni/libzrtp/sources/cryptcommon/skeinApi.c b/jni/libzrtp/sources/srtp/crypto/skeinApi.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skeinApi.c
rename to jni/libzrtp/sources/srtp/crypto/skeinApi.c
index f403b53..84f0120 100644
--- a/jni/libzrtp/sources/cryptcommon/skeinApi.c
+++ b/jni/libzrtp/sources/srtp/crypto/skeinApi.c
@@ -25,7 +25,7 @@
 */
 
 #define SKEIN_ERR_CHECK 1
-#include <cryptcommon/skeinApi.h>
+#include <crypto/skeinApi.h>
 #include <string.h>
 #include <stdio.h>
 
diff --git a/jni/libzrtp/sources/cryptcommon/skeinApi.h b/jni/libzrtp/sources/srtp/crypto/skeinApi.h
similarity index 94%
rename from jni/libzrtp/sources/cryptcommon/skeinApi.h
rename to jni/libzrtp/sources/srtp/crypto/skeinApi.h
index 4d25ba5..2f25073 100644
--- a/jni/libzrtp/sources/cryptcommon/skeinApi.h
+++ b/jni/libzrtp/sources/srtp/crypto/skeinApi.h
@@ -32,12 +32,12 @@
  * @brief A Skein API and its functions.
  * @{
  *
- * This API and the functions that implement this API simplify usage
+ * This API and the functions that implement this API simplify the usage
  * of Skein. The design and the way to use the functions follow the openSSL
  * design but at the same time take care of some Skein specific behaviour
  * and possibilities.
  * 
- * The functions enable applications to create normal Skein hashes and
+ * The functions enable applications to create a normal Skein hashes and
  * message authentication codes (MAC).
  * 
  * Using these functions is simple and straight forward:
@@ -52,9 +52,9 @@
  * // prepare context, here for a Skein with a state size of 512 bits.
  * skeinCtxPrepare(&ctx, Skein512);
  * 
- * // Initialize the context to set the requested hash length in bits:
- * // request an output hash size of 31 bits (Skein supports variable
- * // output sizes, even very strange sizes)
+ * // Initialize the context to set the requested hash length in bits
+ * // here request a output hash size of 31 bits (Skein supports variable
+ * // output sizes even very strange sizes)
  * skeinInit(&ctx, 31);
  * 
  * // Now update Skein with any number of message bits. A function that
@@ -71,14 +71,14 @@
  * An application may use @c skeinReset to reset a Skein context and use
  * it for creation of another hash with the same Skein state size and output
  * bit length. In this case the API implementation restores some internal
- * state data and saves a full Skein initialization round.
+ * internal state data and saves a full Skein initialization round.
  * 
  * To create a MAC the application just uses @c skeinMacInit instead of 
- * @c skeinInit. All other function calls remain the same.
+ * @c skeinInit. All other functions calls remain the same.
  * 
  */
 
-#include <cryptcommon/skein.h>
+#include <crypto/skein.h>
 
 #ifdef _MSC_VER
 typedef signed __int8 int8_t;
diff --git a/jni/libzrtp/sources/cryptcommon/skein_block.c b/jni/libzrtp/sources/srtp/crypto/skein_block.c
similarity index 99%
rename from jni/libzrtp/sources/cryptcommon/skein_block.c
rename to jni/libzrtp/sources/srtp/crypto/skein_block.c
index d1c5ece..fbf37e7 100644
--- a/jni/libzrtp/sources/cryptcommon/skein_block.c
+++ b/jni/libzrtp/sources/srtp/crypto/skein_block.c
@@ -15,7 +15,7 @@
 ************************************************************************/

 

 #include <string.h>

-#include <cryptcommon/skein.h>

+#include <crypto/skein.h>

 

 #ifndef SKEIN_USE_ASM

 #define SKEIN_USE_ASM   (0)                     /* default is all C code (no ASM) */

diff --git a/jni/libzrtp/sources/cryptcommon/skein_iv.h b/jni/libzrtp/sources/srtp/crypto/skein_iv.h
similarity index 98%
rename from jni/libzrtp/sources/cryptcommon/skein_iv.h
rename to jni/libzrtp/sources/srtp/crypto/skein_iv.h
index 22f591e..0c62fac 100644
--- a/jni/libzrtp/sources/cryptcommon/skein_iv.h
+++ b/jni/libzrtp/sources/srtp/crypto/skein_iv.h
@@ -1,7 +1,7 @@
 #ifndef _SKEIN_IV_H_

 #define _SKEIN_IV_H_

 

-#include <cryptcommon/skein.h>    /* get Skein macros and types */

+#include <crypto/skein.h>    /* get Skein macros and types */

 

 /*

 ***************** Pre-computed Skein IVs *******************

diff --git a/jni/libzrtp/sources/cryptcommon/skein_port.h b/jni/libzrtp/sources/srtp/crypto/skein_port.h
similarity index 95%
rename from jni/libzrtp/sources/cryptcommon/skein_port.h
rename to jni/libzrtp/sources/srtp/crypto/skein_port.h
index 10cc08c..256e9d5 100644
--- a/jni/libzrtp/sources/cryptcommon/skein_port.h
+++ b/jni/libzrtp/sources/srtp/crypto/skein_port.h
@@ -15,7 +15,7 @@
 ** 

 ********************************************************************/

 

-#include <cryptcommon/brg_types.h>                      /* get integer type definitions */

+#include <crypto/brg_types.h>                      /* get integer type definitions */

 

 /*r3gis3r : android already has that defined in types */

 #ifndef ANDROID

@@ -49,7 +49,7 @@
  */

 #ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */

 

-#include <cryptcommon/brg_endian.h>              /* get endianness selection */

+#include <crypto/brg_endian.h>              /* get endianness selection */

 #if   PLATFORM_BYTE_ORDER == IS_BIG_ENDIAN

     /* here for big-endian CPUs */

 #define SKEIN_NEED_SWAP   (1)

diff --git a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp b/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
deleted file mode 100644
index abe0a81..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDCacheDb.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-// #define UNIT_TEST
-
-#include <string>
-#include <time.h>
-#include <stdlib.h>
-
-#include <libzrtpcpp/ZIDCacheDb.h>
-
-
-static ZIDCacheDb* instance;
-
-/**
- * A poor man's factory.
- *
- * The build process must not allow to implementation classes linked
- * into the same library.
- */
-
-ZIDCache* getZidCacheInstance() {
-
-    if (instance == NULL) {
-        instance = new ZIDCacheDb();
-    }
-    return instance;
-}
-
-
-ZIDCacheDb::~ZIDCacheDb() {
-    close();
-}
-
-int ZIDCacheDb::open(char* name) {
-
-    // check for an already active ZID file
-    if (zidFile != NULL) {
-        return 0;
-    }
-    if (cacheOps.openCache(name, &zidFile, errorBuffer) == 0)
-        cacheOps.readLocalZid(zidFile, associatedZid, NULL, errorBuffer);
-    else {
-        cacheOps.closeCache(zidFile);
-        zidFile = NULL;
-    }
-
-    return ((zidFile == NULL) ? -1 : 1);
-}
-
-void ZIDCacheDb::close() {
-
-    if (zidFile != NULL) {
-        cacheOps.closeCache(zidFile);
-        zidFile = NULL;
-    }
-}
-
-ZIDRecord *ZIDCacheDb::getRecord(unsigned char *zid) {
-    ZIDRecordDb *zidRecord = new ZIDRecordDb();
-
-    cacheOps.readRemoteZidRecord(zidFile, zid, associatedZid, zidRecord->getRecordData(), errorBuffer);
-
-    zidRecord->setZid(zid);
-
-    // We need to create a new ZID record.
-    if (!zidRecord->isValid()) {
-        zidRecord->setValid();
-        zidRecord->getRecordData()->secureSince = (int64_t)time(NULL);
-        cacheOps.insertRemoteZidRecord(zidFile, zid, associatedZid, zidRecord->getRecordData(), errorBuffer);
-    }
-    return zidRecord;
-}
-
-unsigned int ZIDCacheDb::saveRecord(ZIDRecord *zidRec) {
-    ZIDRecordDb *zidRecord = reinterpret_cast<ZIDRecordDb *>(zidRec);
-
-    cacheOps.updateRemoteZidRecord(zidFile, zidRecord->getIdentifier(), associatedZid, zidRecord->getRecordData(), errorBuffer);
-    return 1;
-}
-
-int32_t ZIDCacheDb::getPeerName(const uint8_t *peerZid, std::string *name) {
-    zidNameRecord_t nameRec;
-    char buffer[201] = {'\0'};
-
-    nameRec.name = buffer;
-    nameRec.nameLength = 200;
-    cacheOps.readZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
-    if ((nameRec.flags & Valid) != Valid) {
-        return 0;
-    }
-    name->assign(buffer);
-    return name->length();
-}
-
-void ZIDCacheDb::putPeerName(const uint8_t *peerZid, const std::string name) {
-    zidNameRecord_t nameRec;
-    char buffer[201] = {'\0'};
-
-    nameRec.name = buffer;
-    nameRec.nameLength = 200;
-    cacheOps.readZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
-
-    nameRec.name = (char*)name.c_str();
-    nameRec.nameLength = name.length();
-    nameRec.nameLength = nameRec.nameLength > 200 ? 200 : nameRec.nameLength;
-    if ((nameRec.flags & Valid) != Valid) {
-        nameRec.flags = Valid;
-        cacheOps.insertZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
-    }
-    else
-        cacheOps.updateZidNameRecord(zidFile, peerZid, associatedZid, NULL, &nameRec, errorBuffer);
-
-    return;
-}
-
-void ZIDCacheDb::cleanup() {
-    cacheOps.cleanCache(zidFile, errorBuffer);
-    cacheOps.readLocalZid(zidFile, associatedZid, NULL, errorBuffer);
-}
diff --git a/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp b/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
deleted file mode 100644
index 5975fc2..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDCacheFile.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-// #define UNIT_TEST
-
-#include <string>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <crypto/zrtpDH.h>
-
-#include <libzrtpcpp/ZIDCacheFile.h>
-
-
-static ZIDCacheFile* instance;
-static int errors = 0;  // maybe we will use as member of ZIDCache later...
-
-
-/**
- * A poor man's factory.
- *
- * The build process must not allow two cache file implementation classes linked
- * into the same library.
- */
-
-ZIDCache* getZidCacheInstance() {
-
-    if (instance == NULL) {
-        instance = new ZIDCacheFile();
-    }
-    return instance;
-}
-
-
-void ZIDCacheFile::createZIDFile(char* name) {
-    zidFile = fopen(name, "wb+");
-    // New file, generate an associated random ZID and save
-    // it as first record
-    if (zidFile != NULL) {
-        randomZRTP(associatedZid, IDENTIFIER_LEN);
-
-        ZIDRecordFile rec;
-        rec.setZid(associatedZid);
-        rec.setOwnZIDRecord();
-        fseek(zidFile, 0L, SEEK_SET);
-        if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
-            ++errors;
-        fflush(zidFile);
-    }
-}
-
-/**
- * Migrate old ZID file format to new one.
- *
- * If ZID file is old format:
- * - close it, rename it, then re-open
- * - create ZID file for new format
- * - copy over contents and flags.
- */
-void ZIDCacheFile::checkDoMigration(char* name) {
-    FILE* fdOld;
-    unsigned char inb[2];
-    zidrecord1_t recOld;
-
-    fseek(zidFile, 0L, SEEK_SET);
-    if (fread(inb, 2, 1, zidFile) < 1) {
-        ++errors;
-        inb[0] = 0;
-    }
-
-    if (inb[0] > 0) {           // if it's new format just return
-        return;
-    }
-    fclose(zidFile);            // close old ZID file
-    zidFile = NULL;
-
-    // create save file name, rename and re-open
-    // if rename fails, just unlink old ZID file and create a brand new file
-    // just a little inconvenience for the user, need to verify new SAS
-    std::string fn = std::string(name) + std::string(".save");
-    if (rename(name, fn.c_str()) < 0) {
-	unlink(name);
-        createZIDFile(name);
-        return;
-    }
-    fdOld = fopen(fn.c_str(), "rb");    // reopen old format in read only mode
-
-    // Get first record from old file - is the own ZID
-    fseek(fdOld, 0L, SEEK_SET);
-    if (fread(&recOld, sizeof(zidrecord1_t), 1, fdOld) != 1) {
-        fclose(fdOld);
-        return;
-    }
-    if (recOld.ownZid != 1) {
-        fclose(fdOld);
-        return;
-    }
-    zidFile = fopen(name, "wb+");    // create new format file in binary r/w mode
-    if (zidFile == NULL) {
-        return;
-    }
-    // create ZIDRecord in new format, copy over own ZID and write the record
-    ZIDRecordFile rec;
-    rec.setZid(recOld.identifier);
-    rec.setOwnZIDRecord();
-    if (fwrite(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) < 1)
-        ++errors;
-
-    // now copy over all valid records from old ZID file format.
-    // Sequentially read old records, sequentially write new records
-    int numRead;
-    do {
-        numRead = fread(&recOld, sizeof(zidrecord1_t), 1, fdOld);
-        if (numRead == 0) {     // all old records processed
-            break;
-        }
-        // skip own ZID record and invalid records
-        if (recOld.ownZid == 1 || recOld.recValid == 0) {
-            continue;
-        }
-        ZIDRecordFile rec2;
-        rec2.setZid(recOld.identifier);
-        rec2.setValid();
-        if (recOld.rs1Valid & SASVerified) {
-            rec2.setSasVerified();
-        }
-        rec2.setNewRs1(recOld.rs2Data); // TODO: check squenec
-        rec2.setNewRs1(recOld.rs1Data);
-        if (fwrite(rec2.getRecordData(), rec2.getRecordLength(), 1, zidFile) < 1)
-            ++errors;
-
-    } while (numRead == 1);
-    fflush(zidFile);
-}
-
-ZIDCacheFile::~ZIDCacheFile() {
-    close();
-}
-
-int ZIDCacheFile::open(char* name) {
-
-    // check for an already active ZID file
-    if (zidFile != NULL) {
-        return 0;
-    }
-    if ((zidFile = fopen(name, "rb+")) == NULL) {
-        createZIDFile(name);
-    } else {
-        checkDoMigration(name);
-        if (zidFile != NULL) {
-            ZIDRecordFile rec;
-            fseek(zidFile, 0L, SEEK_SET);
-            if (fread(rec.getRecordData(), rec.getRecordLength(), 1, zidFile) != 1) {
-                fclose(zidFile);
-                zidFile = NULL;
-                return -1;
-            }
-            if (!rec.isOwnZIDRecord()) {
-                fclose(zidFile);
-                zidFile = NULL;
-                return -1;
-            }
-            memcpy(associatedZid, rec.getIdentifier(), IDENTIFIER_LEN);
-        }
-    }
-    return ((zidFile == NULL) ? -1 : 1);
-}
-
-void ZIDCacheFile::close() {
-
-    if (zidFile != NULL) {
-        fclose(zidFile);
-        zidFile = NULL;
-    }
-}
-
-ZIDRecord *ZIDCacheFile::getRecord(unsigned char *zid) {
-    unsigned long pos;
-    int numRead;
-    //    ZIDRecordFile rec;
-    ZIDRecordFile *zidRecord = new ZIDRecordFile();
-
-    // set read pointer behind first record (
-    fseek(zidFile, zidRecord->getRecordLength(), SEEK_SET);
-
-    do {
-        pos = ftell(zidFile);
-        numRead = fread(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile);
-        if (numRead == 0) {
-            break;
-        }
-
-        // skip own ZID record and invalid records
-        if (zidRecord->isOwnZIDRecord() || !zidRecord->isValid()) {
-            continue;
-        }
-
-    } while (numRead == 1 &&
-             memcmp(zidRecord->getIdentifier(), zid, IDENTIFIER_LEN) != 0);
-
-    // If we reached end of file, then no record with the ZID
-    // found. We need to create a new ZID record.
-    if (numRead == 0) {
-        // create new record
-        //        ZIDRecordFile rec1;
-        zidRecord->setZid(zid);
-        zidRecord->setValid();
-        if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)
-            ++errors;
-    }
-    //  remember position of record in file for save operation
-    zidRecord->setPosition(pos);
-    return zidRecord;
-}
-
-unsigned int ZIDCacheFile::saveRecord(ZIDRecord *zidRec) {
-    ZIDRecordFile *zidRecord = reinterpret_cast<ZIDRecordFile *>(zidRec);
-
-    fseek(zidFile, zidRecord->getPosition(), SEEK_SET);
-    if (fwrite(zidRecord->getRecordData(), zidRecord->getRecordLength(), 1, zidFile) < 1)
-        ++errors;
-    fflush(zidFile);
-    return 1;
-}
-
-int32_t ZIDCacheFile::getPeerName(const uint8_t *peerZid, std::string *name) {
-    return 0;
-}
-
-void ZIDCacheFile::putPeerName(const uint8_t *peerZid, const std::string name) {
-    return;
-}
diff --git a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp b/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
deleted file mode 100644
index b097cbf..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDRecordDb.cpp
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <time.h>
-
-#include <libzrtpcpp/ZIDRecordDb.h>
-
-void ZIDRecordDb::setNewRs1(const unsigned char* data, int32_t expire) {
-
-    // shift RS1 data into RS2 position
-    memcpy(record.rs2, record.rs1, RS_LENGTH);
-    record.rs2Ttl = record.rs1Ttl;
-
-    // set new RS1 data
-    memcpy(record.rs1, data, RS_LENGTH);
-
-    time_t validThru;
-    if (expire == -1) {
-        validThru = -1;
-    }
-    else if (expire <= 0) {
-        validThru = 0;
-    }
-    else {
-        validThru = time(NULL) + expire;
-    }
-    record.rs1Ttl = validThru;
-    resetRs2Valid();
-    setRs1Valid();
-}
-
-
-bool ZIDRecordDb::isRs1NotExpired() {
-    time_t current = time(NULL);
-    time_t validThru;
-
-    validThru = record.rs1Ttl;
-
-    if (validThru == -1)
-        return true;
-    if (validThru == 0)
-        return false;
-    return (current <= validThru) ? true : false;
-}
-
-bool ZIDRecordDb::isRs2NotExpired() {
-    time_t current = time(NULL);
-    time_t validThru;
-
-    validThru = record.rs2Ttl;
-
-    if (validThru == -1)
-        return true;
-    if (validThru == 0)
-        return false;
-    return (current <= validThru) ? true : false;
-}
-
-void ZIDRecordDb::setMiTMData(const unsigned char* data) {
-    memcpy(record.mitmKey, data, RS_LENGTH);
-    setMITMKeyAvailable();
-}
diff --git a/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp b/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
deleted file mode 100644
index fd25dec..0000000
--- a/jni/libzrtp/sources/zrtp/ZIDRecordFile.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <time.h>
-
-#include <libzrtpcpp/ZIDRecordFile.h>
-
-void ZIDRecordFile::setNewRs1(const unsigned char* data, int32_t expire) {
-
-    // shift RS1 data into RS2 position
-    memcpy(record.rs2Data, record.rs1Data, RS_LENGTH);
-    memcpy(record.rs2Interval, record.rs1Interval, TIME_LENGTH);
-
-    // set new RS1 data
-    memcpy(record.rs1Data, data, RS_LENGTH);
-
-    time_t validThru;
-    if (expire == -1) {
-        validThru = -1;
-    }
-    else if (expire <= 0) {
-        validThru = 0;
-    }
-    else {
-        validThru = time(NULL) + expire;
-    }
-
-    if (sizeof(time_t) == 4) {
-        long long temp = validThru;
-        memcpy(record.rs1Interval, (unsigned char*)&temp, TIME_LENGTH);
-    }
-    else {
-        memcpy(record.rs1Interval, (unsigned char*)&validThru, TIME_LENGTH);
-    }
-    resetRs2Valid();
-    setRs1Valid();
-}
-
-
-bool ZIDRecordFile::isRs1NotExpired() {
-    time_t current = time(NULL);
-    time_t validThru;
-
-    if (sizeof(time_t) == 4) {
-        long long temp;
-        memcpy((unsigned char*)&temp, record.rs1Interval, TIME_LENGTH);
-        validThru = temp;
-    }
-    else {
-        memcpy((unsigned char*)&validThru, record.rs1Interval, TIME_LENGTH);
-    }
-
-    if (validThru == -1)
-        return true;
-    if (validThru == 0)
-        return false;
-    return (current <= validThru) ? true : false;
-}
-
-bool ZIDRecordFile::isRs2NotExpired() {
-    time_t current = time(NULL);
-    time_t validThru;
-
-    if (sizeof(time_t) == 4) {
-        long long temp;
-        memcpy((unsigned char*)&temp, record.rs2Interval, TIME_LENGTH);
-        validThru = temp;
-    }
-    else {
-        memcpy((unsigned char*)&validThru, record.rs2Interval, TIME_LENGTH);
-    }
-
-    if (validThru == -1)
-        return true;
-    if (validThru == 0)
-        return false;
-    return (current <= validThru) ? true : false;
-}
-
-void ZIDRecordFile::setMiTMData(const unsigned char* data) {
-    memcpy(record.mitmKey, data, RS_LENGTH);
-    setMITMKeyAvailable();
-}
diff --git a/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp b/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
deleted file mode 100644
index a6756af..0000000
--- a/jni/libzrtp/sources/zrtp/ZrtpSdesStream.cpp
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
-  Copyright (C) 2012-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <string>
-#include <sstream>
-
-#include <libzrtpcpp/ZrtpSdesStream.h>
-#include <libzrtpcpp/ZrtpTextData.h>
-#include <libzrtpcpp/ZrtpConfigure.h>
-#include <libzrtpcpp/zrtpB64Decode.h>
-#include <libzrtpcpp/zrtpB64Encode.h>
-#include <srtp/SrtpHandler.h>
-#include <srtp/CryptoContext.h>
-#include <srtp/CryptoContextCtrl.h>
-#include <cryptcommon/ZrtpRandom.h>
-#include <crypto/hmac384.h>
-
-
-#if defined(_WIN32) || defined(_WIN64)
-# define snprintf _snprintf
-#endif
-
-// SRTP authentication tag length is 80 bits = 10 bytes
-#define ZRTP_TUNNEL_AUTH_LEN  10
-#define ZRTP_TUNNEL_LABEL     10
-/*
- * The ABNF grammar for the crypto attribute is defined below (from RFC 4568):
- *
- *  "a=crypto:" tag 1*WSP crypto-suite 1*WSP key-params *(1*WSP session-param)
- *
- *  tag              = 1*9DIGIT
- */
-
-/*
- * Buffer size for names and other strings inside the crypto string. The parse
- * format below restricts parsing to 99 char to provide space for the @c nul byte.
- */
-#define MAX_INNER_LEN 100
-
-/*
- * This format scans a received SDES crypto attribute string according to the
- * grammer shown above but without a "a=crypto:" prefix.
- *
- * The format string parses:
- * - %d - the tag as decimal value
- * - %s - the crypto suite name, limited to 99 chars (see MAX_INNER_LEN)
- * - %s - the key parameters, limited to 99 chars
- * - %n - the number of parsed characters to far. The pointer to the session
- *   parameters is: cryptoString + numParsedChars.
- */
-static const char parseCrypto[] = "%d %99s %99s %n";
-
-static const int64_t maxTagValue = 999999999;
-
-static const int minElementsCrypto = 3;
-
-/*
- * The ABNF grammar for the key-param (from RFC 4568):
- *
- *  key-param        = key-method ":" key-info
- *
- * The SRTP specific definitions:
- *
- *  key-method          = srtp-key-method
- *  key-info            = srtp-key-info
- *
- *  srtp-key-method     = "inline"
- *  srtp-key-info       = key-salt ["|" lifetime] ["|" mki]
- *
- */
-
-/*
- * This format parses the key parameter string which is never longer than
- * 99 chars (see parse string above):
- * - the fixed string "inline:"
- * - %[A-Za-z0-9+/=] - base 64 characters of master key||master salt
- * - the fixed separator character '|'
- * - %[0-9^] - the lifetime infomration as string that contains digits and ^
- * - the fixed separator character '|'
- * - %[0-9]:%d - parses and strore MKI value and MKI length, separated by ':'
- *
- * If the key parameter string does not contain the operional fields lifetime
- * and MKI information the respective parameters are not filled.
- */
-static const char parseKeyParam[] = " inline:%[A-Za-z0-9+/=]|%[0-9^]|%[0-9]:%d";
-
-static const int minElementsKeyParam = 1;
-
-typedef struct _cryptoMix {
-    const char* name;
-    int32_t hashLength;
-    ZrtpSdesStream::sdesHmacTypeMix hashType;
-} cryptoMix;
-
-static const size_t MIX_HMAC_STRING_MIN_LEN = sizeof("HMAC-SHA-384");
-
-static cryptoMix knownMixAlgos[] = {
-    {"HMAC-SHA-384", 384, ZrtpSdesStream::MIX_HMAC_SHA},
-    {NULL, 0, ZrtpSdesStream::MIX_NONE}
-};
-
-typedef struct _suite {
-    ZrtpSdesStream::sdesSuites suite;
-    const char *name;
-    int32_t    keyLength;             // key length in bits
-    int32_t    saltLength;            // salt lenght in bits
-    int32_t    authKeyLength;         // authentication key length in bits
-    const char *tagLength;            // tag type hs80 or hs32
-    const char *cipher;               // aes1 or aes3
-    uint32_t   b64length;             // length of b64 encoded key/saltstring
-    uint64_t   defaultSrtpLifetime;   // key lifetimes in number of packets
-    uint64_t   defaultSrtcpLifetime;
-} suiteParam;
-
-/* NOTE: the b64len of a 128 bit suite is 40, a 256bit suite uses 64 characters */
-static suiteParam knownSuites[] = {
-    {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_32, "AES_CM_128_HMAC_SHA1_32", 128, 112, 160,
-     hs32, "AES-128", 40, (uint64_t)1<<48, (uint64_t)1<<31
-    },
-    {ZrtpSdesStream::AES_CM_128_HMAC_SHA1_80, "AES_CM_128_HMAC_SHA1_80", 128, 112, 160,
-     hs80, "AES-128", 40, (uint64_t)1<<48, (uint64_t)1<<31
-    },
-    {(ZrtpSdesStream::sdesSuites)0, NULL, 0, 0, 0, 0, 0, 0, 0, 0}
-};
-
-ZrtpSdesStream::ZrtpSdesStream(const sdesSuites s) :
-    state(STREAM_INITALIZED), suite(s), recvSrtp(NULL), recvSrtcp(NULL), sendSrtp(NULL),
-    sendSrtcp(NULL), srtcpIndex(0), recvZrtpTunnel(0), sendZrtpTunnel(0), cryptoMixHashLength(0), 
-    cryptoMixHashType(MIX_NONE)  {
-}
-
-ZrtpSdesStream::~ZrtpSdesStream() {
-    close();
-}
-
-void ZrtpSdesStream::close() {
-    delete sendSrtp;
-    sendSrtp = NULL;
-
-    delete recvSrtp;
-    recvSrtp = NULL;
-
-    delete sendSrtcp;
-    sendSrtp = NULL;
-
-    delete recvSrtcp;
-    recvSrtp = NULL;
-
-    delete recvZrtpTunnel;
-    recvZrtpTunnel = NULL;
-
-    delete sendZrtpTunnel;
-    sendZrtpTunnel = NULL;
-}
-
-bool ZrtpSdesStream::createSdes(char *cryptoString, size_t *maxLen, bool sipInvite) {
-
-    if (sipInvite) {
-        if (state != STREAM_INITALIZED)
-            return false;
-        tag = 1;
-    }
-    else {
-        if (state != IN_PROFILE_READY)
-            return false;
-    }
-
-    bool s = createSdesProfile(cryptoString, maxLen);
-    if (!s)
-        return s;
-
-    if (sipInvite) {
-        state = OUT_PROFILE_READY;
-    }
-    else {
-        createSrtpContexts(sipInvite);
-        state = SDES_SRTP_ACTIVE;
-    }
-    return s;
-}
-
-bool ZrtpSdesStream::parseSdes(const char *cryptoString, size_t length, bool sipInvite) {
-
-    if (sipInvite) {
-        if (state != OUT_PROFILE_READY)
-            return false;
-    }
-    else {
-        if (state != STREAM_INITALIZED)
-            return false;
-    }
-    sdesSuites tmpSuite;
-    int32_t tmpTag;
-
-    bool s = parseCreateSdesProfile(cryptoString, length, &tmpSuite, &tmpTag);
-    if (!s)
-        return s;
-
-    if (sipInvite) {
-        // Check if answerer used same tag and suite as the offerer
-        if (tmpTag != tag || suite != tmpSuite)
-            return false;
-        createSrtpContexts(sipInvite);
-        state = SDES_SRTP_ACTIVE;
-    }
-    else {
-        // Answerer stores tag and suite and uses it in createSdesProfile
-        suite = tmpSuite;
-        tag = tmpTag;
-        state = IN_PROFILE_READY;
-    }
-    return s;
-}
-
-bool ZrtpSdesStream::outgoingRtp(uint8_t *packet, size_t length, size_t *newLength) {
-
-    if (state != SDES_SRTP_ACTIVE || sendSrtp == NULL) {
-        *newLength = length;
-        return true;
-    }
-    bool rc = SrtpHandler::protect(sendSrtp, packet, length, newLength);
-    if (rc)
-        ;//protect++;
-    return rc;
-}
-
-int ZrtpSdesStream::incomingRtp(uint8_t *packet, size_t length, size_t *newLength) {
-    if (state != SDES_SRTP_ACTIVE || recvSrtp == NULL) {    // SRTP inactive, just return with newLength set
-        *newLength = length;
-        return 1;
-    }
-    int32_t rc = SrtpHandler::unprotect(recvSrtp, packet, length, newLength);
-    if (rc == 1) {
-//            unprotect++
-    }
-    else {
-//            unprotectFailed++;
-    }
-    return rc;
-}
-
-
-bool ZrtpSdesStream::outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength) {
-
-    if (state != SDES_SRTP_ACTIVE || sendZrtpTunnel == NULL) {
-        *newLength = length;
-        return true;
-    }
-    bool rc = SrtpHandler::protect(sendZrtpTunnel, packet, length, newLength);
-    if (rc)
-        ;//protect++;
-    return rc;
-}
-
-int ZrtpSdesStream::incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength) {
-    if (state != SDES_SRTP_ACTIVE || recvZrtpTunnel == NULL) {    // SRTP inactive, just return with newLength set
-        *newLength = length;
-        return 1;
-    }
-    int32_t rc = SrtpHandler::unprotect(recvZrtpTunnel, packet, length, newLength);
-    if (rc == 1) {
-//            unprotect++
-    }
-    else {
-//            unprotectFailed++;
-    }
-    return rc;
-}
-
-
-
-bool ZrtpSdesStream::outgoingRtcp(uint8_t *packet, size_t length, size_t *newLength) {
-#if 0
-SrtpHandler::protectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength, uint32_t *srtcpIndex)
-#endif
-    return false;
-}
-
-int ZrtpSdesStream::incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength) {
-#if 0
-int32_t SrtpHandler::unprotectCtrl(CryptoContextCtrl* pcc, uint8_t* buffer, size_t length, size_t* newLength)
-#endif
-    return 0;
-}
-
-const char* ZrtpSdesStream::getCipher() {
-    return knownSuites[suite].cipher;
-}
-
-const char* ZrtpSdesStream::getAuthAlgo() {
-    if (strcmp(knownSuites[suite].tagLength, hs80) == 0)
-        return "HMAC-SHA1 80 bit";
-    else
-        return "HMAC-SHA1 32 bit";
-}
-
-int ZrtpSdesStream::getCryptoMixAttribute(char *algoNames, size_t length) {
-
-    if (length < MIX_HMAC_STRING_MIN_LEN)
-        return 0;
-
-    // In case we support more than one MIX profile select the correct one if the
-    // application called setCryptoMixAttribute(...) and we already selected the one to use.
-    if (cryptoMixHashType != MIX_NONE) {
-        for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {
-            if (cp->hashLength == cryptoMixHashLength && cp->hashType == cryptoMixHashType) {
-                strcpy(algoNames, cp->name);
-                return strlen(cp->name);
-            }
-        }
-    }
-    // TODO: enhance here to support multiple algorithms (concatenate strings into the buffer until buffer full)
-    else {
-        strcpy(algoNames, knownMixAlgos[0].name);
-        return strlen(algoNames);
-    }
-    return 0;
-}
-
-bool ZrtpSdesStream::setCryptoMixAttribute(const char *algoNames) {
-
-    int len = strlen(algoNames);
-    if (len <= 0)
-        return false;
-
-    std::string algoIn(algoNames);
-    algoIn += ' ';
-
-    // split input name string and lookup if we support one of the offered algorithms
-    // We take the first match.
-    std::string delimiters = " ";
-    size_t current;
-    size_t next = -1;
-
-    do {
-        current = next + 1;
-        next = algoIn.find_first_of(delimiters, current);
-        if (next == std::string::npos)
-            break;
-
-        std::string tmps = algoIn.substr(current, next - current );
-        const char* nm = tmps.c_str();
-
-        for (cryptoMix* cp = knownMixAlgos; cp->name != NULL; cp++) {
-            if (strncmp(cp->name, nm, strlen(cp->name)) == 0) {
-                cryptoMixHashLength = cp->hashLength;
-                cryptoMixHashType = cp->hashType;
-                return true;
-            }
-        }
-    } while (true);
-
-    return false;
-}
-
-#ifdef WEAKRANDOM
-/*
- * A standard random number generator that uses the portable random() system function.
- *
- * This should be enhanced to use a better random generator
- */
-static int _random(unsigned char *output, size_t len)
-{
-    size_t i;
-
-    for(i = 0; i < len; ++i )
-        output[i] = random();
-
-    return( 0 );
-}
-#else
-#include <cryptcommon/ZrtpRandom.h>
-static int _random(unsigned char *output, size_t len)
-{
-    return ZrtpRandom::getRandomData(output, len);
-}
-#endif
-
-static int b64Encode(const uint8_t *binData, int32_t binLength, char *b64Data, int32_t b64Length)
-{
-    base64_encodestate _state;
-    int codelength;
-
-    base64_init_encodestate(&_state, 0);
-    codelength = base64_encode_block(binData, binLength, b64Data, &_state);
-    codelength += base64_encode_blockend(b64Data+codelength, &_state);
-
-    return codelength;
-}
-
-static int b64Decode(const char *b64Data, int32_t b64length, uint8_t *binData, int32_t binLength)
-{
-    base64_decodestate _state;
-    int codelength;
-
-    base64_init_decodestate(&_state);
-    codelength = base64_decode_block(b64Data, b64length, binData, &_state);
-    return codelength;
-}
-
-void* createSha384HmacContext(uint8_t* key, int32_t keyLength);
-void freeSha384HmacContext(void* ctx);
-void hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength );
-
-static int expand(uint8_t* prk, uint32_t prkLen, uint8_t* info, int32_t infoLen, int32_t L, uint32_t hashLen, uint8_t* outbuffer)
-{
-    int32_t n;
-    uint8_t *T;
-    void* hmacCtx;
-
-    const uint8_t* data[4];      // 3 data pointers for HMAC data plus terminating NULL
-    uint32_t dataLen[4];
-    int32_t dataIdx = 0;
-
-    uint8_t counter;
-    int32_t macLength;
-
-    if (prkLen < hashLen)
-        return -1;
-
-    n = (L + (hashLen-1)) / hashLen;
-
-    // T points to buffer that holds concatenated T(1) || T(2) || ... T(N))
-    T = reinterpret_cast<uint8_t*>(malloc(n * hashLen));
-
-    if (hashLen == 384/8)
-        hmacCtx = createSha384HmacContext(prk, prkLen);
-    else
-        return -1;
-
-    // Prepare first HMAC. T(0) has zero length, thus we ignore it in first run.
-    // After first run use its output (T(1)) as first data in next HMAC run.
-    for (int i = 1; i <= n; i++) {
-        if (infoLen > 0 && info != NULL) {
-            data[dataIdx] = info;
-            dataLen[dataIdx++] = infoLen;
-        }
-        counter = i & 0xff;
-        data[dataIdx] = &counter;
-        dataLen[dataIdx++] = 1;
-
-        data[dataIdx] = NULL;
-        dataLen[dataIdx++] = 0;
-
-        if (hashLen == 384/8)
-            hmacSha384Ctx(hmacCtx, data, dataLen, T + ((i-1) * hashLen), &macLength);
-
-        // Use output of previous hash run as first input of next hash run
-        dataIdx = 0;
-        data[dataIdx] = T + ((i-1) * hashLen);
-        dataLen[dataIdx++] = hashLen;
-    }
-    freeSha384HmacContext(hmacCtx);
-    memcpy(outbuffer, T, L);
-    free(T);
-    return 0;
-}
-
-void ZrtpSdesStream::computeMixedKeys(bool sipInvite) {
-    uint8_t salt[MAX_SALT_LEN*2];
-    uint8_t ikm[MAX_KEY_LEN*2];
-
-    // Concatenate the existing salt and key data. Depending on our role we have to change
-    // the order of the data.
-    if (sipInvite) {             // We are offerer, use local created data as mso and mko, so they go first
-        memcpy(salt, &localKeySalt[localKeyLenBytes], localSaltLenBytes);
-        memcpy(&salt[localSaltLenBytes], &remoteKeySalt[remoteKeyLenBytes], remoteSaltLenBytes);
-
-        memcpy(ikm, localKeySalt, localKeyLenBytes);
-        memcpy(&ikm[localKeyLenBytes], remoteKeySalt, remoteKeyLenBytes);
-    }
-    else {
-        memcpy(salt, &remoteKeySalt[remoteKeyLenBytes], remoteSaltLenBytes);
-        memcpy(&salt[remoteSaltLenBytes], &localKeySalt[localKeyLenBytes], localSaltLenBytes);
-
-        memcpy(ikm, remoteKeySalt, remoteKeyLenBytes);
-        memcpy(&ikm[remoteKeyLenBytes], localKeySalt, localKeyLenBytes);
-    }
-    uint32_t saltLen = localSaltLenBytes + remoteSaltLenBytes;
-    uint32_t keyLen = localKeyLenBytes + remoteKeyLenBytes;
-    uint32_t L = saltLen + keyLen;
-
-    uint8_t prk[MAX_DIGEST_LENGTH];
-    uint32_t prkLen;
-
-    switch(cryptoMixHashType) {
-        case MIX_HMAC_SHA:
-            if (cryptoMixHashLength == 384)
-                hmac_sha384(salt, saltLen, ikm, keyLen, prk, &prkLen);
-            else
-                return;
-            break;
-
-        case MIX_MAC_SKEIN:
-            return;
-
-        default:
-            return;
-    }
-
-    uint8_t T[(MAX_SALT_LEN + MAX_KEY_LEN)*2] = {0};
-    expand(prk, prkLen, NULL, 0, L, cryptoMixHashLength/8, T);
-
-    // We have a new set of SRTP key data now, replace the old with the new.
-    int32_t offset = 0;
-    if (sipInvite) {    // We are offerer, replace local created data with mso and mko, remote with msa, mka
-        memcpy(&localKeySalt[localKeyLenBytes], T, localSaltLenBytes);
-        offset += localSaltLenBytes;
-        memcpy(&remoteKeySalt[remoteKeyLenBytes], &T[offset], remoteSaltLenBytes);
-        offset += remoteSaltLenBytes;
-
-        memcpy(localKeySalt, &T[offset], localKeyLenBytes);
-        offset += localKeyLenBytes;
-        memcpy(remoteKeySalt, &T[offset], remoteKeyLenBytes);
-    }
-    else {            // We are answerer, replace remote data with mso and mko, local data with msa, mka
-        memcpy(&remoteKeySalt[remoteKeyLenBytes], T, remoteSaltLenBytes);
-        offset += remoteSaltLenBytes;
-        memcpy(&localKeySalt[localKeyLenBytes], &T[offset], localSaltLenBytes);
-        offset += localSaltLenBytes;
-
-        memcpy(remoteKeySalt, &T[offset], remoteKeyLenBytes);
-        offset += remoteKeyLenBytes;
-        memcpy(localKeySalt, &T[offset], localKeyLenBytes);
-    }
-}
-
-void ZrtpSdesStream::createSrtpContexts(bool sipInvite) {
-
-    if (cryptoMixHashType != MIX_NONE) {
-        computeMixedKeys(sipInvite);
-    }
-
-    sendSrtp = new CryptoContext(0,                     // SSRC (used for lookup)
-                                 0,                     // Roll-Over-Counter (ROC)
-                                 0L,                    // keyderivation << 48,
-                                 localCipher,                // encryption algo
-                                 localAuthn,                 // authtentication algo
-                                 localKeySalt,               // Master Key
-                                 localKeyLenBytes,           // Master Key length
-                                 &localKeySalt[localKeyLenBytes], // Master Salt
-                                 localSaltLenBytes,          // Master Salt length
-                                 localKeyLenBytes,           // encryption keylen
-                                 localAuthKeyLen,            // authentication key len (HMAC key lenght)
-                                 localSaltLenBytes,          // session salt len
-                                 localTagLength);            // authentication tag len
-    sendSrtp->deriveSrtpKeys(0L);
-
-    sendZrtpTunnel = new CryptoContext(0,                     // SSRC (used for lookup)
-                                 0,                     // Roll-Over-Counter (ROC)
-                                 0L,                    // keyderivation << 48,
-                                 localCipher,                // encryption algo
-                                 localAuthn,                 // authtentication algo
-                                 localKeySalt,               // Master Key
-                                 localKeyLenBytes,           // Master Key length
-                                 &localKeySalt[localKeyLenBytes], // Master Salt
-                                 localSaltLenBytes,          // Master Salt length
-                                 localKeyLenBytes,           // encryption keylen
-                                 localAuthKeyLen,            // authentication key len (HMAC key lenght)
-                                 localSaltLenBytes,          // session salt len
-                                 ZRTP_TUNNEL_AUTH_LEN);      // authentication tag len
-
-    sendZrtpTunnel->setLabelbase(ZRTP_TUNNEL_LABEL);
-    sendZrtpTunnel->deriveSrtpKeys(0L);
-    memset(localKeySalt, 0, sizeof(localKeySalt));
-
-    recvSrtp = new CryptoContext(0,                     // SSRC (used for lookup)
-                                 0,                     // Roll-Over-Counter (ROC)
-                                 0L,                    // keyderivation << 48,
-                                 remoteCipher,                // encryption algo
-                                 remoteAuthn,                 // authtentication algo
-                                 remoteKeySalt,               // Master Key
-                                 remoteKeyLenBytes,           // Master Key length
-                                 &remoteKeySalt[remoteKeyLenBytes], // Master Salt
-                                 remoteSaltLenBytes,          // Master Salt length
-                                 remoteKeyLenBytes,           // encryption keylen
-                                 remoteAuthKeyLen,            // authentication key len (HMAC key lenght)
-                                 remoteSaltLenBytes,          // session salt len
-                                 remoteTagLength);            // authentication tag len
-    recvSrtp->deriveSrtpKeys(0L);
-
-    recvZrtpTunnel = new CryptoContext(0,                     // SSRC (used for lookup)
-                                 0,                     // Roll-Over-Counter (ROC)
-                                 0L,                    // keyderivation << 48,
-                                 remoteCipher,                // encryption algo
-                                 remoteAuthn,                 // authtentication algo
-                                 remoteKeySalt,               // Master Key
-                                 remoteKeyLenBytes,           // Master Key length
-                                 &remoteKeySalt[remoteKeyLenBytes], // Master Salt
-                                 remoteSaltLenBytes,          // Master Salt length
-                                 remoteKeyLenBytes,           // encryption keylen
-                                 remoteAuthKeyLen,            // authentication key len (HMAC key lenght)
-                                 remoteSaltLenBytes,          // session salt len
-                                 ZRTP_TUNNEL_AUTH_LEN);       // authentication tag len
-
-    recvZrtpTunnel->setLabelbase(ZRTP_TUNNEL_LABEL);
-    recvZrtpTunnel->deriveSrtpKeys(0L);
-    memset(remoteKeySalt, 0, sizeof(remoteKeySalt));
-}
-
-bool ZrtpSdesStream::createSdesProfile(char *cryptoString, size_t *maxLen) {
-
-    char b64keySalt[(MAX_KEY_LEN + MAX_SALT_LEN) * 2] = {'\0'};
-    uint32_t sidx;
-    int32_t b64Len;
-
-    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {  // Lookup crypto suite parameters
-        if (knownSuites[sidx].suite == suite)
-            break;
-    }
-    if (sidx >= sizeof(knownSuites)/sizeof(struct _suite)) {
-        return false;
-    }
-    suiteParam *pSuite = &knownSuites[sidx];
-    _random(localKeySalt, sizeof(localKeySalt));
-
-    AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
-    localAuthn = SrtpAuthenticationSha1Hmac;
-    localAuthKeyLen = pSuite->authKeyLength / 8;
-    localTagLength = auth.getKeylen() / 8;
-
-    // If SDES will support other encryption algos - get it here based on
-    // the algorithm name in suite
-    localCipher = SrtpEncryptionAESCM;
-
-    localKeyLenBytes = pSuite->keyLength / 8;
-    localSaltLenBytes = pSuite->saltLength / 8;
-
-    if (tag == -1)
-        tag = 1;
-
-    // Get B64 code for master key and master salt and then construct the SDES crypto string
-    b64Len = b64Encode(localKeySalt, localKeyLenBytes + localSaltLenBytes, b64keySalt, sizeof(b64keySalt));
-    b64keySalt[b64Len] = '\0';
-    memset(cryptoString, 0, *maxLen);
-    *maxLen = snprintf(cryptoString, *maxLen-1, "%d %s inline:%s", tag, pSuite->name, b64keySalt);
-
-    return true;
-}
-
-bool ZrtpSdesStream::parseCreateSdesProfile(const char *cryptoStr, size_t length, sdesSuites *parsedSuite, int32_t *outTag) {
-    int elements,  i;
-    int charsScanned;
-    int mkiLength = 0;
-    uint32_t sidx;
-
-    char cryptoString[MAX_CRYPT_STRING_LEN+1] = {'\0'};
-
-    /* Parsed strings */
-    char suiteName[MAX_INNER_LEN]  = {'\0'};
-    char keyParams[MAX_INNER_LEN]  = {'\0'};
-    char keySaltB64[MAX_INNER_LEN] = {'\0'};
-    char lifetime[MAX_INNER_LEN]   = {'\0'};
-    char mkiVal[MAX_INNER_LEN]     = {'\0'};
-
-    if (length == 0)
-        length = strlen(cryptoStr);
-
-    if (length > MAX_CRYPT_STRING_LEN) {
-        return false;
-    }
-    memcpy(cryptoString, cryptoStr, length);   // make own copy, null terminated
-
-    *outTag = -1;
-    elements = sscanf(cryptoString, parseCrypto, outTag, suiteName, keyParams, &charsScanned);
-
-    if (elements < minElementsCrypto) {        // Do we have enough elements in the string
-        return false;
-    }
-
-    for (sidx = 0; knownSuites[sidx].name != NULL; sidx++) {  // Lookup crypto suite
-        if (!strcmp(knownSuites[sidx].name, suiteName))
-            break;
-    }
-    if (sidx >= sizeof(knownSuites)/sizeof(struct _suite)) {
-        return false;
-    }
-    suiteParam *pSuite = &knownSuites[sidx];
-    *parsedSuite = pSuite->suite;
-
-    /* Now scan the key parameters */
-    elements = sscanf(keyParams, parseKeyParam, keySaltB64, lifetime, mkiVal, &mkiLength);
-
-    if (elements != minElementsKeyParam) {     // Currently we only accept key||salt B64 string, no other parameters 
-        return false;
-    }
-
-    remoteKeyLenBytes = pSuite->keyLength / 8;
-    remoteSaltLenBytes = pSuite->saltLength / 8;
-
-    if (strlen(keySaltB64) != pSuite->b64length) {  // Check if key||salt B64 string hast the correct length
-        return false;
-    }
-    i = b64Decode(keySaltB64, pSuite->b64length, remoteKeySalt, remoteKeyLenBytes + remoteSaltLenBytes);
-
-    if (i != (remoteKeyLenBytes + remoteSaltLenBytes)) {  // Did the B64 decode delivered enough data for key||salt
-        return false;
-    }
-
-    AlgorithmEnum& auth = zrtpAuthLengths.getByName(pSuite->tagLength);
-    remoteAuthn = SrtpAuthenticationSha1Hmac;
-    remoteAuthKeyLen = pSuite->authKeyLength / 8;
-    remoteTagLength = auth.getKeylen() / 8;
-
-    // If SDES will support other encryption algos - get it here based on
-    // the algorithm name in suite
-    remoteCipher = SrtpEncryptionAESCM;
-
-    return true;
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp b/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
deleted file mode 100644
index ecf5b6d..0000000
--- a/jni/libzrtp/sources/zrtp/ZrtpTextData.cpp
+++ /dev/null
@@ -1,621 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-#include <stdint.h>
-#include <libzrtpcpp/ZrtpConfigure.h>
-//                             1
-//                    1234567890123456
-char clientId[] =    "GNU ZRTP 4.1.1  "; // 16 chars max.
-char zrtpVersion_11[] = "1.10";          // must be 4 chars
-char zrtpVersion_12[] = "1.20";          // must be 4 chars
-/**
- *
- */
-char HelloMsg[]    = "Hello   ";
-char HelloAckMsg[] = "HelloACK";
-char CommitMsg[]   = "Commit  ";
-char DHPart1Msg[]  = "DHPart1 ";
-char DHPart2Msg[]  = "DHPart2 ";
-char Confirm1Msg[] = "Confirm1";
-char Confirm2Msg[] = "Confirm2";
-char Conf2AckMsg[] = "Conf2ACK";
-char ErrorMsg[]    = "Error   ";
-char ErrorAckMsg[] = "ErrorACK";
-char GoClearMsg[]  = "GoClear ";
-char ClearAckMsg[] = "ClearACK";
-char PingMsg[]     = "Ping    ";
-char PingAckMsg[]  = "PingACK ";
-char SasRelayMsg[] = "SASrelay";
-char RelayAckMsg[] = "RelayACK";
-
-char responder[]      = "Responder";
-char initiator[]      = "Initiator";
-char iniMasterKey[]   = "Initiator SRTP master key";
-char iniMasterSalt[]  = "Initiator SRTP master salt";
-char respMasterKey[]  = "Responder SRTP master key";
-char respMasterSalt[] = "Responder SRTP master salt";
-
-char iniHmacKey[]  = "Initiator HMAC key";
-char respHmacKey[] = "Responder HMAC key";
-char retainedSec[] = "retained secret";
-
-char iniZrtpKey[]  = "Initiator ZRTP key";
-char respZrtpKey[] = "Responder ZRTP key";
-
-char sasString[] = "SAS";
-
-char KDFString[] = "ZRTP-HMAC-KDF";
-
-char zrtpSessionKey[] = "ZRTP Session Key";
-
-char zrtpMsk[] = "ZRTP MSK";
-char zrtpTrustedMitm[] = "Trusted MiTM key";
-
-char s256[] = "S256";
-char s384[] = "S384";
-char skn2[] = "SKN2";
-char skn3[] = "SKN3";
-const char* mandatoryHash = s256;
-
-char aes3[] = "AES3";
-char aes2[] = "AES2";
-char aes1[] = "AES1";
-char two3[] = "2FS3";
-char two2[] = "2FS2";
-char two1[] = "2FS1";
-const char* mandatoryCipher = aes1;
-
-char dh2k[] = "DH2k";
-char ec25[] = "EC25";
-char dh3k[] = "DH3k";
-char ec38[] = "EC38";
-char e255[] = "E255";
-char e414[] = "E414";
-char mult[] = "Mult";
-const char* mandatoryPubKey = dh3k;
-
-char b32[] =  "B32 ";
-char b256[] = "B256";
-const char* mandatorySasType = b32;
-
-char hs32[] = "HS32";
-char hs80[] = "HS80";
-char sk32[] = "SK32";
-char sk64[] = "SK64";
-const char* mandatoryAuthLen_1 = hs32;
-const char* mandatoryAuthLen_2 = hs80;
-
-const char* sas256WordsOdd[] = {
-    "adroitness",
-    "adviser",
-    "aftermath",
-    "aggregate",
-    "alkali",
-    "almighty",
-    "amulet",
-    "amusement",
-    "antenna",
-    "applicant",
-    "Apollo",
-    "armistice",
-    "article",
-    "asteroid",
-    "Atlantic",
-    "atmosphere",
-    "autopsy",
-    "Babylon",
-    "backwater",
-    "barbecue",
-    "belowground",
-    "bifocals",
-    "bodyguard",
-    "bookseller",
-    "borderline",
-    "bottomless",
-    "Bradbury",
-    "bravado",
-    "Brazilian",
-    "breakaway",
-    "Burlington",
-    "businessman",
-    "butterfat",
-    "Camelot",
-    "candidate",
-    "cannonball",
-    "Capricorn",
-    "caravan",
-    "caretaker",
-    "celebrate",
-    "cellulose",
-    "certify",
-    "chambermaid",
-    "Cherokee",
-    "Chicago",
-    "clergyman",
-    "coherence",
-    "combustion",
-    "commando",
-    "company",
-    "component",
-    "concurrent",
-    "confidence",
-    "conformist",
-    "congregate",
-    "consensus",
-    "consulting",
-    "corporate",
-    "corrosion",
-    "councilman",
-    "crossover",
-    "crucifix",
-    "cumbersome",
-    "customer",
-    "Dakota",
-    "decadence",
-    "December",
-    "decimal",
-    "designing",
-    "detector",
-    "detergent",
-    "determine",
-    "dictator",
-    "dinosaur",
-    "direction",
-    "disable",
-    "disbelief",
-    "disruptive",
-    "distortion",
-    "document",
-    "embezzle",
-    "enchanting",
-    "enrollment",
-    "enterprise",
-    "equation",
-    "equipment",
-    "escapade",
-    "Eskimo",
-    "everyday",
-    "examine",
-    "existence",
-    "exodus",
-    "fascinate",
-    "filament",
-    "finicky",
-    "forever",
-    "fortitude",
-    "frequency",
-    "gadgetry",
-    "Galveston",
-    "getaway",
-    "glossary",
-    "gossamer",
-    "graduate",
-    "gravity",
-    "guitarist",
-    "hamburger",
-    "Hamilton",
-    "handiwork",
-    "hazardous",
-    "headwaters",
-    "hemisphere",
-    "hesitate",
-    "hideaway",
-    "holiness",
-    "hurricane",
-    "hydraulic",
-    "impartial",
-    "impetus",
-    "inception",
-    "indigo",
-    "inertia",
-    "infancy",
-    "inferno",
-    "informant",
-    "insincere",
-    "insurgent",
-    "integrate",
-    "intention",
-    "inventive",
-    "Istanbul",
-    "Jamaica",
-    "Jupiter",
-    "leprosy",
-    "letterhead",
-    "liberty",
-    "maritime",
-    "matchmaker",
-    "maverick",
-    "Medusa",
-    "megaton",
-    "microscope",
-    "microwave",
-    "midsummer",
-    "millionaire",
-    "miracle",
-    "misnomer",
-    "molasses",
-    "molecule",
-    "Montana",
-    "monument",
-    "mosquito",
-    "narrative",
-    "nebula",
-    "newsletter",
-    "Norwegian",
-    "October",
-    "Ohio",
-    "onlooker",
-    "opulent",
-    "Orlando",
-    "outfielder",
-    "Pacific",
-    "pandemic",
-    "Pandora",
-    "paperweight",
-    "paragon",
-    "paragraph",
-    "paramount",
-    "passenger",
-    "pedigree",
-    "Pegasus",
-    "penetrate",
-    "perceptive",
-    "performance",
-    "pharmacy",
-    "phonetic",
-    "photograph",
-    "pioneer",
-    "pocketful",
-    "politeness",
-    "positive",
-    "potato",
-    "processor",
-    "provincial",
-    "proximate",
-    "puberty",
-    "publisher",
-    "pyramid",
-    "quantity",
-    "racketeer",
-    "rebellion",
-    "recipe",
-    "recover",
-    "repellent",
-    "replica",
-    "reproduce",
-    "resistor",
-    "responsive",
-    "retraction",
-    "retrieval",
-    "retrospect",
-    "revenue",
-    "revival",
-    "revolver",
-    "sandalwood",
-    "sardonic",
-    "Saturday",
-    "savagery",
-    "scavenger",
-    "sensation",
-    "sociable",
-    "souvenir",
-    "specialist",
-    "speculate",
-    "stethoscope",
-    "stupendous",
-    "supportive",
-    "surrender",
-    "suspicious",
-    "sympathy",
-    "tambourine",
-    "telephone",
-    "therapist",
-    "tobacco",
-    "tolerance",
-    "tomorrow",
-    "torpedo",
-    "tradition",
-    "travesty",
-    "trombonist",
-    "truncated",
-    "typewriter",
-    "ultimate",
-    "undaunted",
-    "underfoot",
-    "unicorn",
-    "unify",
-    "universe",
-    "unravel",
-    "upcoming",
-    "vacancy",
-    "vagabond",
-    "vertigo",
-    "Virginia",
-    "visitor",
-    "vocalist",
-    "voyager",
-    "warranty",
-    "Waterloo",
-    "whimsical",
-    "Wichita",
-    "Wilmington",
-    "Wyoming",
-    "yesteryear",
-    "Yucatan"
-    };
-
-const char* sas256WordsEven[] = {
-    "aardvark",
-    "absurd",
-    "accrue",
-    "acme",
-    "adrift",
-    "adult",
-    "afflict",
-    "ahead",
-    "aimless",
-    "Algol",
-    "allow",
-    "alone",
-    "ammo",
-    "ancient",
-    "apple",
-    "artist",
-    "assume",
-    "Athens",
-    "atlas",
-    "Aztec",
-    "baboon",
-    "backfield",
-    "backward",
-    "banjo",
-    "beaming",
-    "bedlamp",
-    "beehive",
-    "beeswax",
-    "befriend",
-    "Belfast",
-    "berserk",
-    "billiard",
-    "bison",
-    "blackjack",
-    "blockade",
-    "blowtorch",
-    "bluebird",
-    "bombast",
-    "bookshelf",
-    "brackish",
-    "breadline",
-    "breakup",
-    "brickyard",
-    "briefcase",
-    "Burbank",
-    "button",
-    "buzzard",
-    "cement",
-    "chairlift",
-    "chatter",
-    "checkup",
-    "chisel",
-    "choking",
-    "chopper",
-    "Christmas",
-    "clamshell",
-    "classic",
-    "classroom",
-    "cleanup",
-    "clockwork",
-    "cobra",
-    "commence",
-    "concert",
-    "cowbell",
-    "crackdown",
-    "cranky",
-    "crowfoot",
-    "crucial",
-    "crumpled",
-    "crusade",
-    "cubic",
-    "dashboard",
-    "deadbolt",
-    "deckhand",
-    "dogsled",
-    "dragnet",
-    "drainage",
-    "dreadful",
-    "drifter",
-    "dropper",
-    "drumbeat",
-    "drunken",
-    "Dupont",
-    "dwelling",
-    "eating",
-    "edict",
-    "egghead",
-    "eightball",
-    "endorse",
-    "endow",
-    "enlist",
-    "erase",
-    "escape",
-    "exceed",
-    "eyeglass",
-    "eyetooth",
-    "facial",
-    "fallout",
-    "flagpole",
-    "flatfoot",
-    "flytrap",
-    "fracture",
-    "framework",
-    "freedom",
-    "frighten",
-    "gazelle",
-    "Geiger",
-    "glitter",
-    "glucose",
-    "goggles",
-    "goldfish",
-    "gremlin",
-    "guidance",
-    "hamlet",
-    "highchair",
-    "hockey",
-    "indoors",
-    "indulge",
-    "inverse",
-    "involve",
-    "island",
-    "jawbone",
-    "keyboard",
-    "kickoff",
-    "kiwi",
-    "klaxon",
-    "locale",
-    "lockup",
-    "merit",
-    "minnow",
-    "miser",
-    "Mohawk",
-    "mural",
-    "music",
-    "necklace",
-    "Neptune",
-    "newborn",
-    "nightbird",
-    "Oakland",
-    "obtuse",
-    "offload",
-    "optic",
-    "orca",
-    "payday",
-    "peachy",
-    "pheasant",
-    "physique",
-    "playhouse",
-    "Pluto",
-    "preclude",
-    "prefer",
-    "preshrunk",
-    "printer",
-    "prowler",
-    "pupil",
-    "puppy",
-    "python",
-    "quadrant",
-    "quiver",
-    "quota",
-    "ragtime",
-    "ratchet",
-    "rebirth",
-    "reform",
-    "regain",
-    "reindeer",
-    "rematch",
-    "repay",
-    "retouch",
-    "revenge",
-    "reward",
-    "rhythm",
-    "ribcage",
-    "ringbolt",
-    "robust",
-    "rocker",
-    "ruffled",
-    "sailboat",
-    "sawdust",
-    "scallion",
-    "scenic",
-    "scorecard",
-    "Scotland",
-    "seabird",
-    "select",
-    "sentence",
-    "shadow",
-    "shamrock",
-    "showgirl",
-    "skullcap",
-    "skydive",
-    "slingshot",
-    "slowdown",
-    "snapline",
-    "snapshot",
-    "snowcap",
-    "snowslide",
-    "solo",
-    "southward",
-    "soybean",
-    "spaniel",
-    "spearhead",
-    "spellbind",
-    "spheroid",
-    "spigot",
-    "spindle",
-    "spyglass",
-    "stagehand",
-    "stagnate",
-    "stairway",
-    "standard",
-    "stapler",
-    "steamship",
-    "sterling",
-    "stockman",
-    "stopwatch",
-    "stormy",
-    "sugar",
-    "surmount",
-    "suspense",
-    "sweatband",
-    "swelter",
-    "tactics",
-    "talon",
-    "tapeworm",
-    "tempest",
-    "tiger",
-    "tissue",
-    "tonic",
-    "topmost",
-    "tracker",
-    "transit",
-    "trauma",
-    "treadmill",
-    "Trojan",
-    "trouble",
-    "tumor",
-    "tunnel",
-    "tycoon",
-    "uncut",
-    "unearth",
-    "unwind",
-    "uproot",
-    "upset",
-    "upshot",
-    "vapor",
-    "village",
-    "virus",
-    "Vulcan",
-    "waffle",
-    "wallet",
-    "watchword",
-    "wayside",
-    "willow",
-    "woodlark",
-    "Zulu"
-    };
diff --git a/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp b/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
deleted file mode 100644
index f3042f8..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/aesCFB.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-  Copyright (C) 2012-2013 by Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author  Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <string.h>
-
-#include <zrtp/crypto/aesCFB.h>
-#include <cryptcommon/aescpp.h>
-
-void aesCfbEncrypt(uint8_t *key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
-{
-    AESencrypt *saAes = new AESencrypt();
-
-    if (keyLength == 16)
-        saAes->key128(key);
-    else if (keyLength == 32)
-        saAes->key256(key);
-    else
-        return;
-
-    // Note: maybe copy IV to an internal array if we encounter strange things.
-    // the cfb encrypt modify the IV on return. Same for output data (inplace encryption)
-    saAes->cfb_encrypt(data, data, dataLength, IV);
-    delete saAes;
-}
-
-
-void aesCfbDecrypt(uint8_t *key, int32_t keyLength, uint8_t* IV, uint8_t *data, int32_t dataLength)
-{
-    AESencrypt *saAes = new AESencrypt();
-    if (keyLength == 16)
-        saAes->key128(key);
-    else if (keyLength == 32)
-        saAes->key256(key);
-    else
-        return;
-
-    // Note: maybe copy IV to an internal array if we encounter strange things.
-    // the cfb encrypt modify the IV on return. Same for output data (inplace encryption)
-    saAes->cfb_decrypt(data, data, dataLength, IV);
-    delete saAes;
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
deleted file mode 100644
index 1e3ceb7..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/hmac256.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
-  Copyright (C) 2012-2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include "zrtp/crypto/sha2.h"
-#include "zrtp/crypto/hmac256.h"
-
-typedef struct _hmacSha256Context {
-    sha256_ctx ctx;
-    sha256_ctx innerCtx;
-    sha256_ctx outerCtx;
-} hmacSha256Context;
-
-static int32_t hmacSha256Init(hmacSha256Context *ctx, const uint8_t *key, uint32_t kLength)
-{
-    int32_t i;
-    uint8_t localPad[SHA256_BLOCK_SIZE] = {0};
-    uint8_t localKey[SHA256_BLOCK_SIZE] = {0};
-
-    if (key == NULL)
-        return 0;
-
-    memset(ctx, 0, sizeof(hmacSha256Context));
-
-    /* check key length and reduce it if necessary */
-    if (kLength > SHA256_BLOCK_SIZE) {
-        sha256_begin(&ctx->ctx);
-        sha256_hash(key, kLength, &ctx->ctx);
-        sha256_end(localKey, &ctx->ctx);
-    }
-    else {
-        memcpy(localKey, key, kLength);
-    }
-    /* prepare inner hash and hold the context */
-    for (i = 0; i < SHA256_BLOCK_SIZE; i++)
-        localPad[i] = localKey[i] ^ 0x36;
-
-    sha256_begin(&ctx->innerCtx);
-    sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->innerCtx);
-
-    /* prepare outer hash and hold the context */
-    for (i = 0; i < SHA256_BLOCK_SIZE; i++)
-        localPad[i] = localKey[i] ^ 0x5c;
-
-    sha256_begin(&ctx->outerCtx);
-    sha256_hash(localPad, SHA256_BLOCK_SIZE, &ctx->outerCtx);
-
-    /* copy prepared inner hash to work hash - ready to process data */
-    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha256_ctx));
-
-    memset(localKey, 0, sizeof(localKey));
-
-    return 1;
-}
-
-static void hmacSha256Reset(hmacSha256Context *ctx)
-{
-    /* copy prepared inner hash to work hash context */
-    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha256_ctx));
-}
-
-static void hmacSha256Update(hmacSha256Context *ctx, const uint8_t *data, uint32_t dLength)
-{
-    /* hash new data to work hash context */
-    sha256_hash(data, dLength, &ctx->ctx);
-}
-
-static void hmacSha256Final(hmacSha256Context *ctx, uint8_t *mac)
-{
-    uint8_t tmpDigest[SHA256_DIGEST_SIZE];
-
-    /* finalize work hash context */
-    sha256_end(tmpDigest, &ctx->ctx);
-
-    /* copy prepared outer hash to work hash */
-    memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha256_ctx));
-
-    /* hash inner digest to work (outer) hash context */
-    sha256_hash(tmpDigest, SHA256_DIGEST_SIZE, &ctx->ctx);
-
-    /* finalize work hash context to get the hmac*/
-    sha256_end(mac, &ctx->ctx);
-}
-
-
-void hmac_sha256(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
-    hmacSha256Context ctx;
-
-    hmacSha256Init(&ctx, key, keyLength);
-    hmacSha256Update(&ctx, data, dataLength);
-    hmacSha256Final(&ctx, mac);
-    *macLength = SHA256_DIGEST_SIZE;
-}
-
-void hmac_sha256(uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],
-                uint8_t* mac, uint32_t* macLength )
-{
-    hmacSha256Context ctx;
-
-    hmacSha256Init(&ctx, key, keyLength);
-
-    while (*dataChunks) {
-        hmacSha256Update(&ctx, *dataChunks, *dataChunckLength);
-        dataChunks ++;
-        dataChunckLength ++;
-    }
-    hmacSha256Final(&ctx, mac);
-    *macLength = SHA256_DIGEST_SIZE;
-}
-
-void* createSha256HmacContext(uint8_t* key, int32_t keyLength)
-{
-    hmacSha256Context *ctx = reinterpret_cast<hmacSha256Context*>(malloc(sizeof(hmacSha256Context)));
-
-    hmacSha256Init(ctx, key, keyLength);
-    return ctx;
-}
-
-void hmacSha256Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,
-                uint8_t* mac, int32_t* macLength)
-{
-    hmacSha256Context *pctx = (hmacSha256Context*)ctx;
-
-    hmacSha256Reset(pctx);
-    hmacSha256Update(pctx, data, dataLength);
-    hmacSha256Final(pctx, mac);
-    *macLength = SHA256_DIGEST_SIZE;
-}
-
-void hmacSha256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
-                uint8_t* mac, int32_t* macLength )
-{
-    hmacSha256Context *pctx = (hmacSha256Context*)ctx;
-
-    hmacSha256Reset(pctx);
-    while (*data) {
-        hmacSha256Update(pctx, *data, *dataLength);
-        data++;
-        dataLength++;
-    }
-    hmacSha256Final(pctx, mac);
-    *macLength = SHA256_DIGEST_SIZE;
-}
-
-void freeSha256HmacContext(void* ctx)
-{
-    if (ctx) {
-        memset(ctx, 0, sizeof(hmacSha256Context));
-        free(ctx);
-    }
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp b/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
deleted file mode 100644
index c7a7abd..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/hmac384.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
-  Copyright (C) 2012 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-#include "zrtp/crypto/sha2.h"
-#include "zrtp/crypto/hmac384.h"
-
-typedef struct _hmacSha384Context {
-    sha384_ctx ctx;
-    sha384_ctx innerCtx;
-    sha384_ctx outerCtx;
-} hmacSha384Context;
-
-static int32_t hmacSha384Init(hmacSha384Context *ctx, const uint8_t *key, uint32_t kLength)
-{
-    int32_t i;
-    uint8_t localPad[SHA384_BLOCK_SIZE] = {0};
-    uint8_t localKey[SHA384_BLOCK_SIZE] = {0};
-
-    if (key == NULL)
-        return 0;
-
-    memset(ctx, 0, sizeof(hmacSha384Context));
-
-    /* check key length and reduce it if necessary */
-    if (kLength > SHA384_BLOCK_SIZE) {
-        sha384_begin(&ctx->ctx);
-        sha384_hash(key, kLength, &ctx->ctx);
-        sha384_end(localKey, &ctx->ctx);
-    }
-    else {
-        memcpy(localKey, key, kLength);
-    }
-    /* prepare inner hash and hold the context */
-    for (i = 0; i < SHA384_BLOCK_SIZE; i++)
-        localPad[i] = localKey[i] ^ 0x36;
-
-    sha384_begin(&ctx->innerCtx);
-    sha384_hash(localPad, SHA384_BLOCK_SIZE, &ctx->innerCtx);
-
-    /* prepare outer hash and hold the context */
-    for (i = 0; i < SHA384_BLOCK_SIZE; i++)
-        localPad[i] = localKey[i] ^ 0x5c;
-
-    sha384_begin(&ctx->outerCtx);
-    sha384_hash(localPad, SHA384_BLOCK_SIZE, &ctx->outerCtx);
-
-    /* copy prepared inner hash to work hash - ready to process data */
-    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha384_ctx));
-
-    memset(localKey, 0, sizeof(localKey));
-
-    return 1;
-}
-
-static void hmacSha384Reset(hmacSha384Context *ctx)
-{
-    /* copy prepared inner hash to work hash context */
-    memcpy(&ctx->ctx, &ctx->innerCtx, sizeof(sha384_ctx));
-}
-
-static void hmacSha384Update(hmacSha384Context *ctx, const uint8_t *data, uint32_t dLength)
-{
-    /* hash new data to work hash context */
-    sha384_hash(data, dLength, &ctx->ctx);
-}
-
-static void hmacSha384Final(hmacSha384Context *ctx, uint8_t *mac)
-{
-    uint8_t tmpDigest[SHA384_DIGEST_SIZE];
-
-    /* finalize work hash context */
-    sha384_end(tmpDigest, &ctx->ctx);
-
-    /* copy prepared outer hash to work hash */
-    memcpy(&ctx->ctx, &ctx->outerCtx, sizeof(sha384_ctx));
-
-    /* hash inner digest to work (outer) hash context */
-    sha384_hash(tmpDigest, SHA384_DIGEST_SIZE, &ctx->ctx);
-
-    /* finalize work hash context to get the hmac*/
-    sha384_end(mac, &ctx->ctx);
-}
-
-
-void hmac_sha384(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
-    hmacSha384Context ctx;
-
-    hmacSha384Init(&ctx, key, keyLength);
-    hmacSha384Update(&ctx, data, dataLength);
-    hmacSha384Final(&ctx, mac);
-    *macLength = SHA384_DIGEST_SIZE;
-}
-
-void hmac_sha384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunckLength[],
-                uint8_t* mac, uint32_t* macLength )
-{
-    hmacSha384Context ctx;
-
-    hmacSha384Init(&ctx, key, keyLength);
-
-    while (*dataChunks) {
-        hmacSha384Update(&ctx, *dataChunks, *dataChunckLength);
-        dataChunks ++;
-        dataChunckLength ++;
-    }
-    hmacSha384Final(&ctx, mac);
-    *macLength = SHA384_DIGEST_SIZE;
-}
-
-void* createSha384HmacContext(uint8_t* key, int32_t keyLength)
-{
-    hmacSha384Context *ctx = reinterpret_cast<hmacSha384Context*>(malloc(sizeof(hmacSha384Context)));
-
-    hmacSha384Init(ctx, key, keyLength);
-    return ctx;
-}
-
-void hmacSha384Ctx(void* ctx, const uint8_t* data, uint32_t dataLength,
-                uint8_t* mac, int32_t* macLength)
-{
-    hmacSha384Context *pctx = (hmacSha384Context*)ctx;
-
-    hmacSha384Reset(pctx);
-    hmacSha384Update(pctx, data, dataLength);
-    hmacSha384Final(pctx, mac);
-    *macLength = SHA384_DIGEST_SIZE;
-}
-
-void hmacSha384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[],
-                uint8_t* mac, int32_t* macLength )
-{
-    hmacSha384Context *pctx = (hmacSha384Context*)ctx;
-
-    hmacSha384Reset(pctx);
-    while (*data) {
-        hmacSha384Update(pctx, *data, *dataLength);
-        data++;
-        dataLength++;
-    }
-    hmacSha384Final(pctx, mac);
-    *macLength = SHA384_DIGEST_SIZE;
-}
-
-void freeSha384HmacContext(void* ctx)
-{
-    if (ctx) {
-        memset(ctx, 0, sizeof(hmacSha384Context));
-        free(ctx);
-    }
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha2.c b/jni/libzrtp/sources/zrtp/crypto/sha2.c
deleted file mode 100644
index 22761f3..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha2.c
+++ /dev/null
@@ -1,773 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products
-      built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-
- This is a byte oriented version of SHA2 that operates on arrays of bytes
- stored in memory. This code implements sha256, sha384 and sha512 but the
- latter two functions rely on efficient 64-bit integer operations that
- may not be very efficient on 32-bit machines
-
- The sha256 functions use a type 'sha256_ctx' to hold details of the
- current hash state and uses the following three calls:
-
-       void sha256_begin(sha256_ctx ctx[1])
-       void sha256_hash(const unsigned char data[],
-                            unsigned long len, sha256_ctx ctx[1])
-       void sha_end1(unsigned char hval[], sha256_ctx ctx[1])
-
- The first subroutine initialises a hash computation by setting up the
- context in the sha256_ctx context. The second subroutine hashes 8-bit
- bytes from array data[] into the hash state withinh sha256_ctx context,
- the number of bytes to be hashed being given by the the unsigned long
- integer len.  The third subroutine completes the hash calculation and
- places the resulting digest value in the array of 8-bit bytes hval[].
-
- The sha384 and sha512 functions are similar and use the interfaces:
-
-       void sha384_begin(sha384_ctx ctx[1]);
-       void sha384_hash(const unsigned char data[],
-                            unsigned long len, sha384_ctx ctx[1]);
-       void sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
-
-       void sha512_begin(sha512_ctx ctx[1]);
-       void sha512_hash(const unsigned char data[],
-                            unsigned long len, sha512_ctx ctx[1]);
-       void sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
-
- In addition there is a function sha2 that can be used to call all these
- functions using a call with a hash length parameter as follows:
-
-       int sha2_begin(unsigned long len, sha2_ctx ctx[1]);
-       void sha2_hash(const unsigned char data[],
-                            unsigned long len, sha2_ctx ctx[1]);
-       void sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
-
- My thanks to Erik Andersen <andersen@codepoet.org> for testing this code
- on big-endian systems and for his assistance with corrections
-*/
-
-#if 0
-#define UNROLL_SHA2     /* for SHA2 loop unroll     */
-#endif
-
-#include <string.h>     /* for memcpy() etc.        */
-
-#include "sha2.h"
-
-#include <cryptcommon/brg_endian.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#if defined( _MSC_VER ) && ( _MSC_VER > 800 )
-#pragma intrinsic(memcpy)
-#endif
-
-#if 0 && defined(_MSC_VER)
-#define rotl32 _lrotl
-#define rotr32 _lrotr
-#else
-#define rotl32(x,n)   (((x) << n) | ((x) >> (32 - n)))
-#define rotr32(x,n)   (((x) >> n) | ((x) << (32 - n)))
-#endif
-
-#if !defined(bswap_32)
-#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00))
-#endif
-
-#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN)
-#define SWAP_BYTES
-#else
-#undef  SWAP_BYTES
-#endif
-
-#if 0
-
-#define ch(x,y,z)       (((x) & (y)) ^ (~(x) & (z)))
-#define maj(x,y,z)      (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-
-#else   /* Thanks to Rich Schroeppel and Colin Plumb for the following      */
-
-#define ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
-#define maj(x,y,z)      (((x) & (y)) | ((z) & ((x) ^ (y))))
-
-#endif
-
-/* round transforms for SHA256 and SHA512 compression functions */
-
-#define vf(n,i) v[(n - i) & 7]
-
-#define hf(i) (p[i & 15] += \
-    g_1(p[(i + 14) & 15]) + p[(i + 9) & 15] + g_0(p[(i + 1) & 15]))
-
-#define v_cycle(i,j)                                \
-    vf(7,i) += (j ? hf(i) : p[i]) + k_0[i+j]        \
-    + s_1(vf(4,i)) + ch(vf(4,i),vf(5,i),vf(6,i));   \
-    vf(3,i) += vf(7,i);                             \
-    vf(7,i) += s_0(vf(0,i))+ maj(vf(0,i),vf(1,i),vf(2,i))
-
-#if defined(SHA_224) || defined(SHA_256)
-
-#define SHA256_MASK (SHA256_BLOCK_SIZE - 1)
-
-#if defined(SWAP_BYTES)
-#define bsw_32(p,n) \
-    { int _i = (n); while(_i--) ((uint_32t*)p)[_i] = bswap_32(((uint_32t*)p)[_i]); }
-#else
-#define bsw_32(p,n)
-#endif
-
-#define s_0(x)  (rotr32((x),  2) ^ rotr32((x), 13) ^ rotr32((x), 22))
-#define s_1(x)  (rotr32((x),  6) ^ rotr32((x), 11) ^ rotr32((x), 25))
-#define g_0(x)  (rotr32((x),  7) ^ rotr32((x), 18) ^ ((x) >>  3))
-#define g_1(x)  (rotr32((x), 17) ^ rotr32((x), 19) ^ ((x) >> 10))
-#define k_0     k256
-
-/* rotated SHA256 round definition. Rather than swapping variables as in    */
-/* FIPS-180, different variables are 'rotated' on each round, returning     */
-/* to their starting positions every eight rounds                           */
-
-#define q(n)  v##n
-
-#define one_cycle(a,b,c,d,e,f,g,h,k,w)  \
-    q(h) += s_1(q(e)) + ch(q(e), q(f), q(g)) + k + w; \
-    q(d) += q(h); q(h) += s_0(q(a)) + maj(q(a), q(b), q(c))
-
-/* SHA256 mixing data   */
-
-const uint_32t k256[64] =
-{   0x428a2f98ul, 0x71374491ul, 0xb5c0fbcful, 0xe9b5dba5ul,
-    0x3956c25bul, 0x59f111f1ul, 0x923f82a4ul, 0xab1c5ed5ul,
-    0xd807aa98ul, 0x12835b01ul, 0x243185beul, 0x550c7dc3ul,
-    0x72be5d74ul, 0x80deb1feul, 0x9bdc06a7ul, 0xc19bf174ul,
-    0xe49b69c1ul, 0xefbe4786ul, 0x0fc19dc6ul, 0x240ca1ccul,
-    0x2de92c6ful, 0x4a7484aaul, 0x5cb0a9dcul, 0x76f988daul,
-    0x983e5152ul, 0xa831c66dul, 0xb00327c8ul, 0xbf597fc7ul,
-    0xc6e00bf3ul, 0xd5a79147ul, 0x06ca6351ul, 0x14292967ul,
-    0x27b70a85ul, 0x2e1b2138ul, 0x4d2c6dfcul, 0x53380d13ul,
-    0x650a7354ul, 0x766a0abbul, 0x81c2c92eul, 0x92722c85ul,
-    0xa2bfe8a1ul, 0xa81a664bul, 0xc24b8b70ul, 0xc76c51a3ul,
-    0xd192e819ul, 0xd6990624ul, 0xf40e3585ul, 0x106aa070ul,
-    0x19a4c116ul, 0x1e376c08ul, 0x2748774cul, 0x34b0bcb5ul,
-    0x391c0cb3ul, 0x4ed8aa4aul, 0x5b9cca4ful, 0x682e6ff3ul,
-    0x748f82eeul, 0x78a5636ful, 0x84c87814ul, 0x8cc70208ul,
-    0x90befffaul, 0xa4506cebul, 0xbef9a3f7ul, 0xc67178f2ul,
-};
-
-/* Compile 64 bytes of hash data into SHA256 digest value   */
-/* NOTE: this routine assumes that the byte order in the    */
-/* ctx->wbuf[] at this point is such that low address bytes */
-/* in the ORIGINAL byte stream will go into the high end of */
-/* words on BOTH big and little endian systems              */
-
-VOID_RETURN sha256_compile(sha256_ctx ctx[1])
-{
-#if !defined(UNROLL_SHA2)
-
-    uint_32t j, *p = ctx->wbuf, v[8];
-
-    memcpy(v, ctx->hash, 8 * sizeof(uint_32t));
-
-    for(j = 0; j < 64; j += 16)
-    {
-        v_cycle( 0, j); v_cycle( 1, j);
-        v_cycle( 2, j); v_cycle( 3, j);
-        v_cycle( 4, j); v_cycle( 5, j);
-        v_cycle( 6, j); v_cycle( 7, j);
-        v_cycle( 8, j); v_cycle( 9, j);
-        v_cycle(10, j); v_cycle(11, j);
-        v_cycle(12, j); v_cycle(13, j);
-        v_cycle(14, j); v_cycle(15, j);
-    }
-
-    ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
-    ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
-    ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
-    ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
-
-#else
-
-    uint_32t *p = ctx->wbuf,v0,v1,v2,v3,v4,v5,v6,v7;
-
-    v0 = ctx->hash[0]; v1 = ctx->hash[1];
-    v2 = ctx->hash[2]; v3 = ctx->hash[3];
-    v4 = ctx->hash[4]; v5 = ctx->hash[5];
-    v6 = ctx->hash[6]; v7 = ctx->hash[7];
-
-    one_cycle(0,1,2,3,4,5,6,7,k256[ 0],p[ 0]);
-    one_cycle(7,0,1,2,3,4,5,6,k256[ 1],p[ 1]);
-    one_cycle(6,7,0,1,2,3,4,5,k256[ 2],p[ 2]);
-    one_cycle(5,6,7,0,1,2,3,4,k256[ 3],p[ 3]);
-    one_cycle(4,5,6,7,0,1,2,3,k256[ 4],p[ 4]);
-    one_cycle(3,4,5,6,7,0,1,2,k256[ 5],p[ 5]);
-    one_cycle(2,3,4,5,6,7,0,1,k256[ 6],p[ 6]);
-    one_cycle(1,2,3,4,5,6,7,0,k256[ 7],p[ 7]);
-    one_cycle(0,1,2,3,4,5,6,7,k256[ 8],p[ 8]);
-    one_cycle(7,0,1,2,3,4,5,6,k256[ 9],p[ 9]);
-    one_cycle(6,7,0,1,2,3,4,5,k256[10],p[10]);
-    one_cycle(5,6,7,0,1,2,3,4,k256[11],p[11]);
-    one_cycle(4,5,6,7,0,1,2,3,k256[12],p[12]);
-    one_cycle(3,4,5,6,7,0,1,2,k256[13],p[13]);
-    one_cycle(2,3,4,5,6,7,0,1,k256[14],p[14]);
-    one_cycle(1,2,3,4,5,6,7,0,k256[15],p[15]);
-
-    one_cycle(0,1,2,3,4,5,6,7,k256[16],hf( 0));
-    one_cycle(7,0,1,2,3,4,5,6,k256[17],hf( 1));
-    one_cycle(6,7,0,1,2,3,4,5,k256[18],hf( 2));
-    one_cycle(5,6,7,0,1,2,3,4,k256[19],hf( 3));
-    one_cycle(4,5,6,7,0,1,2,3,k256[20],hf( 4));
-    one_cycle(3,4,5,6,7,0,1,2,k256[21],hf( 5));
-    one_cycle(2,3,4,5,6,7,0,1,k256[22],hf( 6));
-    one_cycle(1,2,3,4,5,6,7,0,k256[23],hf( 7));
-    one_cycle(0,1,2,3,4,5,6,7,k256[24],hf( 8));
-    one_cycle(7,0,1,2,3,4,5,6,k256[25],hf( 9));
-    one_cycle(6,7,0,1,2,3,4,5,k256[26],hf(10));
-    one_cycle(5,6,7,0,1,2,3,4,k256[27],hf(11));
-    one_cycle(4,5,6,7,0,1,2,3,k256[28],hf(12));
-    one_cycle(3,4,5,6,7,0,1,2,k256[29],hf(13));
-    one_cycle(2,3,4,5,6,7,0,1,k256[30],hf(14));
-    one_cycle(1,2,3,4,5,6,7,0,k256[31],hf(15));
-
-    one_cycle(0,1,2,3,4,5,6,7,k256[32],hf( 0));
-    one_cycle(7,0,1,2,3,4,5,6,k256[33],hf( 1));
-    one_cycle(6,7,0,1,2,3,4,5,k256[34],hf( 2));
-    one_cycle(5,6,7,0,1,2,3,4,k256[35],hf( 3));
-    one_cycle(4,5,6,7,0,1,2,3,k256[36],hf( 4));
-    one_cycle(3,4,5,6,7,0,1,2,k256[37],hf( 5));
-    one_cycle(2,3,4,5,6,7,0,1,k256[38],hf( 6));
-    one_cycle(1,2,3,4,5,6,7,0,k256[39],hf( 7));
-    one_cycle(0,1,2,3,4,5,6,7,k256[40],hf( 8));
-    one_cycle(7,0,1,2,3,4,5,6,k256[41],hf( 9));
-    one_cycle(6,7,0,1,2,3,4,5,k256[42],hf(10));
-    one_cycle(5,6,7,0,1,2,3,4,k256[43],hf(11));
-    one_cycle(4,5,6,7,0,1,2,3,k256[44],hf(12));
-    one_cycle(3,4,5,6,7,0,1,2,k256[45],hf(13));
-    one_cycle(2,3,4,5,6,7,0,1,k256[46],hf(14));
-    one_cycle(1,2,3,4,5,6,7,0,k256[47],hf(15));
-
-    one_cycle(0,1,2,3,4,5,6,7,k256[48],hf( 0));
-    one_cycle(7,0,1,2,3,4,5,6,k256[49],hf( 1));
-    one_cycle(6,7,0,1,2,3,4,5,k256[50],hf( 2));
-    one_cycle(5,6,7,0,1,2,3,4,k256[51],hf( 3));
-    one_cycle(4,5,6,7,0,1,2,3,k256[52],hf( 4));
-    one_cycle(3,4,5,6,7,0,1,2,k256[53],hf( 5));
-    one_cycle(2,3,4,5,6,7,0,1,k256[54],hf( 6));
-    one_cycle(1,2,3,4,5,6,7,0,k256[55],hf( 7));
-    one_cycle(0,1,2,3,4,5,6,7,k256[56],hf( 8));
-    one_cycle(7,0,1,2,3,4,5,6,k256[57],hf( 9));
-    one_cycle(6,7,0,1,2,3,4,5,k256[58],hf(10));
-    one_cycle(5,6,7,0,1,2,3,4,k256[59],hf(11));
-    one_cycle(4,5,6,7,0,1,2,3,k256[60],hf(12));
-    one_cycle(3,4,5,6,7,0,1,2,k256[61],hf(13));
-    one_cycle(2,3,4,5,6,7,0,1,k256[62],hf(14));
-    one_cycle(1,2,3,4,5,6,7,0,k256[63],hf(15));
-
-    ctx->hash[0] += v0; ctx->hash[1] += v1;
-    ctx->hash[2] += v2; ctx->hash[3] += v3;
-    ctx->hash[4] += v4; ctx->hash[5] += v5;
-    ctx->hash[6] += v6; ctx->hash[7] += v7;
-#endif
-}
-
-/* SHA256 hash data in an array of bytes into hash buffer   */
-/* and call the hash_compile function as required.          */
-
-VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1])
-{   uint_32t pos = (uint_32t)(ctx->count[0] & SHA256_MASK),
-             space = SHA256_BLOCK_SIZE - pos;
-    const unsigned char *sp = data;
-
-    if((ctx->count[0] += len) < len)
-        ++(ctx->count[1]);
-
-    while(len >= space)     /* tranfer whole blocks while possible  */
-    {
-        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
-        sp += space; len -= space; space = SHA256_BLOCK_SIZE; pos = 0;
-        bsw_32(ctx->wbuf, SHA256_BLOCK_SIZE >> 2)
-        sha256_compile(ctx);
-    }
-
-    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
-}
-
-/* SHA256 Final padding and digest calculation  */
-
-static void sha_end1(unsigned char hval[], sha256_ctx ctx[1], const unsigned int hlen)
-{   uint_32t    i = (uint_32t)(ctx->count[0] & SHA256_MASK);
-
-    /* put bytes in the buffer in an order in which references to   */
-    /* 32-bit words will put bytes with lower addresses into the    */
-    /* top of 32 bit words on BOTH big and little endian machines   */
-    bsw_32(ctx->wbuf, (i + 3) >> 2)
-
-    /* we now need to mask valid bytes and add the padding which is */
-    /* a single 1 bit and as many zero bits as necessary. Note that */
-    /* we can always add the first padding byte here because the    */
-    /* buffer always has at least one empty slot                    */
-    ctx->wbuf[i >> 2] &= 0xffffff80 << 8 * (~i & 3);
-    ctx->wbuf[i >> 2] |= 0x00000080 << 8 * (~i & 3);
-
-    /* we need 9 or more empty positions, one for the padding byte  */
-    /* (above) and eight for the length count.  If there is not     */
-    /* enough space pad and empty the buffer                        */
-    if(i > SHA256_BLOCK_SIZE - 9)
-    {
-        if(i < 60) ctx->wbuf[15] = 0;
-        sha256_compile(ctx);
-        i = 0;
-    }
-    else    /* compute a word index for the empty buffer positions  */
-        i = (i >> 2) + 1;
-
-    while(i < 14) /* and zero pad all but last two positions        */
-        ctx->wbuf[i++] = 0;
-
-    /* the following 32-bit length fields are assembled in the      */
-    /* wrong byte order on little endian machines but this is       */
-    /* corrected later since they are only ever used as 32-bit      */
-    /* word values.                                                 */
-    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 29);
-    ctx->wbuf[15] = ctx->count[0] << 3;
-    sha256_compile(ctx);
-
-    /* extract the hash value as bytes in case the hash buffer is   */
-    /* mislaigned for 32-bit words                                  */
-    for(i = 0; i < hlen; ++i)
-        hval[i] = (unsigned char)(ctx->hash[i >> 2] >> (8 * (~i & 3)));
-}
-
-#endif
-
-#if defined(SHA_224)
-
-const uint_32t i224[8] =
-{
-    0xc1059ed8ul, 0x367cd507ul, 0x3070dd17ul, 0xf70e5939ul,
-    0xffc00b31ul, 0x68581511ul, 0x64f98fa7ul, 0xbefa4fa4ul
-};
-
-VOID_RETURN sha224_begin(sha224_ctx ctx[1])
-{
-    ctx->count[0] = ctx->count[1] = 0;
-    memcpy(ctx->hash, i224, 8 * sizeof(uint_32t));
-}
-
-VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1])
-{
-    sha_end1(hval, ctx, SHA224_DIGEST_SIZE);
-}
-
-VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len)
-{   sha224_ctx  cx[1];
-
-    sha224_begin(cx);
-    sha224_hash(data, len, cx);
-    sha_end1(hval, cx, SHA224_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_256)
-
-const uint_32t i256[8] =
-{
-    0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul,
-    0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul
-};
-
-VOID_RETURN sha256_begin(sha256_ctx ctx[1])
-{
-    ctx->count[0] = ctx->count[1] = 0;
-    memcpy(ctx->hash, i256, 8 * sizeof(uint_32t));
-}
-
-VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1])
-{
-    sha_end1(hval, ctx, SHA256_DIGEST_SIZE);
-}
-
-VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len)
-{   sha256_ctx  cx[1];
-
-    sha256_begin(cx);
-    sha256_hash(data, len, cx);
-    sha_end1(hval, cx, SHA256_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_384) || defined(SHA_512)
-
-#define SHA512_MASK (SHA512_BLOCK_SIZE - 1)
-
-#define rotr64(x,n)   (((x) >> n) | ((x) << (64 - n)))
-
-#if !defined(bswap_64)
-#define bswap_64(x) (((uint_64t)(bswap_32((uint_32t)(x)))) << 32 | bswap_32((uint_32t)((x) >> 32)))
-#endif
-
-#if defined(SWAP_BYTES)
-#define bsw_64(p,n) \
-    { int _i = (n); while(_i--) ((uint_64t*)p)[_i] = bswap_64(((uint_64t*)p)[_i]); }
-#else
-#define bsw_64(p,n)
-#endif
-
-/* SHA512 mixing function definitions   */
-
-#ifdef   s_0
-# undef  s_0
-# undef  s_1
-# undef  g_0
-# undef  g_1
-# undef  k_0
-#endif
-
-#define s_0(x)  (rotr64((x), 28) ^ rotr64((x), 34) ^ rotr64((x), 39))
-#define s_1(x)  (rotr64((x), 14) ^ rotr64((x), 18) ^ rotr64((x), 41))
-#define g_0(x)  (rotr64((x),  1) ^ rotr64((x),  8) ^ ((x) >>  7))
-#define g_1(x)  (rotr64((x), 19) ^ rotr64((x), 61) ^ ((x) >>  6))
-#define k_0     k512
-
-/* SHA384/SHA512 mixing data    */
-
-const uint_64t  k512[80] =
-{
-    li_64(428a2f98d728ae22), li_64(7137449123ef65cd),
-    li_64(b5c0fbcfec4d3b2f), li_64(e9b5dba58189dbbc),
-    li_64(3956c25bf348b538), li_64(59f111f1b605d019),
-    li_64(923f82a4af194f9b), li_64(ab1c5ed5da6d8118),
-    li_64(d807aa98a3030242), li_64(12835b0145706fbe),
-    li_64(243185be4ee4b28c), li_64(550c7dc3d5ffb4e2),
-    li_64(72be5d74f27b896f), li_64(80deb1fe3b1696b1),
-    li_64(9bdc06a725c71235), li_64(c19bf174cf692694),
-    li_64(e49b69c19ef14ad2), li_64(efbe4786384f25e3),
-    li_64(0fc19dc68b8cd5b5), li_64(240ca1cc77ac9c65),
-    li_64(2de92c6f592b0275), li_64(4a7484aa6ea6e483),
-    li_64(5cb0a9dcbd41fbd4), li_64(76f988da831153b5),
-    li_64(983e5152ee66dfab), li_64(a831c66d2db43210),
-    li_64(b00327c898fb213f), li_64(bf597fc7beef0ee4),
-    li_64(c6e00bf33da88fc2), li_64(d5a79147930aa725),
-    li_64(06ca6351e003826f), li_64(142929670a0e6e70),
-    li_64(27b70a8546d22ffc), li_64(2e1b21385c26c926),
-    li_64(4d2c6dfc5ac42aed), li_64(53380d139d95b3df),
-    li_64(650a73548baf63de), li_64(766a0abb3c77b2a8),
-    li_64(81c2c92e47edaee6), li_64(92722c851482353b),
-    li_64(a2bfe8a14cf10364), li_64(a81a664bbc423001),
-    li_64(c24b8b70d0f89791), li_64(c76c51a30654be30),
-    li_64(d192e819d6ef5218), li_64(d69906245565a910),
-    li_64(f40e35855771202a), li_64(106aa07032bbd1b8),
-    li_64(19a4c116b8d2d0c8), li_64(1e376c085141ab53),
-    li_64(2748774cdf8eeb99), li_64(34b0bcb5e19b48a8),
-    li_64(391c0cb3c5c95a63), li_64(4ed8aa4ae3418acb),
-    li_64(5b9cca4f7763e373), li_64(682e6ff3d6b2b8a3),
-    li_64(748f82ee5defb2fc), li_64(78a5636f43172f60),
-    li_64(84c87814a1f0ab72), li_64(8cc702081a6439ec),
-    li_64(90befffa23631e28), li_64(a4506cebde82bde9),
-    li_64(bef9a3f7b2c67915), li_64(c67178f2e372532b),
-    li_64(ca273eceea26619c), li_64(d186b8c721c0c207),
-    li_64(eada7dd6cde0eb1e), li_64(f57d4f7fee6ed178),
-    li_64(06f067aa72176fba), li_64(0a637dc5a2c898a6),
-    li_64(113f9804bef90dae), li_64(1b710b35131c471b),
-    li_64(28db77f523047d84), li_64(32caab7b40c72493),
-    li_64(3c9ebe0a15c9bebc), li_64(431d67c49c100d4c),
-    li_64(4cc5d4becb3e42b6), li_64(597f299cfc657e2a),
-    li_64(5fcb6fab3ad6faec), li_64(6c44198c4a475817)
-};
-
-/* Compile 128 bytes of hash data into SHA384/512 digest    */
-/* NOTE: this routine assumes that the byte order in the    */
-/* ctx->wbuf[] at this point is such that low address bytes */
-/* in the ORIGINAL byte stream will go into the high end of */
-/* words on BOTH big and little endian systems              */
-
-VOID_RETURN sha512_compile(sha512_ctx ctx[1])
-{   uint_64t    v[8], *p = ctx->wbuf;
-    uint_32t    j;
-
-    memcpy(v, ctx->hash, 8 * sizeof(uint_64t));
-
-    for(j = 0; j < 80; j += 16)
-    {
-        v_cycle( 0, j); v_cycle( 1, j);
-        v_cycle( 2, j); v_cycle( 3, j);
-        v_cycle( 4, j); v_cycle( 5, j);
-        v_cycle( 6, j); v_cycle( 7, j);
-        v_cycle( 8, j); v_cycle( 9, j);
-        v_cycle(10, j); v_cycle(11, j);
-        v_cycle(12, j); v_cycle(13, j);
-        v_cycle(14, j); v_cycle(15, j);
-    }
-
-    ctx->hash[0] += v[0]; ctx->hash[1] += v[1];
-    ctx->hash[2] += v[2]; ctx->hash[3] += v[3];
-    ctx->hash[4] += v[4]; ctx->hash[5] += v[5];
-    ctx->hash[6] += v[6]; ctx->hash[7] += v[7];
-}
-
-/* Compile 128 bytes of hash data into SHA256 digest value  */
-/* NOTE: this routine assumes that the byte order in the    */
-/* ctx->wbuf[] at this point is in such an order that low   */
-/* address bytes in the ORIGINAL byte stream placed in this */
-/* buffer will now go to the high end of words on BOTH big  */
-/* and little endian systems                                */
-
-VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1])
-{   uint_32t pos = (uint_32t)(ctx->count[0] & SHA512_MASK),
-             space = SHA512_BLOCK_SIZE - pos;
-    const unsigned char *sp = data;
-
-    if((ctx->count[0] += len) < len)
-        ++(ctx->count[1]);
-
-    while(len >= space)     /* tranfer whole blocks while possible  */
-    {
-        memcpy(((unsigned char*)ctx->wbuf) + pos, sp, space);
-        sp += space; len -= space; space = SHA512_BLOCK_SIZE; pos = 0;
-        bsw_64(ctx->wbuf, SHA512_BLOCK_SIZE >> 3);
-        sha512_compile(ctx);
-    }
-
-    memcpy(((unsigned char*)ctx->wbuf) + pos, sp, len);
-}
-
-/* SHA384/512 Final padding and digest calculation  */
-
-static void sha_end2(unsigned char hval[], sha512_ctx ctx[1], const unsigned int hlen)
-{   uint_32t    i = (uint_32t)(ctx->count[0] & SHA512_MASK);
-
-    /* put bytes in the buffer in an order in which references to   */
-    /* 32-bit words will put bytes with lower addresses into the    */
-    /* top of 32 bit words on BOTH big and little endian machines   */
-    bsw_64(ctx->wbuf, (i + 7) >> 3);
-
-    /* we now need to mask valid bytes and add the padding which is */
-    /* a single 1 bit and as many zero bits as necessary. Note that */
-    /* we can always add the first padding byte here because the    */
-    /* buffer always has at least one empty slot                    */
-    ctx->wbuf[i >> 3] &= li_64(ffffffffffffff00) << 8 * (~i & 7);
-    ctx->wbuf[i >> 3] |= li_64(0000000000000080) << 8 * (~i & 7);
-
-    /* we need 17 or more empty byte positions, one for the padding */
-    /* byte (above) and sixteen for the length count.  If there is  */
-    /* not enough space pad and empty the buffer                    */
-    if(i > SHA512_BLOCK_SIZE - 17)
-    {
-        if(i < 120) ctx->wbuf[15] = 0;
-        sha512_compile(ctx);
-        i = 0;
-    }
-    else
-        i = (i >> 3) + 1;
-
-    while(i < 14)
-        ctx->wbuf[i++] = 0;
-
-    /* the following 64-bit length fields are assembled in the      */
-    /* wrong byte order on little endian machines but this is       */
-    /* corrected later since they are only ever used as 64-bit      */
-    /* word values.                                                 */
-    ctx->wbuf[14] = (ctx->count[1] << 3) | (ctx->count[0] >> 61);
-    ctx->wbuf[15] = ctx->count[0] << 3;
-    sha512_compile(ctx);
-
-    /* extract the hash value as bytes in case the hash buffer is   */
-    /* misaligned for 32-bit words                                  */
-    for(i = 0; i < hlen; ++i)
-        hval[i] = (unsigned char)(ctx->hash[i >> 3] >> (8 * (~i & 7)));
-}
-
-#endif
-
-#if defined(SHA_384)
-
-/* SHA384 initialisation data   */
-
-const uint_64t  i384[80] =
-{
-    li_64(cbbb9d5dc1059ed8), li_64(629a292a367cd507),
-    li_64(9159015a3070dd17), li_64(152fecd8f70e5939),
-    li_64(67332667ffc00b31), li_64(8eb44a8768581511),
-    li_64(db0c2e0d64f98fa7), li_64(47b5481dbefa4fa4)
-};
-
-VOID_RETURN sha384_begin(sha384_ctx ctx[1])
-{
-    ctx->count[0] = ctx->count[1] = 0;
-    memcpy(ctx->hash, i384, 8 * sizeof(uint_64t));
-}
-
-VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1])
-{
-    sha_end2(hval, ctx, SHA384_DIGEST_SIZE);
-}
-
-VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len)
-{   sha384_ctx  cx[1];
-
-    sha384_begin(cx);
-    sha384_hash(data, len, cx);
-    sha_end2(hval, cx, SHA384_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_512)
-
-/* SHA512 initialisation data   */
-
-const uint_64t  i512[80] =
-{
-    li_64(6a09e667f3bcc908), li_64(bb67ae8584caa73b),
-    li_64(3c6ef372fe94f82b), li_64(a54ff53a5f1d36f1),
-    li_64(510e527fade682d1), li_64(9b05688c2b3e6c1f),
-    li_64(1f83d9abfb41bd6b), li_64(5be0cd19137e2179)
-};
-
-VOID_RETURN sha512_begin(sha512_ctx ctx[1])
-{
-    ctx->count[0] = ctx->count[1] = 0;
-    memcpy(ctx->hash, i512, 8 * sizeof(uint_64t));
-}
-
-VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1])
-{
-    sha_end2(hval, ctx, SHA512_DIGEST_SIZE);
-}
-
-VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len)
-{   sha512_ctx  cx[1];
-
-    sha512_begin(cx);
-    sha512_hash(data, len, cx);
-    sha_end2(hval, cx, SHA512_DIGEST_SIZE);
-}
-
-#endif
-
-#if defined(SHA_2)
-
-#define CTX_224(x)  ((x)->uu->ctx256)
-#define CTX_256(x)  ((x)->uu->ctx256)
-#define CTX_384(x)  ((x)->uu->ctx512)
-#define CTX_512(x)  ((x)->uu->ctx512)
-
-/* SHA2 initialisation */
-
-INT_RETURN sha2_begin(unsigned long len, sha2_ctx ctx[1])
-{
-    switch(len)
-    {
-#if defined(SHA_224)
-        case 224:
-        case  28:   CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
-                    memcpy(CTX_256(ctx)->hash, i224, 32);
-                    ctx->sha2_len = 28; return EXIT_SUCCESS;
-#endif
-#if defined(SHA_256)
-        case 256:
-        case  32:   CTX_256(ctx)->count[0] = CTX_256(ctx)->count[1] = 0;
-                    memcpy(CTX_256(ctx)->hash, i256, 32);
-                    ctx->sha2_len = 32; return EXIT_SUCCESS;
-#endif
-#if defined(SHA_384)
-        case 384:
-        case  48:   CTX_384(ctx)->count[0] = CTX_384(ctx)->count[1] = 0;
-                    memcpy(CTX_384(ctx)->hash, i384, 64);
-                    ctx->sha2_len = 48; return EXIT_SUCCESS;
-#endif
-#if defined(SHA_512)
-        case 512:
-        case  64:   CTX_512(ctx)->count[0] = CTX_512(ctx)->count[1] = 0;
-                    memcpy(CTX_512(ctx)->hash, i512, 64);
-                    ctx->sha2_len = 64; return EXIT_SUCCESS;
-#endif
-        default:    return EXIT_FAILURE;
-    }
-}
-
-VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1])
-{
-    switch(ctx->sha2_len)
-    {
-#if defined(SHA_224)
-        case 28: sha224_hash(data, len, CTX_224(ctx)); return;
-#endif
-#if defined(SHA_256)
-        case 32: sha256_hash(data, len, CTX_256(ctx)); return;
-#endif
-#if defined(SHA_384)
-        case 48: sha384_hash(data, len, CTX_384(ctx)); return;
-#endif
-#if defined(SHA_512)
-        case 64: sha512_hash(data, len, CTX_512(ctx)); return;
-#endif
-    }
-}
-
-VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1])
-{
-    switch(ctx->sha2_len)
-    {
-#if defined(SHA_224)
-        case 28: sha_end1(hval, CTX_224(ctx), SHA224_DIGEST_SIZE); return;
-#endif
-#if defined(SHA_256)
-        case 32: sha_end1(hval, CTX_256(ctx), SHA256_DIGEST_SIZE); return;
-#endif
-#if defined(SHA_384)
-        case 48: sha_end2(hval, CTX_384(ctx), SHA384_DIGEST_SIZE); return;
-#endif
-#if defined(SHA_512)
-        case 64: sha_end2(hval, CTX_512(ctx), SHA512_DIGEST_SIZE); return;
-#endif
-    }
-}
-
-INT_RETURN sha2_all(unsigned char hval[], unsigned long size,
-                                const unsigned char data[], unsigned long len)
-{   sha2_ctx    cx[1];
-
-    if(sha2_begin(size, cx) == EXIT_SUCCESS)
-    {
-        sha2_hash(data, len, cx); sha2_end(hval, cx); return EXIT_SUCCESS;
-    }
-    else
-        return EXIT_FAILURE;
-}
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha2.h b/jni/libzrtp/sources/zrtp/crypto/sha2.h
deleted file mode 100644
index 1ad3889..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha2.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 2002, Dr Brian Gladman, Worcester, UK.   All rights reserved.
-
- LICENSE TERMS
-
- The free distribution and use of this software in both source and binary
- form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright
-      notice, this list of conditions and the following disclaimer;
-
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer
-      in the documentation and/or other associated materials;
-
-   3. the copyright holder's name is not used to endorse products
-      built using this software without specific written permission.
-
- ALTERNATIVELY, provided that this notice is retained in full, this product
- may be distributed under the terms of the GNU General Public License (GPL),
- in which case the provisions of the GPL apply INSTEAD OF those given above.
-
- DISCLAIMER
-
- This software is provided 'as is' with no explicit or implied warranties
- in respect of its properties, including, but not limited to, correctness
- and/or fitness for purpose.
- ---------------------------------------------------------------------------
- Issue Date: 01/08/2005
-*/
-
-#ifndef _SHA2_H
-#define _SHA2_H
-
-#include <stdlib.h>
-
-#define SHA_64BIT
-
-/* define the hash functions that you need  */
-#define SHA_2   /* for dynamic hash length  */
-#define SHA_224
-#define SHA_256
-#ifdef SHA_64BIT
-#  define SHA_384
-#  define SHA_512
-#  define NEED_UINT_64T
-#endif
-
-#include <cryptcommon/brg_types.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-/* Note that the following function prototypes are the same */
-/* for both the bit and byte oriented implementations.  But */
-/* the length fields are in bytes or bits as is appropriate */
-/* for the version used.  Bit sequences are arrays of bytes */
-/* in which bit sequence indexes increase from the most to  */
-/* the least significant end of each byte                   */
-
-#define SHA224_DIGEST_SIZE  28
-#define SHA224_BLOCK_SIZE   64
-#define SHA256_DIGEST_SIZE  32
-#define SHA256_BLOCK_SIZE   64
-
-/* type to hold the SHA256 (and SHA224) context */
-
-typedef struct
-{   uint_32t count[2];
-    uint_32t hash[8];
-    uint_32t wbuf[16];
-} sha256_ctx;
-
-typedef sha256_ctx  sha224_ctx;
-
-VOID_RETURN sha256_compile(sha256_ctx ctx[1]);
-
-VOID_RETURN sha224_begin(sha224_ctx ctx[1]);
-#define sha224_hash sha256_hash
-VOID_RETURN sha224_end(unsigned char hval[], sha224_ctx ctx[1]);
-VOID_RETURN sha224(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-VOID_RETURN sha256_begin(sha256_ctx ctx[1]);
-VOID_RETURN sha256_hash(const unsigned char data[], unsigned long len, sha256_ctx ctx[1]);
-VOID_RETURN sha256_end(unsigned char hval[], sha256_ctx ctx[1]);
-VOID_RETURN sha256(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-#ifndef SHA_64BIT
-
-typedef struct
-{   union
-    { sha256_ctx  ctx256[1];
-    } uu[1];
-    uint_32t    sha2_len;
-} sha2_ctx;
-
-#define SHA2_MAX_DIGEST_SIZE    SHA256_DIGEST_SIZE
-
-#else
-
-#define SHA384_DIGEST_SIZE  48
-#define SHA384_BLOCK_SIZE  128
-#define SHA512_DIGEST_SIZE  64
-#define SHA512_BLOCK_SIZE  128
-#define SHA2_MAX_DIGEST_SIZE    SHA512_DIGEST_SIZE
-
-/* type to hold the SHA384 (and SHA512) context */
-
-typedef struct
-{   uint_64t count[2];
-    uint_64t hash[8];
-    uint_64t wbuf[16];
-} sha512_ctx;
-
-typedef sha512_ctx  sha384_ctx;
-
-typedef struct
-{   union
-    { sha256_ctx  ctx256[1];
-      sha512_ctx  ctx512[1];
-    } uu[1];
-    uint_32t    sha2_len;
-} sha2_ctx;
-
-VOID_RETURN sha512_compile(sha512_ctx ctx[1]);
-
-VOID_RETURN sha384_begin(sha384_ctx ctx[1]);
-#define sha384_hash sha512_hash
-VOID_RETURN sha384_end(unsigned char hval[], sha384_ctx ctx[1]);
-VOID_RETURN sha384(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-VOID_RETURN sha512_begin(sha512_ctx ctx[1]);
-VOID_RETURN sha512_hash(const unsigned char data[], unsigned long len, sha512_ctx ctx[1]);
-VOID_RETURN sha512_end(unsigned char hval[], sha512_ctx ctx[1]);
-VOID_RETURN sha512(unsigned char hval[], const unsigned char data[], unsigned long len);
-
-INT_RETURN  sha2_begin(unsigned long size, sha2_ctx ctx[1]);
-VOID_RETURN sha2_hash(const unsigned char data[], unsigned long len, sha2_ctx ctx[1]);
-VOID_RETURN sha2_end(unsigned char hval[], sha2_ctx ctx[1]);
-INT_RETURN  sha2_all(unsigned char hval[], unsigned long size, const unsigned char data[], unsigned long len);
-
-#endif
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha256.cpp b/jni/libzrtp/sources/zrtp/crypto/sha256.cpp
deleted file mode 100644
index 593b5e5..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha256.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-  Copyright (C) 2012 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <zrtp/crypto/sha2.h>
-#include <zrtp/crypto/sha256.h>
-
-void sha256(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
-    sha256_ctx ctx;
-
-    sha256_begin(&ctx);
-    sha256_hash(data, dataLength, &ctx);
-    sha256_end(digest, &ctx);
-}
-
-void sha256(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
-    sha256_ctx ctx;
-
-    sha256_begin(&ctx);
-    while(*dataChunks) {
-        sha256_hash(*dataChunks, *dataChunckLength, &ctx);
-        dataChunks++;
-        dataChunckLength++;
-    }
-    sha256_end(digest, &ctx);
-}
-
-void* createSha256Context()
-{
-    sha256_ctx *ctx = reinterpret_cast<sha256_ctx*>(malloc(sizeof(sha256_ctx)));
-    sha256_begin(ctx);
-    return (void*)ctx;
-}
-
-void closeSha256Context(void* ctx, unsigned char* digest)
-{
-    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);
-
-    if (digest != NULL) {
-        sha256_end(digest, hd);
-    }
-    free(hd);
-}
-
-void sha256Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
-    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);
-
-    sha256_hash(data, dataLength, hd);
-}
-
-void sha256Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
-    sha256_ctx* hd = reinterpret_cast<sha256_ctx*>(ctx);
-
-    while (*dataChunks) {
-        sha256_hash(*dataChunks, *dataChunkLength, hd);
-        dataChunks++;
-        dataChunkLength++;
-    }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/sha384.cpp b/jni/libzrtp/sources/zrtp/crypto/sha384.cpp
deleted file mode 100644
index d6b9085..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/sha384.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
-  Copyright (C) 2012 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <zrtp/crypto/sha2.h>
-#include <zrtp/crypto/sha384.h>
-
-void sha384(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
-    sha384_ctx ctx;
-
-    sha384_begin(&ctx);
-    sha384_hash(data, dataLength, &ctx);
-    sha384_end(digest, &ctx);
-}
-
-void sha384(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
-    sha384_ctx ctx;
-
-    sha384_begin(&ctx);
-    while(*dataChunks) {
-        sha384_hash(*dataChunks, *dataChunckLength, &ctx);
-        dataChunks++;
-        dataChunckLength++;
-    }
-    sha384_end(digest, &ctx);
-}
-
-void* createSha384Context()
-{
-    sha384_ctx *ctx = reinterpret_cast<sha384_ctx*>(malloc(sizeof(sha384_ctx)));
-    sha384_begin(ctx);
-    return (void*)ctx;
-}
-
-void closeSha384Context(void* ctx, unsigned char* digest)
-{
-    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);
-
-    if (digest != NULL) {
-        sha384_end(digest, hd);
-    }
-    free(hd);
-}
-
-void sha384Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
-    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);
-
-    sha384_hash(data, dataLength, hd);
-}
-
-void sha384Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
-    sha384_ctx* hd = reinterpret_cast<sha384_ctx*>(ctx);
-
-    while (*dataChunks) {
-        sha384_hash(*dataChunks, *dataChunkLength, hd);
-        dataChunks++;
-        dataChunkLength++;
-    }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein256.cpp b/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
deleted file mode 100644
index 94cff63..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein256.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <cryptcommon/skeinApi.h>
-#include <zrtp/crypto/skein256.h>
-
-#include <stdlib.h>
-
-void skein256(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);
-    skeinUpdate(&ctx, data, dataLength);
-
-    skeinFinal(&ctx, digest);
-}
-
-void skein256(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN256_DIGEST_LENGTH*8);
-    while(*dataChunks) {
-        skeinUpdate(&ctx, *dataChunks, *dataChunckLength);
-        dataChunks++;
-        dataChunckLength++;
-    }
-    skeinFinal(&ctx, digest);
-}
-
-void* createSkein256Context()
-{
-    SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));
-    skeinCtxPrepare(ctx, SKEIN_SIZE);
-    skeinInit(ctx, SKEIN256_DIGEST_LENGTH*8);
-    return (void*)ctx;
-}
-
-void closeSkein256Context(void* ctx, unsigned char* digest)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    if (digest != NULL) {
-        skeinFinal(hd, digest);
-    }
-    free(hd);
-}
-
-void skein256Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    skeinUpdate(hd, data, dataLength);
-}
-
-void skein256Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    while (*dataChunks) {
-        skeinUpdate(hd, *dataChunks, *dataChunkLength);
-        dataChunks++;
-        dataChunkLength++;
-    }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein256.h b/jni/libzrtp/sources/zrtp/crypto/skein256.h
deleted file mode 100644
index 6d4e722..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein256.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Functions to compute Skein256 digest.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef _SKEIN256_H
-#define _SKEIN256_H
-
-/**
- * @file skein256.h
- * @brief Functions that provide Skein256 support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN256_DIGEST_LENGTH
-#define SKEIN256_DIGEST_LENGTH  32
-#endif
-#define SKEIN_SIZE Skein512
-
-
-/**
- * Compute Skein256 digest.
- *
- * This functions takes one data chunk and computes its Skein256 digest. This 
- * function creates and deletes an own Skein256 context to perform the Skein256
- * operations.
- *
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).
- */
-void skein256(unsigned char *data,
-            unsigned int data_length,
-            unsigned char *digest);
-
-/**
- * Compute Skein256 digest over several data cunks.
- *
- * This functions takes several data chunks and computes the Skein256 digest.
- * This function creates and deletes an own Skein256 context to perform the
- * Skein256 operations.
- *
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (Skein256_DIGEST_LENGTH).
- */
-void skein256(unsigned char *data[],
-            unsigned int data_length[],
-            unsigned char *digest);
-/**
- * Create and initialize a Skein256 context.
- *
- * An application uses this context to hash several data into one Skein256
- * digest. See also skein256Ctx(...) and closeSha256Context(...).
- *
- * @return Returns a pointer to the initialized Skein256 context
- */
-void* createSkein256Context();
-
-/**
- * Compute a digest and close the SHa256 digest.
- *
- * An application uses this function to compute the Skein256 digest and to
- * close the Skein256 context.
- *
- * @param ctx
- *    Points to the Skein256 context.
- * @param digest
- *    If this pointer is not NULL then it must point to a byte array that
- *    is big enough to hold the Skein256 digest (256 bit = 32 Bytes). If this
- *    pointer is NULL then the functions does not compute the digest but
- *    closes the context only. The context cannot be used anymore.
- */
-void closeSkein256Context(void* ctx,
-                        unsigned char* digest);
-
-/**
- * Update the Skein256 context with data.
- *
- * This functions updates the Skein256 context with some data.
- * See also CloseSha256Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein256 context.
- * @param data
- *    Points to the data to update the context.
- * @param dataLength
- *    The length of the data in bytes.
- */
-void skein256Ctx(void* ctx, unsigned char* data, 
-               unsigned int dataLength);
-
-/**
- * Update the Skein256 context with several data chunks.
- *
- * This functions updates the Skein256 context with some data.
- * See also CloseSha256Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein256 context.
- * @param dataChunks
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param dataChunkLength
- *    Points to an array of integers that hold the length of each data chunk.
- *
- */
-void skein256Ctx(void* ctx, unsigned char* dataChunks[],
-               unsigned int dataChunkLength[]);
-
-/**
- * @}
- */
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein384.cpp b/jni/libzrtp/sources/zrtp/crypto/skein384.cpp
deleted file mode 100644
index 1dbe608..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein384.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/**
- * @author: Werner Dittmann
- */
-
-#include <cryptcommon/skeinApi.h>
-#include <zrtp/crypto/skein384.h>
-
-#include <stdlib.h>
-
-#define SKEIN_SIZE Skein512
-#define SKEIN384_DIGEST_LENGTH  48
-
-void skein384(unsigned char *data, unsigned int dataLength, unsigned char *digest )
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);
-    skeinUpdate(&ctx, data, dataLength);
-
-    skeinFinal(&ctx, digest);
-}
-
-void skein384(unsigned char *dataChunks[], unsigned int dataChunckLength[], unsigned char *digest)
-{
-    SkeinCtx_t ctx;
-
-    skeinCtxPrepare(&ctx, SKEIN_SIZE);
-    skeinInit(&ctx, SKEIN384_DIGEST_LENGTH*8);
-    while(*dataChunks) {
-        skeinUpdate(&ctx, *dataChunks, *dataChunckLength);
-        dataChunks++;
-        dataChunckLength++;
-    }
-    skeinFinal(&ctx, digest);
-}
-
-void* createSkein384Context()
-{
-    SkeinCtx_t *ctx = reinterpret_cast<SkeinCtx_t *>(malloc(sizeof(SkeinCtx_t )));
-    skeinCtxPrepare(ctx, SKEIN_SIZE);
-    skeinInit(ctx, SKEIN384_DIGEST_LENGTH*8);
-    return (void*)ctx;
-}
-
-void closeSkein384Context(void* ctx, unsigned char* digest)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    if (digest != NULL) {
-        skeinFinal(hd, digest);
-    }
-    free(hd);
-}
-
-void skein384Ctx(void* ctx, unsigned char* data, unsigned int dataLength)
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    skeinUpdate(hd, data, dataLength);
-}
-
-void skein384Ctx(void* ctx, unsigned char* dataChunks[], unsigned int dataChunkLength[])
-{
-    SkeinCtx_t* hd = reinterpret_cast<SkeinCtx_t*>(ctx);
-
-    while (*dataChunks) {
-        skeinUpdate(hd, *dataChunks, *dataChunkLength);
-        dataChunks++;
-        dataChunkLength++;
-    }
-}
diff --git a/jni/libzrtp/sources/zrtp/crypto/skein384.h b/jni/libzrtp/sources/zrtp/crypto/skein384.h
deleted file mode 100644
index 61fd64e..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skein384.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * Functions to compute Skein384 digest.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef _SKEIN384_H
-#define _SKEIN384_H
-
-/**
- * @file skein384.h
- * @brief Functions that provide Skein384 support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN384_DIGEST_LENGTH
-#define SKEIN384_DIGEST_LENGTH  48
-#endif
-#define SKEIN_SIZE Skein512
-
-
-/**
- * Compute Skein384 digest.
- *
- * This functions takes one data chunk and computes its Skein384 digest. This 
- * function creates and deletes an own Skein384 context to perform the Skein384
- * operations.
- *
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).
- */
-void skein384(unsigned char *data,
-            unsigned int data_length,
-            unsigned char *digest);
-
-/**
- * Compute Skein384 digest over several data cunks.
- *
- * This functions takes several data chunks and computes the Skein384 digest.
- * This function creates and deletes an own Skein384 context to perform the
- * Skein384 operations.
- *
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param digest
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (Skein384_DIGEST_LENGTH).
- */
-void skein384(unsigned char *data[],
-            unsigned int data_length[],
-            unsigned char *digest);
-/**
- * Create and initialize a Skein384 context.
- *
- * An application uses this context to hash several data into one Skein384
- * digest. See also skein384Ctx(...) and closeSha384Context(...).
- *
- * @return Returns a pointer to the initialized Skein384 context
- */
-void* createSkein384Context();
-
-/**
- * Compute a digest and close the SHa384 digest.
- *
- * An application uses this function to compute the Skein384 digest and to
- * close the Skein384 context.
- *
- * @param ctx
- *    Points to the Skein384 context.
- * @param digest
- *    If this pointer is not NULL then it must point to a byte array that
- *    is big enough to hold the Skein384 digest (384 bit = 48 Bytes). If this
- *    pointer is NULL then the functions does not compute the digest but
- *    closes the context only. The context cannot be used anymore.
- */
-void closeSkein384Context(void* ctx,
-                        unsigned char* digest);
-
-/**
- * Update the Skein384 context with data.
- *
- * This functions updates the Skein384 context with some data.
- * See also CloseSha384Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein384 context.
- * @param data
- *    Points to the data to update the context.
- * @param dataLength
- *    The length of the data in bytes.
- */
-void skein384Ctx(void* ctx, unsigned char* data, 
-               unsigned int dataLength);
-
-/**
- * Update the Skein384 context with several data chunks.
- *
- * This functions updates the Skein384 context with some data.
- * See also CloseSha384Context(...) how to get the digest.
- *
- * @param ctx
- *    Points to the Skein384 context.
- * @param dataChunks
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param dataChunkLength
- *    Points to an array of integers that hold the length of each data chunk.
- *
- */
-void skein384Ctx(void* ctx, unsigned char* dataChunks[],
-               unsigned int dataChunkLength[]);
-
-/**
- * @}
- */
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp
deleted file mode 100644
index b4234e5..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#include <cryptcommon/macSkein.h>
-#include <zrtp/crypto/skeinMac256.h>
-
-void macSkein256(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
-    macSkein(key, keyLength, data, dataLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-
-void macSkein256( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )
-{
-    macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void* createMacSkein256Context(uint8_t* key, int32_t keyLength)
-{
-    return createSkeinMacContext(key, keyLength, SKEIN256_DIGEST_LENGTH*8, SKEIN_SIZE);
-}
-
-void macSkein256Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
-
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void macSkein256Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )
-{
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN256_DIGEST_LENGTH;
-}
-
-void freeMacSkein256Context(void* ctx)
-{
-    freeSkeinMacContext(ctx);
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h b/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h
deleted file mode 100644
index e87a1e1..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac256.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/**
- * Methods to compute a Skein256 HMAC.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef HMAC_SKEIN256_H
-#define HMAC_SKEIN256_H
-
-/**
- * @file skeinMac256.h
- * @brief Function that provide Skein256 HMAC support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN256_DIGEST_LENGTH
-#define SKEIN256_DIGEST_LENGTH 32
-#endif
-
-#define SKEIN_SIZE Skein512
-
-/**
- * Compute Skein256 HMAC.
- *
- * This functions takes one data chunk and computes its Skein256 HMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-void macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );
-
-/**
- * Compute Skein256 HMAC over several data cunks.
- *
- * This functions takes several data chunk and computes the Skein256 HAMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 32 bytes (SKEIN256_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-
-void macSkein256( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp
deleted file mode 100644
index 57c7ad1..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/*
- * Authors: Werner Dittmann
- */
-
-#define SKEIN_SIZE Skein512
-#define SKEIN384_DIGEST_LENGTH  48
-
-#include <cryptcommon/macSkein.h>
-#include <zrtp/crypto/skeinMac384.h>
-
-void macSkein384(uint8_t *key, uint32_t keyLength, uint8_t* data, int32_t dataLength, uint8_t* mac, uint32_t* macLength)
-{
-    macSkein(key, keyLength, data, dataLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-
-void macSkein384( uint8_t* key, uint32_t keyLength, uint8_t* dataChunks[], uint32_t dataChunkLength[], uint8_t* mac, uint32_t* macLength )
-{
-    macSkein(key, keyLength, (const uint8_t**)dataChunks, dataChunkLength, mac, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void* createMacSkein384Context(uint8_t* key, int32_t keyLength)
-{
-    return createSkeinMacContext(key, keyLength, SKEIN384_DIGEST_LENGTH*8, SKEIN_SIZE);
-}
-
-void macSkein384Ctx(void* ctx, const uint8_t* data, uint32_t dataLength, uint8_t* mac, int32_t* macLength)
-{
-
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void macSkein384Ctx(void* ctx, const uint8_t* data[], uint32_t dataLength[], uint8_t* mac, int32_t* macLength )
-{
-    macSkeinCtx(ctx, data, dataLength, mac);
-    *macLength = SKEIN384_DIGEST_LENGTH;
-}
-
-void freeMacSkein384Context(void* ctx)
-{
-    freeSkeinMacContext(ctx);
-}
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h b/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h
deleted file mode 100644
index 2065899..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/skeinMac384.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
-  Copyright (C) 2013 Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-*/
-
-/**
- * Methods to compute a Skein384 HMAC.
- *
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#ifndef HMAC_SKEIN384_H
-#define HMAC_SKEIN384_H
-
-/**
- * @file skeinMac384.h
- * @brief Function that provide Skein384 HMAC support
- * 
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <stdint.h>
-
-#ifndef SKEIN384_DIGEST_LENGTH
-#define SKEIN384_DIGEST_LENGTH 48
-#endif
-
-#define SKEIN_SIZE Skein512
-
-/**
- * Compute Skein384 HMAC.
- *
- * This functions takes one data chunk and computes its Skein384 HMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to the data chunk.
- * @param data_length
- *    Length of the data in bytes
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-void macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data, int32_t data_length, uint8_t* mac, uint32_t* mac_length );
-
-/**
- * Compute Skein384 HMAC over several data cunks.
- *
- * This functions takes several data chunk and computes the Skein384 HAMAC.
- *
- * @param key
- *    The MAC key.
- * @param key_length
- *    Lneght of the MAC key in bytes
- * @param data
- *    Points to an array of pointers that point to the data chunks. A NULL
- *    pointer in an array element terminates the data chunks.
- * @param data_length
- *    Points to an array of integers that hold the length of each data chunk.
- * @param mac
- *    Points to a buffer that receives the computed digest. This
- *    buffer must have a size of at least 48 bytes (SKEIN384_DIGEST_LENGTH).
- * @param mac_length
- *    Point to an integer that receives the length of the computed HMAC.
- */
-
-void macSkein384( uint8_t* key, uint32_t key_length, uint8_t* data[], uint32_t data_length[], uint8_t* mac, uint32_t* mac_length );
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp b/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
deleted file mode 100644
index d718f24..0000000
--- a/jni/libzrtp/sources/zrtp/crypto/zrtpDH.cpp
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
-  Copyright (C) 2006, 2009 by Werner Dittmann
-
-  This library is free software; you can redistribute it and/or
-  modify it under the terms of the GNU Lesser General Public
-  License as published by the Free Software Foundation; either
-  version 2.1 of the License, or (at your option) any later version.
-
-  This library is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public
-  License along with this library; if not, write to the Free Software
-  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
-
- * In addition, as a special exception, the copyright holders give
- * permission to link the code of portions of this program with the
- * OpenSSL library under certain conditions as described in each
- * individual source file, and distribute linked combinations
- * including the two.
- * You must obey the GNU General Public License in all respects
- * for all of the code used other than OpenSSL.  If you modify
- * file(s) with this exception, you may extend this exception to your
- * version of the file(s), but you are not obligated to do so.  If you
- * do not wish to do so, delete this exception statement from your
- * version.  If you delete this exception statement from all source
- * files in the program, then also delete it here.
- */
-
-/** Copyright (C) 2006, 2009
- *
- * @author  Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <bn.h>
-#include <bnprint.h>
-#include <ec/ec.h>
-#include <ec/ecdh.h>
-#include <zrtp/crypto/zrtpDH.h>
-#include <zrtp/libzrtpcpp/ZrtpTextData.h>
-#include <cryptcommon/aes.h>
-#include <cryptcommon/ZrtpRandom.h>
-
-
-static BigNum bnP2048 = {0};
-static BigNum bnP3072 = {0};
-
-static BigNum bnP2048MinusOne = {0};
-static BigNum bnP3072MinusOne = {0};
-
-static BigNum two = {0};
-
-static uint8_t dhinit = 0;
-
-typedef struct _dhCtx {
-    BigNum privKey;
-    BigNum pubKey;
-    EcCurve curve;
-    EcPoint pubPoint;
-} dhCtx;
-
-void randomZRTP(uint8_t *buf, int32_t length)
-{
-    ZrtpRandom::getRandomData(buf, length);
-}
-
-static const uint8_t P2048[] =
-{
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
-    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
-    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
-    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
-    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
-    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
-    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
-    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
-    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
-    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
-    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
-    0xFF, 0xFF, 0xFF, 0xFF
-};
-
-static const uint8_t P3072[] =
-{
-    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
-    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
-    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
-    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
-    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
-    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
-    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
-    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
-    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
-    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
-    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
-    0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
-    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
-    0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
-    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
-    0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
-    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
-    0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
-    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
-    0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
-    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
-    0xA9, 0x3A, 0xD2, 0xCA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-/* **************
-static const uint8_t P4096[] =
-{
-0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
-0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
-0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
-0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
-0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
-0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
-0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
-0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
-0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
-0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
-0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
-0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
-0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
-0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
-0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
-0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
-0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
-0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
-0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
-0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
-0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
-0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
-0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
-0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
-0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
-0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
-0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
-0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
-0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
-0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
-0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
-0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
-0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
-0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
-0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
-0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
-0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
-0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
-0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
-0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
-0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
-0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
-0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-*************** */
-
-ZrtpDH::ZrtpDH(const char* type) {
-
-    uint8_t random[64];
-
-    ctx = static_cast<void*>(new dhCtx);
-    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
-    // Well - the algo type is only 4 char thus cast to int32 and compare
-    if (*(int32_t*)type == *(int32_t*)dh2k) {
-        pkType = DH2K;
-    }
-    else if (*(int32_t*)type == *(int32_t*)dh3k) {
-        pkType = DH3K;
-    }
-    else if (*(int32_t*)type == *(int32_t*)ec25) {
-        pkType = EC25;
-    }
-    else if (*(int32_t*)type == *(int32_t*)ec38) {
-        pkType = EC38;
-    }
-    else if (*(int32_t*)type == *(int32_t*)e255) {
-        pkType = E255;
-    }
-    else if (*(int32_t*)type == *(int32_t*)e414) {
-        pkType = E414;
-    }
-    else {
-        return;
-    }
-
-    randomZRTP(random, sizeof(random));
-
-    if (!dhinit) {
-        bnBegin(&two);
-        bnSetQ(&two, 2);
-
-        bnBegin(&bnP2048);
-        bnInsertBigBytes(&bnP2048, P2048, 0, sizeof(P2048));
-        bnBegin(&bnP3072);
-        bnInsertBigBytes(&bnP3072, P3072, 0, sizeof(P3072));
-
-        bnBegin(&bnP2048MinusOne);
-        bnCopy(&bnP2048MinusOne, &bnP2048);
-        bnSubQ(&bnP2048MinusOne, 1);
-
-        bnBegin(&bnP3072MinusOne);
-        bnCopy(&bnP3072MinusOne, &bnP3072);
-        bnSubQ(&bnP3072MinusOne, 1);
-
-        dhinit = 1;
-    }
-
-    bnBegin(&tmpCtx->privKey);
-    INIT_EC_POINT(&tmpCtx->pubPoint);
-
-    switch (pkType) {
-    case DH2K:
-    case DH3K:
-        bnInsertBigBytes(&tmpCtx->privKey, random, 0, 256/8);
-        break;
-
-    case EC25:
-        ecGetCurveNistECp(NIST256P, &tmpCtx->curve);
-        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
-        break;
-
-    case EC38:
-        ecGetCurveNistECp(NIST384P, &tmpCtx->curve);
-        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
-        break;
-
-    case E255:
-        ecGetCurvesCurve(Curve25519, &tmpCtx->curve);
-        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
-        break;
-
-    case E414:
-        ecGetCurvesCurve(Curve3617, &tmpCtx->curve);
-        ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
-        break;
-    }
-}
-
-ZrtpDH::~ZrtpDH() {
-    if (ctx == NULL)
-        return;
-
-    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-    FREE_EC_POINT(&tmpCtx->pubPoint);
-    bnEnd(&tmpCtx->privKey);
-
-    switch (pkType) {
-    case DH2K:
-    case DH3K:
-        bnEnd(&tmpCtx->pubKey);
-        break;
-
-    case EC25:
-    case EC38:
-        ecFreeCurveNistECp(&tmpCtx->curve);
-        break;
-
-    case E255:
-    case E414:
-        ecFreeCurvesCurve(&tmpCtx->curve);
-        break;
-    }
-}
-
-int32_t ZrtpDH::computeSecretKey(uint8_t *pubKeyBytes, uint8_t *secret) {
-
-    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
-    int32_t length = getDhSize();
-
-    BigNum sec;
-    if (pkType == DH2K || pkType == DH3K) {
-        BigNum pubKeyOther;
-        bnBegin(&pubKeyOther);
-        bnBegin(&sec);
-
-        bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, length);
-
-        if (pkType == DH2K) {
-            bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP2048);
-        }
-        else if (pkType == DH3K) {
-            bnExpMod(&sec, &pubKeyOther, &tmpCtx->privKey, &bnP3072);
-        }
-        else {
-            return 0;
-        }
-        bnEnd(&pubKeyOther);
-        bnExtractBigBytes(&sec, secret, 0, length);
-        bnEnd(&sec);
-
-        return length;
-    }
-
-    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
-        int32_t len = getPubKeySize() / 2;
-        EcPoint pub;
-
-        bnBegin(&sec);
-        INIT_EC_POINT(&pub);
-        bnSetQ(pub.z, 1);               // initialze Z to one, these are affine coords
-
-        bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
-        bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);
-
-        /* Generate agreement for responder: sec = pub * privKey */
-        ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
-        bnExtractBigBytes(&sec, secret, 0, length);
-        bnEnd(&sec);
-        FREE_EC_POINT(&pub);
-
-        return length;
-    }
-    if (pkType == E255) {
-        int32_t len = getPubKeySize();
-        EcPoint pub;
-
-        bnBegin(&sec);
-        INIT_EC_POINT(&pub);
-
-        bnInsertLittleBytes(pub.x, pubKeyBytes, 0, len);
-
-        /* Generate agreement for responder: sec = pub * privKey */
-        ecdhComputeAgreement(&tmpCtx->curve, &sec, &pub, &tmpCtx->privKey);
-        bnExtractLittleBytes(&sec, secret, 0, length);
-        bnEnd(&sec);
-        FREE_EC_POINT(&pub);
-
-        return length;
-    }
-    return -1;
-}
-
-int32_t ZrtpDH::generatePublicKey()
-{
-    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
-    bnBegin(&tmpCtx->pubKey);
-    switch (pkType) {
-    case DH2K:
-        bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP2048);
-        break;
-
-    case DH3K:
-        bnExpMod(&tmpCtx->pubKey, &two, &tmpCtx->privKey, &bnP3072);
-        break;
-
-    case EC25:
-    case EC38:
-    case E255:
-    case E414:
-        while (!ecdhGeneratePublic(&tmpCtx->curve, &tmpCtx->pubPoint, &tmpCtx->privKey))
-            ecGenerateRandomNumber(&tmpCtx->curve, &tmpCtx->privKey);
-    }
-    return 0;
-}
-
-int32_t ZrtpDH::getDhSize() const
-{
-    switch (pkType) {
-    case DH2K:
-        return 2048/8;
-        break;
-    case DH3K:
-        return 3072/8;
-        break;
-
-    case EC25:
-        return 32;
-        break;
-    case EC38:
-        return 48;
-        break;
-
-    case E255:
-        return 32;
-        break;
-    case E414:
-        return 52;
-        break;
-    }
-    return 0;
-}
-
-int32_t ZrtpDH::getPubKeySize() const
-{
-    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-    if (pkType == DH2K || pkType == DH3K)
-        return bnBytes(&tmpCtx->pubKey);
-
-    if (pkType == EC25 || pkType == EC38 || pkType == E414)
-        return bnBytes(tmpCtx->curve.p) * 2;   // *2 -> x and y coordinate
-
-    if (pkType == E255)
-        return bnBytes(tmpCtx->curve.p);
-    return 0;
-
-}
-
-int32_t ZrtpDH::getPubKeyBytes(uint8_t *buf) const
-{
-    dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-
-    if (pkType == DH2K || pkType == DH3K) {
-        // get len of pub_key, prepend with zeros to DH size
-        int size = getPubKeySize();
-        int32_t prepend = getDhSize() - size;
-        if (prepend > 0) {
-            memset(buf, 0, prepend);
-        }
-        bnExtractBigBytes(&tmpCtx->pubKey, buf + prepend, 0, size);
-        return size;
-    }
-
-    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
-        int32_t len = getPubKeySize() / 2;
-
-        bnExtractBigBytes(tmpCtx->pubPoint.x, buf, 0, len);
-        bnExtractBigBytes(tmpCtx->pubPoint.y, buf+len, 0, len);
-        return len * 2;
-    }
-    if (pkType == E255) {
-        int32_t len = getPubKeySize();
-        bnExtractLittleBytes(tmpCtx->pubPoint.x, buf, 0, len);
-        return len;
-    }
-    return 0;
-}
-
-int32_t ZrtpDH::checkPubKey(uint8_t *pubKeyBytes) const
-{
-
-    /* ECC validation (partial), NIST SP800-56A, section 5.6.2.6 */
-    if (pkType == EC25 || pkType == EC38 || pkType == E414) {
-
-        dhCtx* tmpCtx = static_cast<dhCtx*>(ctx);
-        EcPoint pub;
-
-        INIT_EC_POINT(&pub);
-        int32_t len = getPubKeySize() / 2;
-
-        bnInsertBigBytes(pub.x, pubKeyBytes, 0, len);
-        bnInsertBigBytes(pub.y, pubKeyBytes+len, 0, len);
-
-        return ecCheckPubKey(&tmpCtx->curve, &pub);
-    }
-
-    if (pkType == E255) {
-        return 1;
-    }
-
-    BigNum pubKeyOther;
-    bnBegin(&pubKeyOther);
-    bnInsertBigBytes(&pubKeyOther, pubKeyBytes, 0, getDhSize());
-
-    if (pkType == DH2K) {
-        if (bnCmp(&bnP2048MinusOne, &pubKeyOther) == 0) {
-            return 0;
-        }
-    }
-    else if (pkType == DH3K) {
-        if (bnCmp(&bnP3072MinusOne, &pubKeyOther) == 0) {
-            return 0;
-
-        }
-    }
-    else {
-        return 0;
-    }
-    if (bnCmpQ(&pubKeyOther, 1) == 0) {
-        return 0;
-    }
-
-    bnEnd(&pubKeyOther);
-    return 1;
-}
-
-const char* ZrtpDH::getDHtype()
-{
-    switch (pkType) {
-    case DH2K:
-        return dh2k;
-    case DH3K:
-        return dh3k;
-    case EC25:
-        return ec25;
-    case EC38:
-        return ec38;
-    case E255:
-        return e255;
-    case E414:
-        return e414;
-    }
-    return NULL;
-}
-
-/** EMACS **
- * Local variables:
- * mode: c++
- * c-default-style: ellemtel
- * c-basic-offset: 4
- * End:
- */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
deleted file mode 100644
index 2ba1de6..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCache.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <string>
-
-#include "ZIDRecord.h"
-
-#ifndef _ZIDCACHE_H_
-#define _ZIDCACHE_H_
-
-/**
- * @file ZIDCache.h
- * @brief ZID cache management
- *
- * A ZID file stores (caches) some data that helps ZRTP to achives its
- * key continuity feature. See @c ZIDRecord for further info which data
- * the ZID file contains.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * Interface for classes that implements a ZID (ZRTP Identifiers) file.
- *
- * The ZID file holds information about peers.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-class ZIDCache;
-
-__EXPORT ZIDCache* getZidCacheInstance();
-
-
-class __EXPORT ZIDCache {
-
-public:
-
-    /**
-     * @brief Destructor.
-     * Define a virtual destructor to enable cleanup in derived classes.
-     */
-    virtual ~ZIDCache() {};
-
-    /**
-     * @brief Open the named ZID file and return a ZID file class.
-     *
-     * This static function either opens an existing ZID file or
-     * creates a new ZID file with the given name. The ZIDCache is a
-     * singleton, thus only <em>one</em> ZID file can be open at one
-     * time.
-     *
-     * To open another ZID file you must close the active ZID file
-     * first.
-     *
-     * @param name
-     *    The name of the ZID file to open or create
-     * @return
-     *    1 if file could be opened/created, 0 if the ZID instance
-     *    already has an open file, -1 if open/creation of file failed.
-     */
-    virtual int open(char *name) =0;
-
-    /**
-     * @brief Check if ZIDCache has an active (open) file.
-     *
-     * @return
-     *    True if ZIDCache has an active file, false otherwise
-     */
-    virtual bool isOpen() =0;
-
-     /**
-      * @brief Close the ZID file.
-      *
-      * Closes the ZID file, and prepares to open a new ZID file.
-      */
-    virtual void close() =0;
-
-    /**
-     * @brief Get a ZID record from ZID cache or create a new record.
-     *
-     * The method tries to read a ZRTP cache record for the ZID.
-     * If no matching record exists in the cache the method creates
-     * it and fills it with default values.
-     *
-     * @param zid is the ZRTP id of the peer
-     * @return pointer to the ZID record. The call must @c delete the
-     *         record if it is not longer used.
-     */
-    virtual ZIDRecord *getRecord(unsigned char *zid) =0;
-
-    /**
-     * @brief Save a ZID record into the active ZID file.
-     *
-     * This method saves the content of a ZID record into the ZID file. Before
-     * you can save the ZID record you must have performed a getRecord()
-     * first.
-     *
-     * @param zidRecord
-     *    The ZID record to save.
-     * @return
-     *    1 on success
-     */
-    virtual unsigned int saveRecord(ZIDRecord *zidRecord) =0;
-
-    /**
-     * @brief Get the ZID associated with this ZID file.
-     *
-     * @return
-     *    Pointer to the ZID
-     */
-    virtual const unsigned char* getZid() =0;
-
-    /**
-     * @brief Get peer name from database
-     *
-     * This is an optional function.
-     *
-     * A client may use this function to retrieve a name that was assigned
-     * to the peer's ZID.
-     *
-     * @param peerZid the peer's ZID
-     *
-     * @param name string that will get the peer's name. The returned name will
-     *             be truncated to 200 bytes
-     *
-     * @return length og the name read or 0 if no name was previously stored.
-     */
-    virtual int32_t getPeerName(const uint8_t *peerZid, std::string *name) =0;
-
-    /**
-     * @brief Write peer name to database
-     *
-     * This is an optional function.
-     *
-     * A client may use this function to write a name in the ZRTP cache database and
-     * asign it to the peer's ZID.
-     *
-     * @param peerZid the peer's ZID
-     *
-     * @param name the name string
-     *
-     */
-    virtual void putPeerName(const uint8_t *peerZid, const std::string name) =0;
-
-    /**
-     * @brief Clean the cache.
-     *
-     * The function drops and re-creates all tables in the database. This removes all stored
-     * data. The application must not call this while a ZRTP call is active. Also the application
-     * <b>must</b> get the local ZID again.
-     *
-     */
-    virtual void cleanup() =0;
-};
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
deleted file mode 100644
index 7aa6dd0..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheDb.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-
-#include <libzrtpcpp/ZIDCache.h>
-#include <libzrtpcpp/ZIDRecordDb.h>
-#include <libzrtpcpp/zrtpCacheDbBackend.h>
-
-#ifndef _ZIDCACHEDB_H_
-#define _ZIDCACHEDB_H_
-
-
-/**
- * @file ZIDCacheDb.h
- * @brief ZID cache management
- *
- * A ZID file stores (caches) some data that helps ZRTP to achives its
- * key continuity feature. See @c ZIDRecordDb for further info which data
- * the ZID file contains.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * This class implements a ZID (ZRTP Identifiers) file.
- *
- * The interface defintion @c ZIDCache.h contains the method documentation.
- * The ZID cache file holds information about peers.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-class __EXPORT ZIDCacheDb: public ZIDCache {
-
-private:
-
-    void *zidFile;
-    unsigned char associatedZid[IDENTIFIER_LEN];
-
-    dbCacheOps_t cacheOps;
-
-    char errorBuffer[DB_CACHE_ERR_BUFF_SIZE];
-
-    void createZIDFile(char* name);
-
-public:
-
-    ZIDCacheDb(): zidFile(NULL) {
-        getDbCacheOps(&cacheOps);
-    };
-
-    ~ZIDCacheDb();
-
-    int open(char *name);
-
-    bool isOpen() { return (zidFile != NULL); };
-
-    void close();
-
-    ZIDRecord *getRecord(unsigned char *zid);
-
-    unsigned int saveRecord(ZIDRecord *zidRecord);
-
-    const unsigned char* getZid() { return associatedZid; };
-
-    int32_t getPeerName(const uint8_t *peerZid, std::string *name);
-
-    void putPeerName(const uint8_t *peerZid, const std::string name);
-
-    void cleanup();
-
-};
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
deleted file mode 100644
index 7b264e8..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDCacheFile.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <stdio.h>
-
-#include <libzrtpcpp/ZIDCache.h>
-#include <libzrtpcpp/ZIDRecordFile.h>
-
-#ifndef _ZIDCACHEFILE_H_
-#define _ZIDCACHEFILE_H_
-
-
-/**
- * @file ZIDCacheFile.h
- * @brief ZID cache management
- *
- * A ZID file stores (caches) some data that helps ZRTP to achives its
- * key continuity feature. See @c ZIDRecord for further info which data
- * the ZID file contains.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * This class implements a ZID (ZRTP Identifiers) file.
- *
- * The interface defintion @c ZIDCache.h contains the method documentation.
- * The ZID cache file holds information about peers.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-class __EXPORT ZIDCacheFile: public ZIDCache {
-
-private:
-
-    FILE* zidFile;
-    unsigned char associatedZid[IDENTIFIER_LEN];
-
-    void createZIDFile(char* name);
-    void checkDoMigration(char* name);
-
-public:
-
-    ZIDCacheFile(): zidFile(NULL) {};
-
-    ~ZIDCacheFile();
-
-    int open(char *name);
-
-    bool isOpen() { return (zidFile != NULL); };
-
-    void close();
-
-    ZIDRecord *getRecord(unsigned char *zid);
-
-    unsigned int saveRecord(ZIDRecord *zidRecord);
-
-    const unsigned char* getZid() { return associatedZid; };
-
-    int32_t getPeerName(const uint8_t *peerZid, std::string *name);
-
-    void putPeerName(const uint8_t *peerZid, const std::string name);
-
-    // Not implemented for file base cache
-    void cleanup() {};
-};
-
-/**
- * @}
- */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
deleted file mode 100644
index c46fc24..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecord.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZIDRECORD_H_
-#define _ZIDRECORD_H_
-
-#include <stdint.h>
-#include <common/osSpecifics.h>
-/**
- * @file ZIDRecord.h
- * @brief ZID cache record management
- *
- * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP
- * to achives its key continuity feature. Please refer to the ZRTP
- * specification to get detailed information about the ZID.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-/**
- * These length are fixed for ZRTP. See RFC 6189.
- */
-#define IDENTIFIER_LEN  12
-#define RS_LENGTH       32
-
-#if defined(__cplusplus)
-/**
- * Interface for classes that implement a ZID cache record.
- *
- * The ZID cache record holds data about a peer. According to ZRTP specification
- * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data
- * to construct shared secrets.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-class __EXPORT ZIDRecord {
-
-public:
-    /**
-     * @brief Destructor.
-     * Define a virtual destructor to enable cleanup in derived classes.
-     */
-    virtual ~ZIDRecord() {};
-
-    /**
-     * Set the @c ZID in the record.
-     *
-     * Set the ZID in this record before calling read or save.
-     */
-    virtual void setZid(const unsigned char *zid) =0;
-
-    /**
-     * Set @c valid flag in RS1
-     */
-    virtual void setRs1Valid() =0;
-
-    /**
-     * reset @c valid flag in RS1
-     */
-    virtual void resetRs1Valid()  =0;
-
-    /**
-     * Check @c valid flag in RS1
-     */
-    virtual bool isRs1Valid() =0;
-
-    /**
-     * Set @c valid flag in RS2
-     */
-    virtual void setRs2Valid() =0;
-
-    /**
-     * Reset @c valid flag in RS2
-     */
-    virtual void resetRs2Valid() =0;
-
-    /**
-     * Check @c valid flag in RS2
-     */
-    virtual bool isRs2Valid() =0;
-
-    /**
-     * Set MITM key available
-     */
-    virtual void setMITMKeyAvailable() =0;
-
-    /**
-     * Reset MITM key available
-     */
-    virtual void resetMITMKeyAvailable() =0;
-
-    /**
-     * Check MITM key available is set
-     */
-    virtual bool isMITMKeyAvailable() =0;
-
-    /**
-     * Mark this as own ZID record
-     */
-    virtual void setOwnZIDRecord() =0;
-
-    /**
-     * Reset own ZID record marker
-     */
-    virtual void resetOwnZIDRecord() =0;
-
-    /**
-     * Check own ZID record marker
-     */
-    virtual bool isOwnZIDRecord() =0;
-
-    /**
-     * Set SAS for this ZID as verified
-     */
-    virtual void setSasVerified() =0;
-
-    /**
-     * Reset SAS for this ZID as verified
-     */
-    virtual void resetSasVerified() =0;
-
-    /**
-     * Check if SAS for this ZID was verified
-     */
-    virtual bool isSasVerified() =0;
-
-    /**
-     * Return the ZID for this record
-     */
-    virtual const uint8_t* getIdentifier() =0;
-
-    /**
-     * Check if RS1 is still valid
-     *
-     * Returns true if RS1 is still valid, false otherwise.
-     *
-     * @return
-     *    Returns true is RS1 is not expired (valid), false otherwise.
-     */
-    virtual bool isRs1NotExpired() =0;
-
-    /**
-     * Returns pointer to RS1 data.
-     */
-    virtual const unsigned char* getRs1() =0;
-
-    /**
-     * Check if RS2 is still valid
-     *
-     * Returns true if RS2 is still valid, false otherwise.
-     *
-     * @return
-     *    Returns true is RS2 is not expired (valid), false otherwise.
-     */
-    virtual bool isRs2NotExpired() =0;
-
-    /**
-     * Returns pointer to RS1 data.
-     */
-    virtual const unsigned char* getRs2() =0;
-
-    /**
-     * Sets new RS1 data and associated expiration value.
-     *
-     * If the expiration value is >0 or -1 the method stores the new
-     * RS1. Before it stores the new RS1 it shifts the exiting RS1
-     * into RS2 (together with its expiration time). Then it computes
-     * the expiration time of the and stores the result together with
-     * the new RS1.
-     *
-     * If the expiration value is -1 then this RS will never expire.
-     *
-     * If the expiration value is 0 then the expiration value of a
-     * stored RS1 is cleared and no new RS1 value is stored. Also RS2
-     * is left unchanged.
-     *
-     * @param data
-     *    Points to the new RS1 data.
-     * @param expire
-     *    The expiration interval in seconds. Default is -1.
-     *
-     */
-    virtual void setNewRs1(const unsigned char* data, int32_t expire =-1) =0;
-
-    /**
-     * Set MiTM key data.
-     *
-     */
-    virtual void setMiTMData(const unsigned char* data) =0;
-
-    /**
-     * Get MiTM key data.
-     *
-     */
-    virtual const unsigned char* getMiTMData() =0;
-};
-#endif /* (__cplusplus) */
-#endif
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
deleted file mode 100644
index 111b4ed..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZIDRecordDb.h
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZIDRECORDDB_H_
-#define _ZIDRECORDDB_H_
-
-
-/**
- * @file ZIDRecordDb.h
- * @brief ZID cache record management
- *
- * A ZID record stores (caches) ZID (ZRTP ID) specific data that helps ZRTP
- * to achives its key continuity feature. Please refer to the ZRTP
- * specification to get detailed information about the ZID.
- *
- * @ingroup GNU_ZRTP
- * @{
- */
-
-#include <string.h>
-#include <stdint.h>
-#include <libzrtpcpp/ZIDRecord.h>
-
-#define TIME_LENGTH      8      // 64 bit, can hold time on 64 bit systems
-
-/**
- * Internal structure that holds the non-key data of a remote ZID record.
- *
- * The data storage backends use this structure to get or to fill in data
- * to store in or that was read from the data store.
- *
- * Some notes regarding the timestamps: the structure uses 64 bit variables to
- * store a timestamp. The relevant SQL SELECT / UPDATE / INSERT statements and
- * the relevant must take care of this.
- *
- * The methods shall use the standard C time() call to get the current time in
- * seconds since Unix epoch (see time() documentation).
- */
-typedef struct {
-    uint8_t   identifier[IDENTIFIER_LEN]; /* < the peer's ZID or own ZID */
-    uint32_t  flags;
-    uint8_t   rs1[RS_LENGTH];
-    int64_t   rs1LastUse;
-    int64_t   rs1Ttl;
-    uint8_t   rs2[RS_LENGTH];
-    int64_t   rs2LastUse;
-    int64_t   rs2Ttl;
-    uint8_t   mitmKey[RS_LENGTH];
-    int64_t   mitmLastUse;
-    int64_t   secureSince;
-    uint32_t  preshCounter;
-} remoteZidRecord_t;
-
-/*
- * The flag field stores the following bitflags
- */
-static const uint32_t Valid            = 0x1;
-static const uint32_t SASVerified      = 0x2;
-static const uint32_t RS1Valid         = 0x4;
-static const uint32_t RS2Valid         = 0x8;
-static const uint32_t MITMKeyAvailable = 0x10;
-static const uint32_t inUse            = 0x20;
-
-/**
- * Internal structure that holds the non-key data of a ZID name record.
- *
- * The flags field currently just uses the @c Valid bit.
- *
- * See comment on @c remoteZidRecord_t above.
- */
-typedef struct {
-    uint32_t   flags;
-    char       *name;
-    int32_t    nameLength;
-} zidNameRecord_t;
-
-#if defined(__cplusplus)
-/**
- * This class implements the ZID record.
- *
- * The ZID record holds data about a peer. According to ZRTP specification
- * we use a ZID to identify a peer. ZRTP uses the RS (Retained Secret) data
- * to construct shared secrets.
- * <p>
- * NOTE: ZIDRecordDb has ZIDCacheDb as friend. ZIDCacheDb knows about the private
- *   data of ZIDRecord - please keep both classes synchronized.
- *
- * @author: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-class __EXPORT ZIDRecordDb: public ZIDRecord {
-    friend class ZIDCacheDb;
-
-private:
-    remoteZidRecord_t record;
-
-    remoteZidRecord_t* getRecordData() {return &record; }
-    int getRecordLength()              {return sizeof(remoteZidRecord_t); }
-
-    bool isValid()    { return ((record.flags & Valid) == Valid); }
-    void setValid()   { record.flags |= Valid; }
-
-public:
-    /*
-     * @brief The default constructor,
-     */
-    ZIDRecordDb() {
-        memset(&record, 0, sizeof(remoteZidRecord_t));
-    }
-
-    /**
-     * Set the @c ZID in the record.
-     *
-     * Set the ZID in this record before calling read or save.
-     */
-    void setZid(const unsigned char *zid) {
-        memcpy(record.identifier, zid, IDENTIFIER_LEN);
-    }
-
-    /**
-     * Set @c valid flag in RS1
-     */
-    void setRs1Valid()   { record.flags |= RS1Valid; }
-
-    /**
-     * reset @c valid flag in RS1
-     */
-    void resetRs1Valid() { record.flags &= ~RS1Valid; }
-
-    /**
-     * Check @c valid flag in RS1
-     */
-    bool isRs1Valid()    { return ((record.flags & RS1Valid) == RS1Valid); }
-
-    /**
-     * Set @c valid flag in RS2
-     */
-    void setRs2Valid()   { record.flags |= RS2Valid; }
-
-    /**
-     * Reset @c valid flag in RS2
-     */
-    void resetRs2Valid() { record.flags &= ~RS2Valid; }
-
-    /**
-     * Check @c valid flag in RS2
-     */
-    bool isRs2Valid()    { return ((record.flags & RS2Valid) == RS2Valid); }
-
-    /**
-     * Set MITM key available
-     */
-    void setMITMKeyAvailable()    { record.flags |= MITMKeyAvailable; }
-
-    /**
-     * Reset MITM key available
-     */
-    void resetMITMKeyAvailable()  { record.flags &= ~MITMKeyAvailable; }
-
-    /**
-     * Check MITM key available is set
-     */
-    bool isMITMKeyAvailable()     { return ((record.flags & MITMKeyAvailable) == MITMKeyAvailable); }
-
-    /**
-     * Mark this as own ZID record - not used in this DB cache backend
-     */
-    void setOwnZIDRecord()  {}
-    /**
-     * Reset own ZID record marker
-     */
-    void resetOwnZIDRecord(){}
-
-    /**
-     * Check own ZID record marker
-     */
-    bool isOwnZIDRecord()   { return false; }  // in this DB cahe implementation a record is always 'remote'
-
-    /**
-     * Set SAS for this ZID as verified
-     */
-    void setSasVerified()   { record.flags |= SASVerified; }
-    /**
-     * Reset SAS for this ZID as verified
-     */
-    void resetSasVerified() { record.flags &= ~SASVerified; }
-
-    /**
-     * Check if SAS for this ZID was verified
-     */
-    bool isSasVerified()    { return ((record.flags & SASVerified) == SASVerified); }
-
-    /**
-     * Return the ZID for this record
-     */
-    const uint8_t* getIdentifier() {return record.identifier; }
-
-    /**
-     * Check if RS1 is still valid
-     *
-     * Returns true if RS1 is still valid, false otherwise.
-     *
-     * @return
-     *    Returns true is RS1 is not expired (valid), false otherwise.
-     */
-    bool isRs1NotExpired();
-
-    /**
-     * Returns pointer to RS1 data.
-     */
-    const unsigned char* getRs1() { return record.rs1; }
-
-    /**
-     * Check if RS2 is still valid
-     *
-     * Returns true if RS2 is still valid, false otherwise.
-     *
-     * @return
-     *    Returns true is RS2 is not expired (valid), false otherwise.
-     */
-    bool isRs2NotExpired();
-
-    /**
-     * Returns pointer to RS1 data.
-     */
-    const unsigned char* getRs2() { return record.rs2; }
-
-    /**
-     * Sets new RS1 data and associated expiration value.
-     *
-     * If the expiration value is >0 or -1 the method stores the new
-     * RS1. Before it stores the new RS1 it shifts the exiting RS1
-     * into RS2 (together with its expiration time). Then it computes
-     * the expiration time of the and stores the result together with
-     * the new RS1.
-     *
-     * If the expiration value is -1 then this RS will never expire.
-     *
-     * If the expiration value is 0 then the expiration value of a
-     * stored RS1 is cleared and no new RS1 value is stored. Also RS2
-     * is left unchanged.
-     *
-     * @param data
-     *    Points to the new RS1 data.
-     * @param expire
-     *    The expiration interval in seconds. Default is -1.
-     *
-     */
-    void setNewRs1(const unsigned char* data, int32_t expire =-1);
-
-    /**
-     * Set MiTM key data.
-     *
-     */
-    void setMiTMData(const unsigned char* data);
-
-    /**
-     * Get MiTM key data.
-     *
-     */
-    const unsigned char* getMiTMData() {return record.mitmKey; }
-};
-#endif /* (__cplusplus) */
-
-#endif
-
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
deleted file mode 100644
index d7d2265..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/ZrtpSdesStream.h
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
-  Copyright (C) 2012-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZRTPSDESSTREAM_H_
-#define _ZRTPSDESSTREAM_H_
-/**
- * @file ZrtpSdesStream.h
- * @brief The ZRTP main engine
- * @defgroup GNU_ZRTP The GNU ZRTP C++ implementation
- * @{
- *
- * This class implements SDES and provides a simple to use API for applications.
- *
- * This SDES implementation currently supports only two SDES algorithms and it does
- * not support optional parameters such as lifetime or MKI parameters. Also session
- * parameters are not supported. Most applications that use SDES don't use these
- * optional parameters.
- *
- * It is not necessary to explicitly start the SDES stream. The class initiates
- * the SRTP after it created and parsed all necessary SDES crypto strings.
- *
- * Because SDES works together with the signaling protocol, for example SIP, it is
- * important to adhere to a defined flow. The following pseudo code snippet depicts
- * such a flow. Applications shall follow this flow.
- *
- *<pre>
- *
- *     Inviter                           Answerer
- *    (Offerer)
- *
- * ZrtpSdesStream inv;                 ZrtpSdesStream answ;
- *
- * // create/get own SDES data
- * inv.createSdes(...);
- * inv.getCryptoMixAttribute(...)
- *
- * // prepare SIP/SDP offer, send
- * // it to answerer
- *                                    // receive SIP/SDP, get
- *                                    // SDES data, parse/set it
- *                                    answ.setCryptoMixAttribute(...)
- *                                    answ.parseSdes(...)
- *
- *                                    // create/get own SDES data
- *                                    answ.getCryptoMixAttribute(...)
- *                                    answ.createSdes(...)
- *
- *                                    // prepare SIP/SDP answer,
- *                                    // send to offerer
- * // receive SIP/SDP answer, get
- * // SDES data, parse, set mix algo
- * // if availabe
- * inv.setCryptoMixAttribute(...)
- * inv.parseSdes(...)
- *
- * ...                                ...
- *
- * inv.outgoingRtp(...)
- *                                    answ.incomingRtp(...)
- *
- *                                    answ.outgoingRtp(...)
- * inv.incomingRtp(...)
- *</pre>
- *
- * To use SDES without the new crypto mix feature just do not use the crypto mix functions.
- * An application may always send crypto mix attributes. If the answerer does not support this
- * feature it does not send back a selected algorithm and the offerer cannot set an algorithm.
- * Thus the crypto mix feature is not used.
- * 
- * @author Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <common/osSpecifics.h>
-
-class CryptoContext;
-class CryptoContextCtrl;
-
-/*
- * These functions support 256 bit encryption algorithms.
- */
-#define MAX_KEY_LEN           32
-#define MAX_SALT_LEN          14
-#define MAX_DIGEST_LENGTH     64
-
-/**
- * Maximum length of a raw crypto string.
- */
-#define MAX_CRYPT_STRING_LEN 200
-
-class __EXPORT ZrtpSdesStream {
-
-public:
-
-    /**
-     * Supported SDES crypto suites.
-     */
-    typedef enum {
-        AES_CM_128_HMAC_SHA1_32 = 0,
-        AES_CM_128_HMAC_SHA1_80
-    } sdesSuites;
-
-    /**
-     * SDES stream state
-     */
-    typedef enum {
-        STREAM_INITALIZED = 1,
-        OUT_PROFILE_READY,
-        IN_PROFILE_READY,
-        SDES_SRTP_ACTIVE
-    } sdesZrtpStates;
-
-    typedef enum {
-        MIX_NONE = 0,
-        MIX_HMAC_SHA,
-        MIX_MAC_SKEIN
-    } sdesHmacTypeMix;
-
-    /**
-     * @brief Create and SDES/ZRTP stream.
-     *
-     * This method creates an SDES stream with capabilities to handle RTP,
-     * RTCP, SRTP, and SRTCP packets.
-     *
-     * @param suite defines which crypto suite to use for this stream. The values are
-     *              @c AES_CM_128_HMAC_SHA1_80 or @c AES_CM_128_HMAC_SHA1_32.
-     */
-    ZrtpSdesStream(const sdesSuites suite =AES_CM_128_HMAC_SHA1_32);
-
-    ~ZrtpSdesStream();
-
-    /**
-     * @brief Close an SDES/ZRTP stream.
-     *
-     * Close the stream and return allocated memory to the pool.
-     */
-    void close();
-
-    /**
-     * @brief Creates an SDES crypto string for the SDES/ZRTP stream.
-     *
-     * Creates the crypto string that the application can use in the SDP fields of
-     * SIP INVITE or SIP 200 OK.
-     *
-     * An INVITE-ing application shall call this function at the same point when
-     * it calls the functions to get the @c zrtp-hash string and shall insert the
-     * created crypto string into the SDP.
-     *
-     * An answering application shall call this function directly @b after it called
-     * @c sdesZrtpStreamParseSdes. This usually at the same point when it gets the
-     * @c zrtp-hash from the SDP parameters and forwards it to @c libzrtp. The
-     * answering application's SRTP environment is now ready.
-     *
-     * @param cryptoString output buffer that receives the crypto  string in raw
-     *                     format, without the any signaling prefix, for example
-     *                     @c a=crypto:. The function terminates the crypto string
-     *                     with a @c nul byte
-     *
-     * @param maxLen length of the crypto string buffer. On return it contains the
-     *               actual length of the crypto string.
-     *
-     * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must
-     *                  set it to @c false.
-     *
-     * @return @c true if data could be created, @c false otherwise.
-     */
-    bool createSdes(char *cryptoString, size_t *maxLen, bool sipInvite);
-
-    /**
-     * @brief Parses an SDES crypto string for the SDES/ZRTP stream.
-     *
-     * Parses a SDES crypto string that the application received in a SIP INVITE
-     * or SIP 200 OK.
-     *
-     * An INVITE-ing (offerer) application shall call this function right after it received
-     * the 200 OK from the answering application and must call this function with the
-     * @c sipInvite parameter set to @c true. The offerer's SRTP is now ready for use.
-     *
-     * The answering application calls this function after it received the INVITE and
-     * extracted the crypto string from the SDP and must call this function with the
-     * @c sipInvite parameter set to @c false.
-     *
-     * @param cryptoString the received crypto sting in raw format,
-     *                     without any signaling prefix, for example @c a=crypto:
-     *
-     * @param length length of the crypto string to parse. If the length is
-     *               @c zero then the function uses @c strlen to compute
-     *               the length.
-     *
-     * @param sipInvite the inviter (offerer) must set this to @c true, the answerer must
-     *                  set it to @c false.
-     *
-     * @return @c true if data could be created, @c false otherwise.
-     */
-    bool parseSdes(const char *cryptoString, size_t length, bool sipInvite);
-
-    /**
-     * @brief Get Crypto Mix attribute string
-     *
-     * The offerer calls this method to get a string of @b all supported crypto mix algorithms
-     * and shall send this list to the answerer.
-     *
-     * The answerer calls this function only @b after it received the crypto mix string and @b after
-     * calling @c setCryptoMixAttribute(...). The method returns only one (the selected)
-     * crypto mix algorithm and the answerer must send this to the offerer, for example in 200 OK.
-     *
-     * @param algoNames buffer to store the nul terminated crypto mix algorithm names.
-     *                  The buffer must be long enough to hold at least the name of the mandatory
-     *                  algorithm HMAC-SHA-384.
-     *
-     * @param length length of buffer
-     *
-     * @return Length of algorithm names (excluding nul byte) or zero if crypto mix not supported or
-     *         enabled.
-     */
-    int getCryptoMixAttribute(char *algoNames, size_t length);
-
-    /**
-     * @brief Set Crypto Mix attribute string
-     *
-     * The method checks if it the string contains an supported algorithm and selects one algorithm.
-     *
-     * The offerer calls this method @b after it received the selected algorithm in the answer.
-     *
-     * The answerer must call this method @b before it calls the @c getCryptoMixAttribute() method.
-     *
-     * @param algoNames buffer that contains the received crypto mix algorithm names.
-     *                  The buffer must be nul terminated.
-     *
-     * @return @c false if none of the offered algorithms is supported.
-     */
-    bool setCryptoMixAttribute(const char *algoNames);
-
-    /*
-     * ******** Outgoing RTP/RTCP packet handling
-     */
-    /**
-     * @brief Process an outgoing RTP packet
-     *
-     * This function processes an outgoing RTP packet. Depending on the state
-     * the packet is either:
-     *  - not encrypted if neither SDES nor ZRTP are active or supported by the
-     *    other client. This is the standard case if the stream was just initialized.
-     *  - encrypted with SDES provided key data. This is the case if the application
-     *    called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes
-     *    functions to properly setup the SDES key data.
-     *
-     * @param packet the buffer that contains the RTP packet. After processing, the
-     *               encrypted packet is stored in the same buffer. The buffer must
-     *               big enough to hold the additional SRTP data, depending on the
-     *               SRTP profile these are usually 4 - 20 bytes.
-     *
-     * @param length length of the RTP packet
-     *
-     * @param newLength to an integer that get the new length of the packet including SRTP data.
-     *
-     * @return
-     *  - @c true if encryption is successful, app shall send packet to the recipient.
-     *  - @c false if there was an error during encryption, don't send the packet.
-     */
-    bool outgoingRtp(uint8_t *packet, size_t length, size_t *newLength);
-
-    /**
-     * @brief Process an outgoing RTCP packet
-     *
-     * This function works in the same way as @c outgoingRtp.
-     *
-     * @param packet the buffer that contains the RTCP packet. After processing, the
-     *               encrypted packet is stored in the same buffer. The buffer must
-     *               big enough to hold the additional SRTP data, depending on the
-     *               SRTP profile these are usually 8 - 20 bytes.
-     *
-     * @param length length of the RTP packet
-     *
-     * @param newLength to an integer that get the new length of the packet including SRTP data.
-     *
-     * @return
-     *  - @c true if encryption is successful, app shall send packet to the recipient.
-     *  - @c false if there was an error during encryption, don't send the packet.
-     */
-    bool outgoingRtcp(uint8_t *packet, size_t length, size_t *newLength);
-
-    /*
-     * ******** Incoming SRTP/SRTCP packet handling
-     */
-    /**
-     * @brief Process an incoming RTP or SRTP packet
-     *
-     * This function processes an incoming RTP/SRTP packet. Depending on the state
-     * the packet is either:
-     *  - not decrypted if SDES is not active or supported by the
-     *    other client. This is the standard case if the stream was just initialized.
-     *  - decrypted with SDES provided key data. This is the case if the application
-     *    called both @c sdesZrtpStreamCreateSdes and @c sdesZrtpStreamParseSdes
-     *    functions to properly setup the SDES key data.
-     *
-     * @param packet the buffer that contains the RTP/SRTP packet. After processing,
-     *               the decrypted packet is stored in the same buffer.
-     *
-     * @param length length of the RTP packet
-     *
-     * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
-     *
-     * @return
-     *       - 1: success,
-     *       - -1: SRTP authentication failed,
-     *       - -2: SRTP replay check failed
-     */
-    int incomingRtp(uint8_t *packet, size_t length, size_t *newLength);
-
-    /**
-     * @brief Process an incoming RTCP or SRTCP packet
-     *
-     * This function works in the same way as @c incomingRtp.
-     *
-     * @param packet the buffer that contains the RTCP/SRTCP packet. After processing,
-     *               the decrypted packet is stored in the same buffer.
-     *
-     * @param length length of the RTCP packet
-     *
-     * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
-     *
-     * @return
-     *       - 1: success,
-     *       - -1: SRTCP authentication failed,
-     *       - -2: SRTCP replay check failed
-     */
-    int incomingSrtcp(uint8_t *packet, size_t length, size_t *newLength);
-
-    /**
-     * @brief Process an outgoing ZRTP packet.
-     * 
-     * Works like @c outgoingRtp, refer to that documentation.
-     * 
-     * @param packet the buffer that contains the ZRTP packet.
-     *
-     * @param length length of the ZRTP packet
-     *
-     * @param newLength to an integer that get the new length of the packet including SRTP data.
-     *
-     * @return
-     *  - @c true if encryption is successful, app shall send packet to the recipient.
-     *  - @c false if there was an error during encryption, don't send the packet.
-     */
-    bool outgoingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength);
-
-    /**
-     * @brief Process an incoming ZRTP packet
-     *
-     * Works like @c incomingRtp, refer to that documentation.
-     *
-     * @param packet the buffer that contains the ZRTP/SRTP packet. After processing,
-     *               the decrypted packet is stored in the same buffer.
-     *
-     * @param length length of the RTP packet
-     *
-     * @param newLength to an integer that get the new length of the packet excluding SRTCP data.
-     *
-     * @return
-     *       - 1: success,
-     *       - -1: SRTP authentication failed,
-     *       - -2: SRTP replay check failed
-     */
-    int incomingZrtpTunnel(uint8_t *packet, size_t length, size_t *newLength);
-
-        /**
-     * @brief Return state of SDES stream.
-     *
-     * @return state of stream.
-     */
-    sdesZrtpStates getState() {return state;}
-
-    /**
-     * @brief Return SDES crypto mixer HMAC type.
-     *
-     * @return HMAC type
-     */
-    sdesHmacTypeMix getHmacTypeMix() {return cryptoMixHashType;}
-
-    /**
-     * @brief Return name of active cipher algorithm.
-     *
-     * @return point to name of cipher algorithm.
-     */
-    const char* getCipher();
-
-    /**
-     * @brief Return name of active SRTP authentication algorithm.
-     *
-     * @return point to name of authentication algorithm.
-     */
-    const char* getAuthAlgo();
-
-
-    /*
-     * ******** Lower layer functions
-     */
-private:
-    /**
-     * @brief Create an SRTP crypto context and the according SDES crypto string.
-     *
-     * This lower layer method creates an SDES crypto string. It selects a valid
-     * crypto suite, generates the key and salt data, converts these into base 64
-     * and returns the crypto string in raw format without any signaling prefixes.
-     *
-     * The output string has the following format:
-     * @verbatim
-     * 1 AES_CM_128_HMAC_SHA1_32 inline:NzB4d1BINUAvLEw6UzF3WSJ+PSdFcGdUJShpX1Zj
-     * @endverbatim
-     *
-     * Applications usually don't use this method directly. Applications shall
-     * use the SDES stream functions.
-     *
-     * Depending on the crypto suite the overall length of the crypto string
-     * is variable. For a normal AES_128_CM suite the minumum lenth is 73
-     * characters, a AES_256_CM suite results in 97 characters (not counting
-     * any signaling prefixes).
-     *
-     * @param cryptoString points to a char output buffer that receives the
-     *                     crypto  string in the raw format, without the any
-     *                     signaling prefix, for example @c a=crypto: in case
-     *                     of SDP signaling. The function terminates the
-     *                     crypto string with a @c nul byte
-     *
-     * @param maxLen points to an integer. On input this integer specifies the
-     *               length of the output buffer. If @c maxLen is smaller than
-     *               the resulting crypto string the function returns an error
-     *               conde. On return the functions sets @c maxLen to the
-     *               actual length of the resultig crypto string.
-     *
-     * @param tag the value of the @c tag field in the crypto string. The
-     *            answerer must use this input to make sure that the tag value
-     *            in the answer matches the value in the offer. See RFC 4568,
-     *            section 5.1.2.
-     *            If the tag value is @c -1 the function sets the tag to @c 1.
-     *
-     * @return @c true if data could be created, @c false
-     *          otherwise.
-     */
-    bool createSdesProfile(char *cryptoString, size_t *maxLen);
-
-    /**
-     * @brief Parse and check an offered SDES crypto string and create SRTP crypto context.
-     *
-     * The method parses an offered SDES crypto string and checks if it is
-     * valid. Next it checks if the string contains a supported crypto suite
-     * and if the key and salt lengths match the selected crypto suite.
-     *
-     * Applications usually don't use this method directly. Applications shall
-     * use the SDES stream functions.
-     *
-     * @b NOTE: This function does not support the optional parameters lifetime,
-     * MKI, and session parameters. While it can parse liftime and MKI theiy are
-     * not evaluated and used. If these parameters are used in the input crypto
-     * string the function return @c false.
-     *
-     * @param cryptoString points to the crypto sting in raw format,
-     *        without any signaling prefix, for example @c a=crypto: in case of
-     *        SDP signaling.
-     *
-     * @param length length of the crypto string to parse. If the length is
-     *        @c zero then the function uses @c strlen to compute the length.
-     *
-     * @param parsedSuite the function sets this to the @c sdesSuites enumerator of
-     *        the parsed crypto suite. The answerer shall use this as input to
-     *        @c createSdesProfile to make sure that it creates the same crypto suite.
-     *        See RFC 4568, section 5.1.2
-     *
-     * @param tag the function sets this to the @c tag value of the parsed crypto
-     *        string. The answerer must use this as input to @c createSdesProfile
-     *        to make sure that it creates the correct tag in the crypto string.
-     *        See RFC 4568, section 5.1.2
-     *
-     * @return @c true if checks were ok, @c false
-     *          otherwise.
-     */
-    bool parseCreateSdesProfile(const char *cryptoString, size_t length, sdesSuites *parsedSuite, int32_t *tag);
-
-    /**
-     * @brief Create the SRTP contexts after all SDES creation and parsing is done.
-     * 
-     * @param sipInvite if this is set to @c true (not zero) then the method
-     *                  computes the key data for the inviting SIP application (offerer) and
-     *                  for the answerer otherwise.
-     */
-    void createSrtpContexts(bool sipInvite);
-
-    /**
-     * @brief Compute the mixed keys if SDES mixing attribute is set.
-     *
-     * The method takes the parsed or created SDES key material and computes the mixed keys and salt.
-     * It replaces the existing key material with the new data.
-     *
-     * @param sipInvite if this is set to @c true (not zero) then the method
-     *                  computes the key data for the inviting SIP application (offerer) and
-     *                  for the answerer otherwise.
-     */
-    void computeMixedKeys(bool sipInvite);
-
-
-    sdesZrtpStates state;
-    sdesSuites     suite;
-    int32_t        tag;
-    CryptoContext     *recvSrtp;           //!< The SRTP context for this stream
-    CryptoContextCtrl *recvSrtcp;          //!< The SRTCP context for this stream
-    CryptoContext     *sendSrtp;           //!< The SRTP context for this stream
-    CryptoContextCtrl *sendSrtcp;          //!< The SRTCP context for this stream
-    uint32_t srtcpIndex;                   //!< the local SRTCP index
-
-    CryptoContext     *recvZrtpTunnel;     //!< The SRTP context for sender ZRTP tunnel
-    CryptoContext     *sendZrtpTunnel;     //!< The SRTP context for receiver ZRTP tunnel
-
-    int32_t cryptoMixHashLength;
-    sdesHmacTypeMix cryptoMixHashType;
-
-    // Variables for crypto that this client creates and sends to the other client, filled during SDES create
-    uint8_t localKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4];  //!< Some buffer for key and salt, multiple of 4
-    int localKeyLenBytes;
-    int localSaltLenBytes;
-    int localCipher;
-    int localAuthn;
-    int localAuthKeyLen;
-    int localTagLength;
-
-    // Variables for crypto that this client receives from the other client, filled during SDES parse
-    uint8_t remoteKeySalt[((MAX_KEY_LEN + MAX_SALT_LEN + 3)/4)*4];  //!< Some buffer for key and salt, multiple of 4
-    int remoteKeyLenBytes;
-    int remoteSaltLenBytes;
-    int remoteCipher;
-    int remoteAuthn;
-    int remoteAuthKeyLen;
-    int remoteTagLength;
-};
-#endif
\ No newline at end of file
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Decode.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Decode.h
deleted file mode 100644
index f53f1ad..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Decode.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-cdecode.h - c header for a base64 decoding algorithm
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#ifndef BASE64_CDECODE_H
-#define BASE64_CDECODE_H
-
-#include <stdint.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-typedef enum
-{
-	step_a, step_b, step_c, step_d
-} base64_decodestep;
-
-typedef struct
-{
-	base64_decodestep step;
-	char plainchar;
-} base64_decodestate;
-
-void base64_init_decodestate(base64_decodestate* state_in);
-
-int base64_decode_value(char value_in);
-
-int base64_decode_block(const char* code_in, const int length_in, uint8_t *plaintext_out, base64_decodestate* state_in);
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* BASE64_CDECODE_H */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Encode.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Encode.h
deleted file mode 100644
index f054392..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpB64Encode.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
-cencode.h - c header for a base64 encoding algorithm
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#ifndef BASE64_CENCODE_H
-#define BASE64_CENCODE_H
-
-#include <stdint.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-typedef enum
-{
-	step_A, step_B, step_C
-} base64_encodestep;
-
-typedef struct
-{
-	base64_encodestep step;
-	char result;
-	int stepcount;
-    int lineLength;
-} base64_encodestate;
-
-void base64_init_encodestate(base64_encodestate* state_in, int lineLength);
-
-char base64_encode_value(const int8_t value_in);
-
-int base64_encode_block(const uint8_t *plaintext_in, int length_in, char* code_out, base64_encodestate* state_in);
-
-int base64_encode_blockend(char *code_out, base64_encodestate* state_in);
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* BASE64_CENCODE_H */
diff --git a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h b/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
deleted file mode 100644
index 8f33462..0000000
--- a/jni/libzrtp/sources/zrtp/libzrtpcpp/zrtpCacheDbBackend.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
-  Copyright (C) 2006-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _ZRTP_CACHE_DB_BACKEND_H_
-#define _ZRTP_CACHE_DB_BACKEND_H_
-
-#include <libzrtpcpp/ZIDRecordDb.h>
-
-#if defined(__cplusplus)
-extern "C"
-{
-#endif
-
-#define DB_CACHE_ERR_BUFF_SIZE  1000
-
-/**
- * Set of accessible operations of database ZRTP cache implementaion.
- *
- * The only public method of the database ZRTP implementation is
- * getDbCacheOps(...)  that fills in this call structure. This mechanism
- * decouples the database implementations from libzrtp and possible other
- * clients.
- *
- * Some implementation notes:
- * <ul>
- * <li> All data storage methods return 0 (zero) if the call was successful.
- * </li>
-
- * <li> The @c errString parameter points to a buffer of at least @c
- *      DB_CACHE_ERR_BUFF_SIZE character. In case of an error methods shall
- *      store detailed, human readable information in this buffer. Use @c
- *      snprintf or similar functions to format the data.  If this parameter
- *      is @c NULL then methods must not return an error string.
- *</li>
- * <li> The methods cast the @c void to the type they need. Be aware that the
- *      open functions requires a pointer to a pointer.
- * </li>
- * </ul>
- *
- *
- * 
- */
-typedef struct {
-    /**
-     * @brief Open the cache.
-     *
-     * @param name String that identifies the database or data storage.
-     *
-     * @param pdb Pointer to an internal structure that the database
-     *            implementation requires.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*openCache)(const char* name, void **pdb, char *errString);
-
-    /**
-     * Close the cache.
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     */
-    int (*closeCache)(void *db);
-
-    /**
-     * @brief Read a local ZID from the database.
-     *
-     * The cache database may implement methods to generate and store local
-     * ZRTP identifiers (ZID) and optionally link them with account
-     * information. The account information data is the key to the request
-     * local ZID. If the application does not provide account information data
-     * the method implmentation shall use a standard predfined string that
-     * does not collide with usual account information.
-     *
-     * The SQLite backend uses the string @c "_STANDARD_" in this case and
-     * sets a specific type field.
-     * 
-     * The first call to this method with a specific account information
-     * generates a ZID, stores it in the database usind the account
-     * information as key, and returns the ZID to the application. Any
-     * subsequent call with the same account information return the same local
-     * ZID.
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                 uint8_t bytes. The method stores the local ZID in this
-     *                 buffer.
-     *
-     * @param accountInfo Pointer to an account information string or @c NULL
-     *                    if explicit account information is not required.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*readLocalZid)(void *db, uint8_t *localZid, const char *accountInfo, char *errString);
-
-    /**
-     * @brief Read a remote ZID data structure.
-     *
-     * The method uses @c remoteZid and @c localZid as keys to read the remote
-     * ZID record.  If a record does not exist in the database the method
-     * clears the @c flags field in the @c remoteZidRecord_t structure and
-     * returns without error. The application must check the flags if the
-     * method found a valid record.
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                 uint8_t bytes. The buffer must contain the local ZID.
-     *
-     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                  uint8_t bytes. The buffer must contain the remote ZID.
-     *
-     * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
-     *               fills this structure with data it read from the database.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*readRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid, 
-                               remoteZidRecord_t *remZid, char* errString);
-    /**
-     * @brief Update an existing remote ZID data structure.
-     *
-     * The method uses @c remoteZid and @c localZid as keys to update an
-     * existing remote ZID record.
-     *
-     * @b NOTE: application must use this methods only if
-     *          @c readRemoteZidRecord (see above) returned a @b valid record. If
-     *          @c readRemoteZidRecord returned an invalid record then no such
-     *          record exists in the database and the application must use the
-     *          @c insertRemoteZidRecord (see below).
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                 uint8_t bytes. The buffer must contain the local ZID.
-     *
-     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                  uint8_t bytes. The buffer must contain the remote ZID.
-     *
-     * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
-     *               gets data from this structure and stores it in the
-     *               database.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*updateRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid, 
-                                 const remoteZidRecord_t *remZid, char* errString);
-    /**
-     * @brief Insert a new remote ZID data structure.
-     *
-     * The method uses @c remoteZid and @c localZid as keys to insert a new
-     * remote ZID record.
-     *
-     * @b NOTE: application must use this methods only if @c
-     *          readRemoteZidRecord (see above) returned an @b invalid
-     *          record. Refer to note.
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                 uint8_t bytes. The buffer must contain the local ZID.
-     *
-     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                  uint8_t bytes. The buffer must contain the remote ZID.
-     *
-     * @param remZid Pointer to the @c remoteZidRecord_t structure. The method
-     *               gets data from this structure and stores it in the
-     *               database.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*insertRemoteZidRecord)(void *db, const uint8_t *remoteZid, const uint8_t *localZid, 
-                                 const remoteZidRecord_t *remZid, char* errString);
-
-    /**
-     * @brief Read a remote ZID name.
-     *
-     * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys
-     * to read the remote ZID name.  If a record does not exist in the database
-     * the method clears the @c flags field in the @c zidNameRecord_t structure and
-     * returns without error. The application must check the flags if the
-     * method found a valid record.
-     * 
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                 uint8_t bytes. The buffer must contain the local ZID.
-     *
-     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                  uint8_t bytes. The buffer must contain the remote ZID.
-     *
-     * @param accountInfo Pointer to an account information string or @c NULL
-     *                    if explicit account information is not required.
-     *
-     * @param zidName Pointer to the @c zidNameRecord_t structure. The method
-     *                returns the data in this structure.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*readZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
-                             const char *accountInfo, zidNameRecord_t *zidName, char* errString);
-
-    /**
-     * @brief Update an existing remote ZID data structure.
-     *
-     * The method uses @c remoteZid and @c localZid as keys to update an
-     * existing remote ZID record.
-     *
-     * @b NOTE: application must use this methods only if
-     *          @c readZidName (see above) returned a @b valid record. If
-     *          @c readZidName returned an invalid record then no such
-     *          record exists in the database and the application must use the
-     *          @c insertZidNameRecord (see below).
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                 uint8_t bytes. The buffer must contain the local ZID.
-     *
-     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                  uint8_t bytes. The buffer must contain the remote ZID.
-     *
-     * @param accountInfo Pointer to an account information string or @c NULL
-     *                    if explicit account information is not required.
-     *
-     * @param zidName Pointer to the @c zidNameRecord_t structure. The method
-     *               gets data from this structure and stores it in the
-     *               database.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*updateZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
-                               const char *accountInfo, zidNameRecord_t *zidName, char* errString);
-
-    /**
-     * @brief Insert a new ZID name record.
-     *
-     * The method uses @c remoteZid, @c localZid, and @c accountInfo as keys to
-     * insert a new ZID name record.
-     *
-     * @b NOTE: application must use this methods only if @c readZidName
-     *         (see above) returned an @b invalid record.
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param localZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                 uint8_t bytes. The buffer must contain the local ZID.
-     *
-     * @param remoteZid Pointer to a buffer of at least @c IDENTIFIER_LEN @c
-     *                  uint8_t bytes. The buffer must contain the remote ZID.
-     *
-     * @param accountInfo Pointer to an account information string or @c NULL
-     *                    if explicit account information is not required.
-     *
-     * @param zidName Pointer to the @c zidNameRecord_t structure. The method
-     *               gets data from this structure and stores it in the
-     *               database.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*insertZidNameRecord)(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
-                               const char *accountInfo, zidNameRecord_t *zidName, char* errString);
-
-
-    /**
-     * @brief Clean the cache.
-     * 
-     * The function drops and re-creates all tables in the database. This removes all stored
-     * data. The application must not call this while a ZRTP call is active. Also the application
-     * <b>must</b> get the local ZID again.
-     *
-     * @param db Pointer to an internal structure that the database
-     *           implementation requires.
-     *
-     * @param errString Pointer to a character buffer, see implementation
-     *                  notes above.
-     */
-    int (*cleanCache)(void *db, char* errString);
-} dbCacheOps_t;
-
-void getDbCacheOps(dbCacheOps_t *ops);
-
-
-#if defined(__cplusplus)
-}
-#endif
-
-#endif /* _ZRTP_CACHE_DB_BACKEND_H_*/
diff --git a/jni/libzrtp/sources/zrtp/zrtpB64Decode.c b/jni/libzrtp/sources/zrtp/zrtpB64Decode.c
deleted file mode 100644
index d0fb69e..0000000
--- a/jni/libzrtp/sources/zrtp/zrtpB64Decode.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * cdecoder.c - c source to a base64 decoding algorithm implementation
- *
- * This is part of the libb64 project, and has been placed in the public domain.
- * For details, see http://sourceforge.net/projects/libb64
- */
-
-#include <libzrtpcpp/zrtpB64Decode.h>
-
-int base64_decode_value(char value_in)
-{
-    static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
-    static const char decoding_size = sizeof(decoding);
-    value_in -= 43;
-    if (value_in < 0 || value_in > decoding_size) return -1;
-    return decoding[(int)value_in];
-}
-
-void base64_init_decodestate(base64_decodestate* state_in)
-{
-    state_in->step = step_a;
-    state_in->plainchar = 0;
-}
-
-int base64_decode_block(const char* code_in, const int length_in, uint8_t *plaintext_out, base64_decodestate* state_in)
-{
-    const char* codechar = code_in;
-    uint8_t *plainchar = plaintext_out;
-    char fragment;
-
-    *plainchar = state_in->plainchar;
-
-    switch (state_in->step)
-    {
-        while (1)
-        {
-        case step_a:
-            do {
-                if (codechar == code_in+length_in)
-                {
-                    state_in->step = step_a;
-                    state_in->plainchar = *plainchar;
-                    return plainchar - plaintext_out;
-                }
-                fragment = (char)base64_decode_value(*codechar++);
-            } while (fragment < 0);
-            *plainchar    = (fragment & 0x03f) << 2;
-        case step_b:
-            do {
-                if (codechar == code_in+length_in)
-                {
-                    state_in->step = step_b;
-                    state_in->plainchar = *plainchar;
-                    return plainchar - plaintext_out;
-                }
-                fragment = (char)base64_decode_value(*codechar++);
-            } while (fragment < 0);
-            *plainchar++ |= (fragment & 0x030) >> 4;
-            *plainchar    = (fragment & 0x00f) << 4;
-        case step_c:
-            do {
-                if (codechar == code_in+length_in)
-                {
-                    state_in->step = step_c;
-                    state_in->plainchar = *plainchar;
-                    return plainchar - plaintext_out;
-                }
-                fragment = (char)base64_decode_value(*codechar++);
-            } while (fragment < 0);
-            *plainchar++ |= (fragment & 0x03c) >> 2;
-            *plainchar    = (fragment & 0x003) << 6;
-        case step_d:
-            do {
-                if (codechar == code_in+length_in)
-                {
-                    state_in->step = step_d;
-                    state_in->plainchar = *plainchar;
-                    return plainchar - plaintext_out;
-                }
-                fragment = (char)base64_decode_value(*codechar++);
-            } while (fragment < 0);
-            *plainchar++   |= (fragment & 0x03f);
-        }
-    }
-    /* control should not reach here */
-    return plainchar - plaintext_out;
-}
-
diff --git a/jni/libzrtp/sources/zrtp/zrtpB64Encode.c b/jni/libzrtp/sources/zrtp/zrtpB64Encode.c
deleted file mode 100644
index 241e3c5..0000000
--- a/jni/libzrtp/sources/zrtp/zrtpB64Encode.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-cencoder.c - c source to a base64 encoding algorithm implementation
-
-This is part of the libb64 project, and has been placed in the public domain.
-For details, see http://sourceforge.net/projects/libb64
-*/
-
-#include <libzrtpcpp/zrtpB64Encode.h>
-
-const int CHARS_PER_LINE = 72;
-
-void base64_init_encodestate(base64_encodestate* state_in, int lineLength)
-{
-    state_in->step = step_A;
-    state_in->result = 0;
-    state_in->stepcount = 0;
-    if (lineLength < 0)
-        state_in->lineLength = CHARS_PER_LINE / 4;
-    else
-        state_in->lineLength = (lineLength+3) / 4;
-}
-
-char base64_encode_value(const int8_t value_in)
-{
-    static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-    if (value_in > 63) return '=';
-    return encoding[(int)value_in];
-}
-
-int base64_encode_block(const uint8_t *plaintext_in, int length_in, char* code_out, base64_encodestate* state_in)
-{
-    const uint8_t *plainchar = plaintext_in;
-    const uint8_t *const plaintextend = plaintext_in + length_in;
-    char* codechar = code_out;
-    char result;
-    char fragment;
-
-    result = state_in->result;
-
-    switch (state_in->step)
-    {
-        while (1)
-        {
-        case step_A:
-            if (plainchar == plaintextend)
-            {
-                state_in->result = result;
-                state_in->step = step_A;
-                return codechar - code_out;
-            }
-            fragment = *plainchar++;
-            result = (fragment & 0x0fc) >> 2;
-            *codechar++ = base64_encode_value(result);
-            result = (fragment & 0x003) << 4;
-        case step_B:
-            if (plainchar == plaintextend)
-            {
-                state_in->result = result;
-                state_in->step = step_B;
-                return codechar - code_out;
-            }
-            fragment = *plainchar++;
-            result |= (fragment & 0x0f0) >> 4;
-            *codechar++ = base64_encode_value(result);
-            result = (fragment & 0x00f) << 2;
-        case step_C:
-            if (plainchar == plaintextend)
-            {
-                state_in->result = result;
-                state_in->step = step_C;
-                return codechar - code_out;
-            }
-            fragment = *plainchar++;
-            result |= (fragment & 0x0c0) >> 6;
-            *codechar++ = base64_encode_value(result);
-            result  = (fragment & 0x03f) >> 0;
-            *codechar++ = base64_encode_value(result);
-
-            if (state_in->lineLength > 0) {
-                state_in->stepcount++;
-                if (state_in->stepcount == state_in->lineLength)
-                {
-                    *codechar++ = '\n';
-                    state_in->stepcount = 0;
-                }
-            }
-        }
-    }
-    /* control should not reach here */
-    return codechar - code_out;
-}
-
-int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
-{
-    char* codechar = code_out;
-
-    switch (state_in->step)
-    {
-        case step_B:
-            *codechar++ = base64_encode_value(state_in->result);
-            *codechar++ = '=';
-            *codechar++ = '=';
-            break;
-        case step_C:
-            *codechar++ = base64_encode_value(state_in->result);
-            *codechar++ = '=';
-            break;
-        case step_A:
-            break;
-    }
-    if (state_in->lineLength > 0)
-        *codechar++ = '\n';
-
-    return codechar - code_out;
-}
-
diff --git a/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c b/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
deleted file mode 100644
index 7dc9cdf..0000000
--- a/jni/libzrtp/sources/zrtp/zrtpCacheSqliteBackend.c
+++ /dev/null
@@ -1,789 +0,0 @@
-/*
-  Copyright (C) 2012-2013 Werner Dittmann
-
-  This program is free software: you can redistribute it and/or modify
-  it under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  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.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * Authors: Werner Dittmann <Werner.Dittmann@t-online.de>
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <time.h>
-#include <sqlite3.h>
-
-#include <crypto/zrtpDH.h>
-
-#include <libzrtpcpp/zrtpB64Encode.h>
-#include <libzrtpcpp/zrtpB64Decode.h>
-
-#include <libzrtpcpp/zrtpCacheDbBackend.h>
-
-/* Some ported SQLite3 libs do not support the _v2 variants */
-#define SQLITE_USE_V2
-
-#ifdef SQLITE_USE_V2
-#define SQLITE_PREPARE sqlite3_prepare_v2
-#else
-#define SQLITE_PREPARE sqlite3_prepare
-#endif
-
-#if defined(_WIN32) || defined(_WIN64)
-# define snprintf _snprintf
-#endif
-
-#ifdef TRANSACTIONS
-static const char *beginTransactionSql  = "BEGIN TRANSACTION;";
-static const char *commitTransactionSql = "COMMIT;";
-#endif
-
-/*
- * The database backend uses the following definitions if it implements the localZid storage.
- */
-
-/* The type field in zrtpIdOwn stores the following values */
-static const int32_t localZidStandard         = 1; /* this local ZID is not tied to a specific account */
-static const int32_t localZidWithAccount      = 2;
-
-/* Default data for account info if none specified */
-static const char *defaultAccountString = "_STANDARD_";
-
-
-/* *****************************************************************************
- * The SQLite master table.
- *
- * Used to check if we have valid ZRTP cache tables.
- */
-static char *lookupTables = "SELECT name FROM sqlite_master WHERE type='table' AND name='zrtpIdOwn';";
-
-
-/* *****************************************************************************
- * SQL statements to process the zrtpIdOwn table.
- */
-static const char *dropZrtpIdOwn =      "DROP TABLE zrtpIdOwn;";
-
-/* SQLite doesn't care about the VARCHAR length. */
-static char *createZrtpIdOwn = "CREATE TABLE zrtpIdOwn(localZid CHAR(18), type INTEGER, accountInfo VARCHAR(1000));";
-
-static char *selectZrtpIdOwn = "SELECT localZid FROM zrtpIdOwn WHERE type = ?1 AND accountInfo = ?2;";
-static char *insertZrtpIdOwn = "INSERT INTO zrtpIdOwn (localZid, type, accountInfo) VALUES (?1, ?2, ?3);";
-
-
-/* *****************************************************************************
- * SQL statements to process the remoteId table.
- */
-static const char *dropZrtpIdRemote =      "DROP TABLE zrtpIdRemote;";
-
-static const char *createZrtpIdRemote = 
-    "CREATE TABLE zrtpIdRemote "
-    "(remoteZid CHAR(16),  localZid CHAR(16), flags INTEGER,"
-    "rs1 BLOB(32), rs1LastUsed TIMESTAMP, rs1TimeToLive TIMESTAMP," 
-    "rs2 BLOB(32), rs2LastUsed TIMESTAMP, rs2TimeToLive TIMESTAMP,"
-    "mitmKey BLOB(32), mitmLastUsed TIMESTAMP, secureSince TIMESTAMP, preshCounter INTEGER);";
-
-static const char *selectZrtpIdRemoteAll = 
-    "SELECT flags,"
-    "rs1, strftime('%s', rs1LastUsed, 'unixepoch'), strftime('%s', rs1TimeToLive, 'unixepoch'),"
-    "rs2, strftime('%s', rs2LastUsed, 'unixepoch'), strftime('%s', rs2TimeToLive, 'unixepoch'),"
-    "mitmKey, strftime('%s', mitmLastUsed, 'unixepoch'), strftime('%s', secureSince, 'unixepoch'),"
-    "preshCounter "
-    "FROM zrtpIdRemote WHERE remoteZid=?1 AND localZid=?2;";
-
-static const char *insertZrtpIdRemote =
-    "INSERT INTO zrtpIdRemote "
-        "(remoteZid, localZid, flags,"
-        "rs1, rs1LastUsed, rs1TimeToLive,"
-        "rs2, rs2LastUsed, rs2TimeToLive,"
-        "mitmKey, mitmLastUsed, secureSince, preshCounter)"
-      "VALUES"
-        "(?1, ?12, ?2,"
-        "?3, strftime('%s', ?4, 'unixepoch'), strftime('%s', ?5, 'unixepoch'),"
-        "?6, strftime('%s', ?7, 'unixepoch'), strftime('%s', ?8, 'unixepoch'),"
-        "?9, strftime('%s', ?10, 'unixepoch'), strftime('%s', ?11, 'unixepoch'), ?13);";
-
-static const char *updateZrtpIdRemote = 
-    "UPDATE zrtpIdRemote SET "
-    "flags=?2,"
-    "rs1=?3, rs1LastUsed=strftime('%s', ?4, 'unixepoch'), rs1TimeToLive=strftime('%s', ?5, 'unixepoch'),"
-    "rs2=?6, rs2LastUsed=strftime('%s', ?7, 'unixepoch'), rs2TimeToLive=strftime('%s', ?8, 'unixepoch'),"
-    "mitmKey=?9, mitmLastUsed=strftime('%s', ?10, 'unixepoch'),"
-    "secureSince=strftime('%s', ?11, 'unixepoch'), preshCounter=?13 "
-    "WHERE remoteZid=?1 AND localZid=?12;";
-
-
-/* *****************************************************************************
- * SQL statements to process the name table.
- *
- * The name tables holds free format information and binds it to the combination
- * of local, remote ZIDs and an optional account information.
- */
-static const char *dropZrtpNames = "DROP TABLE zrtpNames;";
-
-static const char *createZrtpNames =
-    "CREATE TABLE zrtpNames "
-    "(remoteZid CHAR(16), localZid CHAR(16), flags INTEGER, "
-    "lastUpdate TIMESTAMP, accountInfo VARCHAR(1000), name VARCHAR(1000));";
-
-static const char *selectZrtpNames =
-    "SELECT flags, strftime('%s', lastUpdate, 'unixepoch'), name "
-    "FROM zrtpNames "
-    "WHERE remoteZid=?1 AND localZid=?2 AND accountInfo=?3;";
-
-static const char *insertZrtpNames =
-    "INSERT INTO zrtpNames "
-        "(remoteZid, localZid, flags, lastUpdate, accountInfo, name)"
-      "VALUES"
-        "(?1, ?2, ?4, strftime('%s', ?5, 'unixepoch'), ?3, ?6);";
-
-static const char *updateZrtpNames =
-    "UPDATE zrtpNames SET "
-    "flags=?4,"
-    "lastUpdate=strftime('%s', ?5, 'unixepoch'), name=?6 "
-    "WHERE remoteZid=?1 AND localZid=?2 AND accountInfo=?3;";
-
-
-/* *****************************************************************************
- * A few helping macros. 
- * These macros require some names/patterns in the methods that use these 
- * macros:
- * 
- * ERRMSG requires:
- * - a variable with name "db" is the pointer to sqlite3
- * - a char* with name "errString" points to a buffer of at least SQL_CACHE_ERR_BUFF_SIZE chars
- *
- * SQLITE_CHK requires:
- * - a cleanup label, the macro goes to that label in case of error
- * - an integer (int) variable with name "rc" that stores return codes from sqlite
- * - ERRMSG
- */
-#define ERRMSG  {if (errString) snprintf(errString, (size_t)DB_CACHE_ERR_BUFF_SIZE, \
-                                         "SQLite3 error: %s, line: %d, error message: %s\n", __FILE__, __LINE__, sqlite3_errmsg(db));}
-#define SQLITE_CHK(func) {                                              \
-        rc = (func);                                                    \
-        if(rc != SQLITE_OK) {                                           \
-            ERRMSG;                                                     \
-            goto cleanup;                                               \
-        }                                                               \
-    }
-
-static int b64Encode(const uint8_t *binData, int32_t binLength, char *b64Data, int32_t b64Length)
-{
-    base64_encodestate _state;
-    int codelength;
-
-    base64_init_encodestate(&_state, 0);
-    codelength = base64_encode_block(binData, binLength, b64Data, &_state);
-    codelength += base64_encode_blockend(b64Data+codelength, &_state);
-
-    return codelength;
-}
-
-static int b64Decode(const char *b64Data, int32_t b64length, uint8_t *binData, int32_t binLength)
-{
-    base64_decodestate _state;
-    int codelength;
-
-    base64_init_decodestate(&_state);
-    codelength = base64_decode_block(b64Data, b64length, binData, &_state);
-    return codelength;
-}
-
-#ifdef TRANSACTIONS
-static int beginTransaction(sqlite3 *db, char* errString)
-{
-    sqlite3_stmt *stmt;
-    int rc;
-
-    SQLITE_CHK(SQLITE_PREPARE(db, beginTransactionSql, strlen(beginTransactionSql)+1, &stmt, NULL));
-
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-
-static int commitTransaction(sqlite3 *db, char* errString)
-{
-    sqlite3_stmt *stmt;
-    int rc;
-
-    SQLITE_CHK(SQLITE_PREPARE(db, commitTransactionSql, strlen(commitTransactionSql)+1, &stmt, NULL));
-
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-#endif
-
-/**
- * Initialize remote ZID and remote name tables.
- *
- * First drop the remote ZID and remote name tables and create them again.
- * All information regarding remote peers is lost.
- */
-static int initializeRemoteTables(sqlite3 *db, char* errString)
-{
-    sqlite3_stmt * stmt;
-    int rc;
-
-    /* First drop them, just to be on the save side
-     * Ignore errors, there is nothing to drop on empty DB. If ZrtpIdOwn was
-     * deleted using DB admin command then we need to drop the remote id table
-     * and names also to have a clean state.
-     */
-    rc = SQLITE_PREPARE(db, dropZrtpIdRemote, strlen(dropZrtpIdRemote)+1, &stmt, NULL);
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-
-    rc = SQLITE_PREPARE(db, dropZrtpNames, strlen(dropZrtpNames)+1, &stmt, NULL);
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-
-    SQLITE_CHK(SQLITE_PREPARE(db, createZrtpIdRemote, strlen(createZrtpIdRemote)+1, &stmt, NULL));
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    SQLITE_CHK(SQLITE_PREPARE(db, createZrtpNames, strlen(createZrtpNames)+1, &stmt, NULL));
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return 0;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-
-}
-/**
- * Create ZRTP cache tables in database.
- *
- * openCache calls this function if it cannot find the table zrtpId_own. This indicates
- * that no ZRTP cache tables are available in the database.
- */
-static int createTables(sqlite3 *db, char* errString)
-{
-    sqlite3_stmt * stmt;
-    int rc;
-
-    /* no ZRTP cache tables were found - create them, first the OwnId table */
-    SQLITE_CHK(SQLITE_PREPARE(db, createZrtpIdOwn, strlen(createZrtpIdOwn)+1, &stmt, NULL));
-
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return initializeRemoteTables(db, errString);
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-
-static int insertRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid, 
-                                 const remoteZidRecord_t *remZid, char* errString)
-{
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt *stmt;
-    int rc = 0;
-
-    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
-    char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
-    /* Get B64 code for remoteZid first */
-    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
-    /* Get B64 code for localZid now */
-    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
-    SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpIdRemote, strlen(insertZrtpIdRemote)+1, &stmt, NULL));
-
-    /* For *_bind_* methods: column index starts with 1 (one), not zero */
-    SQLITE_CHK(sqlite3_bind_text(stmt,   1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt,  12, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int(stmt,    2, remZid->flags));
-    SQLITE_CHK(sqlite3_bind_blob(stmt,   3, remZid->rs1, RS_LENGTH, SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  4, remZid->rs1LastUse));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  5, remZid->rs1Ttl));
-    SQLITE_CHK(sqlite3_bind_blob(stmt,   6, remZid->rs2, RS_LENGTH, SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  7, remZid->rs2LastUse));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  8, remZid->rs2Ttl));
-    SQLITE_CHK(sqlite3_bind_blob(stmt,   9, remZid->mitmKey, RS_LENGTH, SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int64(stmt, 10, remZid->mitmLastUse));
-    SQLITE_CHK(sqlite3_bind_int64(stmt, 11, remZid->secureSince));
-    SQLITE_CHK(sqlite3_bind_int(stmt,   13, remZid->preshCounter));
-
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-
-}
-
-static int updateRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid, 
-                                 const remoteZidRecord_t *remZid, char* errString)
-{
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt *stmt;
-    int rc;
-
-    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
-    char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
-    /* Get B64 code for remoteZid first */
-    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
-    /* Get B64 code for localZid now */
-    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
-    SQLITE_CHK(SQLITE_PREPARE(db, updateZrtpIdRemote, strlen(updateZrtpIdRemote)+1, &stmt, NULL));
-
-    /* For *_bind_* methods: column index starts with 1 (one), not zero */
-    /* Select for update with the following keys */
-    SQLITE_CHK(sqlite3_bind_text(stmt,   1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt,  12, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-
-    /* Update the following values */
-    SQLITE_CHK(sqlite3_bind_int(stmt,    2, remZid->flags));
-    SQLITE_CHK(sqlite3_bind_blob(stmt,   3, remZid->rs1, RS_LENGTH, SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  4, remZid->rs1LastUse));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  5, remZid->rs1Ttl));
-    SQLITE_CHK(sqlite3_bind_blob(stmt,   6, remZid->rs2, RS_LENGTH, SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  7, remZid->rs2LastUse));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  8, remZid->rs2Ttl));
-    SQLITE_CHK(sqlite3_bind_blob(stmt,   9, remZid->mitmKey, RS_LENGTH, SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int64(stmt, 10, remZid->mitmLastUse));
-    SQLITE_CHK(sqlite3_bind_int64(stmt, 11, remZid->secureSince));
-    SQLITE_CHK(sqlite3_bind_int(stmt,   13, remZid->preshCounter));
-
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-
-static int readRemoteZidRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid, 
-                               remoteZidRecord_t *remZid, char* errString)
-{
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt *stmt;
-    int rc;
-    int found = 0;
-
-    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
-    char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
-    /* Get B64 code for remoteZid */
-    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
-    /* Get B64 code for localZid */
-    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
-    SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpIdRemoteAll, strlen(selectZrtpIdRemoteAll)+1, &stmt, NULL));
-    SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-
-    /* Getting data from result set: column index starts with 0 (zero), not one */
-    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
-        remZid->flags =         sqlite3_column_int(stmt,    0);
-        memcpy(remZid->rs1,     sqlite3_column_blob(stmt,   1), RS_LENGTH);
-        remZid->rs1LastUse =    sqlite3_column_int64(stmt,  2);
-        remZid->rs1Ttl =        sqlite3_column_int64(stmt,  3);
-        memcpy(remZid->rs2,     sqlite3_column_blob(stmt,   4), RS_LENGTH);
-        remZid->rs2LastUse =    sqlite3_column_int64(stmt,  5);
-        remZid->rs2Ttl =        sqlite3_column_int64(stmt,  6);
-        memcpy(remZid->mitmKey, sqlite3_column_blob(stmt,   7), RS_LENGTH);
-        remZid->mitmLastUse =   sqlite3_column_int64(stmt,  8);
-        remZid->secureSince =   sqlite3_column_int64(stmt,  9);
-        remZid->preshCounter =  sqlite3_column_int(stmt,   10);
-        found++;
-    }
-    sqlite3_finalize(stmt);
-
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    if (found == 0) {
-        remZid->flags = 0;
-    }
-    else if (found > 1) {
-        if (errString) 
-            snprintf(errString, DB_CACHE_ERR_BUFF_SIZE, "ZRTP cache inconsistent. More than one remote ZID found: %d\n", found);
-        return 1;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-
-
-static int readLocalZid(void *vdb, uint8_t *localZid, const char *accountInfo, char *errString)
-{
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt *stmt;
-    char *zidBase64Text;
-    int rc = 0;
-    int found = 0;
-    int type = localZidWithAccount;
-
-    if (accountInfo == NULL || !strcmp(accountInfo, defaultAccountString)) {
-        accountInfo = defaultAccountString;
-        type = localZidStandard;
-    }
-
-    /* Find a localZid record for this combination */
-    SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpIdOwn, strlen(selectZrtpIdOwn)+1, &stmt, NULL));
-
-    SQLITE_CHK(sqlite3_bind_int(stmt,  1, type));
-    SQLITE_CHK(sqlite3_bind_text(stmt, 2, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
-    /* Loop over result set and count it. However, use only the localZid of first row */
-    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
-        if (found == 0) {
-            zidBase64Text = (char *)sqlite3_column_text(stmt, 0);
-            b64Decode(zidBase64Text, strlen(zidBase64Text), localZid, IDENTIFIER_LEN);
-        }
-        found++;
-    }
-    sqlite3_finalize(stmt);
-
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    /* No matching record found, create new local ZID for this combination and store in DB */
-    if (found == 0) {
-        char b64zid[IDENTIFIER_LEN+IDENTIFIER_LEN] = {0};
-        int b64len = 0;
-
-        /* create a 12 byte random value, convert to base 64, insert in zrtpIdOwn table */
-        randomZRTP(localZid, IDENTIFIER_LEN);
-        b64len = b64Encode(localZid, IDENTIFIER_LEN, b64zid, IDENTIFIER_LEN+IDENTIFIER_LEN);
-
-        SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpIdOwn, strlen(insertZrtpIdOwn)+1, &stmt, NULL));
-
-        SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64zid, b64len, SQLITE_STATIC));
-        SQLITE_CHK(sqlite3_bind_int(stmt,  2, type));
-        SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
-        rc = sqlite3_step(stmt);
-        sqlite3_finalize(stmt);
-        if (rc != SQLITE_DONE) {
-            ERRMSG;
-            return rc;
-        }
-    }
-    else if (found > 1) {
-        if (errString) 
-            snprintf(errString, DB_CACHE_ERR_BUFF_SIZE,
-                     "ZRTP cache inconsistent. Found %d matching local ZID for account: %s\n", found, accountInfo);
-        return 1;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-
-/*
- * SQLite use the following table structure to manage some internal data
- *
- * CREATE TABLE sqlite_master (
- *   type TEXT,
- *   name TEXT,
- *   tbl_name TEXT,
- *   rootpage INTEGER,
- *   sql TEXT
- * );
- */
-
-static int openCache(const char* name, void **vpdb, char *errString)
-{
-    sqlite3_stmt *stmt;
-    int found = 0;
-    sqlite3 **pdb = (sqlite3**)vpdb;
-    sqlite3 *db;
-
-#ifdef SQLITE_USE_V2
-    int rc = sqlite3_open_v2(name, pdb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX, NULL);
-#else
-    int rc = sqlite3_open(name, pdb);
-#endif
-    db = *pdb;
-    if (rc) {
-        ERRMSG;
-        return(rc);
-    }
-
-    /* check if ZRTP cache tables are already available, look if zrtpIdOwn is available */
-    SQLITE_CHK(SQLITE_PREPARE(db, lookupTables, strlen(lookupTables)+1, &stmt, NULL));
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-
-    if (rc == SQLITE_ROW) {
-        found++;
-    }
-    else if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    /* If table zrtpOwnId not found then we have an empty cache DB */
-    if (found == 0) {
-        rc = createTables(db, errString);
-        if (rc)
-            return rc;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-
-static int closeCache(void *vdb)
-{
-
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_close(db);
-    return SQLITE_OK;
-}
-
-static int clearCache(void *vdb, char *errString)
-{
-
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt * stmt;
-    int rc;
-
-    rc = SQLITE_PREPARE(db, dropZrtpIdOwn, strlen(dropZrtpIdOwn)+1, &stmt, NULL);
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-
-    rc = createTables(db, errString);
-    if (rc)
-        return rc;
-    return SQLITE_OK;
-}
-
-static int insertZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
-                               const char *accountInfo, zidNameRecord_t *zidName, char* errString)
-{
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt *stmt;
-    int rc = 0;
-    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
-    char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
-    if (accountInfo == NULL) {
-        accountInfo = defaultAccountString;
-    }
-
-    /* Get B64 code for remoteZid */
-    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
-    /* Get B64 code for localZid */
-    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
-    SQLITE_CHK(SQLITE_PREPARE(db, insertZrtpNames, strlen(insertZrtpNames)+1, &stmt, NULL));
-
-    /* For *_bind_* methods: column index starts with 1 (one), not zero */
-    SQLITE_CHK(sqlite3_bind_text(stmt,  1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt,  2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt,  3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_int(stmt,   4, zidName->flags));
-    SQLITE_CHK(sqlite3_bind_int64(stmt, 5, (int64_t)time(NULL)));
-    if (zidName->name != NULL) {
-        SQLITE_CHK(sqlite3_bind_text(stmt,   6, zidName->name, strlen(zidName->name), SQLITE_STATIC));
-    }
-    else {
-        SQLITE_CHK(sqlite3_bind_text(stmt,   6, "_NO_NAME_", 9, SQLITE_STATIC));
-    }
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-
-}
-
-
-static int updateZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
-                               const char *accountInfo, zidNameRecord_t *zidName, char* errString)
-{
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt *stmt;
-    int rc = 0;
-    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
-    char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
-    if (accountInfo == NULL) {
-        accountInfo = defaultAccountString;
-    }
-
-    /* Get B64 code for remoteZid */
-    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
-    /* Get B64 code for localZid */
-    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
-    SQLITE_CHK(SQLITE_PREPARE(db, updateZrtpNames, strlen(updateZrtpNames)+1, &stmt, NULL));
-
-    /* For *_bind_* methods: column index starts with 1 (one), not zero */
-    /* Select for update with the following values */
-    SQLITE_CHK(sqlite3_bind_text(stmt,   1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt,   2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt,   3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
-    /* Update the following vaulues */
-    SQLITE_CHK(sqlite3_bind_int(stmt,    4, zidName->flags));
-    SQLITE_CHK(sqlite3_bind_int64(stmt,  5, (int64_t)time(NULL)));
-    if (zidName->name != NULL) {
-        SQLITE_CHK(sqlite3_bind_text(stmt,   6, zidName->name, strlen(zidName->name), SQLITE_STATIC));
-    }
-    else {
-        SQLITE_CHK(sqlite3_bind_text(stmt,   6, "_NO_NAME_", 9, SQLITE_STATIC));
-    }
-    rc = sqlite3_step(stmt);
-    sqlite3_finalize(stmt);
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-
-}
-
-static int readZidNameRecord(void *vdb, const uint8_t *remoteZid, const uint8_t *localZid,
-                             const char *accountInfo, zidNameRecord_t *zidName, char* errString)
-{
-    sqlite3 *db = (sqlite3*)vdb;
-    sqlite3_stmt *stmt;
-    int rc;
-    int found = 0;
-
-    char b64RemoteZid[IDENTIFIER_LEN*2] = {0};
-    char b64LocalZid[IDENTIFIER_LEN*2] = {0};
-
-    if (accountInfo == NULL) {
-        accountInfo = defaultAccountString;
-    }
-    /* Get B64 code for remoteZid */
-    b64Encode(remoteZid, IDENTIFIER_LEN, b64RemoteZid, IDENTIFIER_LEN*2);
-
-    /* Get B64 code for localZid */
-    b64Encode(localZid, IDENTIFIER_LEN, b64LocalZid, IDENTIFIER_LEN*2);
-
-    SQLITE_CHK(SQLITE_PREPARE(db, selectZrtpNames, strlen(selectZrtpNames)+1, &stmt, NULL));
-
-    SQLITE_CHK(sqlite3_bind_text(stmt, 1, b64RemoteZid, strlen(b64RemoteZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt, 2, b64LocalZid, strlen(b64LocalZid), SQLITE_STATIC));
-    SQLITE_CHK(sqlite3_bind_text(stmt, 3, accountInfo, strlen(accountInfo), SQLITE_STATIC));
-
-    /* Getting data from result set: column index starts with 0 (zero), not one */
-    while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
-        zidName->flags = sqlite3_column_int(stmt,        0);
-        strncpy(zidName->name, (const char*)sqlite3_column_text(stmt, 2), zidName->nameLength);
-        zidName->nameLength = sqlite3_column_bytes(stmt, 2);    /* Return number of bytes in string */
-        found++;
-    }
-    sqlite3_finalize(stmt);
-
-    if (rc != SQLITE_DONE) {
-        ERRMSG;
-        return rc;
-    }
-    if (found == 0)
-        zidName->flags = 0;
-    else if (found > 1) {
-        if (errString)
-            snprintf(errString, DB_CACHE_ERR_BUFF_SIZE, "ZRTP name cache inconsistent. More than one ZID name found: %d\n", found);
-        return 1;
-    }
-    return SQLITE_OK;
-
- cleanup:
-    sqlite3_finalize(stmt);
-    return rc;
-}
-
-void getDbCacheOps(dbCacheOps_t *ops)
-{
-    ops->openCache = openCache;
-    ops->closeCache = closeCache;
-    ops->cleanCache = clearCache;
-
-    ops->readLocalZid = readLocalZid;
-
-    ops->readRemoteZidRecord =   readRemoteZidRecord;
-    ops->updateRemoteZidRecord = updateRemoteZidRecord;
-    ops->insertRemoteZidRecord = insertRemoteZidRecord;
-
-    ops->readZidNameRecord =   readZidNameRecord;
-    ops->updateZidNameRecord = updateZidNameRecord;
-    ops->insertZidNameRecord = insertZidNameRecord;
-}
-