Browse Source

Remove the wolfssl code (#77)

Delete wolfssl from the code base

A few minor issues with build, CI timeouts, and gitignores.
Don Porter 6 years ago
parent
commit
62302518e8

+ 0 - 1
LibOS/shim/src/fs/shim_dcache.c

@@ -182,7 +182,6 @@ static inline void __dput_dentry (struct shim_dentry * dent)
              * on a list; just hack this for now; this code will be reworked
              * soon anyway.
              */
-
             /* Chia-Che 10/17/17: Originally we place all the freed
              * dentries on an unused list, now we just maintain a long list
              * of all dentries. */

+ 4 - 1
LibOS/shim/src/sys/shim_futex.c

@@ -186,6 +186,8 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
             /* DEP 1/28/17: Should return ETIMEDOUT, not EAGAIN, on timeout. */
             if (ret == -EAGAIN)
                 ret = -ETIMEDOUT;
+            if (ret == -ETIMEDOUT)
+                listp_del(&waiter, &futex->waiters, list);
             lock(hdl->lock);
             /* Chia-Che 10/17/17: FUTEX_WAKE should remove the waiter
              * from the list; if not, we should remove it now. */
@@ -200,7 +202,7 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
             int nwaken = 0;
             uint32_t bitset = (futex_op == FUTEX_WAKE_BITSET) ? val3 :
                               0xffffffff;
-
+            
             debug("FUTEX_WAKE: %p (val = %d) count = %d mask = %08x\n",
                   uaddr, *uaddr, val, bitset);
 
@@ -210,6 +212,7 @@ int shim_do_futex (unsigned int * uaddr, int op, int val, void * utime,
 
                 debug("FUTEX_WAKE wake thread %d: %p (val = %d)\n",
                       waiter->thread->tid, uaddr, *uaddr);
+
                 listp_del_init(waiter, &futex->waiters, list);
                 thread_wakeup(waiter->thread);
                 nwaken++;

+ 2 - 1
LibOS/shim/test/apps/lighttpd/.gitignore

@@ -1 +1,2 @@
-ab.*
+ab.*
+result-*

+ 1 - 0
LibOS/shim/test/apps/ltp/.gitignore

@@ -6,3 +6,4 @@ master.zip
 opt/
 run_output
 syscalls.graphene
+ltp-full-*

+ 6 - 0
LibOS/shim/test/apps/ltp/TIMEOUTS

@@ -3,14 +3,20 @@ alarm01,5
 alarm06,16
 clone05,30
 faccessat01,40
+fchdir02,40
 fchmod07,40
 fcntl13_64,40
 fsync03,40
+gethostname01,40
 mprotect04,40
 kill09,40
+lseek02,40
+pread02,40
 preadv01,40
 read01,40
 setuid02,40
+sigaltstack02,40
+stat05_64,40
 syscall01,40
 wait401,40
 waitpid05,160

+ 1 - 0
Pal/lib/Makefile

@@ -11,6 +11,7 @@ ARFLAGS	=
 include ../src/host/$(PAL_HOST)/Makefile.am
 
 CFLAGS += -I. -I../include -I../src
+
 subdirs = string stdlib network graphene util crypto
 headers = api.h pal_crypto.h
 

+ 0 - 5
Pal/lib/api.h

@@ -62,11 +62,6 @@ void *malloc(size_t size);
 void free(void *ptr);
 void *calloc(size_t nmemb, size_t size);
 
-/* Libc memory allocation functions. stdlib.h. */
-void *malloc(size_t size);
-void free(void *ptr);
-void *calloc(size_t nmemb, size_t size);
-
 /* Some useful macro */
 /* force failure if str is not a static string */
 #define force_static(str)   ("" str "")

+ 1 - 0
Pal/lib/crypto/adapters/mbedtls_adapter.c

@@ -13,6 +13,7 @@
    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 <errno.h>
 #include <stdint.h>
 #include <limits.h>
 #include "pal.h"

+ 6 - 1
Pal/lib/crypto/adapters/mbedtls_dh.c

@@ -15,12 +15,16 @@
    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 <errno.h>
+#include <limits.h>
 #include "pal.h"
-#include "pal_crypto.h"
 #include "pal_error.h"
+#include "pal_crypto.h"
 #include "pal_debug.h"
 #include "assert.h"
 
+#define BITS_PER_BYTE 8
+
 /* This is declared in pal_internal.h, but that can't be included here. */
 int _DkRandomBitsRead(void *buffer, int size);
 
@@ -103,3 +107,4 @@ void lib_DhFinal(LIB_DH_CONTEXT *context)
     /* This call zeros out context for us. */
     mbedtls_dhm_free(context);
 }
+

+ 0 - 55
Pal/lib/crypto/adapters/wolfssl_adapter.c

@@ -1,55 +0,0 @@
-/* This file is part of Graphene Library OS.
-
-   Graphene Library OS 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.
-
-   Graphene Library OS 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 <limits.h>
-#include "pal.h"
-#include "pal_crypto.h"
-#include "pal_error.h"
-#include "crypto/wolfssl/sha256.h"
-#include "crypto/wolfssl/cmac.h"
-#include "crypto/wolfssl/rsa.h"
-
-int lib_SHA256Init(LIB_SHA256_CONTEXT *context)
-{
-    return SHA256Init(context);
-}
-
-int lib_SHA256Update(LIB_SHA256_CONTEXT *context, const uint8_t *data,
-                   uint64_t len)
-{
-    /* uint64_t is a 64-bit value, but SHA256Update takes a 32-bit len. */
-    if (len > UINT32_MAX) {
-        return -PAL_ERROR_INVAL;
-    }
-    return SHA256Update(context, data, len);
-}
-
-int lib_SHA256Final(LIB_SHA256_CONTEXT *context, uint8_t *output)
-{
-    return SHA256Final(context, output);
-}
-
-int lib_AESCMAC(const uint8_t *key, uint64_t key_len, const uint8_t *input,
-                uint64_t input_len, uint8_t *mac, uint64_t mac_len)
-{
-    /* The old code only supports 128-bit AES CMAC, and length is a 32-bit
-     * value. */
-    if (key_len != 16 || input_len > INT32_MAX || mac_len < 16) {
-        return -PAL_ERROR_INVAL;
-    }
-    AES_CMAC((unsigned char *) key, (unsigned char *) input, input_len, mac);
-    return 0;
-}

+ 0 - 1719
Pal/lib/crypto/wolfssl/aes.c

@@ -1,1719 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* aes.c
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#include "crypto/wolfssl/aes.h"
-#include "crypto/wolfssl/error-crypt.h"
-#include "api.h"
-
-#define XMEMSET memset
-#define XMEMCPY memcpy
-#define XMEMCMP memcmp
-
-#ifndef rotlFixed
-static inline word32 rotlFixed(word32 x, word32 y)
-{
-    return (x << y) | (x >> (sizeof(y) * 8 - y));
-}
-#endif /* rotlFixed */
-
-#ifndef rotrFixed
-static inline word32 rotrFixed(word32 x, word32 y)
-{
-    return (x >> y) | (x << (sizeof(y) * 8 - y));
-}
-#endif /* rotrFixed */
-
-static inline word32 ByteReverseWord32(word32 value)
-{
-    /* 6 instructions with rotate instruction, 8 without */
-    value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
-    return rotlFixed(value, 16U);
-}
-
-static inline void ByteReverseWords(word32 *out, const word32 *in,
-                                    word32 byteCount)
-{
-    word32 count = byteCount/(word32)sizeof(word32), i;
-
-    for (i = 0; i < count; i++)
-        out[i] = ByteReverseWord32(in[i]);
-}
-
-static inline void XorWords(word *r, const word *a, word32 n)
-{
-    word32 i;
-
-    for (i = 0; i < n; i++) r[i] ^= a[i];
-}
-
-static inline void xorbuf(void *buf, const void *mask, word32 count)
-{
-    if (((word)buf | (word) mask | count) % WORD_SIZE == 0)
-        XorWords( (word *) buf,
-                  (const word *) mask, count / WORD_SIZE);
-    else {
-        word32 i;
-        byte *       b = (byte*)buf;
-        const byte* m = (const byte *)mask;
-
-        for (i = 0; i < count; i++) b[i] ^= m[i];
-    }
-}
-
-static const word32 rcon[] = {
-    0x01000000, 0x02000000, 0x04000000, 0x08000000,
-    0x10000000, 0x20000000, 0x40000000, 0x80000000,
-    0x1B000000, 0x36000000,
-    /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
-};
-
-static const word32 Te[5][256] = {
-{
-    0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU,
-    0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U,
-    0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU,
-    0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU,
-    0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U,
-    0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU,
-    0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU,
-    0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU,
-    0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU,
-    0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU,
-    0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U,
-    0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU,
-    0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU,
-    0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U,
-    0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU,
-    0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU,
-    0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU,
-    0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU,
-    0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU,
-    0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U,
-    0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU,
-    0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU,
-    0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU,
-    0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU,
-    0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U,
-    0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U,
-    0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U,
-    0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U,
-    0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU,
-    0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U,
-    0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U,
-    0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU,
-    0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU,
-    0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U,
-    0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U,
-    0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U,
-    0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU,
-    0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U,
-    0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU,
-    0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U,
-    0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU,
-    0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U,
-    0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U,
-    0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU,
-    0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U,
-    0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U,
-    0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U,
-    0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U,
-    0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U,
-    0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U,
-    0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U,
-    0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U,
-    0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU,
-    0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U,
-    0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U,
-    0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U,
-    0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U,
-    0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U,
-    0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U,
-    0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU,
-    0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U,
-    0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U,
-    0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U,
-    0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU,
-},
-{
-    0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU,
-    0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U,
-    0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU,
-    0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U,
-    0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU,
-    0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U,
-    0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU,
-    0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U,
-    0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U,
-    0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU,
-    0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U,
-    0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U,
-    0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U,
-    0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU,
-    0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U,
-    0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U,
-    0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU,
-    0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U,
-    0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U,
-    0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U,
-    0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU,
-    0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU,
-    0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U,
-    0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU,
-    0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU,
-    0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U,
-    0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU,
-    0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U,
-    0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU,
-    0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U,
-    0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U,
-    0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U,
-    0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU,
-    0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U,
-    0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU,
-    0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U,
-    0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU,
-    0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U,
-    0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U,
-    0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU,
-    0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU,
-    0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU,
-    0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U,
-    0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U,
-    0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU,
-    0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U,
-    0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU,
-    0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U,
-    0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU,
-    0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U,
-    0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU,
-    0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU,
-    0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U,
-    0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU,
-    0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U,
-    0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU,
-    0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U,
-    0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U,
-    0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U,
-    0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU,
-    0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU,
-    0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U,
-    0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU,
-    0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U,
-},
-{
-    0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU,
-    0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U,
-    0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU,
-    0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U,
-    0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU,
-    0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U,
-    0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU,
-    0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U,
-    0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U,
-    0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU,
-    0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U,
-    0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U,
-    0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U,
-    0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU,
-    0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U,
-    0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U,
-    0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU,
-    0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U,
-    0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U,
-    0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U,
-    0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU,
-    0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU,
-    0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U,
-    0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU,
-    0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU,
-    0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U,
-    0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU,
-    0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U,
-    0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU,
-    0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U,
-    0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U,
-    0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U,
-    0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU,
-    0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U,
-    0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU,
-    0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U,
-    0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU,
-    0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U,
-    0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U,
-    0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU,
-    0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU,
-    0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU,
-    0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U,
-    0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U,
-    0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU,
-    0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U,
-    0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU,
-    0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U,
-    0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU,
-    0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U,
-    0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU,
-    0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU,
-    0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U,
-    0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU,
-    0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U,
-    0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU,
-    0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U,
-    0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U,
-    0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U,
-    0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU,
-    0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU,
-    0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U,
-    0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU,
-    0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U,
-},
-{
-    0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U,
-    0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U,
-    0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U,
-    0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU,
-    0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU,
-    0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU,
-    0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U,
-    0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU,
-    0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU,
-    0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U,
-    0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U,
-    0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU,
-    0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU,
-    0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU,
-    0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU,
-    0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU,
-    0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U,
-    0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU,
-    0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU,
-    0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U,
-    0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U,
-    0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U,
-    0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U,
-    0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U,
-    0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU,
-    0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U,
-    0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU,
-    0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU,
-    0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U,
-    0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U,
-    0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U,
-    0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU,
-    0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U,
-    0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU,
-    0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU,
-    0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U,
-    0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U,
-    0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU,
-    0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U,
-    0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU,
-    0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U,
-    0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U,
-    0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U,
-    0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U,
-    0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU,
-    0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U,
-    0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU,
-    0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U,
-    0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU,
-    0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U,
-    0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU,
-    0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU,
-    0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU,
-    0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU,
-    0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U,
-    0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U,
-    0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U,
-    0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U,
-    0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U,
-    0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U,
-    0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU,
-    0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U,
-    0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU,
-    0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU,
-},
-{
-    0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU,
-    0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U,
-    0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU,
-    0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U,
-    0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU,
-    0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U,
-    0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU,
-    0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U,
-    0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U,
-    0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU,
-    0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U,
-    0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U,
-    0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U,
-    0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU,
-    0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U,
-    0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U,
-    0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU,
-    0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U,
-    0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U,
-    0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U,
-    0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU,
-    0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU,
-    0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U,
-    0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU,
-    0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU,
-    0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U,
-    0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU,
-    0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U,
-    0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU,
-    0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U,
-    0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U,
-    0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U,
-    0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU,
-    0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U,
-    0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU,
-    0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U,
-    0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU,
-    0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U,
-    0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U,
-    0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU,
-    0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU,
-    0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU,
-    0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U,
-    0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U,
-    0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU,
-    0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U,
-    0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU,
-    0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U,
-    0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU,
-    0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U,
-    0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU,
-    0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU,
-    0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U,
-    0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU,
-    0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U,
-    0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU,
-    0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U,
-    0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U,
-    0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U,
-    0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU,
-    0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU,
-    0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U,
-    0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU,
-    0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U,
-}
-};
-
-static const word32 Td[5][256] = {
-{
-    0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U,
-    0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U,
-    0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U,
-    0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU,
-    0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U,
-    0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U,
-    0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU,
-    0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U,
-    0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU,
-    0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U,
-    0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U,
-    0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U,
-    0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U,
-    0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU,
-    0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U,
-    0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU,
-    0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U,
-    0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU,
-    0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U,
-    0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U,
-    0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U,
-    0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU,
-    0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U,
-    0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU,
-    0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U,
-    0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU,
-    0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U,
-    0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU,
-    0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU,
-    0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U,
-    0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU,
-    0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U,
-    0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU,
-    0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U,
-    0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U,
-    0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U,
-    0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU,
-    0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U,
-    0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U,
-    0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU,
-    0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U,
-    0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U,
-    0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U,
-    0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U,
-    0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U,
-    0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU,
-    0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U,
-    0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U,
-    0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U,
-    0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U,
-    0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U,
-    0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU,
-    0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU,
-    0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU,
-    0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU,
-    0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U,
-    0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U,
-    0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU,
-    0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU,
-    0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U,
-    0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU,
-    0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U,
-    0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U,
-    0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U,
-},
-{
-    0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU,
-    0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U,
-    0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU,
-    0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U,
-    0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U,
-    0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U,
-    0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U,
-    0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U,
-    0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U,
-    0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU,
-    0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU,
-    0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU,
-    0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U,
-    0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU,
-    0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U,
-    0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U,
-    0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U,
-    0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU,
-    0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU,
-    0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U,
-    0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU,
-    0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U,
-    0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU,
-    0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU,
-    0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U,
-    0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U,
-    0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U,
-    0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU,
-    0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U,
-    0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU,
-    0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U,
-    0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U,
-    0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U,
-    0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU,
-    0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U,
-    0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U,
-    0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U,
-    0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U,
-    0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U,
-    0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U,
-    0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU,
-    0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU,
-    0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U,
-    0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU,
-    0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U,
-    0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU,
-    0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU,
-    0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U,
-    0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU,
-    0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U,
-    0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U,
-    0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U,
-    0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U,
-    0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U,
-    0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U,
-    0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U,
-    0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU,
-    0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U,
-    0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U,
-    0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU,
-    0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U,
-    0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U,
-    0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U,
-    0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U,
-},
-{
-    0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U,
-    0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U,
-    0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U,
-    0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U,
-    0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU,
-    0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U,
-    0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U,
-    0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U,
-    0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U,
-    0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU,
-    0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U,
-    0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U,
-    0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU,
-    0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U,
-    0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U,
-    0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U,
-    0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U,
-    0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U,
-    0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U,
-    0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU,
-
-    0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U,
-    0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U,
-    0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U,
-    0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U,
-    0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U,
-    0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU,
-    0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU,
-    0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U,
-    0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU,
-    0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U,
-    0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU,
-    0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU,
-    0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU,
-    0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU,
-    0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U,
-    0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U,
-    0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U,
-    0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U,
-    0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U,
-    0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U,
-    0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U,
-    0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU,
-    0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU,
-    0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U,
-    0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U,
-    0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU,
-    0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU,
-    0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U,
-    0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U,
-    0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U,
-    0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U,
-    0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U,
-    0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U,
-    0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U,
-    0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU,
-    0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U,
-    0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U,
-    0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U,
-    0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U,
-    0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U,
-    0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U,
-    0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU,
-    0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U,
-    0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U,
-},
-{
-    0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU,
-    0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU,
-    0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U,
-    0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U,
-    0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU,
-    0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU,
-    0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U,
-    0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU,
-    0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U,
-    0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU,
-    0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U,
-    0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U,
-    0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U,
-    0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U,
-    0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U,
-    0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU,
-    0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU,
-    0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U,
-    0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U,
-    0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU,
-    0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU,
-    0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U,
-    0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U,
-    0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U,
-    0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U,
-    0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU,
-    0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U,
-    0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U,
-    0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU,
-    0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU,
-    0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U,
-    0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U,
-    0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U,
-    0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU,
-    0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U,
-    0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U,
-    0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U,
-    0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U,
-    0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U,
-    0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U,
-    0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U,
-    0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU,
-    0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U,
-    0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U,
-    0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU,
-    0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU,
-    0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U,
-    0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU,
-    0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U,
-    0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U,
-    0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U,
-    0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U,
-    0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U,
-    0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U,
-    0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU,
-    0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU,
-    0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU,
-    0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU,
-    0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U,
-    0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U,
-    0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U,
-    0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU,
-    0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U,
-    0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U,
-},
-{
-    0x52525252U, 0x09090909U, 0x6a6a6a6aU, 0xd5d5d5d5U,
-    0x30303030U, 0x36363636U, 0xa5a5a5a5U, 0x38383838U,
-    0xbfbfbfbfU, 0x40404040U, 0xa3a3a3a3U, 0x9e9e9e9eU,
-    0x81818181U, 0xf3f3f3f3U, 0xd7d7d7d7U, 0xfbfbfbfbU,
-    0x7c7c7c7cU, 0xe3e3e3e3U, 0x39393939U, 0x82828282U,
-    0x9b9b9b9bU, 0x2f2f2f2fU, 0xffffffffU, 0x87878787U,
-    0x34343434U, 0x8e8e8e8eU, 0x43434343U, 0x44444444U,
-    0xc4c4c4c4U, 0xdedededeU, 0xe9e9e9e9U, 0xcbcbcbcbU,
-    0x54545454U, 0x7b7b7b7bU, 0x94949494U, 0x32323232U,
-    0xa6a6a6a6U, 0xc2c2c2c2U, 0x23232323U, 0x3d3d3d3dU,
-    0xeeeeeeeeU, 0x4c4c4c4cU, 0x95959595U, 0x0b0b0b0bU,
-    0x42424242U, 0xfafafafaU, 0xc3c3c3c3U, 0x4e4e4e4eU,
-    0x08080808U, 0x2e2e2e2eU, 0xa1a1a1a1U, 0x66666666U,
-    0x28282828U, 0xd9d9d9d9U, 0x24242424U, 0xb2b2b2b2U,
-    0x76767676U, 0x5b5b5b5bU, 0xa2a2a2a2U, 0x49494949U,
-    0x6d6d6d6dU, 0x8b8b8b8bU, 0xd1d1d1d1U, 0x25252525U,
-    0x72727272U, 0xf8f8f8f8U, 0xf6f6f6f6U, 0x64646464U,
-    0x86868686U, 0x68686868U, 0x98989898U, 0x16161616U,
-    0xd4d4d4d4U, 0xa4a4a4a4U, 0x5c5c5c5cU, 0xccccccccU,
-    0x5d5d5d5dU, 0x65656565U, 0xb6b6b6b6U, 0x92929292U,
-    0x6c6c6c6cU, 0x70707070U, 0x48484848U, 0x50505050U,
-    0xfdfdfdfdU, 0xededededU, 0xb9b9b9b9U, 0xdadadadaU,
-    0x5e5e5e5eU, 0x15151515U, 0x46464646U, 0x57575757U,
-    0xa7a7a7a7U, 0x8d8d8d8dU, 0x9d9d9d9dU, 0x84848484U,
-    0x90909090U, 0xd8d8d8d8U, 0xababababU, 0x00000000U,
-    0x8c8c8c8cU, 0xbcbcbcbcU, 0xd3d3d3d3U, 0x0a0a0a0aU,
-    0xf7f7f7f7U, 0xe4e4e4e4U, 0x58585858U, 0x05050505U,
-    0xb8b8b8b8U, 0xb3b3b3b3U, 0x45454545U, 0x06060606U,
-    0xd0d0d0d0U, 0x2c2c2c2cU, 0x1e1e1e1eU, 0x8f8f8f8fU,
-    0xcacacacaU, 0x3f3f3f3fU, 0x0f0f0f0fU, 0x02020202U,
-    0xc1c1c1c1U, 0xafafafafU, 0xbdbdbdbdU, 0x03030303U,
-    0x01010101U, 0x13131313U, 0x8a8a8a8aU, 0x6b6b6b6bU,
-    0x3a3a3a3aU, 0x91919191U, 0x11111111U, 0x41414141U,
-    0x4f4f4f4fU, 0x67676767U, 0xdcdcdcdcU, 0xeaeaeaeaU,
-    0x97979797U, 0xf2f2f2f2U, 0xcfcfcfcfU, 0xcecececeU,
-    0xf0f0f0f0U, 0xb4b4b4b4U, 0xe6e6e6e6U, 0x73737373U,
-    0x96969696U, 0xacacacacU, 0x74747474U, 0x22222222U,
-    0xe7e7e7e7U, 0xadadadadU, 0x35353535U, 0x85858585U,
-    0xe2e2e2e2U, 0xf9f9f9f9U, 0x37373737U, 0xe8e8e8e8U,
-    0x1c1c1c1cU, 0x75757575U, 0xdfdfdfdfU, 0x6e6e6e6eU,
-    0x47474747U, 0xf1f1f1f1U, 0x1a1a1a1aU, 0x71717171U,
-    0x1d1d1d1dU, 0x29292929U, 0xc5c5c5c5U, 0x89898989U,
-    0x6f6f6f6fU, 0xb7b7b7b7U, 0x62626262U, 0x0e0e0e0eU,
-    0xaaaaaaaaU, 0x18181818U, 0xbebebebeU, 0x1b1b1b1bU,
-    0xfcfcfcfcU, 0x56565656U, 0x3e3e3e3eU, 0x4b4b4b4bU,
-    0xc6c6c6c6U, 0xd2d2d2d2U, 0x79797979U, 0x20202020U,
-    0x9a9a9a9aU, 0xdbdbdbdbU, 0xc0c0c0c0U, 0xfefefefeU,
-    0x78787878U, 0xcdcdcdcdU, 0x5a5a5a5aU, 0xf4f4f4f4U,
-    0x1f1f1f1fU, 0xddddddddU, 0xa8a8a8a8U, 0x33333333U,
-    0x88888888U, 0x07070707U, 0xc7c7c7c7U, 0x31313131U,
-    0xb1b1b1b1U, 0x12121212U, 0x10101010U, 0x59595959U,
-    0x27272727U, 0x80808080U, 0xececececU, 0x5f5f5f5fU,
-    0x60606060U, 0x51515151U, 0x7f7f7f7fU, 0xa9a9a9a9U,
-    0x19191919U, 0xb5b5b5b5U, 0x4a4a4a4aU, 0x0d0d0d0dU,
-    0x2d2d2d2dU, 0xe5e5e5e5U, 0x7a7a7a7aU, 0x9f9f9f9fU,
-    0x93939393U, 0xc9c9c9c9U, 0x9c9c9c9cU, 0xefefefefU,
-    0xa0a0a0a0U, 0xe0e0e0e0U, 0x3b3b3b3bU, 0x4d4d4d4dU,
-    0xaeaeaeaeU, 0x2a2a2a2aU, 0xf5f5f5f5U, 0xb0b0b0b0U,
-    0xc8c8c8c8U, 0xebebebebU, 0xbbbbbbbbU, 0x3c3c3c3cU,
-    0x83838383U, 0x53535353U, 0x99999999U, 0x61616161U,
-    0x17171717U, 0x2b2b2b2bU, 0x04040404U, 0x7e7e7e7eU,
-    0xbabababaU, 0x77777777U, 0xd6d6d6d6U, 0x26262626U,
-    0xe1e1e1e1U, 0x69696969U, 0x14141414U, 0x63636363U,
-    0x55555555U, 0x21212121U, 0x0c0c0c0cU, 0x7d7d7d7dU,
-}
-};
-
-#define GETBYTE(x, y) (word32)((byte)((x) >> (8  *(y))))
-
-#if USE_AES_NI == 1
-
-#include <wmmintrin.h>
-
-/* tell C compiler these are asm functions in case any mix up of ABI underscore
-   prefix between clang/gcc/llvm etc */
-void AES_CBC_encrypt(const unsigned char* in, unsigned char* out,
-                     unsigned char* ivec, unsigned long length,
-                     const unsigned char* KS, int nr);
-
-
-void AES_CBC_decrypt(const unsigned char* in, unsigned char* out,
-                     unsigned char* ivec, unsigned long length,
-                     const unsigned char* KS, int nr);
-
-void AES_ECB_encrypt(const unsigned char* in, unsigned char* out,
-                     unsigned long length, const unsigned char* KS, int nr);
-
-
-void AES_ECB_decrypt(const unsigned char* in, unsigned char* out,
-                     unsigned long length, const unsigned char* KS, int nr);
-
-void AES_128_Key_Expansion(const unsigned char* userkey,
-                           unsigned char* key_schedule);
-
-void AES_192_Key_Expansion(const unsigned char* userkey,
-                           unsigned char* key_schedule);
-
-void AES_256_Key_Expansion(const unsigned char* userkey,
-                           unsigned char* key_schedule);
-
-
-static int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
-                               AES* aes)
-{
-    if (!userKey || !aes)
-        return BAD_FUNC_ARG;
-
-    if (bits == 128) {
-       AES_128_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 10;
-       return 0;
-    }
-    else if (bits == 192) {
-       AES_192_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 12;
-       return 0;
-    }
-    else if (bits == 256) {
-       AES_256_Key_Expansion (userKey,(byte*)aes->key); aes->rounds = 14;
-       return 0;
-    }
-    return BAD_FUNC_ARG;
-}
-
-
-static int AES_set_decrypt_key(const unsigned char* userKey, const int bits,
-                               AES* aes)
-{
-    int nr;
-    AES temp_key;
-    __m128i *Key_Schedule = (__m128i*)aes->key;
-    __m128i *Temp_Key_Schedule = (__m128i*)temp_key.key;
-
-    if (!userKey || !aes)
-        return BAD_FUNC_ARG;
-
-    if (AES_set_encrypt_key(userKey,bits,&temp_key) == BAD_FUNC_ARG)
-        return BAD_FUNC_ARG;
-
-    nr = temp_key.rounds;
-    aes->rounds = nr;
-
-    Key_Schedule[nr] = Temp_Key_Schedule[0];
-    Key_Schedule[nr-1] = _mm_aesimc_si128(Temp_Key_Schedule[1]);
-    Key_Schedule[nr-2] = _mm_aesimc_si128(Temp_Key_Schedule[2]);
-    Key_Schedule[nr-3] = _mm_aesimc_si128(Temp_Key_Schedule[3]);
-    Key_Schedule[nr-4] = _mm_aesimc_si128(Temp_Key_Schedule[4]);
-    Key_Schedule[nr-5] = _mm_aesimc_si128(Temp_Key_Schedule[5]);
-    Key_Schedule[nr-6] = _mm_aesimc_si128(Temp_Key_Schedule[6]);
-    Key_Schedule[nr-7] = _mm_aesimc_si128(Temp_Key_Schedule[7]);
-    Key_Schedule[nr-8] = _mm_aesimc_si128(Temp_Key_Schedule[8]);
-    Key_Schedule[nr-9] = _mm_aesimc_si128(Temp_Key_Schedule[9]);
-
-    if(nr>10) {
-        Key_Schedule[nr-10] = _mm_aesimc_si128(Temp_Key_Schedule[10]);
-        Key_Schedule[nr-11] = _mm_aesimc_si128(Temp_Key_Schedule[11]);
-    }
-
-    if(nr>12) {
-        Key_Schedule[nr-12] = _mm_aesimc_si128(Temp_Key_Schedule[12]);
-        Key_Schedule[nr-13] = _mm_aesimc_si128(Temp_Key_Schedule[13]);
-    }
-
-    Key_Schedule[0] = Temp_Key_Schedule[nr];
-
-    return 0;
-}
-
-#endif /* USE_AES_NI == 1 */
-
-void AESEncrypt(AES *aes, const byte *inBlock, byte *outBlock)
-{
-    word32 s0, s1, s2, s3;
-    word32 t0, t1, t2, t3;
-    word32 r = aes->rounds >> 1;
-
-    const word32 *rk = aes->key;
-    if (r > 7 || r == 0)
-        return;  /* stop instead of segfaulting, set up your keys! */
-
-#if USE_AES_NI == 1
-    /* check alignment, decrypt doesn't need alignment */
-    if (!((uint64_t) inBlock % 16)) {
-        AES_ECB_encrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
-                        aes->rounds);
-        return;
-    }
-#endif
-    /*
-      *map byte array block to cipher state
-      *and add initial round key:
-     */
-    XMEMCPY(&s0, inBlock,                  sizeof(s0));
-    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
-    XMEMCPY(&s2, inBlock + 2  *sizeof(s0), sizeof(s2));
-    XMEMCPY(&s3, inBlock + 3  *sizeof(s0), sizeof(s3));
-
-    s0 = ByteReverseWord32(s0);
-    s1 = ByteReverseWord32(s1);
-    s2 = ByteReverseWord32(s2);
-    s3 = ByteReverseWord32(s3);
-
-    s0 ^= rk[0];
-    s1 ^= rk[1];
-    s2 ^= rk[2];
-    s3 ^= rk[3];
-
-    /*
-      *Nr - 1 full rounds:
-     */
-
-    for (;;) {
-        t0 =
-            Te[0][GETBYTE(s0, 3)]  ^
-            Te[1][GETBYTE(s1, 2)]  ^
-            Te[2][GETBYTE(s2, 1)]  ^
-            Te[3][GETBYTE(s3, 0)]  ^
-            rk[4];
-        t1 =
-            Te[0][GETBYTE(s1, 3)]  ^
-            Te[1][GETBYTE(s2, 2)]  ^
-            Te[2][GETBYTE(s3, 1)]  ^
-            Te[3][GETBYTE(s0, 0)]  ^
-            rk[5];
-        t2 =
-            Te[0][GETBYTE(s2, 3)] ^
-            Te[1][GETBYTE(s3, 2)]  ^
-            Te[2][GETBYTE(s0, 1)]  ^
-            Te[3][GETBYTE(s1, 0)]  ^
-            rk[6];
-        t3 =
-            Te[0][GETBYTE(s3, 3)] ^
-            Te[1][GETBYTE(s0, 2)]  ^
-            Te[2][GETBYTE(s1, 1)]  ^
-            Te[3][GETBYTE(s2, 0)]  ^
-            rk[7];
-
-        rk += 8;
-        if (--r == 0) {
-            break;
-        }
-
-        s0 =
-            Te[0][GETBYTE(t0, 3)] ^
-            Te[1][GETBYTE(t1, 2)] ^
-            Te[2][GETBYTE(t2, 1)] ^
-            Te[3][GETBYTE(t3, 0)] ^
-            rk[0];
-        s1 =
-            Te[0][GETBYTE(t1, 3)] ^
-            Te[1][GETBYTE(t2, 2)] ^
-            Te[2][GETBYTE(t3, 1)] ^
-            Te[3][GETBYTE(t0, 0)] ^
-            rk[1];
-        s2 =
-            Te[0][GETBYTE(t2, 3)] ^
-            Te[1][GETBYTE(t3, 2)] ^
-            Te[2][GETBYTE(t0, 1)] ^
-            Te[3][GETBYTE(t1, 0)] ^
-            rk[2];
-        s3 =
-            Te[0][GETBYTE(t3, 3)] ^
-            Te[1][GETBYTE(t0, 2)] ^
-            Te[2][GETBYTE(t1, 1)] ^
-            Te[3][GETBYTE(t2, 0)] ^
-            rk[3];
-    }
-
-    /*
-      *apply last round and
-      *map cipher state to byte array block:
-     */
-
-    s0 =
-        (Te[4][GETBYTE(t0, 3)] & 0xff000000) ^
-        (Te[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
-        (Te[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
-        (Te[4][GETBYTE(t3, 0)] & 0x000000ff) ^
-        rk[0];
-    s1 =
-        (Te[4][GETBYTE(t1, 3)] & 0xff000000) ^
-        (Te[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
-        (Te[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
-        (Te[4][GETBYTE(t0, 0)] & 0x000000ff) ^
-        rk[1];
-    s2 =
-        (Te[4][GETBYTE(t2, 3)] & 0xff000000) ^
-        (Te[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
-        (Te[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
-        (Te[4][GETBYTE(t1, 0)] & 0x000000ff) ^
-        rk[2];
-    s3 =
-        (Te[4][GETBYTE(t3, 3)] & 0xff000000) ^
-        (Te[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
-        (Te[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
-        (Te[4][GETBYTE(t2, 0)] & 0x000000ff) ^
-        rk[3];
-
-    /* write out */
-    s0 = ByteReverseWord32(s0);
-    s1 = ByteReverseWord32(s1);
-    s2 = ByteReverseWord32(s2);
-    s3 = ByteReverseWord32(s3);
-
-    XMEMCPY(outBlock,                  &s0, sizeof(s0));
-    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
-    XMEMCPY(outBlock + 2 * sizeof(s0), &s2, sizeof(s2));
-    XMEMCPY(outBlock + 3 * sizeof(s0), &s3, sizeof(s3));
-}
-
-void AESDecrypt(AES *aes, const byte *inBlock, byte *outBlock)
-{
-    word32 s0, s1, s2, s3;
-    word32 t0, t1, t2, t3;
-    word32 r = aes->rounds >> 1;
-
-    const word32 *rk = aes->key;
-    if (r > 7 || r == 0)
-        return;  /* stop instead of segfaulting, set up your keys! */
-
-#if USE_AES_NI == 1
-    /* if input and output same will overwrite input iv */
-    XMEMCPY(aes->tmp, inBlock, AES_BLOCK_SIZE);
-    AES_ECB_decrypt(inBlock, outBlock, AES_BLOCK_SIZE, (byte*)aes->key,
-                    aes->rounds);
-    return;
-#endif
-
-    /*
-      *map byte array block to cipher state
-      *and add initial round key:
-     */
-    XMEMCPY(&s0, inBlock,                  sizeof(s0));
-    XMEMCPY(&s1, inBlock + sizeof(s0),     sizeof(s1));
-    XMEMCPY(&s2, inBlock + 2  *sizeof(s0), sizeof(s2));
-    XMEMCPY(&s3, inBlock + 3  *sizeof(s0), sizeof(s3));
-
-    s0 = ByteReverseWord32(s0);
-    s1 = ByteReverseWord32(s1);
-    s2 = ByteReverseWord32(s2);
-    s3 = ByteReverseWord32(s3);
-
-    s0 ^= rk[0];
-    s1 ^= rk[1];
-    s2 ^= rk[2];
-    s3 ^= rk[3];
-
-    /*
-      *Nr - 1 full rounds:
-     */
-
-    for (;;) {
-        t0 =
-            Td[0][GETBYTE(s0, 3)] ^
-            Td[1][GETBYTE(s3, 2)] ^
-            Td[2][GETBYTE(s2, 1)] ^
-            Td[3][GETBYTE(s1, 0)] ^
-            rk[4];
-        t1 =
-            Td[0][GETBYTE(s1, 3)] ^
-            Td[1][GETBYTE(s0, 2)] ^
-            Td[2][GETBYTE(s3, 1)] ^
-            Td[3][GETBYTE(s2, 0)] ^
-            rk[5];
-        t2 =
-            Td[0][GETBYTE(s2, 3)] ^
-            Td[1][GETBYTE(s1, 2)] ^
-            Td[2][GETBYTE(s0, 1)] ^
-            Td[3][GETBYTE(s3, 0)] ^
-            rk[6];
-        t3 =
-            Td[0][GETBYTE(s3, 3)] ^
-            Td[1][GETBYTE(s2, 2)] ^
-            Td[2][GETBYTE(s1, 1)] ^
-            Td[3][GETBYTE(s0, 0)] ^
-            rk[7];
-
-        rk += 8;
-        if (--r == 0) {
-            break;
-        }
-
-        s0 =
-            Td[0][GETBYTE(t0, 3)] ^
-            Td[1][GETBYTE(t3, 2)] ^
-            Td[2][GETBYTE(t2, 1)] ^
-            Td[3][GETBYTE(t1, 0)] ^
-            rk[0];
-        s1 =
-            Td[0][GETBYTE(t1, 3)] ^
-            Td[1][GETBYTE(t0, 2)] ^
-            Td[2][GETBYTE(t3, 1)] ^
-            Td[3][GETBYTE(t2, 0)] ^
-            rk[1];
-        s2 =
-            Td[0][GETBYTE(t2, 3)] ^
-            Td[1][GETBYTE(t1, 2)] ^
-            Td[2][GETBYTE(t0, 1)] ^
-            Td[3][GETBYTE(t3, 0)] ^
-            rk[2];
-        s3 =
-            Td[0][GETBYTE(t3, 3)] ^
-            Td[1][GETBYTE(t2, 2)] ^
-            Td[2][GETBYTE(t1, 1)] ^
-            Td[3][GETBYTE(t0, 0)] ^
-            rk[3];
-    }
-    /*
-      *apply last round and
-      *map cipher state to byte array block:
-     */
-    s0 =
-        (Td[4][GETBYTE(t0, 3)] & 0xff000000) ^
-        (Td[4][GETBYTE(t3, 2)] & 0x00ff0000) ^
-        (Td[4][GETBYTE(t2, 1)] & 0x0000ff00) ^
-        (Td[4][GETBYTE(t1, 0)] & 0x000000ff) ^
-        rk[0];
-    s1 =
-        (Td[4][GETBYTE(t1, 3)] & 0xff000000) ^
-        (Td[4][GETBYTE(t0, 2)] & 0x00ff0000) ^
-        (Td[4][GETBYTE(t3, 1)] & 0x0000ff00) ^
-        (Td[4][GETBYTE(t2, 0)] & 0x000000ff) ^
-        rk[1];
-    s2 =
-        (Td[4][GETBYTE(t2, 3)] & 0xff000000) ^
-        (Td[4][GETBYTE(t1, 2)] & 0x00ff0000) ^
-        (Td[4][GETBYTE(t0, 1)] & 0x0000ff00) ^
-        (Td[4][GETBYTE(t3, 0)] & 0x000000ff) ^
-        rk[2];
-    s3 =
-        (Td[4][GETBYTE(t3, 3)] & 0xff000000) ^
-        (Td[4][GETBYTE(t2, 2)] & 0x00ff0000) ^
-        (Td[4][GETBYTE(t1, 1)] & 0x0000ff00) ^
-        (Td[4][GETBYTE(t0, 0)] & 0x000000ff) ^
-        rk[3];
-
-    /* write out */
-    s0 = ByteReverseWord32(s0);
-    s1 = ByteReverseWord32(s1);
-    s2 = ByteReverseWord32(s2);
-    s3 = ByteReverseWord32(s3);
-
-    XMEMCPY(outBlock,                  &s0, sizeof(s0));
-    XMEMCPY(outBlock + sizeof(s0),     &s1, sizeof(s1));
-    XMEMCPY(outBlock + 2  *sizeof(s0), &s2, sizeof(s2));
-    XMEMCPY(outBlock + 3  *sizeof(s0), &s3, sizeof(s3));
-}
-
-static int AESSetKeyLocal(AES *aes, const byte *userKey, word32 keylen,
-            const byte *iv, int dir)
-{
-    word32 temp, *rk = aes->key;
-    unsigned int i = 0;
-
-    aes->left = 0;
-    aes->rounds = keylen/4 + 6;
-
-    XMEMCPY(rk, userKey, keylen);
-    ByteReverseWords(rk, rk, keylen);
-
-    switch(keylen)
-    {
-    case 16:
-        while (1)
-        {
-            temp  = rk[3];
-            rk[4] = rk[0] ^
-                (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
-                rcon[i];
-            rk[5] = rk[1] ^ rk[4];
-            rk[6] = rk[2] ^ rk[5];
-            rk[7] = rk[3] ^ rk[6];
-            if (++i == 10)
-                break;
-            rk += 4;
-        }
-        break;
-
-    case 24:
-        /* for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack */
-        while (1)
-        {
-            temp = rk[ 5];
-            rk[ 6] = rk[ 0] ^
-                (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
-                rcon[i];
-            rk[ 7] = rk[ 1] ^ rk[ 6];
-            rk[ 8] = rk[ 2] ^ rk[ 7];
-            rk[ 9] = rk[ 3] ^ rk[ 8];
-            if (++i == 8)
-                break;
-            rk[10] = rk[ 4] ^ rk[ 9];
-            rk[11] = rk[ 5] ^ rk[10];
-            rk += 6;
-        }
-        break;
-
-    case 32:
-        while (1)
-        {
-            temp = rk[ 7];
-            rk[ 8] = rk[ 0] ^
-                (Te[4][GETBYTE(temp, 2)] & 0xff000000) ^
-                (Te[4][GETBYTE(temp, 1)] & 0x00ff0000) ^
-                (Te[4][GETBYTE(temp, 0)] & 0x0000ff00) ^
-                (Te[4][GETBYTE(temp, 3)] & 0x000000ff) ^
-                rcon[i];
-            rk[ 9] = rk[ 1] ^ rk[ 8];
-            rk[10] = rk[ 2] ^ rk[ 9];
-            rk[11] = rk[ 3] ^ rk[10];
-            if (++i == 7)
-                break;
-            temp = rk[11];
-            rk[12] = rk[ 4] ^
-                (Te[4][GETBYTE(temp, 3)] & 0xff000000) ^
-                (Te[4][GETBYTE(temp, 2)] & 0x00ff0000) ^
-                (Te[4][GETBYTE(temp, 1)] & 0x0000ff00) ^
-                (Te[4][GETBYTE(temp, 0)] & 0x000000ff);
-            rk[13] = rk[ 5] ^ rk[12];
-            rk[14] = rk[ 6] ^ rk[13];
-            rk[15] = rk[ 7] ^ rk[14];
-
-            rk += 8;
-        }
-        break;
-
-    default:
-        return BAD_FUNC_ARG;
-    }
-
-    if (dir == AES_DECRYPTION)
-    {
-        unsigned int j;
-        rk = aes->key;
-
-        /* invert the order of the round keys: */
-        for (i = 0, j = 4 *aes->rounds; i < j; i += 4, j -= 4) {
-            temp = rk[i    ]; rk[i    ] = rk[j    ]; rk[j    ] = temp;
-            temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
-            temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
-            temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
-        }
-        /* apply the inverse MixColumn transform to all round keys but the
-           first and the last: */
-        for (i = 1; i < aes->rounds; i++) {
-            rk += 4;
-            rk[0] =
-                Td[0][Te[4][GETBYTE(rk[0], 3)] & 0xff] ^
-                Td[1][Te[4][GETBYTE(rk[0], 2)] & 0xff] ^
-                Td[2][Te[4][GETBYTE(rk[0], 1)] & 0xff] ^
-                Td[3][Te[4][GETBYTE(rk[0], 0)] & 0xff];
-            rk[1] =
-                Td[0][Te[4][GETBYTE(rk[1], 3)] & 0xff] ^
-                Td[1][Te[4][GETBYTE(rk[1], 2)] & 0xff] ^
-                Td[2][Te[4][GETBYTE(rk[1], 1)] & 0xff] ^
-                Td[3][Te[4][GETBYTE(rk[1], 0)] & 0xff];
-            rk[2] =
-                Td[0][Te[4][GETBYTE(rk[2], 3)] & 0xff] ^
-                Td[1][Te[4][GETBYTE(rk[2], 2)] & 0xff] ^
-                Td[2][Te[4][GETBYTE(rk[2], 1)] & 0xff] ^
-                Td[3][Te[4][GETBYTE(rk[2], 0)] & 0xff];
-            rk[3] =
-                Td[0][Te[4][GETBYTE(rk[3], 3)] & 0xff] ^
-                Td[1][Te[4][GETBYTE(rk[3], 2)] & 0xff] ^
-                Td[2][Te[4][GETBYTE(rk[3], 1)] & 0xff] ^
-                Td[3][Te[4][GETBYTE(rk[3], 0)] & 0xff];
-        }
-    }
-
-    return AESSetIV(aes, iv);
-}
-
-int AESSetKey(AES *aes, const byte *userKey, word32 keylen, const byte *iv,
-              int dir)
-{
-
-    if (!((keylen == 16) || (keylen == 24) || (keylen == 32)))
-        return BAD_FUNC_ARG;
-
-    return AESSetKeyLocal(aes, userKey, keylen, iv, dir);
-}
-
-/* AESSetIV is shared between software and hardware */
-int AESSetIV(AES *aes, const byte *iv)
-{
-    if (aes == NULL)
-        return BAD_FUNC_ARG;
-
-    if (iv)
-        XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
-    else
-        XMEMSET(aes->reg,  0, AES_BLOCK_SIZE);
-
-    return 0;
-}
-
-int AESCBCDecryptWithKey(byte *out, const byte *in, word32 inSz,
-                                  const byte *key, word32 keySz, const byte *iv)
-{
-    int  ret = 0;
-    AES  aes[1];
-
-    ret = AESSetKey(aes, key, keySz, iv, AES_DECRYPTION);
-    if (ret == 0)
-        ret = AESCBCDecrypt(aes, out, in, inSz);
-
-    return ret;
-}
-
-int AESCBCEncrypt(AES *aes, byte *out, const byte *in, word32 sz)
-{
-    word32 blocks = sz / AES_BLOCK_SIZE;
-
-    while (blocks--) {
-        xorbuf((byte *)aes->reg, in, AES_BLOCK_SIZE);
-        AESEncrypt(aes, (byte*)aes->reg, (byte*)aes->reg);
-        XMEMCPY(out, aes->reg, AES_BLOCK_SIZE);
-
-        out += AES_BLOCK_SIZE;
-        in  += AES_BLOCK_SIZE;
-    }
-
-    return 0;
-}
-
-int AESCBCDecrypt(AES *aes, byte *out, const byte *in, word32 sz)
-{
-    word32 blocks = sz / AES_BLOCK_SIZE;
-
-    while (blocks--) {
-        XMEMCPY(aes->tmp, in, AES_BLOCK_SIZE);
-        AESDecrypt(aes, (byte *)aes->tmp, out);
-        xorbuf(out, (byte *)aes->reg, AES_BLOCK_SIZE);
-        XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE);
-
-        out += AES_BLOCK_SIZE;
-        in  += AES_BLOCK_SIZE;
-    }
-
-    return 0;
-}
-
-/* Increment AES counter */
-static inline void IncrementAESCounter(byte *inOutCTR)
-{
-    int i;
-
-    /* in network byte order so start at end and work back */
-    for (i = AES_BLOCK_SIZE - 1; i >= 0; i--) {
-        if (++inOutCTR[i])  /* we're done unless we overflow */
-            return;
-    }
-}
-
-void AESCTREncrypt(AES *aes, byte *out, const byte *in, word32 sz)
-{
-    byte *tmp = (byte *)aes->tmp + AES_BLOCK_SIZE - aes->left;
-
-    /* consume any unused bytes left in aes->tmp */
-    while (aes->left && sz) {
-       *(out++) = *(in++) ^ *(tmp++);
-       aes->left--;
-       sz--;
-    }
-
-    /* do as many block size ops as possible */
-    while (sz >= AES_BLOCK_SIZE) {
-        AESEncrypt(aes, (byte *)aes->reg, out);
-        IncrementAESCounter((byte *)aes->reg);
-        xorbuf(out, in, AES_BLOCK_SIZE);
-
-        out += AES_BLOCK_SIZE;
-        in  += AES_BLOCK_SIZE;
-        sz  -= AES_BLOCK_SIZE;
-        aes->left = 0;
-    }
-
-    /* handle non block size remaining and sotre unused byte count in left */
-    if (sz) {
-        AESEncrypt(aes, (byte *)aes->reg, (byte *)aes->tmp);
-        IncrementAESCounter((byte*)aes->reg);
-
-        aes->left = AES_BLOCK_SIZE;
-        tmp = (byte*)aes->tmp;
-
-        while (sz--) {
-            *(out++) = *(in++) ^ *(tmp++);
-            aes->left--;
-        }
-    }
-}
-
-enum {
-    CTR_SZ = 4
-};
-
-static inline void InitGCMCounter(byte *inOutCtr)
-{
-    inOutCtr[AES_BLOCK_SIZE - 4] = 0;
-    inOutCtr[AES_BLOCK_SIZE - 3] = 0;
-    inOutCtr[AES_BLOCK_SIZE - 2] = 0;
-    inOutCtr[AES_BLOCK_SIZE - 1] = 1;
-}
-
-static inline void IncrementGCMCounter(byte *inOutCtr)
-{
-    int i;
-
-    /* in network byte order so start at end and work back */
-    for (i = AES_BLOCK_SIZE - 1; i >= AES_BLOCK_SIZE - CTR_SZ; i--) {
-        if (++inOutCtr[i])  /* we're done unless we overflow */
-            return;
-    }
-}
-
-static inline void FlattenSzInBits(byte *buf, word32 sz)
-{
-    /* Multiply the sz by 8 */
-    word32 szHi = (sz >> (8*sizeof(sz) - 3));
-    sz <<= 3;
-
-    /* copy over the words of the sz into the destination buffer */
-    buf[0] = (szHi >> 24) & 0xff;
-    buf[1] = (szHi >> 16) & 0xff;
-    buf[2] = (szHi >>  8) & 0xff;
-    buf[3] = szHi & 0xff;
-    buf[4] = (sz >> 24) & 0xff;
-    buf[5] = (sz >> 16) & 0xff;
-    buf[6] = (sz >>  8) & 0xff;
-    buf[7] = sz & 0xff;
-}
-
-static inline void RIGHTSHIFTX(byte *x)
-{
-    int i;
-    int carryOut = 0;
-    int carryIn = 0;
-    int borrow = x[15] & 0x01;
-
-    for (i = 0; i < AES_BLOCK_SIZE; i++) {
-        carryOut = x[i] & 0x01;
-        x[i] = (x[i] >> 1) | (carryIn ? 0x80 : 0);
-        carryIn = carryOut;
-    }
-    if (borrow) x[0] ^= 0xE1;
-}
-
-static void GenerateM0(AES *aes)
-{
-    int i, j;
-    byte (*m)[AES_BLOCK_SIZE] = aes->M0;
-
-    XMEMCPY(m[128], aes->H, AES_BLOCK_SIZE);
-
-    for (i = 64; i > 0; i /= 2) {
-        XMEMCPY(m[i], m[i*2], AES_BLOCK_SIZE);
-        RIGHTSHIFTX(m[i]);
-    }
-
-    for (i = 2; i < 256; i *= 2) {
-        for (j = 1; j < i; j++) {
-            XMEMCPY(m[i+j], m[i], AES_BLOCK_SIZE);
-            xorbuf(m[i+j], m[j], AES_BLOCK_SIZE);
-        }
-    }
-
-    XMEMSET(m[0], 0, AES_BLOCK_SIZE);
-}
-
-int AESGCMSetKey(AES* aes, const byte* key, word32 len)
-{
-    int  ret;
-    byte iv[AES_BLOCK_SIZE];
-
-    if (!((len == 16) || (len == 24) || (len == 32)))
-        return BAD_FUNC_ARG;
-
-    XMEMSET(iv, 0, AES_BLOCK_SIZE);
-    ret = AESSetKey(aes, key, len, iv, AES_ENCRYPTION);
-
-    if (ret == 0) {
-        AESEncrypt(aes, iv, aes->H);
-        GenerateM0(aes);
-    }
-
-    return ret;
-}
-
-static const byte R[256][2] = {
-    {0x00, 0x00}, {0x01, 0xc2}, {0x03, 0x84}, {0x02, 0x46},
-    {0x07, 0x08}, {0x06, 0xca}, {0x04, 0x8c}, {0x05, 0x4e},
-    {0x0e, 0x10}, {0x0f, 0xd2}, {0x0d, 0x94}, {0x0c, 0x56},
-    {0x09, 0x18}, {0x08, 0xda}, {0x0a, 0x9c}, {0x0b, 0x5e},
-    {0x1c, 0x20}, {0x1d, 0xe2}, {0x1f, 0xa4}, {0x1e, 0x66},
-    {0x1b, 0x28}, {0x1a, 0xea}, {0x18, 0xac}, {0x19, 0x6e},
-    {0x12, 0x30}, {0x13, 0xf2}, {0x11, 0xb4}, {0x10, 0x76},
-    {0x15, 0x38}, {0x14, 0xfa}, {0x16, 0xbc}, {0x17, 0x7e},
-    {0x38, 0x40}, {0x39, 0x82}, {0x3b, 0xc4}, {0x3a, 0x06},
-    {0x3f, 0x48}, {0x3e, 0x8a}, {0x3c, 0xcc}, {0x3d, 0x0e},
-    {0x36, 0x50}, {0x37, 0x92}, {0x35, 0xd4}, {0x34, 0x16},
-    {0x31, 0x58}, {0x30, 0x9a}, {0x32, 0xdc}, {0x33, 0x1e},
-    {0x24, 0x60}, {0x25, 0xa2}, {0x27, 0xe4}, {0x26, 0x26},
-    {0x23, 0x68}, {0x22, 0xaa}, {0x20, 0xec}, {0x21, 0x2e},
-    {0x2a, 0x70}, {0x2b, 0xb2}, {0x29, 0xf4}, {0x28, 0x36},
-    {0x2d, 0x78}, {0x2c, 0xba}, {0x2e, 0xfc}, {0x2f, 0x3e},
-    {0x70, 0x80}, {0x71, 0x42}, {0x73, 0x04}, {0x72, 0xc6},
-    {0x77, 0x88}, {0x76, 0x4a}, {0x74, 0x0c}, {0x75, 0xce},
-    {0x7e, 0x90}, {0x7f, 0x52}, {0x7d, 0x14}, {0x7c, 0xd6},
-    {0x79, 0x98}, {0x78, 0x5a}, {0x7a, 0x1c}, {0x7b, 0xde},
-    {0x6c, 0xa0}, {0x6d, 0x62}, {0x6f, 0x24}, {0x6e, 0xe6},
-    {0x6b, 0xa8}, {0x6a, 0x6a}, {0x68, 0x2c}, {0x69, 0xee},
-    {0x62, 0xb0}, {0x63, 0x72}, {0x61, 0x34}, {0x60, 0xf6},
-    {0x65, 0xb8}, {0x64, 0x7a}, {0x66, 0x3c}, {0x67, 0xfe},
-    {0x48, 0xc0}, {0x49, 0x02}, {0x4b, 0x44}, {0x4a, 0x86},
-    {0x4f, 0xc8}, {0x4e, 0x0a}, {0x4c, 0x4c}, {0x4d, 0x8e},
-    {0x46, 0xd0}, {0x47, 0x12}, {0x45, 0x54}, {0x44, 0x96},
-    {0x41, 0xd8}, {0x40, 0x1a}, {0x42, 0x5c}, {0x43, 0x9e},
-    {0x54, 0xe0}, {0x55, 0x22}, {0x57, 0x64}, {0x56, 0xa6},
-    {0x53, 0xe8}, {0x52, 0x2a}, {0x50, 0x6c}, {0x51, 0xae},
-    {0x5a, 0xf0}, {0x5b, 0x32}, {0x59, 0x74}, {0x58, 0xb6},
-    {0x5d, 0xf8}, {0x5c, 0x3a}, {0x5e, 0x7c}, {0x5f, 0xbe},
-    {0xe1, 0x00}, {0xe0, 0xc2}, {0xe2, 0x84}, {0xe3, 0x46},
-    {0xe6, 0x08}, {0xe7, 0xca}, {0xe5, 0x8c}, {0xe4, 0x4e},
-    {0xef, 0x10}, {0xee, 0xd2}, {0xec, 0x94}, {0xed, 0x56},
-    {0xe8, 0x18}, {0xe9, 0xda}, {0xeb, 0x9c}, {0xea, 0x5e},
-    {0xfd, 0x20}, {0xfc, 0xe2}, {0xfe, 0xa4}, {0xff, 0x66},
-    {0xfa, 0x28}, {0xfb, 0xea}, {0xf9, 0xac}, {0xf8, 0x6e},
-    {0xf3, 0x30}, {0xf2, 0xf2}, {0xf0, 0xb4}, {0xf1, 0x76},
-    {0xf4, 0x38}, {0xf5, 0xfa}, {0xf7, 0xbc}, {0xf6, 0x7e},
-    {0xd9, 0x40}, {0xd8, 0x82}, {0xda, 0xc4}, {0xdb, 0x06},
-    {0xde, 0x48}, {0xdf, 0x8a}, {0xdd, 0xcc}, {0xdc, 0x0e},
-    {0xd7, 0x50}, {0xd6, 0x92}, {0xd4, 0xd4}, {0xd5, 0x16},
-    {0xd0, 0x58}, {0xd1, 0x9a}, {0xd3, 0xdc}, {0xd2, 0x1e},
-    {0xc5, 0x60}, {0xc4, 0xa2}, {0xc6, 0xe4}, {0xc7, 0x26},
-    {0xc2, 0x68}, {0xc3, 0xaa}, {0xc1, 0xec}, {0xc0, 0x2e},
-    {0xcb, 0x70}, {0xca, 0xb2}, {0xc8, 0xf4}, {0xc9, 0x36},
-    {0xcc, 0x78}, {0xcd, 0xba}, {0xcf, 0xfc}, {0xce, 0x3e},
-    {0x91, 0x80}, {0x90, 0x42}, {0x92, 0x04}, {0x93, 0xc6},
-    {0x96, 0x88}, {0x97, 0x4a}, {0x95, 0x0c}, {0x94, 0xce},
-    {0x9f, 0x90}, {0x9e, 0x52}, {0x9c, 0x14}, {0x9d, 0xd6},
-    {0x98, 0x98}, {0x99, 0x5a}, {0x9b, 0x1c}, {0x9a, 0xde},
-    {0x8d, 0xa0}, {0x8c, 0x62}, {0x8e, 0x24}, {0x8f, 0xe6},
-    {0x8a, 0xa8}, {0x8b, 0x6a}, {0x89, 0x2c}, {0x88, 0xee},
-    {0x83, 0xb0}, {0x82, 0x72}, {0x80, 0x34}, {0x81, 0xf6},
-    {0x84, 0xb8}, {0x85, 0x7a}, {0x87, 0x3c}, {0x86, 0xfe},
-    {0xa9, 0xc0}, {0xa8, 0x02}, {0xaa, 0x44}, {0xab, 0x86},
-    {0xae, 0xc8}, {0xaf, 0x0a}, {0xad, 0x4c}, {0xac, 0x8e},
-    {0xa7, 0xd0}, {0xa6, 0x12}, {0xa4, 0x54}, {0xa5, 0x96},
-    {0xa0, 0xd8}, {0xa1, 0x1a}, {0xa3, 0x5c}, {0xa2, 0x9e},
-    {0xb5, 0xe0}, {0xb4, 0x22}, {0xb6, 0x64}, {0xb7, 0xa6},
-    {0xb2, 0xe8}, {0xb3, 0x2a}, {0xb1, 0x6c}, {0xb0, 0xae},
-    {0xbb, 0xf0}, {0xba, 0x32}, {0xb8, 0x74}, {0xb9, 0xb6},
-    {0xbc, 0xf8}, {0xbd, 0x3a}, {0xbf, 0x7c}, {0xbe, 0xbe} };
-
-static void GMULT(byte *x, byte m[256][AES_BLOCK_SIZE])
-{
-    int i, j;
-    byte Z[AES_BLOCK_SIZE];
-    byte a;
-
-    XMEMSET(Z, 0, sizeof(Z));
-
-    for (i = 15; i > 0; i--) {
-        xorbuf(Z, m[x[i]], AES_BLOCK_SIZE);
-        a = Z[15];
-
-        for (j = 15; j > 0; j--) {
-            Z[j] = Z[j-1];
-        }
-
-        Z[0] = R[a][0];
-        Z[1] ^= R[a][1];
-    }
-    xorbuf(Z, m[x[0]], AES_BLOCK_SIZE);
-
-    XMEMCPY(x, Z, AES_BLOCK_SIZE);
-}
-
-static void GHASH(AES *aes, const byte *a, word32 aSz,
-                  const byte *c, word32 cSz, byte *s, word32 sSz)
-{
-    byte x[AES_BLOCK_SIZE];
-    byte scratch[AES_BLOCK_SIZE];
-    word32 blocks, partial;
-
-    XMEMSET(x, 0, AES_BLOCK_SIZE);
-
-    /* Hash in A, the Additional Authentication Data */
-    if (aSz != 0 && a != NULL) {
-        blocks = aSz / AES_BLOCK_SIZE;
-        partial = aSz % AES_BLOCK_SIZE;
-        while (blocks--) {
-            xorbuf(x, a, AES_BLOCK_SIZE);
-            GMULT(x, aes->M0);
-            a += AES_BLOCK_SIZE;
-        }
-        if (partial != 0) {
-            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
-            XMEMCPY(scratch, a, partial);
-            xorbuf(x, scratch, AES_BLOCK_SIZE);
-            GMULT(x, aes->M0);
-        }
-    }
-
-    /* Hash in C, the Ciphertext */
-    if (cSz != 0 && c != NULL) {
-        blocks = cSz / AES_BLOCK_SIZE;
-        partial = cSz % AES_BLOCK_SIZE;
-        while (blocks--) {
-            xorbuf(x, c, AES_BLOCK_SIZE);
-            GMULT(x, aes->M0);
-            c += AES_BLOCK_SIZE;
-        }
-        if (partial != 0) {
-            XMEMSET(scratch, 0, AES_BLOCK_SIZE);
-            XMEMCPY(scratch, c, partial);
-            xorbuf(x, scratch, AES_BLOCK_SIZE);
-            GMULT(x, aes->M0);
-        }
-    }
-
-    /* Hash in the lengths of A and C in bits */
-    FlattenSzInBits(&scratch[0], aSz);
-    FlattenSzInBits(&scratch[8], cSz);
-    xorbuf(x, scratch, AES_BLOCK_SIZE);
-    GMULT(x, aes->M0);
-
-    /* Copy the result into s. */
-    XMEMCPY(s, x, sSz);
-}
-
-int  AESGCMEncrypt(AES *aes, byte *out, const byte *in, word32 sz,
-                   const byte *iv, word32 ivSz,
-                   byte *authTag, word32 authTagSz,
-                   const byte *authIn, word32 authInSz)
-{
-    word32 blocks = sz / AES_BLOCK_SIZE;
-    word32 partial = sz % AES_BLOCK_SIZE;
-    const byte *p = in;
-    byte *c = out;
-    byte counter[AES_BLOCK_SIZE];
-    byte *ctr;
-    byte scratch[AES_BLOCK_SIZE];
-
-    ctr = counter;
-
-    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
-    XMEMCPY(ctr, iv, ivSz);
-    InitGCMCounter(ctr);
-
-    while (blocks--) {
-        IncrementGCMCounter(ctr);
-        AESEncrypt(aes, ctr, scratch);
-        xorbuf(scratch, p, AES_BLOCK_SIZE);
-        XMEMCPY(c, scratch, AES_BLOCK_SIZE);
-        p += AES_BLOCK_SIZE;
-        c += AES_BLOCK_SIZE;
-    }
-
-    if (partial != 0) {
-        IncrementGCMCounter(ctr);
-        AESEncrypt(aes, ctr, scratch);
-        xorbuf(scratch, p, partial);
-        XMEMCPY(c, scratch, partial);
-
-    }
-
-    GHASH(aes, authIn, authInSz, out, sz, authTag, authTagSz);
-    InitGCMCounter(ctr);
-    AESEncrypt(aes, ctr, scratch);
-    xorbuf(authTag, scratch, authTagSz);
-
-    return 0;
-}
-
-int  AESGCMDecrypt(AES *aes, byte *out, const byte *in, word32 sz,
-                   const byte *iv, word32 ivSz,
-                   const byte *authTag, word32 authTagSz,
-                   const byte *authIn, word32 authInSz)
-{
-    word32 blocks = sz / AES_BLOCK_SIZE;
-    word32 partial = sz % AES_BLOCK_SIZE;
-    const byte *c = in;
-    byte *p = out;
-    byte counter[AES_BLOCK_SIZE];
-    byte *ctr ;
-    byte scratch[AES_BLOCK_SIZE];
-
-    ctr = counter;
-
-    XMEMSET(ctr, 0, AES_BLOCK_SIZE);
-    XMEMCPY(ctr, iv, ivSz);
-    InitGCMCounter(ctr);
-
-    /* Calculate the authTag again using the received auth data and the
-     * cipher text. */
-    {
-        byte Tprime[AES_BLOCK_SIZE];
-        byte EKY0[AES_BLOCK_SIZE];
-
-        GHASH(aes, authIn, authInSz, in, sz, Tprime, sizeof(Tprime));
-        AESEncrypt(aes, ctr, EKY0);
-        xorbuf(Tprime, EKY0, sizeof(Tprime));
-
-        if (XMEMCMP(authTag, Tprime, authTagSz) != 0) {
-            return AES_GCM_AUTH_E;
-        }
-    }
- 
-    while (blocks--) {
-        IncrementGCMCounter(ctr);
-        AESEncrypt(aes, ctr, scratch);
-        xorbuf(scratch, c, AES_BLOCK_SIZE);
-        XMEMCPY(p, scratch, AES_BLOCK_SIZE);
-        p += AES_BLOCK_SIZE;
-        c += AES_BLOCK_SIZE;
-    }
-    if (partial != 0) {
-        IncrementGCMCounter(ctr);
-        AESEncrypt(aes, ctr, scratch);
-        xorbuf(scratch, c, partial);
-        XMEMCPY(p, scratch, partial);
-    }
-    return 0;
-}

+ 0 - 90
Pal/lib/crypto/wolfssl/aes.h

@@ -1,90 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* aes.h
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#ifndef CTAO_CRYPT_AES_H
-#define CTAO_CRYPT_AES_H
-
-#include <stdint.h>
-
-#ifndef word32
-typedef uint32_t word32;
-#endif
-#ifndef byte
-typedef uint8_t byte;
-#endif
-
-#ifndef word
-#ifdef __x86_64__
-typedef uint64_t word;
-#else
-typedef uint32_t word;
-#endif
-#endif
-
-#define WORD_SIZE sizeof(word)
-
-#define ALIGN16 __attribute__((aligned (16)))
-
-enum {
-    AES_ENC_TYPE   = 1,   /* cipher unique type */
-    AES_ENCRYPTION = 0,
-    AES_DECRYPTION = 1,
-    AES_BLOCK_SIZE = 16
-};
-
-typedef struct AES {
-    /* AESNI needs key first, rounds 2nd, not sure why yet */
-    ALIGN16 word32 key[60];
-    word32  rounds;
-
-    ALIGN16 word32 reg[AES_BLOCK_SIZE / sizeof(word32)];      /* for CBC mode */
-    ALIGN16 word32 tmp[AES_BLOCK_SIZE / sizeof(word32)];      /* same         */
-    word32  left;
-
-    ALIGN16 byte H[AES_BLOCK_SIZE];
-    /* key-based fast multiplication table. */
-    ALIGN16 byte M0[256][AES_BLOCK_SIZE];
-} AES;
-
-int  AESSetKey(AES *aes, const byte *key, word32 len, const byte *iv,
-               int dir);
-int  AESSetIV(AES *aes, const byte *iv);
-void AESEncrypt(AES *aes, const byte *in, byte *out);
-void AESDecrypt(AES *aes, const byte *in, byte *out);
-int  AESCBCEncrypt(AES *aes, byte *out, const byte *in, word32 sz);
-int  AESCBCDecrypt(AES *aes, byte *out, const byte *in, word32 sz);
-int  AESCBCDecryptWithKey(byte *out, const byte *in, word32 inSz,
-                          const byte *key, word32 keySz, const byte *iv);
-void AESCTREncrypt(AES *aes, byte *out, const byte *in, word32 sz);
-int  AESGCMSetKey(AES *aes, const byte *key, word32 len);
-int  AESGCMEncrypt(AES *aes, byte *out, const byte *in, word32 sz,
-                   const byte *iv, word32 ivSz,
-                   byte* authTag, word32 authTagSz,
-                   const byte *authIn, word32 authInSz);
-int  AESGCMDecrypt(AES *aes, byte *out, const byte *in, word32 sz,
-                   const byte *iv, word32 ivSz,
-                   const byte *authTag, word32 authTagSz,
-                   const byte *authIn, word32 authInSz);
-
-#endif /* CTAO_CRYPT_AES_H */

+ 0 - 816
Pal/lib/crypto/wolfssl/aes_ni.S

@@ -1,816 +0,0 @@
-/* aes_asm.s
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-
-/* See Intel® Advanced Encryption Standard (AES) Instructions Set White Paper
- * by Intel Mobility Group, Israel Development Center, Israel Shay Gueron
- */
-
-/* This file is in at&t asm syntax, see .asm for intel syntax */
-
-
-/*
-AES_CBC_encrypt (const unsigned char *in,
-	unsigned char *out,
-	unsigned char ivec[16],
-	unsigned long length,
-	const unsigned char *KS,
-	int nr)
-*/
-.globl AES_CBC_encrypt
-AES_CBC_encrypt:
-# parameter 1: %rdi
-# parameter 2: %rsi
-# parameter 3: %rdx
-# parameter 4: %rcx
-# parameter 5: %r8
-# parameter 6: %r9d
-movq	%rcx, %r10
-shrq	$4, %rcx
-shlq	$60, %r10
-je	NO_PARTS
-addq	$1, %rcx
-NO_PARTS:
-subq	$16, %rsi
-movdqa	(%rdx), %xmm1
-LOOP:
-pxor	(%rdi), %xmm1
-pxor	(%r8), %xmm1
-addq	$16,%rsi
-addq	$16,%rdi
-cmpl	$12, %r9d
-aesenc	16(%r8),%xmm1
-aesenc	32(%r8),%xmm1
-aesenc	48(%r8),%xmm1
-aesenc	64(%r8),%xmm1
-aesenc	80(%r8),%xmm1
-aesenc	96(%r8),%xmm1
-aesenc	112(%r8),%xmm1
-aesenc	128(%r8),%xmm1
-aesenc	144(%r8),%xmm1
-movdqa	160(%r8),%xmm2
-jb	LAST
-cmpl	$14, %r9d
-
-aesenc	160(%r8),%xmm1
-aesenc	176(%r8),%xmm1
-movdqa	192(%r8),%xmm2
-jb	LAST
-aesenc	192(%r8),%xmm1
-aesenc	208(%r8),%xmm1
-movdqa	224(%r8),%xmm2
-LAST:
-decq	%rcx
-aesenclast %xmm2,%xmm1
-movdqu	%xmm1,(%rsi)
-jne	LOOP
-ret
-
-
-
-
-/*
-AES_CBC_decrypt (const unsigned char *in,
-  unsigned char *out,
-  unsigned char ivec[16],
-  unsigned long length,
-  const unsigned char *KS,
-  int nr)
-*/
-.globl AES_CBC_decrypt
-AES_CBC_decrypt:
-# parameter 1: %rdi
-# parameter 2: %rsi
-# parameter 3: %rdx
-# parameter 4: %rcx
-# parameter 5: %r8
-# parameter 6: %r9d
-
-movq    %rcx, %r10
-shrq $4, %rcx
-shlq   $60, %r10
-je    DNO_PARTS_4
-addq    $1, %rcx
-DNO_PARTS_4:
-movq   %rcx, %r10
-shlq    $62, %r10
-shrq  $62, %r10
-shrq  $2, %rcx
-movdqu (%rdx),%xmm5
-je DREMAINDER_4
-subq   $64, %rsi
-DLOOP_4:
-movdqu (%rdi), %xmm1
-movdqu  16(%rdi), %xmm2
-movdqu  32(%rdi), %xmm3
-movdqu  48(%rdi), %xmm4
-movdqa  %xmm1, %xmm6
-movdqa %xmm2, %xmm7
-movdqa %xmm3, %xmm8
-movdqa %xmm4, %xmm15
-movdqa    (%r8), %xmm9
-movdqa 16(%r8), %xmm10
-movdqa  32(%r8), %xmm11
-movdqa  48(%r8), %xmm12
-pxor    %xmm9, %xmm1
-pxor   %xmm9, %xmm2
-pxor   %xmm9, %xmm3
-
-pxor    %xmm9, %xmm4
-aesdec %xmm10, %xmm1
-aesdec    %xmm10, %xmm2
-aesdec    %xmm10, %xmm3
-aesdec    %xmm10, %xmm4
-aesdec    %xmm11, %xmm1
-aesdec    %xmm11, %xmm2
-aesdec    %xmm11, %xmm3
-aesdec    %xmm11, %xmm4
-aesdec    %xmm12, %xmm1
-aesdec    %xmm12, %xmm2
-aesdec    %xmm12, %xmm3
-aesdec    %xmm12, %xmm4
-movdqa    64(%r8), %xmm9
-movdqa   80(%r8), %xmm10
-movdqa  96(%r8), %xmm11
-movdqa  112(%r8), %xmm12
-aesdec %xmm9, %xmm1
-aesdec %xmm9, %xmm2
-aesdec %xmm9, %xmm3
-aesdec %xmm9, %xmm4
-aesdec %xmm10, %xmm1
-aesdec    %xmm10, %xmm2
-aesdec    %xmm10, %xmm3
-aesdec    %xmm10, %xmm4
-aesdec    %xmm11, %xmm1
-aesdec    %xmm11, %xmm2
-aesdec    %xmm11, %xmm3
-aesdec    %xmm11, %xmm4
-aesdec    %xmm12, %xmm1
-aesdec    %xmm12, %xmm2
-aesdec    %xmm12, %xmm3
-aesdec    %xmm12, %xmm4
-movdqa    128(%r8), %xmm9
-movdqa  144(%r8), %xmm10
-movdqa 160(%r8), %xmm11
-cmpl   $12, %r9d
-aesdec  %xmm9, %xmm1
-aesdec %xmm9, %xmm2
-aesdec %xmm9, %xmm3
-aesdec %xmm9, %xmm4
-aesdec %xmm10, %xmm1
-aesdec    %xmm10, %xmm2
-aesdec    %xmm10, %xmm3
-aesdec    %xmm10, %xmm4
-jb    DLAST_4
-movdqa  160(%r8), %xmm9
-movdqa  176(%r8), %xmm10
-movdqa 192(%r8), %xmm11
-cmpl   $14, %r9d
-aesdec  %xmm9, %xmm1
-aesdec %xmm9, %xmm2
-aesdec %xmm9, %xmm3
-aesdec %xmm9, %xmm4
-aesdec %xmm10, %xmm1
-aesdec    %xmm10, %xmm2
-aesdec    %xmm10, %xmm3
-aesdec    %xmm10, %xmm4
-jb    DLAST_4
-
-movdqa  192(%r8), %xmm9
-movdqa  208(%r8), %xmm10
-movdqa 224(%r8), %xmm11
-aesdec %xmm9, %xmm1
-aesdec %xmm9, %xmm2
-aesdec %xmm9, %xmm3
-aesdec %xmm9, %xmm4
-aesdec %xmm10, %xmm1
-aesdec    %xmm10, %xmm2
-aesdec    %xmm10, %xmm3
-aesdec    %xmm10, %xmm4
-DLAST_4:
-addq   $64, %rdi
-addq    $64, %rsi
-decq  %rcx
-aesdeclast %xmm11, %xmm1
-aesdeclast %xmm11, %xmm2
-aesdeclast %xmm11, %xmm3
-aesdeclast %xmm11, %xmm4
-pxor   %xmm5 ,%xmm1
-pxor    %xmm6 ,%xmm2
-pxor   %xmm7 ,%xmm3
-pxor   %xmm8 ,%xmm4
-movdqu %xmm1, (%rsi)
-movdqu    %xmm2, 16(%rsi)
-movdqu  %xmm3, 32(%rsi)
-movdqu  %xmm4, 48(%rsi)
-movdqa  %xmm15,%xmm5
-jne    DLOOP_4
-addq    $64, %rsi
-DREMAINDER_4:
-cmpq    $0, %r10
-je  DEND_4
-DLOOP_4_2:
-movdqu  (%rdi), %xmm1
-movdqa    %xmm1 ,%xmm15
-addq  $16, %rdi
-pxor  (%r8), %xmm1
-movdqu 160(%r8), %xmm2
-cmpl    $12, %r9d
-aesdec    16(%r8), %xmm1
-aesdec   32(%r8), %xmm1
-aesdec   48(%r8), %xmm1
-aesdec   64(%r8), %xmm1
-aesdec   80(%r8), %xmm1
-aesdec   96(%r8), %xmm1
-aesdec   112(%r8), %xmm1
-aesdec  128(%r8), %xmm1
-aesdec  144(%r8), %xmm1
-jb  DLAST_4_2
-movdqu    192(%r8), %xmm2
-cmpl    $14, %r9d
-aesdec    160(%r8), %xmm1
-aesdec  176(%r8), %xmm1
-jb  DLAST_4_2
-movdqu    224(%r8), %xmm2
-aesdec  192(%r8), %xmm1
-aesdec  208(%r8), %xmm1
-DLAST_4_2:
-aesdeclast %xmm2, %xmm1
-pxor    %xmm5, %xmm1
-movdqa %xmm15, %xmm5
-movdqu    %xmm1, (%rsi)
-
-addq    $16, %rsi
-decq    %r10
-jne DLOOP_4_2
-DEND_4:
-ret
-
-
-/*
-AES_ECB_encrypt (const unsigned char *in,
-	unsigned char *out,
-	unsigned long length,
-	const unsigned char *KS,
-	int nr)
-*/
-.globl AES_ECB_encrypt
-AES_ECB_encrypt:
-# parameter 1: %rdi
-# parameter 2: %rsi
-# parameter 3: %rdx
-# parameter 4: %rcx
-# parameter 5: %r8d
-        movq    %rdx, %r10
-        shrq    $4, %rdx
-        shlq    $60, %r10
-        je      EECB_NO_PARTS_4
-        addq    $1, %rdx
-EECB_NO_PARTS_4:
-        movq    %rdx, %r10
-        shlq    $62, %r10
-        shrq    $62, %r10
-        shrq    $2, %rdx
-        je      EECB_REMAINDER_4
-        subq    $64, %rsi
-EECB_LOOP_4:
-        movdqu  (%rdi), %xmm1
-        movdqu  16(%rdi), %xmm2
-        movdqu  32(%rdi), %xmm3
-        movdqu  48(%rdi), %xmm4
-        movdqa  (%rcx), %xmm9
-        movdqa  16(%rcx), %xmm10
-        movdqa  32(%rcx), %xmm11
-        movdqa  48(%rcx), %xmm12
-        pxor    %xmm9, %xmm1
-        pxor    %xmm9, %xmm2
-        pxor    %xmm9, %xmm3
-        pxor    %xmm9, %xmm4
-        aesenc  %xmm10, %xmm1
-        aesenc  %xmm10, %xmm2
-        aesenc  %xmm10, %xmm3
-        aesenc  %xmm10, %xmm4
-        aesenc  %xmm11, %xmm1
-        aesenc  %xmm11, %xmm2
-        aesenc  %xmm11, %xmm3
-        aesenc  %xmm11, %xmm4
-        aesenc  %xmm12, %xmm1
-        aesenc  %xmm12, %xmm2
-        aesenc  %xmm12, %xmm3
-        aesenc  %xmm12, %xmm4
-        movdqa  64(%rcx), %xmm9
-        movdqa  80(%rcx), %xmm10
-        movdqa  96(%rcx), %xmm11
-        movdqa  112(%rcx), %xmm12
-        aesenc  %xmm9, %xmm1
-        aesenc  %xmm9, %xmm2
-        aesenc  %xmm9, %xmm3
-        aesenc  %xmm9, %xmm4
-        aesenc  %xmm10, %xmm1
-        aesenc  %xmm10, %xmm2
-        aesenc  %xmm10, %xmm3
-        aesenc  %xmm10, %xmm4
-        aesenc  %xmm11, %xmm1
-        aesenc  %xmm11, %xmm2
-        aesenc  %xmm11, %xmm3
-        aesenc  %xmm11, %xmm4
-        aesenc  %xmm12, %xmm1
-        aesenc  %xmm12, %xmm2
-        aesenc  %xmm12, %xmm3
-        aesenc  %xmm12, %xmm4
-        movdqa  128(%rcx), %xmm9
-        movdqa  144(%rcx), %xmm10
-        movdqa  160(%rcx), %xmm11
-        cmpl    $12, %r8d
-        aesenc  %xmm9, %xmm1
-        aesenc  %xmm9, %xmm2
-        aesenc  %xmm9, %xmm3
-        aesenc  %xmm9, %xmm4
-        aesenc  %xmm10, %xmm1
-        aesenc  %xmm10, %xmm2
-        aesenc  %xmm10, %xmm3
-        aesenc  %xmm10, %xmm4
-        jb      EECB_LAST_4
-        movdqa  160(%rcx), %xmm9
-        movdqa  176(%rcx), %xmm10
-        movdqa  192(%rcx), %xmm11
-        cmpl    $14, %r8d
-        aesenc  %xmm9, %xmm1
-        aesenc  %xmm9, %xmm2
-        aesenc  %xmm9, %xmm3
-        aesenc  %xmm9, %xmm4
-        aesenc  %xmm10, %xmm1
-        aesenc  %xmm10, %xmm2
-        aesenc  %xmm10, %xmm3
-        aesenc  %xmm10, %xmm4
-        jb      EECB_LAST_4
-        movdqa  192(%rcx), %xmm9
-        movdqa  208(%rcx), %xmm10
-        movdqa  224(%rcx), %xmm11
-        aesenc  %xmm9, %xmm1
-        aesenc  %xmm9, %xmm2
-        aesenc  %xmm9, %xmm3
-        aesenc  %xmm9, %xmm4
-        aesenc  %xmm10, %xmm1
-        aesenc  %xmm10, %xmm2
-        aesenc  %xmm10, %xmm3
-        aesenc  %xmm10, %xmm4
-EECB_LAST_4:
-        addq    $64, %rdi
-        addq    $64, %rsi
-        decq    %rdx
-        aesenclast %xmm11, %xmm1
-        aesenclast %xmm11, %xmm2
-        aesenclast %xmm11, %xmm3
-        aesenclast %xmm11, %xmm4
-        movdqu  %xmm1, (%rsi)
-        movdqu  %xmm2, 16(%rsi)
-        movdqu  %xmm3, 32(%rsi)
-        movdqu  %xmm4, 48(%rsi)
-        jne     EECB_LOOP_4
-        addq    $64, %rsi
-EECB_REMAINDER_4:
-        cmpq    $0, %r10
-        je      EECB_END_4
-EECB_LOOP_4_2:
-        movdqu  (%rdi), %xmm1
-        addq    $16, %rdi
-        pxor    (%rcx), %xmm1
-        movdqu  160(%rcx), %xmm2
-        aesenc  16(%rcx), %xmm1
-        aesenc  32(%rcx), %xmm1
-        aesenc  48(%rcx), %xmm1
-        aesenc  64(%rcx), %xmm1
-        aesenc  80(%rcx), %xmm1
-        aesenc  96(%rcx), %xmm1
-        aesenc  112(%rcx), %xmm1
-        aesenc  128(%rcx), %xmm1
-        aesenc  144(%rcx), %xmm1
-        cmpl    $12, %r8d
-        jb      EECB_LAST_4_2
-        movdqu  192(%rcx), %xmm2
-        aesenc  160(%rcx), %xmm1
-        aesenc  176(%rcx), %xmm1
-        cmpl    $14, %r8d
-        jb      EECB_LAST_4_2
-        movdqu  224(%rcx), %xmm2
-        aesenc  192(%rcx), %xmm1
-        aesenc  208(%rcx), %xmm1
-EECB_LAST_4_2:
-        aesenclast %xmm2, %xmm1
-        movdqu  %xmm1, (%rsi)
-        addq    $16, %rsi
-        decq    %r10
-        jne     EECB_LOOP_4_2
-EECB_END_4:
-        ret
-
-
-/*
-AES_ECB_decrypt (const unsigned char *in,
-  unsigned char *out,
-  unsigned long length,
-  const unsigned char *KS,
-  int nr)
-*/
-.globl AES_ECB_decrypt
-AES_ECB_decrypt:
-# parameter 1: %rdi
-# parameter 2: %rsi
-# parameter 3: %rdx
-# parameter 4: %rcx
-# parameter 5: %r8d
-
-        movq    %rdx, %r10
-        shrq    $4, %rdx
-        shlq    $60, %r10
-        je      DECB_NO_PARTS_4
-        addq    $1, %rdx
-DECB_NO_PARTS_4:
-        movq    %rdx, %r10
-        shlq    $62, %r10
-        shrq    $62, %r10
-        shrq    $2, %rdx
-        je      DECB_REMAINDER_4
-        subq    $64, %rsi
-DECB_LOOP_4:
-        movdqu  (%rdi), %xmm1
-        movdqu  16(%rdi), %xmm2
-        movdqu  32(%rdi), %xmm3
-        movdqu  48(%rdi), %xmm4
-        movdqa  (%rcx), %xmm9
-        movdqa  16(%rcx), %xmm10
-        movdqa  32(%rcx), %xmm11
-        movdqa  48(%rcx), %xmm12
-        pxor    %xmm9, %xmm1
-        pxor    %xmm9, %xmm2
-        pxor    %xmm9, %xmm3
-        pxor    %xmm9, %xmm4
-        aesdec  %xmm10, %xmm1
-        aesdec  %xmm10, %xmm2
-        aesdec  %xmm10, %xmm3
-        aesdec  %xmm10, %xmm4
-        aesdec  %xmm11, %xmm1
-        aesdec  %xmm11, %xmm2
-        aesdec  %xmm11, %xmm3
-        aesdec  %xmm11, %xmm4
-        aesdec  %xmm12, %xmm1
-        aesdec  %xmm12, %xmm2
-        aesdec  %xmm12, %xmm3
-        aesdec  %xmm12, %xmm4
-        movdqa  64(%rcx), %xmm9
-        movdqa  80(%rcx), %xmm10
-        movdqa  96(%rcx), %xmm11
-        movdqa  112(%rcx), %xmm12
-        aesdec  %xmm9, %xmm1
-        aesdec  %xmm9, %xmm2
-        aesdec  %xmm9, %xmm3
-        aesdec  %xmm9, %xmm4
-        aesdec  %xmm10, %xmm1
-        aesdec  %xmm10, %xmm2
-        aesdec  %xmm10, %xmm3
-        aesdec  %xmm10, %xmm4
-        aesdec  %xmm11, %xmm1
-        aesdec  %xmm11, %xmm2
-        aesdec  %xmm11, %xmm3
-        aesdec  %xmm11, %xmm4
-        aesdec  %xmm12, %xmm1
-        aesdec  %xmm12, %xmm2
-        aesdec  %xmm12, %xmm3
-        aesdec  %xmm12, %xmm4
-        movdqa  128(%rcx), %xmm9
-        movdqa  144(%rcx), %xmm10
-        movdqa  160(%rcx), %xmm11
-        cmpl    $12, %r8d
-        aesdec  %xmm9, %xmm1
-        aesdec  %xmm9, %xmm2
-        aesdec  %xmm9, %xmm3
-        aesdec  %xmm9, %xmm4
-        aesdec  %xmm10, %xmm1
-        aesdec  %xmm10, %xmm2
-        aesdec  %xmm10, %xmm3
-        aesdec  %xmm10, %xmm4
-        jb      DECB_LAST_4
-        movdqa  160(%rcx), %xmm9
-        movdqa  176(%rcx), %xmm10
-        movdqa  192(%rcx), %xmm11
-        cmpl    $14, %r8d
-        aesdec  %xmm9, %xmm1
-        aesdec  %xmm9, %xmm2
-        aesdec  %xmm9, %xmm3
-        aesdec  %xmm9, %xmm4
-        aesdec  %xmm10, %xmm1
-        aesdec  %xmm10, %xmm2
-        aesdec  %xmm10, %xmm3
-        aesdec  %xmm10, %xmm4
-        jb      DECB_LAST_4
-        movdqa  192(%rcx), %xmm9
-        movdqa  208(%rcx), %xmm10
-        movdqa  224(%rcx), %xmm11
-        aesdec  %xmm9, %xmm1
-        aesdec  %xmm9, %xmm2
-        aesdec  %xmm9, %xmm3
-        aesdec  %xmm9, %xmm4
-        aesdec  %xmm10, %xmm1
-        aesdec  %xmm10, %xmm2
-        aesdec  %xmm10, %xmm3
-        aesdec  %xmm10, %xmm4
-DECB_LAST_4:
-        addq    $64, %rdi
-        addq    $64, %rsi
-        decq    %rdx
-        aesdeclast %xmm11, %xmm1
-        aesdeclast %xmm11, %xmm2
-        aesdeclast %xmm11, %xmm3
-        aesdeclast %xmm11, %xmm4
-        movdqu  %xmm1, (%rsi)
-        movdqu  %xmm2, 16(%rsi)
-        movdqu  %xmm3, 32(%rsi)
-        movdqu  %xmm4, 48(%rsi)
-        jne     DECB_LOOP_4
-        addq    $64, %rsi
-DECB_REMAINDER_4:
-        cmpq    $0, %r10
-        je      DECB_END_4
-DECB_LOOP_4_2:
-        movdqu  (%rdi), %xmm1
-        addq    $16, %rdi
-        pxor    (%rcx), %xmm1
-        movdqu  160(%rcx), %xmm2
-        cmpl    $12, %r8d
-        aesdec  16(%rcx), %xmm1
-        aesdec  32(%rcx), %xmm1
-        aesdec  48(%rcx), %xmm1
-        aesdec  64(%rcx), %xmm1
-        aesdec  80(%rcx), %xmm1
-        aesdec  96(%rcx), %xmm1
-        aesdec  112(%rcx), %xmm1
-        aesdec  128(%rcx), %xmm1
-        aesdec  144(%rcx), %xmm1
-        jb      DECB_LAST_4_2
-        cmpl    $14, %r8d
-        movdqu  192(%rcx), %xmm2
-        aesdec  160(%rcx), %xmm1
-        aesdec  176(%rcx), %xmm1
-        jb      DECB_LAST_4_2
-        movdqu  224(%rcx), %xmm2
-        aesdec  192(%rcx), %xmm1
-        aesdec  208(%rcx), %xmm1
-DECB_LAST_4_2:
-        aesdeclast %xmm2, %xmm1
-        movdqu  %xmm1, (%rsi)
-        addq    $16, %rsi
-        decq    %r10
-        jne     DECB_LOOP_4_2
-DECB_END_4:
-        ret
-
-
-
-
-/*
-void AES_128_Key_Expansion(const unsigned char* userkey,
-   unsigned char* key_schedule);
-*/
-.align  16,0x90
-.globl AES_128_Key_Expansion
-AES_128_Key_Expansion:
-# parameter 1: %rdi
-# parameter 2: %rsi
-movl    $10, 240(%rsi)
-
-movdqu  (%rdi), %xmm1
-movdqa    %xmm1, (%rsi)
-
-
-ASSISTS:
-aeskeygenassist $1, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 16(%rsi)
-aeskeygenassist $2, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 32(%rsi)
-aeskeygenassist $4, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 48(%rsi)
-aeskeygenassist $8, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 64(%rsi)
-aeskeygenassist $16, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 80(%rsi)
-aeskeygenassist $32, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 96(%rsi)
-aeskeygenassist $64, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 112(%rsi)
-aeskeygenassist $0x80, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 128(%rsi)
-aeskeygenassist $0x1b, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 144(%rsi)
-aeskeygenassist $0x36, %xmm1, %xmm2
-call PREPARE_ROUNDKEY_128
-movdqa %xmm1, 160(%rsi)
-ret
-
-PREPARE_ROUNDKEY_128:
-pshufd $255, %xmm2, %xmm2
-movdqa %xmm1, %xmm3
-pslldq $4, %xmm3
-pxor %xmm3, %xmm1
-pslldq $4, %xmm3
-pxor %xmm3, %xmm1
-pslldq $4, %xmm3
-pxor %xmm3, %xmm1
-pxor %xmm2, %xmm1
-ret
-
-
-/*
-void AES_192_Key_Expansion (const unsigned char *userkey,
-  unsigned char *key)
-*/
-.globl AES_192_Key_Expansion
-AES_192_Key_Expansion:
-# parameter 1: %rdi
-# parameter 2: %rsi
-
-movdqu (%rdi), %xmm1
-movdqu 16(%rdi), %xmm3
-movdqa %xmm1, (%rsi)
-movdqa %xmm3, %xmm5
-
-aeskeygenassist $0x1, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-shufpd $0, %xmm1, %xmm5
-movdqa %xmm5, 16(%rsi)
-movdqa %xmm1, %xmm6
-shufpd $1, %xmm3, %xmm6
-movdqa %xmm6, 32(%rsi)
-
-aeskeygenassist $0x2, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-movdqa %xmm1, 48(%rsi)
-movdqa %xmm3, %xmm5
-
-aeskeygenassist $0x4, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-shufpd $0, %xmm1, %xmm5
-movdqa %xmm5, 64(%rsi)
-movdqa %xmm1, %xmm6
-shufpd $1, %xmm3, %xmm6
-movdqa %xmm6, 80(%rsi)
-
-aeskeygenassist $0x8, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-movdqa %xmm1, 96(%rsi)
-movdqa %xmm3, %xmm5
-
-aeskeygenassist $0x10, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-shufpd $0, %xmm1, %xmm5
-movdqa %xmm5, 112(%rsi)
-movdqa %xmm1, %xmm6
-shufpd $1, %xmm3, %xmm6
-movdqa %xmm6, 128(%rsi)
-
-aeskeygenassist $0x20, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-movdqa %xmm1, 144(%rsi)
-movdqa %xmm3, %xmm5
-
-aeskeygenassist $0x40, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-shufpd $0, %xmm1, %xmm5
-movdqa %xmm5, 160(%rsi)
-movdqa %xmm1, %xmm6
-shufpd $1, %xmm3, %xmm6
-movdqa %xmm6, 176(%rsi)
-
-aeskeygenassist $0x80, %xmm3, %xmm2
-call PREPARE_ROUNDKEY_192
-movdqa %xmm1, 192(%rsi)
-movdqa %xmm3, 208(%rsi)
-ret
-
-PREPARE_ROUNDKEY_192:
-pshufd $0x55, %xmm2, %xmm2
-movdqu %xmm1, %xmm4
-pslldq $4, %xmm4
-pxor   %xmm4, %xmm1
-
-pslldq $4, %xmm4
-pxor   %xmm4, %xmm1
-pslldq $4, %xmm4
-pxor  %xmm4, %xmm1
-pxor   %xmm2, %xmm1
-pshufd $0xff, %xmm1, %xmm2
-movdqu %xmm3, %xmm4
-pslldq $4, %xmm4
-pxor   %xmm4, %xmm3
-pxor   %xmm2, %xmm3
-ret
- 
-
-/*
-void AES_256_Key_Expansion (const unsigned char *userkey,
-  unsigned char *key)
-*/
-.globl AES_256_Key_Expansion
-AES_256_Key_Expansion:
-# parameter 1: %rdi
-# parameter 2: %rsi
-
-movdqu (%rdi), %xmm1
-movdqu 16(%rdi), %xmm3
-movdqa %xmm1, (%rsi)
-movdqa %xmm3, 16(%rsi)
-
-aeskeygenassist $0x1, %xmm3, %xmm2
-call MAKE_RK256_a
-movdqa %xmm1, 32(%rsi)
-aeskeygenassist $0x0, %xmm1, %xmm2
-call MAKE_RK256_b
-movdqa %xmm3, 48(%rsi)
-aeskeygenassist $0x2, %xmm3, %xmm2
-call MAKE_RK256_a
-movdqa %xmm1, 64(%rsi)
-aeskeygenassist $0x0, %xmm1, %xmm2
-call MAKE_RK256_b
-movdqa %xmm3, 80(%rsi)
-aeskeygenassist $0x4, %xmm3, %xmm2
-call MAKE_RK256_a
-movdqa %xmm1, 96(%rsi)
-aeskeygenassist $0x0, %xmm1, %xmm2
-call MAKE_RK256_b
-movdqa %xmm3, 112(%rsi)
-aeskeygenassist $0x8, %xmm3, %xmm2
-call MAKE_RK256_a
-movdqa %xmm1, 128(%rsi)
-aeskeygenassist $0x0, %xmm1, %xmm2
-call MAKE_RK256_b
-movdqa %xmm3, 144(%rsi)
-aeskeygenassist $0x10, %xmm3, %xmm2
-call MAKE_RK256_a
-movdqa %xmm1, 160(%rsi)
-aeskeygenassist $0x0, %xmm1, %xmm2
-call MAKE_RK256_b
-movdqa %xmm3, 176(%rsi)
-aeskeygenassist $0x20, %xmm3, %xmm2
-call MAKE_RK256_a
-movdqa %xmm1, 192(%rsi)
-
-aeskeygenassist $0x0, %xmm1, %xmm2
-call MAKE_RK256_b
-movdqa %xmm3, 208(%rsi)
-aeskeygenassist $0x40, %xmm3, %xmm2
-call MAKE_RK256_a
-movdqa %xmm1, 224(%rsi)
-
-ret
-
-MAKE_RK256_a:
-pshufd $0xff, %xmm2, %xmm2
-movdqa %xmm1, %xmm4
-pslldq $4, %xmm4
-pxor   %xmm4, %xmm1
-pslldq $4, %xmm4
-pxor  %xmm4, %xmm1
-pslldq $4, %xmm4
-pxor  %xmm4, %xmm1
-pxor   %xmm2, %xmm1
-ret
-
-MAKE_RK256_b:
-pshufd $0xaa, %xmm2, %xmm2
-movdqa %xmm3, %xmm4
-pslldq $4, %xmm4
-pxor   %xmm4, %xmm3
-pslldq $4, %xmm4
-pxor  %xmm4, %xmm3
-pslldq $4, %xmm4
-pxor  %xmm4, %xmm3
-pxor   %xmm2, %xmm3
-ret
-

+ 0 - 160
Pal/lib/crypto/wolfssl/cmac.c

@@ -1,160 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The redistribution and use of this software (with or without changes)
- is allowed without the payment of fees or royalties provided that:
-
-  1. source code distributions include the above copyright notice, this
-     list of conditions and the following disclaimer;
-
-  2. binary distributions include the above copyright notice, this list
-     of conditions and the following disclaimer in their documentation;
-
-  3. the name of the copyright holder is not used to endorse products
-     built using this software without specific written permission.
-
- 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: 6/10/2008
-*/
-
-#include <stddef.h>
-
-#include "cmac.h"
-#include "aes.h"
-
-unsigned char const_Rb[16] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87
-};
-unsigned char const_Zero[16] = {
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-void xor_128(unsigned char *a, unsigned char *b, unsigned char *out)
-{
-    int i;
-    for (i = 0 ; i < 16 ; i++)
-        out[i] = a[i] ^ b[i];
-}
-
-/* AES-CMAC Generation Function */
-
-void leftshift_onebit(unsigned char *input,unsigned char *output)
-{
-    int i;
-    unsigned char overflow = 0;
-
-    for (i = 15; i >= 0 ; i--) {
-        output[i] = input[i] << 1;
-        output[i] |= overflow;
-        overflow = (input[i] & 0x80)?1:0;
-    }
-}
-
-void generate_subkey(unsigned char *key, unsigned char *K1, unsigned char *K2)
-{
-    unsigned char L[16];
-    unsigned char Z[16];
-    unsigned char tmp[16];
-    int i;
-
-    for ( i = 0 ; i < 16 ; i++) Z[i] = 0;
-
-    AES aes;
-    AESSetKey(&aes, key, 16, NULL, AES_ENCRYPTION);
-
-    AESEncrypt(&aes, Z, L);
-
-    if ((L[0] & 0x80) == 0) {
-        /* If MSB(L) = 0, then K1 = L << 1 */
-        leftshift_onebit(L,K1);
-    } else {
-        /* Else K1 = ( L << 1 ) (+) Rb */
-        leftshift_onebit(L,tmp);
-        xor_128(tmp,const_Rb,K1);
-    }
-
-    if ((K1[0] & 0x80) == 0) {
-        leftshift_onebit(K1,K2);
-    } else {
-        leftshift_onebit(K1,tmp);
-        xor_128(tmp,const_Rb,K2);
-    }
-}
-
-void padding (unsigned char *lastb, unsigned char *pad, int length)
-{
-    int j;
-
-    /* original last block */
-    for ( j = 0 ; j < 16 ; j++) {
-        if (j < length) {
-            pad[j] = lastb[j];
-        } else if (j == length) {
-            pad[j] = 0x80;
-        } else {
-            pad[j] = 0x00;
-        }
-    }
-}
-
-#include "api.h"
-
-void AES_CMAC (unsigned char *key, unsigned char *input, int length,
-               unsigned char *mac)
-{
-    unsigned char X[16],Y[16], M_last[16], padded[16];
-    unsigned char K1[16], K2[16];
-    int n, i, flag;
-    generate_subkey(key, K1, K2);
-
-    n = (length+15) / 16;       /* n is number of rounds */
-
-    if (n == 0) {
-        n = 1;
-        flag = 0;
-    } else {
-        if ((length%16) == 0) {
-            /* last block is a complete block */
-            flag = 1;
-        } else {
-            /* last block is not complete block */
-            flag = 0;
-        }
-    }
-
-    if (flag) {
-        /* last block is complete block */
-        xor_128(&input[16*(n-1)], K1, M_last);
-    } else {
-        padding(&input[16*(n-1)],padded,length%16);
-        xor_128(padded, K2, M_last);
-    }
-
-    AES aes;
-    AESSetKey(&aes, key, 16, NULL, AES_ENCRYPTION);
-
-    for (i = 0 ; i < 16; i++) X[i] = 0;
-    for (i = 0 ; i < n - 1; i++) {
-        xor_128(X, &input[16 * i], Y); /* Y := Mi (+) X  */
-        AESEncrypt(&aes, Y, X); /* X := AES-128(KEY, Y); */ 
-    }
-
-    xor_128(X, M_last, Y);
-    AESEncrypt(&aes, Y, X);
-
-    for (i = 0; i < 16; i++)
-        mac[i] = X[i];
-}

+ 0 - 39
Pal/lib/crypto/wolfssl/cmac.h

@@ -1,39 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/*
- ---------------------------------------------------------------------------
- Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved.
-
- LICENSE TERMS
-
- The redistribution and use of this software (with or without changes)
- is allowed without the payment of fees or royalties provided that:
-
-  1. source code distributions include the above copyright notice, this
-     list of conditions and the following disclaimer;
-
-  2. binary distributions include the above copyright notice, this list
-     of conditions and the following disclaimer in their documentation;
-
-  3. the name of the copyright holder is not used to endorse products
-     built using this software without specific written permission.
-
- 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: 6/10/2008
-*/
-
-#ifndef CMAC_AES_H
-#define CMAC_AES_H
-
-#include "aes.h"
-
-void AES_CMAC (unsigned char *key, unsigned char *input, int length,
-               unsigned char *mac);
-
-#endif

+ 0 - 233
Pal/lib/crypto/wolfssl/dh.c

@@ -1,233 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* dh.c
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "crypto/wolfssl/integer.h"
-#include "crypto/wolfssl/dh.h"
-#include "crypto/wolfssl/error-crypt.h"
-
-/*
- * source
- * http://fastapprox.googlecode.com/svn/trunk/fastapprox/src/fastonebigheader.h
- */
-
-static inline float
-fastlog2 (float x)
-{
-    union { float f; uint32_t i; } vx = { x };
-    union { uint32_t i; float f; } mx = { (vx.i & 0x007FFFFF) | 0x3f000000 };
-    float y = vx.i;
-    y *= 1.1920928955078125e-7f;
-
-    return y - 124.22551499f
-             - 1.498030302f  *mx.f
-             - 1.72587999f / (0.3520887068f + mx.f);
-}
-
-static inline float
-fastlog (float x)
-{
-    return 0.69314718f  *fastlog2 (x);
-}
-
-static inline float
-fastpow2 (float p)
-{
-  float offset = (p < 0) ? 1.0f : 0.0f;
-  float clipp = (p < -126) ? -126.0f : p;
-  int w = clipp;
-  float z = clipp - w + offset;
-  union { uint32_t i; float f; } v = { (uint32_t) ( (1 << 23)  *(clipp + 121.2740575f + 27.7280233f / (4.84252568f - z) - 1.49012907f  *z) ) };
-
-  return v.f;
-}
-
-static inline float
-fastpow (float x,
-         float p)
-{
-  return fastpow2 (p  *fastlog2 (x));
-}
-
-#define XPOW(x,y) fastpow((x),(y))
-#define XLOG(x)   fastlog((x))
-
-#ifndef min
-static inline word32 min(word32 a, word32 b)
-{
-    return a > b ? b : a;
-}
-#endif /* min */
-
-
-void InitDhKey(DhKey *key)
-{
-    (void)key;
-    key->p.dp = 0;
-    key->g.dp = 0;
-}
-
-
-void FreeDhKey(DhKey *key)
-{
-    (void)key;
-    mp_clear(&key->p);
-    mp_clear(&key->g);
-}
-
-static word32 DiscreteLogWorkFactor(word32 n)
-{
-    /* assuming discrete log takes about the same time as factoring */
-    if (n<5)
-        return 0;
-    else
-        return (word32)(2.4  *XPOW((double)n, 1.0/3.0) *
-                XPOW(XLOG((double)n), 2.0/3.0) - 5);
-}
-
-int _DkRandomBitsRead (void  *buffer, int size);
-
-static int GeneratePrivate(DhKey *key, byte *priv, word32 *privSz)
-{
-    int ret;
-    word32 sz = mp_unsigned_bin_size(&key->p);
-    sz = min(sz, 2  * DiscreteLogWorkFactor(sz * BIT_SIZE) / BIT_SIZE + 1);
-
-    ret = _DkRandomBitsRead(priv, sz);
-    if (ret < 0)
-        return ret;
-
-    priv[0] |= 0x0C;
-    *privSz = sz;
-    return 0;
-}
-
-
-static int GeneratePublic(DhKey *key, const byte *priv, word32 privSz,
-                          byte *pub, word32 *pubSz)
-{
-    int ret = 0;
-
-    mp_int x;
-    mp_int y;
-
-    if (mp_init_multi(&x, &y, 0, 0, 0, 0) != MP_OKAY)
-        return MP_INIT_E;
-
-    if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
-        ret = MP_READ_E;
-
-    if (ret == 0 && mp_exptmod(&key->g, &x, &key->p, &y) != MP_OKAY)
-        ret = MP_EXPTMOD_E;
-
-    if (ret == 0 && mp_to_unsigned_bin(&y, pub) != MP_OKAY)
-        ret = MP_TO_E;
-
-    if (ret == 0)
-        *pubSz = mp_unsigned_bin_size(&y);
-
-    mp_clear(&y);
-    mp_clear(&x);
-
-    return ret;
-}
-
-
-int DhGenerateKeyPair(DhKey *key, byte *priv, word32 *privSz,
-                      byte *pub, word32 *pubSz)
-{
-    int ret = GeneratePrivate(key, priv, privSz);
-
-    return (ret != 0) ? ret : GeneratePublic(key, priv, *privSz, pub, pubSz);
-}
-
-int DhAgree(DhKey *key, byte *agree, word32 *agreeSz, const byte *priv,
-            word32 privSz, const byte *otherPub, word32 pubSz)
-{
-    int ret = 0;
-
-    mp_int x;
-    mp_int y;
-    mp_int z;
-
-    if (mp_init_multi(&x, &y, &z, 0, 0, 0) != MP_OKAY)
-        return MP_INIT_E;
-
-    if (mp_read_unsigned_bin(&x, priv, privSz) != MP_OKAY)
-        ret = MP_READ_E;
-
-    if (ret == 0 && mp_read_unsigned_bin(&y, otherPub, pubSz) != MP_OKAY)
-        ret = MP_READ_E;
-
-    if (ret == 0 && mp_exptmod(&y, &x, &key->p, &z) != MP_OKAY)
-        ret = MP_EXPTMOD_E;
-
-    if (ret == 0 && mp_to_unsigned_bin(&z, agree) != MP_OKAY)
-        ret = MP_TO_E;
-
-    if (ret == 0)
-        *agreeSz = mp_unsigned_bin_size(&z);
-
-    mp_clear(&z);
-    mp_clear(&y);
-    mp_clear(&x);
-
-    return ret;
-}
-
-int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz)
-{
-    if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0)
-        return BAD_FUNC_ARG;
-
-    /* may have leading 0 */
-    if (p[0] == 0) {
-        pSz--; p++;
-    }
-
-    if (g[0] == 0) {
-        gSz--; g++;
-    }
-
-    if (mp_init(&key->p) != MP_OKAY)
-        return MP_INIT_E;
-    if (mp_read_unsigned_bin(&key->p, p, pSz) != 0) {
-        mp_clear(&key->p);
-        return ASN_DH_KEY_E;
-    }
-
-    if (mp_init(&key->g) != MP_OKAY) {
-        mp_clear(&key->p);
-        return MP_INIT_E;
-    }
-    if (mp_read_unsigned_bin(&key->g, g, gSz) != 0) {
-        mp_clear(&key->g);
-        mp_clear(&key->p);
-        return ASN_DH_KEY_E;
-    }
-
-    return 0;
-}

+ 0 - 59
Pal/lib/crypto/wolfssl/dh.h

@@ -1,59 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* dh.h
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#ifndef CTAO_CRYPT_DH_H
-#define CTAO_CRYPT_DH_H
-
-#include <stdint.h>
-
-#ifndef word32
-typedef uint32_t word32;
-#endif
-#ifndef byte
-typedef uint8_t byte;
-#endif
-
-#define BIT_SIZE  8
-
-#include "crypto/wolfssl/integer.h"
-
-/* Diffie-Hellman Key */
-typedef struct DhKey {
-    mp_int p, g;                            /* group parameters  */
-} DhKey;
-
-
-void InitDhKey(DhKey *key);
-void FreeDhKey(DhKey *key);
-
-int DhGenerateKeyPair(DhKey *key, byte *priv,
-                      word32 *privSz, byte *pub, word32 *pubSz);
-int DhAgree(DhKey *key, byte *agree, word32 *agreeSz,
-            const byte *priv, word32 privSz, const byte *otherPub,
-            word32 pubSz);
-
-int DhSetKey(DhKey *key, const byte *p, word32 pSz, const byte *g,
-             word32 gSz);
-
-#endif /* CTAO_CRYPT_DH_H */

+ 0 - 137
Pal/lib/crypto/wolfssl/error-crypt.h

@@ -1,137 +0,0 @@
-/* error-crypt.h
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-
-#ifndef CTAO_CRYPT_ERROR_H
-#define CTAO_CRYPT_ERROR_H
-
-/* error codes */
-enum {
-    MAX_CODE_E         = -100,  /* errors -101 - -299 */
-    OPEN_RAN_E         = -101,  /* opening random device error */
-    READ_RAN_E         = -102,  /* reading random device error */
-    WINCRYPT_E         = -103,  /* windows crypt init error */
-    CRYPTGEN_E         = -104,  /* windows crypt generation error */
-    RAN_BLOCK_E        = -105,  /* reading random device would block */
-    BAD_MUTEX_E        = -106,  /* Bad mutex operation */
-
-    MP_INIT_E          = -110,  /* mp_init error state */
-    MP_READ_E          = -111,  /* mp_read error state */
-    MP_EXPTMOD_E       = -112,  /* mp_exptmod error state */
-    MP_TO_E            = -113,  /* mp_to_xxx error state, can't convert */
-    MP_SUB_E           = -114,  /* mp_sub error state, can't subtract */
-    MP_ADD_E           = -115,  /* mp_add error state, can't add */
-    MP_MUL_E           = -116,  /* mp_mul error state, can't multiply */
-    MP_MULMOD_E        = -117,  /* mp_mulmod error state, can't multiply mod */
-    MP_MOD_E           = -118,  /* mp_mod error state, can't mod */
-    MP_INVMOD_E        = -119,  /* mp_invmod error state, can't inv mod */
-    MP_CMP_E           = -120,  /* mp_cmp error state */
-    MP_ZERO_E          = -121,  /* got a mp zero result, not expected */
-
-    MEMORY_E           = -125,  /* out of memory error */
-
-    RSA_WRONG_TYPE_E   = -130,  /* RSA wrong block type for RSA function */
-    RSA_BUFFER_E       = -131,  /* RSA buffer error, output too small or 
-                                   input too large */
-    BUFFER_E           = -132,  /* output buffer too small or input too large */
-    ALGO_ID_E          = -133,  /* setting algo id error */
-    PUBLIC_KEY_E       = -134,  /* setting public key error */
-    DATE_E             = -135,  /* setting date validity error */
-    SUBJECT_E          = -136,  /* setting subject name error */
-    ISSUER_E           = -137,  /* setting issuer  name error */
-    CA_TRUE_E          = -138,  /* setting CA basic constraint true error */
-    EXTENSIONS_E       = -139,  /* setting extensions error */
-
-    ASN_PARSE_E        = -140,  /* ASN parsing error, invalid input */
-    ASN_VERSION_E      = -141,  /* ASN version error, invalid number */
-    ASN_GETINT_E       = -142,  /* ASN get big int error, invalid data */
-    ASN_RSA_KEY_E      = -143,  /* ASN key init error, invalid input */
-    ASN_OBJECT_ID_E    = -144,  /* ASN object id error, invalid id */
-    ASN_TAG_NULL_E     = -145,  /* ASN tag error, not null */
-    ASN_EXPECT_0_E     = -146,  /* ASN expect error, not zero */
-    ASN_BITSTR_E       = -147,  /* ASN bit string error, wrong id */
-    ASN_UNKNOWN_OID_E  = -148,  /* ASN oid error, unknown sum id */
-    ASN_DATE_SZ_E      = -149,  /* ASN date error, bad size */
-    ASN_BEFORE_DATE_E  = -150,  /* ASN date error, current date before */
-    ASN_AFTER_DATE_E   = -151,  /* ASN date error, current date after */
-    ASN_SIG_OID_E      = -152,  /* ASN signature error, mismatched oid */
-    ASN_TIME_E         = -153,  /* ASN time error, unknown time type */
-    ASN_INPUT_E        = -154,  /* ASN input error, not enough data */
-    ASN_SIG_CONFIRM_E  = -155,  /* ASN sig error, confirm failure */
-    ASN_SIG_HASH_E     = -156,  /* ASN sig error, unsupported hash type */
-    ASN_SIG_KEY_E      = -157,  /* ASN sig error, unsupported key type */
-    ASN_DH_KEY_E       = -158,  /* ASN key init error, invalid input */
-    ASN_NTRU_KEY_E     = -159,  /* ASN ntru key decode error, invalid input */
-    ASN_CRIT_EXT_E     = -160,  /* ASN unsupported critical extension */
-
-    ECC_BAD_ARG_E      = -170,  /* ECC input argument of wrong type */
-    ASN_ECC_KEY_E      = -171,  /* ASN ECC bad input */
-    ECC_CURVE_OID_E    = -172,  /* Unsupported ECC OID curve type */
-    BAD_FUNC_ARG       = -173,  /* Bad function argument provided */
-    NOT_COMPILED_IN    = -174,  /* Feature not compiled in */
-    UNICODE_SIZE_E     = -175,  /* Unicode password too big */
-    NO_PASSWORD        = -176,  /* no password provided by user */
-    ALT_NAME_E         = -177,  /* alt name size problem, too big */
-
-    AES_GCM_AUTH_E     = -180,  /* AES-GCM Authentication check failure */
-    AES_CCM_AUTH_E     = -181,  /* AES-CCM Authentication check failure */
-
-    CAVIUM_INIT_E      = -182,  /* Cavium Init type error */
-
-    COMPRESS_INIT_E    = -183,  /* Compress init error */
-    COMPRESS_E         = -184,  /* Compress error */
-    DECOMPRESS_INIT_E  = -185,  /* DeCompress init error */
-    DECOMPRESS_E       = -186,  /* DeCompress error */
-
-    BAD_ALIGN_E         = -187,  /* Bad alignment for operation, no alloc */
-    ASN_NO_SIGNER_E     = -188,  /* ASN no signer to confirm failure */
-    ASN_CRL_CONFIRM_E   = -189,  /* ASN CRL signature confirm failure */
-    ASN_CRL_NO_SIGNER_E = -190,  /* ASN CRL no signer to confirm failure */
-    ASN_OCSP_CONFIRM_E  = -191,  /* ASN OCSP signature confirm failure */
-
-    BAD_ENC_STATE_E     = -192,  /* Bad ecc enc state operation */
-    BAD_PADDING_E       = -193,  /* Bad padding, msg not correct length  */
-
-    REQ_ATTRIBUTE_E     = -194,  /* setting cert request attributes error */
-
-    PKCS7_OID_E         = -195,  /* PKCS#7, mismatched OID error */
-    PKCS7_RECIP_E       = -196,  /* PKCS#7, recipient error */
-    FIPS_NOT_ALLOWED_E  = -197,  /* FIPS not allowed error */
-    ASN_NAME_INVALID_E  = -198,  /* ASN name constraint error */
-
-    RNG_FAILURE_E       = -199,  /* RNG Failed, Reinitialize */
-    HMAC_MIN_KEYLEN_E   = -200,  /* FIPS Mode HMAC Minimum Key Length error */
-    RSA_PAD_E           = -201,  /* RSA Padding Error */
-    LENGTH_ONLY_E       = -202,  /* Returning output length only */
-
-    IN_CORE_FIPS_E      = -203,  /* In Core Integrity check failure */
-    AES_KAT_FIPS_E      = -204,  /* AES KAT failure */
-    DES3_KAT_FIPS_E     = -205,  /* DES3 KAT failure */
-    HMAC_KAT_FIPS_E     = -206,  /* HMAC KAT failure */
-    RSA_KAT_FIPS_E      = -207,  /* RSA KAT failure */
-    DRBG_KAT_FIPS_E     = -208,  /* HASH DRBG KAT failure */
-    DRBG_CONT_FIPS_E    = -209,  /* HASH DRBG Continious test failure */
-    AESGCM_KAT_FIPS_E   = -210,  /* AESGCM KAT failure */
-
-    MIN_CODE_E          = -300   /* errors -101 - -299 */
-};
-
-#endif /* CTAO_CRYPT_ERROR_H */

+ 0 - 4312
Pal/lib/crypto/wolfssl/integer.c

@@ -1,4312 +0,0 @@
-/* integer.c
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-
-/*
- * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,
- * http://math.libtomcrypt.com
- */
-
-#include <stddef.h>
-#include <stdint.h>
-#include "integer.h"
-
-void * malloc (int size);
-void free (void * mem);
-void * remalloc (const void * mem, int size);
-
-void memcpy(void *, void *, size_t);
-
-#define XMALLOC  malloc
-#define XFREE    free
-#define XREALLOC internal_realloc
-
-/* Implement realloc by ourselves, since the library doesn't provide realloc.
- */
-void * internal_realloc(void *old, int old_size, int new_size)
-{
-    void *new = XMALLOC(new_size);
-    if (new == NULL)
-        return NULL;
-    memcpy(new, old, old_size);
-    XFREE(old);
-    return new;
-}
-
-static inline int toupper (int c)
-{
-    return ('a' <= c && c <= 'z') ? 'A' + (c - 'a') : c;
-}
-
-#define XTOUPPER toupper
-
-static void bn_reverse (unsigned char *s, int len);
-
-/* handle up to 6 inits */
-int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
-                  mp_int* f)
-{
-    int res = MP_OKAY;
-
-    if (a && ((res = mp_init(a)) != MP_OKAY))
-        return res;
-
-    if (b && ((res = mp_init(b)) != MP_OKAY)) {
-        mp_clear(a);
-        return res;
-    }
-
-    if (c && ((res = mp_init(c)) != MP_OKAY)) {
-        mp_clear(a); mp_clear(b);
-        return res;
-    }
-
-    if (d && ((res = mp_init(d)) != MP_OKAY)) {
-        mp_clear(a); mp_clear(b); mp_clear(c);
-        return res;
-    }
-
-    if (e && ((res = mp_init(e)) != MP_OKAY)) {
-        mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d);
-        return res;
-    }
-
-    if (f && ((res = mp_init(f)) != MP_OKAY)) {
-        mp_clear(a); mp_clear(b); mp_clear(c); mp_clear(d); mp_clear(e);
-        return res;
-    }
-
-    return res;
-}
-
-
-/* init a new mp_int */
-int mp_init (mp_int * a)
-{
-  int i;
-
-  /* allocate memory required and clear it */
-  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
-  if (a->dp == NULL) {
-    return MP_MEM;
-  }
-
-  /* set the digits to zero */
-  for (i = 0; i < MP_PREC; i++) {
-      a->dp[i] = 0;
-  }
-
-  /* set the used to zero, allocated digits to the default precision
-   * and sign to positive */
-  a->used  = 0;
-  a->alloc = MP_PREC;
-  a->sign  = MP_ZPOS;
-
-  return MP_OKAY;
-}
-
-
-/* clear one (frees)  */
-void
-mp_clear (mp_int * a)
-{
-  int i;
-
-  if (a == NULL)
-      return;
-
-  /* only do anything if a hasn't been freed previously */
-  if (a->dp != NULL) {
-    /* first zero the digits */
-    for (i = 0; i < a->used; i++) {
-        a->dp[i] = 0;
-    }
-
-    /* free ram */
-    XFREE(a->dp);
-
-    /* reset members to make debugging easier */
-    a->dp    = NULL;
-    a->alloc = a->used = 0;
-    a->sign  = MP_ZPOS;
-  }
-}
-
-
-/* get the size for an unsigned equivalent */
-int mp_unsigned_bin_size (mp_int * a)
-{
-  int     size = mp_count_bits (a);
-  return (size / 8 + ((size & 7) != 0 ? 1 : 0));
-}
-
-
-/* returns the number of bits in an int */
-int
-mp_count_bits (mp_int * a)
-{
-  int     r;
-  mp_digit q;
-
-  /* shortcut */
-  if (a->used == 0) {
-    return 0;
-  }
-
-  /* get number of digits and add that */
-  r = (a->used - 1) * DIGIT_BIT;
-
-  /* take the last digit and count the bits in it */
-  q = a->dp[a->used - 1];
-  while (q > ((mp_digit) 0)) {
-    ++r;
-    q >>= ((mp_digit) 1);
-  }
-  return r;
-}
-
-
-int mp_leading_bit (mp_int * a)
-{
-    int bit = 0;
-    mp_int t;
-
-    if (mp_init_copy(&t, a) != MP_OKAY)
-        return 0;
-
-    while (mp_iszero(&t) == 0) {
-#ifndef MP_8BIT
-        bit = (t.dp[0] & 0x80) != 0;
-#else
-        bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0;
-#endif
-        if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY)
-            break;
-    }
-    mp_clear(&t);
-    return bit;
-}
-
-
-/* store in unsigned [big endian] format */
-int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
-{
-  int     x, res;
-  mp_int  t;
-
-  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
-    return res;
-  }
-
-  x = 0;
-  while (mp_iszero (&t) == 0) {
-#ifndef MP_8BIT
-      b[x++] = (unsigned char) (t.dp[0] & 255);
-#else
-      b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
-#endif
-    if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
-      mp_clear (&t);
-      return res;
-    }
-  }
-  bn_reverse (b, x);
-  mp_clear (&t);
-  return MP_OKAY;
-}
-
-
-/* creates "a" then copies b into it */
-int mp_init_copy (mp_int * a, mp_int * b)
-{
-  int     res;
-
-  if ((res = mp_init (a)) != MP_OKAY) {
-    return res;
-  }
-  return mp_copy (b, a);
-}
-
-
-/* copy, b = a */
-int
-mp_copy (mp_int * a, mp_int * b)
-{
-  int     res, n;
-
-  /* if dst == src do nothing */
-  if (a == b) {
-    return MP_OKAY;
-  }
-
-  /* grow dest */
-  if (b->alloc < a->used) {
-     if ((res = mp_grow (b, a->used)) != MP_OKAY) {
-        return res;
-     }
-  }
-
-  /* zero b and copy the parameters over */
-  {
-    register mp_digit *tmpa, *tmpb;
-
-    /* pointer aliases */
-
-    /* source */
-    tmpa = a->dp;
-
-    /* destination */
-    tmpb = b->dp;
-
-    /* copy all the digits */
-    for (n = 0; n < a->used; n++) {
-      *tmpb++ = *tmpa++;
-    }
-
-    /* clear high digits */
-    for (; n < b->used; n++) {
-      *tmpb++ = 0;
-    }
-  }
-
-  /* copy used count and sign */
-  b->used = a->used;
-  b->sign = a->sign;
-  return MP_OKAY;
-}
-
-
-/* grow as required */
-int mp_grow (mp_int * a, int size)
-{
-  int     i;
-  mp_digit *tmp;
-
-  /* if the alloc size is smaller alloc more ram */
-  if (a->alloc < size) {
-    /* ensure there are always at least MP_PREC digits extra on top */
-    size += (MP_PREC * 2) - (size % MP_PREC);
-
-    /* reallocate the array a->dp
-     *
-     * We store the return in a temporary variable
-     * in case the operation failed we don't want
-     * to overwrite the dp member of a.
-     */
-    //tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
-    tmp = OPT_CAST(mp_digit) internal_realloc(a->dp,
-                                              sizeof (mp_digit) * a->alloc,
-                                              sizeof (mp_digit) * size);
-    if (tmp == NULL) {
-      /* reallocation failed but "a" is still valid [can be freed] */
-      return MP_MEM;
-    }
-
-    /* reallocation succeeded so set a->dp */
-    a->dp = tmp;
-
-    /* zero excess digits */
-    i        = a->alloc;
-    a->alloc = size;
-    for (; i < a->alloc; i++) {
-      a->dp[i] = 0;
-    }
-  }
-  return MP_OKAY;
-}
-
-
-/* reverse an array, used for radix code */
-void
-bn_reverse (unsigned char *s, int len)
-{
-  int     ix, iy;
-  unsigned char t;
-
-  ix = 0;
-  iy = len - 1;
-  while (ix < iy) {
-    t     = s[ix];
-    s[ix] = s[iy];
-    s[iy] = t;
-    ++ix;
-    --iy;
-  }
-}
-
-
-/* shift right by a certain bit count (store quotient in c, optional
-   remainder in d) */
-int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
-{
-  int     D, res;
-  mp_int  t;
-
-
-  /* if the shift count is <= 0 then we do no work */
-  if (b <= 0) {
-    res = mp_copy (a, c);
-    if (d != NULL) {
-      mp_zero (d);
-    }
-    return res;
-  }
-
-  if ((res = mp_init (&t)) != MP_OKAY) {
-    return res;
-  }
-
-  /* get the remainder */
-  if (d != NULL) {
-    if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
-      mp_clear (&t);
-      return res;
-    }
-  }
-
-  /* copy */
-  if ((res = mp_copy (a, c)) != MP_OKAY) {
-    mp_clear (&t);
-    return res;
-  }
-
-  /* shift by as many digits in the bit count */
-  if (b >= (int)DIGIT_BIT) {
-    mp_rshd (c, b / DIGIT_BIT);
-  }
-
-  /* shift any bit count < DIGIT_BIT */
-  D = (b % DIGIT_BIT);
-  if (D != 0) {
-    mp_rshb(c, D);
-  }
-  mp_clamp (c);
-  if (d != NULL) {
-    mp_exch (&t, d);
-  }
-  mp_clear (&t);
-  return MP_OKAY;
-}
-
-
-/* set to zero */
-void mp_zero (mp_int * a)
-{
-  int       n;
-  mp_digit *tmp;
-
-  a->sign = MP_ZPOS;
-  a->used = 0;
-
-  tmp = a->dp;
-  for (n = 0; n < a->alloc; n++) {
-     *tmp++ = 0;
-  }
-}
-
-
-/* trim unused digits 
- *
- * This is used to ensure that leading zero digits are
- * trimed and the leading "used" digit will be non-zero
- * Typically very fast.  Also fixes the sign if there
- * are no more leading digits
- */
-void
-mp_clamp (mp_int * a)
-{
-  /* decrease used while the most significant digit is
-   * zero.
-   */
-  while (a->used > 0 && a->dp[a->used - 1] == 0) {
-    --(a->used);
-  }
-
-  /* reset the sign flag if used == 0 */
-  if (a->used == 0) {
-    a->sign = MP_ZPOS;
-  }
-}
-
-
-/* swap the elements of two integers, for cases where you can't simply swap the 
- * mp_int pointers around
- */
-void
-mp_exch (mp_int * a, mp_int * b)
-{
-  mp_int  t;
-
-  t  = *a;
-  *a = *b;
-  *b = t;
-}
-
-
-/* shift right a certain number of bits */
-void mp_rshb (mp_int *c, int x)
-{
-    register mp_digit *tmpc, mask, shift;
-    mp_digit r, rr;
-    mp_digit D = x;
-
-    /* mask */
-    mask = (((mp_digit)1) << D) - 1;
-
-    /* shift for lsb */
-    shift = DIGIT_BIT - D;
-
-    /* alias */
-    tmpc = c->dp + (c->used - 1);
-
-    /* carry */
-    r = 0;
-    for (x = c->used - 1; x >= 0; x--) {
-      /* get the lower  bits of this word in a temp */
-      rr = *tmpc & mask;
-
-      /* shift the current word and mix in the carry bits from previous word */
-      *tmpc = (*tmpc >> D) | (r << shift);
-      --tmpc;
-
-      /* set the carry to the carry bits of the current word found above */
-      r = rr;
-    }
-}
-
-
-/* shift right a certain amount of digits */
-void mp_rshd (mp_int * a, int b)
-{
-  int     x;
-
-  /* if b <= 0 then ignore it */
-  if (b <= 0) {
-    return;
-  }
-
-  /* if b > used then simply zero it and return */
-  if (a->used <= b) {
-    mp_zero (a);
-    return;
-  }
-
-  {
-    register mp_digit *bottom, *top;
-
-    /* shift the digits down */
-
-    /* bottom */
-    bottom = a->dp;
-
-    /* top [offset into digits] */
-    top = a->dp + b;
-
-    /* this is implemented as a sliding window where 
-     * the window is b-digits long and digits from 
-     * the top of the window are copied to the bottom
-     *
-     * e.g.
-
-     b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
-                 /\                   |      ---->
-                  \-------------------/      ---->
-     */
-    for (x = 0; x < (a->used - b); x++) {
-      *bottom++ = *top++;
-    }
-
-    /* zero the top digits */
-    for (; x < a->used; x++) {
-      *bottom++ = 0;
-    }
-  }
-
-  /* remove excess digits */
-  a->used -= b;
-}
-
-
-/* calc a value mod 2**b */
-int
-mp_mod_2d (mp_int * a, int b, mp_int * c)
-{
-  int     x, res;
-
-  /* if b is <= 0 then zero the int */
-  if (b <= 0) {
-    mp_zero (c);
-    return MP_OKAY;
-  }
-
-  /* if the modulus is larger than the value than return */
-  if (b >= (int) (a->used * DIGIT_BIT)) {
-    res = mp_copy (a, c);
-    return res;
-  }
-
-  /* copy */
-  if ((res = mp_copy (a, c)) != MP_OKAY) {
-    return res;
-  }
-
-  /* zero digits above the last digit of the modulus */
-  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
-    c->dp[x] = 0;
-  }
-  /* clear the digit that is not completely outside/inside the modulus */
-  c->dp[b / DIGIT_BIT] &= (mp_digit) ((((mp_digit) 1) <<
-              (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
-  mp_clamp (c);
-  return MP_OKAY;
-}
-
-
-/* reads a unsigned char array, assumes the msb is stored first [big endian] */
-int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
-{
-  int     res;
-
-  /* make sure there are at least two digits */
-  if (a->alloc < 2) {
-     if ((res = mp_grow(a, 2)) != MP_OKAY) {
-        return res;
-     }
-  }
-
-  /* zero the int */
-  mp_zero (a);
-
-  /* read the bytes in */
-  while (c-- > 0) {
-    if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
-      return res;
-    }
-
-#ifndef MP_8BIT
-      a->dp[0] |= *b++;
-      a->used += 1;
-#else
-      a->dp[0] = (*b & MP_MASK);
-      a->dp[1] |= ((*b++ >> 7U) & 1);
-      a->used += 2;
-#endif
-  }
-  mp_clamp (a);
-  return MP_OKAY;
-}
-
-
-/* shift left by a certain bit count */
-int mp_mul_2d (mp_int * a, int b, mp_int * c)
-{
-  mp_digit d;
-  int      res;
-
-  /* copy */
-  if (a != c) {
-     if ((res = mp_copy (a, c)) != MP_OKAY) {
-       return res;
-     }
-  }
-
-  if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
-     if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
-       return res;
-     }
-  }
-
-  /* shift by as many digits in the bit count */
-  if (b >= (int)DIGIT_BIT) {
-    if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* shift any bit count < DIGIT_BIT */
-  d = (mp_digit) (b % DIGIT_BIT);
-  if (d != 0) {
-    register mp_digit *tmpc, shift, mask, r, rr;
-    register int x;
-
-    /* bitmask for carries */
-    mask = (((mp_digit)1) << d) - 1;
-
-    /* shift for msbs */
-    shift = DIGIT_BIT - d;
-
-    /* alias */
-    tmpc = c->dp;
-
-    /* carry */
-    r    = 0;
-    for (x = 0; x < c->used; x++) {
-      /* get the higher bits of the current word */
-      rr = (*tmpc >> shift) & mask;
-
-      /* shift the current word and OR in the carry */
-      *tmpc = ((*tmpc << d) | r) & MP_MASK;
-      ++tmpc;
-
-      /* set the carry to the carry bits of the current word */
-      r = rr;
-    }
-
-    /* set final carry */
-    if (r != 0) {
-       c->dp[(c->used)++] = r;
-    }
-  }
-  mp_clamp (c);
-  return MP_OKAY;
-}
-
-
-/* shift left a certain amount of digits */
-int mp_lshd (mp_int * a, int b)
-{
-  int     x, res;
-
-  /* if its less than zero return */
-  if (b <= 0) {
-    return MP_OKAY;
-  }
-
-  /* grow to fit the new digits */
-  if (a->alloc < a->used + b) {
-     if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
-       return res;
-     }
-  }
-
-  {
-    register mp_digit *top, *bottom;
-
-    /* increment the used by the shift amount then copy upwards */
-    a->used += b;
-
-    /* top */
-    top = a->dp + a->used - 1;
-
-    /* base */
-    bottom = a->dp + a->used - 1 - b;
-
-    /* much like mp_rshd this is implemented using a sliding window
-     * except the window goes the otherway around.  Copying from
-     * the bottom to the top.  see bn_mp_rshd.c for more info.
-     */
-    for (x = a->used - 1; x >= b; x--) {
-      *top-- = *bottom--;
-    }
-
-    /* zero the lower digits */
-    top = a->dp;
-    for (x = 0; x < b; x++) {
-      *top++ = 0;
-    }
-  }
-  return MP_OKAY;
-}
-
-
-/* this is a shell function that calls either the normal or Montgomery
- * exptmod functions.  Originally the call to the montgomery code was
- * embedded in the normal function but that wasted alot of stack space
- * for nothing (since 99% of the time the Montgomery code would be called)
- */
-int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
-{
-  int dr;
-
-  /* modulus P must be positive */
-  if (P->sign == MP_NEG) {
-     return MP_VAL;
-  }
-
-  /* if exponent X is negative we have to recurse */
-  if (X->sign == MP_NEG) {
-     mp_int tmpG, tmpX;
-     int err;
-
-     /* first compute 1/G mod P */
-     if ((err = mp_init(&tmpG)) != MP_OKAY) {
-        return err;
-     }
-     if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
-        mp_clear(&tmpG);
-        return err;
-     }
-
-     /* now get |X| */
-     if ((err = mp_init(&tmpX)) != MP_OKAY) {
-        mp_clear(&tmpG);
-        return err;
-     }
-     if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
-        mp_clear(&tmpG);
-        mp_clear(&tmpX);
-        return err;
-     }
-
-     /* and now compute (1/G)**|X| instead of G**X [X < 0] */
-     err = mp_exptmod(&tmpG, &tmpX, P, Y);
-     mp_clear(&tmpG);
-     mp_clear(&tmpX);
-     return err;
-  }
-
-/* modified diminished radix reduction */
-  if (mp_reduce_is_2k_l(P) == MP_YES) {
-     return s_mp_exptmod(G, X, P, Y, 1);
-  }
-
-  /* is it a DR modulus? */
-  dr = mp_dr_is_modulus(P);
-
-  /* if not, is it a unrestricted DR modulus? */
-  if (dr == 0) {
-     dr = mp_reduce_is_2k(P) << 1;
-  }
-
-  /* if the modulus is odd or dr != 0 use the montgomery method */
-  if (mp_isodd (P) == 1 || dr !=  0) {
-    return mp_exptmod_fast (G, X, P, Y, dr);
-  } else {
-    /* otherwise use the generic Barrett reduction technique */
-    return s_mp_exptmod (G, X, P, Y, 0);
-  }
-}
-
-
-/* b = |a| 
- *
- * Simple function copies the input and fixes the sign to positive
- */
-int
-mp_abs (mp_int * a, mp_int * b)
-{
-  int     res;
-
-  /* copy a to b */
-  if (a != b) {
-     if ((res = mp_copy (a, b)) != MP_OKAY) {
-       return res;
-     }
-  }
-
-  /* force the sign of b to positive */
-  b->sign = MP_ZPOS;
-
-  return MP_OKAY;
-}
-
-
-/* hac 14.61, pp608 */
-int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
-{
-  /* b cannot be negative */
-  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
-    return MP_VAL;
-  }
-
-  /* if the modulus is odd we can use a faster routine instead */
-  if (mp_isodd (b) == 1) {
-    return fast_mp_invmod (a, b, c);
-  }
-
-  return mp_invmod_slow(a, b, c);
-}
-
-
-/* computes the modular inverse via binary extended euclidean algorithm, 
- * that is c = 1/a mod b 
- *
- * Based on slow invmod except this is optimized for the case where b is 
- * odd as per HAC Note 14.64 on pp. 610
- */
-int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
-{
-  mp_int  x, y, u, v, B, D;
-  int     res, neg;
-
-  /* 2. [modified] b must be odd   */
-  if (mp_iseven (b) == 1) {
-    return MP_VAL;
-  }
-
-  /* init all our temps */
-  if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D)) != MP_OKAY) {
-     return res;
-  }
-
-  /* x == modulus, y == value to invert */
-  if ((res = mp_copy (b, &x)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-
-  /* we need y = |a| */
-  if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-
-  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
-  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  mp_set (&D, 1);
-
-top:
-  /* 4.  while u is even do */
-  while (mp_iseven (&u) == 1) {
-    /* 4.1 u = u/2 */
-    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 4.2 if B is odd then */
-    if (mp_isodd (&B) == 1) {
-      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
-        goto LBL_ERR;
-      }
-    }
-    /* B = B/2 */
-    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 5.  while v is even do */
-  while (mp_iseven (&v) == 1) {
-    /* 5.1 v = v/2 */
-    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 5.2 if D is odd then */
-    if (mp_isodd (&D) == 1) {
-      /* D = (D-x)/2 */
-      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
-        goto LBL_ERR;
-      }
-    }
-    /* D = D/2 */
-    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 6.  if u >= v then */
-  if (mp_cmp (&u, &v) != MP_LT) {
-    /* u = u - v, B = B - D */
-    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  } else {
-    /* v - v - u, D = D - B */
-    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* if not zero goto step 4 */
-  if (mp_iszero (&u) == 0) {
-    goto top;
-  }
-
-  /* now a = C, b = D, gcd == g*v */
-
-  /* if v != 1 then there is no inverse */
-  if (mp_cmp_d (&v, 1) != MP_EQ) {
-    res = MP_VAL;
-    goto LBL_ERR;
-  }
-
-  /* b is now the inverse */
-  neg = a->sign;
-  while (D.sign == MP_NEG) {
-    if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-  mp_exch (&D, c);
-  c->sign = neg;
-  res = MP_OKAY;
-
-LBL_ERR:mp_clear(&x);
-        mp_clear(&y);
-        mp_clear(&u);
-        mp_clear(&v);
-        mp_clear(&B);
-        mp_clear(&D);
-  return res;
-}
-
-
-/* hac 14.61, pp608 */
-int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
-{
-  mp_int  x, y, u, v, A, B, C, D;
-  int     res;
-
-  /* b cannot be negative */
-  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
-    return MP_VAL;
-  }
-
-  /* init temps */
-  if ((res = mp_init_multi(&x, &y, &u, &v, 
-                           &A, &B)) != MP_OKAY) {
-     return res;
-  }
-
-  /* init rest of tmps temps */
-  if ((res = mp_init_multi(&C, &D, 0, 0, 0, 0)) != MP_OKAY) {
-     return res;
-  }
-
-  /* x = a, y = b */
-  if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
-      goto LBL_ERR;
-  }
-  if ((res = mp_copy (b, &y)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-
-  /* 2. [modified] if x,y are both even then return an error! */
-  if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
-    res = MP_VAL;
-    goto LBL_ERR;
-  }
-
-  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
-  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
-    goto LBL_ERR;
-  }
-  mp_set (&A, 1);
-  mp_set (&D, 1);
-
-top:
-  /* 4.  while u is even do */
-  while (mp_iseven (&u) == 1) {
-    /* 4.1 u = u/2 */
-    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 4.2 if A or B is odd then */
-    if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
-      /* A = (A+y)/2, B = (B-x)/2 */
-      if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-    }
-    /* A = A/2, B = B/2 */
-    if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 5.  while v is even do */
-  while (mp_iseven (&v) == 1) {
-    /* 5.1 v = v/2 */
-    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    /* 5.2 if C or D is odd then */
-    if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
-      /* C = (C+y)/2, D = (D-x)/2 */
-      if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-    }
-    /* C = C/2, D = D/2 */
-    if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* 6.  if u >= v then */
-  if (mp_cmp (&u, &v) != MP_LT) {
-    /* u = u - v, A = A - C, B = B - D */
-    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  } else {
-    /* v - v - u, C = C - A, D = D - B */
-    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-
-    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
-      goto LBL_ERR;
-    }
-  }
-
-  /* if not zero goto step 4 */
-  if (mp_iszero (&u) == 0)
-    goto top;
-
-  /* now a = C, b = D, gcd == g*v */
-
-  /* if v != 1 then there is no inverse */
-  if (mp_cmp_d (&v, 1) != MP_EQ) {
-    res = MP_VAL;
-    goto LBL_ERR;
-  }
-
-  /* if its too low */
-  while (mp_cmp_d(&C, 0) == MP_LT) {
-      if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-  }
-
-  /* too big */
-  while (mp_cmp_mag(&C, b) != MP_LT) {
-      if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
-         goto LBL_ERR;
-      }
-  }
-
-  /* C is now the inverse */
-  mp_exch (&C, c);
-  res = MP_OKAY;
-LBL_ERR:mp_clear(&x);
-        mp_clear(&y);
-        mp_clear(&u);
-        mp_clear(&v);
-        mp_clear(&A);
-        mp_clear(&B);
-        mp_clear(&C);
-        mp_clear(&D);
-  return res;
-}
-
-
-/* compare maginitude of two ints (unsigned) */
-int mp_cmp_mag (mp_int * a, mp_int * b)
-{
-  int     n;
-  mp_digit *tmpa, *tmpb;
-
-  /* compare based on # of non-zero digits */
-  if (a->used > b->used) {
-    return MP_GT;
-  }
-
-  if (a->used < b->used) {
-    return MP_LT;
-  }
-
-  /* alias for a */
-  tmpa = a->dp + (a->used - 1);
-
-  /* alias for b */
-  tmpb = b->dp + (a->used - 1);
-
-  /* compare based on digits  */
-  for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
-    if (*tmpa > *tmpb) {
-      return MP_GT;
-    }
-
-    if (*tmpa < *tmpb) {
-      return MP_LT;
-    }
-  }
-  return MP_EQ;
-}
-
-
-/* compare two ints (signed)*/
-int
-mp_cmp (mp_int * a, mp_int * b)
-{
-  /* compare based on sign */
-  if (a->sign != b->sign) {
-     if (a->sign == MP_NEG) {
-        return MP_LT;
-     } else {
-        return MP_GT;
-     }
-  }
-
-  /* compare digits */
-  if (a->sign == MP_NEG) {
-     /* if negative compare opposite direction */
-     return mp_cmp_mag(b, a);
-  } else {
-     return mp_cmp_mag(a, b);
-  }
-}
-
-
-/* compare a digit */
-int mp_cmp_d(mp_int * a, mp_digit b)
-{
-  /* compare based on sign */
-  if (a->sign == MP_NEG) {
-    return MP_LT;
-  }
-
-  /* compare based on magnitude */
-  if (a->used > 1) {
-    return MP_GT;
-  }
-
-  /* compare the only digit of a to b */
-  if (a->dp[0] > b) {
-    return MP_GT;
-  } else if (a->dp[0] < b) {
-    return MP_LT;
-  } else {
-    return MP_EQ;
-  }
-}
-
-
-/* set to a digit */
-void mp_set (mp_int * a, mp_digit b)
-{
-  mp_zero (a);
-  a->dp[0] = b & MP_MASK;
-  a->used  = (a->dp[0] != 0) ? 1 : 0;
-}
-
-
-/* c = a mod b, 0 <= c < b */
-int
-mp_mod (mp_int * a, mp_int * b, mp_int * c)
-{
-  mp_int  t;
-  int     res;
-
-  if ((res = mp_init (&t)) != MP_OKAY) {
-    return res;
-  }
-
-  if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
-    mp_clear (&t);
-    return res;
-  }
-
-  if (t.sign != b->sign) {
-    res = mp_add (b, &t, c);
-  } else {
-    res = MP_OKAY;
-    mp_exch (&t, c);
-  }
-
-  mp_clear (&t);
-  return res;
-}
-
-
-/* slower bit-bang division... also smaller */
-int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
-{
-   mp_int ta, tb, tq, q;
-   int    res, n, n2;
-
-  /* is divisor zero ? */
-  if (mp_iszero (b) == 1) {
-    return MP_VAL;
-  }
-
-  /* if a < b then q=0, r = a */
-  if (mp_cmp_mag (a, b) == MP_LT) {
-    if (d != NULL) {
-      res = mp_copy (a, d);
-    } else {
-      res = MP_OKAY;
-    }
-    if (c != NULL) {
-      mp_zero (c);
-    }
-    return res;
-  }
-	
-  /* init our temps */
-  if ((res = mp_init_multi(&ta, &tb, &tq, &q, 0, 0)) != MP_OKAY) {
-     return res;
-  }
-
-
-  mp_set(&tq, 1);
-  n = mp_count_bits(a) - mp_count_bits(b);
-  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
-      ((res = mp_abs(b, &tb)) != MP_OKAY) || 
-      ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
-      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
-      goto LBL_ERR;
-  }
-
-  while (n-- >= 0) {
-     if (mp_cmp(&tb, &ta) != MP_GT) {
-        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
-            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
-           goto LBL_ERR;
-        }
-     }
-     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
-         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
-           goto LBL_ERR;
-     }
-  }
-
-  /* now q == quotient and ta == remainder */
-  n  = a->sign;
-  n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
-  if (c != NULL) {
-     mp_exch(c, &q);
-     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
-  }
-  if (d != NULL) {
-     mp_exch(d, &ta);
-     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
-  }
-LBL_ERR:
-   mp_clear(&ta);
-   mp_clear(&tb);
-   mp_clear(&tq);
-   mp_clear(&q);
-   return res;
-}
-
-
-/* b = a/2 */
-int mp_div_2(mp_int * a, mp_int * b)
-{
-  int     x, res, oldused;
-
-  /* copy */
-  if (b->alloc < a->used) {
-    if ((res = mp_grow (b, a->used)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  oldused = b->used;
-  b->used = a->used;
-  {
-    register mp_digit r, rr, *tmpa, *tmpb;
-
-    /* source alias */
-    tmpa = a->dp + b->used - 1;
-
-    /* dest alias */
-    tmpb = b->dp + b->used - 1;
-
-    /* carry */
-    r = 0;
-    for (x = b->used - 1; x >= 0; x--) {
-      /* get the carry for the next iteration */
-      rr = *tmpa & 1;
-
-      /* shift the current digit, add in carry and store */
-      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
-
-      /* forward carry to next iteration */
-      r = rr;
-    }
-
-    /* zero excess digits */
-    tmpb = b->dp + b->used;
-    for (x = b->used; x < oldused; x++) {
-      *tmpb++ = 0;
-    }
-  }
-  b->sign = a->sign;
-  mp_clamp (b);
-  return MP_OKAY;
-}
-
-
-/* high level addition (handles signs) */
-int mp_add (mp_int * a, mp_int * b, mp_int * c)
-{
-  int     sa, sb, res;
-
-  /* get sign of both inputs */
-  sa = a->sign;
-  sb = b->sign;
-
-  /* handle two cases, not four */
-  if (sa == sb) {
-    /* both positive or both negative */
-    /* add their magnitudes, copy the sign */
-    c->sign = sa;
-    res = s_mp_add (a, b, c);
-  } else {
-    /* one positive, the other negative */
-    /* subtract the one with the greater magnitude from */
-    /* the one of the lesser magnitude.  The result gets */
-    /* the sign of the one with the greater magnitude. */
-    if (mp_cmp_mag (a, b) == MP_LT) {
-      c->sign = sb;
-      res = s_mp_sub (b, a, c);
-    } else {
-      c->sign = sa;
-      res = s_mp_sub (a, b, c);
-    }
-  }
-  return res;
-}
-
-
-/* low level addition, based on HAC pp.594, Algorithm 14.7 */
-int
-s_mp_add (mp_int * a, mp_int * b, mp_int * c)
-{
-  mp_int *x;
-  int     olduse, res, min, max;
-
-  /* find sizes, we let |a| <= |b| which means we have to sort
-   * them.  "x" will point to the input with the most digits
-   */
-  if (a->used > b->used) {
-    min = b->used;
-    max = a->used;
-    x = a;
-  } else {
-    min = a->used;
-    max = b->used;
-    x = b;
-  }
-
-  /* init result */
-  if (c->alloc < max + 1) {
-    if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* get old used digit count and set new one */
-  olduse = c->used;
-  c->used = max + 1;
-
-  {
-    register mp_digit u, *tmpa, *tmpb, *tmpc;
-    register int i;
-
-    /* alias for digit pointers */
-
-    /* first input */
-    tmpa = a->dp;
-
-    /* second input */
-    tmpb = b->dp;
-
-    /* destination */
-    tmpc = c->dp;
-
-    /* zero the carry */
-    u = 0;
-    for (i = 0; i < min; i++) {
-      /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
-      *tmpc = *tmpa++ + *tmpb++ + u;
-
-      /* U = carry bit of T[i] */
-      u = *tmpc >> ((mp_digit)DIGIT_BIT);
-
-      /* take away carry bit from T[i] */
-      *tmpc++ &= MP_MASK;
-    }
-
-    /* now copy higher words if any, that is in A+B 
-     * if A or B has more digits add those in 
-     */
-    if (min != max) {
-      for (; i < max; i++) {
-        /* T[i] = X[i] + U */
-        *tmpc = x->dp[i] + u;
-
-        /* U = carry bit of T[i] */
-        u = *tmpc >> ((mp_digit)DIGIT_BIT);
-
-        /* take away carry bit from T[i] */
-        *tmpc++ &= MP_MASK;
-      }
-    }
-
-    /* add carry */
-    *tmpc++ = u;
-
-    /* clear digits above oldused */
-    for (i = c->used; i < olduse; i++) {
-      *tmpc++ = 0;
-    }
-  }
-
-  mp_clamp (c);
-  return MP_OKAY;
-}
-
-
-/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
-int
-s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
-{
-  int     olduse, res, min, max;
-
-  /* find sizes */
-  min = b->used;
-  max = a->used;
-
-  /* init result */
-  if (c->alloc < max) {
-    if ((res = mp_grow (c, max)) != MP_OKAY) {
-      return res;
-    }
-  }
-  olduse = c->used;
-  c->used = max;
-
-  {
-    register mp_digit u, *tmpa, *tmpb, *tmpc;
-    register int i;
-
-    /* alias for digit pointers */
-    tmpa = a->dp;
-    tmpb = b->dp;
-    tmpc = c->dp;
-
-    /* set carry to zero */
-    u = 0;
-    for (i = 0; i < min; i++) {
-      /* T[i] = A[i] - B[i] - U */
-      *tmpc = *tmpa++ - *tmpb++ - u;
-
-      /* U = carry bit of T[i]
-       * Note this saves performing an AND operation since
-       * if a carry does occur it will propagate all the way to the
-       * MSB.  As a result a single shift is enough to get the carry
-       */
-      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
-
-      /* Clear carry from T[i] */
-      *tmpc++ &= MP_MASK;
-    }
-
-    /* now copy higher words if any, e.g. if A has more digits than B  */
-    for (; i < max; i++) {
-      /* T[i] = A[i] - U */
-      *tmpc = *tmpa++ - u;
-
-      /* U = carry bit of T[i] */
-      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
-
-      /* Clear carry from T[i] */
-      *tmpc++ &= MP_MASK;
-    }
-
-    /* clear digits above used (since we may not have grown result above) */
-    for (i = c->used; i < olduse; i++) {
-      *tmpc++ = 0;
-    }
-  }
-
-  mp_clamp (c);
-  return MP_OKAY;
-}
-
-
-/* high level subtraction (handles signs) */
-int
-mp_sub (mp_int * a, mp_int * b, mp_int * c)
-{
-  int     sa, sb, res;
-
-  sa = a->sign;
-  sb = b->sign;
-
-  if (sa != sb) {
-    /* subtract a negative from a positive, OR */
-    /* subtract a positive from a negative. */
-    /* In either case, ADD their magnitudes, */
-    /* and use the sign of the first number. */
-    c->sign = sa;
-    res = s_mp_add (a, b, c);
-  } else {
-    /* subtract a positive from a positive, OR */
-    /* subtract a negative from a negative. */
-    /* First, take the difference between their */
-    /* magnitudes, then... */
-    if (mp_cmp_mag (a, b) != MP_LT) {
-      /* Copy the sign from the first */
-      c->sign = sa;
-      /* The first has a larger or equal magnitude */
-      res = s_mp_sub (a, b, c);
-    } else {
-      /* The result has the *opposite* sign from */
-      /* the first number. */
-      c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
-      /* The second has a larger magnitude */
-      res = s_mp_sub (b, a, c);
-    }
-  }
-  return res;
-}
-
-
-/* determines if reduce_2k_l can be used */
-int mp_reduce_is_2k_l(mp_int *a)
-{
-   int ix, iy;
-
-   if (a->used == 0) {
-      return MP_NO;
-   } else if (a->used == 1) {
-      return MP_YES;
-   } else if (a->used > 1) {
-      /* if more than half of the digits are -1 we're sold */
-      for (iy = ix = 0; ix < a->used; ix++) {
-          if (a->dp[ix] == MP_MASK) {
-              ++iy;
-          }
-      }
-      return (iy >= (a->used/2)) ? MP_YES : MP_NO;
-   }
-   return MP_NO;
-}
-
-
-/* determines if mp_reduce_2k can be used */
-int mp_reduce_is_2k(mp_int *a)
-{
-   int ix, iy, iw;
-   mp_digit iz;
-
-   if (a->used == 0) {
-      return MP_NO;
-   } else if (a->used == 1) {
-      return MP_YES;
-   } else if (a->used > 1) {
-      iy = mp_count_bits(a);
-      iz = 1;
-      iw = 1;
-
-      /* Test every bit from the second digit up, must be 1 */
-      for (ix = DIGIT_BIT; ix < iy; ix++) {
-          if ((a->dp[iw] & iz) == 0) {
-             return MP_NO;
-          }
-          iz <<= 1;
-          if (iz > (mp_digit)MP_MASK) {
-             ++iw;
-             iz = 1;
-          }
-      }
-   }
-   return MP_YES;
-}
-
-
-/* determines if a number is a valid DR modulus */
-int mp_dr_is_modulus(mp_int *a)
-{
-   int ix;
-
-   /* must be at least two digits */
-   if (a->used < 2) {
-      return 0;
-   }
-
-   /* must be of the form b**k - a [a <= b] so all
-    * but the first digit must be equal to -1 (mod b).
-    */
-   for (ix = 1; ix < a->used; ix++) {
-       if (a->dp[ix] != MP_MASK) {
-          return 0;
-       }
-   }
-   return 1;
-}
-
-
-/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
- *
- * Uses a left-to-right k-ary sliding window to compute the modular
- * exponentiation.
- * The value of k changes based on the size of the exponent.
- *
- * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
- */
-
-#define TAB_SIZE 256
-
-int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y,
-                     int redmode)
-{
-  mp_int  M[TAB_SIZE], res;
-  mp_digit buf, mp;
-  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
-
-  /* use a pointer to the reduction algorithm.  This allows us to use
-   * one of many reduction algorithms without modding the guts of
-   * the code with if statements everywhere.
-   */
-  int     (*redux)(mp_int*,mp_int*,mp_digit);
-
-  /* find window size */
-  x = mp_count_bits (X);
-  if (x <= 7) {
-    winsize = 2;
-  } else if (x <= 36) {
-    winsize = 3;
-  } else if (x <= 140) {
-    winsize = 4;
-  } else if (x <= 450) {
-    winsize = 5;
-  } else if (x <= 1303) {
-    winsize = 6;
-  } else if (x <= 3529) {
-    winsize = 7;
-  } else {
-    winsize = 8;
-  }
-
-  /* init M array */
-  /* init first cell */
-  if ((err = mp_init(&M[1])) != MP_OKAY) {
-     return err;
-  }
-
-  /* now init the second half of the array */
-  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
-    if ((err = mp_init(&M[x])) != MP_OKAY) {
-      for (y = 1<<(winsize-1); y < x; y++) {
-        mp_clear (&M[y]);
-      }
-      mp_clear(&M[1]);
-      return err;
-    }
-  }
-
-  /* determine and setup reduction code */
-  if (redmode == 0) {
-     /* now setup montgomery  */
-     if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
-        goto LBL_M;
-     }
-
-     /* automatically pick the comba one if available (saves quite a few
-        calls/ifs) */
-     if (((P->used * 2 + 1) < MP_WARRAY) &&
-          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
-        redux = fast_mp_montgomery_reduce;
-     } else {
-        /* use slower baseline Montgomery method */
-        redux = mp_montgomery_reduce;
-     }
-  } else if (redmode == 1) {
-#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
-     /* setup DR reduction for moduli of the form B**k - b */
-     mp_dr_setup(P, &mp);
-     redux = mp_dr_reduce;
-#else
-     err = MP_VAL;
-     goto LBL_M;
-#endif
-  } else {
-#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
-     /* setup DR reduction for moduli of the form 2**k - b */
-     if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
-        goto LBL_M;
-     }
-     redux = mp_reduce_2k;
-#else
-     err = MP_VAL;
-     goto LBL_M;
-#endif
-  }
-
-  /* setup result */
-  if ((err = mp_init (&res)) != MP_OKAY) {
-    goto LBL_M;
-  }
-
-  /* create M table
-   *
-
-   *
-   * The first half of the table is not computed though accept for M[0] and M[1]
-   */
-
-  if (redmode == 0) {
-     /* now we need R mod m */
-     if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
-       goto LBL_RES;
-     }
-
-     /* now set M[1] to G * R mod m */
-     if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
-       goto LBL_RES;
-     }
-  } else {
-     mp_set(&res, 1);
-     if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
-        goto LBL_RES;
-     }
-  }
-
-  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times*/
-  if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
-    goto LBL_RES;
-  }
-
-  for (x = 0; x < (winsize - 1); x++) {
-    if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
-      goto LBL_RES;
-    }
-    if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, mp)) != MP_OKAY) {
-      goto LBL_RES;
-    }
-  }
-
-  /* create upper table */
-  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
-    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
-      goto LBL_RES;
-    }
-    if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
-      goto LBL_RES;
-    }
-  }
-
-  /* set initial mode and bit cnt */
-  mode   = 0;
-  bitcnt = 1;
-  buf    = 0;
-  digidx = X->used - 1;
-  bitcpy = 0;
-  bitbuf = 0;
-
-  for (;;) {
-    /* grab next digit as required */
-    if (--bitcnt == 0) {
-      /* if digidx == -1 we are out of digits so break */
-      if (digidx == -1) {
-        break;
-      }
-      /* read next digit and reset bitcnt */
-      buf    = X->dp[digidx--];
-      bitcnt = (int)DIGIT_BIT;
-    }
-
-    /* grab the next msb from the exponent */
-    y     = (int)(buf >> (DIGIT_BIT - 1)) & 1;
-    buf <<= (mp_digit)1;
-
-    /* if the bit is zero and mode == 0 then we ignore it
-     * These represent the leading zero bits before the first 1 bit
-     * in the exponent.  Technically this opt is not required but it
-     * does lower the # of trivial squaring/reductions used
-     */
-    if (mode == 0 && y == 0) {
-      continue;
-    }
-
-    /* if the bit is zero and mode == 1 then we square */
-    if (mode == 1 && y == 0) {
-      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, mp)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      continue;
-    }
-
-    /* else we add it to the window */
-    bitbuf |= (y << (winsize - ++bitcpy));
-    mode    = 2;
-
-    if (bitcpy == winsize) {
-      /* ok window is filled so square as required and multiply  */
-      /* square first */
-      for (x = 0; x < winsize; x++) {
-        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-        if ((err = redux (&res, P, mp)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-      }
-
-      /* then multiply */
-      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, mp)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-
-      /* empty window and reset */
-      bitcpy = 0;
-      bitbuf = 0;
-      mode   = 1;
-    }
-  }
-
-  /* if bits remain then square/multiply */
-  if (mode == 2 && bitcpy > 0) {
-    /* square then multiply if the bit is set */
-    for (x = 0; x < bitcpy; x++) {
-      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, mp)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-
-      /* get next bit of the window */
-      bitbuf <<= 1;
-      if ((bitbuf & (1 << winsize)) != 0) {
-        /* then multiply */
-        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-        if ((err = redux (&res, P, mp)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-      }
-    }
-  }
-
-  if (redmode == 0) {
-     /* fixup result if Montgomery reduction is used
-      * recall that any value in a Montgomery system is
-      * actually multiplied by R mod n.  So we have
-      * to reduce one more time to cancel out the factor
-      * of R.
-      */
-     if ((err = redux(&res, P, mp)) != MP_OKAY) {
-       goto LBL_RES;
-     }
-  }
-
-  /* swap res with Y */
-  mp_exch (&res, Y);
-  err = MP_OKAY;
-LBL_RES:mp_clear (&res);
-LBL_M:
-  mp_clear(&M[1]);
-  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
-    mp_clear (&M[x]);
-  }
-  return err;
-}
-
-
-/* setups the montgomery reduction stuff */
-int
-mp_montgomery_setup (mp_int * n, mp_digit * rho)
-{
-  mp_digit x, b;
-
-/* fast inversion mod 2**k
- *
- * Based on the fact that
- *
- * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
- *                    =>  2*X*A - X*X*A*A = 1
- *                    =>  2*(1) - (1)     = 1
- */
-  b = n->dp[0];
-
-  if ((b & 1) == 0) {
-    return MP_VAL;
-  }
-
-  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
-  x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
-#if !defined(MP_8BIT)
-  x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
-#endif
-#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
-  x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
-#endif
-#ifdef MP_64BIT
-  x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
-#endif
-
-  /* rho = -1/m mod b */
-  /* TAO, switched mp_word casts to mp_digit to shut up compiler */
-  *rho = (((mp_digit)1 << ((mp_digit) DIGIT_BIT)) - x) & MP_MASK;
-
-  return MP_OKAY;
-}
-
-
-/* computes xR**-1 == x (mod N) via Montgomery Reduction
- *
- * This is an optimized implementation of montgomery_reduce
- * which uses the comba method to quickly calculate the columns of the
- * reduction.
- *
- * Based on Algorithm 14.32 on pp.601 of HAC.
-*/
-int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
-{
-  int     ix, res, olduse;
-  mp_word W[MP_WARRAY];
-
-  /* get old used count */
-  olduse = x->used;
-
-  /* grow a as required */
-  if (x->alloc < n->used + 1) {
-    if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* first we have to get the digits of the input into
-   * an array of double precision words W[...]
-   */
-  {
-    register mp_word *_W;
-    register mp_digit *tmpx;
-
-    /* alias for the W[] array */
-    _W   = W;
-
-    /* alias for the digits of  x*/
-    tmpx = x->dp;
-
-    /* copy the digits of a into W[0..a->used-1] */
-    for (ix = 0; ix < x->used; ix++) {
-      *_W++ = *tmpx++;
-    }
-
-    /* zero the high words of W[a->used..m->used*2] */
-    for (; ix < n->used * 2 + 1; ix++) {
-      *_W++ = 0;
-    }
-  }
-
-  /* now we proceed to zero successive digits
-   * from the least significant upwards
-   */
-  for (ix = 0; ix < n->used; ix++) {
-    /* mu = ai * m' mod b
-     *
-     * We avoid a double precision multiplication (which isn't required)
-     * by casting the value down to a mp_digit.  Note this requires
-     * that W[ix-1] have  the carry cleared (see after the inner loop)
-     */
-    register mp_digit mu;
-    mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
-
-    /* a = a + mu * m * b**i
-     *
-     * This is computed in place and on the fly.  The multiplication
-     * by b**i is handled by offseting which columns the results
-     * are added to.
-     *
-     * Note the comba method normally doesn't handle carries in the
-     * inner loop In this case we fix the carry from the previous
-     * column since the Montgomery reduction requires digits of the
-     * result (so far) [see above] to work.  This is
-     * handled by fixing up one carry after the inner loop.  The
-     * carry fixups are done in order so after these loops the
-     * first m->used words of W[] have the carries fixed
-     */
-    {
-      register int iy;
-      register mp_digit *tmpn;
-      register mp_word *_W;
-
-      /* alias for the digits of the modulus */
-      tmpn = n->dp;
-
-      /* Alias for the columns set by an offset of ix */
-      _W = W + ix;
-
-      /* inner loop */
-      for (iy = 0; iy < n->used; iy++) {
-          *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
-      }
-    }
-
-    /* now fix carry for next digit, W[ix+1] */
-    W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
-  }
-
-  /* now we have to propagate the carries and
-   * shift the words downward [all those least
-   * significant digits we zeroed].
-   */
-  {
-    register mp_digit *tmpx;
-    register mp_word *_W, *_W1;
-
-    /* nox fix rest of carries */
-
-    /* alias for current word */
-    _W1 = W + ix;
-
-    /* alias for next word, where the carry goes */
-    _W = W + ++ix;
-
-    for (; ix <= n->used * 2 + 1; ix++) {
-      *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
-    }
-
-    /* copy out, A = A/b**n
-     *
-     * The result is A/b**n but instead of converting from an
-     * array of mp_word to mp_digit than calling mp_rshd
-     * we just copy them in the right order
-     */
-
-    /* alias for destination word */
-    tmpx = x->dp;
-
-    /* alias for shifted double precision result */
-    _W = W + n->used;
-
-    for (ix = 0; ix < n->used + 1; ix++) {
-      *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
-    }
-
-    /* zero oldused digits, if the input a was larger than
-     * m->used+1 we'll have to clear the digits
-     */
-    for (; ix < olduse; ix++) {
-      *tmpx++ = 0;
-    }
-  }
-
-  /* set the max used and clamp */
-  x->used = n->used + 1;
-  mp_clamp (x);
-
-  /* if A >= m then A = A - m */
-  if (mp_cmp_mag (x, n) != MP_LT) {
-    return s_mp_sub (x, n, x);
-  }
-  return MP_OKAY;
-}
-
-
-/* computes xR**-1 == x (mod N) via Montgomery Reduction */
-int
-mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
-{
-  int     ix, res, digs;
-  mp_digit mu;
-
-  /* can the fast reduction [comba] method be used?
-   *
-   * Note that unlike in mul you're safely allowed *less*
-   * than the available columns [255 per default] since carries
-   * are fixed up in the inner loop.
-   */
-  digs = n->used * 2 + 1;
-  if ((digs < MP_WARRAY) &&
-      n->used <
-      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
-    return fast_mp_montgomery_reduce (x, n, rho);
-  }
-
-  /* grow the input as required */
-  if (x->alloc < digs) {
-    if ((res = mp_grow (x, digs)) != MP_OKAY) {
-      return res;
-    }
-  }
-  x->used = digs;
-
-  for (ix = 0; ix < n->used; ix++) {
-    /* mu = ai * rho mod b
-     *
-     * The value of rho must be precalculated via
-     * montgomery_setup() such that
-     * it equals -1/n0 mod b this allows the
-     * following inner loop to reduce the
-     * input one digit at a time
-     */
-    mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
-
-    /* a = a + mu * m * b**i */
-    {
-      register int iy;
-      register mp_digit *tmpn, *tmpx, u;
-      register mp_word r;
-
-      /* alias for digits of the modulus */
-      tmpn = n->dp;
-
-      /* alias for the digits of x [the input] */
-      tmpx = x->dp + ix;
-
-      /* set the carry to zero */
-      u = 0;
-
-      /* Multiply and add in place */
-      for (iy = 0; iy < n->used; iy++) {
-        /* compute product and sum */
-        r       = ((mp_word)mu) * ((mp_word)*tmpn++) +
-                  ((mp_word) u) + ((mp_word) * tmpx);
-
-        /* get carry */
-        u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
-
-        /* fix digit */
-        *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
-      }
-      /* At this point the ix'th digit of x should be zero */
-
-
-      /* propagate carries upwards as required*/
-      while (u) {
-        *tmpx   += u;
-        u        = *tmpx >> DIGIT_BIT;
-        *tmpx++ &= MP_MASK;
-      }
-    }
-  }
-
-  /* at this point the n.used'th least
-   * significant digits of x are all zero
-   * which means we can shift x to the
-   * right by n.used digits and the
-   * residue is unchanged.
-   */
-
-  /* x = x/b**n.used */
-  mp_clamp(x);
-  mp_rshd (x, n->used);
-
-  /* if x >= n then x = x - n */
-  if (mp_cmp_mag (x, n) != MP_LT) {
-    return s_mp_sub (x, n, x);
-  }
-
-  return MP_OKAY;
-}
-
-
-/* determines the setup value */
-void mp_dr_setup(mp_int *a, mp_digit *d)
-{
-   /* the casts are required if DIGIT_BIT is one less than
-    * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
-    */
-   *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - 
-        ((mp_word)a->dp[0]));
-}
-
-
-/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
- *
- * Based on algorithm from the paper
- *
- * "Generating Efficient Primes for Discrete Log Cryptosystems"
- *                 Chae Hoon Lim, Pil Joong Lee,
- *          POSTECH Information Research Laboratories
- *
- * The modulus must be of a special format [see manual]
- *
- * Has been modified to use algorithm 7.10 from the LTM book instead
- *
- * Input x must be in the range 0 <= x <= (n-1)**2
- */
-int
-mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
-{
-  int      err, i, m;
-  mp_word  r;
-  mp_digit mu, *tmpx1, *tmpx2;
-
-  /* m = digits in modulus */
-  m = n->used;
-
-  /* ensure that "x" has at least 2m digits */
-  if (x->alloc < m + m) {
-    if ((err = mp_grow (x, m + m)) != MP_OKAY) {
-      return err;
-    }
-  }
-
-/* top of loop, this is where the code resumes if
- * another reduction pass is required.
- */
-top:
-  /* aliases for digits */
-  /* alias for lower half of x */
-  tmpx1 = x->dp;
-
-  /* alias for upper half of x, or x/B**m */
-  tmpx2 = x->dp + m;
-
-  /* set carry to zero */
-  mu = 0;
-
-  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
-  for (i = 0; i < m; i++) {
-      r         = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
-      *tmpx1++  = (mp_digit)(r & MP_MASK);
-      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
-  }
-
-  /* set final carry */
-  *tmpx1++ = mu;
-
-  /* zero words above m */
-  for (i = m + 1; i < x->used; i++) {
-      *tmpx1++ = 0;
-  }
-
-  /* clamp, sub and return */
-  mp_clamp (x);
-
-  /* if x >= n then subtract and reduce again
-   * Each successive "recursion" makes the input smaller and smaller.
-   */
-  if (mp_cmp_mag (x, n) != MP_LT) {
-    s_mp_sub(x, n, x);
-    goto top;
-  }
-  return MP_OKAY;
-}
-
-
-/* reduces a modulo n where n is of the form 2**p - d */
-int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
-{
-   mp_int q;
-   int    p, res;
-
-   if ((res = mp_init(&q)) != MP_OKAY) {
-      return res;
-   }
-
-   p = mp_count_bits(n);
-top:
-   /* q = a/2**p, a = a mod 2**p */
-   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
-      goto ERR;
-   }
-
-   if (d != 1) {
-      /* q = q * d */
-      if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) {
-         goto ERR;
-      }
-   }
-
-   /* a = a + q */
-   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
-      goto ERR;
-   }
-
-   if (mp_cmp_mag(a, n) != MP_LT) {
-      s_mp_sub(a, n, a);
-      goto top;
-   }
-
-ERR:
-   mp_clear(&q);
-   return res;
-}
-
-
-/* determines the setup value */
-int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
-{
-   int res, p;
-   mp_int tmp;
-
-   if ((res = mp_init(&tmp)) != MP_OKAY) {
-      return res;
-   }
-
-   p = mp_count_bits(a);
-   if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
-      mp_clear(&tmp);
-      return res;
-   }
-
-   if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
-      mp_clear(&tmp);
-      return res;
-   }
-
-   *d = tmp.dp[0];
-   mp_clear(&tmp);
-   return MP_OKAY;
-}
-
-
-/* computes a = 2**b
- *
- * Simple algorithm which zeroes the int, grows it then just sets one bit
- * as required.
- */
-int
-mp_2expt (mp_int * a, int b)
-{
-  int     res;
-
-  /* zero a as per default */
-  mp_zero (a);
-
-  /* grow a to accomodate the single bit */
-  if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
-    return res;
-  }
-
-  /* set the used count of where the bit will go */
-  a->used = b / DIGIT_BIT + 1;
-
-  /* put the single bit in its place */
-  a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
-
-  return MP_OKAY;
-}
-
-
-/* multiply by a digit */
-int
-mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
-{
-  mp_digit u, *tmpa, *tmpc;
-  mp_word  r;
-  int      ix, res, olduse;
-
-  /* make sure c is big enough to hold a*b */
-  if (c->alloc < a->used + 1) {
-    if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* get the original destinations used count */
-  olduse = c->used;
-
-  /* set the sign */
-  c->sign = a->sign;
-
-  /* alias for a->dp [source] */
-  tmpa = a->dp;
-
-  /* alias for c->dp [dest] */
-  tmpc = c->dp;
-
-  /* zero carry */
-  u = 0;
-
-  /* compute columns */
-  for (ix = 0; ix < a->used; ix++) {
-    /* compute product and carry sum for this term */
-    r       = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
-
-    /* mask off higher bits to get a single digit */
-    *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
-    /* send carry into next iteration */
-    u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
-  }
-
-  /* store final carry [if any] and increment ix offset  */
-  *tmpc++ = u;
-  ++ix;
-
-  /* now zero digits above the top */
-  while (ix++ < olduse) {
-     *tmpc++ = 0;
-  }
-
-  /* set used count */
-  c->used = a->used + 1;
-  mp_clamp(c);
-
-  return MP_OKAY;
-}
-
-
-/* d = a * b (mod c) */
-int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
-{
-  int     res;
-  mp_int  t;
-
-  if ((res = mp_init (&t)) != MP_OKAY) {
-    return res;
-  }
-
-  if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
-    mp_clear (&t);
-    return res;
-  }
-  res = mp_mod (&t, c, d);
-  mp_clear (&t);
-  return res;
-}
-
-
-/* computes b = a*a */
-int
-mp_sqr (mp_int * a, mp_int * b)
-{
-  int     res;
-
-  {
-    /* can we use the fast comba multiplier? */
-    if ((a->used * 2 + 1) < MP_WARRAY && 
-         a->used < 
-         (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
-      res = fast_s_mp_sqr (a, b);
-    } else
-      res = s_mp_sqr (a, b);
-  }
-  b->sign = MP_ZPOS;
-  return res;
-}
-
-
-/* high level multiplication (handles sign) */
-int mp_mul (mp_int * a, mp_int * b, mp_int * c)
-{
-  int     res, neg;
-  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
-
-  {
-    /* can we use the fast multiplier?
-     *
-     * The fast multiplier can be used if the output will 
-     * have less than MP_WARRAY digits and the number of 
-     * digits won't affect carry propagation
-     */
-    int     digs = a->used + b->used + 1;
-
-    if ((digs < MP_WARRAY) &&
-        MIN(a->used, b->used) <= 
-        (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
-      res = fast_s_mp_mul_digs (a, b, c, digs);
-    } else
-      res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
-
-  }
-  c->sign = (c->used > 0) ? neg : MP_ZPOS;
-  return res;
-}
-
-
-/* b = a*2 */
-int mp_mul_2(mp_int * a, mp_int * b)
-{
-  int     x, res, oldused;
-
-  /* grow to accomodate result */
-  if (b->alloc < a->used + 1) {
-    if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  oldused = b->used;
-  b->used = a->used;
-
-  {
-    register mp_digit r, rr, *tmpa, *tmpb;
-
-    /* alias for source */
-    tmpa = a->dp;
-
-    /* alias for dest */
-    tmpb = b->dp;
-
-    /* carry */
-    r = 0;
-    for (x = 0; x < a->used; x++) {
-      /* get what will be the *next* carry bit from the 
-       * MSB of the current digit 
-       */
-      rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
-
-      /* now shift up this digit, add in the carry [from the previous] */
-      *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
-
-      /* copy the carry that would be from the source 
-       * digit into the next iteration 
-       */
-      r = rr;
-    }
-
-    /* new leading digit? */
-    if (r != 0) {
-      /* add a MSB which is always 1 at this point */
-      *tmpb = 1;
-      ++(b->used);
-    }
-
-    /* now zero any excess digits on the destination 
-     * that we didn't write to 
-     */
-    tmpb = b->dp + b->used;
-    for (x = b->used; x < oldused; x++) {
-      *tmpb++ = 0;
-    }
-  }
-  b->sign = a->sign;
-  return MP_OKAY;
-}
-
-
-/* divide by three (based on routine from MPI and the GMP manual) */
-int
-mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
-{
-  mp_int   q;
-  mp_word  w, t;
-  mp_digit b;
-  int      res, ix;
-
-  /* b = 2**DIGIT_BIT / 3 */
-  b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
-
-  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
-     return res;
-  }
-
-  q.used = a->used;
-  q.sign = a->sign;
-  w = 0;
-  for (ix = a->used - 1; ix >= 0; ix--) {
-     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
-
-     if (w >= 3) {
-        /* multiply w by [1/3] */
-        t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
-
-        /* now subtract 3 * [w/3] from w, to get the remainder */
-        w -= t+t+t;
-
-        /* fixup the remainder as required since
-         * the optimization is not exact.
-         */
-        while (w >= 3) {
-           t += 1;
-           w -= 3;
-        }
-      } else {
-        t = 0;
-      }
-      q.dp[ix] = (mp_digit)t;
-  }
-
-  /* [optional] store the remainder */
-  if (d != NULL) {
-     *d = (mp_digit)w;
-  }
-
-  /* [optional] store the quotient */
-  if (c != NULL) {
-     mp_clamp(&q);
-     mp_exch(&q, c);
-  }
-  mp_clear(&q);
-
-  return res;
-}
-
-
-/* init an mp_init for a given size */
-int mp_init_size (mp_int * a, int size)
-{
-  int x;
-
-  /* pad size so there are always extra digits */
-  size += (MP_PREC * 2) - (size % MP_PREC);	
-
-  /* alloc mem */
-  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
-  if (a->dp == NULL) {
-    return MP_MEM;
-  }
-
-  /* set the members */
-  a->used  = 0;
-  a->alloc = size;
-  a->sign  = MP_ZPOS;
-
-  /* zero the digits */
-  for (x = 0; x < size; x++) {
-      a->dp[x] = 0;
-  }
-
-  return MP_OKAY;
-}
-
-
-/* the jist of squaring...
- * you do like mult except the offset of the tmpx [one that 
- * starts closer to zero] can't equal the offset of tmpy.  
- * So basically you set up iy like before then you min it with
- * (ty-tx) so that it never happens.  You double all those 
- * you add in the inner loop
-
-After that loop you do the squares and add them in.
-*/
-
-int fast_s_mp_sqr (mp_int * a, mp_int * b)
-{
-  int       olduse, res, pa, ix, iz;
-  mp_digit W[MP_WARRAY];
-  mp_digit  *tmpx;
-  mp_word   W1;
-
-  /* grow the destination as required */
-  pa = a->used + a->used;
-  if (b->alloc < pa) {
-    if ((res = mp_grow (b, pa)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  if (pa > MP_WARRAY)
-    return MP_RANGE;  /* TAO range check */
-
-  /* number of output digits to produce */
-  W1 = 0;
-  for (ix = 0; ix < pa; ix++) { 
-      int      tx, ty, iy;
-      mp_word  _W;
-      mp_digit *tmpy;
-
-      /* clear counter */
-      _W = 0;
-
-      /* get offsets into the two bignums */
-      ty = MIN(a->used-1, ix);
-      tx = ix - ty;
-
-      /* setup temp aliases */
-      tmpx = a->dp + tx;
-      tmpy = a->dp + ty;
-
-      /* this is the number of times the loop will iterrate, essentially
-         while (tx++ < a->used && ty-- >= 0) { ... }
-       */
-      iy = MIN(a->used-tx, ty+1);
-
-      /* now for squaring tx can never equal ty 
-       * we halve the distance since they approach at a rate of 2x
-       * and we have to round because odd cases need to be executed
-       */
-      iy = MIN(iy, (ty-tx+1)>>1);
-
-      /* execute loop */
-      for (iz = 0; iz < iy; iz++) {
-         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
-      }
-
-      /* double the inner product and add carry */
-      _W = _W + _W + W1;
-
-      /* even columns have the square term in them */
-      if ((ix&1) == 0) {
-         _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
-      }
-
-      /* store it */
-      W[ix] = (mp_digit)(_W & MP_MASK);
-
-      /* make next carry */
-      W1 = _W >> ((mp_word)DIGIT_BIT);
-  }
-
-  /* setup dest */
-  olduse  = b->used;
-  b->used = a->used+a->used;
-
-  {
-    mp_digit *tmpb;
-    tmpb = b->dp;
-    for (ix = 0; ix < pa; ix++) {
-      *tmpb++ = W[ix] & MP_MASK;
-    }
-
-    /* clear unused digits [that existed in the old copy of c] */
-    for (; ix < olduse; ix++) {
-      *tmpb++ = 0;
-    }
-  }
-  mp_clamp (b);
-
-  return MP_OKAY;
-}
-
-
-/* Fast (comba) multiplier
- *
- * This is the fast column-array [comba] multiplier.  It is 
- * designed to compute the columns of the product first 
- * then handle the carries afterwards.  This has the effect 
- * of making the nested loops that compute the columns very
- * simple and schedulable on super-scalar processors.
- *
- * This has been modified to produce a variable number of 
- * digits of output so if say only a half-product is required 
- * you don't have to compute the upper half (a feature 
- * required for fast Barrett reduction).
- *
- * Based on Algorithm 14.12 on pp.595 of HAC.
- *
- */
-int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
-  int     olduse, res, pa, ix, iz;
-  mp_digit W[MP_WARRAY];
-  register mp_word  _W;
-
-  /* grow the destination as required */
-  if (c->alloc < digs) {
-    if ((res = mp_grow (c, digs)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  /* number of output digits to produce */
-  pa = MIN(digs, a->used + b->used);
-  if (pa > MP_WARRAY)
-    return MP_RANGE;  /* TAO range check */
-
-  /* clear the carry */
-  _W = 0;
-  for (ix = 0; ix < pa; ix++) { 
-      int      tx, ty;
-      int      iy;
-      mp_digit *tmpx, *tmpy;
-
-      /* get offsets into the two bignums */
-      ty = MIN(b->used-1, ix);
-      tx = ix - ty;
-
-      /* setup temp aliases */
-      tmpx = a->dp + tx;
-      tmpy = b->dp + ty;
-
-      /* this is the number of times the loop will iterrate, essentially 
-         while (tx++ < a->used && ty-- >= 0) { ... }
-       */
-      iy = MIN(a->used-tx, ty+1);
-
-      /* execute loop */
-      for (iz = 0; iz < iy; ++iz) {
-         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
-
-      }
-
-      /* store term */
-      W[ix] = ((mp_digit)_W) & MP_MASK;
-
-      /* make next carry */
-      _W = _W >> ((mp_word)DIGIT_BIT);
- }
-
-  /* setup dest */
-  olduse  = c->used;
-  c->used = pa;
-
-  {
-    register mp_digit *tmpc;
-    tmpc = c->dp;
-    for (ix = 0; ix < pa+1; ix++) {
-      /* now extract the previous digit [below the carry] */
-      *tmpc++ = W[ix];
-    }
-
-    /* clear unused digits [that existed in the old copy of c] */
-    for (; ix < olduse; ix++) {
-      *tmpc++ = 0;
-    }
-  }
-  mp_clamp (c);
-
-  return MP_OKAY;
-}
-
-
-/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
-int s_mp_sqr (mp_int * a, mp_int * b)
-{
-  mp_int  t;
-  int     res, ix, iy, pa;
-  mp_word r;
-  mp_digit u, tmpx, *tmpt;
-
-  pa = a->used;
-  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
-    return res;
-  }
-
-  /* default used is maximum possible size */
-  t.used = 2*pa + 1;
-
-  for (ix = 0; ix < pa; ix++) {
-    /* first calculate the digit at 2*ix */
-    /* calculate double precision result */
-    r = ((mp_word) t.dp[2*ix]) +
-        ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
-
-    /* store lower part in result */
-    t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
-
-    /* get the carry */
-    u           = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
-
-    /* left hand side of A[ix] * A[iy] */
-    tmpx        = a->dp[ix];
-
-    /* alias for where to store the results */
-    tmpt        = t.dp + (2*ix + 1);
-
-    for (iy = ix + 1; iy < pa; iy++) {
-      /* first calculate the product */
-      r       = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
-
-      /* now calculate the double precision result, note we use
-       * addition instead of *2 since it's easier to optimize
-       */
-      r       = ((mp_word) *tmpt) + r + r + ((mp_word) u);
-
-      /* store lower part */
-      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
-      /* get carry */
-      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
-    }
-    /* propagate upwards */
-    while (u != ((mp_digit) 0)) {
-      r       = ((mp_word) *tmpt) + ((mp_word) u);
-      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
-      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
-    }
-  }
-
-  mp_clamp (&t);
-  mp_exch (&t, b);
-  mp_clear (&t);
-  return MP_OKAY;
-}
-
-
-/* multiplies |a| * |b| and only computes upto digs digits of result
- * HAC pp. 595, Algorithm 14.12  Modified so you can control how 
- * many digits of output are created.
- */
-int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
-  mp_int  t;
-  int     res, pa, pb, ix, iy;
-  mp_digit u;
-  mp_word r;
-  mp_digit tmpx, *tmpt, *tmpy;
-
-  /* can we use the fast multiplier? */
-  if (((digs) < MP_WARRAY) &&
-      MIN (a->used, b->used) < 
-          (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
-    return fast_s_mp_mul_digs (a, b, c, digs);
-  }
-
-  if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
-    return res;
-  }
-  t.used = digs;
-
-  /* compute the digits of the product directly */
-  pa = a->used;
-  for (ix = 0; ix < pa; ix++) {
-    /* set the carry to zero */
-    u = 0;
-
-    /* limit ourselves to making digs digits of output */
-    pb = MIN (b->used, digs - ix);
-
-    /* setup some aliases */
-    /* copy of the digit from a used within the nested loop */
-    tmpx = a->dp[ix];
-
-    /* an alias for the destination shifted ix places */
-    tmpt = t.dp + ix;
-
-    /* an alias for the digits of b */
-    tmpy = b->dp;
-
-    /* compute the columns of the output and propagate the carry */
-    for (iy = 0; iy < pb; iy++) {
-      /* compute the column as a mp_word */
-      r       = ((mp_word)*tmpt) +
-                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
-                ((mp_word) u);
-
-      /* the new column is the lower part of the result */
-      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
-      /* get the carry word from the result */
-      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
-    }
-    /* set carry if it is placed below digs */
-    if (ix + iy < digs) {
-      *tmpt = u;
-    }
-  }
-
-  mp_clamp (&t);
-  mp_exch (&t, c);
-
-  mp_clear (&t);
-  return MP_OKAY;
-}
-
-
-/*
- * shifts with subtractions when the result is greater than b.
- *
- * The method is slightly modified to shift B unconditionally upto just under
- * the leading bit of b.  This saves alot of multiple precision shifting.
- */
-int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
-{
-  int     x, bits, res;
-
-  /* how many bits of last digit does b use */
-  bits = mp_count_bits (b) % DIGIT_BIT;
-
-  if (b->used > 1) {
-     if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
-        return res;
-     }
-  } else {
-     mp_set(a, 1);
-     bits = 1;
-  }
-
-
-  /* now compute C = A * B mod b */
-  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
-    if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
-      return res;
-    }
-    if (mp_cmp_mag (a, b) != MP_LT) {
-      if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
-        return res;
-      }
-    }
-  }
-
-  return MP_OKAY;
-}
-
-
-#define TAB_SIZE 256
-
-int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
-{
-  mp_int  M[TAB_SIZE], res, mu;
-  mp_digit buf;
-  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
-  int (*redux)(mp_int*,mp_int*,mp_int*);
-
-  /* find window size */
-  x = mp_count_bits (X);
-  if (x <= 7) {
-    winsize = 2;
-  } else if (x <= 36) {
-    winsize = 3;
-  } else if (x <= 140) {
-    winsize = 4;
-  } else if (x <= 450) {
-    winsize = 5;
-  } else if (x <= 1303) {
-    winsize = 6;
-  } else if (x <= 3529) {
-    winsize = 7;
-  } else {
-    winsize = 8;
-  }
-
-  /* init M array */
-  /* init first cell */
-  if ((err = mp_init(&M[1])) != MP_OKAY) {
-     return err; 
-  }
-
-  /* now init the second half of the array */
-  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
-    if ((err = mp_init(&M[x])) != MP_OKAY) {
-      for (y = 1<<(winsize-1); y < x; y++) {
-        mp_clear (&M[y]);
-      }
-      mp_clear(&M[1]);
-      return err;
-    }
-  }
-
-  /* create mu, used for Barrett reduction */
-  if ((err = mp_init (&mu)) != MP_OKAY) {
-    goto LBL_M;
-  }
-
-  if (redmode == 0) {
-     if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
-        goto LBL_MU;
-     }
-     redux = mp_reduce;
-  } else {
-     if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
-        goto LBL_MU;
-     }
-     redux = mp_reduce_2k_l;
-  }
-
-  /* create M table
-   *
-   * The M table contains powers of the base, 
-   * e.g. M[x] = G**x mod P
-   *
-   * The first half of the table is not 
-   * computed though accept for M[0] and M[1]
-   */
-  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
-    goto LBL_MU;
-  }
-
-  /* compute the value at M[1<<(winsize-1)] by squaring 
-   * M[1] (winsize-1) times 
-   */
-  if ((err = mp_copy (&M[1], &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
-    goto LBL_MU;
-  }
-
-  for (x = 0; x < (winsize - 1); x++) {
-    /* square it */
-    if ((err = mp_sqr (&M[(mp_digit)(1 << (winsize - 1))], 
-                       &M[(mp_digit)(1 << (winsize - 1))])) != MP_OKAY) {
-      goto LBL_MU;
-    }
-
-    /* reduce modulo P */
-    if ((err = redux (&M[(mp_digit)(1 << (winsize - 1))], P, &mu)) != MP_OKAY) {
-      goto LBL_MU;
-    }
-  }
-
-  /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
-   * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
-   */
-  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
-    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
-      goto LBL_MU;
-    }
-    if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
-      goto LBL_MU;
-    }
-  }
-
-  /* setup result */
-  if ((err = mp_init (&res)) != MP_OKAY) {
-    goto LBL_MU;
-  }
-  mp_set (&res, 1);
-
-  /* set initial mode and bit cnt */
-  mode   = 0;
-  bitcnt = 1;
-  buf    = 0;
-  digidx = X->used - 1;
-  bitcpy = 0;
-  bitbuf = 0;
-
-  for (;;) {
-    /* grab next digit as required */
-    if (--bitcnt == 0) {
-      /* if digidx == -1 we are out of digits */
-      if (digidx == -1) {
-        break;
-      }
-      /* read next digit and reset the bitcnt */
-      buf    = X->dp[digidx--];
-      bitcnt = (int) DIGIT_BIT;
-    }
-
-    /* grab the next msb from the exponent */
-    y     = (int)(buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
-    buf <<= (mp_digit)1;
-
-    /* if the bit is zero and mode == 0 then we ignore it
-     * These represent the leading zero bits before the first 1 bit
-     * in the exponent.  Technically this opt is not required but it
-     * does lower the # of trivial squaring/reductions used
-     */
-    if (mode == 0 && y == 0) {
-      continue;
-    }
-
-    /* if the bit is zero and mode == 1 then we square */
-    if (mode == 1 && y == 0) {
-      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      continue;
-    }
-
-    /* else we add it to the window */
-    bitbuf |= (y << (winsize - ++bitcpy));
-    mode    = 2;
-
-    if (bitcpy == winsize) {
-      /* ok window is filled so square as required and multiply  */
-      /* square first */
-      for (x = 0; x < winsize; x++) {
-        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-      }
-
-      /* then multiply */
-      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-
-      /* empty window and reset */
-      bitcpy = 0;
-      bitbuf = 0;
-      mode   = 1;
-    }
-  }
-
-  /* if bits remain then square/multiply */
-  if (mode == 2 && bitcpy > 0) {
-    /* square then multiply if the bit is set */
-    for (x = 0; x < bitcpy; x++) {
-      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
-        goto LBL_RES;
-      }
-
-      bitbuf <<= 1;
-      if ((bitbuf & (1 << winsize)) != 0) {
-        /* then multiply */
-        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
-          goto LBL_RES;
-        }
-      }
-    }
-  }
-
-  mp_exch (&res, Y);
-  err = MP_OKAY;
-LBL_RES:mp_clear (&res);
-LBL_MU:mp_clear (&mu);
-LBL_M:
-  mp_clear(&M[1]);
-  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
-    mp_clear (&M[x]);
-  }
-  return err;
-}
-
-
-/* pre-calculate the value required for Barrett reduction
- * For a given modulus "b" it calulates the value required in "a"
- */
-int mp_reduce_setup (mp_int * a, mp_int * b)
-{
-  int     res;
-  
-  if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
-    return res;
-  }
-  return mp_div (a, b, a, NULL);
-}
-
-
-/* reduces x mod m, assumes 0 < x < m**2, mu is 
- * precomputed via mp_reduce_setup.
- * From HAC pp.604 Algorithm 14.42
- */
-int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
-{
-  mp_int  q;
-  int     res, um = m->used;
-
-  /* q = x */
-  if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
-    return res;
-  }
-
-  /* q1 = x / b**(k-1)  */
-  mp_rshd (&q, um - 1);
-
-  /* according to HAC this optimization is ok */
-  if (((mp_word) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
-    if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
-      goto CLEANUP;
-    }
-  } else {
-    if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
-      goto CLEANUP;
-    }
-    res = MP_VAL;
-    goto CLEANUP;
-  }
-
-  /* q3 = q2 / b**(k+1) */
-  mp_rshd (&q, um + 1);
-
-  /* x = x mod b**(k+1), quick (no division) */
-  if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
-    goto CLEANUP;
-  }
-
-  /* q = q * m mod b**(k+1), quick (no division) */
-  if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
-    goto CLEANUP;
-  }
-
-  /* x = x - q */
-  if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
-    goto CLEANUP;
-  }
-
-  /* If x < 0, add b**(k+1) to it */
-  if (mp_cmp_d (x, 0) == MP_LT) {
-    mp_set (&q, 1);
-    if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
-      goto CLEANUP;
-    if ((res = mp_add (x, &q, x)) != MP_OKAY)
-      goto CLEANUP;
-  }
-
-  /* Back off if it's too big */
-  while (mp_cmp (x, m) != MP_LT) {
-    if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
-      goto CLEANUP;
-    }
-  }
-
-CLEANUP:
-  mp_clear (&q);
-
-  return res;
-}
-
-
-/* reduces a modulo n where n is of the form 2**p - d 
-   This differs from reduce_2k since "d" can be larger
-   than a single digit.
-*/
-int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
-{
-   mp_int q;
-   int    p, res;
-
-   if ((res = mp_init(&q)) != MP_OKAY) {
-      return res;
-   }
-
-   p = mp_count_bits(n);
-top:
-   /* q = a/2**p, a = a mod 2**p */
-   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
-      goto ERR;
-   }
-
-   /* q = q * d */
-   if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { 
-      goto ERR;
-   }
-
-   /* a = a + q */
-   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
-      goto ERR;
-   }
-
-   if (mp_cmp_mag(a, n) != MP_LT) {
-      s_mp_sub(a, n, a);
-      goto top;
-   }
-
-ERR:
-   mp_clear(&q);
-   return res;
-}
-
-
-/* determines the setup value */
-int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
-{
-   int    res;
-   mp_int tmp;
-
-   if ((res = mp_init(&tmp)) != MP_OKAY) {
-      return res;
-   }
-
-   if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
-      goto ERR;
-   }
-
-   if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
-      goto ERR;
-   }
-
-ERR:
-   mp_clear(&tmp);
-   return res;
-}
-
-
-/* multiplies |a| * |b| and does not compute the lower digs digits
- * [meant to get the higher part of the product]
- */
-int
-s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
-  mp_int  t;
-  int     res, pa, pb, ix, iy;
-  mp_digit u;
-  mp_word r;
-  mp_digit tmpx, *tmpt, *tmpy;
-
-  if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
-    return res;
-  }
-  t.used = a->used + b->used + 1;
-
-  pa = a->used;
-  pb = b->used;
-  for (ix = 0; ix < pa; ix++) {
-    /* clear the carry */
-    u = 0;
-
-    /* left hand side of A[ix] * B[iy] */
-    tmpx = a->dp[ix];
-
-    /* alias to the address of where the digits will be stored */
-    tmpt = &(t.dp[digs]);
-
-    /* alias for where to read the right hand side from */
-    tmpy = b->dp + (digs - ix);
-
-    for (iy = digs - ix; iy < pb; iy++) {
-      /* calculate the double precision result */
-      r       = ((mp_word)*tmpt) +
-                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
-                ((mp_word) u);
-
-      /* get the lower part */
-      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
-
-      /* carry the carry */
-      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
-    }
-    *tmpt = u;
-  }
-  mp_clamp (&t);
-  mp_exch (&t, c);
-  mp_clear (&t);
-  return MP_OKAY;
-}
-
-
-/* this is a modified version of fast_s_mul_digs that only produces
- * output digits *above* digs.  See the comments for fast_s_mul_digs
- * to see how it works.
- *
- * This is used in the Barrett reduction since for one of the multiplications
- * only the higher digits were needed.  This essentially halves the work.
- *
- * Based on Algorithm 14.12 on pp.595 of HAC.
- */
-int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
-{
-  int     olduse, res, pa, ix, iz;
-  mp_digit W[MP_WARRAY];
-  mp_word  _W;
-
-  /* grow the destination as required */
-  pa = a->used + b->used;
-  if (c->alloc < pa) {
-    if ((res = mp_grow (c, pa)) != MP_OKAY) {
-      return res;
-    }
-  }
-
-  if (pa > MP_WARRAY)
-    return MP_RANGE;  /* TAO range check */
-
-  /* number of output digits to produce */
-  pa = a->used + b->used;
-  _W = 0;
-  for (ix = digs; ix < pa; ix++) { 
-      int      tx, ty, iy;
-      mp_digit *tmpx, *tmpy;
-
-      /* get offsets into the two bignums */
-      ty = MIN(b->used-1, ix);
-      tx = ix - ty;
-
-      /* setup temp aliases */
-      tmpx = a->dp + tx;
-      tmpy = b->dp + ty;
-
-      /* this is the number of times the loop will iterrate, essentially its 
-         while (tx++ < a->used && ty-- >= 0) { ... }
-       */
-      iy = MIN(a->used-tx, ty+1);
-
-      /* execute loop */
-      for (iz = 0; iz < iy; iz++) {
-         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
-      }
-
-      /* store term */
-      W[ix] = ((mp_digit)_W) & MP_MASK;
-
-      /* make next carry */
-      _W = _W >> ((mp_word)DIGIT_BIT);
-  }
-
-  /* setup dest */
-  olduse  = c->used;
-  c->used = pa;
-
-  {
-    register mp_digit *tmpc;
-
-    tmpc = c->dp + digs;
-    for (ix = digs; ix <= pa; ix++) {
-      /* now extract the previous digit [below the carry] */
-      *tmpc++ = W[ix];
-    }
-
-    /* clear unused digits [that existed in the old copy of c] */
-    for (; ix < olduse; ix++) {
-      *tmpc++ = 0;
-    }
-  }
-  mp_clamp (c);
-
-  return MP_OKAY;
-}
-
-
-/* set a 32-bit const */
-int mp_set_int (mp_int * a, unsigned long b)
-{
-  int     x, res;
-
-  mp_zero (a);
-
-  /* set four bits at a time */
-  for (x = 0; x < 8; x++) {
-    /* shift the number up four bits */
-    if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
-      return res;
-    }
-
-    /* OR in the top four bits of the source */
-    a->dp[0] |= (b >> 28) & 15;
-
-    /* shift the source up to the next four bits */
-    b <<= 4;
-
-    /* ensure that digits are not clamped off */
-    a->used += 1;
-  }
-  mp_clamp (a);
-  return MP_OKAY;
-}
-
-
-/* c = a * a (mod b) */
-int mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
-{
-  int     res;
-  mp_int  t;
-
-  if ((res = mp_init (&t)) != MP_OKAY) {
-    return res;
-  }
-
-  if ((res = mp_sqr (a, &t)) != MP_OKAY) {
-    mp_clear (&t);
-    return res;
-  }
-  res = mp_mod (&t, b, c);
-  mp_clear (&t);
-  return res;
-}
-
-
-/* single digit addition */
-int mp_add_d (mp_int* a, mp_digit b, mp_int* c)
-{
-  int     res, ix, oldused;
-  mp_digit *tmpa, *tmpc, mu;
-
-  /* grow c as required */
-  if (c->alloc < a->used + 1) {
-     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
-        return res;
-     }
-  }
-
-  /* if a is negative and |a| >= b, call c = |a| - b */
-  if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
-     /* temporarily fix sign of a */
-     a->sign = MP_ZPOS;
-
-     /* c = |a| - b */
-     res = mp_sub_d(a, b, c);
-
-     /* fix sign  */
-     a->sign = c->sign = MP_NEG;
-
-     /* clamp */
-     mp_clamp(c);
-
-     return res;
-  }
-
-  /* old number of used digits in c */
-  oldused = c->used;
-
-  /* sign always positive */
-  c->sign = MP_ZPOS;
-
-  /* source alias */
-  tmpa    = a->dp;
-
-  /* destination alias */
-  tmpc    = c->dp;
-
-  /* if a is positive */
-  if (a->sign == MP_ZPOS) {
-     /* add digit, after this we're propagating
-      * the carry.
-      */
-     *tmpc   = *tmpa++ + b;
-     mu      = *tmpc >> DIGIT_BIT;
-     *tmpc++ &= MP_MASK;
-
-     /* now handle rest of the digits */
-     for (ix = 1; ix < a->used; ix++) {
-        *tmpc   = *tmpa++ + mu;
-        mu      = *tmpc >> DIGIT_BIT;
-        *tmpc++ &= MP_MASK;
-     }
-     /* set final carry */
-     if (mu != 0 && ix < c->alloc) {
-        ix++;
-        *tmpc++  = mu;
-     }
-
-     /* setup size */
-     c->used = a->used + 1;
-  } else {
-     /* a was negative and |a| < b */
-     c->used  = 1;
-
-     /* the result is a single digit */
-     if (a->used == 1) {
-        *tmpc++  =  b - a->dp[0];
-     } else {
-        *tmpc++  =  b;
-     }
-
-     /* setup count so the clearing of oldused
-      * can fall through correctly
-      */
-     ix       = 1;
-  }
-
-  /* now zero to oldused */
-  while (ix++ < oldused) {
-     *tmpc++ = 0;
-  }
-  mp_clamp(c);
-
-  return MP_OKAY;
-}
-
-
-/* single digit subtraction */
-int mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
-{
-  mp_digit *tmpa, *tmpc, mu;
-  int       res, ix, oldused;
-
-  /* grow c as required */
-  if (c->alloc < a->used + 1) {
-     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
-        return res;
-     }
-  }
-
-  /* if a is negative just do an unsigned
-   * addition [with fudged signs]
-   */
-  if (a->sign == MP_NEG) {
-     a->sign = MP_ZPOS;
-     res     = mp_add_d(a, b, c);
-     a->sign = c->sign = MP_NEG;
-
-     /* clamp */
-     mp_clamp(c);
-
-     return res;
-  }
-
-  /* setup regs */
-  oldused = c->used;
-  tmpa    = a->dp;
-  tmpc    = c->dp;
-
-  /* if a <= b simply fix the single digit */
-  if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
-     if (a->used == 1) {
-        *tmpc++ = b - *tmpa;
-     } else {
-        *tmpc++ = b;
-     }
-     ix      = 1;
-
-     /* negative/1digit */
-     c->sign = MP_NEG;
-     c->used = 1;
-  } else {
-     /* positive/size */
-     c->sign = MP_ZPOS;
-     c->used = a->used;
-
-     /* subtract first digit */
-     *tmpc    = *tmpa++ - b;
-     mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
-     *tmpc++ &= MP_MASK;
-
-     /* handle rest of the digits */
-     for (ix = 1; ix < a->used; ix++) {
-        *tmpc    = *tmpa++ - mu;
-        mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
-        *tmpc++ &= MP_MASK;
-     }
-  }
-
-  /* zero excess digits */
-  while (ix++ < oldused) {
-     *tmpc++ = 0;
-  }
-  mp_clamp(c);
-  return MP_OKAY;
-}
-
-static const int lnz[16] = {
-   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
-};
-
-/* Counts the number of lsbs which are zero before the first zero bit */
-int mp_cnt_lsb(mp_int *a)
-{
-    int x;
-    mp_digit q, qq;
-
-    /* easy out */
-    if (mp_iszero(a) == 1) {
-        return 0;
-    }
-
-    /* scan lower digits until non-zero */
-    for (x = 0; x < a->used && a->dp[x] == 0; x++);
-    q = a->dp[x];
-    x *= DIGIT_BIT;
-
-    /* now scan this digit until a 1 is found */
-    if ((q & 1) == 0) {
-        do {
-            qq  = q & 15;
-            x  += lnz[qq];
-            q >>= 4;
-        } while (qq == 0);
-    }
-    return x;
-}
-
-static int s_is_power_of_two(mp_digit b, int *p)
-{
-   int x;
-
-   /* fast return if no power of two */
-   if ((b==0) || (b & (b-1))) {
-      return 0;
-   }
-
-   for (x = 0; x < DIGIT_BIT; x++) {
-      if (b == (((mp_digit)1)<<x)) {
-         *p = x;
-         return 1;
-      }
-   }
-   return 0;
-}
-
-/* single digit division (based on routine from MPI) */
-static int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
-{
-  mp_int  q;
-  mp_word w;
-  mp_digit t;
-  int     res, ix;
-
-  /* cannot divide by zero */
-  if (b == 0) {
-     return MP_VAL;
-  }
-
-  /* quick outs */
-  if (b == 1 || mp_iszero(a) == 1) {
-     if (d != NULL) {
-        *d = 0;
-     }
-     if (c != NULL) {
-        return mp_copy(a, c);
-     }
-     return MP_OKAY;
-  }
-
-  /* power of two ? */
-  if (s_is_power_of_two(b, &ix) == 1) {
-     if (d != NULL) {
-        *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
-     }
-     if (c != NULL) {
-        return mp_div_2d(a, ix, c, NULL);
-     }
-     return MP_OKAY;
-  }
-
-  /* three? */
-  if (b == 3) {
-     return mp_div_3(a, c, d);
-  }
-
-  /* no easy answer [c'est la vie].  Just division */
-  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
-     return res;
-  }
-
-  q.used = a->used;
-  q.sign = a->sign;
-  w = 0;
-  for (ix = a->used - 1; ix >= 0; ix--) {
-     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
-
-     if (w >= b) {
-        t = (mp_digit)(w / b);
-        w -= ((mp_word)t) * ((mp_word)b);
-      } else {
-        t = 0;
-      }
-      q.dp[ix] = (mp_digit)t;
-  }
-
-  if (d != NULL) {
-     *d = (mp_digit)w;
-  }
-
-  if (c != NULL) {
-     mp_clamp(&q);
-     mp_exch(&q, c);
-  }
-  mp_clear(&q);
-
-  return res;
-}
-
-
-int mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
-{
-  return mp_div_d(a, b, NULL, c);
-}
-
-const mp_digit ltm_prime_tab[] = {
-  0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
-  0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
-  0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
-  0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
-#ifndef MP_8BIT
-  0x0083,
-  0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
-  0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
-  0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
-  0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
-
-  0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
-  0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
-  0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
-  0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
-  0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
-  0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
-  0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
-  0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
-
-  0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
-  0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
-  0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
-  0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
-  0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
-  0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
-  0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
-  0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
-
-  0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
-  0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
-  0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
-  0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
-  0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
-  0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
-  0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
-  0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
-#endif
-};
-
-
-/* Miller-Rabin test of "a" to the base of "b" as described in 
- * HAC pp. 139 Algorithm 4.24
- *
- * Sets result to 0 if definitely composite or 1 if probably prime.
- * Randomly the chance of error is no more than 1/4 and often 
- * very much lower.
- */
-static int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
-{
-  mp_int  n1, y, r;
-  int     s, j, err;
-
-  /* default */
-  *result = MP_NO;
-
-  /* ensure b > 1 */
-  if (mp_cmp_d(b, 1) != MP_GT) {
-     return MP_VAL;
-  }
-
-  /* get n1 = a - 1 */
-  if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
-    return err;
-  }
-  if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
-    goto LBL_N1;
-  }
-
-  /* set 2**s * r = n1 */
-  if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
-    goto LBL_N1;
-  }
-
-  /* count the number of least significant bits
-   * which are zero
-   */
-  s = mp_cnt_lsb(&r);
-
-  /* now divide n - 1 by 2**s */
-  if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
-    goto LBL_R;
-  }
-
-  /* compute y = b**r mod a */
-  if ((err = mp_init (&y)) != MP_OKAY) {
-    goto LBL_R;
-  }
-  if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
-    goto LBL_Y;
-  }
-
-  /* if y != 1 and y != n1 do */
-  if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
-    j = 1;
-    /* while j <= s-1 and y != n1 */
-    while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
-      if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
-         goto LBL_Y;
-      }
-
-      /* if y == 1 then composite */
-      if (mp_cmp_d (&y, 1) == MP_EQ) {
-         goto LBL_Y;
-      }
-
-      ++j;
-    }
-
-    /* if y != n1 then composite */
-    if (mp_cmp (&y, &n1) != MP_EQ) {
-      goto LBL_Y;
-    }
-  }
-
-  /* probably prime now */
-  *result = MP_YES;
-LBL_Y:mp_clear (&y);
-LBL_R:mp_clear (&r);
-LBL_N1:mp_clear (&n1);
-  return err;
-}
-
-
-/* determines if an integers is divisible by one 
- * of the first PRIME_SIZE primes or not
- *
- * sets result to 0 if not, 1 if yes
- */
-static int mp_prime_is_divisible (mp_int * a, int *result)
-{
-  int     err, ix;
-  mp_digit res;
-
-  /* default to not */
-  *result = MP_NO;
-
-  for (ix = 0; ix < PRIME_SIZE; ix++) {
-    /* what is a mod LBL_prime_tab[ix] */
-    if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
-      return err;
-    }
-
-    /* is the residue zero? */
-    if (res == 0) {
-      *result = MP_YES;
-      return MP_OKAY;
-    }
-  }
-
-  return MP_OKAY;
-}
-
-
-/*
- * Sets result to 1 if probably prime, 0 otherwise
- */
-int mp_prime_is_prime (mp_int * a, int t, int *result)
-{
-  mp_int  b;
-  int     ix, err, res;
-
-  /* default to no */
-  *result = MP_NO;
-
-  /* valid value of t? */
-  if (t <= 0 || t > PRIME_SIZE) {
-    return MP_VAL;
-  }
-
-  /* is the input equal to one of the primes in the table? */
-  for (ix = 0; ix < PRIME_SIZE; ix++) {
-      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
-         *result = 1;
-         return MP_OKAY;
-      }
-  }
-
-  /* first perform trial division */
-  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
-    return err;
-  }
-
-  /* return if it was trivially divisible */
-  if (res == MP_YES) {
-    return MP_OKAY;
-  }
-
-  /* now perform the miller-rabin rounds */
-  if ((err = mp_init (&b)) != MP_OKAY) {
-    return err;
-  }
-
-  for (ix = 0; ix < t; ix++) {
-    /* set the prime */
-    mp_set (&b, ltm_prime_tab[ix]);
-
-    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
-      goto LBL_B;
-    }
-
-    if (res == MP_NO) {
-      goto LBL_B;
-    }
-  }
-
-  /* passed the test */
-  *result = MP_YES;
-LBL_B:mp_clear (&b);
-  return err;
-}
-
-
-/* computes least common multiple as |a*b|/(a, b) */
-int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
-{
-  int     res;
-  mp_int  t1, t2;
-
-
-  if ((res = mp_init_multi (&t1, &t2, NULL, NULL, NULL, NULL)) != MP_OKAY) {
-    return res;
-  }
-
-  /* t1 = get the GCD of the two inputs */
-  if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
-    goto LBL_T;
-  }
-
-  /* divide the smallest by the GCD */
-  if (mp_cmp_mag(a, b) == MP_LT) {
-     /* store quotient in t2 such that t2 * b is the LCM */
-     if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
-        goto LBL_T;
-     }
-     res = mp_mul(b, &t2, c);
-  } else {
-     /* store quotient in t2 such that t2 * a is the LCM */
-     if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
-        goto LBL_T;
-     }
-     res = mp_mul(a, &t2, c);
-  }
-
-  /* fix the sign to positive */
-  c->sign = MP_ZPOS;
-
-LBL_T:
-  mp_clear(&t1);
-  mp_clear(&t2);
-  return res;
-}
-
-
-
-/* Greatest Common Divisor using the binary method */
-int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
-{
-    mp_int  u, v;
-    int     k, u_lsb, v_lsb, res;
-
-    /* either zero than gcd is the largest */
-    if (mp_iszero (a) == MP_YES) {
-        return mp_abs (b, c);
-    }
-    if (mp_iszero (b) == MP_YES) {
-        return mp_abs (a, c);
-    }
-
-    /* get copies of a and b we can modify */
-    if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
-        return res;
-    }
-
-    if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
-        goto LBL_U;
-    }
-
-    /* must be positive for the remainder of the algorithm */
-    u.sign = v.sign = MP_ZPOS;
-
-    /* B1.  Find the common power of two for u and v */
-    u_lsb = mp_cnt_lsb(&u);
-    v_lsb = mp_cnt_lsb(&v);
-    k     = MIN(u_lsb, v_lsb);
-
-    if (k > 0) {
-        /* divide the power of two out */
-        if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
-            goto LBL_V;
-        }
-
-        if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
-            goto LBL_V;
-        }
-    }
-
-    /* divide any remaining factors of two out */
-    if (u_lsb != k) {
-        if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
-            goto LBL_V;
-        }
-    }
-
-    if (v_lsb != k) {
-        if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
-            goto LBL_V;
-        }
-    }
-
-    while (mp_iszero(&v) == 0) {
-        /* make sure v is the largest */
-        if (mp_cmp_mag(&u, &v) == MP_GT) {
-            /* swap u and v to make sure v is >= u */
-            mp_exch(&u, &v);
-        }
-
-        /* subtract smallest from largest */
-        if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
-            goto LBL_V;
-        }
-
-        /* Divide out all factors of two */
-        if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
-            goto LBL_V;
-        }
-    }
-
-    /* multiply by 2**k which we divided out at the beginning */
-    if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
-        goto LBL_V;
-    }
-    c->sign = MP_ZPOS;
-    res = MP_OKAY;
-LBL_V:mp_clear (&u);
-LBL_U:mp_clear (&v);
-    return res;
-}
-
-/* chars used in radix conversions */
-const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
-
-/* read a string [ASCII] in a given radix */
-int mp_read_radix (mp_int * a, const char *str, int radix)
-{
-  int     y, res, neg;
-  char    ch;
-
-  /* zero the digit bignum */
-  mp_zero(a);
-
-  /* make sure the radix is ok */
-  if (radix < 2 || radix > 64) {
-    return MP_VAL;
-  }
-
-  /* if the leading digit is a 
-   * minus set the sign to negative. 
-   */
-  if (*str == '-') {
-    ++str;
-    neg = MP_NEG;
-  } else {
-    neg = MP_ZPOS;
-  }
-
-  /* set the integer to the default of zero */
-  mp_zero (a);
-
-  /* process each digit of the string */
-  while (*str) {
-    /* if the radix < 36 the conversion is case insensitive
-     * this allows numbers like 1AB and 1ab to represent the same  value
-     * [e.g. in hex]
-     */
-    ch = (char) ((radix < 36) ? XTOUPPER(*str) : *str);
-    for (y = 0; y < 64; y++) {
-      if (ch == mp_s_rmap[y]) {
-         break;
-      }
-    }
-
-    /* if the char was found in the map 
-     * and is less than the given radix add it
-     * to the number, otherwise exit the loop. 
-     */
-    if (y < radix) {
-      if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
-         return res;
-      }
-      if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
-         return res;
-      }
-    } else {
-      break;
-    }
-    ++str;
-  }
-
-  /* set the sign only if a != 0 */
-  if (mp_iszero(a) != 1) {
-     a->sign = neg;
-  }
-  return MP_OKAY;
-}

+ 0 - 319
Pal/lib/crypto/wolfssl/integer.h

@@ -1,319 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* integer.h
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-/*
- * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca,
- * http://math.libtomcrypt.com
- */
-
-
-#ifndef CTAO_CRYPT_INTEGER_H
-#define CTAO_CRYPT_INTEGER_H
-
-#include <stdint.h>
-
-#ifndef word32
-typedef uint32_t word32;
-#endif
-#ifndef byte
-typedef uint8_t byte;
-#endif
-
-/* may optionally use fast math instead, not yet supported on all platforms and
-   may not be faster on all
-*/
-#if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
-    #define WORD64_AVAILABLE
-    #define W64LIT(x) x##ui64
-    typedef unsigned __int64 word64;
-#elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8
-    #define WORD64_AVAILABLE
-    #define W64LIT(x) x##LL
-    typedef unsigned long word64;
-#elif defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8
-    #define WORD64_AVAILABLE
-    #define W64LIT(x) x##LL
-    typedef unsigned long long word64;
-#elif defined(__SIZEOF_LONG_LONG__) && __SIZEOF_LONG_LONG__ == 8
-    #define WORD64_AVAILABLE
-    #define W64LIT(x) x##LL
-    typedef unsigned long long word64;
-#else
-    #define MP_16BIT  /* for mp_int, mp_word needs to be twice as big as
-                         mp_digit, no 64 bit type so make mp_digit 16 bit */
-#endif
-
-#include <limits.h>
-
-#ifndef MIN
-   #define MIN(x,y) ((x)<(y)?(x):(y))
-#endif
-
-#ifndef MAX
-   #define MAX(x,y) ((x)>(y)?(x):(y))
-#endif
-
-/* C on the other hand doesn't care */
-#define  OPT_CAST(x)
-
-/* detect 64-bit mode if possible */
-#if defined(__x86_64__) 
-   #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
-      #define MP_64BIT
-   #endif
-#endif
-/* if intel compiler doesn't provide 128 bit type don't turn on 64bit */
-#if defined(MP_64BIT) && defined(__INTEL_COMPILER) && !defined(HAVE___UINT128_T)
-    #undef MP_64BIT
-#endif
-
-/* some default configurations.
- *
- * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
- * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
- *
- * At the very least a mp_digit must be able to hold 7 bits
- * [any size beyond that is ok provided it doesn't overflow the data type]
- */
-#ifdef MP_8BIT
-   typedef unsigned char      mp_digit;
-   typedef unsigned short     mp_word;
-#elif defined(MP_16BIT) || defined(NO_64BIT)
-   typedef unsigned short     mp_digit;
-   typedef unsigned int       mp_word;
-#elif defined(MP_64BIT)
-   /* for GCC only on supported platforms */
-   typedef unsigned long long mp_digit;  /* 64 bit type, 128 uses mode(TI) */
-   typedef unsigned long      mp_word __attribute__ ((mode(TI)));
-
-   #define DIGIT_BIT          60
-#else
-   /* this is the default case, 28-bit digits */
-
-   #if defined(_MSC_VER) || defined(__BORLANDC__) 
-      typedef unsigned __int64   ulong64;
-   #else
-      typedef unsigned long long ulong64;
-   #endif
-
-   typedef unsigned int       mp_digit;  /* long could be 64 now, changed TAO */
-   typedef ulong64            mp_word;
-
-#ifdef MP_31BIT
-   /* this is an extension that uses 31-bit digits */
-   #define DIGIT_BIT          31
-#else
-   /* default case is 28-bit digits, defines MP_28BIT as a handy test macro */
-   #define DIGIT_BIT          28
-   #define MP_28BIT
-#endif
-#endif
-
-
-/* otherwise the bits per digit is calculated automatically from the size of
-   a mp_digit */
-#ifndef DIGIT_BIT
-   #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1)))
-      /* bits per digit */
-#endif
-
-#define MP_DIGIT_BIT     DIGIT_BIT
-#define MP_MASK          ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
-#define MP_DIGIT_MAX     MP_MASK
-
-/* equalities */
-#define MP_LT        -1   /* less than */
-#define MP_EQ         0   /* equal to */
-#define MP_GT         1   /* greater than */
-
-#define MP_ZPOS       0   /* positive integer */
-#define MP_NEG        1   /* negative */
-
-#define MP_OKAY       0   /* ok result */
-#define MP_MEM        -2  /* out of mem */
-#define MP_VAL        -3  /* invalid input */
-#define MP_RANGE      MP_VAL
-
-#define MP_YES        1   /* yes response */
-#define MP_NO         0   /* no response */
-
-/* Primality generation flags */
-#define LTM_PRIME_BBS      0x0001 /* BBS style prime */
-#define LTM_PRIME_SAFE     0x0002 /* Safe prime (p-1)/2 == prime */
-#define LTM_PRIME_2MSB_ON  0x0008 /* force 2nd MSB to 1 */
-
-typedef int           mp_err;
-
-/* define this to use lower memory usage routines (exptmods mostly) */
-#define MP_LOW_MEM
-
-/* default precision */
-#ifndef MP_PREC
-   #define MP_PREC                 32     /* default digits of precision */
-#endif
-
-/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - 
-   BITS_PER_DIGIT*2) */
-#define MP_WARRAY  (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
-
-/* the infamous mp_int structure */
-typedef struct  {
-    int used, alloc, sign;
-    mp_digit *dp;
-} mp_int;
-
-/* callback for mp_prime_random, should fill dst with random bytes and return
-   how many read [upto len] */
-typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
-
-
-#define USED(m)    ((m)->used)
-#define DIGIT(m,k) ((m)->dp[(k)])
-#define SIGN(m)    ((m)->sign)
-
-
-/* ---> Basic Manipulations <--- */
-#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
-#define mp_iseven(a) \
-    (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
-#define mp_isodd(a) \
-    (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
-
-
-/* number of primes */
-#ifdef MP_8BIT
-   #define PRIME_SIZE      31
-#else
-   #define PRIME_SIZE      256
-#endif
-
-#define mp_prime_random(a, t, size, bbs, cb, dat) \
-   mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
-
-#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
-#define mp_raw_size(mp)           mp_signed_bin_size(mp)
-#define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str))
-#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
-#define mp_mag_size(mp)           mp_unsigned_bin_size(mp)
-#define mp_tomag(mp, str)         mp_to_unsigned_bin((mp), (str))
-
-#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
-#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
-#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
-#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
-
-#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
-
-extern const char *mp_s_rmap;
-
-/* 6 functions needed by Rsa */
-int  mp_init (mp_int * a);
-void mp_clear (mp_int * a);
-int  mp_unsigned_bin_size(mp_int * a);
-int  mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
-int  mp_to_unsigned_bin (mp_int * a, unsigned char *b);
-int  mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
-/* end functions needed by Rsa */
-
-/* functions added to support above needed, removed TOOM and KARATSUBA */
-int  mp_count_bits (mp_int * a);
-int  mp_leading_bit (mp_int * a);
-int  mp_init_copy (mp_int * a, mp_int * b);
-int  mp_copy (mp_int * a, mp_int * b);
-int  mp_grow (mp_int * a, int size);
-int  mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d);
-void mp_zero (mp_int * a);
-void mp_clamp (mp_int * a);
-void mp_exch (mp_int * a, mp_int * b);
-void mp_rshd (mp_int * a, int b);
-void mp_rshb (mp_int * a, int b);
-int  mp_mod_2d (mp_int * a, int b, mp_int * c);
-int  mp_mul_2d (mp_int * a, int b, mp_int * c);
-int  mp_lshd (mp_int * a, int b);
-int  mp_abs (mp_int * a, mp_int * b);
-int  mp_invmod (mp_int * a, mp_int * b, mp_int * c);
-int  fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c);
-int  mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
-int  mp_cmp_mag (mp_int * a, mp_int * b);
-int  mp_cmp (mp_int * a, mp_int * b);
-int  mp_cmp_d(mp_int * a, mp_digit b);
-void mp_set (mp_int * a, mp_digit b);
-int  mp_mod (mp_int * a, mp_int * b, mp_int * c);
-int  mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d);
-int  mp_div_2(mp_int * a, mp_int * b);
-int  mp_add (mp_int * a, mp_int * b, mp_int * c);
-int  s_mp_add (mp_int * a, mp_int * b, mp_int * c);
-int  s_mp_sub (mp_int * a, mp_int * b, mp_int * c);
-int  mp_sub (mp_int * a, mp_int * b, mp_int * c);
-int  mp_reduce_is_2k_l(mp_int *a);
-int  mp_reduce_is_2k(mp_int *a);
-int  mp_dr_is_modulus(mp_int *a);
-int  mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int);
-int  mp_montgomery_setup (mp_int * n, mp_digit * rho);
-int  fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);
-int  mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho);
-void mp_dr_setup(mp_int *a, mp_digit *d);
-int  mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k);
-int  mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
-int  fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
-int  s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
-int  mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
-int  mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
-int  mp_reduce (mp_int * x, mp_int * m, mp_int * mu);
-int  mp_reduce_setup (mp_int * a, mp_int * b);
-int  s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode);
-int  mp_montgomery_calc_normalization (mp_int * a, mp_int * b);
-int  s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
-int  s_mp_sqr (mp_int * a, mp_int * b);
-int  fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs);
-int  fast_s_mp_sqr (mp_int * a, mp_int * b);
-int  mp_init_size (mp_int * a, int size);
-int  mp_div_3 (mp_int * a, mp_int *c, mp_digit * d);
-int  mp_mul_2(mp_int * a, mp_int * b);
-int  mp_mul (mp_int * a, mp_int * b, mp_int * c);
-int  mp_sqr (mp_int * a, mp_int * b);
-int  mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
-int  mp_mul_d (mp_int * a, mp_digit b, mp_int * c);
-int  mp_2expt (mp_int * a, int b);
-int  mp_reduce_2k_setup(mp_int *a, mp_digit *d);
-int  mp_add_d (mp_int* a, mp_digit b, mp_int* c);
-int mp_set_int (mp_int * a, unsigned long b);
-int mp_sub_d (mp_int * a, mp_digit b, mp_int * c);
-/* end support added functions */
-
-/* added */
-int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e,
-                  mp_int* f);
-
-int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c);
-int mp_read_radix(mp_int* a, const char* str, int radix);
-
-int mp_prime_is_prime (mp_int * a, int t, int *result);
-int mp_gcd (mp_int * a, mp_int * b, mp_int * c);
-int mp_lcm (mp_int * a, mp_int * b, mp_int * c);
-
-int mp_cnt_lsb(mp_int *a);
-int mp_mod_d(mp_int* a, mp_digit b, mp_digit* c);
-
-#endif  /* CTAO_CRYPT_INTEGER_H */

+ 0 - 592
Pal/lib/crypto/wolfssl/rsa.c

@@ -1,592 +0,0 @@
-/* rsa.c
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#include "rsa.h"
-#include "error-crypt.h"
-#include "api.h"
-
-#ifdef IN_PAL
-int _DkRandomBitsRead (void  *buffer, int size);
-#define DkRandomBitsRead _DkRandomBitsRead
-#else
-int DkRandomBitsRead (void  *buffer, int size);
-#endif
-
-#define XMALLOC malloc
-#define XFREE   free
-
-#define XMEMCPY memcpy
-#define XMEMSET memset
-
-enum {
-    RSA_PUBLIC_ENCRYPT  = 0,
-    RSA_PUBLIC_DECRYPT  = 1,
-    RSA_PRIVATE_ENCRYPT = 2,
-    RSA_PRIVATE_DECRYPT = 3,
-
-    RSA_BLOCK_TYPE_1 = 1,
-    RSA_BLOCK_TYPE_2 = 2,
-
-    RSA_MIN_SIZE = 512,
-    RSA_MAX_SIZE = 4096,
-
-    RSA_MIN_PAD_SZ   = 11      /* seperator + 0 + pad value + 8 pads */
-};
-
-int InitRSAKey(RSAKey *key)
-{
-    key->type = -1;  /* haven't decided yet */
-
-    key->n.dp = key->e.dp  = 0;  /* public  alloc parts */
-    key->d.dp = key->p.dp  = 0;  /* private alloc parts */
-    key->q.dp = key->dP.dp = 0;
-    key->u.dp = key->dQ.dp = 0;
-
-    return 0;
-}
-
-int FreeRSAKey(RSAKey *key)
-{
-    (void)key;
-
-    if (key->type == RSA_PRIVATE) {
-        mp_clear(&key->u);
-        mp_clear(&key->dQ);
-        mp_clear(&key->dP);
-        mp_clear(&key->q);
-        mp_clear(&key->p);
-        mp_clear(&key->d);
-    }
-    mp_clear(&key->e);
-    mp_clear(&key->n);
-
-    return 0;
-}
-
-static int RSAPad(const byte *input, word32 inputLen, byte *pkcsBlock,
-                  word32 pkcsBlockLen, byte padValue)
-{
-    if (inputLen == 0)
-        return 0;
-
-    pkcsBlock[0] = 0x0;       /* set first byte to zero and advance */
-    pkcsBlock++; pkcsBlockLen--;
-    pkcsBlock[0] = padValue;  /* insert padValue */
-
-    if (padValue == RSA_BLOCK_TYPE_1)
-        /* pad with 0xff bytes */
-        XMEMSET(&pkcsBlock[1], 0xFF, pkcsBlockLen - inputLen - 2);
-    else {
-        /* pad with non-zero random bytes */
-        word32 padLen = pkcsBlockLen - inputLen - 1, i;
-        int    ret    = DkRandomBitsRead(&pkcsBlock[1], padLen);
-
-        if (ret < 0)
-            return ret;
-
-        /* remove zeros */
-        for (i = 1; i < padLen; i++)
-            if (pkcsBlock[i] == 0) pkcsBlock[i] = 0x01;
-    }
-
-    pkcsBlock[pkcsBlockLen-inputLen-1] = 0;     /* separator */
-    XMEMCPY(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen);
-
-    return 0;
-}
-
-
-/* UnPad plaintext, set start to *output, return length of plaintext,
- * < 0 on error */
-static int RSAUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
-                       byte **output, byte padValue)
-{
-    word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0,
-           invalid = 0,
-           i = 1,
-           outputLen;
-
-    if (pkcsBlock[0] != 0x0) /* skip past zero */
-        invalid = 1;
-    pkcsBlock++; pkcsBlockLen--;
-
-    /* Require block type padValue */
-    invalid = (pkcsBlock[0] != padValue) || invalid;
-
-    /* verify the padding until we find the separator */
-    if (padValue == RSA_BLOCK_TYPE_1) {
-        while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
-    }
-    else {
-        while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
-    }
-
-    if(!(i==pkcsBlockLen || pkcsBlock[i-1]==0))
-        return RSA_PAD_E;
-
-    outputLen = pkcsBlockLen - i;
-    invalid = (outputLen > maxOutputLen) || invalid;
-
-    if (invalid)
-        return RSA_PAD_E;
-
-    *output = (byte *)(pkcsBlock + i);
-    return outputLen;
-}
-
-
-static int RSAFunction(const byte *in, word32 inLen, byte *out, word32 *outLen,
-                       int type, RSAKey *key)
-{
-#define ERROR_OUT(x) { ret = (x); goto done;}
-
-    mp_int tmp;
-    int    ret = 0;
-    word32 keyLen, len;
-
-    if (mp_init(&tmp) != MP_OKAY)
-        return MP_INIT_E;
-
-    if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
-        ERROR_OUT(MP_READ_E);
-
-    if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
-
-#define INNER_ERROR_OUT(x) { ret = (x); goto inner_done; }
-
-            mp_int tmpa, tmpb;
-
-            if (mp_init(&tmpa) != MP_OKAY)
-                ERROR_OUT(MP_INIT_E);
-
-            if (mp_init(&tmpb) != MP_OKAY) {
-                mp_clear(&tmpa);
-                ERROR_OUT(MP_INIT_E);
-            }
-
-            /* tmpa = tmp^dP mod p */
-            if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY)
-                INNER_ERROR_OUT(MP_EXPTMOD_E);
-
-            /* tmpb = tmp^dQ mod q */
-            if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY)
-                INNER_ERROR_OUT(MP_EXPTMOD_E);
-
-            /* tmp = (tmpa - tmpb)  *qInv (mod p) */
-            if (mp_sub(&tmpa, &tmpb, &tmp) != MP_OKAY)
-                INNER_ERROR_OUT(MP_SUB_E);
-
-            if (mp_mulmod(&tmp, &key->u, &key->p, &tmp) != MP_OKAY)
-                INNER_ERROR_OUT(MP_MULMOD_E);
-
-            /* tmp = tmpb + q  *tmp */
-            if (mp_mul(&tmp, &key->q, &tmp) != MP_OKAY)
-                INNER_ERROR_OUT(MP_MUL_E);
-
-            if (mp_add(&tmp, &tmpb, &tmp) != MP_OKAY)
-                INNER_ERROR_OUT(MP_ADD_E);
-
-inner_done:
-            mp_clear(&tmpa);
-            mp_clear(&tmpb);
-
-            if (ret != 0) return ret;
-    }
-    else if (type == RSA_PUBLIC_ENCRYPT || type == RSA_PUBLIC_DECRYPT) {
-        if (mp_exptmod(&tmp, &key->e, &key->n, &tmp) != MP_OKAY)
-            ERROR_OUT(MP_EXPTMOD_E);
-    }
-    else
-        ERROR_OUT(RSA_WRONG_TYPE_E);
-
-    keyLen = mp_unsigned_bin_size(&key->n);
-    if (keyLen > *outLen)
-        ERROR_OUT(RSA_BUFFER_E);
-
-    len = mp_unsigned_bin_size(&tmp);
-
-    /* pad front w/ zeros to match key length */
-    while (len < keyLen) {
-        *out++ = 0x00;
-        len++;
-    }
-
-    *outLen = keyLen;
-
-    /* convert */
-    if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
-        ERROR_OUT(MP_TO_E);
-
-done:
-    mp_clear(&tmp);
-    return ret;
-}
-
-
-int RSAPublicEncrypt(const byte *in, word32 inLen, byte *out, word32 outLen,
-                     RSAKey *key)
-{
-    int sz, ret;
-
-    sz = mp_unsigned_bin_size(&key->n);
-    if (sz > (int)outLen)
-        return RSA_BUFFER_E;
-
-    if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
-        return RSA_BUFFER_E;
-
-    ret = RSAPad(in, inLen, out, sz, RSA_BLOCK_TYPE_2);
-    if (ret != 0)
-        return ret;
-
-    if ((ret = RSAFunction(out, sz, out, &outLen, RSA_PUBLIC_ENCRYPT, key)) < 0)
-        sz = ret;
-
-    return sz;
-}
-
-
-int RSAPrivateDecryptInline(byte *in, word32 inLen, byte* *out, RSAKey *key)
-{
-    int ret;
-
-    if ((ret = RSAFunction(in, inLen, in, &inLen, RSA_PRIVATE_DECRYPT, key))
-            < 0) {
-        return ret;
-    }
-
-    return RSAUnPad(in, inLen, out, RSA_BLOCK_TYPE_2);
-}
-
-
-int RSAPrivateDecrypt(const byte *in, word32 inLen, byte *out, word32 outLen,
-                     RSAKey *key)
-{
-    int plainLen;
-    byte *tmp;
-    byte *pad = 0;
-
-    tmp = (byte *)XMALLOC(inLen);
-    if (tmp == NULL) {
-        return MEMORY_E;
-    }
-
-    XMEMCPY(tmp, in, inLen);
-
-    if ( (plainLen = RSAPrivateDecryptInline(tmp, inLen, &pad, key) ) < 0) {
-        XFREE(tmp);
-        return plainLen;
-    }
-    if (plainLen > (int)outLen)
-        plainLen = BAD_FUNC_ARG;
-    else
-        XMEMCPY(out, pad, plainLen);
-    XMEMSET(tmp, 0x00, inLen);
-
-    XFREE(tmp);
-    return plainLen;
-}
-
-
-/* for RSA Verify */
-int RSASSL_VerifyInline(byte *in, word32 inLen, byte* *out, RSAKey *key)
-{
-    int ret;
-
-    if ((ret = RSAFunction(in, inLen, in, &inLen, RSA_PUBLIC_DECRYPT, key))
-            < 0) {
-        return ret;
-    }
-
-    return RSAUnPad(in, inLen, out, RSA_BLOCK_TYPE_1);
-}
-
-
-int RSASSL_Verify(const byte *in, word32 inLen, byte *out, word32 outLen,
-                  RSAKey *key)
-{
-    int plainLen;
-    byte *tmp;
-    byte *pad = 0;
-
-    tmp = (byte *)XMALLOC(inLen);
-    if (tmp == NULL) {
-        return MEMORY_E;
-    }
-
-    XMEMCPY(tmp, in, inLen);
-
-    if ( (plainLen = RSASSL_VerifyInline(tmp, inLen, &pad, key) ) < 0) {
-        XFREE(tmp);
-        return plainLen;
-    }
-
-    if (plainLen > (int)outLen)
-        plainLen = BAD_FUNC_ARG;
-    else
-        XMEMCPY(out, pad, plainLen);
-    XMEMSET(tmp, 0x00, inLen);
-
-    XFREE(tmp);
-    return plainLen;
-}
-
-/* for RSA Sign */
-int RSASSL_Sign(const byte *in, word32 inLen, byte *out, word32 outLen,
-                      RSAKey *key)
-{
-    int sz, ret;
-
-    sz = mp_unsigned_bin_size(&key->n);
-    if (sz > (int)outLen)
-        return RSA_BUFFER_E;
-
-    if (inLen > (word32)(sz - RSA_MIN_PAD_SZ))
-        return RSA_BUFFER_E;
-
-    ret = RSAPad(in, inLen, out, sz, RSA_BLOCK_TYPE_1);
-    if (ret != 0)
-        return ret;
-
-    if ((ret = RSAFunction(out, sz, out, &outLen, RSA_PRIVATE_ENCRYPT,key)) < 0)
-        sz = ret;
-
-    return sz;
-}
-
-
-int RSAEncryptSize(RSAKey *key)
-{
-    return mp_unsigned_bin_size(&key->n);
-}
-
-int RSAPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, word32 eSz,
-                          RSAKey* key)
-{
-    if (n == NULL || e == NULL || key == NULL)
-        return BAD_FUNC_ARG;
-
-    key->type = RSA_PUBLIC;
-
-    if (mp_init(&key->n) != MP_OKAY)
-        return MP_INIT_E;
-
-    if (mp_read_unsigned_bin(&key->n, n, nSz) != 0) {
-        mp_clear(&key->n);
-        return ASN_GETINT_E;
-    }
-
-    if (mp_init(&key->e) != MP_OKAY) {
-        mp_clear(&key->n);
-        return MP_INIT_E;
-    }
-
-    if (mp_read_unsigned_bin(&key->e, e, eSz) != 0) {
-        mp_clear(&key->n);
-        mp_clear(&key->e);
-        return ASN_GETINT_E;
-    }
-
-    return 0;
-}
-
-int RSAFlattenPublicKey(RSAKey *key, byte *e, word32 *eSz, byte *n, word32 *nSz)
-{
-    int sz, ret;
-
-    if (key == NULL || e == NULL || eSz == NULL || n == NULL || nSz == NULL)
-       return BAD_FUNC_ARG;
-
-    sz = mp_unsigned_bin_size(&key->e);
-    if ((word32)sz > *nSz)
-        return RSA_BUFFER_E;
-    ret = mp_to_unsigned_bin(&key->e, e);
-    if (ret != MP_OKAY)
-        return ret;
-    *eSz = (word32)sz;
-
-    sz = mp_unsigned_bin_size(&key->n);
-    if ((word32)sz > *nSz)
-        return RSA_BUFFER_E;
-    ret = mp_to_unsigned_bin(&key->n, n);
-    if (ret != MP_OKAY)
-        return ret;
-    *nSz = (word32)sz;
-
-    return 0;
-}
-
-static int rand_prime(mp_int *N, int len)
-{
-    int   err, res;
-    byte *buf;
-
-    if (N == NULL)
-       return BAD_FUNC_ARG;
-
-    /* allow sizes between 2 and 512 bytes for a prime size */
-    if (len < 2 || len > 512) {
-        return BAD_FUNC_ARG;
-    }
-
-    /* allocate buffer to work with */
-    buf = (byte*)XMALLOC(len);
-    if (buf == NULL) {
-        return MEMORY_E;
-    }
-    XMEMSET(buf, 0, len);
-
-    do {
-        /* generate value */
-        err = DkRandomBitsRead(buf, len);
-        if (err < 0) {
-            XFREE(buf);
-            return err;
-        }
-
-        /* munge bits */
-        buf[0]     |= 0x80 | 0x40;
-        buf[len-1] |= 0x01;
-
-        /* load value */
-        if ((err = mp_read_unsigned_bin(N, buf, len)) != MP_OKAY) {
-            XFREE(buf);
-            return err;
-        }
-
-        /* test */
-        if ((err = mp_prime_is_prime(N, 8, &res)) != MP_OKAY) {
-            XFREE(buf);
-            return err;
-        }
-    } while (res == MP_NO);
-
-    XMEMSET(buf, 0, len);
-    XFREE(buf);
-    return 0;
-}
-
-
-/* Make an RSA key for size bits, with e specified, 65537 is a good e */
-int MakeRSAKey(RSAKey *key, int size, long e)
-{
-    mp_int p, q, tmp1, tmp2, tmp3;
-    int    err;
-
-    if (key == NULL)
-        return BAD_FUNC_ARG;
-
-    if (size < RSA_MIN_SIZE || size > RSA_MAX_SIZE)
-        return BAD_FUNC_ARG;
-
-    if (e < 3 || (e & 1) == 0)
-        return BAD_FUNC_ARG;
-
-    if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY)
-        return err;
-
-    err = mp_set_int(&tmp3, e);
-
-    /* make p */
-    if (err == MP_OKAY) {
-        do {
-            err = rand_prime(&p, size/16); /* size in bytes/2 */
-
-            if (err == MP_OKAY)
-                err = mp_sub_d(&p, 1, &tmp1);  /* tmp1 = p-1 */
-
-            if (err == MP_OKAY)
-                err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(p-1, e) */
-        } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divdes p-1 */
-    }
-
-    /* make q */
-    if (err == MP_OKAY) {
-        do {
-            err = rand_prime(&q, size/16); /* size in bytes/2 */
-
-            if (err == MP_OKAY)
-                err = mp_sub_d(&q, 1, &tmp1);  /* tmp1 = q-1 */
-
-            if (err == MP_OKAY)
-                err = mp_gcd(&tmp1, &tmp3, &tmp2);  /* tmp2 = gcd(q-1, e) */
-        } while (err == MP_OKAY && mp_cmp_d(&tmp2, 1) != 0);  /* e divdes q-1 */
-    }
-
-    if (err == MP_OKAY)
-        err = mp_init_multi(&key->n, &key->e, &key->d, &key->p, &key->q, NULL);
-
-    if (err == MP_OKAY)
-        err = mp_init_multi(&key->dP, &key->dQ, &key->u, NULL, NULL, NULL);
-
-    if (err == MP_OKAY)
-        err = mp_sub_d(&p, 1, &tmp2);  /* tmp2 = p-1 */
-
-    if (err == MP_OKAY)
-        err = mp_lcm(&tmp1, &tmp2, &tmp1);  /* tmp1 = lcm(p-1, q-1),last loop */
-
-    /* make key */
-    if (err == MP_OKAY)
-        err = mp_set_int(&key->e, e);  /* key->e = e */
-
-    if (err == MP_OKAY)                /* key->d = 1/e mod lcm(p-1, q-1) */
-        err = mp_invmod(&key->e, &tmp1, &key->d);
-
-    if (err == MP_OKAY)
-        err = mp_mul(&p, &q, &key->n);  /* key->n = pq */
-
-    if (err == MP_OKAY)
-        err = mp_sub_d(&p, 1, &tmp1);
-
-    if (err == MP_OKAY)
-        err = mp_sub_d(&q, 1, &tmp2);
-
-    if (err == MP_OKAY)
-        err = mp_mod(&key->d, &tmp1, &key->dP);
-
-    if (err == MP_OKAY)
-        err = mp_mod(&key->d, &tmp2, &key->dQ);
-
-    if (err == MP_OKAY)
-        err = mp_invmod(&q, &p, &key->u);
-
-    if (err == MP_OKAY)
-        err = mp_copy(&p, &key->p);
-
-    if (err == MP_OKAY)
-        err = mp_copy(&q, &key->q);
-
-    if (err == MP_OKAY)
-        key->type = RSA_PRIVATE; 
-
-    mp_clear(&tmp3);
-    mp_clear(&tmp2);
-    mp_clear(&tmp1);
-    mp_clear(&q);
-    mp_clear(&p);
-
-    if (err != MP_OKAY) {
-        FreeRSAKey(key);
-        return err;
-    }
-
-    return 0;
-}

+ 0 - 79
Pal/lib/crypto/wolfssl/rsa.h

@@ -1,79 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* rsa.h
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#ifndef CTAO_CRYPT_RSA_H
-#define CTAO_CRYPT_RSA_H
-
-#include <stdint.h>
-
-#ifndef word32
-typedef uint32_t word32;
-#endif
-#ifndef byte
-typedef uint8_t byte;
-#endif
-
-#include "integer.h"
-
-enum {
-    RSA_PUBLIC   = 0,
-    RSA_PRIVATE  = 1
-};
-
-/* RSA */
-typedef struct RSAKey {
-    mp_int n, e, d, p, q, dP, dQ, u;
-    int   type;                               /* public or private */
-} RSAKey;
-
-int InitRSAKey(RSAKey *key);
-int FreeRSAKey(RSAKey *key);
-
-int RSAPublicEncrypt(const byte *in, word32 inLen, byte *out,
-                     word32 outLen, RSAKey *key);
-int RSAPrivateDecryptInline(byte *in, word32 inLen, byte* *out,
-                             RSAKey *key);
-int RSAPrivateDecrypt(const byte *in, word32 inLen, byte *out,
-                      word32 outLen, RSAKey *key);
-int RSASSL_Sign(const byte *in, word32 inLen, byte *out,
-                word32 outLen, RSAKey *key);
-int RSASSL_VerifyInline(byte *in, word32 inLen, byte* *out,
-                        RSAKey *key);
-int RSASSL_Verify(const byte *in, word32 inLen, byte *out,
-                  word32 outLen, RSAKey *key);
-int RSAEncryptSize(RSAKey *key);
-
-int RSAPrivateKeyDecode(const byte *input, word32 *inOutIdx,
-                        RSAKey *key, word32 inSz);
-int RSAPublicKeyDecode(const byte *input, word32 *inOutIdx,
-                       RSAKey *key, word32 inSz);
-int RSAPublicKeyDecodeRaw(const byte *n, word32 nSz, const byte *e,
-                          word32 eSz, RSAKey *key);
-int RSAFlattenPublicKey(RSAKey *key, byte *e, word32 *eSz, byte *n,
-                        word32 *nSz);
-
-int MakeRSAKey(RSAKey *key, int size, long e);
-int RSAKeyToDer(RSAKey*, byte *output, word32 inLen);
-
-#endif /* CTAO_CRYPT_RSA_H */

+ 0 - 253
Pal/lib/crypto/wolfssl/sha256.c

@@ -1,253 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* sha256.c
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#include "crypto/wolfssl/sha256.h"
-#include "api.h"
-
-#define XMEMSET memset
-#define XMEMCPY memcpy
-
-#ifndef rotlFixed
-static inline word32 rotlFixed(word32 x, word32 y)
-{
-    return (x << y) | (x >> (sizeof(y) * 8 - y));
-}
-#endif /* rotlFixed */
-
-#ifndef rotrFixed
-static inline word32 rotrFixed(word32 x, word32 y)
-{
-    return (x >> y) | (x << (sizeof(y) * 8 - y));
-}
-#endif /* rotrFixed */
-
-#ifndef min
-static inline word32 min(word32 a, word32 b)
-{
-     return a > b ? b : a;
-}
-#endif /* min */
-
-static inline word32 ByteReverseWord32(word32 value)
-{
-    /* 6 instructions with rotate instruction, 8 without */
-    value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8);
-    return rotlFixed(value, 16U);
-}
-
-static inline void ByteReverseWords(word32 *out, const word32 *in,
-                                    word32 byteCount)
-{
-    word32 count = byteCount/(word32)sizeof(word32), i;
-
-    for (i = 0; i < count; i++)
-        out[i] = ByteReverseWord32(in[i]);
-}
-
-int SHA256Init(SHA256 *sha256)
-{
-    sha256->digest[0] = 0x6A09E667L;
-    sha256->digest[1] = 0xBB67AE85L;
-    sha256->digest[2] = 0x3C6EF372L;
-    sha256->digest[3] = 0xA54FF53AL;
-    sha256->digest[4] = 0x510E527FL;
-    sha256->digest[5] = 0x9B05688CL;
-    sha256->digest[6] = 0x1F83D9ABL;
-    sha256->digest[7] = 0x5BE0CD19L;
-
-    sha256->buffLen = 0;
-    sha256->loLen   = 0;
-    sha256->hiLen   = 0;
-
-    return 0;
-}
-
-#define XTRANSFORM(S,B)  Transform((S))
-
-static const word32 K[64] = {
-    0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
-    0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
-    0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,
-    0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
-    0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,
-    0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,
-    0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,
-    0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
-    0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,
-    0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,
-    0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,
-    0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
-    0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
-};
-
-#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
-#define Maj(x,y,z)      (((x | y) & z) | (x & y))
-#define S(x, n)         rotrFixed(x, n)
-#define R(x, n)         (((x)&0xFFFFFFFFU)>>(n))
-#define Sigma0(x)       (S(x, 2) ^ S(x, 13) ^ S(x, 22))
-#define Sigma1(x)       (S(x, 6) ^ S(x, 11) ^ S(x, 25))
-#define Gamma0(x)       (S(x, 7) ^ S(x, 18) ^ R(x, 3))
-#define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
-
-#define RND(a,b,c,d,e,f,g,h,i) \
-     t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
-     t1 = Sigma0(a) + Maj(a, b, c); \
-     d += t0; \
-     h  = t0 + t1;
-
-
-static int Transform(SHA256 *sha256)
-{
-    word32 S[8], t0, t1;
-    int i;
-
-    word32 W[64];
-
-    /* Copy context->state[] to working vars */
-    for (i = 0; i < 8; i++)
-        S[i] = sha256->digest[i];
-
-    for (i = 0; i < 16; i++)
-        W[i] = sha256->buffer[i];
-
-    for (i = 16; i < 64; i++)
-        W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
-
-    for (i = 0; i < 64; i += 8) {
-        RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0);
-        RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1);
-        RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2);
-        RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3);
-        RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
-        RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
-        RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
-        RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
-    }
-
-    /* Add the working vars back into digest state[] */
-    for (i = 0; i < 8; i++) {
-        sha256->digest[i] += S[i];
-    }
-
-    return 0;
-}
-
-static inline void AddLength(SHA256 *sha256, word32 len)
-{
-    word32 tmp = sha256->loLen;
-    if ( (sha256->loLen += len) < tmp)
-        sha256->hiLen++;                       /* carry low to high */
-}
-
-int SHA256Update(SHA256 *sha256, const byte *data, word32 len)
-{
-    /* do block size increments */
-    byte *local = (byte*)sha256->buffer;
-
-    while (len) {
-        word32 add = min(len, SHA256_BLOCK_SIZE - sha256->buffLen);
-        XMEMCPY(&local[sha256->buffLen], data, add);
-
-        sha256->buffLen += add;
-        data            += add;
-        len             -= add;
-
-        if (sha256->buffLen == SHA256_BLOCK_SIZE) {
-            int ret;
-
-            ByteReverseWords(sha256->buffer, sha256->buffer,
-                             SHA256_BLOCK_SIZE);
-
-            ret = XTRANSFORM(sha256, local);
-            if (ret != 0)
-                return ret;
-
-            AddLength(sha256, SHA256_BLOCK_SIZE);
-            sha256->buffLen = 0;
-        }
-    }
-
-    return 0;
-}
-
-int SHA256Final(SHA256 *sha256, byte *hash)
-{
-    byte *local = (byte*)sha256->buffer;
-    int ret;
-
-    AddLength(sha256, sha256->buffLen);  /* before adding pads */
-
-    local[sha256->buffLen++] = 0x80;     /* add 1 */
-
-    /* pad with zeros */
-    if (sha256->buffLen > SHA256_PAD_SIZE) {
-        XMEMSET(&local[sha256->buffLen], 0, SHA256_BLOCK_SIZE - sha256->buffLen);
-        sha256->buffLen += SHA256_BLOCK_SIZE - sha256->buffLen;
-
-        ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
-
-        ret = XTRANSFORM(sha256, local);
-        if (ret != 0)
-            return ret;
-
-        sha256->buffLen = 0;
-    }
-    XMEMSET(&local[sha256->buffLen], 0, SHA256_PAD_SIZE - sha256->buffLen);
-
-    /* put lengths in bits */
-    sha256->hiLen = (sha256->loLen >> (8*sizeof(sha256->loLen) - 3)) +
-                 (sha256->hiLen << 3);
-    sha256->loLen = sha256->loLen << 3;
-
-    /* store lengths */
-    ByteReverseWords(sha256->buffer, sha256->buffer, SHA256_BLOCK_SIZE);
-    /* ! length ordering dependent on digest endian type ! */
-    XMEMCPY(&local[SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));
-    XMEMCPY(&local[SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
-            sizeof(word32));
-
-    ret = XTRANSFORM(sha256, local);
-    if (ret != 0)
-        return ret;
-
-    ByteReverseWords(sha256->digest, sha256->digest, SHA256_DIGEST_SIZE);
-    XMEMCPY(hash, sha256->digest, SHA256_DIGEST_SIZE);
-
-    return SHA256Init(sha256);  /* reset state */
-}
-
-int SHA256Hash(const byte * data, word32 len, byte * hash)
-{
-    int ret = 0;
-    SHA256 sha256;
-
-    if ((ret = SHA256Init(&sha256)) != 0)
-        return ret;
-    if ((ret = SHA256Update(&sha256, data, len)) != 0)
-        return ret;
-    else if ((ret = SHA256Final(&sha256, hash)) != 0)
-        return ret;
-
-    return 0;
-}

+ 0 - 51
Pal/lib/crypto/wolfssl/sha256.h

@@ -1,51 +0,0 @@
-/* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
-/* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
-
-/* sha256.h
- *
- * Copyright (C) 2006-2014 wolfSSL Inc.
- *
- * This file is part of CyaSSL.
- *
- * CyaSSL 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.
- *
- * CyaSSL 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
- */
-
-#ifndef CTAO_CRYPT_SHA256_H
-#define CTAO_CRYPT_SHA256_H
-
-#include "crypto/wolfssl/integer.h"
-
-/* in bytes */
-enum {
-    SHA256_BLOCK_SIZE   = 64,
-    SHA256_DIGEST_SIZE  = 32,
-    SHA256_PAD_SIZE     = 56
-};
-
-/* SHA256 digest */
-typedef struct SHA256 {
-    word32  buffLen;   /* in bytes          */
-    word32  loLen;     /* length in bytes   */
-    word32  hiLen;     /* length in bytes   */
-    word32  digest[SHA256_DIGEST_SIZE / sizeof(word32)];
-    word32  buffer[SHA256_BLOCK_SIZE  / sizeof(word32)];
-} SHA256;
-
-int SHA256Init(SHA256 *);
-int SHA256Update(SHA256 *, const byte *, word32);
-int SHA256Final(SHA256 *, byte *);
-int SHA256Hash(const byte *, word32, byte *);
-
-#endif /* CTAO_CRYPT_SHA256_H */

+ 1 - 0
Pal/lib/slabmgr.h

@@ -85,6 +85,7 @@ typedef struct __attribute__((packed)) slab_obj {
 #define AREA_PADDING 12
 
 DEFINE_LIST(slab_area);
+
 typedef struct __attribute__((packed)) slab_area {
     LIST_TYPE(slab_area) __list;
     unsigned int size;