#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "libsys.h"

#include "rmd160.h"

#ifndef RMDsize
#define RMDsize 160
#endif

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;
}

#define	MSG_SIZE	1024*1024		// Bit
int main (void)
{
	int result, i, j, cnt;
	byte *hashcode;
	byte hashref[] = {0xFC,0x20,0x7B,0x84,0x40,0x1C,0x49,0x0B,0x8D,0x69,0x88,0xD2,0x49,0x20,0x01,0x90,0x41,0x77,0x72,0x59};
	volatile int *pLED = (int*)sys_led_port;
	char msg[MSG_SIZE/8];
	char crlf[] = "\n";
	UINT32 start, stop;

	for (i=0; i < MSG_SIZE/8; i++)
		msg[i] = 0x55;

	msg[i] = 0;

	setbuf(stdout, NULL);

	cnt = 0;
	start = clock();
	stop = start + 1000;
	while(1)
	{
		hashcode = RMD((byte *)msg);
		start = clock();
		if (memcmp(hashcode, hashref, sizeof(hashref)))
		{
			printf("Error RipeMD-160!\n");
			return 1;
		}
		if (start >= stop)
		{
			for (i=0; i<RMDsize/8; i++)
				printf("%2.2X", hashcode[i]);
			printf("\n%d Hashes/s of %d Mbit message => %d Mbit/s\n\n", cnt, MSG_SIZE/(1024*1024), cnt*MSG_SIZE/(1024*1024));
			start = clock();
			stop = start + 1000;
			cnt = 0;
		}
		cnt++;
	}

	return 0;
}

