/* Forrest Heller 2009 */ #include void print_round_iteration(int i); void circular_shift(char *str, int bits, char *word); int wire_counter = 0; /* generates SHA1 Verilog code */ int main(int argc, char *argv[]) { int i; int k; char str[256]; char str2[256]; printf("/*** SHA1 By Forrest Heller (2009) ***/\n"); printf("/* This code is based on the C SHA1 implementation as described in RFC 3174 */\n"); printf("/* round constants */\n"); printf("`define kzero 32'h5A827999\n"); printf("`define kone 32'h6ED9EBA1\n"); printf("`define ktwo 32'h8F1BBCDC\n"); printf("`define kthree 32'hCA62C1D6\n"); printf("`define SHA1CircularShift(bits,word) (((word)<<(bits))|((word)>>(32-(bits))))\n"); printf("module sha1(input wire [511:0] block ,\n input wire [159:0] current_hash,\n output wire [159:0] new_hash);\n\n"); printf("/*temporary wire variable to help with W initialization*/\n"); printf("wire [31:0] Wt [63:0];\n"); printf("/*mirrors W in SHA1 RFC reference*/\n"); printf("wire [31:0] W [79:0];\n"); printf("/* These variables mirror those in the SHA1 RFC reference*/\n"); printf("wire [31:0] temp [79:0];\n"); printf("wire [31:0] A [80:0];\n"); printf("wire [31:0] B [80:0];\n"); printf("wire [31:0] C [80:0];\n"); printf("wire [31:0] D [80:0];\n"); printf("wire [31:0] E [80:0];\n\n"); printf(" /* intialize first 16 words of W with the contents of block*/\n"); for(i = 0; i < 16; i++) { printf("assign W[%d] = (block[%d:%d]) | (block[%d:%d] << 8) | (block[%d:%d] << 16) |( block[%d:%d] << 24);\n",i,i*32+31,i*32+24,i*32+23,i*32+16,i*32+15,i*32+8,i*32+7,i*32); } printf("/* initialize rest of W */\n"); for (i = 16; i < 80; i++) { sprintf(str,"W[%d] ^ W[%d] ^ W[%d] ^ W[%d]",i-3,i-8,i-14,i-16); printf("assign Wt[%d]= %s;\n",i-16,str); sprintf(str,"Wt[%d]",i-16); circular_shift(str2,1,str); printf("assign W[%d] = %s;\n",i,str2); } printf("/* assign initial hashes*/\n"); printf("assign A[0] = current_hash[31:0];\n"); printf("assign B[0] = current_hash[63:32];\n"); printf("assign C[0] = current_hash[95:64];\n"); printf("assign D[0] = current_hash[127:96];\n"); printf("assign E[0] = current_hash[159:128];\n\n"); printf("/* * * * * First Rounds [0-19] * * * * */\n"); for(i = 0; i < 20; i++) { sprintf(str2,"A[%d]",i); circular_shift(str,5,str2); printf("assign temp[%d] = %s + ((B[%d] & C[%d]) | ((~B[%d]) & D[%d])) + E[%d] + W[%d] + `kzero;\n",i,str,i,i,i,i,i,i); print_round_iteration(i); } printf("\n/* * * * * Second Rounds [20-39] * * * * */\n"); for (i = 20; i < 40; i++) { sprintf(str2,"A[%d]",i); circular_shift(str,5,str2); printf("assign temp[%d] = %s + (B[%d]^C[%d]^D[%d]) + E[%d] + W[%d] + `kone;\n",i,str,i,i,i,i,i); print_round_iteration(i); } printf("\n/* * * * * Third Rounds [40-59] * * * * */\n"); for (i = 40; i < 60; i++) { sprintf(str2,"A[%d]",i); circular_shift(str,5,str2); printf("assign temp[%d] = %s + ((B[%d] & C[%d]) | (B[%d] & D[%d]) | (C[%d] & D[%d])) + E[%d] + W[%d] + `ktwo;\n",i,str,i,i,i,i,i,i,i,i); print_round_iteration(i); } printf("\n/* * * * * Fourth Rounds [60-79] * * * * */\n"); for (i = 60; i < 80; i++) { sprintf(str2,"A[%d]",i); circular_shift(str,5,str2); printf("assign temp[%d] = %s + (B[%d]^C[%d]^D[%d]) + E[%d] + W[%d] + `kthree;\n",i,str,i,i,i,i,i); print_round_iteration(i); } printf("\n/* finally, add the new values to the current hash for a new hash*/\n"); printf("assign new_hash[31:0] = current_hash[31:0] + A[80];\n"); printf("assign new_hash[63:32] = current_hash[63:32] + B[80];\n"); printf("assign new_hash[95:64] = current_hash[95:64] + C[80];\n"); printf("assign new_hash[127:96] = current_hash[127:96] + D[80];\n"); printf("assign new_hash[159:128]= current_hash[159:128] + E[80];\n"); printf("endmodule\n"); return 0; } void print_round_iteration(int i) { char str2[256],str[256]; printf("assign E[%d+1] = D[%d];\n",i,i); printf("assign D[%d+1] = C[%d];\n",i,i); sprintf(str2,"B[%d]",i); circular_shift(str,30,str2); printf("assign C[%d+1] = %s;\n",i,str); printf("assign B[%d+1] = A[%d];\n",i,i); printf("assign A[%d+1] = temp[%d][31:0];\n",i,i); } void circular_shift(char *str, int bits, char *word) { sprintf(str,"`SHA1CircularShift(%d,%s)",bits,word); }