Selaa lähdekoodia

added libtomcrypt-0.93

Tom St Denis 22 vuotta sitten
vanhempi
commit
53f7f3badd
82 muutettua tiedostoa jossa 3279 lisäystä ja 563 poistoa
  1. 11 0
      aes.c
  2. 10 0
      aes_tab.c
  3. 10 0
      base64.c
  4. 12 41
      bits.c
  5. 22 0
      blowfish.c
  6. 10 0
      cast5.c
  7. 10 0
      cbc.c
  8. 10 0
      cfb.c
  9. 19 0
      changes
  10. 3 1
      config.pl
  11. 50 6
      crypt.c
  12. 3 0
      crypt.out
  13. BIN
      crypt.pdf
  14. 169 1
      crypt.tex
  15. 26 4
      ctr.c
  16. 11 1
      demos/test.c
  17. 0 47
      demos/timer.asm
  18. 0 7
      demos/timer.c
  19. 0 51
      demos/timer.h
  20. 129 5
      demos/tv_gen.c
  21. 10 0
      des.c
  22. 10 39
      dh.c
  23. 10 0
      dh_sys.c
  24. 30 49
      dsa.c
  25. 451 0
      eax.c
  26. 10 0
      ecb.c
  27. 11 38
      ecc.c
  28. 10 0
      ecc_sys.c
  29. 10 0
      gf.c
  30. 10 0
      hash.c
  31. 10 0
      hmac.c
  32. 10 0
      keyring.c
  33. 2 2
      makefile
  34. 1 1
      makefile.cygwin_dll
  35. 1 1
      makefile.msvc
  36. 1 1
      makefile.out
  37. 10 0
      md2.c
  38. 10 0
      md4.c
  39. 13 0
      md5.c
  40. 10 0
      mem.c
  41. 96 44
      mpi.c
  42. 2 2
      mycrypt.h
  43. 3 1
      mycrypt_cipher.h
  44. 2 0
      mycrypt_custom.h
  45. 92 0
      mycrypt_hash.h
  46. 42 0
      mycrypt_pk.h
  47. 36 46
      noekeon.c
  48. 50 50
      notes/cipher_tv.txt
  49. 407 0
      notes/eax_tv.txt
  50. 407 0
      notes/ocb_tv.txt
  51. 33 33
      notes/omac_tv.txt
  52. 1 1
      notes/tech0003.txt
  53. 561 0
      ocb.c
  54. 10 0
      ofb.c
  55. 79 27
      omac.c
  56. 10 0
      packet.c
  57. 10 0
      prime.c
  58. 16 2
      rc2.c
  59. 10 0
      rc4.c
  60. 13 0
      rc5.c
  61. 12 0
      rc6.c
  62. 11 0
      rmd128.c
  63. 11 0
      rmd160.c
  64. 15 41
      rsa.c
  65. 11 0
      rsa_sys.c
  66. 11 0
      safer+.c
  67. 11 0
      safer.c
  68. 11 0
      safer_tab.c
  69. 12 0
      sha1.c
  70. 11 0
      sha224.c
  71. 14 0
      sha256.c
  72. 11 0
      sha384.c
  73. 13 0
      sha512.c
  74. 12 1
      skipjack.c
  75. 11 0
      sprng.c
  76. 11 0
      strings.c
  77. 11 0
      tiger.c
  78. 4 1
      tommath.h
  79. 28 19
      twofish.c
  80. 11 0
      twofish_tab.c
  81. 11 0
      xtea.c
  82. 11 0
      yarrow.c

+ 11 - 0
aes.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* AES implementation by Tom St Denis
  *
  * Derived from the Public Domain source code by

+ 10 - 0
aes_tab.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* The precomputed tables for AES */
 /*
 Te0[x] = S [x].[02, 01, 01, 03];

+ 10 - 0
base64.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* compliant base64 code donated by Wayne Scott ([email protected]) */
 #include "mycrypt.h"
 

+ 12 - 41
bits.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* portable way to get secure random bits to feed a PRNG */
 #include "mycrypt.h"
 
@@ -35,45 +45,8 @@ static unsigned long rng_nix(unsigned char *buf, unsigned long len,
 
 #endif /* DEVRANDOM */
 
-#ifdef SONY_PS2
-#include <eetypes.h>
-#include <eeregs.h>
-#define min(a,b) ((a) < (b) ? (a) : (b))
-// Very simple/stupid MD5-based RNG that samples "entropy" from various PS2 control registers
-static unsigned long rng_ps2(unsigned char *buf, unsigned long len, 
-                             void (*callback)(void))
-{
-  static unsigned long lastx[2] = { 0xaab7cb4b2fd3b2b9, 0xcec58aff72afe49f }; // md5sum of bits.c
-  unsigned long j;
-  unsigned int samples[10];  // number of sample data sources
-  int l;
-  hash_state md;
-
-  for (j = 0; j < len; j += sizeof(lastx)) {
-    md5_init(&md);
-    samples[0] = *T2_COUNT;
-    samples[1] = *T3_COUNT;
-    samples[2] = *IPU_TOP;
-    samples[3] = *GIF_TAG0;
-    samples[4] = *GIF_TAG1;
-    samples[5] = *GIF_TAG2;
-    samples[6] = *VIF1_CODE;
-    samples[7] = *VIF0_CODE;
-    samples[8] = *D0_MADR;
-    samples[9] = *D1_MADR;
-    md5_process(&md, (unsigned char *)(&samples[0]), sizeof(samples));
-    // include previous round
-    md5_process(&md, (unsigned char *)(&lastx[0]), sizeof(lastx));
-    md5_done(&md, (unsigned char *)(&lastx[0]));
-    l = min(sizeof(lastx), len-j);
-    memcpy(buf+j, &lastx[0], l); //min(sizeof(lastx), len-j));
-  }
-  return len;
-}
-#endif /* SONY_PS2 */
-
 /* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
-#if !defined(SONY_PS2) && defined(CLOCKS_PER_SEC)
+#if defined(CLOCKS_PER_SEC)
 
 #define ANSI_RNG
 
@@ -143,9 +116,7 @@ unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
 
    _ARGCHK(buf != NULL);
 
-#ifdef SONY_PS2
-   x = rng_ps2(buf, len, callback);   if (x != 0) { return x; }
-#elif defined(DEVRANDOM)
+#if defined(DEVRANDOM)
    x = rng_nix(buf, len, callback);   if (x != 0) { return x; }
 #endif
 #ifdef WIN32

+ 22 - 0
blowfish.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef BLOWFISH
@@ -350,7 +360,11 @@ int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
    return CRYPT_OK;
 }
 
+#ifndef __GNUC__
 #define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)]
+#else
+#define F(x) ((key->blowfish.S[0][byte(x,3)] + key->blowfish.S[1][byte(x,2)]) ^ key->blowfish.S[2][byte(x,1)]) + key->blowfish.S[3][byte(x,0)]
+#endif
 
 #ifdef CLEAN_STACK
 static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
@@ -360,16 +374,20 @@ void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
 {
    ulong32 L, R;
    int r;
+#ifndef __GNUC__
    ulong32 *S1, *S2, *S3, *S4;
+#endif
 
     _ARGCHK(pt != NULL);
     _ARGCHK(ct != NULL);
     _ARGCHK(key != NULL);
 
+#ifndef __GNUC__
     S1 = key->blowfish.S[0];
     S2 = key->blowfish.S[1];
     S3 = key->blowfish.S[2];
     S4 = key->blowfish.S[3];
+#endif
 
    /* load it */
    LOAD32H(L, &pt[0]);
@@ -408,16 +426,20 @@ void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
 {
    ulong32 L, R;
    int r;
+#ifndef __GNUC__
    ulong32 *S1, *S2, *S3, *S4;
+#endif
 
     _ARGCHK(pt != NULL);
     _ARGCHK(ct != NULL);
     _ARGCHK(key != NULL);
     
+#ifndef __GNUC__
     S1 = key->blowfish.S[0];
     S2 = key->blowfish.S[1];
     S3 = key->blowfish.S[2];
     S4 = key->blowfish.S[3];
+#endif
 
    /* load it */
    LOAD32H(R, &ct[0]);

+ 10 - 0
cast5.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* Implementation of CAST5 (RFC 2144) by Tom St Denis */
 #include "mycrypt.h"
 

+ 10 - 0
cbc.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef CBC

+ 10 - 0
cfb.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef CFB

+ 19 - 0
changes

@@ -1,3 +1,22 @@
+Jan 25th, 2004
+v0.93  -- [note: deleted v0.93 changes by accident... recreating from memory...]
+       -- Fix to RC2 to not deference pointer before ARGCHK
+       -- Fix to NOEKEON to match published test vectors as well as cleaned up the code a bit
+       -- Optimized Twofish [down to 28 cycles/byte on my box] and Blowfish
+       -- Fix to OMAC to test cipher block size first [prevents wasting any time]
+       -- Added more OMAC test vectors
+       -- Added EAX Encrypt+Authenticate support
+       -- Fix to DSA to check return of a few LTM functions I forgot [mp_to_unsigned_bin]
+       -- Added common headers to all C files
+       -- CTR mode supports big and little [default] endian counters now.  
+       -- fix to find_cipher_any() so that it can handle a fragmented cipher_descriptor table.
+       -- added find_hash_any() akin to find_cipher_any().
+       -- Added EAX code to demos/tv_gen.c  Hazaa! 
+       -- Removed SONY defines and files from codebase.
+       -- Added OCB support [patents be damned] and to demos/tv_gen.c
+       -- Merge all of the INPUT/OUTPUT BIGNUM macros (less toc) into mycrypt_pk.h
+       -- Made appropriate changes to the debug string in crypt.c
+
 Dec 24th, 2003
 v0.92  -- Updated the config.pl script so the options have more details.
        -- Updated demos/tv_gen to include RIPEMD hashes

+ 3 - 1
config.pl

@@ -62,6 +62,8 @@
    "RIPEMD160,Include RIPEMD-160 one-way hash,y",
    "HMAC,Include Hash based Message Authentication Support,y",
    "OMAC,Include OMAC1 Message Authentication Support,y",
+   "EAX_MODE,Include EAX Encrypt-and-Authenticate Support,y",
+   "OCB_MODE,Include OCB Encrypt-and-Authenticate Support,y",
 
    "BASE64,Include Base64 encoding support,y",
 
@@ -151,7 +153,7 @@ for (@settings) {
 
 # output objects
 print OUT "\ndefault: library\n\n";
-print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o\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";
 
 # 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";

+ 50 - 6
crypt.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 #include <signal.h>
 
@@ -109,13 +119,8 @@ struct _prng_descriptor prng_descriptor[TAB_SIZE] = {
 #if (ARGTYPE == 0)
 void crypt_argchk(char *v, char *s, int d)
 {
-#ifdef SONY_PS2
- printf("_ARGCHK '%s' failure on line %d of file %s\n",
-         v, d, s);
-#else
  fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n",
          v, d, s);
-#endif
  (void)raise(SIGABRT);
 }
 #endif
@@ -189,7 +194,10 @@ int find_cipher_any(const char *name, int blocklen, int keylen)
    x = find_cipher(name);
    if (x != -1) return x;
 
-   for (x = 0; cipher_descriptor[x].name != NULL && x < TAB_SIZE; x++) {
+   for (x = 0; x < TAB_SIZE; x++) {
+       if (cipher_descriptor[x].name == NULL) {
+          continue;
+       }
        if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
           return x;
        }
@@ -197,6 +205,30 @@ int find_cipher_any(const char *name, int blocklen, int keylen)
    return -1;
 }
 
+/* return first hash with at least [amount over] digestlen bytes of output */
+int find_hash_any(const char *name, int digestlen)
+{
+   int x, y, z;
+   _ARGCHK(name != NULL);
+
+   x = find_hash(name);
+   if (x != -1) return x;
+
+   y = MAXBLOCKSIZE+1;
+   z = -1;
+   for (x = 0; x < TAB_SIZE; x++) {
+       if (hash_descriptor[x].name == NULL) {
+          continue;
+       }
+       if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) {
+          z = x;
+          y = hash_descriptor[x].hashsize;
+       }
+   }
+   return z;
+}
+
+
 int register_cipher(const struct _cipher_descriptor *cipher)
 {
    int x;
@@ -494,6 +526,9 @@ const char *crypt_build_settings =
 #if defined(MECC)
     "   ECC\n"
 #endif
+#if defined(MDSA)
+    "   DSA\n"
+#endif
 #if defined(KR)
     "   KR\n"
 #endif
@@ -528,6 +563,15 @@ const char *crypt_build_settings =
 #if defined(HMAC)
     " HMAC "
 #endif
+#if defined(OMAC)
+    " OMAC "
+#endif
+#if defined(EAX_MODE)
+    " EAX_MODE "
+#endif
+#if defined(OCB_MODE)
+    " OCB_MODE "
+#endif
 #if defined(TRY_UNRANDOM_FIRST)
     " TRY_UNRANDOM_FIRST "
 #endif

+ 3 - 0
crypt.out

@@ -24,6 +24,9 @@
 \BOOKMARK [2][-]{subsection.3.4.1}{Background}{section.3.4}
 \BOOKMARK [2][-]{subsection.3.4.2}{Choice of Mode}{section.3.4}
 \BOOKMARK [2][-]{subsection.3.4.3}{Implementation}{section.3.4}
+\BOOKMARK [1][-]{section.3.5}{Encrypt and Authenticate Modes}{chapter.3}
+\BOOKMARK [2][-]{subsection.3.5.1}{EAX Mode}{section.3.5}
+\BOOKMARK [2][-]{subsection.3.5.2}{OCB Mode}{section.3.5}
 \BOOKMARK [0][-]{chapter.4}{One-Way Cryptographic Hash Functions}{}
 \BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
 \BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}

BIN
crypt.pdf


+ 169 - 1
crypt.tex

@@ -47,7 +47,7 @@
 \def\gap{\vspace{0.5ex}}
 \makeindex
 \begin{document}
-\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.92}
+\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.93}
 \author{Tom St Denis \\
 Algonquin College \\
 \\
@@ -784,6 +784,174 @@ int main(void)
 \end{verbatim}
 \end{small}
 
+\section{Encrypt and Authenticate Modes}
+
+\subsection{EAX Mode}
+LibTomCrypt provides support for a mode called EAX\footnote{See 
+M. Bellare, P. Rogaway, D. Wagner, A Conventional Authenticated-Encryption Mode.} in a manner similar to the
+way it was intended to be used.
+
+First a short description of what EAX mode is before I explain how to use it.  EAX is a mode that requires a cipher,
+CTR and OMAC support and provides encryption and authentication.  It is initialized with a random ``nonce'' that can
+be shared publicly as well as a ``header'' which can be fixed and public as well as a random secret symmetric key.
+
+The ``header'' data is meant to be meta-data associated with a stream that isn't private (e.g. protocol messages).  It can
+be added at anytime during an EAX stream and is part of the authentication tag.  That is, changes in the meta-data can
+be detected by an invalid output tag.
+
+The mode can then process plaintext producing ciphertext as well as compute a partial checksum.  The actual checksum
+called a ``tag'' is only emitted when the message is finished.  In the interim though the user can process any arbitrary
+sized message block to send to the recipient as ciphertext.  This makes the EAX mode especially suited for streaming modes
+of operation.
+
+The mode is initialized with the following function.
+\begin{verbatim}
+int eax_init(eax_state *eax, int cipher, 
+             const unsigned char *key, unsigned long keylen,
+             const unsigned char *nonce, unsigned long noncelen,
+             const unsigned char *header, unsigned long headerlen);
+\end{verbatim}
+
+Where ``eax'' is the EAX state.  ``cipher'' is the index of the desired cipher in the descriptor table.  
+``key'' is the shared secret symmetric key of length ``keylen''.  ``nonce'' is the random public string of
+length ``noncelen''.  ``header'' is the random (or fixed or \textbf{NULL}) header for the message of length
+``headerlen''.
+
+When this function completes ``eax'' will be initialized such that you can now either have data decrypted or 
+encrypted in EAX mode.  Note that if ``headerlen'' is zero you may pass ``header'' as \textbf{NULL}.  It will still
+initialize the EAX ``H'' value to the correct value.  
+
+To encrypt or decrypt data in a streaming mode use the following.
+\begin{verbatim}
+int eax_encrypt(eax_state *eax, const unsigned char *pt, 
+                unsigned char *ct, unsigned long length);
+
+int eax_decrypt(eax_state *eax, const unsigned char *ct, 
+                unsigned char *pt, unsigned long length);
+\end{verbatim}
+The function ``eax\_encrypt'' will encrypt the bytes in ``pt'' of ``length'' bytes and store the ciphertext in
+``ct''.  Note that ``ct'' and ``pt'' may be the same region in memory.   This function will also send the ciphertext
+through the OMAC function.  The function ``eax\_decrypt'' decrypts ``ct'' and stores it in ``pt''.  This also allows 
+``pt'' and ``ct'' to be the same region in memory.  
+
+Note that both of these functions allow you to send the data in any granularity but the order is important.  While
+the eax\_init() function allows you to add initial header data to the stream you can also add header data during the
+EAX stream with the following.
+
+Also note that you cannot both encrypt or decrypt with the same ``eax'' context.  For bi-directional communication you
+will need to initialize two EAX contexts (preferably with different headers and nonces).  
+
+\begin{verbatim}
+int eax_addheader(eax_state *eax, 
+                  const unsigned char *header, unsigned long length);
+\end{verbatim}
+
+This will add the ``length'' bytes from ``header'' to the given ``eax'' stream.  Once the message is finished the 
+``tag'' (checksum) may be computed with the following function.
+
+\begin{verbatim}
+int eax_done(eax_state *eax, 
+             unsigned char *tag, unsigned long *taglen);
+\end{verbatim}
+This will terminate the EAX state ``eax'' and store upto ``taglen'' bytes of the message tag in ``tag''.  The function
+then stores how many bytes of the tag were written out back into ``taglen''.
+
+The EAX mode code can be tested to ensure it matches the test vectors by calling the following function.
+\begin{verbatim}
+int eax_test(void);
+\end{verbatim}
+This requires that the AES (or Rijndael) block cipher be registered with the cipher\_descriptor table first.
+
+\subsection{OCB Mode}
+LibTomCrypt provides support for a mode called OCB\footnote{See 
+P. Rogaway, M. Bellare, J. Black, T. Krovetz, ``OCB: A Block Cipher Mode of Operation for Efficient Authenticated Encryption''.}
+in a mode somewhat similar to as it was meant to be used.
+
+OCB is an encryption protocol that simultaneously provides authentication.  It is slightly faster to use than EAX mode
+but is less flexible.  Let's review how to initialize an OCB context.
+
+\begin{verbatim}
+int ocb_init(ocb_state *ocb, int cipher, 
+             const unsigned char *key, unsigned long keylen, 
+             const unsigned char *nonce);
+\end{verbatim}
+
+This will initialize the ``ocb'' context using cipher descriptor ``cipher''.  It will use a ``key'' of length ``keylen''
+and the random ``nonce''.  Note that ``nonce'' must be a random (public) string the same length as the block ciphers
+block size (e.g. 16 for AES).
+
+This mode has no ``Associated Data'' like EAX mode does which means you cannot authenticate metadata along with the stream.
+To encrypt or decrypt data use the following.
+
+\begin{verbatim}
+int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
+int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
+\end{verbatim}
+
+This will encrypt (or decrypt for the latter) a fixed length of data from ``pt'' to ``ct'' (vice versa for the latter).  
+They assume that ``pt'' and ``ct'' are the same size as the block cipher's block size.  Note that you cannot call 
+both functions given a single ``ocb'' state.  For bi-directional communication you will have to initialize two ``ocb''
+states (with difference nonces).  Also ``pt'' and ``ct'' may point to the same location in memory.
+
+When you are finished encrypting the message you call the following function to compute the tag.
+
+\begin{verbatim}
+int ocb_done_encrypt(ocb_state *ocb, 
+                     const unsigned char *pt, unsigned long ptlen,
+                           unsigned char *ct, 
+                           unsigned char *tag, unsigned long *taglen);
+\end{verbatim}
+
+This will terminate an encrypt stream ``ocb''.  If you have trailing bytes of plaintext that will not complete a block 
+you can pass them here.  This will also encrypt the ``ptlen'' bytes in ``pt'' and store them in ``ct''.  It will also
+store upto ``taglen'' bytes of the tag into ``tag''.
+
+Note that ``ptlen'' must be less than or equal to the block size of block cipher chosen.  Also note that if you have 
+an input message equal to the length of the block size then you pass the data here (not to ocb\_encrypt()) only.  
+
+To terminate a decrypt stream and compared the tag you call the following.
+
+\begin{verbatim}
+int ocb_done_decrypt(ocb_state *ocb, 
+                     const unsigned char *ct,  unsigned long ctlen,
+                           unsigned char *pt, 
+                     const unsigned char *tag, unsigned long taglen, int *res);
+\end{verbatim}
+
+Similarly to the previous function you can pass trailing message bytes into this function.  This will compute the 
+tag of the message (internally) and then compare it against the ``taglen'' bytes of ``tag'' provided.  By default
+``res'' is set to zero.  If all ``taglen'' bytes of ``tag'' can be verified then ``res'' is set to one (authenticated
+message).
+
+To make life simpler the following two functions are provided for memory bound OCB.
+
+\begin{verbatim}
+int ocb_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen);
+\end{verbatim}
+
+This will OCB encrypt the message ``pt'' of length ``ptlen'' and store the ciphertext in ``ct''.  The length ``ptlen''
+can be any arbitrary length.  
+
+\begin{verbatim}
+int ocb_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+    const unsigned char *tag,    unsigned long taglen,
+          int           *res);
+\end{verbatim}
+
+Similarly this will OCB decrypt and compare the internally computed tag against the tag provided. ``res'' is set 
+appropriately.
+
+
+
 \chapter{One-Way Cryptographic Hash Functions}
 \section{Core Functions}
 

+ 26 - 4
ctr.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef CTR
@@ -25,6 +35,7 @@ int ctr_start(int cipher, const unsigned char *count, const unsigned char *key,
    ctr->blocklen = cipher_descriptor[cipher].block_length;
    ctr->cipher   = cipher;
    ctr->padlen   = 0;
+   ctr->mode     = 0;
    for (x = 0; x < ctr->blocklen; x++) {
        ctr->ctr[x] = count[x];
    }
@@ -54,10 +65,21 @@ int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, s
       /* is the pad empty? */
       if (ctr->padlen == ctr->blocklen) {
          /* increment counter */
-         for (x = 0; x < ctr->blocklen; x++) {
-            ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
-            if (ctr->ctr[x] != (unsigned char)0) {
-               break;
+         if (ctr->mode == 0) {
+            /* little-endian */
+            for (x = 0; x < ctr->blocklen; x++) {
+               ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
+               if (ctr->ctr[x] != (unsigned char)0) {
+                  break;
+               }
+            }
+         } else {
+            /* big-endian */
+            for (x = ctr->blocklen-1; x >= 0; x--) {
+               ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
+               if (ctr->ctr[x] != (unsigned char)0) {
+                  break;
+               }
             }
          }
 

+ 11 - 1
demos/test.c

@@ -1837,11 +1837,21 @@ main (void)
   if (hmac_test() != CRYPT_OK) exit(EXIT_FAILURE);
 #endif
 
-#ifdef HMAC
+#ifdef OMAC
   printf ("OMAC: %s\n", omac_test () == CRYPT_OK ? "passed" : "failed");
   if (omac_test() != CRYPT_OK) exit(EXIT_FAILURE);
 #endif
 
+#ifdef EAX_MODE
+  printf ("EAX : %s\n", eax_test () == CRYPT_OK ? "passed" : "failed");
+  if (eax_test() != CRYPT_OK) exit(EXIT_FAILURE);
+#endif
+
+#ifdef OCB_MODE
+  printf ("OCB : %s\n", ocb_test () == CRYPT_OK ? "passed" : "failed");
+  if (ocb_test() != CRYPT_OK) exit(EXIT_FAILURE);
+#endif
+
   store_tests ();
   cipher_tests ();
   hash_tests ();

+ 0 - 47
demos/timer.asm

@@ -1,47 +0,0 @@
-; x86 timer in NASM
-;
-; Tom St Denis, [email protected]
-[bits 32]
-[section .data]
-time dd 0, 0
-
-[section .text]
-
-%ifdef USE_ELF
-[global t_start]
-t_start:
-%else
-[global _t_start]
-_t_start:
-%endif
-   push eax
-   push ebx
-   push ecx
-   push edx
-   cpuid
-   rdtsc
-   mov [time+0],edx
-   mov [time+4],eax
-   pop edx
-   pop ecx
-   pop ebx
-   pop eax
-   ret
-   
-%ifdef USE_ELF
-[global t_read]
-t_read:
-%else
-[global _t_read]
-_t_read:
-%endif
-   push ebx
-   push ecx
-   cpuid
-   rdtsc
-   sub eax,[time+4]
-   sbb edx,[time+0]
-   pop ecx
-   pop ebx
-   ret
-   

+ 0 - 7
demos/timer.c

@@ -1,7 +0,0 @@
-/*
- * The working version of this file can be found
- * at the PlayStation(r)2 Developer Network website
- * under the libtomcrypt project.
- */
-
-#error Please download the implemented version of this file from the PlayStation(r)2 Developer Network website

+ 0 - 51
demos/timer.h

@@ -1,51 +0,0 @@
-#ifndef __TIMER_H__
-#define __TIMER_H__
-/****************************************************************************
-*
-*   Copyright (c) 2000, Sony Computer Entertainment of America Inc.
-*   All rights reserved
-*   SCEA Confidential
-*
-*    Document: TIMER.H
-*      Author: Ben Wiggins
-*        Date: 7/15/2002   
-*      Header: Timer stuff
-*
-****************************************************************************/
-/*============================================================================
-=    INTERFACE REQUIRED HEADERS
-============================================================================*/
-/*============================================================================
-=    INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
-============================================================================*/
-/*============================================================================
-=    INTERFACE STRUCTURES / UTILITY CLASSES
-============================================================================*/
-/*============================================================================
-=    INTERFACE DATA DECLARATIONS
-============================================================================*/
-/*============================================================================
-=    INTERFACE FUNCTION PROTOTYPES
-============================================================================*/
-void TIMER_Init(void);
-void TIMER_Shutdown(void);
-double TIMER_GetTime(void);
-
-#include <time.h>
-#ifdef CLOCKS_PER_SEC
-#undef CLOCKS_PER_SEC
-#endif
-#define CLOCKS_PER_SEC 576000
-extern clock_t TIMER_clock(void);
-
-/*============================================================================
-=    INTERFACE TRAILING HEADERS
-============================================================================*/
-
-/****************************************************************************
-*
-*    END HEADER TIMER.H
-*
-****************************************************************************/
-#endif // __TIMER_H__
-

+ 129 - 5
demos/tv_gen.c

@@ -269,14 +269,138 @@ void omac_gen(void)
    fclose(out);
 }
 
+void eax_gen(void)
+{
+   int err, kl, x, y1, z;
+   FILE *out;
+   unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], header[MAXBLOCKSIZE*2], 
+                 plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
+   unsigned long len;
+
+   out = fopen("eax_tv.txt", "w");
+   fprintf(out, "EAX Test Vectors.  Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key.  The outputs\n"
+                "are of the form ciphertext,tag for a given NN.  The key for step N>1 is the tag of the previous\n"
+                "step repeated sufficiently.\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, "EAX-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
+
+      /* the key */
+      for (z = 0; z < kl; z++) {
+          key[z] = (z & 255);
+      }
+      
+      for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
+         for (z = 0; z < y1; z++) {
+            plaintext[z] = (unsigned char)(z & 255);
+            nonce[z]     = (unsigned char)(z & 255);
+            header[z]    = (unsigned char)(z & 255);
+         }
+         len = sizeof(tag);
+         if ((err = eax_encrypt_authenticate_memory(x, key, kl, nonce, y1, header, y1, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
+            printf("Error EAX'ing: %s\n", error_to_string(err));
+            exit(EXIT_FAILURE);
+         }
+         fprintf(out, "%3d: ", y1);
+         for (z = 0; z < y1; z++) {
+            fprintf(out, "%02X", plaintext[z]);
+         }
+         fprintf(out, ", ");
+         for (z = 0; z <(int)len; z++) {
+            fprintf(out, "%02X", tag[z]);
+         }
+         fprintf(out, "\n");
+
+         /* forward the key */
+         for (z = 0; z < kl; z++) {
+             key[z] = tag[z % len];
+         }
+      }
+      fprintf(out, "\n");
+   }
+   fclose(out);
+}
+
+void ocb_gen(void)
+{
+   int err, kl, x, y1, z;
+   FILE *out;
+   unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], 
+                 plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
+   unsigned long len;
+
+   out = fopen("ocb_tv.txt", "w");
+   fprintf(out, "OCB Test Vectors.  Uses the 00010203...NN-1 pattern for nonce/plaintext/key.  The outputs\n"
+                "are of the form ciphertext,tag for a given NN.  The key for step N>1 is the tag of the previous\n"
+                "step repeated sufficiently.  The nonce is fixed throughout.\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, "OCB-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
+
+      /* the key */
+      for (z = 0; z < kl; z++) {
+          key[z] = (z & 255);
+      }
+
+      /* fixed nonce */
+      for (z = 0; z < cipher_descriptor[x].block_length; z++) {
+          nonce[z] = z;
+      }
+      
+      for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
+         for (z = 0; z < y1; z++) {
+            plaintext[z] = (unsigned char)(z & 255);
+         }
+         len = sizeof(tag);
+         if ((err = ocb_encrypt_authenticate_memory(x, key, kl, nonce, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
+            printf("Error OCB'ing: %s\n", error_to_string(err));
+            exit(EXIT_FAILURE);
+         }
+         fprintf(out, "%3d: ", y1);
+         for (z = 0; z < y1; z++) {
+            fprintf(out, "%02X", plaintext[z]);
+         }
+         fprintf(out, ", ");
+         for (z = 0; z <(int)len; z++) {
+            fprintf(out, "%02X", tag[z]);
+         }
+         fprintf(out, "\n");
+
+         /* forward the key */
+         for (z = 0; z < kl; z++) {
+             key[z] = tag[z % len];
+         }
+      }
+      fprintf(out, "\n");
+   }
+   fclose(out);
+}
+
 int main(void)
 {
    reg_algs();
-   hash_gen();
-   cipher_gen();
-   hmac_gen();
-   omac_gen();
-   
+   printf("Generating hash   vectors..."); fflush(stdout); hash_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 OMAC   vectors..."); fflush(stdout); omac_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");
    return 0;
 }
 

+ 10 - 0
des.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* DES code submitted by Dobes Vandermeer */
 #include "mycrypt.h"
 

+ 10 - 39
dh.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef MDH
@@ -279,45 +289,6 @@ void dh_free(dh_key *key)
    mp_clear_multi(&key->x, &key->y, NULL);
 }
 
-#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 INPUT_BIGNUM(num, in, x, y)                              \
-{                                                                \
-     /* load value */                                            \
-     if (y + 4 > inlen) {                                        \
-        err = CRYPT_INVALID_PACKET;                            \
-        goto error;                                              \
-     }                                                           \
-     LOAD32L(x, in+y);                                           \
-     y += 4;                                                     \
-                                                                 \
-     /* sanity check... */                                       \
-     if (x+y > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                            \
-        goto error;                                              \
-     }                                                           \
-                                                                 \
-     /* load it */                                               \
-     if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != MP_OKAY) {\
-        err = mpi_to_ltc_error(err);                                      \
-        goto error;                                              \
-     }                                                           \
-     y += x;                                                     \
-     if ((err = mp_shrink(num)) != MP_OKAY) {                            \
-        err = mpi_to_ltc_error(err);                                       \
-        goto error;                                              \
-     }                                                           \
-}
-
-
 int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
 {
    unsigned char buf2[1536];

+ 10 - 0
dh_sys.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
                          unsigned char *out,  unsigned long *len,
                          prng_state *prng, int wprng, int hash,

+ 30 - 49
dsa.c

@@ -1,9 +1,17 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef MDSA
 
-#define DRAW(x) { char __buf[1000]; mp_toradix(x, __buf, 16); printf("\n%s == %s\n", #x, __buf); }
-
 int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
 {
    mp_int tmp, tmp2;
@@ -80,7 +88,7 @@ int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size,
          err = CRYPT_ERROR_READPRNG;
          goto error2;
       }
-      if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY)              { goto error; }
+      if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY)           { goto error; }
    } while (mp_cmp_d(&key->x, 1) != MP_GT);
    if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != MP_OKAY)              { goto error; }
    
@@ -146,14 +154,23 @@ int dsa_sign_hash(const unsigned char *in,  unsigned long inlen,
    if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY)               { goto error; }
 
 retry:
-   /* gen random k */
-   if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
-      err = CRYPT_ERROR_READPRNG;
-      goto done;
-   }
 
-   /* read k */
-   if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY)                   { goto error; }
+   do {
+      /* gen random k */
+      if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
+         err = CRYPT_ERROR_READPRNG;
+         goto done;
+      }
+
+      /* read k */
+      if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY)                { goto error; }
+
+      /* k > 1 ? */
+      if (mp_cmp_d(&k, 1) != MP_GT)                                                   { goto retry; }
+
+      /* test gcd */
+      if ((err = mp_gcd(&k, &key->q, &tmp)) != MP_OKAY)                               { goto error; }
+   } while (mp_cmp_d(&tmp, 1) != MP_EQ);
 
    /* now find 1/k mod q */
    if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY)                              { goto error; }
@@ -190,7 +207,7 @@ retry:
    out[y++] = (len & 255);
    
    /* store r */
-   mp_to_unsigned_bin(&r, out+y);
+   if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY)                              { goto error; }
    y += len;
 
    /* store length of s */
@@ -199,7 +216,7 @@ retry:
    out[y++] = (len & 255);
    
    /* store s */
-   mp_to_unsigned_bin(&s, out+y);
+   if ((err = mp_to_unsigned_bin(&s, out+y)) != MP_OKAY)                              { goto error; }
    y += len;
 
    /* reset size */
@@ -297,19 +314,11 @@ done  : mp_clear_multi(&r, &s, &w, &v, &u1, &u2, NULL);
    return err;
 }
 
-#define OUTPUT_BIGNUM(num, buf2, y, z)         \
-{                                              \
-      z = (unsigned long)mp_unsigned_bin_size(num);  \
-      if ((y + 4 + z) > *outlen) { return CRYPT_BUFFER_OVERFLOW; } \
-      STORE32L(z, out+y);                     \
-      y += 4;                                  \
-      if (mp_to_unsigned_bin(num, out+y) != MP_OKAY) { return CRYPT_MEM; }  \
-      y += z;                                  \
-}
 
 int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key)
 {
    unsigned long y, z;
+   int err;
 
    _ARGCHK(out != NULL);
    _ARGCHK(outlen != NULL);
@@ -352,34 +361,6 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_key *key
    return CRYPT_OK;
 }
 
-#define INPUT_BIGNUM(num, in, x, y)                              \
-{                                                                \
-     /* load value */                                            \
-     if (y+4 > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                              \
-        goto error;                                              \
-     }                                                           \
-     LOAD32L(x, in+y);                                           \
-     y += 4;                                                     \
-                                                                 \
-     /* sanity check... */                                       \
-     if (y+x > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                              \
-        goto error;                                              \
-     }                                                           \
-                                                                 \
-     /* load it */                                               \
-     if (mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x) != MP_OKAY) {\
-        err = CRYPT_MEM;                                         \
-        goto error;                                              \
-     }                                                           \
-     y += x;                                                     \
-     if (mp_shrink(num) != MP_OKAY) {                            \
-        err = CRYPT_MEM;                                         \
-        goto error;                                              \
-     }                                                           \
-}
-
 int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
 {
    unsigned long x, y;

+ 451 - 0
eax.c

@@ -0,0 +1,451 @@
+/* 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
+ */
+#include "mycrypt.h"
+
+#ifdef EAX_MODE
+
+int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
+             const unsigned char *nonce, unsigned long noncelen,
+             const unsigned char *header, unsigned long headerlen)
+{
+   unsigned char buf[MAXBLOCKSIZE];
+   int           err, blklen;
+   omac_state    omac;
+   unsigned long len;
+
+
+   _ARGCHK(eax != NULL);
+   _ARGCHK(key != NULL);
+   _ARGCHK(nonce != NULL);
+   if (headerlen > 0) {
+      _ARGCHK(header != NULL);
+   }
+
+   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
+      return err;
+   }
+   blklen = cipher_descriptor[cipher].block_length;
+
+   /* N = OMAC_0K(nonce) */
+   zeromem(buf, sizeof(buf));
+   if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* omac the [0]_n */
+   if ((err = omac_process(&omac, buf, blklen)) != CRYPT_OK) {
+      return err;
+   }
+   /* omac the nonce */
+   if ((err = omac_process(&omac, nonce, noncelen)) != CRYPT_OK) {
+      return err;
+   }
+   /* store result */
+   len = sizeof(eax->N);
+   if ((err = omac_done(&omac, eax->N, &len)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* H = OMAC_1K(header) */
+   zeromem(buf, sizeof(buf));
+   buf[blklen - 1] = 1;
+
+   if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* omac the [1]_n */
+   if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) {
+      return err;
+   }
+   /* omac the header */
+   if (headerlen != 0) {
+      if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) {
+         return err;
+      }
+   }
+
+   /* note we don't finish the headeromac, this allows us to add more header later */
+
+   /* setup the CTR mode */
+   if ((err = ctr_start(cipher, eax->N, key, keylen, 0, &eax->ctr)) != CRYPT_OK) {
+      return err;
+   }
+   /* use big-endian counter */
+   eax->ctr.mode = 1;
+
+   /* setup the OMAC for the ciphertext */
+   if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) { 
+      return err;
+   }
+
+   /* omac [2]_n */
+   zeromem(buf, sizeof(buf));
+   buf[blklen-1] = 2;
+   if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) {
+      return err;
+   }
+
+#ifdef CLEAN_STACK
+   zeromem(buf, sizeof(buf));
+   zeromem(&omac, sizeof(omac));
+#endif
+   return CRYPT_OK;
+}
+
+int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length)
+{
+   int err;
+   
+   _ARGCHK(eax != NULL);
+   _ARGCHK(pt  != NULL);
+   _ARGCHK(ct  != NULL);
+
+   /* encrypt */
+   if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* omac ciphertext */
+   return omac_process(&eax->ctomac, ct, length);
+}
+
+int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length)
+{
+   int err;
+   
+   _ARGCHK(eax != NULL);
+   _ARGCHK(pt  != NULL);
+   _ARGCHK(ct  != NULL);
+
+   /* omac ciphertext */
+   if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* decrypt  */
+   return ctr_decrypt(ct, pt, length, &eax->ctr);
+}
+
+/* add header (metadata) to the stream */
+int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length)
+{
+   _ARGCHK(eax != NULL);
+   _ARGCHK(header != NULL);
+   return omac_process(&eax->headeromac, header, length);
+}
+
+int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen)
+{
+   int           err;
+   unsigned char headermac[MAXBLOCKSIZE], ctmac[MAXBLOCKSIZE];
+   unsigned long x, len;
+
+   _ARGCHK(eax != NULL);
+   _ARGCHK(tag != NULL);
+   _ARGCHK(taglen != NULL);
+
+   /* finish ctomac */
+   len = sizeof(ctmac);
+   if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* finish headeromac */
+
+   /* note we specifically don't reset len so the two lens are minimal */
+
+   if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* compute N xor H xor C */
+   for (x = 0; x < len && x < *taglen; x++) {
+       tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x];
+   }
+   *taglen = x;
+
+#ifdef CLEAN_STACK
+   zeromem(ctmac, sizeof(ctmac));
+   zeromem(headermac, sizeof(headermac));
+#endif
+
+   return CRYPT_OK;
+}
+
+int eax_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen)
+{
+   int err;
+   eax_state eax;
+
+   if ((err = eax_init(&eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
+      return err;
+   }
+
+   if ((err = eax_encrypt(&eax, pt, ct, ptlen)) != CRYPT_OK) {
+      return err;
+   }
+ 
+   if ((err = eax_done(&eax, tag, taglen)) != CRYPT_OK) {
+      return err;
+   }
+
+#ifdef CLEAN_STACK
+   zeromem(&eax, sizeof(eax));
+#endif
+   return CRYPT_OK;
+}
+
+int eax_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+          unsigned char *tag,    unsigned long taglen,
+          int           *res)
+{
+   int err;
+   eax_state eax;
+   unsigned char buf[MAXBLOCKSIZE];
+   unsigned long buflen;
+
+   _ARGCHK(res != NULL);
+
+   /* default to zero */
+   *res = 0;
+
+   if ((err = eax_init(&eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
+      return err;
+   }
+
+   if ((err = eax_decrypt(&eax, ct, pt, ctlen)) != CRYPT_OK) {
+      return err;
+   }
+ 
+   buflen = MIN(sizeof(buf), taglen);
+   if ((err = eax_done(&eax, buf, &buflen)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* compare tags */
+   if (buflen >= taglen && memcmp(buf, tag, taglen) == 0) {
+      *res = 1;
+   }
+
+#ifdef CLEAN_STACK
+   zeromem(&eax, sizeof(eax));
+   zeromem(buf, sizeof(buf));
+#endif
+   return CRYPT_OK;
+}
+
+int eax_test(void)
+{
+#ifndef LTC_TEST
+   return CRYPT_NOP;
+#else
+   static const struct {
+       int               keylen, 
+                       noncelen, 
+                      headerlen, 
+                         msglen;
+
+       unsigned char        key[MAXBLOCKSIZE], 
+                          nonce[MAXBLOCKSIZE], 
+                         header[MAXBLOCKSIZE], 
+                      plaintext[MAXBLOCKSIZE],
+                     ciphertext[MAXBLOCKSIZE], 
+                            tag[MAXBLOCKSIZE];
+   } tests[] = {
+
+/* NULL message */
+{
+   16, 0, 0, 0,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0 },
+   /* header */
+   { 0 },
+   /* plaintext */
+   { 0 },
+   /* ciphertext */
+   { 0 },
+   /* tag */
+   { 0x9a, 0xd0, 0x7e, 0x7d, 0xbf, 0xf3, 0x01, 0xf5,
+     0x05, 0xde, 0x59, 0x6b, 0x96, 0x15, 0xdf, 0xff }
+},
+
+/* test with nonce */
+{
+   16, 16, 0, 0,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* header */
+   { 0 },
+   /* plaintext */
+   { 0 },
+   /* ciphertext */
+   { 0 },
+   /* tag */
+   { 0x1c, 0xe1, 0x0d, 0x3e, 0xff, 0xd4, 0xca, 0xdb,
+     0xe2, 0xe4, 0x4b, 0x58, 0xd6, 0x0a, 0xb9, 0xec }
+},
+
+/* test with header [no nonce]  */
+{
+   16, 0, 16, 0,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0 },
+   /* header */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* plaintext */
+   { 0 },
+   /* ciphertext */
+   { 0 },
+   /* tag */
+   { 0x3a, 0x69, 0x8f, 0x7a, 0x27, 0x0e, 0x51, 0xb0,
+     0xf6, 0x5b, 0x3d, 0x3e, 0x47, 0x19, 0x3c, 0xff }
+},
+
+/* test with header + nonce + plaintext */
+{
+   16, 16, 16, 32,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },  
+   /* header */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* plaintext */
+   { 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 },
+   /* ciphertext */
+   { 0x29, 0xd8, 0x78, 0xd1, 0xa3, 0xbe, 0x85, 0x7b,
+     0x6f, 0xb8, 0xc8, 0xea, 0x59, 0x50, 0xa7, 0x78,
+     0x33, 0x1f, 0xbf, 0x2c, 0xcf, 0x33, 0x98, 0x6f,
+     0x35, 0xe8, 0xcf, 0x12, 0x1d, 0xcb, 0x30, 0xbc },
+   /* tag */
+   { 0x4f, 0xbe, 0x03, 0x38, 0xbe, 0x1c, 0x8c, 0x7e,
+     0x1d, 0x7a, 0xe7, 0xe4, 0x5b, 0x92, 0xc5, 0x87 }
+},
+
+/* test with header + nonce + plaintext [not even sizes!] */
+{
+   16, 15, 14, 29,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e },  
+   /* header */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d },
+   /* plaintext */
+   { 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 },
+   /* ciphertext */
+   { 0xdd, 0x25, 0xc7, 0x54, 0xc5, 0xb1, 0x7c, 0x59,
+     0x28, 0xb6, 0x9b, 0x73, 0x15, 0x5f, 0x7b, 0xb8,
+     0x88, 0x8f, 0xaf, 0x37, 0x09, 0x1a, 0xd9, 0x2c,
+     0x8a, 0x24, 0xdb, 0x86, 0x8b },
+   /* tag */
+   { 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2,
+     0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda }
+},
+};
+   int err, x, idx, res;
+   unsigned long len;
+   unsigned char outct[MAXBLOCKSIZE], 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 = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen,
+            tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
+            tests[x].plaintext, tests[x].msglen, outct, outtag, &len)) != CRYPT_OK) {
+           return err;
+        }
+        if (memcmp(outct, tests[x].ciphertext, tests[x].msglen) || memcmp(outtag, tests[x].tag, len)) {
+#if 0
+           unsigned long y;
+           printf("\n\nFailure: \nCT:\n");
+           for (y = 0; y < (unsigned long)tests[x].msglen; ) {
+               printf("0x%02x", outct[y]);
+               if (y < (unsigned long)(tests[x].msglen-1)) printf(", ");
+               if (!(++y % 8)) printf("\n");
+           }
+           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;
+        }
+
+        /* test decrypt */
+        if ((err = eax_decrypt_verify_memory(idx, tests[x].key, tests[x].keylen,
+             tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
+             outct, tests[x].msglen, outct, outtag, len, &res)) != CRYPT_OK) {
+            return err;
+        }
+        if (res != 1 || memcmp(outct, tests[x].plaintext, tests[x].msglen)) {
+#if 0
+           unsigned long y;
+           printf("\n\nFailure (res == %d): \nPT:\n", res);
+           for (y = 0; y < (unsigned long)tests[x].msglen; ) {
+               printf("0x%02x", outct[y]);
+               if (y < (unsigned long)(tests[x].msglen-1)) printf(", ");
+               if (!(++y % 8)) printf("\n");
+           }
+           printf("\n\n");
+#endif
+           return CRYPT_FAIL_TESTVECTOR;
+        }
+
+     }
+     return CRYPT_OK;
+#endif /* LTC_TEST */
+}
+
+#endif /* EAX_MODE */

+ 10 - 0
ecb.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef ECB

+ 11 - 38
ecc.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
  *
  * All curves taken from NIST recommendation paper of July 1999
@@ -743,44 +754,6 @@ done:
    return res;
 }
 
-#define OUTPUT_BIGNUM(num, buf2, y, z)         \
-{                                              \
-      z = (unsigned long)mp_unsigned_bin_size(num);  \
-      STORE32L(z, buf2+y);                     \
-      y += 4;                                  \
-      if (mp_to_unsigned_bin(num, buf2+y) != MP_OKAY) { return CRYPT_MEM; }   \
-      y += z;                                  \
-}
-
-
-#define INPUT_BIGNUM(num, in, x, y)                              \
-{                                                                \
-     /* load value */                                            \
-     if (y+4 > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                              \
-        goto error;                                              \
-     }                                                           \
-     LOAD32L(x, in+y);                                           \
-     y += 4;                                                     \
-                                                                 \
-     /* sanity check... */                                       \
-     if (y+x > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                              \
-        goto error;                                              \
-     }                                                           \
-                                                                 \
-     /* load it */                                               \
-     if (mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x) != MP_OKAY) {\
-        err = CRYPT_MEM;                                         \
-        goto error;                                              \
-     }                                                           \
-     y += x;                                                     \
-     if (mp_shrink(num) != MP_OKAY) {                            \
-        err = CRYPT_MEM;                                         \
-        goto error;                                              \
-     }                                                           \
-}
-
 int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
 {
    unsigned long y, z;

+ 10 - 0
ecc_sys.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
                           unsigned char *out,  unsigned long *len, 
                           prng_state *prng, int wprng, int hash, 

+ 10 - 0
gf.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* polynomial basis GF(2^w) routines */
 #include "mycrypt.h"
 

+ 10 - 0
hash.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen)

+ 10 - 0
hmac.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* Submited by Dobes Vandermeer  ([email protected]) */
 
 #include "mycrypt.h"

+ 10 - 0
keyring.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* Provides keyring functionality for libtomcrypt, Tom St Denis */
 #include <mycrypt.h>
 

+ 2 - 2
makefile

@@ -9,7 +9,7 @@
 # a build. This is easy to remedy though, for those that have problems.
 
 # The version
-VERSION=0.92
+VERSION=0.93
 
 #ch1-01-1
 # Compiler and Linker Names
@@ -66,7 +66,7 @@ OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \
 bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \
 md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o \
 safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
-prime.o twofish.o packet.o hmac.o strings.o rmd128.o rmd160.o skipjack.o omac.o dsa.o $(MPIOBJECT)
+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)
 
 TESTOBJECTS=demos/test.o
 HASHOBJECTS=demos/hashsum.o

+ 1 - 1
makefile.cygwin_dll

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

+ 1 - 1
makefile.msvc

@@ -11,7 +11,7 @@ bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj s
 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 \
 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
+skipjack.obj omac.obj dsa.obj eax.obj ocb.obj
 
 library: $(OBJECTS)
 	lib /out:tomcrypt.lib $(OBJECTS)

+ 1 - 1
makefile.out

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

+ 10 - 0
md2.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* MD2 (RFC 1319) hash function implementation by Tom St Denis */
 #include "mycrypt.h"
 

+ 10 - 0
md4.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* Submitted by Dobes Vandermeer  ([email protected]) */
 #include "mycrypt.h"
 

+ 13 - 0
md5.c

@@ -1,3 +1,16 @@
+/* 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
+ */
+
+/* MD5 hash function by Tom St Denis */
+
 #include "mycrypt.h"
 
 #ifdef MD5

+ 10 - 0
mem.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 void zeromem(void *dst, size_t len)

+ 96 - 44
mpi.c

@@ -1902,7 +1902,7 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
         t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
 
         /* now subtract 3 * [w/3] from w, to get the remainder */
-        w -= (t << ((mp_word)1)) + t;
+        w -= t+t+t;
 
         /* fixup the remainder as required since
          * the optimization is not exact.
@@ -1966,8 +1966,7 @@ static int s_is_power_of_two(mp_digit b, int *p)
 }
 
 /* single digit division (based on routine from MPI) */
-int
-mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
 {
   mp_int  q;
   mp_word w;
@@ -2665,6 +2664,79 @@ __M:
 
 /* End: bn_mp_exptmod_fast.c */
 
+/* Start: bn_mp_exteuclid.c */
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, [email protected], http://math.libtomcrypt.org
+ */
+#include <tommath.h>
+
+/* Extended euclidean algorithm of (a, b) produces 
+   a*u1 + b*u2 = u3
+ */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
+{
+   mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
+   int err;
+
+   if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   /* initialize, (u1,u2,u3) = (1,0,a) */
+   mp_set(&u1, 1);
+   if ((err = mp_copy(a, &u3)) != MP_OKAY)                                        { goto _ERR; }
+
+   /* initialize, (v1,v2,v3) = (0,1,b) */
+   mp_set(&v2, 1);
+   if ((err = mp_copy(b, &v3)) != MP_OKAY)                                        { goto _ERR; }
+
+   /* loop while v3 != 0 */
+   while (mp_iszero(&v3) == MP_NO) {
+       /* q = u3/v3 */
+       if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY)                         { goto _ERR; }
+
+       /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
+       if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY)                             { goto _ERR; }
+       if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY)                             { goto _ERR; }
+       if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY)                             { goto _ERR; }
+
+       /* (u1,u2,u3) = (v1,v2,v3) */
+       if ((err = mp_copy(&v1, &u1)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&v2, &u2)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&v3, &u3)) != MP_OKAY)                                  { goto _ERR; }
+
+       /* (v1,v2,v3) = (t1,t2,t3) */
+       if ((err = mp_copy(&t1, &v1)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&t2, &v2)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&t3, &v3)) != MP_OKAY)                                  { goto _ERR; }
+   }
+
+   /* copy result out */
+   if (U1 != NULL) { mp_exch(U1, &u1); }
+   if (U2 != NULL) { mp_exch(U2, &u2); }
+   if (U3 != NULL) { mp_exch(U3, &u3); }
+
+   err = MP_OKAY;
+_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
+   return err;
+}
+
+/* End: bn_mp_exteuclid.c */
+
 /* Start: bn_mp_fread.c */
 /* LibTomMath, multiple-precision integer library -- Tom St Denis
  *
@@ -2752,11 +2824,10 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
    char *buf;
    int err, len, x;
    
-   len = mp_radix_size(a, radix);
-   if (len == 0) {
-      return MP_VAL;
+   if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
+      return err;
    }
-   
+
    buf = XMALLOC (len);
    if (buf == NULL) {
       return MP_MEM;
@@ -4201,7 +4272,6 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
     } else {
       res = s_mp_mul (a, b, c);
     }
-
   }
   c->sign = neg;
   return res;
@@ -5251,26 +5321,28 @@ error:
 #include <tommath.h>
 
 /* returns size of ASCII reprensentation */
-int
-mp_radix_size (mp_int * a, int radix)
+int mp_radix_size (mp_int * a, int radix, int *size)
 {
   int     res, digs;
   mp_int  t;
   mp_digit d;
 
+  *size = 0;
+
   /* special case for binary */
   if (radix == 2) {
-    return mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+    *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+    return MP_OKAY;
   }
 
   /* make sure the radix is in range */
   if (radix < 2 || radix > 64) {
-    return 0;
+    return MP_VAL;
   }
 
   /* init a copy of the input */
   if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
-    return 0;
+    return res;
   }
 
   /* digs is the digit count */
@@ -5293,7 +5365,8 @@ mp_radix_size (mp_int * a, int radix)
   mp_clear (&t);
 
   /* return digs + 1, the 1 is for the NULL byte that would be required. */
-  return digs + 1;
+  *size = digs + 1;
+  return MP_OKAY;
 }
 
 
@@ -5392,8 +5465,7 @@ mp_rand (mp_int * a, int digits)
 #include <tommath.h>
 
 /* read a string [ASCII] in a given radix */
-int
-mp_read_radix (mp_int * a, char *str, int radix)
+int mp_read_radix (mp_int * a, char *str, int radix)
 {
   int     y, res, neg;
   char    ch;
@@ -5989,7 +6061,7 @@ int mp_set_int (mp_int * a, unsigned long b)
 int mp_shrink (mp_int * a)
 {
   mp_digit *tmp;
-  if (a->alloc != a->used) {
+  if (a->alloc != a->used && a->used > 0) {
     if ((tmp = OPT_CAST XREALLOC (a->dp, sizeof (mp_digit) * a->used)) == NULL) {
       return MP_MEM;
     }
@@ -6019,8 +6091,7 @@ int mp_shrink (mp_int * a)
 #include <tommath.h>
 
 /* get the size for an signed equivalent */
-int
-mp_signed_bin_size (mp_int * a)
+int mp_signed_bin_size (mp_int * a)
 {
   return 1 + mp_unsigned_bin_size (a);
 }
@@ -6049,6 +6120,7 @@ int
 mp_sqr (mp_int * a, mp_int * b)
 {
   int     res;
+
   /* use Toom-Cook? */
   if (a->used >= TOOM_SQR_CUTOFF) {
     res = mp_toom_sqr(a, b);
@@ -6892,8 +6964,7 @@ ERR:
 #include <tommath.h>
 
 /* stores a bignum as a ASCII string in a given radix (2..64) */
-int
-mp_toradix (mp_int * a, char *str, int radix)
+int mp_toradix (mp_int * a, char *str, int radix)
 {
   int     res, digs;
   mp_int  t;
@@ -7086,25 +7157,7 @@ static const struct {
 {  1408,     3 },
 {  1536,     3 },
 {  1664,     3 },
-{  1792,     2 },
-{  1920,     2 },
-{  2048,     2 },
-{  2176,     2 },
-{  2304,     2 },
-{  2432,     2 },
-{  2560,     2 },
-{  2688,     2 },
-{  2816,     2 },
-{  2944,     2 },
-{  3072,     2 },
-{  3200,     2 },
-{  3328,     2 },
-{  3456,     2 },
-{  3584,     2 },
-{  3712,     2 },
-{  3840,     1 },
-{  3968,     1 },
-{  4096,     1 } };
+{  1792,     2 } };
 
 /* returns # of RM trials required for a given bit size */
 int mp_prime_rabin_miller_trials(int size)
@@ -7351,8 +7404,7 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
    #define TAB_SIZE 256
 #endif
 
-int
-s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
 {
   mp_int  M[TAB_SIZE], res, mu;
   mp_digit buf;
@@ -7516,10 +7568,10 @@ s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
 
       /* then multiply */
       if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
-        goto __MU;
+        goto __RES;
       }
       if ((err = mp_reduce (&res, P, &mu)) != MP_OKAY) {
-        goto __MU;
+        goto __RES;
       }
 
       /* empty window and reset */

+ 2 - 2
mycrypt.h

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

+ 3 - 1
mycrypt_cipher.h

@@ -173,7 +173,7 @@ typedef struct Symmetric_CBC {
 
 /* A block cipher CTR structure */
 typedef struct Symmetric_CTR {
-   int                 cipher, blocklen, padlen;
+   int                 cipher, blocklen, padlen, mode;
    unsigned char       ctr[MAXBLOCKSIZE], pad[MAXBLOCKSIZE];
    symmetric_key       key;
 } symmetric_CTR;
@@ -364,6 +364,8 @@ extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *k
 extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
 extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
 #endif
+
+
     
 extern int find_cipher(const char *name);
 extern int find_cipher_any(const char *name, int blocklen, int keylen);

+ 2 - 0
mycrypt_custom.h

@@ -49,6 +49,8 @@
 #define RIPEMD160
 #define HMAC
 #define OMAC
+#define EAX_MODE
+#define OCB_MODE
 #define BASE64
 #define YARROW
 #define SPRNG

+ 92 - 0
mycrypt_hash.h

@@ -208,6 +208,7 @@ extern const struct _hash_descriptor rmd160_desc;
 
 extern int find_hash(const char *name);
 extern int find_hash_id(unsigned char ID);
+extern int find_hash_any(const char *name, int digestlen);
 extern int register_hash(const struct _hash_descriptor *hash);
 extern int unregister_hash(const struct _hash_descriptor *hash);
 extern int hash_is_valid(int idx);
@@ -291,3 +292,94 @@ extern int omac_file(int cipher, const unsigned char *key, unsigned long keylen,
 extern int omac_test(void);
 #endif
 
+#ifdef EAX_MODE
+
+#if !(defined(OMAC) && defined(CTR))
+   #error EAX_MODE requires OMAC and CTR
+#endif
+
+typedef struct {
+   unsigned char N[MAXBLOCKSIZE];
+   symmetric_CTR ctr;
+   omac_state    headeromac, ctomac;
+} eax_state;
+
+extern int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
+                    const unsigned char *nonce, unsigned long noncelen,
+                    const unsigned char *header, unsigned long headerlen);
+
+extern int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length);
+extern int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length);
+extern int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length);
+extern int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen);
+
+extern int eax_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen);
+
+extern int eax_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  unsigned long noncelen,
+    const unsigned char *header, unsigned long headerlen,
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+          unsigned char *tag,    unsigned long taglen,
+          int           *res);
+
+extern int eax_test(void);
+#endif /* EAX MODE */
+
+#ifdef OCB_MODE
+typedef struct {
+   unsigned char     L[MAXBLOCKSIZE],         /* L value */
+                     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 */
+                     R[MAXBLOCKSIZE],         /* R value */
+                     checksum[MAXBLOCKSIZE];  /* current checksum */
+
+   symmetric_key     key;                     /* scheduled key for cipher */
+   unsigned long     block_index;             /* index # for current block */
+   int               cipher,                  /* cipher idx */
+                     block_len,               /* length of block */
+                     poly;                    /* which set of polys to use */
+} ocb_state;
+
+extern int ocb_init(ocb_state *ocb, int cipher, 
+             const unsigned char *key, unsigned long keylen, const unsigned char *nonce);
+
+extern int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct);
+extern int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt);
+
+extern int ocb_done_encrypt(ocb_state *ocb, 
+                     const unsigned char *pt,  unsigned long ptlen,
+                           unsigned char *ct, 
+                           unsigned char *tag, unsigned long *taglen);
+
+extern int ocb_done_decrypt(ocb_state *ocb, 
+                     const unsigned char *ct,  unsigned long ctlen,
+                           unsigned char *pt, 
+                     const unsigned char *tag, unsigned long taglen, int *res);
+
+extern int ocb_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen);
+
+extern int ocb_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+    const unsigned char *tag,    unsigned long taglen,
+          int           *res);
+
+extern int ocb_test(void);
+
+#endif /* OCB_MODE */

+ 42 - 0
mycrypt_pk.h

@@ -3,6 +3,48 @@
 
 #include "tommath.h"
 
+
+/* in/out macros */
+
+#define OUTPUT_BIGNUM(num, buf2, y, z)         \
+{                                              \
+      z = (unsigned long)mp_unsigned_bin_size(num);           \
+      STORE32L(z, buf2+y);                     \
+      y += 4;                                  \
+      if ((err = mp_to_unsigned_bin(num, buf2+y)) != MP_OKAY) { return mpi_to_ltc_error(err); }   \
+      y += z;                                  \
+}
+
+
+#define INPUT_BIGNUM(num, in, x, y)                              \
+{                                                                \
+     /* load value */                                            \
+     if (y + 4 > inlen) {                                        \
+        err = CRYPT_INVALID_PACKET;                            \
+        goto error;                                              \
+     }                                                           \
+     LOAD32L(x, in+y);                                           \
+     y += 4;                                                     \
+                                                                 \
+     /* sanity check... */                                       \
+     if (x+y > inlen) {                                          \
+        err = CRYPT_INVALID_PACKET;                            \
+        goto error;                                              \
+     }                                                           \
+                                                                 \
+     /* load it */                                               \
+     if ((err = mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x)) != MP_OKAY) {\
+        err = mpi_to_ltc_error(err);                                      \
+        goto error;                                              \
+     }                                                           \
+     y += x;                                                     \
+     if ((err = mp_shrink(num)) != MP_OKAY) {                            \
+        err = mpi_to_ltc_error(err);                                       \
+        goto error;                                              \
+     }                                                           \
+}
+
+
 extern int is_prime(mp_int *, int *);
 extern int rand_prime(mp_int *N, long len, prng_state *prng, int wprng);
 extern mp_err mp_init_multi(mp_int* mp, ...);

+ 36 - 46
noekeon.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* Implementation of the Noekeon block cipher by Tom St Denis */
 #include "mycrypt.h"
 
@@ -65,15 +75,15 @@ int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetri
       return CRYPT_INVALID_ROUNDS;
    }
    
-   LOAD32L(skey->noekeon.K[0],&key[0]);
-   LOAD32L(skey->noekeon.K[1],&key[4]);
-   LOAD32L(skey->noekeon.K[2],&key[8]);
-   LOAD32L(skey->noekeon.K[3],&key[12]);
+   LOAD32H(skey->noekeon.K[0],&key[0]);
+   LOAD32H(skey->noekeon.K[1],&key[4]);
+   LOAD32H(skey->noekeon.K[2],&key[8]);
+   LOAD32H(skey->noekeon.K[3],&key[12]);
    
-   LOAD32L(skey->noekeon.dK[0],&key[0]);
-   LOAD32L(skey->noekeon.dK[1],&key[4]);
-   LOAD32L(skey->noekeon.dK[2],&key[8]);
-   LOAD32L(skey->noekeon.dK[3],&key[12]);
+   LOAD32H(skey->noekeon.dK[0],&key[0]);
+   LOAD32H(skey->noekeon.dK[1],&key[4]);
+   LOAD32H(skey->noekeon.dK[2],&key[8]);
+   LOAD32H(skey->noekeon.dK[3],&key[12]);
 
    kTHETA(skey->noekeon.dK[0], skey->noekeon.dK[1], skey->noekeon.dK[2], skey->noekeon.dK[3]);
 
@@ -95,30 +105,21 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
    _ARGCHK(pt != NULL);
    _ARGCHK(ct != NULL);
    
-   LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
-   LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
+   LOAD32H(a,&pt[0]); LOAD32H(b,&pt[4]);
+   LOAD32H(c,&pt[8]); LOAD32H(d,&pt[12]);
    
-
-#ifdef SMALL_CODE
-#define ROUND \
-       a ^= RC[r]; \
+#define ROUND(i) \
+       a ^= RC[i]; \
        THETA(key->noekeon.K, a,b,c,d); \
        PI1(a,b,c,d); \
        GAMMA(a,b,c,d); \
        PI2(a,b,c,d);
 
+#ifdef SMALL_CODE
    for (r = 0; r < 16; ++r) {
-       ROUND;
+       ROUND(r);
    }
 #else 
-
-#define ROUND(i) \
-       a ^= RC[i]; \
-       THETA(key->noekeon.K, a,b,c,d); \
-       PI1(a,b,c,d); \
-       GAMMA(a,b,c,d); \
-       PI2(a,b,c,d);
-
    ROUND( 0); ROUND( 1); ROUND( 2); ROUND( 3);
    ROUND( 4); ROUND( 5); ROUND( 6); ROUND( 7);
    ROUND( 8); ROUND( 9); ROUND(10); ROUND(11);
@@ -130,8 +131,8 @@ void noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
    a ^= RC[16];
    THETA(key->noekeon.K, a, b, c, d);
    
-   STORE32L(a,&ct[0]); STORE32L(b,&ct[4]);
-   STORE32L(c,&ct[8]); STORE32L(d,&ct[12]);
+   STORE32H(a,&ct[0]); STORE32H(b,&ct[4]);
+   STORE32H(c,&ct[8]); STORE32H(d,&ct[12]);
 }
 
 #ifdef CLEAN_STACK
@@ -157,45 +158,34 @@ void noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
    _ARGCHK(pt != NULL);
    _ARGCHK(ct != NULL);
    
-   LOAD32L(a,&ct[0]); LOAD32L(b,&ct[4]);
-   LOAD32L(c,&ct[8]); LOAD32L(d,&ct[12]);
+   LOAD32H(a,&ct[0]); LOAD32H(b,&ct[4]);
+   LOAD32H(c,&ct[8]); LOAD32H(d,&ct[12]);
    
 
-#ifdef SMALL_CODE
-
-#define ROUND \
+#define ROUND(i) \
        THETA(key->noekeon.dK, a,b,c,d); \
-       a ^= RC[r]; \
+       a ^= RC[i]; \
        PI1(a,b,c,d); \
        GAMMA(a,b,c,d); \
        PI2(a,b,c,d); 
 
+#ifdef SMALL_CODE
    for (r = 16; r > 0; --r) {
-       ROUND;
+       ROUND(r);
    }
-
 #else
-
-#define ROUND(i) \
-       THETA(key->noekeon.dK, a,b,c,d); \
-       a ^= RC[i]; \
-       PI1(a,b,c,d); \
-       GAMMA(a,b,c,d); \
-       PI2(a,b,c,d); 
-
    ROUND(16); ROUND(15); ROUND(14); ROUND(13);
    ROUND(12); ROUND(11); ROUND(10); ROUND( 9);
    ROUND( 8); ROUND( 7); ROUND( 6); ROUND( 5);
    ROUND( 4); ROUND( 3); ROUND( 2); ROUND( 1);
-
 #endif
    
 #undef ROUND
 
    THETA(key->noekeon.dK, a,b,c,d);
    a ^= RC[0];
-   STORE32L(a,&pt[0]); STORE32L(b, &pt[4]);
-   STORE32L(c,&pt[8]); STORE32L(d, &pt[12]);
+   STORE32H(a,&pt[0]); STORE32H(b, &pt[4]);
+   STORE32H(c,&pt[8]); STORE32H(d, &pt[12]);
 }
 
 #ifdef CLEAN_STACK
@@ -219,8 +209,8 @@ int noekeon_test(void)
       16,
       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
       { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
-      { 0x57, 0x9a, 0x6c, 0xe8, 0x91, 0x16, 0x52, 0x53,
-               0x32, 0x00, 0xca, 0x0a, 0x17, 0x5d, 0x28, 0x0e }
+      { 0x18, 0xa6, 0xec, 0xe5, 0x28, 0xaa, 0x79, 0x73,
+        0x28, 0xb2, 0xc0, 0x91, 0xa0, 0x2f, 0x54, 0xc5}
    }
  };
  symmetric_key key;

+ 50 - 50
notes/cipher_tv.txt

@@ -1647,56 +1647,56 @@ Key Size: 16 bytes
 
 Cipher: noekeon
 Key Size: 16 bytes
- 0: 579A6CE8911652533200CA0A175D280E
- 1: 63912A26125657DEA632A0AE4111D4EE
- 2: 0F25F642860261CDC4474D6CFC6F3D90
- 3: 5747B5798279426E91FD69C6F471B608
- 4: 298B7486227A423729EEB0BFD653DCD1
- 5: 47FFD11C5F6B5638F846FE55F9BCF192
- 6: BF7F5610C79727BFF3A0E2318F35F92C
- 7: 418713351CA5800DEFD0976872B6BD5F
- 8: 46B0BFA8FFCF1B90294AD630CEF353F7
- 9: 933E10C381138CFA2419D56BFF3DBF24
-10: F47B4FD4B400E3A5CAE5C2E2732AF77D
-11: 7BEAFF8299E5C530A9F0928195798D5D
-12: A254293BCC71E208698AFAA1C5630C29
-13: 6374FEF1DFC16151F31E71BFE476DD2B
-14: 578ADFFE69E5072E5AC617E99C2A890C
-15: DB8EABA030B5B7425A279E397260D385
-16: B886B5150FABE45F81C111317AA8E1FA
-17: 0156DE757EC43054CA2B8BD300B3A43A
-18: FB423A1AD74955E5E937DEFEBC130A96
-19: 4358F88BCA4649A5C12A2E438F7A416F
-20: B8A8B6A336B7A750EC5C8A635A1DE2C4
-21: 2397C77016C8D1FAA5913390EB66B9D1
-22: F458C608E1A35743726EDA8E94F236F6
-23: D91DCCAF1419704CF7C39DD486C48BB0
-24: 551C9932FF89212454061D77E9E58897
-25: 5FB1F24CA23AB487ACC825F900B43DEA
-26: 76DFFAFB4A7F79B5748795BBB687BA11
-27: 70D34BC18EC3DA47F5E7AF716F5E767A
-28: 4E8410F31F869487956CCA4922E4A787
-29: 68519971FD65F6076FBFDE99AE5F5878
-30: 8C1C64C7E1650F5A09822597A3E25E9B
-31: 82EE58A56C050612BC9AD23AB83B2D5F
-32: 741B22347DC979154DC4FF81ACCEB0A1
-33: 79D8A56ACA0EB5A0FD6ABB34DF4EC2AE
-34: CAA1D93E89FFEC73689B642628297342
-35: 529BC07FB15CA79BBD93F63E14899898
-36: 7027D39A8CF02F8FB14D87940ED4EA15
-37: 4CF18E695D534EF04B8C15974FA31A53
-38: 113C632737E908F45DF5238904A88B95
-39: 723A9D4DFCEE39D6A2C1D90C1AFF9FE8
-40: BEA1D634560BF4F2DB05A40B79C13413
-41: D3B75F2568C0F57E13C8A19E4AC192B6
-42: 27CCAFC6BCDFB20344102D2021879828
-43: FE94A00B65DAF91DF1E99FA2784F930D
-44: 24626085EC4C2F85968E4C60CD591E3F
-45: 2612AE4CE03A5E1066AAAEDEF388E8CE
-46: 4B8E6E59642E19874DF38BB66F65F0A5
-47: 47C145C37C2C048E73E7E85F28B2662C
-48: 79D71CD15255964407198165F32C26F4
-49: 8F02BA60E7E3FC32223CDFD308D4C6FC
+ 0: 18A6ECE528AA797328B2C091A02F54C5
+ 1: 2A570E89CD8B7EEEE2C0249C8B68682E
+ 2: 828F4F6E3F3CB82EEEF26F37B26AEA78
+ 3: A3CA71833499F244BF26F487620266A4
+ 4: 333ACCE84B0A9DE91A22D1407F9DA83C
+ 5: 224285F3DB3D0D184D53F8FFDC8008D0
+ 6: DE39E2973025FE9EC1ACDE8F06985F91
+ 7: 2F00F45A01B1B0AA979E164DC5CCFE10
+ 8: 43775F3CBEE629EF6A9BA77CA36171D9
+ 9: 1E6A67ABF1B6ACF59FB484866AC15A86
+10: 70490989E2CD2145730921CCC37F0A17
+11: 67B0DD0EA903486B1CB56591FCF42678
+12: 774AAB71FF28E49A30E1E718D98114E8
+13: DF4797990E1C65C9F6735BD967164D45
+14: DE2779DF26FC1B99F576ED4CFBAE76CB
+15: A13AD17440641B3460A01175E3274AB9
+16: 1166499165F2A1196CA2DB831F264E77
+17: 35D24A385416CF2A44AB97A4AEC45E14
+18: D3D0E0DC962B1AD1AED92F57129088B2
+19: 00EF3E246B32634ABAF8BEE31D5C592A
+20: 79BBF3F807675B9F264BABC67DF4C2AB
+21: F391F2D58F0998F24BC9E5FA75DB9E99
+22: 066EF13C2617E97E6015B86BA1E059B2
+23: 5B0E2D7AE1E2734B9D5734C87F7BE272
+24: CDF7020212B7CF21F4817829386A6F8E
+25: 24873E1A0EF4908DF85114ED9BDB0168
+26: 99904360C843472F71AB86B26DC78A00
+27: BEE70B3735A67268578FF107C328940B
+28: 97DBB283536BC8AE8DBF56F3474C7740
+29: 2F4C903975EF709E004D24DC132A8A51
+30: 3EF0859A281782F905198C607FBE5C43
+31: 2D9CD48BC6A99E86468CBDD2A55C7D5F
+32: 5518D3ED18D5E5A62752CDF0846D0C77
+33: F751E9CAF107BAD8A1F1F9C374277A6A
+34: C5BA4DE907C41221FBABC5EC43710D0C
+35: 5CA48836330870365A10E7B676695C9D
+36: 937A964E0EA4D246E97293375B167EFD
+37: C0A876CB6957717541A90CCCB034BFB8
+38: A57C93A09F9160A28D3D4DEDC987746C
+39: 1FFA1E0B5EE0F0A18425F62717254419
+40: 8411C87262AE482CFC43C3092BEAFD90
+41: 0B9BB379FB3587A9ACEEED4771D8DC20
+42: 3B32EDBF9557E1DFBCEEC269B51FA494
+43: D1104E2888679A9EF6A13AE00ED7E1FB
+44: 0EC9849BAD58A279B42B5BA629B0045B
+45: CF206E8D3399918E75DE4765DD743060
+46: 55CCEB28E27D4DC7CE2546454FFD2C33
+47: 6E2339281583420B76E1750D35296C12
+48: 7800EC3D8C344BE7F2D2812F5AFF3DA4
+49: B80F4B0BDAA54A04D5A26BCA185F4EA2
 
 
 Cipher: skipjack

+ 407 - 0
notes/eax_tv.txt

@@ -0,0 +1,407 @@
+EAX Test Vectors.  Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key.  The outputs
+are of the form ciphertext,tag for a given NN.  The key for step N>1 is the tag of the previous
+step repeated sufficiently.
+
+EAX-aes (16 byte key)
+  0: , 9AD07E7DBFF301F505DE596B9615DFFF
+  1: 47, 57C4AC75A42D05260AFA093ACD4499ED
+  2: C4E2, 26C5AB00325306772E6F6E4C8093F3D2
+  3: 16177B, 852260F91F27898D4FC176E311F6E1D1
+  4: F09F68BE, 700766CA231643B5D60C3B91B1B700C1
+  5: 8472705EDF, AC4C3359326EEA4CF71FC03E0E0292F2
+  6: 14C25EB5FD0D, 8DBD749CA79CCF11C1B370F8C975858C
+  7: F6A37F60670A85, AFBD1D5921557187504ADE61014C9622
+  8: 1AACFEAE8FBAD833, 82F477325D6F76BB81940AE25F9801C2
+  9: 069414324EC293697C, B980E21C09CA129B69E9032D980A9DC5
+ 10: D8174DE9A2FC92B7DA9C, 1E42CC58BA2C8BFD83806444EA29DB61
+ 11: 2C087DEA30F8B7EE510990, 83DB400A080C4D43CAA6EC3F1085A923
+ 12: F36B93C272A703D3422C6A11, 1370C3AF2F3392916364BBBCC2C62EC1
+ 13: A0F33477BAE2E28E6747AA3193, B626DC719528CAC65DB0EF94E35422CE
+ 14: FCF5193506052E8BFA095C1A5205, F5BD02E0B3C91CC7D6FAAA8A9A76CE6A
+ 15: 3797D7F8599B8EEAB39C56241880DC, 0B70003E77146B903F06EF294FECD517
+ 16: C4BAD0E0356FFD369110C048D45D81BE, DE7C2B1D83BE2CC8EA402ABE1038BB79
+ 17: AF5C358BD31CDCAC2F0EA5252F1C3BE1E4, 2D700986F93B22DFE6695C2A243B4E42
+ 18: 7DEF9056FBDAF491D7206B26B19DEF617AA1, E71A7D00BE972D85C77931D7591B2151
+ 19: 6E9B2C0A90BF9D38A6EA3B5D2B9B2D97F938EB, 5B483D7F15C39602C2918181E57DA341
+ 20: 7C5F68DEE9BBA3B04F11D5FC7C9C7FE6E8B5025C, 0AE6A12D37A9C10BB1A494E16705DC05
+ 21: AF0A886BF673BC72045FC074F06A0176C96105E2E6, 06B2DC9A2868C23F86D710E01E37E07B
+ 22: 5F228A986DFE4301EDBAF07A02E114F1B30932995CD1, 74EBF68627C78B1FD024A59B56B2A8FA
+ 23: 911322F60555118CBECD8DD82F186AC19514316E8D48BA, B6A8BAF2F175CD0C71B63B1EF37E185E
+ 24: E7F52730CFB808EFDB376A5D5DF31A7EF8292DC5FC37E9BC, BA2AD158A2D2E5CE01296402B592E1DB
+ 25: B3F8D7CA47D8D86E94D670AFBAFA3B8D9E186C97DC029D4705, 709D2D2B9975D4729C19D4EAC430E65E
+ 26: 7178FEC027AFADDC2C03518E75CF34D207CAC2EB1537A0DBA520, A315F034CE5E66601444402520F55DE2
+ 27: FC230B2B8522F53459D0B968421469BBA7E683ACB0190393B2870F, 48679A78E470E175CF3D3E9B46CEDFCE
+ 28: 35A641127C78C721ECDC50866C21637FDC9515E41CE60F09015EA713, 0062987222F6412B7AAF8A9ABF6FBF98
+ 29: 3D42D6C113421743C08A6F682CFA0E517D5531BB66241C02EC4DCC26F7, B1AAFE11FA2D6E0C870177DDD7F98FF0
+ 30: DAD065B4669B7C59C8392D8E7BD7E64BC01CEFFF27E335B25A328D356F0E, 8973B9B9ECF26DAB58CCF0787EE928E5
+ 31: EBE626F9E241FD233D9781C359430C982667AA26921B62E98FAEC502C01B0B, 2AC0D7052A2CDCCE8E26FEA7595198AA
+ 32: 64D842B66796A797C2B4C6905742FDF2148FFC445E192F9E03B53810C082F788, 9778B345EC12D222DCC6DBABD2651750
+
+EAX-blowfish (8 byte key)
+  0: , D8C4C23A6AC0B7B7
+  1: 2A, 5E0E4BDDB60772FB
+  2: 7695, 7581B16CCC9C45F1
+  3: EB14C8, 6223A121CFA216C7
+  4: 5A5C809C, 4A47658796337D6A
+  5: 8BC2041181, E1FBA8DBA00571FC
+  6: 89C666F015FA, 2B4A76A0E699FCFE
+  7: 86C1FA92484AF6, 31B3B738A261D6F5
+  8: D1F401C145C9328B, 4C4A045EB489F59C
+  9: 70C9C7753698324A73, AB298B5B20567EB4
+ 10: A50D9D88DC101B6DC8D2, 529DFCBFD13B8E6C
+ 11: 7CC2885C2BE79C44F28FF2, 566255022B40C81C
+ 12: 6902D58347C29250EE07981C, 34619AF18E14C690
+ 13: AB6C3C4AD3EC45143392B642DA, E6D2DD323DA175BB
+ 14: 7065B28BA8AB67B2FB7B6D5E3FAF, AEDCAA54F4B0772F
+ 15: CBBA14A74AD4ADC0EF036EDAE42D51, F2BFFA4D81BAC034
+ 16: 60A315193F58144F5701D547C79FEEED, 912FDBDB05467DF5
+
+EAX-xtea (16 byte key)
+  0: , 86881D824E3BC561
+  1: EE, 4C3505F04611D9C2
+  2: 80C8, 6A3428BEEAD60738
+  3: BF88E7, 04F1E99E9F5906C2
+  4: E06574B7, 33B0153AAEF9776F
+  5: 42D950AF63, 4A0F415640322FDF
+  6: C30F6AD46EC9, 9646FE909D2B95CB
+  7: A0049FCA856A14, A0257289C6BBF278
+  8: 2814B0C1358440E0, C4B0A2354925E887
+  9: BF4F062B52C1E489CF, B56442A3CA57A041
+ 10: 63DF433956831B8780FC, ADF9ED0B46DCA19E
+ 11: C317FD079817F50E0E8A16, 2EA0EC993FC603AE
+ 12: 2BD12FDDD81EB11660346D2A, FBC6F69125BBA88D
+ 13: 85D356536FE2843C6BBE60EDBC, BB2FEFD04F230E79
+ 14: 22493009DB01B4746F4927A8C4FB, 64CC08471D93C9AC
+ 15: C0F3C0DB08DC93FBA725D1E02DE084, 77B762213DDCCFFE
+ 16: 568B66D3112556BD98FF9339E9C002E5, C8355F508219FE0C
+
+EAX-rc5 (8 byte key)
+  0: , 169C7954341EF44D
+  1: 22, DABFDA9A0B0BA067
+  2: 2E54, 6A3D6D9AA5877C5A
+  3: 2A6ECF, 2A34A3AF5DE8919E
+  4: 9CC5F84F, D3F673EDAF75E3B5
+  5: FF5611756C, CC647FAAC8D49BF1
+  6: 74C939BEB31C, C335999CCFE8F5FA
+  7: 7976B6F7709B5F, 2A7969C5FD063A88
+  8: 421EEC5022276174, 2C9BFB1EAC3C54A2
+  9: 6A4761CD266B1C0ECB, 3EA3CCEBC85FAC4E
+ 10: 7C09201098E764239A2E, 8043ABA9BF4D5AEE
+ 11: 8CE26277562F646DE33C88, D72AED48895E3B40
+ 12: 52150F44D37D121560DA87F6, 58E865E22B485906
+ 13: BA0A73B45F93ECFBFC3AB3D8D0, 683D52FA47FB1A52
+ 14: 96546CBE01054AD24CC95DB54724, D80D0D530E5D1DDE
+ 15: 61E654BB18CD26FC36C09F874DC2C7, C65884CB9D9FEC1E
+ 16: 1D77B8BF02CDEAB4A707C07628826D5B, F18D1730C3D64701
+
+EAX-rc6 (16 byte key)
+  0: , 1DF8B0B92A3F0C951C425AF4830E63FD
+  1: 1A, 8A2959EBBE90180999994DEB7036DB85
+  2: 435D, 7EF00CB57DB7B4155DB530D75CE6B025
+  3: 08A6CF, 2ED6AF0F2D5BAB05F623D389480A01F2
+  4: A86E54D3, FC69547C8BD922A5BF2F7B26C4D20F98
+  5: ED0822E439, 0007A3C6DEFC6C912C0E5B853B520368
+  6: 7BEFC7FD4054, D32C43A4D1086D57C5BCFAEE04EBC600
+  7: 5235E58E79287C, A27E9C781327C0FC7C55410EB0C828A9
+  8: CEB5EE99BE521F4D, 547F46383987F2A3582A81A3BCF9B280
+  9: 0358B063D5F99C3770, C0A73730512CDA6AD49599775D59EDA1
+ 10: 434B9AEE07DFADD0A332, 499BD88881E558E09A8E822BE27D2496
+ 11: D47849E650F350BB622D74, 638E37A84E7FAAF8F5D77F1B061773DC
+ 12: 814592F568284085E79A024B, 9EB1405E8422FE50BC0D88D837A2C650
+ 13: 6F2B55EC91B591082053AF692E, C48F91EF01AA43A1EE3B36D233DDD48B
+ 14: 506CBDD2901838EE2F178B6953DA, 03778957F536509BFCA577B23A18F726
+ 15: 446EE435D3D1848B51BB8C5F7BE4A1, 1129EAEAADE534940546D43242A4C839
+ 16: FB9D2B150C42465B1685D8F069CC06DB, 41E2940F5DC63CB4E2FBEC25ED8A31E6
+ 17: 9684F683260107BE8FEBBEE1D3EEDAA7BD, BAE7C116F7FF96631F4ACEE95C65CEF3
+ 18: 5082B1FE48CD3AB58F63C2DCFDD4069AC736, 19AC7B8EE315CBB7131A283851B32266
+ 19: 8C72AE495B6F003A3C784D144E84E88885F78E, FA4CEC023740A8D670E351FBCF62C1CB
+ 20: 815D6361C7AE34C9D796ADF9C71ABC46AEF88BC9, 9A1F7288C61A6623B9A82748137ED7CC
+ 21: 904A853E2E96BD2B85AAB3F5DFB900E9B3642EE667, 9AA90DBDD461CAD20495DCFBCB513DD2
+ 22: 79D738A462F727B3D3C529ED999B6FDCCD991D1C5A4D, BF0987BEDDE650D73CAE7D380FED3431
+ 23: B2DEFDB7D503A84E83155A04B8DE8C8DBB68C2FC475007, B7CE900CF43CD518024123C76F6DA328
+ 24: 9E723E15439E12F6C46DF8A309AE1E97B6FD18436259CFB0, DF8B6E1E23512CC4CF5FF531A1908F69
+ 25: A7F0AD03CEBCC9202718AA164886E1026975306A664C5AC7A9, 4A771BF8B9A4325705C85E5499FD98E9
+ 26: A53A92AD1C6835F28E04EF591E783D36F3D76E489B31B87BEB7A, AA263B52A6E6A043DE4D7029D4DC73F5
+ 27: 79BE3C38291A7F77E932C8A9DEAC08DE6442EA9B3895B101A14E7B, 33B84DE06342E675E019CD0237292ED0
+ 28: FA108123C5A69571CFDFE8C3D00535121FDE3096DDC0D700F8F26A5A, 764025D7CA1A3F2C54D28956423B0C77
+ 29: 36EC2D67FD977BD2B73DB6D8EB756B3EADA13690E1B6DFC12A4781B34B, 4BC6B38DE3B02283D92F4DF19A5C48C5
+ 30: 96D3243C945905C9732B5927E46F00886D511463B38C86002FC26B65AB8C, 5B5511CDEC35687AB8425AB22D58B4F1
+ 31: 9CF83B87BEA3374AF7722E999863E3DABB858B0383383EAC7757F5B80FD44B, 1E0CBC961940FDA93B73A92DACFD67F3
+ 32: CE3BC3C9FA5EF4AFE5272B3EDD24B1B003FED2C2E501528CFF44D3FABFF52CB4, DC94FDDC78AAB2B7CAA1E1EF149AC355
+
+EAX-safer+ (16 byte key)
+  0: , B120C7B37450C46189712E4DFD1F0C44
+  1: CA, 82BA1869C5FF1EF2A4F6ADC1E7DC1F1D
+  2: DD20, 6BD5601B16C9943A84AC1F99A176E6D1
+  3: C1C09F, 0911DC63AA414C004E2BD825BECDC93B
+  4: 27E43F59, BD858F084B082F76814DC385E1FB20D1
+  5: 2A9A92F246, 5ADC4A32491934AC0BD00FCE686B26F1
+  6: 52C78C0CD6F4, F35886F46C03EDCA10B3D01CF07B1E0A
+  7: 23E0D3CED3795F, FE33D96FC98B78A30C0A412C60E93992
+  8: CD3FC9961559F239, 9982364A61609FC41068260267231EE9
+  9: 6EA46CB7AD7505C1BC, BB15053EF0F78B9091B3064118F3E9BF
+ 10: 05D9BA230A56CCA0703A, 1338E68E3DC992B6EB2685C668E75869
+ 11: 7AAD6049DFDCA6771AE42B, 35267E431051E1812495615324C4CBE6
+ 12: 8695091532B83B23C296F620, 7B2EEA861E9A91E6B6A911E10FC3FDD1
+ 13: D909DA4BC7372ACAEA78E6A0EE, EA6C1CD16180DF0B07F4E204A4B4FACB
+ 14: 7DEC8443600D0563AEFE87A2064F, DA454728069B3B409889664783588189
+ 15: C042FE656742CD2FE5D9C212D18C6C, 5929E4AECC2CA047BAE948E7023FE4D0
+ 16: 0B84D3CF59EEF7319633F4A397D47CF8, 31F892FFDB7535DF5D9143456E404163
+ 17: 8C9E57AAFA7969B142742B63AB73286600, C418231C44F96660DDBA8C26B3BB3681
+ 18: E9EED66D370A3A6A39C7E0E570D96F807EAC, A4AFE8D1D3C31B956A3BDBD043E7A665
+ 19: 1A5D47992DA5597D1449B4C8DD47B7404C7657, F3ECEE5182014FC3365FDBC4C33CC06A
+ 20: E7C7945FD1AFD3F5DCE666D8A5A2E8A3C11A7A5F, 86D78B2FBA7597B8806BED505B52BDF6
+ 21: 9E2165B47B29CBC4ACD50660E011D691F061209969, E9B1E860BD02085177E1A94E1EE6F3F0
+ 22: 48EA2945C8DD3FE09407BAC8973A861DB15B788C8FFD, 502926712EDB1B3DD13806052C6C75D7
+ 23: F37D46B35B60819EA52B00457D79155C04B55972D0DFA9, BB2B7D210BF0570F422640BF81F39B9E
+ 24: 12E85C0C78227205CC682360C79E35BF58EC6551CF8FE2D0, 042990D7A58D458C570A15DD375DB4E7
+ 25: 4F6C15109DE980DD14A7F4C27F48671E4787C53A564232F427, B097A5990D8067DD89C21473150C070F
+ 26: AAC472E49DB101B564A8A01E2C80C0C6AE9065D332C2DE79FAB6, ACDD587A7DB86542E195DF73AF1C1CBC
+ 27: B9912CE18019C31692A1F7E11D9CCB20297ACCB9DC62C47C01D2C2, B0ACBF028CA5B15E0035D2EB8CA916BE
+ 28: B4F2B1FE14A1ECDC9C8EA1A0120395E6ED1E69D3FC85DD0F3F90F350, 9A561EBC769369B95B9CB74FC6AC27D3
+ 29: 3FE397C8AD02689B7437A37861F0907AF1F6014A293B46419348771C5A, 6B7BEB9BD5018FECD71BE5081C7C2544
+ 30: 5019089142199F7207E1B7731B8B247A18A685B231499DF12A73F5D67D37, 307E93446777005BA1B088F178A0DB6E
+ 31: EAE8F9F02F8DB3D70B78B08CFB0949D99F1A86C958A8E3823736BCEAB86BE1, 6C94F48591C18BF9C450515B73379973
+ 32: B9C795F7A87305B4AD36DBA10B3B1C70B329D29E49C8C6A932D96A74334AEE4A, D18E6E233FEFD6E5C7148BDC1504299C
+
+EAX-twofish (16 byte key)
+  0: , DB0C02CB069E3773296D3BD4A87A381B
+  1: 99, 7D21D19E9C440F68E99F1F2EA2668694
+  2: 0696, EA590EC417C88E23FD23917F9ECFB0C6
+  3: B9B082, 82D4C9B68DDB02C906496413E13A2D68
+  4: D6B29D74, 5BCE5CA4F662E883BF7FCAAE5FB2CE01
+  5: A59C9CB009, CBFB04226D1029A7EC9D64A48A6729BE
+  6: F4924FE3E355, 3D85B3900DECA0528C815F1447A1F209
+  7: 679C88D52FB519, 931C7A863C3701D8015FDBD8696C6C30
+  8: 26DA41C0D115375E, 7627E23E791A4DCB0FA5ED71B1ED2288
+  9: 8FEC6EB7016AD2B178, F65ED0286A724F0CB2EA317D5022B0D8
+ 10: B5F22415B1334133C531, 87C4F3A8991BBB85984BC4D3305A5CF1
+ 11: 23E1D0ED2E820AFE7DA2FE, 100499F1093FAB2ECF73B643594E98E3
+ 12: 79519ABA91F46B8DAD6D5335, FBDCD1FCDB20AB99135F28A714C6992F
+ 13: 5968D0B4198A0AAD3D0395018F, 781F22E2DA98F83398FCF911B2010057
+ 14: 4E55B14432B601E3EF2EF567CB15, 8BF6E53D7657E56EA3DA1BFD9C9EC06E
+ 15: 6ED89651CE19B3DD1EE5C8780B5015, 131CFD657D32D4E1B35140ADDCA0E13A
+ 16: 2295A968B4D072D12757756247554850, F35FAC95C2AA4155450EAAA6E2E789B5
+ 17: F9B2AA2AA502EA79BBA0C5EAD932B8E1EE, 0ED81AA40B9BF39A9AAEDDDB7A04BEA6
+ 18: 385055F1C1C26C0472A504B4CD225DCA55FE, 24831680B56368231AC54227D737F582
+ 19: 771529585C741A3F8B1C973709892F255A99EE, 2A132B4BF96FD5109DB04459103F5E84
+ 20: E7A2197D9FAA8AB8B303B5EC71AE34AD5EC5DD66, CCAB6518371EC8E0A9E9EE4F7CA5878B
+ 21: 279E54F755EAC6B57375B9EC4406E43DB3139D740C, 7B6F26F2C0ECC9F2DF4EDD7513E6E0B7
+ 22: 27816AA94CBA2BF98E49E595AF5B3FAD12BF1D6F1AC6, D04876C5492D275F15C834E3CF794F0E
+ 23: B5658DC148855F68B282211D879F688F3C142FE555CF81, 4539CDA8A65DB9047AAD76B421B81120
+ 24: 72F0BD4F939C2C9B4FA734DCB0AE4FB9BD342BC8459ED2FE, CEA8469BC0457EBF3418C1114288C904
+ 25: 70568245E6E6BD5D11AD0C74030D7AE08BA05057DEA0FBF4AD, 71554FDE6B87477A51EE4499D78783D2
+ 26: 8702D35BE07D7ADF70684046CC6C72FBBBF821E0BBCCBC973601, 33CC6FBFDA15E306919E0C3BB2E22BB6
+ 27: 0BA23F4A6174165D4A8BA80B7C875340B0F8B2A6967D34E106BC22, 00E6679496714236EECEC84B9AF3072E
+ 28: B9E25ABA84C6BD95B5149E7616FE2E1D6FAACEAAD77A636C60279176, 8D8AD0B9D4C709E1DA370EE01611482A
+ 29: 74759711F6D542581F9F83498FB616638D092732BA07109BF4B5BE045C, 71A40DC777BD09F75362F7B20E0B7576
+ 30: ADBF7E98926484BA2C7F6CD7CD9734FC19265F68AF3BFCAEB025F6296E37, 8DF15B5F69B67F7DABE44E3666B55047
+ 31: 2DC26D449379997D110309B2A0DC2760FCE8CADB4B14ED580F86C70F69C9BA, EFCB60EB2B25737E256BC76700B198EF
+ 32: 2B1890EB9FC0B8293E45D42D2126F4072754AA54E220C853C5F20FBA86BE0795, 1A1B15BBC287372FB9AF035FB124B6A1
+
+EAX-safer-k64 (8 byte key)
+  0: , 9065118C8F6F7842
+  1: A1, 1926B3F5112C33BA
+  2: 2E9A, 5FA6078A0AA7B7C8
+  3: 56FCE2, 984E385F9441FEC8
+  4: C33ACE8A, 24AC1CBBCCD0D00A
+  5: 24307E196B, DD2D52EFCA571B68
+  6: 31471EAA5155, EB41C2B36FAAA774
+  7: 03D397F6CFFF62, 7DFBC8485C8B169B
+  8: 8FA39E282C21B5B2, 2C7EC769966B36D7
+  9: FEA5402D9A8BE34946, A058E165B5FFB556
+ 10: 6CDEF76554CA845193F0, FED516001FFE039A
+ 11: DC50D19E98463543D94820, 8F9CCF32394498A1
+ 12: 42D8DC34F1974FB4EB2535D7, 77F648526BCBB5AF
+ 13: B75F1299EF6211A6318F6A8EAA, C5086AEA1BE7640B
+ 14: 1E28D68373330829DD1FFC5D083E, 33EDA06A7B5929A2
+ 15: 85529CF87C4706751B0D47CC89CEA6, D031905D6141CBED
+ 16: FE5CB61BAF93B30ED3C296EE85F51864, CC484888F0ABD922
+
+EAX-safer-sk64 (8 byte key)
+  0: , 5254AB3079CDCB78
+  1: 75, 798DCF14FEF8F4D1
+  2: 0300, D5FCA75DAC97849C
+  3: 520F98, 10E357957CE20898
+  4: 80E2764D, 5C7F46656C6A46EA
+  5: C48960CDAA, 3CCF44BD41F01CA8
+  6: E0E60BD9AA2C, EBB493983FCEE79D
+  7: D13D8804906A1B, 6EDDCA919978F0B6
+  8: B7AE14C37A343BFB, 2369E38A9B686747
+  9: 5DE326BBCC7D0D35E9, 041E5EE8568E941C
+ 10: 13494F5B0635BA3D6E53, EAEEA8AFA55141DD
+ 11: A9BB35B14C831FDA0D83F7, 4002A696F1363987
+ 12: E242043A1C355409819FABFC, 63A085B8886C5FDC
+ 13: 204598B889272C6FE694BDBB4D, 194A1530138EFECE
+ 14: EE3F39E0823A82615679C664DEBF, 1EFF8134C8BEFB3A
+ 15: 8579D87FD3B5E2780BC229665F1D1B, A832CD3E1C1C2289
+ 16: 74D7290D72DA67C4A9EAD434AE3A0A85, 96BAA615A5253CB5
+
+EAX-safer-k128 (16 byte key)
+  0: , 7E32E3F943777EE7
+  1: D1, BA00336F561731A7
+  2: F6D7, 8E3862846CD1F482
+  3: 5323B5, BD1B8C27B061969B
+  4: A3EC3416, 170BBB9CE17D1D62
+  5: 0C74D66716, 7BD024B890C5CE01
+  6: 6158A630EB37, B5C5BD0652ACB712
+  7: 17F2D0E019947D, F9FF81E2638EC21C
+  8: 68E135CC154509C8, AA9EAEF8426886AA
+  9: EDB1ABE0B486749C21, 355C99E4651C0400
+ 10: DB0C30E9367A72E8F5B2, 631B5671B8A1DB9A
+ 11: D4E5453D9A4C9DB5170FCE, 75A2DF0042E14D82
+ 12: 3F429CC9A550CBDA44107AA7, 2C2977EA13FEBD45
+ 13: A7CA22A97C2361171B415E7083, BFE81185F31727A8
+ 14: 170F79D8B0E3F77299C44208C5B1, D5ED9F9459DF9C22
+ 15: 2E24312D2AE5D5F09D5410900A4BBA, 2FC865CA96EA5A7E
+ 16: 8F3C49A316BA27067FF2C6D99EC8C846, 9D840F40CDB62E4B
+
+EAX-safer-sk128 (16 byte key)
+  0: , 22D90A75BBA5F298
+  1: 3F, 98C31AB2DE61DE82
+  2: 584D, F4701D4A1A09928C
+  3: B9DEAD, 6E221A98505153DA
+  4: 06D4A6EB, 0E57C51B96BA13B6
+  5: 7B58B441CA, E28CCF271F5D0A29
+  6: 7950E0D1EC24, 2ACDDE6E38180C07
+  7: 65A4F4E098D7C6, 7DC1C9E9602BACF2
+  8: FEBE4E72BAA0848F, C4607EA3F138BAD9
+  9: 9B7BD6D6D655985AA3, 8B2C58A9530EA6AC
+ 10: 60C92F925D1478470203, 51E6F5F6DC996F84
+ 11: 7B40769370E651F64AA654, 74F1F8A8D3F4B9AF
+ 12: 7215832C2FB9C54DF7A9C686, 9BF9AEF14F9151D1
+ 13: AD0F9C79008572AB8AE2466EFF, F375D0583D921B69
+ 14: C05076E2C330A0D25D7CEC80597F, 843C12F84B00A8E0
+ 15: D18F0563AB0278140B0CD9A9B07B34, 262B1688E16A171E
+ 16: 650747091F5C532EE37D2D78EE1EC605, 1BAC36144F9A0E8D
+
+EAX-rc2 (8 byte key)
+  0: , D6CC8632EEE0F46B
+  1: 4C, EA19572CB8970CB4
+  2: 5537, 3EDD3253F6D0C1A8
+  3: 206FA6, 20FA88F03F240D31
+  4: 17EE8B40, 702E8194F1FCBFDE
+  5: 2A89287136, 31C5534786E15FB3
+  6: 3A6AEDC7066B, 3C663A4081E1D243
+  7: 8BC5203947A644, 6AAC806C92BFBD6E
+  8: 2E0274BBE14D21A3, CEB0E0CB73C3664C
+  9: 9C4B292B0CF17E3A29, F23CD535559023EC
+ 10: 8E322734308F85662877, 46363D7EFC322821
+ 11: C413C405767FF5F98E3667, E7BA35D8F3678E7E
+ 12: D77806B7A218098B1569EADC, BA67C306E5C0181B
+ 13: 4BE5EF74F9E9799A4D636FEA9F, 4C511C44ADBA4030
+ 14: 7E19969170C2C8D8AEBA8C7FBC2C, 54CC6D466A2DF6DA
+ 15: 2EF1CEDC1DD3403CF440FC5561BE33, 61C6FB277E93701F
+ 16: DE052719153EBACE9D7B19F52AC4282F, 4AC2A96F2FA8634C
+
+EAX-des (8 byte key)
+  0: , 44048B7F240B6F5F
+  1: 0A, 37009B7D4E09953A
+  2: 03BA, BFD2FD7758961728
+  3: 37EE10, 16A6AF96DE888A19
+  4: 07F44290, 100CA84AA0EDAA1D
+  5: 389EF0023B, 9614FB800A533268
+  6: 3F4DBA8AA01C, EFA6B55B7ED5E40F
+  7: 8C7B837896EAE7, C113CE8F664CE3D4
+  8: 7011D993D8EDB0C7, B4C370A919F60497
+  9: 0DEB30A31351B13D7B, 00ABC82DC5F3A1AF
+ 10: 8D3897B2CBE323D6EE1C, 7A2D15627CA1441B
+ 11: DBC002C817DEBFB419F94B, D8EB87F86D6ACDEF
+ 12: 17048E2976FA85AA849E9A80, 229FCD1C9D1E3B9C
+ 13: 30B989EF646544885A478AC198, C1B7EB4F799105C8
+ 14: 5C2E12A7F118A08D6FD585F9C839, C358679FEE6FE7D7
+ 15: 8D1A1E888BBB8648E638C4E74E11B8, 685E006C441448B8
+ 16: 93AE906B8BE4EAC8ED6D8F48F04A7AFF, 71DD7AF752FE28FB
+
+EAX-3des (24 byte key)
+  0: , 8914311BB990B725
+  1: D8, 2094EDC5D03E54B1
+  2: FEE5, 781CFB0EBE3895CA
+  3: DECF5E, 59918E8A5C4B459B
+  4: BD583AAD, 2013BEEBEEA795A1
+  5: 2BC01C6C78, 0B1134DBBEAB5D3F
+  6: 4D5EAF01A895, AB4D17516ECBA50A
+  7: AF229F90614480, D3113C0A9D133CD4
+  8: BCA6F375DF4568E0, 8E9EAEC8E77786BC
+  9: 575F34219E6DD8DB4C, B40C75139E5D1860
+ 10: A199B8AC433B615EC96F, 774AF803698ADE3D
+ 11: 718A2975DD9A872A68AE10, 3B9460F849CBA7FB
+ 12: AB38E148180F6E2FFBB96F91, E3EE3B8FC50DADBC
+ 13: EB10E0233507459D4A6C29EE80, 8D90B46BB1EAB27E
+ 14: EB48559C320DFB056C37458E19B5, 9315F0C4AF8500EB
+ 15: 9E8C73EADA105749B5D8D97392EDC3, 2E749EE66C1E6A16
+ 16: 600FA4149AF252C87B828C780AEFF8BC, 33D7D11DCDC19936
+
+EAX-cast5 (8 byte key)
+  0: , 382FB8F7E9F69FDC
+  1: 99, 20DA959849B3F7AB
+  2: C54B, D05547C6AFA3484A
+  3: 579836, AAA92B2321FC50C5
+  4: FEB7AE55, 639EDF01C4FB965D
+  5: EA8A6023FA, 01274B3ED5CE102C
+  6: B7C4E995121F, 712BFE27CAFF6DDE
+  7: F44236660B0004, FAC51D1DF8EC7093
+  8: 01CD7E3D0BF29E8A, 049C47A45D868D0B
+  9: DAB170493DFD6E0365, 6F3AEDD9A3ECF4FD
+ 10: 82C9EEC4803D9CD11FA8, 32683C0A9128C6EA
+ 11: 324AC59E87B244ECE0F32F, F6B095AAB49353CF
+ 12: DBDDAB11D02C9CA5843C406E, EA728FC46DDD3B04
+ 13: D67376C2A4AD92E7DD80E39303, CAF72B7E7C237EB3
+ 14: F2B9BBEF08036C2982C6DDD06918, 70A29D780C22752C
+ 15: 96E3D9141F8EBF520540C2BC9A9C23, CEFC86A1CD48203D
+ 16: 70CABBA983179106AE7FCD5F1F31D5C3, BF7F9168F4F82F56
+
+EAX-noekeon (16 byte key)
+  0: , 556805EEA595CFB9A30FAD196103D7FD
+  1: F5, 0A7DAEDFB656526CEF4DDBA8087A227A
+  2: 7B8C, 249895D79962D5B4D18FE07366281B72
+  3: ACFF15, DCC489D24832EB106F576AE6B6EB957A
+  4: 08ADE7DB, 0D3215999E9960EDAB29B78744C7F139
+  5: 66139213F6, 505E1E7141D043E903C26EE0959EEECD
+  6: 078B79F880A8, 35B7EB326A55E50332866EEDB682EC20
+  7: 2809E34D9667D4, FFDEC555F68524A09A6ABACA372077D9
+  8: 93D267DE1EC635D3, 4FF3561990A56E4B374618722EF850FF
+  9: F377A4D93FF32F4A51, 91D4070423A90FC54D305169C03F49ED
+ 10: 6244B717E082993EB7A1, 2E3A8A354AFA9473667ED7FDD46BE9FC
+ 11: E917559625D25E6E5F2EDA, 19295C37A70314CC9A1D11FDE8D23C92
+ 12: 1E6DF2EE112A893AB14DFA92, 12C4A89D4CD65F8116A03A135AFD3701
+ 13: 47B18CD762E011770E203CF605, 434909A97E118B20D3AEDC79AFE33A9E
+ 14: 72D9A1A7DA6F33D5E0B927F9F32C, 779C23714FCAA2B2321EC7FB5B03E222
+ 15: DA8B830FFCB3DB274807F780D33240, EDC2F1C8A401F328A53392597730B007
+ 16: B53DD2BB840AD933D36A7B5FFDCCFBBB, 4EC0E6D1F916BF633869239B672B37A1
+ 17: 42936BB9A936C30408660855F4F47F3314, F0DAA6DDA15585E1697ABBB4790B15B5
+ 18: 00372E47F5BA016F1B2A1E680B76AB02052A, CDBF3D241BF7FF96D3DFBEDDB872E901
+ 19: 8AA236B0C8BEF6F67A97C2DF90628F6E5838FF, 731DCD61F7F26004C03519F9500EA824
+ 20: 55338647812FC9D86CBDDCED7120268A4D43F8BA, 0E61B3C835CAD95FD49FEF002C014E72
+ 21: 435820B28E52154B47A04D5E635D8FE37FA47FC985, F6A96DCE4917E8D7C610923627E80970
+ 22: 0D30C15B6FEB4A48B14DD15D41A4B25D442AA677B25C, 28E15CCB74AE992C68BDDC8D87802050
+ 23: D9D701F9AD6B0E13D2CDDA15A5194E7CE8BD2C02137391, 2DB9A15884E9C996C3D6B5BDA44B9598
+ 24: E2390AC5CE10CCFBC72106A52C7F180CB477E3C193CBACA8, 22D3F7DCD6947EA4E78DF57A8E1A9A59
+ 25: ADEFB7D9500658D34996AF6BE6336CD78891064EA1DB8E9785, F239D67D039A15C620A7CD4BE4796B3F
+ 26: 89964C90ABF54A6DF9F13C3681E70C702D80A17BE79F8160F30E, 6336F729ECE1ED7368669D75B7E2DCBA
+ 27: 576B2813CECDA4F905BD5D58349EF070FF41B7EB6BB2B01B061B0B, 125324CBF2ACF1011A44A99A11EC8AFC
+ 28: 430B957481748519A60494F0B5F698F34B1A8235B00AC0D1F0A4442E, 1E80A7FCEBBB8E1E12D6831906154485
+ 29: E781BFE5FCDE0BFC056CC86C4A0B9DD3B815BE8CA678204CF47289B5B5, 190D5AAA9EC1CB4CC86FACE53BF1201B
+ 30: 78BFAC07A9B7B2AE9329BF9F9BF18A1A49DD9587001EFCA00E9AD9752764, 4FB5ECBEEB0995C150EBC66508FA19C1
+ 31: 7D6C20694109DE21F7955855A8FF832347518DD496C2A114DF142C68ACDEAA, B25D4BB34056DC091A7A3950D46C32EC
+ 32: 3E1E4395DEC1AFEA9212B95F37E679B6E2D14DF23C5DE49018C2C8038CC4AD45, 9A6DE7BD41A21918AD504490EF4E581D
+
+EAX-skipjack (10 byte key)
+  0: , 85F74B6AFFB10ACD
+  1: 3F, 604DF8BDD98A0B3F
+  2: EA87, 792374FE07588BF9
+  3: 0169CA, 489AB8AF69DA3306
+  4: A7AC3EB1, 428DAF508E24B583
+  5: AA9028D5B3, C0A44EDA71FB2C86
+  6: DA97BA88A061, DA2EC34077F42585
+  7: 7E25FAA41CEBC8, 36D4987551E06D5B
+  8: F662DA6C9001CBFE, B7DEF76680C316A9
+  9: 6D3F73EC716E1DA897, 5F0F83BAE4D3513B
+ 10: 2A300F585BEE9C889743, F4756C24DEB72A9C
+ 11: 80518B010DD77C82D19106, 50FF5CAA365F4A70
+ 12: 6E579A2173C861B6F37B4CD3, 81E3E5ABBA8F0292
+ 13: 5B04829880A72C38871C7021F3, 6B26F463708A3294
+ 14: 934177878E9A9A9FB4DEB3895922, EBC1C32F0A2A3E96
+ 15: 07AF486D1C458AAB2DBF13C3243FAD, 87288E41A9E64089
+ 16: 84059283DF9A2A8563E7AF69235F26DF, 351652A0DBCE9D6E
+

+ 407 - 0
notes/ocb_tv.txt

@@ -0,0 +1,407 @@
+OCB Test Vectors.  Uses the 00010203...NN-1 pattern for nonce/plaintext/key.  The outputs
+are of the form ciphertext,tag for a given NN.  The key for step N>1 is the tag of the previous
+step repeated sufficiently.  The nonce is fixed throughout.
+
+OCB-aes (16 byte key)
+  0: , 04ADA45E947BC5B6E00F4C8B8053902D
+  1: 40, 2FD20C96473DC80B70AF13AFA11D9B4E
+  2: 133A, 2CCFC6DC16D5587FF3CB3F91C533622D
+  3: 12E5E1, C93F3E09B9029E15185FEA44B3F6BF02
+  4: 3865E0A7, 7410F5F5886E2C5EF4A699A58C498C41
+  5: F0DAFA15D2, 44FE6EE9B2C980684FEDEC658802A63D
+  6: 432E308C6BA1, F7174691EDCF8D7152AFF61F20AC6B8F
+  7: B353379859776A, B087536DAD5C6E38E7C58C4A70074222
+  8: 0C78BEF929856517, 6499752674000993174D1D1B210FD727
+  9: A447088E4FDAA6FC94, B9C1AD71C969357FA2409D71AD334C26
+ 10: 962F7E06CD4CBFE64D60, 41E9C22DAB0E6EFE5869D5C1CA016869
+ 11: E420A8485EFF0BE6E59FA3, 8B555F3331ECBCFBCE60284DF0CE1D29
+ 12: 60AF8E70FE864404C77323BB, 479C3E8E93EE0C20E9E4CA8455149F99
+ 13: 6BE58932CBBA39ADDA999B35EC, 8DAC0E379861AA327DFA52DF712E771A
+ 14: 3404A18D1A5F40EC3EBF3701BB67, B915A619EC2B25453B8195806C538872
+ 15: 2F527E106EB32D5EA6CC2071706FDE, 172559FC20A29D0E1BAF61750951BC66
+ 16: A4F288797EF24DD1209E76322006405A, 0F91836E1769B6F329AF0A7FC69AB07D
+ 17: 8A3B6F2B48E2F6DE3E02D6A166E1E15595, 17BB024582DBEFAE6893BC8903418042
+ 18: 5D7D954BFE815CE208AD04214F6AC62C0A54, 4CA6796851083AD43733E8E4D964FC23
+ 19: A37B487B9D3B05287378108BEBD44B9A7B785D, A4402359F7E4F4BF70B3DF6600061C6E
+ 20: 39341E78E5BDF7BE950B00423E186B91314B7BEF, 49B7E1545C20B0E86D0CDA4F90CC6ABA
+ 21: 3D4E872C6103DB1064AD853D2978E8C5AB12FB69E1, 3551930A00FD2B663B094E6CBAD5BADC
+ 22: 62C36316C5C5BF07296D9210E12BBD9542ADD2384193, 72F4B05BE37D61D2F4EBE778426BD170
+ 23: E3A1EEFB5A1EC7857E6E419C18C1BA3F08AE2DB82220CC, 19F59932FD089F936B56E26768A9F2D5
+ 24: 7AB0FECF7E6DCC1A7328496873DA608C2F90F6F539F76CC6, 067252CA3D59354F70C6EE6C201679B9
+ 25: E811F085FD5460D3AFA4A2A389CFDDE8ACCCB9B16D75D55860, 94403E24AEB19FCEF4A7D600E5B39199
+ 26: 92F42E16B838E63E4A826029126D74782DD8FCB6C8443F355732, E7F3B2F1F537D8A7DFC9FB766EE90687
+ 27: 21E99ED0E5550487CD1966F1845FF302ADB6AA97781875090538A3, 4C8299570BC6BA9AB83B9B14D39D0395
+ 28: 9E8A5A8BFB43D79EDC027DA82C035CA9CABBC41DB66D6256D4A30456, 3D055A9F6D6F0DADEA447157A03B06A6
+ 29: F46CDF2B8E55840F27BEFC0136826912BECD86AEF88CD9B97E597C69FA, 75AB6940C71DF2041F9B1B11F33EC1B5
+ 30: ED8DB3940AFEC7F990736E58CBFFD703317E79022FE951B07717EED12653, AEBD2F849E019AE82162F8A2494C3715
+ 31: CD44A4CE400373FFCBEE37A79A650F73FF767F9D1EBB13F9AC7DF90A013667, 3DBEB69ADFBC8B0547A823237EF4FA68
+ 32: 1BFC4EF0E39A9624C74B72329F525296C75FE9B6371700F9430FAD11016FCE6F, 8C341B4333EEA104A2D813AF71E603E6
+
+OCB-blowfish (8 byte key)
+  0: , 07B7752047F9E0AE
+  1: 72, DC5AEC862D059BF4
+  2: AA44, 3C9F6D8E6A88B5BC
+  3: D58CDC, 5305AE3B67CA99D7
+  4: 40AAF438, 306EBBE817191E72
+  5: 83C6195BBC, 03EFAF8AB3F3A797
+  6: 4CA887041A55, 45685403FADBD62F
+  7: AAEFC9AFC97E1B, 9658D436EBE2B562
+  8: 298ADEC7EE78361E, B90F2F68A2512CCF
+  9: 12D0BF9A2091678026, DA2AA0CEAA665CCE
+ 10: 6E6FBED771FC0F458878, FB74D5C5E3801106
+ 11: C7ED5B6E6306306E9492C7, 7B9EDE455D6FB117
+ 12: A2E9E854EC2F47E367285401, 4E8610D388D8590A
+ 13: 358787DE6F716BDBDD1ABF35C5, 026140FE56B18F40
+ 14: 927A4E1EAAD8F9A7A1976353840B, 3FFCB2659DCECCFA
+ 15: F02A0044174580B388CD92C92A640A, E4FAA7636675F470
+ 16: FAC9731332BDF622E4070F35DA928DFF, B0FDD13E2BFF9971
+
+OCB-xtea (16 byte key)
+  0: , 56722ECFE6ED1300
+  1: 42, 1B8DC606F46D0C70
+  2: 5AFE, C37DA08565D490AF
+  3: 2210D8, C1F685A65A5D96C2
+  4: 3760B566, A3820E4369714716
+  5: DE9A8858D3, ED81EB4158EB9D32
+  6: 4822F1279F1A, 152823C615E44F93
+  7: B83B447A71F943, F9D4243069C2D675
+  8: 968ABEA6B6C65A78, 012DED12CE8E6898
+  9: B1A37D0FFB6A6FC8A2, F749AB7C40152D6E
+ 10: 4D48A2868E751C5CBE21, F8CB1C58475FAFA7
+ 11: 0C81558633A9130A6CC9AE, B5D2075CD13D9AFD
+ 12: C76717CB2F62C3AEC139906C, B9518A5031D84B19
+ 13: 11F7EA02488D7BB84209CDB03C, B4009DC8D6EF5C4F
+ 14: 4E621DDE6BD1B7944285A1CBD396, 95C178682BBB014F
+ 15: 98C771287305A8DD1F0EA001AB3FB0, DBBF192B778BB9AD
+ 16: 13AE423AB94556C3594C15F745BB6887, 4785C52B73DE0864
+
+OCB-rc5 (8 byte key)
+  0: , E7462C3C0C95A73E
+  1: 7B, 4A2E2F035C687741
+  2: 5D18, 67AFF1894807B8CD
+  3: 2D22D8, 0C5FF43CA669E036
+  4: 341397B9, 96B16C84B8507879
+  5: 78DD453CE9, AE90A02A9A427B82
+  6: 607F75BEB5AF, E11F4897573F6672
+  7: 09A273F40C1F2E, 47038024E2F82A75
+  8: 0519985EF3CE9A54, BA78310DB98100D4
+  9: 66F8D6AF3B453E175A, 8E8A6032D7BA4D8E
+ 10: 8EA2CCD6592C9AA13B1F, 8E169657A578DA1D
+ 11: 6046093C8B4C5668182A86, 1E263CA9C35E06C0
+ 12: 7D41AAD34685C2E6A050B860, 96AE4FDBF038AAAB
+ 13: F5E6D3B7773BADDEAABA140123, 7FEE0722FCC229A1
+ 14: 44FA523DD21E9A57685B154113A3, 5F4F727124C9A45F
+ 15: 373B75BADE72A31B61D7FAAA2DFF1A, 526D5C55FBB13C70
+ 16: B245D9B51E69EFF0D0F33463886B22F0, 5A575D73F0E1DD6C
+
+OCB-rc6 (16 byte key)
+  0: , 27B9E3F544B8F567EEBF98ED5FD55C76
+  1: 50, 19639C6FB84C516252045735CBFEB2B1
+  2: F537, 645D0FC41CCD140DB055F7E0C63F58E8
+  3: 2F980F, 317F9D3CD0DAB3C309D17432FD7A802E
+  4: D868693F, E48D64588DFB9AE80C5F0B471A133B96
+  5: C171238B7D, E9027C03EA694306AE9AF3AE4C4E418B
+  6: 2BBB09C1C87D, 6491FB907923B31B3904DAF44E155DB8
+  7: 344E1A1B4CF7AE, A13A7BDB91291914B33A814FF5D3FB3E
+  8: F21AF3A1D17299FD, 367371D31EF18B597348AEC1F2415111
+  9: CEBDDD6DC10BF92082, 8C9EB873E39EEC6D123DC69350178DDB
+ 10: 7932B646E83EB855C568, B147A3F6D63EBA4B79300B1BAFE72F6B
+ 11: 1100687B3E8BAAEA85A8C7, 6AA2C7009E9BCC19D51E18F472260C65
+ 12: 2C7BECF92891FC7B95FE6142, A83FE40AB2A5E176AC7835005E43CDD5
+ 13: 29467982D6361D53357F314332, 93EF8D80A786EAFF9F59CD3365AE62B7
+ 14: CDC2FB60BB5AAB6E6028032DD04F, 6FBD59FFAAF6DB2E0A0CC08AD16FD36A
+ 15: 8BA02FAB113254ED8EC51337605315, DB4C8651CA878CC6FAE2FDC361C1E2AA
+ 16: F36A825E7903BA24D8EF48E49DC2EE12, FF9BCF7D6904CF072FBAAE5EA7637DCB
+ 17: F22042261E247A450CCFDB90D54D42EF36, B3E2972C2B6EB9F80B9E9D5BF395B771
+ 18: B1F0C3216D75C7D5F5C6834F352FEBAE4E26, 5BDDDEB129C08A9D918238B74A436AE7
+ 19: 308F653B63C08990E34655FD0E556AD14ADBD2, 7132EF067DFEC0B16F2E4EE6FD7111DF
+ 20: 65CFEFB0F8258FA5F77AF744A97398CA768169C1, 18EA953A7C3A764DEA9A0A67A12FCA32
+ 21: DA01CBB6F33C91A50B49C6A6FEB95BDDEF0905F7F9, 8F29E4BA14C1707C32F3EAD642D6020F
+ 22: BC35EE861788C672AE10348080346442955D6AD9CA23, D11F8A6E94E663FBFAB79FC124781A2A
+ 23: 02B52941575D7EDE96D336EC26290EC32D2558CC1EB2EE, 84656D07A6502A48E99E760E911531BF
+ 24: 0CB126C57FD06737F728090D945D7A3154316BE109A26D82, 7B242FDC18DD934F9A3486CB5B242F1D
+ 25: D80B8743F79DAAAA6D531E90C72EEE91721B0DBF7D7C3A7BB8, ABDDED12108723E86D4B72E2E88DAF1F
+ 26: 7C94C0174515FC33D8E9265AC8288E8019F6975626F7FF92AAE0, 113140E6C100BF737B5BA7411B35E3C5
+ 27: 0B26D5C8F433E566096D7659ABDEE87183E3AF942859B1FA92CC86, 0BE6A8E265B619D83058C90B758D963E
+ 28: 61FBC6C671AC58DD515024C9E9ABB774DE2F013EAB00226F00E944B9, 0D095AB152C2FE6ACFF2527E89938A82
+ 29: 0D8116EB2BA5C1DA6EB9070B00F819C3CE817085AE3D8BE8028B9F28F0, AA0A1670057C9F7A291BDD45730AF3D1
+ 30: D40E8399579309A395093DD35889A558D8602D2A7C5C4CADC4E5C0195232, E534C6F04E12D2E6D97ACCFAD57C22E2
+ 31: 25037C853CFF6296747B5310F1959ED0628847D8996E10414B1979E340F43F, 8DFB20AFE1B20A702AAACE1C3B9A3E3F
+ 32: E1C2DA2341C0DF0515F11C7AA2EFC88BECEC0228BE220615A5A26F0D9CE164DC, 5AAC9903CB8E340D031688ACDF5D203B
+
+OCB-safer+ (16 byte key)
+  0: , 88618DEF98FE588E23107E9A5D89C26B
+  1: 68, 78C82478DC13012FBC3F600C7A27A208
+  2: 49E0, 6C2823D624ECAD05081E558DBA873883
+  3: 0DACDA, D977DA0446DB3FE2E31EF6423C84D3D1
+  4: 9C81B7EC, 96ED39E22316D48B0652851F3F2EF14C
+  5: BCE204E7C7, 2F2A2556CF50BC372E8D5EB0B196E072
+  6: 51D55B2149F9, 29E5DC8856E0ADD3FF50FD3611C336B5
+  7: 92C82E4C3DCFE1, AD9091779ED4426389E4FD148CECBC36
+  8: 6B7A7E80C71CFEC8, DE0EB38592298B6C98D79DBAF4388062
+  9: 8578B7FF0338C7261A, 8F5B1C5055E789E0D062403099F5B736
+ 10: 31D3E598CF921C73AAD5, 0AC8BC98F0C0822FF677F1873BA246EF
+ 11: 350F10E54E34F1E132B51F, 2F22E4D9FE1E9D5B6FA2DB02CD2112D6
+ 12: A41B0CEEA3B156043A9B3289, 78B8DBBE1259DA24797A65A0A6F21813
+ 13: 97AA05B4EFDA98212538D90826, C49EB0F9110C6A8F64D68CA1AA05D317
+ 14: E7CC0F8CEB35EB63BB5CE067302B, 2318A68066C4692BB7DAD31269E80EB0
+ 15: 9530B10F9D82F2F01220E507C45DBF, F66FC64518F87E40141E273968644EA0
+ 16: 8FA4B27A1F279E426403D0A4960666F3, E297DDC3038C6754B09972C9A81FA346
+ 17: F2DA0B5E70287E504F1606AAE4A60DCD43, DBB1D3FCED2731757271C451FA89BAC2
+ 18: 9F39E37F53A7EB41B471CD9B09C89E2640E9, 5B7139A288009BF029D8BC11610BE58A
+ 19: E07FD02F121F0D497339A3F604CBCCE91AD43F, 7970D40B8C4A728A351F6055B87E451C
+ 20: 344D288DE671675A2539720EC6C36A7C75627F76, 8C14F47BBE0F60117FEC9B3055F122CB
+ 21: 4E8FAA2AC06045F7FCCC386E7BD258F6796256E901, 6C02374CCB50A0E50A39DBC648E70DFB
+ 22: 8FC9ED1351E05EA5E04799A518CF52F21CF689B18EB8, 97A2732C6149FC54C21E5AB8B69C2A94
+ 23: 9B0809249A4D0C8F095AD270FEF3DF72232FE807A92243, FA55F25502F7FEBDFB4638FF27AC7E0A
+ 24: 2B2E0239FC8C1A78011D73890A1169A117B7CC1E8B5B7B77, 02E373B8D36E675D47AD9BB0AC661BD9
+ 25: 28D5A76CE1064E266FCADE5CB7A908E29B60B19482B1C40B3C, 689E34472FE29EACBFBB9BB059DBC90D
+ 26: 6A1C1885DC27697AE22D8AAE9850A8752B4F9D75A7AFF65E4182, 28B6A0DADDB7783929D7C774820CA679
+ 27: 8A414CEBE09F7397D1C997645FA3AF71D19F5BD6227EA0CB47034B, 3C1441F1A4054A37C98DB6EA0268E417
+ 28: 7CEB9392C3E73183567D7876F86E5373B64F01A0D1C0AC0AA0A01413, DD9BA754BA874DDBC6FB531ED46D9CC0
+ 29: 59D7302D064F375940FA8C6D7ED4E4EB27025514576D4ED31037CFCD28, 4A7A7E25C56C0676F9471B0440856F86
+ 30: C738EAD06D011F8F6D39076C660A8BBCE69F470D747E8BAACAB6624E59F9, 474664ED7DC02BE63C7165860464188B
+ 31: AE8386752CD19641133432F27A923AC03E790D6324E7D951866B30B930ECFC, 017375CF18EC2AB24D19E10459977233
+ 32: DB277B162E172882DC35C0D13E8CDD2A51022F711A67491F9788F83C4953342F, F289BFE53BACA5D9818B118E5A236300
+
+OCB-twofish (16 byte key)
+  0: , 2CD8EF22E5457C7FE4016B0FB82FD204
+  1: 5E, 3E38069A9B48C86A6D5B30230AA8FB5D
+  2: 16C5, 88018710A0DE759BB40F63D01D3BFEC5
+  3: 3BB919, 541D64B63CF6256A2B91641C4AD7881D
+  4: 18BF1940, EEB4B67CC606C3BED042713A1C07E148
+  5: B83ECCDD6A, 99AD31F23F10784CC315534AD7DC3227
+  6: 2C6EB390D4CB, 239FD47E333C9E628F53A0AAFFABAB95
+  7: 77A6F443656C96, 6669B100ED5816E5E7EBC6E6FFE9FD28
+  8: 48ABD8C0E7880A3F, 2927A8138FF76C35644C1C260A470E61
+  9: 58618862492B904056, ADA18B1602AB662B1DADA3D17AFDA16F
+ 10: 421666490D83177D6662, 31A434A1AF320564DAC4AB41CB95CCBE
+ 11: E6C856656011B22865BB56, 8308CBA4CA2DFB3BBF50B406AF9787B4
+ 12: C00BDBC3ED137D4DF4AE64A1, 3A6AAAD853FD891608E6E524CC71291D
+ 13: 51FC0197213EAE6C779B0D9591, 2E013655C557BF924C3377119D445A08
+ 14: EFFA38E05FDC7E40A0F73CF9EE75, A20C214FEF00C5B836816D91784EA349
+ 15: 5121A8E7DA2F34FCB27A211AC7B17F, FC16C8CC0F76AED1502E54E5578FA4FE
+ 16: C7B4BACC25D34E3235AF82EF4682BF71, 4A2D4172B5BE33532BDC16792840F807
+ 17: 67C6376AA0C00FBAB7ECAE408F20004842, ED2BE2756636BEEF1EE5DA5CF727E89D
+ 18: 8E2262CDDF6A2523565B6B63BB86311EBA9D, 6E36E1B6ED9E116581B155B5B3CD3A4E
+ 19: A683E2D02AAA473F66FE1B88278C83D1E934DA, 216A3EA8AA533F47F668D8A0D2D7C59B
+ 20: AF5E282860165A89CE43987CD12D54E09F24F930, AAA981071FD86D7FD3D5E1A9B7B0F54E
+ 21: 8CC3AEA5C625B1BD7B7982E0933340C7C6F697A7F3, 211BC13BBB33CA9D9C09FF71E6C6FF0E
+ 22: E7A0BD9580F60EE6FB96830BC03B9DB1C714A5FB1E3A, E80D8AE804A1FC572719C9891728EB0C
+ 23: 8957615AC77DB6D23C5156709A8426D5D947B3BF83F80D, 839A17904B6EF3367F41D86641179E64
+ 24: 89F7444059A006913EC23BC6FA07E2EDA6929F9425ED55B5, 94D3B35D083A99D7CAD703C730B7AC3F
+ 25: 166189030E95293421581FBC56598AC6ACF597FD07BCAB8BA7, B85DFECEB4953DCD16F1D294B77F5251
+ 26: 9D1CBB72E273243A031E061FD1B7B21283C43C607ECEB5F604A3, 37A1370BAE41F2E1A538904B623591F4
+ 27: D5C870356DA4B1A6B5B80958049A04F4B463453F5D54EDC3B90EFB, B1D6913246CCF26C063E282D7B9AECA2
+ 28: FFF152D69AE294A239FB875C038688F0C2025F6B924EA69ED633D974, 8DA6C7D7A7535D33E92776BD51CE7732
+ 29: B327AE2D692BDA7B4F0F46B8025B2D09EACA670F8E4B2D32CB538774C3, 721861B534B2C4DD83B9C3652BB78083
+ 30: FED1AEDC7737586AE88324ADDE9C8396AAD39C1A24773185F47F83A4C9F2, 5987D5FE9CD91AC15C434DECBBE96F49
+ 31: 3B8D6C999FA569F5BF275654ECDD27465420E4A4FD0B791B3082B6746E7494, 92CDADC59BAAB01CFEE801288F669BC6
+ 32: 57A44D012A7D8EC832121B9DD374990C2236A5B5CDE525A105309A5DAB860B04, 13B2461EFBBF3E37C594C10BE45EB3FF
+
+OCB-safer-k64 (8 byte key)
+  0: , 0EDD2A1AB692AA7A
+  1: 20, D8E0A4AA7186D93B
+  2: 3A72, D35ED39A0DE9BB7A
+  3: 63E95A, 5DCC145AC083EBE1
+  4: 66CCE936, 43DC4736618962EE
+  5: 81E790856A, 67FE11BBAC7F0CF4
+  6: 2FCC612AFA2D, D9A73706F6BF0562
+  7: 8D65EC96919C6A, 9859A2C2F467F271
+  8: B968DFF1928FFA70, D6379C99C09205E2
+  9: 1D5AEB22616196731D, 91F6EB57D46B3F4E
+ 10: 8712826B41AF01B45F95, 7482C4B662B4D51F
+ 11: C3DC292B6D37DC8299F005, D66EDF92D14E89ED
+ 12: 41E72489BC2089E3632C50BB, 1D058C13D261FF52
+ 13: 257A6510FB990950D8CA3B6BB2, C7366DDB55647661
+ 14: 74C037F38910E25D746D3A41C422, 6A89AD8D5763B669
+ 15: 58610E575C2938BACF63E9612A5704, FC40C717D3962A95
+ 16: C23657B24E3497C7C3A53C8D99866586, 8092D335D30512A8
+
+OCB-safer-sk64 (8 byte key)
+  0: , 76F16BDCE55B3E23
+  1: 6F, 9BB975FF089B072D
+  2: D0DB, D469B44427B54009
+  3: 9124AE, 29DEEE037ED01B57
+  4: 3CB507B4, 3B2099163A662E8A
+  5: 24916556E2, C645411E75A45A76
+  6: 3861F27498B1, 27CD404E5CBE2530
+  7: B9A4F0F215AD46, EC8ED0F8F5BFA762
+  8: 35F39C5CF8FC195F, D2EF40AB639C6841
+  9: EF387F42DFB145C157, 78A3687643B6A8BF
+ 10: 609B7AD698D6E75FC8A7, 19F2B4BA46C226A8
+ 11: 9EB389D840B5575A431015, D6D5CD12B0A8D58C
+ 12: 773D76C86FC6548E9C3F7106, C84DA314B3D2A265
+ 13: FA9F6A22A448EA8EBC4D5CA1D7, A1F9A8800DEE87F3
+ 14: 8588A29BDA0F754902F45177D98E, FAE4F6A46C282C58
+ 15: 3661A78146680EBD27E1B0A8411F6F, DBDA06B42AFE89E6
+ 16: A7817AFDD86A73DBD088D726950885BC, 39EE24F1DDB14EFE
+
+OCB-safer-k128 (16 byte key)
+  0: , 4919F68F6BC44ABC
+  1: FE, 62E1BB4260A41E8B
+  2: 29D3, 84F7E10309B5A9F6
+  3: 82CAE3, 21AD21271DEECC38
+  4: E8CFF492, 30A28F17566BD7B7
+  5: 42D790100D, 2712BB75C619F235
+  6: 1D7EF9DAD397, 29EA0096FE1B0F8E
+  7: 2328AE9F5F8F23, 823FBB72027588FE
+  8: F1EE17CE5D1D962A, 7E763B44190D412A
+  9: 59995D24D2F343CAE5, D0442E8DA4B7A738
+ 10: 89470C900512352C0AAD, A1B8267CEAC51DE7
+ 11: FA01A56CF4043DC9016507, 3F04CA39354B7945
+ 12: 234CE53F33CC18BC1D87581B, 26045CD92EEB0B7C
+ 13: 09F0F817F0A1C34CC1882349D9, D6690B0CD95E3B81
+ 14: EE59B78A5EA7A7565519BD8394C5, BA02E6FBDAA3D9C0
+ 15: BBE92ED57326C0B8BD718A161F93A2, 6F92501366610B24
+ 16: E7FF3C9225C652EC6E89F4D514AB9529, FB797311AE38EEAC
+
+OCB-safer-sk128 (16 byte key)
+  0: , E523C6DBB3CA178D
+  1: CD, AA12FD56D9ADDB4B
+  2: 0CC4, 98012452ED510588
+  3: 426651, 7FBDB6A5B8960251
+  4: 9EEBE085, 0697D2EB8824BC84
+  5: 346C825C29, 5BECAECCA943C6CB
+  6: 12C8F7C7174F, D6F614EB7FF14058
+  7: 06494CBE89E31E, 51A7F4E7D1B85EB8
+  8: AB7DB8E035CD48D5, F18EDA93515A11D2
+  9: 5F66C9179485A4C178, 77B2EABD6B9D32E9
+ 10: 44E2F4B20A7B5BC5321E, EB0D98A55F19267C
+ 11: 807F11C15D37266D9CAC24, A28A19BDF9967E04
+ 12: 403E55B8744B21CE9EF5F67C, 5E4F91E64F5034CA
+ 13: C38DB3813C26D0DCDB4B3A78EE, C4C9A3A3B057511B
+ 14: 67FFA142996CE550C513F59F8277, DA59DD302D5B0BC7
+ 15: A88F78F05F9AFF45F2625D1F450CB1, E4A32284D3D6EC35
+ 16: 2EC309FC14CA2483FA63A5EA28070833, 3689A7737D796A82
+
+OCB-rc2 (8 byte key)
+  0: , 1A073F25FF5690BE
+  1: E4, 6EC51CC8940B5924
+  2: 4468, 4C549CEC13F5744D
+  3: D2CE47, 3B34AA5CACF700A0
+  4: 4D98182B, 43851C4905037752
+  5: 5784656E03, B1956D2F35E190D6
+  6: 612EC3D4BBBA, 0DA8B476C515C20F
+  7: 88CA9BED760036, FA5C4349AB03192F
+  8: 61219479ECCDC295, 024AFAC39AF5DE41
+  9: B2205D0B520ECD3C98, E8D7F09F54045A91
+ 10: C4B8820AAF0CAFC7F16B, 32AC2DA632FFA7C8
+ 11: 4EF4A33C630329020CA0B6, 00B94EC22CAA440F
+ 12: B26FFEC28419F7ED99B241FB, E484E08689C26430
+ 13: 588D22959AB8D1582049EE0486, EE7E0E38A42BCE31
+ 14: 86A1FD658FC2AC0E1ECE0D528AA7, CDEC84E55E0BE78C
+ 15: C00B073B48026E16562924BFC8EE5A, C65C71EBEA6016B6
+ 16: D4E298B1E610FEBAC020BA0D0507F0F1, 68B094F6F2C46BA5
+
+OCB-des (8 byte key)
+  0: , 8A65BD7DE54082AD
+  1: 7E, 91C5CD7987CC46CC
+  2: A275, B76B5A4ADB75D0B0
+  3: AB0C5D, 2C463609C9933886
+  4: C1ED86D4, E79AE10223890163
+  5: C4D04AEDEB, 509A81814B7873A9
+  6: E0FD095B644F, DE5139ADD9BE6250
+  7: CDD1164659654B, B0536BB2817725FC
+  8: 759F0E801E5AD992, 71EEB01DFFD9D946
+  9: A1E8BCFC90324AA3F3, 5B61AE171ACD4721
+ 10: 3D0BE9B40B8B7933976E, 1D33B66102AE70BF
+ 11: 338F0213A7C843CC335E20, 215F1AF51474E391
+ 12: 9B05F57853F4319140533EBD, ED4425C38848550D
+ 13: 16CCD44B543C1B6939D9F7122C, 22B0577679223676
+ 14: 092E7CE7DFE6C7B07A672680AF81, 761C1C267F62CFC4
+ 15: ACE1AB7120D4092868143FC3E76179, 165DACD587304D1C
+ 16: 9D3764DCD797FDA981A440BFBFCB0F2C, 538254F6164119C4
+
+OCB-3des (24 byte key)
+  0: , 9CB7074F93CD37DD
+  1: 90, DC4E7B29A434DAA3
+  2: 3139, 09BF34C4F770ADC7
+  3: 77161A, 9ACB27184F3BF196
+  4: 1F7666B5, C6578EB1CCE25553
+  5: 043240D354, 23D090F6DACE0B03
+  6: BA84DE76B081, BEBC521446F286C4
+  7: 3EF4272C6AF1BB, A99BD626436F2586
+  8: ECE6A8B0C4EF8D63, B675ACED7D2B28FA
+  9: D4FCF97B677A2CDC2B, BC6B8BC16BFBFB20
+ 10: DF899D92AD0FBB3CA443, 23D486A6B0DBD5D1
+ 11: 1A95F4AF984ECAD4CA52EF, 34DEF497F95BF424
+ 12: D32ADD65BA8604BFB0980BF6, 01C2758914C4D0DE
+ 13: 6D477BC51505C8FD9EDA926596, C5A338A6AF687597
+ 14: 37AE388D897D22789CB79B17E1F1, 75E7372DD653DF15
+ 15: F24F950FF2DD2054510E67EFCDC4DF, 705A27ECFAE74710
+ 16: 1D8AD09B1124EFF0817871754FE6ED40, 3D143151197C59B4
+
+OCB-cast5 (8 byte key)
+  0: , 77E8002236021687
+  1: 98, 9D73A3403B345699
+  2: BF24, 80A7E8123CF54C9D
+  3: 93369E, 01A967A92245F16E
+  4: 5D917EED, FFFB66F53851ABFD
+  5: CA6E2BAEFB, 53596129002C9B7C
+  6: A66DE171E377, 25BC0AD3B0AC21AF
+  7: 04A05EADA80780, 7703120B8DF8B98A
+  8: DD040CCEA55C8830, E4B8ECEAADC292A1
+  9: FEEB112E469F4AB637, 92F0ABA0A554C9B6
+ 10: 5BE2019137752075F35D, 0DC52AED0F2C3894
+ 11: 75DEFFAF2C152E6745A97F, 7752A70A2D9D184C
+ 12: EF90E23366790D62DAE5BA66, 829A9C7684D03C5E
+ 13: 0A4689BD15E338056782F19B13, 5676FAE6E2745929
+ 14: 2534CCD55A471E5840447B6BAE6A, 33D1B4876EFD5FE0
+ 15: 6FC1B4FD3A202CB14D9ECCF88F0E55, 13D8EDBE1BE8F0A5
+ 16: E8BACB11E0864011D72B599025DA2FDF, FE7397323F7DF138
+
+OCB-noekeon (16 byte key)
+  0: , 72751E743D0B7A07EFB23444F1492DDC
+  1: 65, 2BDF86A7C46460BDBB8252E176CB7105
+  2: 9BAE, DB8AFF53F1AEF4FC5A9BF3E1A5DE9430
+  3: 96C214, 25585611B7FE5EC176627DB0BADCBEA4
+  4: B6046645, 32F5FF1347797760C872D92FB3E48085
+  5: E5C89E89E7, 5B1868C4655FF6B28BEEDB0C8A37CBC6
+  6: CB6CC16CBAA8, 8A7C7213989BE3D89D8EBE31024DDDE1
+  7: D09EE74CF99850, 565DA08FB8F154FDBAB27E432324BF77
+  8: F389A90F999147CC, 618535B5685A9F76012B99B0C6FDFAD5
+  9: 32B110B50A8D6F67D9, 379DBCC0B20E3523935621A7C1506A28
+ 10: CAF759FE91C8794D8D93, 50EA638B83E1C85F210989495A8724CC
+ 11: 332B07DA0F942C8F22C1E7, 504DCD9521A42C77C05CE9ABF8FB4FA0
+ 12: D0C422738243A89E54B734A3, FD4FF9C337CF2785EBEC0C128482371B
+ 13: B899277B6557E5E685A5649E64, 868F039212C96E212E280A4DBA6555FE
+ 14: 15E617DAACB18D93428C3BA043B1, E072A199CFAA617CEA2A176B75682516
+ 15: 58B04DDD83045E773811BD6C371978, 6EEA2DCB6DECFC0B542DECAAD37024B3
+ 16: 8DE6C50DD08FD141E7FF20FE3262A340, 6F826FA2FCF34E4285975DE9FB0FC4D4
+ 17: A14711565B0CBA6C88370737F97F803F7E, D84950FCD2C72536711A1503348975A7
+ 18: 5AEE5927EF89D3A09CDA7CC7183EEB701471, FC8DB44F4D6188581A0567C3DF2C498D
+ 19: 12ECFBFF02C5A37DFE7772732659ADFD7DC349, 8ED7F4AB648339A174ADA3317BF82C64
+ 20: F57930534156A623A05FA3A30B4CE5339E8209A7, C78081E80D95BE642DC4F194C902AC3B
+ 21: FF92DF299ADF1EBD22CEAE3876B5DED0AE5EEE2F9B, C491571613AA18C9C4305A9595575EE1
+ 22: 2BBCC3079A01962F7B406662A20924C2AA5D65493FCE, 6AF63F2B8831F8CD41522D32A8BD1C1B
+ 23: 9F05A8AF6256ED46EED6BE3E5F9F5F13A3804AC0DFC110, E310472DB635D60B5BAD5F5B3E24E768
+ 24: DCD82591D67AEEDA00ECAC67E91BC62CF42FE69D6B9A427A, 9758F103B57D3AE6533F736F17C95D48
+ 25: B6388AD629A4A951F2CDE98C80A81C8C499ABFE073EE81FD6A, 70A8217A7652D8325EB717359C1D7830
+ 26: 51D9F3341368BE00BE709F6F009BA53F852CA27ADEF439CB5A59, 6772C710B9D6159F1B0F4BC2BD5DC1A4
+ 27: 4710196F162BFF2BD87945AE012CE9FFC7C6EB651C716DCFBB6706, A338043240EA22FB4B50A1D6BCA241FA
+ 28: 8120FAF7FC1FD6157519A296EC5513F2907ECB8792219CFBE0A3E17E, 45EA2ADF503BCDFD60EDFEA24168D539
+ 29: 34FFD8289321EBD9029158A2C217DC867436CF5346B3B940B3B9339C0A, 3A7C1C2F5CFADF3F4C601C005333826D
+ 30: 8E97C51214057F523B915BE5EE84D72979254577077FD6D9FDA63215668A, BB5E2FC288DE613716BA3F3A69F6D17A
+ 31: F1A13BEC82D4FB33A5E5E6E1A5DD47DDC7F67AF5EBCAE980AB1B641A76FBDE, A2BBEA281BA38731F855EF8533B94C60
+ 32: 77CC8CB5ECBD4CDFC9BA9414B6E6596D7ED01B24C46D9EBCFE150FEA2687EFC3, 5295D9ECAB6E2CC4C6C60D27F4A5E7F9
+
+OCB-skipjack (10 byte key)
+  0: , 90EAAB5131AEB43B
+  1: 01, D8C438498F94B782
+  2: 23BD, 6D650F6CB26C0BEE
+  3: E5D16E, E4459817F4A898E6
+  4: 126212FE, D97B43C7BFB83262
+  5: A1580EA0A3, BC7C325FF295A404
+  6: 9374B704E26D, 97DBA225A0F0136E
+  7: BC2E8E234CBE33, 4603D9A50B9915ED
+  8: C7629762CF53A687, 5DAF80ABDD01CD74
+  9: 151D35020935EFB225, 0898987E5F710240
+ 10: 934BF9846689A0DDC434, FF698391DE287C55
+ 11: 8AF680448D95D32DE31B03, F60110D8968D1FB5
+ 12: E03FDF4028EBB30164C297D7, A80E7FD7A5028E62
+ 13: 614BF4A0A567314FA3990020FC, 6B1C9D495FED96C7
+ 14: D8BFFD57B4BB8C100F3F026105C3, 2F99A8895B86B798
+ 15: 81B2DD86C7252B4FD8D4FD385E65BB, 7788260BCABCCC8F
+ 16: 8AE9FEF234B5FC98AE95C1AFD6780C61, B332941A6EB467F7
+

+ 33 - 33
notes/omac_tv.txt

@@ -352,39 +352,39 @@ OMAC-cast5 (8 byte key)
  16: E8B0B219D4CB699B
 
 OMAC-noekeon (16 byte key)
-  0: 897F93D42DF43E4FDACB0E19A27D0CF5
-  1: 3FAB4FD1A374C36E80D0535ADA81583A
-  2: 209F1B04BD823B068BC19CEF40B875DB
-  3: E8FC96A2D8EB9BDA9E8A4EA8F6FE611A
-  4: 35DE59C345C4AF97924187A6EA73F556
-  5: 59793AB3D84D614D8AEE6E233B3DE755
-  6: 64DCB7E74485DF98F4DC70B14DD26107
-  7: 42E87ABB43E4504DB362B59A9BBC28DC
-  8: 98EC0C30C1AFBF4BC9A2DF421AC446E4
-  9: 8B3B59B481B7AFDB6BC593E2BB2A80B2
- 10: 0F60392A9518682015F43B8109E3A773
- 11: A99BEC6BB467B5949EC4819B8FB47874
- 12: 8E15ED270998CD1D7226B2BB9B5A8BC8
- 13: B4D637277DE68E507DD95E6EC495B364
- 14: DCCF001FA3A9AB5C58213CEB90B341E7
- 15: 508C01FDA50B06DDC1AF9CD78F0FD2C7
- 16: 3DB78001DE8115BE9E0B884AE4243926
- 17: 165951DF3F7D28AD6A2FE56DC32A0F60
- 18: 155944AEA14A6E08283421E8F19FE6F3
- 19: 151BEE5BC94004DFD407A0EFE51F8D9A
- 20: 081C3192C00D7BACB147FDDA5C460A4A
- 21: BEEB181DB90F5B3B1DD5BCFFC87C66DE
- 22: D83B9F8AFD912D8424C85AB0FBDD4751
- 23: A3BAF0E00DEBFB9C3A7B65A5AFCEE670
- 24: D03695C35C7D36C05FD26ADBF070E559
- 25: 5BFAA49199ABCE1CFBA626D30FA6AB0F
- 26: 9C3601196AD328AADBE62C730ECCC888
- 27: 75D79E48C5797963EBAF466BC0E1639E
- 28: 968DF7D963E6D023EC8421C7B2787E7B
- 29: 5E315EB6B6E583E7D8CF78A3A81D28C9
- 30: 322E00FC522FA7B41A6564E37F3D9DDC
- 31: AAB04CB0B25A7A7951C75592BA7CB360
- 32: CD5B1ED284EDCD493EFE133ECEA0F822
+  0: EC61647B281C47C1B43F9815064BF953
+  1: B100B1B6CD96DCED8F47A77E70670A92
+  2: A96CDE3C48831A6B0A5ADFECA6399BDB
+  3: 14E75E7CAD840208834918B29A5D4430
+  4: 9577083713AE6E44EEC987C77C93C072
+  5: 2A738C02841E461238C02F5CFC8E66A6
+  6: A901327E451BE0D2D9DEC83DEEA9A022
+  7: 5ED7EE1BE04A64A689D15F6970A821A6
+  8: BA053E24FCFD02C731A8CFCA19EE66A0
+  9: 57139CA8C91072555B29F85A19E2C84D
+ 10: 4585EAC7EFB84869FD96EE7A5FDD350B
+ 11: 62AF6C415CA73E54E82EA306254C1BDE
+ 12: 75304F9724BD364F84371EE154F5210E
+ 13: 7FE5DBCEE826760434745D417453182B
+ 14: EC98DA2A580E9131218D1CDE835423D4
+ 15: 631BD9EAFD1AE445F2C1C35E2B4416ED
+ 16: CA2D902A1D83388FE35BAB7C29F359BA
+ 17: 0DBF0AF7FCBEEE21FB6159C0A2FFCD4C
+ 18: BD7CD2C49241032DA33B1975EE2EE982
+ 19: B30B090EE8626D77D310EDB957552D46
+ 20: 64F608AC5707C381AC6878AA38345144
+ 21: 28513CA7795B23A02B37DC3732413D23
+ 22: 9F440700094517847E9E013C8915C433
+ 23: 8CA483F313D20BFE7E0C089DAA4145BD
+ 24: FA44872743E20E5E0A069B3C4578DB50
+ 25: F6DE8FFBECD52CC1F213CD9E406DF3BC
+ 26: B9702B7E846735A3DCC0724255F88FEC
+ 27: A1DDAFED2B1732C7BA89C2F194AF039E
+ 28: 2549C5F0E30F8F4002431D2C098805B8
+ 29: 52E3836181BF5C9B09A507D5330CD14F
+ 30: 01C55DCBCCFD9D7A4D27BDE2A89AA8EF
+ 31: 3CF721A0CF006702CDA91F2FF3E4D5E3
+ 32: 6D264B9065BE98C170E68E9D2A4DE86E
 
 OMAC-skipjack (10 byte key)
   0: 84EDFA769040603C

+ 1 - 1
notes/tech0003.txt

@@ -25,11 +25,11 @@ Blowfish    | 4,168                         |
 SAFER+      | 532                           |
 Serpent     | 528                           |
 Rijndael    | 516                           |
-RC5         | 204                           |
 XTEA        | 256                           |
 RC2         | 256                           |
 DES         | 256                           |
 SAFER [#]   | 217                           |
+RC5         | 204                           |
 Twofish [*] | 193                           |
 RC6         | 176                           |
 CAST5       | 132                           |

+ 561 - 0
ocb.c

@@ -0,0 +1,561 @@
+/* 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
+ */
+#include "mycrypt.h"
+
+#define OCB_MODE
+#ifdef OCB_MODE
+
+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 ocb_init(ocb_state *ocb, int cipher, 
+             const unsigned char *key, unsigned long keylen, const unsigned char *nonce)
+{
+   int x, y, z, m, p, err;
+   unsigned char tmp[MAXBLOCKSIZE];
+
+   _ARGCHK(ocb != NULL);
+   _ARGCHK(key != NULL);
+   _ARGCHK(nonce != NULL);
+
+   /* valid cipher? */
+   if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* determine which polys to use */
+   ocb->block_len = cipher_descriptor[cipher].block_length;
+   for (ocb->poly = 0; ocb->poly < (int)(sizeof(polys)/sizeof(polys[0])); ocb->poly++) {
+       if (polys[ocb->poly].len == ocb->block_len) { 
+          break;
+       }
+   }
+   if (polys[ocb->poly].len != ocb->block_len) {
+      return CRYPT_INVALID_ARG;
+   }   
+
+   /* schedule the key */
+   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &ocb->key)) != CRYPT_OK) {
+      return err;
+   }
+ 
+   /* find L = E[0] */
+   zeromem(ocb->L, ocb->block_len);
+   cipher_descriptor[cipher].ecb_encrypt(ocb->L, ocb->L, &ocb->key);
+
+   /* find R = E[N xor L] */
+   for (x = 0; x < ocb->block_len; x++) {
+       ocb->R[x] = ocb->L[x] ^ nonce[x];
+   }
+   cipher_descriptor[cipher].ecb_encrypt(ocb->R, ocb->R, &ocb->key);
+
+   /* find Ls[i] = L << i for i == 0..31 */
+   memcpy(ocb->Ls[0], ocb->L, ocb->block_len);
+   for (x = 1; x < 32; x++) {
+       m = ocb->Ls[x-1][0] >> 7;
+       for (y = 0; y < ocb->block_len-1; y++) {
+           ocb->Ls[x][y] = ((ocb->Ls[x-1][y] << 1) | (ocb->Ls[x-1][y+1] >> 7)) & 255;
+       }
+       ocb->Ls[x][ocb->block_len-1] = (ocb->Ls[x-1][ocb->block_len-1] << 1) & 255;
+
+       if (m == 1) {
+          for (y = 0; y < ocb->block_len; y++) {
+              ocb->Ls[x][y] ^= polys[ocb->poly].poly_mul[y];
+          }
+       }
+    }
+
+    /* find Lr = L / x */
+    m = ocb->L[ocb->block_len-1] & 1;
+
+    /* shift right */
+    for (x = ocb->block_len - 1; x > 0; x--) {
+        ocb->Lr[x] = ((ocb->L[x] >> 1) | (ocb->L[x-1] << 7)) & 255;
+    }
+    ocb->Lr[0] = ocb->L[0] >> 1;
+
+    if (m == 1) {
+       for (x = 0; x < ocb->block_len; x++) {
+           ocb->Lr[x] ^= polys[ocb->poly].poly_div[x];
+       }
+    }
+
+    /* set Li, checksum */
+    zeromem(ocb->Li, ocb->block_len);
+    zeromem(ocb->checksum, ocb->block_len);
+
+    /* set other params */
+    ocb->block_index = 1;
+    ocb->cipher      = cipher;
+
+    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(ocb_state *ocb, unsigned char *Z)
+{
+   int x, y;
+   y = ntz(ocb->block_index++);
+   for (x = 0; x < ocb->block_len; x++) {
+       ocb->Li[x] ^= ocb->Ls[y][x];
+       Z[x]        = ocb->Li[x] ^ ocb->R[x];
+   }
+}
+
+int ocb_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned char *ct)
+{
+   unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
+   int err, x, y;
+
+   _ARGCHK(ocb != NULL);
+   _ARGCHK(pt  != NULL);
+   _ARGCHK(ct  != NULL);
+   if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
+      return err;
+   }
+   if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* compute checksum */
+   for (x = 0; x < ocb->block_len; x++) {
+       ocb->checksum[x] ^= pt[x];
+   }
+
+   /* Get Z[i] value */
+   shift_xor(ocb, Z);
+
+   /* xor pt in, encrypt, xor Z out */
+   for (x = 0; x < ocb->block_len; x++) {
+       tmp[x] = pt[x] ^ Z[x];
+   }
+   cipher_descriptor[ocb->cipher].ecb_encrypt(tmp, ct, &ocb->key);
+   for (x = 0; x < ocb->block_len; x++) {
+       ct[x] ^= Z[x];
+   }
+
+#ifdef CLEAN_STACK
+   zeromem(Z, sizeof(Z));
+   zeromem(tmp, sizeof(tmp));
+#endif
+   return CRYPT_OK;
+}
+
+int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
+{
+   unsigned char Z[MAXBLOCKSIZE], tmp[MAXBLOCKSIZE];
+   int err, x, y;
+
+   _ARGCHK(ocb != NULL);
+   _ARGCHK(pt  != NULL);
+   _ARGCHK(ct  != NULL);
+   if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
+      return err;
+   }
+   if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* Get Z[i] value */
+   shift_xor(ocb, Z);
+
+   /* xor ct in, encrypt, xor Z out */
+   for (x = 0; x < ocb->block_len; x++) {
+       tmp[x] = ct[x] ^ Z[x];
+   }
+   cipher_descriptor[ocb->cipher].ecb_decrypt(tmp, pt, &ocb->key);
+   for (x = 0; x < ocb->block_len; x++) {
+       pt[x] ^= Z[x];
+   }
+
+   /* compute checksum */
+   for (x = 0; x < ocb->block_len; x++) {
+       ocb->checksum[x] ^= pt[x];
+   }
+
+
+#ifdef CLEAN_STACK
+   zeromem(Z, sizeof(Z));
+   zeromem(tmp, sizeof(tmp));
+#endif
+   return CRYPT_OK;
+}
+
+
+/* Since the last block is encrypted in CTR mode the same code can
+ * be used to finish a decrypt or encrypt stream.  The only difference
+ * is we XOR the final ciphertext into the checksum so we have to xor it
+ * before we CTR [decrypt] or after [encrypt]
+ *
+ * the names pt/ptlen/ct really just mean in/inlen/out but this is the way I wrote it... 
+ */
+static int _ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
+                     unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode)
+
+{
+   unsigned char Z[MAXBLOCKSIZE], Y[MAXBLOCKSIZE], X[MAXBLOCKSIZE];
+   int err, x, y;
+
+   _ARGCHK(ocb != NULL);
+   _ARGCHK(pt  != NULL);
+   _ARGCHK(ct  != NULL);
+   _ARGCHK(tag != NULL);
+   _ARGCHK(taglen != NULL);
+   if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
+      return err;
+   }
+   if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length ||
+       (int)ptlen > ocb->block_len || (int)ptlen < 0) {
+      return CRYPT_INVALID_ARG;
+   }
+
+   /* compute X[m] = len(pt[m]) XOR Lr XOR Z[m] */
+   shift_xor(ocb, X); 
+   memcpy(Z, X, ocb->block_len);
+
+   X[ocb->block_len-1] ^= ptlen&255;
+   for (x = 0; x < ocb->block_len; x++) {
+       X[x] ^= ocb->Lr[x]; 
+   }
+
+   /* Y[m] = E(X[m])) */
+   cipher_descriptor[ocb->cipher].ecb_encrypt(X, Y, &ocb->key);
+
+   if (mode == 1) {
+      /* decrypt mode, so let's xor it first */
+      /* xor C[m] into checksum */
+      for (x = 0; x < (int)ptlen; x++) {
+         ocb->checksum[x] ^= ct[x];
+      }  
+   }
+
+   /* C[m] = P[m] xor Y[m] */
+   for (x = 0; x < (int)ptlen; x++) {
+       ct[x] = pt[x] ^ Y[x];
+   }
+
+   if (mode == 0) {
+      /* encrypt mode */    
+      /* xor C[m] into checksum */
+      for (x = 0; x < (int)ptlen; x++) {
+          ocb->checksum[x] ^= ct[x];
+      }
+   }
+
+   /* xor Y[m] and Z[m] into checksum */
+   for (x = 0; x < ocb->block_len; x++) {
+       ocb->checksum[x] ^= Y[x] ^ Z[x];
+   }
+   
+   /* encrypt checksum, er... tag!! */
+   cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->checksum, X, &ocb->key);
+
+   /* now store it */
+   for (x = 0; x < ocb->block_len && x < (int)*taglen; x++) {
+       tag[x] = X[x];
+   }
+   *taglen = x;
+
+#ifdef CLEAN_STACK
+   zeromem(X, sizeof(X));
+   zeromem(Y, sizeof(Y));
+   zeromem(Z, sizeof(Z));
+#endif
+   return CRYPT_OK;
+}
+
+int ocb_done_encrypt(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen,
+                     unsigned char *ct, unsigned char *tag, unsigned long *taglen)
+{
+   return _ocb_done(ocb, pt, ptlen, ct, tag, taglen, 0);
+}
+
+
+int ocb_done_decrypt(ocb_state *ocb, 
+                     const unsigned char *ct,  unsigned long ctlen,
+                           unsigned char *pt, 
+                     const unsigned char *tag, unsigned long taglen, int *res)
+{
+   int err;
+   unsigned char tagbuf[MAXBLOCKSIZE];
+   unsigned long tagbuflen;
+
+
+   _ARGCHK(ocb != NULL);
+   _ARGCHK(pt  != NULL);
+   _ARGCHK(ct  != NULL);
+   _ARGCHK(tag != NULL);
+   _ARGCHK(res != NULL);
+
+   *res = 0;
+
+   tagbuflen = sizeof(tagbuf);
+   if ((err = _ocb_done(ocb, ct, ctlen, pt, tagbuf, &tagbuflen, 1)) != CRYPT_OK) {
+      return err;
+   }
+
+   if (taglen <= tagbuflen && memcmp(tagbuf, tag, taglen) == 0) {
+      *res = 1;
+   }
+
+#ifdef CLEAN_STACK
+   zeromem(tagbuf, sizeof(tagbuf));
+#endif
+
+   return CRYPT_OK;
+}
+
+int ocb_encrypt_authenticate_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *pt,     unsigned long ptlen,
+          unsigned char *ct,
+          unsigned char *tag,    unsigned long *taglen)
+{
+   int err, n;
+   ocb_state ocb;
+
+   if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
+      return err;
+   }
+
+   while (ptlen > (unsigned long)ocb.block_len) {
+        if ((err = ocb_encrypt(&ocb, pt, ct)) != CRYPT_OK) {
+           return err;
+        }
+        ptlen   -= ocb.block_len;
+        pt      += ocb.block_len;
+        ct      += ocb.block_len;
+   }
+
+   err = ocb_done_encrypt(&ocb, pt, ptlen, ct, tag, taglen);
+
+#ifdef CLEAN_STACK
+   zeromem(&ocb, sizeof(ocb));
+#endif
+   return err;
+}
+
+int ocb_decrypt_verify_memory(int cipher,
+    const unsigned char *key,    unsigned long keylen,
+    const unsigned char *nonce,  
+    const unsigned char *ct,     unsigned long ctlen,
+          unsigned char *pt,
+    const unsigned char *tag,    unsigned long taglen,
+          int           *res)
+{
+   int err, n;
+   ocb_state ocb;
+
+   if ((err = ocb_init(&ocb, cipher, key, keylen, nonce)) != CRYPT_OK) {
+      return err;
+   }
+
+   while (ctlen > (unsigned long)ocb.block_len) {
+        if ((err = ocb_decrypt(&ocb, ct, pt)) != CRYPT_OK) {
+           return err;
+        }
+        ctlen   -= ocb.block_len;
+        pt      += ocb.block_len;
+        ct      += ocb.block_len;
+   }
+
+   err = ocb_done_decrypt(&ocb, ct, ctlen, pt, tag, taglen, res);
+
+#ifdef CLEAN_STACK
+   zeromem(&ocb, sizeof(ocb));
+#endif
+   return err;
+}
+
+int ocb_test(void)
+{
+#ifndef LTC_TEST
+   return CRYPT_NOP;
+#else
+   static const struct {
+         int ptlen;
+         unsigned char key[16], nonce[16], pt[32], ct[32], tag[16];
+   } tests[] = {
+
+   /* NULL message */
+{
+   0,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* pt */
+   { 0x00 },
+   /* ct */
+   { 0x00 },
+   /* tag */
+   { 0x04, 0xad, 0xa4, 0x5e, 0x94, 0x7b, 0xc5, 0xb6,
+     0xe0, 0x0f, 0x4c, 0x8b, 0x80, 0x53, 0x90, 0x2d }
+},
+   
+   /* one byte message */
+{
+   1,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* pt */
+   { 0x11 },
+   /* ct */
+   { 0x6f },
+   /* tag */
+   { 0xe2, 0x61, 0x42, 0x3e, 0xbb, 0x0e, 0x7f, 0x3b,
+     0xa6, 0xdd, 0xf1, 0x3e, 0xe8, 0x0b, 0x7b, 0x00}
+},
+
+   /* 16 byte message */
+{
+   16,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* pt */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* ct */
+   { 0x6a, 0xaf, 0xac, 0x40, 0x6d, 0xfa, 0x87, 0x40,
+     0x57, 0xc7, 0xdb, 0xe9, 0x6f, 0x1b, 0x39, 0x53 },
+   /* tag */
+   { 0xff, 0xbf, 0x96, 0x87, 0x72, 0xfe, 0xee, 0x59,
+     0x08, 0x1f, 0xc7, 0x8c, 0x8f, 0xd9, 0x16, 0xc2 }
+},
+
+   /* 17 byte message */
+{
+   17,
+   /* key */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* nonce */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+   /* pt */
+   { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+     0x10 },
+   /* ct */
+   { 0x8c, 0x94, 0xbd, 0xd4, 0x2d, 0xdd, 0x1c, 0x40,
+     0xbe, 0xe0, 0x06, 0xb5, 0xab, 0x54, 0x3b, 0x00,
+     0x20 },
+   /* tag */
+   { 0x0e, 0x72, 0x7c, 0x88, 0x73, 0xbb, 0x66, 0xd7,
+     0x4a, 0x4f, 0xd4, 0x84, 0x83, 0xc7, 0x9a, 0x29 }
+}
+
+};
+
+   int err, x, idx, res;
+   unsigned long len;
+   unsigned char outct[MAXBLOCKSIZE], 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 = ocb_encrypt_authenticate_memory(idx, tests[x].key, 16,
+             tests[x].nonce, tests[x].pt, tests[x].ptlen, outct, outtag, &len)) != CRYPT_OK) {
+           return err;
+        }
+        
+        if (memcmp(outtag, tests[x].tag, len) || memcmp(outct, tests[x].ct, tests[x].ptlen)) {
+#if 0
+           unsigned long y;
+           printf("\n\nFailure: \nCT:\n");
+           for (y = 0; y < (unsigned long)tests[x].ptlen; ) {
+               printf("0x%02x", outct[y]);
+               if (y < (unsigned long)(tests[x].ptlen-1)) printf(", ");
+               if (!(++y % 8)) printf("\n");
+           }
+           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;
+        }
+        
+        if ((err = ocb_decrypt_verify_memory(idx, tests[x].key, 16, tests[x].nonce, outct, tests[x].ptlen,
+             outct, tests[x].tag, len, &res)) != CRYPT_OK) {
+           return err;
+        }
+        if (res != 1 || memcmp(tests[x].pt, outct, tests[x].ptlen)) {
+#if 0
+           unsigned long y;
+           printf("\n\nFailure-decrypt: \nPT:\n");
+           for (y = 0; y < (unsigned long)tests[x].ptlen; ) {
+               printf("0x%02x", outct[y]);
+               if (y < (unsigned long)(tests[x].ptlen-1)) printf(", ");
+               if (!(++y % 8)) printf("\n");
+           }
+           printf("\nres = %d\n\n", res);
+#endif
+        }
+    }
+    return CRYPT_OK;
+#endif /* LTC_TEST */
+}
+
+#endif /* OCB_MODE */
+
+
+/* some comments
+
+   -- it's hard to seek
+   -- hard to stream [you can't emit ciphertext until full block]
+   -- The setup is somewhat complicated...
+*/

+ 10 - 0
ofb.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef OFB

+ 79 - 27
omac.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /* OMAC1 Support by Tom St Denis (for 64 and 128 bit block ciphers only) */
 #include "mycrypt.h"
 
@@ -15,16 +25,6 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l
       return err;
    }
 
-   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) {
-      return err;
-   }
-
-   /* ok now we need Lu and Lu^2 [calc one from the other] */
-
-   /* first calc L which is Ek(0) */
-   zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
-   cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key);
-
    /* now setup the system */
    switch (cipher_descriptor[cipher].block_length) {
        case 8:  mask = 0x1B;
@@ -36,6 +36,16 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l
        default: return CRYPT_INVALID_ARG;
    }
 
+   if ((err = cipher_descriptor[cipher].setup(key, keylen, 0, &omac->key)) != CRYPT_OK) {
+      return err;
+   }
+
+   /* ok now we need Lu and Lu^2 [calc one from the other] */
+
+   /* first calc L which is Ek(0) */
+   zeromem(omac->Lu[0], cipher_descriptor[cipher].block_length);
+   cipher_descriptor[cipher].ecb_encrypt(omac->Lu[0], omac->Lu[0], &omac->key);
+
    /* now do the mults, whoopy! */
    for (x = 0; x < 2; x++) {
        /* if msb(L * u^(x+1)) = 0 then just shift, otherwise shift and xor constant mask */
@@ -57,7 +67,7 @@ int omac_init(omac_state *omac, int cipher, const unsigned char *key, unsigned l
    omac->cipher_idx = cipher;
    omac->buflen     = 0;
    omac->blklen     = len;
-   zeromem(omac->prev, sizeof(omac->prev));
+   zeromem(omac->prev,  sizeof(omac->prev));
    zeromem(omac->block, sizeof(omac->block));
 
    return CRYPT_OK;
@@ -209,17 +219,54 @@ int omac_test(void)
 #if !defined(LTC_TEST)
     return CRYPT_NOP;
 #else
-    static const unsigned char key[] = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 
-                                         0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c };
-    static const unsigned char pt[]  = { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
-                                         0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
-                                         0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 
-                                         0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
-                                         0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 };
-    static const unsigned char tag[] = { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
-                                         0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 };
+    static const struct { 
+        int keylen, msglen;
+        unsigned char key[32], msg[64], tag[16];
+    } tests[] = {
+    { 16, 0,
+      { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 
+        0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+      { 0x00 },
+      { 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
+        0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 }
+    },
+    { 16, 16, 
+      { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 
+        0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+      { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
+      { 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, 
+        0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c }
+    },
+    { 16, 40, 
+      { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 
+        0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+      { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+        0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 
+        0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+        0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11 },
+      { 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
+        0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 }
+    },
+    { 16, 64, 
+      { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 
+        0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
+      { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
+        0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
+        0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 
+        0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
+        0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+        0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
+        0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
+        0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
+      { 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, 
+        0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe }
+    }
+
+    };
     unsigned char out[16];
-    int err, idx;
+    int x, y, err, idx;
     unsigned long len;
 
 
@@ -229,13 +276,18 @@ int omac_test(void)
           return CRYPT_NOP;
        }
     }
-    len = sizeof(out);
-    if ((err = omac_memory(idx, key, 16, pt, 40, out, &len)) != CRYPT_OK) {
-       return err;
-    }
 
-    if (memcmp(out, tag, 16) != 0) {
-       return CRYPT_FAIL_TESTVECTOR;
+    for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
+       len = sizeof(out); 
+       if ((err = omac_memory(idx, tests[x].key, tests[x].keylen, tests[x].msg, tests[x].msglen, out, &len)) != CRYPT_OK) {
+          return err;
+       }
+
+       if (memcmp(out, tests[x].tag, 16) != 0) {
+          printf("\n\nTag: ");
+          for (y = 0; y < 16; y++) printf("%02x", out[y]); printf("\n\n");
+          return CRYPT_FAIL_TESTVECTOR;
+       }
     }
     return CRYPT_OK;
 #endif

+ 10 - 0
packet.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef PACKET

+ 10 - 0
prime.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef MPI

+ 16 - 2
rc2.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 /**********************************************************************\
 * To commemorate the 1996 RSA Data Security Conference, the following  *
 * code is released into the public domain by its author.  Prost!       *
@@ -116,13 +126,15 @@ void rc2_ecb_encrypt( const unsigned char *plain,
                             symmetric_key *skey)
 #endif
 {
-    unsigned *xkey = skey->rc2.xkey;
+    unsigned *xkey;
     unsigned x76, x54, x32, x10, i;
 
     _ARGCHK(plain != NULL);
     _ARGCHK(cipher != NULL);
     _ARGCHK(skey != NULL);
 
+    xkey = skey->rc2.xkey;
+
     x76 = ((unsigned)plain[7] << 8) + (unsigned)plain[6];
     x54 = ((unsigned)plain[5] << 8) + (unsigned)plain[4];
     x32 = ((unsigned)plain[3] << 8) + (unsigned)plain[2];
@@ -184,13 +196,15 @@ void rc2_ecb_decrypt( const unsigned char *cipher,
 #endif
 {
     unsigned x76, x54, x32, x10;
-    unsigned *xkey = skey->rc2.xkey;
+    unsigned *xkey;
     int i;
 
     _ARGCHK(plain != NULL);
     _ARGCHK(cipher != NULL);
     _ARGCHK(skey != NULL);
 
+    xkey = skey->rc2.xkey;
+
     x76 = ((unsigned)cipher[7] << 8) + (unsigned)cipher[6];
     x54 = ((unsigned)cipher[5] << 8) + (unsigned)cipher[4];
     x32 = ((unsigned)cipher[3] << 8) + (unsigned)cipher[2];

+ 10 - 0
rc4.c

@@ -1,3 +1,13 @@
+/* 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
+ */
 #include "mycrypt.h"
 
 #ifdef RC4

+ 13 - 0
rc5.c

@@ -1,3 +1,16 @@
+/* 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
+ */
+
+/* RC5 code by Tom St Denis */
+
 #include "mycrypt.h"
 
 #ifdef RC5

+ 12 - 0
rc6.c

@@ -1,3 +1,15 @@
+/* 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
+ */
+
+/* RC6 code by Tom St Denis */
 #include "mycrypt.h"
 
 #ifdef RC6

+ 11 - 0
rmd128.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* Implementation of RIPEMD-128 based on the source by Antoon Bosselaers, ESAT-COSIC
  *
  * This source has been radically overhauled to be portable and work within

+ 11 - 0
rmd160.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* Implementation of RIPEMD-160 based on the source by Antoon Bosselaers, ESAT-COSIC
  *
  * This source has been radically overhauled to be portable and work within

+ 15 - 41
rsa.c

@@ -1,3 +1,15 @@
+/* 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
+ */
+
+/* RSA Code by Tom St Denis */
 #include "mycrypt.h"
 
 #ifdef MRSA
@@ -308,49 +320,11 @@ int rsa_depad(const unsigned char *in,  unsigned long inlen,
    return CRYPT_OK;
 }
 
-#define OUTPUT_BIGNUM(num, buf2, y, z)         \
-{                                              \
-      z = (unsigned long)mp_unsigned_bin_size(num);  \
-      STORE32L(z, buf2+y);                     \
-      y += 4;                                  \
-      if (mp_to_unsigned_bin(num, buf2+y) != MP_OKAY) { return CRYPT_MEM; }    \
-      y += z;                                  \
-}
-
-
-#define INPUT_BIGNUM(num, in, x, y)                              \
-{                                                                \
-     /* load value */                                            \
-     if (y + 4 > inlen) {                                        \
-         err = CRYPT_INVALID_PACKET;                           \
-         goto error2;                                            \
-     }                                                           \
-     LOAD32L(x, in+y);                                           \
-     y += 4;                                                     \
-                                                                 \
-     /* sanity check... */                                       \
-     if (y+x > inlen) {                                          \
-        err = CRYPT_INVALID_PACKET;                            \
-        goto error2;                                             \
-     }                                                           \
-                                                                 \
-     /* load it */                                               \
-     if (mp_read_unsigned_bin(num, (unsigned char *)in+y, (int)x) != MP_OKAY) {\
-        err = CRYPT_MEM;                                       \
-        goto error2;                                             \
-     }                                                           \
-     y += x;                                                     \
-                                                                 \
-     if (mp_shrink(num) != MP_OKAY) {                            \
-        err = CRYPT_MEM;                                       \
-        goto error2;                                             \
-     }                                                           \
-}
-
 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;
 
    _ARGCHK(out != NULL);
    _ARGCHK(outlen != NULL);
@@ -464,7 +438,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
    }
 
    return CRYPT_OK;
-error2:
+error:
    mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
                   &key->pQ, &key->qP, &key->p, &key->q, NULL);
    return err;

+ 11 - 0
rsa_sys.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* these are smaller routines written by Clay Culver.  They do the same function as the rsa_encrypt/decrypt 
  * except that they are used to RSA encrypt/decrypt a single value and not a packet.
  */

+ 11 - 0
safer+.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* SAFER+ Implementation by Tom St Denis */
 #include "mycrypt.h"
 

+ 11 - 0
safer.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /*******************************************************************************
 *
 * FILE:           safer.c

+ 11 - 0
safer_tab.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 #include "mycrypt.h"
 
 #if defined(SAFERP) || defined(SAFER)

+ 12 - 0
sha1.c

@@ -1,3 +1,15 @@
+/* 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
+ */
+
+/* SHA1 code by Tom St Denis */
 #include "mycrypt.h"
 
 #ifdef SHA1

+ 11 - 0
sha224.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* SHA-224 new NIST standard based off of SHA-256 truncated to 224 bits */
 const struct _hash_descriptor sha224_desc =
 {

+ 14 - 0
sha256.c

@@ -1,3 +1,17 @@
+/* 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
+ */
+
+
+/* SHA256 by Tom St Denis */
+
 #include "mycrypt.h"
 
 #ifdef SHA256 

+ 11 - 0
sha384.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* included in sha512.c */
 
 const struct _hash_descriptor sha384_desc =

+ 13 - 0
sha512.c

@@ -1,3 +1,16 @@
+/* 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
+ */
+
+/* SHA512 by Tom St Denis */
+
 #include "mycrypt.h"
 
 #ifdef SHA512

+ 12 - 1
skipjack.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* Skipjack Implementation by Tom St Denis */
 #include "mycrypt.h"
 
@@ -84,7 +95,7 @@ int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetr
    tmp = ig_func(w2, &kp, key->skipjack.key);     \
    w2  = tmp ^ w3 ^ x;                            \
    w3  = w4; w4 = w1; w1 = tmp;
-   
+
 static unsigned g_func(unsigned w, int *kp, unsigned char *key)
 {
    unsigned char g1,g2;

+ 11 - 0
sprng.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* A secure PRNG using the RNG functions.  Basically this is a
  * wrapper that allows you to use a secure RNG as a PRNG
  * in the various other functions.

+ 11 - 0
strings.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* Future releases will make use of this */
 #include "mycrypt.h"
 

+ 11 - 0
tiger.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 #include "mycrypt.h"
 
 #ifdef TIGER

+ 4 - 1
tommath.h

@@ -338,6 +338,9 @@ int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
 /* c = (a, b) */
 int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
 
+/* produces value such that U1*a + U2*b = U3 */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
+
 /* c = [a, b] or (a*b)/(a, b) */
 int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
 
@@ -466,7 +469,7 @@ int mp_to_signed_bin(mp_int *a, unsigned char *b);
 
 int mp_read_radix(mp_int *a, char *str, int radix);
 int mp_toradix(mp_int *a, char *str, int radix);
-int mp_radix_size(mp_int *a, int radix);
+int mp_radix_size(mp_int *a, int radix, int *size);
 
 int mp_fread(mp_int *a, int radix, FILE *stream);
 int mp_fwrite(mp_int *a, int radix, FILE *stream);

+ 28 - 19
twofish.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 /* Implementation of Twofish by Tom St Denis */
 #include "mycrypt.h"
 
@@ -467,18 +478,17 @@ void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_k
     d ^= key->twofish.K[3];
     
     k  = key->twofish.K + 8;
-    for (r = 0; r < 16; r += 2) {
-        t1 = g_func(a, key);
+    for (r = 8; r != 0; --r) {
         t2 = g1_func(b, key);
-        c  = ROR(c ^ (t1 + t2 + k[0]), 1);
-        d  = ROL(d, 1) ^ (t2 + t2 + t1 + k[1]);
-        k += 2;
+        t1 = g_func(a, key) + t2;
+        c  = ROR(c ^ (t1 + k[0]), 1);
+        d  = ROL(d, 1) ^ (t2 + t1 + k[1]);
         
-        t1 = g_func(c, key);
         t2 = g1_func(d, key);
-        a  = ROR(a ^ (t1 + t2 + k[0]), 1);
-        b  = ROL(b, 1) ^ (t2 + t2 + t1 + k[1]);
-        k += 2;
+        t1 = g_func(c, key) + t2;
+        a  = ROR(a ^ (t1 + k[2]), 1);
+        b  = ROL(b, 1) ^ (t2 + t1 + k[3]);
+        k += 4;
    }
 
     /* output with "undo last swap" */
@@ -533,19 +543,18 @@ void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_k
     c = ta ^ key->twofish.K[4];
     d = tb ^ key->twofish.K[5];
 
-    k = key->twofish.K + 38;
-    for (r = 14; r >= 0; r -= 2) {
-        t1 = g_func(c, key);
+    k = key->twofish.K + 36;
+    for (r = 8; r != 0; --r) {
         t2 = g1_func(d, key);
-        a = ROL(a, 1) ^ (t1 + t2 + k[0]);
-        b = ROR(b ^ (t2 + t2 + t1 + k[1]), 1);
-        k -= 2;
+        t1 = g_func(c, key) + t2;
+        a = ROL(a, 1) ^ (t1 + k[2]);
+        b = ROR(b ^ (t2 + t1 + k[3]), 1);
 
-        t1 = g_func(a, key);
         t2 = g1_func(b, key);
-        c = ROL(c, 1) ^ (t1 + t2 + k[0]);
-        d = ROR(d ^ (t2 + t2 + t1 + k[1]), 1);
-        k -= 2;
+        t1 = g_func(a, key) + t2;
+        c = ROL(c, 1) ^ (t1 + k[0]);
+        d = ROR(d ^ (t2 +  t1 + k[1]), 1);
+        k -= 4;
     }
 
     /* pre-white */

+ 11 - 0
twofish_tab.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 #ifdef TWOFISH_TABLES
 
 /* pre generated 8x8 tables from the four 4x4s */

+ 11 - 0
xtea.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 #include "mycrypt.h"
 
 #ifdef XTEA

+ 11 - 0
yarrow.c

@@ -1,3 +1,14 @@
+/* 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
+ */
+
 #include "mycrypt.h"
 
 #ifdef YARROW