adding some new hashes
authorabner doubleday <wsmith@abners-MacBook-Air.local>
Fri, 14 Oct 2016 19:25:32 +0000 (15:25 -0400)
committerabner doubleday <wsmith@abners-MacBook-Air.local>
Fri, 14 Oct 2016 19:25:32 +0000 (15:25 -0400)
Crypto/blake.h [new file with mode: 0644]
Crypto/blake512.c [new file with mode: 0644]
Crypto/brg_types.h [new file with mode: 0644]
Crypto/skein.c [new file with mode: 0644]
Crypto/skein.h [new file with mode: 0644]
Crypto/skein_port.h [new file with mode: 0644]

diff --git a/Crypto/blake.h b/Crypto/blake.h
new file mode 100644 (file)
index 0000000..2b4e3a8
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+   BLAKE reference C implementation
+
+   Copyright (c) 2012 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
+
+   To the extent possible under law, the author(s) have dedicated all copyright
+   and related and neighboring rights to this software to the public domain
+   worldwide. This software is distributed without any warranty.
+
+   You should have received a copy of the CC0 Public Domain Dedication along with
+   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#define U8TO32_BIG(p)                                        \
+  (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) |  \
+   ((uint32_t)((p)[2]) <<  8) | ((uint32_t)((p)[3])      ))
+
+#define U32TO8_BIG(p, v)                                       \
+  (p)[0] = (uint8_t)((v) >> 24); (p)[1] = (uint8_t)((v) >> 16); \
+  (p)[2] = (uint8_t)((v) >>  8); (p)[3] = (uint8_t)((v)      );
+
+#define U8TO64_BIG(p) \
+  (((uint64_t)U8TO32_BIG(p) << 32) | (uint64_t)U8TO32_BIG((p) + 4))
+
+#define U64TO8_BIG(p, v)                     \
+  U32TO8_BIG((p),     (uint32_t)((v) >> 32)); \
+  U32TO8_BIG((p) + 4, (uint32_t)((v)      ));
+
+typedef struct
+{
+  uint32_t h[8], s[4], t[2];
+  int buflen, nullt;
+  uint8_t  buf[64];
+} state256;
+
+typedef state256 state224;
+
+typedef struct
+{
+  uint64_t h[8], s[4], t[2];
+  int buflen, nullt;
+  uint8_t buf[128];
+} state512;
+
+typedef state512 state384;
+
+const uint8_t sigma[][16] =
+{
+  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+  {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+  {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+  { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+  { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+  { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
+  {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
+  {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
+  { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
+  {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 },
+  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
+  {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
+  {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
+  { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
+  { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
+  { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }
+};
+
+const uint32_t u256[16] =
+{
+  0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+  0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+  0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+  0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917
+};
+
+const uint64_t u512[16] =
+{
+  0x243f6a8885a308d3ULL, 0x13198a2e03707344ULL, 
+  0xa4093822299f31d0ULL, 0x082efa98ec4e6c89ULL,
+  0x452821e638d01377ULL, 0xbe5466cf34e90c6cULL, 
+  0xc0ac29b7c97c50ddULL, 0x3f84d5b5b5470917ULL,
+  0x9216d5d98979fb1bULL, 0xd1310ba698dfb5acULL, 
+  0x2ffd72dbd01adfb7ULL, 0xb8e1afed6a267e96ULL,
+  0xba7c9045f12c7f99ULL, 0x24a19947b3916cf7ULL, 
+  0x0801f2e2858efc16ULL, 0x636920d871574e69ULL
+};
+
+
+static const uint8_t padding[129] =
+{
+  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
diff --git a/Crypto/blake512.c b/Crypto/blake512.c
new file mode 100644 (file)
index 0000000..44c2906
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+   BLAKE reference C implementation
+
+   Copyright (c) 2012 Jean-Philippe Aumasson <jeanphilippe.aumasson@gmail.com>
+
+   To the extent possible under law, the author(s) have dedicated all copyright
+   and related and neighboring rights to this software to the public domain
+   worldwide. This software is distributed without any warranty.
+
+   You should have received a copy of the CC0 Public Domain Dedication along with
+   this software. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
+ */
+#include "blake.h"
+
+void blake512_compress( state512 *S, const uint8_t *block )
+{
+  uint64_t v[16], m[16], i;
+#define ROT(x,n) (((x)<<(64-n))|( (x)>>(n)))
+#define G(a,b,c,d,e)          \
+  v[a] += (m[sigma[i][e]] ^ u512[sigma[i][e+1]]) + v[b];\
+  v[d] = ROT( v[d] ^ v[a],32);        \
+  v[c] += v[d];           \
+  v[b] = ROT( v[b] ^ v[c],25);        \
+  v[a] += (m[sigma[i][e+1]] ^ u512[sigma[i][e]])+v[b];  \
+  v[d] = ROT( v[d] ^ v[a],16);        \
+  v[c] += v[d];           \
+  v[b] = ROT( v[b] ^ v[c],11);
+
+  for( i = 0; i < 16; ++i )  m[i] = U8TO64_BIG( block + i * 8 );
+
+  for( i = 0; i < 8; ++i )  v[i] = S->h[i];
+
+  v[ 8] = S->s[0] ^ u512[0];
+  v[ 9] = S->s[1] ^ u512[1];
+  v[10] = S->s[2] ^ u512[2];
+  v[11] = S->s[3] ^ u512[3];
+  v[12] =  u512[4];
+  v[13] =  u512[5];
+  v[14] =  u512[6];
+  v[15] =  u512[7];
+
+  /* don't xor t when the block is only padding */
+  if ( !S->nullt )
+  {
+    v[12] ^= S->t[0];
+    v[13] ^= S->t[0];
+    v[14] ^= S->t[1];
+    v[15] ^= S->t[1];
+  }
+
+  for( i = 0; i < 16; ++i )
+  {
+    /* column step */
+    G( 0, 4, 8, 12, 0 );
+    G( 1, 5, 9, 13, 2 );
+    G( 2, 6, 10, 14, 4 );
+    G( 3, 7, 11, 15, 6 );
+    /* diagonal step */
+    G( 0, 5, 10, 15, 8 );
+    G( 1, 6, 11, 12, 10 );
+    G( 2, 7, 8, 13, 12 );
+    G( 3, 4, 9, 14, 14 );
+  }
+
+  for( i = 0; i < 16; ++i )  S->h[i % 8] ^= v[i];
+
+  for( i = 0; i < 8 ; ++i )  S->h[i] ^= S->s[i % 4];
+}
+
+
+void blake512_init( state512 *S )
+{
+  S->h[0] = 0x6a09e667f3bcc908ULL;
+  S->h[1] = 0xbb67ae8584caa73bULL;
+  S->h[2] = 0x3c6ef372fe94f82bULL;
+  S->h[3] = 0xa54ff53a5f1d36f1ULL;
+  S->h[4] = 0x510e527fade682d1ULL;
+  S->h[5] = 0x9b05688c2b3e6c1fULL;
+  S->h[6] = 0x1f83d9abfb41bd6bULL;
+  S->h[7] = 0x5be0cd19137e2179ULL;
+  S->t[0] = S->t[1] = S->buflen = S->nullt = 0;
+  S->s[0] = S->s[1] = S->s[2] = S->s[3] = 0;
+}
+
+
+void blake512_update( state512 *S, const uint8_t *in, uint64_t inlen )
+{
+  int left = S->buflen;
+  int fill = 128 - left;
+
+  /* data left and data received fill a block  */
+  if( left && ( inlen >= fill ) )
+  {
+    memcpy( ( void * ) ( S->buf + left ), ( void * ) in, fill );
+    S->t[0] += 1024;
+
+    if ( S->t[0] == 0 ) S->t[1]++;
+
+    blake512_compress( S, S->buf );
+    in += fill;
+    inlen  -= fill;
+    left = 0;
+  }
+
+  /* compress blocks of data received */
+  while( inlen >= 128 )
+  {
+    S->t[0] += 1024;
+
+    if ( S->t[0] == 0 ) S->t[1]++;
+
+    blake512_compress( S, in );
+    in += 128;
+    inlen -= 128;
+  }
+
+  /* store any data left */
+  if( inlen > 0 )
+  {
+    memcpy( ( void * ) ( S->buf + left ),   \
+            ( void * ) in, ( size_t ) inlen );
+    S->buflen = left + ( int )inlen;
+  }
+  else S->buflen = 0;
+}
+
+
+void blake512_final( state512 *S, uint8_t *out )
+{
+  uint8_t msglen[16], zo = 0x01, oo = 0x81;
+  uint64_t lo = S->t[0] + ( S->buflen << 3 ), hi = S->t[1];
+
+  /* support for hashing more than 2^32 bits */
+  if ( lo < ( S->buflen << 3 ) ) hi++;
+
+  U64TO8_BIG(  msglen + 0, hi );
+  U64TO8_BIG(  msglen + 8, lo );
+
+  if ( S->buflen == 111 )   /* one padding byte */
+  {
+    S->t[0] -= 8;
+    blake512_update( S, &oo, 1 );
+  }
+  else
+  {
+    if ( S->buflen < 111 )  /* enough space to fill the block */
+    {
+      if ( !S->buflen ) S->nullt = 1;
+
+      S->t[0] -= 888 - ( S->buflen << 3 );
+      blake512_update( S, padding, 111 - S->buflen );
+    }
+    else   /* need 2 compressions */
+    {
+      S->t[0] -= 1024 - ( S->buflen << 3 );
+      blake512_update( S, padding, 128 - S->buflen );
+      S->t[0] -= 888;
+      blake512_update( S, padding + 1, 111 );
+      S->nullt = 1;
+    }
+
+    blake512_update( S, &zo, 1 );
+    S->t[0] -= 8;
+  }
+
+  S->t[0] -= 128;
+  blake512_update( S, msglen, 16 );
+  U64TO8_BIG( out + 0, S->h[0] );
+  U64TO8_BIG( out + 8, S->h[1] );
+  U64TO8_BIG( out + 16, S->h[2] );
+  U64TO8_BIG( out + 24, S->h[3] );
+  U64TO8_BIG( out + 32, S->h[4] );
+  U64TO8_BIG( out + 40, S->h[5] );
+  U64TO8_BIG( out + 48, S->h[6] );
+  U64TO8_BIG( out + 56, S->h[7] );
+}
+
+
+void blake512_hash( uint8_t *out, const uint8_t *in, uint64_t inlen )
+{
+  state512 S;
+  blake512_init( &S );
+  blake512_update( &S, in, inlen );
+  blake512_final( &S, out );
+}
+
+
+void blake512_test()
+{
+  int i, v;
+  uint8_t in[144], out[64];
+  uint8_t test1[] =
+  {
+    0x97, 0x96, 0x15, 0x87, 0xf6, 0xd9, 0x70, 0xfa, 0xba, 0x6d, 0x24, 0x78, 0x04, 0x5d, 0xe6, 0xd1,
+    0xfa, 0xbd, 0x09, 0xb6, 0x1a, 0xe5, 0x09, 0x32, 0x05, 0x4d, 0x52, 0xbc, 0x29, 0xd3, 0x1b, 0xe4,
+    0xff, 0x91, 0x02, 0xb9, 0xf6, 0x9e, 0x2b, 0xbd, 0xb8, 0x3b, 0xe1, 0x3d, 0x4b, 0x9c, 0x06, 0x09,
+    0x1e, 0x5f, 0xa0, 0xb4, 0x8b, 0xd0, 0x81, 0xb6, 0x34, 0x05, 0x8b, 0xe0, 0xec, 0x49, 0xbe, 0xb3
+  };
+  uint8_t test2[] =
+  {
+    0x31, 0x37, 0x17, 0xd6, 0x08, 0xe9, 0xcf, 0x75, 0x8d, 0xcb, 0x1e, 0xb0, 0xf0, 0xc3, 0xcf, 0x9f,
+    0xC1, 0x50, 0xb2, 0xd5, 0x00, 0xfb, 0x33, 0xf5, 0x1c, 0x52, 0xaf, 0xc9, 0x9d, 0x35, 0x8a, 0x2f,
+    0x13, 0x74, 0xb8, 0xa3, 0x8b, 0xba, 0x79, 0x74, 0xe7, 0xf6, 0xef, 0x79, 0xca, 0xb1, 0x6f, 0x22,
+    0xCE, 0x1e, 0x64, 0x9d, 0x6e, 0x01, 0xad, 0x95, 0x89, 0xc2, 0x13, 0x04, 0x5d, 0x54, 0x5d, 0xde
+  };
+  memset( in, 0, 144 );
+  blake512_hash( out, in, 1 );
+  v = 0;
+
+  for( i = 0; i < 64; ++i )
+  {
+    if ( out[i] != test1[i] ) v = 1;
+  }
+
+  if ( v ) printf( "test 1 error\n" );
+
+  blake512_hash( out, in, 144 );
+  v = 0;
+
+  for( i = 0; i < 64; ++i )
+  {
+    if ( out[i] != test2[i] ) v = 1;
+  }
+
+  if ( v ) printf( "test 2 error\n" );
+}
+
+int main( int argc, char **argv )
+{
+#define BLOCK512 64
+  FILE *fp;
+  int i, j, bytesread;
+  uint8_t in[BLOCK512], out[64];
+  state512 S;
+  blake512_test();
+
+  for( i = 1; i < argc; ++i )
+  {
+    fp = fopen( *( argv + i ), "r" );
+
+    if ( fp == NULL )
+    {
+      printf( "Error: unable to open %s\n", *( argv + i ) );
+      return 1;
+    }
+
+    blake512_init( &S );
+
+    while( 1 )
+    {
+      bytesread = fread( in, 1, BLOCK512, fp );
+
+      if ( bytesread )
+        blake512_update( &S, in, bytesread );
+      else
+        break;
+    }
+
+    blake512_final( &S, out );
+
+    for( j = 0; j < 64; ++j )
+      printf( "%02x", out[j] );
+
+    printf( " %s\n", *( argv + i ) );
+    fclose( fp );
+  }
+
+  return 0;
+}
diff --git a/Crypto/brg_types.h b/Crypto/brg_types.h
new file mode 100644 (file)
index 0000000..6db737d
--- /dev/null
@@ -0,0 +1,188 @@
+/*\r
+ ---------------------------------------------------------------------------\r
+ Copyright (c) 1998-2006, Brian Gladman, Worcester, UK. All rights reserved.\r
+\r
+ LICENSE TERMS\r
+\r
+ The free distribution and use of this software in both source and binary\r
+ form is allowed (with or without changes) provided that:\r
+\r
+   1. distributions of this source code include the above copyright\r
+      notice, this list of conditions and the following disclaimer;\r
+\r
+   2. distributions in binary form include the above copyright\r
+      notice, this list of conditions and the following disclaimer\r
+      in the documentation and/or other associated materials;\r
+\r
+   3. the copyright holder's name is not used to endorse products\r
+      built using this software without specific written permission.\r
+\r
+ ALTERNATIVELY, provided that this notice is retained in full, this product\r
+ may be distributed under the terms of the GNU General Public License (GPL),\r
+ in which case the provisions of the GPL apply INSTEAD OF those given above.\r
+\r
+ DISCLAIMER\r
+\r
+ This software is provided 'as is' with no explicit or implied warranties\r
+ in respect of its properties, including, but not limited to, correctness\r
+ and/or fitness for purpose.\r
+ ---------------------------------------------------------------------------\r
+ Issue 09/09/2006\r
+\r
+ The unsigned integer types defined here are of the form uint_<nn>t where\r
+ <nn> is the length of the type; for example, the unsigned 32-bit type is\r
+ 'uint_32t'.  These are NOT the same as the 'C99 integer types' that are\r
+ defined in the inttypes.h and stdint.h headers since attempts to use these\r
+ types have shown that support for them is still highly variable.  However,\r
+ since the latter are of the form uint<nn>_t, a regular expression search\r
+ and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t')\r
+ can be used to convert the types used here to the C99 standard types.\r
+*/\r
+\r
+#ifndef BRG_TYPES_H\r
+#define BRG_TYPES_H\r
+\r
+#if defined(__cplusplus)\r
+extern "C" {\r
+#endif\r
+\r
+#include <limits.h>\r
+\r
+#ifndef BRG_UI8\r
+#  define BRG_UI8\r
+#  if UCHAR_MAX == 255u\r
+     typedef unsigned char uint_8t;\r
+#  else\r
+#    error Please define uint_8t as an 8-bit unsigned integer type in brg_types.h\r
+#  endif\r
+#endif\r
+\r
+#ifndef BRG_UI16\r
+#  define BRG_UI16\r
+#  if USHRT_MAX == 65535u\r
+     typedef unsigned short uint_16t;\r
+#  else\r
+#    error Please define uint_16t as a 16-bit unsigned short type in brg_types.h\r
+#  endif\r
+#endif\r
+\r
+#ifndef BRG_UI32\r
+#  define BRG_UI32\r
+#  if UINT_MAX == 4294967295u\r
+#    define li_32(h) 0x##h##u\r
+     typedef unsigned int uint_32t;\r
+#  elif ULONG_MAX == 4294967295u\r
+#    define li_32(h) 0x##h##ul\r
+     typedef unsigned long uint_32t;\r
+#  elif defined( _CRAY )\r
+#    error This code needs 32-bit data types, which Cray machines do not provide\r
+#  else\r
+#    error Please define uint_32t as a 32-bit unsigned integer type in brg_types.h\r
+#  endif\r
+#endif\r
+\r
+#ifndef BRG_UI64\r
+#  if defined( __BORLANDC__ ) && !defined( __MSDOS__ )\r
+#    define BRG_UI64\r
+#    define li_64(h) 0x##h##ui64\r
+     typedef unsigned __int64 uint_64t;\r
+#  elif defined( _MSC_VER ) && ( _MSC_VER < 1300 )    /* 1300 == VC++ 7.0 */\r
+#    define BRG_UI64\r
+#    define li_64(h) 0x##h##ui64\r
+     typedef unsigned __int64 uint_64t;\r
+#  elif defined( __sun ) && defined(ULONG_MAX) && ULONG_MAX == 0xfffffffful\r
+#    define BRG_UI64\r
+#    define li_64(h) 0x##h##ull\r
+     typedef unsigned long long uint_64t;\r
+#  elif defined( UINT_MAX ) && UINT_MAX > 4294967295u\r
+#    if UINT_MAX == 18446744073709551615u\r
+#      define BRG_UI64\r
+#      define li_64(h) 0x##h##u\r
+       typedef unsigned int uint_64t;\r
+#    endif\r
+#  elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u\r
+#    if ULONG_MAX == 18446744073709551615ul\r
+#      define BRG_UI64\r
+#      define li_64(h) 0x##h##ul\r
+       typedef unsigned long uint_64t;\r
+#    endif\r
+#  elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u\r
+#    if ULLONG_MAX == 18446744073709551615ull\r
+#      define BRG_UI64\r
+#      define li_64(h) 0x##h##ull\r
+       typedef unsigned long long uint_64t;\r
+#    endif\r
+#  elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u\r
+#    if ULONG_LONG_MAX == 18446744073709551615ull\r
+#      define BRG_UI64\r
+#      define li_64(h) 0x##h##ull\r
+       typedef unsigned long long uint_64t;\r
+#    endif\r
+#  elif defined(__GNUC__)  /* DLW: avoid mingw problem with -ansi */\r
+#      define BRG_UI64\r
+#      define li_64(h) 0x##h##ull\r
+       typedef unsigned long long uint_64t;\r
+#  endif\r
+#endif\r
+\r
+#if defined( NEED_UINT_64T ) && !defined( BRG_UI64 )\r
+#  error Please define uint_64t as an unsigned 64 bit type in brg_types.h\r
+#endif\r
+\r
+#ifndef RETURN_VALUES\r
+#  define RETURN_VALUES\r
+#  if defined( DLL_EXPORT )\r
+#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\r
+#      define VOID_RETURN    __declspec( dllexport ) void __stdcall\r
+#      define INT_RETURN     __declspec( dllexport ) int  __stdcall\r
+#    elif defined( __GNUC__ )\r
+#      define VOID_RETURN    __declspec( __dllexport__ ) void\r
+#      define INT_RETURN     __declspec( __dllexport__ ) int\r
+#    else\r
+#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\r
+#    endif\r
+#  elif defined( DLL_IMPORT )\r
+#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )\r
+#      define VOID_RETURN    __declspec( dllimport ) void __stdcall\r
+#      define INT_RETURN     __declspec( dllimport ) int  __stdcall\r
+#    elif defined( __GNUC__ )\r
+#      define VOID_RETURN    __declspec( __dllimport__ ) void\r
+#      define INT_RETURN     __declspec( __dllimport__ ) int\r
+#    else\r
+#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers\r
+#    endif\r
+#  elif defined( __WATCOMC__ )\r
+#    define VOID_RETURN  void __cdecl\r
+#    define INT_RETURN   int  __cdecl\r
+#  else\r
+#    define VOID_RETURN  void\r
+#    define INT_RETURN   int\r
+#  endif\r
+#endif\r
+\r
+/*  These defines are used to declare buffers in a way that allows\r
+    faster operations on longer variables to be used.  In all these\r
+    defines 'size' must be a power of 2 and >= 8\r
+\r
+    dec_unit_type(size,x)       declares a variable 'x' of length \r
+                                'size' bits\r
+\r
+    dec_bufr_type(size,bsize,x) declares a buffer 'x' of length 'bsize' \r
+                                bytes defined as an array of variables\r
+                                each of 'size' bits (bsize must be a \r
+                                multiple of size / 8)\r
+\r
+    ptr_cast(x,size)            casts a pointer to a pointer to a \r
+                                varaiable of length 'size' bits\r
+*/\r
+\r
+#define ui_type(size)               uint_##size##t\r
+#define dec_unit_type(size,x)       typedef ui_type(size) x\r
+#define dec_bufr_type(size,bsize,x) typedef ui_type(size) x[bsize / (size >> 3)]\r
+#define ptr_cast(x,size)            ((ui_type(size)*)(x))\r
+\r
+#if defined(__cplusplus)\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/Crypto/skein.c b/Crypto/skein.c
new file mode 100644 (file)
index 0000000..9cdde90
--- /dev/null
@@ -0,0 +1,747 @@
+/***********************************************************************\r
+**\r
+** Implementation of the Skein hash function.\r
+**\r
+** Source code author: Doug Whiting, 2008.\r
+**\r
+** This algorithm and source code is released to the public domain.\r
+** \r
+************************************************************************/\r
+\r
+#include <string.h>      /* get the memcpy/memset functions */\r
+#include "skein.h"       /* get the Skein API definitions   */\r
+\r
+/*****************************************************************/\r
+/* External function to process blkCnt (nonzero) full block(s) of data. */\r
+void    Skein_256_Process_Block(Skein_256_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);\r
+void    Skein_512_Process_Block(Skein_512_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);\r
+void    Skein1024_Process_Block(Skein1024_Ctxt_t *ctx,const u08b_t *blkPtr,size_t blkCnt,size_t byteCntAdd);\r
+\r
+/*****************************************************************/\r
+/*     Portable (i.e., slow) endianness conversion functions     */\r
+u64b_t Skein_Swap64(u64b_t w64)\r
+    {    /* instantiate the function body here */\r
+    static const u64b_t ONE = 1;              /* use this to check endianness */\r
+\r
+    /* figure out endianness "on-the-fly" */\r
+    if (1 == ((u08b_t *) & ONE)[0])\r
+        return w64;                           /* little-endian is fast */\r
+    else\r
+        return  (( w64       & 0xFF) << 56) | /*    big-endian is slow */\r
+                (((w64 >> 8) & 0xFF) << 48) |\r
+                (((w64 >>16) & 0xFF) << 40) |\r
+                (((w64 >>24) & 0xFF) << 32) |\r
+                (((w64 >>32) & 0xFF) << 24) |\r
+                (((w64 >>40) & 0xFF) << 16) |\r
+                (((w64 >>48) & 0xFF) <<  8) |\r
+                (((w64 >>56) & 0xFF)      ) ;\r
+    }\r
+\r
+void    Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt)\r
+    { /* this version is fully portable (big-endian or little-endian), but slow */\r
+    size_t n;\r
+\r
+    for (n=0;n<bCnt;n++)\r
+        dst[n] = (u08b_t) (src[n>>3] >> (8*(n&7)));\r
+    }\r
+\r
+void    Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt)\r
+    { /* this version is fully portable (big-endian or little-endian), but slow */\r
+    size_t n;\r
+\r
+    for (n=0;n<8*wCnt;n+=8)\r
+        dst[n/8] = (((u64b_t) src[n  ])      ) +\r
+                   (((u64b_t) src[n+1]) <<  8) +\r
+                   (((u64b_t) src[n+2]) << 16) +\r
+                   (((u64b_t) src[n+3]) << 24) +\r
+                   (((u64b_t) src[n+4]) << 32) +\r
+                   (((u64b_t) src[n+5]) << 40) +\r
+                   (((u64b_t) src[n+6]) << 48) +\r
+                   (((u64b_t) src[n+7]) << 56) ;\r
+    }\r
+\r
+/*****************************************************************/\r
+/*     256-bit Skein                                             */\r
+/*****************************************************************/\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* init the context for a straight hashing operation */\r
+int Skein_256_Init(Skein_256_Ctxt_t *ctx, size_t hashBitLen)\r
+    {\r
+    union\r
+        {\r
+        u08b_t  b[SKEIN_256_STATE_BYTES];\r
+        u64b_t  w[SKEIN_256_STATE_WORDS];\r
+        } cfg;                                  /* config block */\r
+        \r
+    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r
+\r
+    /* build/process config block for hashing */\r
+    ctx->h.hashBitLen = hashBitLen;             /* output hash byte count */\r
+    Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\r
+\r
+    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r
+    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\r
+    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r
+    cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\r
+\r
+    /* compute the initial chaining values from config block */\r
+    memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\r
+    Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r
+\r
+    /* The chaining vars ctx->X are now initialized for the given hashBitLen. */\r
+    /* Set up to process the data message portion of the hash (default) */\r
+    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type, h.bCnt=0 */\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* init the context for a MAC and/or tree hash operation */\r
+/* [identical to Skein_256_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\r
+int Skein_256_InitExt(Skein_256_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\r
+    {\r
+    uint_t i;\r
+    union\r
+        {\r
+        u08b_t  b[SKEIN_256_STATE_BYTES];\r
+        u64b_t  w[SKEIN_256_STATE_WORDS];\r
+        } cfg;                                  /* config block */\r
+        \r
+    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r
+    Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\r
+\r
+    /* compute the initial chaining values ctx->X[], based on key */\r
+    if (keyBytes == 0)                          /* is there a key? */\r
+        {                                   \r
+        memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\r
+        }\r
+    else                                        /* here to pre-process a key */\r
+        {\r
+        Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\r
+        /* do a mini-Init right here */\r
+        ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\r
+        Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\r
+        memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\r
+        Skein_256_Update(ctx,key,keyBytes);     /* hash the key */\r
+        Skein_256_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\r
+        memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\r
+        for (i=0;i<SKEIN_256_STATE_WORDS;i++)   /* convert key bytes to context words */\r
+            ctx->X[i] = Skein_Swap64(ctx->X[i]);\r
+        }\r
+\r
+    /* build/process the config block, type == CONFIG (could be precomputed for each key) */\r
+    ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\r
+    Skein_Start_New_Type(ctx,CFG_FINAL);\r
+\r
+    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r
+    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\r
+    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r
+    cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\r
+\r
+    Skein_Show_Key(256,&ctx->h,key,keyBytes);\r
+\r
+    /* compute the initial chaining values from config block */\r
+    Skein_256_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r
+\r
+    /* The chaining vars ctx->X are now initialized */\r
+    /* Set up to process the data message portion of the hash */\r
+    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type, h.bCnt=0 */\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* process the input bytes */\r
+int Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\r
+    {\r
+    size_t n;\r
+\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);     /* catch uninitialized context */\r
+\r
+    /* process full blocks, if any */\r
+    if (msgByteCnt + ctx->h.bCnt > SKEIN_256_BLOCK_BYTES)\r
+        {\r
+        if (ctx->h.bCnt)                              /* finish up any buffered message data */\r
+            {\r
+            n = SKEIN_256_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\r
+            if (n)\r
+                {\r
+                Skein_assert(n < msgByteCnt);         /* check on our logic here */\r
+                memcpy(&ctx->b[ctx->h.bCnt],msg,n);\r
+                msgByteCnt  -= n;\r
+                msg         += n;\r
+                ctx->h.bCnt += n;\r
+                }\r
+            Skein_assert(ctx->h.bCnt == SKEIN_256_BLOCK_BYTES);\r
+            Skein_256_Process_Block(ctx,ctx->b,1,SKEIN_256_BLOCK_BYTES);\r
+            ctx->h.bCnt = 0;\r
+            }\r
+        /* now process any remaining full blocks, directly from input message data */\r
+        if (msgByteCnt > SKEIN_256_BLOCK_BYTES)\r
+            {\r
+            n = (msgByteCnt-1) / SKEIN_256_BLOCK_BYTES;   /* number of full blocks to process */\r
+            Skein_256_Process_Block(ctx,msg,n,SKEIN_256_BLOCK_BYTES);\r
+            msgByteCnt -= n * SKEIN_256_BLOCK_BYTES;\r
+            msg        += n * SKEIN_256_BLOCK_BYTES;\r
+            }\r
+        Skein_assert(ctx->h.bCnt == 0);\r
+        }\r
+\r
+    /* copy any remaining source message data bytes into b[] */\r
+    if (msgByteCnt)\r
+        {\r
+        Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES);\r
+        memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\r
+        ctx->h.bCnt += msgByteCnt;\r
+        }\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+   \r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* finalize the hash computation and output the result */\r
+int Skein_256_Final(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    size_t i,n,byteCnt;\r
+    u64b_t X[SKEIN_256_STATE_WORDS];\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\r
+    if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)   /* zero pad b[] if necessary */\r
+        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);\r
+    Skein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\r
+    \r
+    /* now output the result */\r
+    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r
+\r
+    /* run Threefish in "counter mode" to generate output */\r
+    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r
+    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */\r
+    for (i=0;i*SKEIN_256_BLOCK_BYTES < byteCnt;i++)\r
+        {\r
+        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r
+        Skein_Start_New_Type(ctx,OUT_FINAL);\r
+        Skein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */\r
+        n = byteCnt - i*SKEIN_256_BLOCK_BYTES;   /* number of output bytes left to go */\r
+        if (n >= SKEIN_256_BLOCK_BYTES)\r
+            n  = SKEIN_256_BLOCK_BYTES;\r
+        Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */\r
+        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);\r
+        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r
+        }\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\r
+size_t Skein_256_API_CodeSize(void)\r
+    {\r
+    return ((u08b_t *) Skein_256_API_CodeSize) -\r
+           ((u08b_t *) Skein_256_Init);\r
+    }\r
+#endif\r
+\r
+/*****************************************************************/\r
+/*     512-bit Skein                                             */\r
+/*****************************************************************/\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* init the context for a straight hashing operation */\r
+int Skein_512_Init(Skein_512_Ctxt_t *ctx, size_t hashBitLen)\r
+    {\r
+    union\r
+        {\r
+        u08b_t  b[SKEIN_512_STATE_BYTES];\r
+        u64b_t  w[SKEIN_512_STATE_WORDS];\r
+        } cfg;                                  /* config block */\r
+        \r
+    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r
+\r
+    /* build/process config block for hashing */\r
+    ctx->h.hashBitLen = hashBitLen;             /* output hash byte count */\r
+    Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\r
+\r
+    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r
+    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\r
+    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r
+    cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\r
+\r
+    /* compute the initial chaining values from config block */\r
+    memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\r
+    Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r
+\r
+    /* The chaining vars ctx->X are now initialized for the given hashBitLen. */\r
+    /* Set up to process the data message portion of the hash (default) */\r
+    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type, h.bCnt=0 */\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* init the context for a MAC and/or tree hash operation */\r
+/* [identical to Skein_512_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\r
+int Skein_512_InitExt(Skein_512_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\r
+    {\r
+    uint_t i;\r
+    union\r
+        {\r
+        u08b_t  b[SKEIN_512_STATE_BYTES];\r
+        u64b_t  w[SKEIN_512_STATE_WORDS];\r
+        } cfg;                                  /* config block */\r
+        \r
+    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r
+    Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\r
+\r
+    /* compute the initial chaining values ctx->X[], based on key */\r
+    if (keyBytes == 0)                          /* is there a key? */\r
+        {                                   \r
+        memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\r
+        }\r
+    else                                        /* here to pre-process a key */\r
+        {\r
+        Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\r
+        /* do a mini-Init right here */\r
+        ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\r
+        Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\r
+        memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\r
+        Skein_512_Update(ctx,key,keyBytes);     /* hash the key */\r
+        Skein_512_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\r
+        memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\r
+        for (i=0;i<SKEIN_512_STATE_WORDS;i++)   /* convert key bytes to context words */\r
+            ctx->X[i] = Skein_Swap64(ctx->X[i]);\r
+        }\r
+\r
+    /* build/process the config block, type == CONFIG (could be precomputed for each key) */\r
+    ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\r
+    Skein_Start_New_Type(ctx,CFG_FINAL);\r
+\r
+    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r
+    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\r
+    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r
+    cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\r
+\r
+    Skein_Show_Key(512,&ctx->h,key,keyBytes);\r
+\r
+    /* compute the initial chaining values from config block */\r
+    Skein_512_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r
+\r
+    /* The chaining vars ctx->X are now initialized */\r
+    /* Set up to process the data message portion of the hash */\r
+    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type, h.bCnt=0 */\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* process the input bytes */\r
+int Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\r
+    {\r
+    size_t n;\r
+\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);     /* catch uninitialized context */\r
+\r
+    /* process full blocks, if any */\r
+    if (msgByteCnt + ctx->h.bCnt > SKEIN_512_BLOCK_BYTES)\r
+        {\r
+        if (ctx->h.bCnt)                              /* finish up any buffered message data */\r
+            {\r
+            n = SKEIN_512_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\r
+            if (n)\r
+                {\r
+                Skein_assert(n < msgByteCnt);         /* check on our logic here */\r
+                memcpy(&ctx->b[ctx->h.bCnt],msg,n);\r
+                msgByteCnt  -= n;\r
+                msg         += n;\r
+                ctx->h.bCnt += n;\r
+                }\r
+            Skein_assert(ctx->h.bCnt == SKEIN_512_BLOCK_BYTES);\r
+            Skein_512_Process_Block(ctx,ctx->b,1,SKEIN_512_BLOCK_BYTES);\r
+            ctx->h.bCnt = 0;\r
+            }\r
+        /* now process any remaining full blocks, directly from input message data */\r
+        if (msgByteCnt > SKEIN_512_BLOCK_BYTES)\r
+            {\r
+            n = (msgByteCnt-1) / SKEIN_512_BLOCK_BYTES;   /* number of full blocks to process */\r
+            Skein_512_Process_Block(ctx,msg,n,SKEIN_512_BLOCK_BYTES);\r
+            msgByteCnt -= n * SKEIN_512_BLOCK_BYTES;\r
+            msg        += n * SKEIN_512_BLOCK_BYTES;\r
+            }\r
+        Skein_assert(ctx->h.bCnt == 0);\r
+        }\r
+\r
+    /* copy any remaining source message data bytes into b[] */\r
+    if (msgByteCnt)\r
+        {\r
+        Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES);\r
+        memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\r
+        ctx->h.bCnt += msgByteCnt;\r
+        }\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+   \r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* finalize the hash computation and output the result */\r
+int Skein_512_Final(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    size_t i,n,byteCnt;\r
+    u64b_t X[SKEIN_512_STATE_WORDS];\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\r
+    if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)   /* zero pad b[] if necessary */\r
+        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);\r
+\r
+    Skein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\r
+    \r
+    /* now output the result */\r
+    byteCnt = (ctx->h.hashBitLen + 7) >> 3;             /* total number of output bytes */\r
+\r
+    /* run Threefish in "counter mode" to generate more output */\r
+    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r
+    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */\r
+    for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)\r
+        {\r
+        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r
+        Skein_Start_New_Type(ctx,OUT_FINAL);\r
+        Skein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */\r
+        n = byteCnt - i*SKEIN_512_BLOCK_BYTES;   /* number of output bytes left to go */\r
+        if (n >= SKEIN_512_BLOCK_BYTES)\r
+            n  = SKEIN_512_BLOCK_BYTES;\r
+        Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */\r
+        Skein_Show_Final(512,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);\r
+        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r
+        }\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\r
+size_t Skein_512_API_CodeSize(void)\r
+    {\r
+    return ((u08b_t *) Skein_512_API_CodeSize) -\r
+           ((u08b_t *) Skein_512_Init);\r
+    }\r
+#endif\r
+\r
+/*****************************************************************/\r
+/*    1024-bit Skein                                             */\r
+/*****************************************************************/\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* init the context for a straight hashing operation */\r
+int Skein1024_Init(Skein1024_Ctxt_t *ctx, size_t hashBitLen)\r
+    {\r
+    union\r
+        {\r
+        u08b_t  b[SKEIN1024_STATE_BYTES];\r
+        u64b_t  w[SKEIN1024_STATE_WORDS];\r
+        } cfg;                                  /* config block */\r
+        \r
+    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r
+\r
+    /* build/process config block for hashing */\r
+    ctx->h.hashBitLen = hashBitLen;             /* output hash byte count */\r
+    Skein_Start_New_Type(ctx,CFG_FINAL);        /* set tweaks: T0=0; T1=CFG | FINAL */\r
+\r
+    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r
+    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);  /* set the schema, version */\r
+    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r
+    cfg.w[2] = Skein_Swap64(SKEIN_CFG_TREE_INFO_SEQUENTIAL);\r
+\r
+    /* compute the initial chaining values from config block */\r
+    memset(ctx->X,0,sizeof(ctx->X));            /* zero the chaining variables */\r
+    Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r
+\r
+    /* The chaining vars ctx->X are now initialized for the given hashBitLen. */\r
+    /* Set up to process the data message portion of the hash (default) */\r
+    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type, h.bCnt=0 */\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* init the context for a MAC and/or tree hash operation */\r
+/* [identical to Skein1024_Init() when keyBytes == 0 && treeInfo == SKEIN_CFG_TREE_INFO_SEQUENTIAL] */\r
+int Skein1024_InitExt(Skein1024_Ctxt_t *ctx,size_t hashBitLen,u64b_t treeInfo, const u08b_t *key, size_t keyBytes)\r
+    {\r
+    uint_t i;\r
+    union\r
+        {\r
+        u08b_t  b[SKEIN1024_STATE_BYTES];\r
+        u64b_t  w[SKEIN1024_STATE_WORDS];\r
+        } cfg;                                  /* config block */\r
+        \r
+    Skein_Assert(hashBitLen > 0,SKEIN_BAD_HASHLEN);\r
+    Skein_Assert(keyBytes == 0 || key != NULL,SKEIN_FAIL);\r
+\r
+    /* compute the initial chaining values ctx->X[], based on key */\r
+    if (keyBytes == 0)                          /* is there a key? */\r
+        {                                   \r
+        memset(ctx->X,0,sizeof(ctx->X));        /* no key: use all zeroes as key for config block */\r
+        }\r
+    else                                        /* here to pre-process a key */\r
+        {\r
+        Skein_assert(sizeof(cfg.b) >= sizeof(ctx->X));\r
+        /* do a mini-Init right here */\r
+        ctx->h.hashBitLen=8*sizeof(ctx->X);     /* set output hash bit count = state size */\r
+        Skein_Start_New_Type(ctx,KEY);          /* set tweaks: T0 = 0; T1 = KEY type */\r
+        memset(ctx->X,0,sizeof(ctx->X));        /* zero the initial chaining variables */\r
+        Skein1024_Update(ctx,key,keyBytes);     /* hash the key */\r
+        Skein1024_Final_Pad(ctx,cfg.b);         /* put result into cfg.b[] */\r
+        memcpy(ctx->X,cfg.b,sizeof(cfg.b));     /* copy over into ctx->X[] */\r
+        for (i=0;i<SKEIN1024_STATE_WORDS;i++)   /* convert key bytes to context words */\r
+            ctx->X[i] = Skein_Swap64(ctx->X[i]);\r
+        }\r
+\r
+    /* build/process the config block, type == CONFIG (could be precomputed for each key) */\r
+    ctx->h.hashBitLen = hashBitLen;             /* output hash bit count */\r
+    Skein_Start_New_Type(ctx,CFG_FINAL);\r
+\r
+    memset(&cfg.w,0,sizeof(cfg.w));             /* pre-pad cfg.w[] with zeroes */\r
+    cfg.w[0] = Skein_Swap64(SKEIN_SCHEMA_VER);\r
+    cfg.w[1] = Skein_Swap64(hashBitLen);        /* hash result length in bits */\r
+    cfg.w[2] = Skein_Swap64(treeInfo);          /* tree hash config info (or SKEIN_CFG_TREE_INFO_SEQUENTIAL) */\r
+\r
+    Skein_Show_Key(1024,&ctx->h,key,keyBytes);\r
+\r
+    /* compute the initial chaining values from config block */\r
+    Skein1024_Process_Block(ctx,cfg.b,1,SKEIN_CFG_STR_LEN);\r
+\r
+    /* The chaining vars ctx->X are now initialized */\r
+    /* Set up to process the data message portion of the hash */\r
+    Skein_Start_New_Type(ctx,MSG);              /* T0=0, T1= MSG type, h.bCnt=0 */\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* process the input bytes */\r
+int Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt)\r
+    {\r
+    size_t n;\r
+\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);     /* catch uninitialized context */\r
+\r
+    /* process full blocks, if any */\r
+    if (msgByteCnt + ctx->h.bCnt > SKEIN1024_BLOCK_BYTES)\r
+        {\r
+        if (ctx->h.bCnt)                              /* finish up any buffered message data */\r
+            {\r
+            n = SKEIN1024_BLOCK_BYTES - ctx->h.bCnt;  /* # bytes free in buffer b[] */\r
+            if (n)\r
+                {\r
+                Skein_assert(n < msgByteCnt);         /* check on our logic here */\r
+                memcpy(&ctx->b[ctx->h.bCnt],msg,n);\r
+                msgByteCnt  -= n;\r
+                msg         += n;\r
+                ctx->h.bCnt += n;\r
+                }\r
+            Skein_assert(ctx->h.bCnt == SKEIN1024_BLOCK_BYTES);\r
+            Skein1024_Process_Block(ctx,ctx->b,1,SKEIN1024_BLOCK_BYTES);\r
+            ctx->h.bCnt = 0;\r
+            }\r
+        /* now process any remaining full blocks, directly from input message data */\r
+        if (msgByteCnt > SKEIN1024_BLOCK_BYTES)\r
+            {\r
+            n = (msgByteCnt-1) / SKEIN1024_BLOCK_BYTES;   /* number of full blocks to process */\r
+            Skein1024_Process_Block(ctx,msg,n,SKEIN1024_BLOCK_BYTES);\r
+            msgByteCnt -= n * SKEIN1024_BLOCK_BYTES;\r
+            msg        += n * SKEIN1024_BLOCK_BYTES;\r
+            }\r
+        Skein_assert(ctx->h.bCnt == 0);\r
+        }\r
+\r
+    /* copy any remaining source message data bytes into b[] */\r
+    if (msgByteCnt)\r
+        {\r
+        Skein_assert(msgByteCnt + ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES);\r
+        memcpy(&ctx->b[ctx->h.bCnt],msg,msgByteCnt);\r
+        ctx->h.bCnt += msgByteCnt;\r
+        }\r
+\r
+    return SKEIN_SUCCESS;\r
+    }\r
+   \r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* finalize the hash computation and output the result */\r
+int Skein1024_Final(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    size_t i,n,byteCnt;\r
+    u64b_t X[SKEIN1024_STATE_WORDS];\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;                 /* tag as the final block */\r
+    if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)   /* zero pad b[] if necessary */\r
+        memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);\r
+\r
+    Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);  /* process the final block */\r
+    \r
+    /* now output the result */\r
+    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r
+\r
+    /* run Threefish in "counter mode" to generate output */\r
+    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r
+    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */\r
+    for (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)\r
+        {\r
+        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r
+        Skein_Start_New_Type(ctx,OUT_FINAL);\r
+        Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */\r
+        n = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left to go */\r
+        if (n >= SKEIN1024_BLOCK_BYTES)\r
+            n  = SKEIN1024_BLOCK_BYTES;\r
+        Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */\r
+        Skein_Show_Final(1024,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);\r
+        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r
+        }\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+#if defined(SKEIN_CODE_SIZE) || defined(SKEIN_PERF)\r
+size_t Skein1024_API_CodeSize(void)\r
+    {\r
+    return ((u08b_t *) Skein1024_API_CodeSize) -\r
+           ((u08b_t *) Skein1024_Init);\r
+    }\r
+#endif\r
+\r
+#if SKEIN_TREE_HASH\r
+/**************** Functions to support tree hashing ***************/\r
+/* (this code is identical for Optimized and Reference versions)  */\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* finalize the hash computation and output the block, no OUTPUT stage */\r
+int Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\r
+    if (ctx->h.bCnt < SKEIN_256_BLOCK_BYTES)   /* zero pad b[] if necessary */\r
+        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_256_BLOCK_BYTES - ctx->h.bCnt);\r
+    Skein_256_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\r
+    \r
+    Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN_256_BLOCK_BYTES);   /* "output" the state bytes */\r
+    \r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* finalize the hash computation and output the block, no OUTPUT stage */\r
+int Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\r
+    if (ctx->h.bCnt < SKEIN_512_BLOCK_BYTES)   /* zero pad b[] if necessary */\r
+        memset(&ctx->b[ctx->h.bCnt],0,SKEIN_512_BLOCK_BYTES - ctx->h.bCnt);\r
+    Skein_512_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\r
+    \r
+    Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN_512_BLOCK_BYTES);   /* "output" the state bytes */\r
+    \r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* finalize the hash computation and output the block, no OUTPUT stage */\r
+int Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    ctx->h.T[1] |= SKEIN_T1_FLAG_FINAL;        /* tag as the final block */\r
+    if (ctx->h.bCnt < SKEIN1024_BLOCK_BYTES)   /* zero pad b[] if necessary */\r
+        memset(&ctx->b[ctx->h.bCnt],0,SKEIN1024_BLOCK_BYTES - ctx->h.bCnt);\r
+    Skein1024_Process_Block(ctx,ctx->b,1,ctx->h.bCnt);    /* process the final block */\r
+    \r
+    Skein_Put64_LSB_First(hashVal,ctx->X,SKEIN1024_BLOCK_BYTES);   /* "output" the state bytes */\r
+    \r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* just do the OUTPUT stage                                       */\r
+int Skein_256_Output(Skein_256_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    size_t i,n,byteCnt;\r
+    u64b_t X[SKEIN_256_STATE_WORDS];\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_256_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    /* now output the result */\r
+    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r
+\r
+    /* run Threefish in "counter mode" to generate output */\r
+    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r
+    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */\r
+    for (i=0;i*SKEIN_256_BLOCK_BYTES < byteCnt;i++)\r
+        {\r
+        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r
+        Skein_Start_New_Type(ctx,OUT_FINAL);\r
+        Skein_256_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */\r
+        n = byteCnt - i*SKEIN_256_BLOCK_BYTES;   /* number of output bytes left to go */\r
+        if (n >= SKEIN_256_BLOCK_BYTES)\r
+            n  = SKEIN_256_BLOCK_BYTES;\r
+        Skein_Put64_LSB_First(hashVal+i*SKEIN_256_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */\r
+        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_256_BLOCK_BYTES);\r
+        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r
+        }\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* just do the OUTPUT stage                                       */\r
+int Skein_512_Output(Skein_512_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    size_t i,n,byteCnt;\r
+    u64b_t X[SKEIN_512_STATE_WORDS];\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN_512_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    /* now output the result */\r
+    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r
+\r
+    /* run Threefish in "counter mode" to generate output */\r
+    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r
+    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */\r
+    for (i=0;i*SKEIN_512_BLOCK_BYTES < byteCnt;i++)\r
+        {\r
+        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r
+        Skein_Start_New_Type(ctx,OUT_FINAL);\r
+        Skein_512_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */\r
+        n = byteCnt - i*SKEIN_512_BLOCK_BYTES;   /* number of output bytes left to go */\r
+        if (n >= SKEIN_512_BLOCK_BYTES)\r
+            n  = SKEIN_512_BLOCK_BYTES;\r
+        Skein_Put64_LSB_First(hashVal+i*SKEIN_512_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */\r
+        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN_512_BLOCK_BYTES);\r
+        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r
+        }\r
+    return SKEIN_SUCCESS;\r
+    }\r
+\r
+/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/\r
+/* just do the OUTPUT stage                                       */\r
+int Skein1024_Output(Skein1024_Ctxt_t *ctx, u08b_t *hashVal)\r
+    {\r
+    size_t i,n,byteCnt;\r
+    u64b_t X[SKEIN1024_STATE_WORDS];\r
+    Skein_Assert(ctx->h.bCnt <= SKEIN1024_BLOCK_BYTES,SKEIN_FAIL);    /* catch uninitialized context */\r
+\r
+    /* now output the result */\r
+    byteCnt = (ctx->h.hashBitLen + 7) >> 3;    /* total number of output bytes */\r
+\r
+    /* run Threefish in "counter mode" to generate output */\r
+    memset(ctx->b,0,sizeof(ctx->b));  /* zero out b[], so it can hold the counter */\r
+    memcpy(X,ctx->X,sizeof(X));       /* keep a local copy of counter mode "key" */\r
+    for (i=0;i*SKEIN1024_BLOCK_BYTES < byteCnt;i++)\r
+        {\r
+        ((u64b_t *)ctx->b)[0]= Skein_Swap64((u64b_t) i); /* build the counter block */\r
+        Skein_Start_New_Type(ctx,OUT_FINAL);\r
+        Skein1024_Process_Block(ctx,ctx->b,1,sizeof(u64b_t)); /* run "counter mode" */\r
+        n = byteCnt - i*SKEIN1024_BLOCK_BYTES;   /* number of output bytes left to go */\r
+        if (n >= SKEIN1024_BLOCK_BYTES)\r
+            n  = SKEIN1024_BLOCK_BYTES;\r
+        Skein_Put64_LSB_First(hashVal+i*SKEIN1024_BLOCK_BYTES,ctx->X,n);   /* "output" the ctr mode bytes */\r
+        Skein_Show_Final(256,&ctx->h,n,hashVal+i*SKEIN1024_BLOCK_BYTES);\r
+        memcpy(ctx->X,X,sizeof(X));   /* restore the counter mode key for next time */\r
+        }\r
+    return SKEIN_SUCCESS;\r
+    }\r
+#endif\r
diff --git a/Crypto/skein.h b/Crypto/skein.h
new file mode 100644 (file)
index 0000000..174401c
--- /dev/null
@@ -0,0 +1,315 @@
+#ifndef _SKEIN_H_\r
+#define _SKEIN_H_     1\r
+/**************************************************************************\r
+**\r
+** Interface declarations and internal definitions for Skein hashing.\r
+**\r
+** Source code author: Doug Whiting, 2008.\r
+**\r
+** This algorithm and source code is released to the public domain.\r
+**\r
+***************************************************************************\r
+** \r
+** The following compile-time switches may be defined to control some\r
+** tradeoffs between speed, code size, error checking, and security.\r
+**\r
+** The "default" note explains what happens when the switch is not defined.\r
+**\r
+**  SKEIN_DEBUG            -- make callouts from inside Skein code\r
+**                            to examine/display intermediate values.\r
+**                            [default: no callouts (no overhead)]\r
+**\r
+**  SKEIN_ERR_CHECK        -- how error checking is handled inside Skein\r
+**                            code. If not defined, most error checking \r
+**                            is disabled (for performance). Otherwise, \r
+**                            the switch value is interpreted as:\r
+**                                0: use assert()      to flag errors\r
+**                                1: return SKEIN_FAIL to flag errors\r
+**\r
+***************************************************************************/\r
+\r
+#include <stddef.h>                          /* get size_t definition */\r
+#include "skein_port.h"                      /* get platform-specific definitions */\r
+\r
+enum\r
+    {\r
+    SKEIN_SUCCESS         =      0,          /* return codes from Skein calls */\r
+    SKEIN_FAIL            =      1,\r
+    SKEIN_BAD_HASHLEN     =      2\r
+    };\r
+\r
+#define  SKEIN_MODIFIER_WORDS  ( 2)          /* number of modifier (tweak) words */\r
+\r
+#define  SKEIN_256_STATE_WORDS ( 4)\r
+#define  SKEIN_512_STATE_WORDS ( 8)\r
+#define  SKEIN1024_STATE_WORDS (16)\r
+#define  SKEIN_MAX_STATE_WORDS (16)\r
+\r
+#define  SKEIN_256_STATE_BYTES ( 8*SKEIN_256_STATE_WORDS)\r
+#define  SKEIN_512_STATE_BYTES ( 8*SKEIN_512_STATE_WORDS)\r
+#define  SKEIN1024_STATE_BYTES ( 8*SKEIN1024_STATE_WORDS)\r
+\r
+#define  SKEIN_256_STATE_BITS  (64*SKEIN_256_STATE_WORDS)\r
+#define  SKEIN_512_STATE_BITS  (64*SKEIN_512_STATE_WORDS)\r
+#define  SKEIN1024_STATE_BITS  (64*SKEIN1024_STATE_WORDS)\r
+\r
+#define  SKEIN_256_BLOCK_BYTES ( 8*SKEIN_256_STATE_WORDS)\r
+#define  SKEIN_512_BLOCK_BYTES ( 8*SKEIN_512_STATE_WORDS)\r
+#define  SKEIN1024_BLOCK_BYTES ( 8*SKEIN1024_STATE_WORDS)\r
+\r
+typedef struct\r
+    {\r
+    size_t  hashBitLen;                      /* size of hash result, in bits */\r
+    size_t  bCnt;                            /* current byte count in buffer b[] */\r
+    u64b_t  T[SKEIN_MODIFIER_WORDS];         /* tweak words: T[0]=byte cnt, T[1]=flags */\r
+    } Skein_Ctxt_Hdr_t;\r
+\r
+typedef struct                               /*  256-bit Skein hash context structure */\r
+    {\r
+    Skein_Ctxt_Hdr_t h;                      /* common header context variables */\r
+    u64b_t  X[SKEIN_256_STATE_WORDS];        /* chaining variables */\r
+    u08b_t  b[SKEIN_256_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\r
+    } Skein_256_Ctxt_t;\r
+\r
+typedef struct                               /*  512-bit Skein hash context structure */\r
+    {\r
+    Skein_Ctxt_Hdr_t h;                      /* common header context variables */\r
+    u64b_t  X[SKEIN_512_STATE_WORDS];        /* chaining variables */\r
+    u08b_t  b[SKEIN_512_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\r
+    } Skein_512_Ctxt_t;\r
+\r
+typedef struct                               /* 1024-bit Skein hash context structure */\r
+    {\r
+    Skein_Ctxt_Hdr_t h;                      /* common header context variables */\r
+    u64b_t  X[SKEIN1024_STATE_WORDS];        /* chaining variables */\r
+    u08b_t  b[SKEIN1024_BLOCK_BYTES];        /* partial block buffer (8-byte aligned) */\r
+    } Skein1024_Ctxt_t;\r
+\r
+/*   Skein APIs for (incremental) "straight hashing" */\r
+int  Skein_256_Init  (Skein_256_Ctxt_t *ctx, size_t hashBitLen);\r
+int  Skein_512_Init  (Skein_512_Ctxt_t *ctx, size_t hashBitLen);\r
+int  Skein1024_Init  (Skein1024_Ctxt_t *ctx, size_t hashBitLen);\r
+\r
+int  Skein_256_Update(Skein_256_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\r
+int  Skein_512_Update(Skein_512_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\r
+int  Skein1024_Update(Skein1024_Ctxt_t *ctx, const u08b_t *msg, size_t msgByteCnt);\r
+\r
+int  Skein_256_Final (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\r
+int  Skein_512_Final (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\r
+int  Skein1024_Final (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\r
+\r
+/*\r
+**   Skein APIs for "extended" initialization: MAC keys, tree hashing.\r
+**   After an InitExt() call, just use Update/Final calls as with Init().\r
+**\r
+**   Notes: Same parameters as _Init() calls, plus treeInfo/key/keyBytes.\r
+**          When keyBytes == 0 and treeInfo == SKEIN_SEQUENTIAL, \r
+**              the results of InitExt() are identical to calling Init().\r
+**          The function Init() may be called once to "precompute" the IV for\r
+**              a given hashBitLen value, then by saving a copy of the context\r
+**              the IV computation may be avoided in later calls.\r
+**          Similarly, the function InitExt() may be called once per MAC key \r
+**              to precompute the MAC IV, then a copy of the context saved and\r
+**              reused for each new MAC computation.\r
+**/\r
+int  Skein_256_InitExt(Skein_256_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\r
+int  Skein_512_InitExt(Skein_512_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\r
+int  Skein1024_InitExt(Skein1024_Ctxt_t *ctx, size_t hashBitLen, u64b_t treeInfo, const u08b_t *key, size_t keyBytes);\r
+\r
+/*\r
+**   Skein APIs for MAC and tree hash:\r
+**      Final_Pad:  pad, do final block, but no OUTPUT type\r
+**      Output:     do just the output stage\r
+*/\r
+int  Skein_256_Final_Pad(Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\r
+int  Skein_512_Final_Pad(Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\r
+int  Skein1024_Final_Pad(Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\r
+\r
+#ifndef SKEIN_TREE_HASH\r
+#define SKEIN_TREE_HASH (1)\r
+#endif\r
+#if  SKEIN_TREE_HASH\r
+int  Skein_256_Output   (Skein_256_Ctxt_t *ctx, u08b_t * hashVal);\r
+int  Skein_512_Output   (Skein_512_Ctxt_t *ctx, u08b_t * hashVal);\r
+int  Skein1024_Output   (Skein1024_Ctxt_t *ctx, u08b_t * hashVal);\r
+#endif\r
+\r
+/*****************************************************************\r
+** "Internal" Skein definitions\r
+**    -- not needed for sequential hashing API, but will be \r
+**           helpful for other uses of Skein (e.g., tree hash mode).\r
+**    -- included here so that they can be shared between\r
+**           reference and optimized code.\r
+******************************************************************/\r
+\r
+/* tweak word T[1]: bit field starting positions */\r
+#define SKEIN_T1_BIT(BIT)       ((BIT) - 64)            /* offset 64 because it's the second word  */\r
+                                \r
+#define SKEIN_T1_POS_TREE_LVL   SKEIN_T1_BIT(112)       /* bits 112..118: level in hash tree       */\r
+#define SKEIN_T1_POS_BIT_PAD    SKEIN_T1_BIT(119)       /* bit  119     : partial final input byte */\r
+#define SKEIN_T1_POS_BLK_TYPE   SKEIN_T1_BIT(120)       /* bits 120..125: type field               */\r
+#define SKEIN_T1_POS_FIRST      SKEIN_T1_BIT(126)       /* bits 126     : first block flag         */\r
+#define SKEIN_T1_POS_FINAL      SKEIN_T1_BIT(127)       /* bit  127     : final block flag         */\r
+                                \r
+/* tweak word T[1]: flag bit definition(s) */\r
+#define SKEIN_T1_FLAG_FIRST     (((u64b_t)  1 ) << SKEIN_T1_POS_FIRST)\r
+#define SKEIN_T1_FLAG_FINAL     (((u64b_t)  1 ) << SKEIN_T1_POS_FINAL)\r
+#define SKEIN_T1_FLAG_BIT_PAD   (((u64b_t)  1 ) << SKEIN_T1_POS_BIT_PAD)\r
+                                \r
+/* tweak word T[1]: tree level bit field mask */\r
+#define SKEIN_T1_TREE_LVL_MASK  (((u64b_t)0x7F) << SKEIN_T1_POS_TREE_LVL)\r
+#define SKEIN_T1_TREE_LEVEL(n)  (((u64b_t) (n)) << SKEIN_T1_POS_TREE_LVL)\r
+\r
+/* tweak word T[1]: block type field */\r
+#define SKEIN_BLK_TYPE_KEY      ( 0)                    /* key, for MAC and KDF */\r
+#define SKEIN_BLK_TYPE_CFG      ( 4)                    /* configuration block */\r
+#define SKEIN_BLK_TYPE_PERS     ( 8)                    /* personalization string */\r
+#define SKEIN_BLK_TYPE_PK       (12)                    /* public key (for digital signature hashing) */\r
+#define SKEIN_BLK_TYPE_KDF      (16)                    /* key identifier for KDF */\r
+#define SKEIN_BLK_TYPE_NONCE    (20)                    /* nonce for PRNG */\r
+#define SKEIN_BLK_TYPE_MSG      (48)                    /* message processing */\r
+#define SKEIN_BLK_TYPE_OUT      (63)                    /* output stage */\r
+#define SKEIN_BLK_TYPE_MASK     (63)                    /* bit field mask */\r
+\r
+#define SKEIN_T1_BLK_TYPE(T)   (((u64b_t) (SKEIN_BLK_TYPE_##T)) << SKEIN_T1_POS_BLK_TYPE)\r
+#define SKEIN_T1_BLK_TYPE_KEY   SKEIN_T1_BLK_TYPE(KEY)  /* key, for MAC and KDF */\r
+#define SKEIN_T1_BLK_TYPE_CFG   SKEIN_T1_BLK_TYPE(CFG)  /* configuration block */\r
+#define SKEIN_T1_BLK_TYPE_PERS  SKEIN_T1_BLK_TYPE(PERS) /* personalization string */\r
+#define SKEIN_T1_BLK_TYPE_PK    SKEIN_T1_BLK_TYPE(PK)   /* public key (for digital signature hashing) */\r
+#define SKEIN_T1_BLK_TYPE_KDF   SKEIN_T1_BLK_TYPE(KDF)  /* key identifier for KDF */\r
+#define SKEIN_T1_BLK_TYPE_NONCE SKEIN_T1_BLK_TYPE(NONCE)/* nonce for PRNG */\r
+#define SKEIN_T1_BLK_TYPE_MSG   SKEIN_T1_BLK_TYPE(MSG)  /* message processing */\r
+#define SKEIN_T1_BLK_TYPE_OUT   SKEIN_T1_BLK_TYPE(OUT)  /* output stage */\r
+#define SKEIN_T1_BLK_TYPE_MASK  SKEIN_T1_BLK_TYPE(MASK) /* field bit mask */\r
+\r
+#define SKEIN_T1_BLK_TYPE_CFG_FINAL       (SKEIN_T1_BLK_TYPE_CFG | SKEIN_T1_FLAG_FINAL)\r
+#define SKEIN_T1_BLK_TYPE_OUT_FINAL       (SKEIN_T1_BLK_TYPE_OUT | SKEIN_T1_FLAG_FINAL)\r
+\r
+#define SKEIN_VERSION           (1)\r
+\r
+#ifndef SKEIN_ID_STRING_LE      /* allow compile-time personalization */\r
+#define SKEIN_ID_STRING_LE      (0x33414853)            /* "SHA3" (little-endian)*/\r
+#endif\r
+\r
+#define SKEIN_MK_64(hi32,lo32)  ((lo32) + (((u64b_t) (hi32)) << 32))\r
+#define SKEIN_SCHEMA_VER        SKEIN_MK_64(SKEIN_VERSION,SKEIN_ID_STRING_LE)\r
+#define SKEIN_KS_PARITY         SKEIN_MK_64(0x55555555,0x55555555)\r
+\r
+#define SKEIN_CFG_STR_LEN       (4*8)\r
+\r
+/* bit field definitions in config block treeInfo word */\r
+#define SKEIN_CFG_TREE_LEAF_SIZE_POS  ( 0)\r
+#define SKEIN_CFG_TREE_NODE_SIZE_POS  ( 8)\r
+#define SKEIN_CFG_TREE_MAX_LEVEL_POS  (16)\r
+\r
+#define SKEIN_CFG_TREE_LEAF_SIZE_MSK  ((u64b_t) 0xFF) << SKEIN_CFG_TREE_LEAF_SIZE_POS)\r
+#define SKEIN_CFG_TREE_NODE_SIZE_MSK  ((u64b_t) 0xFF) << SKEIN_CFG_TREE_NODE_SIZE_POS)\r
+#define SKEIN_CFG_TREE_MAX_LEVEL_MSK  ((u64b_t) 0xFF) << SKEIN_CFG_TREE_MAX_LEVEL_POS)\r
+\r
+#define SKEIN_CFG_TREE_INFO_SEQUENTIAL (0) /* use as treeInfo in InitExt() call for sequential processing */\r
+#define SKEIN_CFG_TREE_INFO(leaf,node,maxLevel) ((u64b_t) ((leaf) | ((node) << 8) | ((maxLevel) << 16)))\r
+\r
+/*\r
+**   Skein macros for getting/setting tweak words, etc.\r
+**   These are useful for partial input bytes, hash tree init/update, etc.\r
+**/\r
+#define Skein_Get_Tweak(ctxPtr,TWK_NUM)         ((ctxPtr)->h.T[TWK_NUM])\r
+#define Skein_Set_Tweak(ctxPtr,TWK_NUM,tVal)    {(ctxPtr)->h.T[TWK_NUM] = (tVal);}\r
+\r
+#define Skein_Get_T0(ctxPtr)    Skein_Get_Tweak(ctxPtr,0)\r
+#define Skein_Get_T1(ctxPtr)    Skein_Get_Tweak(ctxPtr,1)\r
+#define Skein_Set_T0(ctxPtr,T0) Skein_Set_Tweak(ctxPtr,0,T0)\r
+#define Skein_Set_T1(ctxPtr,T1) Skein_Set_Tweak(ctxPtr,1,T1)\r
+\r
+/* set both tweak words at once */\r
+#define Skein_Set_T0_T1(ctxPtr,T0,T1)           \\r
+    {                                           \\r
+    Skein_Set_T0(ctxPtr,(T0));                  \\r
+    Skein_Set_T1(ctxPtr,(T1));                  \\r
+    }\r
+\r
+#define Skein_Set_Type(ctxPtr,BLK_TYPE)         \\r
+    Skein_Set_T1(ctxPtr,SKEIN_T1_BLK_TYPE_##BLK_TYPE)\r
+\r
+/* set up for starting with a new type: h.T[0]=0; h.T[1] = NEW_TYPE; h.bCnt=0; */\r
+#define Skein_Start_New_Type(ctxPtr,BLK_TYPE)   \\r
+    { Skein_Set_T0_T1(ctxPtr,0,SKEIN_T1_FLAG_FIRST | SKEIN_T1_BLK_TYPE_##BLK_TYPE); (ctxPtr)->h.bCnt=0; }\r
+\r
+#define Skein_Clear_First_Flag(hdr)      { (hdr).T[1] &= ~SKEIN_T1_FLAG_FIRST;       }\r
+#define Skein_Set_Bit_Pad_Flag(hdr)      { (hdr).T[1] |=  SKEIN_T1_FLAG_BIT_PAD;     }\r
+\r
+#define Skein_Set_Tree_Level(hdr,height) { (hdr).T[1] |= SKEIN_T1_TREE_LEVEL(height);}\r
+\r
+/*****************************************************************\r
+** "Internal" Skein definitions for debugging and error checking\r
+******************************************************************/\r
+#ifdef  SKEIN_DEBUG             /* examine/display intermediate values? */\r
+#include "skein_debug.h"\r
+#else                           /* default is no callouts */\r
+#define Skein_Show_Block(bits,ctx,X,blkPtr,wPtr,ksEvenPtr,ksOddPtr)\r
+#define Skein_Show_Round(bits,ctx,r,X)\r
+#define Skein_Show_R_Ptr(bits,ctx,r,X_ptr)\r
+#define Skein_Show_Final(bits,ctx,cnt,outPtr)\r
+#define Skein_Show_Key(bits,ctx,key,keyBytes)\r
+#endif\r
+\r
+#ifndef SKEIN_ERR_CHECK        /* run-time checks (e.g., bad params, uninitialized context)? */\r
+#define Skein_Assert(x,retCode)/* default: ignore all Asserts, for performance */\r
+#define Skein_assert(x)\r
+#elif   defined(SKEIN_ASSERT)\r
+#include <assert.h>     \r
+#define Skein_Assert(x,retCode) assert(x) \r
+#define Skein_assert(x)         assert(x) \r
+#else\r
+#include <assert.h>     \r
+#define Skein_Assert(x,retCode) { if (!(x)) return retCode; } /*  caller  error */\r
+#define Skein_assert(x)         assert(x)                     /* internal error */\r
+#endif\r
+\r
+/*****************************************************************\r
+** Skein block function constants (shared across Ref and Opt code)\r
+******************************************************************/\r
+enum    \r
+    {   \r
+        /* Skein_256 round rotation constants */\r
+    R_256_0_0= 5, R_256_0_1=56,\r
+    R_256_1_0=36, R_256_1_1=28,\r
+    R_256_2_0=13, R_256_2_1=46,\r
+    R_256_3_0=58, R_256_3_1=44,\r
+    R_256_4_0=26, R_256_4_1=20,\r
+    R_256_5_0=53, R_256_5_1=35,\r
+    R_256_6_0=11, R_256_6_1=42,\r
+    R_256_7_0=59, R_256_7_1=50,\r
+\r
+        /* Skein_512 round rotation constants */\r
+    R_512_0_0=38, R_512_0_1=30, R_512_0_2=50, R_512_0_3=53,\r
+    R_512_1_0=48, R_512_1_1=20, R_512_1_2=43, R_512_1_3=31,\r
+    R_512_2_0=34, R_512_2_1=14, R_512_2_2=15, R_512_2_3=27,\r
+    R_512_3_0=26, R_512_3_1=12, R_512_3_2=58, R_512_3_3= 7,\r
+    R_512_4_0=33, R_512_4_1=49, R_512_4_2= 8, R_512_4_3=42,\r
+    R_512_5_0=39, R_512_5_1=27, R_512_5_2=41, R_512_5_3=14,\r
+    R_512_6_0=29, R_512_6_1=26, R_512_6_2=11, R_512_6_3= 9,\r
+    R_512_7_0=33, R_512_7_1=51, R_512_7_2=39, R_512_7_3=35,\r
+\r
+        /* Skein1024 round rotation constants */\r
+    R1024_0_0=55, R1024_0_1=43, R1024_0_2=37, R1024_0_3=40, R1024_0_4=16, R1024_0_5=22, R1024_0_6=38, R1024_0_7=12,\r
+    R1024_1_0=25, R1024_1_1=25, R1024_1_2=46, R1024_1_3=13, R1024_1_4=14, R1024_1_5=13, R1024_1_6=52, R1024_1_7=57,\r
+    R1024_2_0=33, R1024_2_1= 8, R1024_2_2=18, R1024_2_3=57, R1024_2_4=21, R1024_2_5=12, R1024_2_6=32, R1024_2_7=54,\r
+    R1024_3_0=34, R1024_3_1=43, R1024_3_2=25, R1024_3_3=60, R1024_3_4=44, R1024_3_5= 9, R1024_3_6=59, R1024_3_7=34,\r
+    R1024_4_0=28, R1024_4_1= 7, R1024_4_2=47, R1024_4_3=48, R1024_4_4=51, R1024_4_5= 9, R1024_4_6=35, R1024_4_7=41,\r
+    R1024_5_0=17, R1024_5_1= 6, R1024_5_2=18, R1024_5_3=25, R1024_5_4=43, R1024_5_5=42, R1024_5_6=40, R1024_5_7=15,\r
+    R1024_6_0=58, R1024_6_1= 7, R1024_6_2=32, R1024_6_3=45, R1024_6_4=19, R1024_6_5=18, R1024_6_6= 2, R1024_6_7=56,\r
+    R1024_7_0=47, R1024_7_1=49, R1024_7_2=27, R1024_7_3=58, R1024_7_4=37, R1024_7_5=48, R1024_7_6=53, R1024_7_7=56\r
+    };\r
+\r
+#ifndef SKEIN_ROUNDS\r
+#define SKEIN_256_ROUNDS_TOTAL (72)          /* number of rounds for the different block sizes */\r
+#define SKEIN_512_ROUNDS_TOTAL (72)\r
+#define SKEIN1024_ROUNDS_TOTAL (80)\r
+#else                                        /* allow command-line define in range 8*(5..14)   */\r
+#define SKEIN_256_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/100) + 5) % 10) + 5))\r
+#define SKEIN_512_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS/ 10) + 5) % 10) + 5))\r
+#define SKEIN1024_ROUNDS_TOTAL (8*((((SKEIN_ROUNDS    ) + 5) % 10) + 5))\r
+#endif\r
+\r
+#endif  /* ifndef _SKEIN_H_ */\r
diff --git a/Crypto/skein_port.h b/Crypto/skein_port.h
new file mode 100644 (file)
index 0000000..6d583f8
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef _SKEIN_PORT_H_\r
+#define _SKEIN_PORT_H_\r
+/*******************************************************************\r
+**\r
+** Platform-specific definitions for Skein hash function.\r
+**\r
+** Source code author: Doug Whiting, 2008.\r
+**\r
+** This algorithm and source code is released to the public domain.\r
+**\r
+** Many thanks to Brian Gladman for his portable header files, which\r
+** have been modified slightly here, to handle a few more platforms.\r
+**\r
+** To port Skein to an "unsupported" platform, change the definitions\r
+** in this file appropriately.\r
+** \r
+********************************************************************/\r
+\r
+#include "brg_types.h"                      /* get integer type definitions */\r
+\r
+typedef unsigned int    uint_t;             /* native unsigned integer */\r
+typedef uint_8t         u08b_t;             /*  8-bit unsigned integer */\r
+typedef uint_64t        u64b_t;             /* 64-bit unsigned integer */\r
+\r
+/*\r
+ * Skein is "natively" little-endian (unlike SHA-xxx), for optimal\r
+ * performance on x86 CPUs.  The Skein code requires the following\r
+ * definitions for dealing with endianness:\r
+ *\r
+ *    Skein_Put64_LSB_First\r
+ *    Skein_Get64_LSB_First\r
+ *    Skein_Swap64\r
+ *\r
+ * In the reference code, these functions are implemented in a\r
+ * very portable (and thus slow) fashion, for clarity. See the file\r
+ * "skein_port.h" in the Optimized_Code directory for ways to make\r
+ * these functions fast(er) on x86 platforms.\r
+ */\r
+\r
+u64b_t Skein_Swap64(u64b_t w64);\r
+void   Skein_Put64_LSB_First(u08b_t *dst,const u64b_t *src,size_t bCnt);\r
+void   Skein_Get64_LSB_First(u64b_t *dst,const u08b_t *src,size_t wCnt);\r
+\r
+#endif   /* ifndef _SKEIN_PORT_H_ */\r
This page took 0.103155 seconds and 4 git commands to generate. Download a nemesis OSX (sierra+high sierra, tested/working) binary, with fuse-ext3 via e2fsprogs, at this link. application and installer are signed by screwjack, llc. must install fuse with macFUSE layer first.