// SHA cipher by Ruptor

#include <string.h>
#include <stdlib.h>
#include "sha.h"

#define SHA_v		1

// 1 for SHA-1, 0 for the original SHA, or make it variable ;)
// Rotation will be optimized out for SHA-0

#define SHA_expand(i)	ks[i] = _lrotl (blk[i-3] ^ blk[i-8] ^ blk[i-14] ^ blk[i-16], SHA_v)

#define SHA_F0(v,w,x,y,z,i) (z += ks[i] + 0x5A827999 + _lrotl (v, 5) + ((w&(x^y))^y)    , w = _lrotl (w, 30))
#define SHA_F1(v,w,x,y,z,i) (z += ks[i] + 0x6ED9EBA1 + _lrotl (v, 5) + (w^x^y)          , w = _lrotl (w, 30))
#define SHA_F2(v,w,x,y,z,i) (z += ks[i] + 0x8F1BBCDC + _lrotl (v, 5) + (((w|x)&y)|(w&x)), w = _lrotl (w, 30))
#define SHA_F3(v,w,x,y,z,i) (z += ks[i] + 0xCA62C1D6 + _lrotl (v, 5) + (w^x^y)          , w = _lrotl (w, 30))

#define SHA_R0(v,w,x,y,z,i) (w = _lrotr (w, 30), z -= ks[i] + 0x5A827999 + _lrotl (v, 5) + ((w&(x^y))^y))
#define SHA_R1(v,w,x,y,z,i) (w = _lrotr (w, 30), z -= ks[i] + 0x6ED9EBA1 + _lrotl (v, 5) + (w^x^y))
#define SHA_R2(v,w,x,y,z,i) (w = _lrotr (w, 30), z -= ks[i] + 0x8F1BBCDC + _lrotl (v, 5) + (((w|x)&y)|(w&x)))
#define SHA_R3(v,w,x,y,z,i) (w = _lrotr (w, 30), z -= ks[i] + 0xCA62C1D6 + _lrotl (v, 5) + (w^x^y))

static void SHA_encrypt (const unsigned long *data_in, unsigned long *data_out, const unsigned __int32 *key)
{
	unsigned long				ks[80];
	register unsigned long		A = data_in[0], B = data_in[1], C = data_in[2], D = data_in[3], E = data_in[4];
	
	memcpy (ks, key, SHA_KEY_BYTES);
	
	SHA_expand (16); SHA_expand (17); SHA_expand (18); SHA_expand (19);
	SHA_expand (20); SHA_expand (21); SHA_expand (22); SHA_expand (23);
	SHA_expand (24); SHA_expand (25); SHA_expand (26); SHA_expand (27);
	SHA_expand (28); SHA_expand (29); SHA_expand (30); SHA_expand (31);
	SHA_expand (32); SHA_expand (33); SHA_expand (34); SHA_expand (35);
	SHA_expand (36); SHA_expand (37); SHA_expand (38); SHA_expand (39);
	SHA_expand (40); SHA_expand (41); SHA_expand (42); SHA_expand (43);
	SHA_expand (44); SHA_expand (45); SHA_expand (46); SHA_expand (47);
	SHA_expand (48); SHA_expand (49); SHA_expand (50); SHA_expand (51);
	SHA_expand (52); SHA_expand (53); SHA_expand (54); SHA_expand (55);
	SHA_expand (56); SHA_expand (57); SHA_expand (58); SHA_expand (59);
	SHA_expand (60); SHA_expand (61); SHA_expand (62); SHA_expand (63);
	SHA_expand (64); SHA_expand (65); SHA_expand (66); SHA_expand (67);
	SHA_expand (68); SHA_expand (69); SHA_expand (70); SHA_expand (71);
	SHA_expand (72); SHA_expand (73); SHA_expand (74); SHA_expand (75);
	SHA_expand (76); SHA_expand (77); SHA_expand (78); SHA_expand (79);
	
	SHA_F0 (A,B,C,D,E, 0);
	SHA_F0 (E,A,B,C,D, 1);
	SHA_F0 (D,E,A,B,C, 2);
	SHA_F0 (C,D,E,A,B, 3);
	SHA_F0 (B,C,D,E,A, 4);
	SHA_F0 (A,B,C,D,E, 5);
	SHA_F0 (E,A,B,C,D, 6);
	SHA_F0 (D,E,A,B,C, 7);
	SHA_F0 (C,D,E,A,B, 8);
	SHA_F0 (B,C,D,E,A, 9);
	SHA_F0 (A,B,C,D,E,10);
	SHA_F0 (E,A,B,C,D,11);
	SHA_F0 (D,E,A,B,C,12);
	SHA_F0 (C,D,E,A,B,13);
	SHA_F0 (B,C,D,E,A,14);
	SHA_F0 (A,B,C,D,E,15);
	SHA_F0 (E,A,B,C,D,16);
	SHA_F0 (D,E,A,B,C,17);
	SHA_F0 (C,D,E,A,B,18);
	SHA_F0 (B,C,D,E,A,19);
	
	SHA_F1 (A,B,C,D,E,20);
	SHA_F1 (E,A,B,C,D,21);
	SHA_F1 (D,E,A,B,C,22);
	SHA_F1 (C,D,E,A,B,23);
	SHA_F1 (B,C,D,E,A,24);
	SHA_F1 (A,B,C,D,E,25);
	SHA_F1 (E,A,B,C,D,26);
	SHA_F1 (D,E,A,B,C,27);
	SHA_F1 (C,D,E,A,B,28);
	SHA_F1 (B,C,D,E,A,29);
	SHA_F1 (A,B,C,D,E,30);
	SHA_F1 (E,A,B,C,D,31);
	SHA_F1 (D,E,A,B,C,32);
	SHA_F1 (C,D,E,A,B,33);
	SHA_F1 (B,C,D,E,A,34);
	SHA_F1 (A,B,C,D,E,35);
	SHA_F1 (E,A,B,C,D,36);
	SHA_F1 (D,E,A,B,C,37);
	SHA_F1 (C,D,E,A,B,38);
	SHA_F1 (B,C,D,E,A,39);
	
	SHA_F2 (A,B,C,D,E,40);
	SHA_F2 (E,A,B,C,D,41);
	SHA_F2 (D,E,A,B,C,42);
	SHA_F2 (C,D,E,A,B,43);
	SHA_F2 (B,C,D,E,A,44);
	SHA_F2 (A,B,C,D,E,45);
	SHA_F2 (E,A,B,C,D,46);
	SHA_F2 (D,E,A,B,C,47);
	SHA_F2 (C,D,E,A,B,48);
	SHA_F2 (B,C,D,E,A,49);
	SHA_F2 (A,B,C,D,E,50);
	SHA_F2 (E,A,B,C,D,51);
	SHA_F2 (D,E,A,B,C,52);
	SHA_F2 (C,D,E,A,B,53);
	SHA_F2 (B,C,D,E,A,54);
	SHA_F2 (A,B,C,D,E,55);
	SHA_F2 (E,A,B,C,D,56);
	SHA_F2 (D,E,A,B,C,57);
	SHA_F2 (C,D,E,A,B,58);
	SHA_F2 (B,C,D,E,A,59);
	
	SHA_F3 (A,B,C,D,E,60);
	SHA_F3 (E,A,B,C,D,61);
	SHA_F3 (D,E,A,B,C,62);
	SHA_F3 (C,D,E,A,B,63);
	SHA_F3 (B,C,D,E,A,64);
	SHA_F3 (A,B,C,D,E,65);
	SHA_F3 (E,A,B,C,D,66);
	SHA_F3 (D,E,A,B,C,67);
	SHA_F3 (C,D,E,A,B,68);
	SHA_F3 (B,C,D,E,A,69);
	SHA_F3 (A,B,C,D,E,70);
	SHA_F3 (E,A,B,C,D,71);
	SHA_F3 (D,E,A,B,C,72);
	SHA_F3 (C,D,E,A,B,73);
	SHA_F3 (B,C,D,E,A,74);
	SHA_F3 (A,B,C,D,E,75);
	SHA_F3 (E,A,B,C,D,76);
	SHA_F3 (D,E,A,B,C,77);
	SHA_F3 (C,D,E,A,B,78);
	SHA_F3 (B,C,D,E,A,79);
	
	data_out[0] = A; data_out[1] = B; data_out[2] = C; data_out[3] = D; data_out[4] = E;
}

static void SHA_decrypt (const unsigned long *data_in, unsigned long *data_out, const unsigned __int32 *key)
{
	unsigned long				ks[80];
	register unsigned long		A = data_in[0], B = data_in[1], C = data_in[2], D = data_in[3], E = data_in[4];
	
	memcpy (ks, key, SHA_KEY_BYTES);
	
	SHA_expand (16); SHA_expand (17); SHA_expand (18); SHA_expand (19);
	SHA_expand (20); SHA_expand (21); SHA_expand (22); SHA_expand (23);
	SHA_expand (24); SHA_expand (25); SHA_expand (26); SHA_expand (27);
	SHA_expand (28); SHA_expand (29); SHA_expand (30); SHA_expand (31);
	SHA_expand (32); SHA_expand (33); SHA_expand (34); SHA_expand (35);
	SHA_expand (36); SHA_expand (37); SHA_expand (38); SHA_expand (39);
	SHA_expand (40); SHA_expand (41); SHA_expand (42); SHA_expand (43);
	SHA_expand (44); SHA_expand (45); SHA_expand (46); SHA_expand (47);
	SHA_expand (48); SHA_expand (49); SHA_expand (50); SHA_expand (51);
	SHA_expand (52); SHA_expand (53); SHA_expand (54); SHA_expand (55);
	SHA_expand (56); SHA_expand (57); SHA_expand (58); SHA_expand (59);
	SHA_expand (60); SHA_expand (61); SHA_expand (62); SHA_expand (63);
	SHA_expand (64); SHA_expand (65); SHA_expand (66); SHA_expand (67);
	SHA_expand (68); SHA_expand (69); SHA_expand (70); SHA_expand (71);
	SHA_expand (72); SHA_expand (73); SHA_expand (74); SHA_expand (75);
	SHA_expand (76); SHA_expand (77); SHA_expand (78); SHA_expand (79);
	
	SHA_R3 (B,C,D,E,A,79);
	SHA_R3 (C,D,E,A,B,78);
	SHA_R3 (D,E,A,B,C,77);
	SHA_R3 (E,A,B,C,D,76);
	SHA_R3 (A,B,C,D,E,75);
	SHA_R3 (B,C,D,E,A,74);
	SHA_R3 (C,D,E,A,B,73);
	SHA_R3 (D,E,A,B,C,72);
	SHA_R3 (E,A,B,C,D,71);
	SHA_R3 (A,B,C,D,E,70);
	SHA_R3 (B,C,D,E,A,69);
	SHA_R3 (C,D,E,A,B,68);
	SHA_R3 (D,E,A,B,C,67);
	SHA_R3 (E,A,B,C,D,66);
	SHA_R3 (A,B,C,D,E,65);
	SHA_R3 (B,C,D,E,A,64);
	SHA_R3 (C,D,E,A,B,63);
	SHA_R3 (D,E,A,B,C,62);
	SHA_R3 (E,A,B,C,D,61);
	SHA_R3 (A,B,C,D,E,60);
	
	SHA_R2 (B,C,D,E,A,59);
	SHA_R2 (C,D,E,A,B,58);
	SHA_R2 (D,E,A,B,C,57);
	SHA_R2 (E,A,B,C,D,56);
	SHA_R2 (A,B,C,D,E,55);
	SHA_R2 (B,C,D,E,A,54);
	SHA_R2 (C,D,E,A,B,53);
	SHA_R2 (D,E,A,B,C,52);
	SHA_R2 (E,A,B,C,D,51);
	SHA_R2 (A,B,C,D,E,50);
	SHA_R2 (B,C,D,E,A,49);
	SHA_R2 (C,D,E,A,B,48);
	SHA_R2 (D,E,A,B,C,47);
	SHA_R2 (E,A,B,C,D,46);
	SHA_R2 (A,B,C,D,E,45);
	SHA_R2 (B,C,D,E,A,44);
	SHA_R2 (C,D,E,A,B,43);
	SHA_R2 (D,E,A,B,C,42);
	SHA_R2 (E,A,B,C,D,41);
	SHA_R2 (A,B,C,D,E,40);
	
	SHA_R1 (B,C,D,E,A,39);
	SHA_R1 (C,D,E,A,B,38);
	SHA_R1 (D,E,A,B,C,37);
	SHA_R1 (E,A,B,C,D,36);
	SHA_R1 (A,B,C,D,E,35);
	SHA_R1 (B,C,D,E,A,34);
	SHA_R1 (C,D,E,A,B,33);
	SHA_R1 (D,E,A,B,C,32);
	SHA_R1 (E,A,B,C,D,31);
	SHA_R1 (A,B,C,D,E,30);
	SHA_R1 (B,C,D,E,A,29);
	SHA_R1 (C,D,E,A,B,28);
	SHA_R1 (D,E,A,B,C,27);
	SHA_R1 (E,A,B,C,D,26);
	SHA_R1 (A,B,C,D,E,25);
	SHA_R1 (B,C,D,E,A,24);
	SHA_R1 (C,D,E,A,B,23);
	SHA_R1 (D,E,A,B,C,22);
	SHA_R1 (E,A,B,C,D,21);
	SHA_R1 (A,B,C,D,E,20);
	
	SHA_R0 (B,C,D,E,A,19);
	SHA_R0 (C,D,E,A,B,18);
	SHA_R0 (D,E,A,B,C,17);
	SHA_R0 (E,A,B,C,D,16);
	SHA_R0 (A,B,C,D,E,15);
	SHA_R0 (B,C,D,E,A,14);
	SHA_R0 (C,D,E,A,B,13);
	SHA_R0 (D,E,A,B,C,12);
	SHA_R0 (E,A,B,C,D,11);
	SHA_R0 (A,B,C,D,E,10);
	SHA_R0 (B,C,D,E,A, 9);
	SHA_R0 (C,D,E,A,B, 8);
	SHA_R0 (D,E,A,B,C, 7);
	SHA_R0 (E,A,B,C,D, 6);
	SHA_R0 (A,B,C,D,E, 5);
	SHA_R0 (B,C,D,E,A, 4);
	SHA_R0 (C,D,E,A,B, 3);
	SHA_R0 (D,E,A,B,C, 2);
	SHA_R0 (E,A,B,C,D, 1);
	SHA_R0 (A,B,C,D,E, 0);
	
	data_out[0] = A; data_out[1] = B; data_out[2] = C; data_out[3] = D; data_out[4] = E;
}
