Permalink
Browse files

modification to skein512 algorithm to have skein256

  • Loading branch information...
vincenthz committed Aug 8, 2010
1 parent cd9941d commit 12ec1da5e2c5e2208bb740a209b076ee1e38ea9d
Showing with 55 additions and 73 deletions.
  1. +1 −1 Data/CryptoHash/Skein256.hs
  2. +52 −70 cbits/skein256.c
  3. +2 −2 cbits/skein256.h
@@ -35,7 +35,7 @@ import Data.ByteString.Internal (create)
data Ctx = Ctx !ByteString
sizeCtx :: Int
-sizeCtx = 160
+sizeCtx = 100
instance Storable Ctx where
sizeOf _ = sizeCtx
View
@@ -27,30 +27,26 @@
#include "skein256.h"
#include "bitfn.h"
-static const uint8_t K256_0[4] = { 46, 36, 19, 37, };
-static const uint8_t K256_1[4] = { 33, 27, 14, 42, };
-static const uint8_t K256_2[4] = { 17, 49, 36, 39, };
-static const uint8_t K256_3[4] = { 44, 9, 54, 56, };
-static const uint8_t K256_4[4] = { 39, 30, 34, 24, };
-static const uint8_t K256_5[4] = { 13, 50, 10, 17, };
-static const uint8_t K256_6[4] = { 25, 29, 39, 43, };
-static const uint8_t K256_7[4] = { 8, 35, 56, 22, };
+static const uint8_t K256_0[2] = { 14, 16, };
+static const uint8_t K256_1[2] = { 52, 57, };
+static const uint8_t K256_2[2] = { 23, 40, };
+static const uint8_t K256_3[2] = { 5, 37, };
+static const uint8_t K256_4[2] = { 25, 33, };
+static const uint8_t K256_5[2] = { 46, 12, };
+static const uint8_t K256_6[2] = { 58, 22, };
+static const uint8_t K256_7[2] = { 32, 32, };
static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, uint32_t len)
{
- uint64_t x[8];
+ uint64_t x[4];
uint64_t ts[3];
- uint64_t ks[8+1];
-
- ks[8] = 0x5555555555555555;
- ks[0] = ctx->h[0]; ks[8] ^= ctx->h[0];
- ks[1] = ctx->h[1]; ks[8] ^= ctx->h[1];
- ks[2] = ctx->h[2]; ks[8] ^= ctx->h[2];
- ks[3] = ctx->h[3]; ks[8] ^= ctx->h[3];
- ks[4] = ctx->h[4]; ks[8] ^= ctx->h[4];
- ks[5] = ctx->h[5]; ks[8] ^= ctx->h[5];
- ks[6] = ctx->h[6]; ks[8] ^= ctx->h[6];
- ks[7] = ctx->h[7]; ks[8] ^= ctx->h[7];
+ uint64_t ks[4+1];
+
+ ks[4] = 0x5555555555555555;
+ ks[0] = ctx->h[0]; ks[4] ^= ctx->h[0];
+ ks[1] = ctx->h[1]; ks[4] ^= ctx->h[1];
+ ks[2] = ctx->h[2]; ks[4] ^= ctx->h[2];
+ ks[3] = ctx->h[3]; ks[4] ^= ctx->h[3];
ts[0] = ctx->t0;
ts[1] = ctx->t1;
@@ -60,41 +56,31 @@ static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, ui
ts[2] = ts[0] ^ ts[1];
#define INJECTKEY(r) \
- x[0] += ks[((r)+0) % (8+1)]; \
- x[1] += ks[((r)+1) % (8+1)]; \
- x[2] += ks[((r)+2) % (8+1)]; \
- x[3] += ks[((r)+3) % (8+1)]; \
- x[4] += ks[((r)+4) % (8+1)]; \
- x[5] += ks[((r)+5) % (8+1)] + ts[((r)+0) % 3]; \
- x[6] += ks[((r)+6) % (8+1)] + ts[((r)+1) % 3]; \
- x[7] += ks[((r)+7) % (8+1)] + (r)
-
-#define ROUND(a,b,c,d,e,f,g,h,k) \
+ x[0] += ks[((r)+0) % (4+1)]; \
+ x[1] += ks[((r)+1) % (4+1)] + ts[((r)+0) % 3]; \
+ x[2] += ks[((r)+2) % (4+1)] + ts[((r)+1) % 3]; \
+ x[3] += ks[((r)+3) % (4+1)] + (r)
+
+#define ROUND(a,b,c,d,k) \
x[a] += x[b]; x[b] = rol64(x[b],k[0]); x[b] ^= x[a]; \
- x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c]; \
- x[e] += x[f]; x[f] = rol64(x[f],k[2]); x[f] ^= x[e]; \
- x[g] += x[h]; x[h] = rol64(x[h],k[3]); x[h] ^= x[g];
+ x[c] += x[d]; x[d] = rol64(x[d],k[1]); x[d] ^= x[c];
#define PASS(i) \
- ROUND(0,1,2,3,4,5,6,7,K256_0); \
- ROUND(2,1,4,7,6,5,0,3,K256_1); \
- ROUND(4,1,6,3,0,5,2,7,K256_2); \
- ROUND(6,1,0,7,2,5,4,3,K256_3); \
+ ROUND(0,1,2,3,K256_0); \
+ ROUND(0,3,2,1,K256_1); \
+ ROUND(0,1,2,3,K256_2); \
+ ROUND(0,3,2,1,K256_3); \
INJECTKEY((i*2) + 1); \
- ROUND(0,1,2,3,4,5,6,7,K256_4); \
- ROUND(2,1,4,7,6,5,0,3,K256_5); \
- ROUND(4,1,6,3,0,5,2,7,K256_6); \
- ROUND(6,1,0,7,2,5,4,3,K256_7); \
+ ROUND(0,1,2,3,K256_4); \
+ ROUND(0,3,2,1,K256_5); \
+ ROUND(0,1,2,3,K256_6); \
+ ROUND(0,3,2,1,K256_7); \
INJECTKEY((i*2) + 2)
x[0] = le64_to_cpu(buf[0]) + ks[0];
- x[1] = le64_to_cpu(buf[1]) + ks[1];
- x[2] = le64_to_cpu(buf[2]) + ks[2];
+ x[1] = le64_to_cpu(buf[1]) + ks[1] + ts[0];
+ x[2] = le64_to_cpu(buf[2]) + ks[2] + ts[1];
x[3] = le64_to_cpu(buf[3]) + ks[3];
- x[4] = le64_to_cpu(buf[4]) + ks[4];
- x[5] = le64_to_cpu(buf[5]) + ks[5] + ts[0];
- x[6] = le64_to_cpu(buf[6]) + ks[6] + ts[1];
- x[7] = le64_to_cpu(buf[7]) + ks[7];
/* 9 pass of 8 rounds = 72 rounds */
PASS(0);
@@ -115,15 +101,11 @@ static inline void skein256_do_chunk(struct skein256_ctx *ctx, uint64_t *buf, ui
ctx->h[1] = x[1] ^ cpu_to_le64(buf[1]);
ctx->h[2] = x[2] ^ cpu_to_le64(buf[2]);
ctx->h[3] = x[3] ^ cpu_to_le64(buf[3]);
- ctx->h[4] = x[4] ^ cpu_to_le64(buf[4]);
- ctx->h[5] = x[5] ^ cpu_to_le64(buf[5]);
- ctx->h[6] = x[6] ^ cpu_to_le64(buf[6]);
- ctx->h[7] = x[7] ^ cpu_to_le64(buf[7]);
}
void skein256_init(struct skein256_ctx *ctx, uint32_t hashlen)
{
- uint64_t buf[8];
+ uint64_t buf[4];
memset(ctx, 0, sizeof(*ctx));
ctx->hashlen = cpu_to_le64(hashlen);
@@ -142,20 +124,20 @@ void skein256_update(struct skein256_ctx *ctx, uint8_t *data, uint32_t len)
{
uint32_t to_fill;
- to_fill = 64 - ctx->bufindex;
+ to_fill = 32 - ctx->bufindex;
/* process partial buffer if there's enough data to make a block */
- if ((ctx->bufindex & 0x3f) && len >= to_fill) {
+ if ((ctx->bufindex & 0x1f) && len >= to_fill) {
memcpy(ctx->buf + ctx->bufindex, data, to_fill);
- skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 64);
+ skein256_do_chunk(ctx, (uint64_t *) ctx->buf, 32);
len -= to_fill;
data += to_fill;
ctx->bufindex = 0;
}
- /* process as much 64-block as possible except the last one in case we finalize */
- for (; len > 64; len -= 64, data += 64)
- skein256_do_chunk(ctx, (uint64_t *) data, 64);
+ /* process as much 32-block as possible except the last one in case we finalize */
+ for (; len > 32; len -= 32, data += 32)
+ skein256_do_chunk(ctx, (uint64_t *) data, 32);
/* append data into buf */
if (len) {
@@ -168,37 +150,37 @@ void skein256_finalize(struct skein256_ctx *ctx, uint8_t *out)
{
uint32_t outsize;
uint64_t *p = (uint64_t *) out;
- uint64_t x[8];
+ uint64_t x[4];
int i, j, n;
ctx->t1 |= FLAG_FINAL;
/* if buf is not complete pad with 0 bytes */
- if (ctx->bufindex < 64)
- memset(ctx->buf + ctx->bufindex, '\0', 64 - ctx->bufindex);
+ if (ctx->bufindex < 32)
+ memset(ctx->buf + ctx->bufindex, '\0', 32 - ctx->bufindex);
skein256_do_chunk(ctx, (uint64_t *) ctx->buf, ctx->bufindex);
- memset(ctx->buf, '\0', 64);
+ memset(ctx->buf, '\0', 32);
/* make sure we have a 8 bit rounded value */
outsize = (le64_to_cpu(ctx->hashlen) + 7) >> 3;
- /* backup h[0--7] */
- for (j = 0; j < 8; j++)
+ /* backup h[0--4] */
+ for (j = 0; j < 4; j++)
x[j] = ctx->h[j];
/* threefish in counter mode, 0 for 1st 64 bytes, 1 for 2nd 64 bytes, .. */
- for (i = 0; i*64 < outsize; i++) {
+ for (i = 0; i*32 < outsize; i++) {
*((uint64_t *) ctx->buf) = cpu_to_le64(i);
SET_TYPE(ctx, FLAG_FIRST | FLAG_FINAL | FLAG_TYPE(TYPE_OUT));
skein256_do_chunk(ctx, (uint64_t *) ctx->buf, sizeof(uint64_t));
- n = outsize - i * 64;
- if (n >= 64) n = 64;
+ n = outsize - i * 32;
+ if (n >= 32) n = 32;
/* FIXME should be little endian array copy ? */
- memcpy(out + i*64, ctx->h, n);
+ memcpy(out + i*32, ctx->h, n);
- /* restore h[0--7] */
- for (j = 0; j < 8; j++)
+ /* restore h[0--4] */
+ for (j = 0; j < 4; j++)
ctx->h[j] = x[j];
}
}
View
@@ -30,8 +30,8 @@ struct skein256_ctx
{
uint32_t hashlen;
uint32_t bufindex;
- uint8_t buf[64];
- uint64_t h[8];
+ uint8_t buf[32];
+ uint64_t h[4];
uint64_t t0;
uint64_t t1;
};

0 comments on commit 12ec1da

Please sign in to comment.