Browse Source

added libtomcrypt-0.94

Tom St Denis 21 years ago
parent
commit
1f8b8bda6f
50 changed files with 3480 additions and 1490 deletions
  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. BIN
      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 long i, len2, leven;
    unsigned char *p;
    unsigned char *p;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
 
 
    /* valid output size ? */
    /* valid output size ? */
@@ -58,21 +58,20 @@ int base64_encode(const unsigned char *in,  unsigned long len,
    p = out;
    p = out;
    leven = 3*(len / 3);
    leven = 3*(len / 3);
    for (i = 0; i < leven; i += 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;
        in += 3;
    }
    }
    /* Pad it if necessary...  */
    /* Pad it if necessary...  */
    if (i < len) {
    if (i < len) {
        unsigned a = in[0];
        unsigned a = in[0];
        unsigned b = (i+1 < len) ? in[1] : 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++ = '=';
        *p++ = '=';
    }
    }
 
 
@@ -89,19 +88,22 @@ int base64_decode(const unsigned char *in,  unsigned long len,
 {
 {
    unsigned long t, x, y, z;
    unsigned long t, x, y, z;
    unsigned char c;
    unsigned char c;
-   int	g = 3;
+   int           g;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
 
 
+   g = 3;
    for (x = y = z = t = 0; x < len; x++) {
    for (x = y = z = t = 0; x < len; x++) {
-       c = map[in[x]];
+       c = map[in[x]&0xFF];
        if (c == 255) continue;
        if (c == 255) continue;
        if (c == 254) { c = 0; g--; }
        if (c == 254) { c = 0; g--; }
        t = (t<<6)|c;
        t = (t<<6)|c;
        if (++y == 4) {
        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);
           out[z++] = (unsigned char)((t>>16)&255);
           if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
           if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
           if (g > 2) out[z++] = (unsigned char)(t&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
 Jan 25th, 2004
 v0.93  -- [note: deleted v0.93 changes by accident... recreating from memory...]
 v0.93  -- [note: deleted v0.93 changes by accident... recreating from memory...]
        -- Fix to RC2 to not deference pointer before ARGCHK
        -- Fix to RC2 to not deference pointer before ARGCHK

+ 4 - 2
config.pl

@@ -31,7 +31,7 @@
    "RC5,Include RC5 block cipher,y",
    "RC5,Include RC5 block cipher,y",
    "RC6,Include RC6 block cipher,y",
    "RC6,Include RC6 block cipher,y",
    "SAFERP,Include Safer+ 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",
    "RIJNDAEL,Include Rijndael (AES) block cipher,y",
    "XTEA,Include XTEA block cipher,y",
    "XTEA,Include XTEA block cipher,y",
    "TWOFISH,Include Twofish block cipher (default: fast),y",
    "TWOFISH,Include Twofish block cipher (default: fast),y",
@@ -49,6 +49,7 @@
    "CBC,Include CBC block mode of operation,y",
    "CBC,Include CBC block mode of operation,y",
    "CTR,Include CTR 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",
    "SHA512,Include SHA512 one-way hash,y",
    "SHA384,Include SHA384 one-way hash (requires SHA512),y",
    "SHA384,Include SHA384 one-way hash (requires SHA512),y",
    "SHA256,Include SHA256 one-way hash,y",
    "SHA256,Include SHA256 one-way hash,y",
@@ -62,6 +63,7 @@
    "RIPEMD160,Include RIPEMD-160 one-way hash,y",
    "RIPEMD160,Include RIPEMD-160 one-way hash,y",
    "HMAC,Include Hash based Message Authentication Support,y",
    "HMAC,Include Hash based Message Authentication Support,y",
    "OMAC,Include OMAC1 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",
    "EAX_MODE,Include EAX Encrypt-and-Authenticate Support,y",
    "OCB_MODE,Include OCB Encrypt-and-Authenticate Support,y",
    "OCB_MODE,Include OCB Encrypt-and-Authenticate Support,y",
 
 
@@ -153,7 +155,7 @@ for (@settings) {
 
 
 # output objects
 # output objects
 print OUT "\ndefault: library\n\n";
 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
 # 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";
 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)
 #if defined(OMAC)
     " OMAC "
     " OMAC "
 #endif
 #endif
+#if defined(PMAC)
+    " PMAC "
+#endif
 #if defined(EAX_MODE)
 #if defined(EAX_MODE)
     " EAX_MODE "
     " EAX_MODE "
 #endif
 #endif

+ 50 - 48
crypt.out

@@ -31,56 +31,58 @@
 \BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
 \BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
 \BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}
 \BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}
 \BOOKMARK [2][-]{subsection.4.2.1}{Notice}{section.4.2}
 \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.1}{Background}{chapter.7}
 \BOOKMARK [1][-]{section.7.2}{Core Functions}{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.1}{Background}{chapter.8}
 \BOOKMARK [1][-]{section.8.2}{Core Functions}{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.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}

BIN
crypt.pdf


+ 142 - 52
crypt.tex

@@ -47,9 +47,8 @@
 \def\gap{\vspace{0.5ex}}
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \makeindex
 \begin{document}
 \begin{document}
-\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.93}
+\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.94}
 \author{Tom St Denis \\
 \author{Tom St Denis \\
-Algonquin College \\
 \\
 \\
 [email protected] \\
 [email protected] \\
 http://libtomcrypt.org \\ \\
 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, 
 int ocb_done_decrypt(ocb_state *ocb, 
                      const unsigned char *ct,  unsigned long ctlen,
                      const unsigned char *ct,  unsigned long ctlen,
                            unsigned char *pt, 
                            unsigned char *pt, 
-                     const unsigned char *tag, unsigned long taglen, int *res);
+                     const unsigned char *tag, unsigned long taglen, 
+                           int *res);
 \end{verbatim}
 \end{verbatim}
 
 
 Similarly to the previous function you can pass trailing message bytes into this function.  This will compute the 
 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{center}
 \begin{tabular}{|c|c|c|}
 \begin{tabular}{|c|c|c|}
       \hline Name & Descriptor Name & Size of Message Digest (bytes) \\
       \hline Name & Descriptor Name & Size of Message Digest (bytes) \\
+      \hline WHIRLPOOL & whirlpool\_desc & 64 \\
       \hline SHA-512 & sha512\_desc & 64 \\
       \hline SHA-512 & sha512\_desc & 64 \\
       \hline SHA-384 & sha384\_desc & 48 \\
       \hline SHA-384 & sha384\_desc & 48 \\
       \hline SHA-256 & sha256\_desc & 32 \\
       \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
 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.
 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
 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
 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
 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);
                  const unsigned char *buf, unsigned long len);
 \end{verbatim}
 \end{verbatim}
 This will send ``len'' bytes from ``buf'' through the active OMAC state ``state''.  Returns \textbf{CRYPT\_OK} if the 
 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}
 \begin{verbatim}
 int omac_done(omac_state *state, 
 int omac_done(omac_state *state, 
@@ -1353,7 +1368,7 @@ OMAC system is given below.
 #include <mycrypt.h>
 #include <mycrypt.h>
 int main(void)
 int main(void)
 {
 {
-   int idx, errno;
+   int idx, err;
    omac_state omac;
    omac_state omac;
    unsigned char key[16], dst[MAXBLOCKSIZE];
    unsigned char key[16], dst[MAXBLOCKSIZE];
    unsigned long dstlen;
    unsigned long dstlen;
@@ -1370,21 +1385,21 @@ int main(void)
    /* we would make up our symmetric key in "key[]" here */
    /* we would make up our symmetric key in "key[]" here */
 
 
    /* start the OMAC */
    /* 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;
       return -1;
    }
    }
 
 
    /* process a few octets */
    /* 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;
       return -1;
    }
    }
 
 
    /* get result (presumably to use it somehow...) */
    /* get result (presumably to use it somehow...) */
    dstlen = sizeof(dst);
    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;
       return -1;
    }
    }
    printf("The omac is %lu bytes long\n", dstlen);
    printf("The omac is %lu bytes long\n", dstlen);
@@ -1395,6 +1410,81 @@ int main(void)
 \end{verbatim}
 \end{verbatim}
 \end{small}
 \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}
 \chapter{Pseudo-Random Number Generators}
 \section{Core Functions}
 \section{Core Functions}
 
 
@@ -1445,19 +1535,19 @@ int main(void)
 {
 {
    prng_state prng;
    prng_state prng;
    unsigned char buf[10];
    unsigned char buf[10];
-   int errno;
+   int err;
    
    
    /* start it */
    /* 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 */
    /* 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 */
    /* 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));
    printf("Read %lu bytes from yarrow\n", yarrow_read(buf, 10, &prng));
    return 0;
    return 0;
@@ -1504,22 +1594,22 @@ int main(void)
 {
 {
    prng_state prng;
    prng_state prng;
    unsigned char buf[32];
    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);
       exit(-1);
    }
    }
 
 
    /* use ``key'' as the key */
    /* 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);
       exit(-1);
    }
    }
 
 
    /* setup RC4 for use */
    /* 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);
       exit(-1);
    }
    }
 
 
@@ -1572,7 +1662,7 @@ int main(void)
 {
 {
    ecc_key mykey;
    ecc_key mykey;
    prng_state prng;
    prng_state prng;
-   int errno;
+   int err;
 
 
    /* register yarrow */
    /* register yarrow */
    if (register_prng(&yarrow_desc) == -1) {
    if (register_prng(&yarrow_desc) == -1) {
@@ -1581,14 +1671,14 @@ int main(void)
    }
    }
 
 
    /* setup the PRNG */
    /* 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;
       return -1;
    }
    }
 
 
    /* make a 192-bit ECC key */
    /* 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 -1;
    }
    }
    return 0;
    return 0;
@@ -1608,7 +1698,7 @@ the previous example using this PRNG.
 int main(void)
 int main(void)
 {
 {
    ecc_key mykey;
    ecc_key mykey;
-   int errno;
+   int err;
 
 
    /* register SPRNG */
    /* register SPRNG */
    if (register_prng(&sprng_desc) == -1) {
    if (register_prng(&sprng_desc) == -1) {
@@ -1617,8 +1707,8 @@ int main(void)
    }
    }
 
 
    /* make a 192-bit ECC key */
    /* 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 -1;
    }
    }
    return 0;
    return 0;
@@ -1873,18 +1963,18 @@ int establish_secure_socket(int sock, int mode, unsigned char *key,
 {
 {
    unsigned char buf[4096], buf2[4096];
    unsigned char buf[4096], buf2[4096];
    unsigned long x, len;
    unsigned long x, len;
-   int res, errno, inlen;
+   int res, err, inlen;
    dh_key mykey, theirkey;
    dh_key mykey, theirkey;
 
 
    /* make up our private key */
    /* 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 */ 
    /* export our key as public */ 
    x = sizeof(buf);
    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;
       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;
       goto done2;
    }
    }
 
 
    /* make shared secret */
    /* make shared secret */
    x = sizeof(buf);
    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;
       goto done;
    }
    }
  
  
    /* hash it */
    /* hash it */
    len = 16;        /* default is MD5 so "key" must be at least 16 bytes long */
    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;
       goto done;
    }
    }
 
 
@@ -2382,26 +2472,26 @@ int main(void)
    pk_key *kr;
    pk_key *kr;
    unsigned char buf[4096], buf2[4096];
    unsigned char buf[4096], buf2[4096];
    unsigned long len;
    unsigned long len;
-   int errno;
+   int err;
 
 
    /* make a new list */
    /* 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);
       exit(-1);
    }
    }
 
 
    /* add a key to it */
    /* add a key to it */
    register_prng(&sprng_desc);
    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) {
                 "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);
       exit(-1);
    }
    }
 
 
    /* export the first key */
    /* export the first key */
    len = sizeof(buf);
    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);
       exit(-1);
    }
    }
 
 

+ 37 - 11
demos/hashsum.c

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

+ 79 - 0
demos/tv_gen.c

@@ -79,6 +79,9 @@ void reg_algs(void)
 #ifdef RIPEMD160
 #ifdef RIPEMD160
   register_hash (&rmd160_desc);
   register_hash (&rmd160_desc);
 #endif
 #endif
+#ifdef WHIRLPOOL
+  register_hash (&whirlpool_desc);
+#endif
 }
 }
 
 
 void hash_gen(void)
 void hash_gen(void)
@@ -269,6 +272,61 @@ void omac_gen(void)
    fclose(out);
    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)
 void eax_gen(void)
 {
 {
    int err, kl, x, y1, z;
    int err, kl, x, y1, z;
@@ -392,6 +450,25 @@ void ocb_gen(void)
    fclose(out);
    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)
 int main(void)
 {
 {
    reg_algs();
    reg_algs();
@@ -399,8 +476,10 @@ int main(void)
    printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n");
    printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n");
    printf("Generating HMAC   vectors..."); fflush(stdout); hmac_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 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 EAX    vectors..."); fflush(stdout); eax_gen(); printf("done\n");
    printf("Generating OCB    vectors..."); fflush(stdout); ocb_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;
    return 0;
 }
 }
 
 

+ 5 - 2
demos/x86_prof.c

@@ -52,9 +52,9 @@ void tally_results(int type)
 static ulong64 rdtsc (void)
 static ulong64 rdtsc (void)
    {
    {
    #if defined __GNUC__
    #if defined __GNUC__
-      #ifdef i386
+      #ifdef __i386__
          ulong64 a;
          ulong64 a;
-         asm volatile("rdtsc ":"=A" (a));
+         __asm__ __volatile__ ("rdtsc ":"=A" (a));
          return a;
          return a;
       #else /* gcc-IA64 version */
       #else /* gcc-IA64 version */
          unsigned long result;
          unsigned long result;
@@ -190,6 +190,9 @@ void reg_algs(void)
 #ifdef RIPEMD160
 #ifdef RIPEMD160
   register_hash (&rmd160_desc);
   register_hash (&rmd160_desc);
 #endif
 #endif
+#ifdef WHIRLPOOL
+  register_hash (&whirlpool_desc);
+#endif
 
 
 register_prng(&yarrow_desc);
 register_prng(&yarrow_desc);
 rng_make_prng(128, find_prng("yarrow"), &prng, NULL);
 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)
 int dh_test(void)
 {
 {
     mp_int p, g, tmp;
     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++) {
     for (x = 0; sets[x].size != 0; x++) {
 #if 0
 #if 0
         printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
         printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
 #endif
 #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 */
         /* 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) {
         if (primality == 0) {
-           res = CRYPT_FAIL_TESTVECTOR;
+           err = CRYPT_FAIL_TESTVECTOR;
            goto done;
            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 */
         /* 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) {
         if (primality == 0) {
-           res = CRYPT_FAIL_TESTVECTOR;
+           err = CRYPT_FAIL_TESTVECTOR;
            goto done;
            goto done;
         }
         }
 
 
         /* now see if g^((p-1)/2) mod p is in fact 1 */
         /* 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)) {
         if (mp_cmp_d(&tmp, 1)) {
-           res = CRYPT_FAIL_TESTVECTOR;
+           err = CRYPT_FAIL_TESTVECTOR;
            goto done;
            goto done;
         }
         }
     }
     }
-    res = CRYPT_OK;
+    err = CRYPT_OK;
     goto done;
     goto done;
 error:
 error:
-    res = mpi_to_ltc_error(res);
+    err = mpi_to_ltc_error(err);
 done:
 done:
     mp_clear_multi(&tmp, &g, &p, NULL);
     mp_clear_multi(&tmp, &g, &p, NULL);
-    return res;
+    return err;
 }
 }
 
 
 void dh_sizes(int *low, int *high)
 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 char buf[512];
    unsigned long x;
    unsigned long x;
    mp_int p, g;
    mp_int p, g;
-   int res, err;
+   int err;
 
 
    _ARGCHK(key  != NULL);
    _ARGCHK(key  != NULL);
 
 
@@ -257,30 +257,30 @@ int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
    }
    }
 
 
    /* init parameters */
    /* 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 */
    /* 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;
    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 */
    /* free up ram */
-   res = CRYPT_OK;
-   goto done2;
+   err = CRYPT_OK;
+   goto done;
 error:
 error:
-   res = mpi_to_ltc_error(res);
+   err = mpi_to_ltc_error(err);
    mp_clear_multi(&key->x, &key->y, NULL);
    mp_clear_multi(&key->x, &key->y, NULL);
-done2:
+done:
    mp_clear_multi(&p, &g, NULL);
    mp_clear_multi(&p, &g, NULL);
    zeromem(buf, sizeof(buf));
    zeromem(buf, sizeof(buf));
-   return res;
+   return err;
 }
 }
 
 
 void dh_free(dh_key *key)
 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)
 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
 {
 {
-   unsigned char buf2[1536];
    unsigned long y, z;
    unsigned long y, z;
    int err;
    int err;
 
 
@@ -299,6 +298,11 @@ int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(key != 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) {
    if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
       return CRYPT_PK_NOT_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;
    y = PACKET_SIZE;
 
 
    /* header */
    /* 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 */
    /* export y */
-   OUTPUT_BIGNUM(&key->y, buf2, y, z);
+   OUTPUT_BIGNUM(&key->y, out, y, z);
 
 
    if (type == PK_PRIVATE) {
    if (type == PK_PRIVATE) {
       /* export x */
       /* 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 */
    /* 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;
    *outlen = y;
-   memcpy(out, buf2, (size_t)y);
-
-   /* clear mem */
-#ifdef CLEAN_STACK
-   zeromem(buf2, sizeof(buf2));
-#endif
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
@@ -349,7 +339,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
    _ARGCHK(key != NULL);
    _ARGCHK(key != NULL);
 
 
    /* make sure valid length */
    /* make sure valid length */
-   if (2+PACKET_SIZE > inlen) {
+   if ((2+PACKET_SIZE) > inlen) {
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;
    }
    }
 
 
@@ -414,12 +404,12 @@ int dh_shared_secret(dh_key *private_key, dh_key *public_key,
 {
 {
    mp_int tmp, p;
    mp_int tmp, p;
    unsigned long x;
    unsigned long x;
-   int res;
+   int err;
 
 
    _ARGCHK(private_key != NULL);
    _ARGCHK(private_key != NULL);
    _ARGCHK(public_key  != NULL);
    _ARGCHK(public_key  != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(outlen != NULL);
+   _ARGCHK(out         != NULL);
+   _ARGCHK(outlen      != NULL);
 
 
    /* types valid? */
    /* types valid? */
    if (private_key->type != PK_PRIVATE) {
    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 */
    /* 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? */
    /* enough space for output? */
    x = (unsigned long)mp_unsigned_bin_size(&tmp);
    x = (unsigned long)mp_unsigned_bin_size(&tmp);
    if (*outlen < x) {
    if (*outlen < x) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done;
       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;
    *outlen = x;
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
    goto done;
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&p, &tmp, NULL);
    mp_clear_multi(&p, &tmp, NULL);
-   return res;
+   return err;
 }
 }
 
 
 #include "dh_sys.c"
 #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;
     int err;
 
 
     _ARGCHK(inkey != NULL);
     _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 */
     /* check that wprng/hash are not invalid */
     if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
     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;
        return err;
     }
     }
 
 
+    /* store header */
+    packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
+
     /* output header */
     /* output header */
     y = PACKET_SIZE;
     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++) {
     for (x = 0; x < keylen; x++, y++) {
       out[y] = skey[x] ^ inkey[x];
       out[y] = skey[x] ^ inkey[x];
     }
     }
-
-    /* store header */
-    packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
+    *len = y;
 
 
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
     /* clean up */
     /* clean up */
@@ -99,7 +100,6 @@ int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     zeromem(skey, sizeof(skey));
     zeromem(skey, sizeof(skey));
 #endif
 #endif
 
 
-    *len = y;
     return CRYPT_OK;
     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 char shared_secret[768], skey[MAXBLOCKSIZE];
    unsigned long x, y, z,hashsize, keysize;
    unsigned long x, y, z,hashsize, keysize;
-   int res, hash, err;
+   int  hash, err;
    dh_key pubkey;
    dh_key pubkey;
 
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in     != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(keylen != NULL);
    _ARGCHK(keylen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
 
    /* right key type? */
    /* right key type? */
    if (key->type != PK_PRIVATE) {
    if (key->type != PK_PRIVATE) {
@@ -184,7 +184,7 @@ int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
    }
    }
    
    
    if (keysize > *keylen) {
    if (keysize > *keylen) {
-       res = CRYPT_BUFFER_OVERFLOW;
+       err = CRYPT_BUFFER_OVERFLOW;
        goto done;
        goto done;
    }
    }
    y += 4;
    y += 4;
@@ -195,13 +195,13 @@ int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
       outkey[x] = skey[x] ^ in[y];
       outkey[x] = skey[x] ^ in[y];
    }
    }
 
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
 done:
 done:
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
    zeromem(shared_secret, sizeof(shared_secret));
    zeromem(shared_secret, sizeof(shared_secret));
    zeromem(skey, sizeof(skey));
    zeromem(skey, sizeof(skey));
 #endif
 #endif
-   return res;
+   return err;
 }
 }
 
 
 /* perform an ElGamal Signature of a hash 
 /* 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)
                        prng_state *prng, int wprng, dh_key *key)
 {
 {
    mp_int a, b, k, m, g, p, p1, tmp;
    mp_int a, b, k, m, g, p, p1, tmp;
-   unsigned char buf[1536];
+   unsigned char buf[520];
    unsigned long x, y;
    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(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
 
    /* check parameters */
    /* check parameters */
    if (key->type != PK_PRIVATE) {
    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_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_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 */
    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  */
    /* store header  */
    y = PACKET_SIZE;
    y = PACKET_SIZE;
 
 
    /* now store them both (a,b) */
    /* now store them both (a,b) */
    x = (unsigned long)mp_unsigned_bin_size(&a);
    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;
    y += x;
 
 
    x = (unsigned long)mp_unsigned_bin_size(&b);
    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;
    y += x;
 
 
    /* check if size too big */
    /* check if size too big */
    if (*outlen < y) {
    if (*outlen < y) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done;
       goto done;
    }
    }
 
 
    /* store header */
    /* 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;
    *outlen = y;
-#ifdef CLEAN_STACK
-   zeromem(buf, sizeof(buf));
-#endif
 
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
    goto done;
 error:
 error:
-   res = mpi_to_ltc_error(err);
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);
    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,
 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;
    mp_int a, b, p, g, m, tmp;
    unsigned long x, y;
    unsigned long x, y;
-   int res, err;
+   int err;
 
 
-   _ARGCHK(sig != NULL);
+   _ARGCHK(sig  != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(stat != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
 
    /* default to invalid */
    /* default to invalid */
    *stat = 0;
    *stat = 0;
@@ -371,7 +371,7 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
    }
    }
    
    
    y += 4;
    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;
    y += x;
 
 
    LOAD32L(x, sig+y);
    LOAD32L(x, sig+y);
@@ -381,23 +381,23 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
       siglen -= x;
       siglen -= x;
    }
    }
    y += 4;
    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;
    y += x;
 
 
    /* load p and g */
    /* 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 */
    /* load m */
    if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error; }
    if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error; }
 
 
    /* find g^m mod p */
    /* 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 */
    /* 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 ??? */
    /* y^a * a^b == g^m ??? */
    if (mp_cmp(&a, &m) == 0) {
    if (mp_cmp(&a, &m) == 0) {
@@ -405,12 +405,12 @@ int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
    }
    }
 
 
    /* clean up */
    /* clean up */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
    goto done;
 error:
 error:
-   res = mpi_to_ltc_error(err);
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL);
    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;
    int err, res;
    unsigned char buf[512];
    unsigned char buf[512];
 
 
-   _ARGCHK(prng != NULL);
    _ARGCHK(key  != NULL);
    _ARGCHK(key  != NULL);
 
 
    /* check prng */
    /* check prng */
@@ -132,11 +131,10 @@ int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
    unsigned long len;
    unsigned long len;
 
 
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
-   _ARGCHK(prng != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
 
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
    if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
       return err;
       return err;
@@ -204,7 +202,7 @@ retry:
    /* store length of r */
    /* store length of r */
    len = mp_unsigned_bin_size(&r);
    len = mp_unsigned_bin_size(&r);
    out[y++] = (len>>8)&255;
    out[y++] = (len>>8)&255;
-   out[y++] = (len & 255);
+   out[y++] = len&255;
    
    
    /* store r */
    /* store r */
    if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY)                              { goto error; }
    if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY)                              { goto error; }
@@ -213,7 +211,7 @@ retry:
    /* store length of s */
    /* store length of s */
    len = mp_unsigned_bin_size(&s);
    len = mp_unsigned_bin_size(&s);
    out[y++] = (len>>8)&255;
    out[y++] = (len>>8)&255;
-   out[y++] = (len & 255);
+   out[y++] = len&255;
    
    
    /* store s */
    /* store s */
    if ((err = mp_to_unsigned_bin(&s, out+y)) != MP_OKAY)                              { goto error; }
    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;
    unsigned long x, y;
    int err;
    int err;
 
 
-   _ARGCHK(sig != NULL);
+   _ARGCHK(sig  != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(stat != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
 
    /* default to invalid signature */
    /* default to invalid signature */
    *stat = 0;
    *stat = 0;
@@ -320,10 +318,15 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key
    unsigned long y, z;
    unsigned long y, z;
    int err;
    int err;
 
 
-   _ARGCHK(out != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != 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) {
    if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
       return CRYPT_PK_TYPE_MISMATCH;
       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;
       return CRYPT_INVALID_ARG;
    }
    }
 
 
-   /* can we store the static header?  */
-   if (*outlen < (PACKET_SIZE + 1 + 2)) {
-      return CRYPT_BUFFER_OVERFLOW;
-   }
-
    /* store header */
    /* store header */
    packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY);
    packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY);
    y = PACKET_SIZE;
    y = PACKET_SIZE;
@@ -366,7 +364,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
    unsigned long x, y;
    unsigned long x, y;
    int err;
    int err;
 
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in  != NULL);
    _ARGCHK(key != NULL);
    _ARGCHK(key != NULL);
 
 
    /* check length */
    /* check length */
@@ -410,7 +408,7 @@ int dsa_verify_key(dsa_key *key, int *stat)
    mp_int tmp, tmp2;
    mp_int tmp, tmp2;
    int res, err;
    int res, err;
 
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(stat != NULL);
    _ARGCHK(stat != NULL);
 
 
    *stat = 0;
    *stat = 0;

+ 62 - 0
eax.c

@@ -8,6 +8,8 @@
  *
  *
  * Tom St Denis, [email protected], http://libtomcrypt.org
  * Tom St Denis, [email protected], http://libtomcrypt.org
  */
  */
+
+/* EAX Implementation by Tom St Denis */
 #include "mycrypt.h"
 #include "mycrypt.h"
 
 
 #ifdef EAX_MODE
 #ifdef EAX_MODE
@@ -385,6 +387,66 @@ int eax_test(void)
    { 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2,
    { 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2,
      0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda }
      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;
    int err, x, idx, res;
    unsigned long len;
    unsigned long len;

+ 178 - 192
ecc.c

@@ -247,9 +247,7 @@ static ecc_point *new_point(void)
 static void del_point(ecc_point *p)
 static void del_point(ecc_point *p)
 {
 {
    /* prevents free'ing null arguments */
    /* prevents free'ing null arguments */
-   if (p == NULL) {
-      return;
-   } else {
+   if (p != NULL) {
       mp_clear_multi(&p->x, &p->y, NULL);
       mp_clear_multi(&p->x, &p->y, NULL);
       XFREE(p);
       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)
 static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu)
 {
 {
    mp_int s, tmp, tmpx;
    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) */
    /* 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 (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 */
    /* 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)  */
    /* 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;
    goto done;
 error:
 error:
-   res = mpi_to_ltc_error(res);
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&tmpx, &tmp, &s, NULL);
    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 */
 /* 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)
 static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu)
 {
 {
    mp_int s, tmp, tmpx;
    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? */
    /* 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);
       mp_clear(&tmp);
-      return mpi_to_ltc_error(res);
+      return mpi_to_ltc_error(err);
    }
    }
 
 
    if (mp_cmp(&P->x, &Q->x) == MP_EQ)
    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);
          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);
       mp_clear(&tmp);
-      return mpi_to_ltc_error(res);
+      return mpi_to_ltc_error(err);
    }
    }
 
 
    /* get s = (Yp - Yq)/(Xp-Xq) mod p */
    /* 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 (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 (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 */
    /* 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) */
    /* 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;
    goto done;
 error:
 error:
-   res = mpi_to_ltc_error(res);
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&s, &tmpx, &tmp, NULL);
    mp_clear_multi(&s, &tmpx, &tmp, NULL);
-   return res;
+   return err;
 }
 }
 
 
 /* size of sliding window, don't change this! */
 /* 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)
 static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
 {
 {
    ecc_point *tG, *M[8];
    ecc_point *tG, *M[8];
-   int i, j, res;
+   int i, j, err;
    mp_int mu;
    mp_int mu;
    mp_digit buf;
    mp_digit buf;
    int     first, bitbuf, bitcpy, bitcnt, mode, digidx;
    int     first, bitbuf, bitcpy, bitcnt, mode, digidx;
 
 
   /* init barrett reduction */
   /* 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);
       mp_clear(&mu);
-      return mpi_to_ltc_error(res);
+      return mpi_to_ltc_error(err);
   }
   }
 
 
   /* alloc ram for window temps */
   /* 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 */
    /* make a copy of G incase R==G */
    tG = new_point();
    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 */
    /* calc the M tab, which holds kG for k==8..15 */
    /* M[0] == 8G */
    /* 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 */
    /* now find (8+k)G for k=1..7 */
    for (j = 9; j < 16; j++) {
    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 */
    /* setup sliding window */
    mode   = 0;
    mode   = 0;
    bitcnt = 1;
    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 the bit is zero and mode == 1 then we double */
      if (mode == 1 && i == 0) {
      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;
         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 this is the first window we do a simple copy */
        if (first == 1) {
        if (first == 1) {
           /* R = kG [k = first window] */
           /* 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;
           first = 0;
        } else {
        } else {
          /* normal window */
          /* normal window */
          /* ok window is filled so double as required and add  */
          /* ok window is filled so double as required and add  */
          /* double first */
          /* double first */
          for (j = 0; j < WINSIZE; j++) {
          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 */
          /* 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 */
        /* empty window and reset */
        bitcpy = bitbuf = 0;
        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++) {
      for (j = 0; j < bitcpy; j++) {
        /* only double if we have had at least one add first */
        /* only double if we have had at least one add first */
        if (first == 0) {
        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;
        bitbuf <<= 1;
        if ((bitbuf & (1 << WINSIZE)) != 0) {
        if ((bitbuf & (1 << WINSIZE)) != 0) {
          if (first == 1){
          if (first == 1){
             /* first add, so copy */
             /* 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;
             first = 0;
          } else {
          } else {
             /* then add */
             /* 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;
    goto done;
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    del_point(tG);
    del_point(tG);
    for (i = 0; i < 8; i++) {
    for (i = 0; i < 8; i++) {
        del_point(M[i]);
        del_point(M[i]);
    }
    }
    mp_clear(&mu);
    mp_clear(&mu);
-   return res;
+   return err;
 }
 }
 
 
 #undef WINSIZE
 #undef WINSIZE
@@ -516,22 +514,18 @@ int ecc_test(void)
 {
 {
    mp_int     modulus, order;
    mp_int     modulus, order;
    ecc_point  *G, *GG;
    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();
    G   = new_point();
-   if (G == NULL) {
-      mp_clear_multi(&modulus, &order, NULL);
-      return CRYPT_MEM;
-   }
-
    GG  = new_point();
    GG  = new_point();
-   if (GG == NULL) {
+   if (G == NULL || GG == NULL) {
       mp_clear_multi(&modulus, &order, NULL);
       mp_clear_multi(&modulus, &order, NULL);
       del_point(G);
       del_point(G);
+      del_point(GG);
       return CRYPT_MEM;
       return CRYPT_MEM;
    }
    }
 
 
@@ -539,43 +533,43 @@ int ecc_test(void)
        #if 0
        #if 0
           printf("Testing %d\n", sets[i].size);
           printf("Testing %d\n", sets[i].size);
        #endif
        #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? */
        /* 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) {
        if (primality == 0) {
-          res = CRYPT_FAIL_TESTVECTOR;
-          goto done1;
+          err = CRYPT_FAIL_TESTVECTOR;
+          goto done;
        }
        }
 
 
        /* is order prime ? */
        /* 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) {
        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 */
        /* 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) {
        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:
 error:
-   res = CRYPT_MEM;
-done1:
+   err = mpi_to_ltc_error(err);
+done:
    del_point(GG);
    del_point(GG);
    del_point(G);
    del_point(G);
    mp_clear_multi(&order, &modulus, NULL);
    mp_clear_multi(&order, &modulus, NULL);
-   return res;
+   return err;
 }
 }
 
 
 void ecc_sizes(int *low, int *high)
 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 ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
 {
 {
-   int x, res, err;
+   int x, err;
    ecc_point *base;
    ecc_point *base;
    mp_int prime;
    mp_int prime;
    unsigned char buf[128];
    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 */
    /* 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();
    base = new_point();
    if (base == NULL) {
    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 */
    /* 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 */
    /* 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;
    key->type = PK_PRIVATE;
 
 
    /* shrink key */
    /* 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 */
    /* free up ram */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
    goto done;
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    del_point(base);
    del_point(base);
    mp_clear(&prime);
    mp_clear(&prime);
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
    zeromem(buf, sizeof(buf));
    zeromem(buf, sizeof(buf));
 #endif
 #endif
-   return res;
+   return err;
 }
 }
 
 
 void ecc_free(ecc_key *key)
 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)
 static int compress_y_point(ecc_point *pt, int idx, int *result)
 {
 {
    mp_int tmp, tmp2, p;
    mp_int tmp, tmp2, p;
-   int res;
+   int err;
 
 
-   _ARGCHK(pt != NULL);
+   _ARGCHK(pt     != NULL);
    _ARGCHK(result != 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 */
    /* 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 */
    /* 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 tmp equals the y point give a 0, otherwise 1 */
    if (mp_cmp(&tmp, &pt->y) == 0) {
    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;
       *result = 1;
    }
    }
 
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
    goto done;
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&p, &tmp, &tmp2, NULL);
    mp_clear_multi(&p, &tmp, &tmp2, NULL);
-   return res;
+   return err;
 }
 }
 
 
 static int expand_y_point(ecc_point *pt, int idx, int result)
 static int expand_y_point(ecc_point *pt, int idx, int result)
 {
 {
    mp_int tmp, tmp2, p;
    mp_int tmp, tmp2, p;
-   int res;
+   int err;
 
 
    _ARGCHK(pt != NULL);
    _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;
       return CRYPT_MEM;
    }
    }
 
 
    /* get x^3 - 3x + b */
    /* 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 */
    /* 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, then y==tmp, otherwise y==p-tmp */
    if (result == 0) {
    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 {
    } 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;
    goto done;
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&p, &tmp, &tmp2, NULL);
    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)
 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
 {
 {
    unsigned long y, z;
    unsigned long y, z;
-   int res, err;
-   unsigned char buf2[512];
+   int cp, err;
 
 
-   _ARGCHK(out != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != 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? */
    /* type valid? */
    if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
    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 */
    /* output type and magic byte */
    y = PACKET_SIZE;
    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 x coordinate */
-   OUTPUT_BIGNUM(&(key->pubkey.x), buf2, y, z);
+   OUTPUT_BIGNUM(&(key->pubkey.x), out, y, z);
 
 
    /* compress y and output it  */
    /* 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;
       return err;
    }
    }
-   buf2[y++] = (unsigned char)res;
+   out[y++] = (unsigned char)cp;
 
 
    if (type == PK_PRIVATE) {
    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 */
    /* 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;
    *outlen = y;
 
 
-   #ifdef CLEAN_STACK
-       zeromem(buf2, sizeof(buf2));
-   #endif
    return CRYPT_OK;
    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;
    unsigned long x, y, s;
    int err;
    int err;
 
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in  != NULL);
    _ARGCHK(key != NULL);
    _ARGCHK(key != NULL);
 
 
    /* check length */
    /* check length */
-   if (2+PACKET_SIZE > inlen) {
+   if ((3+PACKET_SIZE) > inlen) {
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;
    }
    }
 
 
@@ -881,12 +867,12 @@ int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
    unsigned long x, y;
    unsigned long x, y;
    ecc_point *result;
    ecc_point *result;
    mp_int prime;
    mp_int prime;
-   int res;
+   int err;
 
 
    _ARGCHK(private_key != NULL);
    _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? */
    /* type valid? */
    if (private_key->type != PK_PRIVATE) {
    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;
       return CRYPT_MEM;
    }
    }
 
 
-   if (mp_init(&prime) != MP_OKAY) {
+   if ((err = mp_init(&prime)) != MP_OKAY) {
       del_point(result);
       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);
    x = (unsigned long)mp_unsigned_bin_size(&result->x);
    y = (unsigned long)mp_unsigned_bin_size(&result->y);
    y = (unsigned long)mp_unsigned_bin_size(&result->y);
 
 
    if (*outlen < (x+y)) {
    if (*outlen < (x+y)) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done1;
       goto done1;
    }
    }
    *outlen = x+y;
    *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;
    goto done1;
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done1:
 done1:
    mp_clear(&prime);
    mp_clear(&prime);
    del_point(result);
    del_point(result);
-   return res;
+   return err;
 }
 }
 
 
 int ecc_get_size(ecc_key *key)
 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;
     int err;
 
 
     _ARGCHK(inkey != NULL);
     _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 */
     /* check that wprng/cipher/hash are not invalid */
     if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
     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) {
     if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) {
        return err;
        return err;
     }
     }
+    
+    /* store header */
+    packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY);    
 
 
     /* output header */
     /* output header */
     y = PACKET_SIZE;
     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++) {
     for (x = 0; x < keylen; x++, y++) {
       out[y] = skey[x] ^ inkey[x];
       out[y] = skey[x] ^ inkey[x];
     }
     }
-
-    /* store header */
-    packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY);
+    *len = y;
 
 
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
     /* clean up */
     /* clean up */
@@ -97,7 +98,6 @@ int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
     zeromem(ecc_shared, sizeof(ecc_shared));
     zeromem(ecc_shared, sizeof(ecc_shared));
     zeromem(skey, sizeof(skey));
     zeromem(skey, sizeof(skey));
 #endif
 #endif
-    *len = y;
     return CRYPT_OK;
     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 char shared_secret[256], skey[MAXBLOCKSIZE];
    unsigned long x, y, z, hashsize, keysize;
    unsigned long x, y, z, hashsize, keysize;
-   int hash, res, err;
+   int hash, err;
    ecc_key pubkey;
    ecc_key pubkey;
 
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in     != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(keylen != NULL);
    _ARGCHK(keylen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
 
    /* right key type? */
    /* right key type? */
    if (key->type != PK_PRIVATE) {
    if (key->type != PK_PRIVATE) {
@@ -177,7 +177,7 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
    y += 4;
    y += 4;
 
 
    if (*keylen < keysize) {
    if (*keylen < keysize) {
-       res = CRYPT_BUFFER_OVERFLOW;
+       err = CRYPT_BUFFER_OVERFLOW;
        goto done;
        goto done;
    }
    }
 
 
@@ -188,13 +188,13 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
 
 
    *keylen = keysize;
    *keylen = keysize;
 
 
-   res = CRYPT_OK;
+   err = CRYPT_OK;
 done:
 done:
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
    zeromem(shared_secret, sizeof(shared_secret));
    zeromem(shared_secret, sizeof(shared_secret));
    zeromem(skey, sizeof(skey));
    zeromem(skey, sizeof(skey));
 #endif
 #endif
-   return res;
+   return err;
 }
 }
 
 
 int ecc_sign_hash(const unsigned char *in,  unsigned long inlen, 
 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;
    mp_int b, p;
    unsigned char epubkey[256], er[256];
    unsigned char epubkey[256], er[256];
    unsigned long x, y, pubkeysize, rsize;
    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(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
 
    /* is this a private key? */
    /* is this a private key? */
    if (key->type != PK_PRIVATE) {
    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' */
    /* get the hash and load it as a bignum into 'b' */
    /* init the bignums */
    /* 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);
       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 */
    /* 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 */
    /* export it */
    rsize = (unsigned long)mp_unsigned_bin_size(&b);
    rsize = (unsigned long)mp_unsigned_bin_size(&b);
    if (rsize > (unsigned long)sizeof(er)) { 
    if (rsize > (unsigned long)sizeof(er)) { 
+      err = CRYPT_BUFFER_OVERFLOW;
       goto error; 
       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 */
    /* now lets check the outlen before we write */
    if (*outlen < (12 + rsize + pubkeysize)) {
    if (*outlen < (12 + rsize + pubkeysize)) {
-      res = CRYPT_BUFFER_OVERFLOW;
-      goto done1;
+      err = CRYPT_BUFFER_OVERFLOW;
+      goto done;
    }
    }
 
 
    /* lets output */
    /* lets output */
@@ -290,18 +291,18 @@ int ecc_sign_hash(const unsigned char *in,  unsigned long inlen,
 
 
    /* clear memory */
    /* clear memory */
    *outlen = y;
    *outlen = y;
-   res = CRYPT_OK;
-   goto done1;
+   err = CRYPT_OK;
+   goto done;
 error:
 error:
-   res = CRYPT_MEM;
-done1:
+   err = mpi_to_ltc_error(err);
+done:
    mp_clear_multi(&b, &p, NULL);
    mp_clear_multi(&b, &p, NULL);
    ecc_free(&pubkey);
    ecc_free(&pubkey);
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
    zeromem(er, sizeof(er));
    zeromem(er, sizeof(er));
    zeromem(epubkey, sizeof(epubkey));
    zeromem(epubkey, sizeof(epubkey));
 #endif
 #endif
-   return res;   
+   return err;   
 }
 }
 
 
 /* verify that mG = (bA + Y)
 /* verify that mG = (bA + Y)
@@ -325,12 +326,12 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
    ecc_key   pubkey;
    ecc_key   pubkey;
    mp_int b, p, m, mu;
    mp_int b, p, m, mu;
    unsigned long x, y;
    unsigned long x, y;
-   int res, err;
+   int err;
 
 
-   _ARGCHK(sig != NULL);
+   _ARGCHK(sig  != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(hash != NULL);
    _ARGCHK(stat != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
 
    /* default to invalid signature */
    /* default to invalid signature */
    *stat = 0;
    *stat = 0;
@@ -374,9 +375,9 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
    y += 4;
    y += 4;
 
 
    /* init values */
    /* 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);
       ecc_free(&pubkey);
-      return CRYPT_MEM;
+      return mpi_to_ltc_error(err);
    }
    }
 
 
    mG = new_point();
    mG = new_point();
@@ -387,33 +388,30 @@ int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
    } 
    } 
 
 
    /* load b */
    /* 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;
    y += x;
 
 
    /* get m in binary a bignum */
    /* 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 */
    /* 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 */
    /* calculate barrett stuff */
    mp_set(&mu, 1); 
    mp_set(&mu, 1); 
    mp_lshd(&mu, 2 * USED(&p));
    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 */
    /* 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 */
    /* 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 */
    /* 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 */
    /* compare mG to bA + Y */
    if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) {
    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 */
    /* clear up and return */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
    goto done;
 error:
 error:
-   res = CRYPT_ERROR;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    del_point(mG);
    del_point(mG);
    ecc_free(&pubkey);
    ecc_free(&pubkey);
    mp_clear_multi(&p, &m, &b, &mu, NULL);
    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;
     hash_state md;
     int err;
     int err;
 
 
-    _ARGCHK(data != NULL);
-    _ARGCHK(dst != NULL);
+    _ARGCHK(data   != NULL);
+    _ARGCHK(dst    != NULL);
     _ARGCHK(outlen != NULL);
     _ARGCHK(outlen != NULL);
 
 
     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
     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;
     size_t x;
     int err;
     int err;
 
 
-    _ARGCHK(dst != NULL);
+    _ARGCHK(dst    != NULL);
     _ARGCHK(outlen != NULL);
     _ARGCHK(outlen != NULL);
-    _ARGCHK(in != NULL);
+    _ARGCHK(in     != NULL);
 
 
     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
         return err;
         return err;
@@ -78,8 +78,8 @@ int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *ou
 #else
 #else
     FILE *in;
     FILE *in;
     int err;
     int err;
-    _ARGCHK(fname != NULL);
-    _ARGCHK(dst != NULL);
+    _ARGCHK(fname  != NULL);
+    _ARGCHK(dst    != NULL);
     _ARGCHK(outlen != NULL);
     _ARGCHK(outlen != NULL);
 
 
     if ((err = hash_is_valid(hash)) != CRYPT_OK) {
     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;
     hmac_state hmac;
     int err;
     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) {
     if((err = hash_is_valid(hash)) != CRYPT_OK) {
         return err;
         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 */
 /* 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
 #ifdef NO_FILE
     return CRYPT_NOP;
     return CRYPT_NOP;
@@ -186,9 +187,10 @@ int hmac_file(int hash, const char *fname, const unsigned char *key,
    size_t x;
    size_t x;
    int err;
    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) {
    if((err = hash_is_valid(hash)) != CRYPT_OK) {
        return err;
        return err;

+ 7 - 4
makefile

@@ -9,7 +9,7 @@
 # a build. This is easy to remedy though, for those that have problems.
 # a build. This is easy to remedy though, for those that have problems.
 
 
 # The version
 # The version
-VERSION=0.93
+VERSION=0.94
 
 
 #ch1-01-1
 #ch1-01-1
 # Compiler and Linker Names
 # 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 \
 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 \
 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 \
 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
 TESTOBJECTS=demos/test.o
 HASHOBJECTS=demos/hashsum.o
 HASHOBJECTS=demos/hashsum.o
@@ -152,7 +153,9 @@ docs: crypt.tex
 	rm -f crypt.pdf $(LEFTOVERS)
 	rm -f crypt.pdf $(LEFTOVERS)
 	latex crypt > /dev/null
 	latex crypt > /dev/null
 	makeindex crypt > /dev/null
 	makeindex crypt > /dev/null
-	pdflatex crypt > /dev/null
+	latex crypt > /dev/null
+	latex crypt > /dev/null
+	dvipdf crypt
 	rm -f $(LEFTOVERS)
 	rm -f $(LEFTOVERS)
        
        
 #beta
 #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 \
 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 \
 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 \
 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)
 ltc_dll: $(OBJECTS) $(MPIOBJECT)
 	gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32
 	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 \
 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 \
 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 \
 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 \
 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)
 library: $(OBJECTS)
 	lib /out:tomcrypt.lib $(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
 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
 rsa.o: rsa_sys.c
 dh.o: dh_sys.c
 dh.o: dh_sys.c

+ 2 - 2
mycrypt.h

@@ -16,8 +16,8 @@ extern "C" {
 #endif
 #endif
 
 
 /* version */
 /* 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] */
 /* max size of either a cipher/hash block or symmetric key [largest of the two] */
 #define MAXBLOCKSIZE           128
 #define MAXBLOCKSIZE           128

+ 2 - 1
mycrypt_custom.h

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

+ 55 - 3
mycrypt_hash.h

@@ -70,7 +70,18 @@ struct rmd160_state {
 };
 };
 #endif
 #endif
 
 
+#ifdef WHIRLPOOL
+struct whirlpool_state {
+    ulong64 length, state[8];
+    unsigned char buf[64];
+    ulong32 curlen;
+};
+#endif
+
 typedef union Hash_state {
 typedef union Hash_state {
+#ifdef WHIRLPOOL
+    struct whirlpool_state whirlpool;
+#endif
 #ifdef SHA512
 #ifdef SHA512
     struct sha512_state sha512;
     struct sha512_state sha512;
 #endif
 #endif
@@ -111,6 +122,15 @@ extern struct _hash_descriptor {
     int  (*test)(void);
     int  (*test)(void);
 } hash_descriptor[];
 } 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
 #ifdef SHA512
 extern void sha512_init(hash_state * md);
 extern void sha512_init(hash_state * md);
 extern int sha512_process(hash_state * md, const unsigned char *buf, unsigned long len);
 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,
 extern int omac_file(int cipher, const unsigned char *key, unsigned long keylen,
               const char *filename, unsigned char *out, unsigned long *outlen);
               const char *filename, unsigned char *out, unsigned long *outlen);
 extern int omac_test(void);
 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
 #ifdef EAX_MODE
 
 
@@ -345,8 +396,7 @@ typedef struct {
    symmetric_key     key;                     /* scheduled key for cipher */
    symmetric_key     key;                     /* scheduled key for cipher */
    unsigned long     block_index;             /* index # for current block */
    unsigned long     block_index;             /* index # for current block */
    int               cipher,                  /* cipher idx */
    int               cipher,                  /* cipher idx */
-                     block_len,               /* length of block */
-                     poly;                    /* which set of polys to use */
+                     block_len;               /* length of block */
 } ocb_state;
 } ocb_state;
 
 
 extern int ocb_init(ocb_state *ocb, int cipher, 
 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);
 extern int ocb_test(void);
 
 
 #endif /* OCB_MODE */
 #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)
 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)
 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
 #else

+ 16 - 16
mycrypt_pk.h

@@ -3,43 +3,43 @@
 
 
 #include "tommath.h"
 #include "tommath.h"
 
 
-
 /* in/out macros */
 /* 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)                              \
 #define INPUT_BIGNUM(num, in, x, y)                              \
 {                                                                \
 {                                                                \
      /* load value */                                            \
      /* load value */                                            \
-     if (y + 4 > inlen) {                                        \
-        err = CRYPT_INVALID_PACKET;                            \
+     if ((y + 4) > inlen) {                                      \
+        err = CRYPT_INVALID_PACKET;                              \
         goto error;                                              \
         goto error;                                              \
      }                                                           \
      }                                                           \
      LOAD32L(x, in+y);                                           \
      LOAD32L(x, in+y);                                           \
      y += 4;                                                     \
      y += 4;                                                     \
                                                                  \
                                                                  \
      /* sanity check... */                                       \
      /* sanity check... */                                       \
-     if (x+y > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                            \
+     if ((x+y) > inlen) {                                        \
+        err = CRYPT_INVALID_PACKET;                              \
         goto error;                                              \
         goto error;                                              \
      }                                                           \
      }                                                           \
                                                                  \
                                                                  \
      /* load it */                                               \
      /* load it */                                               \
      if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != MP_OKAY) {\
      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;                                              \
         goto error;                                              \
      }                                                           \
      }                                                           \
      y += x;                                                     \
      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;                                              \
         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
 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
 Cipher: rc2
 Key Size: 8 bytes
 Key Size: 8 bytes
  0: 83B189DE87161805
  0: 83B189DE87161805

+ 0 - 76
notes/eax_tv.txt

@@ -199,82 +199,6 @@ EAX-twofish (16 byte key)
  31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF
  31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF
  32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1
  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)
 EAX-rc2 (8 byte key)
   0: , D6CC8632EEE0F46B
   0: , D6CC8632EEE0F46B
   1: 4C, EA19572CB8970CB4
   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
 127: 2BE8E565E24A87171F0700ECAFA3C2942C97023E
 128: 7C4D36070C1E1176B2960A1B0DD2319D547CF8EB
 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
 127: B107A8B0C7B68581969A0F6DB95DB2F790098F1D
 128: AD090CC9A6B381C0B3D87035274FBC056012A4E6
 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)
 OCB-aes (16 byte key)
   0: , 04ADA45E947BC5B6E00F4C8B8053902D
   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)
 OCB-blowfish (8 byte key)
   0: , 07B7752047F9E0AE
   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)
 OCB-xtea (16 byte key)
   0: , 56722ECFE6ED1300
   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)
 OCB-rc5 (8 byte key)
   0: , E7462C3C0C95A73E
   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)
 OCB-rc6 (16 byte key)
   0: , 27B9E3F544B8F567EEBF98ED5FD55C76
   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)
 OCB-safer+ (16 byte key)
   0: , 88618DEF98FE588E23107E9A5D89C26B
   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)
 OCB-twofish (16 byte key)
   0: , 2CD8EF22E5457C7FE4016B0FB82FD204
   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)
 OCB-rc2 (8 byte key)
   0: , 1A073F25FF5690BE
   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)
 OCB-des (8 byte key)
   0: , 8A65BD7DE54082AD
   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)
 OCB-3des (24 byte key)
   0: , 9CB7074F93CD37DD
   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)
 OCB-cast5 (8 byte key)
   0: , 77E8002236021687
   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)
 OCB-noekeon (16 byte key)
   0: , 72751E743D0B7A07EFB23444F1492DDC
   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)
 OCB-skipjack (10 byte key)
   0: , 90EAAB5131AEB43B
   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
  31: C24FCA5DD4AE0DF2BFF17364D17D6743
  32: DC6738080478AF9AF7CA833295031E06
  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)
 OMAC-rc2 (8 byte key)
   0: F001FE9BBC3A97B0
   0: F001FE9BBC3A97B0
   1: 8F8DC9C952897FBD
   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
  * Tom St Denis, [email protected], http://libtomcrypt.org
  */
  */
+
+/* OCB Implementation by Tom St Denis */
 #include "mycrypt.h"
 #include "mycrypt.h"
 
 
 #define OCB_MODE
 #define OCB_MODE
@@ -34,11 +36,10 @@ static const struct {
 int ocb_init(ocb_state *ocb, int cipher, 
 int ocb_init(ocb_state *ocb, int cipher, 
              const unsigned char *key, unsigned long keylen, const unsigned char *nonce)
              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);
    _ARGCHK(nonce != NULL);
 
 
    /* valid cipher? */
    /* valid cipher? */
@@ -48,12 +49,12 @@ int ocb_init(ocb_state *ocb, int cipher,
 
 
    /* determine which polys to use */
    /* determine which polys to use */
    ocb->block_len = cipher_descriptor[cipher].block_length;
    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;
           break;
        }
        }
    }
    }
-   if (polys[ocb->poly].len != ocb->block_len) {
+   if (polys[poly].len != ocb->block_len) {
       return CRYPT_INVALID_ARG;
       return CRYPT_INVALID_ARG;
    }   
    }   
 
 
@@ -83,7 +84,7 @@ int ocb_init(ocb_state *ocb, int cipher,
 
 
        if (m == 1) {
        if (m == 1) {
           for (y = 0; y < ocb->block_len; y++) {
           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) {
     if (m == 1) {
        for (x = 0; x < ocb->block_len; x++) {
        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)
 int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
 {
 {
    unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
    unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
-   int err, x, y;
+   int err, x;
 
 
    _ARGCHK(ocb != NULL);
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != 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)
 int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
 {
 {
    unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
    unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
-   int err, x, y;
+   int err, x;
 
 
    _ARGCHK(ocb != NULL);
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != 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];
    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);
    _ARGCHK(taglen != NULL);
    if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
    if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
       return err;
       return err;
@@ -247,7 +248,8 @@ static int _ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptle
    shift_xor(ocb, X); 
    shift_xor(ocb, X); 
    memcpy(Z, X, ocb->block_len);
    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++) {
    for (x = 0; x < ocb->block_len; x++) {
        X[x] ^= ocb->Lr[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(X, sizeof(X));
    zeromem(Y, sizeof(Y));
    zeromem(Y, sizeof(Y));
    zeromem(Z, sizeof(Z));
    zeromem(Z, sizeof(Z));
+   zeromem(ocb, sizeof(*ocb));
 #endif
 #endif
    return CRYPT_OK;
    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,
 int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
                      unsigned char *ct, unsigned char *tag, unsigned long *taglen)
                      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);
    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 char tagbuf[MAXBLOCKSIZE];
    unsigned long tagbuflen;
    unsigned long tagbuflen;
 
 
-
    _ARGCHK(ocb != NULL);
    _ARGCHK(ocb != NULL);
    _ARGCHK(pt  != NULL);
    _ARGCHK(pt  != NULL);
    _ARGCHK(ct  != NULL);
    _ARGCHK(ct  != NULL);
@@ -346,9 +353,16 @@ int ocb_encrypt_authenticate_memory(int cipher,
           unsigned char *ct,
           unsigned char *ct,
           unsigned char *tag,    unsigned long *taglen)
           unsigned char *tag,    unsigned long *taglen)
 {
 {
-   int err, n;
+   int err;
    ocb_state ocb;
    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) {
    if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
@@ -378,9 +392,17 @@ int ocb_decrypt_verify_memory(int cipher,
     const unsigned char *tag,    unsigned long taglen,
     const unsigned char *tag,    unsigned long taglen,
           int           *res)
           int           *res)
 {
 {
-   int err, n;
+   int err;
    ocb_state ocb;
    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) {
    if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
@@ -409,86 +431,139 @@ int ocb_test(void)
 #else
 #else
    static const struct {
    static const struct {
          int ptlen;
          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[] = {
    } tests[] = {
 
 
-   /* NULL message */
+   /* OCB-AES-128-0B */
 {
 {
    0,
    0,
    /* key */
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
    /* 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,
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
      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 */
    /* pt */
-   { 0x00 },
+   { 0x00, 0x01, 0x02 },
    /* ct */
    /* ct */
-   { 0x00 },
+   { 0xfc, 0xd3, 0x7d },
    /* tag */
    /* 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 */
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
    /* 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,
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
-   /* pt */
-   { 0x11 },
    /* ct */
    /* ct */
-   { 0x6f },
+   { 0x37, 0xdf, 0x8c, 0xe1, 0x5b, 0x48, 0x9b, 0xf3,
+     0x1d, 0x0f, 0xc4, 0x4d, 0xa1, 0xfa, 0xf6, 0xd6 },
    /* tag */
    /* 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 */
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
    /* 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 */
    /* pt */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    { 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 */
    /* 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 */
    /* 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 */
    /* key */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    /* nonce */
    /* 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,
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
      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 */
    /* pt */
    { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    { 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 */
    /* 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 */
    /* 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;
    int err;
    omac_state omac;
    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) {
    if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) {
       return err;
       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) {
    if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
+
+#ifdef CLEAN_STACK
+   zeromem(&omac, sizeof(omac));
+#endif
+
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
@@ -188,6 +198,13 @@ int omac_file(int cipher, const unsigned char *key, unsigned long keylen,
    FILE *in;
    FILE *in;
    unsigned char buf[512];
    unsigned char buf[512];
 
 
+
+   _ARGCHK(key      != NULL);
+   _ARGCHK(filename != NULL);
+   _ARGCHK(out      != NULL);
+   _ARGCHK(outlen   != NULL);
+
+
    in = fopen(filename, "rb");
    in = fopen(filename, "rb");
    if (in == NULL) {
    if (in == NULL) {
       return CRYPT_FILE_NOTFOUND;
       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) {
    if ((err = omac_done(&omac, out, outlen)) != CRYPT_OK) {
       return err;
       return err;
    }
    }
+
+#ifdef CLEAN_STACK
+   zeromem(buf, sizeof(buf));
+#endif
+
    return CRYPT_OK;
    return CRYPT_OK;
 #endif
 #endif
 }
 }
@@ -221,7 +243,7 @@ int omac_test(void)
 #else
 #else
     static const struct { 
     static const struct { 
         int keylen, msglen;
         int keylen, msglen;
-        unsigned char key[32], msg[64], tag[16];
+        unsigned char key[16], msg[64], tag[16];
     } tests[] = {
     } tests[] = {
     { 16, 0,
     { 16, 0,
       { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 
       { 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 */
 /* RSA Code by Tom St Denis */
 #include "mycrypt.h"
 #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
 #ifdef MRSA
 
 
 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
 int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
 {
 {
    mp_int p, q, tmp1, tmp2, tmp3;
    mp_int p, q, tmp1, tmp2, tmp3;
-   int res, err;
+   int err;
 
 
    _ARGCHK(key != NULL);
    _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;
       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;
       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) */
    /* 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" */
    /* make prime "p" */
    do {
    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" */
    /* make prime "q" */
    do {
    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) */
    /* 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 */
    /* 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;
       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 */
 /* optimize for CRT now */
    /* find d mod q-1 and d mod p-1 */
    /* 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  */
    /* 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;
    key->type = PK_PRIVATE_OPTIMIZED;
    goto done;
    goto done;
 error2:
 error2:
    mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
    mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
                   &key->qP, &key->pQ, &key->p, &key->q, NULL);
                   &key->qP, &key->pQ, &key->p, &key->q, NULL);
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL);
    mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL);
-   return res;
+   return err;
 }
 }
 
 
 void rsa_free(rsa_key *key)
 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;
    mp_int tmp, tmpa, tmpb;
    unsigned long x;
    unsigned long x;
-   int res;
+   int err;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
 
    if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) {
    if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) {
       return CRYPT_PK_NOT_PRIVATE;
       return CRYPT_PK_NOT_PRIVATE;
@@ -140,51 +147,51 @@ int rsa_exptmod(const unsigned char *in,  unsigned long inlen,
    }
    }
 
 
    /* init and copy into tmp */
    /* 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 */
    /* sanity check on the input */
    if (mp_cmp(&key->N, &tmp) == MP_LT) {
    if (mp_cmp(&key->N, &tmp) == MP_LT) {
-      res = CRYPT_PK_INVALID_SIZE;
+      err = CRYPT_PK_INVALID_SIZE;
       goto done;
       goto done;
    }
    }
 
 
    /* are we using the private exponent and is the key optimized? */
    /* are we using the private exponent and is the key optimized? */
    if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) {
    if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) {
       /* tmpa = tmp^dP mod p */
       /* 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 */
       /* 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 */
       /* 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 {
    } else {
       /* exptmod it */
       /* 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 */
    /* read it back */
    x = (unsigned long)mp_unsigned_bin_size(&tmp);
    x = (unsigned long)mp_unsigned_bin_size(&tmp);
    if (x > *outlen) {
    if (x > *outlen) {
-      res = CRYPT_BUFFER_OVERFLOW;
+      err = CRYPT_BUFFER_OVERFLOW;
       goto done;
       goto done;
    }
    }
    *outlen = x;
    *outlen = x;
 
 
    /* convert it */
    /* 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 */
    /* clean up and return */
-   res = CRYPT_OK;
+   err = CRYPT_OK;
    goto done;
    goto done;
 error:
 error:
-   res = CRYPT_MEM;
+   err = mpi_to_ltc_error(err);
 done:
 done:
    mp_clear_multi(&tmp, &tmpa, &tmpb, NULL);
    mp_clear_multi(&tmp, &tmpa, &tmpb, NULL);
-   return res;
+   return err;
 }
 }
 
 
 int rsa_signpad(const unsigned char *in,  unsigned long inlen,
 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;
    unsigned long x, y;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
 
 
    if (*outlen < (3 * inlen)) {
    if (*outlen < (3 * inlen)) {
@@ -219,12 +226,12 @@ int rsa_pad(const unsigned char *in,  unsigned long inlen,
                   unsigned char *out, unsigned long *outlen,
                   unsigned char *out, unsigned long *outlen,
                   int wprng, prng_state *prng)
                   int wprng, prng_state *prng)
 {
 {
-   unsigned char buf[1536];
+   unsigned char buf[3*(MAX_RSA_SIZE/8)];
    unsigned long x;
    unsigned long x;
    int err;
    int err;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
 
 
    /* is output big enough? */
    /* is output big enough? */
@@ -238,7 +245,7 @@ int rsa_pad(const unsigned char *in,  unsigned long inlen,
    }
    }
 
 
    /* check inlen */
    /* check inlen */
-   if (inlen > 512) {
+   if (inlen > (MAX_RSA_SIZE/8)) {
       return CRYPT_PK_INVALID_SIZE;
       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,
 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;
    unsigned long x;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
 
 
    if (*outlen < inlen/3) {
    if (*outlen < inlen/3) {
@@ -306,8 +313,8 @@ int rsa_depad(const unsigned char *in,  unsigned long inlen,
 {
 {
    unsigned long x;
    unsigned long x;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
 
 
    if (*outlen < inlen/3) {
    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)
 int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
 {
 {
-   unsigned char buf2[5120];
    unsigned long y, z; 
    unsigned long y, z; 
    int err;
    int err;
 
 
-   _ARGCHK(out != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != 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? */
    /* type valid? */
    if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
    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;
    y = PACKET_SIZE;
 
 
    /* output key type */
    /* output key type */
-   buf2[y++] = type;
+   out[y++] = type;
 
 
    /* output modulus */
    /* output modulus */
-   OUTPUT_BIGNUM(&key->N, buf2, y, z);
+   OUTPUT_BIGNUM(&key->N, out, y, z);
 
 
    /* output public key */
    /* 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) {
    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) {
    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 */
    /* 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 */
    /* copy to the user buffer */
-   memcpy(out, buf2, (size_t)y);
    *outlen = y;
    *outlen = y;
 
 
    /* clear stack and return */
    /* clear stack and return */
-#ifdef CLEAN_STACK
-   zeromem(buf2, sizeof(buf2));
-#endif
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
@@ -385,11 +387,11 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    unsigned long x, y;
    unsigned long x, y;
    int err;
    int err;
 
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in  != NULL);
    _ARGCHK(key != NULL);
    _ARGCHK(key != NULL);
 
 
    /* check length */
    /* check length */
-   if (inlen < 1+PACKET_SIZE) {
+   if (inlen < (1+PACKET_SIZE)) {
       return CRYPT_INVALID_PACKET;
       return CRYPT_INVALID_PACKET;
    }
    }
 
 
@@ -399,9 +401,9 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    }
    }
 
 
    /* init 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 */
    /* 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,
                     unsigned char *outkey, unsigned long *outlen,
                     prng_state *prng, int wprng, rsa_key *key)
                     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;
    unsigned long x, y, rsa_size;
    int err;
    int err;
 
 
-   _ARGCHK(inkey != NULL);
+   _ARGCHK(inkey  != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
    
    
    /* only allow keys from 64 to 256 bits */
    /* only allow keys from 64 to 256 bits */
    if (inlen < 8 || inlen > 32) {
    if (inlen < 8 || inlen > 32) {
@@ -52,6 +52,9 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
       return CRYPT_BUFFER_OVERFLOW;
       return CRYPT_BUFFER_OVERFLOW;
    }
    }
 
 
+   /* store header */
+   packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY);
+
    /* now lets make the header */
    /* now lets make the header */
    y = PACKET_SIZE;
    y = PACKET_SIZE;
    
    
@@ -64,15 +67,13 @@ int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
        outkey[y] = rsa_out[x];
        outkey[y] = rsa_out[x];
    }
    }
 
 
-   /* store header */
-   packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY);
-
+   *outlen = y;
 #ifdef CLEAN_STACK
 #ifdef CLEAN_STACK
    /* clean up */
    /* clean up */
    zeromem(rsa_in, sizeof(rsa_in));
    zeromem(rsa_in, sizeof(rsa_in));
    zeromem(rsa_out, sizeof(rsa_out));
    zeromem(rsa_out, sizeof(rsa_out));
 #endif
 #endif
-   *outlen = y;
+
    return CRYPT_OK;
    return CRYPT_OK;
 }
 }
 
 
@@ -80,14 +81,14 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
                           unsigned char *outkey, unsigned long *keylen, 
                           unsigned char *outkey, unsigned long *keylen, 
                           rsa_key *key)
                           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;
    unsigned long x, y, z, i, rsa_size;
    int err;
    int err;
 
 
-   _ARGCHK(in != NULL);
+   _ARGCHK(in     != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(outkey != NULL);
    _ARGCHK(keylen != NULL);
    _ARGCHK(keylen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
 
 
    /* right key type? */
    /* right key type? */
    if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
    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)
                         rsa_key *key)
 {
 {
    unsigned long rsa_size, x, y;
    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;
    int err;
 
 
-   _ARGCHK(in != NULL);
-   _ARGCHK(out != NULL);
+   _ARGCHK(in     != NULL);
+   _ARGCHK(out    != NULL);
    _ARGCHK(outlen != NULL);
    _ARGCHK(outlen != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key    != NULL);
    
    
    /* reject nonsense sizes */
    /* reject nonsense sizes */
-   if (inlen > MAXBLOCKSIZE || inlen < 16) {
+   if (inlen > (512/3) || inlen < 16) {
       return CRYPT_INVALID_ARG;
       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)
                     const unsigned char *md, int *stat, rsa_key *key)
 {
 {
    unsigned long rsa_size, x, y, z;
    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;
    int err;
 
 
-   _ARGCHK(sig != NULL);
-   _ARGCHK(md != NULL);
+   _ARGCHK(sig  != NULL);
+   _ARGCHK(md   != NULL);
    _ARGCHK(stat != NULL);
    _ARGCHK(stat != NULL);
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
 
 
    /* always be incorrect by default */
    /* always be incorrect by default */
    *stat = 0;
    *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];
    unsigned char t[33];
    static const int rounds[3] = { 8, 12, 16 };
    static const int rounds[3] = { 8, 12, 16 };
 
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(skey != NULL);
    _ARGCHK(skey != NULL);
 
 
    /* check arguments */
    /* check arguments */
@@ -316,8 +316,8 @@ void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ke
    unsigned char b[16];
    unsigned char b[16];
    int x;
    int x;
 
 
-   _ARGCHK(pt != NULL);
-   _ARGCHK(ct != NULL);
+   _ARGCHK(pt   != NULL);
+   _ARGCHK(ct   != NULL);
    _ARGCHK(skey != NULL);
    _ARGCHK(skey != NULL);
 
 
    /* do eight rounds */
    /* do eight rounds */
@@ -372,8 +372,8 @@ void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ke
    unsigned char b[16];
    unsigned char b[16];
    int x;
    int x;
 
 
-   _ARGCHK(pt != NULL);
-   _ARGCHK(ct != NULL);
+   _ARGCHK(pt   != NULL);
+   _ARGCHK(ct   != NULL);
    _ARGCHK(skey != NULL);
    _ARGCHK(skey != NULL);
 
 
    /* do eight rounds */
    /* do eight rounds */

+ 1 - 1
sha224.c

@@ -69,7 +69,7 @@ int  sha224_test(void)
     },
     },
     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
       { 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76,
       { 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,
         0x01, 0x50, 0xb0, 0xc6, 0x45, 0x5c, 0xb4,
         0xf5, 0x8b, 0x19, 0x52, 0x52, 0x25, 0x25 }
         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] = {
 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. */
 /* 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;
    int x;
 
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(skey != NULL);
    _ARGCHK(skey != NULL);
 
 
    if (keylen != 10) {
    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];
    unsigned char tmp[4], tmp2[4], M[8*4];
    ulong32 A, B;
    ulong32 A, B;
 
 
-   _ARGCHK(key != NULL);
+   _ARGCHK(key  != NULL);
    _ARGCHK(skey != NULL);
    _ARGCHK(skey != NULL);
 
 
    /* invalid arguments? */
    /* invalid arguments? */
@@ -459,8 +459,8 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
     ulong32 *S1, *S2, *S3, *S4;
     ulong32 *S1, *S2, *S3, *S4;
 #endif    
 #endif    
 
 
-    _ARGCHK(pt != NULL);
-    _ARGCHK(ct != NULL);
+    _ARGCHK(pt  != NULL);
+    _ARGCHK(ct  != NULL);
     _ARGCHK(key != NULL);
     _ARGCHK(key != NULL);
     
     
 #if !defined(TWOFISH_SMALL) && !defined(__GNUC__)
 #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),
+};
+