Files
interactive/gms/KT/sdkfreebsd64/libs/mhash-0.9.9.9/lib/tiger.c
T
2026-08-07 17:38:18 +09:00

710 lines
19 KiB
C

/*
* Copyright (C) 2001 Nikos Mavroyanopoulos
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/* According to Tiger's web page
* http://www.cs.technion.ac.il/~biham/Reports/Tiger/
*
* Tiger has no usage restrictions nor patents. It can be used freely, with the
* reference implementation, with other implementations or with a modification
* to the reference implementation (as long as it still implements Tiger).
*
* This implementation is based on the reference implementation.
*
* --nikos
*/
#include "libdefs.h"
#ifdef ENABLE_TIGER
#include "mhash_tiger.h"
#define PASSES 3
#ifdef TIGER_64BIT
/* Unconditionally use the optimizations. There is already separate code for
* 32-bit processors, and the comments about alpha probably apply to all modern
* 64-bit processors. (Ex: the optimized version is faster on Athlon64 too.)
*/
#define OPTIMIZE_FOR_ALPHA
extern __const mutils_word64 tiger_table[4*256];
#define t1 (tiger_table)
#define t2 (tiger_table+256)
#define t3 (tiger_table+256*2)
#define t4 (tiger_table+256*3)
#define save_abc \
aa = a; \
bb = b; \
cc = c;
#ifdef OPTIMIZE_FOR_ALPHA
/* This is the official definition of round */
#define round(a,b,c,x,mul) \
c ^= x; \
a -= t1[((c)>>(0*8))&0xFF] ^ t2[((c)>>(2*8))&0xFF] ^ \
t3[((c)>>(4*8))&0xFF] ^ t4[((c)>>(6*8))&0xFF] ; \
b += t4[((c)>>(1*8))&0xFF] ^ t3[((c)>>(3*8))&0xFF] ^ \
t2[((c)>>(5*8))&0xFF] ^ t1[((c)>>(7*8))&0xFF] ; \
b *= mul;
#else
/* This code works faster when compiled on 32-bit machines */
/* (but works slower on Alpha) */
#define round(a,b,c,x,mul) \
c ^= x; \
a -= t1[(mutils_word8)(c)] ^ \
t2[(mutils_word8)(((mutils_word32)(c))>>(2*8))] ^ \
t3[(mutils_word8)((c)>>(4*8))] ^ \
t4[(mutils_word8)(((mutils_word32)((c)>>(4*8)))>>(2*8))] ; \
b += t4[(mutils_word8)(((mutils_word32)(c))>>(1*8))] ^ \
t3[(mutils_word8)(((mutils_word32)(c))>>(3*8))] ^ \
t2[(mutils_word8)(((mutils_word32)((c)>>(4*8)))>>(1*8))] ^ \
t1[(mutils_word8)(((mutils_word32)((c)>>(4*8)))>>(3*8))]; \
b *= mul;
#endif
#define pass(a,b,c,mul) \
round(a,b,c,x0,mul) \
round(b,c,a,x1,mul) \
round(c,a,b,x2,mul) \
round(a,b,c,x3,mul) \
round(b,c,a,x4,mul) \
round(c,a,b,x5,mul) \
round(a,b,c,x6,mul) \
round(b,c,a,x7,mul)
#define key_schedule \
x0 -= x7 ^ 0xA5A5A5A5A5A5A5A5LL; \
x1 ^= x0; \
x2 += x1; \
x3 -= x2 ^ ((~x1)<<19); \
x4 ^= x3; \
x5 += x4; \
x6 -= x5 ^ ((~x4)>>23); \
x7 ^= x6; \
x0 += x7; \
x1 -= x0 ^ ((~x7)<<19); \
x2 ^= x1; \
x3 += x2; \
x4 -= x3 ^ ((~x2)>>23); \
x5 ^= x4; \
x6 += x5; \
x7 -= x6 ^ 0x0123456789ABCDEFLL;
#define feedforward \
a ^= aa; \
b -= bb; \
c += cc;
#ifdef OPTIMIZE_FOR_ALPHA
/* The loop is unrolled: works better on Alpha */
#define compress \
save_abc \
pass(a,b,c,5) \
key_schedule \
pass(c,a,b,7) \
key_schedule \
pass(b,c,a,9) \
for(pass_no=3; pass_no<PASSES; pass_no++) { \
key_schedule \
pass(a,b,c,9) \
tmpa=a; a=c; c=b; b=tmpa;} \
feedforward
#else
/* loop: works better on PC and Sun (smaller cache?) */
#define compress \
save_abc \
for(pass_no=0; pass_no<PASSES; pass_no++) { \
if(pass_no != 0) {key_schedule} \
pass(a,b,c,(pass_no==0?5:pass_no==1?7:9)); \
tmpa=a; a=c; c=b; b=tmpa;} \
feedforward
#endif
#define tiger_compress_macro(str, state) \
{ \
register mutils_word64 a, b, c, tmpa; \
mutils_word64 aa, bb, cc; \
register mutils_word64 x0, x1, x2, x3, x4, x5, x6, x7; \
mutils_word8 pass_no; \
\
a = state[0]; \
b = state[1]; \
c = state[2]; \
\
x0=str[0]; x1=str[1]; x2=str[2]; x3=str[3]; \
x4=str[4]; x5=str[5]; x6=str[6]; x7=str[7]; \
\
compress; \
\
state[0] = a; \
state[1] = b; \
state[2] = c; \
}
#ifndef OPTIMIZE_FOR_ALPHA
/* The compress function is a function. Requires smaller cache? */
static void tiger_compress(mutils_word64 *str, mutils_word64 state[3])
{
tiger_compress_macro(((mutils_word64*)str), ((mutils_word64*)state));
}
#else /* OPTIMIZE_FOR_ALPHA */
/* The compress function is inlined: works better on Alpha. */
#define tiger_compress(str, state) \
tiger_compress_macro(((mutils_word64*)str), ((mutils_word64*)state))
#endif /* OPTIMIZE_FOR_ALPHA */
#ifndef EXTRACT_UCHAR
#define EXTRACT_UCHAR(p) (*(mutils_word8 *)(p))
#endif
#define STRING2INT64(s) ((((((((((((((mutils_word64)(EXTRACT_UCHAR(s+7) << 8) \
| EXTRACT_UCHAR(s+6)) << 8) \
| EXTRACT_UCHAR(s+5)) << 8) \
| EXTRACT_UCHAR(s+4)) << 8) \
| EXTRACT_UCHAR(s+3)) << 8) \
| EXTRACT_UCHAR(s+2)) << 8) \
| EXTRACT_UCHAR(s+1)) << 8) \
| EXTRACT_UCHAR(s))
static void tiger_block(struct tiger_ctx *ctx, mutils_word8 * str)
{
mutils_word64 temp[TIGER_DATALEN];
#if defined(WORDS_BIGENDIAN)
mutils_word32 j;
for(j=0; j<TIGER_DATALEN; j++, str+=8)
temp[j] = STRING2INT64(str);
tiger_compress(temp, ctx->digest);
#else
mutils_memcpy(temp, str, TIGER_DATASIZE); /* Required to avoid un-aligned access on some arches */
tiger_compress(temp, ctx->digest);
#endif
/* Update block count */
ctx->count++;
}
void tiger_init(struct tiger_ctx *ctx)
{
/* Set the h-vars to their initial values */
ctx->digest[0] = h0init;
ctx->digest[1] = h1init;
ctx->digest[2] = h2init;
/* Initialize block count */
ctx->count = 0;
/* Initialize buffer */
ctx->index = 0;
}
void tiger_update(struct tiger_ctx *ctx, mutils_word8 * buffer, mutils_word32 len)
{
mutils_word32 left;
if (ctx->index) { /* Try to fill partial block */
left = TIGER_DATASIZE - ctx->index;
if (len < left)
{
mutils_memcpy(ctx->block + ctx->index, buffer, len);
ctx->index += len;
return; /* Finished */
} else {
mutils_memcpy(ctx->block + ctx->index, buffer, left);
tiger_block(ctx, ctx->block);
buffer += left;
len -= left;
}
}
while (len >= TIGER_DATASIZE)
{
tiger_block(ctx, buffer);
buffer += TIGER_DATASIZE;
len -= TIGER_DATASIZE;
}
if ((ctx->index = len))
/* This assignment is intended */
/* Buffer leftovers */
mutils_memcpy(ctx->block, buffer, len);
}
void tiger_final(struct tiger_ctx *ctx)
{
register mutils_word64 i, j;
mutils_word8 temp[TIGER_DATASIZE];
i = ctx->index;
#if defined(WORDS_BIGENDIAN)
for(j=0; j<i; j++)
temp[j^7] = ctx->block[j];
temp[j^7] = 0x01;
j++;
for(; j&7; j++)
temp[j^7] = 0;
#else
for(j=0; j<i; j++)
temp[j] = ctx->block[j];
temp[j++] = 0x01;
for(; j&7; j++)
temp[j] = 0;
#endif
if(j>56)
{
for(; j<64; j++)
temp[j] = 0;
tiger_compress(((mutils_word64*)temp), ctx->digest);
j=0;
}
for(; j<56; j++)
temp[j] = 0;
/* Theres 512 = 2^9 bits in one block */
((mutils_word64*)(&(temp[56])))[0] = (ctx->count << 9) + (ctx->index << 3);
tiger_compress(((mutils_word64*)temp), ctx->digest);
}
void tiger_digest(struct tiger_ctx *ctx, mutils_word8 * s)
{
mutils_word32 i;
if (s!=NULL)
for (i = 0; i < TIGER_DIGESTLEN; i++) { /* 64 bit and LITTLE ENDIAN -that's cool! */
s[7] = ctx->digest[i];
s[6] = 0xff & (ctx->digest[i] >> 8);
s[5] = 0xff & (ctx->digest[i] >> 16);
s[4] = 0xff & (ctx->digest[i] >> 24);
s[3] = 0xff & (ctx->digest[i] >> 32);
s[2] = 0xff & (ctx->digest[i] >> 40);
s[1] = 0xff & (ctx->digest[i] >> 48);
s[0] = 0xff & (ctx->digest[i] >> 56);
s+=8;
}
}
void tiger128_digest(struct tiger_ctx *ctx, mutils_word8 * s)
{
mutils_word32 i;
if (s!=NULL)
for (i = 0; i < TIGER128_DIGESTLEN; i++) { /* 64 bit and LITTLE ENDIAN -that's cool! */
s[7] = ctx->digest[i];
s[6] = 0xff & (ctx->digest[i] >> 8);
s[5] = 0xff & (ctx->digest[i] >> 16);
s[4] = 0xff & (ctx->digest[i] >> 24);
s[3] = 0xff & (ctx->digest[i] >> 32);
s[2] = 0xff & (ctx->digest[i] >> 40);
s[1] = 0xff & (ctx->digest[i] >> 48);
s[0] = 0xff & (ctx->digest[i] >> 56);
s+=8;
}
}
void tiger160_digest(struct tiger_ctx *ctx, mutils_word8 * s)
{
mutils_word32 i;
if (s==NULL) return;
for (i = 0; i < TIGER160_DIGESTLEN; i++) { /* 64 bit and LITTLE ENDIAN -that's cool! */
s[7] = ctx->digest[i];
s[6] = 0xff & (ctx->digest[i] >> 8);
s[5] = 0xff & (ctx->digest[i] >> 16);
s[4] = 0xff & (ctx->digest[i] >> 24);
s[3] = 0xff & (ctx->digest[i] >> 32);
s[2] = 0xff & (ctx->digest[i] >> 40);
s[1] = 0xff & (ctx->digest[i] >> 48);
s[0] = 0xff & (ctx->digest[i] >> 56);
s+=8;
}
/* last block */
s[3] = 0xff & (ctx->digest[i] >> 32);
s[2] = 0xff & (ctx->digest[i] >> 40);
s[1] = 0xff & (ctx->digest[i] >> 48);
s[0] = 0xff & (ctx->digest[i] >> 56);
}
#else /* !TIGER_64BIT */
extern __const mutils_word32 tiger_table[4*256][2];
#define t1 (tiger_table)
#define t2 (tiger_table+256)
#define t3 (tiger_table+256*2)
#define t4 (tiger_table+256*3)
#define sub64(s0, s1, p0, p1) \
temps0 = (p0); \
tcarry = s0 < temps0; \
s0 -= temps0; \
s1 -= (p1) + tcarry;
#define add64(s0, s1, p0, p1) \
temps0 = (p0); \
s0 += temps0; \
tcarry = s0 < temps0; \
s1 += (p1) + tcarry;
#define xor64(s0, s1, p0, p1) \
s0 ^= (p0); \
s1 ^= (p1);
#define mul5(s0, s1) \
tempt0 = s0<<2; \
tempt1 = (s1<<2)|(s0>>30); \
add64(s0, s1, tempt0, tempt1);
#define mul7(s0, s1) \
tempt0 = s0<<3; \
tempt1 = (s1<<3)|(s0>>29); \
sub64(tempt0, tempt1, s0, s1); \
s0 = tempt0; \
s1 = tempt1;
#define mul9(s0, s1) \
tempt0 = s0<<3; \
tempt1 = (s1<<3)|(s0>>29); \
add64(s0, s1, tempt0, tempt1);
#define save_abc \
aa0 = a0; \
aa1 = a1; \
bb0 = b0; \
bb1 = b1; \
cc0 = c0; \
cc1 = c1;
#define round(a0,a1,b0,b1,c0,c1,x0,x1,mul) \
xor64(c0, c1, x0, x1); \
temp0 = t1[((c0)>>(0*8))&0xFF][0] ; \
temp1 = t1[((c0)>>(0*8))&0xFF][1] ; \
temp0 ^= t2[((c0)>>(2*8))&0xFF][0] ; \
temp1 ^= t2[((c0)>>(2*8))&0xFF][1] ; \
temp0 ^= t3[((c1)>>(0*8))&0xFF][0] ; \
temp1 ^= t3[((c1)>>(0*8))&0xFF][1] ; \
temp0 ^= t4[((c1)>>(2*8))&0xFF][0] ; \
temp1 ^= t4[((c1)>>(2*8))&0xFF][1] ; \
sub64(a0, a1, temp0, temp1); \
temp0 = t4[((c0)>>(1*8))&0xFF][0] ; \
temp1 = t4[((c0)>>(1*8))&0xFF][1] ; \
temp0 ^= t3[((c0)>>(3*8))&0xFF][0] ; \
temp1 ^= t3[((c0)>>(3*8))&0xFF][1] ; \
temp0 ^= t2[((c1)>>(1*8))&0xFF][0] ; \
temp1 ^= t2[((c1)>>(1*8))&0xFF][1] ; \
temp0 ^= t1[((c1)>>(3*8))&0xFF][0] ; \
temp1 ^= t1[((c1)>>(3*8))&0xFF][1] ; \
add64(b0, b1, temp0, temp1); \
if((mul)==5) \
{mul5(b0, b1);} \
else \
if((mul)==7) \
{mul7(b0, b1);} \
else \
{mul9(b0, b1)};
#define pass(a0,a1,b0,b1,c0,c1,mul) \
round(a0,a1,b0,b1,c0,c1,x00,x01,mul); \
round(b0,b1,c0,c1,a0,a1,x10,x11,mul); \
round(c0,c1,a0,a1,b0,b1,x20,x21,mul); \
round(a0,a1,b0,b1,c0,c1,x30,x31,mul); \
round(b0,b1,c0,c1,a0,a1,x40,x41,mul); \
round(c0,c1,a0,a1,b0,b1,x50,x51,mul); \
round(a0,a1,b0,b1,c0,c1,x60,x61,mul); \
round(b0,b1,c0,c1,a0,a1,x70,x71,mul);
#define key_schedule \
sub64(x00, x01, x70^0xA5A5A5A5, x71^0xA5A5A5A5); \
xor64(x10, x11, x00, x01); \
add64(x20, x21, x10, x11); \
sub64(x30, x31, x20^((~x10)<<19), ~x21^(((x11)<<19)|((x10)>>13))); \
xor64(x40, x41, x30, x31); \
add64(x50, x51, x40, x41); \
sub64(x60, x61, ~x50^(((x40)>>23)|((x41)<<9)), x51^((~x41)>>23)); \
xor64(x70, x71, x60, x61); \
add64(x00, x01, x70, x71); \
sub64(x10, x11, x00^((~x70)<<19), ~x01^(((x71)<<19)|((x70)>>13))); \
xor64(x20, x21, x10, x11); \
add64(x30, x31, x20, x21); \
sub64(x40, x41, ~x30^(((x20)>>23)|((x21)<<9)), x31^((~x21)>>23)); \
xor64(x50, x51, x40, x41); \
add64(x60, x61, x50, x51); \
sub64(x70, x71, x60^0x89ABCDEF, x61^0x01234567);
#define feedforward \
xor64(a0, a1, aa0, aa1); \
sub64(b0, b1, bb0, bb1); \
add64(c0, c1, cc0, cc1);
#ifdef UNROLL_COMPRESS
#define compress \
save_abc \
pass(a0,a1,b0,b1,c0,c1,5); \
key_schedule; \
pass(c0,c1,a0,a1,b0,b1,7); \
key_schedule; \
pass(b0,b1,c0,c1,a0,a1,9); \
for(pass_no=3; pass_no<PASSES; pass_no++) { \
key_schedule \
pass(a0,a1,b0,b1,c0,c1,9); \
tmpa=a0; a0=c0; c0=b0; b0=tmpa; \
tmpa=a1; a1=c1; c1=b1; b1=tmpa;} \
feedforward
#else
#define compress \
save_abc \
for(pass_no=0; pass_no<PASSES; pass_no++) { \
if(pass_no != 0) {key_schedule} \
pass(a0,a1,b0,b1,c0,c1,(pass_no==0?5:pass_no==1?7:9)) \
tmpa=a0; a0=c0; c0=b0; b0=tmpa; \
tmpa=a1; a1=c1; c1=b1; b1=tmpa;} \
feedforward
#endif
#define tiger_compress_macro(str, state) \
{ \
register mutils_word32 a0, a1, b0, b1, c0, c1, tmpa; \
mutils_word32 aa0, aa1, bb0, bb1, cc0, cc1; \
mutils_word32 x00, x01, x10, x11, x20, x21, x30, x31, \
x40, x41, x50, x51, x60, x61, x70, x71; \
register mutils_word32 temp0, temp1, tempt0, tempt1, temps0, tcarry; \
mutils_word32 i; \
int pass_no; \
\
a0 = state[0]; \
a1 = state[1]; \
b0 = state[2]; \
b1 = state[3]; \
c0 = state[4]; \
c1 = state[5]; \
\
x00=str[0*2]; x01=str[0*2+1]; x10=str[1*2]; x11=str[1*2+1]; \
x20=str[2*2]; x21=str[2*2+1]; x30=str[3*2]; x31=str[3*2+1]; \
x40=str[4*2]; x41=str[4*2+1]; x50=str[5*2]; x51=str[5*2+1]; \
x60=str[6*2]; x61=str[6*2+1]; x70=str[7*2]; x71=str[7*2+1]; \
\
compress; \
\
state[0] = a0; \
state[1] = a1; \
state[2] = b0; \
state[3] = b1; \
state[4] = c0; \
state[5] = c1; \
}
#define UNROLL_COMPRESS
#ifdef UNROLL_COMPRESS
/* The compress function is inlined */
#define tiger_compress(str, state) \
tiger_compress_macro(((mutils_word32*)str), ((mutils_word32*)state))
#else
/* The compress function is a function */
tiger_compress(__const mutils_word32 *str, mutils_word32 state[6])
{
tiger_compress_macro(((mutils_word32*)str), ((mutils_word32*)state));
}
#endif
#ifndef EXTRACT_UCHAR
#define EXTRACT_UCHAR(p) (*(mutils_word8 *)(p))
#endif
#define STRING2INT(s) ((((((EXTRACT_UCHAR(s+3) << 8) \
| EXTRACT_UCHAR(s+2)) << 8) \
| EXTRACT_UCHAR(s+1)) << 8) \
| EXTRACT_UCHAR(s))
static void tiger_block(struct tiger_ctx *ctx, mutils_word8 * block)
{
mutils_word32 data[TIGER_DATALEN];
mutils_word32 i;
/* Update block count */
if (!++ctx->count_l)
++ctx->count_h;
/* Endian independent conversion */
for (i = 0; i < TIGER_DATALEN; i++, block += sizeof(mutils_word32))
data[i] = STRING2INT(block);
tiger_compress(data, ctx->digest);
}
void tiger_init(struct tiger_ctx *ctx)
{
/* Set the h-vars to their initial values */
ctx->digest[0] = h0init;
ctx->digest[1] = h1init;
ctx->digest[2] = h2init;
ctx->digest[3] = h3init;
ctx->digest[4] = h4init;
ctx->digest[5] = h5init;
/* Initialize bit count */
ctx->count_l = ctx->count_h = 0;
/* Initialize buffer */
ctx->index = 0;
}
void tiger_update(struct tiger_ctx *ctx, mutils_word8 * buffer, mutils_word32 len)
{
if (ctx->index) { /* Try to fill partial block */
mutils_word32 left = TIGER_DATASIZE - ctx->index;
if (len < left) {
mutils_memcpy(ctx->block + ctx->index, buffer, len);
ctx->index += len;
return; /* Finished */
} else {
mutils_memcpy(ctx->block + ctx->index, buffer, left);
tiger_block(ctx, ctx->block);
buffer += left;
len -= left;
}
}
while (len >= TIGER_DATASIZE)
{
tiger_block(ctx, buffer);
buffer += TIGER_DATASIZE;
len -= TIGER_DATASIZE;
}
if ((ctx->index = len))
{
/* This assignment is intended */
/* Buffer leftovers */
mutils_memcpy(ctx->block, buffer, len);
}
}
void tiger_final(struct tiger_ctx *ctx)
{
mutils_word32 data[TIGER_DATALEN];
mutils_word32 i;
mutils_word32 words;
i = ctx->index;
/* Set the first char of padding to 0x01. This is safe since there is
always at least one byte free */
ctx->block[i++] = 0x01;
/* Fill rest of word */
for (; i & 3; i++)
ctx->block[i] = 0;
/* i is now a multiple of the word size 4 */
words = i >> 2;
for (i = 0; i < words; i++)
data[i] = STRING2INT(ctx->block + 4 * i);
if (words > (TIGER_DATALEN - 2)) { /* No room for length in this block. Process it and
* pad with another one */
for (i = words; i < TIGER_DATALEN; i++)
data[i] = 0;
tiger_compress( data, ctx->digest);
for (i = 0; i < (TIGER_DATALEN - 2); i++)
data[i] = 0;
} else
for (i = words; i < TIGER_DATALEN - 2; i++)
data[i] = 0;
/* Theres 512 = 2^9 bits in one block */
data[TIGER_DATALEN - 1] =
(ctx->count_h << 9) | (ctx->count_l >> 23);
data[TIGER_DATALEN - 2] = (ctx->count_l << 9) | (ctx->index << 3);
tiger_compress( data, ctx->digest);
}
void tiger_digest(struct tiger_ctx *ctx, mutils_word8 * s)
{
mutils_word32 i;
if (s!=NULL)
for (i = 0; i < TIGER_DIGESTLEN; i+=2)
{ /* 64 bit and LITTLE ENDIAN -that's cool! */
s[7] = ctx->digest[i];
s[6] = 0xff & (ctx->digest[i] >> 8);
s[5] = 0xff & (ctx->digest[i] >> 16);
s[4] = 0xff & ctx->digest[i] >> 24;
s[3] = ctx->digest[i+1];
s[2] = 0xff & (ctx->digest[i+1] >> 8);
s[1] = 0xff & (ctx->digest[i+1] >> 16);
s[0] = 0xff & ctx->digest[i+1] >> 24;
s+=8;
}
}
void tiger128_digest(struct tiger_ctx *ctx, mutils_word8 * s)
{
mutils_word32 i;
if (s!=NULL)
for (i = 0; i < TIGER128_DIGESTLEN; i+=2)
{ /* 64 bit and LITTLE ENDIAN -that's cool! */
s[7] = ctx->digest[i];
s[6] = 0xff & (ctx->digest[i] >> 8);
s[5] = 0xff & (ctx->digest[i] >> 16);
s[4] = 0xff & ctx->digest[i] >> 24;
s[3] = ctx->digest[i+1];
s[2] = 0xff & (ctx->digest[i+1] >> 8);
s[1] = 0xff & (ctx->digest[i+1] >> 16);
s[0] = 0xff & ctx->digest[i+1] >> 24;
s+=8;
}
}
void tiger160_digest(struct tiger_ctx *ctx, mutils_word8 * s)
{
mutils_word32 i;
for (i = 0; i < TIGER160_DIGESTLEN-1; i+=2) { /* 64 bit and LITTLE ENDIAN -that's cool! */
s[7] = ctx->digest[i];
s[6] = 0xff & (ctx->digest[i] >> 8);
s[5] = 0xff & (ctx->digest[i] >> 16);
s[4] = 0xff & ctx->digest[i] >> 24;
s[3] = ctx->digest[i+1];
s[2] = 0xff & (ctx->digest[i+1] >> 8);
s[1] = 0xff & (ctx->digest[i+1] >> 16);
s[0] = 0xff & ctx->digest[i+1] >> 24;
s+=8;
}
/* last block */
s[3] = ctx->digest[i+1];
s[2] = 0xff & (ctx->digest[i+1] >> 8);
s[1] = 0xff & (ctx->digest[i+1] >> 16);
s[0] = 0xff & ctx->digest[i+1] >> 24;
}
#endif /* !TIGER_64BIT */
#endif /* ENABLE_TIGER */