Files
mips/src/hashtest.c
T
jens 26291bca3d - initial import
git-svn-id: http://moon:8086/svn/mips@1 a8ebac50-d88d-4704-bea3-6648445a41b3
2014-07-20 15:01:37 +00:00

324 lines
10 KiB
C

/********************************************************************\
*
* FILE: hashtest.c
*
* CONTENTS: test file for sample C-implementation of
* RIPEMD-160 and RIPEMD128
* * command line arguments:
* filename -- compute hash code of file read binary
* -sstring -- print string & hashcode
* -t -- perform time trial
* -x -- execute standard test suite, ASCII input
* * for linkage with rmd128.c: define RMDsize as 128
* for linkage with rmd160.c: define RMDsize as 160 (default)
* TARGET: any computer with an ANSI C compiler
*
* AUTHOR: Antoon Bosselaers, ESAT-COSIC
* DATE: 18 April 1996
* VERSION: 1.1
* HISTORY: bug in RMDonemillion() corrected
*
* Copyright (c) Katholieke Universiteit Leuven
* 1996, All Rights Reserved
*
* Conditions for use of the RIPEMD-160 Software
*
* The RIPEMD-160 software is freely available for use under the terms and
* conditions described hereunder, which shall be deemed to be accepted by
* any user of the software and applicable on any use of the software:
*
* 1. K.U.Leuven Department of Electrical Engineering-ESAT/COSIC shall for
* all purposes be considered the owner of the RIPEMD-160 software and of
* all copyright, trade secret, patent or other intellectual property
* rights therein.
* 2. The RIPEMD-160 software is provided on an "as is" basis without
* warranty of any sort, express or implied. K.U.Leuven makes no
* representation that the use of the software will not infringe any
* patent or proprietary right of third parties. User will indemnify
* K.U.Leuven and hold K.U.Leuven harmless from any claims or liabilities
* which may arise as a result of its use of the software. In no
* circumstances K.U.Leuven R&D will be held liable for any deficiency,
* fault or other mishappening with regard to the use or performance of
* the software.
* 3. User agrees to give due credit to K.U.Leuven in scientific publications
* or communications in relation with the use of the RIPEMD-160 software
* as follows: RIPEMD-160 software written by Antoon Bosselaers,
* available at http://www.esat.kuleuven.be/~cosicart/ps/AB-9601/.
*
\********************************************************************/
#ifndef RMDsize
#define RMDsize 160
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#if RMDsize == 128
#include "rmd128.h"
#elif RMDsize == 160
#include "rmd160.h"
#endif
#define TEST_BLOCK_SIZE 8000
#define TEST_BLOCKS 1250
#define TEST_BYTES ((long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS)
/********************************************************************/
byte *RMD(byte *message)
/*
* returns RMD(message)
* message should be a string terminated by '\0'
*/
{
dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */
static byte hashcode[RMDsize/8]; /* for final hash-value */
dword X[16]; /* current 16-word chunk */
unsigned int i; /* counter */
dword length; /* length in bytes of message */
dword nbytes; /* # of bytes not yet processed */
/* initialize */
MDinit(MDbuf);
length = (dword)strlen((char *)message);
/* process message in 16-word chunks */
for (nbytes=length; nbytes > 63; nbytes-=64) {
for (i=0; i<16; i++) {
X[i] = BYTES_TO_DWORD(message);
message += 4;
}
compress(MDbuf, X);
} /* length mod 64 bytes left */
/* finish: */
MDfinish(MDbuf, message, length, 0);
for (i=0; i<RMDsize/8; i+=4) {
hashcode[i] = MDbuf[i>>2]; /* implicit cast to byte */
hashcode[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */
hashcode[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */
hashcode[i+3] = (MDbuf[i>>2] >> 24);
}
return (byte *)hashcode;
}
/********************************************************************/
byte *RMDbinary(char *fname)
/*
* returns RMD(message in file fname)
* fname is read as binary data.
*/
{
FILE *mf; /* pointer to file <fname> */
byte data[1024]; /* contains current mess. block */
dword nbytes; /* length of this block */
dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */
static byte hashcode[RMDsize/8]; /* for final hash-value */
dword X[16]; /* current 16-word chunk */
unsigned int i, j; /* counters */
dword length[2]; /* length in bytes of message */
dword offset; /* # of unprocessed bytes at */
/* call of MDfinish */
/* initialize */
if ((mf = fopen(fname, "rb")) == NULL) {
fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n",
fname);
exit(1);
}
MDinit(MDbuf);
length[0] = 0;
length[1] = 0;
while ((nbytes = fread(data, 1, 1024, mf)) != 0) {
/* process all complete blocks */
for (i=0; i<(nbytes>>6); i++) {
for (j=0; j<16; j++)
X[j] = BYTES_TO_DWORD(data+64*i+4*j);
compress(MDbuf, X);
}
/* update length[] */
if (length[0] + nbytes < length[0])
length[1]++; /* overflow to msb of length */
length[0] += nbytes;
}
/* finish: */
offset = length[0] & 0x3C0; /* extract bytes 6 to 10 inclusive */
MDfinish(MDbuf, data+offset, length[0], length[1]);
for (i=0; i<RMDsize/8; i+=4) {
hashcode[i] = MDbuf[i>>2];
hashcode[i+1] = (MDbuf[i>>2] >> 8);
hashcode[i+2] = (MDbuf[i>>2] >> 16);
hashcode[i+3] = (MDbuf[i>>2] >> 24);
}
fclose(mf);
return (byte *)hashcode;
}
/********************************************************************/
void speedtest(void)
/*
* A time trial routine, to measure the speed of ripemd.
* Measures processor time required to process TEST_BLOCKS times
* a message of TEST_BLOCK_SIZE characters.
*/
{
clock_t t0, t1;
byte *data;
byte hashcode[RMDsize/8];
dword X[16];
dword MDbuf[RMDsize/32];
unsigned int i, j, k;
srand(time(NULL));
/* allocate and initialize test data */
if ((data = (byte*)malloc(TEST_BLOCK_SIZE)) == NULL) {
fprintf(stderr, "speedtest: allocation error\n");
exit(1);
}
for (i=0; i<TEST_BLOCK_SIZE; i++)
data[i] = (byte)(rand() >> 7);
/* start timer */
printf("\n\nRIPEMD-%u time trial. Processing %ld characters...\n",
RMDsize, TEST_BYTES);
t0 = clock();
/* process data */
MDinit(MDbuf);
for (i=0; i<TEST_BLOCKS; i++) {
for (j=0; j<TEST_BLOCK_SIZE; j+=64) {
for (k=0; k<16; k++)
X[k] = BYTES_TO_DWORD(data+j+4*k);
compress(MDbuf, X);
}
}
MDfinish(MDbuf, data, TEST_BYTES, 0);
/* stop timer, get time difference */
t1 = clock();
printf("\nTest input processed in %g seconds.\n",
(double)(t1-t0)/(double)CLOCKS_PER_SEC);
printf("Characters processed per second: %g\n",
(double)CLOCKS_PER_SEC*TEST_BYTES/((double)t1-t0));
printf("\n=> %3.2f Mbit/s\n\n", 8*(double)CLOCKS_PER_SEC*TEST_BYTES/((double)t1-t0)/(1024*1024));
for (i=0; i<RMDsize/8; i+=4) {
hashcode[i] = MDbuf[i>>2];
hashcode[i+1] = (MDbuf[i>>2] >> 8);
hashcode[i+2] = (MDbuf[i>>2] >> 16);
hashcode[i+3] = (MDbuf[i>>2] >> 24);
}
printf("\nhashcode: ");
for (i=0; i<RMDsize/8; i++)
printf("%02x", hashcode[i]);
printf("\n");
free(data);
return;
}
/********************************************************************/
void RMDonemillion(void)
/*
* returns RMD() of message consisting of 1 million 'a' characters
*/
{
dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */
static byte hashcode[RMDsize/8]; /* for final hash-value */
dword X[16]; /* current 16-word chunk */
unsigned int i; /* counter */
MDinit(MDbuf);
memcpy(X, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 32);
memcpy(X+8, X, 32);
for (i=15625; i>0; i--)
compress(MDbuf, X);
MDfinish(MDbuf, NULL, 1000000UL, 0);
for (i=0; i<RMDsize/8; i+=4) {
hashcode[i] = MDbuf[i>>2];
hashcode[i+1] = (MDbuf[i>>2] >> 8);
hashcode[i+2] = (MDbuf[i>>2] >> 16);
hashcode[i+3] = (MDbuf[i>>2] >> 24);
}
printf("\n* message: 1 million times \"a\"\n hashcode: ");
for (i=0; i<RMDsize/8; i++)
printf("%02x", hashcode[i]);
}
/********************************************************************/
void RMDstring(char *message, char *print)
{
unsigned int i;
byte *hashcode;
hashcode = RMD((byte *)message);
printf("\n* message: %s\n hashcode: ", print);
for (i=0; i<RMDsize/8; i++)
printf("%02x", hashcode[i]);
}
/********************************************************************/
void testsuite (void)
/*
* standard test suite
*/
{
printf("\n\nRIPEMD-%u test suite results (ASCII):\n", RMDsize);
RMDstring("", "\"\" (empty string)");
RMDstring("a", "\"a\"");
RMDstring("abc", "\"abc\"");
RMDstring("message digest", "\"message digest\"");
RMDstring("abcdefghijklmnopqrstuvwxyz", "\"abcdefghijklmnopqrstuvwxyz\"");
RMDstring("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\"");
RMDstring("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"\"A...Za...z0...9\"");
RMDstring("1234567890123456789012345678901234567890"
"1234567890123456789012345678901234567890",
"8 times \"1234567890\"");
RMDonemillion();
printf("\n");
return;
}
/********************************************************************/
main (int argc, char *argv[])
/*
* main program. calls one or more of the test routines depending
* on command line arguments. see the header of this file.
*
*/
{
while(1)
{
// testsuite ();
// printf("\n");
speedtest ();
printf("\n");
}
return 0;
}
/********************** end of file hashtest.c **********************/