/********************************************************************\ * * FILE: mactest.c * * CONTENTS: test file for sample C-implementation of * RIPEMD160-MAC and RIPEMD128-MAC * * command line arguments: * filename keyfilename -- compute MAC of file binary read using * key in keyfilename (hexadecimal format) * -sstring -- print string & MAC for default key * -t -- perform time trial * -x -- execute standard test suite, ASCII input * * for linkage with rmd128mc.c: define RMDsize as 128 * for linkage with rmd160mc.c: define RMDsize as 160 (default) * TARGET: any computer with an ANSI C compiler * * AUTHOR: Antoon Bosselaers, ESAT-COSIC * DATE: 26 March 1998 * VERSION: 1.0 * * Copyright (c) Katholieke Universiteit Leuven * 1998, All Rights Reserved * \********************************************************************/ #ifndef RMDsize #define RMDsize 160 #endif #include #include #include #include #if RMDsize == 128 #include "rmd128mc.h" #elif RMDsize == 160 #include "rmd160mc.h" #endif #define TEST_BLOCK_SIZE 8000 #define TEST_BLOCKS 1250 #define TEST_BYTES ((long)TEST_BLOCK_SIZE * (long)TEST_BLOCKS) /********************************************************************/ byte *RMDMAC(byte *key, byte *message) /* * returns RMDMAC(key, message) * message should be a string terminated by '\0' */ { dword MDbuf[RMDsize/32]; /* contains (A, B, C, D(, E)) */ static byte rmdmac[RMDsize/8]; /* for final mac-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 */ dword *MDK; /* pointer to expanded key */ /* key setup */ MDK = MDMACsetup(key); /* initialize */ MDMACinit(MDK, 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(MDK, MDbuf, X); } /* length mod 64 bytes left */ /* finish: */ MDMACfinish(MDK, MDbuf, message, length, 0); for (i=0; i>2]; /* implicit cast to byte */ rmdmac[i+1] = (MDbuf[i>>2] >> 8); /* extracts the 8 least */ rmdmac[i+2] = (MDbuf[i>>2] >> 16); /* significant bits. */ rmdmac[i+3] = (MDbuf[i>>2] >> 24); } return (byte *)rmdmac; } /********************************************************************/ byte *RMDMACbinary(byte *key, char *fname) /* * returns RMDMAC(key, message in file fname) * fname is read as binary data. */ { FILE *mf; /* pointer to file */ 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 rmdmac[RMDsize/8]; /* for final mac-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 MDMACfinish */ dword *MDK; /* pointer to expanded key */ /* key setup */ MDK = MDMACsetup(key); /* initialize */ if ((mf = fopen(fname, "rb")) == NULL) { fprintf(stderr, "\nRMDbinary: cannot open file \"%s\".\n", fname); exit(1); } MDMACinit(MDK, 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(MDK, 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 */ MDMACfinish(MDK, MDbuf, data+offset, length[0], length[1]); for (i=0; i>2]; rmdmac[i+1] = (MDbuf[i>>2] >> 8); rmdmac[i+2] = (MDbuf[i>>2] >> 16); rmdmac[i+3] = (MDbuf[i>>2] >> 24); } fclose(mf); return (byte *)rmdmac; } /***********************************************************************/ byte *RMDMACreadkey(char *fname) /* * reads 128-bit MAC key from fname * key should be given in hexadecimal format */ { FILE *file; unsigned int i, temp; static byte key[16]; if ( (file = fopen(fname, "r")) == NULL ) { fprintf(stderr, "RMDMACreadkey: cannot open file \"%s\".\n", fname); exit(1); } for (i=0;i < 16;i++) { if (fscanf(file, "%02x", &temp) == EOF) fprintf(stderr, "RMDMACreadkey: EOF encountered before read was " "completed in \"%s\".\n", fname); key[i] = (byte)temp; } fclose(file); return key; } /********************************************************************/ void speedtest(void) /* * A time trial routine, to measure the speed of RIPEMD160/128-MAC. * Measures processor time required to process TEST_BLOCKS times * a message of TEST_BLOCK_SIZE characters. */ { clock_t t0, t1; byte *data; byte rmdmac[RMDsize/8]; dword X[16]; dword MDbuf[RMDsize/32]; unsigned int i, j, k; byte MDMACkey[16]; dword *MDK; srand(time(NULL)); /* pick a random key and perform key setup */ for (i=0; i<16; i++) MDMACkey[i] = (byte)(rand() >> 7); MDK = MDMACsetup(MDMACkey); /* 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> 7); /* start timer */ printf("\n\nRIPEMD-%uMAC time trial. Processing %ld characters...\n", RMDsize, TEST_BYTES); t0 = clock(); /* process data */ MDMACinit(MDK, MDbuf); for (i=0; i>2]; rmdmac[i+1] = (MDbuf[i>>2] >> 8); rmdmac[i+2] = (MDbuf[i>>2] >> 16); rmdmac[i+3] = (MDbuf[i>>2] >> 24); } printf("\nMAC: "); for (i=0; i0; i--) compress(MDK, MDbuf, X); MDMACfinish(MDK, MDbuf, NULL, 1000000UL, 0); for (i=0; i>2]; rmdmac[i+1] = (MDbuf[i>>2] >> 8); rmdmac[i+2] = (MDbuf[i>>2] >> 16); rmdmac[i+3] = (MDbuf[i>>2] >> 24); } printf("\n* message: 1 million times \"a\"\n MAC: "); for (i=0; i