changeset 16:09ab3354aa21 libtomcrypt

propagate of e8bea23df30f9f46c647d06db3b223427b4e3604 and b0b6b4a8843b94d9f049cb5ffe0b1ae91ec1bf8b from branch 'au.asn.ucc.matt.ltc-orig' to 'au.asn.ucc.matt.ltc-db'
author Matt Johnston <matt@ucc.asn.au>
date Tue, 15 Jun 2004 14:27:14 +0000
parents 6362d3854bb4 (diff) 059ec00f32a1 (current diff)
children 1a066933c5e1
files crypt.c crypt_cipher_descriptor.c crypt_hash_descriptor.c crypt_prng_descriptor.c demos/small.c makefile makefile.msvc mycrypt.h mycrypt_argchk.h mycrypt_custom.h mycrypt_misc.h sha224.c sha256.c sha384.c sha512.c tiger.c whirl.c yarrow.c
diffstat 84 files changed, 3992 insertions(+), 3336 deletions(-) [+]
line wrap: on
line diff
--- a/aes.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/aes.c	Tue Jun 15 14:27:14 2004 +0000
@@ -30,16 +30,20 @@
 
 #ifdef RIJNDAEL
 
+#ifndef ENCRYPT_ONLY 
+
+#define SETUP    rijndael_setup
+#define ECB_ENC  rijndael_ecb_encrypt
+#define ECB_DEC  rijndael_ecb_decrypt
+#define ECB_TEST rijndael_test
+#define ECB_KS   rijndael_keysize
+
 const struct _cipher_descriptor rijndael_desc =
 {
     "rijndael",
     6,
     16, 32, 16, 10,
-    &rijndael_setup,
-    &rijndael_ecb_encrypt,
-    &rijndael_ecb_decrypt,
-    &rijndael_test,
-    &rijndael_keysize
+    SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
 };
 
 const struct _cipher_descriptor aes_desc =
@@ -47,21 +51,63 @@
     "aes",
     6,
     16, 32, 16, 10,
-    &rijndael_setup,
-    &rijndael_ecb_encrypt,
-    &rijndael_ecb_decrypt,
-    &rijndael_test,
-    &rijndael_keysize
+    SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
 };
 
+#else
+
+#define SETUP    rijndael_enc_setup
+#define ECB_ENC  rijndael_enc_ecb_encrypt
+#define ECB_KS   rijndael_enc_keysize
+
+const struct _cipher_descriptor rijndael_enc_desc =
+{
+    "rijndael",
+    6,
+    16, 32, 16, 10,
+    SETUP, ECB_ENC, NULL, NULL, ECB_KS
+};
+
+const struct _cipher_descriptor aes_enc_desc =
+{
+    "aes",
+    6,
+    16, 32, 16, 10,
+    SETUP, ECB_ENC, NULL, NULL, ECB_KS
+};
+
+#endif
+
 #include "aes_tab.c"
 
-int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
+static ulong32 setup_mix(ulong32 temp)
+{
+   return (Te4_3[byte(temp, 2)]) ^
+          (Te4_2[byte(temp, 1)]) ^
+          (Te4_1[byte(temp, 0)]) ^
+          (Te4_0[byte(temp, 3)]);
+}
+
+#ifndef ENCRYPT_ONLY
+
+static ulong32 setup_mix2(ulong32 temp)
+{
+   return Td0(255 & Te4[byte(temp, 3)]) ^
+          Td1(255 & Te4[byte(temp, 2)]) ^
+          Td2(255 & Te4[byte(temp, 1)]) ^
+          Td3(255 & Te4[byte(temp, 0)]);
+}
+
+#endif
+
+int SETUP(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
 {
     int i, j;
-    ulong32 temp, *rk, *rrk;
-    
-    _ARGCHK(key != NULL);
+    ulong32 temp, *rk;
+#ifndef ENCRYPT_ONLY
+    ulong32 *rrk;
+#endif    
+    _ARGCHK(key  != NULL);
     _ARGCHK(skey != NULL);
     
     if (keylen != 16 && keylen != 24 && keylen != 32) {
@@ -85,12 +131,7 @@
         j = 44;
         for (;;) {
             temp  = rk[3];
-            rk[4] = rk[0] ^
-                (Te4_3[byte(temp, 2)]) ^
-                (Te4_2[byte(temp, 1)]) ^
-                (Te4_1[byte(temp, 0)]) ^
-                (Te4_0[byte(temp, 3)]) ^
-                rcon[i];
+            rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
             rk[5] = rk[1] ^ rk[4];
             rk[6] = rk[2] ^ rk[5];
             rk[7] = rk[3] ^ rk[6];
@@ -109,12 +150,7 @@
         #else
             temp = rk[5];
         #endif
-            rk[ 6] = rk[ 0] ^
-                (Te4_3[byte(temp, 2)]) ^
-                (Te4_2[byte(temp, 1)]) ^
-                (Te4_1[byte(temp, 0)]) ^
-                (Te4_0[byte(temp, 3)]) ^
-                rcon[i];
+            rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
             rk[ 7] = rk[ 1] ^ rk[ 6];
             rk[ 8] = rk[ 2] ^ rk[ 7];
             rk[ 9] = rk[ 3] ^ rk[ 8];
@@ -137,12 +173,7 @@
         #else
             temp = rk[7];
         #endif
-            rk[ 8] = rk[ 0] ^
-                (Te4_3[byte(temp, 2)]) ^
-                (Te4_2[byte(temp, 1)]) ^
-                (Te4_1[byte(temp, 0)]) ^
-                (Te4_0[byte(temp, 3)]) ^
-                rcon[i];
+            rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
             rk[ 9] = rk[ 1] ^ rk[ 8];
             rk[10] = rk[ 2] ^ rk[ 9];
             rk[11] = rk[ 3] ^ rk[10];
@@ -150,11 +181,7 @@
                 break;
             }
             temp = rk[11];
-            rk[12] = rk[ 4] ^
-                (Te4_3[byte(temp, 3)]) ^
-                (Te4_2[byte(temp, 2)]) ^
-                (Te4_1[byte(temp, 1)]) ^
-                (Te4_0[byte(temp, 0)]);
+            rk[12] = rk[ 4] ^ setup_mix(ROR(temp, 8));
             rk[13] = rk[ 5] ^ rk[12];
             rk[14] = rk[ 6] ^ rk[13];
             rk[15] = rk[ 7] ^ rk[14];
@@ -164,7 +191,8 @@
        /* this can't happen */
        j = 4;
     }
-    
+
+#ifndef ENCRYPT_ONLY    
     /* setup the inverse key now */
     rk   = skey->rijndael.dK;
     rrk  = skey->rijndael.eK + j - 4; 
@@ -182,29 +210,13 @@
         rk  += 4;
     #ifdef SMALL_CODE        
         temp = rrk[0];
-        rk[0] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[0] = setup_mix2(temp);
         temp = rrk[1];
-        rk[1] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[1] = setup_mix2(temp);
         temp = rrk[2];
-        rk[2] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[2] = setup_mix2(temp);
         temp = rrk[3];
-        rk[3] =
-            Td0(255 & Te4[byte(temp, 3)]) ^
-            Td1(255 & Te4[byte(temp, 2)]) ^
-            Td2(255 & Te4[byte(temp, 1)]) ^
-            Td3(255 & Te4[byte(temp, 0)]);
+        rk[3] = setup_mix2(temp);
      #else
         temp = rrk[0];
         rk[0] =
@@ -241,6 +253,7 @@
     *rk++ = *rrk++;
     *rk++ = *rrk++;
     *rk   = *rrk;
+#endif /* ENCRYPT_ONLY */
 
     return CRYPT_OK;   
 }
@@ -248,7 +261,7 @@
 #ifdef CLEAN_STACK
 static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
 #else
-void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
+void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
 #endif
 {
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@@ -270,6 +283,44 @@
     LOAD32H(s2, pt  +  8); s2 ^= rk[2];
     LOAD32H(s3, pt  + 12); s3 ^= rk[3];
 
+
+#ifdef SMALL_CODE
+
+    for (r = 0; ; r++) {
+        rk += 4;
+        t0 =
+            Te0(byte(s0, 3)) ^
+            Te1(byte(s1, 2)) ^
+            Te2(byte(s2, 1)) ^
+            Te3(byte(s3, 0)) ^
+            rk[0];
+        t1 =
+            Te0(byte(s1, 3)) ^
+            Te1(byte(s2, 2)) ^
+            Te2(byte(s3, 1)) ^
+            Te3(byte(s0, 0)) ^
+            rk[1];
+        t2 =
+            Te0(byte(s2, 3)) ^
+            Te1(byte(s3, 2)) ^
+            Te2(byte(s0, 1)) ^
+            Te3(byte(s1, 0)) ^
+            rk[2];
+        t3 =
+            Te0(byte(s3, 3)) ^
+            Te1(byte(s0, 2)) ^
+            Te2(byte(s1, 1)) ^
+            Te3(byte(s2, 0)) ^
+            rk[3];
+        if (r == Nr-2) { 
+           break;
+        }
+        s0 = t0; s1 = t1; s2 = t2; s3 = t3;
+    }
+    rk += 4;
+
+#else
+
     /*
      * Nr - 1 full rounds:
      */
@@ -330,52 +381,57 @@
             Te3(byte(t2, 0)) ^
             rk[3];
     }
+
+#endif
+
     /*
      * apply last round and
      * map cipher state to byte array block:
      */
     s0 =
-        (Te4_3[(t0 >> 24)       ]) ^
-        (Te4_2[(t1 >> 16) & 0xff]) ^
-        (Te4_1[(t2 >>  8) & 0xff]) ^
-        (Te4_0[(t3      ) & 0xff]) ^
+        (Te4_3[byte(t0, 3)]) ^
+        (Te4_2[byte(t1, 2)]) ^
+        (Te4_1[byte(t2, 1)]) ^
+        (Te4_0[byte(t3, 0)]) ^
         rk[0];
     STORE32H(s0, ct);
     s1 =
-        (Te4_3[(t1 >> 24)       ]) ^
-        (Te4_2[(t2 >> 16) & 0xff]) ^
-        (Te4_1[(t3 >>  8) & 0xff]) ^
-        (Te4_0[(t0      ) & 0xff]) ^
+        (Te4_3[byte(t1, 3)]) ^
+        (Te4_2[byte(t2, 2)]) ^
+        (Te4_1[byte(t3, 1)]) ^
+        (Te4_0[byte(t0, 0)]) ^
         rk[1];
     STORE32H(s1, ct+4);
     s2 =
-        (Te4_3[(t2 >> 24)       ]) ^
-        (Te4_2[(t3 >> 16) & 0xff]) ^
-        (Te4_1[(t0 >>  8) & 0xff]) ^
-        (Te4_0[(t1      ) & 0xff]) ^
+        (Te4_3[byte(t2, 3)]) ^
+        (Te4_2[byte(t3, 2)]) ^
+        (Te4_1[byte(t0, 1)]) ^
+        (Te4_0[byte(t1, 0)]) ^
         rk[2];
     STORE32H(s2, ct+8);
     s3 =
-        (Te4_3[(t3 >> 24)       ]) ^
-        (Te4_2[(t0 >> 16) & 0xff]) ^
-        (Te4_1[(t1 >>  8) & 0xff]) ^
-        (Te4_0[(t2      ) & 0xff]) ^ 
+        (Te4_3[byte(t3, 3)]) ^
+        (Te4_2[byte(t0, 2)]) ^
+        (Te4_1[byte(t1, 1)]) ^
+        (Te4_0[byte(t2, 0)]) ^ 
         rk[3];
     STORE32H(s3, ct+12);
 }
 
 #ifdef CLEAN_STACK
-void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
+void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) 
 {
    _rijndael_ecb_encrypt(pt, ct, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
 }
 #endif
 
+#ifndef ENCRYPT_ONLY 
+
 #ifdef CLEAN_STACK
 static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
 #else
-void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
+void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
 #endif
 {
     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@@ -397,6 +453,42 @@
     LOAD32H(s2, ct  +  8); s2 ^= rk[2];
     LOAD32H(s3, ct  + 12); s3 ^= rk[3];
 
+#ifdef SMALL_CODE
+    for (r = 0; ; r++) {
+        rk += 4;
+        t0 =
+            Td0(byte(s0, 3)) ^
+            Td1(byte(s3, 2)) ^
+            Td2(byte(s2, 1)) ^
+            Td3(byte(s1, 0)) ^
+            rk[0];
+        t1 =
+            Td0(byte(s1, 3)) ^
+            Td1(byte(s0, 2)) ^
+            Td2(byte(s3, 1)) ^
+            Td3(byte(s2, 0)) ^
+            rk[1];
+        t2 =
+            Td0(byte(s2, 3)) ^
+            Td1(byte(s1, 2)) ^
+            Td2(byte(s0, 1)) ^
+            Td3(byte(s3, 0)) ^
+            rk[2];
+        t3 =
+            Td0(byte(s3, 3)) ^
+            Td1(byte(s2, 2)) ^
+            Td2(byte(s1, 1)) ^
+            Td3(byte(s0, 0)) ^
+            rk[3];
+        if (r == Nr-2) {
+           break; 
+        }
+        s0 = t0; s1 = t1; s2 = t2; s3 = t3;
+    }
+    rk += 4;
+
+#else       
+
     /*
      * Nr - 1 full rounds:
      */
@@ -459,51 +551,52 @@
             Td3(byte(t0, 0)) ^
             rk[3];
     }
+#endif
 
     /*
      * apply last round and
      * map cipher state to byte array block:
      */
     s0 =
-        (Td4[(t0 >> 24)       ] & 0xff000000) ^
-        (Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t2 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t1      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t0, 3)] & 0xff000000) ^
+        (Td4[byte(t3, 2)] & 0x00ff0000) ^
+        (Td4[byte(t2, 1)] & 0x0000ff00) ^
+        (Td4[byte(t1, 0)] & 0x000000ff) ^
         rk[0];
     STORE32H(s0, pt);
     s1 =
-        (Td4[(t1 >> 24)       ] & 0xff000000) ^
-        (Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t3 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t2      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t1, 3)] & 0xff000000) ^
+        (Td4[byte(t0, 2)] & 0x00ff0000) ^
+        (Td4[byte(t3, 1)] & 0x0000ff00) ^
+        (Td4[byte(t2, 0)] & 0x000000ff) ^
         rk[1];
     STORE32H(s1, pt+4);
     s2 =
-        (Td4[(t2 >> 24)       ] & 0xff000000) ^
-        (Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t0 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t3      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t2, 3)] & 0xff000000) ^
+        (Td4[byte(t1, 2)] & 0x00ff0000) ^
+        (Td4[byte(t0, 1)] & 0x0000ff00) ^
+        (Td4[byte(t3, 0)] & 0x000000ff) ^
         rk[2];
     STORE32H(s2, pt+8);
     s3 =
-        (Td4[(t3 >> 24)       ] & 0xff000000) ^
-        (Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
-        (Td4[(t1 >>  8) & 0xff] & 0x0000ff00) ^
-        (Td4[(t0      ) & 0xff] & 0x000000ff) ^
+        (Td4[byte(t3, 3)] & 0xff000000) ^
+        (Td4[byte(t2, 2)] & 0x00ff0000) ^
+        (Td4[byte(t1, 1)] & 0x0000ff00) ^
+        (Td4[byte(t0, 0)] & 0x000000ff) ^
         rk[3];
     STORE32H(s3, pt+12);
 }
 
 
 #ifdef CLEAN_STACK
-void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
+void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) 
 {
    _rijndael_ecb_decrypt(ct, pt, skey);
    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
 }
 #endif
 
-int rijndael_test(void)
+int ECB_TEST(void)
 {
  #ifndef LTC_TEST
     return CRYPT_NOP;
@@ -584,7 +677,9 @@
  #endif
 }
 
-int rijndael_keysize(int *desired_keysize)
+#endif /* ENCRYPT_ONLY */
+
+int ECB_KS(int *desired_keysize)
 {
    _ARGCHK(desired_keysize != NULL);
 
--- a/aes_tab.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/aes_tab.c	Tue Jun 15 14:27:14 2004 +0000
@@ -157,6 +157,8 @@
     0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL,
 };
 
+#ifndef ENCRYPT_ONLY
+
 static const ulong32 TD0[256] = {
     0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
     0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
@@ -291,6 +293,8 @@
     0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL,
 };
 
+#endif /* ENCRYPT_ONLY */
+
 #ifdef SMALL_CODE
 
 #define Te0(x) TE0[x]
@@ -660,6 +664,8 @@
 0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL
 };
 
+#ifndef ENCRYPT_ONLY
+
 static const ulong32 TD1[256] = {
     0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
     0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
@@ -999,6 +1005,8 @@
 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL
 };
 
+#endif /* ENCRYPT_ONLY */
+
 #endif /* SMALL CODE */
 
 static const ulong32 rcon[] = {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base64_decode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,76 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+/* compliant base64 code donated by Wayne Scott ([email protected]) */
+#include "mycrypt.h"
+
+#ifdef BASE64
+
+static const unsigned char map[256] = {
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,
+ 52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255,
+255, 254, 255, 255, 255,   0,   1,   2,   3,   4,   5,   6,
+  7,   8,   9,  10,  11,  12,  13,  14,  15,  16,  17,  18,
+ 19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,
+255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,
+ 37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,  48,
+ 49,  50,  51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
+255, 255, 255, 255 };
+
+int base64_decode(const unsigned char *in,  unsigned long len, 
+                        unsigned char *out, unsigned long *outlen)
+{
+   unsigned long t, x, y, z;
+   unsigned char c;
+   int           g;
+
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+
+   g = 3;
+   for (x = y = z = t = 0; x < len; x++) {
+       c = map[in[x]&0xFF];
+       if (c == 255) continue;
+       if (c == 254) { c = 0; g--; }
+       t = (t<<6)|c;
+       if (++y == 4) {
+          if (z + g > *outlen) { 
+             return CRYPT_BUFFER_OVERFLOW; 
+          }
+          out[z++] = (unsigned char)((t>>16)&255);
+          if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
+          if (g > 2) out[z++] = (unsigned char)(t&255);
+          y = t = 0;
+       }
+   }
+   if (y != 0) {
+       return CRYPT_INVALID_PACKET;
+   }
+   *outlen = z;
+   return CRYPT_OK;
+}
+
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base64_encode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,63 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+/* compliant base64 code donated by Wayne Scott ([email protected]) */
+#include "mycrypt.h"
+
+#ifdef BASE64
+
+static const char *codes = 
+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+int base64_encode(const unsigned char *in,  unsigned long len, 
+                        unsigned char *out, unsigned long *outlen)
+{
+   unsigned long i, len2, leven;
+   unsigned char *p;
+
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+
+   /* valid output size ? */
+   len2 = 4 * ((len + 2) / 3);
+   if (*outlen < len2 + 1) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   p = out;
+   leven = 3*(len / 3);
+   for (i = 0; i < leven; i += 3) {
+       *p++ = codes[(in[0] >> 2) & 0x3F];
+       *p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
+       *p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
+       *p++ = codes[in[2] & 0x3F];
+       in += 3;
+   }
+   /* Pad it if necessary...  */
+   if (i < len) {
+       unsigned a = in[0];
+       unsigned b = (i+1 < len) ? in[1] : 0;
+
+       *p++ = codes[(a >> 2) & 0x3F];
+       *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
+       *p++ = (i+1 < len) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
+       *p++ = '=';
+   }
+
+   /* append a NULL byte */
+   *p = '\0';
+
+   /* return ok */
+   *outlen = p - out;
+   return CRYPT_OK;
+}
+
+#endif
+
--- a/cbc_decrypt.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/cbc_decrypt.c	Tue Jun 15 14:27:14 2004 +0000
@@ -25,14 +25,15 @@
    if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
        return err;
    }
-   cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
-   
+   _ARGCHK(cipher_descriptor[cbc->cipher].ecb_decrypt != NULL);
+      
    /* is blocklen valid? */
    if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) {
       return CRYPT_INVALID_ARG;
    } 
 
-   /* xor IV against the plaintext of the previous step */
+   /* decrypt and xor IV against the plaintext of the previous step */
+   cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
    for (x = 0; x < cbc->blocklen; x++) { 
        /* copy CT in case ct == pt */
        tmp2[x] = ct[x]; 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cbc_getiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CBC
+
+int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(cbc != NULL);
+   if ((unsigned long)cbc->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, cbc->IV, cbc->blocklen);
+   *len = cbc->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cbc_setiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,28 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CBC
+
+int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(cbc != NULL);
+   if (len != (unsigned long)cbc->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+   memcpy(cbc->IV, IV, len);
+   return CRYPT_OK;
+}
+
+#endif 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cfb_getiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CFB
+
+int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(cfb != NULL);
+   if ((unsigned long)cfb->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, cfb->IV, cfb->blocklen);
+   *len = cfb->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cfb_setiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,39 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CFB
+
+int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
+{
+   int err;
+   
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(cfb != NULL);
+
+   if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
+       return err;
+   }
+   
+   if (len != (unsigned long)cfb->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+      
+   /* force next block */
+   cfb->padlen = 0;
+   cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
+
+   return CRYPT_OK;
+}
+
+#endif 
+
--- a/changes	Wed Jun 02 08:31:25 2004 +0000
+++ b/changes	Tue Jun 15 14:27:14 2004 +0000
@@ -1,3 +1,28 @@
+May 30th, 2004
+v0.96  -- Removed GF and Keyring code
+       -- Extended OAEP decoder to distinguish better [and use a more uniform API]
+       -- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments)
+       -- rsa_exptmod() now pads with leading zeroes as per I2OSP.
+       -- added error checking to yarrow code
+       -- Mike Frysinger pointed out that tommath.h from this distro will overwrite tommath.h
+          from libtommath.  I changed this to ltc_tommath.h to avoid any such problems.
+       -- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly
+       -- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space.
+       -- modded Yarrow to try and use refactored AES code and added WHIRLPOOL support (d'oh) ;-)
+       -- updated ECB, OCB and CBC decrypt functions to detect when "encrypt only" descriptor is used.
+       -- replaced old RSA code with new code that uses PKCS #1 v2.0 padding
+       -- replaced old test harness with new over-engineer'ed one in /demos/test/
+       -- updated cbc/cfb/ofb/ctr code with setiv/getiv functions to change/read the IV without re-keying.
+       -- Added PKCS #1 v1.5 RSA encryption and signature padding routines
+       -- Added DER OID's to most hash descriptors (as many as I could find) 
+       -- modded rsa_exptmod() to use timing-resilient tim_exptmod() when doing private key operations 
+          added #define RSA_TIMING which can turn on/off this feature.
+       -- No more config.pl so please just read mycrypt_custom.h for build-time tweaks
+       -- Small update to rand_prime()
+       -- Updated sha1, md5 and sha256 so they are smaller when SMALL_CODE is defined.  If you want speed though,
+          you're going to have to undefine SMALL_CODE ;-)
+       -- Worked over AES so that it's even smaller now [in both modes].
+       
 May 12th, 2004
 v0.95  -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact
           the transforms are circulant.  AES dropped 5KB and WHIRLPOOL dropped 13KB
--- a/crypt.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/crypt.c	Tue Jun 15 14:27:14 2004 +0000
@@ -122,6 +122,9 @@
 #if defined(RIPEMD160)
    "   RIPEMD160\n"
 #endif
+#if defined(WHIRLPOOL)
+   "   WHIRLPOOL\n"
+#endif
 
     "\nBlock Chaining Modes:\n"
 #if defined(CFB)
@@ -153,7 +156,11 @@
 
     "\nPK Algs:\n"
 #if defined(MRSA)
-    "   RSA\n"
+    "   RSA"
+#if defined(RSA_TIMING)
+    " + RSA_TIMING "
+#endif
+    "\n"
 #endif
 #if defined(MDH)
     "   DH\n"
@@ -164,9 +171,6 @@
 #if defined(MDSA)
     "   DSA\n"
 #endif
-#if defined(KR)
-    "   KR\n"
-#endif
 
     "\nCompiler:\n"
 #if defined(WIN32)
@@ -189,9 +193,6 @@
 #endif
 
     "\nVarious others: "
-#if defined(GF)
-    " GF "
-#endif
 #if defined(BASE64)
     " BASE64 "
 #endif
@@ -225,6 +226,15 @@
 #if defined(PKCS_5)
     " PKCS#5 "
 #endif
+#if defined(SMALL_CODE)
+    " SMALL_CODE "
+#endif
+#if defined(NO_FILE)
+    " NO_FILE "
+#endif
+#if defined(LTC_TEST)
+    " LTC_TEST "
+#endif
     "\n"
     "\n\n\n"
     ;
--- a/crypt.tex	Wed Jun 02 08:31:25 2004 +0000
+++ b/crypt.tex	Tue Jun 15 14:27:14 2004 +0000
@@ -47,7 +47,7 @@
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \begin{document}
-\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.95}
+\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.96}
 \author{Tom St Denis \\
 \\
 [email protected] \\
@@ -103,7 +103,8 @@
 
 The library also serves well as a toolkit for applications where they don't need to be OpenPGP, PKCS, etc. compliant.
 Included are fully operational public key routines for encryption, decryption, signature generation and verification.  
-These routines are fully portable but are not conformant to any known set of standards.  They are all based on established
+These routines are fully portable but are not conformant to any known set of standards\footnote{With the exception of 
+the RSA code which is based on the PKCS \#1 standards.}.  They are all based on established
 number theory and cryptography.  
 
 \subsection{What the library IS NOT for?}
@@ -241,19 +242,20 @@
 if it failed.  Certain functions that return int will return $-1$ to indicate an error.  These functions will be explicitly
 commented upon.  When a function does return a CRYPT error code it can be translated into a string with
 
+\index{error\_to\_string()}
 \begin{verbatim}
-const char *error_to_string(int errno);
+const char *error_to_string(int err);
 \end{verbatim}
 
 An example of handling an error is:
 \begin{verbatim}
 void somefunc(void)
 {
-   int errno;
+   int err;
    
    /* call a cryptographic function */
-   if ((errno = some_crypto_function(...)) != CRYPT_OK) {
-      printf("A crypto error occured, %s\n", error_to_string(errno));
+   if ((err = some_crypto_function(...)) != CRYPT_OK) {
+      printf("A crypto error occured, %s\n", error_to_string(err));
       /* perform error handling */
    }
    /* continue on if no error occured */
@@ -320,14 +322,14 @@
     rsa_key key;
     unsigned char buffer[1024];
     unsigned long x;
-    int errno;
+    int err;
 
     /* ... Make up the RSA key somehow */
 
     /* lets export the key, set x to the size of the output buffer */
     x = sizeof(buffer);
-    if ((errno = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) {
-       printf("Export error: %s\n", error_to_string(errno));
+    if ((err = rsa_export(buffer, &x, PK_PUBLIC, &key)) != CRYPT_OK) {
+       printf("Export error: %s\n", error_to_string(err));
        return -1;
     }
     
@@ -411,12 +413,12 @@
 #include <mycrypt.h>
 int main(void)
 {
-   int keysize, errno;
+   int keysize, err;
 
    /* now given a 20 byte key what keysize does Twofish want to use? */
    keysize = 20;
-   if ((errno = twofish_keysize(&keysize)) != CRYPT_OK) {
-      printf("Error getting key size: %s\n", error_to_string(errno));
+   if ((err = twofish_keysize(&keysize)) != CRYPT_OK) {
+      printf("Error getting key size: %s\n", error_to_string(err));
       return -1;
    }
    printf("Twofish suggested a key size of %d\n", keysize);
@@ -434,22 +436,30 @@
 { 
    unsigned char pt[8], ct[8], key[8];
    symmetric_key skey;
-   int errno;
+   int err;
 
    /* ... key is loaded appropriately in ``key'' ... */
    /* ... load a block of plaintext in ``pt'' ... */
 
    /* schedule the key */
-   if ((errno = blowfish_setup(key, 8, 0, &skey)) != CRYPT_OK) {
-      printf("Setup error: %s\n", error_to_string(errno));
+   if ((err = blowfish_setup(key,     /* the key we will use */
+                               8,     /* key is 8 bytes (64-bits) long */
+                               0,     /* 0 == use default # of rounds */
+                           &skey)     /* where to put the scheduled key */
+       ) != CRYPT_OK) {
+      printf("Setup error: %s\n", error_to_string(err));
       return -1;
    }
 
    /* encrypt the block */
-   blowfish_ecb_encrypt(pt, ct, &skey);
+   blowfish_ecb_encrypt(pt,             /* encrypt this 8-byte array */
+                        ct,             /* store encrypted data here */ 
+                        &skey);         /* our previously scheduled key */
 
    /* decrypt the block */
-   blowfish_ecb_decrypt(ct, pt, &skey);
+   blowfish_ecb_decrypt(ct,             /* decrypt this 8-byte array */
+                        pt,             /* store decrypted data here */
+                        &skey);         /* our previously scheduled key */
 
    return 0;
 }
@@ -501,6 +511,7 @@
 
 As of this release the current cipher\_descriptors elements are
 
+\index{Cipher descriptor table}
 \begin{small}
 \begin{center}
 \begin{tabular}{|c|c|c|c|c|c|}
@@ -516,6 +527,7 @@
      \hline Safer K128  & safer\_k128\_desc & 8 & 16 & 6 $\ldots$ 13 \\
      \hline Safer SK128 & safer\_sk128\_desc & 8 & 16 & 6 $\ldots$ 13 \\
      \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
+                & aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
      \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\
      \hline DES & des\_desc & 8 & 7 & 16 \\
      \hline 3DES (EDE mode) & des3\_desc & 8 & 21 & 16 \\
@@ -528,14 +540,32 @@
 \end{small}
 
 \subsection{Notes}
+\begin{small}
+\begin{enumerate}
+\item
+For AES (also known as Rijndael) there are four descriptors which complicate issues a little.  The descriptors 
+rijndael\_desc and rijndael\_enc\_desc provide the cipher named ``rijndael''.  The descriptors aes\_desc and 
+aes\_enc\_desc provide the cipher name ``aes''.  Functionally both ``rijndael'' and ``aes'' are the same cipher.  The
+only difference is when you call find\_cipher() you have to pass the correct name.  The cipher descriptors with ``enc'' 
+in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine
+and tables.  The decryption and self--test function pointers of both ``encrypt only'' descriptors are set to \textbf{NULL} and 
+should not be called.
+
+The ``encrypt only'' descriptors are useful for applications that only use the encryption function of the cipher.  Algorithms such
+as EAX, PMAC and OMAC only require the encryption function.  So far this ``encrypt only'' functionality has only been implemented for
+Rijndael as it makes the most sense for this cipher.
+
+\item
 For the 64-bit SAFER famliy of ciphers (e.g K64, SK64, K128, SK128) the ecb\_encrypt() and ecb\_decrypt()
 functions are the same.  So if you want to use those functions directly just call safer\_ecb\_encrypt()
 or safer\_ecb\_decrypt() respectively.
 
+\item
 Note that for ``DES'' and ``3DES'' they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in
 fact used for the purposes of encryption.  My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24
 byte string from the real 7/21 byte key.
 
+\item
 Note that ``Twofish'' has additional configuration options that take place at build time.  These options are found in
 the file ``mycrypt\_cfg.h''.  The first option is ``TWOFISH\_SMALL'' which when defined will force the Twofish code
 to not pre-compute the Twofish ``$g(X)$'' function as a set of four $8 \times 32$ s-boxes.  This means that a scheduled
@@ -545,6 +575,7 @@
 speed increase is useful when ``TWOFISH\_SMALL'' is defined since the s-boxes and MDS multiply form the heart of the
 Twofish round function.
 
+\index{Twofish build options}
 \begin{small}
 \begin{center}
 \begin{tabular}{|l|l|l|}
@@ -558,7 +589,11 @@
 \end{center}
 \end{small}
 
+\end{enumerate}
+\end{small}
+
 To work with the cipher\_descriptor array there is a function:
+\index{find\_cipher()}
 \begin{verbatim}
 int find_cipher(char *name)
 \end{verbatim}
@@ -571,7 +606,7 @@
 {
    unsigned char key[8];
    symmetric_key skey;
-   int errno;
+   int err;
 
    /* you must register a cipher before you use it */
    if (register_cipher(&blowfish_desc)) == -1) {
@@ -580,8 +615,8 @@
    }
 
    /* generic call to function (assuming the key in key[] was already setup) */
-   if ((errno = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != CRYPT_OK) {
-      printf("Error setting up Blowfish: %s\n", error_to_string(errno));
+   if ((err = cipher_descriptor[find_cipher("blowfish")].setup(key, 8, 0, &skey)) != CRYPT_OK) {
+      printf("Error setting up Blowfish: %s\n", error_to_string(err));
       return -1;
    }
 
@@ -592,12 +627,14 @@
 
 A good safety would be to check the return value of ``find\_cipher()'' before accessing the desired function.  In order
 to use a cipher with the descriptor table you must register it first using:
+\index{register\_cipher()}
 \begin{verbatim}
 int register_cipher(const struct _cipher_descriptor *cipher);
 \end{verbatim}
 Which accepts a pointer to a descriptor and returns the index into the global descriptor table.  If an error occurs such
 as there is no more room (it can have 32 ciphers at most) it will return {\bf{-1}}.  If you try to add the same cipher more
 than once it will just return the index of the first copy.  To remove a cipher call:
+\index{unregister\_cipher()}
 \begin{verbatim}
 int unregister_cipher(const struct _cipher_descriptor *cipher);
 \end{verbatim}
@@ -607,7 +644,7 @@
 #include <mycrypt.h>
 int main(void)
 {
-   int errno;
+   int err;
    
    /* register the cipher */
    if (register_cipher(&rijndael_desc) == -1) {
@@ -618,8 +655,8 @@
    /* use Rijndael */
 
    /* remove it */
-   if ((errno = unregister_cipher(&rijndael_desc)) != CRYPT_OK) {
-      printf("Error removing Rijndael: %s\n", error_to_string(errno));
+   if ((err = unregister_cipher(&rijndael_desc)) != CRYPT_OK) {
+      printf("Error removing Rijndael: %s\n", error_to_string(err));
       return -1;
    }
 
@@ -636,6 +673,7 @@
 $P$ under the key $k$ as $E_k(P)$.  In some modes there exists an initial vector denoted as $C_{-1}$.
 
 \subsubsection{ECB Mode}
+\index{ECB mode}
 ECB or Electronic Codebook Mode is the simplest method to use.  It is given as:
 \begin{equation}
 C_i = E_k(P_i)
@@ -644,6 +682,7 @@
 than once.
 
 \subsubsection{CBC Mode}
+\index{CBC mode}
 CBC or Cipher Block Chaining mode is a simple mode designed to prevent trivial forms of replay and swap attacks on ciphers.
 It is given as:
 \begin{equation}
@@ -652,6 +691,7 @@
 It is important that the initial vector be unique and preferably random for each message encrypted under the same key.
 
 \subsubsection{CTR Mode}
+\index{CTR mode}
 CTR or Counter Mode is a mode which only uses the encryption function of the cipher.  Given a initial vector which is
 treated as a large binary counter the CTR mode is given as:
 \begin{eqnarray}
@@ -663,6 +703,7 @@
 as the block cipher is under a chosen plaintext attack (provided the initial vector is unique).
 
 \subsubsection{CFB Mode}
+\index{CFB mode}
 CFB or Ciphertext Feedback Mode is a mode akin to CBC.  It is given as:
 \begin{eqnarray}
 C_i = P_i \oplus C_{-1} \nonumber \\
@@ -673,6 +714,7 @@
 blocks without a delay.  When this mode is first setup it will initially encrypt the initial vector as required.
 
 \subsubsection{OFB Mode}
+\index{OFB mode}
 OFB or Output Feedback Mode is a mode akin to CBC as well.  It is given as:
 \begin{eqnarray}
 C_{-1} = E_k(C_{-1}) \nonumber \\
@@ -703,6 +745,7 @@
 The library provides simple support routines for handling CBC, CTR, CFB, OFB and ECB encoded messages.  Assuming the mode 
 you want is XXX there is a structure called ``symmetric\_XXX'' that will contain the information required to
 use that mode.  They have identical setup routines (except ECB mode for obvious reasons):
+\index{ecb\_start()} \index{cfb\_start()} \index{cbc\_start()} \index{ofb\_start()} \index{ctr\_start()}
 \begin{verbatim}
 int XXX_start(int cipher, const unsigned char *IV, 
               const unsigned char *key, int keylen, 
@@ -721,6 +764,8 @@
 
 Both routines return {\bf CRYPT\_OK} if the cipher initialized correctly, otherwise they return an error code.  To 
 actually encrypt or decrypt the following routines are provided:
+\index{ecb\_encrypt()} \index{ecb\_decrypt()} \index{cfb\_encrypt()} \index{cfb\_decrypt()} 
+\index{cbc\_encrypt()} \index{cbc\_decrypt()} \index{ofb\_encrypt()} \index{ofb\_decrypt()} \index{ctr\_encrypt()} \index{ctr\_decrypt()}
 \begin{verbatim}
 int XXX_encrypt(const unsigned char *pt, unsigned char *ct, 
                 symmetric_XXX *XXX);
@@ -739,8 +784,23 @@
 five of the modes will return {\bf CRYPT\_OK} on success from the encrypt or decrypt functions.
 
 To decrypt in either mode you simply perform the setup like before (recall you have to fetch the IV value you used)
-and use the decrypt routine on all of the blocks.  When you are done working with either mode you should wipe the 
-memory (using ``zeromem()'') to help prevent the key from leaking.  For example:
+and use the decrypt routine on all of the blocks.
+
+To change or read the IV of a previously initialized chaining mode use the following two functions.
+
+\index{cbc\_setiv()} \index{cbc\_getiv()} \index{ofb\_setiv()} \index{ofb\_getiv()} \index{cfb\_setiv()} \index{cfb\_getiv()}
+\index{ctr\_setiv()} \index{ctr\_getiv()}
+\begin{verbatim}
+int XXX_getiv(unsigned char *IV, unsigned long *len, symmetric_XXX *XXX);
+int XXX_setiv(const unsigned char *IV, unsigned long len, symmetric_XXX *XXX);
+\end{verbatim}
+
+The XXX\_getiv function will read the IV out of the chaining mode and store it into ``IV'' along with the length of the IV 
+stored in ``len''.  The XXX\_setiv will initialize the chaining mode state as if the original IV were the new IV specified.  The length
+of the IV passed in must be the size of the ciphers block size.
+
+The XXX\_setiv functions are handy if you wish to change the IV without re--keying the cipher.  
+
 \newpage
 \begin{small}
 \begin{verbatim}
@@ -749,7 +809,7 @@
 {
    unsigned char key[16], IV[16], buffer[512];
    symmetric_CTR ctr;
-   int x, errno;
+   int x, err;
 
    /* register twofish first */
    if (register_cipher(&twofish_desc) == -1) {
@@ -760,19 +820,47 @@
    /* somehow fill out key and IV */
 
    /* start up CTR mode */
-   if ((errno = ctr_start(find_cipher("twofish"), IV, key, 16, 0, &ctr)) != CRYPT_OK) {
-      printf("ctr_start error: %s\n", error_to_string(errno));
+   if ((err = ctr_start(find_cipher("twofish"), /* index of desired cipher */
+                                            IV, /* the initial vector */
+                                           key, /* the secret key */
+                                            16, /* length of secret key (16 bytes, 128 bits) */
+                                             0, /* 0 == default # of rounds */
+                                         &ctr)  /* where to store initialized CTR state */
+      ) != CRYPT_OK) {
+      printf("ctr_start error: %s\n", error_to_string(err));
       return -1;
    }
 
    /* somehow fill buffer than encrypt it */
-   if ((errno = ctr_encrypt(buffer, buffer, sizeof(buffer), &ctr)) != CRYPT_OK) {
-      printf("ctr_encrypt error: %s\n", error_to_string(errno));
+   if ((err = ctr_encrypt(        buffer, /* plaintext */
+                                  buffer, /* ciphertext */
+                          sizeof(buffer), /* length of data to encrypt */
+                                   &ctr)  /* previously initialized CTR state */
+      ) != CRYPT_OK) {
+      printf("ctr_encrypt error: %s\n", error_to_string(err));
       return -1;
    }
 
    /* make use of ciphertext... */
 
+   /* now we want to decrypt so let's use ctr_setiv */
+   if ((err = ctr_setiv(  IV, /* the initial IV we gave to ctr_start */
+                          16, /* the IV is 16 bytes long */
+                        &ctr) /* the ctr state we wish to modify */
+       ) != CRYPT_OK) {
+      printf("ctr_setiv error: %s\n", error_to_string(err));
+      return -1;
+   }
+
+   if ((err = ctr_decrypt(        buffer, /* ciphertext */
+                                  buffer, /* plaintext */
+                          sizeof(buffer), /* length of data to encrypt */
+                                   &ctr)  /* previously initialized CTR state */
+      ) != CRYPT_OK) {
+      printf("ctr_decrypt error: %s\n", error_to_string(err));
+      return -1;
+   }
+
    /* clear up and return */
    zeromem(key, sizeof(key));
    zeromem(&ctr, sizeof(ctr));
@@ -787,15 +875,14 @@
 \subsection{EAX Mode}
 LibTomCrypt provides support for a mode called EAX\footnote{See 
 M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the
-way it was intended to be used.
-
-First a short description of what EAX mode is before I explain how to use it.  EAX is a mode that requires a cipher,
-CTR and OMAC support and provides encryption and authentication.  It is initialized with a random ``nonce'' that can
-be shared publicly as well as a ``header'' which can be fixed and public as well as a random secret symmetric key.
+way it was intended to be used by the designers.  First a short description of what EAX mode is before I explain how to use it.  
+EAX is a mode that requires a cipher, CTR and OMAC support and provides encryption and authentication\footnote{Note that since EAX only requires OMAC and CTR you may use ``encrypt only'' cipher descriptors with this mode.}.  
+It is initialized with a random ``nonce'' that can be shared publicly as well as a ``header'' which can be fixed and public as well as a random 
+secret symmetric key.
 
 The ``header'' data is meant to be meta-data associated with a stream that isn't private (e.g. protocol messages).  It can
 be added at anytime during an EAX stream and is part of the authentication tag.  That is, changes in the meta-data can
-be detected by an invalid output tag.
+be detected by changes in the output tag.
 
 The mode can then process plaintext producing ciphertext as well as compute a partial checksum.  The actual checksum
 called a ``tag'' is only emitted when the message is finished.  In the interim though the user can process any arbitrary
@@ -803,6 +890,7 @@
 of operation.
 
 The mode is initialized with the following function.
+\index{eax\_init()}
 \begin{verbatim}
 int eax_init(eax_state *eax, int cipher, 
              const unsigned char *key, unsigned long keylen,
@@ -816,10 +904,11 @@
 ``headerlen''.
 
 When this function completes ``eax'' will be initialized such that you can now either have data decrypted or 
-encrypted in EAX mode.  Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL}.  It will still
-initialize the EAX ``H'' value to the correct value.  
+encrypted in EAX mode.  Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL} to indicate
+there is no initial header data.
 
 To encrypt or decrypt data in a streaming mode use the following.
+\index{eax\_encrypt()} \index{eax\_decrypt()}
 \begin{verbatim}
 int eax_encrypt(eax_state *eax, const unsigned char *pt, 
                 unsigned char *ct, unsigned long length);
@@ -832,13 +921,14 @@
 through the OMAC function.  The function ``eax\_decrypt'' decrypts ``ct'' and stores it in ``pt''.  This also allows 
 ``pt'' and ``ct'' to be the same region in memory.  
 
+You cannot both encrypt or decrypt with the same ``eax'' context.  For bi-directional communication you
+will need to initialize two EAX contexts (preferably with different headers and nonces).  
+
 Note that both of these functions allow you to send the data in any granularity but the order is important.  While
 the eax\_init() function allows you to add initial header data to the stream you can also add header data during the
 EAX stream with the following.
 
-Also note that you cannot both encrypt or decrypt with the same ``eax'' context.  For bi-directional communication you
-will need to initialize two EAX contexts (preferably with different headers and nonces).  
-
+\index{eax\_addheader()}
 \begin{verbatim}
 int eax_addheader(eax_state *eax, 
                   const unsigned char *header, unsigned long length);
@@ -847,6 +937,7 @@
 This will add the ``length'' bytes from ``header'' to the given ``eax'' stream.  Once the message is finished the 
 ``tag'' (checksum) may be computed with the following function.
 
+\index{eax\_done()}
 \begin{verbatim}
 int eax_done(eax_state *eax, 
              unsigned char *tag, unsigned long *taglen);
@@ -855,19 +946,102 @@
 then stores how many bytes of the tag were written out back into ``taglen''.
 
 The EAX mode code can be tested to ensure it matches the test vectors by calling the following function.
+\index{eax\_test()}
 \begin{verbatim}
 int eax_test(void);
 \end{verbatim}
 This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first.
 
+\begin{verbatim}
+#include <mycrypt.h>
+int main(void)
+{
+   int           err;
+   eax_state     eax;
+   unsigned char pt[64], ct[64], nonce[16], key[16], tag[16];
+   unsigned long taglen;
+
+   if (register_cipher(&rijndael_desc) == -1) {
+      printf("Error registering Rijndael");
+      return EXIT_FAILURE;
+   }
+
+   /* ... make up random nonce and key ... */
+
+   /* initialize context */
+   if ((err = eax_init(            &eax,  /* the context */
+                find_cipher("rijndael"),  /* cipher we want to use */
+                                  nonce,  /* our state nonce */
+                                     16,  /* none is 16 bytes */
+                              "TestApp",  /* example header, identifies this program */
+                                      7)  /* length of the header */
+       ) != CRYPT_OK) {
+      printf("Error eax_init: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* now encrypt data, say in a loop or whatever */
+   if ((err = eax_encrypt(     &eax,      /* eax context */
+                                 pt,      /* plaintext  (source) */
+                                 ct,      /* ciphertext (destination) */
+                          sizeof(pt)      /* size of plaintext */
+      ) != CRYPT_OK) {
+      printf("Error eax_encrypt: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* finish message and get authentication tag */
+   taglen = sizeof(tag);
+   if ((err = eax_done(   &eax,           /* eax context */
+                           tag,           /* where to put tag */
+                       &taglen            /* length of tag space */
+      ) != CRYPT_OK) {
+      printf("Error eax_done: %s", error_to_string(err));
+      return EXIT_FAILURE;
+   }
+
+   /* now we have the authentication tag in "tag" and it's taglen bytes long */
+
+}
+\end{verbatim}
+                       
+You can also perform an entire EAX state on a block of memory in a single function call with the 
+following functions.
+
+
+\index{eax\_encrypt\_authenticate\_memory} \index{eax\_decrypt\_verify\_memory}
+\begin{verbatim}
+int eax_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen);
+
+int eax_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+          unsigned char *tag,    unsigned long taglen,
+          int           *res);
+\end{verbatim}
+
+Both essentially just call eax\_init() followed by eax\_encrypt() (or eax\_decrypt() respectively) and eax\_done().  The parameters
+have the same meaning as with those respective functions.  
+
+The only difference is eax\_decrypt\_verify\_memory() does not emit a tag.  Instead you pass it a tag as input and it compares it against
+the tag it computed while decrypting the message.  If the tags match then it stores a $1$ in ``res'', otherwise it stores a $0$.
+
 \subsection{OCB Mode}
 LibTomCrypt provides support for a mode called OCB\footnote{See 
 P. Rogaway, M. Bellare, J. Black, T. Krovetz, ``OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption''.}
-in a mode somewhat similar to as it was meant to be used.
-
-OCB is an encryption protocol that simultaneously provides authentication.  It is slightly faster to use than EAX mode
+.  OCB is an encryption protocol that simultaneously provides authentication.  It is slightly faster to use than EAX mode
 but is less flexible.  Let's review how to initialize an OCB context.
 
+\index{ocb\_init()}
 \begin{verbatim}
 int ocb_init(ocb_state *ocb, int cipher, 
              const unsigned char *key, unsigned long keylen, 
@@ -876,11 +1050,12 @@
 
 This will initialize the ``ocb'' context using cipher descriptor ``cipher''.  It will use a ``key'' of length ``keylen''
 and the random ``nonce''.  Note that ``nonce'' must be a random (public) string the same length as the block ciphers
-block size (e.g. 16 for AES).
+block size (e.g. 16 bytes for AES).
 
 This mode has no ``Associated Data'' like EAX mode does which means you cannot authenticate metadata along with the stream.
 To encrypt or decrypt data use the following.
 
+\index{ocb\_encrypt()} \index{ocb\_decrypt()}
 \begin{verbatim}
 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
 int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
@@ -893,6 +1068,7 @@
 
 When you are finished encrypting the message you call the following function to compute the tag.
 
+\index{ocb\_done\_encrypt()}
 \begin{verbatim}
 int ocb_done_encrypt(ocb_state *ocb, 
                      const unsigned char *pt, unsigned long ptlen,
@@ -909,6 +1085,7 @@
 
 To terminate a decrypt stream and compared the tag you call the following.
 
+\index{ocb\_done\_decrypt()}
 \begin{verbatim}
 int ocb_done_decrypt(ocb_state *ocb, 
                      const unsigned char *ct,  unsigned long ctlen,
@@ -924,6 +1101,7 @@
 
 To make life simpler the following two functions are provided for memory bound OCB.
 
+\index{ocb\_encrypt\_authenticate\_memory()}
 \begin{verbatim}
 int ocb_encrypt_authenticate_memory(int cipher,
     const unsigned char *key,    unsigned long keylen,
@@ -936,6 +1114,7 @@
 This will OCB encrypt the message ``pt'' of length ``ptlen'' and store the ciphertext in ``ct''.  The length ``ptlen''
 can be any arbitrary length.  
 
+\index{ocb\_decrypt\_verify\_memory()}
 \begin{verbatim}
 int ocb_decrypt_verify_memory(int cipher,
     const unsigned char *key,    unsigned long keylen,
@@ -949,8 +1128,6 @@
 Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set 
 appropriately.
 
-
-
 \chapter{One-Way Cryptographic Hash Functions}
 \section{Core Functions}
 
@@ -1020,7 +1197,6 @@
 \end{small}
 
 \section{Hash Descriptors}
-\index{Hash Descriptors}
 Like the set of ciphers the set of hashes have descriptors too.  They are stored in an array called ``hash\_descriptor'' and
 are defined by:
 \begin{verbatim}
@@ -1116,7 +1292,7 @@
 #include <mycrypt.h>
 int main(void)
 {
-   int idx, errno;
+   int idx, err;
    unsigned long len;
    unsigned char out[MAXBLOCKSIZE];
 
@@ -1131,8 +1307,8 @@
 
    /* call the hash */
    len = sizeof(out);
-   if ((errno = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) {
-      printf("Error hashing data: %s\n", error_to_string(errno));
+   if ((err = hash_memory(idx, "hello world", 11, out, &len)) != CRYPT_OK) {
+      printf("Error hashing data: %s\n", error_to_string(err));
       return -1;
    }
    return 0;
@@ -1141,6 +1317,7 @@
 \end{small}
 
 The following hashes are provided as of this release:
+\index{Hash descriptor table}
 \begin{center}
 \begin{tabular}{|c|c|c|}
       \hline Name & Descriptor Name & Size of Message Digest (bytes) \\
@@ -1162,6 +1339,7 @@
 
 Similar to the cipher descriptor table you must register your hash algorithms before you can use them.  These functions
 work exactly like those of the cipher registration code.  The functions are:
+\index{register\_hash()} \index{unregister\_hash()}
 \begin{verbatim}
 int register_hash(const struct _hash_descriptor *hash);
 int unregister_hash(const struct _hash_descriptor *hash);
@@ -1185,6 +1363,7 @@
 The HMAC support works much like the normal hash functions except that the initialization routine requires you to pass a key 
 and its length.  The key is much like a key you would pass to a cipher.  That is, it is simply an array of octets stored in
 chars.  The initialization routine is:
+\index{hmac\_init()}
 \begin{verbatim}
 int hmac_init(hmac_state *hmac, int hash, 
               const unsigned char *key, unsigned long keylen);
@@ -1192,6 +1371,7 @@
 The ``hmac'' parameter is the state for the HMAC code.  ``hash'' is the index into the descriptor table of the hash you want
 to use to authenticate the message.  ``key'' is the pointer to the array of chars that make up the key.  ``keylen'' is the
 length (in octets) of the key you want to use to authenticate the message.  To send octets of a message through the HMAC system you must use the following function:
+\index{hmac\_process()}
 \begin{verbatim}
 int hmac_process(hmac_state *hmac, const unsigned char *buf,
                   unsigned long len);
@@ -1199,6 +1379,7 @@
 ``hmac'' is the HMAC state you are working with. ``buf'' is the array of octets to send into the HMAC process.  ``len'' is the
 number of octets to process.  Like the hash process routines you can send the data in arbitrarly sized chunks. When you 
 are finished with the HMAC process you must call the following function to get the HMAC code:
+\index{hmac\_done()}
 \begin{verbatim}
 int hmac_done(hmac_state *hmac, unsigned char *hashOut,
               unsigned long *outlen);
@@ -1212,6 +1393,7 @@
 message (file pointer, address in memory) and produce the HMAC result in one shot.  These are useful if you want to avoid
 calling the three step process yourself.
 
+\index{hmac\_memory()}
 \begin{verbatim}
 int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
                 const unsigned char *data, unsigned long len, 
@@ -1221,6 +1403,7 @@
 table must be provided in ``hash''.  It uses the key from ``key'' with a key length of ``keylen''.  
 The result is stored in the array of octets ``dst'' and the length in ``dstlen''.  The value of ``dstlen'' must be set
 to the size of the destination buffer before calling this function.  Similarly for files there is the  following function:
+\index{hmac\_file()}
 \begin{verbatim}
 int hmac_file(int hash, const char *fname, const unsigned char *key,
               unsigned long keylen, 
@@ -1231,6 +1414,7 @@
 result should be stored.
 
 To test if the HMAC code is working there is the following function:
+\index{hmac\_test()}
 \begin{verbatim}
 int hmac_test(void);
 \end{verbatim}
@@ -1242,7 +1426,7 @@
 #include <mycrypt.h>
 int main(void)
 {
-   int idx, errno;
+   int idx, err;
    hmac_state hmac;
    unsigned char key[16], dst[MAXBLOCKSIZE];
    unsigned long dstlen;
@@ -1259,21 +1443,21 @@
    /* we would make up our symmetric key in "key[]" here */
 
    /* start the HMAC */
-   if ((errno = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) {
-      printf("Error setting up hmac: %s\n", error_to_string(errno));
+   if ((err = hmac_init(&hmac, idx, key, 16)) != CRYPT_OK) {
+      printf("Error setting up hmac: %s\n", error_to_string(err));
       return -1;
    }
 
    /* process a few octets */
-   if((errno = hmac_process(&hmac, "hello", 5) != CRYPT_OK) {
-      printf("Error processing hmac: %s\n", error_to_string(errno));
+   if((err = hmac_process(&hmac, "hello", 5) != CRYPT_OK) {
+      printf("Error processing hmac: %s\n", error_to_string(err));
       return -1;
    }
 
    /* get result (presumably to use it somehow...) */
    dstlen = sizeof(dst);
-   if ((errno = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) {
-      printf("Error finishing hmac: %s\n", error_to_string(errno));
+   if ((err = hmac_done(&hmac, dst, &dstlen)) != CRYPT_OK) {
+      printf("Error finishing hmac: %s\n", error_to_string(err));
       return -1;
    }
    printf("The hmac is %lu bytes long\n", dstlen);
@@ -1290,7 +1474,7 @@
 standpoint the OMAC routines work much like the HMAC routines do.  Instead in this case a cipher is used instead of a hash.  
 
 To start an OMAC state you call
-
+\index{omac\_init()}
 \begin{verbatim}
 int omac_init(omac_state *omac, int cipher, 
               const unsigned char *key, unsigned long keylen);
@@ -1300,6 +1484,7 @@
 wish to use.  ``key'' and ``keylen'' are the keys used to authenticate the data.
 
 To send data through the algorithm call
+\index{omac\_process()}
 \begin{verbatim}
 int omac_process(omac_state *state, 
                  const unsigned char *buf, unsigned long len);
@@ -1320,6 +1505,7 @@
 
 When you are done processing the message you can call the following to compute the message tag.
 
+\index{omac\_done()}
 \begin{verbatim}
 int omac_done(omac_state *state, 
               unsigned char *out, unsigned long *outlen);
@@ -1333,6 +1519,7 @@
 Similar to the HMAC code the file and memory functions are also provided.  To OMAC a buffer of memory in one shot use the 
 following function.
 
+\index{omac\_memory()}
 \begin{verbatim}
 int omac_memory(int cipher, 
                 const unsigned char *key, unsigned long keylen,
@@ -1344,6 +1531,7 @@
 rules as omac\_done.
 
 To OMAC a file use
+\index{omac\_file()}
 \begin{verbatim}
 int omac_file(int cipher, 
               const unsigned char *key, unsigned long keylen,
@@ -1356,6 +1544,7 @@
 the same rules as omac\_done.
 
 To test if the OMAC code is working there is the following function:
+\index{omac\_test()}
 \begin{verbatim}
 int omac_test(void);
 \end{verbatim}
@@ -1416,6 +1605,7 @@
 
 A PMAC state is initialized with the following.
 
+\index{pmac\_init()}
 \begin{verbatim}
 int pmac_init(pmac_state *pmac, int cipher, 
               const unsigned char *key, unsigned long keylen);
@@ -1425,6 +1615,7 @@
 
 To MAC data simply send it through the process function.
 
+\index{pmac\_process()}
 \begin{verbatim}
 int pmac_process(pmac_state *state, 
                  const unsigned char *buf, unsigned long len);
@@ -1445,6 +1636,7 @@
 
 When a complete message has been processed the following function can be called to compute the message tag.
 
+\index{pmac\_done()}
 \begin{verbatim}
 int pmac_done(pmac_state *state, 
               unsigned char *out, unsigned long *outlen);
@@ -1455,6 +1647,7 @@
 Similar to the PMAC code the file and memory functions are also provided.  To PMAC a buffer of memory in one shot use the 
 following function.
 
+\index{pmac\_memory()}
 \begin{verbatim}
 int pmac_memory(int cipher, 
                 const unsigned char *key, unsigned long keylen,
@@ -1466,6 +1659,7 @@
 rules as omac\_done.
 
 To PMAC a file use
+\index{pmac\_file()}
 \begin{verbatim}
 int pmac_file(int cipher, 
               const unsigned char *key, unsigned long keylen,
@@ -1716,8 +1910,12 @@
 \end{small}
 
 \chapter{RSA Public Key Cryptography}
-\textbf{Note: } \textit{This chapter on PKCS \#1 RSA will replace the older chapter on RSA (The current chapter nine) in subsequent 
-releases of the library.  Users are encouraged to stop using the LibTomCrypt style padding functions.}
+
+\section{Introduction}
+RSA wrote the PKCS \#1 specifications which detail RSA Public Key Cryptography.  In the specifications are
+padding algorithms for encryption and signatures.  The standard includes ``v1.5'' and ``v2.0'' algorithms.
+To simplify matters a little the v2.0 encryption and signature padding algorithms are called OAEP and PSS 
+respectively.  
 
 \section{PKCS \#1 Encryption}
 
@@ -1726,11 +1924,12 @@
 
 \subsection{OAEP Encoding}
 
+\index{pkcs\_1\_oaep\_encode()}
 \begin{alltt}
 int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
-                             unsigned long modulus_bitlen, int hash_idx,
-                             int           prng_idx,    prng_state *prng,
+                             unsigned long modulus_bitlen, prng_state *prng,
+                             int           prng_idx,         int  hash_idx,
                              unsigned char *out,    unsigned long *outlen);
 \end{alltt}
 
@@ -1752,11 +1951,13 @@
 
 \subsection{OAEP Decoding}
 
+\index{pkcs\_1\_oaep\_decode()}
 \begin{alltt}
 int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
                              unsigned long modulus_bitlen, int hash_idx,
-                             unsigned char *out,    unsigned long *outlen);
+                             unsigned char *out,    unsigned long *outlen,
+                             int           *res);
 \end{alltt}
 
 This function decodes an OAEP encoded message and outputs the original message that was passed to the OAEP encoder.  ``msg'' is the 
@@ -1765,17 +1966,47 @@
 and must match what was used during encoding.  Similarly the ``hash\_idx'' index into the hash descriptor table must match what was used
 during encoding.
 
-If the function succeeds it decodes the OAEP encoded message into ``out'' of length ``outlen''.  
+If the function succeeds it decodes the OAEP encoded message into ``out'' of length ``outlen'' and stores a 
+$1$ in ``res''.  If the packet is invalid it stores $0$ in ``res'' and if the function fails for another reason
+it returns an error code.  
+
+\subsection{PKCS \#1 v1.5 Encoding}
+
+\index{pkcs\_1\_v15\_es\_encode()}
+\begin{verbatim}
+int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
+                               unsigned long  modulus_bitlen, 
+                               prng_state    *prng,   int           prng_idx,
+                               unsigned char *out,    unsigned long *outlen);
+\end{verbatim}
+
+This will PKCS v1.5 encode the data in ``msg'' of length ``msglen''.  Pass the length (in bits) of your
+RSA modulus in ``modulus\_bitlen''.  The encoded data will be stored in ``out'' of length ``outlen''.
+
+\subsection{PKCS \#1 v1.5 Decoding}
+\index{pkcs\_1\_v15\_es\_decode()}
+\begin{verbatim}
+int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
+                               unsigned long modulus_bitlen,
+                               unsigned char *out,  unsigned long outlen,
+                               int           *res);
+\end{verbatim}
+
+This will PKCS v1.5 decode the message in ``msg'' of length ``msglen''.  It will store the output in ``out''. Note
+that the length of the output ``outlen'' is a constant.  This decoder cannot determine the original message 
+length.  If the data in ``msg'' is a valid packet then a $1$ is stored in ``res'', otherwise a $0$ is 
+stored.
 
 \section{PKCS \#1 Digital Signatures}
 
 \subsection{PSS Encoding}
 PSS encoding is the second half of the PKCS \#1 standard which is padding to be applied to messages that are signed.  
 
+\index{pkcs\_1\_pss\_encode()}
 \begin{alltt}
 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
-                            unsigned long saltlen,  int           hash_idx,
-                            int           prng_idx, prng_state   *prng,
+                            unsigned long saltlen,  prng_state   *prng,     
+                            int           prng_idx, int           hash_idx,
                             unsigned long modulus_bitlen,
                             unsigned char *out,     unsigned long *outlen);
 \end{alltt}
@@ -1785,7 +2016,7 @@
 ``hash\_idx'' is the index into the hash descriptor table of the hash to use.  ``prng\_idx'' and ``prng'' are the random
 number generator information required for the salt.
 
-Similar to OAEP encoding ``modulus\_bitlen'' is the size of the RSA modulus.  It limits the size of the salt.  If $m$ is the length
+Similar to OAEP encoding ``modulus\_bitlen'' is the size of the RSA modulus (in bits).  It limits the size of the salt.  If $m$ is the length
 of the modulus $h$ the length of the hash output (in octets) then there can be $m - h - 2$ bytes of salt.  
 
 This function does not actually sign the data it merely pads the hash of a message so that it can be processed by rsa\_exptmod().
@@ -1794,6 +2025,7 @@
 
 To decode a PSS encoded signature block you have to use the following.
 
+\index{pkcs\_1\_pss\_decode()}
 \begin{alltt}
 int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
                       const unsigned char *sig,     unsigned long siglen,
@@ -1806,6 +2038,240 @@
 
 It's important to use the same ``saltlen'' and hash for both encoding and decoding as otherwise the procedure will not work.
 
+\subsection{PKCS \#1 v1.5 Encoding}
+
+\index{pkcs\_1\_v15\_sa\_encode()}
+\begin{verbatim}
+int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
+                               int            hash_idx, unsigned long modulus_bitlen,
+                               unsigned char *out,      unsigned long *outlen);
+\end{verbatim}
+
+This will PKCS \#1 v1.5 signature encode the message hash ``msghash''  of length ``msghashlen''.  You have
+to tell this routine which hash produced the message hash in ``hash\_idx''.  The encoded hash is stored
+in ``out'' of length ``outlen''.
+
+\subsection{PKCS \#1 v1.5 Decoding}
+
+\index{pkcs\_1\_v15\_sa\_decode()}
+\begin{verbatim}
+int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
+                         const unsigned char *sig,     unsigned long siglen,
+                               int           hash_idx, unsigned long modulus_bitlen, 
+                               int          *res);
+\end{verbatim}
+
+This will PKCS \#1 v1.5 signature decode the data in ``sig'' of length ``siglen'' and compare the extracted
+hash against ``msghash'' of length ``msghashlen''.  You have to tell this routine which hash produced the
+message digest in ``hash\_idx''.  If the packet is valid and the hashes match ``res'' is set to $1$.  Otherwise,
+it is set to $0$.
+
+\section{RSA Operations}
+\subsection{Background}
+
+RSA is a public key algorithm that is based on the inability to find the ``e-th'' root modulo a composite of unknown 
+factorization.  Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are
+not strictly equivalent.
+
+The system begins with with two primes $p$ and $q$ and their product $N = pq$.  The order or ``Euler totient'' of the
+multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to 
+$\mbox{lcm}(p - 1, q - 1)$.  The public key consists of the composite $N$ and some integer $e$ such that 
+$\mbox{gcd}(e, \phi(N)) = 1$.  The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$ 
+often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$.
+
+A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that 
+$1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$.  Since finding the inverse exponent $d$
+given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute
+$C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$.  Similarly the owner of the private key 
+can sign a message by ``decrypting'' it.  Others can verify it by ``encrypting'' it.  
+
+Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other.  
+Ideally $e$ should be larger than $100$ to prevent direct analysis.  For example, if $e$ is three and you do not pad
+the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial.  
+The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well 
+designed for fast exponentiation (requires 16 squarings and one multiplication).
+
+It is important to pad the input to RSA since it has particular mathematical structure.  For instance  
+$M_1^dM_2^d = (M_1M_2)^d$ which can be used to forge a signature.  Suppose $M_3 = M_1M_2$ is a message you want
+to have a forged signature for.  Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result
+together.  Similar tricks can be used to deduce plaintexts from ciphertexts.  It is important not only to sign 
+the hash of documents only but also to pad the inputs with data to remove such structure.  
+
+\subsection{RSA Key Generation}
+
+For RSA routines a single ``rsa\_key'' structure is used.  To make a new RSA key call:
+\index{rsa\_make\_key()}
+\begin{verbatim}
+int rsa_make_key(prng_state *prng, 
+                 int wprng, int size, 
+                 long e, rsa_key *key);
+\end{verbatim}
+
+Where ``wprng'' is the index into the PRNG descriptor array.  ``size'' is the size in bytes of the RSA modulus desired.
+``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537.  I suggest you stick with 65537 since its big
+enough to prevent trivial math attacks and not super slow.  ``key'' is where the key is placed.  All keys must be at 
+least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}).
+
+Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key.  Make sure to call 
+``rsa\_free()'' (see below) when you are finished with the key.  If ``rsa\_make\_key()'' fails it will automatically 
+free the ram allocated itself.
+
+There are three types of RSA keys.  The types are {\bf PK\_PRIVATE\_OPTIMIZED}, {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}.  The first
+two are private keys where the ``optimized'' type uses the Chinese Remainder Theorem to speed up decryption/signatures.  By 
+default all new keys are of the ``optimized'' type.  The non-optimized private type is provided for backwards compatibility
+as well as to save space since the optimized key requires about four times as much memory.
+
+\subsection{RSA Exponentiation}
+
+To do raw work with the RSA function call:
+\index{rsa\_exptmod()}
+\begin{verbatim}
+int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
+                      unsigned char *out,  unsigned long *outlen, int which,
+                      prng_state    *prng, int           prng_idx,
+                      rsa_key *key);
+\end{verbatim}
+This loads the bignum from ``in'' as a big endian word in the format PKCS specifies, raises it to either ``e'' or ``d'' and stores the result
+in ``out'' and the size of the result in ``outlen''. ``which'' is set to {\bf PK\_PUBLIC} to use ``e'' 
+(i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use ``d'' as the exponent (i.e. for decrypting/signing).
+
+Note that the output of his function is zero-padded as per PKCS \#1 specifications.  This allows this routine to 
+interoprate with PKCS \#1 padding functions properly.
+
+\subsection{RSA Key Encryption}
+Normally RSA is used to encrypt short symmetric keys which are then used in block ciphers to encrypt a message.
+To facilitate encrypting short keys the following functions have been provided.
+
+\index{rsa\_encrypt\_key()}
+\begin{verbatim}
+int rsa_encrypt_key(const unsigned char *inkey,  unsigned long inlen,
+                          unsigned char *outkey, unsigned long *outlen,
+                    const unsigned char *lparam, unsigned long lparamlen,
+                    prng_state *prng, int prng_idx, int hash_idx, rsa_key *key);
+\end{verbatim}
+This function will OAEP pad ``inkey'' of length inlen bytes then RSA encrypt it and store the ciphertext
+in ``outkey'' of length ``outlen''.  The ``lparam'' and ``lparamlen'' are the same parameters you would pass
+to pkcs\_1\_oaep\_encode().
+
+\index{rsa\_decrypt\_key()}
+\begin{verbatim}
+int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
+                          unsigned char *outkey, unsigned long *keylen, 
+                    const unsigned char *lparam, unsigned long lparamlen,
+                          prng_state    *prng,   int           prng_idx,
+                          int            hash_idx, int *res,
+                          rsa_key       *key);
+\end{verbatim}
+This function will RSA decrypt ``in'' of length ``inlen'' then OAEP depad the resulting data and store it in
+``outkey'' of length ``outlen''.  The ``lparam'' and ``lparamlen'' are the same parameters you would pass
+to pkcs\_1\_oaep\_decode().
+
+If the RSA decrypted data isn't a valid OAEP packet then ``res'' is set to $0$.  Otherwise, it is set to $1$.
+
+\subsection{RSA Hash Signatures}
+Similar to RSA key encryption RSA is also used to ``digitally sign'' message digests (hashes).  To facilitate this
+process the following functions have been provided.
+
+\index{rsa\_sign\_hash()}
+\begin{verbatim}
+int rsa_sign_hash(const unsigned char *msghash,  unsigned long  msghashlen, 
+                        unsigned char *sig,      unsigned long *siglen, 
+                        prng_state    *prng,     int            prng_idx,
+                        int            hash_idx, unsigned long  saltlen,
+                        rsa_key *key);
+\end{verbatim}
+
+This will PSS encode the message hash ``msghash'' of length ``msghashlen''.  Next the PSS encoded message is
+RSA ``signed'' and the output is stored in ``sig'' of length ``siglen''.  
+
+
+\index{rsa\_verify\_hash()}
+\begin{verbatim}
+int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
+                    const unsigned char *msghash,  unsigned long msghashlen,
+                          prng_state    *prng,     int           prng_idx,
+                          int            hash_idx, unsigned long saltlen,
+                          int           *stat,     rsa_key      *key);
+\end{verbatim}
+
+This will RSA ``verify'' the signature in ``sig'' of length ``siglen''.  Next the RSA decoded data is PSS decoded
+and the extracted hash is compared against the message hash ``msghash'' of length ``msghashlen''.
+
+If the RSA decoded data is not a valid PSS message or if the PSS decoded hash does not match the ``msghash'' 
+the value ``res'' is set to $0$.  Otherwise, if the function succeeds and signature is valid ``res'' is set
+to $1$.
+
+\begin{verbatim}
+#include <mycrypt.h>
+int main(void)
+{
+   int           err, hash_idx, prng_idx, res;
+   unsigned long l1, l2;
+   unsigned char pt[16], pt2[16], out[1024];
+   rsa_key       key;
+
+   /* register prng/hash */
+   if (register_prng(&sprng_desc) == -1) {
+      printf("Error registering sprng");
+      return EXIT_FAILURE;
+   }
+
+   if (register_hash(&sha1_desc) == -1) {
+      printf("Error registering sha1");
+      return EXIT_FAILURE;
+   }
+   hash_idx = find_hash("sha1");
+   prng_idx = find_prng("sprng");
+
+   /* make an RSA-1024 key */
+   if ((err = rsa_make_key(NULL,     /* PRNG state */
+                           prng_idx, /* PRNG idx */
+                           1024/8,   /* 1024-bit key */
+                           65537,    /* we like e=65537 */
+                           &key)     /* where to store the key */
+       ) != CRYPT_OK) {
+       printf("rsa_make_key %s", error_to_string(err));
+       return EXIT_FAILURE;
+   }
+
+   /* fill in pt[] with a key we want to send ... */
+   l1 = sizeof(out);
+   if ((err = rsa_encrypt_key(pt,    /* data we wish to encrypt */
+                              16,    /* data is 16 bytes long */
+                             out,    /* where to store ciphertext */
+                             &l1,    /* length of ciphertext */
+                       "TestApp",    /* our lparam for this program */
+                               7,    /* lparam is 7 bytes long */
+                            NULL,    /* PRNG state */
+                        prng_idx,    /* prng idx */
+                        hash_idx,    /* hash idx */
+                            &key)    /* our RSA key */
+       ) != CRYPT_OK) {
+       printf("rsa_encrypt_key %s", error_to_string(err));
+       return EXIT_FAILURE;
+   }
+
+   /* now let's decrypt the encrypted key */
+   l2 = sizeof(pt2);
+   if ((err = rsa_decrypt_key(out, /* encrypted data */
+                               l1, /* length of ciphertext */
+                              pt2, /* where to put plaintext */
+                              &l2, /* plaintext length */
+                        "TestApp", /* lparam for this program */
+                                7, /* lparam is 7 bytes long */
+                             NULL, /* PRNG state */
+                         prng_idx, /* prng idx */
+                         hash_idx, /* hash idx */
+                             &res, /* validity of data */
+                             &key) /* our RSA key */ 
+        ) != CRYPT_OK) {
+       printf("rsa_decrypt_key %s", error_to_string(err));
+       return EXIT_FAILURE;
+   }
+   /* if all went well pt == pt2, l2 == 16, res == 1 */
+}
+\end{verbatim}
+
 \chapter{Password Based Cryptography}
 \section{PKCS \#5}
 In order to securely handle user passwords for the purposes of creating session keys and chaining IVs the PKCS \#5 was drafted.   PKCS \#5
@@ -1817,6 +2283,7 @@
 people trying to brute force guess the password.  The higher the iteration counter the longer the delay.  This algorithm also requires a hash 
 algorithm and produces an output no longer than the output of the hash.  
 
+\index{pkcs\_5\_alg1()}
 \begin{alltt}
 int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, 
                 const unsigned char *salt, 
@@ -1836,6 +2303,7 @@
 hash functions output.  As such it can easily be used to derive session keys for ciphers and MACs as well initial vectors as required
 from a single password and invokation of this algorithm.
 
+\index{pkcs\_5\_alg2()}
 \begin{alltt}
 int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, 
                 const unsigned char *salt,     unsigned long salt_len,
@@ -1878,161 +2346,6 @@
 \}
 \end{alltt}
 
-\chapter{RSA Routines}
-
-\textbf{Note: } \textit{This chapter has been marked for removal.  In particular any function that uses the LibTomCrypt style 
-RSA padding (e.g. rsa\_pad() rsa\_signpad())  will be removed in the v0.96 release cycle.  The functions like rsa\_make\_key() and
-rsa\_exptmod() will stay but may be slightly modified. }
-
-\section{Background}
-
-RSA is a public key algorithm that is based on the inability to find the ``e-th'' root modulo a composite of unknown 
-factorization.  Normally the difficulty of breaking RSA is associated with the integer factoring problem but they are
-not strictly equivalent.
-
-The system begins with with two primes $p$ and $q$ and their product $N = pq$.  The order or ``Euler totient'' of the
-multiplicative sub-group formed modulo $N$ is given as $\phi(N) = (p - 1)(q - 1)$ which can be reduced to 
-$\mbox{lcm}(p - 1, q - 1)$.  The public key consists of the composite $N$ and some integer $e$ such that 
-$\mbox{gcd}(e, \phi(N)) = 1$.  The private key consists of the composite $N$ and the inverse of $e$ modulo $\phi(N)$ 
-often simply denoted as $de \equiv 1\mbox{ }(\mbox{mod }\phi(N))$.
-
-A person who wants to encrypt with your public key simply forms an integer (the plaintext) $M$ such that 
-$1 < M < N-2$ and computes the ciphertext $C = M^e\mbox{ }(\mbox{mod }N)$.  Since finding the inverse exponent $d$
-given only $N$ and $e$ appears to be intractable only the owner of the private key can decrypt the ciphertext and compute
-$C^d \equiv \left (M^e \right)^d \equiv M^1 \equiv M\mbox{ }(\mbox{mod }N)$.  Similarly the owner of the private key 
-can sign a message by ``decrypting'' it.  Others can verify it by ``encrypting'' it.  
-
-Currently RSA is a difficult system to cryptanalyze provided that both primes are large and not close to each other.  
-Ideally $e$ should be larger than $100$ to prevent direct analysis.  For example, if $e$ is three and you do not pad
-the plaintext to be encrypted than it is possible that $M^3 < N$ in which case finding the cube-root would be trivial.  
-The most often suggested value for $e$ is $65537$ since it is large enough to make such attacks impossible and also well 
-designed for fast exponentiation (requires 16 squarings and one multiplication).
-
-It is important to pad the input to RSA since it has particular mathematical structure.  For instance  
-$M_1^dM_2^d = (M_1M_2)^d$ which can be used to forge a signature.  Suppose $M_3 = M_1M_2$ is a message you want
-to have a forged signature for.  Simply get the signatures for $M_1$ and $M_2$ on their own and multiply the result
-together.  Similar tricks can be used to deduce plaintexts from ciphertexts.  It is important not only to sign 
-the hash of documents only but also to pad the inputs with data to remove such structure.  
-
-\section{Core Functions}
-
-For RSA routines a single ``rsa\_key'' structure is used.  To make a new RSA key call:
-\index{rsa\_make\_key()}
-\begin{verbatim}
-int rsa_make_key(prng_state *prng, 
-                 int wprng, int size, 
-                 long e, rsa_key *key);
-\end{verbatim}
-
-Where ``wprng'' is the index into the PRNG descriptor array.  ``size'' is the size in bytes of the RSA modulus desired.
-``e'' is the encryption exponent desired, typical values are 3, 17, 257 and 65537.  I suggest you stick with 65537 since its big
-enough to prevent trivial math attacks and not super slow.  ``key'' is where the key is placed.  All keys must be at 
-least 128 bytes and no more than 512 bytes in size (\textit{that is from 1024 to 4096 bits}).
-
-Note that the ``rsa\_make\_key()'' function allocates memory at runtime when you make the key.  Make sure to call 
-``rsa\_free()'' (see below) when you are finished with the key.  If ``rsa\_make\_key()'' fails it will automatically 
-free the ram allocated itself.
-
-There are three types of RSA keys.  The types are {\bf PK\_PRIVATE\_OPTIMIZED}, {\bf PK\_PRIVATE} and {\bf PK\_PUBLIC}.  The first
-two are private keys where the ``optimized'' type uses the Chinese Remainder Theorem to speed up decryption/signatures.  By 
-default all new keys are of the ``optimized'' type.  The non-optimized private type is provided for backwards compatibility
-as well as to save space since the optimized key requires about four times as much memory.
-
-To do raw work with the RSA function call:
-\index{rsa\_exptmod()}
-\begin{verbatim}
-int rsa_exptmod(const unsigned char *in, unsigned long inlen, 
-                unsigned char *out, unsigned long *outlen, 
-                int which, rsa_key *key);
-\end{verbatim}
-This loads the bignum from ``in'' as a big endian word in the format PKCS specifies, raises it to either ``e'' or ``d'' and stores the result
-in ``out'' and the size of the result in ``outlen''. ``which'' is set to {\bf PK\_PUBLIC} to use ``e'' 
-(i.e. for encryption/verifying) and set to {\bf PK\_PRIVATE} to use ``d'' as the exponent (i.e. for decrypting/signing).
-
-Note that this function does not perform padding on the input (as per PKCS).  So if you send in ``0000001'' you will
-get ``01'' back (when you do the opposite operation).  Make sure you pad properly which usually involves setting the msb to
-a non-zero value.
-
-\section{Packet Routines}
-To encrypt or decrypt a symmetric key using RSA the following functions are provided.  The idea is that you make up
-a random symmetric key and use that to encode your message.  By RSA encrypting the symmetric key you can send it to a
-recipient who can RSA decrypt it and symmetrically decrypt the message.
-\begin{verbatim}
-int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
-                          unsigned char *outkey, unsigned long *outlen,
-                          prng_state *prng, int wprng, rsa_key *key);
-\end{verbatim}
-This function is used to RSA encrypt a symmetric to share with another user.  The symmetric key and its length are
-passed as ``inkey'' and ``inlen'' respectively.  The symmetric key is limited to a range of 8 to 32 bytes 
-(\textit{64 to 256 bits}).  The RSA encrypted packet is stored in ``outkey'' and will be of length ``outlen'' bytes.  The
-value of ``outlen'' must be originally set to the size of the output buffer. 
-
-\begin{verbatim}
-int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, 
-                          unsigned char *outkey, unsigned long *keylen, 
-                          rsa_key *key);
-\end{verbatim}
-
-This function will decrypt an RSA packet to retrieve the original symmetric key encrypted with rsa\_encrypt\_key().  
-Similarly to sign or verify a hash of a message the following two messages are provided.  The idea is to hash your message 
-then use these functions to RSA sign the hash.  
-\begin{verbatim}
-int rsa_sign_hash(const unsigned char *in,  unsigned long inlen, 
-                        unsigned char *out, unsigned long *outlen, 
-                        rsa_key *key);
-
-int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
-                    const unsigned char *hash, int *stat, rsa_key *key);
-\end{verbatim}
-For ``rsa\_sign\_hash'' the input is intended to be the hash of a message the user wants to sign.  The output is the 
-RSA signed packet which ``rsa\_verify\_hash'' can verify.  For the verification function ``sig'' is the RSA signature
-and ``hash'' is the hash of the message.  The integer ``stat'' is set to non-zero if the signature is valid or zero 
-otherwise.
-
-To import/export RSA keys as a memory buffer (e.g. to store them to disk) call:
-\begin{verbatim}
-int rsa_export(unsigned char *out, unsigned long *outlen, 
-               int type, rsa_key *key);
-
-int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
-\end{verbatim}
-
-The ``type'' parameter is {\bf PK\_PUBLIC}, {\bf PK\_PRIVATE} or {\bf PK\_PRIVATE\_OPTIMIZED} to export either a public or 
-private key.  The latter type will export a key with the optimized parameters.  To free the memory used by an RSA key call:
-\index{rsa\_free()}
-\begin{verbatim}
-void rsa_free(rsa_key *key);
-\end{verbatim}
-
-Note that if the key fails to ``rsa\_import()'' you do not have to free the memory allocated for it.
-
-\section{Remarks}
-It is important that you match your RSA key size with the function you are performing.  The internal padding for both
-signatures and encryption triple the size of the plaintext.  This means to encrypt or sign
-a message of N bytes you must have a modulus of 1+3N bytes.  Note that this doesn't affect the length of the plaintext 
-you pass into functions like rsa\_encrypt().  This restriction applies only to data that is passed through the
-internal RSA routines directly directly.
-
-The following table gives the size requirements for various hashes.
-\begin{center}
-\begin{tabular}{|c|c|c|}
-      \hline Name & Size of Message Digest (bytes) & RSA Key Size (bits)\\
-      \hline SHA-512 & 64 & 1544\\
-      \hline SHA-384 & 48 & 1160 \\
-      \hline SHA-256 & 32 & 776\\
-      \hline TIGER-192 & 24 & 584\\
-      \hline SHA-1 & 20 & 488\\
-      \hline MD5 & 16 & 392\\
-      \hline MD4 & 16 & 392\\
-      \hline
-\end{tabular}
-\end{center}
-
-The symmetric ciphers will use at a maximum a 256-bit key which means at the least a 776-bit RSA key is 
-required to use all of the symmetric ciphers with the RSA routines. If you want to use any of the large size 
-message digests (SHA-512 or SHA-384) you will have to use a larger key.  Or to be simple just make 2048-bit or larger
-keys.  None of the hashes will have problems with such key sizes.
-
 \chapter{Diffie-Hellman Key Exchange}
 
 \section{Background}
@@ -2224,6 +2537,7 @@
 \section{DH Packet}
 Similar to the RSA related functions there are functions to encrypt or decrypt symmetric keys using the DH public key
 algorithms.  
+\index{dh\_encrypt\_key()} \index{dh\_decrypt\_key()}
 \begin{verbatim}
 int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
                          unsigned char *out,  unsigned long *len, 
@@ -2240,6 +2554,7 @@
 as the symmetric key you are trying to share.
 
 Similar to the RSA system you can sign and verify a hash of a message.
+\index{dh\_sign\_hash()} \index{dh\_verify\_hash()}
 \begin{verbatim}
 int dh_sign_hash(const unsigned char *in,  unsigned long inlen,
                        unsigned char *out, unsigned long *outlen,
@@ -2334,6 +2649,8 @@
 \section{ECC Packet}
 Similar to the RSA API there are two functions which encrypt and decrypt symmetric keys using the ECC public key
 algorithms.
+
+\index{ecc\_encrypt\_key()} \index{ecc\_decrypt\_key()}
 \begin{verbatim}
 int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
                           unsigned char *out,  unsigned long *len, 
@@ -2351,6 +2668,7 @@
 as the symmetric key you are trying to share.
 
 There are also functions to sign and verify the hash of a message.
+\index{ecc\_sign\_hash()} \index{ecc\_verify\_hash()}
 \begin{verbatim}
 int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
                         unsigned char *out, unsigned long *outlen,
@@ -2409,6 +2727,7 @@
 \end{center}
 
 When you are finished with a DSA key you can call the following function to free the memory used.
+\index{dsa\_free()}
 \begin{verbatim}
 void dsa_free(dsa_key *key);
 \end{verbatim}
@@ -2447,6 +2766,7 @@
 
 The following function will perform these tests.
 
+\index{dsa\_verify\_key()}
 \begin{verbatim}
 int dsa_verify_key(dsa_key *key, int *stat);
 \end{verbatim}
@@ -2459,6 +2779,7 @@
 \section{Signatures}
 To generate a DSA signature call the following function
 
+\index{dsa\_sign\_hash()}
 \begin{verbatim}
 int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
                         unsigned char *out, unsigned long *outlen,
@@ -2471,6 +2792,7 @@
 
 To verify a hash created with that function use the following function
 
+\index{dsa\_verify\_hash()} 
 \begin{verbatim}
 int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
                     const unsigned char *hash, unsigned long inlen, 
@@ -2482,6 +2804,7 @@
 \section{Import and Export}
 
 To export a DSA key so that it can be transported use the following function
+\index{dsa\_export()}
 \begin{verbatim}
 int dsa_export(unsigned char *out, unsigned long *outlen, 
                int type, 
@@ -2493,6 +2816,7 @@
 
 To import an exported DSA key use the following function
 
+\index{dsa\_import()}
 \begin{verbatim}
 int dsa_import(const unsigned char *in, unsigned long inlen, 
                dsa_key *key);
@@ -2501,239 +2825,6 @@
 This will import the DSA key from the buffer ``in'' of length ``inlen'' to the ``key''.  If the process fails the function
 will automatically free all of the heap allocated in the process (you don't have to call dsa\_free()).  
 
-\chapter{Public Keyrings}
-\section{Introduction}
-In order to simplify the usage of the public key algorithms a set of keyring routines have been developed.  They let the 
-developer manage asymmetric keys by providing load, save, export, import routines as well as encrypt, decrypt, sign, verify
-routines in a unified API.  That is all three types of PK systems can be used within the same keyring with the same API.
-
-To define types of keys there are four enumerations used globaly:
-\begin{verbatim}
-enum {
-   NON_KEY=0,
-   RSA_KEY,
-   DH_KEY,
-   ECC_KEY
-};
-\end{verbatim}
-
-To make use of the system the developer has to know how link-lists work.  The main structure that the keyring routines use 
-is the ``pk\_key'' defined as:
-\begin{small}
-\begin{verbatim}
-typedef struct Pk_key {
-    int     key_type,             /* PUBLIC, PRIVATE, PRIVATE_OPTIMIZED */
-            system;               /* RSA, ECC or DH ?   */
-
-    char    name[MAXLEN],         /* various info's about this key */
-            email[MAXLEN],
-            description[MAXLEN];
-
-    unsigned long ID;             /* CRC32 of the name/email/description together */
-
-    _pk_key key;
-
-    struct Pk_key  *next;         /* linked list chain */
-} pk_key;
-\end{verbatim}
-\end{small}
-
-The list is chained via the ``next'' member and terminated with the node of the list that has ``system'' equal to 
-{\bf NON\_KEY}.
-
-\section{The Keyring API}
-To initialize a blank keyring the function ``kr\_init()'' is used.
-\begin{verbatim}
-int kr_init(pk_key **pk);
-\end{verbatim}
-You pass it a pointer to a pointer of type ``pk\_key'' where it will allocate ram for one node of the keyring and sets the
-pointer.
-
-Now instead of calling the PK specific ``make\_key'' functions there is one function that can make all three types of keys.
-\begin{verbatim}
-int kr_make_key(pk_key *pk, prng_state *prng, int wprng, 
-                int system, int keysize, const char *name,
-                const char *email, const char *description);
-\end{verbatim}
-The ``name'', ``email'' and ``description'' parameters are simply little pieces of information that you can tag along with a
-key.  They can each be either blank or any string less than 256 bytes.  ``system'' is one of the enumeration elements, that
-is {\bf RSA\_KEY}, {\bf DH\_KEY} or {\bf ECC\_KEY}.  ``keysize'' is the size of the key you desire which is regulated by
-the individual systems, for example, RSA keys are limited in keysize from 128 to 512 bytes.
-
-To find keys along a keyring there are two functions provided:
-\begin{verbatim}
-pk_key *kr_find(pk_key *pk, unsigned long ID);
-
-pk_key *kr_find_name(pk_key *pk, const char *name);
-\end{verbatim}
-The first searches by the 32-bit ID provided and the latter checks the name against the keyring.  They both return a pointer
-to the node in the ring of a match or {\bf NULL} if no match is found.
-
-To export or import a single node of a keyring the two functions are provided:
-\begin{verbatim}
-int kr_export(pk_key *pk, unsigned long ID, int key_type, 
-              unsigned char *out, unsigned long *outlen);
-
-int kr_import(pk_key *pk, const unsigned char *in);
-\end{verbatim}
-The export function exports the key with an ID provided and of a specific type much like the normal PK export routines.  The
-``key\_type'' is one of {\bf PK\_PUBLIC} or {\bf PK\_PRIVATE}.  In this function with RSA keys the type 
-{\bf PK\_PRIVATE\_OPTIMIZED} is the same as the {\bf PK\_PRIVATE} type.  The import function will read in a packet and 
-add it to the keyring.  
-
-To load and save whole keyrings from disk:
-\begin{verbatim}
-int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr);
-
-int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr);
-\end{verbatim}
-Both take file pointers to allow the user to pre-append data to the stream.  The ``ctr'' parameter should be setup with 
-``ctr\_start'' or set to NULL.  This parameter lets the user encrypt the keyring as its written to disk, if it is set
-to NULL the data is written without being encrypted.  The load function assumes the list has not been initialized yet 
-and will reset the pointer given to it.
-
-There are the four encrypt, decrypt, sign and verify functions as well
-\begin{verbatim}
-int kr_encrypt_key(pk_key *pk, unsigned long ID, 
-                   const unsigned char *in, unsigned long inlen,
-                   unsigned char *out, unsigned long *outlen,
-                   prng_state *prng, int wprng, int hash);
-
-int kr_decrypt_key(pk_key *pk, const unsigned char *in,
-                   unsigned char *out, unsigned long *outlen);
-\end{verbatim}
-
-The kr\_encrypt\_key() routine is designed to encrypt a symmetric key with a specified users public key.  The symmetric
-key is then used with a block cipher to encode the message.  The recipient can call kr\_decrypt\_key() to get the original
-symmetric key back and decode the message.  The hash specified must produce a message digest longer than symmetric key 
-provided.  
-
-\begin{verbatim}
-int kr_sign_hash(pk_key *pk, unsigned long ID, 
-                 const unsigned char *in, unsigned long inlen,
-                 unsigned char *out, unsigned long *outlen,
-                 prng_state *prng, int wprng);
-
-int kr_verify_hash(pk_key *pk, const unsigned char *in, 
-                   const unsigned char *hash, unsigned long hashlen,
-                   int *stat);
-\end{verbatim}
-
-Similar to the two previous these are used to sign a message digest or verify one.  This requires hashing the message
-first then passing the output in. 
-
-To delete keys and clear rings there are:
-\begin{verbatim}
-int kr_del(pk_key **_pk, unsigned long ID);
-int kr_clear(pk_key **pk);
-\end{verbatim}
-``kr\_del'' will try to remove a key with a given ID from the ring and ``kr\_clear'' will completely empty a list and free
-the memory associated with it.  Below is small example using the keyring API:
-
-\begin{small}
-\begin{verbatim}
-#include <mycrypt.h>
-int main(void)
-{
-   pk_key *kr;
-   unsigned char buf[4096], buf2[4096];
-   unsigned long len;
-   int err;
-
-   /* make a new list */
-   if ((err = kr_init(&kr)) != CRYPT_OK) {
-      printf("kr_init: %s\n", error_to_string(err));
-      exit(-1);
-   }
-
-   /* add a key to it */
-   register_prng(&sprng_desc);
-   if ((err = kr_make_key(kr, NULL, find_prng("sprng"), RSA_KEY, 128, 
-                "TomBot", "[email protected]", "test key")) == CRYPT_OK) {
-      printf("kr_make_key: %s\n", error_to_string(err));
-      exit(-1);
-   }
-
-   /* export the first key */
-   len = sizeof(buf);
-   if ((err = kr_export(kr, kr->ID, PK_PRIVATE, buf, &len)) != CRYPT_OK) {
-      printf("kr_export: %s\n", error_to_string(err));
-      exit(-1);
-   }
-
-   /* ... */
-}  
-\end{verbatim}
-\end{small}
-
-\chapter{$GF(2^w)$ Math Routines}
-
-The library provides a set of polynomial-basis $GF(2^w)$ routines to help facilitate algorithms such as ECC over such
-fields.  Note that the current implementation of ECC in the library is strictly over the integers only.  The routines
-are simple enough to use for other purposes outside of ECC.  
-
-At the heart of all of the GF routines is the data type ``gf\_int'.  It is simply a type definition for an array of 
-$L$ 32-bit words.  You can configure the maximum size $L$ of the ``gf\_int'' type by opening the file ``mycrypt.h'' and 
-changing ``LSIZE''.  Note that if you set it to $n$ then you can only multiply upto two $n \over 2$ bit polynomials without
-an overflow.  The type ``gf\_intp'' is associated with a pointer to an ``unsigned long'' as required in the algorithms.
-
-There are no initialization routines for ``gf\_int'' variables and you can simply use them after declaration.  There are five
-low level functions:
-\index{gf\_copy()} \index{gf\_zero()} \index{gf\_iszero()} \index{gf\_isone()} 
-\index{gf\_deg()} 
-\begin{verbatim}
-void gf_copy(gf_intp a, gf_intp b);
-void gf_zero(gf_intp a);
-int gf_iszero(gf_intp a);
-int gf_isone(gf_intp a);
-int gf_deg(gf_intp a);
-\end{verbatim}
-There are all fairly self-explanatory.  ``gf\_copy(a, b)'' copies the contents of ``a'' into ``b''.  ``gf\_zero()'' simply
-zeroes the entire polynomial.  ``gf\_iszero()'' tests to see if the polynomial is all zero and ``gf\_isone()'' tests to see
-if the polynomial is equal to the multiplicative identity.  ``gf\_deg()'' returns the degree of the polynomial or $-1$ if its
-a zero polynomial.
-
-There are five core math routines as well:
-\index{gf\_shl()} \index{gf\_shr()} \index{gf\_add()} \index{gf\_mul()} \index{gf\_div()} 
-\begin{verbatim}
-void gf_shl(gf_intp a, gf_intp b);
-void gf_shr(gf_intp a, gf_intp b);
-void gf_add(gf_intp a, gf_intp b, gf_intp c);
-void gf_mul(gf_intp a, gf_intp b, gf_intp c);
-void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r);
-\end{verbatim}
-
-Which are all fairly obvious.  ``gf\_shl(a,b)'' multiplies the polynomial ``a'' by $x$ and stores it in ``b''.  
-``gf\_shl(a,b)'' divides the polynomial ``a'' by $x$ and stores it in ``b''.  ``gf\_add(a,b,c)'' adds the polynomial
-``a'' to ``b'' and stores the sum in ``c''.  Similarly for ``gf\_mul(a,b,c)''.  The ``gf\_div(a,b,q,r)'' function divides
-``a'' by ``b'' and stores the quotient in ``q'' and the remainder in ``r''.
-
-There are six number theoretic functions as well:
-\index{gf\_mod()} \index{gf\_mulmod()} \index{gf\_invmod()} \index{gf\_gcd()} \index{gf\_is\_prime()} 
-\index{gf\_sqrt()}
-\begin{verbatim}
-void gf_mod(gf_intp a, gf_intp m, gf_intp b);
-void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c);
-void gf_invmod(gf_intp A, gf_intp M, gf_intp B);
-void gf_sqrt(gf_intp a, gf_intp m, gf_intp b);
-void gf_gcd(gf_intp A, gf_intp B, gf_intp c);
-int gf_is_prime(gf_intp a);
-\end{verbatim}
-
-Which all work similarly except for  ``gf\_mulmod(a,b,m,c)'' which computes $c = ab\mbox{ }(\mbox{mod }m)$.  The 
-``gf\_is\_prime()'' function returns one if the polynomial is primitive, otherwise it returns zero.
-
-Finally to read/store a ``gf\_int'' in a binary string use:
-\index{gf\_size()} \index{gf\_toraw()} \index{gf\_readraw()} 
-\begin{verbatim}
-int gf_size(gf_intp a);
-void gf_toraw(gf_intp a, unsigned char *dst);
-void gf_readraw(gf_intp a, unsigned char *str, int len);
-\end{verbatim}
-Where ``gf\_size()'' returns the size in bytes required for the data.  ``gf\_toraw(a,b)'' stores the polynomial in ``b''
-in binary format (endian neutral).  ``gf\_readraw(a,b,c)'' reads the binary string in ``b'' back.  Note that the length 
-you pass it must be the same as returned by ``gf\_size()'' or it will not load correctly.
-
 \chapter{Miscellaneous}
 \section{Base64 Encoding and Decoding}
 The library provides functions to encode and decode a RFC1521 base64 coding scheme.  This means that it can decode what it 
@@ -3037,4 +3128,6 @@
 When this is defined some of the code such as the Rijndael and SAFER+ ciphers are replaced with smaller code variants.
 These variants are slower but can save quite a bit of code space.
 
+\input{crypt.ind}
+
 \end{document}
--- a/crypt_hash_descriptor.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/crypt_hash_descriptor.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,17 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-#include "mycrypt.h"
-
-struct _hash_descriptor hash_descriptor[TAB_SIZE] = {
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
-{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ctr_getiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CTR
+
+int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(ctr != NULL);
+   if ((unsigned long)ctr->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, ctr->ctr, ctr->blocklen);
+   *len = ctr->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ctr_setiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,43 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef CTR
+
+int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
+{
+   int err;
+   
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(ctr != NULL);
+
+   /* bad param? */
+   if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
+      return err;
+   }
+   
+   if (len != (unsigned long)ctr->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* set IV */
+   memcpy(ctr->ctr, IV, len);
+   
+   /* force next block */
+   ctr->padlen = 0;
+   cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
+   
+   return CRYPT_OK;
+}
+
+#endif 
+
--- a/demos/small.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/demos/small.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,11 +0,0 @@
-// small demo app that just includes a cipher/hash/prng
-
-#include <mycrypt.h>
-
-int main(void)
-{
-   register_cipher(&rijndael_desc);
-   register_prng(&yarrow_desc);
-   register_hash(&sha256_desc);
-   return 0;
-}
--- a/demos/test.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/demos/test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1202,69 +1202,6 @@
 }
 #endif
 
-#ifdef GF
-void
-gf_tests (void)
-{
-  gf_int  a, b, c, d;
-  int     n;
-  unsigned char buf[1024];
-
-  printf ("GF tests\n");
-  gf_zero (a);
-  gf_zero (b);
-  gf_zero (c);
-  gf_zero (d);
-
-  /* a == 0x18000000b */
-  a[1] = 1;
-  a[0] = 0x8000000bUL;
-
-  /* b == 0x012345678 */
-  b[0] = 0x012345678UL;
-
-  /* find 1/b mod a */
-  gf_invmod (b, a, c);
-
-  /* find 1/1/b mod a */
-  gf_invmod (c, a, d);
-
-  /* display them */
-  printf ("  %08lx %08lx\n", c[0], d[0]);
-
-  /* store as binary string */
-  n = gf_size (a);
-  printf ("  a takes %d bytes\n", n);
-  gf_toraw (a, buf);
-  gf_readraw (a, buf, n);
-  printf ("  a == %08lx%08lx\n", a[1], a[0]);
-
-  /* primality testing */
-  gf_zero (a);
-  a[0] = 0x169;
-  printf ("  GF prime: %s, ", gf_is_prime (a) ? "passed" : "failed");
-  a[0] = 0x168;
-  printf ("  %s\n", gf_is_prime (a) ? "failed" : "passed");
-
-  /* test sqrt code */
-  gf_zero (a);
-  a[1] = 0x00000001;
-  a[0] = 0x8000000bUL;
-  gf_zero (b);
-  b[0] = 0x12345678UL;
-
-  gf_sqrt (b, a, c);
-  gf_mulmod (c, c, a, b);
-  printf ("  (%08lx)^2 = %08lx (mod %08lx%08lx) \n", c[0], b[0], a[1], a[0]);
-}
-#else
-void
-gf_tests (void)
-{
-  printf ("GF not compiled in\n");
-}
-#endif
-
 #ifdef MPI
 void
 test_prime (void)
@@ -1390,299 +1327,6 @@
 #endif
 }
 
-#ifdef KR
-void
-kr_display (pk_key * kr)
-{
-  static const char *sys[] = { "NON-KEY", "RSA", "DH", "ECC" };
-  static const char *type[] = { "PRIVATE", "PUBLIC", "PRIVATE_OPTIMIZED" };
-
-  while (kr->system != NON_KEY) {
-    printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID,
-        sys[kr->system], type[kr->key_type], kr->name, kr->email,
-        kr->description);
-    kr = kr->next;
-  }
-  printf ("\n");
-}
-
-void
-kr_test_makekeys (pk_key ** kr)
-{
-  if ((errnum = kr_init (kr)) != CRYPT_OK) {
-    printf ("KR init error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a DH key */
-  printf ("KR: Making DH key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey",
-            "[email protected]", "dhkey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a ECC key */
-  printf ("KR: Making ECC key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey",
-            "[email protected]", "ecckey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* make a RSA key */
-  printf ("KR: Making RSA key...\n");
-  if ((errnum =
-       kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey",
-            "[email protected]", "rsakey one")) != CRYPT_OK) {
-    printf ("Make key error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-}
-
-void
-kr_test (void)
-{
-  pk_key *kr, *_kr;
-  unsigned char buf[8192], buf2[8192], buf3[8192];
-  unsigned long len;
-  int     i, j, stat;
-#ifndef NO_FILE
-  FILE   *f;
-#endif
-
-  kr_test_makekeys (&kr);
-
-  printf ("The original list:\n");
-  kr_display (kr);
-
-  for (i = 0; i < 3; i++) {
-    len = sizeof (buf);
-    if ((errnum = kr_export (kr, kr->ID, kr->key_type, buf, &len)) != CRYPT_OK) {
-      printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("Exported key was: %lu bytes\n", len);
-    if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
-      printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-    if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-      printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-  }
-
-  for (i = 0; i < 3; i++) {
-    len = sizeof (buf);
-    if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
-      printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("Exported key was: %lu bytes\n", len);
-    if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
-      printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-    if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-      printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    kr_display (kr);
-  }
-
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("Error clearing ring: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-
-/* TEST output to file */
-#ifndef NO_FILE
-
-  if ((errnum = kr_init (&kr)) != CRYPT_OK) {
-    printf ("KR init error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_test_makekeys (&kr);
-
-  /* save to file */
-  f = fopen ("ring.dat", "wb");
-  if ((errnum = kr_save (kr, f, NULL)) != CRYPT_OK) {
-    printf ("kr_save error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  fclose (f);
-
-  /* delete and load */
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("clear error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  f = fopen ("ring.dat", "rb");
-  if ((errnum = kr_load (&kr, f, NULL)) != CRYPT_OK) {
-    printf ("kr_load error %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  fclose (f);
-  remove ("ring.dat");
-  printf ("After load and save...\n");
-  kr_display (kr);
-
-  if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
-    printf ("clear error: %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-#endif
-
-/* test the packet encryption/sign stuff */
-  for (i = 0; i < 32; i++)
-    buf[i] = i;
-  kr_test_makekeys (&kr);
-  _kr = kr;
-  for (i = 0; i < 3; i++) {
-    printf ("Testing a key with system %d, type %d:\t", _kr->system,
-        _kr->key_type);
-    len = sizeof (buf2);
-    if ((errnum =
-     kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng,
-             find_prng ("yarrow"),
-             find_hash ("md5"))) != CRYPT_OK) {
-      printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    len = sizeof (buf3);
-    if ((errnum = kr_decrypt_key (kr, buf2, buf3, &len)) != CRYPT_OK) {
-      printf ("decrypt error, %d, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    if (len != 16 || memcmp (buf3, buf, 16)) {
-      printf ("kr_decrypt_key failed, %i, %lu\n", i, len);
-      exit (-1);
-    }
-    printf ("kr_encrypt_key passed, ");
-
-    len = sizeof (buf2);
-    if ((errnum =
-     kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng,
-               find_prng ("yarrow"))) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("kr_sign_hash: ");
-    if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("%s, ", stat ? "passed" : "failed");
-    buf[15] ^= 1;
-    if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
-      printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
-      exit (-1);
-    }
-    printf ("%s\n", (!stat) ? "passed" : "failed");
-    buf[15] ^= 1;
-
-    len = sizeof (buf);
-    if ((errnum =
-     kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf,
-             &len)) != CRYPT_OK) {
-      printf ("kr_fingerprint failed, %i, %lu\n", i, len);
-      exit (-1);
-    }
-    printf ("Fingerprint:  ");
-    for (j = 0; j < 20; j++) {
-      printf ("%02x", buf[j]);
-      if (j < 19)
-    printf (":");
-    }
-    printf ("\n\n");
-
-    _kr = _kr->next;
-  }
-
-/* Test encrypting/decrypting to a public key */
-/* first dump the other two keys */
-  kr_del (&kr, kr->ID);
-  kr_del (&kr, kr->ID);
-  kr_display (kr);
-
-  /* now export it as public and private */
-  len = sizeof (buf);
-  if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
-    printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* check boundaries */
-  memset (buf + len, 0, sizeof (buf) - len);
-
-  len = sizeof (buf2);
-  if ((errnum = kr_export (kr, kr->ID, PK_PRIVATE, buf2, &len)) != CRYPT_OK) {
-    printf ("Error exporting key  %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* check boundaries */
-  memset (buf2 + len, 0, sizeof (buf2) - len);
-
-  /* delete the key and import the public */
-  kr_clear (&kr);
-  kr_init (&kr);
-  kr_display (kr);
-  if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
-    printf ("Error importing key %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_display (kr);
-
-  /* now encrypt a buffer */
-  for (i = 0; i < 16; i++)
-    buf[i] = i;
-  len = sizeof (buf3);
-  if ((errnum =
-       kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng,
-               find_prng ("yarrow"),
-               find_hash ("md5"))) != CRYPT_OK) {
-    printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
-    exit (-1);
-  }
-
-  /* now delete the key and import the private one */
-  kr_clear (&kr);
-  kr_init (&kr);
-  kr_display (kr);
-  if ((errnum = kr_import (kr, buf2, len)) != CRYPT_OK) {
-    printf ("Error importing key %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-  kr_display (kr);
-
-  /* now decrypt */
-  len = sizeof (buf2);
-  if ((errnum = kr_decrypt_key (kr, buf3, buf2, &len)) != CRYPT_OK) {
-    printf ("decrypt error, %s\n", error_to_string (errnum));
-    exit (-1);
-  }
-
-  printf ("KR encrypt to public, decrypt with private: ");
-  if (len == 16 && !memcmp (buf2, buf, 16)) {
-    printf ("passed\n");
-  } else {
-    printf ("failed\n");
-  }
-
-  kr_clear (&kr);
-}
-#endif
-
 void
 test_errs (void)
 {
@@ -1840,13 +1484,13 @@
 
       /* decode it */
       l2 = sizeof(buf[2]);
-      if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2)) != CRYPT_OK) {
+      if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2, &res1)) != CRYPT_OK) {
          printf("OAEP decode: %s\n", error_to_string(err));
          exit(-1);
       }
 
-      if (l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
-         printf("Outsize == %lu, should have been %lu, msg contents follow.\n", l2, l3);
+      if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
+         printf("res == %d, Outsize == %lu, should have been %lu, msg contents follow.\n", res1, l2, l3);
          printf("ORIGINAL:\n");
          for (x = 0; x < l3; x++) {
              printf("%02x ", buf[0][x]);
@@ -1959,16 +1603,12 @@
   rng_tests ();
   test_prime();
 
-#ifdef KR
-  kr_test ();
-#endif
   dsa_tests();
   rsa_test ();
   pad_test ();
   ecc_tests ();
   dh_tests ();
 
-  gf_tests ();
   base64_test ();
 
   time_ecb ();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/base64_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,20 @@
+#include  "test.h"
+
+int base64_test(void)
+{
+   unsigned char in[64], out[256], tmp[64];
+   unsigned long x, l1, l2;
+   
+   for  (x = 0; x < 64; x++) {
+       yarrow_read(in, x, &test_yarrow);
+       l1 = sizeof(out);
+       DO(base64_encode(in, x, out, &l1));
+       l2 = sizeof(tmp);
+       DO(base64_decode(out, l1, tmp, &l2));
+       if (l2 != x || memcmp(tmp, in, x)) {
+           printf("base64  failed %lu %lu %lu", x, l1, l2);
+           return 1;
+       }
+   }
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/cipher_hash_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,20 @@
+/* test the ciphers and hashes using their built-in self-tests */
+
+#include "test.h"
+
+int cipher_hash_test(void)
+{
+   int x;
+   
+   /* test ciphers */
+   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+      DO(cipher_descriptor[x].test());
+   }
+   
+   /* test hashes */
+   for (x = 0; hash_descriptor[x].name != NULL; x++) {
+      DO(hash_descriptor[x].test());
+   }
+   
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/dh_tests.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,87 @@
+#include "test.h"
+
+int dh_tests (void)
+{
+  unsigned char buf[3][4096];
+  unsigned long x, y, z;
+  int           stat, stat2;
+  dh_key        usera, userb;
+
+  DO(dh_test());
+
+  /* make up two keys */
+  DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 96, &usera));
+  DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 96, &userb));
+
+  /* make the shared secret */
+  x = 4096;
+  DO(dh_shared_secret (&usera, &userb, buf[0], &x));
+
+  y = 4096;
+  DO(dh_shared_secret (&userb, &usera, buf[1], &y));
+  if (y != x) {
+    printf ("DH Shared keys are not same size.\n");
+    return 1;
+  }
+  if (memcmp (buf[0], buf[1], x)) {
+    printf ("DH Shared keys not same contents.\n");
+    return 1;
+  }
+
+  /* now export userb */
+  y = 4096;
+  DO(dh_export (buf[1], &y, PK_PUBLIC, &userb));
+	  dh_free (&userb);
+
+  /* import and make the shared secret again */
+  DO(dh_import (buf[1], y, &userb));
+  z = 4096;
+  DO(dh_shared_secret (&usera, &userb, buf[2], &z));
+
+  if (z != x) {
+    printf ("failed.  Size don't match?\n");
+    return 1;
+  }
+  if (memcmp (buf[0], buf[2], x)) {
+    printf ("Failed.  Content didn't match.\n");
+    return 1;
+  }
+  dh_free (&usera);
+  dh_free (&userb);
+
+/* test encrypt_key */
+  dh_make_key (&test_yarrow, find_prng ("yarrow"), 128, &usera);
+  for (x = 0; x < 16; x++) {
+    buf[0][x] = x;
+  }
+  y = sizeof (buf[1]);
+  DO(dh_encrypt_key (buf[0], 16, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("md5"), &usera));
+  zeromem (buf[0], sizeof (buf[0]));
+  x = sizeof (buf[0]);
+  DO(dh_decrypt_key (buf[1], y, buf[0], &x, &usera));
+  if (x != 16) {
+    printf ("Failed (length)\n");
+    return 1;
+  }
+  for (x = 0; x < 16; x++)
+    if (buf[0][x] != x) {
+      printf ("Failed (contents)\n");
+      return 1;
+    }
+
+/* test sign_hash */
+  for (x = 0; x < 16; x++) {
+     buf[0][x] = x;
+  }
+  x = sizeof (buf[1]);
+  DO(dh_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow		, find_prng ("yarrow"), &usera));
+  DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat, &usera));
+  buf[0][0] ^= 1;
+  DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera));
+  if (!(stat == 1 && stat2 == 0)) { 
+     printf("dh_sign/verify_hash %d %d", stat, stat2);
+     return 1;
+  }
+  dh_free (&usera);
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/dsa_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,51 @@
+#include "test.h"
+
+int dsa_test(void)
+{
+   unsigned char msg[16], out[1024], out2[1024];
+   unsigned long x, y;
+   int err, stat1, stat2;
+   dsa_key key, key2;
+
+   /* make a random key */
+   DO(dsa_make_key(&test_yarrow, find_prng("yarrow"), 20, 128, &key));
+
+   /* verify it */
+   DO(dsa_verify_key(&key, &stat1));
+   if (stat1 == 0) { printf("dsa_verify_key "); return 1; }
+
+   /* sign the message */
+   x = sizeof(out);
+   DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &test_yarrow, find_prng("yarrow"), &key));
+
+   /* verify it once */
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key));
+
+   /* Modify and verify again */
+   msg[0] ^= 1;
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key));
+   msg[0] ^= 1;
+   if (!(stat1 == 1 && stat2 == 0)) { printf("dsa_verify %d %d", stat1, stat2); return 1; }
+
+   /* test exporting it */
+   x = sizeof(out2);
+   DO(dsa_export(out2, &x, PK_PRIVATE, &key));
+   DO(dsa_import(out2, x, &key2));
+
+   /* verify a signature with it */
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
+   if (stat1 == 0) { printf("dsa_verify (import private) %d ", stat1); return 1; }
+   dsa_free(&key2);
+
+   /* export as public now */
+   x = sizeof(out2);
+   DO(dsa_export(out2, &x, PK_PUBLIC, &key));
+   DO(dsa_import(out2, x, &key2));
+   /* verify a signature with it */
+   DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
+   if (stat1 == 0) { printf("dsa_verify (import public) %d ", stat1); return 1; }
+   dsa_free(&key2);
+   dsa_free(&key);
+
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/ecc_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,89 @@
+#include "test.h"
+
+int ecc_tests (void)
+{
+  unsigned char buf[4][4096];
+  unsigned long x, y, z;
+  int           stat, stat2;
+  ecc_key usera, userb;
+	
+  DO(ecc_test ());
+
+  /* make up two keys */
+  DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 24, &usera));
+  DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 24, &userb));
+
+  /* make the shared secret */
+  x = 4096;
+  DO(ecc_shared_secret (&usera, &userb, buf[0], &x));
+
+  y = 4096;
+  DO(ecc_shared_secret (&userb, &usera, buf[1], &y));
+
+  if (y != x) {
+    printf ("ecc Shared keys are not same size.");
+    return 1;
+  }
+
+  if (memcmp (buf[0], buf[1], x)) {
+    printf ("ecc Shared keys not same contents.");
+    return 1;
+  }
+
+  /* now export userb */
+  y = 4096;
+  DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
+  ecc_free (&userb);
+
+  /* import and make the shared secret again */
+  DO(ecc_import (buf[1], y, &userb));
+
+  z = 4096;
+  DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
+
+  if (z != x) {
+    printf ("failed.  Size don't match?");
+    return 1;
+  }
+  if (memcmp (buf[0], buf[2], x)) {
+    printf ("Failed.  Content didn't match.");
+    return 1;
+  }
+  ecc_free (&usera);
+  ecc_free (&userb);
+
+/* test encrypt_key */
+  ecc_make_key (&test_yarrow, find_prng ("yarrow"), 20, &usera);
+  for (x = 0; x < 32; x++) {
+    buf[0][x] = x;
+  }
+  y = sizeof (buf[1]);
+  DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("sha256"), &usera));
+  zeromem (buf[0], sizeof (buf[0]));
+  x = sizeof (buf[0]);
+  DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &usera));
+  if (x != 32) {
+    printf ("Failed (length)");
+    return 1;
+  }
+  for (x = 0; x < 32; x++)
+    if (buf[0][x] != x) {
+      printf ("Failed (contents)");
+      return 1;
+    }
+/* test sign_hash */
+  for (x = 0; x < 16; x++) {
+    buf[0][x] = x;
+  }
+  x = sizeof (buf[1]);
+  DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow, find_prng ("yarrow"), &usera));
+  DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &usera));
+  buf[0][0] ^= 1;
+  DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera));
+  if (!(stat == 1 && stat2 == 0)) { 
+    printf("ecc_verify_hash failed");
+    return 1;
+  }
+  ecc_free (&usera);
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/mac_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,12 @@
+/* test pmac/omac/hmac */
+#include "test.h"
+
+int mac_test(void)
+{
+   DO(hmac_test());
+   DO(pmac_test());
+   DO(omac_test());
+   DO(eax_test());
+   DO(ocb_test());
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/makefile	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,13 @@
+# make test harness, it is good.
+CFLAGS += -Wall -W -Os -I../../ -I./
+
+default: test
+
+OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \
+pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o 
+
+test: $(OBJECTS)
+	$(CC) $(OBJECTS) -ltomcrypt -o test
+	
+clean:
+	rm -f test *.o *.obj *.exe *~	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/makefile.icc	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,14 @@
+# make test harness, it is good.
+CFLAGS += -O3 -xN -ip -I../../ -I./
+CC=icc
+
+default: test
+
+OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \
+pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o 
+
+test: $(OBJECTS)
+	$(CC) $(OBJECTS) -ltomcrypt -o test
+	
+clean:
+	rm -f test *.o *~	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/makefile.msvc	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,14 @@
+# make test harness, it is good.
+CFLAGS = $(CFLAGS) /W3 /Ox -I../../ -I./
+
+default: test.exe
+
+OBJECTS = test.obj cipher_hash_test.obj mac_test.obj modes_test.obj \
+pkcs_1_test.obj store_test.obj rsa_test.obj ecc_test.obj dsa_test.c dh_tests.obj 
+
+
+test.exe: $(OBJECTS)
+	cl $(OBJECTS) tomcrypt.lib advapi32.lib 
+	
+clean:
+	rm -f test.exe *.obj *~	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/modes_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,112 @@
+/* test CFB/OFB/CBC modes */
+#include "test.h"
+
+int modes_test(void)
+{
+   unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16];
+   int x, cipher_idx;
+   symmetric_CBC cbc;
+   symmetric_CFB cfb;
+   symmetric_OFB ofb;
+   symmetric_CTR ctr;
+   unsigned long l;
+   
+   /* make a random pt, key and iv */
+   yarrow_read(pt,  64, &test_yarrow);
+   yarrow_read(key, 16, &test_yarrow);
+   yarrow_read(iv,  16, &test_yarrow);
+   
+   /* get idx of AES handy */
+   cipher_idx = find_cipher("aes");
+   if (cipher_idx == -1) {
+      printf("test requires AES");
+      return 1;
+   }
+   
+   /* test CBC mode */
+   /* encode the block */
+   DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
+   l = sizeof(iv2);
+   DO(cbc_getiv(iv2, &l, &cbc));
+   if (l != 16 || memcmp(iv2, iv, 16)) {
+      printf("cbc_getiv failed");
+      return 1;
+   }
+   for (x = 0; x < 4; x++) {
+      DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc));
+   }
+   
+   /* decode the block */
+   DO(cbc_setiv(iv2, l, &cbc));
+   zeromem(tmp, sizeof(tmp));
+   for (x = 0; x < 4; x++) {
+      DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc));
+   }
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CBC failed");
+      return 1;
+   }
+   
+   /* test CFB mode */
+   /* encode the block */
+   DO(cfb_start(cipher_idx, iv, key, 16, 0, &cfb));
+   l = sizeof(iv2);
+   DO(cfb_getiv(iv2, &l, &cfb));
+   /* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */
+   if (l != 16) {
+      printf("cfb_getiv failed");
+      return 1;
+   }
+   DO(cfb_encrypt(pt, ct, 64, &cfb));
+   
+   /* decode the block */
+   DO(cfb_setiv(iv, l, &cfb));
+   zeromem(tmp, sizeof(tmp));
+   DO(cfb_decrypt(ct, tmp, 64, &cfb));
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CFB failed");
+      return 1;
+   }
+   
+   /* test OFB mode */
+   /* encode the block */
+   DO(ofb_start(cipher_idx, iv, key, 16, 0, &ofb));
+   l = sizeof(iv2);
+   DO(ofb_getiv(iv2, &l, &ofb));
+   if (l != 16 || memcmp(iv2, iv, 16)) {
+      printf("ofb_getiv failed");
+      return 1;
+   }
+   DO(ofb_encrypt(pt, ct, 64, &ofb));
+   
+   /* decode the block */
+   DO(ofb_setiv(iv2, l, &ofb));
+   zeromem(tmp, sizeof(tmp));
+   DO(ofb_decrypt(ct, tmp, 64, &ofb));
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("OFB failed");
+      return 1;
+   }
+   
+   /* test CTR mode */
+   /* encode the block */
+   DO(ctr_start(cipher_idx, iv, key, 16, 0, &ctr));
+   l = sizeof(iv2);
+   DO(ctr_getiv(iv2, &l, &ctr));
+   if (l != 16 || memcmp(iv2, iv, 16)) {
+      printf("ctr_getiv failed");
+      return 1;
+   }
+   DO(ctr_encrypt(pt, ct, 64, &ctr));
+   
+   /* decode the block */
+   DO(ctr_setiv(iv2, l, &ctr));
+   zeromem(tmp, sizeof(tmp));
+   DO(ctr_decrypt(ct, tmp, 64, &ctr));
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CTR failed");
+      return 1;
+   }
+         
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/pkcs_1_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,103 @@
+#include "test.h"
+
+int pkcs_1_test(void)
+{
+   unsigned char buf[3][128];
+   int res1, res2, res3, prng_idx, hash_idx;
+   unsigned long x, y, l1, l2, l3, i1, i2, lparamlen, saltlen, modlen;
+   static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
+
+   /* get hash/prng  */
+   hash_idx = find_hash("sha1");
+   prng_idx = find_prng("yarrow");
+   
+   if (hash_idx == -1 || prng_idx == -1) {
+      printf("pkcs_1 tests require sha1/yarrow");
+      return 1;
+   }   
+
+   /* do many tests */
+   for (x = 0; x < 10000; x++) {
+      zeromem(buf, sizeof(buf));
+
+      /* make a dummy message (of random length) */
+      l3 = (rand() & 31) + 8;
+      for (y = 0; y < l3; y++) buf[0][y] = rand() & 255;
+
+      /* random modulus len (v1.5 must be multiple of 8 though arbitrary sizes seem to work) */
+      modlen = 800 + 8 * (abs(rand()) % 28);
+
+      /* PKCS v1.5 testing (encryption) */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_v15_es_encode(buf[0], l3, modlen, &test_yarrow, prng_idx, buf[1], &l1));
+      DO(pkcs_1_v15_es_decode(buf[1], l1, modlen, buf[2], l3, &res1));
+      if (res1 != 1 || memcmp(buf[0], buf[2], l3)) {
+         printf("pkcs v1.5 encrypt failed %d, %lu, %lu ", res1, l1, l3);
+         return 1;
+      }
+
+      /* PKCS v1.5 testing (signatures) */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_v15_sa_encode(buf[0], l3, hash_idx, modlen, buf[1], &l1));
+      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res1));
+      buf[0][i1 = abs(rand()) % l3] ^= 1;
+      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res2));
+      buf[0][i1] ^= 1;
+      buf[1][i2 = abs(rand()) % l1] ^= 1;
+      DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res3));
+
+      if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
+         printf("pkcs v1.5 sign failed %d %d %d ", res1, res2, res3);
+         return 1;
+      }
+
+      /* pick a random lparam len [0..16] */
+      lparamlen = abs(rand()) % 17;
+
+      /* pick a random saltlen 0..16 */
+      saltlen   = abs(rand()) % 17;
+
+      /* PKCS #1 v2.0 supports modlens not multiple of 8 */
+      modlen = 800 + (abs(rand()) % 224);
+
+      /* encode it */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &test_yarrow, prng_idx, hash_idx, buf[1], &l1));
+
+      /* decode it */
+      l2 = sizeof(buf[2]);
+      DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1));
+
+      if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
+         printf("Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);
+         printf("ORIGINAL:\n");
+         for (x = 0; x < l3; x++) {
+             printf("%02x ", buf[0][x]);
+         }
+         printf("\nRESULT:\n");
+         for (x = 0; x < l2; x++) {
+             printf("%02x ", buf[2][x]);
+         }
+         printf("\n\n");
+         return 1;
+      }
+
+      /* test PSS */
+      l1 = sizeof(buf[1]);
+      DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &test_yarrow, prng_idx, hash_idx, modlen, buf[1], &l1));
+      DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1));
+      
+      buf[0][i1 = abs(rand()) % l3] ^= 1;
+      DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2));
+
+      buf[0][i1] ^= 1;
+      buf[1][i2 = abs(rand()) % l1] ^= 1;
+      DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3));
+
+      if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
+         printf("PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen);
+         return 1;
+      }
+   }
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/rsa_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,91 @@
+#include "test.h"
+
+int rsa_test(void)
+{
+   unsigned char in[1024], out[1024], tmp[1024];
+   rsa_key       key;
+   int           hash_idx, prng_idx, stat, stat2;
+   unsigned long len, len2;
+   static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
+      
+   hash_idx = find_hash("sha1");
+   prng_idx = find_prng("yarrow");
+   if (hash_idx == -1 || prng_idx == -1) {
+      printf("rsa_test requires SHA1 and yarrow");
+      return 1;
+   }
+   
+   /* make a random key/msg */
+   yarrow_read(in, 20, &test_yarrow);
+   
+   /* make a random key */
+   DO(rsa_make_key(&test_yarrow, prng_idx, 1024/8, 65537, &key));
+   
+   /* encrypt the key (without lparam) */
+   len  = sizeof(out);
+   len2 = sizeof(tmp);
+   DO(rsa_encrypt_key(in, 20, out, &len, NULL, 0, &test_yarrow, prng_idx, hash_idx, &key));
+   /* change a byte */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat2, &key));
+   /* change a byte back */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat, &key));
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_decrypt_key failed");
+      return 1;
+   }
+   if (len2 != 20 || memcmp(tmp, in, 20)) {
+      printf("rsa_decrypt_key mismatch len %lu", len2);
+      return 1;
+   }
+
+   /* encrypt the key (with lparam) */
+   len  = sizeof(out);
+   len2 = sizeof(tmp);
+   DO(rsa_encrypt_key(in, 20, out, &len, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &key));
+   /* change a byte */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat2, &key));
+   /* change a byte back */
+   out[0] ^= 1;
+   DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat, &key));
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_decrypt_key failed");
+      return 1;
+   }
+   if (len2 != 20 || memcmp(tmp, in, 20)) {
+      printf("rsa_decrypt_key mismatch len %lu", len2);
+      return 1;
+   }
+
+   /* sign a message (unsalted, lower cholestorol and Atkins approved) now */
+   len = sizeof(out);
+   DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 0, &key));
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat, &key));
+   /* change a byte */
+   in[0] ^= 1;
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat2, &key));
+   
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_verify_hash (unsalted) failed, %d, %d", stat, stat2);
+      return 1;
+   }
+
+   /* sign a message (salted) now */
+   len = sizeof(out);
+   DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 8, &key));
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat, &key));
+   /* change a byte */
+   in[0] ^= 1;
+   DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat2, &key));
+   
+   if (!(stat == 1 && stat2 == 0)) {
+      printf("rsa_verify_hash (salted) failed, %d, %d", stat, stat2);
+      return 1;
+   }
+   
+   /* free the key and return */
+   rsa_free(&key);
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/store_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,43 @@
+#include "test.h"
+
+int store_test(void)
+{
+  unsigned char buf[8];
+  unsigned long L;
+  ulong64 LL;
+
+  L = 0x12345678UL;
+  STORE32L (L, &buf[0]);
+  L = 0;
+  LOAD32L (L, &buf[0]);
+  if (L != 0x12345678UL) {
+    printf ("LOAD/STORE32 Little don't work");
+    return 1;
+  }
+  LL = CONST64 (0x01020304050607);
+  STORE64L (LL, &buf[0]);
+  LL = 0;
+  LOAD64L (LL, &buf[0])
+    if (LL != CONST64 (0x01020304050607)) {
+    printf ("LOAD/STORE64 Little don't work");
+    return 1;
+  }
+
+  L = 0x12345678UL;
+  STORE32H (L, &buf[0]);
+  L = 0;
+  LOAD32H (L, &buf[0]);
+  if (L != 0x12345678UL) {
+    printf ("LOAD/STORE32 High don't work, %08lx", L);
+    return 1;
+  }
+  LL = CONST64 (0x01020304050607);
+  STORE64H (LL, &buf[0]);
+  LL = 0;
+  LOAD64H (LL, &buf[0])
+    if (LL != CONST64 (0x01020304050607)) {
+    printf ("LOAD/STORE64 High don't work");
+    return 1;
+  }
+  return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,177 @@
+#include "test.h"
+
+test_entry tests[26];
+
+test_entry test_list[26] = { 
+
+/* test name          provides    requires             entry */
+{"store_test",             "a",         "",          store_test           },
+{"cipher_hash_test",       "b",        "a",          cipher_hash_test     },
+{"modes_test",             "c",        "b",          modes_test           },
+{"mac_test",               "d",        "c",          mac_test             },
+{"pkcs_1_test",            "e",        "b",          pkcs_1_test          },
+{"rsa_test",               "f",        "e",          rsa_test             },
+{"ecc_test",               "g",        "a",          ecc_tests            },
+{"dsa_test",               "h",        "a",          dsa_test             },
+{"dh_test",                "i",        "a",          dh_tests             },
+
+{NULL, NULL, NULL, NULL} 
+};
+
+prng_state test_yarrow;
+static int current_test;
+
+void run_cmd(int res, int line, char *file, char *cmd)
+{
+   if (res != CRYPT_OK) {
+      fprintf(stderr, "[%s]: %s (%d)\n%s:%d:%s\n", tests[current_test].name, error_to_string(res), res, file, line, cmd);
+      exit(EXIT_FAILURE);
+   }
+}
+
+void register_algs(void)
+{
+#ifdef RIJNDAEL
+  register_cipher (&aes_desc);
+#endif
+#ifdef BLOWFISH
+  register_cipher (&blowfish_desc);
+#endif
+#ifdef XTEA
+  register_cipher (&xtea_desc);
+#endif
+#ifdef RC5
+  register_cipher (&rc5_desc);
+#endif
+#ifdef RC6
+  register_cipher (&rc6_desc);
+#endif
+#ifdef SAFERP
+  register_cipher (&saferp_desc);
+#endif
+#ifdef TWOFISH
+  register_cipher (&twofish_desc);
+#endif
+#ifdef SAFER
+  register_cipher (&safer_k64_desc);
+  register_cipher (&safer_sk64_desc);
+  register_cipher (&safer_k128_desc);
+  register_cipher (&safer_sk128_desc);
+#endif
+#ifdef RC2
+  register_cipher (&rc2_desc);
+#endif
+#ifdef DES
+  register_cipher (&des_desc);
+  register_cipher (&des3_desc);
+#endif
+#ifdef CAST5
+  register_cipher (&cast5_desc);
+#endif
+#ifdef NOEKEON
+  register_cipher (&noekeon_desc);
+#endif
+#ifdef SKIPJACK
+  register_cipher (&skipjack_desc);
+#endif
+#ifdef TIGER
+  register_hash (&tiger_desc);
+#endif
+#ifdef MD2
+  register_hash (&md2_desc);
+#endif
+#ifdef MD4
+  register_hash (&md4_desc);
+#endif
+#ifdef MD5
+  register_hash (&md5_desc);
+#endif
+#ifdef SHA1
+  register_hash (&sha1_desc);
+#endif
+#ifdef SHA256
+  register_hash (&sha256_desc);
+#endif
+#ifdef SHA224
+  register_hash (&sha224_desc);
+#endif
+#ifdef SHA384
+  register_hash (&sha384_desc);
+#endif
+#ifdef SHA512
+  register_hash (&sha512_desc);
+#endif
+#ifdef RIPEMD128
+  register_hash (&rmd128_desc);
+#endif
+#ifdef RIPEMD160
+  register_hash (&rmd160_desc);
+#endif
+#ifdef WHIRLPOOL
+  register_hash (&whirlpool_desc);
+#endif
+
+   if (register_prng(&yarrow_desc) == -1) {
+      printf("Error registering yarrow PRNG\n");
+      exit(-1);
+   }
+
+   if (register_prng(&sprng_desc) == -1) {
+      printf("Error registering sprng PRNG\n");
+      exit(-1);
+   }
+}
+
+/* sort tests based on their requirement/services.  Helps make sure dependencies are tested first */
+void sort(void)
+{
+   unsigned x, y, z, a, pidx[26];
+      
+   /* find out where things are provided */
+   zeromem(pidx, sizeof(pidx));   
+   z = 0;
+   do { 
+      y = 0;
+      for (x = 0; test_list[x].name != NULL; x++) {
+        if (test_list[x].entry == NULL) continue;
+        if (strlen(test_list[x].prov) == 0) {
+           y = 1;
+           tests[z++] = test_list[x]; test_list[x].entry = NULL;
+           pidx[test_list[x].prov[0]-'a'] = 1;
+           break;
+        } else {
+           for (a = 0; a < strlen(test_list[x].req); a++) {
+               if (pidx[test_list[x].req[a]-'a'] == 0) break;
+           }
+           if (a == strlen(test_list[x].req)) {
+              y = 1;
+              tests[z++] = test_list[x]; test_list[x].entry = NULL;
+              pidx[test_list[x].prov[0]-'a'] = 1;
+              break;
+           }
+        }
+      }
+   } while (y == 1);
+}
+   
+int main(void)
+{
+   printf("Built with\n%s\n", crypt_build_settings);
+
+   srand(time(NULL));
+   sort();
+   register_algs();
+      
+   // start dummy yarrow for internal use 
+   DO(yarrow_start(&test_yarrow));
+   DO(yarrow_add_entropy("test", 4, &test_yarrow));
+   DO(yarrow_ready(&test_yarrow));
+
+   // do tests
+   for (current_test = 0; tests[current_test].name != NULL; current_test++) {
+       printf("[%-20s]: ", tests[current_test].name); fflush(stdout);
+       printf("\t%s\n", tests[current_test].entry()==0?"passed":"failed"); 
+   }
+   
+   return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/test/test.h	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,29 @@
+#ifndef __TEST_H_
+#define __TEST_H_
+
+#include "mycrypt.h"
+
+typedef struct {
+    char *name, *prov, *req;
+    int  (*entry)(void);
+} test_entry;
+
+extern prng_state test_yarrow;
+
+void run_cmd(int res, int line, char *file, char *cmd);
+#define DO(x) run_cmd((x), __LINE__, __FILE__, #x)
+
+
+
+/* TESTS */
+int cipher_hash_test(void);
+int modes_test(void);
+int mac_test(void);
+int pkcs_1_test(void);
+int store_test(void);
+int rsa_test(void);
+int ecc_tests(void);
+int dsa_test(void);
+int dh_tests(void);
+
+#endif
Binary file doc/crypt.pdf has changed
--- a/ecb_decrypt.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/ecb_decrypt.c	Tue Jun 15 14:27:14 2004 +0000
@@ -19,9 +19,12 @@
    _ARGCHK(ct != NULL);
    _ARGCHK(ecb != NULL);
 
+   /* valid cipher? */
    if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
        return err;
    }
+   _ARGCHK(cipher_descriptor[ecb->cipher].ecb_decrypt != NULL);
+   
    cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
    return CRYPT_OK;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/error_to_string.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,60 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+static const char *err_2_str[] =
+{
+   "CRYPT_OK",
+   "CRYPT_ERROR",
+   "Non-fatal 'no-operation' requested.",
+
+   "Invalid keysize for block cipher.",
+   "Invalid number of rounds for block cipher.",
+   "Algorithm failed test vectors.",
+
+   "Buffer overflow.",
+   "Invalid input packet.",
+
+   "Invalid number of bits for a PRNG.",
+   "Error reading the PRNG.",
+
+   "Invalid cipher specified.",
+   "Invalid hash specified.",
+   "Invalid PRNG specified.",
+
+   "Out of memory.",
+
+   "Invalid PK key or key type specified for function.",
+   "A private PK key is required.",
+
+   "Invalid argument provided.",
+   "File Not Found",
+
+   "Invalid PK type.",
+   "Invalid PK system.",
+   "Duplicate PK key found on keyring.",
+   "Key not found in keyring.",
+   "Invalid sized parameter.",
+
+   "Invalid size for prime.",
+
+};
+
+const char *error_to_string(int err)
+{
+   if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
+      return "Invalid error code.";
+   } else {
+      return err_2_str[err];
+   }   
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ltc_tommath.h	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,556 @@
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://math.libtomcrypt.org
+ */
+#ifndef BN_H_
+#define BN_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+
+#undef MIN
+#define MIN(x,y) ((x)<(y)?(x):(y))
+#undef MAX
+#define MAX(x,y) ((x)>(y)?(x):(y))
+
+#ifdef __cplusplus
+extern "C" {
+
+/* C++ compilers don't like assigning void * to mp_digit * */
+#define  OPT_CAST(x)  (x *)
+
+#else
+
+/* C on the other hand doesn't care */
+#define  OPT_CAST(x)
+
+#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)
+   typedef unsigned short     mp_digit;
+   typedef unsigned long      mp_word;
+#elif defined(MP_64BIT)
+   /* for GCC only on supported platforms */
+#ifndef CRYPT
+   typedef unsigned long long ulong64;
+   typedef signed long long   long64;
+#endif
+
+   typedef ulong64            mp_digit;
+   typedef unsigned long      mp_word __attribute__ ((mode(TI)));
+
+   #define DIGIT_BIT          60
+#else
+   /* this is the default case, 28-bit digits */
+   
+   /* this is to make porting into LibTomCrypt easier :-) */
+#ifndef CRYPT
+   #if defined(_MSC_VER) || defined(__BORLANDC__) 
+      typedef unsigned __int64   ulong64;
+      typedef signed __int64     long64;
+   #else
+      typedef unsigned long long ulong64;
+      typedef signed long long   long64;
+   #endif
+#endif
+
+   typedef unsigned long      mp_digit;
+   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 macro to test */
+   #define DIGIT_BIT          28
+   #define MP_28BIT
+#endif   
+#endif
+
+/* define heap macros */
+#ifndef CRYPT
+   /* default to libc stuff */
+   #ifndef XMALLOC 
+       #define XMALLOC  malloc
+       #define XFREE    free
+       #define XREALLOC realloc
+       #define XCALLOC  calloc
+   #else
+      /* prototypes for our heap functions */
+      extern void *XMALLOC(size_t n);
+      extern void *REALLOC(void *p, size_t n);
+      extern void *XCALLOC(size_t n, size_t s);
+      extern void XFREE(void *p);
+   #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_OFF 0x0004 /* force 2nd MSB to 0 */
+#define LTM_PRIME_2MSB_ON  0x0008 /* force 2nd MSB to 1 */
+
+typedef int           mp_err;
+
+/* you'll have to tune these... */
+extern int KARATSUBA_MUL_CUTOFF,
+           KARATSUBA_SQR_CUTOFF,
+           TOOM_MUL_CUTOFF,
+           TOOM_SQR_CUTOFF;
+
+/* define this to use lower memory usage routines (exptmods mostly) */
+/* #define MP_LOW_MEM */
+
+/* default precision */
+#ifndef MP_PREC
+   #ifdef MP_LOW_MEM
+      #define MP_PREC                 64     /* default digits of precision */
+   #else
+      #define MP_PREC                 8      /* default digits of precision */
+   #endif   
+#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)
+
+/* error code to char* string */
+char *mp_error_to_string(int code);
+
+/* ---> init and deinit bignum functions <--- */
+/* init a bignum */
+int mp_init(mp_int *a);
+
+/* free a bignum */
+void mp_clear(mp_int *a);
+
+/* init a null terminated series of arguments */
+int mp_init_multi(mp_int *mp, ...);
+
+/* clear a null terminated series of arguments */
+void mp_clear_multi(mp_int *mp, ...);
+
+/* exchange two ints */
+void mp_exch(mp_int *a, mp_int *b);
+
+/* shrink ram required for a bignum */
+int mp_shrink(mp_int *a);
+
+/* grow an int to a given size */
+int mp_grow(mp_int *a, int size);
+
+/* init to a given number of digits */
+int mp_init_size(mp_int *a, int size);
+
+/* ---> 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)
+
+/* set to zero */
+void mp_zero(mp_int *a);
+
+/* set to a digit */
+void mp_set(mp_int *a, mp_digit b);
+
+/* set a 32-bit const */
+int mp_set_int(mp_int *a, unsigned long b);
+
+/* get a 32-bit value */
+unsigned long mp_get_int(mp_int * a);
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b);
+
+/* initialize and set 32-bit value */
+int mp_init_set_int (mp_int * a, unsigned long b);
+
+/* copy, b = a */
+int mp_copy(mp_int *a, mp_int *b);
+
+/* inits and copies, a = b */
+int mp_init_copy(mp_int *a, mp_int *b);
+
+/* trim unused digits */
+void mp_clamp(mp_int *a);
+
+/* ---> digit manipulation <--- */
+
+/* right shift by "b" digits */
+void mp_rshd(mp_int *a, int b);
+
+/* left shift by "b" digits */
+int mp_lshd(mp_int *a, int b);
+
+/* c = a / 2**b */
+int mp_div_2d(mp_int *a, int b, mp_int *c, mp_int *d);
+
+/* b = a/2 */
+int mp_div_2(mp_int *a, mp_int *b);
+
+/* c = a * 2**b */
+int mp_mul_2d(mp_int *a, int b, mp_int *c);
+
+/* b = a*2 */
+int mp_mul_2(mp_int *a, mp_int *b);
+
+/* c = a mod 2**d */
+int mp_mod_2d(mp_int *a, int b, mp_int *c);
+
+/* computes a = 2**b */
+int mp_2expt(mp_int *a, int b);
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a);
+
+/* I Love Earth! */
+
+/* makes a pseudo-random int of a given size */
+int mp_rand(mp_int *a, int digits);
+
+/* ---> binary operations <--- */
+/* c = a XOR b  */
+int mp_xor(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a OR b */
+int mp_or(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a AND b */
+int mp_and(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> Basic arithmetic <--- */
+
+/* b = -a */
+int mp_neg(mp_int *a, mp_int *b);
+
+/* b = |a| */
+int mp_abs(mp_int *a, mp_int *b);
+
+/* compare a to b */
+int mp_cmp(mp_int *a, mp_int *b);
+
+/* compare |a| to |b| */
+int mp_cmp_mag(mp_int *a, mp_int *b);
+
+/* c = a + b */
+int mp_add(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a - b */
+int mp_sub(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a * b */
+int mp_mul(mp_int *a, mp_int *b, mp_int *c);
+
+/* b = a*a  */
+int mp_sqr(mp_int *a, mp_int *b);
+
+/* a/b => cb + d == a */
+int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a mod b, 0 <= c < b  */
+int mp_mod(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> single digit functions <--- */
+
+/* compare against a single digit */
+int mp_cmp_d(mp_int *a, mp_digit b);
+
+/* c = a + b */
+int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a - b */
+int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a * b */
+int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* a/b => cb + d == a */
+int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
+
+/* a/3 => 3c + d == a */
+int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
+
+/* c = a**b */
+int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a mod b, 0 <= c < b  */
+int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
+
+/* ---> number theory <--- */
+
+/* d = a + b (mod c) */
+int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a - b (mod c) */
+int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a * b (mod c) */
+int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a * a (mod b) */
+int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = 1/a (mod b) */
+int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = (a, b) */
+int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+
+/* produces value such that U1*a + U2*b = U3 */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
+
+/* c = [a, b] or (a*b)/(a, b) */
+int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+
+/* finds one of the b'th root of a, such that |c|**b <= |a|
+ *
+ * returns error if a < 0 and b is even
+ */
+int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
+
+/* special sqrt algo */
+int mp_sqrt(mp_int *arg, mp_int *ret);
+
+/* is number a square? */
+int mp_is_square(mp_int *arg, int *ret);
+
+/* computes the jacobi c = (a | n) (or Legendre if b is prime)  */
+int mp_jacobi(mp_int *a, mp_int *n, int *c);
+
+/* used to setup the Barrett reduction for a given modulus b */
+int mp_reduce_setup(mp_int *a, mp_int *b);
+
+/* Barrett Reduction, computes a (mod b) with a precomputed value c
+ *
+ * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
+ * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
+ */
+int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
+
+/* setups the montgomery reduction */
+int mp_montgomery_setup(mp_int *a, mp_digit *mp);
+
+/* computes a = B**n mod b without division or multiplication useful for
+ * normalizing numbers in a Montgomery system.
+ */
+int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
+
+/* computes x/R == x (mod N) via Montgomery Reduction */
+int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+
+/* returns 1 if a is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a);
+
+/* sets the value of "d" required for mp_dr_reduce */
+void mp_dr_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b using the Diminished Radix method */
+int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
+
+/* returns true if a can be reduced with mp_reduce_2k */
+int mp_reduce_is_2k(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+
+/* d = a**b (mod c) */
+int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* ---> Primes <--- */
+
+/* number of primes */
+#ifdef MP_8BIT
+   #define PRIME_SIZE      31
+#else
+   #define PRIME_SIZE      256
+#endif
+
+/* table of first PRIME_SIZE primes */
+extern const mp_digit __prime_tab[];
+
+/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
+int mp_prime_is_divisible(mp_int *a, int *result);
+
+/* performs one Fermat test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
+
+/* performs one Miller-Rabin test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
+
+/* This gives [for a given bit size] the number of trials required
+ * such that Miller-Rabin gives a prob of failure lower than 2^-96 
+ */
+int mp_prime_rabin_miller_trials(int size);
+
+/* performs t rounds of Miller-Rabin on "a" using the first
+ * t prime bases.  Also performs an initial sieve of trial
+ * division.  Determines if "a" is prime with probability
+ * of error no more than (1/4)**t.
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime(mp_int *a, int t, int *result);
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
+
+/* makes a truly random prime of a given size (bytes),
+ * call with bbs = 1 if you want it to be congruent to 3 mod 4 
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ * The prime generated will be larger than 2^(8*size).
+ */
+#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)
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ * 
+ *   LTM_PRIME_BBS      - make prime congruent to 3 mod 4
+ *   LTM_PRIME_SAFE     - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ *   LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ *   LTM_PRIME_2MSB_ON  - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
+
+/* ---> radix conversion <--- */
+int mp_count_bits(mp_int *a);
+
+int mp_unsigned_bin_size(mp_int *a);
+int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c);
+int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+
+int mp_signed_bin_size(mp_int *a);
+int mp_read_signed_bin(mp_int *a, unsigned char *b, int c);
+int mp_to_signed_bin(mp_int *a, unsigned char *b);
+
+int mp_read_radix(mp_int *a, char *str, int radix);
+int mp_toradix(mp_int *a, char *str, int radix);
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
+int mp_radix_size(mp_int *a, int radix, int *size);
+
+int mp_fread(mp_int *a, int radix, FILE *stream);
+int mp_fwrite(mp_int *a, int radix, FILE *stream);
+
+#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)
+
+/* lowlevel functions, do not call! */
+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);
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+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 fast_s_mp_sqr(mp_int *a, mp_int *b);
+int s_mp_sqr(mp_int *a, mp_int *b);
+int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_karatsuba_sqr(mp_int *a, mp_int *b);
+int mp_toom_sqr(mp_int *a, mp_int *b);
+int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
+void bn_reverse(unsigned char *s, int len);
+
+extern const char *mp_s_rmap;
+
+#ifdef __cplusplus
+   }
+#endif
+
+#endif
+
--- a/makefile	Wed Jun 02 08:31:25 2004 +0000
+++ b/makefile	Tue Jun 15 14:27:14 2004 +0000
@@ -9,9 +9,8 @@
 # a build. This is easy to remedy though, for those that have problems.
 
 # The version
-VERSION=0.95
+VERSION=0.96
 
-#ch1-01-1
 # Compiler and Linker Names
 #CC=gcc
 #LD=ld
@@ -19,9 +18,7 @@
 # Archiver [makes .a files]
 #AR=ar
 #ARFLAGS=r
-#ch1-01-1
 
-#ch1-01-3
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 # The rest of the flags come from the parent Dropbear makefile
 CFLAGS += -c -I./
@@ -44,7 +41,6 @@
 
 #Output filenames for various targets.
 LIBNAME=libtomcrypt.a
-TEST=test
 HASH=hashsum
 CRYPT=encrypt
 SMALL=small
@@ -64,7 +60,7 @@
 #Leave MPI built-in or force developer to link against libtommath?
 MPIOBJECT=mpi.o
 
-OBJECTS=keyring.o gf.o base64.o \
+OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
 \
 crypt.o                    crypt_find_cipher.o      crypt_find_hash_any.o      \
 crypt_hash_is_valid.o      crypt_register_hash.o    crypt_unregister_prng.o    \
@@ -80,12 +76,16 @@
 \
 ecc.o  dh.o \
 \
-rsa.o rsa_exptmod.o  rsa_free.o  rsa_make_key.o \
+rsa_decrypt_key.o  rsa_encrypt_key.o  rsa_exptmod.o  rsa_free.o  rsa_make_key.o  \
+rsa_sign_hash.o  rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
 \
-dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  dsa_verify_hash.o  dsa_verify_key.o \
+dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  \
+dsa_verify_hash.o  dsa_verify_key.o \
 \
-xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \
-rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
+aes.o aes_enc.o \
+\
+blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
+rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
 \
 md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
 rmd128.o rmd160.o \
@@ -104,10 +104,10 @@
 pmac_done.o  pmac_file.o  pmac_init.o  pmac_memory.o  pmac_ntz.o  pmac_process.o  \
 pmac_shift_xor.o  pmac_test.o \
 \
-cbc_start.o cbc_encrypt.o cbc_decrypt.o \
-cfb_start.o cfb_encrypt.o cfb_decrypt.o \
-ofb_start.o ofb_encrypt.o ofb_decrypt.o \
-ctr_start.o ctr_encrypt.o ctr_decrypt.o \
+cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
+cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
+ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
+ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
 ecb_start.o ecb_encrypt.o ecb_decrypt.o \
 \
 hash_file.o  hash_filehandle.o  hash_memory.o \
@@ -116,6 +116,7 @@
 \
 pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o  \
 pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
+pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
 \
 pkcs_5_1.o pkcs_5_2.o \
 \
@@ -130,26 +131,27 @@
 TVS=demos/tv_gen.o
 
 #Files left over from making the crypt.pdf.
-LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind
+LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out
 
 #Compressed filenames
-COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
+COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip
 
 #Header files used by libtomcrypt.
-HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
+HEADERS=ltc_tommath.h mycrypt_cfg.h \
 mycrypt_misc.h  mycrypt_prng.h mycrypt_cipher.h  mycrypt_hash.h \
 mycrypt_macros.h  mycrypt_pk.h mycrypt.h mycrypt_argchk.h \
 mycrypt_custom.h mycrypt_pkcs.h
 
 #The default rule for make builds the libtomcrypt library.
-default:library mycrypt.h mycrypt_cfg.h
+default:library
 
+#ciphers come in two flavours... enc+dec and enc 
+aes_enc.o: aes.c aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
+		
 #These are the rules to make certain object files.
-rsa.o: rsa.c rsa_sys.c
 ecc.o: ecc.c ecc_sys.c
 dh.o: dh.c dh_sys.c
-aes.o: aes.c aes_tab.c
-twofish.o: twofish.c twofish_tab.c
 sha512.o: sha512.c sha384.c
 sha256.o: sha256.c sha224.c
 
@@ -158,11 +160,6 @@
 
 $(LIBNAME): $(OBJECTS)
 	$(AR) $(ARFLAGS) [email protected] $(OBJECTS) 
-	$(RANLIB) $(LIBNAME)
-
-#This rule makes the test program included with libtomcrypt
-test: library $(TESTOBJECTS)
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN)
 
 #This rule makes the hash program included with libtomcrypt
 hashsum: library $(HASHOBJECTS)
@@ -182,34 +179,6 @@
 tv_gen: library $(TVS)
 	$(CC) $(TVS) $(LIBNAME) -o $(TV)
 
-
-#make a profiled library (takes a while!!!)
-#
-# This will build the library with profile generation
-# then run the test demo and rebuild the library.
-# 
-# So far I've seen improvements in the MP math
-#
-# This works with GCC v3.3.x [tested with 3.3.3]
-profiled: $(TESTOBJECTS)
-	make CFLAGS="$(CFLAGS) -fprofile-arcs"
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST)
-	./test
-	rm -f *.a *.o test demos/test.o
-	make CFLAGS="$(CFLAGS) -fbranch-probabilities"
-
-
-#Profiling in GCC 3.4.x is a little diff.  
-#
-#Tested with GCC v3.4.0
-profiled34: $(TESTOBJECTS)
-	make CFLAGS="$(CFLAGS) -fprofile-generate"
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -lgcov -o $(TEST)
-	./test
-	rm -f *.a *.o test demos/test.o
-	make CFLAGS="$(CFLAGS) -fprofile-use"
-
-
 #This rule installs the library and the header files. This must be run
 #as root in order to have a high enough permission to write to the correct
 #directories and to set the owner and group to root.
@@ -219,7 +188,7 @@
 	install -d -g root -o root $(DESTDIR)$(DATAPATH)
 	install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH)
 	install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH)
-	install -g root -o root crypt.pdf $(DESTDIR)$(DATAPATH)
+	install -g root -o root doc/crypt.pdf $(DESTDIR)$(DATAPATH)
 
 #This rule cleans the source tree of all compiled code, not including the pdf
 #documentation.
@@ -227,21 +196,31 @@
 	rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
 	rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV)
 	rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn *.dpi \
-         *.gcda *.gcno demos/*.gcno demos/*.gcda *~
+         *.gcda *.gcno demos/*.gcno demos/*.gcda *~ doc/*
+	cd demos/test ; make clean   
 
 #This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
 #from the clean command! This is because most people would like to keep the
 #nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
 #delete it if we are rebuilding it.
 docs: crypt.tex
-	rm -f crypt.pdf $(LEFTOVERS)
+	rm -f doc/crypt.pdf $(LEFTOVERS)
+	echo "hello" > crypt.ind
 	latex crypt > /dev/null
 	makeindex crypt > /dev/null
 	latex crypt > /dev/null
 	latex crypt > /dev/null
 	dvipdf crypt
+	mv -ivf crypt.pdf doc/crypt.pdf
 	rm -f $(LEFTOVERS)
-       
+
+docdvi: crypt.tex
+	echo hello > crypt.ind
+	latex crypt > /dev/null
+	latex crypt > /dev/null
+	makeindex crypt
+	latex crypt > /dev/null
+
 #beta
 beta: clean
 	cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \
@@ -252,4 +231,6 @@
 zipup: clean docs
 	cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \
 	cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; tar -c libtomcrypt-$(VERSION)/* > crypt-$(VERSION).tar ; \
-	bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/*
+	bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/* ; \
+	gpg -b -a crypt-$(VERSION).tar.bz2 ; \
+   gpg -b -a crypt-$(VERSION).zip
--- a/makefile.cygwin_dll	Wed Jun 02 08:31:25 2004 +0000
+++ b/makefile.cygwin_dll	Tue Jun 15 14:27:14 2004 +0000
@@ -1,4 +1,4 @@
-
+#makefile for Cygwin [makes a .dll]
 
 default: ltc_dll
 
@@ -18,7 +18,7 @@
 #Leave MPI built-in or force developer to link against libtommath?
 MPIOBJECT=mpi.o
 
-OBJECTS=keyring.o gf.o strings.o base64.o \
+OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
 \
 crypt.o                    crypt_find_cipher.o      crypt_find_hash_any.o      \
 crypt_hash_is_valid.o      crypt_register_hash.o    crypt_unregister_prng.o    \
@@ -34,12 +34,16 @@
 \
 ecc.o  dh.o \
 \
-rsa.o rsa_exptmod.o  rsa_free.o  rsa_make_key.o \
+rsa_decrypt_key.o  rsa_encrypt_key.o  rsa_exptmod.o  rsa_free.o  rsa_make_key.o  \
+rsa_sign_hash.o  rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
 \
-dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  dsa_verify_hash.o  dsa_verify_key.o \
+dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  \
+dsa_verify_hash.o  dsa_verify_key.o \
 \
-xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \
-rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
+aes.o aes_enc.o \
+\
+blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
+rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
 \
 md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
 rmd128.o rmd160.o \
@@ -58,10 +62,10 @@
 pmac_done.o  pmac_file.o  pmac_init.o  pmac_memory.o  pmac_ntz.o  pmac_process.o  \
 pmac_shift_xor.o  pmac_test.o \
 \
-cbc_start.o cbc_encrypt.o cbc_decrypt.o \
-cfb_start.o cfb_encrypt.o cfb_decrypt.o \
-ofb_start.o ofb_encrypt.o ofb_decrypt.o \
-ctr_start.o ctr_encrypt.o ctr_decrypt.o \
+cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
+cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
+ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
+ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
 ecb_start.o ecb_encrypt.o ecb_decrypt.o \
 \
 hash_file.o  hash_filehandle.o  hash_memory.o \
@@ -70,15 +74,17 @@
 \
 pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o  \
 pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
+pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
 \
 pkcs_5_1.o pkcs_5_2.o \
 \
 burn_stack.o zeromem.o \
 $(MPIOBJECT)
 
+#ciphers come in two flavours... enc+dec and enc 
+aes_enc.o: aes.c aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
+
 ltc_dll: $(OBJECTS) $(MPIOBJECT)
 	gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32
 	ranlib libtomcrypt.dll.a
-
-test: ltc_dll
-	gcc $(CFLAGS) demos/test.c libtomcrypt.dll.a -Wl,--enable-auto-import -o test -s
--- a/makefile.icc	Wed Jun 02 08:31:25 2004 +0000
+++ b/makefile.icc	Tue Jun 15 14:27:14 2004 +0000
@@ -24,6 +24,9 @@
 # Compilation flags. Note the += does not write over the user's CFLAGS!
 CFLAGS += -c -I./ -DINTEL_CC
 
+#The default rule for make builds the libtomcrypt library.
+default:library
+
 # optimize for SPEED
 #
 # -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4
@@ -47,7 +50,6 @@
 
 #Output filenames for various targets.
 LIBNAME=libtomcrypt.a
-TEST=test
 HASH=hashsum
 CRYPT=encrypt
 SMALL=small
@@ -67,7 +69,7 @@
 #Leave MPI built-in or force developer to link against libtommath?
 MPIOBJECT=mpi.o
 
-OBJECTS=keyring.o gf.o strings.o base64.o \
+OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
 \
 crypt.o                    crypt_find_cipher.o      crypt_find_hash_any.o      \
 crypt_hash_is_valid.o      crypt_register_hash.o    crypt_unregister_prng.o    \
@@ -83,12 +85,16 @@
 \
 ecc.o  dh.o \
 \
-rsa.o rsa_exptmod.o  rsa_free.o  rsa_make_key.o \
+rsa_decrypt_key.o  rsa_encrypt_key.o  rsa_exptmod.o  rsa_free.o  rsa_make_key.o  \
+rsa_sign_hash.o  rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
 \
-dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  dsa_verify_hash.o  dsa_verify_key.o \
+dsa_export.o  dsa_free.o  dsa_import.o  dsa_make_key.o  dsa_sign_hash.o  \
+dsa_verify_hash.o  dsa_verify_key.o \
 \
-xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \
-rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
+aes.o aes_enc.o \
+\
+blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
+rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
 \
 md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
 rmd128.o rmd160.o \
@@ -107,10 +113,10 @@
 pmac_done.o  pmac_file.o  pmac_init.o  pmac_memory.o  pmac_ntz.o  pmac_process.o  \
 pmac_shift_xor.o  pmac_test.o \
 \
-cbc_start.o cbc_encrypt.o cbc_decrypt.o \
-cfb_start.o cfb_encrypt.o cfb_decrypt.o \
-ofb_start.o ofb_encrypt.o ofb_decrypt.o \
-ctr_start.o ctr_encrypt.o ctr_decrypt.o \
+cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
+cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
+ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
+ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
 ecb_start.o ecb_encrypt.o ecb_decrypt.o \
 \
 hash_file.o  hash_filehandle.o  hash_memory.o \
@@ -119,13 +125,18 @@
 \
 pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o  \
 pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
+pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
 \
 pkcs_5_1.o pkcs_5_2.o \
 \
 burn_stack.o zeromem.o \
 $(MPIOBJECT)
 
-TESTOBJECTS=demos/test.o
+
+#ciphers come in two flavours... enc+dec and enc 
+aes_enc.o: aes.c aes_tab.c
+	$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
+
 HASHOBJECTS=demos/hashsum.o
 CRYPTOBJECTS=demos/encrypt.o
 SMALLOBJECTS=demos/small.o
@@ -143,9 +154,6 @@
 mycrypt_misc.h  mycrypt_prng.h mycrypt_cipher.h  mycrypt_hash.h \
 mycrypt_macros.h  mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h
 
-#The default rule for make builds the libtomcrypt library.
-default:library mycrypt.h mycrypt_cfg.h
-
 #These are the rules to make certain object files.
 rsa.o: rsa.c rsa_sys.c
 ecc.o: ecc.c ecc_sys.c
@@ -161,10 +169,6 @@
 $(LIBNAME): $(OBJECTS)
 	$(AR) $(ARFLAGS) [email protected] $(OBJECTS) 
 
-#This rule makes the test program included with libtomcrypt
-test: library $(TESTOBJECTS)
-	$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN)
-
 #This rule makes the hash program included with libtomcrypt
 hashsum: library $(HASHOBJECTS)
 	$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
@@ -183,19 +187,7 @@
 tv_gen: library $(TVS)
 	$(CC) $(TVS) $(LIBNAME) -o $(TV)
 
-
-#make a profiled library (takes a while!!!)
-#
-# This will build the library with profile generation
-# then run the test demo and rebuild the library.
-# 
-# So far I've seen improvements in the MP math
-profiled:
-	make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen" test
-	./test
-	rm -f *.a *.o test demos/test.o
-	make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use"
-   
+  
 #This rule installs the library and the header files. This must be run
 #as root in order to have a high enough permission to write to the correct
 #directories and to set the owner and group to root.
--- a/makefile.msvc	Wed Jun 02 08:31:25 2004 +0000
+++ b/makefile.msvc	Tue Jun 15 14:27:14 2004 +0000
@@ -1,86 +0,0 @@
-#MSVC Makefile [tested with MSVC 6.00 with SP5]
-#
-#Tom St Denis
-CFLAGS = /I. /Ox /DWIN32 /W3
-
-default: library
-
-# leave this blank and link against libtommath if you want better link resolution
-MPIOBJECT=mpi.obj
-
-#List of objects to compile.
-OBJECTS=keyring.obj gf.obj strings.obj base64.obj \
-\
-crypt.obj                    crypt_find_cipher.obj      crypt_find_hash_any.obj      \
-crypt_hash_is_valid.obj      crypt_register_hash.obj    crypt_unregister_prng.obj    \
-crypt_argchk.obj             crypt_find_cipher_any.obj  crypt_find_hash_id.obj       \
-crypt_prng_descriptor.obj    crypt_register_prng.obj    crypt_cipher_descriptor.obj  \
-crypt_find_cipher_id.obj     crypt_find_prng.obj        crypt_prng_is_valid.obj      \
-crypt_unregister_cipher.obj  crypt_cipher_is_valid.obj  crypt_find_hash.obj          \
-crypt_hash_descriptor.obj    crypt_register_cipher.obj  crypt_unregister_hash.obj    \
-\
-sprng.obj yarrow.obj rc4.obj rng_get_bytes.obj  rng_make_prng.obj \
-\
-rand_prime.obj is_prime.obj \
-\
-ecc.obj  dh.obj \
-\
-rsa.obj rsa_exptmod.obj  rsa_free.obj  rsa_make_key.obj \
-\
-dsa_export.obj  dsa_free.obj  dsa_import.obj  dsa_make_key.obj  dsa_sign_hash.obj  dsa_verify_hash.obj  dsa_verify_key.obj \
-\
-xtea.obj aes.obj des.obj safer_tab.obj safer.obj saferp.obj rc2.obj \
-rc6.obj rc5.obj cast5.obj noekeon.obj blowfish.obj twofish.obj skipjack.obj \
-\
-md2.obj md4.obj md5.obj sha1.obj sha256.obj sha512.obj tiger.obj whirl.obj \
-rmd128.obj rmd160.obj \
-\
-packet_store_header.obj  packet_valid_header.obj \
-\
-eax_addheader.obj  eax_decrypt.obj  eax_decrypt_verify_memory.obj  eax_done.obj  eax_encrypt.obj  \
-eax_encrypt_authenticate_memory.obj  eax_init.obj  eax_test.obj \
-\
-ocb_decrypt.obj  ocb_decrypt_verify_memory.obj  ocb_done_decrypt.obj  ocb_done_encrypt.obj  \
-ocb_encrypt.obj  ocb_encrypt_authenticate_memory.obj  ocb_init.obj  ocb_ntz.obj  \
-ocb_shift_xor.obj  ocb_test.obj s_ocb_done.obj \
-\
-omac_done.obj  omac_file.obj  omac_init.obj  omac_memory.obj  omac_process.obj  omac_test.obj \
-\
-pmac_done.obj  pmac_file.obj  pmac_init.obj  pmac_memory.obj  pmac_ntz.obj  pmac_process.obj  \
-pmac_shift_xor.obj  pmac_test.obj \
-\
-cbc_start.obj cbc_encrypt.obj cbc_decrypt.obj \
-cfb_start.obj cfb_encrypt.obj cfb_decrypt.obj \
-ofb_start.obj ofb_encrypt.obj ofb_decrypt.obj \
-ctr_start.obj ctr_encrypt.obj ctr_decrypt.obj \
-ecb_start.obj ecb_encrypt.obj ecb_decrypt.obj \
-\
-hash_file.obj  hash_filehandle.obj  hash_memory.obj \
-\
-hmac_done.obj  hmac_file.obj  hmac_init.obj  hmac_memory.obj  hmac_process.obj  hmac_test.obj \
-\
-pkcs_1_mgf1.obj pkcs_1_oaep_encode.obj pkcs_1_oaep_decode.obj  \
-pkcs_1_pss_encode.obj pkcs_1_pss_decode.obj pkcs_1_i2osp.obj pkcs_1_os2ip.obj \
-\
-pkcs_5_1.obj pkcs_5_2.obj \
-\
-burn_stack.obj zeromem.obj 	\
-$(MPIOBJECT)
-
-library: $(OBJECTS)
-	lib /out:tomcrypt.lib $(OBJECTS)
-	
-test.obj: demos/test.c
-	cl $(CFLAGS) /c demos/test.c
-
-test: library test.obj
-	cl test.obj tomcrypt.lib advapi32.lib	
-	
-x86_prof: demos/x86_prof.c library
-	cl $(CFLAGS) demos/x86_prof.c tomcrypt.lib advapi32.lib 
-
-tv_gen: demos/tv_gen.c library
-	cl $(CFLAGS) demos/tv_gen.c tomcrypt.lib advapi32.lib 
-
-hashsum: demos/hashsum.c library
-	cl $(CFLAGS) demos/hashsum.c tomcrypt.lib advapi32.lib
--- a/md2.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/md2.c	Tue Jun 15 14:27:14 2004 +0000
@@ -19,6 +19,13 @@
     7,
     16,
     16,
+
+    /* DER encoding */
+    { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 
+      0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 
+      0x04, 0x10 },
+    18,
+
     &md2_init,
     &md2_process,
     &md2_done,
--- a/md4.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/md4.c	Tue Jun 15 14:27:14 2004 +0000
@@ -19,6 +19,11 @@
     6,
     16,
     64,
+ 
+    /* DER encoding (not yet supported) */
+    { 0x00 },
+    0,    
+
     &md4_init,
     &md4_process,
     &md4_done,
--- a/md5.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/md5.c	Tue Jun 15 14:27:14 2004 +0000
@@ -21,6 +21,13 @@
     3,
     16,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 
+      0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 
+      0x04, 0x10 },
+    18,
+
     &md5_init,
     &md5_process,
     &md5_done,
@@ -44,6 +51,35 @@
 #define II(a,b,c,d,M,s,t) \
     a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
 
+#ifdef SMALL_CODE
+
+static const unsigned char Worder[64] = {
+   0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
+   1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
+   5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
+   0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
+};
+
+static const unsigned char Rorder[64] = {
+   7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
+   5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
+   4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
+   6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
+};
+
+static const ulong32 Korder[64] = {
+0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
+0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
+0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
+0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
+0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
+0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
+0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
+0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
+};
+
+#endif   
+
 #ifdef CLEAN_STACK
 static void _md5_compress(hash_state *md, unsigned char *buf)
 #else
@@ -51,6 +87,9 @@
 #endif
 {
     ulong32 i, W[16], a, b, c, d;
+#ifdef SMALL_CODE
+    ulong32 t;
+#endif
 
     /* copy the state into 512-bits into W[0..15] */
     for (i = 0; i < 16; i++) {
@@ -63,6 +102,28 @@
     c = md->md5.state[2];
     d = md->md5.state[3];
 
+#ifdef SMALL_CODE
+    for (i = 0; i < 16; ++i) {
+        FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 32; ++i) {
+        GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 48; ++i) {
+        HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 64; ++i) {
+        II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
+        t = d; d = c; c = b; b = a; a = t;
+    }
+
+#else
     FF(a,b,c,d,W[0],7,0xd76aa478UL)
     FF(d,a,b,c,W[1],12,0xe8c7b756UL)
     FF(c,d,a,b,W[2],17,0x242070dbUL)
@@ -127,6 +188,7 @@
     II(d,a,b,c,W[11],10,0xbd3af235UL)
     II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
     II(b,c,d,a,W[9],21,0xeb86d391UL)
+#endif
 
     md->md5.state[0] = md->md5.state[0] + a;
     md->md5.state[1] = md->md5.state[1] + b;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modes_test.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,46 @@
+/* test CFB/OFB/CBC modes */
+#include "test.h"
+
+int modes_test(void)
+{
+   unsigned char pt[64], ct[64], tmp[64], key[16], iv[16];
+   int x, cipher_idx;
+   symmetric_CBC cbc;
+   
+   /* make a random pt, key and iv */
+   yarrow_read(pt, 64,  &test_yarrow);
+   yarrow_read(key, 16, &test_yarrow);
+   yarrow_read(iv, 16,  &test_yarrow);
+   
+/* test CBC mode */
+   cipher_idx = find_cipher("aes");
+   if (cipher_idx == -1) {
+      printf("test requires AES");
+      return 1;
+   }
+   
+   
+   /* encode the block */
+   DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
+   for (x = 0; x < 4; x++) {
+      DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc));
+   }
+   
+   /* decode the block */
+   DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
+   for (x = 0; x < 4; x++) {
+      DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc));
+   }
+   if (memcmp(tmp, pt, 64) != 0) {
+      printf("CBC failed");
+      return 1;
+   }
+   
+/*   
+   extern int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
+                     int keylen, int num_rounds, symmetric_CBC *cbc);
+extern int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc);
+extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc);
+*/
+
+}
--- a/mpi.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/mpi.c	Tue Jun 15 14:27:14 2004 +0000
@@ -13,7 +13,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 static const struct {
      int code;
@@ -58,7 +58,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes the modular inverse via binary extended euclidean algorithm, 
  * that is c = 1/a mod b 
@@ -205,7 +205,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes xR**-1 == x (mod N) via Montgomery Reduction
  *
@@ -376,7 +376,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* Fast (comba) multiplier
  *
@@ -452,7 +452,7 @@
   }
 
   /* setup dest */
-  olduse = c->used;
+  olduse  = c->used;
   c->used = digs;
 
   {
@@ -510,7 +510,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
- #include <tommath.h>
+ #include <ltc_tommath.h>
 
 /* this is a modified version of fast_s_mp_mul_digs that only produces
  * output digits *above* digs.  See the comments for fast_s_mp_mul_digs
@@ -612,7 +612,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* fast squaring
  *
@@ -755,7 +755,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes a = 2**b 
  *
@@ -801,7 +801,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* b = |a| 
  *
@@ -842,7 +842,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* high level addition (handles signs) */
 int mp_add (mp_int * a, mp_int * b, mp_int * c)
@@ -893,7 +893,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* single digit addition */
 int
@@ -1000,7 +1000,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* d = a + b (mod c) */
 int
@@ -1039,7 +1039,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* AND two ints together */
 int
@@ -1094,7 +1094,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* trim unused digits 
  *
@@ -1136,7 +1136,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* clear one (frees)  */
 void
@@ -1174,7 +1174,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 #include <stdarg.h>
 
 void mp_clear_multi(mp_int *mp, ...) 
@@ -1206,7 +1206,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* compare two ints (signed)*/
 int
@@ -1247,7 +1247,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* compare a digit */
 int mp_cmp_d(mp_int * a, mp_digit b)
@@ -1289,7 +1289,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* compare maginitude of two ints (unsigned) */
 int mp_cmp_mag (mp_int * a, mp_int * b)
@@ -1342,7 +1342,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 static const int lnz[16] = { 
    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
@@ -1393,7 +1393,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* copy, b = a */
 int
@@ -1459,7 +1459,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* returns the number of bits in an int */
 int
@@ -1502,7 +1502,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* integer signed division. 
  * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
@@ -1717,7 +1717,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* b = a/2 */
 int mp_div_2(mp_int * a, mp_int * b)
@@ -1783,7 +1783,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* 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)
@@ -1878,7 +1878,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* divide by three (based on routine from MPI and the GMP manual) */
 int
@@ -1955,7 +1955,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 static int s_is_power_of_two(mp_digit b, int *p)
 {
@@ -2061,7 +2061,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* determines if a number is a valid DR modulus */
 int mp_dr_is_modulus(mp_int *a)
@@ -2102,7 +2102,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
  *
@@ -2194,7 +2194,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* determines the setup value */
 void mp_dr_setup(mp_int *a, mp_digit *d)
@@ -2224,7 +2224,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* swap the elements of two integers, for cases where you can't simply swap the 
  * mp_int pointers around
@@ -2256,7 +2256,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* calculate c = a**b  using a square-multiply algorithm */
 int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
@@ -2311,7 +2311,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 
 /* this is a shell function that calls either the normal or Montgomery
@@ -2393,7 +2393,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
  *
@@ -2684,7 +2684,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* Extended euclidean algorithm of (a, b) produces 
    a*u1 + b*u2 = u3
@@ -2757,7 +2757,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* read a bigint from a file stream in ASCII */
 int mp_fread(mp_int *a, int radix, FILE *stream)
@@ -2822,7 +2822,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 int mp_fwrite(mp_int *a, int radix, FILE *stream)
 {
@@ -2872,7 +2872,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* Greatest Common Divisor using the binary method */
 int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
@@ -2983,7 +2983,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* get the lower 32-bits of an mp_int */
 unsigned long mp_get_int(mp_int * a) 
@@ -3026,7 +3026,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* grow as required */
 int mp_grow (mp_int * a, int size)
@@ -3081,7 +3081,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* init a new bigint */
 int mp_init (mp_int * a)
@@ -3118,7 +3118,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* creates "a" then copies b into it */
 int mp_init_copy (mp_int * a, mp_int * b)
@@ -3148,7 +3148,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 #include <stdarg.h>
 
 int mp_init_multi(mp_int *mp, ...) 
@@ -3205,7 +3205,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* initialize and set a digit */
 int mp_init_set (mp_int * a, mp_digit b)
@@ -3235,7 +3235,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* initialize and set a digit */
 int mp_init_set_int (mp_int * a, unsigned long b)
@@ -3264,7 +3264,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* init an mp_init for a given size */
 int mp_init_size (mp_int * a, int size)
@@ -3301,7 +3301,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* hac 14.61, pp608 */
 int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
@@ -3479,7 +3479,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* Check if remainders are possible squares - fast exclude non-squares */
 static const char rem_128[128] = {
@@ -3586,7 +3586,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes the jacobi c = (a | n) (or Legendre if n is prime)
  * HAC pp. 73 Algorithm 2.149
@@ -3689,7 +3689,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* c = |a| * |b| using Karatsuba Multiplication using 
  * three half size multiplications
@@ -3857,7 +3857,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* Karatsuba squaring, computes b = a*a using three 
  * half size squarings
@@ -3976,7 +3976,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes least common multiple as |a*b|/(a, b) */
 int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
@@ -4034,7 +4034,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* shift left a certain amount of digits */
 int mp_lshd (mp_int * a, int b)
@@ -4099,7 +4099,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* c = a mod b, 0 <= c < b */
 int
@@ -4145,7 +4145,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* calc a value mod 2**b */
 int
@@ -4198,7 +4198,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 int
 mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
@@ -4223,7 +4223,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* calculates a = B^n mod b for Montgomery reduction
  * Where B is the base [e.g. 2^DIGIT_BIT].
@@ -4280,7 +4280,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes xR**-1 == x (mod N) via Montgomery Reduction */
 int
@@ -4396,7 +4396,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* setups the montgomery reduction stuff */
 int
@@ -4453,7 +4453,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* high level multiplication (handles sign) */
 int mp_mul (mp_int * a, mp_int * b, mp_int * c)
@@ -4505,7 +4505,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* b = a*2 */
 int mp_mul_2(mp_int * a, mp_int * b)
@@ -4585,7 +4585,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* shift left by a certain bit count */
 int mp_mul_2d (mp_int * a, int b, mp_int * c)
@@ -4668,7 +4668,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* multiply by a digit */
 int
@@ -4744,7 +4744,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* d = a * b (mod c) */
 int
@@ -4783,7 +4783,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* find the n'th root of an integer 
  *
@@ -4913,7 +4913,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* b = -a */
 int mp_neg (mp_int * a, mp_int * b)
@@ -4945,7 +4945,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* OR two ints together */
 int mp_or (mp_int * a, mp_int * b, mp_int * c)
@@ -4993,7 +4993,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* performs one Fermat test.
  * 
@@ -5053,7 +5053,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* determines if an integers is divisible by one 
  * of the first PRIME_SIZE primes or not
@@ -5101,7 +5101,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* performs a variable number of rounds of Miller-Rabin
  *
@@ -5182,7 +5182,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* Miller-Rabin test of "a" to the base of "b" as described in 
  * HAC pp. 139 Algorithm 4.24
@@ -5283,7 +5283,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* finds the next prime after the number "a" using "t" trials
  * of Miller-Rabin.
@@ -5451,7 +5451,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* makes a truly random prime of a given size (bits),
  *
@@ -5573,7 +5573,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* returns size of ASCII reprensentation */
 int mp_radix_size (mp_int * a, int radix, int *size)
@@ -5642,7 +5642,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* chars used in radix conversions */
 const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
@@ -5664,7 +5664,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* makes a pseudo-random int of a given size */
 int
@@ -5717,7 +5717,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* read a string [ASCII] in a given radix */
 int mp_read_radix (mp_int * a, char *str, int radix)
@@ -5797,7 +5797,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* read signed bin, big endian, first byte is 0==positive or 1==negative */
 int
@@ -5837,7 +5837,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* reads a unsigned char array, assumes the msb is stored first [big endian] */
 int
@@ -5891,7 +5891,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* reduces x mod m, assumes 0 < x < m**2, mu is 
  * precomputed via mp_reduce_setup.
@@ -5979,7 +5979,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* reduces a modulo n where n is of the form 2**p - d */
 int
@@ -6039,7 +6039,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* determines the setup value */
 int 
@@ -6085,7 +6085,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* determines if mp_reduce_2k can be used */
 int mp_reduce_is_2k(mp_int *a)
@@ -6134,7 +6134,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* pre-calculate the value required for Barrett reduction
  * For a given modulus "b" it calulates the value required in "a"
@@ -6167,7 +6167,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* shift right a certain amount of digits */
 void mp_rshd (mp_int * a, int b)
@@ -6237,7 +6237,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* set to a digit */
 void mp_set (mp_int * a, mp_digit b)
@@ -6264,7 +6264,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* set a 32-bit const */
 int mp_set_int (mp_int * a, unsigned long b)
@@ -6310,7 +6310,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* shrink a bignum */
 int mp_shrink (mp_int * a)
@@ -6343,7 +6343,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* get the size for an signed equivalent */
 int mp_signed_bin_size (mp_int * a)
@@ -6368,7 +6368,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* computes b = a*a */
 int
@@ -6413,7 +6413,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* c = a * a (mod b) */
 int
@@ -6452,7 +6452,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* this function is less generic than mp_n_root, simpler and faster */
 int mp_sqrt(mp_int *arg, mp_int *ret) 
@@ -6531,7 +6531,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* high level subtraction (handles signs) */
 int
@@ -6588,7 +6588,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* single digit subtraction */
 int
@@ -6675,7 +6675,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* d = a - b (mod c) */
 int
@@ -6715,7 +6715,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* store in signed [big endian] format */
 int
@@ -6747,7 +6747,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* store in unsigned [big endian] format */
 int
@@ -6794,7 +6794,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* multiplication using the Toom-Cook 3-way algorithm */
 int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
@@ -7070,7 +7070,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* squaring using Toom-Cook 3-way algorithm */
 int
@@ -7294,7 +7294,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* stores a bignum as a ASCII string in a given radix (2..64) */
 int mp_toradix (mp_int * a, char *str, int radix)
@@ -7367,7 +7367,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* stores a bignum as a ASCII string in a given radix (2..64) 
  *
@@ -7454,7 +7454,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* get the size for an unsigned equivalent */
 int
@@ -7481,7 +7481,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* XOR two ints together */
 int
@@ -7530,7 +7530,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* set to zero */
 void
@@ -7558,7 +7558,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */
 static const struct {
@@ -7613,7 +7613,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 const mp_digit __prime_tab[] = {
   0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
   0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
@@ -7672,7 +7672,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* reverse an array, used for radix code */
 void
@@ -7709,7 +7709,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* low level addition, based on HAC pp.594, Algorithm 14.7 */
 int
@@ -7816,7 +7816,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 #ifdef MP_LOW_MEM
    #define TAB_SIZE 32
@@ -8054,7 +8054,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* multiplies |a| * |b| and only computes upto digs digits of result
  * HAC pp. 595, Algorithm 14.12  Modified so you can control how 
@@ -8143,7 +8143,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* multiplies |a| * |b| and does not compute the lower digs digits
  * [meant to get the higher part of the product]
@@ -8220,7 +8220,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
 int
@@ -8303,7 +8303,7 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
 int
@@ -8390,20 +8390,22 @@
  *
  * Tom St Denis, [email protected], http://math.libtomcrypt.org
  */
-#include <tommath.h>
+#include <ltc_tommath.h>
 
 /* Known optimal configurations
 
  CPU                    /Compiler     /MUL CUTOFF/SQR CUTOFF
 -------------------------------------------------------------
- Intel P4               /GCC v3.2     /        70/       108
- AMD Athlon XP          /GCC v3.2     /       109/       127
-
+ Intel P4 Northwood     /GCC v3.3.3   /        59/        81/profiled build
+ Intel P4 Northwood     /GCC v3.3.3   /        59/        80/profiled_single build
+ Intel P4 Northwood     /ICC v8.0     /        57/        70/profiled build
+ Intel P4 Northwood     /ICC v8.0     /        54/        76/profiled_single build
+ AMD Athlon XP          /GCC v3.2     /       109/       127/
+ 
 */
 
-/* configured for a AMD XP Thoroughbred core with etc/tune.c */
-int     KARATSUBA_MUL_CUTOFF = 70,      /* Min. number of digits before Karatsuba multiplication is used. */
-        KARATSUBA_SQR_CUTOFF = 108,      /* Min. number of digits before Karatsuba squaring is used. */
+int     KARATSUBA_MUL_CUTOFF = 57,      /* Min. number of digits before Karatsuba multiplication is used. */
+        KARATSUBA_SQR_CUTOFF = 70,      /* Min. number of digits before Karatsuba squaring is used. */
         
         TOOM_MUL_CUTOFF      = 350,      /* no optimal values of these are known yet so set em high */
         TOOM_SQR_CUTOFF      = 400; 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mpi_to_ltc_error.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,36 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MPI
+static const struct {
+    int mpi_code, ltc_code;
+} mpi_to_ltc_codes[] = {
+   { MP_OKAY ,  CRYPT_OK},
+   { MP_MEM  ,  CRYPT_MEM},
+   { MP_VAL  ,  CRYPT_INVALID_ARG},
+};
+
+/* convert a MPI error to a LTC error (Possibly the most powerful function ever!  Oh wait... no) */
+int mpi_to_ltc_error(int err)
+{
+   int x;
+
+   for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
+       if (err == mpi_to_ltc_codes[x].mpi_code) { 
+          return mpi_to_ltc_codes[x].ltc_code;
+       }
+   }
+   return CRYPT_ERROR;
+}
+#endif
+
--- a/mycrypt.h	Wed Jun 02 08:31:25 2004 +0000
+++ b/mycrypt.h	Tue Jun 15 14:27:14 2004 +0000
@@ -16,8 +16,8 @@
 #endif
 
 /* version */
-#define CRYPT   0x0095
-#define SCRYPT  "0.95"
+#define CRYPT   0x0096
+#define SCRYPT  "0.96"
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE           128
@@ -69,9 +69,7 @@
 #include <mycrypt_hash.h>
 #include <mycrypt_prng.h>
 #include <mycrypt_pk.h>
-#include <mycrypt_gf.h>
 #include <mycrypt_misc.h>
-#include <mycrypt_kr.h>
 #include <mycrypt_argchk.h>
 #include <mycrypt_pkcs.h>
 
--- a/mycrypt_argchk.h	Wed Jun 02 08:31:25 2004 +0000
+++ b/mycrypt_argchk.h	Tue Jun 15 14:27:14 2004 +0000
@@ -2,11 +2,7 @@
 
 /* ch1-01-1 */
 /* ARGTYPE is defined in mycrypt_cfg.h */
-#if ARGTYPE == 2 || defined(NDEBUG)
-
-#define _ARGCHK(x) 
-
-#elif ARGTYPE == 0
+#if ARGTYPE == 0
 
 #include <signal.h>
 
@@ -19,6 +15,10 @@
 /* fatal type of error */
 #define _ARGCHK(x) assert((x))
 
+#elif ARGTYPE == 2
+
+#define _ARGCHK(x) 
+
 #endif
 /* ch1-01-1 */
 
--- a/mycrypt_cipher.h	Wed Jun 02 08:31:25 2004 +0000
+++ b/mycrypt_cipher.h	Tue Jun 15 14:27:14 2004 +0000
@@ -261,12 +261,22 @@
 #define aes_test            rijndael_test
 #define aes_keysize         rijndael_keysize
 
+#define aes_enc_setup           rijndael_enc_setup
+#define aes_enc_ecb_encrypt     rijndael_enc_ecb_encrypt
+#define aes_enc_keysize         rijndael_enc_keysize
+
 extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
 extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
 extern void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
 extern int rijndael_test(void);
 extern int rijndael_keysize(int *desired_keysize);
+
+extern int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+extern void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
+extern int rijndael_enc_keysize(int *desired_keysize);
+
 extern const struct _cipher_descriptor rijndael_desc, aes_desc;
+extern const struct _cipher_descriptor rijndael_enc_desc, aes_enc_desc;
 #endif
 
 #ifdef XTEA
@@ -342,6 +352,8 @@
                      int keylen, int num_rounds, symmetric_CFB *cfb);
 extern int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
 extern int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
+extern int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb);
+extern int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb);
 #endif
 
 #ifdef OFB
@@ -349,6 +361,8 @@
                      int keylen, int num_rounds, symmetric_OFB *ofb);
 extern int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb);
 extern int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
+extern int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb);
+extern int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb);
 #endif
 
 #ifdef CBC
@@ -356,6 +370,8 @@
                      int keylen, int num_rounds, symmetric_CBC *cbc);
 extern int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc);
 extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc);
+extern int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc);
+extern int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc);
 #endif
 
 #ifdef CTR
@@ -363,6 +379,8 @@
                      int keylen, int num_rounds, symmetric_CTR *ctr);
 extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
 extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
+extern int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
+extern int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
 #endif
 
 
--- a/mycrypt_custom.h	Wed Jun 02 08:31:25 2004 +0000
+++ b/mycrypt_custom.h	Tue Jun 15 14:27:14 2004 +0000
@@ -12,6 +12,7 @@
 	#error mycrypt_custom.h should be included before mycrypt.h
 #endif
 
+/* macros for various libc functions */
 #define XMALLOC malloc
 #define XREALLOC realloc
 #define XCALLOC calloc
@@ -24,6 +25,8 @@
 #endif
 
 /* #define LTC_TEST */
+#define CLEAN_STACK
+#define NO_FILE
 
 #ifdef DROPBEAR_BLOWFISH_CBC
 #define BLOWFISH
--- a/mycrypt_hash.h	Wed Jun 02 08:31:25 2004 +0000
+++ b/mycrypt_hash.h	Tue Jun 15 14:27:14 2004 +0000
@@ -116,6 +116,8 @@
     unsigned char ID;
     unsigned long hashsize;       /* digest output size in bytes  */
     unsigned long blocksize;      /* the block size the hash uses */
+    unsigned char DER[64];        /* DER encoded identifier */
+    unsigned long DERlen;         /* length of DER encoding */
     void (*init)(hash_state *);
     int (*process)(hash_state *, const unsigned char *, unsigned long);
     int (*done)(hash_state *, unsigned char *);
--- a/mycrypt_pk.h	Wed Jun 02 08:31:25 2004 +0000
+++ b/mycrypt_pk.h	Tue Jun 15 14:27:14 2004 +0000
@@ -1,7 +1,7 @@
 /* ---- NUMBER THEORY ---- */
 #ifdef MPI
 
-#include "tommath.h"
+#include "ltc_tommath.h"
 
 /* in/out macros */
 #define OUTPUT_BIGNUM(num, out, y, z)                                                             \
@@ -86,7 +86,7 @@
 #define MAX_RSA_SIZE 4096
 
 /* Stack required for temps (plus padding) */
-#define RSA_STACK    (8 + (MAX_RSA_SIZE/8))
+// #define RSA_STACK    (8 + (MAX_RSA_SIZE/8))
 
 typedef struct Rsa_key {
     int type;
@@ -95,43 +95,51 @@
 
 extern int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
 
-extern int rsa_exptmod(const unsigned char *in,  unsigned long inlen, 
-                             unsigned char *out, unsigned long *outlen, int which, 
-                             rsa_key *key);
+extern int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
+                      unsigned char *out,  unsigned long *outlen, int which,
+                      prng_state    *prng, int           prng_idx,
+                      rsa_key *key);
 
-extern int rsa_pad(const unsigned char *in,  unsigned long inlen, 
-                         unsigned char *out, unsigned long *outlen, 
-                         int wprng, prng_state *prng);
+#ifdef RSA_TIMING
 
-extern int rsa_signpad(const unsigned char *in,  unsigned long inlen, 
-                             unsigned char *out, unsigned long *outlen);
+extern int tim_exptmod(prng_state *prng, int prng_idx, 
+                       mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m);
 
-extern int rsa_depad(const unsigned char *in,  unsigned long inlen, 
-                           unsigned char *out, unsigned long *outlen);
+#else
 
-extern int rsa_signdepad(const unsigned char *in,  unsigned long inlen,
-                               unsigned char *out, unsigned long *outlen);
+#define tim_exptmod(prng, prng_idx, c, e, d, n, m) mpi_to_ltc_error(mp_exptmod(c, d, n, m))
 
+#endif
 
 extern void rsa_free(rsa_key *key);
 
-extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
-                                 unsigned char *outkey, unsigned long *outlen,
-                                 prng_state *prng, int wprng, rsa_key *key);
-
-extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
-                                 unsigned char *outkey, unsigned long *keylen, 
-                                 rsa_key *key);
+int rsa_encrypt_key(const unsigned char *inkey,  unsigned long inlen,
+                          unsigned char *outkey, unsigned long *outlen,
+                    const unsigned char *lparam, unsigned long lparamlen,
+                    prng_state *prng, int prng_idx, int hash_idx, rsa_key *key);
+                                        
+int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
+                          unsigned char *outkey, unsigned long *keylen, 
+                    const unsigned char *lparam, unsigned long lparamlen,
+                          prng_state    *prng,   int           prng_idx,
+                          int            hash_idx, int *res,
+                          rsa_key       *key);
 
-extern int rsa_sign_hash(const unsigned char *in,  unsigned long inlen, 
-                               unsigned char *out, unsigned long *outlen, 
-                               rsa_key *key);
+int rsa_sign_hash(const unsigned char *msghash,  unsigned long  msghashlen, 
+                        unsigned char *sig,      unsigned long *siglen, 
+                        prng_state    *prng,     int            prng_idx,
+                        int            hash_idx, unsigned long  saltlen,
+                        rsa_key *key);
 
-extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
-                           const unsigned char *hash, int *stat, rsa_key *key);
+int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
+                    const unsigned char *msghash,  unsigned long msghashlen,
+                          prng_state    *prng,     int           prng_idx,
+                          int            hash_idx, unsigned long saltlen,
+                          int           *stat,     rsa_key      *key);
 
-extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
-extern int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
+int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
+int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key);
+                        
 #endif
 
 /* ---- DH Routines ---- */
--- a/mycrypt_pkcs.h	Wed Jun 02 08:31:25 2004 +0000
+++ b/mycrypt_pkcs.h	Tue Jun 15 14:27:14 2004 +0000
@@ -7,20 +7,25 @@
                       int            hash_idx,
                       unsigned char *mask, unsigned long masklen);
 
+int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out);
+int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen);
+
+/* *** v2.0 padding */
 int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
-                             unsigned long modulus_bitlen, int hash_idx,
-                             int           prng_idx,    prng_state *prng,
+                             unsigned long modulus_bitlen, prng_state *prng,
+                             int           prng_idx,         int  hash_idx,
                              unsigned char *out,    unsigned long *outlen);
 
 int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
                        const unsigned char *lparam, unsigned long lparamlen,
                              unsigned long modulus_bitlen, int hash_idx,
-                             unsigned char *out,    unsigned long *outlen);
+                             unsigned char *out,    unsigned long *outlen,
+                             int           *res);
 
 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
-                            unsigned long saltlen,  int           hash_idx,
-                            int           prng_idx, prng_state   *prng,
+                            unsigned long saltlen,  prng_state   *prng,     
+                            int           prng_idx, int           hash_idx,
                             unsigned long modulus_bitlen,
                             unsigned char *out,     unsigned long *outlen);
 
@@ -29,8 +34,30 @@
                             unsigned long saltlen,  int           hash_idx,
                             unsigned long modulus_bitlen, int    *res);
 
-int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out);
-int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen);
+/* *** v1.5 padding */
+/* encryption padding */
+int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
+                               unsigned long  modulus_bitlen, 
+                               prng_state    *prng,   int           prng_idx,
+                               unsigned char *out,    unsigned long *outlen);
+
+/* note "outlen" is fixed, you have to tell this decoder how big
+ * the original message was.  Unlike the OAEP decoder it cannot auto-detect it.
+ */
+int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
+                               unsigned long modulus_bitlen,
+                               unsigned char *out,  unsigned long outlen,
+                               int           *res);
+
+/* signature padding */
+int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
+                               int            hash_idx, unsigned long modulus_bitlen,
+                               unsigned char *out,      unsigned long *outlen);
+
+int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
+                         const unsigned char *sig,     unsigned long siglen,
+                               int           hash_idx, unsigned long modulus_bitlen, 
+                               int          *res);
 
 
 #endif /* PKCS_1 */
--- a/ocb_decrypt.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/ocb_decrypt.c	Tue Jun 15 14:27:14 2004 +0000
@@ -22,9 +22,14 @@
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != NULL);
    _ARGCHK(ct  != NULL);
+
+   /* check if valid cipher */
    if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
       return err;
    }
+   _ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL);
+   
+   /* check length */
    if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
       return CRYPT_INVALID_ARG;
    }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofb_getiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,30 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef OFB
+
+int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb)
+{
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(len != NULL);
+   _ARGCHK(ofb != NULL);
+   if ((unsigned long)ofb->blocklen > *len) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   memcpy(IV, ofb->IV, ofb->blocklen);
+   *len = ofb->blocklen;
+
+   return CRYPT_OK;
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ofb_setiv.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,38 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef OFB
+
+int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
+{
+   int err;
+
+   _ARGCHK(IV  != NULL);
+   _ARGCHK(ofb != NULL);
+
+   if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
+       return err;
+   }
+
+   if (len != (unsigned long)ofb->blocklen) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* force next block */
+   ofb->padlen = 0;
+   cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
+   return CRYPT_OK;
+}
+
+#endif 
+
--- a/pkcs_1_oaep_decode.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/pkcs_1_oaep_decode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -15,9 +15,10 @@
 #ifdef PKCS_1
 
 int pkcs_1_oaep_decode(const unsigned char *msg,    unsigned long msglen,
-                        const unsigned char *lparam, unsigned long lparamlen,
-                              unsigned long modulus_bitlen, int hash_idx,
-                              unsigned char *out,    unsigned long *outlen)
+                       const unsigned char *lparam, unsigned long lparamlen,
+                             unsigned long modulus_bitlen, int hash_idx,
+                             unsigned char *out,    unsigned long *outlen,
+                             int           *res)
 {
    unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
    unsigned long hLen, x, y, modulus_len;
@@ -26,6 +27,10 @@
    _ARGCHK(msg    != NULL);
    _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
+   _ARGCHK(res    != NULL);
+
+   /* default to invalid packet */
+   *res = 0;
    
    /* test valid hash */
    if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { 
@@ -49,7 +54,7 @@
 
    /* must have leading 0x00 byte */
    if (msg[0] != 0x00) {
-      return CRYPT_INVALID_PACKET;
+      return CRYPT_OK;
    }
 
    /* now read the masked seed */
@@ -99,7 +104,7 @@
 
    /* compare the lhash'es */
    if (memcmp(seed, DB, hLen) != 0) {
-      return CRYPT_INVALID_PACKET;
+      return CRYPT_OK;
    }
 
    /* now zeroes before a 0x01 */
@@ -109,7 +114,7 @@
 
    /* error out if wasn't 0x01 */
    if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
-      return CRYPT_INVALID_PACKET;
+      return CRYPT_OK;
    }
 
    /* rest is the message (and skip 0x01) */
@@ -129,6 +134,9 @@
    zeromem(mask, sizeof(mask));
 #endif
 
+   /* valid packet */
+   *res = 1;
+
    return CRYPT_OK;
 }
 
--- a/pkcs_1_oaep_encode.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/pkcs_1_oaep_encode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -15,10 +15,10 @@
 #ifdef PKCS_1
 
 int pkcs_1_oaep_encode(const unsigned char *msg,    unsigned long msglen,
-                        const unsigned char *lparam, unsigned long lparamlen,
-                              unsigned long modulus_bitlen, int hash_idx,
-                              int           prng_idx,    prng_state *prng,
-                              unsigned char *out,    unsigned long *outlen)
+                       const unsigned char *lparam, unsigned long lparamlen,
+                             unsigned long modulus_bitlen, prng_state *prng,
+                             int           prng_idx,         int  hash_idx,
+                             unsigned char *out,    unsigned long *outlen)
 {
    unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
    unsigned long hLen, x, y, modulus_len;
--- a/pkcs_1_pss_decode.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/pkcs_1_pss_decode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -60,7 +60,7 @@
    }
 
    /* check the MSB */
-   if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - modulus_bitlen))) != 0) {
+   if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
       return CRYPT_OK;
    }
 
@@ -73,6 +73,9 @@
    for (y = 0; y < (modulus_len - hLen - 1); y++) {
       DB[y] ^= mask[y];
    }
+   
+   /* now clear the first byte [make sure smaller than modulus] */
+   DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
 
    /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
 
--- a/pkcs_1_pss_encode.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/pkcs_1_pss_encode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -15,8 +15,8 @@
 #ifdef PKCS_1
 
 int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
-                            unsigned long saltlen,  int           hash_idx,
-                            int           prng_idx, prng_state   *prng,
+                            unsigned long saltlen,  prng_state   *prng,     
+                            int           prng_idx, int           hash_idx,
                             unsigned long modulus_bitlen,
                             unsigned char *out,     unsigned long *outlen)
 {
@@ -104,7 +104,7 @@
    out[y] = 0xBC;
 
    /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
-   out[0] &= 0xFF >> ((modulus_len<<3) - modulus_bitlen);
+   out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
 
    /* store output size */
    *outlen = modulus_len;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkcs_1_v15_es_decode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,61 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* PKCS #1 v1.5 Encryption Padding -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_es_decode(const unsigned char *msg,  unsigned long msglen,
+                               unsigned long modulus_bitlen,
+                               unsigned char *out,  unsigned long outlen,
+                               int           *res)
+{
+   unsigned long x, modulus_bytelen;
+
+   _ARGCHK(msg != NULL);
+   _ARGCHK(out != NULL);
+   _ARGCHK(res != NULL);
+   
+   /* default to failed */
+   *res = 0;
+
+   /* must be at least 12 bytes long */
+   if (msglen < 12) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+
+   /* should start with 0x00 0x02 */
+   if (msg[0] != 0x00 || msg[1] != 0x02) {
+      return CRYPT_OK;
+   }
+   
+   /* skip over PS */
+   x = 2 + (modulus_bytelen - outlen - 3);
+
+   /* should be 0x00 */
+   if (msg[x++] != 0x00) {
+      return CRYPT_OK;
+   }
+
+   /* the message is left */
+   if (x + outlen > modulus_bytelen) {
+      return CRYPT_PK_INVALID_SIZE;
+   }
+   memcpy(out, msg + x, outlen);
+   *res = 1;
+   return CRYPT_OK;
+}
+
+#endif 
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkcs_1_v15_es_encode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,55 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* v1.5 Encryption Padding for PKCS #1 -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_es_encode(const unsigned char *msg,    unsigned long msglen,
+                               unsigned long  modulus_bitlen, 
+                               prng_state    *prng,   int           prng_idx,
+                               unsigned char *out,    unsigned long *outlen)
+{ 
+   unsigned long modulus_bytelen, x, y;
+
+   _ARGCHK(msg    != NULL);
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+
+   /* get modulus len */
+   modulus_bytelen = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
+   if (modulus_bytelen < 12) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* verify length */
+   if (msglen > (modulus_bytelen - 11) || *outlen < modulus_bytelen) {
+      return CRYPT_PK_INVALID_SIZE;
+   }
+
+   /* 0x00 0x02 PS 0x00 M */
+   x = 0;
+   out[x++] = 0x00;
+   out[x++] = 0x02;
+   y = modulus_bytelen - msglen - 3;
+   if (prng_descriptor[prng_idx].read(out+x, y, prng) != y) {
+      return CRYPT_ERROR_READPRNG;
+   }
+   x += y;
+   out[x++] = 0x00;
+   memcpy(out+x, msg, msglen);
+   *outlen = modulus_bytelen;
+
+   return CRYPT_OK;
+}
+
+#endif /* PKCS_1 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkcs_1_v15_sa_decode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,77 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* PKCS #1 v1.5 Signature Padding -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
+                         const unsigned char *sig,     unsigned long siglen,
+                               int           hash_idx, unsigned long modulus_bitlen, 
+                               int          *res)
+{
+   unsigned long x, y, modulus_bytelen, derlen;
+   int err;
+   
+   _ARGCHK(msghash != NULL);
+   _ARGCHK(sig     != NULL);
+   _ARGCHK(res     != NULL);
+
+   /* default to invalid */
+   *res = 0;
+
+   /* valid hash ? */
+   if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* get derlen */
+   derlen = hash_descriptor[hash_idx].DERlen;
+
+   /* get modulus len */
+   modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+
+   /* valid sizes? */
+   if ((msghashlen + 3 + derlen > modulus_bytelen) || (siglen != modulus_bytelen)) {
+      return CRYPT_PK_INVALID_SIZE;
+   }
+
+   /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
+   x = 0;
+   if (sig[x++] != 0x00 || sig[x++] != 0x01) {
+      return CRYPT_OK;
+   }
+
+   /* now follows (modulus_bytelen - 3 - derlen - msghashlen) 0xFF bytes */
+   for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
+     if (sig[x++] != 0xFF) {
+        return CRYPT_OK;
+     }
+   }
+
+   if (sig[x++] != 0x00) {
+      return CRYPT_OK;
+   }
+
+   for (y = 0; y < derlen; y++) {
+      if (sig[x++] != hash_descriptor[hash_idx].DER[y]) {
+         return CRYPT_OK;
+      }
+   }
+
+   if (memcmp(msghash, sig+x, msghashlen) == 0) {
+      *res = 1;
+   }
+   return CRYPT_OK;
+}
+
+#endif 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkcs_1_v15_sa_encode.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,71 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+#include "mycrypt.h"
+
+/* PKCS #1 v1.5 Signature Padding -- Tom St Denis */
+
+#ifdef PKCS_1
+
+int pkcs_1_v15_sa_encode(const unsigned char *msghash,  unsigned long msghashlen,
+                               int            hash_idx, unsigned long modulus_bitlen,
+                               unsigned char *out,      unsigned long *outlen)
+{
+  unsigned long derlen, modulus_bytelen, x, y;
+  int err;
+
+  _ARGCHK(msghash != NULL)
+  _ARGCHK(out     != NULL);
+  _ARGCHK(outlen  != NULL);
+
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+
+  /* hack, to detect any hash without a DER OID */
+  if (hash_descriptor[hash_idx].DERlen == 0) {
+     return CRYPT_INVALID_ARG; 
+  }
+
+  /* get modulus len */
+  modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
+
+  /* get der len ok?  Forgive my lame German accent.... */
+  derlen = hash_descriptor[hash_idx].DERlen;
+
+  /* valid sizes? */
+  if (msghashlen + 3 + derlen > modulus_bytelen) {
+     return CRYPT_PK_INVALID_SIZE;
+  }
+
+  if (*outlen < modulus_bytelen) {
+     return CRYPT_BUFFER_OVERFLOW;
+  }
+
+  /* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
+  x = 0;
+  out[x++] = 0x00;
+  out[x++] = 0x01;
+  for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
+     out[x++] = 0xFF;
+  }
+  out[x++] = 0x00;
+  for (y = 0; y < derlen; y++) {
+     out[x++] = hash_descriptor[hash_idx].DER[y];
+  }
+  for (y = 0; y < msghashlen; y++) {
+     out[x++] = msghash[y];
+  }
+
+  *outlen = modulus_bytelen;
+  return CRYPT_OK;
+}
+
+#endif /* PKCS_1 */
--- a/rand_prime.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/rand_prime.c	Tue Jun 15 14:27:14 2004 +0000
@@ -54,11 +54,7 @@
    /* New prime generation makes the code even more cryptoish-insane.  Do you know what this means!!!
       -- Gir:  Yeah, oh wait, er, no.
     */
-   if ((err = mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng)) != MP_OKAY) {
-      return mpi_to_ltc_error(err);
-   }
-
-   return CRYPT_OK;
+   return mpi_to_ltc_error(mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng));
 }
       
 #endif
--- a/rmd128.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/rmd128.c	Tue Jun 15 14:27:14 2004 +0000
@@ -24,6 +24,11 @@
     8,
     16,
     64,
+
+    /* DER identifier (not supported) */
+    { 0x00 },
+    0,
+
     &rmd128_init,
     &rmd128_process,
     &rmd128_done,
--- a/rmd160.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/rmd160.c	Tue Jun 15 14:27:14 2004 +0000
@@ -24,6 +24,12 @@
     9,
     20,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 
+      0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 },
+    15,
+
     &rmd160_init,
     &rmd160_process,
     &rmd160_done,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rsa_decrypt_key.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,61 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* decrypt then OAEP depad  */
+int rsa_decrypt_key(const unsigned char *in,     unsigned long inlen,
+                          unsigned char *outkey, unsigned long *keylen, 
+                    const unsigned char *lparam, unsigned long lparamlen,
+                          prng_state    *prng,   int           prng_idx,
+                          int            hash_idx, int *res,
+                          rsa_key       *key)
+{
+  unsigned long modulus_bitlen, modulus_bytelen, x;
+  int           err;
+  
+  _ARGCHK(outkey != NULL);
+  _ARGCHK(keylen != NULL);
+  _ARGCHK(key    != NULL);
+  _ARGCHK(res    != NULL);
+  
+  /* valid hash ? */
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen != inlen) {
+     return CRYPT_INVALID_PACKET;
+  }
+
+  /* rsa decode the packet */
+  x = *keylen;
+  if ((err = rsa_exptmod(in, inlen, outkey, &x, PK_PRIVATE, prng, prng_idx, key)) != CRYPT_OK) {
+     return err;
+  }
+
+  /* now OAEP decode the packet */
+  return pkcs_1_oaep_decode(outkey, x, lparam, lparamlen, modulus_bitlen, hash_idx,
+                            outkey, keylen, res);
+}
+
+#endif /* MRSA */
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rsa_encrypt_key.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,59 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* OAEP pad then encrypt */
+int rsa_encrypt_key(const unsigned char *inkey,  unsigned long inlen,
+                          unsigned char *outkey, unsigned long *outlen,
+                    const unsigned char *lparam, unsigned long lparamlen,
+                    prng_state *prng, int prng_idx, int hash_idx, rsa_key *key)
+{
+  unsigned long modulus_bitlen, modulus_bytelen, x;
+  int           err;
+  
+  _ARGCHK(inkey  != NULL);
+  _ARGCHK(outkey != NULL);
+  _ARGCHK(outlen != NULL);
+  _ARGCHK(key    != NULL);
+  
+  /* valid prng and hash ? */
+  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+     return err;
+  }
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen > *outlen) {
+     return CRYPT_BUFFER_OVERFLOW;
+  }
+      
+  /* OAEP pad the key */
+  x = *outlen;
+  if ((err = pkcs_1_oaep_encode(inkey, inlen, lparam, 
+                                lparamlen, modulus_bitlen, prng, prng_idx, hash_idx, 
+                                outkey, &x)) != CRYPT_OK) {
+     return err;
+  }                                
+
+  /* rsa exptmod the OAEP pad */
+  return rsa_exptmod(outkey, x, outkey, outlen, PK_PUBLIC, prng, prng_idx, key);
+}
+
+#endif /* MRSA */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rsa_export.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,72 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
+{
+   unsigned long y, z; 
+   int err;
+
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+   _ARGCHK(key    != NULL);
+   
+   /* can we store the static header?  */
+   if (*outlen < (PACKET_SIZE + 1)) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }   
+
+   /* type valid? */
+   if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
+        (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
+      return CRYPT_PK_INVALID_TYPE;
+   }
+
+   /* start at offset y=PACKET_SIZE */
+   y = PACKET_SIZE;
+
+   /* output key type */
+   out[y++] = type;
+
+   /* output modulus */
+   OUTPUT_BIGNUM(&key->N, out, y, z);
+
+   /* output public key */
+   OUTPUT_BIGNUM(&key->e, out, y, z);
+
+   if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
+      OUTPUT_BIGNUM(&key->d, out, y, z);
+   }
+
+   if (type == PK_PRIVATE_OPTIMIZED) {
+      OUTPUT_BIGNUM(&key->dQ, out, y, z);
+      OUTPUT_BIGNUM(&key->dP, out, y, z);
+      OUTPUT_BIGNUM(&key->pQ, out, y, z);
+      OUTPUT_BIGNUM(&key->qP, out, y, z);
+      OUTPUT_BIGNUM(&key->p, out, y, z);
+      OUTPUT_BIGNUM(&key->q, out, y, z);
+   }
+
+   /* store packet header */
+   packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY);
+
+   /* copy to the user buffer */
+   *outlen = y;
+
+   /* clear stack and return */
+   return CRYPT_OK;
+}
+
+#endif /* MRSA */
+
--- a/rsa_exptmod.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/rsa_exptmod.c	Tue Jun 15 14:27:14 2004 +0000
@@ -14,18 +14,23 @@
 
 #ifdef MRSA
 
-int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
-                      unsigned char *out, unsigned long *outlen, int which,
+int rsa_exptmod(const unsigned char *in,   unsigned long inlen,
+                      unsigned char *out,  unsigned long *outlen, int which,
+                      prng_state    *prng, int           prng_idx,
                       rsa_key *key)
 {
-   mp_int tmp, tmpa, tmpb;
+   mp_int        tmp, tmpa, tmpb;
    unsigned long x;
-   int err;
+   int           err;
 
    _ARGCHK(in     != NULL);
    _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(key    != NULL);
+   
+   if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+      return err;
+   }
 
    if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) {
       return CRYPT_PK_NOT_PRIVATE;
@@ -49,10 +54,10 @@
    /* are we using the private exponent and is the key optimized? */
    if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) {
       /* tmpa = tmp^dP mod p */
-      if ((err = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != MP_OKAY)    { goto error; }
+      if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->dP, &key->p, &tmpa)) != MP_OKAY)    { goto error; }
 
       /* tmpb = tmp^dQ mod q */
-      if ((err = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != MP_OKAY)    { goto error; }
+      if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e,  &key->dQ, &key->q, &tmpb)) != MP_OKAY)    { goto error; }
 
       /* tmp = tmpa*qP + tmpb*pQ mod N */
       if ((err = mp_mul(&tmpa, &key->qP, &tmpa)) != MP_OKAY)                { goto error; }
@@ -60,11 +65,15 @@
       if ((err = mp_addmod(&tmpa, &tmpb, &key->N, &tmp)) != MP_OKAY)        { goto error; }
    } else {
       /* exptmod it */
-      if ((err = mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp)) != MP_OKAY) { goto error; }
+      if (which == PK_PRIVATE) {
+         if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->d, &key->N, &tmp)) != MP_OKAY) { goto error; }
+      } else {
+         if ((err = mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != MP_OKAY) { goto error; }
+      }
    }
 
    /* read it back */
-   x = (unsigned long)mp_unsigned_bin_size(&tmp);
+   x = (unsigned long)mp_unsigned_bin_size(&key->N);
    if (x > *outlen) {
       err = CRYPT_BUFFER_OVERFLOW;
       goto done;
@@ -72,7 +81,8 @@
    *outlen = x;
 
    /* convert it */
-   if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY)                    { goto error; }
+   zeromem(out, x);
+   if ((err = mp_to_unsigned_bin(&tmp, out+(x-mp_unsigned_bin_size(&tmp)))) != MP_OKAY) { goto error; }
 
    /* clean up and return */
    err = CRYPT_OK;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rsa_import.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,81 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
+{
+   unsigned long x, y;
+   int err;
+
+   _ARGCHK(in  != NULL);
+   _ARGCHK(key != NULL);
+
+   /* check length */
+   if (inlen < (1+PACKET_SIZE)) {
+      return CRYPT_INVALID_PACKET;
+   }
+
+   /* test packet header */
+   if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* init key */
+   if ((err = mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
+                     &key->pQ, &key->p, &key->q, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
+   }
+
+   /* get key type */
+   y = PACKET_SIZE;
+   key->type = (int)in[y++];
+
+   /* load the modulus  */
+   INPUT_BIGNUM(&key->N, in, x, y, inlen);
+
+   /* load public exponent */
+   INPUT_BIGNUM(&key->e, in, x, y, inlen);
+
+   /* get private exponent */
+   if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) {
+      INPUT_BIGNUM(&key->d, in, x, y, inlen);
+   }
+
+   /* get CRT private data if required */
+   if (key->type == PK_PRIVATE_OPTIMIZED) {
+      INPUT_BIGNUM(&key->dQ, in, x, y, inlen);
+      INPUT_BIGNUM(&key->dP, in, x, y, inlen);
+      INPUT_BIGNUM(&key->pQ, in, x, y, inlen);
+      INPUT_BIGNUM(&key->qP, in, x, y, inlen);
+      INPUT_BIGNUM(&key->p, in, x, y, inlen);
+      INPUT_BIGNUM(&key->q, in, x, y, inlen);
+   }
+
+   /* free up ram not required */
+   if (key->type != PK_PRIVATE_OPTIMIZED) {
+      mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
+   }
+   if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
+      mp_clear(&key->d);
+   }
+
+   return CRYPT_OK;
+error:
+   mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
+                  &key->pQ, &key->qP, &key->p, &key->q, NULL);
+   return err;
+}
+
+#endif /* MRSA */
+
--- a/rsa_make_key.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/rsa_make_key.c	Tue Jun 15 14:27:14 2004 +0000
@@ -17,7 +17,7 @@
 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
 {
    mp_int p, q, tmp1, tmp2, tmp3;
-   int err;
+   int    err;
 
    _ARGCHK(key != NULL);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rsa_sign_hash.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,59 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* PSS pad then sign */
+int rsa_sign_hash(const unsigned char *msghash,  unsigned long  msghashlen, 
+                        unsigned char *sig,      unsigned long *siglen, 
+                        prng_state    *prng,     int            prng_idx,
+                        int            hash_idx, unsigned long  saltlen,
+                        rsa_key *key)
+{
+   unsigned long modulus_bitlen, modulus_bytelen, x;
+   int           err;
+   
+  _ARGCHK(msghash  != NULL);
+  _ARGCHK(sig      != NULL);
+  _ARGCHK(siglen   != NULL);
+  _ARGCHK(key      != NULL);
+  
+  /* valid prng and hash ? */
+  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+     return err;
+  }
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen > *siglen) {
+     return CRYPT_BUFFER_OVERFLOW;
+  }
+      
+  /* PSS pad the key */
+  x = *siglen;
+  if ((err = pkcs_1_pss_encode(msghash, msghashlen, saltlen, prng, prng_idx,
+                               hash_idx, modulus_bitlen, sig, &x)) != CRYPT_OK) {
+     return err;
+  }
+
+  /* RSA encode it */
+  return rsa_exptmod(sig, x, sig, siglen, PK_PRIVATE, prng, prng_idx, key);
+}
+
+#endif /* MRSA */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rsa_verify_hash.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,69 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+#include "mycrypt.h"
+
+#ifdef MRSA
+
+/* design then PSS depad */
+int rsa_verify_hash(const unsigned char *sig,      unsigned long siglen,
+                    const unsigned char *msghash,  unsigned long msghashlen,
+                          prng_state    *prng,     int           prng_idx,
+                          int            hash_idx, unsigned long saltlen,
+                          int           *stat,     rsa_key      *key)
+{
+   unsigned long modulus_bitlen, modulus_bytelen, x;
+   int           err;
+   unsigned char *tmpbuf;
+   
+  _ARGCHK(msghash  != NULL);
+  _ARGCHK(sig      != NULL);
+  _ARGCHK(stat     != NULL);
+  _ARGCHK(key      != NULL);
+  
+  /* valid hash ? */
+  if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
+     return err;
+  }
+
+  if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+     return err;
+  }
+  
+  /* get modulus len in bits */
+  modulus_bitlen = mp_count_bits(&(key->N));
+
+  /* outlen must be at least the size of the modulus */
+  modulus_bytelen = mp_unsigned_bin_size(&(key->N));
+  if (modulus_bytelen != siglen) {
+     return CRYPT_INVALID_PACKET;
+  }
+  
+  /* allocate temp buffer for decoded sig */
+  tmpbuf = XCALLOC(1, modulus_bytelen + 1);
+  if (tmpbuf == NULL) {
+     return CRYPT_MEM;
+  }
+      
+  /* RSA decode it  */
+  x = siglen;
+  if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, prng, prng_idx, key)) != CRYPT_OK) {
+     XFREE(tmpbuf);
+     return err;
+  }
+  
+  /* PSS decode it */
+  err = pkcs_1_pss_decode(msghash, msghashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
+  XFREE(tmpbuf);
+  return err;
+}
+
+#endif /* MRSA */
--- a/sha1.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/sha1.c	Tue Jun 15 14:27:14 2004 +0000
@@ -20,6 +20,12 @@
     2,
     20,
     64,
+
+    /* DER identifier */
+    { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 
+      0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 },
+    15,
+
     &sha1_init,
     &sha1_process,
     &sha1_done,
@@ -38,6 +44,9 @@
 #endif
 {
     ulong32 a,b,c,d,e,W[80],i;
+#ifdef SMALL_CODE
+    ulong32 t;
+#endif
 
     /* copy the state into 512-bits into W[0..15] */
     for (i = 0; i < 16; i++) {
@@ -63,6 +72,26 @@
     #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
     #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
  
+#ifdef SMALL_CODE
+ 
+    for (i = 0; i < 20; ) {
+       FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 40; ) {
+       FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 60; ) {
+       FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+    for (; i < 80; ) {
+       FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
+    }
+
+#else
+
     for (i = 0; i < 20; ) {
        FF0(a,b,c,d,e,i++);
        FF0(e,a,b,c,d,i++);
@@ -97,6 +126,7 @@
        FF3(c,d,e,a,b,i++);
        FF3(b,c,d,e,a,i++);
     }
+#endif
 
     #undef FF0
     #undef FF1
--- a/sha224.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/sha224.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,93 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-/* SHA-224 new NIST standard based off of SHA-256 truncated to 224 bits */
-const struct _hash_descriptor sha224_desc =
-{
-    "sha224",
-    10,
-    28,
-    64,
-    &sha224_init,
-    &sha256_process,
-    &sha224_done,
-    &sha224_test
-};
-
-/* init the sha256 er... sha224 state ;-) */
-void sha224_init(hash_state * md)
-{
-    _ARGCHK(md != NULL);
-
-    md->sha256.curlen = 0;
-    md->sha256.length = 0;
-    md->sha256.state[0] = 0xc1059ed8UL;
-    md->sha256.state[1] = 0x367cd507UL;
-    md->sha256.state[2] = 0x3070dd17UL;
-    md->sha256.state[3] = 0xf70e5939UL;
-    md->sha256.state[4] = 0xffc00b31UL;
-    md->sha256.state[5] = 0x68581511UL;
-    md->sha256.state[6] = 0x64f98fa7UL;
-    md->sha256.state[7] = 0xbefa4fa4UL;
-}
-
-int sha224_done(hash_state * md, unsigned char *hash)
-{
-    unsigned char buf[32];
-    int err;
-
-    err = sha256_done(md, buf);
-    memcpy(hash, buf, 28);
-#ifdef CLEAN_STACK
-    zeromem(buf, sizeof(buf));
-#endif 
-    return err;
-}
-
-int  sha224_test(void)
-{
- #ifndef LTC_TEST
-    return CRYPT_NOP;
- #else    
-  static const struct {
-      char *msg;
-      unsigned char hash[28];
-  } tests[] = {
-    { "abc",
-      { 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8,
-        0x22, 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2,
-        0x55, 0xb3, 0x2a, 0xad, 0xbc, 0xe4, 0xbd,
-        0xa0, 0xb3, 0xf7, 0xe3, 0x6c, 0x9d, 0xa7 }
-    },
-    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-      { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
-        0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
-        0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
-        0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
-    },
-  };
-
-  int i;
-  unsigned char tmp[28];
-  hash_state md;
-
-  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
-      sha224_init(&md);
-      sha224_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
-      sha224_done(&md, tmp);
-      if (memcmp(tmp, tests[i].hash, 28) != 0) {
-         return CRYPT_FAIL_TESTVECTOR;
-      }
-  }
-  return CRYPT_OK;
- #endif
-}
-
--- a/sha256.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/sha256.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,305 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-
-/* SHA256 by Tom St Denis */
-
-#include "mycrypt.h"
-
-#ifdef SHA256 
-
-const struct _hash_descriptor sha256_desc =
-{
-    "sha256",
-    0,
-    32,
-    64,
-    &sha256_init,
-    &sha256_process,
-    &sha256_done,
-    &sha256_test
-};
-
-/* the K array */
-static const unsigned long K[64] = {
-    0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
-    0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
-    0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
-    0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
-    0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
-    0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
-    0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
-    0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
-    0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
-    0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
-    0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
-    0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
-    0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
-};
-
-/* Various logical functions */
-#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
-#define Maj(x,y,z)      (((x | y) & z) | (x & y)) 
-#define S(x, n)         ROR((x),(n))
-#define R(x, n)         (((x)&0xFFFFFFFFUL)>>(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))
-
-/* compress 512-bits */
-#ifdef CLEAN_STACK
-static void _sha256_compress(hash_state * md, unsigned char *buf)
-#else
-static void sha256_compress(hash_state * md, unsigned char *buf)
-#endif
-{
-    ulong32 S[8], W[64], t0, t1;
-    int i;
-
-    /* copy state into S */
-    for (i = 0; i < 8; i++) {
-        S[i] = md->sha256.state[i];
-    }
-
-    /* copy the state into 512-bits into W[0..15] */
-    for (i = 0; i < 16; i++) {
-        LOAD32H(W[i], buf + (4*i));
-    }
-
-    /* fill W[16..63] */
-    for (i = 16; i < 64; i++) {
-        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
-    }        
-
-    /* Compress */
-#ifdef SMALL_CODE   
-#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;
-
-     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);
-     }  
-#else 
-#define RND(a,b,c,d,e,f,g,h,i,ki)                    \
-     t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i];   \
-     t1 = Sigma0(a) + Maj(a, b, c);                  \
-     d += t0;                                        \
-     h  = t0 + t1;
-
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],0,0x428a2f98);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],1,0x71374491);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],2,0xb5c0fbcf);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],3,0xe9b5dba5);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],4,0x3956c25b);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],5,0x59f111f1);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],6,0x923f82a4);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],7,0xab1c5ed5);
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],8,0xd807aa98);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],9,0x12835b01);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],10,0x243185be);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],11,0x550c7dc3);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],12,0x72be5d74);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],13,0x80deb1fe);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],14,0x9bdc06a7);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],15,0xc19bf174);
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],16,0xe49b69c1);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],17,0xefbe4786);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],18,0x0fc19dc6);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],19,0x240ca1cc);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],20,0x2de92c6f);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],21,0x4a7484aa);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],22,0x5cb0a9dc);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],23,0x76f988da);
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],24,0x983e5152);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],25,0xa831c66d);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],26,0xb00327c8);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],27,0xbf597fc7);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],28,0xc6e00bf3);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],29,0xd5a79147);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],30,0x06ca6351);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],31,0x14292967);
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],32,0x27b70a85);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],33,0x2e1b2138);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],34,0x4d2c6dfc);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],35,0x53380d13);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],36,0x650a7354);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],37,0x766a0abb);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],38,0x81c2c92e);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],39,0x92722c85);
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],40,0xa2bfe8a1);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],41,0xa81a664b);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],42,0xc24b8b70);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],43,0xc76c51a3);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],44,0xd192e819);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],45,0xd6990624);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],46,0xf40e3585);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],47,0x106aa070);
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],48,0x19a4c116);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],49,0x1e376c08);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],50,0x2748774c);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],51,0x34b0bcb5);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],52,0x391c0cb3);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],53,0x4ed8aa4a);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],54,0x5b9cca4f);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],55,0x682e6ff3);
-    RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],56,0x748f82ee);
-    RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],57,0x78a5636f);
-    RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],58,0x84c87814);
-    RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],59,0x8cc70208);
-    RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],60,0x90befffa);
-    RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],61,0xa4506ceb);
-    RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],62,0xbef9a3f7);
-    RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],63,0xc67178f2);
-
-#undef RND     
-    
-#endif     
-
-    /* feedback */
-    for (i = 0; i < 8; i++) {
-        md->sha256.state[i] = md->sha256.state[i] + S[i];
-    }
-
-}
-
-#ifdef CLEAN_STACK
-static void sha256_compress(hash_state * md, unsigned char *buf)
-{
-    _sha256_compress(md, buf);
-    burn_stack(sizeof(ulong32) * 74);
-}
-#endif
-
-/* init the sha256 state */
-void sha256_init(hash_state * md)
-{
-    _ARGCHK(md != NULL);
-
-    md->sha256.curlen = 0;
-    md->sha256.length = 0;
-    md->sha256.state[0] = 0x6A09E667UL;
-    md->sha256.state[1] = 0xBB67AE85UL;
-    md->sha256.state[2] = 0x3C6EF372UL;
-    md->sha256.state[3] = 0xA54FF53AUL;
-    md->sha256.state[4] = 0x510E527FUL;
-    md->sha256.state[5] = 0x9B05688CUL;
-    md->sha256.state[6] = 0x1F83D9ABUL;
-    md->sha256.state[7] = 0x5BE0CD19UL;
-}
-
-HASH_PROCESS(sha256_process, sha256_compress, sha256, 64)
-
-int sha256_done(hash_state * md, unsigned char *hash)
-{
-    int i;
-
-    _ARGCHK(md != NULL);
-    _ARGCHK(hash != NULL);
-
-    if (md->sha256.curlen >= sizeof(md->sha256.buf)) {
-       return CRYPT_INVALID_ARG;
-    }
-
-
-    /* increase the length of the message */
-    md->sha256.length += md->sha256.curlen * 8;
-
-    /* append the '1' bit */
-    md->sha256.buf[md->sha256.curlen++] = (unsigned char)0x80;
-
-    /* if the length is currently above 56 bytes we append zeros
-     * then compress.  Then we can fall back to padding zeros and length
-     * encoding like normal.
-     */
-    if (md->sha256.curlen > 56) {
-        while (md->sha256.curlen < 64) {
-            md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
-        }
-        sha256_compress(md, md->sha256.buf);
-        md->sha256.curlen = 0;
-    }
-
-    /* pad upto 56 bytes of zeroes */
-    while (md->sha256.curlen < 56) {
-        md->sha256.buf[md->sha256.curlen++] = (unsigned char)0;
-    }
-
-    /* store length */
-    STORE64H(md->sha256.length, md->sha256.buf+56);
-    sha256_compress(md, md->sha256.buf);
-
-    /* copy output */
-    for (i = 0; i < 8; i++) {
-        STORE32H(md->sha256.state[i], hash+(4*i));
-    }
-#ifdef CLEAN_STACK
-    zeromem(md, sizeof(hash_state));
-#endif
-    return CRYPT_OK;
-}
-
-int  sha256_test(void)
-{
- #ifndef LTC_TEST
-    return CRYPT_NOP;
- #else    
-  static const struct {
-      char *msg;
-      unsigned char hash[32];
-  } tests[] = {
-    { "abc",
-      { 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
-        0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
-        0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
-        0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
-    },
-    { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
-      { 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, 
-        0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
-        0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, 
-        0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
-    },
-  };
-
-  int i;
-  unsigned char tmp[32];
-  hash_state md;
-
-  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
-      sha256_init(&md);
-      sha256_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
-      sha256_done(&md, tmp);
-      if (memcmp(tmp, tests[i].hash, 32) != 0) {
-         return CRYPT_FAIL_TESTVECTOR;
-      }
-  }
-  return CRYPT_OK;
- #endif
-}
-
-#ifdef SHA224
-#include "sha224.c"
-#endif
-
-#endif
-
-
--- a/sha384.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/sha384.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,107 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-/* included in sha512.c */
-
-const struct _hash_descriptor sha384_desc =
-{
-    "sha384",
-    4,
-    48,
-    128,
-    &sha384_init,
-    &sha512_process,
-    &sha384_done,
-    &sha384_test
-};
-
-void sha384_init(hash_state * md)
-{
-    _ARGCHK(md != NULL);
-
-    md->sha512.curlen = 0;
-    md->sha512.length = 0;
-    md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8);
-    md->sha512.state[1] = CONST64(0x629a292a367cd507);
-    md->sha512.state[2] = CONST64(0x9159015a3070dd17);
-    md->sha512.state[3] = CONST64(0x152fecd8f70e5939);
-    md->sha512.state[4] = CONST64(0x67332667ffc00b31);
-    md->sha512.state[5] = CONST64(0x8eb44a8768581511);
-    md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7);
-    md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4);
-}
-
-int sha384_done(hash_state * md, unsigned char *hash)
-{
-   unsigned char buf[64];
-
-   _ARGCHK(md != NULL);
-   _ARGCHK(hash != NULL);
-
-    if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
-       return CRYPT_INVALID_ARG;
-    }
-
-   sha512_done(md, buf);
-   memcpy(hash, buf, 48);
-#ifdef CLEAN_STACK
-   zeromem(buf, sizeof(buf));
-#endif
-   return CRYPT_OK;
-}
-
-int  sha384_test(void)
-{
- #ifndef LTC_TEST
-    return CRYPT_NOP;
- #else    
-  static const struct {
-      char *msg;
-      unsigned char hash[48];
-  } tests[] = {
-    { "abc",
-      { 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
-        0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
-        0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
-        0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
-        0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
-        0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
-    },
-    { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
-      { 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
-        0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
-        0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
-        0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
-        0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
-        0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
-    },
-  };
-
-  int i;
-  unsigned char tmp[48];
-  hash_state md;
-
-  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
-      sha384_init(&md);
-      sha384_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
-      sha384_done(&md, tmp);
-      if (memcmp(tmp, tests[i].hash, 48) != 0) {
-         return CRYPT_FAIL_TESTVECTOR;
-      }
-  }
-  return CRYPT_OK;
- #endif
-}
-
-
-
-
-
--- a/sha512.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/sha512.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,282 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-/* SHA512 by Tom St Denis */
-
-#include "mycrypt.h"
-
-#ifdef SHA512
-
-const struct _hash_descriptor sha512_desc =
-{
-    "sha512",
-    5,
-    64,
-    128,
-    &sha512_init,
-    &sha512_process,
-    &sha512_done,
-    &sha512_test
-};
-
-/* the K array */
-static const ulong64 K[80] = {
-CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd), 
-CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
-CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019), 
-CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
-CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe), 
-CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
-CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1), 
-CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
-CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3), 
-CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
-CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483), 
-CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
-CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210), 
-CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
-CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725), 
-CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
-CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926), 
-CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
-CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8), 
-CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
-CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
-CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
-CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910), 
-CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
-CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53), 
-CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
-CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb), 
-CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
-CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60), 
-CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
-CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9), 
-CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
-CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207), 
-CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
-CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6), 
-CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
-CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493), 
-CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
-CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a), 
-CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
-};
-
-/* Various logical functions */
-#define Ch(x,y,z)       (z ^ (x & (y ^ z)))
-#define Maj(x,y,z)      (((x | y) & z) | (x & y)) 
-#define S(x, n)         ROR64((x),(n))
-#define R(x, n)         (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
-#define Sigma0(x)       (S(x, 28) ^ S(x, 34) ^ S(x, 39))
-#define Sigma1(x)       (S(x, 14) ^ S(x, 18) ^ S(x, 41))
-#define Gamma0(x)       (S(x, 1) ^ S(x, 8) ^ R(x, 7))
-#define Gamma1(x)       (S(x, 19) ^ S(x, 61) ^ R(x, 6))
-
-/* compress 1024-bits */
-#ifdef CLEAN_STACK
-static void _sha512_compress(hash_state * md, unsigned char *buf)
-#else
-static void sha512_compress(hash_state * md, unsigned char *buf)
-#endif
-{
-    ulong64 S[8], W[80], t0, t1;
-    int i;
-
-    /* copy state into S */
-    for (i = 0; i < 8; i++) {
-        S[i] = md->sha512.state[i];
-    }
-
-    /* copy the state into 1024-bits into W[0..15] */
-    for (i = 0; i < 16; i++) {
-        LOAD64H(W[i], buf + (8*i));
-    }
-
-    /* fill W[16..79] */
-    for (i = 16; i < 80; i++) {
-        W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
-    }        
-
-    /* Compress */
-#ifdef SMALL_CODE
-    for (i = 0; i < 80; i++) {
-        t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
-        t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
-        S[7] = S[6];
-        S[6] = S[5];
-        S[5] = S[4];
-        S[4] = S[3] + t0;
-        S[3] = S[2];
-        S[2] = S[1];
-        S[1] = S[0];
-        S[0] = t0 + t1;
-    }
-#else
-#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;
-
-     for (i = 0; i < 80; 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);
-     }
-#endif     
-
-
-    /* feedback */
-    for (i = 0; i < 8; i++) {
-        md->sha512.state[i] = md->sha512.state[i] + S[i];
-    }
-}
-
-/* compress 1024-bits */
-#ifdef CLEAN_STACK
-static void sha512_compress(hash_state * md, unsigned char *buf)
-{
-    _sha512_compress(md, buf);
-    burn_stack(sizeof(ulong64) * 90 + sizeof(int));
-}
-#endif
-
-/* init the sha512 state */
-void sha512_init(hash_state * md)
-{
-    _ARGCHK(md != NULL);
-
-    md->sha512.curlen = 0;
-    md->sha512.length = 0;
-    md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
-    md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
-    md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
-    md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
-    md->sha512.state[4] = CONST64(0x510e527fade682d1);
-    md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
-    md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
-    md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
-}
-
-HASH_PROCESS(sha512_process, sha512_compress, sha512, 128)
-
-int sha512_done(hash_state * md, unsigned char *hash)
-{
-    int i;
-
-    _ARGCHK(md != NULL);
-    _ARGCHK(hash != NULL);
-
-    if (md->sha512.curlen >= sizeof(md->sha512.buf)) {
-       return CRYPT_INVALID_ARG;
-    }
-
-    /* increase the length of the message */
-    md->sha512.length += md->sha512.curlen * CONST64(8);
-
-    /* append the '1' bit */
-    md->sha512.buf[md->sha512.curlen++] = (unsigned char)0x80;
-
-    /* if the length is currently above 112 bytes we append zeros
-     * then compress.  Then we can fall back to padding zeros and length
-     * encoding like normal.
-     */
-    if (md->sha512.curlen > 112) {
-        while (md->sha512.curlen < 128) {
-            md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
-        }
-        sha512_compress(md, md->sha512.buf);
-        md->sha512.curlen = 0;
-    }
-
-    /* pad upto 120 bytes of zeroes 
-     * note: that from 112 to 120 is the 64 MSB of the length.  We assume that you won't hash
-     * > 2^64 bits of data... :-)
-     */
-    while (md->sha512.curlen < 120) {
-        md->sha512.buf[md->sha512.curlen++] = (unsigned char)0;
-    }
-
-    /* store length */
-    STORE64H(md->sha512.length, md->sha512.buf+120);
-    sha512_compress(md, md->sha512.buf);
-
-    /* copy output */
-    for (i = 0; i < 8; i++) {
-        STORE64H(md->sha512.state[i], hash+(8*i));
-    }
-#ifdef CLEAN_STACK
-    zeromem(md, sizeof(hash_state));
-#endif
-    return CRYPT_OK;
-}
-
-int  sha512_test(void)
-{
- #ifndef LTC_TEST
-    return CRYPT_NOP;
- #else    
-  static const struct {
-      char *msg;
-      unsigned char hash[64];
-  } tests[] = {
-    { "abc",
-     { 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
-       0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
-       0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
-       0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
-       0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
-       0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
-       0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
-       0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
-    },
-    { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
-     { 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
-       0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
-       0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
-       0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
-       0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
-       0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
-       0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
-       0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
-    },
-  };
-
-  int i;
-  unsigned char tmp[64];
-  hash_state md;
-
-  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
-      sha512_init(&md);
-      sha512_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
-      sha512_done(&md, tmp);
-      if (memcmp(tmp, tests[i].hash, 64) != 0) {
-         return CRYPT_FAIL_TESTVECTOR;
-      }
-  }
-  return CRYPT_OK;
-  #endif
-}
-
-#ifdef SHA384
-   #include "sha384.c"
-#endif
-
-#endif
-
-
-
--- a/tiger.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/tiger.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,772 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-#include "mycrypt.h"
-
-#ifdef TIGER
-
-const struct _hash_descriptor tiger_desc =
-{
-    "tiger",
-    1,
-    24,
-    64,
-    &tiger_init,
-    &tiger_process,
-    &tiger_done,
-    &tiger_test
-};
-
-#define t1 (table)
-#define t2 (table+256)
-#define t3 (table+256*2)
-#define t4 (table+256*3)
-
-static const ulong64 table[4*256] = {
-    CONST64(0x02AAB17CF7E90C5E) /*    0 */, CONST64(0xAC424B03E243A8EC) /*    1 */,
-    CONST64(0x72CD5BE30DD5FCD3) /*    2 */, CONST64(0x6D019B93F6F97F3A) /*    3 */,
-    CONST64(0xCD9978FFD21F9193) /*    4 */, CONST64(0x7573A1C9708029E2) /*    5 */,
-    CONST64(0xB164326B922A83C3) /*    6 */, CONST64(0x46883EEE04915870) /*    7 */,
-    CONST64(0xEAACE3057103ECE6) /*    8 */, CONST64(0xC54169B808A3535C) /*    9 */,
-    CONST64(0x4CE754918DDEC47C) /*   10 */, CONST64(0x0AA2F4DFDC0DF40C) /*   11 */,
-    CONST64(0x10B76F18A74DBEFA) /*   12 */, CONST64(0xC6CCB6235AD1AB6A) /*   13 */,
-    CONST64(0x13726121572FE2FF) /*   14 */, CONST64(0x1A488C6F199D921E) /*   15 */,
-    CONST64(0x4BC9F9F4DA0007CA) /*   16 */, CONST64(0x26F5E6F6E85241C7) /*   17 */,
-    CONST64(0x859079DBEA5947B6) /*   18 */, CONST64(0x4F1885C5C99E8C92) /*   19 */,
-    CONST64(0xD78E761EA96F864B) /*   20 */, CONST64(0x8E36428C52B5C17D) /*   21 */,
-    CONST64(0x69CF6827373063C1) /*   22 */, CONST64(0xB607C93D9BB4C56E) /*   23 */,
-    CONST64(0x7D820E760E76B5EA) /*   24 */, CONST64(0x645C9CC6F07FDC42) /*   25 */,
-    CONST64(0xBF38A078243342E0) /*   26 */, CONST64(0x5F6B343C9D2E7D04) /*   27 */,
-    CONST64(0xF2C28AEB600B0EC6) /*   28 */, CONST64(0x6C0ED85F7254BCAC) /*   29 */,
-    CONST64(0x71592281A4DB4FE5) /*   30 */, CONST64(0x1967FA69CE0FED9F) /*   31 */,
-    CONST64(0xFD5293F8B96545DB) /*   32 */, CONST64(0xC879E9D7F2A7600B) /*   33 */,
-    CONST64(0x860248920193194E) /*   34 */, CONST64(0xA4F9533B2D9CC0B3) /*   35 */,
-    CONST64(0x9053836C15957613) /*   36 */, CONST64(0xDB6DCF8AFC357BF1) /*   37 */,
-    CONST64(0x18BEEA7A7A370F57) /*   38 */, CONST64(0x037117CA50B99066) /*   39 */,
-    CONST64(0x6AB30A9774424A35) /*   40 */, CONST64(0xF4E92F02E325249B) /*   41 */,
-    CONST64(0x7739DB07061CCAE1) /*   42 */, CONST64(0xD8F3B49CECA42A05) /*   43 */,
-    CONST64(0xBD56BE3F51382F73) /*   44 */, CONST64(0x45FAED5843B0BB28) /*   45 */,
-    CONST64(0x1C813D5C11BF1F83) /*   46 */, CONST64(0x8AF0E4B6D75FA169) /*   47 */,
-    CONST64(0x33EE18A487AD9999) /*   48 */, CONST64(0x3C26E8EAB1C94410) /*   49 */,
-    CONST64(0xB510102BC0A822F9) /*   50 */, CONST64(0x141EEF310CE6123B) /*   51 */,
-    CONST64(0xFC65B90059DDB154) /*   52 */, CONST64(0xE0158640C5E0E607) /*   53 */,
-    CONST64(0x884E079826C3A3CF) /*   54 */, CONST64(0x930D0D9523C535FD) /*   55 */,
-    CONST64(0x35638D754E9A2B00) /*   56 */, CONST64(0x4085FCCF40469DD5) /*   57 */,
-    CONST64(0xC4B17AD28BE23A4C) /*   58 */, CONST64(0xCAB2F0FC6A3E6A2E) /*   59 */,
-    CONST64(0x2860971A6B943FCD) /*   60 */, CONST64(0x3DDE6EE212E30446) /*   61 */,
-    CONST64(0x6222F32AE01765AE) /*   62 */, CONST64(0x5D550BB5478308FE) /*   63 */,
-    CONST64(0xA9EFA98DA0EDA22A) /*   64 */, CONST64(0xC351A71686C40DA7) /*   65 */,
-    CONST64(0x1105586D9C867C84) /*   66 */, CONST64(0xDCFFEE85FDA22853) /*   67 */,
-    CONST64(0xCCFBD0262C5EEF76) /*   68 */, CONST64(0xBAF294CB8990D201) /*   69 */,
-    CONST64(0xE69464F52AFAD975) /*   70 */, CONST64(0x94B013AFDF133E14) /*   71 */,
-    CONST64(0x06A7D1A32823C958) /*   72 */, CONST64(0x6F95FE5130F61119) /*   73 */,
-    CONST64(0xD92AB34E462C06C0) /*   74 */, CONST64(0xED7BDE33887C71D2) /*   75 */,
-    CONST64(0x79746D6E6518393E) /*   76 */, CONST64(0x5BA419385D713329) /*   77 */,
-    CONST64(0x7C1BA6B948A97564) /*   78 */, CONST64(0x31987C197BFDAC67) /*   79 */,
-    CONST64(0xDE6C23C44B053D02) /*   80 */, CONST64(0x581C49FED002D64D) /*   81 */,
-    CONST64(0xDD474D6338261571) /*   82 */, CONST64(0xAA4546C3E473D062) /*   83 */,
-    CONST64(0x928FCE349455F860) /*   84 */, CONST64(0x48161BBACAAB94D9) /*   85 */,
-    CONST64(0x63912430770E6F68) /*   86 */, CONST64(0x6EC8A5E602C6641C) /*   87 */,
-    CONST64(0x87282515337DDD2B) /*   88 */, CONST64(0x2CDA6B42034B701B) /*   89 */,
-    CONST64(0xB03D37C181CB096D) /*   90 */, CONST64(0xE108438266C71C6F) /*   91 */,
-    CONST64(0x2B3180C7EB51B255) /*   92 */, CONST64(0xDF92B82F96C08BBC) /*   93 */,
-    CONST64(0x5C68C8C0A632F3BA) /*   94 */, CONST64(0x5504CC861C3D0556) /*   95 */,
-    CONST64(0xABBFA4E55FB26B8F) /*   96 */, CONST64(0x41848B0AB3BACEB4) /*   97 */,
-    CONST64(0xB334A273AA445D32) /*   98 */, CONST64(0xBCA696F0A85AD881) /*   99 */,
-    CONST64(0x24F6EC65B528D56C) /*  100 */, CONST64(0x0CE1512E90F4524A) /*  101 */,
-    CONST64(0x4E9DD79D5506D35A) /*  102 */, CONST64(0x258905FAC6CE9779) /*  103 */,
-    CONST64(0x2019295B3E109B33) /*  104 */, CONST64(0xF8A9478B73A054CC) /*  105 */,
-    CONST64(0x2924F2F934417EB0) /*  106 */, CONST64(0x3993357D536D1BC4) /*  107 */,
-    CONST64(0x38A81AC21DB6FF8B) /*  108 */, CONST64(0x47C4FBF17D6016BF) /*  109 */,
-    CONST64(0x1E0FAADD7667E3F5) /*  110 */, CONST64(0x7ABCFF62938BEB96) /*  111 */,
-    CONST64(0xA78DAD948FC179C9) /*  112 */, CONST64(0x8F1F98B72911E50D) /*  113 */,
-    CONST64(0x61E48EAE27121A91) /*  114 */, CONST64(0x4D62F7AD31859808) /*  115 */,
-    CONST64(0xECEBA345EF5CEAEB) /*  116 */, CONST64(0xF5CEB25EBC9684CE) /*  117 */,
-    CONST64(0xF633E20CB7F76221) /*  118 */, CONST64(0xA32CDF06AB8293E4) /*  119 */,
-    CONST64(0x985A202CA5EE2CA4) /*  120 */, CONST64(0xCF0B8447CC8A8FB1) /*  121 */,
-    CONST64(0x9F765244979859A3) /*  122 */, CONST64(0xA8D516B1A1240017) /*  123 */,
-    CONST64(0x0BD7BA3EBB5DC726) /*  124 */, CONST64(0xE54BCA55B86ADB39) /*  125 */,
-    CONST64(0x1D7A3AFD6C478063) /*  126 */, CONST64(0x519EC608E7669EDD) /*  127 */,
-    CONST64(0x0E5715A2D149AA23) /*  128 */, CONST64(0x177D4571848FF194) /*  129 */,
-    CONST64(0xEEB55F3241014C22) /*  130 */, CONST64(0x0F5E5CA13A6E2EC2) /*  131 */,
-    CONST64(0x8029927B75F5C361) /*  132 */, CONST64(0xAD139FABC3D6E436) /*  133 */,
-    CONST64(0x0D5DF1A94CCF402F) /*  134 */, CONST64(0x3E8BD948BEA5DFC8) /*  135 */,
-    CONST64(0xA5A0D357BD3FF77E) /*  136 */, CONST64(0xA2D12E251F74F645) /*  137 */,
-    CONST64(0x66FD9E525E81A082) /*  138 */, CONST64(0x2E0C90CE7F687A49) /*  139 */,
-    CONST64(0xC2E8BCBEBA973BC5) /*  140 */, CONST64(0x000001BCE509745F) /*  141 */,
-    CONST64(0x423777BBE6DAB3D6) /*  142 */, CONST64(0xD1661C7EAEF06EB5) /*  143 */,
-    CONST64(0xA1781F354DAACFD8) /*  144 */, CONST64(0x2D11284A2B16AFFC) /*  145 */,
-    CONST64(0xF1FC4F67FA891D1F) /*  146 */, CONST64(0x73ECC25DCB920ADA) /*  147 */,
-    CONST64(0xAE610C22C2A12651) /*  148 */, CONST64(0x96E0A810D356B78A) /*  149 */,
-    CONST64(0x5A9A381F2FE7870F) /*  150 */, CONST64(0xD5AD62EDE94E5530) /*  151 */,
-    CONST64(0xD225E5E8368D1427) /*  152 */, CONST64(0x65977B70C7AF4631) /*  153 */,
-    CONST64(0x99F889B2DE39D74F) /*  154 */, CONST64(0x233F30BF54E1D143) /*  155 */,
-    CONST64(0x9A9675D3D9A63C97) /*  156 */, CONST64(0x5470554FF334F9A8) /*  157 */,
-    CONST64(0x166ACB744A4F5688) /*  158 */, CONST64(0x70C74CAAB2E4AEAD) /*  159 */,
-    CONST64(0xF0D091646F294D12) /*  160 */, CONST64(0x57B82A89684031D1) /*  161 */,
-    CONST64(0xEFD95A5A61BE0B6B) /*  162 */, CONST64(0x2FBD12E969F2F29A) /*  163 */,
-    CONST64(0x9BD37013FEFF9FE8) /*  164 */, CONST64(0x3F9B0404D6085A06) /*  165 */,
-    CONST64(0x4940C1F3166CFE15) /*  166 */, CONST64(0x09542C4DCDF3DEFB) /*  167 */,
-    CONST64(0xB4C5218385CD5CE3) /*  168 */, CONST64(0xC935B7DC4462A641) /*  169 */,
-    CONST64(0x3417F8A68ED3B63F) /*  170 */, CONST64(0xB80959295B215B40) /*  171 */,
-    CONST64(0xF99CDAEF3B8C8572) /*  172 */, CONST64(0x018C0614F8FCB95D) /*  173 */,
-    CONST64(0x1B14ACCD1A3ACDF3) /*  174 */, CONST64(0x84D471F200BB732D) /*  175 */,
-    CONST64(0xC1A3110E95E8DA16) /*  176 */, CONST64(0x430A7220BF1A82B8) /*  177 */,
-    CONST64(0xB77E090D39DF210E) /*  178 */, CONST64(0x5EF4BD9F3CD05E9D) /*  179 */,
-    CONST64(0x9D4FF6DA7E57A444) /*  180 */, CONST64(0xDA1D60E183D4A5F8) /*  181 */,
-    CONST64(0xB287C38417998E47) /*  182 */, CONST64(0xFE3EDC121BB31886) /*  183 */,
-    CONST64(0xC7FE3CCC980CCBEF) /*  184 */, CONST64(0xE46FB590189BFD03) /*  185 */,
-    CONST64(0x3732FD469A4C57DC) /*  186 */, CONST64(0x7EF700A07CF1AD65) /*  187 */,
-    CONST64(0x59C64468A31D8859) /*  188 */, CONST64(0x762FB0B4D45B61F6) /*  189 */,
-    CONST64(0x155BAED099047718) /*  190 */, CONST64(0x68755E4C3D50BAA6) /*  191 */,
-    CONST64(0xE9214E7F22D8B4DF) /*  192 */, CONST64(0x2ADDBF532EAC95F4) /*  193 */,
-    CONST64(0x32AE3909B4BD0109) /*  194 */, CONST64(0x834DF537B08E3450) /*  195 */,
-    CONST64(0xFA209DA84220728D) /*  196 */, CONST64(0x9E691D9B9EFE23F7) /*  197 */,
-    CONST64(0x0446D288C4AE8D7F) /*  198 */, CONST64(0x7B4CC524E169785B) /*  199 */,
-    CONST64(0x21D87F0135CA1385) /*  200 */, CONST64(0xCEBB400F137B8AA5) /*  201 */,
-    CONST64(0x272E2B66580796BE) /*  202 */, CONST64(0x3612264125C2B0DE) /*  203 */,
-    CONST64(0x057702BDAD1EFBB2) /*  204 */, CONST64(0xD4BABB8EACF84BE9) /*  205 */,
-    CONST64(0x91583139641BC67B) /*  206 */, CONST64(0x8BDC2DE08036E024) /*  207 */,
-    CONST64(0x603C8156F49F68ED) /*  208 */, CONST64(0xF7D236F7DBEF5111) /*  209 */,
-    CONST64(0x9727C4598AD21E80) /*  210 */, CONST64(0xA08A0896670A5FD7) /*  211 */,
-    CONST64(0xCB4A8F4309EBA9CB) /*  212 */, CONST64(0x81AF564B0F7036A1) /*  213 */,
-    CONST64(0xC0B99AA778199ABD) /*  214 */, CONST64(0x959F1EC83FC8E952) /*  215 */,
-    CONST64(0x8C505077794A81B9) /*  216 */, CONST64(0x3ACAAF8F056338F0) /*  217 */,
-    CONST64(0x07B43F50627A6778) /*  218 */, CONST64(0x4A44AB49F5ECCC77) /*  219 */,
-    CONST64(0x3BC3D6E4B679EE98) /*  220 */, CONST64(0x9CC0D4D1CF14108C) /*  221 */,
-    CONST64(0x4406C00B206BC8A0) /*  222 */, CONST64(0x82A18854C8D72D89) /*  223 */,
-    CONST64(0x67E366B35C3C432C) /*  224 */, CONST64(0xB923DD61102B37F2) /*  225 */,
-    CONST64(0x56AB2779D884271D) /*  226 */, CONST64(0xBE83E1B0FF1525AF) /*  227 */,
-    CONST64(0xFB7C65D4217E49A9) /*  228 */, CONST64(0x6BDBE0E76D48E7D4) /*  229 */,
-    CONST64(0x08DF828745D9179E) /*  230 */, CONST64(0x22EA6A9ADD53BD34) /*  231 */,
-    CONST64(0xE36E141C5622200A) /*  232 */, CONST64(0x7F805D1B8CB750EE) /*  233 */,
-    CONST64(0xAFE5C7A59F58E837) /*  234 */, CONST64(0xE27F996A4FB1C23C) /*  235 */,
-    CONST64(0xD3867DFB0775F0D0) /*  236 */, CONST64(0xD0E673DE6E88891A) /*  237 */,
-    CONST64(0x123AEB9EAFB86C25) /*  238 */, CONST64(0x30F1D5D5C145B895) /*  239 */,
-    CONST64(0xBB434A2DEE7269E7) /*  240 */, CONST64(0x78CB67ECF931FA38) /*  241 */,
-    CONST64(0xF33B0372323BBF9C) /*  242 */, CONST64(0x52D66336FB279C74) /*  243 */,
-    CONST64(0x505F33AC0AFB4EAA) /*  244 */, CONST64(0xE8A5CD99A2CCE187) /*  245 */,
-    CONST64(0x534974801E2D30BB) /*  246 */, CONST64(0x8D2D5711D5876D90) /*  247 */,
-    CONST64(0x1F1A412891BC038E) /*  248 */, CONST64(0xD6E2E71D82E56648) /*  249 */,
-    CONST64(0x74036C3A497732B7) /*  250 */, CONST64(0x89B67ED96361F5AB) /*  251 */,
-    CONST64(0xFFED95D8F1EA02A2) /*  252 */, CONST64(0xE72B3BD61464D43D) /*  253 */,
-    CONST64(0xA6300F170BDC4820) /*  254 */, CONST64(0xEBC18760ED78A77A) /*  255 */,
-    CONST64(0xE6A6BE5A05A12138) /*  256 */, CONST64(0xB5A122A5B4F87C98) /*  257 */,
-    CONST64(0x563C6089140B6990) /*  258 */, CONST64(0x4C46CB2E391F5DD5) /*  259 */,
-    CONST64(0xD932ADDBC9B79434) /*  260 */, CONST64(0x08EA70E42015AFF5) /*  261 */,
-    CONST64(0xD765A6673E478CF1) /*  262 */, CONST64(0xC4FB757EAB278D99) /*  263 */,
-    CONST64(0xDF11C6862D6E0692) /*  264 */, CONST64(0xDDEB84F10D7F3B16) /*  265 */,
-    CONST64(0x6F2EF604A665EA04) /*  266 */, CONST64(0x4A8E0F0FF0E0DFB3) /*  267 */,
-    CONST64(0xA5EDEEF83DBCBA51) /*  268 */, CONST64(0xFC4F0A2A0EA4371E) /*  269 */,
-    CONST64(0xE83E1DA85CB38429) /*  270 */, CONST64(0xDC8FF882BA1B1CE2) /*  271 */,
-    CONST64(0xCD45505E8353E80D) /*  272 */, CONST64(0x18D19A00D4DB0717) /*  273 */,
-    CONST64(0x34A0CFEDA5F38101) /*  274 */, CONST64(0x0BE77E518887CAF2) /*  275 */,
-    CONST64(0x1E341438B3C45136) /*  276 */, CONST64(0xE05797F49089CCF9) /*  277 */,
-    CONST64(0xFFD23F9DF2591D14) /*  278 */, CONST64(0x543DDA228595C5CD) /*  279 */,
-    CONST64(0x661F81FD99052A33) /*  280 */, CONST64(0x8736E641DB0F7B76) /*  281 */,
-    CONST64(0x15227725418E5307) /*  282 */, CONST64(0xE25F7F46162EB2FA) /*  283 */,
-    CONST64(0x48A8B2126C13D9FE) /*  284 */, CONST64(0xAFDC541792E76EEA) /*  285 */,
-    CONST64(0x03D912BFC6D1898F) /*  286 */, CONST64(0x31B1AAFA1B83F51B) /*  287 */,
-    CONST64(0xF1AC2796E42AB7D9) /*  288 */, CONST64(0x40A3A7D7FCD2EBAC) /*  289 */,
-    CONST64(0x1056136D0AFBBCC5) /*  290 */, CONST64(0x7889E1DD9A6D0C85) /*  291 */,
-    CONST64(0xD33525782A7974AA) /*  292 */, CONST64(0xA7E25D09078AC09B) /*  293 */,
-    CONST64(0xBD4138B3EAC6EDD0) /*  294 */, CONST64(0x920ABFBE71EB9E70) /*  295 */,
-    CONST64(0xA2A5D0F54FC2625C) /*  296 */, CONST64(0xC054E36B0B1290A3) /*  297 */,
-    CONST64(0xF6DD59FF62FE932B) /*  298 */, CONST64(0x3537354511A8AC7D) /*  299 */,
-    CONST64(0xCA845E9172FADCD4) /*  300 */, CONST64(0x84F82B60329D20DC) /*  301 */,
-    CONST64(0x79C62CE1CD672F18) /*  302 */, CONST64(0x8B09A2ADD124642C) /*  303 */,
-    CONST64(0xD0C1E96A19D9E726) /*  304 */, CONST64(0x5A786A9B4BA9500C) /*  305 */,
-    CONST64(0x0E020336634C43F3) /*  306 */, CONST64(0xC17B474AEB66D822) /*  307 */,
-    CONST64(0x6A731AE3EC9BAAC2) /*  308 */, CONST64(0x8226667AE0840258) /*  309 */,
-    CONST64(0x67D4567691CAECA5) /*  310 */, CONST64(0x1D94155C4875ADB5) /*  311 */,
-    CONST64(0x6D00FD985B813FDF) /*  312 */, CONST64(0x51286EFCB774CD06) /*  313 */,
-    CONST64(0x5E8834471FA744AF) /*  314 */, CONST64(0xF72CA0AEE761AE2E) /*  315 */,
-    CONST64(0xBE40E4CDAEE8E09A) /*  316 */, CONST64(0xE9970BBB5118F665) /*  317 */,
-    CONST64(0x726E4BEB33DF1964) /*  318 */, CONST64(0x703B000729199762) /*  319 */,
-    CONST64(0x4631D816F5EF30A7) /*  320 */, CONST64(0xB880B5B51504A6BE) /*  321 */,
-    CONST64(0x641793C37ED84B6C) /*  322 */, CONST64(0x7B21ED77F6E97D96) /*  323 */,
-    CONST64(0x776306312EF96B73) /*  324 */, CONST64(0xAE528948E86FF3F4) /*  325 */,
-    CONST64(0x53DBD7F286A3F8F8) /*  326 */, CONST64(0x16CADCE74CFC1063) /*  327 */,
-    CONST64(0x005C19BDFA52C6DD) /*  328 */, CONST64(0x68868F5D64D46AD3) /*  329 */,
-    CONST64(0x3A9D512CCF1E186A) /*  330 */, CONST64(0x367E62C2385660AE) /*  331 */,
-    CONST64(0xE359E7EA77DCB1D7) /*  332 */, CONST64(0x526C0773749ABE6E) /*  333 */,
-    CONST64(0x735AE5F9D09F734B) /*  334 */, CONST64(0x493FC7CC8A558BA8) /*  335 */,
-    CONST64(0xB0B9C1533041AB45) /*  336 */, CONST64(0x321958BA470A59BD) /*  337 */,
-    CONST64(0x852DB00B5F46C393) /*  338 */, CONST64(0x91209B2BD336B0E5) /*  339 */,
-    CONST64(0x6E604F7D659EF19F) /*  340 */, CONST64(0xB99A8AE2782CCB24) /*  341 */,
-    CONST64(0xCCF52AB6C814C4C7) /*  342 */, CONST64(0x4727D9AFBE11727B) /*  343 */,
-    CONST64(0x7E950D0C0121B34D) /*  344 */, CONST64(0x756F435670AD471F) /*  345 */,
-    CONST64(0xF5ADD442615A6849) /*  346 */, CONST64(0x4E87E09980B9957A) /*  347 */,
-    CONST64(0x2ACFA1DF50AEE355) /*  348 */, CONST64(0xD898263AFD2FD556) /*  349 */,
-    CONST64(0xC8F4924DD80C8FD6) /*  350 */, CONST64(0xCF99CA3D754A173A) /*  351 */,
-    CONST64(0xFE477BACAF91BF3C) /*  352 */, CONST64(0xED5371F6D690C12D) /*  353 */,
-    CONST64(0x831A5C285E687094) /*  354 */, CONST64(0xC5D3C90A3708A0A4) /*  355 */,
-    CONST64(0x0F7F903717D06580) /*  356 */, CONST64(0x19F9BB13B8FDF27F) /*  357 */,
-    CONST64(0xB1BD6F1B4D502843) /*  358 */, CONST64(0x1C761BA38FFF4012) /*  359 */,
-    CONST64(0x0D1530C4E2E21F3B) /*  360 */, CONST64(0x8943CE69A7372C8A) /*  361 */,
-    CONST64(0xE5184E11FEB5CE66) /*  362 */, CONST64(0x618BDB80BD736621) /*  363 */,
-    CONST64(0x7D29BAD68B574D0B) /*  364 */, CONST64(0x81BB613E25E6FE5B) /*  365 */,
-    CONST64(0x071C9C10BC07913F) /*  366 */, CONST64(0xC7BEEB7909AC2D97) /*  367 */,
-    CONST64(0xC3E58D353BC5D757) /*  368 */, CONST64(0xEB017892F38F61E8) /*  369 */,
-    CONST64(0xD4EFFB9C9B1CC21A) /*  370 */, CONST64(0x99727D26F494F7AB) /*  371 */,
-    CONST64(0xA3E063A2956B3E03) /*  372 */, CONST64(0x9D4A8B9A4AA09C30) /*  373 */,
-    CONST64(0x3F6AB7D500090FB4) /*  374 */, CONST64(0x9CC0F2A057268AC0) /*  375 */,
-    CONST64(0x3DEE9D2DEDBF42D1) /*  376 */, CONST64(0x330F49C87960A972) /*  377 */,
-    CONST64(0xC6B2720287421B41) /*  378 */, CONST64(0x0AC59EC07C00369C) /*  379 */,
-    CONST64(0xEF4EAC49CB353425) /*  380 */, CONST64(0xF450244EEF0129D8) /*  381 */,
-    CONST64(0x8ACC46E5CAF4DEB6) /*  382 */, CONST64(0x2FFEAB63989263F7) /*  383 */,
-    CONST64(0x8F7CB9FE5D7A4578) /*  384 */, CONST64(0x5BD8F7644E634635) /*  385 */,
-    CONST64(0x427A7315BF2DC900) /*  386 */, CONST64(0x17D0C4AA2125261C) /*  387 */,
-    CONST64(0x3992486C93518E50) /*  388 */, CONST64(0xB4CBFEE0A2D7D4C3) /*  389 */,
-    CONST64(0x7C75D6202C5DDD8D) /*  390 */, CONST64(0xDBC295D8E35B6C61) /*  391 */,
-    CONST64(0x60B369D302032B19) /*  392 */, CONST64(0xCE42685FDCE44132) /*  393 */,
-    CONST64(0x06F3DDB9DDF65610) /*  394 */, CONST64(0x8EA4D21DB5E148F0) /*  395 */,
-    CONST64(0x20B0FCE62FCD496F) /*  396 */, CONST64(0x2C1B912358B0EE31) /*  397 */,
-    CONST64(0xB28317B818F5A308) /*  398 */, CONST64(0xA89C1E189CA6D2CF) /*  399 */,
-    CONST64(0x0C6B18576AAADBC8) /*  400 */, CONST64(0xB65DEAA91299FAE3) /*  401 */,
-    CONST64(0xFB2B794B7F1027E7) /*  402 */, CONST64(0x04E4317F443B5BEB) /*  403 */,
-    CONST64(0x4B852D325939D0A6) /*  404 */, CONST64(0xD5AE6BEEFB207FFC) /*  405 */,
-    CONST64(0x309682B281C7D374) /*  406 */, CONST64(0xBAE309A194C3B475) /*  407 */,
-    CONST64(0x8CC3F97B13B49F05) /*  408 */, CONST64(0x98A9422FF8293967) /*  409 */,
-    CONST64(0x244B16B01076FF7C) /*  410 */, CONST64(0xF8BF571C663D67EE) /*  411 */,
-    CONST64(0x1F0D6758EEE30DA1) /*  412 */, CONST64(0xC9B611D97ADEB9B7) /*  413 */,
-    CONST64(0xB7AFD5887B6C57A2) /*  414 */, CONST64(0x6290AE846B984FE1) /*  415 */,
-    CONST64(0x94DF4CDEACC1A5FD) /*  416 */, CONST64(0x058A5BD1C5483AFF) /*  417 */,
-    CONST64(0x63166CC142BA3C37) /*  418 */, CONST64(0x8DB8526EB2F76F40) /*  419 */,
-    CONST64(0xE10880036F0D6D4E) /*  420 */, CONST64(0x9E0523C9971D311D) /*  421 */,
-    CONST64(0x45EC2824CC7CD691) /*  422 */, CONST64(0x575B8359E62382C9) /*  423 */,
-    CONST64(0xFA9E400DC4889995) /*  424 */, CONST64(0xD1823ECB45721568) /*  425 */,
-    CONST64(0xDAFD983B8206082F) /*  426 */, CONST64(0xAA7D29082386A8CB) /*  427 */,
-    CONST64(0x269FCD4403B87588) /*  428 */, CONST64(0x1B91F5F728BDD1E0) /*  429 */,
-    CONST64(0xE4669F39040201F6) /*  430 */, CONST64(0x7A1D7C218CF04ADE) /*  431 */,
-    CONST64(0x65623C29D79CE5CE) /*  432 */, CONST64(0x2368449096C00BB1) /*  433 */,
-    CONST64(0xAB9BF1879DA503BA) /*  434 */, CONST64(0xBC23ECB1A458058E) /*  435 */,
-    CONST64(0x9A58DF01BB401ECC) /*  436 */, CONST64(0xA070E868A85F143D) /*  437 */,
-    CONST64(0x4FF188307DF2239E) /*  438 */, CONST64(0x14D565B41A641183) /*  439 */,
-    CONST64(0xEE13337452701602) /*  440 */, CONST64(0x950E3DCF3F285E09) /*  441 */,
-    CONST64(0x59930254B9C80953) /*  442 */, CONST64(0x3BF299408930DA6D) /*  443 */,
-    CONST64(0xA955943F53691387) /*  444 */, CONST64(0xA15EDECAA9CB8784) /*  445 */,
-    CONST64(0x29142127352BE9A0) /*  446 */, CONST64(0x76F0371FFF4E7AFB) /*  447 */,
-    CONST64(0x0239F450274F2228) /*  448 */, CONST64(0xBB073AF01D5E868B) /*  449 */,
-    CONST64(0xBFC80571C10E96C1) /*  450 */, CONST64(0xD267088568222E23) /*  451 */,
-    CONST64(0x9671A3D48E80B5B0) /*  452 */, CONST64(0x55B5D38AE193BB81) /*  453 */,
-    CONST64(0x693AE2D0A18B04B8) /*  454 */, CONST64(0x5C48B4ECADD5335F) /*  455 */,
-    CONST64(0xFD743B194916A1CA) /*  456 */, CONST64(0x2577018134BE98C4) /*  457 */,
-    CONST64(0xE77987E83C54A4AD) /*  458 */, CONST64(0x28E11014DA33E1B9) /*  459 */,
-    CONST64(0x270CC59E226AA213) /*  460 */, CONST64(0x71495F756D1A5F60) /*  461 */,
-    CONST64(0x9BE853FB60AFEF77) /*  462 */, CONST64(0xADC786A7F7443DBF) /*  463 */,
-    CONST64(0x0904456173B29A82) /*  464 */, CONST64(0x58BC7A66C232BD5E) /*  465 */,
-    CONST64(0xF306558C673AC8B2) /*  466 */, CONST64(0x41F639C6B6C9772A) /*  467 */,
-    CONST64(0x216DEFE99FDA35DA) /*  468 */, CONST64(0x11640CC71C7BE615) /*  469 */,
-    CONST64(0x93C43694565C5527) /*  470 */, CONST64(0xEA038E6246777839) /*  471 */,
-    CONST64(0xF9ABF3CE5A3E2469) /*  472 */, CONST64(0x741E768D0FD312D2) /*  473 */,
-    CONST64(0x0144B883CED652C6) /*  474 */, CONST64(0xC20B5A5BA33F8552) /*  475 */,
-    CONST64(0x1AE69633C3435A9D) /*  476 */, CONST64(0x97A28CA4088CFDEC) /*  477 */,
-    CONST64(0x8824A43C1E96F420) /*  478 */, CONST64(0x37612FA66EEEA746) /*  479 */,
-    CONST64(0x6B4CB165F9CF0E5A) /*  480 */, CONST64(0x43AA1C06A0ABFB4A) /*  481 */,
-    CONST64(0x7F4DC26FF162796B) /*  482 */, CONST64(0x6CBACC8E54ED9B0F) /*  483 */,
-    CONST64(0xA6B7FFEFD2BB253E) /*  484 */, CONST64(0x2E25BC95B0A29D4F) /*  485 */,
-    CONST64(0x86D6A58BDEF1388C) /*  486 */, CONST64(0xDED74AC576B6F054) /*  487 */,
-    CONST64(0x8030BDBC2B45805D) /*  488 */, CONST64(0x3C81AF70E94D9289) /*  489 */,
-    CONST64(0x3EFF6DDA9E3100DB) /*  490 */, CONST64(0xB38DC39FDFCC8847) /*  491 */,
-    CONST64(0x123885528D17B87E) /*  492 */, CONST64(0xF2DA0ED240B1B642) /*  493 */,
-    CONST64(0x44CEFADCD54BF9A9) /*  494 */, CONST64(0x1312200E433C7EE6) /*  495 */,
-    CONST64(0x9FFCC84F3A78C748) /*  496 */, CONST64(0xF0CD1F72248576BB) /*  497 */,
-    CONST64(0xEC6974053638CFE4) /*  498 */, CONST64(0x2BA7B67C0CEC4E4C) /*  499 */,
-    CONST64(0xAC2F4DF3E5CE32ED) /*  500 */, CONST64(0xCB33D14326EA4C11) /*  501 */,
-    CONST64(0xA4E9044CC77E58BC) /*  502 */, CONST64(0x5F513293D934FCEF) /*  503 */,
-    CONST64(0x5DC9645506E55444) /*  504 */, CONST64(0x50DE418F317DE40A) /*  505 */,
-    CONST64(0x388CB31A69DDE259) /*  506 */, CONST64(0x2DB4A83455820A86) /*  507 */,
-    CONST64(0x9010A91E84711AE9) /*  508 */, CONST64(0x4DF7F0B7B1498371) /*  509 */,
-    CONST64(0xD62A2EABC0977179) /*  510 */, CONST64(0x22FAC097AA8D5C0E) /*  511 */,
-    CONST64(0xF49FCC2FF1DAF39B) /*  512 */, CONST64(0x487FD5C66FF29281) /*  513 */,
-    CONST64(0xE8A30667FCDCA83F) /*  514 */, CONST64(0x2C9B4BE3D2FCCE63) /*  515 */,
-    CONST64(0xDA3FF74B93FBBBC2) /*  516 */, CONST64(0x2FA165D2FE70BA66) /*  517 */,
-    CONST64(0xA103E279970E93D4) /*  518 */, CONST64(0xBECDEC77B0E45E71) /*  519 */,
-    CONST64(0xCFB41E723985E497) /*  520 */, CONST64(0xB70AAA025EF75017) /*  521 */,
-    CONST64(0xD42309F03840B8E0) /*  522 */, CONST64(0x8EFC1AD035898579) /*  523 */,
-    CONST64(0x96C6920BE2B2ABC5) /*  524 */, CONST64(0x66AF4163375A9172) /*  525 */,
-    CONST64(0x2174ABDCCA7127FB) /*  526 */, CONST64(0xB33CCEA64A72FF41) /*  527 */,
-    CONST64(0xF04A4933083066A5) /*  528 */, CONST64(0x8D970ACDD7289AF5) /*  529 */,
-    CONST64(0x8F96E8E031C8C25E) /*  530 */, CONST64(0xF3FEC02276875D47) /*  531 */,
-    CONST64(0xEC7BF310056190DD) /*  532 */, CONST64(0xF5ADB0AEBB0F1491) /*  533 */,
-    CONST64(0x9B50F8850FD58892) /*  534 */, CONST64(0x4975488358B74DE8) /*  535 */,
-    CONST64(0xA3354FF691531C61) /*  536 */, CONST64(0x0702BBE481D2C6EE) /*  537 */,
-    CONST64(0x89FB24057DEDED98) /*  538 */, CONST64(0xAC3075138596E902) /*  539 */,
-    CONST64(0x1D2D3580172772ED) /*  540 */, CONST64(0xEB738FC28E6BC30D) /*  541 */,
-    CONST64(0x5854EF8F63044326) /*  542 */, CONST64(0x9E5C52325ADD3BBE) /*  543 */,
-    CONST64(0x90AA53CF325C4623) /*  544 */, CONST64(0xC1D24D51349DD067) /*  545 */,
-    CONST64(0x2051CFEEA69EA624) /*  546 */, CONST64(0x13220F0A862E7E4F) /*  547 */,
-    CONST64(0xCE39399404E04864) /*  548 */, CONST64(0xD9C42CA47086FCB7) /*  549 */,
-    CONST64(0x685AD2238A03E7CC) /*  550 */, CONST64(0x066484B2AB2FF1DB) /*  551 */,
-    CONST64(0xFE9D5D70EFBF79EC) /*  552 */, CONST64(0x5B13B9DD9C481854) /*  553 */,
-    CONST64(0x15F0D475ED1509AD) /*  554 */, CONST64(0x0BEBCD060EC79851) /*  555 */,
-    CONST64(0xD58C6791183AB7F8) /*  556 */, CONST64(0xD1187C5052F3EEE4) /*  557 */,
-    CONST64(0xC95D1192E54E82FF) /*  558 */, CONST64(0x86EEA14CB9AC6CA2) /*  559 */,
-    CONST64(0x3485BEB153677D5D) /*  560 */, CONST64(0xDD191D781F8C492A) /*  561 */,
-    CONST64(0xF60866BAA784EBF9) /*  562 */, CONST64(0x518F643BA2D08C74) /*  563 */,
-    CONST64(0x8852E956E1087C22) /*  564 */, CONST64(0xA768CB8DC410AE8D) /*  565 */,
-    CONST64(0x38047726BFEC8E1A) /*  566 */, CONST64(0xA67738B4CD3B45AA) /*  567 */,
-    CONST64(0xAD16691CEC0DDE19) /*  568 */, CONST64(0xC6D4319380462E07) /*  569 */,
-    CONST64(0xC5A5876D0BA61938) /*  570 */, CONST64(0x16B9FA1FA58FD840) /*  571 */,
-    CONST64(0x188AB1173CA74F18) /*  572 */, CONST64(0xABDA2F98C99C021F) /*  573 */,
-    CONST64(0x3E0580AB134AE816) /*  574 */, CONST64(0x5F3B05B773645ABB) /*  575 */,
-    CONST64(0x2501A2BE5575F2F6) /*  576 */, CONST64(0x1B2F74004E7E8BA9) /*  577 */,
-    CONST64(0x1CD7580371E8D953) /*  578 */, CONST64(0x7F6ED89562764E30) /*  579 */,
-    CONST64(0xB15926FF596F003D) /*  580 */, CONST64(0x9F65293DA8C5D6B9) /*  581 */,
-    CONST64(0x6ECEF04DD690F84C) /*  582 */, CONST64(0x4782275FFF33AF88) /*  583 */,
-    CONST64(0xE41433083F820801) /*  584 */, CONST64(0xFD0DFE409A1AF9B5) /*  585 */,
-    CONST64(0x4325A3342CDB396B) /*  586 */, CONST64(0x8AE77E62B301B252) /*  587 */,
-    CONST64(0xC36F9E9F6655615A) /*  588 */, CONST64(0x85455A2D92D32C09) /*  589 */,
-    CONST64(0xF2C7DEA949477485) /*  590 */, CONST64(0x63CFB4C133A39EBA) /*  591 */,
-    CONST64(0x83B040CC6EBC5462) /*  592 */, CONST64(0x3B9454C8FDB326B0) /*  593 */,
-    CONST64(0x56F56A9E87FFD78C) /*  594 */, CONST64(0x2DC2940D99F42BC6) /*  595 */,
-    CONST64(0x98F7DF096B096E2D) /*  596 */, CONST64(0x19A6E01E3AD852BF) /*  597 */,
-    CONST64(0x42A99CCBDBD4B40B) /*  598 */, CONST64(0xA59998AF45E9C559) /*  599 */,
-    CONST64(0x366295E807D93186) /*  600 */, CONST64(0x6B48181BFAA1F773) /*  601 */,
-    CONST64(0x1FEC57E2157A0A1D) /*  602 */, CONST64(0x4667446AF6201AD5) /*  603 */,
-    CONST64(0xE615EBCACFB0F075) /*  604 */, CONST64(0xB8F31F4F68290778) /*  605 */,
-    CONST64(0x22713ED6CE22D11E) /*  606 */, CONST64(0x3057C1A72EC3C93B) /*  607 */,
-    CONST64(0xCB46ACC37C3F1F2F) /*  608 */, CONST64(0xDBB893FD02AAF50E) /*  609 */,
-    CONST64(0x331FD92E600B9FCF) /*  610 */, CONST64(0xA498F96148EA3AD6) /*  611 */,
-    CONST64(0xA8D8426E8B6A83EA) /*  612 */, CONST64(0xA089B274B7735CDC) /*  613 */,
-    CONST64(0x87F6B3731E524A11) /*  614 */, CONST64(0x118808E5CBC96749) /*  615 */,
-    CONST64(0x9906E4C7B19BD394) /*  616 */, CONST64(0xAFED7F7E9B24A20C) /*  617 */,
-    CONST64(0x6509EADEEB3644A7) /*  618 */, CONST64(0x6C1EF1D3E8EF0EDE) /*  619 */,
-    CONST64(0xB9C97D43E9798FB4) /*  620 */, CONST64(0xA2F2D784740C28A3) /*  621 */,
-    CONST64(0x7B8496476197566F) /*  622 */, CONST64(0x7A5BE3E6B65F069D) /*  623 */,
-    CONST64(0xF96330ED78BE6F10) /*  624 */, CONST64(0xEEE60DE77A076A15) /*  625 */,
-    CONST64(0x2B4BEE4AA08B9BD0) /*  626 */, CONST64(0x6A56A63EC7B8894E) /*  627 */,
-    CONST64(0x02121359BA34FEF4) /*  628 */, CONST64(0x4CBF99F8283703FC) /*  629 */,
-    CONST64(0x398071350CAF30C8) /*  630 */, CONST64(0xD0A77A89F017687A) /*  631 */,
-    CONST64(0xF1C1A9EB9E423569) /*  632 */, CONST64(0x8C7976282DEE8199) /*  633 */,
-    CONST64(0x5D1737A5DD1F7ABD) /*  634 */, CONST64(0x4F53433C09A9FA80) /*  635 */,
-    CONST64(0xFA8B0C53DF7CA1D9) /*  636 */, CONST64(0x3FD9DCBC886CCB77) /*  637 */,
-    CONST64(0xC040917CA91B4720) /*  638 */, CONST64(0x7DD00142F9D1DCDF) /*  639 */,
-    CONST64(0x8476FC1D4F387B58) /*  640 */, CONST64(0x23F8E7C5F3316503) /*  641 */,
-    CONST64(0x032A2244E7E37339) /*  642 */, CONST64(0x5C87A5D750F5A74B) /*  643 */,
-    CONST64(0x082B4CC43698992E) /*  644 */, CONST64(0xDF917BECB858F63C) /*  645 */,
-    CONST64(0x3270B8FC5BF86DDA) /*  646 */, CONST64(0x10AE72BB29B5DD76) /*  647 */,
-    CONST64(0x576AC94E7700362B) /*  648 */, CONST64(0x1AD112DAC61EFB8F) /*  649 */,
-    CONST64(0x691BC30EC5FAA427) /*  650 */, CONST64(0xFF246311CC327143) /*  651 */,
-    CONST64(0x3142368E30E53206) /*  652 */, CONST64(0x71380E31E02CA396) /*  653 */,
-    CONST64(0x958D5C960AAD76F1) /*  654 */, CONST64(0xF8D6F430C16DA536) /*  655 */,
-    CONST64(0xC8FFD13F1BE7E1D2) /*  656 */, CONST64(0x7578AE66004DDBE1) /*  657 */,
-    CONST64(0x05833F01067BE646) /*  658 */, CONST64(0xBB34B5AD3BFE586D) /*  659 */,
-    CONST64(0x095F34C9A12B97F0) /*  660 */, CONST64(0x247AB64525D60CA8) /*  661 */,
-    CONST64(0xDCDBC6F3017477D1) /*  662 */, CONST64(0x4A2E14D4DECAD24D) /*  663 */,
-    CONST64(0xBDB5E6D9BE0A1EEB) /*  664 */, CONST64(0x2A7E70F7794301AB) /*  665 */,
-    CONST64(0xDEF42D8A270540FD) /*  666 */, CONST64(0x01078EC0A34C22C1) /*  667 */,
-    CONST64(0xE5DE511AF4C16387) /*  668 */, CONST64(0x7EBB3A52BD9A330A) /*  669 */,
-    CONST64(0x77697857AA7D6435) /*  670 */, CONST64(0x004E831603AE4C32) /*  671 */,
-    CONST64(0xE7A21020AD78E312) /*  672 */, CONST64(0x9D41A70C6AB420F2) /*  673 */,
-    CONST64(0x28E06C18EA1141E6) /*  674 */, CONST64(0xD2B28CBD984F6B28) /*  675 */,
-    CONST64(0x26B75F6C446E9D83) /*  676 */, CONST64(0xBA47568C4D418D7F) /*  677 */,
-    CONST64(0xD80BADBFE6183D8E) /*  678 */, CONST64(0x0E206D7F5F166044) /*  679 */,
-    CONST64(0xE258A43911CBCA3E) /*  680 */, CONST64(0x723A1746B21DC0BC) /*  681 */,
-    CONST64(0xC7CAA854F5D7CDD3) /*  682 */, CONST64(0x7CAC32883D261D9C) /*  683 */,
-    CONST64(0x7690C26423BA942C) /*  684 */, CONST64(0x17E55524478042B8) /*  685 */,
-    CONST64(0xE0BE477656A2389F) /*  686 */, CONST64(0x4D289B5E67AB2DA0) /*  687 */,
-    CONST64(0x44862B9C8FBBFD31) /*  688 */, CONST64(0xB47CC8049D141365) /*  689 */,
-    CONST64(0x822C1B362B91C793) /*  690 */, CONST64(0x4EB14655FB13DFD8) /*  691 */,
-    CONST64(0x1ECBBA0714E2A97B) /*  692 */, CONST64(0x6143459D5CDE5F14) /*  693 */,
-    CONST64(0x53A8FBF1D5F0AC89) /*  694 */, CONST64(0x97EA04D81C5E5B00) /*  695 */,
-    CONST64(0x622181A8D4FDB3F3) /*  696 */, CONST64(0xE9BCD341572A1208) /*  697 */,
-    CONST64(0x1411258643CCE58A) /*  698 */, CONST64(0x9144C5FEA4C6E0A4) /*  699 */,
-    CONST64(0x0D33D06565CF620F) /*  700 */, CONST64(0x54A48D489F219CA1) /*  701 */,
-    CONST64(0xC43E5EAC6D63C821) /*  702 */, CONST64(0xA9728B3A72770DAF) /*  703 */,
-    CONST64(0xD7934E7B20DF87EF) /*  704 */, CONST64(0xE35503B61A3E86E5) /*  705 */,
-    CONST64(0xCAE321FBC819D504) /*  706 */, CONST64(0x129A50B3AC60BFA6) /*  707 */,
-    CONST64(0xCD5E68EA7E9FB6C3) /*  708 */, CONST64(0xB01C90199483B1C7) /*  709 */,
-    CONST64(0x3DE93CD5C295376C) /*  710 */, CONST64(0xAED52EDF2AB9AD13) /*  711 */,
-    CONST64(0x2E60F512C0A07884) /*  712 */, CONST64(0xBC3D86A3E36210C9) /*  713 */,
-    CONST64(0x35269D9B163951CE) /*  714 */, CONST64(0x0C7D6E2AD0CDB5FA) /*  715 */,
-    CONST64(0x59E86297D87F5733) /*  716 */, CONST64(0x298EF221898DB0E7) /*  717 */,
-    CONST64(0x55000029D1A5AA7E) /*  718 */, CONST64(0x8BC08AE1B5061B45) /*  719 */,
-    CONST64(0xC2C31C2B6C92703A) /*  720 */, CONST64(0x94CC596BAF25EF42) /*  721 */,
-    CONST64(0x0A1D73DB22540456) /*  722 */, CONST64(0x04B6A0F9D9C4179A) /*  723 */,
-    CONST64(0xEFFDAFA2AE3D3C60) /*  724 */, CONST64(0xF7C8075BB49496C4) /*  725 */,
-    CONST64(0x9CC5C7141D1CD4E3) /*  726 */, CONST64(0x78BD1638218E5534) /*  727 */,
-    CONST64(0xB2F11568F850246A) /*  728 */, CONST64(0xEDFABCFA9502BC29) /*  729 */,
-    CONST64(0x796CE5F2DA23051B) /*  730 */, CONST64(0xAAE128B0DC93537C) /*  731 */,
-    CONST64(0x3A493DA0EE4B29AE) /*  732 */, CONST64(0xB5DF6B2C416895D7) /*  733 */,
-    CONST64(0xFCABBD25122D7F37) /*  734 */, CONST64(0x70810B58105DC4B1) /*  735 */,
-    CONST64(0xE10FDD37F7882A90) /*  736 */, CONST64(0x524DCAB5518A3F5C) /*  737 */,
-    CONST64(0x3C9E85878451255B) /*  738 */, CONST64(0x4029828119BD34E2) /*  739 */,
-    CONST64(0x74A05B6F5D3CECCB) /*  740 */, CONST64(0xB610021542E13ECA) /*  741 */,
-    CONST64(0x0FF979D12F59E2AC) /*  742 */, CONST64(0x6037DA27E4F9CC50) /*  743 */,
-    CONST64(0x5E92975A0DF1847D) /*  744 */, CONST64(0xD66DE190D3E623FE) /*  745 */,
-    CONST64(0x5032D6B87B568048) /*  746 */, CONST64(0x9A36B7CE8235216E) /*  747 */,
-    CONST64(0x80272A7A24F64B4A) /*  748 */, CONST64(0x93EFED8B8C6916F7) /*  749 */,
-    CONST64(0x37DDBFF44CCE1555) /*  750 */, CONST64(0x4B95DB5D4B99BD25) /*  751 */,
-    CONST64(0x92D3FDA169812FC0) /*  752 */, CONST64(0xFB1A4A9A90660BB6) /*  753 */,
-    CONST64(0x730C196946A4B9B2) /*  754 */, CONST64(0x81E289AA7F49DA68) /*  755 */,
-    CONST64(0x64669A0F83B1A05F) /*  756 */, CONST64(0x27B3FF7D9644F48B) /*  757 */,
-    CONST64(0xCC6B615C8DB675B3) /*  758 */, CONST64(0x674F20B9BCEBBE95) /*  759 */,
-    CONST64(0x6F31238275655982) /*  760 */, CONST64(0x5AE488713E45CF05) /*  761 */,
-    CONST64(0xBF619F9954C21157) /*  762 */, CONST64(0xEABAC46040A8EAE9) /*  763 */,
-    CONST64(0x454C6FE9F2C0C1CD) /*  764 */, CONST64(0x419CF6496412691C) /*  765 */,
-    CONST64(0xD3DC3BEF265B0F70) /*  766 */, CONST64(0x6D0E60F5C3578A9E) /*  767 */,
-    CONST64(0x5B0E608526323C55) /*  768 */, CONST64(0x1A46C1A9FA1B59F5) /*  769 */,
-    CONST64(0xA9E245A17C4C8FFA) /*  770 */, CONST64(0x65CA5159DB2955D7) /*  771 */,
-    CONST64(0x05DB0A76CE35AFC2) /*  772 */, CONST64(0x81EAC77EA9113D45) /*  773 */,
-    CONST64(0x528EF88AB6AC0A0D) /*  774 */, CONST64(0xA09EA253597BE3FF) /*  775 */,
-    CONST64(0x430DDFB3AC48CD56) /*  776 */, CONST64(0xC4B3A67AF45CE46F) /*  777 */,
-    CONST64(0x4ECECFD8FBE2D05E) /*  778 */, CONST64(0x3EF56F10B39935F0) /*  779 */,
-    CONST64(0x0B22D6829CD619C6) /*  780 */, CONST64(0x17FD460A74DF2069) /*  781 */,
-    CONST64(0x6CF8CC8E8510ED40) /*  782 */, CONST64(0xD6C824BF3A6ECAA7) /*  783 */,
-    CONST64(0x61243D581A817049) /*  784 */, CONST64(0x048BACB6BBC163A2) /*  785 */,
-    CONST64(0xD9A38AC27D44CC32) /*  786 */, CONST64(0x7FDDFF5BAAF410AB) /*  787 */,
-    CONST64(0xAD6D495AA804824B) /*  788 */, CONST64(0xE1A6A74F2D8C9F94) /*  789 */,
-    CONST64(0xD4F7851235DEE8E3) /*  790 */, CONST64(0xFD4B7F886540D893) /*  791 */,
-    CONST64(0x247C20042AA4BFDA) /*  792 */, CONST64(0x096EA1C517D1327C) /*  793 */,
-    CONST64(0xD56966B4361A6685) /*  794 */, CONST64(0x277DA5C31221057D) /*  795 */,
-    CONST64(0x94D59893A43ACFF7) /*  796 */, CONST64(0x64F0C51CCDC02281) /*  797 */,
-    CONST64(0x3D33BCC4FF6189DB) /*  798 */, CONST64(0xE005CB184CE66AF1) /*  799 */,
-    CONST64(0xFF5CCD1D1DB99BEA) /*  800 */, CONST64(0xB0B854A7FE42980F) /*  801 */,
-    CONST64(0x7BD46A6A718D4B9F) /*  802 */, CONST64(0xD10FA8CC22A5FD8C) /*  803 */,
-    CONST64(0xD31484952BE4BD31) /*  804 */, CONST64(0xC7FA975FCB243847) /*  805 */,
-    CONST64(0x4886ED1E5846C407) /*  806 */, CONST64(0x28CDDB791EB70B04) /*  807 */,
-    CONST64(0xC2B00BE2F573417F) /*  808 */, CONST64(0x5C9590452180F877) /*  809 */,
-    CONST64(0x7A6BDDFFF370EB00) /*  810 */, CONST64(0xCE509E38D6D9D6A4) /*  811 */,
-    CONST64(0xEBEB0F00647FA702) /*  812 */, CONST64(0x1DCC06CF76606F06) /*  813 */,
-    CONST64(0xE4D9F28BA286FF0A) /*  814 */, CONST64(0xD85A305DC918C262) /*  815 */,
-    CONST64(0x475B1D8732225F54) /*  816 */, CONST64(0x2D4FB51668CCB5FE) /*  817 */,
-    CONST64(0xA679B9D9D72BBA20) /*  818 */, CONST64(0x53841C0D912D43A5) /*  819 */,
-    CONST64(0x3B7EAA48BF12A4E8) /*  820 */, CONST64(0x781E0E47F22F1DDF) /*  821 */,
-    CONST64(0xEFF20CE60AB50973) /*  822 */, CONST64(0x20D261D19DFFB742) /*  823 */,
-    CONST64(0x16A12B03062A2E39) /*  824 */, CONST64(0x1960EB2239650495) /*  825 */,
-    CONST64(0x251C16FED50EB8B8) /*  826 */, CONST64(0x9AC0C330F826016E) /*  827 */,
-    CONST64(0xED152665953E7671) /*  828 */, CONST64(0x02D63194A6369570) /*  829 */,
-    CONST64(0x5074F08394B1C987) /*  830 */, CONST64(0x70BA598C90B25CE1) /*  831 */,
-    CONST64(0x794A15810B9742F6) /*  832 */, CONST64(0x0D5925E9FCAF8C6C) /*  833 */,
-    CONST64(0x3067716CD868744E) /*  834 */, CONST64(0x910AB077E8D7731B) /*  835 */,
-    CONST64(0x6A61BBDB5AC42F61) /*  836 */, CONST64(0x93513EFBF0851567) /*  837 */,
-    CONST64(0xF494724B9E83E9D5) /*  838 */, CONST64(0xE887E1985C09648D) /*  839 */,
-    CONST64(0x34B1D3C675370CFD) /*  840 */, CONST64(0xDC35E433BC0D255D) /*  841 */,
-    CONST64(0xD0AAB84234131BE0) /*  842 */, CONST64(0x08042A50B48B7EAF) /*  843 */,
-    CONST64(0x9997C4EE44A3AB35) /*  844 */, CONST64(0x829A7B49201799D0) /*  845 */,
-    CONST64(0x263B8307B7C54441) /*  846 */, CONST64(0x752F95F4FD6A6CA6) /*  847 */,
-    CONST64(0x927217402C08C6E5) /*  848 */, CONST64(0x2A8AB754A795D9EE) /*  849 */,
-    CONST64(0xA442F7552F72943D) /*  850 */, CONST64(0x2C31334E19781208) /*  851 */,
-    CONST64(0x4FA98D7CEAEE6291) /*  852 */, CONST64(0x55C3862F665DB309) /*  853 */,
-    CONST64(0xBD0610175D53B1F3) /*  854 */, CONST64(0x46FE6CB840413F27) /*  855 */,
-    CONST64(0x3FE03792DF0CFA59) /*  856 */, CONST64(0xCFE700372EB85E8F) /*  857 */,
-    CONST64(0xA7BE29E7ADBCE118) /*  858 */, CONST64(0xE544EE5CDE8431DD) /*  859 */,
-    CONST64(0x8A781B1B41F1873E) /*  860 */, CONST64(0xA5C94C78A0D2F0E7) /*  861 */,
-    CONST64(0x39412E2877B60728) /*  862 */, CONST64(0xA1265EF3AFC9A62C) /*  863 */,
-    CONST64(0xBCC2770C6A2506C5) /*  864 */, CONST64(0x3AB66DD5DCE1CE12) /*  865 */,
-    CONST64(0xE65499D04A675B37) /*  866 */, CONST64(0x7D8F523481BFD216) /*  867 */,
-    CONST64(0x0F6F64FCEC15F389) /*  868 */, CONST64(0x74EFBE618B5B13C8) /*  869 */,
-    CONST64(0xACDC82B714273E1D) /*  870 */, CONST64(0xDD40BFE003199D17) /*  871 */,
-    CONST64(0x37E99257E7E061F8) /*  872 */, CONST64(0xFA52626904775AAA) /*  873 */,
-    CONST64(0x8BBBF63A463D56F9) /*  874 */, CONST64(0xF0013F1543A26E64) /*  875 */,
-    CONST64(0xA8307E9F879EC898) /*  876 */, CONST64(0xCC4C27A4150177CC) /*  877 */,
-    CONST64(0x1B432F2CCA1D3348) /*  878 */, CONST64(0xDE1D1F8F9F6FA013) /*  879 */,
-    CONST64(0x606602A047A7DDD6) /*  880 */, CONST64(0xD237AB64CC1CB2C7) /*  881 */,
-    CONST64(0x9B938E7225FCD1D3) /*  882 */, CONST64(0xEC4E03708E0FF476) /*  883 */,
-    CONST64(0xFEB2FBDA3D03C12D) /*  884 */, CONST64(0xAE0BCED2EE43889A) /*  885 */,
-    CONST64(0x22CB8923EBFB4F43) /*  886 */, CONST64(0x69360D013CF7396D) /*  887 */,
-    CONST64(0x855E3602D2D4E022) /*  888 */, CONST64(0x073805BAD01F784C) /*  889 */,
-    CONST64(0x33E17A133852F546) /*  890 */, CONST64(0xDF4874058AC7B638) /*  891 */,
-    CONST64(0xBA92B29C678AA14A) /*  892 */, CONST64(0x0CE89FC76CFAADCD) /*  893 */,
-    CONST64(0x5F9D4E0908339E34) /*  894 */, CONST64(0xF1AFE9291F5923B9) /*  895 */,
-    CONST64(0x6E3480F60F4A265F) /*  896 */, CONST64(0xEEBF3A2AB29B841C) /*  897 */,
-    CONST64(0xE21938A88F91B4AD) /*  898 */, CONST64(0x57DFEFF845C6D3C3) /*  899 */,
-    CONST64(0x2F006B0BF62CAAF2) /*  900 */, CONST64(0x62F479EF6F75EE78) /*  901 */,
-    CONST64(0x11A55AD41C8916A9) /*  902 */, CONST64(0xF229D29084FED453) /*  903 */,
-    CONST64(0x42F1C27B16B000E6) /*  904 */, CONST64(0x2B1F76749823C074) /*  905 */,
-    CONST64(0x4B76ECA3C2745360) /*  906 */, CONST64(0x8C98F463B91691BD) /*  907 */,
-    CONST64(0x14BCC93CF1ADE66A) /*  908 */, CONST64(0x8885213E6D458397) /*  909 */,
-    CONST64(0x8E177DF0274D4711) /*  910 */, CONST64(0xB49B73B5503F2951) /*  911 */,
-    CONST64(0x10168168C3F96B6B) /*  912 */, CONST64(0x0E3D963B63CAB0AE) /*  913 */,
-    CONST64(0x8DFC4B5655A1DB14) /*  914 */, CONST64(0xF789F1356E14DE5C) /*  915 */,
-    CONST64(0x683E68AF4E51DAC1) /*  916 */, CONST64(0xC9A84F9D8D4B0FD9) /*  917 */,
-    CONST64(0x3691E03F52A0F9D1) /*  918 */, CONST64(0x5ED86E46E1878E80) /*  919 */,
-    CONST64(0x3C711A0E99D07150) /*  920 */, CONST64(0x5A0865B20C4E9310) /*  921 */,
-    CONST64(0x56FBFC1FE4F0682E) /*  922 */, CONST64(0xEA8D5DE3105EDF9B) /*  923 */,
-    CONST64(0x71ABFDB12379187A) /*  924 */, CONST64(0x2EB99DE1BEE77B9C) /*  925 */,
-    CONST64(0x21ECC0EA33CF4523) /*  926 */, CONST64(0x59A4D7521805C7A1) /*  927 */,
-    CONST64(0x3896F5EB56AE7C72) /*  928 */, CONST64(0xAA638F3DB18F75DC) /*  929 */,
-    CONST64(0x9F39358DABE9808E) /*  930 */, CONST64(0xB7DEFA91C00B72AC) /*  931 */,
-    CONST64(0x6B5541FD62492D92) /*  932 */, CONST64(0x6DC6DEE8F92E4D5B) /*  933 */,
-    CONST64(0x353F57ABC4BEEA7E) /*  934 */, CONST64(0x735769D6DA5690CE) /*  935 */,
-    CONST64(0x0A234AA642391484) /*  936 */, CONST64(0xF6F9508028F80D9D) /*  937 */,
-    CONST64(0xB8E319A27AB3F215) /*  938 */, CONST64(0x31AD9C1151341A4D) /*  939 */,
-    CONST64(0x773C22A57BEF5805) /*  940 */, CONST64(0x45C7561A07968633) /*  941 */,
-    CONST64(0xF913DA9E249DBE36) /*  942 */, CONST64(0xDA652D9B78A64C68) /*  943 */,
-    CONST64(0x4C27A97F3BC334EF) /*  944 */, CONST64(0x76621220E66B17F4) /*  945 */,
-    CONST64(0x967743899ACD7D0B) /*  946 */, CONST64(0xF3EE5BCAE0ED6782) /*  947 */,
-    CONST64(0x409F753600C879FC) /*  948 */, CONST64(0x06D09A39B5926DB6) /*  949 */,
-    CONST64(0x6F83AEB0317AC588) /*  950 */, CONST64(0x01E6CA4A86381F21) /*  951 */,
-    CONST64(0x66FF3462D19F3025) /*  952 */, CONST64(0x72207C24DDFD3BFB) /*  953 */,
-    CONST64(0x4AF6B6D3E2ECE2EB) /*  954 */, CONST64(0x9C994DBEC7EA08DE) /*  955 */,
-    CONST64(0x49ACE597B09A8BC4) /*  956 */, CONST64(0xB38C4766CF0797BA) /*  957 */,
-    CONST64(0x131B9373C57C2A75) /*  958 */, CONST64(0xB1822CCE61931E58) /*  959 */,
-    CONST64(0x9D7555B909BA1C0C) /*  960 */, CONST64(0x127FAFDD937D11D2) /*  961 */,
-    CONST64(0x29DA3BADC66D92E4) /*  962 */, CONST64(0xA2C1D57154C2ECBC) /*  963 */,
-    CONST64(0x58C5134D82F6FE24) /*  964 */, CONST64(0x1C3AE3515B62274F) /*  965 */,
-    CONST64(0xE907C82E01CB8126) /*  966 */, CONST64(0xF8ED091913E37FCB) /*  967 */,
-    CONST64(0x3249D8F9C80046C9) /*  968 */, CONST64(0x80CF9BEDE388FB63) /*  969 */,
-    CONST64(0x1881539A116CF19E) /*  970 */, CONST64(0x5103F3F76BD52457) /*  971 */,
-    CONST64(0x15B7E6F5AE47F7A8) /*  972 */, CONST64(0xDBD7C6DED47E9CCF) /*  973 */,
-    CONST64(0x44E55C410228BB1A) /*  974 */, CONST64(0xB647D4255EDB4E99) /*  975 */,
-    CONST64(0x5D11882BB8AAFC30) /*  976 */, CONST64(0xF5098BBB29D3212A) /*  977 */,
-    CONST64(0x8FB5EA14E90296B3) /*  978 */, CONST64(0x677B942157DD025A) /*  979 */,
-    CONST64(0xFB58E7C0A390ACB5) /*  980 */, CONST64(0x89D3674C83BD4A01) /*  981 */,
-    CONST64(0x9E2DA4DF4BF3B93B) /*  982 */, CONST64(0xFCC41E328CAB4829) /*  983 */,
-    CONST64(0x03F38C96BA582C52) /*  984 */, CONST64(0xCAD1BDBD7FD85DB2) /*  985 */,
-    CONST64(0xBBB442C16082AE83) /*  986 */, CONST64(0xB95FE86BA5DA9AB0) /*  987 */,
-    CONST64(0xB22E04673771A93F) /*  988 */, CONST64(0x845358C9493152D8) /*  989 */,
-    CONST64(0xBE2A488697B4541E) /*  990 */, CONST64(0x95A2DC2DD38E6966) /*  991 */,
-    CONST64(0xC02C11AC923C852B) /*  992 */, CONST64(0x2388B1990DF2A87B) /*  993 */,
-    CONST64(0x7C8008FA1B4F37BE) /*  994 */, CONST64(0x1F70D0C84D54E503) /*  995 */,
-    CONST64(0x5490ADEC7ECE57D4) /*  996 */, CONST64(0x002B3C27D9063A3A) /*  997 */,
-    CONST64(0x7EAEA3848030A2BF) /*  998 */, CONST64(0xC602326DED2003C0) /*  999 */,
-    CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */,
-    CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */,
-    CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */,
-    CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */,
-    CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */,
-    CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */,
-    CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */,
-    CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */,
-    CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */,
-    CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */,
-    CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */,
-    CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */};
-
-#ifdef _MSC_VER
-   #define INLINE __inline
-#else
-   #define INLINE 
-#endif   
-
-/* one round of the hash function */
-INLINE static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, int mul)
-{
-    ulong64 tmp;
-    tmp = (*c ^= x); 
-           *a -= t1[byte(tmp, 0)] ^ t2[byte(tmp, 2)] ^ t3[byte(tmp, 4)] ^ t4[byte(tmp, 6)];      
-    tmp = (*b += t4[byte(tmp, 1)] ^ t3[byte(tmp, 3)] ^ t2[byte(tmp,5)] ^ t1[byte(tmp,7)]); 
-    switch (mul) {
-        case 5:  *b = (tmp << 2) + tmp; break;
-        case 7:  *b = (tmp << 3) - tmp; break;
-        case 9:  *b = (tmp << 3) + tmp; break;
-    }
-}
-
-/* one complete pass */
-static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, int mul)
-{
-   round(a,b,c,x[0],mul); 
-   round(b,c,a,x[1],mul); 
-   round(c,a,b,x[2],mul); 
-   round(a,b,c,x[3],mul); 
-   round(b,c,a,x[4],mul); 
-   round(c,a,b,x[5],mul); 
-   round(a,b,c,x[6],mul); 
-   round(b,c,a,x[7],mul);          
-}   
-
-/* The key mixing schedule */
-static void key_schedule(ulong64 *x) 
-{
-    x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5); 
-    x[1] ^= x[0];                               
-    x[2] += x[1];                               
-    x[3] -= x[2] ^ ((~x[1])<<19);               
-    x[4] ^= x[3];                               
-    x[5] += x[4];                               
-    x[6] -= x[5] ^ ((~x[4])>>23);               
-    x[7] ^= x[6];                               
-    x[0] += x[7];                               
-    x[1] -= x[0] ^ ((~x[7])<<19);               
-    x[2] ^= x[1];                               
-    x[3] += x[2];                               
-    x[4] -= x[3] ^ ((~x[2])>>23);               
-    x[5] ^= x[4];                               
-    x[6] += x[5];                               
-    x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF);
-}    
-
-#ifdef CLEAN_STACK
-static void _tiger_compress(hash_state *md, unsigned char *buf)
-#else
-static void tiger_compress(hash_state *md, unsigned char *buf)
-#endif
-{
-    ulong64 a, b, c, x[8];
-    unsigned long i;
-
-    /* load words */
-    for (i = 0; i < 8; i++) {
-        LOAD64L(x[i],&buf[8*i]);
-    }
-    a = md->tiger.state[0];
-    b = md->tiger.state[1];
-    c = md->tiger.state[2];
-
-    pass(&a,&b,&c,x,5);
-    key_schedule(x);
-    pass(&c,&a,&b,x,7);
-    key_schedule(x);
-    pass(&b,&c,&a,x,9);
-
-    /* store state */
-    md->tiger.state[0] = a ^ md->tiger.state[0];
-    md->tiger.state[1] = b - md->tiger.state[1];
-    md->tiger.state[2] = c + md->tiger.state[2];
-}
-
-#ifdef CLEAN_STACK
-static void tiger_compress(hash_state *md, unsigned char *buf)
-{
-   _tiger_compress(md, buf);
-   burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long));
-}
-#endif
-
-void tiger_init(hash_state *md)
-{
-    _ARGCHK(md != NULL);
-    md->tiger.state[0] = CONST64(0x0123456789ABCDEF);
-    md->tiger.state[1] = CONST64(0xFEDCBA9876543210);
-    md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187);
-    md->tiger.curlen = 0;
-    md->tiger.length = 0;
-}
-
-HASH_PROCESS(tiger_process, tiger_compress, tiger, 64)
-
-int tiger_done(hash_state * md, unsigned char *hash)
-{
-    _ARGCHK(md   != NULL);
-    _ARGCHK(hash != NULL);
-
-    if (md->tiger.curlen >= sizeof(md->tiger.buf)) {
-       return CRYPT_INVALID_ARG;
-    }
-
-    /* increase the length of the message */
-    md->tiger.length += md->tiger.curlen * 8;
-
-    /* append the '1' bit */
-    md->tiger.buf[md->tiger.curlen++] = (unsigned char)0x01;
-
-    /* if the length is currently above 56 bytes we append zeros
-     * then compress.  Then we can fall back to padding zeros and length
-     * encoding like normal. */
-    if (md->tiger.curlen > 56) {
-        while (md->tiger.curlen < 64) {
-            md->tiger.buf[md->tiger.curlen++] = (unsigned char)0;
-        }
-        tiger_compress(md, md->tiger.buf);
-        md->tiger.curlen = 0;
-    }
-
-    /* pad upto 56 bytes of zeroes */
-    while (md->tiger.curlen < 56) {
-        md->tiger.buf[md->tiger.curlen++] = (unsigned char)0; 
-    }
-
-    /* store length */
-    STORE64L(md->tiger.length, md->tiger.buf+56);
-    tiger_compress(md, md->tiger.buf);
-
-    /* copy output */
-    STORE64L(md->tiger.state[0], &hash[0]);
-    STORE64L(md->tiger.state[1], &hash[8]);
-    STORE64L(md->tiger.state[2], &hash[16]);
-#ifdef CLEAN_STACK
-    zeromem(md, sizeof(hash_state));
-#endif
-
-    return CRYPT_OK;
-}
-
-int  tiger_test(void)
-{
- #ifndef LTC_TEST
-    return CRYPT_NOP;
- #else    
-  static const struct {
-      char *msg;
-      unsigned char hash[24];
-  } tests[] = {
-    { "",
-     { 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24,
-       0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16,
-       0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 }
-    },
-    { "abc",
-     { 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2,
-       0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52,
-       0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 }
-    },
-    { "Tiger",
-     { 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f,
-       0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27,
-       0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 }
-    },
-    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
-     { 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87,
-       0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47,
-       0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 }
-    },
-    { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
-     { 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00,
-       0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
-       0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 }
-    },
-  };
-
-  int i;
-  unsigned char tmp[24];
-  hash_state md;
-
-  for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
-      tiger_init(&md);
-      tiger_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
-      tiger_done(&md, tmp);
-      if (memcmp(tmp, tests[i].hash, 24) != 0) {
-          return CRYPT_FAIL_TESTVECTOR;
-      }
-  }
-  return CRYPT_OK;
-  #endif
-}
-
-#endif
-
-/*
-Hash of "":
-        24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
-Hash of "abc":
-        F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
-Hash of "Tiger":
-        9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
-Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
-        87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
-Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789":
-        467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
-Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham":
-        0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
-Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.":
-        EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
-Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.":
-        3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
-Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
-        00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
-*/
-
-
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tim_exptmod.c	Tue Jun 15 14:27:14 2004 +0000
@@ -0,0 +1,77 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis
+ *
+ * LibTomCrypt is a library that provides various cryptographic
+ * algorithms in a highly modular and flexible manner.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+/* RSA Code by Tom St Denis */
+#include "mycrypt.h"
+
+#ifdef RSA_TIMING
+
+/* decrypts c into m */
+int tim_exptmod(prng_state *prng, int prng_idx, 
+                mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m)
+{
+   int           err;
+   mp_int        r, tmp, tmp2;
+   unsigned char *rtmp;
+   unsigned long rlen;
+
+   _ARGCHK(c != NULL);
+   _ARGCHK(e != NULL);
+   _ARGCHK(d != NULL);
+   _ARGCHK(n != NULL);
+   _ARGCHK(m != NULL);
+
+   if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* pick random r */ 
+   rtmp = XMALLOC(MAX_RSA_SIZE/8);
+   if (rtmp == NULL) {
+      return CRYPT_MEM;
+   }
+
+
+   rlen = mp_unsigned_bin_size(n);
+   if (prng_descriptor[prng_idx].read(rtmp, rlen, prng) != rlen) {
+      XFREE(rtmp);
+      return CRYPT_ERROR_READPRNG;
+   }
+
+   if ((err = mp_init_multi(&r, &tmp, &tmp2, NULL)) != MP_OKAY) {
+      XFREE(rtmp);
+      return mpi_to_ltc_error(err);
+   }
+
+   /* read in r */
+   if ((err = mp_read_unsigned_bin(&r, rtmp, rlen)) != MP_OKAY)              { goto __ERR; }
+
+   /* compute tmp = r^e */
+   if ((err = mp_exptmod(&r, e, n, &tmp)) != MP_OKAY)                        { goto __ERR; }
+
+   /* multiply C into the mix */
+   if ((err = mp_mulmod(c, &tmp, n, &tmp)) != MP_OKAY)                       { goto __ERR; }
+
+   /* raise to d */
+   if ((err = mp_exptmod(&tmp, d, n, &tmp)) != MP_OKAY)                      { goto __ERR; }
+   
+   /* invert r and multiply */
+   if ((err = mp_invmod(&r, n, &tmp2)) != MP_OKAY)                           { goto __ERR; }
+
+   /* multiply and we are totally set */
+   if ((err = mp_mulmod(&tmp, &tmp2, n, m)) != MP_OKAY)                      { goto __ERR; }
+
+__ERR:  mp_clear_multi(&r, &tmp, &tmp2, NULL);
+   XFREE(rtmp);
+   return mpi_to_ltc_error(err);
+}
+
+#endif 
--- a/whirl.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/whirl.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,275 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-/* WHIRLPOOL (using their new sbox) hash function by Tom St Denis */
-
-#include "mycrypt.h"
-
-#ifdef WHIRLPOOL
-
-const struct _hash_descriptor whirlpool_desc =
-{
-    "whirlpool",
-    11,
-    64,
-    64,
-    &whirlpool_init,
-    &whirlpool_process,
-    &whirlpool_done,
-    &whirlpool_test
-};
-
-/* the sboxes */
-#include "whirltab.c"
-
-/* get a_{i,j} */
-#define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
-
-/* shortcut macro to perform three functions at once */
-#define theta_pi_gamma(a, i)               \
-    SB0(GB(a, i-0, 7)) ^                 \
-    SB1(GB(a, i-1, 6)) ^                 \
-    SB2(GB(a, i-2, 5)) ^                 \
-    SB3(GB(a, i-3, 4)) ^                 \
-    SB4(GB(a, i-4, 3)) ^                 \
-    SB5(GB(a, i-5, 2)) ^                 \
-    SB6(GB(a, i-6, 1)) ^                 \
-    SB7(GB(a, i-7, 0))
-
-#ifdef CLEAN_STACK
-static void _whirlpool_compress(hash_state *md, unsigned char *buf)
-#else
-static void whirlpool_compress(hash_state *md, unsigned char *buf)
-#endif
-{
-   ulong64 K[2][8], T[3][8];
-   int x, y;
-   
-   /* load the block/state */
-   for (x = 0; x < 8; x++) {
-      K[0][x] = md->whirlpool.state[x];
-
-      LOAD64H(T[0][x], buf + (8 * x));
-      T[2][x]  = T[0][x];
-      T[0][x] ^= K[0][x];
-   }
-  
-   /* do rounds 1..10 */
-   for (x = 0; x < 10; x += 2) {
-       /* odd round */
-       /* apply main transform to K[0] into K[1] */
-       for (y = 0; y < 8; y++) {
-           K[1][y] = theta_pi_gamma(K[0], y);
-       }
-       /* xor the constant */
-       K[1][0] ^= cont[x];
-       
-       /* apply main transform to T[0] into T[1] */
-       for (y = 0; y < 8; y++) {
-           T[1][y] = theta_pi_gamma(T[0], y) ^ K[1][y];
-       }
-
-       /* even round */
-       /* apply main transform to K[1] into K[0] */
-       for (y = 0; y < 8; y++) {
-           K[0][y] = theta_pi_gamma(K[1], y);
-       }
-       /* xor the constant */
-       K[0][0] ^= cont[x+1];
-       
-       /* apply main transform to T[0] into T[1] */
-       for (y = 0; y < 8; y++) {
-           T[0][y] = theta_pi_gamma(T[1], y) ^ K[0][y];
-       }
-   }
-   
-   /* store state */
-   for (x = 0; x < 8; x++) {
-      md->whirlpool.state[x] ^= T[0][x] ^ T[2][x];
-   }
-}
-
-
-#ifdef CLEAN_STACK
-static void whirlpool_compress(hash_state *md, unsigned char *buf)
-{
-   _whirlpool_compress(md, buf);
-   burn_stack((5 * 8 * sizeof(ulong64)) + (2 * sizeof(int)));
-}
-#endif
-
-
-void whirlpool_init(hash_state * md)
-{
-   _ARGCHK(md != NULL);
-   zeromem(&md->whirlpool, sizeof(md->whirlpool));
-}
-
-HASH_PROCESS(whirlpool_process, whirlpool_compress, whirlpool, 64)
-
-int whirlpool_done(hash_state * md, unsigned char *hash)
-{
-    int i;
-
-    _ARGCHK(md   != NULL);
-    _ARGCHK(hash != NULL);
-
-    if (md->whirlpool.curlen >= sizeof(md->whirlpool.buf)) {
-       return CRYPT_INVALID_ARG;
-    }
-
-    /* increase the length of the message */
-    md->whirlpool.length += md->whirlpool.curlen * 8;
-
-    /* append the '1' bit */
-    md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0x80;
-
-    /* if the length is currently above 32 bytes we append zeros
-     * then compress.  Then we can fall back to padding zeros and length
-     * encoding like normal.
-     */
-    if (md->whirlpool.curlen > 32) {
-        while (md->whirlpool.curlen < 64) {
-            md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
-        }
-        whirlpool_compress(md, md->whirlpool.buf);
-        md->whirlpool.curlen = 0;
-    }
-
-    /* pad upto 56 bytes of zeroes (should be 32 but we only support 64-bit lengths)  */
-    while (md->whirlpool.curlen < 56) {
-        md->whirlpool.buf[md->whirlpool.curlen++] = (unsigned char)0;
-    }
-
-    /* store length */
-    STORE64H(md->whirlpool.length, md->whirlpool.buf+56);
-    whirlpool_compress(md, md->whirlpool.buf);
-
-    /* copy output */
-    for (i = 0; i < 8; i++) {
-        STORE64H(md->whirlpool.state[i], hash+(8*i));
-    }
-#ifdef CLEAN_STACK
-    zeromem(md, sizeof(*md));
-#endif
-    return CRYPT_OK;
-}
-
-
-int  whirlpool_test(void)
-{
- #ifndef LTC_TEST
-    return CRYPT_NOP;
- #else    
-  static const struct {
-      int len;
-      unsigned char msg[128], hash[64];
-  } tests[] = {
-  
-  /* NULL Message */
-{
-  0, 
-  { 0x00 },
-  { 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26,
-    0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7,
-    0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57,
-    0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 }
-},
-
-
-   /* 448-bits of 0 bits */
-{
-
-  56,
-  { 0x00 },
-  { 0x0B, 0x3F, 0x53, 0x78, 0xEB, 0xED, 0x2B, 0xF4, 0xD7, 0xBE, 0x3C, 0xFD, 0x81, 0x8C, 0x1B, 0x03,
-    0xB6, 0xBB, 0x03, 0xD3, 0x46, 0x94, 0x8B, 0x04, 0xF4, 0xF4, 0x0C, 0x72, 0x6F, 0x07, 0x58, 0x70,
-    0x2A, 0x0F, 0x1E, 0x22, 0x58, 0x80, 0xE3, 0x8D, 0xD5, 0xF6, 0xED, 0x6D, 0xE9, 0xB1, 0xE9, 0x61,
-    0xE4, 0x9F, 0xC1, 0x31, 0x8D, 0x7C, 0xB7, 0x48, 0x22, 0xF3, 0xD0, 0xE2, 0xE9, 0xA7, 0xE7, 0xB0 }
-},
-
-   /* 520-bits of 0 bits */
-{
-  65,
-  { 0x00 },
-  { 0x85, 0xE1, 0x24, 0xC4, 0x41, 0x5B, 0xCF, 0x43, 0x19, 0x54, 0x3E, 0x3A, 0x63, 0xFF, 0x57, 0x1D,
-    0x09, 0x35, 0x4C, 0xEE, 0xBE, 0xE1, 0xE3, 0x25, 0x30, 0x8C, 0x90, 0x69, 0xF4, 0x3E, 0x2A, 0xE4,
-    0xD0, 0xE5, 0x1D, 0x4E, 0xB1, 0xE8, 0x64, 0x28, 0x70, 0x19, 0x4E, 0x95, 0x30, 0xD8, 0xD8, 0xAF,
-    0x65, 0x89, 0xD1, 0xBF, 0x69, 0x49, 0xDD, 0xF9, 0x0A, 0x7F, 0x12, 0x08, 0x62, 0x37, 0x95, 0xB9 }
-},
-
-   /* 512-bits, leading set */
-{
-  64,
-  { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-  { 0x10, 0x3E, 0x00, 0x55, 0xA9, 0xB0, 0x90, 0xE1, 0x1C, 0x8F, 0xDD, 0xEB, 0xBA, 0x06, 0xC0, 0x5A,
-    0xCE, 0x8B, 0x64, 0xB8, 0x96, 0x12, 0x8F, 0x6E, 0xED, 0x30, 0x71, 0xFC, 0xF3, 0xDC, 0x16, 0x94,
-    0x67, 0x78, 0xE0, 0x72, 0x23, 0x23, 0x3F, 0xD1, 0x80, 0xFC, 0x40, 0xCC, 0xDB, 0x84, 0x30, 0xA6,
-    0x40, 0xE3, 0x76, 0x34, 0x27, 0x1E, 0x65, 0x5C, 0xA1, 0x67, 0x4E, 0xBF, 0xF5, 0x07, 0xF8, 0xCB }
-},
-
-   /* 512-bits, leading set of second byte */
-{
-  64,
-  { 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
-  { 0x35, 0x7B, 0x42, 0xEA, 0x79, 0xBC, 0x97, 0x86, 0x97, 0x5A, 0x3C, 0x44, 0x70, 0xAA, 0xB2, 0x3E,
-    0x62, 0x29, 0x79, 0x7B, 0xAD, 0xBD, 0x54, 0x36, 0x5B, 0x54, 0x96, 0xE5, 0x5D, 0x9D, 0xD7, 0x9F,
-    0xE9, 0x62, 0x4F, 0xB4, 0x22, 0x66, 0x93, 0x0A, 0x62, 0x8E, 0xD4, 0xDB, 0x08, 0xF9, 0xDD, 0x35,
-    0xEF, 0x1B, 0xE1, 0x04, 0x53, 0xFC, 0x18, 0xF4, 0x2C, 0x7F, 0x5E, 0x1F, 0x9B, 0xAE, 0x55, 0xE0 }
-},
-
-   /* 512-bits, leading set of last byte */
-{
-  64,
-  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
-  { 0x8B, 0x39, 0x04, 0xDD, 0x19, 0x81, 0x41, 0x26, 0xFD, 0x02, 0x74, 0xAB, 0x49, 0xC5, 0x97, 0xF6,
-    0xD7, 0x75, 0x33, 0x52, 0xA2, 0xDD, 0x91, 0xFD, 0x8F, 0x9F, 0x54, 0x05, 0x4C, 0x54, 0xBF, 0x0F,
-    0x06, 0xDB, 0x4F, 0xF7, 0x08, 0xA3, 0xA2, 0x8B, 0xC3, 0x7A, 0x92, 0x1E, 0xEE, 0x11, 0xED, 0x7B,
-    0x6A, 0x53, 0x79, 0x32, 0xCC, 0x5E, 0x94, 0xEE, 0x1E, 0xA6, 0x57, 0x60, 0x7E, 0x36, 0xC9, 0xF7 }
-},
-   
-};
-
-  int i;
-  unsigned char tmp[64];
-  hash_state md;
-
-  for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
-      whirlpool_init(&md);
-      whirlpool_process(&md, (unsigned char *)tests[i].msg, tests[i].len);
-      whirlpool_done(&md, tmp);
-      if (memcmp(tmp, tests[i].hash, 64) != 0) {
-#if 0      
-         printf("\nFailed test %d\n", i);
-         for (i = 0; i < 64; ) {
-            printf("%02x ", tmp[i]);
-            if (!(++i & 15)) printf("\n");
-         }
-#endif         
-         return CRYPT_FAIL_TESTVECTOR;
-      }
-  }
-  return CRYPT_OK;
- #endif
-}
-
-
-#endif
-
--- a/yarrow.c	Wed Jun 02 08:31:25 2004 +0000
+++ b/yarrow.c	Tue Jun 15 14:27:14 2004 +0000
@@ -1,167 +0,0 @@
-/* LibTomCrypt, modular cryptographic library -- Tom St Denis
- *
- * LibTomCrypt is a library that provides various cryptographic
- * algorithms in a highly modular and flexible manner.
- *
- * The library is free for all purposes without any express
- * guarantee it works.
- *
- * Tom St Denis, [email protected], http://libtomcrypt.org
- */
-
-#include "mycrypt.h"
-
-#ifdef YARROW
-
-const struct _prng_descriptor yarrow_desc =
-{
-    "yarrow",
-    &yarrow_start,
-    &yarrow_add_entropy,
-    &yarrow_ready,
-    &yarrow_read
-};
-
-int yarrow_start(prng_state *prng)
-{
-   int err;
-   
-   _ARGCHK(prng != NULL);
-
-   /* these are the default hash/cipher combo used */
-#ifdef RIJNDAEL
-   prng->yarrow.cipher = register_cipher(&rijndael_desc);
-#elif defined(BLOWFISH)
-   prng->yarrow.cipher = register_cipher(&blowfish_desc);
-#elif defined(TWOFISH)
-   prng->yarrow.cipher = register_cipher(&twofish_desc);
-#elif defined(RC6)
-   prng->yarrow.cipher = register_cipher(&rc6_desc);
-#elif defined(RC5)
-   prng->yarrow.cipher = register_cipher(&rc5_desc);
-#elif defined(SAFERP)
-   prng->yarrow.cipher = register_cipher(&saferp_desc);
-#elif defined(RC2)
-   prng->yarrow.cipher = register_cipher(&rc2_desc);
-#elif defined(NOEKEON)   
-   prng->yarrow.cipher = register_cipher(&noekeon_desc);
-#elif defined(CAST5)
-   prng->yarrow.cipher = register_cipher(&cast5_desc);
-#elif defined(XTEA)
-   prng->yarrow.cipher = register_cipher(&xtea_desc);
-#elif defined(SAFER)
-   prng->yarrow.cipher = register_cipher(&safer_sk128_desc);
-#elif defined(DES)
-   prng->yarrow.cipher = register_cipher(&des3_desc);
-#elif
-   #error YARROW needs at least one CIPHER
-#endif
-   if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
-      return err;
-   }
-
-#ifdef SHA256
-   prng->yarrow.hash   = register_hash(&sha256_desc);
-#elif defined(SHA512)
-   prng->yarrow.hash   = register_hash(&sha512_desc);
-#elif defined(TIGER)
-   prng->yarrow.hash   = register_hash(&tiger_desc);
-#elif defined(SHA1)
-   prng->yarrow.hash   = register_hash(&sha1_desc);
-#elif defined(RIPEMD160)
-   prng->yarrow.hash   = register_hash(&rmd160_desc);
-#elif defined(RIPEMD128)
-   prng->yarrow.hash   = register_hash(&rmd128_desc);
-#elif defined(MD5)
-   prng->yarrow.hash   = register_hash(&md5_desc);
-#elif defined(MD4)
-   prng->yarrow.hash   = register_hash(&md4_desc);
-#elif defined(MD2)
-   prng->yarrow.hash   = register_hash(&md2_desc);
-#else
-   #error YARROW needs at least one HASH
-#endif
-   if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* zero the memory used */
-   zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
-
-   return CRYPT_OK;
-}
-
-int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
-{
-   hash_state md;
-   int err;
-
-   _ARGCHK(buf  != NULL);
-   _ARGCHK(prng != NULL);
-
-   if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* start the hash */
-   hash_descriptor[prng->yarrow.hash].init(&md);
-
-   /* hash the current pool */
-   hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize);
-
-   /* add the new entropy */
-   hash_descriptor[prng->yarrow.hash].process(&md, buf, len);
-
-   /* store result */
-   hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool);
-
-   return CRYPT_OK;
-}
-
-int yarrow_ready(prng_state *prng)
-{
-   int ks, err;
-
-   _ARGCHK(prng != NULL);
-
-   if ((err = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
-      return err;
-   }
-   
-   if ((err = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* setup CTR mode using the "pool" as the key */
-   ks = (int)hash_descriptor[prng->yarrow.hash].hashsize;
-   if ((err = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
-      return err;
-   }
-
-   if ((err = ctr_start(prng->yarrow.cipher,     /* what cipher to use */
-                        prng->yarrow.pool,       /* IV */
-                        prng->yarrow.pool, ks,   /* KEY and key size */
-                        0,                       /* number of rounds */
-                        &prng->yarrow.ctr)) != CRYPT_OK) {
-      return err;
-   }
-   return CRYPT_OK;
-}
-
-unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng)
-{
-   _ARGCHK(buf  != NULL);
-   _ARGCHK(prng != NULL);
-
-   /* put buf in predictable state first */
-   zeromem(buf, len);
-   
-   /* now randomize it */
-   if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) {
-      return 0;
-   }
-   return len;
-}
-
-#endif
-