/* * Copyright Ó 1992 by Xerox Corporation. All rights reserved. * Carl Hauser, February 7, 1992 * A straightforward implementation of the inner 16-word computation * of the proposed Secure Hash Standard (SHS), dated 22 January 1992 * This function is applied to successive 16 word blocks of the final * padded message. (The padding has to be done separately-- see section 4 * of the SHS standard) * * To use: initialize a five word array, h, to * {0x67452301, 0x0efcdab89, 0x98badcfe, 0x10325476, 0x0c3d2e1f0} * and then pass h and pointers to successive 16 word message blocks * to parameters h and m of onem. * The five word hash is the contents of h after the last block * has been processed. */ #define S5(x) (((x)<<5) | ((x)>>27)) #define S30(x) (((x)<<30) | ((x)>>2)) #define K0 0x5a827999 #define K1 0x6ed9eba1 #define K2 0x8f1bbcdc #define K3 0x0ca62c1d6 #define AND(x,y) ((x)&(y)) #define F0(x,y,z) (AND(x,y) | AND(~(x),z)) #define F1(x,y,z) ((x)^(y)^(z)) #define F2(x,y,z) (AND(x,y) | AND(x,z) | AND(y,z)) #define word unsigned long static reversebytes(w) word *w; { char *p = (char *) w; char t; t = *p; *p = *(p+3); *(p+3) = t; t = *(p+1); *(p+1) = *(p+2); *(p+2) = t; } void onem(m, h) word m[16]; word h[5]; { word w[80]; int t; word A, B, C, D, E; word *p, *q; word *pm3, *pm8, *pm14, *pm16; word temp; int i; #ifdef LITTLE_ENDIAN for (i=0; i<16; i++) { reversebytes(&(m[i)); }; #endif A = h[0]; B=h[1]; C=h[2]; D=h[3]; E=h[4]; for (p = m, q=w; p < m+16; p++, q++) { *q = *p; } pm3 = w+13; pm8 = w+8; pm14=w+2; pm16=w; for (p=w+16; p < w+80; p++, pm3++, pm8++, pm14++, pm16++) { *p = *pm3 ^ *pm8 ^ *pm14 ^ *pm16; } for (i=0; i<20; i++) { temp = S5(A) + F0(B,C,D) + E + w[i] + K0; E=D; D=C; C=S30(B); B=A; A=temp; } for (i=20; i<40; i++) { temp = S5(A) + F1(B,C,D) + E + w[i] + K1; E=D; D=C; C=S30(B); B=A; A=temp; } for (i=40; i<60; i++) { temp = S5(A) + F2(B,C,D) + E + w[i] + K2; E=D; D=C; C=S30(B); B=A; A=temp; } for (i=60; i<80; i++) { temp = S5(A) + F1(B,C,D) + E + w[i] + K3; E=D; D=C; C=S30(B); B=A; A=temp; } h[0]=h[0]+A; h[1]=h[1]+B; h[2]=h[2]+C; h[3]=h[3]+D; h[4]=h[4]+E; }