/* hashlib.c -- hash function library for problem set 1 in 6.857 [Fall 2001]. Much of this code hash been copied from RC5REF.C. */ /* RC5REF.C -- Reference implementation of RC5-32/12/16 in C. */ /* Copyright (C) 1995 RSA Data Security, Inc. */ #include #include #include "hashlib.h" #define w 16 /* word size in bits */ #define r 12 /* number of rounds */ #define b 8 /* number of bytes in key */ #define c 4 /* number words in key */ /* c = max(1,ceil(8*b/w)) */ #define t 26 /* size of table S = 2*(r+1) words */ WORD S[t]; /* expanded key table */ WORD P = 0xb7e1, Q = 0x9e37; /* magic constants */ /* Rotation operators. x must be unsigned, to get logical right shift*/ #define ROTL(x,y) (((x)<<(y&(w-1))) | ((x)>>(w-(y&(w-1))))) #define ROTR(x,y) (((x)>>(y&(w-1))) | ((x)<<(w-(y&(w-1))))) void printword(WORD A) { WORD k; for (k=0;k>k)&0xFF); } void RC5_ENCRYPT(WORD *pt, WORD *ct) /* 2 WORD input pt/output ct */ { WORD i, A=(WORD)(pt[0]+S[0]), B=(WORD)(pt[1]+S[1]); for (i=1; i<=r; i++) { A = (WORD)(ROTL( (A^B),B)+S[2*i]); B = (WORD)(ROTL( (B^A),A)+S[2*i+1]); } ct[0] = A; ct[1] = B; } void RC5_DECRYPT(WORD *ct, WORD *pt) /* 2 WORD input ct/output pt */ { WORD i, B=ct[1], A=ct[0], C; for (i=r; i>0; i--) { C = (WORD)(B-S[2*i+1]); B = ROTR( C , A) ^ A; C = (WORD)(A-S[2*i]); A = ROTR( C , B) ^ B; } pt[1] = (WORD)(B-S[1]); pt[0] = (WORD)(A-S[0]); } void RC5_SETUP(unsigned char *K) /* secret input key K[0...b-1] */ { unsigned int i; WORD j, k, u=w/8, A, B, C, D, E, F, L[c]; /* Initialize L, then S, then mix key into S */ for (i=b-1,L[c-1]=0; i!=-1; i--) L[i/u] = (L[i/u]<<8)+K[i]; for (S[0]=P,i=1; i 3*c */ C = (WORD)(A+B); C = (WORD)(S[i]+C); A = S[i] = ROTL(C,3); C = (WORD)(A+B); D = (WORD)(L[j]+C); B = L[j] = ROTL(D, C); } } void hash(char *msg, WORD *out) /* input is msg. out[2] holds the digest */ { int i=0,j,n; unsigned char key[b]; WORD tmp[2] = {1,2}; n = strlen(msg); while(i