瀏覽代碼

added libtomcrypt-0.94

Tom St Denis 21 年之前
父節點
當前提交
1f8b8bda6f
共有 50 個文件被更改,包括 3480 次插入1490 次删除
  1. 7 0
      LICENSE
  2. 17 15
      base64.c
  3. 23 0
      changes
  4. 4 2
      config.pl
  5. 3 0
      crypt.c
  6. 50 48
      crypt.out
  7. 二進制
      crypt.pdf
  8. 142 52
      crypt.tex
  9. 37 11
      demos/hashsum.c
  10. 9 1
      demos/test.c
  11. 79 0
      demos/tv_gen.c
  12. 5 2
      demos/x86_prof.c
  13. 53 63
      dh.c
  14. 48 48
      dh_sys.c
  15. 16 18
      dsa.c
  16. 62 0
      eax.c
  17. 178 192
      ecc.c
  18. 50 52
      ecc_sys.c
  19. 6 6
      hash.c
  20. 11 9
      hmac.c
  21. 7 4
      makefile
  22. 3 2
      makefile.cygwin_dll
  23. 2 2
      makefile.msvc
  24. 1 1
      makefile.out
  25. 2 2
      mycrypt.h
  26. 2 1
      mycrypt_custom.h
  27. 55 3
      mycrypt_hash.h
  28. 8 8
      mycrypt_macros.h
  29. 16 16
      mycrypt_pk.h
  30. 35 0
      notes/base64_tv.txt
  31. 0 216
      notes/cipher_tv.txt
  32. 0 76
      notes/eax_tv.txt
  33. 91 0
      notes/etc/whirlgen.c
  34. 15 0
      notes/etc/whirltest.c
  35. 131 0
      notes/hash_tv.txt
  36. 131 0
      notes/hmac_tv.txt
  37. 288 364
      notes/ocb_tv.txt
  38. 0 76
      notes/omac_tv.txt
  39. 331 0
      notes/pmac_tv.txt
  40. 128 53
      ocb.c
  41. 23 1
      omac.c
  42. 437 0
      pmac.c
  43. 103 101
      rsa.c
  44. 20 19
      rsa_sys.c
  45. 5 5
      saferp.c
  46. 1 1
      sha224.c
  47. 17 17
      skipjack.c
  48. 3 3
      twofish.c
  49. 275 0
      whirl.c
  50. 550 0
      whirltab.c

+ 7 - 0
LICENSE

@@ -0,0 +1,7 @@
+LibTomCrypt is public domain.  As should all quality software be.
+
+All of the software was either written by or donated to Tom St Denis for the purposes
+of this project.  The only exception is the SAFER.C source which has no known
+license status (assumed copyrighted) which is why SAFER,C is shipped as disabled.
+
+Tom St Denis

+ 17 - 15
base64.c

@@ -46,8 +46,8 @@ int base64_encode(const unsigned char *in,  unsigned long len,
    unsigned long i, len2, leven;
    unsigned char *p;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
 
    /* valid output size ? */
@@ -58,21 +58,20 @@ int base64_encode(const unsigned char *in,  unsigned long len,
    p = out;
    leven = 3*(len / 3);
    for (i = 0; i < leven; i += 3) {
-       *p++ = codes[in[0] >> 2];
-       *p++ = codes[((in[0] & 3) << 4) + (in[1] >> 4)];
-       *p++ = codes[((in[1] & 0xf) << 2) + (in[2] >> 6)];
-       *p++ = codes[in[2] & 0x3f];
+       *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;
-       unsigned c = 0;
 
-       *p++ = codes[a >> 2];
-       *p++ = codes[((a & 3) << 4) + (b >> 4)];
-       *p++ = (i+1 < len) ? codes[((b & 0xf) << 2) + (c >> 6)] : '=';
+       *p++ = codes[(a >> 2) & 0x3F];
+       *p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
+       *p++ = (i+1 < len) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
        *p++ = '=';
    }
 
@@ -89,19 +88,22 @@ int base64_decode(const unsigned char *in,  unsigned long len,
 {
    unsigned long t, x, y, z;
    unsigned char c;
-   int	g = 3;
+   int           g;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
 
+   g = 3;
    for (x = y = z = t = 0; x < len; x++) {
-       c = map[in[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; }
+          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);

+ 23 - 0
changes

@@ -1,3 +1,26 @@
+Feb 20th, 2004
+v0.94  -- removed unused variables from ocb.c and fixed it to match known test vectors.
+       -- Added PMAC support, minor changes to OMAC/EAX code [I think....]
+       -- Teamed up with Brian Gladman.  His code verifies against my vectors and my code
+          verifies against his test vectors.  Hazaa for co-operation!
+       -- Various small changes (added missing ARGCHKs and cleaned up indentation)
+       -- Optimization to base64, removed unused variable "c"
+       -- Added base64 gen to demos/tv_gen.c
+       -- Fix to demos/x86_prof.c to correctly identify the i386 architecture... weird...
+       -- Fixed up all of the PK code by adding missing error checking, removed "res" variables,
+          shrunk some stack variables, removed non-required stack variables and added proper
+          error conversion from MPI to LTC codes.  I also spotted a few "off by one" error
+          checking which could have been used to force the code to read past the end of
+          the buffer (in theory, haven't checked if it would work) by a few bytes.
+       -- Added checks to OUTPUT_BIGNUM so the *_export() functions cannot overflow the output and I 
+          also modded it so it stores in the output provided to the function (that is not on
+          the local stack) which saves memory and time.
+       -- Made SAFER default to disabled for now (plans are to cleanhouse write an implementation later)
+       -- Added the 512-bit one-way hash WHIRLPOOL which clocks in at 138 cycles per byte on my
+          Athlon XP [for comparison, SHA-512 clocks in at 77 cycles per byte].  This code uses the 
+          teams new sbox design (not the original NESSIE one).
+      
+
 Jan 25th, 2004
 v0.93  -- [note: deleted v0.93 changes by accident... recreating from memory...]
        -- Fix to RC2 to not deference pointer before ARGCHK

+ 4 - 2
config.pl

@@ -31,7 +31,7 @@
    "RC5,Include RC5 block cipher,y",
    "RC6,Include RC6 block cipher,y",
    "SAFERP,Include Safer+ block cipher,y",
-   "SAFER,Include Safer-64 block ciphers,y",
+   "SAFER,Include Safer-64 block ciphers,n",
    "RIJNDAEL,Include Rijndael (AES) block cipher,y",
    "XTEA,Include XTEA block cipher,y",
    "TWOFISH,Include Twofish block cipher (default: fast),y",
@@ -49,6 +49,7 @@
    "CBC,Include CBC block mode of operation,y",
    "CTR,Include CTR block mode of operation,y",
 
+   "WHIRLPOOL,Include WHIRLPOOL 512-bit one-way hash,y",
    "SHA512,Include SHA512 one-way hash,y",
    "SHA384,Include SHA384 one-way hash (requires SHA512),y",
    "SHA256,Include SHA256 one-way hash,y",
@@ -62,6 +63,7 @@
    "RIPEMD160,Include RIPEMD-160 one-way hash,y",
    "HMAC,Include Hash based Message Authentication Support,y",
    "OMAC,Include OMAC1 Message Authentication Support,y",
+   "PMAC,Include PMAC Message Authentication Support,y",
    "EAX_MODE,Include EAX Encrypt-and-Authenticate Support,y",
    "OCB_MODE,Include OCB Encrypt-and-Authenticate Support,y",
 
@@ -153,7 +155,7 @@ for (@settings) {
 
 # output objects
 print OUT "\ndefault: library\n\n";
-print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o eax.o ocb.o \n\n";
+print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o eax.o ocb.o pmac.o whirl.o\n\n";
 
 # some depends
 print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\naes.o: aes.c aes_tab.c\ntwofish.o: twofish.c twofish_tab.c\nsha512.o: sha384.c sha512.c\nsha256.o: sha256.c sha224.c\n\n";

+ 3 - 0
crypt.c

@@ -566,6 +566,9 @@ const char *crypt_build_settings =
 #if defined(OMAC)
     " OMAC "
 #endif
+#if defined(PMAC)
+    " PMAC "
+#endif
 #if defined(EAX_MODE)
     " EAX_MODE "
 #endif

+ 50 - 48
crypt.out

@@ -31,56 +31,58 @@
 \BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
 \BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}
 \BOOKMARK [2][-]{subsection.4.2.1}{Notice}{section.4.2}
-\BOOKMARK [1][-]{section.4.3}{Hash based Message Authenication Codes}{chapter.4}
-\BOOKMARK [1][-]{section.4.4}{OMAC Support}{chapter.4}
-\BOOKMARK [0][-]{chapter.5}{Pseudo-Random Number Generators}{}
-\BOOKMARK [1][-]{section.5.1}{Core Functions}{chapter.5}
-\BOOKMARK [2][-]{subsection.5.1.1}{Remarks}{section.5.1}
-\BOOKMARK [2][-]{subsection.5.1.2}{Example}{section.5.1}
-\BOOKMARK [1][-]{section.5.2}{PRNG Descriptors}{chapter.5}
-\BOOKMARK [1][-]{section.5.3}{The Secure RNG}{chapter.5}
-\BOOKMARK [2][-]{subsection.5.3.1}{The Secure PRNG Interface}{section.5.3}
-\BOOKMARK [0][-]{chapter.6}{RSA Routines}{}
-\BOOKMARK [1][-]{section.6.1}{Background}{chapter.6}
-\BOOKMARK [1][-]{section.6.2}{Core Functions}{chapter.6}
-\BOOKMARK [1][-]{section.6.3}{Packet Routines}{chapter.6}
-\BOOKMARK [1][-]{section.6.4}{Remarks}{chapter.6}
-\BOOKMARK [0][-]{chapter.7}{Diffie-Hellman Key Exchange}{}
+\BOOKMARK [0][-]{chapter.5}{Message Authentication Codes}{}
+\BOOKMARK [1][-]{section.5.1}{HMAC Protocol}{chapter.5}
+\BOOKMARK [1][-]{section.5.2}{OMAC Support}{chapter.5}
+\BOOKMARK [1][-]{section.5.3}{PMAC Support}{chapter.5}
+\BOOKMARK [0][-]{chapter.6}{Pseudo-Random Number Generators}{}
+\BOOKMARK [1][-]{section.6.1}{Core Functions}{chapter.6}
+\BOOKMARK [2][-]{subsection.6.1.1}{Remarks}{section.6.1}
+\BOOKMARK [2][-]{subsection.6.1.2}{Example}{section.6.1}
+\BOOKMARK [1][-]{section.6.2}{PRNG Descriptors}{chapter.6}
+\BOOKMARK [1][-]{section.6.3}{The Secure RNG}{chapter.6}
+\BOOKMARK [2][-]{subsection.6.3.1}{The Secure PRNG Interface}{section.6.3}
+\BOOKMARK [0][-]{chapter.7}{RSA Routines}{}
 \BOOKMARK [1][-]{section.7.1}{Background}{chapter.7}
 \BOOKMARK [1][-]{section.7.2}{Core Functions}{chapter.7}
-\BOOKMARK [2][-]{subsection.7.2.1}{Remarks on Usage}{section.7.2}
-\BOOKMARK [2][-]{subsection.7.2.2}{Remarks on The Snippet}{section.7.2}
-\BOOKMARK [1][-]{section.7.3}{Other Diffie-Hellman Functions}{chapter.7}
-\BOOKMARK [1][-]{section.7.4}{DH Packet}{chapter.7}
-\BOOKMARK [0][-]{chapter.8}{Elliptic Curve Cryptography}{}
+\BOOKMARK [1][-]{section.7.3}{Packet Routines}{chapter.7}
+\BOOKMARK [1][-]{section.7.4}{Remarks}{chapter.7}
+\BOOKMARK [0][-]{chapter.8}{Diffie-Hellman Key Exchange}{}
 \BOOKMARK [1][-]{section.8.1}{Background}{chapter.8}
 \BOOKMARK [1][-]{section.8.2}{Core Functions}{chapter.8}
-\BOOKMARK [1][-]{section.8.3}{ECC Packet}{chapter.8}
-\BOOKMARK [1][-]{section.8.4}{ECC Keysizes}{chapter.8}
-\BOOKMARK [0][-]{chapter.9}{Digital Signature Algorithm}{}
-\BOOKMARK [1][-]{section.9.1}{Introduction}{chapter.9}
-\BOOKMARK [1][-]{section.9.2}{Key Generation}{chapter.9}
-\BOOKMARK [1][-]{section.9.3}{Key Verification}{chapter.9}
-\BOOKMARK [1][-]{section.9.4}{Signatures}{chapter.9}
-\BOOKMARK [1][-]{section.9.5}{Import and Export}{chapter.9}
-\BOOKMARK [0][-]{chapter.10}{Public Keyrings}{}
+\BOOKMARK [2][-]{subsection.8.2.1}{Remarks on Usage}{section.8.2}
+\BOOKMARK [2][-]{subsection.8.2.2}{Remarks on The Snippet}{section.8.2}
+\BOOKMARK [1][-]{section.8.3}{Other Diffie-Hellman Functions}{chapter.8}
+\BOOKMARK [1][-]{section.8.4}{DH Packet}{chapter.8}
+\BOOKMARK [0][-]{chapter.9}{Elliptic Curve Cryptography}{}
+\BOOKMARK [1][-]{section.9.1}{Background}{chapter.9}
+\BOOKMARK [1][-]{section.9.2}{Core Functions}{chapter.9}
+\BOOKMARK [1][-]{section.9.3}{ECC Packet}{chapter.9}
+\BOOKMARK [1][-]{section.9.4}{ECC Keysizes}{chapter.9}
+\BOOKMARK [0][-]{chapter.10}{Digital Signature Algorithm}{}
 \BOOKMARK [1][-]{section.10.1}{Introduction}{chapter.10}
-\BOOKMARK [1][-]{section.10.2}{The Keyring API}{chapter.10}
-\BOOKMARK [0][-]{chapter.11}{GF\(2w\) Math Routines}{}
-\BOOKMARK [0][-]{chapter.12}{Miscellaneous}{}
-\BOOKMARK [1][-]{section.12.1}{Base64 Encoding and Decoding}{chapter.12}
-\BOOKMARK [1][-]{section.12.2}{The Multiple Precision Integer Library \(MPI\)}{chapter.12}
-\BOOKMARK [2][-]{subsection.12.2.1}{Binary Forms of ``mp\137int'' Variables}{section.12.2}
-\BOOKMARK [2][-]{subsection.12.2.2}{Primality Testing}{section.12.2}
-\BOOKMARK [0][-]{chapter.13}{Programming Guidelines}{}
-\BOOKMARK [1][-]{section.13.1}{Secure Pseudo Random Number Generators}{chapter.13}
-\BOOKMARK [1][-]{section.13.2}{Preventing Trivial Errors}{chapter.13}
-\BOOKMARK [1][-]{section.13.3}{Registering Your Algorithms}{chapter.13}
-\BOOKMARK [1][-]{section.13.4}{Key Sizes}{chapter.13}
-\BOOKMARK [2][-]{subsection.13.4.1}{Symmetric Ciphers}{section.13.4}
-\BOOKMARK [2][-]{subsection.13.4.2}{Assymetric Ciphers}{section.13.4}
-\BOOKMARK [1][-]{section.13.5}{Thread Safety}{chapter.13}
-\BOOKMARK [0][-]{chapter.14}{Configuring the Library}{}
-\BOOKMARK [1][-]{section.14.1}{Introduction}{chapter.14}
-\BOOKMARK [1][-]{section.14.2}{mycrypt\137cfg.h}{chapter.14}
-\BOOKMARK [1][-]{section.14.3}{The Configure Script}{chapter.14}
+\BOOKMARK [1][-]{section.10.2}{Key Generation}{chapter.10}
+\BOOKMARK [1][-]{section.10.3}{Key Verification}{chapter.10}
+\BOOKMARK [1][-]{section.10.4}{Signatures}{chapter.10}
+\BOOKMARK [1][-]{section.10.5}{Import and Export}{chapter.10}
+\BOOKMARK [0][-]{chapter.11}{Public Keyrings}{}
+\BOOKMARK [1][-]{section.11.1}{Introduction}{chapter.11}
+\BOOKMARK [1][-]{section.11.2}{The Keyring API}{chapter.11}
+\BOOKMARK [0][-]{chapter.12}{GF\(2w\) Math Routines}{}
+\BOOKMARK [0][-]{chapter.13}{Miscellaneous}{}
+\BOOKMARK [1][-]{section.13.1}{Base64 Encoding and Decoding}{chapter.13}
+\BOOKMARK [1][-]{section.13.2}{The Multiple Precision Integer Library \(MPI\)}{chapter.13}
+\BOOKMARK [2][-]{subsection.13.2.1}{Binary Forms of ``mp\137int'' Variables}{section.13.2}
+\BOOKMARK [2][-]{subsection.13.2.2}{Primality Testing}{section.13.2}
+\BOOKMARK [0][-]{chapter.14}{Programming Guidelines}{}
+\BOOKMARK [1][-]{section.14.1}{Secure Pseudo Random Number Generators}{chapter.14}
+\BOOKMARK [1][-]{section.14.2}{Preventing Trivial Errors}{chapter.14}
+\BOOKMARK [1][-]{section.14.3}{Registering Your Algorithms}{chapter.14}
+\BOOKMARK [1][-]{section.14.4}{Key Sizes}{chapter.14}
+\BOOKMARK [2][-]{subsection.14.4.1}{Symmetric Ciphers}{section.14.4}
+\BOOKMARK [2][-]{subsection.14.4.2}{Assymetric Ciphers}{section.14.4}
+\BOOKMARK [1][-]{section.14.5}{Thread Safety}{chapter.14}
+\BOOKMARK [0][-]{chapter.15}{Configuring the Library}{}
+\BOOKMARK [1][-]{section.15.1}{Introduction}{chapter.15}
+\BOOKMARK [1][-]{section.15.2}{mycrypt\137cfg.h}{chapter.15}
+\BOOKMARK [1][-]{section.15.3}{The Configure Script}{chapter.15}

二進制
crypt.pdf


+ 142 - 52
crypt.tex

@@ -47,9 +47,8 @@
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \begin{document}
-\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.93}
+\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.94}
 \author{Tom St Denis \\
-Algonquin College \\
 \\
 [email protected] \\
 http://libtomcrypt.org \\ \\
@@ -915,7 +914,8 @@ To terminate a decrypt stream and compared the tag you call the following.
 int ocb_done_decrypt(ocb_state *ocb, 
                      const unsigned char *ct,  unsigned long ctlen,
                            unsigned char *pt, 
-                     const unsigned char *tag, unsigned long taglen, int *res);
+                     const unsigned char *tag, unsigned long taglen, 
+                           int *res);
 \end{verbatim}
 
 Similarly to the previous function you can pass trailing message bytes into this function.  This will compute the 
@@ -1145,6 +1145,7 @@ The following hashes are provided as of this release:
 \begin{center}
 \begin{tabular}{|c|c|c|}
       \hline Name & Descriptor Name & Size of Message Digest (bytes) \\
+      \hline WHIRLPOOL & whirlpool\_desc & 64 \\
       \hline SHA-512 & sha512\_desc & 64 \\
       \hline SHA-384 & sha384\_desc & 48 \\
       \hline SHA-256 & sha256\_desc & 32 \\
@@ -1175,7 +1176,8 @@ These hashes are provided for completeness and they still can be used for the pu
 The other hashes such as the SHA-1, SHA-2 (that includes SHA-512, SHA-384 and SHA-256) and TIGER-192 are still considered secure
 for all purposes you would normally use a hash for.
 
-\section{Hash based Message Authenication Codes}
+\chapter{Message Authentication Codes}
+\section{HMAC Protocol}
 Thanks to Dobes Vandermeer the library now includes support for hash based message authenication codes or HMAC for short.  An HMAC
 of a message is a keyed authenication code that only the owner of a private symmetric key will be able to verify.  The purpose is
 to allow an owner of a private symmetric key to produce an HMAC on a message then later verify if it is correct.  Any impostor or
@@ -1304,7 +1306,20 @@ int omac_process(omac_state *state,
                  const unsigned char *buf, unsigned long len);
 \end{verbatim}
 This will send ``len'' bytes from ``buf'' through the active OMAC state ``state''.  Returns \textbf{CRYPT\_OK} if the 
-function succeeds.  When you are done with the message you can call
+function succeeds.  The function is not sensitive to the granularity of the data.  For example,
+
+\begin{verbatim}
+omac_process(&mystate, "hello",  5);
+omac_process(&mystate, " world", 6);
+\end{verbatim}
+
+Would produce the same result as,
+
+\begin{verbatim}
+omac_process(&mystate, "hello world",  11);
+\end{verbatim}
+
+When you are done processing the message you can call the following to compute the message tag.
 
 \begin{verbatim}
 int omac_done(omac_state *state, 
@@ -1353,7 +1368,7 @@ OMAC system is given below.
 #include <mycrypt.h>
 int main(void)
 {
-   int idx, errno;
+   int idx, err;
    omac_state omac;
    unsigned char key[16], dst[MAXBLOCKSIZE];
    unsigned long dstlen;
@@ -1370,21 +1385,21 @@ int main(void)
    /* we would make up our symmetric key in "key[]" here */
 
    /* start the OMAC */
-   if ((errno = omac_init(&omac, idx, key, 16)) != CRYPT_OK) {
-      printf("Error setting up omac: %s\n", error_to_string(errno));
+   if ((err = omac_init(&omac, idx, key, 16)) != CRYPT_OK) {
+      printf("Error setting up omac: %s\n", error_to_string(err));
       return -1;
    }
 
    /* process a few octets */
-   if((errno = omac_process(&omac, "hello", 5) != CRYPT_OK) {
-      printf("Error processing omac: %s\n", error_to_string(errno));
+   if((err = omac_process(&omac, "hello", 5) != CRYPT_OK) {
+      printf("Error processing omac: %s\n", error_to_string(err));
       return -1;
    }
 
    /* get result (presumably to use it somehow...) */
    dstlen = sizeof(dst);
-   if ((errno = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) {
-      printf("Error finishing omac: %s\n", error_to_string(errno));
+   if ((err = omac_done(&omac, dst, &dstlen)) != CRYPT_OK) {
+      printf("Error finishing omac: %s\n", error_to_string(err));
       return -1;
    }
    printf("The omac is %lu bytes long\n", dstlen);
@@ -1395,6 +1410,81 @@ int main(void)
 \end{verbatim}
 \end{small}
 
+\section{PMAC Support}
+The PMAC\footnote{J.Black, P.Rogaway, ``A Block--Cipher Mode of Operation for Parallelizable Message Authentication''} 
+protocol is another MAC algorithm that relies solely on a symmetric-key block cipher.  It uses essentially the same
+API as the provided OMAC code.  
+
+A PMAC state is initialized with the following.
+
+\begin{verbatim}
+int pmac_init(pmac_state *pmac, int cipher, 
+              const unsigned char *key, unsigned long keylen);
+\end{verbatim}
+Which initializes the ``pmac'' state with the given ``cipher'' and ``key'' of length ``keylen'' bytes.  The chosen cipher
+must have a 64 or 128 bit block size (e.x. AES).
+
+To MAC data simply send it through the process function.
+
+\begin{verbatim}
+int pmac_process(pmac_state *state, 
+                 const unsigned char *buf, unsigned long len);
+\end{verbatim}
+This will process ``len'' bytes of ``buf'' in the given ``state''.  The function is not sensitive to the granularity of the
+data.  For example,
+
+\begin{verbatim}
+pmac_process(&mystate, "hello",  5);
+pmac_process(&mystate, " world", 6);
+\end{verbatim}
+
+Would produce the same result as,
+
+\begin{verbatim}
+pmac_process(&mystate, "hello world",  11);
+\end{verbatim}
+
+When a complete message has been processed the following function can be called to compute the message tag.
+
+\begin{verbatim}
+int pmac_done(pmac_state *state, 
+              unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+This will store upto ``outlen'' bytes of the tag for the given ``state'' into ``out''.  Note that if ``outlen'' is larger
+than the size of the tag it is set to the amount of bytes stored in ``out''.
+
+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.
+
+\begin{verbatim}
+int pmac_memory(int cipher, 
+                const unsigned char *key, unsigned long keylen,
+                const unsigned char *msg, unsigned long msglen,
+                unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+This will compute the PMAC of ``msglen'' bytes of ``msg'' using the key ``key'' of length ``keylen'' bytes and the cipher
+specified by the ``cipher'''th entry in the cipher\_descriptor table.  It will store the MAC in ``out'' with the same
+rules as omac\_done.
+
+To PMAC a file use
+\begin{verbatim}
+int pmac_file(int cipher, 
+              const unsigned char *key, unsigned long keylen,
+              const char *filename, 
+              unsigned char *out, unsigned long *outlen);
+\end{verbatim}
+
+Which will PMAC the entire contents of the file specified by ``filename'' using the key ``key'' of length ``keylen'' bytes
+and the cipher specified by the ``cipher'''th entry in the cipher\_descriptor table.  It will store the MAC in ``out'' with 
+the same rules as omac\_done.
+
+To test if the PMAC code is working there is the following function:
+\begin{verbatim}
+int pmac_test(void);
+\end{verbatim}
+Which returns {\bf CRYPT\_OK} if the code passes otherwise it returns an error code.
+
+
 \chapter{Pseudo-Random Number Generators}
 \section{Core Functions}
 
@@ -1445,19 +1535,19 @@ int main(void)
 {
    prng_state prng;
    unsigned char buf[10];
-   int errno;
+   int err;
    
    /* start it */
-   if ((errno = yarrow_start(&prng)) != CRYPT_OK) {
-      printf("Start error: %s\n", error_to_string(errno));
+   if ((err = yarrow_start(&prng)) != CRYPT_OK) {
+      printf("Start error: %s\n", error_to_string(err));
    }
    /* add entropy */
-   if ((errno = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) {
-      printf("Add_entropy error: %s\n", error_to_string(errno));
+   if ((err = yarrow_add_entropy("hello world", 11, &prng)) != CRYPT_OK) {
+      printf("Add_entropy error: %s\n", error_to_string(err));
    }
    /* ready and read */
-   if ((errno = yarrow_ready(&prng)) != CRYPT_OK) {
-      printf("Ready error: %s\n", error_to_string(errno));
+   if ((err = yarrow_ready(&prng)) != CRYPT_OK) {
+      printf("Ready error: %s\n", error_to_string(err));
    }
    printf("Read %lu bytes from yarrow\n", yarrow_read(buf, 10, &prng));
    return 0;
@@ -1504,22 +1594,22 @@ int main(void)
 {
    prng_state prng;
    unsigned char buf[32];
-   int errno;
+   int err;
 
-   if ((errno = rc4_start(&prng)) != CRYPT_OK) {
-      printf("RC4 init error: %s\n", error_to_string(errno));
+   if ((err = rc4_start(&prng)) != CRYPT_OK) {
+      printf("RC4 init error: %s\n", error_to_string(err));
       exit(-1);
    }
 
    /* use ``key'' as the key */
-   if ((errno = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) {
-      printf("RC4 add entropy error: %s\n", error_to_string(errno));
+   if ((err = rc4_add_entropy("key", 3, &prng)) != CRYPT_OK) {
+      printf("RC4 add entropy error: %s\n", error_to_string(err));
       exit(-1);
    }
 
    /* setup RC4 for use */
-   if ((errno = rc4_ready(&prng)) != CRYPT_OK) {
-      printf("RC4 ready error: %s\n", error_to_string(errno));
+   if ((err = rc4_ready(&prng)) != CRYPT_OK) {
+      printf("RC4 ready error: %s\n", error_to_string(err));
       exit(-1);
    }
 
@@ -1572,7 +1662,7 @@ int main(void)
 {
    ecc_key mykey;
    prng_state prng;
-   int errno;
+   int err;
 
    /* register yarrow */
    if (register_prng(&yarrow_desc) == -1) {
@@ -1581,14 +1671,14 @@ int main(void)
    }
 
    /* setup the PRNG */
-   if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
-      printf("Error setting up PRNG, %s\n", error_to_string(errno));
+   if ((err = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
+      printf("Error setting up PRNG, %s\n", error_to_string(err));
       return -1;
    }
 
    /* make a 192-bit ECC key */
-   if ((errno = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) {
-      printf("Error making key: %s\n", error_to_string(errno));
+   if ((err = ecc_make_key(&prng, find_prng("yarrow"), 24, &mykey)) != CRYPT_OK) {
+      printf("Error making key: %s\n", error_to_string(err));
       return -1;
    }
    return 0;
@@ -1608,7 +1698,7 @@ the previous example using this PRNG.
 int main(void)
 {
    ecc_key mykey;
-   int errno;
+   int err;
 
    /* register SPRNG */
    if (register_prng(&sprng_desc) == -1) {
@@ -1617,8 +1707,8 @@ int main(void)
    }
 
    /* make a 192-bit ECC key */
-   if ((errno = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) {
-      printf("Error making key: %s\n", error_to_string(errno));
+   if ((err = ecc_make_key(NULL, find_prng("sprng"), 24, &mykey)) != CRYPT_OK) {
+      printf("Error making key: %s\n", error_to_string(err));
       return -1;
    }
    return 0;
@@ -1873,18 +1963,18 @@ int establish_secure_socket(int sock, int mode, unsigned char *key,
 {
    unsigned char buf[4096], buf2[4096];
    unsigned long x, len;
-   int res, errno, inlen;
+   int res, err, inlen;
    dh_key mykey, theirkey;
 
    /* make up our private key */
-   if ((errno = dh_make_key(prng, wprng, 128, &mykey)) != CRYPT_OK)  {
-      return errno;
+   if ((err = dh_make_key(prng, wprng, 128, &mykey)) != CRYPT_OK)  {
+      return err;
    }
 
    /* export our key as public */ 
    x = sizeof(buf);
-   if ((errno = dh_export(buf, &x, PK_PUBLIC, &mykey)) != CRYPT_OK) {
-      res = errno;
+   if ((err = dh_export(buf, &x, PK_PUBLIC, &mykey)) != CRYPT_OK) {
+      res = err;
       goto done2;
    }
 
@@ -1913,22 +2003,22 @@ int establish_secure_socket(int sock, int mode, unsigned char *key,
       }
    }
 
-   if ((errno = dh_import(buf2, inlen, &theirkey)) != CRYPT_OK) { 
-      res = errno;
+   if ((err = dh_import(buf2, inlen, &theirkey)) != CRYPT_OK) { 
+      res = err;
       goto done2;
    }
 
    /* make shared secret */
    x = sizeof(buf);
-   if ((errno = dh_shared_secret(&mykey, &theirkey, buf, &x)) != CRYPT_OK) {
-      res = errno;
+   if ((err = dh_shared_secret(&mykey, &theirkey, buf, &x)) != CRYPT_OK) {
+      res = err;
       goto done;
    }
  
    /* hash it */
    len = 16;        /* default is MD5 so "key" must be at least 16 bytes long */
-   if ((errno = hash_memory(find_hash("md5"), buf, x, key, &len)) != CRYPT_OK) {
-      res = errno;
+   if ((err = hash_memory(find_hash("md5"), buf, x, key, &len)) != CRYPT_OK) {
+      res = err;
       goto done;
    }
 
@@ -2382,26 +2472,26 @@ int main(void)
    pk_key *kr;
    unsigned char buf[4096], buf2[4096];
    unsigned long len;
-   int errno;
+   int err;
 
    /* make a new list */
-   if ((errno = kr_init(&kr)) != CRYPT_OK) {
-      printf("kr_init: %s\n", error_to_string(errno));
+   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 ((errno = kr_make_key(kr, NULL, find_prng("sprng"), RSA_KEY, 128, 
+   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(errno));
+      printf("kr_make_key: %s\n", error_to_string(err));
       exit(-1);
    }
 
    /* export the first key */
    len = sizeof(buf);
-   if ((errno = kr_export(kr, kr->ID, PK_PRIVATE, buf, &len)) != CRYPT_OK) {
-      printf("kr_export: %s\n", error_to_string(errno));
+   if ((err = kr_export(kr, kr->ID, PK_PRIVATE, buf, &len)) != CRYPT_OK) {
+      printf("kr_export: %s\n", error_to_string(err));
       exit(-1);
    }
 

+ 37 - 11
demos/hashsum.c

@@ -66,15 +66,41 @@ int main(int argc, char **argv)
 
 void register_algs(void)
 {
-   register_hash(&sha512_desc);
-   register_hash(&sha384_desc);
-   register_hash(&sha256_desc);
-   register_hash(&sha1_desc);
-   register_hash(&md5_desc);
-   register_hash(&md4_desc);
-   register_hash(&tiger_desc);
-   register_hash(&md2_desc);
-   register_hash(&rmd128_desc);
-   register_hash(&rmd160_desc);
-   register_hash(&sha224_desc);
+#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 SHA224
+  register_hash (&sha224_desc);
+#endif
+#ifdef SHA256
+  register_hash (&sha256_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
+
 }

+ 9 - 1
demos/test.c

@@ -509,7 +509,7 @@ pad_test (void)
 void
 rsa_test (void)
 {
-  unsigned char in[4096], out[4096];
+  unsigned char in[520], out[520];
   unsigned long x, y, z, limit;
   int     stat;
   rsa_key key;
@@ -1375,6 +1375,9 @@ register_all_algs (void)
 #ifdef RIPEMD160
   register_hash (&rmd160_desc);
 #endif
+#ifdef WHIRLPOOL
+  register_hash (&whirlpool_desc);
+#endif
 
 #ifdef YARROW
   register_prng (&yarrow_desc);
@@ -1842,6 +1845,11 @@ main (void)
   if (omac_test() != CRYPT_OK) exit(EXIT_FAILURE);
 #endif
 
+#ifdef PMAC
+  printf ("PMAC: %s\n", pmac_test () == CRYPT_OK ? "passed" : "failed");
+  if (pmac_test() != CRYPT_OK) exit(EXIT_FAILURE);
+#endif
+
 #ifdef EAX_MODE
   printf ("EAX : %s\n", eax_test () == CRYPT_OK ? "passed" : "failed");
   if (eax_test() != CRYPT_OK) exit(EXIT_FAILURE);

+ 79 - 0
demos/tv_gen.c

@@ -79,6 +79,9 @@ void reg_algs(void)
 #ifdef RIPEMD160
   register_hash (&rmd160_desc);
 #endif
+#ifdef WHIRLPOOL
+  register_hash (&whirlpool_desc);
+#endif
 }
 
 void hash_gen(void)
@@ -269,6 +272,61 @@ void omac_gen(void)
    fclose(out);
 }
 
+void pmac_gen(void)
+{
+   unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2];
+   int err, x, y, z, kl;
+   FILE *out;
+   unsigned long len;
+  
+   out = fopen("pmac_tv.txt", "w");
+
+   fprintf(out, 
+"PMAC Tests.  In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed.  The initial key is\n"
+"of the same format (length specified per cipher).  The OMAC key in step N+1 is the OMAC output of\n"
+"step N (repeated as required to fill the array).\n\n");
+
+   for (x = 0; cipher_descriptor[x].name != NULL; x++) {
+      kl = cipher_descriptor[x].block_length;
+
+      /* skip ciphers which do not have 64 or 128 bit block sizes */
+      if (kl != 8 && kl != 16) continue;
+
+      if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
+         kl = cipher_descriptor[x].max_key_length;
+      }
+      fprintf(out, "PMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
+      
+      /* initial key/block */
+      for (y = 0; y < kl; y++) {
+          key[y] = (y & 255);
+      }
+      
+      for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) {
+         for (z = 0; z < y; z++) {
+            input[z] = (unsigned char)(z & 255);
+         }
+         len = sizeof(output);
+         if ((err = pmac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) {
+            printf("Error omacing: %s\n", error_to_string(err));
+            exit(EXIT_FAILURE);
+         }
+         fprintf(out, "%3d: ", y);
+         for (z = 0; z <(int)len; z++) {
+            fprintf(out, "%02X", output[z]);
+         }
+         fprintf(out, "\n");
+
+         /* forward the key */
+         for (z = 0; z < kl; z++) {
+             key[z] = output[z % len];
+         }
+      }
+      fprintf(out, "\n");
+   }
+   fclose(out);
+}
+
 void eax_gen(void)
 {
    int err, kl, x, y1, z;
@@ -392,6 +450,25 @@ void ocb_gen(void)
    fclose(out);
 }
 
+void base64_gen(void)
+{
+   FILE *out;
+   unsigned char dst[256], src[32];
+   unsigned long x, y, len;
+   
+   out = fopen("base64_tv.txt", "w");
+   fprintf(out, "Base64 vectors.  These are the base64 encodings of the strings 00,01,02...NN-1\n\n");
+   for (x = 0; x <= 32; x++) {
+       for (y = 0; y < x; y++) {
+           src[y] = y;
+       }
+       len = sizeof(dst);
+       base64_encode(src, x, dst, &len);
+       fprintf(out, "%2lu: %s\n", x, dst);
+   }
+   fclose(out);
+}
+
 int main(void)
 {
    reg_algs();
@@ -399,8 +476,10 @@ int main(void)
    printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n");
    printf("Generating HMAC   vectors..."); fflush(stdout); hmac_gen(); printf("done\n");
    printf("Generating OMAC   vectors..."); fflush(stdout); omac_gen(); printf("done\n");
+   printf("Generating PMAC   vectors..."); fflush(stdout); pmac_gen(); printf("done\n");
    printf("Generating EAX    vectors..."); fflush(stdout); eax_gen(); printf("done\n");
    printf("Generating OCB    vectors..."); fflush(stdout); ocb_gen(); printf("done\n");
+   printf("Generating BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n");
    return 0;
 }
 

+ 5 - 2
demos/x86_prof.c

@@ -52,9 +52,9 @@ void tally_results(int type)
 static ulong64 rdtsc (void)
    {
    #if defined __GNUC__
-      #ifdef i386
+      #ifdef __i386__
          ulong64 a;
-         asm volatile("rdtsc ":"=A" (a));
+         __asm__ __volatile__ ("rdtsc ":"=A" (a));
          return a;
       #else /* gcc-IA64 version */
          unsigned long result;
@@ -190,6 +190,9 @@ void reg_algs(void)
 #ifdef RIPEMD160
   register_hash (&rmd160_desc);
 #endif
+#ifdef WHIRLPOOL
+  register_hash (&whirlpool_desc);
+#endif
 
 register_prng(&yarrow_desc);
 rng_make_prng(128, find_prng("yarrow"), &prng, NULL);

+ 53 - 63
dh.c

@@ -157,48 +157,48 @@ static int is_valid_idx(int n)
 int dh_test(void)
 {
     mp_int p, g, tmp;
-    int x, res, primality;
+    int x, err, primality;
 
-    if ((res = mp_init_multi(&p, &g, &tmp, NULL)) != MP_OKAY)                 { goto error; }
+    if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != MP_OKAY)                 { goto error; }
 
     for (x = 0; sets[x].size != 0; x++) {
 #if 0
         printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
 #endif
-        if ((res = mp_read_radix(&g,(char *)sets[x].base, 64)) != MP_OKAY)    { goto error; }
-        if ((res = mp_read_radix(&p,(char *)sets[x].prime, 64)) != MP_OKAY)   { goto error; }
+        if ((err = mp_read_radix(&g,(char *)sets[x].base, 64)) != MP_OKAY)    { goto error; }
+        if ((err = mp_read_radix(&p,(char *)sets[x].prime, 64)) != MP_OKAY)   { goto error; }
 
         /* ensure p is prime */
-        if ((res = is_prime(&p, &primality)) != CRYPT_OK)                     { goto done; }
+        if ((err = is_prime(&p, &primality)) != CRYPT_OK)                     { goto done; }
         if (primality == 0) {
-           res = CRYPT_FAIL_TESTVECTOR;
+           err = CRYPT_FAIL_TESTVECTOR;
            goto done;
         }
 
-        if ((res = mp_sub_d(&p, 1, &tmp)) != MP_OKAY)                         { goto error; }
-        if ((res = mp_div_2(&tmp, &tmp)) != MP_OKAY)                          { goto error; }
+        if ((err = mp_sub_d(&p, 1, &tmp)) != MP_OKAY)                         { goto error; }
+        if ((err = mp_div_2(&tmp, &tmp)) != MP_OKAY)                          { goto error; }
 
         /* ensure (p-1)/2 is prime */
-        if ((res = is_prime(&tmp, &primality)) != CRYPT_OK)                   { goto done; }
+        if ((err = is_prime(&tmp, &primality)) != CRYPT_OK)                   { goto done; }
         if (primality == 0) {
-           res = CRYPT_FAIL_TESTVECTOR;
+           err = CRYPT_FAIL_TESTVECTOR;
            goto done;
         }
 
         /* now see if g^((p-1)/2) mod p is in fact 1 */
-        if ((res = mp_exptmod(&g, &tmp, &p, &tmp)) != MP_OKAY)                { goto error; }
+        if ((err = mp_exptmod(&g, &tmp, &p, &tmp)) != MP_OKAY)                { goto error; }
         if (mp_cmp_d(&tmp, 1)) {
-           res = CRYPT_FAIL_TESTVECTOR;
+           err = CRYPT_FAIL_TESTVECTOR;
            goto done;
         }
     }
-    res = CRYPT_OK;
+    err = CRYPT_OK;
     goto done;
 error:
-    res = mpi_to_ltc_error(res);
+    err = mpi_to_ltc_error(err);
 done:
     mp_clear_multi(&tmp, &g, &p, NULL);
-    return res;
+    return err;
 }
 
 void dh_sizes(int *low, int *high)
@@ -229,7 +229,7 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
    unsigned char buf[512];
    unsigned long x;
    mp_int p, g;
-   int res, err;
+   int err;
 
    _ARGCHK(key  != NULL);
 
@@ -257,30 +257,30 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
    }
 
    /* init parameters */
-   if ((res = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != MP_OKAY) {
-      return mpi_to_ltc_error(res);
+   if ((err = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
-   if ((res = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY)      { goto error; }
-   if ((res = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY)     { goto error; }
+   if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY)      { goto error; }
+   if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY)     { goto error; }
 
    /* load the x value */
-   if ((res = mp_read_unsigned_bin(&key->x, buf, keysize)) != MP_OKAY)     { goto error; }
-   if ((res = mp_exptmod(&g, &key->x, &p, &key->y)) != MP_OKAY)            { goto error; }
+   if ((err = mp_read_unsigned_bin(&key->x, buf, keysize)) != MP_OKAY)     { goto error; }
+   if ((err = mp_exptmod(&g, &key->x, &p, &key->y)) != MP_OKAY)            { goto error; }
    key->type = PK_PRIVATE;
 
-   if ((res = mp_shrink(&key->x)) != MP_OKAY)                              { goto error; }
-   if ((res = mp_shrink(&key->y)) != MP_OKAY)                              { goto error; }
+   if ((err = mp_shrink(&key->x)) != MP_OKAY)                              { goto error; }
+   if ((err = mp_shrink(&key->y)) != MP_OKAY)                              { goto error; }
 
    /* free up ram */
-   res = CRYPT_OK;
-   goto done2;
+   err = CRYPT_OK;
+   goto done;
 error:
-   res = mpi_to_ltc_error(res);
+   err = mpi_to_ltc_error(err);
    mp_clear_multi(&key->x, &key->y, NULL);
-done2:
+done:
    mp_clear_multi(&p, &g, NULL);
    zeromem(buf, sizeof(buf));
-   return res;
+   return err;
 }
 
 void dh_free(dh_key *key)
@@ -291,7 +291,6 @@ void dh_free(dh_key *key)
 
 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
 {
-   unsigned char buf2[1536];
    unsigned long y, z;
    int err;
 
@@ -299,6 +298,11 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
    _ARGCHK(outlen != NULL);
    _ARGCHK(key != NULL);
 
+   /* can we store the static header?  */
+   if (*outlen < (PACKET_SIZE + 2)) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   
    if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
       return CRYPT_PK_NOT_PRIVATE;
    }
@@ -307,36 +311,22 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
    y = PACKET_SIZE;
 
    /* header */
-   buf2[y++] = type;
-   buf2[y++] = (unsigned char)(sets[key->idx].size / 8);
+   out[y++] = type;
+   out[y++] = (unsigned char)(sets[key->idx].size / 8);
 
    /* export y */
-   OUTPUT_BIGNUM(&key->y, buf2, y, z);
+   OUTPUT_BIGNUM(&key->y, out, y, z);
 
    if (type == PK_PRIVATE) {
       /* export x */
-      OUTPUT_BIGNUM(&key->x, buf2, y, z);
-   }
-
-   /* check for overflow */
-   if (*outlen < y) {
-      #ifdef CLEAN_STACK
-         zeromem(buf2, sizeof(buf2));
-      #endif
-      return CRYPT_BUFFER_OVERFLOW;
+      OUTPUT_BIGNUM(&key->x, out, y, z);
    }
 
    /* store header */
-   packet_store_header(buf2, PACKET_SECT_DH, PACKET_SUB_KEY);
+   packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_KEY);
 
-   /* output it */
+   /* store len */
    *outlen = y;
-   memcpy(out, buf2, (size_t)y);
-
-   /* clear mem */
-#ifdef CLEAN_STACK
-   zeromem(buf2, sizeof(buf2));
-#endif
    return CRYPT_OK;
 }
 
@@ -349,7 +339,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
    _ARGCHK(key != NULL);
 
    /* make sure valid length */
-   if (2+PACKET_SIZE > inlen) {
+   if ((2+PACKET_SIZE) > inlen) {
       return CRYPT_INVALID_PACKET;
    }
 
@@ -414,12 +404,12 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
 {
    mp_int tmp, p;
    unsigned long x;
-   int res;
+   int err;
 
    _ARGCHK(private_key != NULL);
    _ARGCHK(public_key  != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
+   _ARGCHK(out         != NULL);
+   _ARGCHK(outlen      != NULL);
 
    /* types valid? */
    if (private_key->type != PK_PRIVATE) {
@@ -432,28 +422,28 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
    }
 
    /* compute y^x mod p */
-   if (mp_init_multi(&tmp, &p, NULL) != MP_OKAY) {
-      return CRYPT_MEM;
+   if ((err = mp_init_multi(&tmp, &p, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
 
-   if (mp_read_radix(&p, (char *)sets[private_key->idx].prime, 64) != MP_OKAY)     { goto error; }
-   if (mp_exptmod(&public_key->y, &private_key->x, &p, &tmp) != MP_OKAY)           { goto error; }
+   if ((err = mp_read_radix(&p, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY)     { goto error; }
+   if ((err = mp_exptmod(&public_key->y, &private_key->x, &p, &tmp)) != MP_OKAY)           { goto error; }
 
    /* enough space for output? */
    x = (unsigned long)mp_unsigned_bin_size(&tmp);
    if (*outlen < x) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done;
    }
-   if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)                                   { goto error; }
+   if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY)                                   { goto error; }
    *outlen = x;
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&p, &tmp, NULL);
-   return res;
+   return err;
 }
 
 #include "dh_sys.c"

+ 48 - 48
dh_sys.c

@@ -19,9 +19,9 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     int err;
 
     _ARGCHK(inkey != NULL);
-    _ARGCHK(out != NULL);
-    _ARGCHK(len != NULL);
-    _ARGCHK(key != NULL);
+    _ARGCHK(out   != NULL);
+    _ARGCHK(len   != NULL);
+    _ARGCHK(key   != NULL);
 
     /* check that wprng/hash are not invalid */
     if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
@@ -68,6 +68,9 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
        return err;
     }
 
+    /* store header */
+    packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
+
     /* output header */
     y = PACKET_SIZE;
 
@@ -88,9 +91,7 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     for (x = 0; x < keylen; x++, y++) {
       out[y] = skey[x] ^ inkey[x];
     }
-
-    /* store header */
-    packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
+    *len = y;
 
 #ifdef CLEAN_STACK
     /* clean up */
@@ -99,7 +100,6 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     zeromem(skey, sizeof(skey));
 #endif
 
-    *len = y;
     return CRYPT_OK;
 }
 
@@ -109,13 +109,13 @@ int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
 {
    unsigned char shared_secret[768], skey[MAXBLOCKSIZE];
    unsigned long x, y, z,hashsize, keysize;
-   int res, hash, err;
+   int  hash, err;
    dh_key pubkey;
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in     != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(keylen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
    /* right key type? */
    if (key->type != PK_PRIVATE) {
@@ -184,7 +184,7 @@ int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
    }
    
    if (keysize > *keylen) {
-       res = CRYPT_BUFFER_OVERFLOW;
+       err = CRYPT_BUFFER_OVERFLOW;
        goto done;
    }
    y += 4;
@@ -195,13 +195,13 @@ int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
       outkey[x] = skey[x] ^ in[y];
    }
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
 done:
 #ifdef CLEAN_STACK
    zeromem(shared_secret, sizeof(shared_secret));
    zeromem(skey, sizeof(skey));
 #endif
-   return res;
+   return err;
 }
 
 /* perform an ElGamal Signature of a hash 
@@ -227,14 +227,14 @@ int dh_sign_hash(const unsigned char *in,  unsigned long inlen,
                        prng_state *prng, int wprng, dh_key *key)
 {
    mp_int a, b, k, m, g, p, p1, tmp;
-   unsigned char buf[1536];
+   unsigned char buf[520];
    unsigned long x, y;
-   int res, err;
+   int err;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
    /* check parameters */
    if (key->type != PK_PRIVATE) {
@@ -286,44 +286,44 @@ int dh_sign_hash(const unsigned char *in,  unsigned long inlen,
    if ((err = mp_mulmod(&a, &key->x, &p1, &tmp)) != MP_OKAY)                        { goto error; } /* tmp = xa */
    if ((err = mp_submod(&m, &tmp, &p1, &tmp)) != MP_OKAY)                           { goto error; } /* tmp = M - xa */
    if ((err = mp_mulmod(&k, &tmp, &p1, &b)) != MP_OKAY)                             { goto error; } /* b = (M - xa)/k */
-
+   
+   /* check for overflow */
+   if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(&a) + mp_unsigned_bin_size(&b)) > *outlen) {
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto done;
+   }
+   
    /* store header  */
    y = PACKET_SIZE;
 
    /* now store them both (a,b) */
    x = (unsigned long)mp_unsigned_bin_size(&a);
-   STORE32L(x, buf+y);  y += 4;
-   if ((err = mp_to_unsigned_bin(&a, buf+y)) != MP_OKAY)                            { goto error; }
+   STORE32L(x, out+y);  y += 4;
+   if ((err = mp_to_unsigned_bin(&a, out+y)) != MP_OKAY)                            { goto error; }
    y += x;
 
    x = (unsigned long)mp_unsigned_bin_size(&b);
-   STORE32L(x, buf+y);  y += 4;
-   if ((err = mp_to_unsigned_bin(&b, buf+y)) != MP_OKAY)                            { goto error; }
+   STORE32L(x, out+y);  y += 4;
+   if ((err = mp_to_unsigned_bin(&b, out+y)) != MP_OKAY)                            { goto error; }
    y += x;
 
    /* check if size too big */
    if (*outlen < y) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done;
    }
 
    /* store header */
-   packet_store_header(buf, PACKET_SECT_DH, PACKET_SUB_SIGNED);
-
-   /* store it */
-   memcpy(out, buf, (size_t)y);
+   packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED);
    *outlen = y;
-#ifdef CLEAN_STACK
-   zeromem(buf, sizeof(buf));
-#endif
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = mpi_to_ltc_error(err);
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);
-   return res;
+   return err;
 }
 
 int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
@@ -332,12 +332,12 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
 {
    mp_int a, b, p, g, m, tmp;
    unsigned long x, y;
-   int res, err;
+   int err;
 
-   _ARGCHK(sig != NULL);
+   _ARGCHK(sig  != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
    /* default to invalid */
    *stat = 0;
@@ -371,7 +371,7 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
    }
    
    y += 4;
-   if ((err = mp_read_unsigned_bin(&a, (unsigned char *)sig+y, x)) != MP_OKAY)    { goto error; }
+   if ((err = mp_read_unsigned_bin(&a, (unsigned char *)sig+y, x)) != MP_OKAY)      { goto error; }
    y += x;
 
    LOAD32L(x, sig+y);
@@ -381,23 +381,23 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
       siglen -= x;
    }
    y += 4;
-   if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, x)) != MP_OKAY)   { goto error; }
+   if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, x)) != MP_OKAY)      { goto error; }
    y += x;
 
    /* load p and g */
-   if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY)           { goto error; }
-   if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY)            { goto error; }
+   if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY)              { goto error; }
+   if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY)               { goto error; }
 
    /* load m */
    if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error; }
 
    /* find g^m mod p */
-   if ((err = mp_exptmod(&g, &m, &p, &m)) != MP_OKAY)                            { goto error; } /* m = g^m mod p */
+   if ((err = mp_exptmod(&g, &m, &p, &m)) != MP_OKAY)                { goto error; } /* m = g^m mod p */
 
    /* find y^a * a^b */
-   if ((err = mp_exptmod(&key->y, &a, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = y^a mod p */
-   if ((err = mp_exptmod(&a, &b, &p, &a)) != MP_OKAY)                            { goto error; } /* a = a^b mod p */
-   if ((err = mp_mulmod(&a, &tmp, &p, &a)) != MP_OKAY)                           { goto error; } /* a = y^a * a^b mod p */
+   if ((err = mp_exptmod(&key->y, &a, &p, &tmp)) != MP_OKAY)         { goto error; } /* tmp = y^a mod p */
+   if ((err = mp_exptmod(&a, &b, &p, &a)) != MP_OKAY)                { goto error; } /* a = a^b mod p */
+   if ((err = mp_mulmod(&a, &tmp, &p, &a)) != MP_OKAY)               { goto error; } /* a = y^a * a^b mod p */
 
    /* y^a * a^b == g^m ??? */
    if (mp_cmp(&a, &m) == 0) {
@@ -405,12 +405,12 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
    }
 
    /* clean up */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = mpi_to_ltc_error(err);
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL);
-   return res;
+   return err;
 }
 

+ 16 - 18
dsa.c

@@ -18,7 +18,6 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
    int err, res;
    unsigned char buf[512];
 
-   _ARGCHK(prng != NULL);
    _ARGCHK(key  != NULL);
 
    /* check prng */
@@ -132,11 +131,10 @@ int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
    unsigned long len;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(prng != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
       return err;
@@ -204,7 +202,7 @@ retry:
    /* store length of r */
    len = mp_unsigned_bin_size(&r);
    out[y++] = (len>>8)&255;
-   out[y++] = (len & 255);
+   out[y++] = len&255;
    
    /* store r */
    if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY)                              { goto error; }
@@ -213,7 +211,7 @@ retry:
    /* store length of s */
    len = mp_unsigned_bin_size(&s);
    out[y++] = (len>>8)&255;
-   out[y++] = (len & 255);
+   out[y++] = len&255;
    
    /* store s */
    if ((err = mp_to_unsigned_bin(&s, out+y)) != MP_OKAY)                              { goto error; }
@@ -241,10 +239,10 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
    unsigned long x, y;
    int err;
 
-   _ARGCHK(sig != NULL);
+   _ARGCHK(sig  != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
    /* default to invalid signature */
    *stat = 0;
@@ -320,10 +318,15 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key
    unsigned long y, z;
    int err;
 
-   _ARGCHK(out != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
+   /* can we store the static header?  */
+   if (*outlen < (PACKET_SIZE + 1 + 2)) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
+   
    if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
       return CRYPT_PK_TYPE_MISMATCH;
    }
@@ -332,11 +335,6 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key
       return CRYPT_INVALID_ARG;
    }
 
-   /* can we store the static header?  */
-   if (*outlen < (PACKET_SIZE + 1 + 2)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
    /* store header */
    packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY);
    y = PACKET_SIZE;
@@ -366,7 +364,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
    unsigned long x, y;
    int err;
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in  != NULL);
    _ARGCHK(key != NULL);
 
    /* check length */
@@ -410,7 +408,7 @@ int dsa_verify_key(dsa_key *key, int *stat)
    mp_int tmp, tmp2;
    int res, err;
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(stat != NULL);
 
    *stat = 0;

+ 62 - 0
eax.c

@@ -8,6 +8,8 @@
  *
  * Tom St Denis, [email protected], http://libtomcrypt.org
  */
+
+/* EAX Implementation by Tom St Denis */
 #include "mycrypt.h"
 
 #ifdef EAX_MODE
@@ -385,6 +387,66 @@ int eax_test(void)
    { 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2,
      0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda }
 },
+
+/* Vectors from Brian Gladman */
+
+{
+   16, 16, 8, 0,
+   /* key */
+   { 0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f,
+     0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78 },
+   /* nonce */
+   { 0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07,
+     0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3 },
+   /* header */
+   { 0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b },
+   /* PT */
+   { 0x00 },
+   /* CT */
+   { 0x00 },
+   /* tag */
+   { 0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b,
+     0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01 }
+},
+
+{
+   16, 16, 8, 2,
+   /* key */ 
+   { 0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b,
+     0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4 },
+   /* nonce */
+   { 0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84,
+     0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd },
+   /* header */
+   { 0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa },
+   /* PT */
+   { 0xf7, 0xfb },
+   /* CT */
+   { 0x19, 0xdd },
+   /* tag */
+   { 0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda,
+     0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5 }
+},
+
+{
+   16, 16, 8, 5,
+   /* key */
+   { 0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7,
+     0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23 },
+   /* nonce */
+   { 0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84,
+     0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e },
+   /* header */
+   { 0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6 },
+   /* PT */
+   { 0x1a, 0x47, 0xcb, 0x49, 0x33 },
+   /* CT */
+   { 0xd8, 0x51, 0xd5, 0xba, 0xe0 },
+   /* Tag */
+   { 0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19,
+     0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80 }
+}   
+
 };
    int err, x, idx, res;
    unsigned long len;

+ 178 - 192
ecc.c

@@ -247,9 +247,7 @@ static ecc_point *new_point(void)
 static void del_point(ecc_point *p)
 {
    /* prevents free'ing null arguments */
-   if (p == NULL) {
-      return;
-   } else {
+   if (p != NULL) {
       mp_clear_multi(&p->x, &p->y, NULL);
       XFREE(p);
    }
@@ -259,60 +257,60 @@ static void del_point(ecc_point *p)
 static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu)
 {
    mp_int s, tmp, tmpx;
-   int res;
+   int err;
 
-   if ((res = mp_init_multi(&s, &tmp, &tmpx, NULL)) != MP_OKAY) {
-      return mpi_to_ltc_error(res);
+   if ((err = mp_init_multi(&s, &tmp, &tmpx, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
 
    /* s = (3Xp^2 + a) / (2Yp) */
-   if ((res = mp_mul_2(&P->y, &tmp)) != MP_OKAY)                   { goto error; } /* tmp = 2*y */
-   if ((res = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY)          { goto error; } /* tmp = 1/tmp mod modulus */
-   if ((res = mp_sqr(&P->x, &s)) != MP_OKAY)                       { goto error; } /* s = x^2  */
-   if ((res = mp_reduce(&s, modulus, mu)) != MP_OKAY)              { goto error; }
-   if ((res = mp_mul_d(&s,(mp_digit)3, &s)) != MP_OKAY)            { goto error; } /* s = 3*(x^2) */
-   if ((res = mp_sub_d(&s,(mp_digit)3, &s)) != MP_OKAY)            { goto error; } /* s = 3*(x^2) - 3 */
+   if ((err = mp_mul_2(&P->y, &tmp)) != MP_OKAY)                   { goto error; } /* tmp = 2*y */
+   if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY)          { goto error; } /* tmp = 1/tmp mod modulus */
+   if ((err = mp_sqr(&P->x, &s)) != MP_OKAY)                       { goto error; } /* s = x^2  */
+   if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY)              { goto error; }
+   if ((err = mp_mul_d(&s,(mp_digit)3, &s)) != MP_OKAY)            { goto error; } /* s = 3*(x^2) */
+   if ((err = mp_sub_d(&s,(mp_digit)3, &s)) != MP_OKAY)            { goto error; } /* s = 3*(x^2) - 3 */
    if (mp_cmp_d(&s, 0) == MP_LT) {                                         /* if s < 0 add modulus */
-      if ((res = mp_add(&s, modulus, &s)) != MP_OKAY)              { goto error; }
+      if ((err = mp_add(&s, modulus, &s)) != MP_OKAY)              { goto error; }
    }
-   if ((res = mp_mul(&s, &tmp, &s)) != MP_OKAY)                    { goto error; } /* s = tmp * s mod modulus */
-   if ((res = mp_reduce(&s, modulus, mu)) != MP_OKAY)              { goto error; }
+   if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY)                    { goto error; } /* s = tmp * s mod modulus */
+   if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY)              { goto error; }
 
    /* Xr = s^2 - 2Xp */
-   if ((res = mp_sqr(&s,  &tmpx)) != MP_OKAY)                      { goto error; } /* tmpx = s^2  */
-   if ((res = mp_reduce(&tmpx, modulus, mu)) != MP_OKAY)           { goto error; } /* tmpx = tmpx mod modulus */
-   if ((res = mp_sub(&tmpx, &P->x, &tmpx)) != MP_OKAY)             { goto error; } /* tmpx = tmpx - x */
-   if ((res = mp_submod(&tmpx, &P->x, modulus, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */
+   if ((err = mp_sqr(&s,  &tmpx)) != MP_OKAY)                      { goto error; } /* tmpx = s^2  */
+   if ((err = mp_reduce(&tmpx, modulus, mu)) != MP_OKAY)           { goto error; } /* tmpx = tmpx mod modulus */
+   if ((err = mp_sub(&tmpx, &P->x, &tmpx)) != MP_OKAY)             { goto error; } /* tmpx = tmpx - x */
+   if ((err = mp_submod(&tmpx, &P->x, modulus, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */
 
    /* Yr = -Yp + s(Xp - Xr)  */
-   if ((res = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY)              { goto error; } /* tmp = x - tmpx */
-   if ((res = mp_mul(&tmp, &s, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp * s */
-   if ((res = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY)  { goto error; } /* y = tmp - y mod modulus */
-   if ((res = mp_copy(&tmpx, &R->x)) != MP_OKAY)                   { goto error; } /* x = tmpx */
+   if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY)              { goto error; } /* tmp = x - tmpx */
+   if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp * s */
+   if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY)  { goto error; } /* y = tmp - y mod modulus */
+   if ((err = mp_copy(&tmpx, &R->x)) != MP_OKAY)                   { goto error; } /* x = tmpx */
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = mpi_to_ltc_error(res);
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&tmpx, &tmp, &s, NULL);
-   return res;
+   return err;
 }
 
 /* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */
 static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu)
 {
    mp_int s, tmp, tmpx;
-   int res;
+   int err;
 
-   if ((res = mp_init(&tmp)) != MP_OKAY) {
-      return mpi_to_ltc_error(res);
+   if ((err = mp_init(&tmp)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
 
    /* is P==Q or P==-Q? */
-   if (((res = mp_neg(&Q->y, &tmp)) != MP_OKAY) || ((res = mp_mod(&tmp, modulus, &tmp)) != MP_OKAY)) {
+   if (((err = mp_neg(&Q->y, &tmp)) != MP_OKAY) || ((err = mp_mod(&tmp, modulus, &tmp)) != MP_OKAY)) {
       mp_clear(&tmp);
-      return mpi_to_ltc_error(res);
+      return mpi_to_ltc_error(err);
    }
 
    if (mp_cmp(&P->x, &Q->x) == MP_EQ)
@@ -321,43 +319,43 @@ static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus,
          return dbl_point(P, R, modulus, mu);
       }
 
-   if ((res = mp_init_multi(&tmpx, &s, NULL)) != MP_OKAY) {
+   if ((err = mp_init_multi(&tmpx, &s, NULL)) != MP_OKAY) {
       mp_clear(&tmp);
-      return mpi_to_ltc_error(res);
+      return mpi_to_ltc_error(err);
    }
 
    /* get s = (Yp - Yq)/(Xp-Xq) mod p */
-   if ((res = mp_sub(&P->x, &Q->x, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = Px - Qx mod modulus */
+   if ((err = mp_sub(&P->x, &Q->x, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = Px - Qx mod modulus */
    if (mp_cmp_d(&tmp, 0) == MP_LT) {                                          /* if tmp<0 add modulus */
-      if ((res = mp_add(&tmp, modulus, &tmp)) != MP_OKAY)             { goto error; }
+      if ((err = mp_add(&tmp, modulus, &tmp)) != MP_OKAY)             { goto error; }
    }
-   if ((res = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY)             { goto error; } /* tmp = 1/tmp mod modulus */
-   if ((res = mp_sub(&P->y, &Q->y, &s)) != MP_OKAY)                   { goto error; } /* s = Py - Qy mod modulus */
+   if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY)             { goto error; } /* tmp = 1/tmp mod modulus */
+   if ((err = mp_sub(&P->y, &Q->y, &s)) != MP_OKAY)                   { goto error; } /* s = Py - Qy mod modulus */
    if (mp_cmp_d(&s, 0) == MP_LT) {                                            /* if s<0 add modulus */
-      if ((res = mp_add(&s, modulus, &s)) != MP_OKAY)                 { goto error; }
+      if ((err = mp_add(&s, modulus, &s)) != MP_OKAY)                 { goto error; }
    }
-   if ((res = mp_mul(&s, &tmp, &s)) != MP_OKAY)                       { goto error; } /* s = s * tmp mod modulus */
-   if ((res = mp_reduce(&s, modulus, mu)) != MP_OKAY)                 { goto error; }
+   if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY)                       { goto error; } /* s = s * tmp mod modulus */
+   if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY)                 { goto error; }
 
    /* Xr = s^2 - Xp - Xq */
-   if ((res = mp_sqr(&s, &tmp)) != MP_OKAY)                           { goto error; } /* tmp = s^2 mod modulus */
-   if ((res = mp_reduce(&tmp, modulus, mu)) != MP_OKAY)               { goto error; }
-   if ((res = mp_sub(&tmp, &P->x, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp - Px */
-   if ((res = mp_sub(&tmp, &Q->x, &tmpx)) != MP_OKAY)                 { goto error; } /* tmpx = tmp - Qx */
+   if ((err = mp_sqr(&s, &tmp)) != MP_OKAY)                           { goto error; } /* tmp = s^2 mod modulus */
+   if ((err = mp_reduce(&tmp, modulus, mu)) != MP_OKAY)               { goto error; }
+   if ((err = mp_sub(&tmp, &P->x, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp - Px */
+   if ((err = mp_sub(&tmp, &Q->x, &tmpx)) != MP_OKAY)                 { goto error; } /* tmpx = tmp - Qx */
 
    /* Yr = -Yp + s(Xp - Xr) */
-   if ((res = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = Px - tmpx */
-   if ((res = mp_mul(&tmp, &s, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp * s */
-   if ((res = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY)     { goto error; } /* Ry = tmp - Py mod modulus */
-   if ((res = mp_mod(&tmpx, modulus, &R->x)) != MP_OKAY)              { goto error; } /* Rx = tmpx mod modulus */
+   if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = Px - tmpx */
+   if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp * s */
+   if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY)     { goto error; } /* Ry = tmp - Py mod modulus */
+   if ((err = mp_mod(&tmpx, modulus, &R->x)) != MP_OKAY)              { goto error; } /* Rx = tmpx mod modulus */
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = mpi_to_ltc_error(res);
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&s, &tmpx, &tmp, NULL);
-   return res;
+   return err;
 }
 
 /* size of sliding window, don't change this! */
@@ -367,18 +365,18 @@ done:
 static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
 {
    ecc_point *tG, *M[8];
-   int i, j, res;
+   int i, j, err;
    mp_int mu;
    mp_digit buf;
    int     first, bitbuf, bitcpy, bitcnt, mode, digidx;
 
   /* init barrett reduction */
-  if ((res = mp_init(&mu)) != MP_OKAY) {
-      return mpi_to_ltc_error(res);
+  if ((err = mp_init(&mu)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
   }
-  if ((res = mp_reduce_setup(&mu, modulus)) != MP_OKAY) {
+  if ((err = mp_reduce_setup(&mu, modulus)) != MP_OKAY) {
       mp_clear(&mu);
-      return mpi_to_ltc_error(res);
+      return mpi_to_ltc_error(err);
   }
 
   /* alloc ram for window temps */
@@ -395,23 +393,23 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
 
    /* make a copy of G incase R==G */
    tG = new_point();
-   if (tG == NULL)                                                    { goto error; }
+   if (tG == NULL)                                                            { err = CRYPT_MEM; goto done; }
 
+   /* tG = G */
+   if ((err = mp_copy(&G->x, &tG->x)) != MP_OKAY)                             { goto error; }
+   if ((err = mp_copy(&G->y, &tG->y)) != MP_OKAY)                             { goto error; }
+   
    /* calc the M tab, which holds kG for k==8..15 */
    /* M[0] == 8G */
-   if (dbl_point(G, M[0], modulus, &mu) != CRYPT_OK)                  { goto error; }
-   if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK)               { goto error; }
-   if (dbl_point(M[0], M[0], modulus, &mu) != CRYPT_OK)               { goto error; }
+   if ((err = dbl_point(G, M[0], modulus, &mu)) != CRYPT_OK)                  { goto done; }
+   if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK)               { goto done; }
+   if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK)               { goto done; }
 
    /* now find (8+k)G for k=1..7 */
    for (j = 9; j < 16; j++) {
-       if (add_point(M[j-9], G, M[j-8], modulus, &mu) != CRYPT_OK)    { goto error; }
+       if ((err = add_point(M[j-9], G, M[j-8], modulus, &mu)) != CRYPT_OK)    { goto done; }
    }
 
-   /* tG = G */
-   if (mp_copy(&G->x, &tG->x) != MP_OKAY)                             { goto error; }
-   if (mp_copy(&G->y, &tG->y) != MP_OKAY)                             { goto error; }
-
    /* setup sliding window */
    mode   = 0;
    bitcnt = 1;
@@ -442,7 +440,7 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
 
      /* if the bit is zero and mode == 1 then we double */
      if (mode == 1 && i == 0) {
-        if (dbl_point(R, R, modulus, &mu) != CRYPT_OK)                          { goto error; }
+        if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK)                { goto done; }
         continue;
      }
 
@@ -454,19 +452,19 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
        /* if this is the first window we do a simple copy */
        if (first == 1) {
           /* R = kG [k = first window] */
-          if (mp_copy(&M[bitbuf-8]->x, &R->x) != MP_OKAY)                       { goto error; }
-          if (mp_copy(&M[bitbuf-8]->y, &R->y) != MP_OKAY)                       { goto error; }
+          if ((err = mp_copy(&M[bitbuf-8]->x, &R->x)) != MP_OKAY)             { goto error; }
+          if ((err = mp_copy(&M[bitbuf-8]->y, &R->y)) != MP_OKAY)             { goto error; }
           first = 0;
        } else {
          /* normal window */
          /* ok window is filled so double as required and add  */
          /* double first */
          for (j = 0; j < WINSIZE; j++) {
-           if (dbl_point(R, R, modulus, &mu) != CRYPT_OK)                       { goto error; }
+           if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK)             { goto done; }
          }
 
          /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
-         if (add_point(R, M[bitbuf-8], R, modulus, &mu) != CRYPT_OK)            { goto error; }
+         if ((err = add_point(R, M[bitbuf-8], R, modulus, &mu)) != CRYPT_OK)  { goto done; }
        }
        /* empty window and reset */
        bitcpy = bitbuf = 0;
@@ -480,34 +478,34 @@ static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
      for (j = 0; j < bitcpy; j++) {
        /* only double if we have had at least one add first */
        if (first == 0) {
-          if (dbl_point(R, R, modulus, &mu) != CRYPT_OK)                       { goto error; }
+          if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK)               { goto done; }
        }
 
        bitbuf <<= 1;
        if ((bitbuf & (1 << WINSIZE)) != 0) {
          if (first == 1){
             /* first add, so copy */
-            if (mp_copy(&tG->x, &R->x) != MP_OKAY)                             { goto error; }
-            if (mp_copy(&tG->y, &R->y) != MP_OKAY)                             { goto error; }
+            if ((err = mp_copy(&tG->x, &R->x)) != MP_OKAY)                     { goto error; }
+            if ((err = mp_copy(&tG->y, &R->y)) != MP_OKAY)                     { goto error; }
             first = 0;
          } else {
             /* then add */
-            if (add_point(R, tG, R, modulus, &mu) != CRYPT_OK)                 { goto error; }
+            if ((err = add_point(R, tG, R, modulus, &mu)) != CRYPT_OK)         { goto done; }
          }
        }
      }
    }
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
    del_point(tG);
    for (i = 0; i < 8; i++) {
        del_point(M[i]);
    }
    mp_clear(&mu);
-   return res;
+   return err;
 }
 
 #undef WINSIZE
@@ -516,22 +514,18 @@ int ecc_test(void)
 {
    mp_int     modulus, order;
    ecc_point  *G, *GG;
-   int i, res, primality;
+   int i, err, primality;
 
-   if (mp_init_multi(&modulus, &order, NULL) != MP_OKAY) {
-      return CRYPT_MEM;
+   if ((err = mp_init_multi(&modulus, &order, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
 
    G   = new_point();
-   if (G == NULL) {
-      mp_clear_multi(&modulus, &order, NULL);
-      return CRYPT_MEM;
-   }
-
    GG  = new_point();
-   if (GG == NULL) {
+   if (G == NULL || GG == NULL) {
       mp_clear_multi(&modulus, &order, NULL);
       del_point(G);
+      del_point(GG);
       return CRYPT_MEM;
    }
 
@@ -539,43 +533,43 @@ int ecc_test(void)
        #if 0
           printf("Testing %d\n", sets[i].size);
        #endif
-       if (mp_read_radix(&modulus, (char *)sets[i].prime, 64) != MP_OKAY)   { goto error; }
-       if (mp_read_radix(&order, (char *)sets[i].order, 64) != MP_OKAY)     { goto error; }
+       if ((err = mp_read_radix(&modulus, (char *)sets[i].prime, 64)) != MP_OKAY)   { goto error; }
+       if ((err = mp_read_radix(&order, (char *)sets[i].order, 64)) != MP_OKAY)     { goto error; }
 
        /* is prime actually prime? */
-       if (is_prime(&modulus, &primality) != CRYPT_OK)           { goto error; }
+       if ((err = is_prime(&modulus, &primality)) != CRYPT_OK)                      { goto done; }
        if (primality == 0) {
-          res = CRYPT_FAIL_TESTVECTOR;
-          goto done1;
+          err = CRYPT_FAIL_TESTVECTOR;
+          goto done;
        }
 
        /* is order prime ? */
-       if (is_prime(&order, &primality) != CRYPT_OK)             { goto error; }
+       if ((err = is_prime(&order, &primality)) != CRYPT_OK)                        { goto done; }
        if (primality == 0) {
-          res = CRYPT_FAIL_TESTVECTOR;
-          goto done1;
+          err = CRYPT_FAIL_TESTVECTOR;
+          goto done;
        }
 
-       if (mp_read_radix(&G->x, (char *)sets[i].Gx, 64) != MP_OKAY) { goto error; }
-       if (mp_read_radix(&G->y, (char *)sets[i].Gy, 64) != MP_OKAY) { goto error; }
+       if ((err = mp_read_radix(&G->x, (char *)sets[i].Gx, 64)) != MP_OKAY)         { goto error; }
+       if ((err = mp_read_radix(&G->y, (char *)sets[i].Gy, 64)) != MP_OKAY)         { goto error; }
 
        /* then we should have G == (order + 1)G */
-       if (mp_add_d(&order, 1, &order) != MP_OKAY)                  { goto error; }
-       if (ecc_mulmod(&order, G, GG, &modulus) != CRYPT_OK)         { goto error; }
+       if ((err = mp_add_d(&order, 1, &order)) != MP_OKAY)                          { goto error; }
+       if ((err = ecc_mulmod(&order, G, GG, &modulus)) != CRYPT_OK)                 { goto done; }
        if (mp_cmp(&G->x, &GG->x) != 0 || mp_cmp(&G->y, &GG->y) != 0) {
-          res = CRYPT_FAIL_TESTVECTOR;
-          goto done1;
+          err = CRYPT_FAIL_TESTVECTOR;
+          goto done;
        }
    }
-   res = CRYPT_OK;
-   goto done1;
+   err = CRYPT_OK;
+   goto done;
 error:
-   res = CRYPT_MEM;
-done1:
+   err = mpi_to_ltc_error(err);
+done:
    del_point(GG);
    del_point(G);
    mp_clear_multi(&order, &modulus, NULL);
-   return res;
+   return err;
 }
 
 void ecc_sizes(int *low, int *high)
@@ -598,7 +592,7 @@ void ecc_sizes(int *low, int *high)
 
 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
 {
-   int x, res, err;
+   int x, err;
    ecc_point *base;
    mp_int prime;
    unsigned char buf[128];
@@ -625,8 +619,8 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
    }
 
    /* setup the key variables */
-   if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL) != MP_OKAY) {
-      return CRYPT_MEM;
+   if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
    base = new_point();
    if (base == NULL) {
@@ -635,32 +629,32 @@ int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
    }
 
    /* read in the specs for this key */
-   if (mp_read_radix(&prime, (char *)sets[key->idx].prime, 64) != MP_OKAY)  { goto error; }
-   if (mp_read_radix(&base->x, (char *)sets[key->idx].Gx, 64) != MP_OKAY)   { goto error; }
-   if (mp_read_radix(&base->y, (char *)sets[key->idx].Gy, 64) != MP_OKAY)   { goto error; }
-   if (mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize) != MP_OKAY)      { goto error; }
+   if ((err = mp_read_radix(&prime, (char *)sets[key->idx].prime, 64)) != MP_OKAY)      { goto error; }
+   if ((err = mp_read_radix(&base->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY)       { goto error; }
+   if ((err = mp_read_radix(&base->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY)       { goto error; }
+   if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; }
 
    /* make the public key */
-   if (ecc_mulmod(&key->k, base, &key->pubkey, &prime) != CRYPT_OK) { goto error; }
+   if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime)) != CRYPT_OK)             { goto done; }
    key->type = PK_PRIVATE;
 
    /* shrink key */
-   if (mp_shrink(&key->k) != MP_OKAY)          { goto error; }
-   if (mp_shrink(&key->pubkey.x) != MP_OKAY)   { goto error; }
-   if (mp_shrink(&key->pubkey.y) != MP_OKAY)   { goto error; }
+   if ((err = mp_shrink(&key->k)) != MP_OKAY)                                           { goto error; }
+   if ((err = mp_shrink(&key->pubkey.x)) != MP_OKAY)                                    { goto error; }
+   if ((err = mp_shrink(&key->pubkey.y)) != MP_OKAY)                                    { goto error; }
 
    /* free up ram */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
    del_point(base);
    mp_clear(&prime);
 #ifdef CLEAN_STACK
    zeromem(buf, sizeof(buf));
 #endif
-   return res;
+   return err;
 }
 
 void ecc_free(ecc_key *key)
@@ -672,29 +666,28 @@ void ecc_free(ecc_key *key)
 static int compress_y_point(ecc_point *pt, int idx, int *result)
 {
    mp_int tmp, tmp2, p;
-   int res;
+   int err;
 
-   _ARGCHK(pt != NULL);
+   _ARGCHK(pt     != NULL);
    _ARGCHK(result != NULL);
 
-   if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) {
-      return CRYPT_MEM;
+   if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
 
    /* get x^3 - 3x + b */
-   if (mp_read_radix(&p, (char *)sets[idx].B, 64) != MP_OKAY) { goto error; } /* p = B */
-   if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY)              { goto error; } /* tmp = pX^3  */
-   if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY)              { goto error; } /* tmp2 = 3*pX^3 */
-   if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY)               { goto error; } /* tmp = tmp - tmp2 */
-   if (mp_add(&tmp, &p, &tmp) != MP_OKAY)                  { goto error; } /* tmp = tmp + p */
-   if (mp_read_radix(&p, (char *)sets[idx].prime, 64) != MP_OKAY)  { goto error; } /* p = prime */
-   if (mp_mod(&tmp, &p, &tmp) != MP_OKAY)                  { goto error; } /* tmp = tmp mod p */
+   if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
+   if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = pX^3  */
+   if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY)                 { goto error; } /* tmp2 = 3*pX^3 */
+   if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp - tmp2 */
+   if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp + p */
+   if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY)  { goto error; } /* p = prime */
+   if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp mod p */
 
    /* now find square root */
-   if (mp_add_d(&p, 1, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = p + 1 */
-   if (mp_div_2(&tmp2, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = tmp2/2 */
-   if (mp_div_2(&tmp2, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = (p+1)/4 */
-   if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY)       { goto error; } /* tmp  = (x^3 - 3x + b)^((p+1)/4) mod p */
+   if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY)                     { goto error; } /* tmp2 = p + 1 */
+   if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY)           { goto error; } /* tmp2 = (p+1)/4 */
+   if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY)          { goto error; } /* tmp  = (x^3 - 3x + b)^((p+1)/4) mod p */
 
    /* if tmp equals the y point give a 0, otherwise 1 */
    if (mp_cmp(&tmp, &pt->y) == 0) {
@@ -703,66 +696,69 @@ static int compress_y_point(ecc_point *pt, int idx, int *result)
       *result = 1;
    }
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&p, &tmp, &tmp2, NULL);
-   return res;
+   return err;
 }
 
 static int expand_y_point(ecc_point *pt, int idx, int result)
 {
    mp_int tmp, tmp2, p;
-   int res;
+   int err;
 
    _ARGCHK(pt != NULL);
 
-   if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) {
+   if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
       return CRYPT_MEM;
    }
 
    /* get x^3 - 3x + b */
-   if (mp_read_radix(&p, (char *)sets[idx].B, 64) != MP_OKAY) { goto error; } /* p = B */
-   if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY)              { goto error; } /* tmp = pX^3 */
-   if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY)              { goto error; } /* tmp2 = 3*pX^3 */
-   if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY)               { goto error; } /* tmp = tmp - tmp2 */
-   if (mp_add(&tmp, &p, &tmp) != MP_OKAY)                  { goto error; } /* tmp = tmp + p */
-   if (mp_read_radix(&p, (char *)sets[idx].prime, 64) != MP_OKAY)  { goto error; } /* p = prime */
-   if (mp_mod(&tmp, &p, &tmp) != MP_OKAY)                  { goto error; } /* tmp = tmp mod p */
+   if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
+   if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY)                 { goto error; } /* tmp = pX^3 */
+   if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY)                 { goto error; } /* tmp2 = 3*pX^3 */
+   if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY)                  { goto error; } /* tmp = tmp - tmp2 */
+   if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp + p */
+   if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY)  { goto error; } /* p = prime */
+   if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY)                     { goto error; } /* tmp = tmp mod p */
 
    /* now find square root */
-   if (mp_add_d(&p, 1, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = p + 1 */
-   if (mp_div_2(&tmp2, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = tmp2/2 */
-   if (mp_div_2(&tmp2, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = (p+1)/4 */
-   if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY)       { goto error; } /* tmp  = (x^3 - 3x + b)^((p+1)/4) mod p */
+   if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY)                     { goto error; } /* tmp2 = p + 1 */
+   if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY)           { goto error; } /* tmp2 = (p+1)/4 */
+   if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY)          { goto error; } /* tmp  = (x^3 - 3x + b)^((p+1)/4) mod p */
 
    /* if result==0, then y==tmp, otherwise y==p-tmp */
    if (result == 0) {
-      if (mp_copy(&tmp, &pt->y) != MP_OKAY) { goto error; }
+      if ((err = mp_copy(&tmp, &pt->y) != MP_OKAY))                   { goto error; }
    } else {
-      if (mp_sub(&p, &tmp, &pt->y) != MP_OKAY) { goto error; }
+      if ((err = mp_sub(&p, &tmp, &pt->y) != MP_OKAY))                { goto error; }
    }
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&p, &tmp, &tmp2, NULL);
-   return res;
+   return err;
 }
 
 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
 {
    unsigned long y, z;
-   int res, err;
-   unsigned char buf2[512];
+   int cp, err;
 
-   _ARGCHK(out != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
+   
+   /* can we store the static header?  */
+   if (*outlen < (PACKET_SIZE + 3)) {
+      return CRYPT_BUFFER_OVERFLOW;
+   }
 
    /* type valid? */
    if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
@@ -771,36 +767,26 @@ int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key
 
    /* output type and magic byte */
    y = PACKET_SIZE;
-   buf2[y++] = (unsigned char)type;
-   buf2[y++] = (unsigned char)sets[key->idx].size;
+   out[y++] = (unsigned char)type;
+   out[y++] = (unsigned char)sets[key->idx].size;
 
    /* output x coordinate */
-   OUTPUT_BIGNUM(&(key->pubkey.x), buf2, y, z);
+   OUTPUT_BIGNUM(&(key->pubkey.x), out, y, z);
 
    /* compress y and output it  */
-   if ((err = compress_y_point(&key->pubkey, key->idx, &res)) != CRYPT_OK) {
+   if ((err = compress_y_point(&key->pubkey, key->idx, &cp)) != CRYPT_OK) {
       return err;
    }
-   buf2[y++] = (unsigned char)res;
+   out[y++] = (unsigned char)cp;
 
    if (type == PK_PRIVATE) {
-      OUTPUT_BIGNUM(&key->k, buf2, y, z);
-   }
-
-   /* check size */
-   if (*outlen < y) {
-      return CRYPT_BUFFER_OVERFLOW;
+      OUTPUT_BIGNUM(&key->k, out, y, z);
    }
 
    /* store header */
-   packet_store_header(buf2, PACKET_SECT_ECC, PACKET_SUB_KEY);
-
-   memcpy(out, buf2, (size_t)y);
+   packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_KEY);
    *outlen = y;
 
-   #ifdef CLEAN_STACK
-       zeromem(buf2, sizeof(buf2));
-   #endif
    return CRYPT_OK;
 }
 
@@ -809,11 +795,11 @@ int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
    unsigned long x, y, s;
    int err;
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in  != NULL);
    _ARGCHK(key != NULL);
 
    /* check length */
-   if (2+PACKET_SIZE > inlen) {
+   if ((3+PACKET_SIZE) > inlen) {
       return CRYPT_INVALID_PACKET;
    }
 
@@ -881,12 +867,12 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
    unsigned long x, y;
    ecc_point *result;
    mp_int prime;
-   int res;
+   int err;
 
    _ARGCHK(private_key != NULL);
-   _ARGCHK(public_key != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
+   _ARGCHK(public_key  != NULL);
+   _ARGCHK(out         != NULL);
+   _ARGCHK(outlen      != NULL);
 
    /* type valid? */
    if (private_key->type != PK_PRIVATE) {
@@ -903,33 +889,33 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
       return CRYPT_MEM;
    }
 
-   if (mp_init(&prime) != MP_OKAY) {
+   if ((err = mp_init(&prime)) != MP_OKAY) {
       del_point(result);
-      return CRYPT_MEM;
+      return mpi_to_ltc_error(err);
    }
 
-   if (mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64) != MP_OKAY)  { goto error; }
-   if ((res = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; }
+   if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY)   { goto error; }
+   if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; }
 
    x = (unsigned long)mp_unsigned_bin_size(&result->x);
    y = (unsigned long)mp_unsigned_bin_size(&result->y);
 
    if (*outlen < (x+y)) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done1;
    }
    *outlen = x+y;
-   if (mp_to_unsigned_bin(&result->x, out) != MP_OKAY)                                       { goto error; }
-   if (mp_to_unsigned_bin(&result->y, out+x) != MP_OKAY)                                     { goto error; }
+   if ((err = mp_to_unsigned_bin(&result->x, out))   != MP_OKAY)          { goto error; }
+   if ((err = mp_to_unsigned_bin(&result->y, out+x)) != MP_OKAY)          { goto error; }
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done1;
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done1:
    mp_clear(&prime);
    del_point(result);
-   return res;
+   return err;
 }
 
 int ecc_get_size(ecc_key *key)

+ 50 - 52
ecc_sys.c

@@ -19,9 +19,9 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     int err;
 
     _ARGCHK(inkey != NULL);
-    _ARGCHK(out != NULL);
-    _ARGCHK(len != NULL);
-    _ARGCHK(key != NULL);
+    _ARGCHK(out   != NULL);
+    _ARGCHK(len   != NULL);
+    _ARGCHK(key   != NULL);
 
     /* check that wprng/cipher/hash are not invalid */
     if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
@@ -65,6 +65,9 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) {
        return err;
     }
+    
+    /* store header */
+    packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY);    
 
     /* output header */
     y = PACKET_SIZE;
@@ -87,9 +90,7 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     for (x = 0; x < keylen; x++, y++) {
       out[y] = skey[x] ^ inkey[x];
     }
-
-    /* store header */
-    packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY);
+    *len = y;
 
 #ifdef CLEAN_STACK
     /* clean up */
@@ -97,7 +98,6 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     zeromem(ecc_shared, sizeof(ecc_shared));
     zeromem(skey, sizeof(skey));
 #endif
-    *len = y;
     return CRYPT_OK;
 }
 
@@ -107,13 +107,13 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
 {
    unsigned char shared_secret[256], skey[MAXBLOCKSIZE];
    unsigned long x, y, z, hashsize, keysize;
-   int hash, res, err;
+   int hash, err;
    ecc_key pubkey;
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in     != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(keylen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
    /* right key type? */
    if (key->type != PK_PRIVATE) {
@@ -177,7 +177,7 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
    y += 4;
 
    if (*keylen < keysize) {
-       res = CRYPT_BUFFER_OVERFLOW;
+       err = CRYPT_BUFFER_OVERFLOW;
        goto done;
    }
 
@@ -188,13 +188,13 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
 
    *keylen = keysize;
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
 done:
 #ifdef CLEAN_STACK
    zeromem(shared_secret, sizeof(shared_secret));
    zeromem(skey, sizeof(skey));
 #endif
-   return res;
+   return err;
 }
 
 int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
@@ -205,12 +205,12 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
    mp_int b, p;
    unsigned char epubkey[256], er[256];
    unsigned long x, y, pubkeysize, rsize;
-   int res, err;
+   int  err;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
    /* is this a private key? */
    if (key->type != PK_PRIVATE) {
@@ -239,29 +239,30 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
 
    /* get the hash and load it as a bignum into 'b' */
    /* init the bignums */
-   if (mp_init_multi(&b, &p, NULL) != MP_OKAY) { 
+   if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) { 
       ecc_free(&pubkey);
-      return CRYPT_MEM;
+      return mpi_to_ltc_error(err);
    }
-   if (mp_read_radix(&p, (char *)sets[key->idx].order, 64) != MP_OKAY)     { goto error; }
-   if (mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen) != MP_OKAY)        { goto error; }
+   if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY)        { goto error; }
+   if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY)  { goto error; }
 
    /* find b = (m - x)/k */
-   if (mp_invmod(&pubkey.k, &p, &pubkey.k) != MP_OKAY)                    { goto error; } /* k = 1/k */
-   if (mp_submod(&b, &key->k, &p, &b) != MP_OKAY)                         { goto error; } /* b = m - x */
-   if (mp_mulmod(&b, &pubkey.k, &p, &b) != MP_OKAY)                       { goto error; } /* b = (m - x)/k */
+   if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY)            { goto error; } /* k = 1/k */
+   if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY)                 { goto error; } /* b = m - x */
+   if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY)               { goto error; } /* b = (m - x)/k */
 
    /* export it */
    rsize = (unsigned long)mp_unsigned_bin_size(&b);
    if (rsize > (unsigned long)sizeof(er)) { 
+      err = CRYPT_BUFFER_OVERFLOW;
       goto error; 
    }
-   (void)mp_to_unsigned_bin(&b, er);
+   if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY)                     { goto error; }
 
    /* now lets check the outlen before we write */
    if (*outlen < (12 + rsize + pubkeysize)) {
-      res = CRYPT_BUFFER_OVERFLOW;
-      goto done1;
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto done;
    }
 
    /* lets output */
@@ -290,18 +291,18 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
 
    /* clear memory */
    *outlen = y;
-   res = CRYPT_OK;
-   goto done1;
+   err = CRYPT_OK;
+   goto done;
 error:
-   res = CRYPT_MEM;
-done1:
+   err = mpi_to_ltc_error(err);
+done:
    mp_clear_multi(&b, &p, NULL);
    ecc_free(&pubkey);
 #ifdef CLEAN_STACK
    zeromem(er, sizeof(er));
    zeromem(epubkey, sizeof(epubkey));
 #endif
-   return res;   
+   return err;   
 }
 
 /* verify that mG = (bA + Y)
@@ -325,12 +326,12 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
    ecc_key   pubkey;
    mp_int b, p, m, mu;
    unsigned long x, y;
-   int res, err;
+   int err;
 
-   _ARGCHK(sig != NULL);
+   _ARGCHK(sig  != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
    /* default to invalid signature */
    *stat = 0;
@@ -374,9 +375,9 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
    y += 4;
 
    /* init values */
-   if (mp_init_multi(&b, &m, &p, &mu, NULL) != MP_OKAY) { 
+   if ((err = mp_init_multi(&b, &m, &p, &mu, NULL)) != MP_OKAY) { 
       ecc_free(&pubkey);
-      return CRYPT_MEM;
+      return mpi_to_ltc_error(err);
    }
 
    mG = new_point();
@@ -387,33 +388,30 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
    } 
 
    /* load b */
-   if (mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x) != MP_OKAY)        { goto error; }
+   if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x)) != MP_OKAY)        { goto error; }
    y += x;
 
    /* get m in binary a bignum */
-   if (mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)inlen) != MP_OKAY)     { goto error; }
+   if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)inlen)) != MP_OKAY)     { goto error; }
    
    /* load prime */
-   if (mp_read_radix(&p, (char *)sets[key->idx].prime, 64) != MP_OKAY)    { goto error; }
+   if ((err = mp_read_radix(&p, (char *)sets[key->idx].prime, 64)) != MP_OKAY)             { goto error; }
    
    /* calculate barrett stuff */
    mp_set(&mu, 1); 
    mp_lshd(&mu, 2 * USED(&p));
-   if (mp_div(&mu, &p, &mu, NULL) != MP_OKAY) {
-     res = CRYPT_MEM;
-     goto done;
-   }
+   if ((err = mp_div(&mu, &p, &mu, NULL)) != MP_OKAY)                                      { goto error; }
 
    /* get bA */
-   if (ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p) != CRYPT_OK)                  { goto error; }
+   if ((err = ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p)) != CRYPT_OK)                  { goto done; }
    
    /* get bA + Y */
-   if (add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu) != CRYPT_OK)    { goto error; }
+   if ((err = add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu)) != CRYPT_OK)    { goto done; }
 
    /* get mG */
-   if (mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64) != MP_OKAY)   { goto error; }
-   if (mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64) != MP_OKAY)   { goto error; }
-   if (ecc_mulmod(&m, mG, mG, &p) != CRYPT_OK)                                     { goto error; }
+   if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY)                 { goto error; }
+   if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY)                 { goto error; }
+   if ((err = ecc_mulmod(&m, mG, mG, &p)) != CRYPT_OK)                                          { goto done; }
 
    /* compare mG to bA + Y */
    if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) {
@@ -421,14 +419,14 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
    }
 
    /* clear up and return */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = CRYPT_ERROR;
+   err = mpi_to_ltc_error(err);
 done:
    del_point(mG);
    ecc_free(&pubkey);
    mp_clear_multi(&p, &m, &b, &mu, NULL);
-   return res;
+   return err;
 }
 

+ 6 - 6
hash.c

@@ -15,8 +15,8 @@ int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned
     hash_state md;
     int err;
 
-    _ARGCHK(data != NULL);
-    _ARGCHK(dst != NULL);
+    _ARGCHK(data   != NULL);
+    _ARGCHK(dst    != NULL);
     _ARGCHK(outlen != NULL);
 
     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
@@ -44,9 +44,9 @@ int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outle
     size_t x;
     int err;
 
-    _ARGCHK(dst != NULL);
+    _ARGCHK(dst    != NULL);
     _ARGCHK(outlen != NULL);
-    _ARGCHK(in != NULL);
+    _ARGCHK(in     != NULL);
 
     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
         return err;
@@ -78,8 +78,8 @@ int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *ou
 #else
     FILE *in;
     int err;
-    _ARGCHK(fname != NULL);
-    _ARGCHK(dst != NULL);
+    _ARGCHK(fname  != NULL);
+    _ARGCHK(dst    != NULL);
     _ARGCHK(outlen != NULL);
 
     if ((err = hash_is_valid(hash)) != CRYPT_OK) {

+ 11 - 9
hmac.c

@@ -150,9 +150,10 @@ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
     hmac_state hmac;
     int err;
 
-    _ARGCHK(key != NULL);
-    _ARGCHK(data != NULL);
-    _ARGCHK(dst != NULL);
+    _ARGCHK(key    != NULL);
+    _ARGCHK(data   != NULL);
+    _ARGCHK(dst    != NULL); 
+    _ARGCHK(dstlen != NULL);
     
     if((err = hash_is_valid(hash)) != CRYPT_OK) {
         return err;
@@ -173,9 +174,9 @@ int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
 }
 
 /* hmac_file added by Tom St Denis */
-int hmac_file(int hash, const char *fname, const unsigned char *key,
-                unsigned long keylen, 
-                unsigned char *dst, unsigned long *dstlen)
+int hmac_file(int hash, const char *fname, 
+              const unsigned char *key, unsigned long keylen, 
+                    unsigned char *dst, unsigned long *dstlen)
 {
 #ifdef NO_FILE
     return CRYPT_NOP;
@@ -186,9 +187,10 @@ int hmac_file(int hash, const char *fname, const unsigned char *key,
    size_t x;
    int err;
 
-   _ARGCHK(fname != NULL);
-   _ARGCHK(key != NULL);
-   _ARGCHK(dst != NULL);
+   _ARGCHK(fname  != NULL);
+   _ARGCHK(key    != NULL);
+   _ARGCHK(dst    != NULL);
+   _ARGCHK(dstlen != NULL);
    
    if((err = hash_is_valid(hash)) != CRYPT_OK) {
        return err;

+ 7 - 4
makefile

@@ -9,7 +9,7 @@
 # a build. This is easy to remedy though, for those that have problems.
 
 # The version
-VERSION=0.93
+VERSION=0.94
 
 #ch1-01-1
 # Compiler and Linker Names
@@ -65,8 +65,9 @@ MPIOBJECT=mpi.o
 OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \
 bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \
 md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o \
-safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
-prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o eax.o ocb.o $(MPIOBJECT)
+safer_tab.o safer.o saferp.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
+prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o \
+eax.o ocb.o pmac.o whirl.o $(MPIOBJECT)
 
 TESTOBJECTS=demos/test.o
 HASHOBJECTS=demos/hashsum.o
@@ -152,7 +153,9 @@ docs: crypt.tex
 	rm -f crypt.pdf $(LEFTOVERS)
 	latex crypt > /dev/null
 	makeindex crypt > /dev/null
-	pdflatex crypt > /dev/null
+	latex crypt > /dev/null
+	latex crypt > /dev/null
+	dvipdf crypt
 	rm -f $(LEFTOVERS)
        
 #beta

+ 3 - 2
makefile.cygwin_dll

@@ -21,8 +21,9 @@ MPIOBJECT=mpi.o
 OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \
 bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \
 md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o \
-safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
-prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o eax.o ocb.o $(MPIOBJECT)
+safer_tab.o safer.o saferp.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
+prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o eax.o \
+ocb.o pmac.o whirl.o $(MPIOBJECT)
 
 ltc_dll: $(OBJECTS) $(MPIOBJECT)
 	gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32

+ 2 - 2
makefile.msvc

@@ -9,9 +9,9 @@ default: library
 OBJECTS=keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj \
 bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \
 md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj des.obj \
-safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \
+safer_tab.obj safer.obj saferp.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \
 blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj rmd128.obj rmd160.obj \
-skipjack.obj omac.obj dsa.obj eax.obj ocb.obj
+skipjack.obj omac.obj dsa.obj eax.obj ocb.obj pmac.obj whirl.obj
 
 library: $(OBJECTS)
 	lib /out:tomcrypt.lib $(OBJECTS)

+ 1 - 1
makefile.out

@@ -9,7 +9,7 @@ CFLAGS += -Os -Wall -Wsign-compare -W -Wno-unused -Werror -I./
 
 default: library
 
-OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o eax.o ocb.o 
+OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o eax.o ocb.o pmac.o whirl.o
 
 rsa.o: rsa_sys.c
 dh.o: dh_sys.c

+ 2 - 2
mycrypt.h

@@ -16,8 +16,8 @@ extern "C" {
 #endif
 
 /* version */
-#define CRYPT   0x0093
-#define SCRYPT  "0.93"
+#define CRYPT   0x0094
+#define SCRYPT  "0.94"
 
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE           128

+ 2 - 1
mycrypt_custom.h

@@ -22,7 +22,6 @@
 #define RC5
 #define RC6
 #define SAFERP
-#define SAFER
 #define RIJNDAEL
 #define XTEA
 #define TWOFISH
@@ -36,6 +35,7 @@
 #define ECB
 #define CBC
 #define CTR
+#define WHIRLPOOL
 #define SHA512
 #define SHA384
 #define SHA256
@@ -49,6 +49,7 @@
 #define RIPEMD160
 #define HMAC
 #define OMAC
+#define PMAC
 #define EAX_MODE
 #define OCB_MODE
 #define BASE64

+ 55 - 3
mycrypt_hash.h

@@ -70,7 +70,18 @@ struct rmd160_state {
 };
 #endif
 
+#ifdef WHIRLPOOL
+struct whirlpool_state {
+    ulong64 length, state[8];
+    unsigned char buf[64];
+    ulong32 curlen;
+};
+#endif
+
 typedef union Hash_state {
+#ifdef WHIRLPOOL
+    struct whirlpool_state whirlpool;
+#endif
 #ifdef SHA512
     struct sha512_state sha512;
 #endif
@@ -111,6 +122,15 @@ extern struct _hash_descriptor {
     int  (*test)(void);
 } hash_descriptor[];
 
+
+#ifdef WHIRLPOOL
+extern void whirlpool_init(hash_state * md);
+extern int whirlpool_process(hash_state * md, const unsigned char *buf, unsigned long len);
+extern int whirlpool_done(hash_state * md, unsigned char *hash);
+extern int  whirlpool_test(void);
+extern const struct _hash_descriptor whirlpool_desc;
+#endif
+
 #ifdef SHA512
 extern void sha512_init(hash_state * md);
 extern int sha512_process(hash_state * md, const unsigned char *buf, unsigned long len);
@@ -290,7 +310,38 @@ extern int omac_memory(int cipher, const unsigned char *key, unsigned long keyle
 extern int omac_file(int cipher, const unsigned char *key, unsigned long keylen,
               const char *filename, unsigned char *out, unsigned long *outlen);
 extern int omac_test(void);
-#endif
+#endif /* OMAC */
+
+#ifdef PMAC
+
+typedef struct {
+   unsigned char     Ls[32][MAXBLOCKSIZE],    /* L shifted by i bits to the left */
+                     Li[MAXBLOCKSIZE],        /* value of Li [current value, we calc from previous recall] */
+                     Lr[MAXBLOCKSIZE],        /* L * x^-1 */
+                     block[MAXBLOCKSIZE],     /* currently accumulated block */
+                     checksum[MAXBLOCKSIZE];  /* current checksum */
+
+   symmetric_key     key;                     /* scheduled key for cipher */
+   unsigned long     block_index;             /* index # for current block */
+   int               cipher_idx,              /* cipher idx */
+                     block_len,               /* length of block */
+                     buflen;                  /* number of bytes in the buffer */
+} pmac_state;
+
+extern int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen);
+extern int pmac_process(pmac_state *state, const unsigned char *buf, unsigned long len);
+extern int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen);
+
+extern int pmac_memory(int cipher, const unsigned char *key, unsigned long keylen,
+                const unsigned char *msg, unsigned long msglen,
+                unsigned char *out, unsigned long *outlen);
+
+extern int pmac_file(int cipher, const unsigned char *key, unsigned long keylen,
+              const char *filename, unsigned char *out, unsigned long *outlen);
+
+extern int pmac_test(void);
+
+#endif /* PMAC */
 
 #ifdef EAX_MODE
 
@@ -345,8 +396,7 @@ typedef struct {
    symmetric_key     key;                     /* scheduled key for cipher */
    unsigned long     block_index;             /* index # for current block */
    int               cipher,                  /* cipher idx */
-                     block_len,               /* length of block */
-                     poly;                    /* which set of polys to use */
+                     block_len;               /* length of block */
 } ocb_state;
 
 extern int ocb_init(ocb_state *ocb, int cipher, 
@@ -383,3 +433,5 @@ extern int ocb_decrypt_verify_memory(int cipher,
 extern int ocb_test(void);
 
 #endif /* OCB_MODE */
+
+

+ 8 - 8
mycrypt_macros.h

@@ -198,18 +198,18 @@ typedef unsigned long ulong32;
 
 static inline unsigned long ROL(unsigned long word, int i)
 {
-	__asm__("roll %%cl,%0"
-		:"=r" (word)
-		:"0" (word),"c" (i));
-	return word;
+   __asm__("roll %%cl,%0"
+      :"=r" (word)
+      :"0" (word),"c" (i));
+   return word;
 }
 
 static inline unsigned long ROR(unsigned long word, int i)
 {
-	__asm__("rorl %%cl,%0"
-		:"=r" (word)
-		:"0" (word),"c" (i));
-	return word;
+   __asm__("rorl %%cl,%0"
+      :"=r" (word)
+      :"0" (word),"c" (i));
+   return word;
 }
 
 #else

+ 16 - 16
mycrypt_pk.h

@@ -3,43 +3,43 @@
 
 #include "tommath.h"
 
-
 /* in/out macros */
-
-#define OUTPUT_BIGNUM(num, buf2, y, z)         \
-{                                              \
-      z = (unsigned long)mp_unsigned_bin_size(num);           \
-      STORE32L(z, buf2+y);                     \
-      y += 4;                                  \
-      if ((err = mp_to_unsigned_bin(num, buf2+y)) != MP_OKAY) { return mpi_to_ltc_error(err); }   \
-      y += z;                                  \
+#define OUTPUT_BIGNUM(num, out, y, z)                                                             \
+{                                                                                                 \
+      if ((y + 4) > *outlen) { return CRYPT_BUFFER_OVERFLOW; }                                    \
+      z = (unsigned long)mp_unsigned_bin_size(num);                                               \
+      STORE32L(z, out+y);                                                                         \
+      y += 4;                                                                                     \
+      if ((y + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; }                                    \
+      if ((err = mp_to_unsigned_bin(num, out+y)) != MP_OKAY) { return mpi_to_ltc_error(err); }    \
+      y += z;                                                                                     \
 }
 
 
 #define INPUT_BIGNUM(num, in, x, y)                              \
 {                                                                \
      /* load value */                                            \
-     if (y + 4 > inlen) {                                        \
-        err = CRYPT_INVALID_PACKET;                            \
+     if ((y + 4) > inlen) {                                      \
+        err = CRYPT_INVALID_PACKET;                              \
         goto error;                                              \
      }                                                           \
      LOAD32L(x, in+y);                                           \
      y += 4;                                                     \
                                                                  \
      /* sanity check... */                                       \
-     if (x+y > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                            \
+     if ((x+y) > inlen) {                                        \
+        err = CRYPT_INVALID_PACKET;                              \
         goto error;                                              \
      }                                                           \
                                                                  \
      /* load it */                                               \
      if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != MP_OKAY) {\
-        err = mpi_to_ltc_error(err);                                      \
+        err = mpi_to_ltc_error(err);                             \
         goto error;                                              \
      }                                                           \
      y += x;                                                     \
-     if ((err = mp_shrink(num)) != MP_OKAY) {                            \
-        err = mpi_to_ltc_error(err);                                       \
+     if ((err = mp_shrink(num)) != MP_OKAY) {                    \
+        err = mpi_to_ltc_error(err);                             \
         goto error;                                              \
      }                                                           \
 }

+ 35 - 0
notes/base64_tv.txt

@@ -0,0 +1,35 @@
+Base64 vectors.  These are the base64 encodings of the strings 00,01,02...NN-1
+
+ 0: 
+ 1: AA==
+ 2: AAE=
+ 3: AAEC
+ 4: AAECAw==
+ 5: AAECAwQ=
+ 6: AAECAwQF
+ 7: AAECAwQFBg==
+ 8: AAECAwQFBgc=
+ 9: AAECAwQFBgcI
+10: AAECAwQFBgcICQ==
+11: AAECAwQFBgcICQo=
+12: AAECAwQFBgcICQoL
+13: AAECAwQFBgcICQoLDA==
+14: AAECAwQFBgcICQoLDA0=
+15: AAECAwQFBgcICQoLDA0O
+16: AAECAwQFBgcICQoLDA0ODw==
+17: AAECAwQFBgcICQoLDA0ODxA=
+18: AAECAwQFBgcICQoLDA0ODxAR
+19: AAECAwQFBgcICQoLDA0ODxAREg==
+20: AAECAwQFBgcICQoLDA0ODxAREhM=
+21: AAECAwQFBgcICQoLDA0ODxAREhMU
+22: AAECAwQFBgcICQoLDA0ODxAREhMUFQ==
+23: AAECAwQFBgcICQoLDA0ODxAREhMUFRY=
+24: AAECAwQFBgcICQoLDA0ODxAREhMUFRYX
+25: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGA==
+26: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBk=
+27: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBka
+28: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGw==
+29: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxw=
+30: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwd
+31: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHg==
+32: AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=

+ 0 - 216
notes/cipher_tv.txt

@@ -1005,222 +1005,6 @@ Key Size: 32 bytes
 49: F8B974A4BC134F39BE9B27BD8B2F1129
 
 
-Cipher: safer-k64
-Key Size: 8 bytes
- 0: 533F0CD7CCC6DDF6
- 1: C3CD66BB1E5E5C17
- 2: 079DFD68F6AF9A79
- 3: 84EB4922264A1204
- 4: 31F3A7D739C7E42C
- 5: 381F88FB46E1DCA2
- 6: CAF4AC443E50EF47
- 7: 2914E255DA9BDDBB
- 8: A160A24120E4FECC
- 9: F748C6009FFBC465
-10: 8B3CB5784846D2B0
-11: 4F98C1621473399B
-12: B486B0BC365ABEE9
-13: 314EAB2B4E9F7840
-14: 613FE3637968A8FE
-15: 28935352361E1239
-16: 0DCB090233B8EB3C
-17: CF0BC7F307586C8B
-18: 64DF354F96CB0781
-19: D2B73C6BAACA7FB1
-20: 638FCEEF49A29743
-21: 204C4E0E0C0A8B63
-22: F041EF6BE046D8AA
-23: 76954D822F5E2C32
-24: 6700C60971A73C9E
-25: 80019293AA929DF2
-26: 8EF4DE13F054ED98
-27: 41DDF9845ABA2B7A
-28: B91834079643850C
-29: 8F44EC823D5D70DC
-30: EC2FF8DE726C84CE
-31: 25DF59DC2EA22CB5
-32: FC1130B511794ABB
-33: ED3259359D2E68D4
-34: D7773C04804033F6
-35: C1A32C114589251C
-36: 51647E61EE32542E
-37: B95A8037457C8425
-38: 4F84B3D483F239EE
-39: 458401C3787BCA5E
-40: F59B5A93FD066F8A
-41: 1450E10189CC4000
-42: 0F758B71804B3AB3
-43: 51B744B271554626
-44: B55ADA1ED1B29F0D
-45: 585DF794461FEBDA
-46: 3790CC4DCA437505
-47: 7F7D46616FF05DFA
-48: 6AE981921DFCFB13
-49: FE89299D55465BC6
-
-
-Cipher: safer-sk64
-Key Size: 8 bytes
- 0: 14A391FCE1DECD95
- 1: 16A5418C990D77F4
- 2: EE33161465F7E2DD
- 3: AB85A34464D58EC4
- 4: 3D247C84C1B98737
- 5: D88D275545132F17
- 6: 00B45A81780E3441
- 7: 6830FAE6C4A6D0D3
- 8: 93DF6918E1975723
- 9: 15AB9036D02AA290
-10: 0933666F0BA4486E
-11: 93F42DEE726D949C
-12: 756E7BA3A6D4DE2E
-13: 4922DCE8EED38CFD
-14: 8EC07AFBD42DF21C
-15: E82BEBCFB1D7C6B4
-16: B3EDB4CB62B8A9BA
-17: 5521307CA52DD2F3
-18: 54B5D75512E1F8F3
-19: 1A736293F2D460A8
-20: 778C71384545F710
-21: CBC041D3BF742253
-22: 9C47FC0FDA1FE8D9
-23: B84E290D4BF6EE66
-24: FC3E514CE66BB9E3
-25: E8742C92E3640AA8
-26: 4DA275A571BDE1F0
-27: C5698E3F6AC5ED9D
-28: AC3E758DBC7425EA
-29: B1D316FC0C5A59FD
-30: 2861C78CA59069B9
-31: E742B9B6525201CF
-32: 2072746EDF9B32A6
-33: 41EF55A26D66FEBC
-34: EC57905E4EED5AC9
-35: 5854E6D1C2FB2B88
-36: 492D7E4A699EA6D6
-37: D3E6B9298813982C
-38: 65071A860261288B
-39: 401EEF4839AC3C2E
-40: 1025CA9BD9109F1D
-41: 0C28B570A1AE84EA
-42: BFBE239720E4B3C5
-43: 09FB0339ACCEC228
-44: DFF2E0E2631B556D
-45: ECE375020575B084
-46: 1C4C14890D44EB42
-47: EA9062A14D4E1F7F
-48: 82773D9EEFCAB1AB
-49: 516C78FF770B6A2F
-
-
-Cipher: safer-k128
-Key Size: 16 bytes
- 0: 4D791DB28D724E55
- 1: 53788205114E1200
- 2: 4472BCCAF3DDEF59
- 3: FE9B3640ED11589C
- 4: 4DDD7859819857D7
- 5: 6BF901C4B46CC9DB
- 6: 930DBFC0DE0F5007
- 7: E89F702158A00D82
- 8: BEB661953BF46D50
- 9: 6F0DA64C0FD101F9
-10: 4EBBCE4E5A37BED8
-11: 996EAA0AF92A09AC
-12: AED6BB9522E0B00F
-13: DF9C643624A271B4
-14: 2E5C789DD44EF0CF
-15: 86A5BA1060177330
-16: 2385DBA4DEBEB4A3
-17: 82E2FC765722094D
-18: B3CA2161757695EF
-19: F8A4C6081F3ABC06
-20: 6422316E1BEFFAC8
-21: C178511BFBFF380E
-22: 049B8CBEDE5942A9
-23: 0E181292C1B1DEFC
-24: C347BA0632A49E55
-25: 32FDA46669714F99
-26: 0523743E30C16788
-27: 782BE96A93769ED0
-28: 9F99C9E8BD4A69D8
-29: 104C094F120C926D
-30: 1F7EA3C4654D59E6
-31: 90C263629BC81D53
-32: 1803469BE59FED9E
-33: 1478C7C176B86336
-34: 362FE111601411FF
-35: 6428417432ECC3C8
-36: D74C42FCC6946FC5
-37: 1A8F3A82C78C2BE6
-38: EE22C641DC096375
-39: 59D34A0187C5C021
-40: F68CC96F09686A30
-41: CF8C608BDCC4A7FC
-42: D2896AB16C284A85
-43: 8375C5B139D93189
-44: 0F0462F9D8EBAED0
-45: C3359B7CF78B3963
-46: E4F7233D6F05DCC9
-47: 8533D1062397119B
-48: 4B300915F320DFCE
-49: A050956A4F705DB9
-
-
-Cipher: safer-sk128
-Key Size: 16 bytes
- 0: 511E4D5D8D70B37E
- 1: 3C688F629490B796
- 2: 41CB15571FE700C6
- 3: F1CBFE79F0AD23C8
- 4: 0A0DC4AA14C2E8AA
- 5: 05740CF7CD1CA039
- 6: 24E886AD6E0C0A67
- 7: EEF14D7B967066BC
- 8: 6ABDF6D8AF85EAA0
- 9: 0EB947521357ED27
-10: BDD2C15957F9EC95
-11: 0989B87A74A2D454
-12: 04C793BA2FAB7462
-13: 3DAD2FACDDFA3C45
-14: D1194935CC4E1BD7
-15: BAC0A2C8248FF782
-16: 7DD5894A82298C64
-17: A59F552A4377C08B
-18: 8DDDE41AB4586151
-19: 7CC4261B38FFA833
-20: E99204D6584158EC
-21: AACC8ED0803CB5C4
-22: C105CA72A7688E79
-23: 3D662FDC35B88C09
-24: A4BCEDC0AE99E30E
-25: EAECF9B6024D353C
-26: 214651A3D34AFF40
-27: 807099325F9D73C2
-28: 45EC21AEB6B90A24
-29: DCED39526687F219
-30: 2CC248E301D3101D
-31: C7F37AB8570BA13C
-32: BB9B31A34A39641B
-33: 5314570844948CAC
-34: 4581F837C02CD4F4
-35: 4E036B1B62303BF3
-36: 7B3B88DE1F5492A4
-37: CEF2865C14875035
-38: 14DE8BEE09A155DE
-39: 3AA284C74867161B
-40: 3616B4607369D597
-41: 07512F57E75EDEF7
-42: 710D1641FCE64DC2
-43: DB2A089E87C867A2
-44: A192D7B392AA2E2F
-45: 8D797A62FBFE6C81
-46: E52CE898E19BF110
-47: 72695C25158CB870
-48: 29F945B733FB498F
-49: 27057037E976F3FB
-
-
 Cipher: rc2
 Key Size: 8 bytes
  0: 83B189DE87161805

+ 0 - 76
notes/eax_tv.txt

@@ -199,82 +199,6 @@ EAX-twofish (16 byte key)
  31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF
  32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1
 
-EAX-safer-k64 (8 byte key)
-  0: , 9065118C8F6F7842
-  1: A1, 1926B3F5112C33BA
-  2: 2E9A, 5FA6078A0AA7B7C8
-  3: 56FCE2, 984E385F9441FEC8
-  4: C33ACE8A, 24AC1CBBCCD0D00A
-  5: 24307E196B, DD2D52EFCA571B68
-  6: 31471EAA5155, EB41C2B36FAAA774
-  7: 03D397F6CFFF62, 7DFBC8485C8B169B
-  8: 8FA39E282C21B5B2, 2C7EC769966B36D7
-  9: FEA5402D9A8BE34946, A058E165B5FFB556
- 10: 6CDEF76554CA845193F0, FED516001FFE039A
- 11: DC50D19E98463543D94820, 8F9CCF32394498A1
- 12: 42D8DC34F1974FB4EB2535D7, 77F648526BCBB5AF
- 13: B75F1299EF6211A6318F6A8EAA, C5086AEA1BE7640B
- 14: 1E28D68373330829DD1FFC5D083E, 33EDA06A7B5929A2
- 15: 85529CF87C4706751B0D47CC89CEA6, D031905D6141CBED
- 16: FE5CB61BAF93B30ED3C296EE85F51864, CC484888F0ABD922
-
-EAX-safer-sk64 (8 byte key)
-  0: , 5254AB3079CDCB78
-  1: 75, 798DCF14FEF8F4D1
-  2: 0300, D5FCA75DAC97849C
-  3: 520F98, 10E357957CE20898
-  4: 80E2764D, 5C7F46656C6A46EA
-  5: C48960CDAA, 3CCF44BD41F01CA8
-  6: E0E60BD9AA2C, EBB493983FCEE79D
-  7: D13D8804906A1B, 6EDDCA919978F0B6
-  8: B7AE14C37A343BFB, 2369E38A9B686747
-  9: 5DE326BBCC7D0D35E9, 041E5EE8568E941C
- 10: 13494F5B0635BA3D6E53, EAEEA8AFA55141DD
- 11: A9BB35B14C831FDA0D83F7, 4002A696F1363987
- 12: E242043A1C355409819FABFC, 63A085B8886C5FDC
- 13: 204598B889272C6FE694BDBB4D, 194A1530138EFECE
- 14: EE3F39E0823A82615679C664DEBF, 1EFF8134C8BEFB3A
- 15: 8579D87FD3B5E2780BC229665F1D1B, A832CD3E1C1C2289
- 16: 74D7290D72DA67C4A9EAD434AE3A0A85, 96BAA615A5253CB5
-
-EAX-safer-k128 (16 byte key)
-  0: , 7E32E3F943777EE7
-  1: D1, BA00336F561731A7
-  2: F6D7, 8E3862846CD1F482
-  3: 5323B5, BD1B8C27B061969B
-  4: A3EC3416, 170BBB9CE17D1D62
-  5: 0C74D66716, 7BD024B890C5CE01
-  6: 6158A630EB37, B5C5BD0652ACB712
-  7: 17F2D0E019947D, F9FF81E2638EC21C
-  8: 68E135CC154509C8, AA9EAEF8426886AA
-  9: EDB1ABE0B486749C21, 355C99E4651C0400
- 10: DB0C30E9367A72E8F5B2, 631B5671B8A1DB9A
- 11: D4E5453D9A4C9DB5170FCE, 75A2DF0042E14D82
- 12: 3F429CC9A550CBDA44107AA7, 2C2977EA13FEBD45
- 13: A7CA22A97C2361171B415E7083, BFE81185F31727A8
- 14: 170F79D8B0E3F77299C44208C5B1, D5ED9F9459DF9C22
- 15: 2E24312D2AE5D5F09D5410900A4BBA, 2FC865CA96EA5A7E
- 16: 8F3C49A316BA27067FF2C6D99EC8C846, 9D840F40CDB62E4B
-
-EAX-safer-sk128 (16 byte key)
-  0: , 22D90A75BBA5F298
-  1: 3F, 98C31AB2DE61DE82
-  2: 584D, F4701D4A1A09928C
-  3: B9DEAD, 6E221A98505153DA
-  4: 06D4A6EB, 0E57C51B96BA13B6
-  5: 7B58B441CA, E28CCF271F5D0A29
-  6: 7950E0D1EC24, 2ACDDE6E38180C07
-  7: 65A4F4E098D7C6, 7DC1C9E9602BACF2
-  8: FEBE4E72BAA0848F, C4607EA3F138BAD9
-  9: 9B7BD6D6D655985AA3, 8B2C58A9530EA6AC
- 10: 60C92F925D1478470203, 51E6F5F6DC996F84
- 11: 7B40769370E651F64AA654, 74F1F8A8D3F4B9AF
- 12: 7215832C2FB9C54DF7A9C686, 9BF9AEF14F9151D1
- 13: AD0F9C79008572AB8AE2466EFF, F375D0583D921B69
- 14: C05076E2C330A0D25D7CEC80597F, 843C12F84B00A8E0
- 15: D18F0563AB0278140B0CD9A9B07B34, 262B1688E16A171E
- 16: 650747091F5C532EE37D2D78EE1EC605, 1BAC36144F9A0E8D
-
 EAX-rc2 (8 byte key)
   0: , D6CC8632EEE0F46B
   1: 4C, EA19572CB8970CB4

+ 91 - 0
notes/etc/whirlgen.c

@@ -0,0 +1,91 @@
+#include <stdio.h>
+
+unsigned E[16] =  { 1, 0xb, 9, 0xc, 0xd, 6, 0xf, 3, 0xe, 8, 7, 4, 0xa, 2, 5, 0 };
+unsigned Ei[16];
+unsigned R[16] =  { 7, 0xc, 0xb, 0xd, 0xe, 4, 9, 0xf, 6, 3, 8, 0xa, 2, 5, 1, 0 };
+unsigned cir[8][8] = { 
+ {1, 1, 4, 1, 8, 5, 2, 9 },
+}; 
+
+
+unsigned gf_mul(unsigned a, unsigned b)
+{
+   unsigned r;
+   
+   r = 0;
+   while (a) {
+      if (a & 1) r ^= b;
+      a >>= 1;
+      b = (b << 1) ^ (b & 0x80 ? 0x11d : 0x00);
+   }
+   return r;
+}
+
+unsigned sbox(unsigned x)
+{
+   unsigned a, b, w;
+   
+   a = x >> 4;
+   b = x & 15;
+   
+   a = E[a]; b = Ei[b];
+   w = a ^ b; w = R[w];
+   a = E[a ^ w]; b = Ei[b ^ w];
+   
+   
+   return (a << 4) | b;
+}
+
+int main(void)
+{
+   unsigned x, y;
+   
+   for (x = 0; x < 16; x++) Ei[E[x]] = x;
+   
+//   for (x = 0; x < 16; x++) printf("%2x ", sbox(x));
+   for (y = 1; y < 8; y++) {
+      for (x = 0; x < 8; x++) {
+          cir[y][x] = cir[y-1][(x-1)&7];
+      }
+   }
+
+/*   
+   printf("\n");
+   for (y = 0; y < 8; y++) {
+       for (x = 0; x < 8; x++) printf("%2d ", cir[y][x]);
+       printf("\n");
+   }
+*/
+
+   for (y = 0; y < 8; y++) {
+       printf("static const ulong64 sbox%d[] = {\n", y);
+       for (x = 0; x < 256; ) {
+           printf("CONST64(0x%02x%02x%02x%02x%02x%02x%02x%02x)",
+              gf_mul(sbox(x), cir[y][0]),
+              gf_mul(sbox(x), cir[y][1]),
+              gf_mul(sbox(x), cir[y][2]),
+              gf_mul(sbox(x), cir[y][3]),
+              gf_mul(sbox(x), cir[y][4]),
+              gf_mul(sbox(x), cir[y][5]),
+              gf_mul(sbox(x), cir[y][6]),
+              gf_mul(sbox(x), cir[y][7]));
+           if (x < 255) printf(", ");
+           if (!(++x & 3)) printf("\n");
+       }
+       printf("};\n\n");
+  }
+  
+  printf("static const ulong64 cont[] = {\n");
+  for (y = 0; y <= 10; y++) {
+      printf("CONST64(0x");
+      for (x = 0; x < 8; x++) {
+         printf("%02x", sbox((8*y + x)&255));
+      }
+      printf("),\n");
+  }
+  printf("};\n\n");
+  return 0;
+   
+}
+
+

+ 15 - 0
notes/etc/whirltest.c

@@ -0,0 +1,15 @@
+#include <stdio.h>
+
+int main(void)
+{
+   char buf[4096];
+   int x;
+   
+   while (fgets(buf, sizeof(buf)-2, stdin) != NULL) {
+        for (x = 0; x < 128; ) {
+            printf("0x%c%c, ", buf[x], buf[x+1]);
+            if (!((x += 2) & 31)) printf("\n");
+        }
+   }
+}
+

+ 131 - 0
notes/hash_tv.txt

@@ -1603,3 +1603,134 @@ Hash: rmd160
 127: 2BE8E565E24A87171F0700ECAFA3C2942C97023E
 128: 7C4D36070C1E1176B2960A1B0DD2319D547CF8EB
 
+Hash: whirlpool
+  0: 19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A73E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3
+  1: 4D9444C212955963D425A410176FCCFB74161E6839692B4C11FDE2ED6EB559EFE0560C39A7B61D5A8BCABD6817A3135AF80F342A4942CCAAE745ABDDFB6AFED0
+  2: 2661D03372ED5C961EE23F42ED9498B451030EED2FD01F29178955529B2F8A758F0444087C82AED85540C8217E959EB8CB43EBBBB77A7E0D2980D6406AA2190B
+  3: 7314E8035788304E57E68AC9EA89544ACE6D2379035697D91B98B64B105130DC814B67A4B46B4DF6C103016B8F7C7403E0B943F0291ED6909E2219B6E18E89D8
+  4: A6C01D8CB93A5CEC17A9BDD270B24C8EE78686CAFFC454F253D9B8DAD5398E52304CD57F30F2111BE78FD98338DD3A41FD8A45124C940C4A59F270100DD6CB6F
+  5: DB22986F9FECA154CCF0E7DAD914AE8C0851E170D116E9B550C39B373F109FD073395C0711745E40233226F96B5FBF6C8EF1D7F8E2E4AF5375821C897EB18514
+  6: 793498B98970BB3CF187B0A28D353AB2EEC8F6CDA12E6D484CBCCDB96B2BFE6B5278CDB38C9BEDAEB59A8404645DBEDFBE1FE54227947E226EDFD36114067F34
+  7: 052A7C4EC5AD200B6B8131F30E97A9A5DA44899E1C6C31BBE078058630D5E208FD6F2F51A796F814F8AD048D759F8DCE442C405D96D6E1B1A197AD908B366E98
+  8: 219B01987262C597603DBC495792F2423E24A4BCD38825A74CEE8ED91D55935296D80E73DB43A78FDD6119233A31DA5940C6E335EB22600729478A20F61A56DD
+  9: 4BBB8746D1D754CE91C27F3A6262ACBBFD4A38D100A65ADADD3174ED6EF8F6AD343F0ED2DF28309A6E979E02B12E732A3E70371EF1E0935E8A30B7C55146D9AC
+ 10: 81BE2AD26A90BF502C9514F46681276F927E916A630FAC442D823FE4D8EDE0FAE2E8384F3C267B56126F0C009BF8689D475C53425322BF8CD7F6C80CD2C725C6
+ 11: FCDEAB03C0FAC7939E8478FD152EEC2408D4A6C0D829B55AFCC5184C50706C253676CF68DA3ABC1C1AEEB5822898C5194AC801881B8CBCC8DB15930EAAEE9373
+ 12: F943E5CD2DF74699913B25EEF0B08FCA6BAE9E66BC073DF0BD950CA02FF17276F4A28393BCCCF6E567024CBC6C05C94EA912F1B07034AA375009F594B25D9542
+ 13: 1260728E085D172EE82065B3F878FE21F550748598E72A40F4FAC3F54B72A99E6B3CFDA7141C7E5BE123757AE4332C8320786408523DFC8655D7E1F7010792B2
+ 14: 67EB4E93961EF18A82152DE2882CC5AF4DD1254732A8FC1959147268441A80EAF0E0B68041F7CF013313ACAD044BD440F1E06D3E449D206433F3B52BE2C9E7B9
+ 15: 9AB90A3384DA32A03B31DDA21732B398358DD40D7586E836CFA047961360CEA2F1E3DD0CF2D90CBB57F68C4334110694A6C1BA17B1E9E533E6CF3A3ACCEFF84E
+ 16: 112C2ED4CE732E21334D7248A30E683246BA602AD3681BAE365E857AA840F1F80FCEF1B9ADA33AC1F9BF6FB75045F9E61449B26F9201E482E7F2ADC8ED9A1D80
+ 17: EF574EE7B498AA64F3ACBE1972E42B873C6FADE053A1459AB52D5E5B49C0AFA0C62FE901ADC3FF07A7D0ACC459C3DDB3F6D499C70B63F68B60B02E2784BB9AC4
+ 18: C6185B5836DD3B160695E5E27058AB266EDE91A5417DC086988EA5181DF5BA0C51DEB11F6BA14AF2847540BE368B6C561CD976809E2D9982F4D49F96E0AF4F7C
+ 19: 8510D305A5E1AB3A0832B242ED402BEC2D70C24B41BD840B8D2DE436A6B4DBB7CB5F7F9F1432E694F0CB1239EAB0DDD92E6D0C7E96FDAD5F8E465E286D7588EC
+ 20: 926800FF566CAFAEABACA9990772EFEC8AC956C3C572A360194F95AAAAE477F98AB7750B2710E262D039D8584BE79D93E9E6405BA25DFF6DCF29C54D748DD655
+ 21: 0F0B98CE94E2CC67D36086D153A2DF48F20283413407C3CD0570B619871DAC188AA37BA30BD706AFEF475BDA7AEFAB63055ADE8B792F025D088B51A08E941B01
+ 22: E6538F3479D33979F046FBC88D4BA785B072EF58877BFC9D1214FA8374B78DA6895D5A4F4E50E6AC6A237E48A73EB18E4452E7C8AD50C82238FA9B323C96935C
+ 23: 378E83B88847F234A6A2FF7304ABA759A422E6823334ECF71E9C3C1F8B21B016D9A8A100B6B160772FFF12482A50613BD832EF534DBD1D4D055F3227C7513F11
+ 24: ECFC0F6C168962197E181C27FC9AA1975FED01E655B3D4A7857872451D6AF810783184534C401709A63BF6BE6CDB1D1455C382CBAA6F68E8180CBA9E0CDDB9EE
+ 25: 8523B737250579A3787BD83E5DCC57F7038B393F003223A7BAB98EE4D040441190622290B164F32FB96682730DF62CC366FC33126DE2F7DDE3A38C818C48F680
+ 26: C6BE341A28878B733C30F50D67F6933D3A15A0950CAAB96B9F3D7D78C95C61874A400CAB65A100302D9E2DCEADC4A0C043834EB0433D5D684C187AED93B5EC6A
+ 27: 4AE827A36DA140D2271F74DF1AF4303DF4B1C319428F8BA94EA28BD3765BE4535275053DA49B630E6B754097ADCD7F17DC7C16158F43E2C1851951EC3016CD8B
+ 28: 6D3F01856A8A28E28EADF60401E84253C3F7CD13F3A9FB8F94D8B07B74F7416817F274903C135BA0DA4509A78D004388CBCCA75B06132C7CFC0156C03803E85B
+ 29: 07CDC2BDD9CDC49853384FB647736B50D788AB80A0A54A0969B86603B683C22A1C5FD32D3AC92E73D378F379C4BA30A48E7D38FBB867E981271FB3962C745659
+ 30: 9DC875BF987C55CE646A709E89CA89E226B0F15666D5174771368FAD768BF3318B8BC7D8CA80AFB5E6BB7FC0090B5559F11DA165DE51B940C9DFE911D4790477
+ 31: 58BEE92BE003CCC34F9CE8C0B323C6BAF1297460BAAB4998CB3B52D2BBAA24D1B06CB597EB2E609A008572FF93710E3A7F42AC53E3FF09D4733757EACA41E20C
+ 32: 888AEB1BE2BECB28598556A128AFEA037D0689C8D13D9894F1416B2C48B2551CB2FDA321A26CC4D7E1C87332D7A3C18FFB455C92C0E7AAF829FA40B8A28BB656
+ 33: 19099B4E8ABF225DC7BD1C1DC6D52F54E8FB7E4EAE0AB19293C686E6FD2828221A1153BBA4C143795D1A718585D9255B6DC911C0EDA5E0042A10565AA5D6D8E7
+ 34: 22B3ED65F64C8E51257A922FF90DC09447224B9A8C7B5A6A94D68601F3D4C7C1557BB90B91DF318EF9F8BB367E838D36A3CA82FDCB85721AEA20A8A2268D90AF
+ 35: 0D2B24C6FD5D772704BC17D2FC8C011F1511F92491104F3C22470864882656AA40DD07C0C329C8BAFD90ADEA7F473349038CE475D352DA41E24FF64723070566
+ 36: FEB43F7DCDE56A2EE963236C234E5800C011FC54D14396288DE5A7AC7DB2A72D1E8F63F04D1DDB3C55CF3BF19F4E0FBA4B79405A6B45ECB31254C9F1951C632B
+ 37: B8AE2C8427A750F34647C3529A05D44691B8DE0C79525D9145665BDA5C0C396C00E936BF2493F12945899B6FDAA9F61E6E7B22846023D140F873EE7D48D76BC8
+ 38: E80C49D1E29F6FAF0BB5C7B47F5A85B3A0EDDED84418890748724792CC83B53AB044B051722F1ADAAB713E5069E883C1D172CE0EFF6EE6AEBE05B1FD77DB652B
+ 39: 1FED03FA70436EF45286648ABF39057C33815E6A80A19E22009B89C809DD6F0099C944B882FF9DF3DF08DD51295F3F02FBAB40F606C045BD4395969E27647D24
+ 40: 2E3630EB519F6DD115B3E4818DB4429CDDF1C6CC2C8548F8CCA226A24F87A949A27DCBF141803B87B2A2C0F8AF830031DB1FE084E3996D8834F8E7D29EEA4AFB
+ 41: D54509526805DFC0871CBD6E41ACE395C64373E8F57146A657C28BB3ADBF7E57A152D27BE24B8F30F08329C2E040359B119690D9A1118BC14A3B1883D093466E
+ 42: 0AB062968EE4D71DCE807EFAF835EE11588854ACA0959B5341DDFD10E70BA9AD427D92168B31B8E6EF81F58615AF9215A8708CE1F144EE29901D1FC282C3F78F
+ 43: 45862B0D0F0AC5CC1C5769C29D786FD3AC788CFBCDD6CAECFB120D05D71F2575F4174CAD5E5A00D2D740D0714E92822427085F044A72D66631755BC55E5BCC8E
+ 44: D3A9EFFA759181346D8FE53130F05B2C65F96E1D5908A61DA8FA3A9BC551A7781ED7B1A6CFFCB2F742DDAE8D22B0EC99D82B14EB85719253693FF920FD5071D8
+ 45: DB53395A78DDE62A406211955EC56C6F7BEB9EC2275501C35CA955268C3E2D71BA246B4286C76FAFDE012F9E2CAAC8601A74699B466023FE9F8B1BA26F65042B
+ 46: 9426FFB7B70DEDF1CFBCE6610583CDCD91AB421FE39DDC31F4215CF7604B9050C84A3BA29C4B236F1CC3B09F53D29229132FDDDD9B468CBB6338BBBA6193F84B
+ 47: 3D74F17DC6FE057703C72452BC7A078EC019424A89783F1FA40003657C323997DF30BBA38CB4B16BAD8FDC43260956090F765C26AB1FC88BF7F87EACA1821B52
+ 48: C6EF119085EB17EC1B9F74791D95E366FE916F5397C20857A8966C52512F4EE16E63B53A28F7632A867EFC7FFD8080B173D5E2E33A2063FEC7D1181ACF8C7824
+ 49: D878B30402FECA5EC93362105D5E183D658DD2FD38B8173FF609740CC84239C4F8F533AC3451D369001CCD4AC78814058DE0F7E1F93D167A46E85E3002F4F386
+ 50: 948C4254AD2C5658A28D42DDC3CB4FE4CF731B4180B8A4A183C23C54CCEA045307422547600598CCFFD3C6229DAA6CDD006D3C782ED91AC61172059D016970DE
+ 51: B74FDFED0388D5164BEE25E37C6687FA8D5C069D4FB0D42A7F1A270A676F83F24FD1C9048EC0D49F7BE913D893E0015E0A3F724653B3F0AB0017683948712E46
+ 52: 497EB803D053D5DF498369BADBF8AAD57ED1B072CF361D3DB2A528D3DB16DD962887916E9D21FFB439DC2C025CDD8C21ADCC98A23C8C5B0245F2D71CF728F10F
+ 53: 63F4098F650820EDCEA3E7C10B65D3B0F1949A28FEA323702F27C7D311C7E6BFC82D4C01F4FAD06FE0288E410EF325DE192F78B88E04075FA9581AE2B031A68B
+ 54: 337914B013B8056D7849E42ADB47FA761B5AB05696CB8FDA6B87FFF88B0477902991AD81664727164053E4E47ACDF880DCAD0E0E67F7141123DB494450CF0B61
+ 55: A385FE66F8C852638F5BE44503B680298EBBF27DBD9F20B1A0447215C0E2C1078926002113A71C78148D5019FB22C8132DD05356C78A1A8D8E4EEC5A6442DBA9
+ 56: 218336585A419E9877CB63387C5E759FC93F0FE1A7BA717B8BE9B2302393E0D14DEF2F749D138692D0A0296F1C792B567F40037DD2B8787F1F47FF363CF34F37
+ 57: 7EB842771A61A9AF779C8794CA055518E7F38CD13F61638900EAAEA000B12816D52C593B62B9DAD79DB7397A463AB99A9D0035E7A1369B0556D593DB41EEEB6B
+ 58: E41D1492D3472FBD42F2460650F9DAF2ECCDEAEF5F4516B452D940DAD516F5168439154B4BA76610461B343BCF1E7DD7DD8C285EC0CC46C17CE3C7E14103042A
+ 59: 88057C0B8442BC5763283EA17FD1FE1AE011A988E1D7E0F914004CD3AD2E06FEEECDF59E309B9EBDABF19559954C37F71FA98C14BB19F7B91CE5F827C1DDE1B5
+ 60: C5DE99AA273D1971272263C740E689739B39725A0B7C48B41577F05738A24F5EE2C0B673F93BD52A083798DDDC6E70A209213B58C95D49ABC5BCBABDD6AE7D22
+ 61: 68296AC346BA3B14C038CDC629C5F5700CEB9F5DAFD94F948C6B991C0F91813BFD02660A2A05A02A61D8EB03BC93601F9F6A38196650047E1D7DD1071CC6974D
+ 62: 1CE0E6793B0ED59C4DB7D5F24FEF75A4ED2F28CE4AA7E5EB25919219C2C04935E4B15841821FA92FC7537DE2A538871E5A043A773CB1ED061333113223248C18
+ 63: 37BF321F66ACE827B66ECAA651CCFCAD30AB627E717AA4FE441279C4FA48555CB7784B0AF25A73B86375BE71A1E3FDDEC661E0EB8115E0BB2B9A7FF81DC75DF9
+ 64: 5C3C6F524C8AE1E7A4F76B84977B1560E78EB568E2FD8D72699AD79186481BD42B53AB39A0B741D9C098A4ECB01F3ECCF3844CF1B73A9355EE5D496A2A1FB5B3
+ 65: 85A19923268414DE6A10A2CDEF7917D7AA01E68DF9D028CBAB5C5236FAEFCED836BDE9CF90D8A214013056202A1BAE5CB73606078C5572D8FE85C36002C92D70
+ 66: C2FB9763A6F86225F6C66F55ACC8E7E17C1A2664416B2704D64AAC2CC5B04A626030B5243CA61D62076DDBDF3C6B3765C38D0CFA01D4D45C124EA28DA593F84F
+ 67: 5083280300FA5A1B172D7B5CCADA5CECE1EE5B7B5D382EB4A430179EB133970B0B89F6BB6DCBB1F38EC9F13F5B7D1559F114DE0EE26178EBC56CBE31BB26A91D
+ 68: B3571E8C1CBC0C58E23094B39352D554B43F9E7DD0FF981C12A01E0D8BBFF06A39875D90BEDA7F345550E6F67935A49E0183456B9967BB319D74AAD87CCA3695
+ 69: D11537B780D458D37279D00621F646EBAD3244A22E4D45DF11AC5D084FDF70E7A32F897DF727E65EDD1019DABCC05DF0B5E015FC5CC1184129C5DDFB14F62154
+ 70: C146458EF40E6F1944BFD863B2862A97145BA580D47C7ACA67E797EAC6790841C57D68A74930AEFCD49031819FBED806A0C033DD529A203B4E460F357BA1BBFB
+ 71: 660F3E1D5CD3B2AFD95DB0D8C258F6AD74DD40DB688A37AB4A24D720766541B1CB928001EF6D67CE5429039C9C1490613DDF90A27E6152BE7D42E1614C590056
+ 72: DEC468EF73E98F44B60EB994935921F920DC0CEEB7498655F0FAB7607A77A7A3D9462DD8BAD46CB408EFA81FF08D7E9508BC565C1578C37C2B87D41A0A32A549
+ 73: 070D4C36A0934C5C12E6B65FFF385404E49C3871DA8674D93D26E3166A7EF9693D946B419F0E10C9624964B37493DC8A46D26D8AB8942E60143036659CA4C91D
+ 74: BB8935CC84E08E6B4E7C6233E41D880D70CC018D1668EE64F19906A83730495D01AFCE1A4EA8129A98B7F9E074FD35C0BA6D5667625DB63A867BAA67BDEFC190
+ 75: A0A7A0B619643115C582BB6953D2A3EAA942451F631FC56C0933B535313D668FA4CA7D6BEC4DC9FE2AD7528DD6F8DBE68478A040FBFDD2F3DC3AD7035DB67371
+ 76: D6C57C3FB08D07A30A622B25985A52A6E552499345244725B1084E41691B11EB31D3B9776940A9A7E6115D2D1A93372D3A7388D87B01D13BCA726E8823E89729
+ 77: 413CB26BE2B1BA8ABE930ED1B9978BA4874CF32B38C825CB6DFE9C21A87C0BD115D3357198FDA0A5B7CDEB4235A354E9C2F37D11B33AC6A257DEC67326830E23
+ 78: 748E4648FBD009E4848E44A284D0CB2088300F50CD5215A285826E968B9DA59B6322E1987F78447150AF72CE37E516BE9E83B05A9817AB7A924ED8B09557CB5F
+ 79: 0A8111FEA824D43E0991C22FC3B1368A191D0C73308283494309D0762AB1EE5AF0CE2DB8F0562DECAC636128688540E845D72BEA3852A19CA2ED22D6C1E82CF1
+ 80: DB1067879F014EF676471D950A81DA073D676DE52E85F67890C8471FE6144078DAF940CB6F9F097BEDB8FAC94C737C5B8A3B4217CFF4A56DC349B2AE845AB25B
+ 81: 6165F19F569BAAA3A3ABE6D6108D07E1ECB22092F66227DC27173DAC097118C2D927F2E5F7D20C8CEF0F99C6FE6C7AA46BF18FBC452F6FDD733728030CD0A4A6
+ 82: 1D4AA14617A4BB9E48DCC1A7EE5DF65298AE45FB193F077FDB6D1C2B3252E1633AF86A527C29861661CE155A47E5BAC91D9B07715E0FF7E08B39A3128891EC42
+ 83: C2C22B53D6BA460954C2D826FD3DEEE60E33AF2EFC87A61CBF2AA021166AFB90967ADE2C564D037518E4141BE9C0D0BC0B4F95498D5AD920BF28CAD4F5FE700C
+ 84: BB5E9CFE19C6A2D14EA4C1F6BDE51855DF61D650B23330BAC30A5072EAACF86CA02AD31FE4C146176DEC75C56A56C2B868177E0E365414508D2E7606AB9E8921
+ 85: 6B40A13C5486396864608BE7285BD4D1205180BC41E10E537042A1CC6CD12FA7737B5E73D768BBC5D687FCCE41880A8D9773C26316ACEA2D78DA26FECCC11E90
+ 86: DAD0DC8A7D78E29B12182D36F47B93CAB562C44FD6C5B1718651022CDEEC30133437431D13C43EC1C02DCE776F459A57C29355B3FA0D67C6BF84AD26194A8854
+ 87: 8118AEE5DFBD7FD9F94403FFD3C6BEA08706D4C4DC78CDE72F751A6C4027ABEC7786A62732819ADC036B787E25E151AC51B60BD2381A64F05A326800D7514B15
+ 88: C64737334A61872EC00C8A3F1B1EA931FEE8D80203CE6DB9F1ABEFEE2CD3E652971615AE4F9A23400B9E31D861BE6B7E0F6DED28ED74B45D6AE90E70AD49508B
+ 89: F927B571B03B892B46C0A16148F13A2E6B80630CE41BA7DBE311F9ADBB5E8F23923CF0CA527DDD20BB3FE42BBE805066BEAD569F6FED12A2722A8629427ED841
+ 90: 2576A445CCD8977F24F50EE30EA7A51F0F3F49D41BAA663BD1C1734E02367A382E3D0E8C07EAED0C6A47CF662FE573BAE5593D9C4BA8FFDB4AF024F6064F7A89
+ 91: E85C73AEB638F35565BDD2523AE2A86B573C339B4D5FF8498ADF71BA587CBF146AE63B8C920B2F0A166F802167A04CD0D7F7A842D7D058165894CF9188289032
+ 92: E74E2ABDD6AFFF851EF78F8A866DDE9B9F86D906B298DD1E3630E1D4A30B6FCD7FF91943A57367A00E2658A84346F53ABC896EDAA395167E5EBD12C954E0B820
+ 93: 6827226985276BA731A9AE2E4DBF2D0187C05D566F06D098E05E3F425DC058958B50F09B4CE0741F1375E9B522F94A61F1ED8A43A8D03A036D2ABFCEDD4F0C1F
+ 94: 19A71A12DCABA1BA185BA38BCC0D915584A801EA49F975393B25AFBC456571CBF1A6F9121CBAE89A9B438092C65532489A95A0864320102EAD9A2EBD30D41F6F
+ 95: C70F19BAEA7420A7482C9C54CBB689A9AB93E4F8538EDC2371A1EDB3A103DFB7176E04DF170FF71EF46DFDAC1E8F9CD6FF96115BE1EFC271A56BDCFB67D29E67
+ 96: 8BBCCFC8815786ADD9F108F4381A2B084179002AE940ADD4C42AA2550C353CD0351C2F7F1BD544D8F268FA332B0E803838318A39079E9D93269A01EAF9CAC967
+ 97: 5266FA966A04B8A2450ECF3826C9E1516FEDC33EE81D4911A601351564D27C8BD4A11BF00E0DE237E50D75421CBE475E38967F28E6A1C5D311A2C95B84898D1E
+ 98: DF87823E1E02AF34532C5F3A08CF03CB9B2017B835525B3E3C448B1ED15569935D9A1DA19A6B1E8D056FBC868447ABE6226B97F256F6B638B052B4BAB3BD4808
+ 99: A1317CAC2364B10EABBD3540B6139D337C0EB3F7A740C050988FF9B3584213DF5833AAD81D36C30CE6CE76962A9E1D45F08667A314036A299454F25F73EB067F
+100: B752B6EEB497A8BEBFC1BE1649CA41D57FD1973BFFC2261CA196B5474E0F353762F354C1D743581F61C51F4D86921360BC2E8AD35E830578B68B12E884A50894
+101: B0BB23AED2CFC9C58C8BAB019CD10DBE75717EE8F04AA45FD8D84748E3F05C523FD2F70DCC460F7A18DF7D28A224BCB86CFA4C8164D081D51F3487A7BD0C8109
+102: 0FA46C6A759DA9A3649679780A28FDD51EDFD3F99A4B801C5824247B270A137CF40006609E149C919CDA0A6C856A9A8E855A670A2BB2CD5211FAD42E84F6E365
+103: C4E350267BD335848D00151AF2C380E49A323E63AA264D534EA1BF7A860B764A78993F7FFF34ED93ACB1F5A5AB66758C462B4D2F2F4E14225D29FEC0C102E772
+104: AFA0F1DB8A321FC6C4EF7C65ED2ADC4B094E928E230D27295699DE68FB5C1657FE0E5C4E66C5852ACFC45DA94BEFDAC89CF0D4174B262E6FD51CDC3E7FFFA5CE
+105: 9A86A440FF8A33DCD38C69D7564EF827F614629CB699B7F45E7FFF1CFF4AD5E27EFFDD32EF1D0845987A6A273EA34C19374E9FB606BB2E3B909157CC6666D29A
+106: 1FAF8C564575D654133B0A452EC43959C9F9E20C044724B74EFC90D2CECE4C49A0512C9F4DA2E999552E3ACC04CE0F0E2FDA9826C2A1FBBACEC4330081D5CA43
+107: 8B35FFFCD91E617C8A49B13CD0FFA2199FA1F20E5633AE6E95881BBCA02B1E047392DC9A4C0F0A4C39D3984E78ECC4DCC1B5C94A26ACDC1F69C7ABABFFB45175
+108: 6C8AB69E946FE86DEF6F14B955B8F1977686EAFF8E384CA45F245CCC0EB1C80AF8E62B0E7387C0DA52BBA31B1A01EBB00CA26CBFDA9D8069A773C3B62F989A2C
+109: C3A243B45B7C3C2002CB197BADBD84C4900D504FCD277D2DC6C06D34B1317B41EF098BB980800FA9D011C0363D074308835AEBCF3393B1C925045E97E14831C0
+110: 803E065AFEFC6C48EF9F701233AF512465729E81B0DBFF99A2E7FEFFB542831E1D3B30230BFA2F30343695C060AC8140C37CC8D1E25E95E6A1139C5522F4ED28
+111: 86618429B8720ADCBC8B9FEAED8BD44E0848572CB6137213273563EBFDA859240E17DFDAFF68B09953F1853C9E7EF217875E7BD6959E76DC3A1CE5F548B76CEB
+112: 96439A93295B5C479F0310B28377FC10DF81B593AC233556B15897F1FA3886C940639AFF2ECEB29894DA884626B4811254FE2622EC7B4577087D9046C96AA556
+113: 9F7BAE13DB80C72A434BC4704998A73D7E546CC2590E0D0EE511CAFC63C622A8B2A296426E42754606D02B6EA060892E325EA1AC13EF0B523A3551F4D25BE241
+114: E999A862E5C479B7BB21EB52E4BD301571A8A39B712EBFEFAC720F28C515025E98CCC74B950D57CF3C3B34D788D62CDA0339AE0DA02C8A107BCDD797C4751FF1
+115: CD00EC5142CBBCA87BC15D69EBE96B5222F25BE1576B318208178679B13A9A8BA4BBABE9A488BB38C4EEF327C9A4DEA4225DD30C0F70B97C18C5C2FB19FC2134
+116: 1289951D2B62112BA590D8C0CF9EFA38AB77737F994060596738612E6BDC41EC8672F50A027A2C049299FD39E1776BC3EEBFE3E66CCF4009615D63F0A4C43ABE
+117: 451A46FBDC954FB76E744AF3DA8429C881197F6BC12D22412438729288AA4540843B9FD4CD1BDBA5E864FEAEF0CD6CFF045A37510B3759FADFEF4697E9BF9240
+118: A267FCDF72D9160DA2A01E781E07701478F95A38C262ADEBFA194EA6D5A50A9CF3E04D32AA4B492580C6E8D8FAE1F813F3C17F82B7F47D8CE0C900F0F3052F98
+119: 3D910AB6579455653EFC939BE1B22D993537408086361008EBB166724FAFE3C8578EF4BE0378BC28ED883FC0FF3DE5A9310CEDE65FAF3AD9590A13B3CA4F81C5
+120: 47386DF4D41775737BC4E52D7CB2EFC11BA335A5D59597B5DEB3DD0A35032461F5DB4779D48BD6F3A10C5503AC563C790235E6F54EA79CEADB6A56AFCCE890DF
+121: BA59044EF3A242974F074337CBB6840FA0506C2227A429498F546B2CEBE0644DFF1D442190C48CB54BEE72F960670F71AF1F8402AD5ABE8C1482DEFA881FA903
+122: 89B4F35E5C8C19AD61CF1600BA80C1A1BBCFDC86AD9F8066C967BA10F62827FCEFA1EBD07C90C82B48082A5B7D6A72E0AAFD230DE05955C7E8C081286B0CA96D
+123: 0C7F94250F4EA7647F91E7EA8B8612AE8E7BFE4F5BCDD90CDCE564BC9842F6987AFB4C3661D8431440FEE18EB2EC70BCCD34A6B61D209CB72BE782A0808C08E2
+124: 2C8B8B17820085795BC6A2720B5D0BDF5407D9DEE1CAA4270FFAD010AE9555DFD2B74A742512BAFFAA1D5B4F14ECDB2BD4BF37838D5981A317C7287805974019
+125: B464C5A9D040F11DA45D98C4BCA9295D0F589DB11EE5603410C62BDACCC329B9AC14567C3A6F3BBA4B92CD3B95BE58AD4DA435199CE62D8BD61269F8BEA38FE4
+126: 2F64554FD54AA4A04ADE3793AFCC5C968B1C3603F4F71E1BB5342BA4E951D79A4580BF57736E7FC13A43604A057E9C360C099AC5B3403DA8AAFDBBF417FF6ADC
+127: 3C9A7F387B7104DF19CF264B0B5821B2E46E44ADC79262546E98FFA113EB3D45799EAC78CCA4643C937FCC3C1D249A212FACB34C63D45EEC81069095D7CDCE7B
+128: 803A3B37C89E84FBBEC75BEE3D00DD728FFC4246B5A5E989DC8DC2CD0F7937966AB78C79E1D4648EE6EB40F3D70491CB46B8AB42E155672E2AB8374FCF70DD79
+

+ 131 - 0
notes/hmac_tv.txt

@@ -1603,3 +1603,134 @@ HMAC-rmd160
 127: B107A8B0C7B68581969A0F6DB95DB2F790098F1D
 128: AD090CC9A6B381C0B3D87035274FBC056012A4E6
 
+HMAC-whirlpool
+  0: 5C36BE24B458FD3713761955F28353E433B1B818C8EF90F5B7582E249ED0F8C7C518ECF713410885E3FA2B1987B5DEE0FBAC210A007DA0FE995717F8FEA98995
+  1: 30C66EA7CE95764F4CFCFBBE4C166E80A1F23E8C88D2DB7FAC118BCA9EE28299778610D94CD545C18C114A2A144F9E933CD80238E9F1AC737F7149BA232FB846
+  2: A61FAC4DAAADF3DB746DCDC24CACDD8C2B74429CA812D86091B5E7F8186753B34532047B3263D2E231074CCDFB18188747B657E0B685693901CBBEC524949244
+  3: AC3BBA8D998C234F9BCE9A96643E8EFC342F4772DF5606A812C1C6CFD644E8F2B8F9BD724CBC8D769B74C52669705BD3AD390CA61DBC7EBE4438726A91FB2455
+  4: 59AD4171B4C33E09312A01B97B3BC2B7DA43F8791561E32A9186C9B0C418BBC31DF54D6A9ACA00910C0F3DF5D7C2DD7CF5634B76506646B7D4EE5C60AA7C7950
+  5: EDFD9FB5B7BCB39811D87A890171096AD2237B78862C4921191F8B0B137DE5178BE8DA898B6A895FA6C4F401714D2AAC743F512F8989E39081F02A2A0F9F6137
+  6: 6BBE26824C7582213F89F773C520710AE400F01B99BCE126C5F3ABDE79C8B304139352427A3E25A313A5F753A94B55F1EE9D3A0300E8E987E98004F58707F73F
+  7: EB89DDACA2BA68940C4616B3B1BDFC25D94A78B8C3A533F1231A259BAF6A6706E1B90CBC2F21A76210C0322C7E4286E393B167A2455DB24C6B52B0CEF3EB78A5
+  8: E8AF385440589959D67746FCD40E295026E942E44259169780B3954D20CBFE2586D2A8BBE408AC2D707B0FE539DB43B3E9B29A8D26D09A41FA6F191999A45186
+  9: F6B9CF6E0A337906517DB09EFA31E91D57D6B908ED5116C13B49B8F1F3C3A872EF42DED53F939CC4EA4122FD8580D528AD2DA72BE063251CC89FB52741E2AEB2
+ 10: 274FEF3E5EF7AD7AFB1161A29492F0DF44BA9E1C30E1E88CD708A5D27F2B35C45085A200E9F42F340B0D9B3A1A354B1F5F6D0D1A754D51DFC39CB2EE213112DF
+ 11: E2EF7A0A64A3F384F95823201823BC95060707F273E395F46F3C0627E1CD2BCE97DB2984C0EE7A11B22E617F0CF64A3F44BE9FD6B38C3A07A504DDC1D33C73B4
+ 12: 681D72B9BCA446200BA7578E038A8FC418225BE5F02D8DA3CF085182628B7BE587DCAD4851863CE1CE8653E4916047F8E92E91A6B0D7FFB065F316DA93C4F44A
+ 13: 2CC82F237ECC1B9B0B9FB76E6B9651C56AE57CAA072A0C20B968F2A74FCA6A9749FA264331F4F2612AE0DF32810B0CAE95E5861473F4675766459B7380F7B9A7
+ 14: 1F3818CFB04AA3882442FDF1F5CB0DB2FA9604228D3CCA1F14DA16B35D9B2071B372996A176AF0592F00175EEA4C16A6E0162DE62DE30E8A80FA669FAE9A33CD
+ 15: BFE4BF868A8AFED289DED5F6E7B21E6856107EBEFAEAB5CD644FB5634181D52D8DEAA203C468ABD279E9BE73507A690C0B715869F6E722C4512E815FA4EF641C
+ 16: CCBA3834AC7BF06B16675376ECCD96A0F91E3E3C588C5BEE1711A00C107B35D603B20DA8E5CC5FBA6937A24DA53D8F55C907F3E53F0F255E080396426E7ADF9B
+ 17: B09F6898640E5CF77B6DD3D5A8A4452F4F1D25C90F7AA55A205EFF2C319EC0BE245CEB4190F11D85C2F7234BEB899BDA465C95A1C59568987C4C020B9A7AFC00
+ 18: AA7FEEC56E16AD79990B003AD51626C87C9CCB90EBFD748DC268C0C8C1DEE1BDCA1C8064FE7570A5C624AA0CB6BEC163E63680377A16AD49D1AE166090DC0D80
+ 19: F755304A4694DBBEB0E59B978943F3D4E429F8123B3D6CE27AB400D3C4BD81A13A8C3C0BA0FA7E5F13BCB0B48290933A05DCB49A5907C074039427F0EC9004FC
+ 20: CB8B5804EF0478645400B1655DC6E194C8DC26112EF76C57823A02F39C8ADB42F1225B130FF0D40F580DA8CA95D82C0441E3A82C206D9D8D6DBD63B4BB1BCCE2
+ 21: 4EEA4AF294C458BDBA7F49AC0826BC295BAF5B16D16F40D379F6B7C3456EF4145B5EC7F7CFB85638F641CF4D07FE3904DA891E68288FC11C0C72F54430915024
+ 22: EC52FC8CC0F849E633E3F7339031DCBCEAB69B6634D3E54E7C153CC63DF7D3D3F93B13C8E751E79290ED4845FAA3D5A79A7DE6B100F538E0FFF470A51CD630E4
+ 23: D44419C0A36FBFD0FB441B596E8821D3F543D80FC7EB5A3389037BE0139921027571502B5C53BA30D31D4A053E830E610A394842229E08485A2376CB9766313D
+ 24: 3F4BDBC8A4C86B3F646CC445E2CD54B4C786BAEDEE9FD91A879640B4085D46FEBEECECC95E819ECF6AA9085C2309E79DE1A988C6B68930ABCB9BBAB90F1C2F85
+ 25: E5EBC015269E0E61BBD1717618C15D44953AB6F854D962A04FE88865626DCDDEC5F094AAEDCB708D947A9547A985F0B287CA0FBBE3FF2ECCC4C0C4FEE4FE74CB
+ 26: 010C622DF84E677805108A2C5FB1E8BF5922D35CFAC2408F2AE174D353AF169A40169709C39BFE90E51B095C8C0D2886B4F10B37BEFF805D384E29CECE89C4C8
+ 27: 3E9C7BE96E03C48DEA773204E1EC3721EE817ED2403E3C8F950A4C447949438037E2AF0A030CDB983D3FBE5B82226F510FD91CF8830F59212F8CF26C2B5E4DFE
+ 28: 8797C9C14CD2DE3CB1D29808DA9F23A5502A7BA579586DE9513B980FC06990DE0E29837ED06E24B15DD0000697666B8D3DDC556D818E87F84D125697D5E2F8FE
+ 29: 93DFA3DEB3258FC7C4F5362D36C2AE21AC0471AF8B895B5AD1C407E8D50DDCD0111AF76EC500D7BE035E6F9CE932190712A3F52FBA4BB0DFCE74400C82D1BD8F
+ 30: 5587EF7A31353C0E9C346C837EA645770BC5F5C541B72886844B4B0789FF1D95134F558B29385B35960AFDFEA7E3AA40562C12683CB7DD9A410873565CA10880
+ 31: 052CB0FAABB263A49516E39525023E2A02DCDB2D5FC78948E042E59F89363FAAF1869D42EC9D7AFB0DADB7D4E99544BEDA92E3270544900A5641F059571B6238
+ 32: 2FAEBF049CC4C9C2770E859739B1774EB6E6AC2EAF1AF7D3EB55774C03ADC4C865A65C82E795959CBC4BF00A64AFD2AE0CCA16D58AEB874E253FB9FB9A266790
+ 33: 82FBFD2A46F2102AC27089B6889024FA9172FA691C1E3BA9B44A394D52EBF5A7A8BB2321708ED9AF2776D8BAEA13A5F2E9EA4AAF420A24B6F59E2F583D54A797
+ 34: B306D18161C766DBDC734FCEB08D14248EBCC63FCBB5B9CC0AE9D690E20E7152D771B3D623D7ECA1CBD305A31EE10C220FCDDC2CE76B578E2F15DE4741E9C9AE
+ 35: F527D57F0A5F13D7FC6A30A84BF414712044B56FB8F6C1E1375A09783968A851DBD495D51C693590E7A8BB570A7F1C0C9ADAADB74EF8EC71A0093D8D1A4285EE
+ 36: 0D9F9DB43A0FB4BDF70487002943A6CD3BF200518500B6934BA518B3B0958095930EF59BAC48C84C1E1ADB815A6569FBBE7E61F039BFD8C2F727EF4636542A5D
+ 37: 614CFB257400128FBBB7B56550E86198155A5647FC11111FB4D36073BB57AE4D9C0A54BCF0DCDB8B54ADE4FF8AE5645821CF9C83F7FA9468FC2CCB552E30BEDF
+ 38: 7032724503FA5B0765D610D3FA4609F4537F6EAB75D7CC4E2A15D2B1421293D9411C9E8F38999F7D64D607EFE95224331E47FAD4F9BDB6AC19CD3ADE47C17E7D
+ 39: A8E4316126475B429E72432073CBF26E94DA450DB553D46667D597F0AACB99325C9EDDB94F8CE33551857827AF3935F2DFFE1EE69A20884D58E095390C04B925
+ 40: E7E90B19E76017EE80E4979FE56A488AAEEA011DE9DC068DBE53AF06ED44DA4CA3BF662358F191FE2842B083BC5DF2D4183668F4E7FA9E2750869DECA7302202
+ 41: 818D734A02A0AE76A0012D7BFE983B17CACE37D4890214C7C53A81CA9F42EF0A472101D609BE5D3DF4F0A55DAF154C20A1A97D53112E22D136C03004FE09149C
+ 42: 0B9F5B2D4BC3DF781F55ECEE149470F3BF68FC51D121D021DF0CB8D4A5EDA42EA6840DD735ADF8DED72B325662BCEECC6195AE831D169A891F6663F8D7C6E0D3
+ 43: 7A5AE42C635B250598C536E531FDAA1746DE2EC7984DC1BE488DE4766D0CD544AB51AB1E62A8A170D120999A61CC6920DB96935F295817851A4CE285D2755112
+ 44: 95093085CFE52D746C54DDF8D2FBE33EC00D71C39BE0865B896C331C7E5682FBC0DD84ED15B3F790166D537A9A68EEE5FEEC63FC761EB854018CEB68245CCB90
+ 45: 8BA177C495E9832CA8EB55E67E5D7F34C59C4C59D56D50BF6982B36AC341CBFDFBF5A98BBEBC26A9509FBDFB239312DF3B3D5BCE70386EF0E593E17A621F41F5
+ 46: 6DD39D94235D012C89FD030341392AE42BE7702C4D8E725C4229940BC273EBB8EDA7A6893B4FF86D1EF84DFA119058BC6C8CA47675492A0D37C859E6D9BD5471
+ 47: 13A2FBE3DBAEFCAC5AB8BBAF91BAFDEF5FE38B7F2EBA8BFF0F44B4BBB236613B8BB122BECAD9852BF7638E48F0FC656F9C432D9A66C1188DF3FD1D2A88161139
+ 48: 33B9B7EF63B302C1C79E0A43D77487C55D38C53F29C800B4CC287A99A440435121C7ED78BE7406349E65AAF991EA0EF19D06C1AFBB814FE4E0BD68613AF0C760
+ 49: 720E1005ACE28903D9C2B6EDE02A52F89860788AFB35208B4B7C147E43BAB3D06445DA138606F334624C606DFF288B0C70B487679685D1DDD26F1DA0A5F6839F
+ 50: 2A742F1E8CE6CDB501E8AD9BD256786A42E7F1888D9803AA8D5750817B3EA101331D7266298962FA28AF2232BF956FAC7C1C0B1C3DE4C5B3FDDF8E63BEB02185
+ 51: 05CF6361A4A238091A1FD011336F7F53B9ACF78BA1B96997EE49B99FE36F0F1163E04B446EEFC117B377593EE078B85BB9588918C76612E2A6F9515E0CA244B2
+ 52: F510C877546FD2D022051364A09F2051523F8E7FDCD3E9D2AC5158205FB36CF25A9E0FC394ED2FACA7CB4F0639B33B706FD4D072D62F6EB229E4D7879DFB45CD
+ 53: 2664476D94776DB52BAAF3B2DE05A36D3E35EF44ABB6F09670F37EEE00C2C54B38F70D06359B20F7E40E22B42901863864EF89EA473A1F3C834D22176E87E617
+ 54: 62620CBDA92EC8241DD3A6A0EFB28254B0CEBF3E2351B10CF93029244A6A3D1DCE10D9A895EB6E8A33108DDBAA897DFF2703757DA3706209A7871F4274901E3F
+ 55: 51282A90B63998F7AE7ADE4787D957992A81D3009D6AC5BF824DD1507B53F6918E9AB6AA1F36373D5E5D3EF8D01AF9D05FBC224781C62C1DCB4A2089BFF5496F
+ 56: FE1C4394AE26E4B85752045DB14E0AD378726BC1C985C8805222B614C62721E40B2A0D21983FF40AACE8E5F9CD57BA62C37C8F0968EE12FAE14267D6AE906A7A
+ 57: E570E1183CC6AD7A2C73D7D0E96D3AE0605039603B6F6467FA5CA62E4C1424BC14B17E9614F0ACACCAFC2B1B39D8C081B05DFE2B9796F32C0C742FB09DC7B8DD
+ 58: E690D667A94344E267A6EA7F3F7A6A5385C961BB6139800CD5257BFD6C4A672DB576B52335D22160A372987D652741EC3AA9439B35D8975AEA49698F8D5528E8
+ 59: 59FE977EC1D9927FB09389E3D31272E625F089AA75401D1B541DDCE8C6983A363622CA4F2AA9741F0D1484195CA31D6D315DF6B66E74888D111FEFD249FA0174
+ 60: 2CAA990D06814CA73ACEFE0D9A815589958398999707BD52C3773F61B2DC2F20EE7AB7F66D643BD9686C4C460AF45D58BE9F8DFC1B5CFE3A5C2DC2C93D9491A3
+ 61: F198E9238E9592A97DDFE1B0B56DE5DC05D358940672D84F15E1CE71ECFD3854CDD38762DF11E1871EE615EB6080E329495B37B23710DCA9F4179F5F95F3E2A3
+ 62: 3D7C45603510C6916226B192C81B90EC213D30C11AA21C8520437CA5639D00EAB529A4C443C9A39C5E40DFEEA0F685B3D0E1277BEBDDBF80C3D5F9C8326765D9
+ 63: BA081CA12FFBE3CA8F1E2703C96587634F8EB3BA140F93D997B6D0FAD1C1915ECF7D77CC0421E639B083451EDA605571D68DE81E7A4BFC183D7A53A07122168E
+ 64: CEFE2203F6428D267CD2E284C3B8C31E1946558A56A33291508093DCBF64FD5FA4D33FB723ED49CBA02D97743312138FA77AE960EDF5910E3ADBD02B1203FD97
+ 65: DE0379336B1C7421AB4A7F5708BAA3D4E15CE75CEEB8C7349265E71942A963216559FD628C52F71356134AC328D0315ACB63A06382D4251A28127380CCEB08FA
+ 66: 95FD3399270415A80C2F295957C0BD8E33E35C679C31B2118DFABD542EF02F6E2E432559ED4066954AFBF90C982F60D73DA8BCC94DD48BEDBB00A8E458CCB6B8
+ 67: DE49AD8262EACF733B567D8F7752711ECB5D0FF5CB18E5A99C6C35442E652643149A51C820E6D4481AFE63F5B6955105F8173DA57DEFA392E43F7285799A32B9
+ 68: BED41AF0733EED85BB26E8A06949AFA1CBCA9BA87C085BDE29FD38F94709F4AC20360F7C7958457D2C49BC5A38FBA06D6A6AF77ACC883783B357032FBA9F93CD
+ 69: CE72D475D983EB5E528C4D71EEE48EF337E1723DEFDF142598E4CEB3B2978B1B4E36A69EAB6CEE8F3DB2EB353CBD27BF7D41F73FB184CC8785DDCE8EC22E9741
+ 70: 24A8A7C759F59CD3DE2E3BA953EA975B60079D9B331AEC4D1F4586FFAD190EF53C2EC6BAB566660EB5D652D7D54265B8584C6BBF986537F54F9D8E4068C01F67
+ 71: A7CBE72C99EEEACB387D4532BDB651EB46B8D30A9D5DB8095C9B3422D9D5C9480AA820CFAFE4047AA0546C03DBF07424FCF7B812274B3CDFDC76B9FBBBF08190
+ 72: 16D536D1D673F74D9E298B16AE65C65E467131FDE5B4356FE16E3FC36624E19FA7B55727240C51C20491F3122A1AB073B98E095A24F4B3260EBE5211EA2DCB0F
+ 73: 692189C1FF6DA5862657623BC862F5041D63A2A1EC8986139CCBCAB114427B1A2500B152CC611C5D5599E9792F014A640FBF7C6D944EDA811CD92374326B2C52
+ 74: 273E18F4B94E624988C47CC45820E4552DCC53BB40A9A24F744A14E56FB1DADD3EA4087A785AEDB5400A65971709DA1AAB9C18EF534087EA73A1FC8FDC865170
+ 75: 8F048230B202743FF1DEBAFEF8CC93244687A58A8E5E3E6F7D85237ADBC724641431783E63FC8EF2FBEF9DE9CD50C9FB294341654706DBEFE6B05CA8588E1A3C
+ 76: 7AEF7701439F9DB556AD3B166B0B25A51795638A83E0EE25E5244BBE9D2E8CB6A8242D81E78E4906AC9CA0AD4FECD1006D89C5A8582D1BF51C278EE7A357232D
+ 77: 55CE718F7686A0692B3727BB5C24B16FCB87D8E8EC943A80236CF3E9B37A4A20194243E461B453CF03AD846A0B3287A2005D6603D5E080D700ED2FA25F0FCA87
+ 78: 3378B07E0563CA7BCB91F29C8ECA876AD748760748AD07DE0208BAC227E0EED4A4834B8879F3DFE51FFA27B70AAD1F3E9FE1586B1D6B2B9757D545D9CC5DFBB2
+ 79: 040E1EC767CDD85FEED2AC6767F0B3C17CE4579FD9525213A682A9B49ED03979144CCE2B94026AAF7D401355B90B25259954163E0C9739CB9E756177ABA053CE
+ 80: D1CAE0E4FB245C1AC27659C2EE86BADCE26228CF8EA24AA62B69995FF02F9A59B1ACC1C959EF91A7B6EC90EA9D57F49CD0E7621D09E4016676953A3F9B9D40E9
+ 81: B41EAC0850797959C62DA2750F2BCAECCDFBAB843D56C034E4E0DC15C961FA611C50F22BBC135E5D99DC4E4B7634A8DF4B0262829593A8A86EF6C265DB9AE907
+ 82: 66BE82FD1582736D0DE7861D9DF74715658CF3CD2BCED12868EC4D92F4B015B7BACBB331ACA8D58386AE6B0642C3740BF5F3CB26E76551541AD57E1C303D4527
+ 83: C38BC2639AFEC1964C89CB92DE5ECB78E0B2994EF37F839D0A61EA688CCEB068B1A590D6CCC929EFF1145F5A5925A17BF2FC0AD352801CB92651F08352A992D5
+ 84: B699ADFC29C54F178B3EFFBF8FE8BFBCD722F2997AC30754A8FC5CC6D51352AFFF7F31D7F71FD9D136E78D1C1E040B05E25CCB75C7AEEF714018F51663C7AD91
+ 85: FDC4207E97D12B7A8D05F5073D47EF32BA32961568599ED34CA160F2EDC87726C53087711A63F6BB7E840F305477B931D1CBC1939A8B80205565D453675FCFD7
+ 86: 07E1DDE64790A279B69873C6887FBFCA69B87C97BC25B969E2B16040CDD2051BCF43637F490EF1B051CD882B64E22DA55C253A5E796528526EC62A305FB05621
+ 87: 3ABE353A4291A3A0ECF204994D49443C1FCC60C80BF6096026551048533E02C475B905046C7708F4852645168C88125221504E174A8B7E67AE424C0077163E0D
+ 88: 33793697140180A04DA72C0F74E1F845139937CD6F05AF74E3F3C5031D1D2DE571BD72916CBE67859FE501C0E56354C1360E3EBC36EBC11D11C1EE08D158247C
+ 89: 9E5A386AA9C4C5A2419B902D239E49ED84E542A6F949895C88129DFC2844FC77FB132592C7C1474E619C55FC2835F0810F227799984777CE99D586C158C8F9ED
+ 90: 6E0D9841C04BB47DEE30F6AB430E53FA1637421E460BBBD7BC8EA167B9A341DDC5E933B6983A025226B1FB3CC663EDC3477F8F0C8FA109A8B97B4B17AF3C2774
+ 91: AA0218FD54533314F62390B8C02219D26801C249D394E33981E3B853C5735E331826FA02697DF54C9268B891592DBD876E25C8D985DE8752ADAA0CBE55AE7FFB
+ 92: 23905B9273CA17D80D9C877DD78150B5382744896B073DC636618C540876B9BA51EC60F5E45DD53BE210B6076554238A3B5EA95DCE3481F0FCF2825B852BDE3E
+ 93: 1815D1AA4018626EAFF051AFBB92E91F6D6D136F58E8DB160C9E85BEC027B6CC92F0F0760DFD722BE12A97F7D29EEC341BD309F230B55B81D146B409EAEEB7D0
+ 94: A2358789A04795BB20D2EDBF95D5DA28A1FBAB329F99DFD0B103304F868CE5AA2DC1F52FE98CC84EB095B9C5ACBD6DC05FD03CFBB3F1D26675D0A8F652D38236
+ 95: 2C4DEF028098A0680DF15DEBFE6A7FA42C7A7D75CF410340ADD5257037F0B2F98FB5A068361DF33010FD48A4B41E0E40A2730FF2148C45FA568FAA182589A543
+ 96: 360F3B6819EAFD9B3D6BC469F4272F9458C0791759EC1136FAD500F3FCB4FA0598204669E865D7D5F8C289043A2A1CCB47F55CEEFAEAD98C7FDEF38FB22D3A29
+ 97: 1CB2E98EE8795761EDB7579583EF86E7223A2109267E5234663BCAAF9FBF28EAE35FE362AE9AD075023C1D36672002E08CB36189A603C174D73BB9489E13355F
+ 98: 9B3F2D2B2E3D0401229F11E6DED451A1289C631122684BB32B8C0450043ED2267AAEA20E950F52B44EA5941C507F38D23CA76E212593B65BAB347841179BED1D
+ 99: 2E27C53324017626F7EE7EE26BB0C88450B3D882C2D8823647ECA7650CADDFF3E4201D7DFA2A07A51B9372FCB04C1A79A264DCD3D260DE135D08DBABD2C5869A
+100: 0B3D7FFC5DC1CB18B867D995E3D02FB2FBA0DE27BCC85E49A3B01C5581EB3B14C19254C87D92D2EEF952C98E4E6F51C9662CDB982BC95B88C11CB2EECF032576
+101: 85C0B9C8AB8C670C01E179F495DE26F818EE772AAF6FCE4ECBDB4FFADEB1CFD8EA86E42020B47894301920B86082DE52A7E7CDC6DB4904F8F0D383D9CDA312E7
+102: 0C6637D399CFE2734AF7B63F81B7493158B7842E3C5B72E6CEA4388A5C6DB7222D46727B92FB82D88551A227703B8BB6A1AAF47247661E074CF6AE4277D586DB
+103: DC54B4ABBB7942C502BF3275E37570947FF7162B6831AA430566E69AA80658C6E792B78EA081611256C64552A9E15A66000632116AC83769B7C58B809FD96021
+104: 532372848D0F525884E5ACED9A727E96A8D92B484DC2D4089206B001CF9EC52902E49E6FD9FDE634941BDF5AA2B45B0787D0B183B895470BF1E79B57DC976EE0
+105: 4B6CEB5AA2174E6486ECB185044629BE6C280807F102CE52D2CE2DCCCFE96E5586A6888DF7500614896C9FE70CF7BC83FE755E88170B3D39EF9B218BE809E495
+106: 6D506B4BD3F079EF4818FCFDA519E7E2AB6A03293525711142C3CDC5236A7CD82A880D9CEDCBC089F7A3D5D3E48BD75DCCA7ADC53B13A2FC9CAC80C037F2CE5D
+107: B8ABE308840CC901C6C5FD908E2680886AAA0BDF7085C1A6ABC257186AFC52C522528BD7BF4E82553D9E64CBEE09B9318995E13715AB1F7809EF185E8473D70E
+108: 9790A198DA7616F4D8ACDE68DE19635A555874EAE77AD4ECFEF7207DC305D475FD250F308F466B189425AB6A9722D744AEF14541FEB83698943E87E8A39DF838
+109: 816678F1D7484660F4701CE77F4C5E13E5DFADEE6622411BE86DBA4EB71A110DD1087AF7D3F37B8ECB1B9C44A3BD5EA73901C21AAB51E569E61EFF25B5E955F9
+110: 51881FF4B150EDC3542CA12CE6554A40415AFFAA1197FE7CA4B8B065A4FB1DC3B924A444CA31776CED52514C525261269895EBD8584C29747F8D527213534E49
+111: 6D8902F285029EE683CE1803B2D9C6BF6E4B7B59C0ADBFBCED3346782A35652DE3F304ABBDE9F22E4960DF6049431139EC6AA023EE2B013A426DB9A816D92699
+112: 06E5847A060BBC4FCE1375DCC15AEAFBF514EE1ADCDF42AFF932AA277DC09EF614651255E35C499D6BA1BB875EA3E80F80AABF8B7710AA5696B058BE91B99B01
+113: CB1859580DCA13556FAB791572E523C2E888115C18C043B0E33F2268DD0056F9A60EDBB65DD9C8B552CE2299E847ED4617BEF3A453ED2AC3B5366B4D9A651B61
+114: 39778F80D346E53D1B0E60FF7B36A92639D9E7F11548C9326A59D9311D57BF09F33BFD6AC5352F2F041BD07A6D26A181419F5FCD1D5FF8AD38E485DA7DBD5419
+115: E508C9A77F53E36F76F0E477DFF076DE810F9F1599A16A3EFF1840332B26D6C7CC40E03CA8CC212FDA776F4DF968FCF92CE492AEBAABD65F069D1AEBECD11B7B
+116: 4659D0E1F9E5318D7B92FCF7700C467429B63F27188C0BA168F0D5696DC764FBFE2C5EFFCF6DF11EA77A17B0565CADC04F95FFB0485CE6900161B82608B1647B
+117: B3DB7FF2F08F57F0CBF2195BB9600E9AE5D86A15921EB164A98D25D559BAF5FD740D68430653DE73F3277425DD77CC3FB0CB44ACC5FDE693D59D5FA6DED84597
+118: CA4559843946A7583F944D51E31FDF32BBDBBFC049724454C090A6DB9C356739F2B7E254CF9746521D965593FBBCFB26092069FBFB0D17A1593416D69681B687
+119: 27CB8A2143D1073AC17009C31B28DB95DC195E20AD7D245D8AD880789898F043F0565FE41485EDC239C7129E4B7FB693D9044B2C3D34C5648E4FD8447E85FD71
+120: 99811490C7FC83A10AAD197E95D3618ABF5018E9AF7EA0AA2CC0C771FC11FCEF9FD6070A0962A563D260E8CCFDB77B48745C8C27018F9140870F146F124FF14B
+121: A1537FDAD7E18F732181CD9EC9BFD3993FAF5F994A8809A106B59D13BB70FD8D7D4E6A4BEDFA806A9D434AAB0368DE840FD64395B4A9A874DB39405707AE3AE3
+122: FB0D6D962055B47D3A72371BDAF77BE7BF965EA7D53018CAE086E3536804AC748E706E89772DB60896EB8FE2ED8F580866BAF3108CA0C97938B69830FFBC14E3
+123: 3C947F4136D9E780A7572CA4D5D7998DD82D3890CC3F1BCB59A7FE230E31DE322DBA7CF7C1DACB33A3EB1F7E75297C056570D2846EDF756D36C1AE92F8DF6954
+124: BC1BDEFFC6AB779A7ACFE53A3F9DD588CD3C77C740F944C69E331C38F162607E0D4A0CA874AC3D1D74965468843133AA9F961FBFCBF59B58818577132B863181
+125: 51143DA8F5D6E68EC97CE22A4961EF43B3AB658711280587D9ACEE701CA65CAE90D34B66DB52D779A8E2BB6204FFCBCA945C6B98B2C17C8375551FAAFE4C8A44
+126: 2550FCF54872616ED31C60FB3FD97B9AEC7A27B3CEC07D774FCE694ED9D60C43A968251C5F3C5B50E6214426B00C55D7DB1DB31CFC4BC07F6ACEA222052AB796
+127: 1D8B2525E519A3FF8BDAAF31E80EE695F5914B78E7DAB801729B5D84C3A7A2B36A33803F5E0723981CF8A9586EC1BEABC58154EFD919AFF08935FBD756327AAB
+128: 4AABF1C3F24C20FFAA61D6106E32EF1BB7CDEB607354BD4B6251893941730054244E198EECD4943C77082CC9B406A2E12271BCA455DF15D3613336615C36B22E
+

+ 288 - 364
notes/ocb_tv.txt

@@ -4,404 +4,328 @@ step repeated sufficiently.  The nonce is fixed throughout.
 
 OCB-aes (16 byte key)
   0: , 04ADA45E947BC5B6E00F4C8B8053902D
-  1: 40, 2FD20C96473DC80B70AF13AFA11D9B4E
-  2: 133A, 2CCFC6DC16D5587FF3CB3F91C533622D
-  3: 12E5E1, C93F3E09B9029E15185FEA44B3F6BF02
-  4: 3865E0A7, 7410F5F5886E2C5EF4A699A58C498C41
-  5: F0DAFA15D2, 44FE6EE9B2C980684FEDEC658802A63D
-  6: 432E308C6BA1, F7174691EDCF8D7152AFF61F20AC6B8F
-  7: B353379859776A, B087536DAD5C6E38E7C58C4A70074222
-  8: 0C78BEF929856517, 6499752674000993174D1D1B210FD727
-  9: A447088E4FDAA6FC94, B9C1AD71C969357FA2409D71AD334C26
- 10: 962F7E06CD4CBFE64D60, 41E9C22DAB0E6EFE5869D5C1CA016869
- 11: E420A8485EFF0BE6E59FA3, 8B555F3331ECBCFBCE60284DF0CE1D29
- 12: 60AF8E70FE864404C77323BB, 479C3E8E93EE0C20E9E4CA8455149F99
- 13: 6BE58932CBBA39ADDA999B35EC, 8DAC0E379861AA327DFA52DF712E771A
- 14: 3404A18D1A5F40EC3EBF3701BB67, B915A619EC2B25453B8195806C538872
- 15: 2F527E106EB32D5EA6CC2071706FDE, 172559FC20A29D0E1BAF61750951BC66
- 16: A4F288797EF24DD1209E76322006405A, 0F91836E1769B6F329AF0A7FC69AB07D
- 17: 8A3B6F2B48E2F6DE3E02D6A166E1E15595, 17BB024582DBEFAE6893BC8903418042
- 18: 5D7D954BFE815CE208AD04214F6AC62C0A54, 4CA6796851083AD43733E8E4D964FC23
- 19: A37B487B9D3B05287378108BEBD44B9A7B785D, A4402359F7E4F4BF70B3DF6600061C6E
- 20: 39341E78E5BDF7BE950B00423E186B91314B7BEF, 49B7E1545C20B0E86D0CDA4F90CC6ABA
- 21: 3D4E872C6103DB1064AD853D2978E8C5AB12FB69E1, 3551930A00FD2B663B094E6CBAD5BADC
- 22: 62C36316C5C5BF07296D9210E12BBD9542ADD2384193, 72F4B05BE37D61D2F4EBE778426BD170
- 23: E3A1EEFB5A1EC7857E6E419C18C1BA3F08AE2DB82220CC, 19F59932FD089F936B56E26768A9F2D5
- 24: 7AB0FECF7E6DCC1A7328496873DA608C2F90F6F539F76CC6, 067252CA3D59354F70C6EE6C201679B9
- 25: E811F085FD5460D3AFA4A2A389CFDDE8ACCCB9B16D75D55860, 94403E24AEB19FCEF4A7D600E5B39199
- 26: 92F42E16B838E63E4A826029126D74782DD8FCB6C8443F355732, E7F3B2F1F537D8A7DFC9FB766EE90687
- 27: 21E99ED0E5550487CD1966F1845FF302ADB6AA97781875090538A3, 4C8299570BC6BA9AB83B9B14D39D0395
- 28: 9E8A5A8BFB43D79EDC027DA82C035CA9CABBC41DB66D6256D4A30456, 3D055A9F6D6F0DADEA447157A03B06A6
- 29: F46CDF2B8E55840F27BEFC0136826912BECD86AEF88CD9B97E597C69FA, 75AB6940C71DF2041F9B1B11F33EC1B5
- 30: ED8DB3940AFEC7F990736E58CBFFD703317E79022FE951B07717EED12653, AEBD2F849E019AE82162F8A2494C3715
- 31: CD44A4CE400373FFCBEE37A79A650F73FF767F9D1EBB13F9AC7DF90A013667, 3DBEB69ADFBC8B0547A823237EF4FA68
- 32: 1BFC4EF0E39A9624C74B72329F525296C75FE9B6371700F9430FAD11016FCE6F, 8C341B4333EEA104A2D813AF71E603E6
+  1: 07, 987354C062CD6251CAA6D93280EFE9BE
+  2: 1CB7, B9F1620EA8374E1C2D05110878D93069
+  3: B98C59, 3793FB737C2DFB29E73DD1AD8B8F71C7
+  4: 8978F240, 5E25316ED13D3300F2EC12D718A0BA8E
+  5: CB4D261594, EDA252A1A5C7D0A4AB4620F771446DD3
+  6: 30D6B6688D59, 684037DE07832C6FC38CA42BDF2A7D53
+  7: D0583F9741BFA4, 3DF53DFF73431C0245982F4EEEAD432F
+  8: EE3B9596CBEFF520, D283D1B9D990739EA05F4BAE2E96BE4E
+  9: 6570FC25E6103AC125, 90D3F1FA6595B775749FAE7B00A8E5B1
+ 10: F56750C98C370DFDC4A0, 19389A6875FAB432B72D64BCDD6BD26C
+ 11: 3344AE6D9528603CC1E4E1, 87AB6FBC7F919125A7DB0D17D19056B8
+ 12: F3D9D816A727D3E67330C779, 07AC0F3841DFCFEC58A5AAC22270538C
+ 13: 976651E63ABC3B276799BC1FE4, EE603A8C66099AD6FF8667B3F34ABF29
+ 14: A48E3ABC31336C6B717A96170A9B, A9D1B973D84D3125F5F9D7923BA0A8FF
+ 15: F60E9B2A911FAFB0080FAA3ECDEE42, 4902F8AEB7685F7B255ECC45B5B7D3D4
+ 16: 0855DE488940144AF18C65A9966DDB66, A66B3E7A75D394273AC196FFD062F9DD
+ 17: 172DC1740F75AB2A27B2B80895961A69AB, D6986BB95F7E4137430CAC67F773623B
+ 18: A414234DCCC61B65A79B7C618A6B91ACA410, 6CE32E55E158BC3E51E94116A615F3A2
+ 19: 16A1B16BC0F63D63179901F1CBC772D612C102, 54007EF9822E0E4A4F953838577C76FA
+ 20: 539788EBF85C15B3A638017B4054D71315BFF25F, 9B2511322E16CECD53E3241F3D51EB97
+ 21: 7E74595A3DCFE1EA2C91B67738765463D50A22924A, AC9C9B526251C16F112E769F9FBE74E4
+ 22: A2B61792102B2E44F1DC0E48B40472CE883730504FEB, 76452A49C2524404C8A4B098D6390F98
+ 23: F58174BC06A022AB7D81991E9346F5E4B0AEC535D93473, 47F96374BC094BB2C1A5D1D291806912
+ 24: A3A7713895D178A85D9092EA6138323DC2FF9090D7F01AC5, 3814208FA7009A2934F9A172D029667D
+ 25: 385525DAF9949DCDEB22F7518AF96438E40F7D94933706A9F2, 1249F3DF50084A6D1A76AA350FD85B0B
+ 26: 6838E207D98A5BF8D8E41454CF51663D8F8B76FD26092D45D1D9, 301723D0F49BF8CF37828340B894689C
+ 27: 736413C025A549CB2550E93139DFD5DC3CE241C296C9FE641FF520, BE07259963F251743A85DF51EB1B47FB
+ 28: 7F2CD26367A885BD9E2B515D4E871272AC1BEA1C650B530E5616B2D3, EEB37E8451597E5A53CB49072EDA9346
+ 29: 68F23DCDEF223B60B46E3D724A93BEEF8B110D4394C990AC3D0E34E1B6, 9A60344982F852EFE02CBE9CBBAB60F1
+ 30: 66C5DE3EB27139983D48BED81D0E5FCE6BA1AB402C357062FE989D31C69C, BAFA0A7997A529039F0CE8528E670415
+ 31: D3B9009C1A930EE288C61B0B15C7E92CB73484C345594DC5A3F377147981DB, 1EDAACF7F1F3AC7EA613F94DA4DEF930
+ 32: F7818DF15FE6FBC42A28FDE1D55A2C07EC8D82AA0E7A680DBD3CF26C13448F9B, 67FEB344108008A88067E92B210766D5
 
 OCB-blowfish (8 byte key)
   0: , 07B7752047F9E0AE
-  1: 72, DC5AEC862D059BF4
-  2: AA44, 3C9F6D8E6A88B5BC
-  3: D58CDC, 5305AE3B67CA99D7
-  4: 40AAF438, 306EBBE817191E72
-  5: 83C6195BBC, 03EFAF8AB3F3A797
-  6: 4CA887041A55, 45685403FADBD62F
-  7: AAEFC9AFC97E1B, 9658D436EBE2B562
-  8: 298ADEC7EE78361E, B90F2F68A2512CCF
-  9: 12D0BF9A2091678026, DA2AA0CEAA665CCE
- 10: 6E6FBED771FC0F458878, FB74D5C5E3801106
- 11: C7ED5B6E6306306E9492C7, 7B9EDE455D6FB117
- 12: A2E9E854EC2F47E367285401, 4E8610D388D8590A
- 13: 358787DE6F716BDBDD1ABF35C5, 026140FE56B18F40
- 14: 927A4E1EAAD8F9A7A1976353840B, 3FFCB2659DCECCFA
- 15: F02A0044174580B388CD92C92A640A, E4FAA7636675F470
- 16: FAC9731332BDF622E4070F35DA928DFF, B0FDD13E2BFF9971
+  1: CE, 7D69017C42B06204
+  2: 1D6F, 4DFD4BD58439062F
+  3: 30A011, DB49D988798F8842
+  4: B71C8951, AA3261584B0C20FD
+  5: 06F89957DA, 88BFA80D36427F64
+  6: 45BC4CE5FABD, 4CAF71136ED166A7
+  7: A7405F124D0296, 5D8993CE64FFF0E7
+  8: ECABEFD9E6574E4D, B69349673CF86E41
+  9: F7D26A7E82A34ACC71, AFFDEE843ABEA68A
+ 10: E225C5F0FA1D649F81A3, 03AC1D5DF1323EF8
+ 11: 58722FBFB86C2697061217, CE731D80E6355710
+ 12: E577EB8FA70225C5A18D31DC, 2F08B140F0D3A255
+ 13: 92154A94CD7D42EBADB6CFEE14, DC949170E84D3CA2
+ 14: 5A3C08744FD85CA262D51AC6CD25, E83CE45547403BAD
+ 15: 8B2E4980ABA10A20573A402D89AD12, E3D978611DD831D0
+ 16: 3EDC4A0FA95BD8F944BCE4F252B6470C, 87B54BBEA86A5B5C
 
 OCB-xtea (16 byte key)
   0: , 56722ECFE6ED1300
-  1: 42, 1B8DC606F46D0C70
-  2: 5AFE, C37DA08565D490AF
-  3: 2210D8, C1F685A65A5D96C2
-  4: 3760B566, A3820E4369714716
-  5: DE9A8858D3, ED81EB4158EB9D32
-  6: 4822F1279F1A, 152823C615E44F93
-  7: B83B447A71F943, F9D4243069C2D675
-  8: 968ABEA6B6C65A78, 012DED12CE8E6898
-  9: B1A37D0FFB6A6FC8A2, F749AB7C40152D6E
- 10: 4D48A2868E751C5CBE21, F8CB1C58475FAFA7
- 11: 0C81558633A9130A6CC9AE, B5D2075CD13D9AFD
- 12: C76717CB2F62C3AEC139906C, B9518A5031D84B19
- 13: 11F7EA02488D7BB84209CDB03C, B4009DC8D6EF5C4F
- 14: 4E621DDE6BD1B7944285A1CBD396, 95C178682BBB014F
- 15: 98C771287305A8DD1F0EA001AB3FB0, DBBF192B778BB9AD
- 16: 13AE423AB94556C3594C15F745BB6887, 4785C52B73DE0864
+  1: CA, DF53479333DB86AA
+  2: 9529, D0B5A859106FCC9B
+  3: DDBAB2, 3B31FFDA57CF51C8
+  4: 22EB7DD4, 2BB34D04FFF810CB
+  5: 108693761A, 7AFF6F52574A019A
+  6: 391FB7C61E76, 616C5E66297F2CCE
+  7: 3E22E4A4A0BD13, E84C385ABE25C8D8
+  8: 94FA11D5243EE34F, 8F017DE96049D0F9
+  9: DADB6B5D27049240A7, CA69E14047C6BBA7
+ 10: F79C8EA83C69DE914DAC, 1EF042DA68106C64
+ 11: C5B6E04AB8B9491E6A99F8, 143515779A55C972
+ 12: 33F493AB7AE62DADA38C5B24, 531BF7799A778620
+ 13: 6DAA66BF02E66DF8C0B6C1CC24, 6CDF72786C5EC761
+ 14: 4940E22F083A0F3EC01B3D468928, 185EE9CD2D7521AB
+ 15: 5D100BF55708147A9537C7DB6E42A6, 78984C682124E904
+ 16: 744033532DDB372BA4AFADEA1959251E, 438EB9F6B939844C
 
 OCB-rc5 (8 byte key)
   0: , E7462C3C0C95A73E
-  1: 7B, 4A2E2F035C687741
-  2: 5D18, 67AFF1894807B8CD
-  3: 2D22D8, 0C5FF43CA669E036
-  4: 341397B9, 96B16C84B8507879
-  5: 78DD453CE9, AE90A02A9A427B82
-  6: 607F75BEB5AF, E11F4897573F6672
-  7: 09A273F40C1F2E, 47038024E2F82A75
-  8: 0519985EF3CE9A54, BA78310DB98100D4
-  9: 66F8D6AF3B453E175A, 8E8A6032D7BA4D8E
- 10: 8EA2CCD6592C9AA13B1F, 8E169657A578DA1D
- 11: 6046093C8B4C5668182A86, 1E263CA9C35E06C0
- 12: 7D41AAD34685C2E6A050B860, 96AE4FDBF038AAAB
- 13: F5E6D3B7773BADDEAABA140123, 7FEE0722FCC229A1
- 14: 44FA523DD21E9A57685B154113A3, 5F4F727124C9A45F
- 15: 373B75BADE72A31B61D7FAAA2DFF1A, 526D5C55FBB13C70
- 16: B245D9B51E69EFF0D0F33463886B22F0, 5A575D73F0E1DD6C
+  1: C5, 83CB00E780937259
+  2: 1533, 022FF70566E0BA87
+  3: 57543B, AC4EF15FC83BDF2D
+  4: 01E4474B, BD817C06AC2141E0
+  5: 4CD7E850EE, 7BB6B3BDA5373422
+  6: 489C0CD1502A, 23DD4406F87EB164
+  7: 0CBAAE08E07EFF, 92569C958B722413
+  8: 073612F283F8A6E4, 1DD978D01CE8D1DF
+  9: CDE676B1A3AC98B00E, C033F099E2620668
+ 10: AD3BC88EEEDA40A83685, 36DA44E13C0C8A4D
+ 11: CA60E8B918F73E99986021, 45634CA0E43E4B13
+ 12: 3B3CF82157ECEACAD8658EF5, E681F57616146CC7
+ 13: EBC1A7068346EC1B7EB815A7DC, 2C806D2A909CCAF1
+ 14: 97CDB3EF8276F1E7D6B6677DA2DB, 53F00B9A2E43DE08
+ 15: 44169B3EDAD9506C51A6DA055EF9C2, 5BB6DD996130896B
+ 16: 35EC29065B1FC640015B0F779E7A358A, 867EBD0E86823F09
 
 OCB-rc6 (16 byte key)
   0: , 27B9E3F544B8F567EEBF98ED5FD55C76
-  1: 50, 19639C6FB84C516252045735CBFEB2B1
-  2: F537, 645D0FC41CCD140DB055F7E0C63F58E8
-  3: 2F980F, 317F9D3CD0DAB3C309D17432FD7A802E
-  4: D868693F, E48D64588DFB9AE80C5F0B471A133B96
-  5: C171238B7D, E9027C03EA694306AE9AF3AE4C4E418B
-  6: 2BBB09C1C87D, 6491FB907923B31B3904DAF44E155DB8
-  7: 344E1A1B4CF7AE, A13A7BDB91291914B33A814FF5D3FB3E
-  8: F21AF3A1D17299FD, 367371D31EF18B597348AEC1F2415111
-  9: CEBDDD6DC10BF92082, 8C9EB873E39EEC6D123DC69350178DDB
- 10: 7932B646E83EB855C568, B147A3F6D63EBA4B79300B1BAFE72F6B
- 11: 1100687B3E8BAAEA85A8C7, 6AA2C7009E9BCC19D51E18F472260C65
- 12: 2C7BECF92891FC7B95FE6142, A83FE40AB2A5E176AC7835005E43CDD5
- 13: 29467982D6361D53357F314332, 93EF8D80A786EAFF9F59CD3365AE62B7
- 14: CDC2FB60BB5AAB6E6028032DD04F, 6FBD59FFAAF6DB2E0A0CC08AD16FD36A
- 15: 8BA02FAB113254ED8EC51337605315, DB4C8651CA878CC6FAE2FDC361C1E2AA
- 16: F36A825E7903BA24D8EF48E49DC2EE12, FF9BCF7D6904CF072FBAAE5EA7637DCB
- 17: F22042261E247A450CCFDB90D54D42EF36, B3E2972C2B6EB9F80B9E9D5BF395B771
- 18: B1F0C3216D75C7D5F5C6834F352FEBAE4E26, 5BDDDEB129C08A9D918238B74A436AE7
- 19: 308F653B63C08990E34655FD0E556AD14ADBD2, 7132EF067DFEC0B16F2E4EE6FD7111DF
- 20: 65CFEFB0F8258FA5F77AF744A97398CA768169C1, 18EA953A7C3A764DEA9A0A67A12FCA32
- 21: DA01CBB6F33C91A50B49C6A6FEB95BDDEF0905F7F9, 8F29E4BA14C1707C32F3EAD642D6020F
- 22: BC35EE861788C672AE10348080346442955D6AD9CA23, D11F8A6E94E663FBFAB79FC124781A2A
- 23: 02B52941575D7EDE96D336EC26290EC32D2558CC1EB2EE, 84656D07A6502A48E99E760E911531BF
- 24: 0CB126C57FD06737F728090D945D7A3154316BE109A26D82, 7B242FDC18DD934F9A3486CB5B242F1D
- 25: D80B8743F79DAAAA6D531E90C72EEE91721B0DBF7D7C3A7BB8, ABDDED12108723E86D4B72E2E88DAF1F
- 26: 7C94C0174515FC33D8E9265AC8288E8019F6975626F7FF92AAE0, 113140E6C100BF737B5BA7411B35E3C5
- 27: 0B26D5C8F433E566096D7659ABDEE87183E3AF942859B1FA92CC86, 0BE6A8E265B619D83058C90B758D963E
- 28: 61FBC6C671AC58DD515024C9E9ABB774DE2F013EAB00226F00E944B9, 0D095AB152C2FE6ACFF2527E89938A82
- 29: 0D8116EB2BA5C1DA6EB9070B00F819C3CE817085AE3D8BE8028B9F28F0, AA0A1670057C9F7A291BDD45730AF3D1
- 30: D40E8399579309A395093DD35889A558D8602D2A7C5C4CADC4E5C0195232, E534C6F04E12D2E6D97ACCFAD57C22E2
- 31: 25037C853CFF6296747B5310F1959ED0628847D8996E10414B1979E340F43F, 8DFB20AFE1B20A702AAACE1C3B9A3E3F
- 32: E1C2DA2341C0DF0515F11C7AA2EFC88BECEC0228BE220615A5A26F0D9CE164DC, 5AAC9903CB8E340D031688ACDF5D203B
+  1: 92, 219FD2D74D7E3F21AA6C2A507C0A546B
+  2: BECF, 96A656A16FB3C4579E6955D592AECAE1
+  3: 4DDE09, 7D1882879B5D6FD8C151502BD8AB220A
+  4: 0D6B4FCC, E01FBD1ECA2A6A8DC6697A06AB12BDB0
+  5: E5E19C973B, E5A86AADF2F333D5DEDCE410688CC6A4
+  6: 90BA7D2A6965, 80523A2CAB2A7BB2E90B121DE80F46A9
+  7: 6FE258148EC8D0, B7254B11276A77C5F99FE5EC91D81F57
+  8: D887080095DF8817, F3FB938068A01EF89DE0F1226C544362
+  9: D9823313289D597614, A547764EF20BD4B4B303882B64FAF2C5
+ 10: FF68942112CF01701E86, 94F3860D4438428EE296CEACB3EB67F5
+ 11: FFD390D3E0B64F64D3192F, 99D2E424C67EBACCD4E2EB9A0CDB8CDD
+ 12: 3162235748BDDECC84FC8C94, BDD400A58AF59100A731DD5B4386444E
+ 13: D2A0EC8B1F20672289F7236C56, B245CF42644BDAC5F077143AF2A57BA7
+ 14: 830929B2850E22F6C1BA2027248C, B6B522F7D6BA3CFFA92D093B383542FE
+ 15: 2A5FCCCCF43F845AA77750D3BC6B1E, 53A0A0882C7844636900509921661FCA
+ 16: 8480234796F9EAC313140CE014B0265C, 0656CA8D851B53FD5C1AAC303B264E43
+ 17: F011A67C22F16A42CEA5E493CB766964AA, 830B8158B7A96224A53FB7F3A08CD128
+ 18: F76274A730A608C2AB37497A049C3699882E, 4DC4DD4DF39D0E68D6169F9DC7F4A6D5
+ 19: 7B38DD237DE552A72E4369A81C30AFEA5E5063, 01A62CBD30153702A5B29FB2A1683899
+ 20: 58EB866F1FCB060ACC821D776AAC4AD9E87C326A, 25AFB8FC48605E1396EA8471F55C1294
+ 21: A25F2C0FAD66B3580627498EC66C994B49C5445911, 0182A951D9A3DA53675612DE8EED1FB9
+ 22: 8813977F092F07F251A1497C898967F3F98F5CB878CB, 80BC353E310880A83DD4DE4FE96AB6F0
+ 23: 52DC8B76F5A6F78D51FB7DB51048E2663563335EC876A5, DC3689AA079C04C19D83646B272F9DEC
+ 24: 965437D3FDF91784B63C73C8CD001BD9372167963DF36B89, 9FF84E2845E3C1E3E6711D1646B18F21
+ 25: ADD40F674BD56FFC8F9B4047FAAD2471F0A48F4544C894F806, 9D684F74F9734F1C497E33D96A27E00C
+ 26: 7B049B688839BC62785082397DEC7AA94B837D094AECA4B14571, EE711DF1C15B5C9E36B6E38B6F7152D2
+ 27: DD4681F9C498A3CF69A9AC876E02BD9CDC4FB1F6798F772013B62D, C5A50676EFAA2A56CBDBE55CFED3050D
+ 28: 471B5E89A1337E75E88AFBAACA1C011790F1657425483229E55C34EE, 20F73F2AC452FFEA423BE2EBDF33CFA1
+ 29: 71812C83DE34DB329C8DCD98890AFB1F7719E890DAE5CEB7AC9668CAD0, 6FAA03E10C6FB67D425C683C6D85FD76
+ 30: 4BC2DB33786CFD29B5CA5B804454169906138E90E29E7BE9197971027AF7, 75053C433EF5572A70C58EEC96F56C53
+ 31: 5E3A0AB41264AB65365458ED3B7E6A25827E50075A9E347F1622ED0723E229, C8F1ECD19AD5FC970CF0D31BF46B0F2B
+ 32: 2E48DEE4B379CD59F5367D17DC397C1BFD53B8C4CE46A8202518614076174EB6, EFCE758ECCB6BE875D16B7E03A498D31
 
 OCB-safer+ (16 byte key)
   0: , 88618DEF98FE588E23107E9A5D89C26B
-  1: 68, 78C82478DC13012FBC3F600C7A27A208
-  2: 49E0, 6C2823D624ECAD05081E558DBA873883
-  3: 0DACDA, D977DA0446DB3FE2E31EF6423C84D3D1
-  4: 9C81B7EC, 96ED39E22316D48B0652851F3F2EF14C
-  5: BCE204E7C7, 2F2A2556CF50BC372E8D5EB0B196E072
-  6: 51D55B2149F9, 29E5DC8856E0ADD3FF50FD3611C336B5
-  7: 92C82E4C3DCFE1, AD9091779ED4426389E4FD148CECBC36
-  8: 6B7A7E80C71CFEC8, DE0EB38592298B6C98D79DBAF4388062
-  9: 8578B7FF0338C7261A, 8F5B1C5055E789E0D062403099F5B736
- 10: 31D3E598CF921C73AAD5, 0AC8BC98F0C0822FF677F1873BA246EF
- 11: 350F10E54E34F1E132B51F, 2F22E4D9FE1E9D5B6FA2DB02CD2112D6
- 12: A41B0CEEA3B156043A9B3289, 78B8DBBE1259DA24797A65A0A6F21813
- 13: 97AA05B4EFDA98212538D90826, C49EB0F9110C6A8F64D68CA1AA05D317
- 14: E7CC0F8CEB35EB63BB5CE067302B, 2318A68066C4692BB7DAD31269E80EB0
- 15: 9530B10F9D82F2F01220E507C45DBF, F66FC64518F87E40141E273968644EA0
- 16: 8FA4B27A1F279E426403D0A4960666F3, E297DDC3038C6754B09972C9A81FA346
- 17: F2DA0B5E70287E504F1606AAE4A60DCD43, DBB1D3FCED2731757271C451FA89BAC2
- 18: 9F39E37F53A7EB41B471CD9B09C89E2640E9, 5B7139A288009BF029D8BC11610BE58A
- 19: E07FD02F121F0D497339A3F604CBCCE91AD43F, 7970D40B8C4A728A351F6055B87E451C
- 20: 344D288DE671675A2539720EC6C36A7C75627F76, 8C14F47BBE0F60117FEC9B3055F122CB
- 21: 4E8FAA2AC06045F7FCCC386E7BD258F6796256E901, 6C02374CCB50A0E50A39DBC648E70DFB
- 22: 8FC9ED1351E05EA5E04799A518CF52F21CF689B18EB8, 97A2732C6149FC54C21E5AB8B69C2A94
- 23: 9B0809249A4D0C8F095AD270FEF3DF72232FE807A92243, FA55F25502F7FEBDFB4638FF27AC7E0A
- 24: 2B2E0239FC8C1A78011D73890A1169A117B7CC1E8B5B7B77, 02E373B8D36E675D47AD9BB0AC661BD9
- 25: 28D5A76CE1064E266FCADE5CB7A908E29B60B19482B1C40B3C, 689E34472FE29EACBFBB9BB059DBC90D
- 26: 6A1C1885DC27697AE22D8AAE9850A8752B4F9D75A7AFF65E4182, 28B6A0DADDB7783929D7C774820CA679
- 27: 8A414CEBE09F7397D1C997645FA3AF71D19F5BD6227EA0CB47034B, 3C1441F1A4054A37C98DB6EA0268E417
- 28: 7CEB9392C3E73183567D7876F86E5373B64F01A0D1C0AC0AA0A01413, DD9BA754BA874DDBC6FB531ED46D9CC0
- 29: 59D7302D064F375940FA8C6D7ED4E4EB27025514576D4ED31037CFCD28, 4A7A7E25C56C0676F9471B0440856F86
- 30: C738EAD06D011F8F6D39076C660A8BBCE69F470D747E8BAACAB6624E59F9, 474664ED7DC02BE63C7165860464188B
- 31: AE8386752CD19641133432F27A923AC03E790D6324E7D951866B30B930ECFC, 017375CF18EC2AB24D19E10459977233
- 32: DB277B162E172882DC35C0D13E8CDD2A51022F711A67491F9788F83C4953342F, F289BFE53BACA5D9818B118E5A236300
+  1: 39, 2B01B202E751F957E331ECD1CEDE3456
+  2: 13CB, 17071E5AFD5D8CE953A73F49412BE8C4
+  3: DC4428, 4B0B1881C2540FF92E7DE63C479A7750
+  4: 120382B0, 0BB11D57B5BD9D846CF31033CD4CCB92
+  5: 97F332F95B, 335E0424D0A820F60DBB968B8B5AA057
+  6: 3C7AAE72037B, C8034C2C76C1CCD7C1B3F36DD8907E1D
+  7: 8A99E4A1B89B6D, 06A8165DFADF1EA5ABD89E574422DF7F
+  8: 676587065F0342B8, 93ADE63994DF2189079234DC204BF92B
+  9: 8EC394CBC6877B245A, 1A89F0AB0B44BC708EBD9DE489E2EEB8
+ 10: 5FB5366E5CAE4DB72411, 5CA5881A5805D53ACA4904A5EEC01550
+ 11: 72A1994028F09ED6A4E45C, 0FFC0052996CE45DF4A28F7A6E9CFEA6
+ 12: 1D5EF20F52A9B72386D1A601, A697DF1179628DE1120D5E8D9F39DA6E
+ 13: 79BD002AA59D74F125AD9E32DE, 2F02CB6F70BF57BBA0DF100DE503F633
+ 14: 442C6F9016DF4C090056258756A9, 58C6FD3180B9B74459D70B5684BE3F4C
+ 15: 4FC5543D9A892B44ED04EE8B25E232, B8B858B3D3EB4B26E867E429F88A56B4
+ 16: F06E7503167C2210AB332259BAFD6AB4, 73CE2589D1DF34CA3DC2B14CC9FA6276
+ 17: BCCC260BD4823B64090FB33E6816F9C330, 81ABBDC83B2544907840FEB5AF4479EC
+ 18: 450C1105B76F960D1A5F33D7F9D37DAE20C3, C41DDC8980E88E3986D9C84857BBE1E7
+ 19: C9F36EF3A990E0554EDB59E6788F8E9BF1DBC7, 90DD543E148D9A0B79A8B376C5509E09
+ 20: 3666FEEA98A4FC434EDB7517E7FCEE2320C69BCB, 99F11B360DDB3A15C42110831CCBF21C
+ 21: 126F39C19D1E0B87F1180F6589A75712B66209E2CE, B4D268FB8EF5C048CA9A35337D57828A
+ 22: C1B6D14EE8B6D0A653BFCC295D5F94E6BCA09E181D8A, 4B4883B614D5CC412B53ED4203EA93B7
+ 23: D1F2A10F1A9DAB738C61CD0EF66FE5F6D1DA95DC671128, 3F1EFDA55EFEF1A0B24708E132BC4D25
+ 24: 9D457216C584F43DBA1DD55C54822A8B6A86D22DBFFA14D4, 53402970B128E98A5F0D62476A38F959
+ 25: 012828614B5D67C9A1EE24A1EBCD322FE9C8BE0C3F20A53714, 2BFF288D90DBDC638084F80F3F7AADF3
+ 26: B1904AECF599F6C74557475E409E75E646271DEDEC7A830260DB, BF119BDBDA27773E038B7067D2B0EECD
+ 27: ED831771C4346FC19435354AE29F7A9436D6E8D4D42CFF26207DBD, C3F029FC8AE690E84FBD0EF806B801F3
+ 28: E051B958601223FECEADF932A277BCF18C25025AE4DA791155B85035, EB75E56BE7856F1B5ED3D125C092D38A
+ 29: AB3449537C5E22125BC32D483F74C3A3DBDBD5232839A85D300F65B4FD, 851B0FBABD080F783BDE4F47ADCD6D76
+ 30: 4E68550837130652795A8C9D68530717D2B0AA5A17F3AEF92FFB502E46AC, 10E222706527A64E757EDE4B9EFC09DD
+ 31: C2D7033DA7A1857D79497EA6C64779EB969046CCEE6C74E6592FEE6E7C94C4, 2015674ECA80AC9B67AE854E18A7D56E
+ 32: 2F3F0374DDC24AE21F02D4DA74D46C71F0CD2269A68F32F7FAA0BAB64AA8E9BC, 737C8BA1677A8CE97D42FBB07530EE99
 
 OCB-twofish (16 byte key)
   0: , 2CD8EF22E5457C7FE4016B0FB82FD204
-  1: 5E, 3E38069A9B48C86A6D5B30230AA8FB5D
-  2: 16C5, 88018710A0DE759BB40F63D01D3BFEC5
-  3: 3BB919, 541D64B63CF6256A2B91641C4AD7881D
-  4: 18BF1940, EEB4B67CC606C3BED042713A1C07E148
-  5: B83ECCDD6A, 99AD31F23F10784CC315534AD7DC3227
-  6: 2C6EB390D4CB, 239FD47E333C9E628F53A0AAFFABAB95
-  7: 77A6F443656C96, 6669B100ED5816E5E7EBC6E6FFE9FD28
-  8: 48ABD8C0E7880A3F, 2927A8138FF76C35644C1C260A470E61
-  9: 58618862492B904056, ADA18B1602AB662B1DADA3D17AFDA16F
- 10: 421666490D83177D6662, 31A434A1AF320564DAC4AB41CB95CCBE
- 11: E6C856656011B22865BB56, 8308CBA4CA2DFB3BBF50B406AF9787B4
- 12: C00BDBC3ED137D4DF4AE64A1, 3A6AAAD853FD891608E6E524CC71291D
- 13: 51FC0197213EAE6C779B0D9591, 2E013655C557BF924C3377119D445A08
- 14: EFFA38E05FDC7E40A0F73CF9EE75, A20C214FEF00C5B836816D91784EA349
- 15: 5121A8E7DA2F34FCB27A211AC7B17F, FC16C8CC0F76AED1502E54E5578FA4FE
- 16: C7B4BACC25D34E3235AF82EF4682BF71, 4A2D4172B5BE33532BDC16792840F807
- 17: 67C6376AA0C00FBAB7ECAE408F20004842, ED2BE2756636BEEF1EE5DA5CF727E89D
- 18: 8E2262CDDF6A2523565B6B63BB86311EBA9D, 6E36E1B6ED9E116581B155B5B3CD3A4E
- 19: A683E2D02AAA473F66FE1B88278C83D1E934DA, 216A3EA8AA533F47F668D8A0D2D7C59B
- 20: AF5E282860165A89CE43987CD12D54E09F24F930, AAA981071FD86D7FD3D5E1A9B7B0F54E
- 21: 8CC3AEA5C625B1BD7B7982E0933340C7C6F697A7F3, 211BC13BBB33CA9D9C09FF71E6C6FF0E
- 22: E7A0BD9580F60EE6FB96830BC03B9DB1C714A5FB1E3A, E80D8AE804A1FC572719C9891728EB0C
- 23: 8957615AC77DB6D23C5156709A8426D5D947B3BF83F80D, 839A17904B6EF3367F41D86641179E64
- 24: 89F7444059A006913EC23BC6FA07E2EDA6929F9425ED55B5, 94D3B35D083A99D7CAD703C730B7AC3F
- 25: 166189030E95293421581FBC56598AC6ACF597FD07BCAB8BA7, B85DFECEB4953DCD16F1D294B77F5251
- 26: 9D1CBB72E273243A031E061FD1B7B21283C43C607ECEB5F604A3, 37A1370BAE41F2E1A538904B623591F4
- 27: D5C870356DA4B1A6B5B80958049A04F4B463453F5D54EDC3B90EFB, B1D6913246CCF26C063E282D7B9AECA2
- 28: FFF152D69AE294A239FB875C038688F0C2025F6B924EA69ED633D974, 8DA6C7D7A7535D33E92776BD51CE7732
- 29: B327AE2D692BDA7B4F0F46B8025B2D09EACA670F8E4B2D32CB538774C3, 721861B534B2C4DD83B9C3652BB78083
- 30: FED1AEDC7737586AE88324ADDE9C8396AAD39C1A24773185F47F83A4C9F2, 5987D5FE9CD91AC15C434DECBBE96F49
- 31: 3B8D6C999FA569F5BF275654ECDD27465420E4A4FD0B791B3082B6746E7494, 92CDADC59BAAB01CFEE801288F669BC6
- 32: 57A44D012A7D8EC832121B9DD374990C2236A5B5CDE525A105309A5DAB860B04, 13B2461EFBBF3E37C594C10BE45EB3FF
-
-OCB-safer-k64 (8 byte key)
-  0: , 0EDD2A1AB692AA7A
-  1: 20, D8E0A4AA7186D93B
-  2: 3A72, D35ED39A0DE9BB7A
-  3: 63E95A, 5DCC145AC083EBE1
-  4: 66CCE936, 43DC4736618962EE
-  5: 81E790856A, 67FE11BBAC7F0CF4
-  6: 2FCC612AFA2D, D9A73706F6BF0562
-  7: 8D65EC96919C6A, 9859A2C2F467F271
-  8: B968DFF1928FFA70, D6379C99C09205E2
-  9: 1D5AEB22616196731D, 91F6EB57D46B3F4E
- 10: 8712826B41AF01B45F95, 7482C4B662B4D51F
- 11: C3DC292B6D37DC8299F005, D66EDF92D14E89ED
- 12: 41E72489BC2089E3632C50BB, 1D058C13D261FF52
- 13: 257A6510FB990950D8CA3B6BB2, C7366DDB55647661
- 14: 74C037F38910E25D746D3A41C422, 6A89AD8D5763B669
- 15: 58610E575C2938BACF63E9612A5704, FC40C717D3962A95
- 16: C23657B24E3497C7C3A53C8D99866586, 8092D335D30512A8
-
-OCB-safer-sk64 (8 byte key)
-  0: , 76F16BDCE55B3E23
-  1: 6F, 9BB975FF089B072D
-  2: D0DB, D469B44427B54009
-  3: 9124AE, 29DEEE037ED01B57
-  4: 3CB507B4, 3B2099163A662E8A
-  5: 24916556E2, C645411E75A45A76
-  6: 3861F27498B1, 27CD404E5CBE2530
-  7: B9A4F0F215AD46, EC8ED0F8F5BFA762
-  8: 35F39C5CF8FC195F, D2EF40AB639C6841
-  9: EF387F42DFB145C157, 78A3687643B6A8BF
- 10: 609B7AD698D6E75FC8A7, 19F2B4BA46C226A8
- 11: 9EB389D840B5575A431015, D6D5CD12B0A8D58C
- 12: 773D76C86FC6548E9C3F7106, C84DA314B3D2A265
- 13: FA9F6A22A448EA8EBC4D5CA1D7, A1F9A8800DEE87F3
- 14: 8588A29BDA0F754902F45177D98E, FAE4F6A46C282C58
- 15: 3661A78146680EBD27E1B0A8411F6F, DBDA06B42AFE89E6
- 16: A7817AFDD86A73DBD088D726950885BC, 39EE24F1DDB14EFE
-
-OCB-safer-k128 (16 byte key)
-  0: , 4919F68F6BC44ABC
-  1: FE, 62E1BB4260A41E8B
-  2: 29D3, 84F7E10309B5A9F6
-  3: 82CAE3, 21AD21271DEECC38
-  4: E8CFF492, 30A28F17566BD7B7
-  5: 42D790100D, 2712BB75C619F235
-  6: 1D7EF9DAD397, 29EA0096FE1B0F8E
-  7: 2328AE9F5F8F23, 823FBB72027588FE
-  8: F1EE17CE5D1D962A, 7E763B44190D412A
-  9: 59995D24D2F343CAE5, D0442E8DA4B7A738
- 10: 89470C900512352C0AAD, A1B8267CEAC51DE7
- 11: FA01A56CF4043DC9016507, 3F04CA39354B7945
- 12: 234CE53F33CC18BC1D87581B, 26045CD92EEB0B7C
- 13: 09F0F817F0A1C34CC1882349D9, D6690B0CD95E3B81
- 14: EE59B78A5EA7A7565519BD8394C5, BA02E6FBDAA3D9C0
- 15: BBE92ED57326C0B8BD718A161F93A2, 6F92501366610B24
- 16: E7FF3C9225C652EC6E89F4D514AB9529, FB797311AE38EEAC
-
-OCB-safer-sk128 (16 byte key)
-  0: , E523C6DBB3CA178D
-  1: CD, AA12FD56D9ADDB4B
-  2: 0CC4, 98012452ED510588
-  3: 426651, 7FBDB6A5B8960251
-  4: 9EEBE085, 0697D2EB8824BC84
-  5: 346C825C29, 5BECAECCA943C6CB
-  6: 12C8F7C7174F, D6F614EB7FF14058
-  7: 06494CBE89E31E, 51A7F4E7D1B85EB8
-  8: AB7DB8E035CD48D5, F18EDA93515A11D2
-  9: 5F66C9179485A4C178, 77B2EABD6B9D32E9
- 10: 44E2F4B20A7B5BC5321E, EB0D98A55F19267C
- 11: 807F11C15D37266D9CAC24, A28A19BDF9967E04
- 12: 403E55B8744B21CE9EF5F67C, 5E4F91E64F5034CA
- 13: C38DB3813C26D0DCDB4B3A78EE, C4C9A3A3B057511B
- 14: 67FFA142996CE550C513F59F8277, DA59DD302D5B0BC7
- 15: A88F78F05F9AFF45F2625D1F450CB1, E4A32284D3D6EC35
- 16: 2EC309FC14CA2483FA63A5EA28070833, 3689A7737D796A82
+  1: 64, EB7BB60E4932C0E97A7A5906BD044ACF
+  2: 3A59, E3D2024241666369BB542ED096F20C71
+  3: 67C038, 7E6F1EB3F2088F6416BB675DCAC0D484
+  4: BB36BF02, BDEEEF07EBB7A50A5201C8A2D72C0036
+  5: 6F06C0E293, C63557681D84ACCFFBFEE87D82EF1D3C
+  6: 2015F94CC5AA, EF1DEAD4134D2A1A47A20F26FAA3554D
+  7: A5F8CDD07964B0, 672B74D88C8AA7567C6AC4A896E0F6D1
+  8: 5EFC9D8C3B9E7F3F, DB9160C53AD429D4C22BC0E2E6C509C5
+  9: B62CB80F75594BC54F, 20020A798FF59F0472E750C796B5CC94
+ 10: 970983B0F889760EEEF0, 360AE43CEBCC27755548D4984CEEA10C
+ 11: 75C3A8CCB30A94CD57D1F8, 79820F3B1625E216B5BC1D1A22B198F9
+ 12: 033DA41CCBFE3C6897230FCE, CFE3EDD11627270CD63916508B058B7A
+ 13: 15358032F30043A66F49D3F76A, 98B8056A7991D5EF498E7C09DAC7B25D
+ 14: 71FBA7D6C2C8DC4A0E2773766F26, 22BA0ECEF19532554335D8F1A1C7DEFC
+ 15: BD761CD92C6F9FB651B38555CDFDC7, 8E3C7E1D8C4702B85C6FCD04184739E4
+ 16: EB6D310E2B7F84C24872EC48BFAA6BD7, 12DE548D982A122716CEDF5B5D2176D9
+ 17: 8DDF6CE25A67B409D3FB42A25C3AA7A842, 3E9FA2C6C65341A8E1101C15E1BBD936
+ 18: 5563DFC29B750FBC647E427C5480B65846DB, 90881C6820901BD41F7B3C2DF529B8A9
+ 19: 93343C1E9624321C2A0A155BA8B4E66FD92BE2, 71A641DDCD49825E10880D54BEF30E91
+ 20: C256BCA0CF0ACCEEC1AA4B9372AF27D2C3C65AFC, 91D45C4DA49BBAD1809A11F4041C7D09
+ 21: 3DE69FDB72C93518A3E317F7B26C425EE3DD42DA7E, 85E37B3E8EC3AF476DB7819D739D07D5
+ 22: 676AC7885C7C8FBE9862242FCCC46C181440EE49AE59, BCDB42B53AC4FDDF9C3BF8849AB96EEC
+ 23: D71B98B88F46CC47D90BB931564CDF0157F0ABCB5E6954, 289CD5799D9E49F36D70F67726A59610
+ 24: 669C16DB9DC175200C08476832155DAA52F1F8969DF3B79A, 835B210EBBE5C9D34C2E052E1843C1F8
+ 25: 2F39346E14A34BBED0491929CD9F1FB3CEC412C25AB703372A, DC4B42E8BA676BA100B87BEE328C5229
+ 26: 1FD0F8BD0AC95E91881635EB0CF0E4FB099CBB214CE556422E2D, 898CEB3CA8FCA565CE5B01EF932FD391
+ 27: 7FBD32B3D88B7E002BA6055585B5D0E1CC648315A81CFECA363CC8, 804820B1E3813D244164F778B9C2A8C8
+ 28: 877A5F336A1D33AB94751A33E285C21666F0D8F103AC1187FC205372, AF9F0AC165EAFCEE8C2A831608F166B4
+ 29: ECCA297705B0395E71B9E4263343D486B29207DA188C2F1BA626EDBF46, A05DC873406B236E4DDBC038DC4D2627
+ 30: FF3BD8D4E1108E98FBAE2E28BC12819CD7956BC491C0B3A291FBEE739599, 68DFE58473BA2818A23095D1D6EC065C
+ 31: F175230606040ADACEBAFE4D58BBD140B2D45E8BF7E5C904510B58E4B53D3F, DAF579E1A12481D39F4DCFB7C28794B1
+ 32: 261388D491EF1CB92C261FD9B91CAD5B95440DE0A747144EB8697699F600801D, 749056EBEAF4F20CD8746AA8C8846C47
 
 OCB-rc2 (8 byte key)
   0: , 1A073F25FF5690BE
-  1: E4, 6EC51CC8940B5924
-  2: 4468, 4C549CEC13F5744D
-  3: D2CE47, 3B34AA5CACF700A0
-  4: 4D98182B, 43851C4905037752
-  5: 5784656E03, B1956D2F35E190D6
-  6: 612EC3D4BBBA, 0DA8B476C515C20F
-  7: 88CA9BED760036, FA5C4349AB03192F
-  8: 61219479ECCDC295, 024AFAC39AF5DE41
-  9: B2205D0B520ECD3C98, E8D7F09F54045A91
- 10: C4B8820AAF0CAFC7F16B, 32AC2DA632FFA7C8
- 11: 4EF4A33C630329020CA0B6, 00B94EC22CAA440F
- 12: B26FFEC28419F7ED99B241FB, E484E08689C26430
- 13: 588D22959AB8D1582049EE0486, EE7E0E38A42BCE31
- 14: 86A1FD658FC2AC0E1ECE0D528AA7, CDEC84E55E0BE78C
- 15: C00B073B48026E16562924BFC8EE5A, C65C71EBEA6016B6
- 16: D4E298B1E610FEBAC020BA0D0507F0F1, 68B094F6F2C46BA5
+  1: F4, 3D3221E92E40F634
+  2: 2C76, C22C20B7231A0DB9
+  3: C647CB, 3E6348D996399629
+  4: 2021891A, 8EF76B24E9D55FDA
+  5: 1966CBCBBF, 310D24024D573E8D
+  6: 42C15AC9AAF0, 217E83C0CDE4F077
+  7: AB70F3F73DF0B6, 16AB2679D96A591B
+  8: B7C7DD845D7E76DD, F33065EA531545CA
+  9: 468CC16A37CF63EA73, 88879733F70AE3D3
+ 10: 4F769E25A7346E22A932, 26E1A92FEDEE0597
+ 11: 304A8B53B1CD24C6C27C17, 48B46E9F091B0B2E
+ 12: 4E3DF867FEFF0B8E06D5FA70, 53BB48BFB8AB4750
+ 13: 2BAB3F0A8C38A3BD3C49DBBA5A, 52303CADCBB6D312
+ 14: 3D04A29924589AAEF93A29003EE7, 120EF9364B83748F
+ 15: 486127A80E4EC599C461451CF1D79B, 2245D51599CAD629
+ 16: AF8FB3FD2DB343F1AFF564FCBEA58785, 805BF441E660B0B0
 
 OCB-des (8 byte key)
   0: , 8A65BD7DE54082AD
-  1: 7E, 91C5CD7987CC46CC
-  2: A275, B76B5A4ADB75D0B0
-  3: AB0C5D, 2C463609C9933886
-  4: C1ED86D4, E79AE10223890163
-  5: C4D04AEDEB, 509A81814B7873A9
-  6: E0FD095B644F, DE5139ADD9BE6250
-  7: CDD1164659654B, B0536BB2817725FC
-  8: 759F0E801E5AD992, 71EEB01DFFD9D946
-  9: A1E8BCFC90324AA3F3, 5B61AE171ACD4721
- 10: 3D0BE9B40B8B7933976E, 1D33B66102AE70BF
- 11: 338F0213A7C843CC335E20, 215F1AF51474E391
- 12: 9B05F57853F4319140533EBD, ED4425C38848550D
- 13: 16CCD44B543C1B6939D9F7122C, 22B0577679223676
- 14: 092E7CE7DFE6C7B07A672680AF81, 761C1C267F62CFC4
- 15: ACE1AB7120D4092868143FC3E76179, 165DACD587304D1C
- 16: 9D3764DCD797FDA981A440BFBFCB0F2C, 538254F6164119C4
+  1: A8, 3A83897CC8EC7CF6
+  2: 9256, DC66C39C7DD87D93
+  3: C145A0, 45967F3764F62F48
+  4: CD314BAB, EF38B0213259C3D4
+  5: 7074014741, 6748F4BAF06DD7BD
+  6: 9A874CAE01F1, E382DB7235624104
+  7: DFA0D86DC4CA84, 627ABB432E50455E
+  8: 685C2B2CBDD8D144, D166082E085063BA
+  9: 53515DAAC7F7B8CE1D, 6680B6C26E1B0994
+ 10: 2B3967812BF4155A8D36, AFED7F38AFEFC543
+ 11: F4E5AC3CC5913B8A7F35FB, 6181DD3C46A6C24F
+ 12: F3EC89AD4235287D53715A81, 12CC354833FE5BD8
+ 13: 66D554AC2CA85C079F051B8459, 097F31088CFBA239
+ 14: 8746061C26D72771A7586949A3E4, 6CEF3565D0E45C6B
+ 15: FB3BCC650B29F418930A467EA4FB73, 64D12723E100F08B
+ 16: DE1C27E9B3C391AF5DF403291F2C084A, 6BADE4638AE46BE2
 
 OCB-3des (24 byte key)
   0: , 9CB7074F93CD37DD
-  1: 90, DC4E7B29A434DAA3
-  2: 3139, 09BF34C4F770ADC7
-  3: 77161A, 9ACB27184F3BF196
-  4: 1F7666B5, C6578EB1CCE25553
-  5: 043240D354, 23D090F6DACE0B03
-  6: BA84DE76B081, BEBC521446F286C4
-  7: 3EF4272C6AF1BB, A99BD626436F2586
-  8: ECE6A8B0C4EF8D63, B675ACED7D2B28FA
-  9: D4FCF97B677A2CDC2B, BC6B8BC16BFBFB20
- 10: DF899D92AD0FBB3CA443, 23D486A6B0DBD5D1
- 11: 1A95F4AF984ECAD4CA52EF, 34DEF497F95BF424
- 12: D32ADD65BA8604BFB0980BF6, 01C2758914C4D0DE
- 13: 6D477BC51505C8FD9EDA926596, C5A338A6AF687597
- 14: 37AE388D897D22789CB79B17E1F1, 75E7372DD653DF15
- 15: F24F950FF2DD2054510E67EFCDC4DF, 705A27ECFAE74710
- 16: 1D8AD09B1124EFF0817871754FE6ED40, 3D143151197C59B4
+  1: 4D, 51541A838A154E0B
+  2: 5C77, 60E86F2F1F4C6F96
+  3: B3D2F0, 7D74A9E6A061457D
+  4: B3556075, EAF7A89A07453460
+  5: 1B61CE7230, F90D18620E1AB877
+  6: 3987FEC8D0D7, B5EF04DEE2E528F9
+  7: EBD0A7EBEEFF3B, A72CA24DD77A5DDA
+  8: 429FB38DDABF76D4, D0578484C37227C8
+  9: F8DF28BF5C4CD28B1B, 5E7C4DC8E694E3B4
+ 10: 2BF436BBE063F7E830C2, 8D919637C973C71B
+ 11: ED21656C8878319F1B7D29, 8813280C1277DF26
+ 12: F45F90980D38EDF5D0FEC926, F9619341E273A31F
+ 13: 52F2D3CACC294B141B35D73BBF, 7BBC3F1A0D38F61F
+ 14: 2E6DA0FB55962F79B8E890E8DD8D, 8060799DCAB802E4
+ 15: D6F9A6B2420174C499F9FE91178784, D3AAF969ED2F7215
+ 16: 4F1CF285B8748C4F8F4D201C06B343CA, 203A2692C077F1B5
 
 OCB-cast5 (8 byte key)
   0: , 77E8002236021687
-  1: 98, 9D73A3403B345699
-  2: BF24, 80A7E8123CF54C9D
-  3: 93369E, 01A967A92245F16E
-  4: 5D917EED, FFFB66F53851ABFD
-  5: CA6E2BAEFB, 53596129002C9B7C
-  6: A66DE171E377, 25BC0AD3B0AC21AF
-  7: 04A05EADA80780, 7703120B8DF8B98A
-  8: DD040CCEA55C8830, E4B8ECEAADC292A1
-  9: FEEB112E469F4AB637, 92F0ABA0A554C9B6
- 10: 5BE2019137752075F35D, 0DC52AED0F2C3894
- 11: 75DEFFAF2C152E6745A97F, 7752A70A2D9D184C
- 12: EF90E23366790D62DAE5BA66, 829A9C7684D03C5E
- 13: 0A4689BD15E338056782F19B13, 5676FAE6E2745929
- 14: 2534CCD55A471E5840447B6BAE6A, 33D1B4876EFD5FE0
- 15: 6FC1B4FD3A202CB14D9ECCF88F0E55, 13D8EDBE1BE8F0A5
- 16: E8BACB11E0864011D72B599025DA2FDF, FE7397323F7DF138
+  1: 52, D57DF1037B6A799D
+  2: 31C9, 7E781759B057D695
+  3: 5C8324, 56965D6CB2C97C0C
+  4: 17D99099, 7C52B5D09475F5D3
+  5: 400082C475, 3CA5CDB9B4A0FAE9
+  6: 4DF0E4000C24, DCFEE2C3384F9731
+  7: 10004C3CE32255, 0A6832F985F61658
+  8: FFA6EA76B346893C, 6202693B153254D6
+  9: E96378C94D246AB51C, 5B259FEB715B9159
+ 10: A9BED2D59A92D3D9418A, 1E7E066C098A023D
+ 11: 4EF144B7D4622BAD4DC840, 5DAB2C1D0DF56B08
+ 12: 6DBCDF56E57CE47DD3D0CF44, 2A24F2A224368F55
+ 13: 43241A0AD933635D7C8EAD47DC, 86B4B5AC22177F19
+ 14: 920D6BDBE073F3C75052420C883D, 10943DBB23BD894D
+ 15: B2C75DF024269833B039CAB19EC865, 84B7DBB425E45855
+ 16: 6A9424B6A873BB7155C01DC87E23EC52, 82C5047655952B01
 
 OCB-noekeon (16 byte key)
   0: , 72751E743D0B7A07EFB23444F1492DDC
-  1: 65, 2BDF86A7C46460BDBB8252E176CB7105
-  2: 9BAE, DB8AFF53F1AEF4FC5A9BF3E1A5DE9430
-  3: 96C214, 25585611B7FE5EC176627DB0BADCBEA4
-  4: B6046645, 32F5FF1347797760C872D92FB3E48085
-  5: E5C89E89E7, 5B1868C4655FF6B28BEEDB0C8A37CBC6
-  6: CB6CC16CBAA8, 8A7C7213989BE3D89D8EBE31024DDDE1
-  7: D09EE74CF99850, 565DA08FB8F154FDBAB27E432324BF77
-  8: F389A90F999147CC, 618535B5685A9F76012B99B0C6FDFAD5
-  9: 32B110B50A8D6F67D9, 379DBCC0B20E3523935621A7C1506A28
- 10: CAF759FE91C8794D8D93, 50EA638B83E1C85F210989495A8724CC
- 11: 332B07DA0F942C8F22C1E7, 504DCD9521A42C77C05CE9ABF8FB4FA0
- 12: D0C422738243A89E54B734A3, FD4FF9C337CF2785EBEC0C128482371B
- 13: B899277B6557E5E685A5649E64, 868F039212C96E212E280A4DBA6555FE
- 14: 15E617DAACB18D93428C3BA043B1, E072A199CFAA617CEA2A176B75682516
- 15: 58B04DDD83045E773811BD6C371978, 6EEA2DCB6DECFC0B542DECAAD37024B3
- 16: 8DE6C50DD08FD141E7FF20FE3262A340, 6F826FA2FCF34E4285975DE9FB0FC4D4
- 17: A14711565B0CBA6C88370737F97F803F7E, D84950FCD2C72536711A1503348975A7
- 18: 5AEE5927EF89D3A09CDA7CC7183EEB701471, FC8DB44F4D6188581A0567C3DF2C498D
- 19: 12ECFBFF02C5A37DFE7772732659ADFD7DC349, 8ED7F4AB648339A174ADA3317BF82C64
- 20: F57930534156A623A05FA3A30B4CE5339E8209A7, C78081E80D95BE642DC4F194C902AC3B
- 21: FF92DF299ADF1EBD22CEAE3876B5DED0AE5EEE2F9B, C491571613AA18C9C4305A9595575EE1
- 22: 2BBCC3079A01962F7B406662A20924C2AA5D65493FCE, 6AF63F2B8831F8CD41522D32A8BD1C1B
- 23: 9F05A8AF6256ED46EED6BE3E5F9F5F13A3804AC0DFC110, E310472DB635D60B5BAD5F5B3E24E768
- 24: DCD82591D67AEEDA00ECAC67E91BC62CF42FE69D6B9A427A, 9758F103B57D3AE6533F736F17C95D48
- 25: B6388AD629A4A951F2CDE98C80A81C8C499ABFE073EE81FD6A, 70A8217A7652D8325EB717359C1D7830
- 26: 51D9F3341368BE00BE709F6F009BA53F852CA27ADEF439CB5A59, 6772C710B9D6159F1B0F4BC2BD5DC1A4
- 27: 4710196F162BFF2BD87945AE012CE9FFC7C6EB651C716DCFBB6706, A338043240EA22FB4B50A1D6BCA241FA
- 28: 8120FAF7FC1FD6157519A296EC5513F2907ECB8792219CFBE0A3E17E, 45EA2ADF503BCDFD60EDFEA24168D539
- 29: 34FFD8289321EBD9029158A2C217DC867436CF5346B3B940B3B9339C0A, 3A7C1C2F5CFADF3F4C601C005333826D
- 30: 8E97C51214057F523B915BE5EE84D72979254577077FD6D9FDA63215668A, BB5E2FC288DE613716BA3F3A69F6D17A
- 31: F1A13BEC82D4FB33A5E5E6E1A5DD47DDC7F67AF5EBCAE980AB1B641A76FBDE, A2BBEA281BA38731F855EF8533B94C60
- 32: 77CC8CB5ECBD4CDFC9BA9414B6E6596D7ED01B24C46D9EBCFE150FEA2687EFC3, 5295D9ECAB6E2CC4C6C60D27F4A5E7F9
+  1: 61, 41BDE9478A47B2B612A23752B5A42915
+  2: F4EB, 90EF542D89F867CDFB1A0807F8AA3CC6
+  3: F5A59B, 1BED873B613096546D4C201347CC3858
+  4: F454610B, FB4035F28AA75221F599668ABBE21782
+  5: 382FC932F1, B40270E2084E8DCEB14C6603D080D7C2
+  6: 18F921441119, 47F1F889B307298150750E81E94AB360
+  7: EF01C70C9D1810, AE0439DBB3825F27CF846B43E4C3AA80
+  8: 89863EDCAD471C3A, F4E8AF73BFC4CB79AECBBB3774DAF8C2
+  9: A6F494092E066A70F6, F73D3B04752B7D913420C17E656C7F86
+ 10: 342459682E0A8D53AF4F, 61E7CF14E9878E0726C64B1E8CA08BFF
+ 11: 65E520D5A99825DE2441D1, 7A2AA740D786EB7015C61B31959E55D9
+ 12: 2F96D0BB72E37DA202410302, 1A313242527FB522289094B9AFDB5F7B
+ 13: 3E8F8A1FCEE3F866EC29128BA0, B8065DA2DABF04129E5AE28ECC11A15B
+ 14: C2C15976D3C2499ACB9454878131, 372CAD486E104098EB1AA78A2922A1BE
+ 15: 1F12CADABAEE80E448B7EDCB42F8FE, 86A38DE5363787F55B16462C684E08DC
+ 16: 3B9ABB3304E75BF5B63E7F5B5A3F3980, 1FBD6B93E457B9779E2D12D78301EFA9
+ 17: DC0CD805E43675A4317452E378AD48AC4C, 40AE4AFA4B3E580EFDB4AD0AF5BC4E4A
+ 18: E9DD52EA7264C6C7BBA39B761B6E87B65687, 4061DD65D5E7FFFE8D3D4261494D4F8C
+ 19: 80A9735CA1175072823828123413CCE772D521, D3378A12E79C49A37378DF527A460AB2
+ 20: 09AD495AFFBF7CB8841262E7E5E8952878D4391A, C25D7A98C6F260B5FBCA3B8B5F7F33C1
+ 21: 3925615707CC40C351D4A49794778545BC1F683175, 97622437A7208383A4A8D276D5551876
+ 22: 5BB0D41ECD7BD2CF0B12A933255D95A3FE35E4C896BB, 4B8AD84EEA3156765A46AC19C68B6F88
+ 23: 1EE71FE23CBFD5683AB1B391FC12B4E5952E4E6AA3D189, B0FD75996F28E071EB6C86BD7102BAA5
+ 24: 0AA3D8C98AADEEE1867B13B017DD263BD16E960DA64FD071, 5204780963A62C2F4F7B3555BFF73836
+ 25: 3A88B6F2AE321B226DA90B98E04A6A1589411BEDBE994632D5, 5638AF04EACF1EB986AC0702B4373A22
+ 26: C2731661AC634A4DC0345F040DA7AEE507A3B9D019B5958543BA, 4C67D3FE37ABEE928B3BB812E7346823
+ 27: D3E7651AA6DA035D05D599EFB806E8FD45177224593B5974758419, 5814E84258E1B9BD56A188AAE6F25138
+ 28: 17818E7102B8C123230C5D64F18BE94C3159B85C8F7B64A7D4712CDA, FAA905B587A93DCF600BA8589A985432
+ 29: BCA4335C6C29D978032C216114D39C01C6F161BF69D5A1CE55FBA8C575, BE24424A162E43A19755E2EFD274DBED
+ 30: 24C33CEE022F8A633DE9DFD009F535B52BCF64F390D2375E5BED65B70D08, 138F21D54B6B7E34628397DCDE0D33BF
+ 31: 838FE950C8165ADBBD6B61E9732F9A727CA7AE74376981382F0C531C331915, 0742E769CCBA2D1CAC7CAD4E0F012810
+ 32: 57CD778DAD477271794FBF763662D97F8A10B17D70A69FDCB974FFE67E558519, 942C7D1C200C3845748F8131DF71AE26
 
 OCB-skipjack (10 byte key)
   0: , 90EAAB5131AEB43B
-  1: 01, D8C438498F94B782
-  2: 23BD, 6D650F6CB26C0BEE
-  3: E5D16E, E4459817F4A898E6
-  4: 126212FE, D97B43C7BFB83262
-  5: A1580EA0A3, BC7C325FF295A404
-  6: 9374B704E26D, 97DBA225A0F0136E
-  7: BC2E8E234CBE33, 4603D9A50B9915ED
-  8: C7629762CF53A687, 5DAF80ABDD01CD74
-  9: 151D35020935EFB225, 0898987E5F710240
- 10: 934BF9846689A0DDC434, FF698391DE287C55
- 11: 8AF680448D95D32DE31B03, F60110D8968D1FB5
- 12: E03FDF4028EBB30164C297D7, A80E7FD7A5028E62
- 13: 614BF4A0A567314FA3990020FC, 6B1C9D495FED96C7
- 14: D8BFFD57B4BB8C100F3F026105C3, 2F99A8895B86B798
- 15: 81B2DD86C7252B4FD8D4FD385E65BB, 7788260BCABCCC8F
- 16: 8AE9FEF234B5FC98AE95C1AFD6780C61, B332941A6EB467F7
+  1: 2F, 6274B82063314006
+  2: DAF6, 6A6BCCE84FD4EF02
+  3: 5C2A88, C83D54C562A62852
+  4: B6E8FB5E, C44459EF41C8F296
+  5: 6C0888C119, 269DD7657BD0225F
+  6: 1FD9AD7ECCC3, 3CA090F46B107839
+  7: 1EDBFF8AE458A3, 440380BF9745132B
+  8: 04DBECC1F31F9F96, 2653620A4877B0E6
+  9: 908AE5648AF988A896, 00180FF33C1DD249
+ 10: 53E63E0C297C1FC7859B, 36616209504C4230
+ 11: 407BE16144187B4BEBD3A3, 4754B7DD4DB2927B
+ 12: 9961D87CFEDDF9CC22F2C806, 5947FC41E6B9CEC9
+ 13: 9F5254962E4D210ED8AC301252, 97A392BEAF9B3B04
+ 14: 379FDA76ECCFDAAC10F67FBF624C, 1D895ABD932BD5EC
+ 15: 1D5A7AD556FF3078284BB21A536DAA, 01FAE2F4936ED9D2
+ 16: 4B8B71396924880CB33EA6EC6593F969, A0F4B1BE3B9B4CCE
 

+ 0 - 76
notes/omac_tv.txt

@@ -199,82 +199,6 @@ OMAC-twofish (16 byte key)
  31: C24FCA5DD4AE0DF2BFF17364D17D6743
  32: DC6738080478AF9AF7CA833295031E06
 
-OMAC-safer-k64 (8 byte key)
-  0: 726FE2DD40A43924
-  1: 2A138B65EB352621
-  2: 9588A1B53E29616C
-  3: C025DEFDE1A59850
-  4: 73D062F1B6D8E003
-  5: 944598A2FC8A2D76
-  6: B176C25D8CAFFC98
-  7: 14F05014DE6A090A
-  8: A7B9847B2CE22D0F
-  9: FCD71310CBAA3A62
- 10: BFF00CE5D4A20331
- 11: BEE12A2171333ED5
- 12: 333FD849BEB4A64A
- 13: D048EC7E93B90435
- 14: F04960356689CFEF
- 15: 9E63D9744BF1B61A
- 16: 7C744982F32F8889
-
-OMAC-safer-sk64 (8 byte key)
-  0: E96711BA37D53743
-  1: 7DCFF26A03509FE1
-  2: 0A20EF19C8EE9BF2
-  3: FE2883748A6963CF
-  4: 557060195B820A18
-  5: 771A7931FBBE5C0F
-  6: 6BDBCE5F96CF91D8
-  7: F3B924CCE8724595
-  8: EC7191286D83C2C3
-  9: 94F55B19BB7A8AC1
- 10: 2189F4F2B06A8CA4
- 11: 99853DAEBCA33A46
- 12: 66EAC37A033802D7
- 13: 845D7AA866F8A8AD
- 14: 33A874DFECAC22AC
- 15: 63DD9F7A7F3683DF
- 16: EAC277D951676C44
-
-OMAC-safer-k128 (16 byte key)
-  0: 8037B89AF193F129
-  1: FF2314E87BA6AFE1
-  2: C3243DF896B61D85
-  3: 0F61C715CE821AB8
-  4: EBFDC6A9CFD2F5A4
-  5: AB6497D7AF2C7FFF
-  6: C920CEEB7C1819C2
-  7: 3E186951B545A7E5
-  8: 5EA36A93C94AF4AC
-  9: 6A2C59FAE33709BE
- 10: BF1BAFAF9FC39C19
- 11: 69EB6EF046677B7C
- 12: CDDCEE6B20453094
- 13: A3833BD3FED6895C
- 14: B6C05E51F01E049B
- 15: 90A2D0EAB739D39B
- 16: 07BF607A161D0A66
-
-OMAC-safer-sk128 (16 byte key)
-  0: 5E8B137A3946A557
-  1: 0228FA66B13F3C7E
-  2: A6F9BBAFF050DCDD
-  3: F75880F684A796CE
-  4: E0AEFB8E32040EBD
-  5: 9F65D658B86D310F
-  6: 3FA52804FB46CCAA
-  7: 2F6D12D199FCD2FB
-  8: CB56AF60AFB4D2BB
-  9: 8E6F0FF6FDD262FD
- 10: 490245BE3CCCEDE2
- 11: EFD319AE46C73005
- 12: 43E00E545C848995
- 13: 10444B41ECA15EBE
- 14: 521775C389D5BE71
- 15: 9B683EF8B097FEBA
- 16: 3C5D746EED09530A
-
 OMAC-rc2 (8 byte key)
   0: F001FE9BBC3A97B0
   1: 8F8DC9C952897FBD

+ 331 - 0
notes/pmac_tv.txt

@@ -0,0 +1,331 @@
+PMAC Tests.  In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed.  The initial key is
+of the same format (length specified per cipher).  The OMAC key in step N+1 is the OMAC output of
+step N (repeated as required to fill the array).
+
+PMAC-aes (16 byte key)
+  0: 4399572CD6EA5341B8D35876A7098AF7
+  1: 580F7AA4AA45857C79BA2FB892228893
+  2: 24D2D1DBABDB25F9F2D391BB61F4204A
+  3: 083BF95E310B42A89751BC8E65ABA8B5
+  4: 69BEB9268CD7FD3D7AB820BD7E226955
+  5: FD71B0E647ADB4BB3F587E82B8B3401A
+  6: 07EA46271081840737CEB1AC9E5E22E3
+  7: FFA12AD9A9FDB5EE126084F82B381B10
+  8: 8A11AF301AAFEAC8A75984ED16BB3292
+  9: 368BDC3F4220E89B54C5F9D09FFB8F34
+ 10: 8B6DBFF776FD526147D1C4655626374F
+ 11: C538C09FC10DF38217CD8E799D8D1DC9
+ 12: FC1264A2051DEF73339432EA39443CFD
+ 13: 8AF37ED2FB2E8E30E9C4B75C1F1363E1
+ 14: 4295541FC62F6774068B8194CC9D9A46
+ 15: CFAF4D8EA09BB342F07131344DB0AA52
+ 16: B6CBD6E95959B2A8E22DE07E38B64D8D
+ 17: 3124E42DE3273B0F4806FB72A50F3E54
+ 18: 252D49403509B618AB3A6A1D99F9E9FA
+ 19: 9CDA75594CB696EB19C022DDA7324C10
+ 20: 33BB8AE43B7BC179E85F157FA19607D0
+ 21: 12FE91BCF2F2875379DC671C6F1B403E
+ 22: 416A3E519D1E406C92F8BB0DDBBBB6BF
+ 23: 6F98DCCD5A8D60DEAF612ACCEDD7E465
+ 24: FFCE7604609B2C3C050921854C638B7E
+ 25: DD2BB10AA07A5EC8D326BB7BF8D407F4
+ 26: 468BFE669FCDF354E4F9768FE1EAF8F6
+ 27: 01724D2F2C61EB4F380852218212E892
+ 28: 2D90EC658F57138505598C659C539A3E
+ 29: 6301EAA0E1500FFEB86752744EFFF23D
+ 30: 3CCB177486377616056D835F6F857F7C
+ 31: BFB3C7755C1F4543B516EB8610CB219F
+ 32: D5C505847D7CFFD8CED848F6CB613105
+
+PMAC-blowfish (8 byte key)
+  0: 3B7E4EFE92FA46AF
+  1: 746840017C38C892
+  2: 3B6A92C731465B64
+  3: D89D3B05143B6704
+  4: 43F70D54B808B7CE
+  5: 84E4063AB32F046C
+  6: A7E78CD5CCD23805
+  7: A78FB083475FEF10
+  8: D4F6C26B5386BA25
+  9: 184768A079853C90
+ 10: 0702E6C8140C5D3B
+ 11: 786D94565AA0DF4B
+ 12: F6D36D3A2F4FB2C1
+ 13: 7BB3A0592E02B391
+ 14: 5B575C77A470946B
+ 15: 686DAD633B5A8CC3
+ 16: BDFE0C7F0254BAD5
+
+PMAC-xtea (16 byte key)
+  0: A7EF6BB667216DDA
+  1: B039E53812C4ABDC
+  2: 87D2F8EA5FB6864D
+  3: F85E3F4C1D9F5EFC
+  4: 4EB749D982FB5FE2
+  5: 0BFA0F172027441A
+  6: FF82D01F36A6EC91
+  7: 3BC2AA2028EBBD7A
+  8: 15AA03A97A971E2A
+  9: C974691F5D66B835
+ 10: 4FC7AA8F399A79ED
+ 11: 2633DA9E94673BAE
+ 12: 82A9FD48C5B60902
+ 13: 31BF6DA9EE0CE7E4
+ 14: 26B2538601B7620E
+ 15: D103F3C0B4579BE5
+ 16: 031346BA20CD87BC
+
+PMAC-rc5 (8 byte key)
+  0: C6B48F8DEC631F7C
+  1: F7AA62C39972C358
+  2: 0E26EC105D99F417
+  3: 7D3C942798F20B8C
+  4: 415CDA53E1DE3888
+  5: A314BA5BCA9A67AC
+  6: 02A5D00A3E371326
+  7: E210F0A597A639E5
+  8: D4A15EED872B78A2
+  9: AC5F99886123F7DC
+ 10: 69AEB2478B58FFDF
+ 11: 8AB167DFC9EF7854
+ 12: 945786A136B98E07
+ 13: F3822AB46627CAB5
+ 14: 23833793C3A83DA9
+ 15: 70E6AB9E6734E5A6
+ 16: 0705C312A4BB6EDE
+
+PMAC-rc6 (16 byte key)
+  0: C7715A17012401DE248DC944DEEBD551
+  1: 5B804C6CCDF97BB28811C9ED24FE6157
+  2: 7528378C052F4346253CB0DFA3D251C7
+  3: 6DA86EE0B28606861B1A954D7429A93C
+  4: B4DFF84C25937FB50EE79D4037323160
+  5: A60FD9BE5E1FF67EC9734776C8781096
+  6: 81D3F8EDC0A197DD3739EAE648F38580
+  7: 8BAF47F02120E898916D678DBD0C1641
+  8: 7A9EEC96F10B7CF557B61EF35BB55B08
+  9: B88C11221014F8AE048E56C427DF4A46
+ 10: 4BBA8EED89F357861A265006816D9B04
+ 11: 8497C1D55010A65ED8C3688B75A7CABF
+ 12: 95E1720C06A373CAD1A22F432F26BCCA
+ 13: A175FB732692831E96AFB587BC49E18C
+ 14: 54EBC04FCFD90302907BF77C4D8AC77C
+ 15: EA9F13EE5548CDF771C354527CDDA09B
+ 16: 4EDBCFD0E2E6B321530EB31B3E8C2FE4
+ 17: F412304C1A5B9005CC3B7900A597DFB5
+ 18: 3B9247C12BB25DF048BF5541E91E1A78
+ 19: 39626488635D0A6224CD23C13B25AE8E
+ 20: 40305F5C2FCEF34E764E33EF635A3DC5
+ 21: F84499804086033E85633A1EF9908617
+ 22: C4D263CDC7E0969B8AC6FA9AD9D65CB8
+ 23: 6137DC840E61EA6A288D017EFB9646FC
+ 24: 8619960428EB29B1D5390F40173C152F
+ 25: F0464509D0FBDBECEC9DFC57A820016D
+ 26: 630EED23E87059051E564194831BAEF6
+ 27: 4B792B412458DC9411F281D5DD3A8DF6
+ 28: F2349FA4418BC89853706B35A9F887BA
+ 29: FEAC41D48AEAB0955745DC2BE1E024D5
+ 30: A67A135B4E6043CB7C9CAFBFA25D1828
+ 31: EC12C9574BDE5B0001EE3895B53716E2
+ 32: 44903C5737EE6B08FD7D7A3937CC840D
+
+PMAC-safer+ (16 byte key)
+  0: E8603C78F9324E9D294DA13C1C6E6E9B
+  1: 3F1178DFC2A10567D4BCC817D35D1E16
+  2: 27FE01F90E09237B4B888746199908EE
+  3: 4F5172E3D8A58CD775CD480D85E70835
+  4: 74BED75EFAAB3E8AA0027D6730318521
+  5: 54B003AB0BE29B7C69F7C7494E4E9623
+  6: 8A2DAD967747AEA24670141B52494E2F
+  7: 69EB054A24EE814E1FB7E78395339781
+  8: E59C2D16B76B700DC62093F0A7F716CC
+  9: AB227D6303007FD2001D0B6A9E2BFEB7
+ 10: AE107117D9457A1166C6DFD27A819B44
+ 11: F84DE551B480CED350458851BAE20541
+ 12: B0EB5103E7559B967D06A081665421E0
+ 13: CDB14F3AD1170CE8C6091947BE89DE7B
+ 14: 24FA2F476407094152D528FCF124E438
+ 15: 440144B31EC09BD8791BFE02E24EA170
+ 16: 697D268A46E8B33CEC0BAB8CAF43F52D
+ 17: 587CBDE7608449BD162184020FBFCC8D
+ 18: 3EA999C2169CC65735737F50FCD7956B
+ 19: C6D692698CD8BEEBF2387C6A35A261B0
+ 20: 46DAB3AD3C4E2EF712FAC38F846C63E1
+ 21: 7261E68B530D10DDC9AD4C9AB5D95693
+ 22: 4D0BA5773E988C2B7B2302BBA0A9D368
+ 23: 8617154626362736698613151D1FD03A
+ 24: 23CF25F68B281E21777DC409FE3B774A
+ 25: CA626956C97DC4207D968A8CC85940B8
+ 26: 24C39BE160BDBB753513F949C238014E
+ 27: 83CD65C010FB69A77EEDEA022A650530
+ 28: 1A72DC8438B927464125C0DFEACDE75D
+ 29: 546054936A2CB5BFBB5E25FFD07C9B51
+ 30: 0EB81A268F1BB91997CB9809D7F9F2AD
+ 31: 7D08B4DE960CADC483D55745BB4B2C17
+ 32: FD45061D378A31D0186598B088F6261B
+
+PMAC-twofish (16 byte key)
+  0: D2D40F078CEDC1A330279CB71B0FF12B
+  1: D1C1E80FD5F38212C3527DA3797DA71D
+  2: 071118A5A87F637D627E27CB581AD58C
+  3: C8CFA166A9B300F720590382CE503B94
+  4: 3965342C5A6AC5F7B0A40DC3B89ED4EB
+  5: 6830AB8969796682C3705E368B2BDF74
+  6: FF4DCC4D16B71AFEEA405D0097AD6B89
+  7: ADB77760B079C010889F79AA02190D70
+  8: 5F2FCD6AA2A22CEECAA4671EE0403B88
+  9: 70DD6D396330904A0A03E19046F4C0BF
+ 10: 8A2C9D88FA0303123275C704445A7F47
+ 11: BA0B2F6D029DCD72566821AB884A8427
+ 12: C8DF45FF13D7A2E4CFE1546279172300
+ 13: 512659AD40DC2B9D31D299A1B00B3DAD
+ 14: A8A0E99D2E231180949FC4DFB4B79ED4
+ 15: CA161AFB2BC7D891AAE268D167897EF2
+ 16: D6C19BBDFFC5822663B604B1F836D8BD
+ 17: 4BF115F409A41A26E89C8D758BBF5F68
+ 18: 02E3196D888D5A8DE818DBCBAD6E6DC7
+ 19: 995C9DD698EC711A73BD41CAAE8EB633
+ 20: A031857FADC8C8AFEABF14EF663A712D
+ 21: 124695C9A8132618B10E9800A4EFACC5
+ 22: 997E5E41798648B8CE0C398EF9135A2C
+ 23: 42C92154B71FB4E133F8F5B2A2007AB2
+ 24: 945DC568188D036AC91051A11AC92BBF
+ 25: D5A860CC4C3087E9F4988B25D1F7FAAE
+ 26: 6CD6ABF8EDF3102659AFFBE476E2CBE8
+ 27: 45ECD0C37091414E28153AA5AFA3E0B2
+ 28: CBA6FE296DDE36FE689C65667F67A038
+ 29: C4022281633F2FC438625540B2EE4EB8
+ 30: 864E27045F9CC79B5377FDF80A6199CF
+ 31: 0D06F2FAEC5AA404A4087AAEBC4DBB36
+ 32: 0F396FE9E3D9D74D17EB7A0BF603AB51
+
+PMAC-rc2 (8 byte key)
+  0: E5AF80FAC4580444
+  1: 6A15D6211EB4FF99
+  2: DDB95E9486C4B034
+  3: 9764761DC2AAD5C0
+  4: 1B1CD2E799D44B4F
+  5: 4F80FE32256CF2EC
+  6: 7B70CF31C81CD384
+  7: 9BC10DD9332CF3BB
+  8: 628189801879FDD8
+  9: 5FC17C555E2AE28B
+ 10: E20E68327ABEAC32
+ 11: 5D375CA59E7E2A7C
+ 12: A9F4CFC684113161
+ 13: 3A0E069940DDD13C
+ 14: EAC25B6351941674
+ 15: CB8B5CF885D838CF
+ 16: DCBCDDFC06D3DB9A
+
+PMAC-des (8 byte key)
+  0: 086A2A7CFC08E28E
+  1: F66A1FB75AF18EC9
+  2: B58561DE2BEB96DF
+  3: 9C50856F571B3167
+  4: 6CC645BF3FB00754
+  5: 0E4BEE62B2972C5A
+  6: D2215E451649F11F
+  7: E83DDC61D12F3995
+  8: 155B20BDA899D2CF
+  9: 2567071973052B1D
+ 10: DB9C20237A2D8575
+ 11: DAF4041E5674A48C
+ 12: 552DB7A627E8ECC4
+ 13: 1E8B7F823488DEC0
+ 14: 84AA15713793B25D
+ 15: FCE22E6CAD528B49
+ 16: 993884FB9B3FB620
+
+PMAC-3des (24 byte key)
+  0: E42CCBC9C9457DF6
+  1: FE766F7930557708
+  2: B9011E8AF7CD1E16
+  3: 5AE38B037BEA850B
+  4: A6B2C586E1875116
+  5: BF8BA4F1D53A4473
+  6: 3EB4A079E4E39AD5
+  7: 80293018AC36EDBF
+  8: CC3F5F62C2CEE93C
+  9: EE6AA24CE39BE821
+ 10: 487A6EAF915966EA
+ 11: D94AD6393DF44F00
+ 12: F4BFCCC818B4E20D
+ 13: 2BE9BC57412591AA
+ 14: 7F7CC8D87F2CDAB7
+ 15: B13BFD07E7A202CB
+ 16: 58A6931335B4B2C2
+
+PMAC-cast5 (8 byte key)
+  0: 0654F2F4BC1F7470
+  1: 3F725B162A1C8E6B
+  2: BCFBDC680A20F379
+  3: 027922705BCACDEE
+  4: 44E2F4BE59774BA4
+  5: 3ABD1AFC8EE291F7
+  6: D96347E717921E96
+  7: 96257299FCE55BC6
+  8: C2C1DA176EE98170
+  9: FD415C122E604589
+ 10: DCBCA228D45AEDA4
+ 11: 7801FBCFAAB9DF75
+ 12: D38CB38574474B7F
+ 13: F5C5A23FF3E80F37
+ 14: 83FA4DAD55D092F5
+ 15: BDC0A27EE0CB1657
+ 16: 87D907CACA80A138
+
+PMAC-noekeon (16 byte key)
+  0: A1E4C84B5958726557DF0855B37AA551
+  1: 5DE20299CA919D3365B493D3D4895F92
+  2: AF7E70C336571A857F62A18649EDB197
+  3: C5F55CFE1AA119C352B64252AD246CBD
+  4: FEF68A0CE08E8BA315B73B62F861824F
+  5: 8321C2958DE4903DC12C42A8845ECC20
+  6: 370466D1324AECF1F5B42E0E01381613
+  7: 5CB900190F5CACBACFE5EAB0CC289D87
+  8: A13C043E6CAAA1E34601A93C497446A4
+  9: 865E11622A4CC8A9E1408E00F56C4543
+ 10: 9DC42C26868374649BD17D69D025CA1B
+ 11: 37D33C11B433C91DA09925CA9E86757A
+ 12: 1373D769C270E7137C953AC0F8F37941
+ 13: 7E81DEC583348B1E2F6267ECF82CB994
+ 14: 505B6329338556518FF364CAA730F5E8
+ 15: 0C085AEEB315968B0BDE904E8BBC6FD0
+ 16: 5FED63259364BE7E5133FF0507DD2D4C
+ 17: F7EE5C80A99AAEADB49E7CC69BFFF679
+ 18: 4388FA5E763A641130940EB705BEFD08
+ 19: 1BC31CA79EBE1674CEBE01BC9988267B
+ 20: BE88961637EFFE2D6905D104FEDD51A4
+ 21: 9C341004FB22AFCC496094E3207CA761
+ 22: B9DAA3620E38FFC7C5D5E7D2D8FE3DE4
+ 23: A38D2E571F037061B4400F1131FDBDEA
+ 24: 61DB71AE77A6EB47F2E9E14E8CBF2F4B
+ 25: 9903A072274CC048EF2C51493266D9ED
+ 26: 1EBEA421DD08859C17DDF39B20A82102
+ 27: F425858618E1A86F4912E4714EFB9E75
+ 28: 3B3D4EA07F7FE6DDFDD02D624ACDFC9F
+ 29: CEEE256591D701514EB17DF73B08A970
+ 30: 5CC56D5D46120C530A23B6C511C685FC
+ 31: 68E484CE18BE28EADD0BBF23291B8237
+ 32: ABD58A9CDF8AA68168A1A402074CF520
+
+PMAC-skipjack (10 byte key)
+  0: 9CD94B75BC43B647
+  1: B069ACB82B12BC7B
+  2: 6DD40E71EB03E311
+  3: 74CBED61D77DBA7D
+  4: DD1B7E0D181537FE
+  5: ACB5B96FA0AD1786
+  6: B34E01EB2567D381
+  7: 9623DAADE57B9549
+  8: 8BA384BABB798344
+  9: B147AA9D5C5C67CF
+ 10: 0033C520F4C67523
+ 11: 42DAC184BEABC3E5
+ 12: 428029311004AEBB
+ 13: AC2BB1C0F0ED649B
+ 14: F7CAA9A3BF749C1A
+ 15: 2C5BD475AAC44C77
+ 16: FEB892DA66D31A84
+

+ 128 - 53
ocb.c

@@ -8,6 +8,8 @@
  *
  * Tom St Denis, [email protected], http://libtomcrypt.org
  */
+
+/* OCB Implementation by Tom St Denis */
 #include "mycrypt.h"
 
 #define OCB_MODE
@@ -34,11 +36,10 @@ static const struct {
 int ocb_init(ocb_state *ocb, int cipher, 
              const unsigned char *key, unsigned long keylen, const unsigned char *nonce)
 {
-   int x, y, z, m, p, err;
-   unsigned char tmp[MAXBLOCKSIZE];
+   int poly, x, y, m, err;
 
-   _ARGCHK(ocb != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(ocb   != NULL);
+   _ARGCHK(key   != NULL);
    _ARGCHK(nonce != NULL);
 
    /* valid cipher? */
@@ -48,12 +49,12 @@ int ocb_init(ocb_state *ocb, int cipher,
 
    /* determine which polys to use */
    ocb->block_len = cipher_descriptor[cipher].block_length;
-   for (ocb->poly = 0; ocb->poly < (int)(sizeof(polys)/sizeof(polys[0])); ocb->poly++) {
-       if (polys[ocb->poly].len == ocb->block_len) { 
+   for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {
+       if (polys[poly].len == ocb->block_len) { 
           break;
        }
    }
-   if (polys[ocb->poly].len != ocb->block_len) {
+   if (polys[poly].len != ocb->block_len) {
       return CRYPT_INVALID_ARG;
    }   
 
@@ -83,7 +84,7 @@ int ocb_init(ocb_state *ocb, int cipher,
 
        if (m == 1) {
           for (y = 0; y < ocb->block_len; y++) {
-              ocb->Ls[x][y] ^= polys[ocb->poly].poly_mul[y];
+              ocb->Ls[x][y] ^= polys[poly].poly_mul[y];
           }
        }
     }
@@ -99,7 +100,7 @@ int ocb_init(ocb_state *ocb, int cipher,
 
     if (m == 1) {
        for (x = 0; x < ocb->block_len; x++) {
-           ocb->Lr[x] ^= polys[ocb->poly].poly_div[x];
+           ocb->Lr[x] ^= polys[poly].poly_div[x];
        }
     }
 
@@ -139,7 +140,7 @@ static void shift_xor(ocb_state *ocb, unsigned char *Z)
 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
 {
    unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
-   int err, x, y;
+   int err, x;
 
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != NULL);
@@ -178,7 +179,7 @@ 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)
 {
    unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
-   int err, x, y;
+   int err, x;
 
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != NULL);
@@ -228,12 +229,12 @@ static int _ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptle
 
 {
    unsigned char Z[MAXBLOCKSIZE], Y[MAXBLOCKSIZE], X[MAXBLOCKSIZE];
-   int err, x, y;
+   int err, x;
 
-   _ARGCHK(ocb != NULL);
-   _ARGCHK(pt  != NULL);
-   _ARGCHK(ct  != NULL);
-   _ARGCHK(tag != NULL);
+   _ARGCHK(ocb    != NULL);
+   _ARGCHK(pt     != NULL);
+   _ARGCHK(ct     != NULL);
+   _ARGCHK(tag    != NULL);
    _ARGCHK(taglen != NULL);
    if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
       return err;
@@ -247,7 +248,8 @@ static int _ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptle
    shift_xor(ocb, X); 
    memcpy(Z, X, ocb->block_len);
 
-   X[ocb->block_len-1] ^= ptlen&255;
+   X[ocb->block_len-1] ^= (ptlen*8)&255;
+   X[ocb->block_len-2] ^= ((ptlen*8)>>8)&255;
    for (x = 0; x < ocb->block_len; x++) {
        X[x] ^= ocb->Lr[x]; 
    }
@@ -294,6 +296,7 @@ static int _ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptle
    zeromem(X, sizeof(X));
    zeromem(Y, sizeof(Y));
    zeromem(Z, sizeof(Z));
+   zeromem(ocb, sizeof(*ocb));
 #endif
    return CRYPT_OK;
 }
@@ -301,6 +304,11 @@ static int _ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptle
 int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
                      unsigned char *ct, unsigned char *tag, unsigned long *taglen)
 {
+   _ARGCHK(ocb    != NULL);
+   _ARGCHK(pt     != NULL);
+   _ARGCHK(ct     != NULL);
+   _ARGCHK(tag    != NULL);
+   _ARGCHK(taglen != NULL);
    return _ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0);
 }
 
@@ -314,7 +322,6 @@ int ocb_done_decrypt(ocb_state *ocb,
    unsigned char tagbuf[MAXBLOCKSIZE];
    unsigned long tagbuflen;
 
-
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != NULL);
    _ARGCHK(ct  != NULL);
@@ -346,9 +353,16 @@ int ocb_encrypt_authenticate_memory(int cipher,
           unsigned char *ct,
           unsigned char *tag,    unsigned long *taglen)
 {
-   int err, n;
+   int err;
    ocb_state ocb;
 
+   _ARGCHK(key    != NULL);
+   _ARGCHK(nonce  != NULL);
+   _ARGCHK(pt     != NULL);
+   _ARGCHK(ct     != NULL);
+   _ARGCHK(tag    != NULL);
+   _ARGCHK(taglen != NULL);
+
    if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
       return err;
    }
@@ -378,9 +392,17 @@ int ocb_decrypt_verify_memory(int cipher,
     const unsigned char *tag,    unsigned long taglen,
           int           *res)
 {
-   int err, n;
+   int err;
    ocb_state ocb;
 
+
+   _ARGCHK(key    != NULL);
+   _ARGCHK(nonce  != NULL);
+   _ARGCHK(pt     != NULL);
+   _ARGCHK(ct     != NULL);
+   _ARGCHK(tag    != NULL);
+   _ARGCHK(res    != NULL);
+
    if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
       return err;
    }
@@ -409,86 +431,139 @@ int ocb_test(void)
 #else
    static const struct {
          int ptlen;
-         unsigned char key[16], nonce[16], pt[32], ct[32], tag[16];
+         unsigned char key[16], nonce[16], pt[34], ct[34], tag[16];
    } tests[] = {
 
-   /* NULL message */
+   /* OCB-AES-128-0B */
 {
    0,
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
+   /* pt */
+   { 0 },
+   /* ct */
+   { 0 },
+   /* tag */
+   { 0x15, 0xd3, 0x7d, 0xd7, 0xc8, 0x90, 0xd5, 0xd6,
+     0xac, 0xab, 0x92, 0x7b, 0xc0, 0xdc, 0x60, 0xee },
+},
+
+
+   /* OCB-AES-128-3B */
+{
+   3, 
+   /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
    /* pt */
-   { 0x00 },
+   { 0x00, 0x01, 0x02 },
    /* ct */
-   { 0x00 },
+   { 0xfc, 0xd3, 0x7d },
    /* tag */
-   { 0x04, 0xad, 0xa4, 0x5e, 0x94, 0x7b, 0xc5, 0xb6,
-     0xe0, 0x0f, 0x4c, 0x8b, 0x80, 0x53, 0x90, 0x2d }
+   { 0x02, 0x25, 0x47, 0x39, 0xa5, 0xe3, 0x56, 0x5a,
+     0xe2, 0xdc, 0xd6, 0x2c, 0x65, 0x97, 0x46, 0xba },
 },
-   
-   /* one byte message */
+
+   /* OCB-AES-128-16B */
 {
-   1,
+   16, 
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
+   /* pt */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-   /* pt */
-   { 0x11 },
    /* ct */
-   { 0x6f },
+   { 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3,
+     0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 },
    /* tag */
-   { 0xe2, 0x61, 0x42, 0x3e, 0xbb, 0x0e, 0x7f, 0x3b,
-     0xa6, 0xdd, 0xf1, 0x3e, 0xe8, 0x0b, 0x7b, 0x00}
+   { 0xdf, 0xb7, 0x63, 0xeb, 0xdb, 0x5f, 0x0e, 0x71,
+     0x9c, 0x7b, 0x41, 0x61, 0x80, 0x80, 0x04, 0xdf },
 },
 
-   /* 16 byte message */
+   /* OCB-AES-128-20B  */
 {
-   16,
+   20, 
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
-   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
    /* pt */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 
+     0x10, 0x11, 0x12, 0x13 },
    /* ct */
-   { 0x6a, 0xaf, 0xac, 0x40, 0x6d, 0xfa, 0x87, 0x40,
-     0x57, 0xc7, 0xdb, 0xe9, 0x6f, 0x1b, 0x39, 0x53 },
+   { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
+     0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
+     0x70, 0x03, 0xeb, 0x55},
    /* tag */
-   { 0xff, 0xbf, 0x96, 0x87, 0x72, 0xfe, 0xee, 0x59,
-     0x08, 0x1f, 0xc7, 0x8c, 0x8f, 0xd9, 0x16, 0xc2 }
+   { 0x75, 0x30, 0x84, 0x14, 0x4e, 0xb6, 0x3b, 0x77,
+     0x0b, 0x06, 0x3c, 0x2e, 0x23, 0xcd, 0xa0, 0xbb },
 },
 
-   /* 17 byte message */
+   /* OCB-AES-128-32B  */
 {
-   17,
+   32, 
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
+   /* pt */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 
+     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+   /* ct */
+   { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
+     0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
+     0x4a, 0xfc, 0xbb, 0x7f, 0xed, 0xc0, 0x8c, 0xa8,
+     0x65, 0x4c, 0x6d, 0x30, 0x4d, 0x16, 0x12, 0xfa },
+
+   /* tag */
+   { 0xc1, 0x4c, 0xbf, 0x2c, 0x1a, 0x1f, 0x1c, 0x3c,
+     0x13, 0x7e, 0xad, 0xea, 0x1f, 0x2f, 0x2f, 0xcf },
+},
+
+   /* OCB-AES-128-34B  */
+{
+   34, 
+   /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
    /* pt */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-     0x10 },
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 
+     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+     0x20, 0x21 },
    /* ct */
-   { 0x8c, 0x94, 0xbd, 0xd4, 0x2d, 0xdd, 0x1c, 0x40,
-     0xbe, 0xe0, 0x06, 0xb5, 0xab, 0x54, 0x3b, 0x00,
-     0x20 },
+   { 0x01, 0xa0, 0x75, 0xf0, 0xd8, 0x15, 0xb1, 0xa4,
+     0xe9, 0xc8, 0x81, 0xa1, 0xbc, 0xff, 0xc3, 0xeb,
+     0xd4, 0x90, 0x3d, 0xd0, 0x02, 0x5b, 0xa4, 0xaa,
+     0x83, 0x7c, 0x74, 0xf1, 0x21, 0xb0, 0x26, 0x0f,
+     0xa9, 0x5d },
+
    /* tag */
-   { 0x0e, 0x72, 0x7c, 0x88, 0x73, 0xbb, 0x66, 0xd7,
-     0x4a, 0x4f, 0xd4, 0x84, 0x83, 0xc7, 0x9a, 0x29 }
-}
+   { 0xcf, 0x83, 0x41, 0xbb, 0x10, 0x82, 0x0c, 0xcf,
+     0x14, 0xbd, 0xec, 0x56, 0xb8, 0xd7, 0xd6, 0xab },
+},
 
 };
 

+ 23 - 1
omac.c

@@ -165,6 +165,11 @@ int omac_memory(int cipher, const unsigned char *key, unsigned long keylen,
    int err;
    omac_state omac;
 
+   _ARGCHK(key != NULL);
+   _ARGCHK(msg != NULL);
+   _ARGCHK(out != NULL);
+   _ARGCHK(outlen != NULL);
+
    if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) {
       return err;
    }
@@ -174,6 +179,11 @@ int omac_memory(int cipher, const unsigned char *key, unsigned long keylen,
    if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) {
       return err;
    }
+
+#ifdef CLEAN_STACK
+   zeromem(&omac, sizeof(omac));
+#endif
+
    return CRYPT_OK;
 }
 
@@ -188,6 +198,13 @@ int omac_file(int cipher, const unsigned char *key, unsigned long keylen,
    FILE *in;
    unsigned char buf[512];
 
+
+   _ARGCHK(key      != NULL);
+   _ARGCHK(filename != NULL);
+   _ARGCHK(out      != NULL);
+   _ARGCHK(outlen   != NULL);
+
+
    in = fopen(filename, "rb");
    if (in == NULL) {
       return CRYPT_FILE_NOTFOUND;
@@ -210,6 +227,11 @@ int omac_file(int cipher, const unsigned char *key, unsigned long keylen,
    if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) {
       return err;
    }
+
+#ifdef CLEAN_STACK
+   zeromem(buf, sizeof(buf));
+#endif
+
    return CRYPT_OK;
 #endif
 }
@@ -221,7 +243,7 @@ int omac_test(void)
 #else
     static const struct { 
         int keylen, msglen;
-        unsigned char key[32], msg[64], tag[16];
+        unsigned char key[16], msg[64], tag[16];
     } tests[] = {
     { 16, 0,
       { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 

+ 437 - 0
pmac.c

@@ -0,0 +1,437 @@
+/* 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
+ * gurantee it works.
+ *
+ * Tom St Denis, [email protected], http://libtomcrypt.org
+ */
+
+/* PMAC implementation by Tom St Denis */
+#include "mycrypt.h"
+
+#ifdef PMAC
+
+static const struct {
+    int           len;
+    unsigned char poly_div[MAXBLOCKSIZE], 
+                  poly_mul[MAXBLOCKSIZE];
+} polys[] = {
+{
+    8,
+    { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D },
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B }
+}, {
+    16, 
+    { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 },
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87 }
+}
+};
+
+int pmac_init(pmac_state *pmac, int cipher, const unsigned char *key, unsigned long keylen)
+{
+   int poly, x, y, m, err;
+   unsigned char L[MAXBLOCKSIZE];
+
+   _ARGCHK(pmac  != NULL);
+   _ARGCHK(key   != NULL);
+
+   /* valid cipher? */
+   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* determine which polys to use */
+   pmac->block_len = cipher_descriptor[cipher].block_length;
+   for (poly = 0; poly < (int)(sizeof(polys)/sizeof(polys[0])); poly++) {
+       if (polys[poly].len == pmac->block_len) { 
+          break;
+       }
+   }
+   if (polys[poly].len != pmac->block_len) {
+      return CRYPT_INVALID_ARG;
+   }   
+
+   /* schedule the key */
+   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &pmac->key)) != CRYPT_OK) {
+      return err;
+   }
+ 
+   /* find L = E[0] */
+   zeromem(L, pmac->block_len);
+   cipher_descriptor[cipher].ecb_encrypt(L, L, &pmac->key);
+
+   /* find Ls[i] = L << i for i == 0..31 */
+   memcpy(pmac->Ls[0], L, pmac->block_len);
+   for (x = 1; x < 32; x++) {
+       m = pmac->Ls[x-1][0] >> 7;
+       for (y = 0; y < pmac->block_len-1; y++) {
+           pmac->Ls[x][y] = ((pmac->Ls[x-1][y] << 1) | (pmac->Ls[x-1][y+1] >> 7)) & 255;
+       }
+       pmac->Ls[x][pmac->block_len-1] = (pmac->Ls[x-1][pmac->block_len-1] << 1) & 255;
+
+       if (m == 1) {
+          for (y = 0; y < pmac->block_len; y++) {
+              pmac->Ls[x][y] ^= polys[poly].poly_mul[y];
+          }
+       }
+    }
+
+    /* find Lr = L / x */
+    m = L[pmac->block_len-1] & 1;
+
+    /* shift right */
+    for (x = pmac->block_len - 1; x > 0; x--) {
+        pmac->Lr[x] = ((L[x] >> 1) | (L[x-1] << 7)) & 255;
+    }
+    pmac->Lr[0] = L[0] >> 1;
+
+    if (m == 1) {
+       for (x = 0; x < pmac->block_len; x++) {
+           pmac->Lr[x] ^= polys[poly].poly_div[x];
+       }
+    }
+
+    /* zero buffer, counters, etc... */
+    pmac->block_index = 1;
+    pmac->cipher_idx  = cipher;
+    pmac->buflen      = 0;
+    zeromem(pmac->block,    sizeof(pmac->block));
+    zeromem(pmac->Li,       sizeof(pmac->Li));
+    zeromem(pmac->checksum, sizeof(pmac->checksum));
+
+#ifdef CLEAN_STACK
+    zeromem(L, sizeof(L));
+#endif
+
+    return CRYPT_OK;
+}
+
+static int ntz(unsigned long x)
+{
+   int c;
+   x &= 0xFFFFFFFFUL;
+   c = 0;
+   while ((x & 1) == 0) {
+      ++c;
+      x >>= 1;
+   }
+   return c;
+}
+
+static void shift_xor(pmac_state *pmac)
+{
+   int x, y;
+   y = ntz(pmac->block_index++);
+   for (x = 0; x < pmac->block_len; x++) {
+       pmac->Li[x] ^= pmac->Ls[y][x];
+   }
+}
+
+int pmac_process(pmac_state *state, const unsigned char *buf, unsigned long len)
+{
+   int err, n, x;
+   unsigned char Z[MAXBLOCKSIZE];
+
+   _ARGCHK(state != NULL);
+   _ARGCHK(buf   != NULL);
+   if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) {
+      return err;
+   }
+
+   if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) ||
+       (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   while (len != 0) { 
+       /* ok if the block is full we xor in prev, encrypt and replace prev */
+       if (state->buflen == state->block_len) {
+          shift_xor(state);
+          for (x = 0; x < state->block_len; x++) {
+              Z[x] = state->Li[x] ^ state->block[x];
+          }
+          cipher_descriptor[state->cipher_idx].ecb_encrypt(Z, Z, &state->key);
+          for (x = 0; x < state->block_len; x++) {
+              state->checksum[x] ^= Z[x];
+          }
+          state->buflen = 0;
+       }
+
+       /* add bytes */
+       n = MIN(len, (unsigned long)(state->block_len - state->buflen));
+       memcpy(state->block + state->buflen, buf, n);
+       state->buflen += n;
+       len           -= n;
+       buf           += n;
+   }
+
+#ifdef CLEAN_STACK
+   zeromem(Z, sizeof(Z));
+#endif
+
+   return CRYPT_OK;
+}
+
+int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen)
+{
+   int err, x;
+
+   _ARGCHK(state != NULL);
+   _ARGCHK(out   != NULL);
+   if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) {
+      return err;
+   }
+
+   if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) ||
+       (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) {
+      return CRYPT_INVALID_ARG;
+   }
+
+
+   /* handle padding.  If multiple xor in L/x */
+
+   if (state->buflen == state->block_len) {
+      /* xor Lr against the checksum */
+      for (x = 0; x < state->block_len; x++) {
+          state->checksum[x] ^= state->block[x] ^ state->Lr[x];
+      }
+   } else {
+      /* otherwise xor message bytes then the 0x80 byte */
+      for (x = 0; x < state->buflen; x++) {
+          state->checksum[x] ^= state->block[x];
+      }
+      state->checksum[x] ^= 0x80;
+   }
+
+   /* encrypt it */
+   cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key);
+
+   /* store it */
+   for (x = 0; x < state->block_len && x <= (int)*outlen; x++) {
+       out[x] = state->checksum[x];
+   }
+   *outlen = x;
+
+#ifdef CLEAN_STACK
+   zeromem(state, sizeof(*state));
+#endif
+   return CRYPT_OK;
+}
+
+int pmac_memory(int cipher, const unsigned char *key, unsigned long keylen,
+                const unsigned char *msg, unsigned long msglen,
+                unsigned char *out, unsigned long *outlen)
+{
+   int err;
+   pmac_state pmac;
+
+   _ARGCHK(key    != NULL);
+   _ARGCHK(msg    != NULL);
+   _ARGCHK(out    != NULL);
+   _ARGCHK(outlen != NULL);
+
+
+   if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = pmac_process(&pmac, msg, msglen)) != CRYPT_OK) {
+      return err;
+   }
+   if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) {
+      return err;
+   }
+
+   return CRYPT_OK;
+}
+
+int pmac_file(int cipher, const unsigned char *key, unsigned long keylen,
+              const char *filename, unsigned char *out, unsigned long *outlen)
+{
+#ifdef NO_FILE
+   return CRYPT_NOP;
+#else
+   int err, x;
+   pmac_state pmac;
+   FILE *in;
+   unsigned char buf[512];
+
+
+   _ARGCHK(key      != NULL);
+   _ARGCHK(filename != NULL);
+   _ARGCHK(out      != NULL);
+   _ARGCHK(outlen   != NULL);
+
+
+   in = fopen(filename, "rb");
+   if (in == NULL) {
+      return CRYPT_FILE_NOTFOUND;
+   }
+
+   if ((err = pmac_init(&pmac, cipher, key, keylen)) != CRYPT_OK) {
+      fclose(in);
+      return err;
+   }
+
+   do {
+      x = fread(buf, 1, sizeof(buf), in);
+      if ((err = pmac_process(&pmac, buf, x)) != CRYPT_OK) {
+         fclose(in);
+         return err;
+      }
+   } while (x == sizeof(buf));
+   fclose(in);
+
+   if ((err = pmac_done(&pmac, out, outlen)) != CRYPT_OK) {
+      return err;
+   }
+
+#ifdef CLEAN_STACK
+   zeromem(buf, sizeof(buf));
+#endif
+
+   return CRYPT_OK;
+#endif
+}
+
+int pmac_test(void)
+{
+#if !defined(LTC_TEST)
+    return CRYPT_NOP;
+#else
+    static const struct { 
+        int msglen;
+        unsigned char key[16], msg[34], tag[16];
+    } tests[] = {
+
+   /* PMAC-AES-128-0B */
+{
+   0,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* msg */
+   { 0x00 },
+   /* tag */
+   { 0x43, 0x99, 0x57, 0x2c, 0xd6, 0xea, 0x53, 0x41,
+     0xb8, 0xd3, 0x58, 0x76, 0xa7, 0x09, 0x8a, 0xf7 }
+},
+
+   /* PMAC-AES-128-3B */
+{
+   3,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* msg */
+   { 0x00, 0x01, 0x02 },
+   /* tag */
+   { 0x25, 0x6b, 0xa5, 0x19, 0x3c, 0x1b, 0x99, 0x1b,
+     0x4d, 0xf0, 0xc5, 0x1f, 0x38, 0x8a, 0x9e, 0x27 }
+},
+
+   /* PMAC-AES-128-16B */
+{
+   16,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* msg */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* tag */
+   { 0xeb, 0xbd, 0x82, 0x2f, 0xa4, 0x58, 0xda, 0xf6,
+     0xdf, 0xda, 0xd7, 0xc2, 0x7d, 0xa7, 0x63, 0x38 }
+},
+
+   /* PMAC-AES-128-20B */
+{
+   20,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* msg */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+     0x10, 0x11, 0x12, 0x13 },
+   /* tag */
+   { 0x04, 0x12, 0xca, 0x15, 0x0b, 0xbf, 0x79, 0x05,
+     0x8d, 0x8c, 0x75, 0xa5, 0x8c, 0x99, 0x3f, 0x55 }
+},
+
+   /* PMAC-AES-128-32B */
+{
+   32,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* msg */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+   /* tag */
+   { 0xe9, 0x7a, 0xc0, 0x4e, 0x9e, 0x5e, 0x33, 0x99,
+     0xce, 0x53, 0x55, 0xcd, 0x74, 0x07, 0xbc, 0x75 }
+},
+
+   /* PMAC-AES-128-34B */
+{
+   34,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* msg */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+     0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+     0x20, 0x21 },
+   /* tag */
+   { 0x5c, 0xba, 0x7d, 0x5e, 0xb2, 0x4f, 0x7c, 0x86,
+     0xcc, 0xc5, 0x46, 0x04, 0xe5, 0x3d, 0x55, 0x12 }
+}
+
+};
+   int err, x, idx;
+   unsigned long len;
+   unsigned char outtag[MAXBLOCKSIZE];
+
+    /* AES can be under rijndael or aes... try to find it */ 
+    if ((idx = find_cipher("aes")) == -1) {
+       if ((idx = find_cipher("rijndael")) == -1) {
+          return CRYPT_NOP;
+       }
+    }
+
+    for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
+        len = sizeof(outtag);
+        if ((err = pmac_memory(idx, tests[x].key, 16, tests[x].msg, tests[x].msglen, outtag, &len)) != CRYPT_OK) {
+           return err;
+        }
+        
+        if (memcmp(outtag, tests[x].tag, len)) {
+#if 0
+           unsigned long y;
+           printf("\nTAG:\n");
+           for (y = 0; y < len; ) {
+               printf("0x%02x", outtag[y]);
+               if (y < len-1) printf(", ");
+               if (!(++y % 8)) printf("\n");
+           }
+#endif
+           return CRYPT_FAIL_TESTVECTOR;
+        }
+     }
+     return CRYPT_OK;
+#endif /* LTC_TEST */
+}
+
+#endif /* PMAC_MODE */
+
+
+ 

+ 103 - 101
rsa.c

@@ -12,16 +12,23 @@
 /* RSA Code by Tom St Denis */
 #include "mycrypt.h"
 
+/* Min and Max RSA key sizes (in bits) */
+#define MIN_RSA_SIZE 1024
+#define MAX_RSA_SIZE 4096
+
+/* Stack required for temps (plus padding) */
+#define RSA_STACK    (8 + (MAX_RSA_SIZE/8))
+
 #ifdef MRSA
 
 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
 {
    mp_int p, q, tmp1, tmp2, tmp3;
-   int res, err;
+   int err;
 
    _ARGCHK(key != NULL);
 
-   if ((size < (1024/8)) || (size > (4096/8))) {
+   if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
       return CRYPT_INVALID_KEYSIZE;
    }
 
@@ -33,81 +40,81 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
       return err;
    }
 
-   if (mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL) != MP_OKAY) {
-      return CRYPT_MEM;
+   if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL)) != MP_OKAY) {
+      return mpi_to_ltc_error(err);
    }
 
    /* make primes p and q (optimization provided by Wayne Scott) */
-   if (mp_set_int(&tmp3, e) != MP_OKAY) { goto error; }            /* tmp3 = e */
+   if ((err = mp_set_int(&tmp3, e)) != MP_OKAY) { goto error; }            /* tmp3 = e */
 
    /* make prime "p" */
    do {
-       if (rand_prime(&p, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
-       if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY)              { goto error; }  /* tmp1 = p-1 */
-       if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; }  /* tmp2 = gcd(p-1, e) */
-   } while (mp_cmp_d(&tmp2, 1) != 0);                                       /* while e divides p-1 */
+       if ((err = rand_prime(&p, size/2, prng, wprng)) != CRYPT_OK) { goto done; }
+       if ((err = mp_sub_d(&p, 1, &tmp1)) != MP_OKAY)               { goto error; }  /* tmp1 = p-1 */
+       if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != MP_OKAY)          { goto error; }  /* tmp2 = gcd(p-1, e) */
+   } while (mp_cmp_d(&tmp2, 1) != 0);                                                /* while e divides p-1 */
 
    /* make prime "q" */
    do {
-       if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
-       if (mp_sub_d(&q, 1, &tmp1) != MP_OKAY)              { goto error; } /* tmp1 = q-1 */
-       if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY)         { goto error; } /* tmp2 = gcd(q-1, e) */
-   } while (mp_cmp_d(&tmp2, 1) != 0);                                      /* while e divides q-1 */
+       if ((err = rand_prime(&q, size/2, prng, wprng)) != CRYPT_OK) { goto done; }
+       if ((err = mp_sub_d(&q, 1, &tmp1)) != MP_OKAY)               { goto error; } /* tmp1 = q-1 */
+       if ((err = mp_gcd(&tmp1, &tmp3, &tmp2)) != MP_OKAY)          { goto error; } /* tmp2 = gcd(q-1, e) */
+   } while (mp_cmp_d(&tmp2, 1) != 0);                                               /* while e divides q-1 */
 
    /* tmp1 = lcm(p-1, q-1) */
-   if (mp_sub_d(&p, 1, &tmp2) != MP_OKAY)                  { goto error; } /* tmp2 = p-1 */
-                                                                           /* tmp1 = q-1 (previous do/while loop) */
-   if (mp_lcm(&tmp1, &tmp2, &tmp1) != MP_OKAY)             { goto error; } /* tmp1 = lcm(p-1, q-1) */
+   if ((err = mp_sub_d(&p, 1, &tmp2)) != MP_OKAY)                  { goto error; } /* tmp2 = p-1 */
+                                                                   /* tmp1 = q-1 (previous do/while loop) */
+   if ((err = mp_lcm(&tmp1, &tmp2, &tmp1)) != MP_OKAY)             { goto error; } /* tmp1 = lcm(p-1, q-1) */
 
    /* make key */
-   if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
-                     &key->qP, &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {
+   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) {
       goto error;
    }
 
-   if (mp_set_int(&key->e, e) != MP_OKAY)                  { goto error2; } /* key->e =  e */
-   if (mp_invmod(&key->e, &tmp1, &key->d) != MP_OKAY)      { goto error2; } /* key->d = 1/e mod lcm(p-1,q-1) */
-   if (mp_mul(&p, &q, &key->N) != MP_OKAY)                 { goto error2; } /* key->N = pq */
+   if ((err = mp_set_int(&key->e, e)) != MP_OKAY)                  { goto error2; } /* key->e =  e */
+   if ((err = mp_invmod(&key->e, &tmp1, &key->d)) != MP_OKAY)      { goto error2; } /* key->d = 1/e mod lcm(p-1,q-1) */
+   if ((err = mp_mul(&p, &q, &key->N)) != MP_OKAY)                 { goto error2; } /* key->N = pq */
 
 /* optimize for CRT now */
    /* find d mod q-1 and d mod p-1 */
-   if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY)                  { goto error2; } /* tmp1 = q-1 */
-   if (mp_sub_d(&q, 1, &tmp2) != MP_OKAY)                  { goto error2; } /* tmp2 = p-1 */
+   if ((err = mp_sub_d(&p, 1, &tmp1)) != MP_OKAY)                  { goto error2; } /* tmp1 = q-1 */
+   if ((err = mp_sub_d(&q, 1, &tmp2)) != MP_OKAY)                  { goto error2; } /* tmp2 = p-1 */
 
-   if (mp_mod(&key->d, &tmp1, &key->dP) != MP_OKAY)        { goto error2; } /* dP = d mod p-1 */
-   if (mp_mod(&key->d, &tmp2, &key->dQ) != MP_OKAY)        { goto error2; } /* dQ = d mod q-1 */
+   if ((err = mp_mod(&key->d, &tmp1, &key->dP)) != MP_OKAY)        { goto error2; } /* dP = d mod p-1 */
+   if ((err = mp_mod(&key->d, &tmp2, &key->dQ)) != MP_OKAY)        { goto error2; } /* dQ = d mod q-1 */
 
-   if (mp_invmod(&q, &p, &key->qP) != MP_OKAY)             { goto error2; } /* qP = 1/q mod p */
-   if (mp_mulmod(&key->qP, &q, &key->N, &key->qP))         { goto error2; } /* qP = q * (1/q mod p) mod N */
+   if ((err = mp_invmod(&q, &p, &key->qP)) != MP_OKAY)             { goto error2; } /* qP = 1/q mod p */
+   if ((err = mp_mulmod(&key->qP, &q, &key->N, &key->qP)) != MP_OKAY)         { goto error2; } /* qP = q * (1/q mod p) mod N */
 
-   if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY)             { goto error2; } /* pQ = 1/p mod q */
-   if (mp_mulmod(&key->pQ, &p, &key->N, &key->pQ))         { goto error2; } /* pQ = p * (1/p mod q) mod N */
+   if ((err = mp_invmod(&p, &q, &key->pQ)) != MP_OKAY)             { goto error2; } /* pQ = 1/p mod q */
+   if ((err = mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) != MP_OKAY)         { goto error2; } /* pQ = p * (1/p mod q) mod N */
 
-   if (mp_copy(&p, &key->p) != MP_OKAY)                    { goto error2; }
-   if (mp_copy(&q, &key->q) != MP_OKAY)                    { goto error2; }
+   if ((err = mp_copy(&p, &key->p)) != MP_OKAY)                    { goto error2; }
+   if ((err = mp_copy(&q, &key->q)) != MP_OKAY)                    { goto error2; }
 
    /* shrink ram required  */
-   if (mp_shrink(&key->e) != MP_OKAY)                      { goto error2; }
-   if (mp_shrink(&key->d) != MP_OKAY)                      { goto error2; }
-   if (mp_shrink(&key->N) != MP_OKAY)                      { goto error2; }
-   if (mp_shrink(&key->dQ) != MP_OKAY)                     { goto error2; }
-   if (mp_shrink(&key->dP) != MP_OKAY)                     { goto error2; }
-   if (mp_shrink(&key->qP) != MP_OKAY)                     { goto error2; }
-   if (mp_shrink(&key->pQ) != MP_OKAY)                     { goto error2; }
-   if (mp_shrink(&key->p) != MP_OKAY)                      { goto error2; }
-   if (mp_shrink(&key->q) != MP_OKAY)                      { goto error2; }
-
-   res = CRYPT_OK;
+   if ((err = mp_shrink(&key->e)) != MP_OKAY)                      { goto error2; }
+   if ((err = mp_shrink(&key->d)) != MP_OKAY)                      { goto error2; }
+   if ((err = mp_shrink(&key->N)) != MP_OKAY)                      { goto error2; }
+   if ((err = mp_shrink(&key->dQ)) != MP_OKAY)                     { goto error2; }
+   if ((err = mp_shrink(&key->dP)) != MP_OKAY)                     { goto error2; }
+   if ((err = mp_shrink(&key->qP)) != MP_OKAY)                     { goto error2; }
+   if ((err = mp_shrink(&key->pQ)) != MP_OKAY)                     { goto error2; }
+   if ((err = mp_shrink(&key->p)) != MP_OKAY)                      { goto error2; }
+   if ((err = mp_shrink(&key->q)) != MP_OKAY)                      { goto error2; }
+
+   err = CRYPT_OK;
    key->type = PK_PRIVATE_OPTIMIZED;
    goto done;
 error2:
    mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
                   &key->qP, &key->pQ, &key->p, &key->q, NULL);
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL);
-   return res;
+   return err;
 }
 
 void rsa_free(rsa_key *key)
@@ -123,12 +130,12 @@ int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
 {
    mp_int tmp, tmpa, tmpb;
    unsigned long x;
-   int res;
+   int err;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
    if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) {
       return CRYPT_PK_NOT_PRIVATE;
@@ -140,51 +147,51 @@ int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
    }
 
    /* init and copy into tmp */
-   if (mp_init_multi(&tmp, &tmpa, &tmpb, NULL) != MP_OKAY)                          { goto error; }
-   if (mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen) != MP_OKAY)      { goto error; }
+   if ((err = mp_init_multi(&tmp, &tmpa, &tmpb, NULL)) != MP_OKAY)                     { goto error; }
+   if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; }
 
    /* sanity check on the input */
    if (mp_cmp(&key->N, &tmp) == MP_LT) {
-      res = CRYPT_PK_INVALID_SIZE;
+      err = CRYPT_PK_INVALID_SIZE;
       goto done;
    }
 
    /* 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 (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY)    { goto error; }
+      if ((err = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != MP_OKAY)    { goto error; }
 
       /* tmpb = tmp^dQ mod q */
-      if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY)    { goto error; }
+      if ((err = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != MP_OKAY)    { goto error; }
 
       /* tmp = tmpa*qP + tmpb*pQ mod N */
-      if (mp_mul(&tmpa, &key->qP, &tmpa) != MP_OKAY)                { goto error; }
-      if (mp_mul(&tmpb, &key->pQ, &tmpb) != MP_OKAY)                { goto error; }
-      if (mp_addmod(&tmpa, &tmpb, &key->N, &tmp) != MP_OKAY)        { goto error; }
+      if ((err = mp_mul(&tmpa, &key->qP, &tmpa)) != MP_OKAY)                { goto error; }
+      if ((err = mp_mul(&tmpb, &key->pQ, &tmpb)) != MP_OKAY)                { goto error; }
+      if ((err = mp_addmod(&tmpa, &tmpb, &key->N, &tmp)) != MP_OKAY)        { goto error; }
    } else {
       /* exptmod it */
-      if (mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp) != MP_OKAY) { goto error; }
+      if ((err = mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp)) != MP_OKAY) { goto error; }
    }
 
    /* read it back */
    x = (unsigned long)mp_unsigned_bin_size(&tmp);
    if (x > *outlen) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done;
    }
    *outlen = x;
 
    /* convert it */
-   if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)                    { goto error; }
+   if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY)                    { goto error; }
 
    /* clean up and return */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
    mp_clear_multi(&tmp, &tmpa, &tmpb, NULL);
-   return res;
+   return err;
 }
 
 int rsa_signpad(const unsigned char *in,  unsigned long inlen,
@@ -192,8 +199,8 @@ int rsa_signpad(const unsigned char *in,  unsigned long inlen,
 {
    unsigned long x, y;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
 
    if (*outlen < (3 * inlen)) {
@@ -219,12 +226,12 @@ int rsa_pad(const unsigned char *in,  unsigned long inlen,
                   unsigned char *out, unsigned long *outlen,
                   int wprng, prng_state *prng)
 {
-   unsigned char buf[1536];
+   unsigned char buf[3*(MAX_RSA_SIZE/8)];
    unsigned long x;
    int err;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
 
    /* is output big enough? */
@@ -238,7 +245,7 @@ int rsa_pad(const unsigned char *in,  unsigned long inlen,
    }
 
    /* check inlen */
-   if (inlen > 512) {
+   if (inlen > (MAX_RSA_SIZE/8)) {
       return CRYPT_PK_INVALID_SIZE;
    }
 
@@ -276,12 +283,12 @@ int rsa_pad(const unsigned char *in,  unsigned long inlen,
 }
 
 int rsa_signdepad(const unsigned char *in,  unsigned long inlen,
-                    unsigned char *out, unsigned long *outlen)
+                        unsigned char *out, unsigned long *outlen)
 {
    unsigned long x;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
 
    if (*outlen < inlen/3) {
@@ -306,8 +313,8 @@ int rsa_depad(const unsigned char *in,  unsigned long inlen,
 {
    unsigned long x;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
 
    if (*outlen < inlen/3) {
@@ -322,13 +329,17 @@ int rsa_depad(const unsigned char *in,  unsigned long inlen,
 
 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
 {
-   unsigned char buf2[5120];
    unsigned long y, z; 
    int err;
 
-   _ARGCHK(out != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != 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) &&
@@ -340,43 +351,34 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key
    y = PACKET_SIZE;
 
    /* output key type */
-   buf2[y++] = type;
+   out[y++] = type;
 
    /* output modulus */
-   OUTPUT_BIGNUM(&key->N, buf2, y, z);
+   OUTPUT_BIGNUM(&key->N, out, y, z);
 
    /* output public key */
-   OUTPUT_BIGNUM(&key->e, buf2, y, z);
+   OUTPUT_BIGNUM(&key->e, out, y, z);
 
    if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
-      OUTPUT_BIGNUM(&key->d, buf2, y, z);
+      OUTPUT_BIGNUM(&key->d, out, y, z);
    }
 
    if (type == PK_PRIVATE_OPTIMIZED) {
-      OUTPUT_BIGNUM(&key->dQ, buf2, y, z);
-      OUTPUT_BIGNUM(&key->dP, buf2, y, z);
-      OUTPUT_BIGNUM(&key->pQ, buf2, y, z);
-      OUTPUT_BIGNUM(&key->qP, buf2, y, z);
-      OUTPUT_BIGNUM(&key->p, buf2, y, z);
-      OUTPUT_BIGNUM(&key->q, buf2, y, z);
-   }
-
-   /* check size */
-   if (*outlen < y) {
-      return CRYPT_BUFFER_OVERFLOW;
+      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(buf2, PACKET_SECT_RSA, PACKET_SUB_KEY);
+   packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY);
 
    /* copy to the user buffer */
-   memcpy(out, buf2, (size_t)y);
    *outlen = y;
 
    /* clear stack and return */
-#ifdef CLEAN_STACK
-   zeromem(buf2, sizeof(buf2));
-#endif
    return CRYPT_OK;
 }
 
@@ -385,11 +387,11 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    unsigned long x, y;
    int err;
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in  != NULL);
    _ARGCHK(key != NULL);
 
    /* check length */
-   if (inlen < 1+PACKET_SIZE) {
+   if (inlen < (1+PACKET_SIZE)) {
       return CRYPT_INVALID_PACKET;
    }
 
@@ -399,9 +401,9 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    }
 
    /* init key */
-   if (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 CRYPT_MEM;
+   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 */

+ 20 - 19
rsa_sys.c

@@ -16,14 +16,14 @@ 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)
 {
-   unsigned char rsa_in[4096], rsa_out[4096];
+   unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK];
    unsigned long x, y, rsa_size;
    int err;
 
-   _ARGCHK(inkey != NULL);
+   _ARGCHK(inkey  != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
    
    /* only allow keys from 64 to 256 bits */
    if (inlen < 8 || inlen > 32) {
@@ -52,6 +52,9 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
       return CRYPT_BUFFER_OVERFLOW;
    }
 
+   /* store header */
+   packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY);
+
    /* now lets make the header */
    y = PACKET_SIZE;
    
@@ -64,15 +67,13 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
        outkey[y] = rsa_out[x];
    }
 
-   /* store header */
-   packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY);
-
+   *outlen = y;
 #ifdef CLEAN_STACK
    /* clean up */
    zeromem(rsa_in, sizeof(rsa_in));
    zeromem(rsa_out, sizeof(rsa_out));
 #endif
-   *outlen = y;
+
    return CRYPT_OK;
 }
 
@@ -80,14 +81,14 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
                           unsigned char *outkey, unsigned long *keylen, 
                           rsa_key *key)
 {
-   unsigned char sym_key[MAXBLOCKSIZE], rsa_out[4096];
+   unsigned char sym_key[MAXBLOCKSIZE], rsa_out[RSA_STACK];
    unsigned long x, y, z, i, rsa_size;
    int err;
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in     != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(keylen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
    /* right key type? */
    if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
@@ -151,16 +152,16 @@ int rsa_sign_hash(const unsigned char *in,  unsigned long inlen,
                         rsa_key *key)
 {
    unsigned long rsa_size, x, y;
-   unsigned char rsa_in[4096], rsa_out[4096];
+   unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK];
    int err;
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
    
    /* reject nonsense sizes */
-   if (inlen > MAXBLOCKSIZE || inlen < 16) {
+   if (inlen > (512/3) || inlen < 16) {
       return CRYPT_INVALID_ARG;
    }
 
@@ -214,13 +215,13 @@ int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
                     const unsigned char *md, int *stat, rsa_key *key)
 {
    unsigned long rsa_size, x, y, z;
-   unsigned char rsa_in[4096], rsa_out[4096];
+   unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK];
    int err;
 
-   _ARGCHK(sig != NULL);
-   _ARGCHK(md != NULL);
+   _ARGCHK(sig  != NULL);
+   _ARGCHK(md   != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
    /* always be incorrect by default */
    *stat = 0;

+ 5 - 5
safer+.c → saferp.c

@@ -206,7 +206,7 @@ int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric
    unsigned char t[33];
    static const int rounds[3] = { 8, 12, 16 };
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(skey != NULL);
 
    /* check arguments */
@@ -316,8 +316,8 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
    unsigned char b[16];
    int x;
 
-   _ARGCHK(pt != NULL);
-   _ARGCHK(ct != NULL);
+   _ARGCHK(pt   != NULL);
+   _ARGCHK(ct   != NULL);
    _ARGCHK(skey != NULL);
 
    /* do eight rounds */
@@ -372,8 +372,8 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
    unsigned char b[16];
    int x;
 
-   _ARGCHK(pt != NULL);
-   _ARGCHK(ct != NULL);
+   _ARGCHK(pt   != NULL);
+   _ARGCHK(ct   != NULL);
    _ARGCHK(skey != NULL);
 
    /* do eight rounds */

+ 1 - 1
sha224.c

@@ -69,7 +69,7 @@ int  sha224_test(void)
     },
     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
       { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
-	0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
+        0xcc, 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89,
         0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
         0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
     },

+ 17 - 17
skipjack.c

@@ -27,22 +27,22 @@ const struct _cipher_descriptor skipjack_desc =
 };
 
 static const unsigned char sbox[256] = {
-	0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
-	0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
-	0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
-	0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
-	0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
-	0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
-	0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
-	0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
-	0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
-	0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
-	0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
-	0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
-	0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
-	0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
-	0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
-	0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
+   0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9,
+   0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28,
+   0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53,
+   0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2,
+   0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8,
+   0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90,
+   0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76,
+   0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d,
+   0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18,
+   0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4,
+   0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40,
+   0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5,
+   0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2,
+   0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8,
+   0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac,
+   0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
 };
 
 /* simple x + 1 (mod 10) in one step. */
@@ -55,7 +55,7 @@ int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetr
 {
    int x;
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(skey != NULL);
 
    if (keylen != 10) {

+ 3 - 3
twofish.c

@@ -340,7 +340,7 @@ int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
    unsigned char tmp[4], tmp2[4], M[8*4];
    ulong32 A, B;
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(skey != NULL);
 
    /* invalid arguments? */
@@ -459,8 +459,8 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
     ulong32 *S1, *S2, *S3, *S4;
 #endif    
 
-    _ARGCHK(pt != NULL);
-    _ARGCHK(ct != NULL);
+    _ARGCHK(pt  != NULL);
+    _ARGCHK(ct  != NULL);
     _ARGCHK(key != NULL);
     
 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)

+ 275 - 0
whirl.c

@@ -0,0 +1,275 @@
+/* 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
+ * gurantee 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)               \
+    sbox0[GB(a, i-0, 7)] ^                 \
+    sbox1[GB(a, i-1, 6)] ^                 \
+    sbox2[GB(a, i-2, 5)] ^                 \
+    sbox3[GB(a, i-3, 4)] ^                 \
+    sbox4[GB(a, i-4, 3)] ^                 \
+    sbox5[GB(a, i-5, 2)] ^                 \
+    sbox6[GB(a, i-6, 1)] ^                 \
+    sbox7[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
+

+ 550 - 0
whirltab.c

@@ -0,0 +1,550 @@
+static const ulong64 sbox0[] = {
+CONST64(0x18186018c07830d8), CONST64(0x23238c2305af4626), CONST64(0xc6c63fc67ef991b8), CONST64(0xe8e887e8136fcdfb), 
+CONST64(0x878726874ca113cb), CONST64(0xb8b8dab8a9626d11), CONST64(0x0101040108050209), CONST64(0x4f4f214f426e9e0d), 
+CONST64(0x3636d836adee6c9b), CONST64(0xa6a6a2a6590451ff), CONST64(0xd2d26fd2debdb90c), CONST64(0xf5f5f3f5fb06f70e), 
+CONST64(0x7979f979ef80f296), CONST64(0x6f6fa16f5fcede30), CONST64(0x91917e91fcef3f6d), CONST64(0x52525552aa07a4f8), 
+CONST64(0x60609d6027fdc047), CONST64(0xbcbccabc89766535), CONST64(0x9b9b569baccd2b37), CONST64(0x8e8e028e048c018a), 
+CONST64(0xa3a3b6a371155bd2), CONST64(0x0c0c300c603c186c), CONST64(0x7b7bf17bff8af684), CONST64(0x3535d435b5e16a80), 
+CONST64(0x1d1d741de8693af5), CONST64(0xe0e0a7e05347ddb3), CONST64(0xd7d77bd7f6acb321), CONST64(0xc2c22fc25eed999c), 
+CONST64(0x2e2eb82e6d965c43), CONST64(0x4b4b314b627a9629), CONST64(0xfefedffea321e15d), CONST64(0x575741578216aed5), 
+CONST64(0x15155415a8412abd), CONST64(0x7777c1779fb6eee8), CONST64(0x3737dc37a5eb6e92), CONST64(0xe5e5b3e57b56d79e), 
+CONST64(0x9f9f469f8cd92313), CONST64(0xf0f0e7f0d317fd23), CONST64(0x4a4a354a6a7f9420), CONST64(0xdada4fda9e95a944), 
+CONST64(0x58587d58fa25b0a2), CONST64(0xc9c903c906ca8fcf), CONST64(0x2929a429558d527c), CONST64(0x0a0a280a5022145a), 
+CONST64(0xb1b1feb1e14f7f50), CONST64(0xa0a0baa0691a5dc9), CONST64(0x6b6bb16b7fdad614), CONST64(0x85852e855cab17d9), 
+CONST64(0xbdbdcebd8173673c), CONST64(0x5d5d695dd234ba8f), CONST64(0x1010401080502090), CONST64(0xf4f4f7f4f303f507), 
+CONST64(0xcbcb0bcb16c08bdd), CONST64(0x3e3ef83eedc67cd3), CONST64(0x0505140528110a2d), CONST64(0x676781671fe6ce78), 
+CONST64(0xe4e4b7e47353d597), CONST64(0x27279c2725bb4e02), CONST64(0x4141194132588273), CONST64(0x8b8b168b2c9d0ba7), 
+CONST64(0xa7a7a6a7510153f6), CONST64(0x7d7de97dcf94fab2), CONST64(0x95956e95dcfb3749), CONST64(0xd8d847d88e9fad56), 
+CONST64(0xfbfbcbfb8b30eb70), CONST64(0xeeee9fee2371c1cd), CONST64(0x7c7ced7cc791f8bb), CONST64(0x6666856617e3cc71), 
+CONST64(0xdddd53dda68ea77b), CONST64(0x17175c17b84b2eaf), CONST64(0x4747014702468e45), CONST64(0x9e9e429e84dc211a), 
+CONST64(0xcaca0fca1ec589d4), CONST64(0x2d2db42d75995a58), CONST64(0xbfbfc6bf9179632e), CONST64(0x07071c07381b0e3f), 
+CONST64(0xadad8ead012347ac), CONST64(0x5a5a755aea2fb4b0), CONST64(0x838336836cb51bef), CONST64(0x3333cc3385ff66b6), 
+CONST64(0x636391633ff2c65c), CONST64(0x02020802100a0412), CONST64(0xaaaa92aa39384993), CONST64(0x7171d971afa8e2de), 
+CONST64(0xc8c807c80ecf8dc6), CONST64(0x19196419c87d32d1), CONST64(0x494939497270923b), CONST64(0xd9d943d9869aaf5f), 
+CONST64(0xf2f2eff2c31df931), CONST64(0xe3e3abe34b48dba8), CONST64(0x5b5b715be22ab6b9), CONST64(0x88881a8834920dbc), 
+CONST64(0x9a9a529aa4c8293e), CONST64(0x262698262dbe4c0b), CONST64(0x3232c8328dfa64bf), CONST64(0xb0b0fab0e94a7d59), 
+CONST64(0xe9e983e91b6acff2), CONST64(0x0f0f3c0f78331e77), CONST64(0xd5d573d5e6a6b733), CONST64(0x80803a8074ba1df4), 
+CONST64(0xbebec2be997c6127), CONST64(0xcdcd13cd26de87eb), CONST64(0x3434d034bde46889), CONST64(0x48483d487a759032), 
+CONST64(0xffffdbffab24e354), CONST64(0x7a7af57af78ff48d), CONST64(0x90907a90f4ea3d64), CONST64(0x5f5f615fc23ebe9d), 
+CONST64(0x202080201da0403d), CONST64(0x6868bd6867d5d00f), CONST64(0x1a1a681ad07234ca), CONST64(0xaeae82ae192c41b7), 
+CONST64(0xb4b4eab4c95e757d), CONST64(0x54544d549a19a8ce), CONST64(0x93937693ece53b7f), CONST64(0x222288220daa442f), 
+CONST64(0x64648d6407e9c863), CONST64(0xf1f1e3f1db12ff2a), CONST64(0x7373d173bfa2e6cc), CONST64(0x12124812905a2482), 
+CONST64(0x40401d403a5d807a), CONST64(0x0808200840281048), CONST64(0xc3c32bc356e89b95), CONST64(0xecec97ec337bc5df), 
+CONST64(0xdbdb4bdb9690ab4d), CONST64(0xa1a1bea1611f5fc0), CONST64(0x8d8d0e8d1c830791), CONST64(0x3d3df43df5c97ac8), 
+CONST64(0x97976697ccf1335b), CONST64(0x0000000000000000), CONST64(0xcfcf1bcf36d483f9), CONST64(0x2b2bac2b4587566e), 
+CONST64(0x7676c57697b3ece1), CONST64(0x8282328264b019e6), CONST64(0xd6d67fd6fea9b128), CONST64(0x1b1b6c1bd87736c3), 
+CONST64(0xb5b5eeb5c15b7774), CONST64(0xafaf86af112943be), CONST64(0x6a6ab56a77dfd41d), CONST64(0x50505d50ba0da0ea), 
+CONST64(0x45450945124c8a57), CONST64(0xf3f3ebf3cb18fb38), CONST64(0x3030c0309df060ad), CONST64(0xefef9bef2b74c3c4), 
+CONST64(0x3f3ffc3fe5c37eda), CONST64(0x55554955921caac7), CONST64(0xa2a2b2a2791059db), CONST64(0xeaea8fea0365c9e9), 
+CONST64(0x656589650fecca6a), CONST64(0xbabad2bab9686903), CONST64(0x2f2fbc2f65935e4a), CONST64(0xc0c027c04ee79d8e), 
+CONST64(0xdede5fdebe81a160), CONST64(0x1c1c701ce06c38fc), CONST64(0xfdfdd3fdbb2ee746), CONST64(0x4d4d294d52649a1f), 
+CONST64(0x92927292e4e03976), CONST64(0x7575c9758fbceafa), CONST64(0x06061806301e0c36), CONST64(0x8a8a128a249809ae), 
+CONST64(0xb2b2f2b2f940794b), CONST64(0xe6e6bfe66359d185), CONST64(0x0e0e380e70361c7e), CONST64(0x1f1f7c1ff8633ee7), 
+CONST64(0x6262956237f7c455), CONST64(0xd4d477d4eea3b53a), CONST64(0xa8a89aa829324d81), CONST64(0x96966296c4f43152), 
+CONST64(0xf9f9c3f99b3aef62), CONST64(0xc5c533c566f697a3), CONST64(0x2525942535b14a10), CONST64(0x59597959f220b2ab), 
+CONST64(0x84842a8454ae15d0), CONST64(0x7272d572b7a7e4c5), CONST64(0x3939e439d5dd72ec), CONST64(0x4c4c2d4c5a619816), 
+CONST64(0x5e5e655eca3bbc94), CONST64(0x7878fd78e785f09f), CONST64(0x3838e038ddd870e5), CONST64(0x8c8c0a8c14860598), 
+CONST64(0xd1d163d1c6b2bf17), CONST64(0xa5a5aea5410b57e4), CONST64(0xe2e2afe2434dd9a1), CONST64(0x616199612ff8c24e), 
+CONST64(0xb3b3f6b3f1457b42), CONST64(0x2121842115a54234), CONST64(0x9c9c4a9c94d62508), CONST64(0x1e1e781ef0663cee), 
+CONST64(0x4343114322528661), CONST64(0xc7c73bc776fc93b1), CONST64(0xfcfcd7fcb32be54f), CONST64(0x0404100420140824), 
+CONST64(0x51515951b208a2e3), CONST64(0x99995e99bcc72f25), CONST64(0x6d6da96d4fc4da22), CONST64(0x0d0d340d68391a65), 
+CONST64(0xfafacffa8335e979), CONST64(0xdfdf5bdfb684a369), CONST64(0x7e7ee57ed79bfca9), CONST64(0x242490243db44819), 
+CONST64(0x3b3bec3bc5d776fe), CONST64(0xabab96ab313d4b9a), CONST64(0xcece1fce3ed181f0), CONST64(0x1111441188552299), 
+CONST64(0x8f8f068f0c890383), CONST64(0x4e4e254e4a6b9c04), CONST64(0xb7b7e6b7d1517366), CONST64(0xebeb8beb0b60cbe0), 
+CONST64(0x3c3cf03cfdcc78c1), CONST64(0x81813e817cbf1ffd), CONST64(0x94946a94d4fe3540), CONST64(0xf7f7fbf7eb0cf31c), 
+CONST64(0xb9b9deb9a1676f18), CONST64(0x13134c13985f268b), CONST64(0x2c2cb02c7d9c5851), CONST64(0xd3d36bd3d6b8bb05), 
+CONST64(0xe7e7bbe76b5cd38c), CONST64(0x6e6ea56e57cbdc39), CONST64(0xc4c437c46ef395aa), CONST64(0x03030c03180f061b), 
+CONST64(0x565645568a13acdc), CONST64(0x44440d441a49885e), CONST64(0x7f7fe17fdf9efea0), CONST64(0xa9a99ea921374f88), 
+CONST64(0x2a2aa82a4d825467), CONST64(0xbbbbd6bbb16d6b0a), CONST64(0xc1c123c146e29f87), CONST64(0x53535153a202a6f1), 
+CONST64(0xdcdc57dcae8ba572), CONST64(0x0b0b2c0b58271653), CONST64(0x9d9d4e9d9cd32701), CONST64(0x6c6cad6c47c1d82b), 
+CONST64(0x3131c43195f562a4), CONST64(0x7474cd7487b9e8f3), CONST64(0xf6f6fff6e309f115), CONST64(0x464605460a438c4c), 
+CONST64(0xacac8aac092645a5), CONST64(0x89891e893c970fb5), CONST64(0x14145014a04428b4), CONST64(0xe1e1a3e15b42dfba), 
+CONST64(0x16165816b04e2ca6), CONST64(0x3a3ae83acdd274f7), CONST64(0x6969b9696fd0d206), CONST64(0x09092409482d1241), 
+CONST64(0x7070dd70a7ade0d7), CONST64(0xb6b6e2b6d954716f), CONST64(0xd0d067d0ceb7bd1e), CONST64(0xeded93ed3b7ec7d6), 
+CONST64(0xcccc17cc2edb85e2), CONST64(0x424215422a578468), CONST64(0x98985a98b4c22d2c), CONST64(0xa4a4aaa4490e55ed), 
+CONST64(0x2828a0285d885075), CONST64(0x5c5c6d5cda31b886), CONST64(0xf8f8c7f8933fed6b), CONST64(0x8686228644a411c2)
+};
+
+static const ulong64 sbox1[] = {
+CONST64(0xd818186018c07830), CONST64(0x2623238c2305af46), CONST64(0xb8c6c63fc67ef991), CONST64(0xfbe8e887e8136fcd), 
+CONST64(0xcb878726874ca113), CONST64(0x11b8b8dab8a9626d), CONST64(0x0901010401080502), CONST64(0x0d4f4f214f426e9e), 
+CONST64(0x9b3636d836adee6c), CONST64(0xffa6a6a2a6590451), CONST64(0x0cd2d26fd2debdb9), CONST64(0x0ef5f5f3f5fb06f7), 
+CONST64(0x967979f979ef80f2), CONST64(0x306f6fa16f5fcede), CONST64(0x6d91917e91fcef3f), CONST64(0xf852525552aa07a4), 
+CONST64(0x4760609d6027fdc0), CONST64(0x35bcbccabc897665), CONST64(0x379b9b569baccd2b), CONST64(0x8a8e8e028e048c01), 
+CONST64(0xd2a3a3b6a371155b), CONST64(0x6c0c0c300c603c18), CONST64(0x847b7bf17bff8af6), CONST64(0x803535d435b5e16a), 
+CONST64(0xf51d1d741de8693a), CONST64(0xb3e0e0a7e05347dd), CONST64(0x21d7d77bd7f6acb3), CONST64(0x9cc2c22fc25eed99), 
+CONST64(0x432e2eb82e6d965c), CONST64(0x294b4b314b627a96), CONST64(0x5dfefedffea321e1), CONST64(0xd5575741578216ae), 
+CONST64(0xbd15155415a8412a), CONST64(0xe87777c1779fb6ee), CONST64(0x923737dc37a5eb6e), CONST64(0x9ee5e5b3e57b56d7), 
+CONST64(0x139f9f469f8cd923), CONST64(0x23f0f0e7f0d317fd), CONST64(0x204a4a354a6a7f94), CONST64(0x44dada4fda9e95a9), 
+CONST64(0xa258587d58fa25b0), CONST64(0xcfc9c903c906ca8f), CONST64(0x7c2929a429558d52), CONST64(0x5a0a0a280a502214), 
+CONST64(0x50b1b1feb1e14f7f), CONST64(0xc9a0a0baa0691a5d), CONST64(0x146b6bb16b7fdad6), CONST64(0xd985852e855cab17), 
+CONST64(0x3cbdbdcebd817367), CONST64(0x8f5d5d695dd234ba), CONST64(0x9010104010805020), CONST64(0x07f4f4f7f4f303f5), 
+CONST64(0xddcbcb0bcb16c08b), CONST64(0xd33e3ef83eedc67c), CONST64(0x2d0505140528110a), CONST64(0x78676781671fe6ce), 
+CONST64(0x97e4e4b7e47353d5), CONST64(0x0227279c2725bb4e), CONST64(0x7341411941325882), CONST64(0xa78b8b168b2c9d0b), 
+CONST64(0xf6a7a7a6a7510153), CONST64(0xb27d7de97dcf94fa), CONST64(0x4995956e95dcfb37), CONST64(0x56d8d847d88e9fad), 
+CONST64(0x70fbfbcbfb8b30eb), CONST64(0xcdeeee9fee2371c1), CONST64(0xbb7c7ced7cc791f8), CONST64(0x716666856617e3cc), 
+CONST64(0x7bdddd53dda68ea7), CONST64(0xaf17175c17b84b2e), CONST64(0x454747014702468e), CONST64(0x1a9e9e429e84dc21), 
+CONST64(0xd4caca0fca1ec589), CONST64(0x582d2db42d75995a), CONST64(0x2ebfbfc6bf917963), CONST64(0x3f07071c07381b0e), 
+CONST64(0xacadad8ead012347), CONST64(0xb05a5a755aea2fb4), CONST64(0xef838336836cb51b), CONST64(0xb63333cc3385ff66), 
+CONST64(0x5c636391633ff2c6), CONST64(0x1202020802100a04), CONST64(0x93aaaa92aa393849), CONST64(0xde7171d971afa8e2), 
+CONST64(0xc6c8c807c80ecf8d), CONST64(0xd119196419c87d32), CONST64(0x3b49493949727092), CONST64(0x5fd9d943d9869aaf), 
+CONST64(0x31f2f2eff2c31df9), CONST64(0xa8e3e3abe34b48db), CONST64(0xb95b5b715be22ab6), CONST64(0xbc88881a8834920d), 
+CONST64(0x3e9a9a529aa4c829), CONST64(0x0b262698262dbe4c), CONST64(0xbf3232c8328dfa64), CONST64(0x59b0b0fab0e94a7d), 
+CONST64(0xf2e9e983e91b6acf), CONST64(0x770f0f3c0f78331e), CONST64(0x33d5d573d5e6a6b7), CONST64(0xf480803a8074ba1d), 
+CONST64(0x27bebec2be997c61), CONST64(0xebcdcd13cd26de87), CONST64(0x893434d034bde468), CONST64(0x3248483d487a7590), 
+CONST64(0x54ffffdbffab24e3), CONST64(0x8d7a7af57af78ff4), CONST64(0x6490907a90f4ea3d), CONST64(0x9d5f5f615fc23ebe), 
+CONST64(0x3d202080201da040), CONST64(0x0f6868bd6867d5d0), CONST64(0xca1a1a681ad07234), CONST64(0xb7aeae82ae192c41), 
+CONST64(0x7db4b4eab4c95e75), CONST64(0xce54544d549a19a8), CONST64(0x7f93937693ece53b), CONST64(0x2f222288220daa44), 
+CONST64(0x6364648d6407e9c8), CONST64(0x2af1f1e3f1db12ff), CONST64(0xcc7373d173bfa2e6), CONST64(0x8212124812905a24), 
+CONST64(0x7a40401d403a5d80), CONST64(0x4808082008402810), CONST64(0x95c3c32bc356e89b), CONST64(0xdfecec97ec337bc5), 
+CONST64(0x4ddbdb4bdb9690ab), CONST64(0xc0a1a1bea1611f5f), CONST64(0x918d8d0e8d1c8307), CONST64(0xc83d3df43df5c97a), 
+CONST64(0x5b97976697ccf133), CONST64(0x0000000000000000), CONST64(0xf9cfcf1bcf36d483), CONST64(0x6e2b2bac2b458756), 
+CONST64(0xe17676c57697b3ec), CONST64(0xe68282328264b019), CONST64(0x28d6d67fd6fea9b1), CONST64(0xc31b1b6c1bd87736), 
+CONST64(0x74b5b5eeb5c15b77), CONST64(0xbeafaf86af112943), CONST64(0x1d6a6ab56a77dfd4), CONST64(0xea50505d50ba0da0), 
+CONST64(0x5745450945124c8a), CONST64(0x38f3f3ebf3cb18fb), CONST64(0xad3030c0309df060), CONST64(0xc4efef9bef2b74c3), 
+CONST64(0xda3f3ffc3fe5c37e), CONST64(0xc755554955921caa), CONST64(0xdba2a2b2a2791059), CONST64(0xe9eaea8fea0365c9), 
+CONST64(0x6a656589650fecca), CONST64(0x03babad2bab96869), CONST64(0x4a2f2fbc2f65935e), CONST64(0x8ec0c027c04ee79d), 
+CONST64(0x60dede5fdebe81a1), CONST64(0xfc1c1c701ce06c38), CONST64(0x46fdfdd3fdbb2ee7), CONST64(0x1f4d4d294d52649a), 
+CONST64(0x7692927292e4e039), CONST64(0xfa7575c9758fbcea), CONST64(0x3606061806301e0c), CONST64(0xae8a8a128a249809), 
+CONST64(0x4bb2b2f2b2f94079), CONST64(0x85e6e6bfe66359d1), CONST64(0x7e0e0e380e70361c), CONST64(0xe71f1f7c1ff8633e), 
+CONST64(0x556262956237f7c4), CONST64(0x3ad4d477d4eea3b5), CONST64(0x81a8a89aa829324d), CONST64(0x5296966296c4f431), 
+CONST64(0x62f9f9c3f99b3aef), CONST64(0xa3c5c533c566f697), CONST64(0x102525942535b14a), CONST64(0xab59597959f220b2), 
+CONST64(0xd084842a8454ae15), CONST64(0xc57272d572b7a7e4), CONST64(0xec3939e439d5dd72), CONST64(0x164c4c2d4c5a6198), 
+CONST64(0x945e5e655eca3bbc), CONST64(0x9f7878fd78e785f0), CONST64(0xe53838e038ddd870), CONST64(0x988c8c0a8c148605), 
+CONST64(0x17d1d163d1c6b2bf), CONST64(0xe4a5a5aea5410b57), CONST64(0xa1e2e2afe2434dd9), CONST64(0x4e616199612ff8c2), 
+CONST64(0x42b3b3f6b3f1457b), CONST64(0x342121842115a542), CONST64(0x089c9c4a9c94d625), CONST64(0xee1e1e781ef0663c), 
+CONST64(0x6143431143225286), CONST64(0xb1c7c73bc776fc93), CONST64(0x4ffcfcd7fcb32be5), CONST64(0x2404041004201408), 
+CONST64(0xe351515951b208a2), CONST64(0x2599995e99bcc72f), CONST64(0x226d6da96d4fc4da), CONST64(0x650d0d340d68391a), 
+CONST64(0x79fafacffa8335e9), CONST64(0x69dfdf5bdfb684a3), CONST64(0xa97e7ee57ed79bfc), CONST64(0x19242490243db448), 
+CONST64(0xfe3b3bec3bc5d776), CONST64(0x9aabab96ab313d4b), CONST64(0xf0cece1fce3ed181), CONST64(0x9911114411885522), 
+CONST64(0x838f8f068f0c8903), CONST64(0x044e4e254e4a6b9c), CONST64(0x66b7b7e6b7d15173), CONST64(0xe0ebeb8beb0b60cb), 
+CONST64(0xc13c3cf03cfdcc78), CONST64(0xfd81813e817cbf1f), CONST64(0x4094946a94d4fe35), CONST64(0x1cf7f7fbf7eb0cf3), 
+CONST64(0x18b9b9deb9a1676f), CONST64(0x8b13134c13985f26), CONST64(0x512c2cb02c7d9c58), CONST64(0x05d3d36bd3d6b8bb), 
+CONST64(0x8ce7e7bbe76b5cd3), CONST64(0x396e6ea56e57cbdc), CONST64(0xaac4c437c46ef395), CONST64(0x1b03030c03180f06), 
+CONST64(0xdc565645568a13ac), CONST64(0x5e44440d441a4988), CONST64(0xa07f7fe17fdf9efe), CONST64(0x88a9a99ea921374f), 
+CONST64(0x672a2aa82a4d8254), CONST64(0x0abbbbd6bbb16d6b), CONST64(0x87c1c123c146e29f), CONST64(0xf153535153a202a6), 
+CONST64(0x72dcdc57dcae8ba5), CONST64(0x530b0b2c0b582716), CONST64(0x019d9d4e9d9cd327), CONST64(0x2b6c6cad6c47c1d8), 
+CONST64(0xa43131c43195f562), CONST64(0xf37474cd7487b9e8), CONST64(0x15f6f6fff6e309f1), CONST64(0x4c464605460a438c), 
+CONST64(0xa5acac8aac092645), CONST64(0xb589891e893c970f), CONST64(0xb414145014a04428), CONST64(0xbae1e1a3e15b42df), 
+CONST64(0xa616165816b04e2c), CONST64(0xf73a3ae83acdd274), CONST64(0x066969b9696fd0d2), CONST64(0x4109092409482d12), 
+CONST64(0xd77070dd70a7ade0), CONST64(0x6fb6b6e2b6d95471), CONST64(0x1ed0d067d0ceb7bd), CONST64(0xd6eded93ed3b7ec7), 
+CONST64(0xe2cccc17cc2edb85), CONST64(0x68424215422a5784), CONST64(0x2c98985a98b4c22d), CONST64(0xeda4a4aaa4490e55), 
+CONST64(0x752828a0285d8850), CONST64(0x865c5c6d5cda31b8), CONST64(0x6bf8f8c7f8933fed), CONST64(0xc28686228644a411)
+};
+
+static const ulong64 sbox2[] = {
+CONST64(0x30d818186018c078), CONST64(0x462623238c2305af), CONST64(0x91b8c6c63fc67ef9), CONST64(0xcdfbe8e887e8136f), 
+CONST64(0x13cb878726874ca1), CONST64(0x6d11b8b8dab8a962), CONST64(0x0209010104010805), CONST64(0x9e0d4f4f214f426e), 
+CONST64(0x6c9b3636d836adee), CONST64(0x51ffa6a6a2a65904), CONST64(0xb90cd2d26fd2debd), CONST64(0xf70ef5f5f3f5fb06), 
+CONST64(0xf2967979f979ef80), CONST64(0xde306f6fa16f5fce), CONST64(0x3f6d91917e91fcef), CONST64(0xa4f852525552aa07), 
+CONST64(0xc04760609d6027fd), CONST64(0x6535bcbccabc8976), CONST64(0x2b379b9b569baccd), CONST64(0x018a8e8e028e048c), 
+CONST64(0x5bd2a3a3b6a37115), CONST64(0x186c0c0c300c603c), CONST64(0xf6847b7bf17bff8a), CONST64(0x6a803535d435b5e1), 
+CONST64(0x3af51d1d741de869), CONST64(0xddb3e0e0a7e05347), CONST64(0xb321d7d77bd7f6ac), CONST64(0x999cc2c22fc25eed), 
+CONST64(0x5c432e2eb82e6d96), CONST64(0x96294b4b314b627a), CONST64(0xe15dfefedffea321), CONST64(0xaed5575741578216), 
+CONST64(0x2abd15155415a841), CONST64(0xeee87777c1779fb6), CONST64(0x6e923737dc37a5eb), CONST64(0xd79ee5e5b3e57b56), 
+CONST64(0x23139f9f469f8cd9), CONST64(0xfd23f0f0e7f0d317), CONST64(0x94204a4a354a6a7f), CONST64(0xa944dada4fda9e95), 
+CONST64(0xb0a258587d58fa25), CONST64(0x8fcfc9c903c906ca), CONST64(0x527c2929a429558d), CONST64(0x145a0a0a280a5022), 
+CONST64(0x7f50b1b1feb1e14f), CONST64(0x5dc9a0a0baa0691a), CONST64(0xd6146b6bb16b7fda), CONST64(0x17d985852e855cab), 
+CONST64(0x673cbdbdcebd8173), CONST64(0xba8f5d5d695dd234), CONST64(0x2090101040108050), CONST64(0xf507f4f4f7f4f303), 
+CONST64(0x8bddcbcb0bcb16c0), CONST64(0x7cd33e3ef83eedc6), CONST64(0x0a2d050514052811), CONST64(0xce78676781671fe6), 
+CONST64(0xd597e4e4b7e47353), CONST64(0x4e0227279c2725bb), CONST64(0x8273414119413258), CONST64(0x0ba78b8b168b2c9d), 
+CONST64(0x53f6a7a7a6a75101), CONST64(0xfab27d7de97dcf94), CONST64(0x374995956e95dcfb), CONST64(0xad56d8d847d88e9f), 
+CONST64(0xeb70fbfbcbfb8b30), CONST64(0xc1cdeeee9fee2371), CONST64(0xf8bb7c7ced7cc791), CONST64(0xcc716666856617e3), 
+CONST64(0xa77bdddd53dda68e), CONST64(0x2eaf17175c17b84b), CONST64(0x8e45474701470246), CONST64(0x211a9e9e429e84dc), 
+CONST64(0x89d4caca0fca1ec5), CONST64(0x5a582d2db42d7599), CONST64(0x632ebfbfc6bf9179), CONST64(0x0e3f07071c07381b), 
+CONST64(0x47acadad8ead0123), CONST64(0xb4b05a5a755aea2f), CONST64(0x1bef838336836cb5), CONST64(0x66b63333cc3385ff), 
+CONST64(0xc65c636391633ff2), CONST64(0x041202020802100a), CONST64(0x4993aaaa92aa3938), CONST64(0xe2de7171d971afa8), 
+CONST64(0x8dc6c8c807c80ecf), CONST64(0x32d119196419c87d), CONST64(0x923b494939497270), CONST64(0xaf5fd9d943d9869a), 
+CONST64(0xf931f2f2eff2c31d), CONST64(0xdba8e3e3abe34b48), CONST64(0xb6b95b5b715be22a), CONST64(0x0dbc88881a883492), 
+CONST64(0x293e9a9a529aa4c8), CONST64(0x4c0b262698262dbe), CONST64(0x64bf3232c8328dfa), CONST64(0x7d59b0b0fab0e94a), 
+CONST64(0xcff2e9e983e91b6a), CONST64(0x1e770f0f3c0f7833), CONST64(0xb733d5d573d5e6a6), CONST64(0x1df480803a8074ba), 
+CONST64(0x6127bebec2be997c), CONST64(0x87ebcdcd13cd26de), CONST64(0x68893434d034bde4), CONST64(0x903248483d487a75), 
+CONST64(0xe354ffffdbffab24), CONST64(0xf48d7a7af57af78f), CONST64(0x3d6490907a90f4ea), CONST64(0xbe9d5f5f615fc23e), 
+CONST64(0x403d202080201da0), CONST64(0xd00f6868bd6867d5), CONST64(0x34ca1a1a681ad072), CONST64(0x41b7aeae82ae192c), 
+CONST64(0x757db4b4eab4c95e), CONST64(0xa8ce54544d549a19), CONST64(0x3b7f93937693ece5), CONST64(0x442f222288220daa), 
+CONST64(0xc86364648d6407e9), CONST64(0xff2af1f1e3f1db12), CONST64(0xe6cc7373d173bfa2), CONST64(0x248212124812905a), 
+CONST64(0x807a40401d403a5d), CONST64(0x1048080820084028), CONST64(0x9b95c3c32bc356e8), CONST64(0xc5dfecec97ec337b), 
+CONST64(0xab4ddbdb4bdb9690), CONST64(0x5fc0a1a1bea1611f), CONST64(0x07918d8d0e8d1c83), CONST64(0x7ac83d3df43df5c9), 
+CONST64(0x335b97976697ccf1), CONST64(0x0000000000000000), CONST64(0x83f9cfcf1bcf36d4), CONST64(0x566e2b2bac2b4587), 
+CONST64(0xece17676c57697b3), CONST64(0x19e68282328264b0), CONST64(0xb128d6d67fd6fea9), CONST64(0x36c31b1b6c1bd877), 
+CONST64(0x7774b5b5eeb5c15b), CONST64(0x43beafaf86af1129), CONST64(0xd41d6a6ab56a77df), CONST64(0xa0ea50505d50ba0d), 
+CONST64(0x8a5745450945124c), CONST64(0xfb38f3f3ebf3cb18), CONST64(0x60ad3030c0309df0), CONST64(0xc3c4efef9bef2b74), 
+CONST64(0x7eda3f3ffc3fe5c3), CONST64(0xaac755554955921c), CONST64(0x59dba2a2b2a27910), CONST64(0xc9e9eaea8fea0365), 
+CONST64(0xca6a656589650fec), CONST64(0x6903babad2bab968), CONST64(0x5e4a2f2fbc2f6593), CONST64(0x9d8ec0c027c04ee7), 
+CONST64(0xa160dede5fdebe81), CONST64(0x38fc1c1c701ce06c), CONST64(0xe746fdfdd3fdbb2e), CONST64(0x9a1f4d4d294d5264), 
+CONST64(0x397692927292e4e0), CONST64(0xeafa7575c9758fbc), CONST64(0x0c3606061806301e), CONST64(0x09ae8a8a128a2498), 
+CONST64(0x794bb2b2f2b2f940), CONST64(0xd185e6e6bfe66359), CONST64(0x1c7e0e0e380e7036), CONST64(0x3ee71f1f7c1ff863), 
+CONST64(0xc4556262956237f7), CONST64(0xb53ad4d477d4eea3), CONST64(0x4d81a8a89aa82932), CONST64(0x315296966296c4f4), 
+CONST64(0xef62f9f9c3f99b3a), CONST64(0x97a3c5c533c566f6), CONST64(0x4a102525942535b1), CONST64(0xb2ab59597959f220), 
+CONST64(0x15d084842a8454ae), CONST64(0xe4c57272d572b7a7), CONST64(0x72ec3939e439d5dd), CONST64(0x98164c4c2d4c5a61), 
+CONST64(0xbc945e5e655eca3b), CONST64(0xf09f7878fd78e785), CONST64(0x70e53838e038ddd8), CONST64(0x05988c8c0a8c1486), 
+CONST64(0xbf17d1d163d1c6b2), CONST64(0x57e4a5a5aea5410b), CONST64(0xd9a1e2e2afe2434d), CONST64(0xc24e616199612ff8), 
+CONST64(0x7b42b3b3f6b3f145), CONST64(0x42342121842115a5), CONST64(0x25089c9c4a9c94d6), CONST64(0x3cee1e1e781ef066), 
+CONST64(0x8661434311432252), CONST64(0x93b1c7c73bc776fc), CONST64(0xe54ffcfcd7fcb32b), CONST64(0x0824040410042014), 
+CONST64(0xa2e351515951b208), CONST64(0x2f2599995e99bcc7), CONST64(0xda226d6da96d4fc4), CONST64(0x1a650d0d340d6839), 
+CONST64(0xe979fafacffa8335), CONST64(0xa369dfdf5bdfb684), CONST64(0xfca97e7ee57ed79b), CONST64(0x4819242490243db4), 
+CONST64(0x76fe3b3bec3bc5d7), CONST64(0x4b9aabab96ab313d), CONST64(0x81f0cece1fce3ed1), CONST64(0x2299111144118855), 
+CONST64(0x03838f8f068f0c89), CONST64(0x9c044e4e254e4a6b), CONST64(0x7366b7b7e6b7d151), CONST64(0xcbe0ebeb8beb0b60), 
+CONST64(0x78c13c3cf03cfdcc), CONST64(0x1ffd81813e817cbf), CONST64(0x354094946a94d4fe), CONST64(0xf31cf7f7fbf7eb0c), 
+CONST64(0x6f18b9b9deb9a167), CONST64(0x268b13134c13985f), CONST64(0x58512c2cb02c7d9c), CONST64(0xbb05d3d36bd3d6b8), 
+CONST64(0xd38ce7e7bbe76b5c), CONST64(0xdc396e6ea56e57cb), CONST64(0x95aac4c437c46ef3), CONST64(0x061b03030c03180f), 
+CONST64(0xacdc565645568a13), CONST64(0x885e44440d441a49), CONST64(0xfea07f7fe17fdf9e), CONST64(0x4f88a9a99ea92137), 
+CONST64(0x54672a2aa82a4d82), CONST64(0x6b0abbbbd6bbb16d), CONST64(0x9f87c1c123c146e2), CONST64(0xa6f153535153a202), 
+CONST64(0xa572dcdc57dcae8b), CONST64(0x16530b0b2c0b5827), CONST64(0x27019d9d4e9d9cd3), CONST64(0xd82b6c6cad6c47c1), 
+CONST64(0x62a43131c43195f5), CONST64(0xe8f37474cd7487b9), CONST64(0xf115f6f6fff6e309), CONST64(0x8c4c464605460a43), 
+CONST64(0x45a5acac8aac0926), CONST64(0x0fb589891e893c97), CONST64(0x28b414145014a044), CONST64(0xdfbae1e1a3e15b42), 
+CONST64(0x2ca616165816b04e), CONST64(0x74f73a3ae83acdd2), CONST64(0xd2066969b9696fd0), CONST64(0x124109092409482d), 
+CONST64(0xe0d77070dd70a7ad), CONST64(0x716fb6b6e2b6d954), CONST64(0xbd1ed0d067d0ceb7), CONST64(0xc7d6eded93ed3b7e), 
+CONST64(0x85e2cccc17cc2edb), CONST64(0x8468424215422a57), CONST64(0x2d2c98985a98b4c2), CONST64(0x55eda4a4aaa4490e), 
+CONST64(0x50752828a0285d88), CONST64(0xb8865c5c6d5cda31), CONST64(0xed6bf8f8c7f8933f), CONST64(0x11c28686228644a4)
+};
+
+static const ulong64 sbox3[] = {
+CONST64(0x7830d818186018c0), CONST64(0xaf462623238c2305), CONST64(0xf991b8c6c63fc67e), CONST64(0x6fcdfbe8e887e813), 
+CONST64(0xa113cb878726874c), CONST64(0x626d11b8b8dab8a9), CONST64(0x0502090101040108), CONST64(0x6e9e0d4f4f214f42), 
+CONST64(0xee6c9b3636d836ad), CONST64(0x0451ffa6a6a2a659), CONST64(0xbdb90cd2d26fd2de), CONST64(0x06f70ef5f5f3f5fb), 
+CONST64(0x80f2967979f979ef), CONST64(0xcede306f6fa16f5f), CONST64(0xef3f6d91917e91fc), CONST64(0x07a4f852525552aa), 
+CONST64(0xfdc04760609d6027), CONST64(0x766535bcbccabc89), CONST64(0xcd2b379b9b569bac), CONST64(0x8c018a8e8e028e04), 
+CONST64(0x155bd2a3a3b6a371), CONST64(0x3c186c0c0c300c60), CONST64(0x8af6847b7bf17bff), CONST64(0xe16a803535d435b5), 
+CONST64(0x693af51d1d741de8), CONST64(0x47ddb3e0e0a7e053), CONST64(0xacb321d7d77bd7f6), CONST64(0xed999cc2c22fc25e), 
+CONST64(0x965c432e2eb82e6d), CONST64(0x7a96294b4b314b62), CONST64(0x21e15dfefedffea3), CONST64(0x16aed55757415782), 
+CONST64(0x412abd15155415a8), CONST64(0xb6eee87777c1779f), CONST64(0xeb6e923737dc37a5), CONST64(0x56d79ee5e5b3e57b), 
+CONST64(0xd923139f9f469f8c), CONST64(0x17fd23f0f0e7f0d3), CONST64(0x7f94204a4a354a6a), CONST64(0x95a944dada4fda9e), 
+CONST64(0x25b0a258587d58fa), CONST64(0xca8fcfc9c903c906), CONST64(0x8d527c2929a42955), CONST64(0x22145a0a0a280a50), 
+CONST64(0x4f7f50b1b1feb1e1), CONST64(0x1a5dc9a0a0baa069), CONST64(0xdad6146b6bb16b7f), CONST64(0xab17d985852e855c), 
+CONST64(0x73673cbdbdcebd81), CONST64(0x34ba8f5d5d695dd2), CONST64(0x5020901010401080), CONST64(0x03f507f4f4f7f4f3), 
+CONST64(0xc08bddcbcb0bcb16), CONST64(0xc67cd33e3ef83eed), CONST64(0x110a2d0505140528), CONST64(0xe6ce78676781671f), 
+CONST64(0x53d597e4e4b7e473), CONST64(0xbb4e0227279c2725), CONST64(0x5882734141194132), CONST64(0x9d0ba78b8b168b2c), 
+CONST64(0x0153f6a7a7a6a751), CONST64(0x94fab27d7de97dcf), CONST64(0xfb374995956e95dc), CONST64(0x9fad56d8d847d88e), 
+CONST64(0x30eb70fbfbcbfb8b), CONST64(0x71c1cdeeee9fee23), CONST64(0x91f8bb7c7ced7cc7), CONST64(0xe3cc716666856617), 
+CONST64(0x8ea77bdddd53dda6), CONST64(0x4b2eaf17175c17b8), CONST64(0x468e454747014702), CONST64(0xdc211a9e9e429e84), 
+CONST64(0xc589d4caca0fca1e), CONST64(0x995a582d2db42d75), CONST64(0x79632ebfbfc6bf91), CONST64(0x1b0e3f07071c0738), 
+CONST64(0x2347acadad8ead01), CONST64(0x2fb4b05a5a755aea), CONST64(0xb51bef838336836c), CONST64(0xff66b63333cc3385), 
+CONST64(0xf2c65c636391633f), CONST64(0x0a04120202080210), CONST64(0x384993aaaa92aa39), CONST64(0xa8e2de7171d971af), 
+CONST64(0xcf8dc6c8c807c80e), CONST64(0x7d32d119196419c8), CONST64(0x70923b4949394972), CONST64(0x9aaf5fd9d943d986), 
+CONST64(0x1df931f2f2eff2c3), CONST64(0x48dba8e3e3abe34b), CONST64(0x2ab6b95b5b715be2), CONST64(0x920dbc88881a8834), 
+CONST64(0xc8293e9a9a529aa4), CONST64(0xbe4c0b262698262d), CONST64(0xfa64bf3232c8328d), CONST64(0x4a7d59b0b0fab0e9), 
+CONST64(0x6acff2e9e983e91b), CONST64(0x331e770f0f3c0f78), CONST64(0xa6b733d5d573d5e6), CONST64(0xba1df480803a8074), 
+CONST64(0x7c6127bebec2be99), CONST64(0xde87ebcdcd13cd26), CONST64(0xe468893434d034bd), CONST64(0x75903248483d487a), 
+CONST64(0x24e354ffffdbffab), CONST64(0x8ff48d7a7af57af7), CONST64(0xea3d6490907a90f4), CONST64(0x3ebe9d5f5f615fc2), 
+CONST64(0xa0403d202080201d), CONST64(0xd5d00f6868bd6867), CONST64(0x7234ca1a1a681ad0), CONST64(0x2c41b7aeae82ae19), 
+CONST64(0x5e757db4b4eab4c9), CONST64(0x19a8ce54544d549a), CONST64(0xe53b7f93937693ec), CONST64(0xaa442f222288220d), 
+CONST64(0xe9c86364648d6407), CONST64(0x12ff2af1f1e3f1db), CONST64(0xa2e6cc7373d173bf), CONST64(0x5a24821212481290), 
+CONST64(0x5d807a40401d403a), CONST64(0x2810480808200840), CONST64(0xe89b95c3c32bc356), CONST64(0x7bc5dfecec97ec33), 
+CONST64(0x90ab4ddbdb4bdb96), CONST64(0x1f5fc0a1a1bea161), CONST64(0x8307918d8d0e8d1c), CONST64(0xc97ac83d3df43df5), 
+CONST64(0xf1335b97976697cc), CONST64(0x0000000000000000), CONST64(0xd483f9cfcf1bcf36), CONST64(0x87566e2b2bac2b45), 
+CONST64(0xb3ece17676c57697), CONST64(0xb019e68282328264), CONST64(0xa9b128d6d67fd6fe), CONST64(0x7736c31b1b6c1bd8), 
+CONST64(0x5b7774b5b5eeb5c1), CONST64(0x2943beafaf86af11), CONST64(0xdfd41d6a6ab56a77), CONST64(0x0da0ea50505d50ba), 
+CONST64(0x4c8a574545094512), CONST64(0x18fb38f3f3ebf3cb), CONST64(0xf060ad3030c0309d), CONST64(0x74c3c4efef9bef2b), 
+CONST64(0xc37eda3f3ffc3fe5), CONST64(0x1caac75555495592), CONST64(0x1059dba2a2b2a279), CONST64(0x65c9e9eaea8fea03), 
+CONST64(0xecca6a656589650f), CONST64(0x686903babad2bab9), CONST64(0x935e4a2f2fbc2f65), CONST64(0xe79d8ec0c027c04e), 
+CONST64(0x81a160dede5fdebe), CONST64(0x6c38fc1c1c701ce0), CONST64(0x2ee746fdfdd3fdbb), CONST64(0x649a1f4d4d294d52), 
+CONST64(0xe0397692927292e4), CONST64(0xbceafa7575c9758f), CONST64(0x1e0c360606180630), CONST64(0x9809ae8a8a128a24), 
+CONST64(0x40794bb2b2f2b2f9), CONST64(0x59d185e6e6bfe663), CONST64(0x361c7e0e0e380e70), CONST64(0x633ee71f1f7c1ff8), 
+CONST64(0xf7c4556262956237), CONST64(0xa3b53ad4d477d4ee), CONST64(0x324d81a8a89aa829), CONST64(0xf4315296966296c4), 
+CONST64(0x3aef62f9f9c3f99b), CONST64(0xf697a3c5c533c566), CONST64(0xb14a102525942535), CONST64(0x20b2ab59597959f2), 
+CONST64(0xae15d084842a8454), CONST64(0xa7e4c57272d572b7), CONST64(0xdd72ec3939e439d5), CONST64(0x6198164c4c2d4c5a), 
+CONST64(0x3bbc945e5e655eca), CONST64(0x85f09f7878fd78e7), CONST64(0xd870e53838e038dd), CONST64(0x8605988c8c0a8c14), 
+CONST64(0xb2bf17d1d163d1c6), CONST64(0x0b57e4a5a5aea541), CONST64(0x4dd9a1e2e2afe243), CONST64(0xf8c24e616199612f), 
+CONST64(0x457b42b3b3f6b3f1), CONST64(0xa542342121842115), CONST64(0xd625089c9c4a9c94), CONST64(0x663cee1e1e781ef0), 
+CONST64(0x5286614343114322), CONST64(0xfc93b1c7c73bc776), CONST64(0x2be54ffcfcd7fcb3), CONST64(0x1408240404100420), 
+CONST64(0x08a2e351515951b2), CONST64(0xc72f2599995e99bc), CONST64(0xc4da226d6da96d4f), CONST64(0x391a650d0d340d68), 
+CONST64(0x35e979fafacffa83), CONST64(0x84a369dfdf5bdfb6), CONST64(0x9bfca97e7ee57ed7), CONST64(0xb44819242490243d), 
+CONST64(0xd776fe3b3bec3bc5), CONST64(0x3d4b9aabab96ab31), CONST64(0xd181f0cece1fce3e), CONST64(0x5522991111441188), 
+CONST64(0x8903838f8f068f0c), CONST64(0x6b9c044e4e254e4a), CONST64(0x517366b7b7e6b7d1), CONST64(0x60cbe0ebeb8beb0b), 
+CONST64(0xcc78c13c3cf03cfd), CONST64(0xbf1ffd81813e817c), CONST64(0xfe354094946a94d4), CONST64(0x0cf31cf7f7fbf7eb), 
+CONST64(0x676f18b9b9deb9a1), CONST64(0x5f268b13134c1398), CONST64(0x9c58512c2cb02c7d), CONST64(0xb8bb05d3d36bd3d6), 
+CONST64(0x5cd38ce7e7bbe76b), CONST64(0xcbdc396e6ea56e57), CONST64(0xf395aac4c437c46e), CONST64(0x0f061b03030c0318), 
+CONST64(0x13acdc565645568a), CONST64(0x49885e44440d441a), CONST64(0x9efea07f7fe17fdf), CONST64(0x374f88a9a99ea921), 
+CONST64(0x8254672a2aa82a4d), CONST64(0x6d6b0abbbbd6bbb1), CONST64(0xe29f87c1c123c146), CONST64(0x02a6f153535153a2), 
+CONST64(0x8ba572dcdc57dcae), CONST64(0x2716530b0b2c0b58), CONST64(0xd327019d9d4e9d9c), CONST64(0xc1d82b6c6cad6c47), 
+CONST64(0xf562a43131c43195), CONST64(0xb9e8f37474cd7487), CONST64(0x09f115f6f6fff6e3), CONST64(0x438c4c464605460a), 
+CONST64(0x2645a5acac8aac09), CONST64(0x970fb589891e893c), CONST64(0x4428b414145014a0), CONST64(0x42dfbae1e1a3e15b), 
+CONST64(0x4e2ca616165816b0), CONST64(0xd274f73a3ae83acd), CONST64(0xd0d2066969b9696f), CONST64(0x2d12410909240948), 
+CONST64(0xade0d77070dd70a7), CONST64(0x54716fb6b6e2b6d9), CONST64(0xb7bd1ed0d067d0ce), CONST64(0x7ec7d6eded93ed3b), 
+CONST64(0xdb85e2cccc17cc2e), CONST64(0x578468424215422a), CONST64(0xc22d2c98985a98b4), CONST64(0x0e55eda4a4aaa449), 
+CONST64(0x8850752828a0285d), CONST64(0x31b8865c5c6d5cda), CONST64(0x3fed6bf8f8c7f893), CONST64(0xa411c28686228644)
+};
+
+static const ulong64 sbox4[] = {
+CONST64(0xc07830d818186018), CONST64(0x05af462623238c23), CONST64(0x7ef991b8c6c63fc6), CONST64(0x136fcdfbe8e887e8), 
+CONST64(0x4ca113cb87872687), CONST64(0xa9626d11b8b8dab8), CONST64(0x0805020901010401), CONST64(0x426e9e0d4f4f214f), 
+CONST64(0xadee6c9b3636d836), CONST64(0x590451ffa6a6a2a6), CONST64(0xdebdb90cd2d26fd2), CONST64(0xfb06f70ef5f5f3f5), 
+CONST64(0xef80f2967979f979), CONST64(0x5fcede306f6fa16f), CONST64(0xfcef3f6d91917e91), CONST64(0xaa07a4f852525552), 
+CONST64(0x27fdc04760609d60), CONST64(0x89766535bcbccabc), CONST64(0xaccd2b379b9b569b), CONST64(0x048c018a8e8e028e), 
+CONST64(0x71155bd2a3a3b6a3), CONST64(0x603c186c0c0c300c), CONST64(0xff8af6847b7bf17b), CONST64(0xb5e16a803535d435), 
+CONST64(0xe8693af51d1d741d), CONST64(0x5347ddb3e0e0a7e0), CONST64(0xf6acb321d7d77bd7), CONST64(0x5eed999cc2c22fc2), 
+CONST64(0x6d965c432e2eb82e), CONST64(0x627a96294b4b314b), CONST64(0xa321e15dfefedffe), CONST64(0x8216aed557574157), 
+CONST64(0xa8412abd15155415), CONST64(0x9fb6eee87777c177), CONST64(0xa5eb6e923737dc37), CONST64(0x7b56d79ee5e5b3e5), 
+CONST64(0x8cd923139f9f469f), CONST64(0xd317fd23f0f0e7f0), CONST64(0x6a7f94204a4a354a), CONST64(0x9e95a944dada4fda), 
+CONST64(0xfa25b0a258587d58), CONST64(0x06ca8fcfc9c903c9), CONST64(0x558d527c2929a429), CONST64(0x5022145a0a0a280a), 
+CONST64(0xe14f7f50b1b1feb1), CONST64(0x691a5dc9a0a0baa0), CONST64(0x7fdad6146b6bb16b), CONST64(0x5cab17d985852e85), 
+CONST64(0x8173673cbdbdcebd), CONST64(0xd234ba8f5d5d695d), CONST64(0x8050209010104010), CONST64(0xf303f507f4f4f7f4), 
+CONST64(0x16c08bddcbcb0bcb), CONST64(0xedc67cd33e3ef83e), CONST64(0x28110a2d05051405), CONST64(0x1fe6ce7867678167), 
+CONST64(0x7353d597e4e4b7e4), CONST64(0x25bb4e0227279c27), CONST64(0x3258827341411941), CONST64(0x2c9d0ba78b8b168b), 
+CONST64(0x510153f6a7a7a6a7), CONST64(0xcf94fab27d7de97d), CONST64(0xdcfb374995956e95), CONST64(0x8e9fad56d8d847d8), 
+CONST64(0x8b30eb70fbfbcbfb), CONST64(0x2371c1cdeeee9fee), CONST64(0xc791f8bb7c7ced7c), CONST64(0x17e3cc7166668566), 
+CONST64(0xa68ea77bdddd53dd), CONST64(0xb84b2eaf17175c17), CONST64(0x02468e4547470147), CONST64(0x84dc211a9e9e429e), 
+CONST64(0x1ec589d4caca0fca), CONST64(0x75995a582d2db42d), CONST64(0x9179632ebfbfc6bf), CONST64(0x381b0e3f07071c07), 
+CONST64(0x012347acadad8ead), CONST64(0xea2fb4b05a5a755a), CONST64(0x6cb51bef83833683), CONST64(0x85ff66b63333cc33), 
+CONST64(0x3ff2c65c63639163), CONST64(0x100a041202020802), CONST64(0x39384993aaaa92aa), CONST64(0xafa8e2de7171d971), 
+CONST64(0x0ecf8dc6c8c807c8), CONST64(0xc87d32d119196419), CONST64(0x7270923b49493949), CONST64(0x869aaf5fd9d943d9), 
+CONST64(0xc31df931f2f2eff2), CONST64(0x4b48dba8e3e3abe3), CONST64(0xe22ab6b95b5b715b), CONST64(0x34920dbc88881a88), 
+CONST64(0xa4c8293e9a9a529a), CONST64(0x2dbe4c0b26269826), CONST64(0x8dfa64bf3232c832), CONST64(0xe94a7d59b0b0fab0), 
+CONST64(0x1b6acff2e9e983e9), CONST64(0x78331e770f0f3c0f), CONST64(0xe6a6b733d5d573d5), CONST64(0x74ba1df480803a80), 
+CONST64(0x997c6127bebec2be), CONST64(0x26de87ebcdcd13cd), CONST64(0xbde468893434d034), CONST64(0x7a75903248483d48), 
+CONST64(0xab24e354ffffdbff), CONST64(0xf78ff48d7a7af57a), CONST64(0xf4ea3d6490907a90), CONST64(0xc23ebe9d5f5f615f), 
+CONST64(0x1da0403d20208020), CONST64(0x67d5d00f6868bd68), CONST64(0xd07234ca1a1a681a), CONST64(0x192c41b7aeae82ae), 
+CONST64(0xc95e757db4b4eab4), CONST64(0x9a19a8ce54544d54), CONST64(0xece53b7f93937693), CONST64(0x0daa442f22228822), 
+CONST64(0x07e9c86364648d64), CONST64(0xdb12ff2af1f1e3f1), CONST64(0xbfa2e6cc7373d173), CONST64(0x905a248212124812), 
+CONST64(0x3a5d807a40401d40), CONST64(0x4028104808082008), CONST64(0x56e89b95c3c32bc3), CONST64(0x337bc5dfecec97ec), 
+CONST64(0x9690ab4ddbdb4bdb), CONST64(0x611f5fc0a1a1bea1), CONST64(0x1c8307918d8d0e8d), CONST64(0xf5c97ac83d3df43d), 
+CONST64(0xccf1335b97976697), CONST64(0x0000000000000000), CONST64(0x36d483f9cfcf1bcf), CONST64(0x4587566e2b2bac2b), 
+CONST64(0x97b3ece17676c576), CONST64(0x64b019e682823282), CONST64(0xfea9b128d6d67fd6), CONST64(0xd87736c31b1b6c1b), 
+CONST64(0xc15b7774b5b5eeb5), CONST64(0x112943beafaf86af), CONST64(0x77dfd41d6a6ab56a), CONST64(0xba0da0ea50505d50), 
+CONST64(0x124c8a5745450945), CONST64(0xcb18fb38f3f3ebf3), CONST64(0x9df060ad3030c030), CONST64(0x2b74c3c4efef9bef), 
+CONST64(0xe5c37eda3f3ffc3f), CONST64(0x921caac755554955), CONST64(0x791059dba2a2b2a2), CONST64(0x0365c9e9eaea8fea), 
+CONST64(0x0fecca6a65658965), CONST64(0xb9686903babad2ba), CONST64(0x65935e4a2f2fbc2f), CONST64(0x4ee79d8ec0c027c0), 
+CONST64(0xbe81a160dede5fde), CONST64(0xe06c38fc1c1c701c), CONST64(0xbb2ee746fdfdd3fd), CONST64(0x52649a1f4d4d294d), 
+CONST64(0xe4e0397692927292), CONST64(0x8fbceafa7575c975), CONST64(0x301e0c3606061806), CONST64(0x249809ae8a8a128a), 
+CONST64(0xf940794bb2b2f2b2), CONST64(0x6359d185e6e6bfe6), CONST64(0x70361c7e0e0e380e), CONST64(0xf8633ee71f1f7c1f), 
+CONST64(0x37f7c45562629562), CONST64(0xeea3b53ad4d477d4), CONST64(0x29324d81a8a89aa8), CONST64(0xc4f4315296966296), 
+CONST64(0x9b3aef62f9f9c3f9), CONST64(0x66f697a3c5c533c5), CONST64(0x35b14a1025259425), CONST64(0xf220b2ab59597959), 
+CONST64(0x54ae15d084842a84), CONST64(0xb7a7e4c57272d572), CONST64(0xd5dd72ec3939e439), CONST64(0x5a6198164c4c2d4c), 
+CONST64(0xca3bbc945e5e655e), CONST64(0xe785f09f7878fd78), CONST64(0xddd870e53838e038), CONST64(0x148605988c8c0a8c), 
+CONST64(0xc6b2bf17d1d163d1), CONST64(0x410b57e4a5a5aea5), CONST64(0x434dd9a1e2e2afe2), CONST64(0x2ff8c24e61619961), 
+CONST64(0xf1457b42b3b3f6b3), CONST64(0x15a5423421218421), CONST64(0x94d625089c9c4a9c), CONST64(0xf0663cee1e1e781e), 
+CONST64(0x2252866143431143), CONST64(0x76fc93b1c7c73bc7), CONST64(0xb32be54ffcfcd7fc), CONST64(0x2014082404041004), 
+CONST64(0xb208a2e351515951), CONST64(0xbcc72f2599995e99), CONST64(0x4fc4da226d6da96d), CONST64(0x68391a650d0d340d), 
+CONST64(0x8335e979fafacffa), CONST64(0xb684a369dfdf5bdf), CONST64(0xd79bfca97e7ee57e), CONST64(0x3db4481924249024), 
+CONST64(0xc5d776fe3b3bec3b), CONST64(0x313d4b9aabab96ab), CONST64(0x3ed181f0cece1fce), CONST64(0x8855229911114411), 
+CONST64(0x0c8903838f8f068f), CONST64(0x4a6b9c044e4e254e), CONST64(0xd1517366b7b7e6b7), CONST64(0x0b60cbe0ebeb8beb), 
+CONST64(0xfdcc78c13c3cf03c), CONST64(0x7cbf1ffd81813e81), CONST64(0xd4fe354094946a94), CONST64(0xeb0cf31cf7f7fbf7), 
+CONST64(0xa1676f18b9b9deb9), CONST64(0x985f268b13134c13), CONST64(0x7d9c58512c2cb02c), CONST64(0xd6b8bb05d3d36bd3), 
+CONST64(0x6b5cd38ce7e7bbe7), CONST64(0x57cbdc396e6ea56e), CONST64(0x6ef395aac4c437c4), CONST64(0x180f061b03030c03), 
+CONST64(0x8a13acdc56564556), CONST64(0x1a49885e44440d44), CONST64(0xdf9efea07f7fe17f), CONST64(0x21374f88a9a99ea9), 
+CONST64(0x4d8254672a2aa82a), CONST64(0xb16d6b0abbbbd6bb), CONST64(0x46e29f87c1c123c1), CONST64(0xa202a6f153535153), 
+CONST64(0xae8ba572dcdc57dc), CONST64(0x582716530b0b2c0b), CONST64(0x9cd327019d9d4e9d), CONST64(0x47c1d82b6c6cad6c), 
+CONST64(0x95f562a43131c431), CONST64(0x87b9e8f37474cd74), CONST64(0xe309f115f6f6fff6), CONST64(0x0a438c4c46460546), 
+CONST64(0x092645a5acac8aac), CONST64(0x3c970fb589891e89), CONST64(0xa04428b414145014), CONST64(0x5b42dfbae1e1a3e1), 
+CONST64(0xb04e2ca616165816), CONST64(0xcdd274f73a3ae83a), CONST64(0x6fd0d2066969b969), CONST64(0x482d124109092409), 
+CONST64(0xa7ade0d77070dd70), CONST64(0xd954716fb6b6e2b6), CONST64(0xceb7bd1ed0d067d0), CONST64(0x3b7ec7d6eded93ed), 
+CONST64(0x2edb85e2cccc17cc), CONST64(0x2a57846842421542), CONST64(0xb4c22d2c98985a98), CONST64(0x490e55eda4a4aaa4), 
+CONST64(0x5d8850752828a028), CONST64(0xda31b8865c5c6d5c), CONST64(0x933fed6bf8f8c7f8), CONST64(0x44a411c286862286)
+};
+
+static const ulong64 sbox5[] = {
+CONST64(0x18c07830d8181860), CONST64(0x2305af462623238c), CONST64(0xc67ef991b8c6c63f), CONST64(0xe8136fcdfbe8e887), 
+CONST64(0x874ca113cb878726), CONST64(0xb8a9626d11b8b8da), CONST64(0x0108050209010104), CONST64(0x4f426e9e0d4f4f21), 
+CONST64(0x36adee6c9b3636d8), CONST64(0xa6590451ffa6a6a2), CONST64(0xd2debdb90cd2d26f), CONST64(0xf5fb06f70ef5f5f3), 
+CONST64(0x79ef80f2967979f9), CONST64(0x6f5fcede306f6fa1), CONST64(0x91fcef3f6d91917e), CONST64(0x52aa07a4f8525255), 
+CONST64(0x6027fdc04760609d), CONST64(0xbc89766535bcbcca), CONST64(0x9baccd2b379b9b56), CONST64(0x8e048c018a8e8e02), 
+CONST64(0xa371155bd2a3a3b6), CONST64(0x0c603c186c0c0c30), CONST64(0x7bff8af6847b7bf1), CONST64(0x35b5e16a803535d4), 
+CONST64(0x1de8693af51d1d74), CONST64(0xe05347ddb3e0e0a7), CONST64(0xd7f6acb321d7d77b), CONST64(0xc25eed999cc2c22f), 
+CONST64(0x2e6d965c432e2eb8), CONST64(0x4b627a96294b4b31), CONST64(0xfea321e15dfefedf), CONST64(0x578216aed5575741), 
+CONST64(0x15a8412abd151554), CONST64(0x779fb6eee87777c1), CONST64(0x37a5eb6e923737dc), CONST64(0xe57b56d79ee5e5b3), 
+CONST64(0x9f8cd923139f9f46), CONST64(0xf0d317fd23f0f0e7), CONST64(0x4a6a7f94204a4a35), CONST64(0xda9e95a944dada4f), 
+CONST64(0x58fa25b0a258587d), CONST64(0xc906ca8fcfc9c903), CONST64(0x29558d527c2929a4), CONST64(0x0a5022145a0a0a28), 
+CONST64(0xb1e14f7f50b1b1fe), CONST64(0xa0691a5dc9a0a0ba), CONST64(0x6b7fdad6146b6bb1), CONST64(0x855cab17d985852e), 
+CONST64(0xbd8173673cbdbdce), CONST64(0x5dd234ba8f5d5d69), CONST64(0x1080502090101040), CONST64(0xf4f303f507f4f4f7), 
+CONST64(0xcb16c08bddcbcb0b), CONST64(0x3eedc67cd33e3ef8), CONST64(0x0528110a2d050514), CONST64(0x671fe6ce78676781), 
+CONST64(0xe47353d597e4e4b7), CONST64(0x2725bb4e0227279c), CONST64(0x4132588273414119), CONST64(0x8b2c9d0ba78b8b16), 
+CONST64(0xa7510153f6a7a7a6), CONST64(0x7dcf94fab27d7de9), CONST64(0x95dcfb374995956e), CONST64(0xd88e9fad56d8d847), 
+CONST64(0xfb8b30eb70fbfbcb), CONST64(0xee2371c1cdeeee9f), CONST64(0x7cc791f8bb7c7ced), CONST64(0x6617e3cc71666685), 
+CONST64(0xdda68ea77bdddd53), CONST64(0x17b84b2eaf17175c), CONST64(0x4702468e45474701), CONST64(0x9e84dc211a9e9e42), 
+CONST64(0xca1ec589d4caca0f), CONST64(0x2d75995a582d2db4), CONST64(0xbf9179632ebfbfc6), CONST64(0x07381b0e3f07071c), 
+CONST64(0xad012347acadad8e), CONST64(0x5aea2fb4b05a5a75), CONST64(0x836cb51bef838336), CONST64(0x3385ff66b63333cc), 
+CONST64(0x633ff2c65c636391), CONST64(0x02100a0412020208), CONST64(0xaa39384993aaaa92), CONST64(0x71afa8e2de7171d9), 
+CONST64(0xc80ecf8dc6c8c807), CONST64(0x19c87d32d1191964), CONST64(0x497270923b494939), CONST64(0xd9869aaf5fd9d943), 
+CONST64(0xf2c31df931f2f2ef), CONST64(0xe34b48dba8e3e3ab), CONST64(0x5be22ab6b95b5b71), CONST64(0x8834920dbc88881a), 
+CONST64(0x9aa4c8293e9a9a52), CONST64(0x262dbe4c0b262698), CONST64(0x328dfa64bf3232c8), CONST64(0xb0e94a7d59b0b0fa), 
+CONST64(0xe91b6acff2e9e983), CONST64(0x0f78331e770f0f3c), CONST64(0xd5e6a6b733d5d573), CONST64(0x8074ba1df480803a), 
+CONST64(0xbe997c6127bebec2), CONST64(0xcd26de87ebcdcd13), CONST64(0x34bde468893434d0), CONST64(0x487a75903248483d), 
+CONST64(0xffab24e354ffffdb), CONST64(0x7af78ff48d7a7af5), CONST64(0x90f4ea3d6490907a), CONST64(0x5fc23ebe9d5f5f61), 
+CONST64(0x201da0403d202080), CONST64(0x6867d5d00f6868bd), CONST64(0x1ad07234ca1a1a68), CONST64(0xae192c41b7aeae82), 
+CONST64(0xb4c95e757db4b4ea), CONST64(0x549a19a8ce54544d), CONST64(0x93ece53b7f939376), CONST64(0x220daa442f222288), 
+CONST64(0x6407e9c86364648d), CONST64(0xf1db12ff2af1f1e3), CONST64(0x73bfa2e6cc7373d1), CONST64(0x12905a2482121248), 
+CONST64(0x403a5d807a40401d), CONST64(0x0840281048080820), CONST64(0xc356e89b95c3c32b), CONST64(0xec337bc5dfecec97), 
+CONST64(0xdb9690ab4ddbdb4b), CONST64(0xa1611f5fc0a1a1be), CONST64(0x8d1c8307918d8d0e), CONST64(0x3df5c97ac83d3df4), 
+CONST64(0x97ccf1335b979766), CONST64(0x0000000000000000), CONST64(0xcf36d483f9cfcf1b), CONST64(0x2b4587566e2b2bac), 
+CONST64(0x7697b3ece17676c5), CONST64(0x8264b019e6828232), CONST64(0xd6fea9b128d6d67f), CONST64(0x1bd87736c31b1b6c), 
+CONST64(0xb5c15b7774b5b5ee), CONST64(0xaf112943beafaf86), CONST64(0x6a77dfd41d6a6ab5), CONST64(0x50ba0da0ea50505d), 
+CONST64(0x45124c8a57454509), CONST64(0xf3cb18fb38f3f3eb), CONST64(0x309df060ad3030c0), CONST64(0xef2b74c3c4efef9b), 
+CONST64(0x3fe5c37eda3f3ffc), CONST64(0x55921caac7555549), CONST64(0xa2791059dba2a2b2), CONST64(0xea0365c9e9eaea8f), 
+CONST64(0x650fecca6a656589), CONST64(0xbab9686903babad2), CONST64(0x2f65935e4a2f2fbc), CONST64(0xc04ee79d8ec0c027), 
+CONST64(0xdebe81a160dede5f), CONST64(0x1ce06c38fc1c1c70), CONST64(0xfdbb2ee746fdfdd3), CONST64(0x4d52649a1f4d4d29), 
+CONST64(0x92e4e03976929272), CONST64(0x758fbceafa7575c9), CONST64(0x06301e0c36060618), CONST64(0x8a249809ae8a8a12), 
+CONST64(0xb2f940794bb2b2f2), CONST64(0xe66359d185e6e6bf), CONST64(0x0e70361c7e0e0e38), CONST64(0x1ff8633ee71f1f7c), 
+CONST64(0x6237f7c455626295), CONST64(0xd4eea3b53ad4d477), CONST64(0xa829324d81a8a89a), CONST64(0x96c4f43152969662), 
+CONST64(0xf99b3aef62f9f9c3), CONST64(0xc566f697a3c5c533), CONST64(0x2535b14a10252594), CONST64(0x59f220b2ab595979), 
+CONST64(0x8454ae15d084842a), CONST64(0x72b7a7e4c57272d5), CONST64(0x39d5dd72ec3939e4), CONST64(0x4c5a6198164c4c2d), 
+CONST64(0x5eca3bbc945e5e65), CONST64(0x78e785f09f7878fd), CONST64(0x38ddd870e53838e0), CONST64(0x8c148605988c8c0a), 
+CONST64(0xd1c6b2bf17d1d163), CONST64(0xa5410b57e4a5a5ae), CONST64(0xe2434dd9a1e2e2af), CONST64(0x612ff8c24e616199), 
+CONST64(0xb3f1457b42b3b3f6), CONST64(0x2115a54234212184), CONST64(0x9c94d625089c9c4a), CONST64(0x1ef0663cee1e1e78), 
+CONST64(0x4322528661434311), CONST64(0xc776fc93b1c7c73b), CONST64(0xfcb32be54ffcfcd7), CONST64(0x0420140824040410), 
+CONST64(0x51b208a2e3515159), CONST64(0x99bcc72f2599995e), CONST64(0x6d4fc4da226d6da9), CONST64(0x0d68391a650d0d34), 
+CONST64(0xfa8335e979fafacf), CONST64(0xdfb684a369dfdf5b), CONST64(0x7ed79bfca97e7ee5), CONST64(0x243db44819242490), 
+CONST64(0x3bc5d776fe3b3bec), CONST64(0xab313d4b9aabab96), CONST64(0xce3ed181f0cece1f), CONST64(0x1188552299111144), 
+CONST64(0x8f0c8903838f8f06), CONST64(0x4e4a6b9c044e4e25), CONST64(0xb7d1517366b7b7e6), CONST64(0xeb0b60cbe0ebeb8b), 
+CONST64(0x3cfdcc78c13c3cf0), CONST64(0x817cbf1ffd81813e), CONST64(0x94d4fe354094946a), CONST64(0xf7eb0cf31cf7f7fb), 
+CONST64(0xb9a1676f18b9b9de), CONST64(0x13985f268b13134c), CONST64(0x2c7d9c58512c2cb0), CONST64(0xd3d6b8bb05d3d36b), 
+CONST64(0xe76b5cd38ce7e7bb), CONST64(0x6e57cbdc396e6ea5), CONST64(0xc46ef395aac4c437), CONST64(0x03180f061b03030c), 
+CONST64(0x568a13acdc565645), CONST64(0x441a49885e44440d), CONST64(0x7fdf9efea07f7fe1), CONST64(0xa921374f88a9a99e), 
+CONST64(0x2a4d8254672a2aa8), CONST64(0xbbb16d6b0abbbbd6), CONST64(0xc146e29f87c1c123), CONST64(0x53a202a6f1535351), 
+CONST64(0xdcae8ba572dcdc57), CONST64(0x0b582716530b0b2c), CONST64(0x9d9cd327019d9d4e), CONST64(0x6c47c1d82b6c6cad), 
+CONST64(0x3195f562a43131c4), CONST64(0x7487b9e8f37474cd), CONST64(0xf6e309f115f6f6ff), CONST64(0x460a438c4c464605), 
+CONST64(0xac092645a5acac8a), CONST64(0x893c970fb589891e), CONST64(0x14a04428b4141450), CONST64(0xe15b42dfbae1e1a3), 
+CONST64(0x16b04e2ca6161658), CONST64(0x3acdd274f73a3ae8), CONST64(0x696fd0d2066969b9), CONST64(0x09482d1241090924), 
+CONST64(0x70a7ade0d77070dd), CONST64(0xb6d954716fb6b6e2), CONST64(0xd0ceb7bd1ed0d067), CONST64(0xed3b7ec7d6eded93), 
+CONST64(0xcc2edb85e2cccc17), CONST64(0x422a578468424215), CONST64(0x98b4c22d2c98985a), CONST64(0xa4490e55eda4a4aa), 
+CONST64(0x285d8850752828a0), CONST64(0x5cda31b8865c5c6d), CONST64(0xf8933fed6bf8f8c7), CONST64(0x8644a411c2868622)
+};
+
+static const ulong64 sbox6[] = {
+CONST64(0x6018c07830d81818), CONST64(0x8c2305af46262323), CONST64(0x3fc67ef991b8c6c6), CONST64(0x87e8136fcdfbe8e8), 
+CONST64(0x26874ca113cb8787), CONST64(0xdab8a9626d11b8b8), CONST64(0x0401080502090101), CONST64(0x214f426e9e0d4f4f), 
+CONST64(0xd836adee6c9b3636), CONST64(0xa2a6590451ffa6a6), CONST64(0x6fd2debdb90cd2d2), CONST64(0xf3f5fb06f70ef5f5), 
+CONST64(0xf979ef80f2967979), CONST64(0xa16f5fcede306f6f), CONST64(0x7e91fcef3f6d9191), CONST64(0x5552aa07a4f85252), 
+CONST64(0x9d6027fdc0476060), CONST64(0xcabc89766535bcbc), CONST64(0x569baccd2b379b9b), CONST64(0x028e048c018a8e8e), 
+CONST64(0xb6a371155bd2a3a3), CONST64(0x300c603c186c0c0c), CONST64(0xf17bff8af6847b7b), CONST64(0xd435b5e16a803535), 
+CONST64(0x741de8693af51d1d), CONST64(0xa7e05347ddb3e0e0), CONST64(0x7bd7f6acb321d7d7), CONST64(0x2fc25eed999cc2c2), 
+CONST64(0xb82e6d965c432e2e), CONST64(0x314b627a96294b4b), CONST64(0xdffea321e15dfefe), CONST64(0x41578216aed55757), 
+CONST64(0x5415a8412abd1515), CONST64(0xc1779fb6eee87777), CONST64(0xdc37a5eb6e923737), CONST64(0xb3e57b56d79ee5e5), 
+CONST64(0x469f8cd923139f9f), CONST64(0xe7f0d317fd23f0f0), CONST64(0x354a6a7f94204a4a), CONST64(0x4fda9e95a944dada), 
+CONST64(0x7d58fa25b0a25858), CONST64(0x03c906ca8fcfc9c9), CONST64(0xa429558d527c2929), CONST64(0x280a5022145a0a0a), 
+CONST64(0xfeb1e14f7f50b1b1), CONST64(0xbaa0691a5dc9a0a0), CONST64(0xb16b7fdad6146b6b), CONST64(0x2e855cab17d98585), 
+CONST64(0xcebd8173673cbdbd), CONST64(0x695dd234ba8f5d5d), CONST64(0x4010805020901010), CONST64(0xf7f4f303f507f4f4), 
+CONST64(0x0bcb16c08bddcbcb), CONST64(0xf83eedc67cd33e3e), CONST64(0x140528110a2d0505), CONST64(0x81671fe6ce786767), 
+CONST64(0xb7e47353d597e4e4), CONST64(0x9c2725bb4e022727), CONST64(0x1941325882734141), CONST64(0x168b2c9d0ba78b8b), 
+CONST64(0xa6a7510153f6a7a7), CONST64(0xe97dcf94fab27d7d), CONST64(0x6e95dcfb37499595), CONST64(0x47d88e9fad56d8d8), 
+CONST64(0xcbfb8b30eb70fbfb), CONST64(0x9fee2371c1cdeeee), CONST64(0xed7cc791f8bb7c7c), CONST64(0x856617e3cc716666), 
+CONST64(0x53dda68ea77bdddd), CONST64(0x5c17b84b2eaf1717), CONST64(0x014702468e454747), CONST64(0x429e84dc211a9e9e), 
+CONST64(0x0fca1ec589d4caca), CONST64(0xb42d75995a582d2d), CONST64(0xc6bf9179632ebfbf), CONST64(0x1c07381b0e3f0707), 
+CONST64(0x8ead012347acadad), CONST64(0x755aea2fb4b05a5a), CONST64(0x36836cb51bef8383), CONST64(0xcc3385ff66b63333), 
+CONST64(0x91633ff2c65c6363), CONST64(0x0802100a04120202), CONST64(0x92aa39384993aaaa), CONST64(0xd971afa8e2de7171), 
+CONST64(0x07c80ecf8dc6c8c8), CONST64(0x6419c87d32d11919), CONST64(0x39497270923b4949), CONST64(0x43d9869aaf5fd9d9), 
+CONST64(0xeff2c31df931f2f2), CONST64(0xabe34b48dba8e3e3), CONST64(0x715be22ab6b95b5b), CONST64(0x1a8834920dbc8888), 
+CONST64(0x529aa4c8293e9a9a), CONST64(0x98262dbe4c0b2626), CONST64(0xc8328dfa64bf3232), CONST64(0xfab0e94a7d59b0b0), 
+CONST64(0x83e91b6acff2e9e9), CONST64(0x3c0f78331e770f0f), CONST64(0x73d5e6a6b733d5d5), CONST64(0x3a8074ba1df48080), 
+CONST64(0xc2be997c6127bebe), CONST64(0x13cd26de87ebcdcd), CONST64(0xd034bde468893434), CONST64(0x3d487a7590324848), 
+CONST64(0xdbffab24e354ffff), CONST64(0xf57af78ff48d7a7a), CONST64(0x7a90f4ea3d649090), CONST64(0x615fc23ebe9d5f5f), 
+CONST64(0x80201da0403d2020), CONST64(0xbd6867d5d00f6868), CONST64(0x681ad07234ca1a1a), CONST64(0x82ae192c41b7aeae), 
+CONST64(0xeab4c95e757db4b4), CONST64(0x4d549a19a8ce5454), CONST64(0x7693ece53b7f9393), CONST64(0x88220daa442f2222), 
+CONST64(0x8d6407e9c8636464), CONST64(0xe3f1db12ff2af1f1), CONST64(0xd173bfa2e6cc7373), CONST64(0x4812905a24821212), 
+CONST64(0x1d403a5d807a4040), CONST64(0x2008402810480808), CONST64(0x2bc356e89b95c3c3), CONST64(0x97ec337bc5dfecec), 
+CONST64(0x4bdb9690ab4ddbdb), CONST64(0xbea1611f5fc0a1a1), CONST64(0x0e8d1c8307918d8d), CONST64(0xf43df5c97ac83d3d), 
+CONST64(0x6697ccf1335b9797), CONST64(0x0000000000000000), CONST64(0x1bcf36d483f9cfcf), CONST64(0xac2b4587566e2b2b), 
+CONST64(0xc57697b3ece17676), CONST64(0x328264b019e68282), CONST64(0x7fd6fea9b128d6d6), CONST64(0x6c1bd87736c31b1b), 
+CONST64(0xeeb5c15b7774b5b5), CONST64(0x86af112943beafaf), CONST64(0xb56a77dfd41d6a6a), CONST64(0x5d50ba0da0ea5050), 
+CONST64(0x0945124c8a574545), CONST64(0xebf3cb18fb38f3f3), CONST64(0xc0309df060ad3030), CONST64(0x9bef2b74c3c4efef), 
+CONST64(0xfc3fe5c37eda3f3f), CONST64(0x4955921caac75555), CONST64(0xb2a2791059dba2a2), CONST64(0x8fea0365c9e9eaea), 
+CONST64(0x89650fecca6a6565), CONST64(0xd2bab9686903baba), CONST64(0xbc2f65935e4a2f2f), CONST64(0x27c04ee79d8ec0c0), 
+CONST64(0x5fdebe81a160dede), CONST64(0x701ce06c38fc1c1c), CONST64(0xd3fdbb2ee746fdfd), CONST64(0x294d52649a1f4d4d), 
+CONST64(0x7292e4e039769292), CONST64(0xc9758fbceafa7575), CONST64(0x1806301e0c360606), CONST64(0x128a249809ae8a8a), 
+CONST64(0xf2b2f940794bb2b2), CONST64(0xbfe66359d185e6e6), CONST64(0x380e70361c7e0e0e), CONST64(0x7c1ff8633ee71f1f), 
+CONST64(0x956237f7c4556262), CONST64(0x77d4eea3b53ad4d4), CONST64(0x9aa829324d81a8a8), CONST64(0x6296c4f431529696), 
+CONST64(0xc3f99b3aef62f9f9), CONST64(0x33c566f697a3c5c5), CONST64(0x942535b14a102525), CONST64(0x7959f220b2ab5959), 
+CONST64(0x2a8454ae15d08484), CONST64(0xd572b7a7e4c57272), CONST64(0xe439d5dd72ec3939), CONST64(0x2d4c5a6198164c4c), 
+CONST64(0x655eca3bbc945e5e), CONST64(0xfd78e785f09f7878), CONST64(0xe038ddd870e53838), CONST64(0x0a8c148605988c8c), 
+CONST64(0x63d1c6b2bf17d1d1), CONST64(0xaea5410b57e4a5a5), CONST64(0xafe2434dd9a1e2e2), CONST64(0x99612ff8c24e6161), 
+CONST64(0xf6b3f1457b42b3b3), CONST64(0x842115a542342121), CONST64(0x4a9c94d625089c9c), CONST64(0x781ef0663cee1e1e), 
+CONST64(0x1143225286614343), CONST64(0x3bc776fc93b1c7c7), CONST64(0xd7fcb32be54ffcfc), CONST64(0x1004201408240404), 
+CONST64(0x5951b208a2e35151), CONST64(0x5e99bcc72f259999), CONST64(0xa96d4fc4da226d6d), CONST64(0x340d68391a650d0d), 
+CONST64(0xcffa8335e979fafa), CONST64(0x5bdfb684a369dfdf), CONST64(0xe57ed79bfca97e7e), CONST64(0x90243db448192424), 
+CONST64(0xec3bc5d776fe3b3b), CONST64(0x96ab313d4b9aabab), CONST64(0x1fce3ed181f0cece), CONST64(0x4411885522991111), 
+CONST64(0x068f0c8903838f8f), CONST64(0x254e4a6b9c044e4e), CONST64(0xe6b7d1517366b7b7), CONST64(0x8beb0b60cbe0ebeb), 
+CONST64(0xf03cfdcc78c13c3c), CONST64(0x3e817cbf1ffd8181), CONST64(0x6a94d4fe35409494), CONST64(0xfbf7eb0cf31cf7f7), 
+CONST64(0xdeb9a1676f18b9b9), CONST64(0x4c13985f268b1313), CONST64(0xb02c7d9c58512c2c), CONST64(0x6bd3d6b8bb05d3d3), 
+CONST64(0xbbe76b5cd38ce7e7), CONST64(0xa56e57cbdc396e6e), CONST64(0x37c46ef395aac4c4), CONST64(0x0c03180f061b0303), 
+CONST64(0x45568a13acdc5656), CONST64(0x0d441a49885e4444), CONST64(0xe17fdf9efea07f7f), CONST64(0x9ea921374f88a9a9), 
+CONST64(0xa82a4d8254672a2a), CONST64(0xd6bbb16d6b0abbbb), CONST64(0x23c146e29f87c1c1), CONST64(0x5153a202a6f15353), 
+CONST64(0x57dcae8ba572dcdc), CONST64(0x2c0b582716530b0b), CONST64(0x4e9d9cd327019d9d), CONST64(0xad6c47c1d82b6c6c), 
+CONST64(0xc43195f562a43131), CONST64(0xcd7487b9e8f37474), CONST64(0xfff6e309f115f6f6), CONST64(0x05460a438c4c4646), 
+CONST64(0x8aac092645a5acac), CONST64(0x1e893c970fb58989), CONST64(0x5014a04428b41414), CONST64(0xa3e15b42dfbae1e1), 
+CONST64(0x5816b04e2ca61616), CONST64(0xe83acdd274f73a3a), CONST64(0xb9696fd0d2066969), CONST64(0x2409482d12410909), 
+CONST64(0xdd70a7ade0d77070), CONST64(0xe2b6d954716fb6b6), CONST64(0x67d0ceb7bd1ed0d0), CONST64(0x93ed3b7ec7d6eded), 
+CONST64(0x17cc2edb85e2cccc), CONST64(0x15422a5784684242), CONST64(0x5a98b4c22d2c9898), CONST64(0xaaa4490e55eda4a4), 
+CONST64(0xa0285d8850752828), CONST64(0x6d5cda31b8865c5c), CONST64(0xc7f8933fed6bf8f8), CONST64(0x228644a411c28686)
+};
+
+static const ulong64 sbox7[] = {
+CONST64(0x186018c07830d818), CONST64(0x238c2305af462623), CONST64(0xc63fc67ef991b8c6), CONST64(0xe887e8136fcdfbe8), 
+CONST64(0x8726874ca113cb87), CONST64(0xb8dab8a9626d11b8), CONST64(0x0104010805020901), CONST64(0x4f214f426e9e0d4f), 
+CONST64(0x36d836adee6c9b36), CONST64(0xa6a2a6590451ffa6), CONST64(0xd26fd2debdb90cd2), CONST64(0xf5f3f5fb06f70ef5), 
+CONST64(0x79f979ef80f29679), CONST64(0x6fa16f5fcede306f), CONST64(0x917e91fcef3f6d91), CONST64(0x525552aa07a4f852), 
+CONST64(0x609d6027fdc04760), CONST64(0xbccabc89766535bc), CONST64(0x9b569baccd2b379b), CONST64(0x8e028e048c018a8e), 
+CONST64(0xa3b6a371155bd2a3), CONST64(0x0c300c603c186c0c), CONST64(0x7bf17bff8af6847b), CONST64(0x35d435b5e16a8035), 
+CONST64(0x1d741de8693af51d), CONST64(0xe0a7e05347ddb3e0), CONST64(0xd77bd7f6acb321d7), CONST64(0xc22fc25eed999cc2), 
+CONST64(0x2eb82e6d965c432e), CONST64(0x4b314b627a96294b), CONST64(0xfedffea321e15dfe), CONST64(0x5741578216aed557), 
+CONST64(0x155415a8412abd15), CONST64(0x77c1779fb6eee877), CONST64(0x37dc37a5eb6e9237), CONST64(0xe5b3e57b56d79ee5), 
+CONST64(0x9f469f8cd923139f), CONST64(0xf0e7f0d317fd23f0), CONST64(0x4a354a6a7f94204a), CONST64(0xda4fda9e95a944da), 
+CONST64(0x587d58fa25b0a258), CONST64(0xc903c906ca8fcfc9), CONST64(0x29a429558d527c29), CONST64(0x0a280a5022145a0a), 
+CONST64(0xb1feb1e14f7f50b1), CONST64(0xa0baa0691a5dc9a0), CONST64(0x6bb16b7fdad6146b), CONST64(0x852e855cab17d985), 
+CONST64(0xbdcebd8173673cbd), CONST64(0x5d695dd234ba8f5d), CONST64(0x1040108050209010), CONST64(0xf4f7f4f303f507f4), 
+CONST64(0xcb0bcb16c08bddcb), CONST64(0x3ef83eedc67cd33e), CONST64(0x05140528110a2d05), CONST64(0x6781671fe6ce7867), 
+CONST64(0xe4b7e47353d597e4), CONST64(0x279c2725bb4e0227), CONST64(0x4119413258827341), CONST64(0x8b168b2c9d0ba78b), 
+CONST64(0xa7a6a7510153f6a7), CONST64(0x7de97dcf94fab27d), CONST64(0x956e95dcfb374995), CONST64(0xd847d88e9fad56d8), 
+CONST64(0xfbcbfb8b30eb70fb), CONST64(0xee9fee2371c1cdee), CONST64(0x7ced7cc791f8bb7c), CONST64(0x66856617e3cc7166), 
+CONST64(0xdd53dda68ea77bdd), CONST64(0x175c17b84b2eaf17), CONST64(0x47014702468e4547), CONST64(0x9e429e84dc211a9e), 
+CONST64(0xca0fca1ec589d4ca), CONST64(0x2db42d75995a582d), CONST64(0xbfc6bf9179632ebf), CONST64(0x071c07381b0e3f07), 
+CONST64(0xad8ead012347acad), CONST64(0x5a755aea2fb4b05a), CONST64(0x8336836cb51bef83), CONST64(0x33cc3385ff66b633), 
+CONST64(0x6391633ff2c65c63), CONST64(0x020802100a041202), CONST64(0xaa92aa39384993aa), CONST64(0x71d971afa8e2de71), 
+CONST64(0xc807c80ecf8dc6c8), CONST64(0x196419c87d32d119), CONST64(0x4939497270923b49), CONST64(0xd943d9869aaf5fd9), 
+CONST64(0xf2eff2c31df931f2), CONST64(0xe3abe34b48dba8e3), CONST64(0x5b715be22ab6b95b), CONST64(0x881a8834920dbc88), 
+CONST64(0x9a529aa4c8293e9a), CONST64(0x2698262dbe4c0b26), CONST64(0x32c8328dfa64bf32), CONST64(0xb0fab0e94a7d59b0), 
+CONST64(0xe983e91b6acff2e9), CONST64(0x0f3c0f78331e770f), CONST64(0xd573d5e6a6b733d5), CONST64(0x803a8074ba1df480), 
+CONST64(0xbec2be997c6127be), CONST64(0xcd13cd26de87ebcd), CONST64(0x34d034bde4688934), CONST64(0x483d487a75903248), 
+CONST64(0xffdbffab24e354ff), CONST64(0x7af57af78ff48d7a), CONST64(0x907a90f4ea3d6490), CONST64(0x5f615fc23ebe9d5f), 
+CONST64(0x2080201da0403d20), CONST64(0x68bd6867d5d00f68), CONST64(0x1a681ad07234ca1a), CONST64(0xae82ae192c41b7ae), 
+CONST64(0xb4eab4c95e757db4), CONST64(0x544d549a19a8ce54), CONST64(0x937693ece53b7f93), CONST64(0x2288220daa442f22), 
+CONST64(0x648d6407e9c86364), CONST64(0xf1e3f1db12ff2af1), CONST64(0x73d173bfa2e6cc73), CONST64(0x124812905a248212), 
+CONST64(0x401d403a5d807a40), CONST64(0x0820084028104808), CONST64(0xc32bc356e89b95c3), CONST64(0xec97ec337bc5dfec), 
+CONST64(0xdb4bdb9690ab4ddb), CONST64(0xa1bea1611f5fc0a1), CONST64(0x8d0e8d1c8307918d), CONST64(0x3df43df5c97ac83d), 
+CONST64(0x976697ccf1335b97), CONST64(0x0000000000000000), CONST64(0xcf1bcf36d483f9cf), CONST64(0x2bac2b4587566e2b), 
+CONST64(0x76c57697b3ece176), CONST64(0x82328264b019e682), CONST64(0xd67fd6fea9b128d6), CONST64(0x1b6c1bd87736c31b), 
+CONST64(0xb5eeb5c15b7774b5), CONST64(0xaf86af112943beaf), CONST64(0x6ab56a77dfd41d6a), CONST64(0x505d50ba0da0ea50), 
+CONST64(0x450945124c8a5745), CONST64(0xf3ebf3cb18fb38f3), CONST64(0x30c0309df060ad30), CONST64(0xef9bef2b74c3c4ef), 
+CONST64(0x3ffc3fe5c37eda3f), CONST64(0x554955921caac755), CONST64(0xa2b2a2791059dba2), CONST64(0xea8fea0365c9e9ea), 
+CONST64(0x6589650fecca6a65), CONST64(0xbad2bab9686903ba), CONST64(0x2fbc2f65935e4a2f), CONST64(0xc027c04ee79d8ec0), 
+CONST64(0xde5fdebe81a160de), CONST64(0x1c701ce06c38fc1c), CONST64(0xfdd3fdbb2ee746fd), CONST64(0x4d294d52649a1f4d), 
+CONST64(0x927292e4e0397692), CONST64(0x75c9758fbceafa75), CONST64(0x061806301e0c3606), CONST64(0x8a128a249809ae8a), 
+CONST64(0xb2f2b2f940794bb2), CONST64(0xe6bfe66359d185e6), CONST64(0x0e380e70361c7e0e), CONST64(0x1f7c1ff8633ee71f), 
+CONST64(0x62956237f7c45562), CONST64(0xd477d4eea3b53ad4), CONST64(0xa89aa829324d81a8), CONST64(0x966296c4f4315296), 
+CONST64(0xf9c3f99b3aef62f9), CONST64(0xc533c566f697a3c5), CONST64(0x25942535b14a1025), CONST64(0x597959f220b2ab59), 
+CONST64(0x842a8454ae15d084), CONST64(0x72d572b7a7e4c572), CONST64(0x39e439d5dd72ec39), CONST64(0x4c2d4c5a6198164c), 
+CONST64(0x5e655eca3bbc945e), CONST64(0x78fd78e785f09f78), CONST64(0x38e038ddd870e538), CONST64(0x8c0a8c148605988c), 
+CONST64(0xd163d1c6b2bf17d1), CONST64(0xa5aea5410b57e4a5), CONST64(0xe2afe2434dd9a1e2), CONST64(0x6199612ff8c24e61), 
+CONST64(0xb3f6b3f1457b42b3), CONST64(0x21842115a5423421), CONST64(0x9c4a9c94d625089c), CONST64(0x1e781ef0663cee1e), 
+CONST64(0x4311432252866143), CONST64(0xc73bc776fc93b1c7), CONST64(0xfcd7fcb32be54ffc), CONST64(0x0410042014082404), 
+CONST64(0x515951b208a2e351), CONST64(0x995e99bcc72f2599), CONST64(0x6da96d4fc4da226d), CONST64(0x0d340d68391a650d), 
+CONST64(0xfacffa8335e979fa), CONST64(0xdf5bdfb684a369df), CONST64(0x7ee57ed79bfca97e), CONST64(0x2490243db4481924), 
+CONST64(0x3bec3bc5d776fe3b), CONST64(0xab96ab313d4b9aab), CONST64(0xce1fce3ed181f0ce), CONST64(0x1144118855229911), 
+CONST64(0x8f068f0c8903838f), CONST64(0x4e254e4a6b9c044e), CONST64(0xb7e6b7d1517366b7), CONST64(0xeb8beb0b60cbe0eb), 
+CONST64(0x3cf03cfdcc78c13c), CONST64(0x813e817cbf1ffd81), CONST64(0x946a94d4fe354094), CONST64(0xf7fbf7eb0cf31cf7), 
+CONST64(0xb9deb9a1676f18b9), CONST64(0x134c13985f268b13), CONST64(0x2cb02c7d9c58512c), CONST64(0xd36bd3d6b8bb05d3), 
+CONST64(0xe7bbe76b5cd38ce7), CONST64(0x6ea56e57cbdc396e), CONST64(0xc437c46ef395aac4), CONST64(0x030c03180f061b03), 
+CONST64(0x5645568a13acdc56), CONST64(0x440d441a49885e44), CONST64(0x7fe17fdf9efea07f), CONST64(0xa99ea921374f88a9), 
+CONST64(0x2aa82a4d8254672a), CONST64(0xbbd6bbb16d6b0abb), CONST64(0xc123c146e29f87c1), CONST64(0x535153a202a6f153), 
+CONST64(0xdc57dcae8ba572dc), CONST64(0x0b2c0b582716530b), CONST64(0x9d4e9d9cd327019d), CONST64(0x6cad6c47c1d82b6c), 
+CONST64(0x31c43195f562a431), CONST64(0x74cd7487b9e8f374), CONST64(0xf6fff6e309f115f6), CONST64(0x4605460a438c4c46), 
+CONST64(0xac8aac092645a5ac), CONST64(0x891e893c970fb589), CONST64(0x145014a04428b414), CONST64(0xe1a3e15b42dfbae1), 
+CONST64(0x165816b04e2ca616), CONST64(0x3ae83acdd274f73a), CONST64(0x69b9696fd0d20669), CONST64(0x092409482d124109), 
+CONST64(0x70dd70a7ade0d770), CONST64(0xb6e2b6d954716fb6), CONST64(0xd067d0ceb7bd1ed0), CONST64(0xed93ed3b7ec7d6ed), 
+CONST64(0xcc17cc2edb85e2cc), CONST64(0x4215422a57846842), CONST64(0x985a98b4c22d2c98), CONST64(0xa4aaa4490e55eda4), 
+CONST64(0x28a0285d88507528), CONST64(0x5c6d5cda31b8865c), CONST64(0xf8c7f8933fed6bf8), CONST64(0x86228644a411c286)
+};
+
+static const ulong64 cont[] = {
+CONST64(0x1823c6e887b8014f),
+CONST64(0x36a6d2f5796f9152),
+CONST64(0x60bc9b8ea30c7b35),
+CONST64(0x1de0d7c22e4bfe57),
+CONST64(0x157737e59ff04ada),
+CONST64(0x58c9290ab1a06b85),
+CONST64(0xbd5d10f4cb3e0567),
+CONST64(0xe427418ba77d95d8),
+CONST64(0xfbee7c66dd17479e),
+CONST64(0xca2dbf07ad5a8333),
+CONST64(0x6302aa71c81949d9),
+};
+