Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module super_hash_processor(input logic clk, reset_n, start,
- input logic [1:0] opcode,
- input logic [31:0] message_addr, size, output_addr,
- output logic done, mem_clk, mem_we,
- output logic [15:0] mem_addr,
- output logic [31:0] mem_write_data,
- input logic [31:0] mem_read_data);
- enum logic [2:0] {IDLE=3'b000, BUFF_READ=3'b001, READ=3'b010, COMPUTE=3'b011, WRITE=3'b100, BUFF_WRITE=3'b101} state;
- assign mem_clk = clk;
- logic [31:0] h0, h1, h2, h3, h4, h5, h6, h7;
- logic [31:0] a, b, c, d, e, f, g, h;
- logic [31:0] w[0:79];
- logic [31:0] s1, s0;
- logic [127:0] md5_digest;
- logic [159:0] sha1_digest;
- logic [255:0] sha256_digest;
- //logic [63:0] length;
- logic [15:0] num_blocks;
- int count_words;
- int t, rc, wc, bc, tmax, wmax;
- //int delim_block;
- /*===========================================================================*/
- //FUNCTION: changeEndian
- function logic[31:0] changeEndian(input logic [31:0] value);
- changeEndian = {value[7:0], value[15:8], value[23:16], value[31:24]};
- endfunction
- //FUNCTION: determine_num_blocks
- function logic [15:0] determine_num_blocks(input logic [31:0] size);
- if ((size << 3) % 512 <= 447)
- determine_num_blocks = ((size << 3) / 512) + 1;
- else
- determine_num_blocks = ((size << 3) / 512) + 2;
- endfunction
- //FUNCTION: rightrotate
- function logic [31:0] rightrotate(input logic [31:0] x,
- input logic [7:0] r);
- begin
- rightrotate = (x >> r) | (x << (32 - r));
- end
- endfunction
- //FUNCTION: leftrotate
- function logic [31:0] leftrotate(input logic [31:0] x);
- begin
- leftrotate = (x << 1) | (x >> 31);
- end
- endfunction
- /*---------------------------------------------------------------------------*/
- //MD5 s constants
- /*parameter byte md5_s[0:63] = '{
- 8'd7, 8'd12, 8'd17, 8'd22, 8'd7, 8'd12, 8'd17, 8'd22, 8'd7, 8'd12, 8'd17, 8'd22, 8'd7, 8'd12, 8'd17, 8'd22,
- 8'd5, 8'd9, 8'd14, 8'd20, 8'd5, 8'd9, 8'd14, 8'd20, 8'd5, 8'd9, 8'd14, 8'd20, 8'd5, 8'd9, 8'd14, 8'd20,
- 8'd4, 8'd11, 8'd16, 8'd23, 8'd4, 8'd11, 8'd16, 8'd23, 8'd4, 8'd11, 8'd16, 8'd23, 8'd4, 8'd11, 8'd16, 8'd23,
- 8'd6, 8'd10, 8'd15, 8'd21, 8'd6, 8'd10, 8'd15, 8'd21, 8'd6, 8'd10, 8'd15, 8'd21, 8'd6, 8'd10, 8'd15, 8'd21
- };*/
- parameter byte md5_s[0:15] = '{
- 8'd7, 8'd12, 8'd17, 8'd22,
- 8'd5, 8'd9, 8'd14, 8'd20,
- 8'd4, 8'd11, 8'd16, 8'd23,
- 8'd6, 8'd10, 8'd15, 8'd21
- };
- //FUNCTION FOR MD5: md5_getS
- function logic [31:0] md5_getS(input logic [5:0] t);
- logic [3:0] i;
- i = {t[5:4], t[1:0]};
- return md5_s[i];
- endfunction
- //MD5 k constants
- parameter int md5_k[0:63] = '{
- 32'hd76aa478, 32'he8c7b756, 32'h242070db, 32'hc1bdceee,
- 32'hf57c0faf, 32'h4787c62a, 32'ha8304613, 32'hfd469501,
- 32'h698098d8, 32'h8b44f7af, 32'hffff5bb1, 32'h895cd7be,
- 32'h6b901122, 32'hfd987193, 32'ha679438e, 32'h49b40821,
- 32'hf61e2562, 32'hc040b340, 32'h265e5a51, 32'he9b6c7aa,
- 32'hd62f105d, 32'h02441453, 32'hd8a1e681, 32'he7d3fbc8,
- 32'h21e1cde6, 32'hc33707d6, 32'hf4d50d87, 32'h455a14ed,
- 32'ha9e3e905, 32'hfcefa3f8, 32'h676f02d9, 32'h8d2a4c8a,
- 32'hfffa3942, 32'h8771f681, 32'h6d9d6122, 32'hfde5380c,
- 32'ha4beea44, 32'h4bdecfa9, 32'hf6bb4b60, 32'hbebfbc70,
- 32'h289b7ec6, 32'heaa127fa, 32'hd4ef3085, 32'h04881d05,
- 32'hd9d4d039, 32'he6db99e5, 32'h1fa27cf8, 32'hc4ac5665,
- 32'hf4292244, 32'h432aff97, 32'hab9423a7, 32'hfc93a039,
- 32'h655b59c3, 32'h8f0ccc92, 32'hffeff47d, 32'h85845dd1,
- 32'h6fa87e4f, 32'hfe2ce6e0, 32'ha3014314, 32'h4e0811a1,
- 32'hf7537e82, 32'hbd3af235, 32'h2ad7d2bb, 32'heb86d391
- };
- //FUNCTION FOR MD5: md5_w
- function logic [3:0] md5_w(input logic [7:0] t);
- begin
- if (t <= 15)
- md5_w = t;
- else if (t <= 31)
- md5_w = (5 * t + 1) % 16;
- else if (t <= 47)
- md5_w = (3 * t + 5) % 16;
- else
- md5_w = (7 * t) % 16;
- end
- endfunction
- //FUNCTION FOR MD5: md5_f
- function logic [31:0] md5_f(input logic [7:0] t);
- begin
- if (t <= 15)
- md5_f = (b & c) | ((~b) & d);
- else if (t <= 31)
- md5_f = (d & b) | ((~d) & c);
- else if (t <= 47)
- md5_f = b ^ c ^ d;
- else
- md5_f = c ^ (b | (~d));
- end
- endfunction
- //FUNCTION FOR MD5: md5_op
- function logic [127:0] md5_op(input logic [31:0] a, b, c, d, w,
- input logic [7:0] t);
- logic [31:0] temp1, temp2;
- begin
- temp1 = a + md5_f(t) + md5_k[t] + w;
- //temp2 = b + ((temp1 << md5_s[t]) | (temp1 >> (32 - md5_s[t])));
- temp2 = b + ((temp1 << md5_getS(t)) | (temp1 >> (32 - md5_getS(t))));
- md5_op = {d, temp2, b, c};
- end
- endfunction
- /*---------------------------------------------------------------------------*/
- //FUNCTION FOR SHA1: sha1_f
- function logic [31:0] sha1_f(input logic [7:0] t);
- begin
- if (t <= 19)
- sha1_f = (b & c) | ((~b) & d);
- else if (t <= 39)
- sha1_f = b ^ c ^ d;
- else if (t <= 59)
- sha1_f = (b & c) | (b & d) | (c & d);
- else
- sha1_f = b ^ c ^ d;
- end
- endfunction
- ////FUNCTION FOR SHA1: sha1_k
- function logic [31:0] sha1_k(input logic [7:0] t);
- begin
- if (t <= 19)
- sha1_k = 32'h5a827999;
- else if (t <= 39)
- sha1_k = 32'h6ed9eba1;
- else if (t <= 59)
- sha1_k = 32'h8f1bbcdc;
- else
- sha1_k = 32'hca62c1d6;
- end
- endfunction
- //FUNCTION FOR SHA1: sha1_op
- function logic [159:0] sha1_op(input logic [31:0] a, b, c, d, e, w,
- input logic [7:0] t);
- logic [31:0] temp, tc; // internal signals
- begin
- temp = ((a << 5)|(a >> 27)) + sha1_f(t) + e + sha1_k(t) + w;
- tc = ((b << 30)|(b >> 2));
- sha1_op = {temp, a, tc, c, d};
- end
- endfunction
- /*---------------------------------------------------------------------------*/
- //SHA256 k constants
- parameter int sha256_k[0:63] = '{
- 32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5, 32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,
- 32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3, 32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,
- 32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc, 32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,
- 32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7, 32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,
- 32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13, 32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,
- 32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3, 32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,
- 32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5, 32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,
- 32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208, 32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2
- };
- //FUNCTION FOR SHA256: sha256_op
- /*function logic [255:0] sha256_op(input logic [31:0] a, b, c, d, e, f, g, h, w,
- input logic [7:0] t);
- logic [31:0] s1, s0, ch, maj, t1, t2;
- begin
- s1 = rightrotate(e, 6) ^ rightrotate(e, 11) ^ rightrotate(e, 25);
- ch = (e & f) ^ ((~e) & g);
- t1 = h + s1 + ch + sha256_k[t] + w;
- s0 = rightrotate(a, 2) ^ rightrotate(a, 13) ^ rightrotate(a, 22);
- maj = (a & b) ^ (a & c) ^ (b & c);
- t2 = s0 + maj;
- sha256_op = {t1 + t2, a, b, c, d + t1, e, f, g};
- end
- endfunction*/
- function logic [255:0] sha256_op(input logic [31:0] a, b, c, d, e, f, g, h, w,
- input logic [7:0] t);
- logic [31:0] s1, s0, ch, maj, t1, t2;
- begin
- s0 = rightrotate(a, 2) ^ rightrotate(a, 13) ^ rightrotate(a, 22);
- maj = (a & b) ^ (a & c) ^ (b & c);
- t2 = s0 + maj;
- s1 = rightrotate(e, 6) ^ rightrotate(e, 11) ^ rightrotate(e, 25);
- ch = (e & f) ^ ((~e) & g);
- t1 = h + s1 + ch + sha256_k[t] + w;
- sha256_op = {t1 + t2, a, b, c, d + t1, e, f, g};
- end
- endfunction
- /*===========================================================================*/
- always_ff @(posedge clk, negedge reset_n)
- begin
- if (!reset_n) begin
- done <= 0;
- state <= IDLE;
- end else begin
- case (state)
- IDLE: begin
- if (start) begin
- case (opcode)
- 2'b00: begin //MD5
- //Initialize h words
- h0 = 32'h67452301;
- h1 = 32'hefcdab89;
- h2 = 32'h98badcfe;
- h3 = 32'h10325476;
- h4 = 32'h00000000;
- h5 = 32'h00000000;
- h6 = 32'h00000000;
- h7 = 32'h00000000;
- //Initialize misc. variables
- tmax <= 64;
- wmax <= 5;
- end
- 2'b01: begin //SHA-1
- //Initialize H words
- h0 = 32'h67452301;
- h1 = 32'hEFCDAB89;
- h2 = 32'h98BADCFE;
- h3 = 32'h10325476;
- h4 = 32'hC3D2E1F0;
- h5 = 32'h00000000;
- h6 = 32'h00000000;
- h7 = 32'h00000000;
- //Initialize misc. variables
- tmax <= 80;
- wmax <= 5;
- end
- default: begin //SHA-256
- //Initialize words
- h0 = 32'h6a09e667;
- h1 = 32'hbb67ae85;
- h2 = 32'h3c6ef372;
- h3 = 32'ha54ff53a;
- h4 = 32'h510e527f;
- h5 = 32'h9b05688c;
- h6 = 32'h1f83d9ab;
- h7 = 32'h5be0cd19;
- //Initialize misc. variables
- tmax <= 64;
- wmax <= 7;
- end
- endcase
- //Set values for hashing
- a = h0;
- b = h1;
- c = h2;
- d = h3;
- e = h4;
- f = h5;
- g = h6;
- h = h7;
- //Initialize counters
- t <= 0;
- rc <= 0;
- wc <= 0;
- bc <= 0;
- //Initialize misc. variables
- //delim_block <= 0;
- //length <= size << 3;
- //Identifying how many words there are in message
- /*if (size % 4 == 0)
- count_words <= size / 4;
- else
- count_words <= (size + 3) / 4 - 1;*/
- case (size % 4)
- 0: count_words <= size / 4;
- 1: count_words <= (size + 3) / 4 - 1;
- 2: count_words <= (size + 2) / 4 - 1;
- 3: count_words <= (size + 1) / 4 - 1;
- endcase
- //Calculate number of blocks needed
- num_blocks <= determine_num_blocks(size);
- //Read
- mem_we <= 0;
- mem_addr <= message_addr;
- state <= BUFF_READ;
- end
- end
- BUFF_READ: begin
- if (bc < num_blocks)
- state <= READ;
- else begin
- case (opcode)
- 2'b00: md5_digest = {h0, h1, h2, h3};
- 2'b01: sha1_digest = {h0, h1, h2, h3, h4};
- default: sha256_digest = {h0, h1, h2, h3, h4, h5, h6, h7};
- endcase
- //Begin Write
- mem_we <= 1;
- mem_addr <= output_addr;
- case (opcode)
- 2'b00: mem_write_data = md5_digest[127 - 32 * wc -: 32];
- 2'b01: mem_write_data = sha1_digest[159 - 32 * wc -: 32];
- default: mem_write_data = sha256_digest[255 - 32 * wc -: 32];
- endcase
- state <= BUFF_WRITE;
- end
- end
- READ: begin
- if (count_words == 0) begin
- //Identify where to place the delimiter
- case (size % 4)
- 0: w[rc] = 32'h80000000;
- 1: w[rc] = (changeEndian(mem_read_data) & 32'hFF000000) | 32'h00800000;
- 2: w[rc] = (changeEndian(mem_read_data) & 32'hFFFF0000) | 32'h00008000;
- 3: w[rc] = (changeEndian(mem_read_data) & 32'hFFFFFF00) | 32'h00000080;
- endcase
- //Decrement count_words count
- count_words <= count_words - 1;
- //Increment rc
- rc <= rc + 1;
- end else if (count_words < 0 && rc < 16) begin
- //Reset value in w at rc
- w[rc] = 32'h00000000;
- //Decrement count_words count
- count_words <= count_words - 1;
- //Increment rc
- rc <= rc + 1;
- //Append length
- if (bc == num_blocks - 1 && (rc == 14 || rc == 15)) begin
- //w[14] = length >> 32;
- //w[15] = (length << 32) >> 32;
- w[14] = size >> 29;
- w[15] = size * 8;
- end
- end else if (rc < 16) begin
- //Change Endian of message
- w[rc] <= changeEndian(mem_read_data);
- //Increment rc
- rc <= rc + 1;
- //Read
- mem_we <= 0;
- mem_addr <= mem_addr + 1;
- //Decrementing word_read
- count_words <= count_words - 1;
- state <= BUFF_READ;
- end else begin
- //Done reading block
- rc <= 0;
- state <= COMPUTE;
- end
- end
- COMPUTE: begin
- if (t < tmax) begin
- //Changing w[t] values
- if (t >= 16) begin
- case (opcode)
- 2'b00: w[t] = w[md5_w(t)];
- 2'b01: w[t] = leftrotate(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
- default: begin
- s0 = rightrotate(w[t - 15], 7) ^ rightrotate(w[t - 15], 18) ^ (w[t - 15] >> 3);
- s1 = rightrotate(w[t - 2], 17) ^ rightrotate(w[t - 2], 19) ^ (w[t - 2] >> 10);
- w[t] = w[t - 16] + s0 + w[t - 7] + s1;
- end
- endcase
- end
- //Hashing
- case (opcode)
- 2'b00: begin
- {a, b, c, d} = md5_op(a, b, c, d, w[t], t);
- //$display("t: %d | w[t] = %h | a = %h | b = %h | c = %h | d = %h", t, w[t], a, b, c, d);
- end
- 2'b01: {a, b, c, d, e} = sha1_op(a, b, c, d, e, w[t], t);
- default: {a, b, c, d, e, f, g, h} = sha256_op(a, b, c, d, e, f, g, h, w[t], t);
- endcase
- //Increment t
- t = t + 1;
- state <= COMPUTE;
- end else begin
- //Update Results
- h0 = h0 + a;
- h1 = h1 + b;
- h2 = h2 + c;
- h3 = h3 + d;
- h4 = h4 + e;
- h5 = h5 + f;
- h6 = h6 + g;
- h7 = h7 + h;
- //Update a, b, c, d
- a = h0;
- b = h1;
- c = h2;
- d = h3;
- e = h4;
- f = h5;
- g = h6;
- h = h7;
- //Increment bc
- bc <= bc + 1;
- //Reset t
- t <= 0;
- state <= BUFF_READ;
- end
- end
- BUFF_WRITE: begin
- state <= WRITE;
- end
- WRITE: begin
- if (wc < wmax) begin
- //Increment wc
- wc = wc + 1;
- //Write
- mem_we = 1;
- mem_addr = mem_addr + 1;
- //Write to Output
- case (opcode)
- 2'b00: mem_write_data = md5_digest[127 - 32 * wc -: 32];
- 2'b01: mem_write_data = sha1_digest[159 - 32 * wc -: 32];
- default: mem_write_data = sha256_digest[255 - 32 * wc -: 32];
- endcase
- state <= BUFF_WRITE;
- end else begin
- done <= 1;
- state <= IDLE;
- end
- end
- endcase
- end
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement