332 lines
8.8 KiB
C
332 lines
8.8 KiB
C
/*
|
||
* The Tiger algorithm was written by Eli Biham and Ross Anderson and
|
||
* is available on the official Tiger algorithm page .
|
||
* The below Tiger implementation is a C++ version of their original C code.
|
||
* Permission was granted by Eli Biham to use with the following conditions;
|
||
* a) This note must be retained.
|
||
* b) The algorithm must correctly compute Tiger.
|
||
* c) The algorithm’s use must be legal.
|
||
* d) The algorithm may not be exported to countries banned by law.
|
||
* e) The authors of the C code are not responsible of this use of the code,
|
||
* the software or anything else.
|
||
*/
|
||
|
||
/* This was extracted from the original reference implementation to check
|
||
* this one.
|
||
*/
|
||
|
||
#include<stdlib.h>
|
||
#include<time.h>
|
||
#include<stdio.h>
|
||
#include <time.h>
|
||
#include <string.h>
|
||
#include "tiger.h"
|
||
|
||
#ifndef ITERATIONS
|
||
#ifdef i386
|
||
#define ITERATIONS 50000
|
||
#else
|
||
#define ITERATIONS 50000
|
||
#endif
|
||
#endif
|
||
|
||
#undef t1
|
||
#undef t2
|
||
#undef t3
|
||
#undef t4
|
||
typedef unsigned long long int word64;
|
||
typedef uint32_t word32;
|
||
typedef unsigned char byte;
|
||
|
||
void check_partialh (char *str, t_word length) {
|
||
char psalt[128];
|
||
char ssalt[128];
|
||
unsigned int ssalts;
|
||
int i,j,k,l;
|
||
t_pres tres;
|
||
t_res res1;
|
||
t_res res2;
|
||
char *allocd = malloc((length+256)*sizeof(char));
|
||
srandom(time(NULL));
|
||
memcpy(allocd,str,length);
|
||
for ( i = 0; i < 10; i++) {
|
||
for ( j = 0; j < 128; j++)
|
||
allocd[length+j] = psalt[j] = random();
|
||
tigerp1(str, length, psalt, &tres);
|
||
for ( k = 0; k < 256; k++) {
|
||
l = (k & 127) + 1;
|
||
for ( j = 0; j < l; j++)
|
||
allocd[length+128+j] = ssalt[j] = random();
|
||
tigerp2(&tres, ssalt, l, res1);
|
||
tiger(allocd,length+128+l, res2);
|
||
if( res1[0] != res2[0] || res1[1] != res2[1] || res1[2] != res2[2] )
|
||
puts("Partial error!");
|
||
}
|
||
}
|
||
free(allocd);
|
||
}
|
||
|
||
#ifndef bufsize
|
||
#define bufsize 65536
|
||
#endif
|
||
int main()
|
||
{
|
||
byte buffer[bufsize];
|
||
byte buffer_[bufsize];
|
||
byte buffer2[bufsize];
|
||
byte buffer2_[bufsize];
|
||
byte buffer3[1025];
|
||
byte buffer3_[1025];
|
||
long t1;
|
||
long t2;
|
||
double rate;
|
||
int i;
|
||
|
||
t_res res;
|
||
t_res res2;
|
||
t_res res3;
|
||
unsigned char prepend;
|
||
#define show_hash for ( i = 0; i < 24; i++) {\
|
||
printf("%02X",((unsigned char*)res)[i]);\
|
||
}
|
||
#define hash(str) \
|
||
check_partialh(str, strlen(str));\
|
||
tiger((byte*)str, strlen(str), res); \
|
||
printf("Hash of \"%s\":\n\t", str); \
|
||
show_hash; \
|
||
puts("");
|
||
|
||
/* Hash of short strings */
|
||
hash("");
|
||
hash("abc");
|
||
hash("Tiger");
|
||
/* Hash of 512-bit strings */
|
||
hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-");
|
||
hash("ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789");
|
||
hash("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham");
|
||
/* Hash of two-block strings strings */
|
||
hash("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.");
|
||
hash("Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.");
|
||
hash("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-");
|
||
|
||
/* Hash of a 64K byte string */
|
||
for (i=0;i<bufsize;i++) {
|
||
buffer[i] = i&0xff;
|
||
buffer_[i] = (~i)&0xff;
|
||
}
|
||
|
||
for (i=0;i<1025;i++) {
|
||
buffer3[i] = i&0xff;
|
||
buffer3_[i] = (~i)&0xff;
|
||
}
|
||
|
||
|
||
tiger(buffer, bufsize, res);
|
||
printf("Hash of a %d byte string:\n\t",bufsize);
|
||
show_hash; puts("");
|
||
|
||
tiger_2((byte*)buffer, (byte*)buffer_, bufsize, res, res2);
|
||
tiger((byte*)buffer, bufsize, res3);
|
||
if (memcmp(res,res3,24)!=0) puts("Tiger_2_1 failure");
|
||
tiger((byte*)buffer_, bufsize, res3);
|
||
if (memcmp(res2,res3,24)!=0) puts("Tiger_2_2 failure");
|
||
|
||
*buffer3 = 0x01;
|
||
tiger_49((byte*)buffer3+1, res);
|
||
tiger((byte*)buffer3, 49, res2);
|
||
if (memcmp(res,res2,24)!=0) puts("Tiger_49 failure");
|
||
|
||
*buffer3 = 0x00;
|
||
tiger_1025((byte*)buffer3+1, res);
|
||
tiger((byte*)buffer3, 1025, res2);
|
||
if (memcmp(res,res2,24)!=0) puts("Tiger_1025 failure");
|
||
|
||
*buffer3 = 0x01;
|
||
*buffer3_ = 0x01;
|
||
tiger_2_49((byte*)buffer3+1, (byte*)buffer3_+1, res, res2);
|
||
tiger((byte*)buffer3, 49, res3);
|
||
if (memcmp(res,res3,24)!=0) puts("Tiger_2_49_1 failure");
|
||
tiger((byte*)buffer3_, 49, res3);
|
||
if (memcmp(res2,res3,24)!=0) puts("Tiger_2_49_2 failure");
|
||
|
||
*buffer3 = 0x00;
|
||
*buffer3_ = 0x00;
|
||
tiger_2_1025((byte*)buffer3+1, (byte*)buffer3_+1, res, res2);
|
||
tiger((byte*)buffer3, 1025, res3);
|
||
if (memcmp(res,res3,24)!=0) puts("Tiger_2_1025_1 failure");
|
||
tiger((byte*)buffer3_, 1025, res3);
|
||
if (memcmp(res2,res3,24)!=0) puts("Tiger_2_1025_2 failure");
|
||
|
||
#ifdef __SSE2__
|
||
tiger_sse2((byte*)buffer, (byte*)buffer_, bufsize, res, res2);
|
||
tiger((byte*)buffer, bufsize, res3);
|
||
if (memcmp(res,res3,24)!=0) puts("Tiger_2_1 failure");
|
||
tiger((byte*)buffer_, bufsize, res3);
|
||
if (memcmp(res2,res3,24)!=0) puts("Tiger_2_2 failure");
|
||
|
||
*buffer3 = 0x01;
|
||
*buffer3_ = 0x01;
|
||
tiger_sse2_49((byte*)buffer3+1, (byte*)buffer3_+1, res, res2);
|
||
tiger((byte*)buffer3, 49, res3);
|
||
if (memcmp(res,res3,24)!=0) puts("Tiger_2_49_1 failure");
|
||
tiger((byte*)buffer3_, 49, res3);
|
||
if (memcmp(res2,res3,24)!=0) puts("Tiger_2_49_2 failure");
|
||
|
||
*buffer3 = 0x00;
|
||
*buffer3_ = 0x00;
|
||
tiger_sse2_1025((byte*)buffer3+1, (byte*)buffer3_+1, res, res2);
|
||
tiger((byte*)buffer3, 1025, res3);
|
||
if (memcmp(res,res3,24)!=0) puts("Tiger_2_1025_1 failure");
|
||
tiger((byte*)buffer3_, 1025, res3);
|
||
if (memcmp(res2,res3,24)!=0) puts("Tiger_2_1025_2 failure");
|
||
#endif
|
||
|
||
#if bufsize == 49
|
||
//Hash tree node
|
||
prepend = 0x01;
|
||
#elif bufsize == 1025
|
||
//Hash tree leaf
|
||
prepend = 0x00;
|
||
#else
|
||
//keep original values
|
||
#endif
|
||
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
#if bufsize == 49 || bufsize == 1025
|
||
//This initial memcopy may be required by the caller to prepend the type byte
|
||
*buffer2=prepend;
|
||
memcpy(buffer2+1,buffer,bufsize-1);
|
||
tiger(buffer2, bufsize, res);
|
||
*buffer2_=prepend;
|
||
memcpy(buffer2_+1,buffer_,bufsize-1);
|
||
tiger(buffer2_, bufsize, res2);
|
||
#else
|
||
tiger(buffer, bufsize, res);
|
||
tiger(buffer_, bufsize, res2);
|
||
#endif
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate standard = %.0lf bit/s\n", rate);
|
||
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
#if bufsize == 49 || bufsize == 1025
|
||
//This initial memcopy may be required by the caller to prepend the type byte
|
||
*buffer2=prepend;
|
||
memcpy(buffer2+1,buffer,bufsize-1);
|
||
*buffer2_=prepend;
|
||
memcpy(buffer2_+1,buffer_,bufsize-1);
|
||
tiger_2(buffer2, buffer2_, bufsize, res, res2);
|
||
#else
|
||
tiger_2(buffer, buffer_, bufsize, res, res2);
|
||
#endif
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _2 = %.0lf bit/s\n", rate);
|
||
|
||
#ifdef __SSE2__
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
#if bufsize == 49 || bufsize == 1025
|
||
//This initial memcopy may be required by the caller to prepend the type byte
|
||
*buffer2=prepend;
|
||
memcpy(buffer2+1,buffer,bufsize-1);
|
||
*buffer2_=prepend;
|
||
memcpy(buffer2_+1,buffer_,bufsize-1);
|
||
tiger_sse2(buffer2, buffer2_, bufsize, res, res2);
|
||
#else
|
||
tiger_sse2(buffer, buffer_, bufsize, res, res2);
|
||
#endif
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _sse2 = %.0lf bit/s\n", rate);
|
||
#endif
|
||
|
||
#if bufsize == 49
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
tiger_49(buffer, res);
|
||
tiger_49(buffer_, res2);
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _49 = %.0lf bit/s\n", rate);
|
||
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
tiger_2_49(buffer, buffer_, res, res2);
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _2_49 = %.0lf bit/s\n", rate);
|
||
|
||
#ifdef __SSE2__
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
tiger_sse2_49(buffer, buffer_, res, res2);
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _sse2_49 = %.0lf bit/s\n", rate);
|
||
#endif
|
||
#elif bufsize == 1025
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
tiger_1025(buffer, res);
|
||
tiger_1025(buffer_, res2);
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _1025 = %.0lf bit/s\n", rate);
|
||
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
tiger_2_1025(buffer, buffer_, res, res2);
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _2_1025 = %.0lf bit/s\n", rate);
|
||
|
||
#ifdef __SSE2__
|
||
t1 = clock();
|
||
for (i=0;i<ITERATIONS;i+=2)
|
||
{
|
||
tiger_2_1025(buffer, buffer_, res, res2);
|
||
}
|
||
t2 = clock();
|
||
|
||
rate = (double)CLOCKS_PER_SEC*(double)ITERATIONS*((double)bufsize)*8.0/
|
||
((double)(t2 - t1));
|
||
printf("rate _sse2_1025 = %.0lf bit/s\n", rate);
|
||
#endif
|
||
#endif
|
||
|
||
}
|