Advertisement
Guest User

Untitled

a guest
Mar 20th, 2017
305
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module super_hash_processor(input logic clk, reset_n, start,
  2.                             input logic [1:0] opcode,
  3.                             input logic [31:0] message_addr, size, output_addr,
  4.                            output logic done, mem_clk, mem_we,
  5.                            output logic [15:0] mem_addr,
  6.                            output logic [31:0] mem_write_data,
  7.                             input logic [31:0] mem_read_data);
  8.    
  9.     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;
  10.  
  11.     assign mem_clk = clk;
  12.  
  13.     logic [31:0] h0, h1, h2, h3, h4, h5, h6, h7;
  14.     logic [31:0] a, b, c, d, e, f, g, h;
  15.     logic [31:0] w[0:79];
  16.     logic [31:0] s1, s0;
  17.  
  18.     logic [127:0] md5_digest;
  19.     logic [159:0] sha1_digest;
  20.     logic [255:0] sha256_digest;
  21.    
  22.     //logic [63:0] length;
  23.     logic [15:0] num_blocks;
  24.    
  25.     int count_words;
  26.     int t, rc, wc, bc, tmax, wmax;
  27.     //int delim_block;
  28.    
  29. /*===========================================================================*/
  30.  
  31.     //FUNCTION: changeEndian
  32.     function logic[31:0] changeEndian(input logic [31:0] value);
  33.         changeEndian = {value[7:0], value[15:8], value[23:16], value[31:24]};
  34.     endfunction
  35.    
  36.     //FUNCTION: determine_num_blocks
  37.     function logic [15:0] determine_num_blocks(input logic [31:0] size);
  38.         if ((size << 3) % 512 <= 447)
  39.             determine_num_blocks = ((size << 3) / 512) + 1;
  40.         else
  41.             determine_num_blocks = ((size << 3) / 512) + 2;
  42.     endfunction
  43.    
  44.     //FUNCTION: rightrotate
  45.     function logic [31:0] rightrotate(input logic [31:0] x,
  46.                                       input logic [7:0] r);
  47.     begin
  48.         rightrotate = (x >> r) | (x << (32 - r));
  49.     end
  50.     endfunction
  51.    
  52.     //FUNCTION: leftrotate
  53.     function logic [31:0] leftrotate(input logic [31:0] x);
  54.     begin
  55.         leftrotate = (x << 1) | (x >> 31);
  56.     end
  57.     endfunction
  58.  
  59. /*---------------------------------------------------------------------------*/
  60.  
  61.     //MD5 s constants
  62.     /*parameter byte md5_s[0:63] = '{
  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,
  64.         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,
  65.         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,
  66.         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
  67.     };*/
  68.    
  69.     parameter byte md5_s[0:15] = '{
  70.         8'd7, 8'd12, 8'd17, 8'd22,
  71.         8'd5, 8'd9, 8'd14, 8'd20,
  72.         8'd4, 8'd11, 8'd16, 8'd23,
  73.         8'd6, 8'd10, 8'd15, 8'd21
  74.     };
  75.    
  76.     //FUNCTION FOR MD5: md5_getS
  77.     function logic [31:0] md5_getS(input logic [5:0] t);
  78.         logic [3:0] i;
  79.         i = {t[5:4], t[1:0]};
  80.         return md5_s[i];
  81.     endfunction
  82.  
  83.     //MD5 k constants
  84.     parameter int md5_k[0:63] = '{
  85.         32'hd76aa478, 32'he8c7b756, 32'h242070db, 32'hc1bdceee,
  86.         32'hf57c0faf, 32'h4787c62a, 32'ha8304613, 32'hfd469501,
  87.         32'h698098d8, 32'h8b44f7af, 32'hffff5bb1, 32'h895cd7be,
  88.         32'h6b901122, 32'hfd987193, 32'ha679438e, 32'h49b40821,
  89.         32'hf61e2562, 32'hc040b340, 32'h265e5a51, 32'he9b6c7aa,
  90.         32'hd62f105d, 32'h02441453, 32'hd8a1e681, 32'he7d3fbc8,
  91.         32'h21e1cde6, 32'hc33707d6, 32'hf4d50d87, 32'h455a14ed,
  92.         32'ha9e3e905, 32'hfcefa3f8, 32'h676f02d9, 32'h8d2a4c8a,
  93.         32'hfffa3942, 32'h8771f681, 32'h6d9d6122, 32'hfde5380c,
  94.         32'ha4beea44, 32'h4bdecfa9, 32'hf6bb4b60, 32'hbebfbc70,
  95.         32'h289b7ec6, 32'heaa127fa, 32'hd4ef3085, 32'h04881d05,
  96.         32'hd9d4d039, 32'he6db99e5, 32'h1fa27cf8, 32'hc4ac5665,
  97.         32'hf4292244, 32'h432aff97, 32'hab9423a7, 32'hfc93a039,
  98.         32'h655b59c3, 32'h8f0ccc92, 32'hffeff47d, 32'h85845dd1,
  99.         32'h6fa87e4f, 32'hfe2ce6e0, 32'ha3014314, 32'h4e0811a1,
  100.         32'hf7537e82, 32'hbd3af235, 32'h2ad7d2bb, 32'heb86d391
  101.     };
  102.  
  103.     //FUNCTION FOR MD5: md5_w
  104.     function logic [3:0] md5_w(input logic [7:0] t);
  105.     begin
  106.         if (t <= 15)
  107.             md5_w = t;
  108.         else if (t <= 31)
  109.             md5_w = (5 * t + 1) % 16;
  110.         else if (t <= 47)
  111.             md5_w = (3 * t + 5) % 16;
  112.         else
  113.             md5_w = (7 * t) % 16;
  114.     end
  115.     endfunction
  116.    
  117.     //FUNCTION FOR MD5: md5_f
  118.     function logic [31:0] md5_f(input logic [7:0] t);
  119.     begin
  120.         if (t <= 15)
  121.             md5_f = (b & c) | ((~b) & d);
  122.         else if (t <= 31)
  123.             md5_f = (d & b) | ((~d) & c);
  124.         else if (t <= 47)
  125.             md5_f = b ^ c ^ d;
  126.         else
  127.             md5_f = c ^ (b | (~d));
  128.     end
  129.     endfunction
  130.    
  131.     //FUNCTION FOR MD5: md5_op
  132.     function logic [127:0] md5_op(input logic [31:0] a, b, c, d, w,
  133.                                   input logic [7:0] t);
  134.         logic [31:0] temp1, temp2;
  135.     begin
  136.         temp1 = a + md5_f(t) + md5_k[t] + w;
  137.         //temp2 = b + ((temp1 << md5_s[t]) | (temp1 >> (32 - md5_s[t])));
  138.         temp2 = b + ((temp1 << md5_getS(t)) | (temp1 >> (32 - md5_getS(t))));
  139.         md5_op = {d, temp2, b, c};
  140.     end
  141.     endfunction
  142.  
  143. /*---------------------------------------------------------------------------*/
  144.    
  145.     //FUNCTION FOR SHA1: sha1_f
  146.     function logic [31:0] sha1_f(input logic [7:0] t);
  147.     begin
  148.        if (t <= 19)
  149.            sha1_f = (b & c) | ((~b) & d);
  150.        else if (t <= 39)
  151.            sha1_f = b ^ c ^ d;
  152.        else if (t <= 59)
  153.            sha1_f = (b & c) | (b & d) | (c & d);
  154.        else
  155.            sha1_f = b ^ c ^ d;
  156.     end
  157.     endfunction
  158.  
  159.     ////FUNCTION FOR SHA1: sha1_k
  160.     function logic [31:0] sha1_k(input logic [7:0] t);
  161.     begin
  162.        if (t <= 19)
  163.            sha1_k = 32'h5a827999;
  164.        else if (t <= 39)
  165.            sha1_k = 32'h6ed9eba1;
  166.        else if (t <= 59)
  167.            sha1_k = 32'h8f1bbcdc;
  168.        else
  169.            sha1_k = 32'hca62c1d6;
  170.     end
  171.     endfunction
  172.  
  173.     //FUNCTION FOR SHA1: sha1_op
  174.     function logic [159:0] sha1_op(input logic [31:0] a, b, c, d, e, w,
  175.                                    input logic [7:0] t);
  176.        logic [31:0] temp, tc; // internal signals
  177.     begin
  178.        temp = ((a << 5)|(a >> 27)) + sha1_f(t) + e + sha1_k(t) + w;
  179.        tc = ((b << 30)|(b >> 2));
  180.        sha1_op = {temp, a, tc, c, d};
  181.     end
  182.     endfunction
  183.  
  184. /*---------------------------------------------------------------------------*/
  185.  
  186.     //SHA256 k constants
  187.     parameter int sha256_k[0:63] = '{
  188.         32'h428a2f98, 32'h71374491, 32'hb5c0fbcf, 32'he9b5dba5, 32'h3956c25b, 32'h59f111f1, 32'h923f82a4, 32'hab1c5ed5,
  189.         32'hd807aa98, 32'h12835b01, 32'h243185be, 32'h550c7dc3, 32'h72be5d74, 32'h80deb1fe, 32'h9bdc06a7, 32'hc19bf174,
  190.         32'he49b69c1, 32'hefbe4786, 32'h0fc19dc6, 32'h240ca1cc, 32'h2de92c6f, 32'h4a7484aa, 32'h5cb0a9dc, 32'h76f988da,
  191.         32'h983e5152, 32'ha831c66d, 32'hb00327c8, 32'hbf597fc7, 32'hc6e00bf3, 32'hd5a79147, 32'h06ca6351, 32'h14292967,
  192.         32'h27b70a85, 32'h2e1b2138, 32'h4d2c6dfc, 32'h53380d13, 32'h650a7354, 32'h766a0abb, 32'h81c2c92e, 32'h92722c85,
  193.         32'ha2bfe8a1, 32'ha81a664b, 32'hc24b8b70, 32'hc76c51a3, 32'hd192e819, 32'hd6990624, 32'hf40e3585, 32'h106aa070,
  194.         32'h19a4c116, 32'h1e376c08, 32'h2748774c, 32'h34b0bcb5, 32'h391c0cb3, 32'h4ed8aa4a, 32'h5b9cca4f, 32'h682e6ff3,
  195.         32'h748f82ee, 32'h78a5636f, 32'h84c87814, 32'h8cc70208, 32'h90befffa, 32'ha4506ceb, 32'hbef9a3f7, 32'hc67178f2
  196.     };
  197.  
  198.     //FUNCTION FOR SHA256: sha256_op
  199.     /*function logic [255:0] sha256_op(input logic [31:0] a, b, c, d, e, f, g, h, w,
  200.                                      input logic [7:0] t);
  201.         logic [31:0] s1, s0, ch, maj, t1, t2;
  202.     begin
  203.         s1 = rightrotate(e, 6) ^ rightrotate(e, 11) ^ rightrotate(e, 25);
  204.         ch = (e & f) ^ ((~e) & g);
  205.         t1 = h + s1 + ch + sha256_k[t] + w;
  206.         s0 = rightrotate(a, 2) ^ rightrotate(a, 13) ^ rightrotate(a, 22);
  207.         maj = (a & b) ^ (a & c) ^ (b & c);
  208.         t2 = s0 + maj;
  209.    
  210.         sha256_op = {t1 + t2, a, b, c, d + t1, e, f, g};
  211.     end
  212.     endfunction*/
  213.    
  214.     function logic [255:0] sha256_op(input logic [31:0] a, b, c, d, e, f, g, h, w,
  215.                                      input logic [7:0] t);
  216.         logic [31:0] s1, s0, ch, maj, t1, t2;
  217.     begin
  218.         s0 = rightrotate(a, 2) ^ rightrotate(a, 13) ^ rightrotate(a, 22);
  219.         maj = (a & b) ^ (a & c) ^ (b & c);
  220.         t2 = s0 + maj;
  221.         s1 = rightrotate(e, 6) ^ rightrotate(e, 11) ^ rightrotate(e, 25);
  222.         ch = (e & f) ^ ((~e) & g);
  223.         t1 = h + s1 + ch + sha256_k[t] + w;
  224.    
  225.         sha256_op = {t1 + t2, a, b, c, d + t1, e, f, g};
  226.     end
  227.     endfunction
  228.  
  229. /*===========================================================================*/
  230.    
  231.     always_ff @(posedge clk, negedge reset_n)
  232.     begin
  233.         if (!reset_n) begin
  234.             done <= 0;
  235.             state <= IDLE;
  236.         end else begin
  237.             case (state)
  238.                 IDLE: begin
  239.                     if (start) begin
  240.                         case (opcode)
  241.                             2'b00: begin //MD5
  242.                                 //Initialize h words
  243.                                 h0 = 32'h67452301;
  244.                                 h1 = 32'hefcdab89;
  245.                                 h2 = 32'h98badcfe;
  246.                                 h3 = 32'h10325476;
  247.                                 h4 = 32'h00000000;
  248.                                 h5 = 32'h00000000;
  249.                                 h6 = 32'h00000000;
  250.                                 h7 = 32'h00000000;
  251.      
  252.                                 //Initialize misc. variables
  253.                                 tmax <= 64;
  254.                                 wmax <= 5;
  255.                             end
  256.                             2'b01: begin //SHA-1
  257.                                 //Initialize H words
  258.                                 h0 = 32'h67452301;
  259.                                 h1 = 32'hEFCDAB89;
  260.                                 h2 = 32'h98BADCFE;
  261.                                 h3 = 32'h10325476;
  262.                                 h4 = 32'hC3D2E1F0;
  263.                                 h5 = 32'h00000000;
  264.                                 h6 = 32'h00000000;
  265.                                 h7 = 32'h00000000;
  266.      
  267.                                 //Initialize misc. variables
  268.                                 tmax <= 80;
  269.                                 wmax <= 5;
  270.                             end
  271.                             default: begin //SHA-256
  272.                                 //Initialize words
  273.                                 h0 = 32'h6a09e667;
  274.                                 h1 = 32'hbb67ae85;
  275.                                 h2 = 32'h3c6ef372;
  276.                                 h3 = 32'ha54ff53a;
  277.                                 h4 = 32'h510e527f;
  278.                                 h5 = 32'h9b05688c;
  279.                                 h6 = 32'h1f83d9ab;
  280.                                 h7 = 32'h5be0cd19;
  281.                                
  282.                                 //Initialize misc. variables
  283.                                 tmax <= 64;
  284.                                 wmax <= 7;
  285.                             end
  286.                         endcase
  287.                        
  288.                         //Set values for hashing
  289.                         a = h0;
  290.                         b = h1;
  291.                         c = h2;
  292.                         d = h3;
  293.                         e = h4;
  294.                         f = h5;
  295.                         g = h6;
  296.                         h = h7;
  297.  
  298.                         //Initialize counters
  299.                         t <= 0;
  300.                         rc <= 0;
  301.                         wc <= 0;
  302.                         bc <= 0;
  303.                        
  304.                         //Initialize misc. variables
  305.                         //delim_block <= 0;
  306.                         //length <= size << 3;
  307.                        
  308.                         //Identifying how many words there are in message
  309.                         /*if (size % 4 == 0)
  310.                             count_words <= size / 4;
  311.                         else
  312.                             count_words <= (size + 3) / 4 - 1;*/
  313.                            
  314.                         case (size % 4)
  315.                             0: count_words <= size / 4;
  316.                             1: count_words <= (size + 3) / 4 - 1;
  317.                             2: count_words <= (size + 2) / 4 - 1;
  318.                             3: count_words <= (size + 1) / 4 - 1;
  319.                         endcase
  320.                        
  321.                         //Calculate number of blocks needed
  322.                         num_blocks <= determine_num_blocks(size);
  323.                        
  324.                         //Read
  325.                         mem_we <= 0;
  326.                         mem_addr <= message_addr;
  327.                        
  328.                         state <= BUFF_READ;
  329.                     end
  330.                 end
  331.                 BUFF_READ: begin
  332.                     if (bc < num_blocks)
  333.                         state <= READ;
  334.                     else begin
  335.                         case (opcode)
  336.                             2'b00: md5_digest = {h0, h1, h2, h3};
  337.                             2'b01: sha1_digest = {h0, h1, h2, h3, h4};
  338.                             default: sha256_digest = {h0, h1, h2, h3, h4, h5, h6, h7};
  339.                         endcase
  340.                        
  341.                         //Begin Write
  342.                         mem_we <= 1;
  343.                         mem_addr <= output_addr;
  344.                        
  345.                         case (opcode)
  346.                             2'b00: mem_write_data = md5_digest[127 - 32 * wc -: 32];
  347.                             2'b01: mem_write_data = sha1_digest[159 - 32 * wc -: 32];
  348.                             default: mem_write_data = sha256_digest[255 - 32 * wc -: 32];
  349.                         endcase
  350.                        
  351.                         state <= BUFF_WRITE;
  352.                     end
  353.                 end
  354.                 READ: begin
  355.                     if (count_words == 0) begin
  356.                         //Identify where to place the delimiter
  357.                         case (size % 4)
  358.                             0: w[rc] = 32'h80000000;
  359.                             1: w[rc] = (changeEndian(mem_read_data) & 32'hFF000000) | 32'h00800000;
  360.                             2: w[rc] = (changeEndian(mem_read_data) & 32'hFFFF0000) | 32'h00008000;
  361.                             3: w[rc] = (changeEndian(mem_read_data) & 32'hFFFFFF00) | 32'h00000080;
  362.                         endcase
  363.  
  364.                         //Decrement count_words count
  365.                         count_words <= count_words - 1;
  366.  
  367.                         //Increment rc
  368.                         rc <= rc + 1;
  369.                     end else if (count_words < 0 && rc < 16) begin
  370.                         //Reset value in w at rc
  371.                         w[rc] = 32'h00000000;
  372.  
  373.                         //Decrement count_words count
  374.                         count_words <= count_words - 1;
  375.  
  376.                         //Increment rc
  377.                         rc <= rc + 1;
  378.  
  379.                         //Append length
  380.                         if (bc == num_blocks - 1 && (rc == 14 || rc == 15)) begin
  381.                             //w[14] = length >> 32;
  382.                             //w[15] = (length << 32) >> 32;
  383.                             w[14] = size >> 29;
  384.                             w[15] = size * 8;
  385.                         end
  386.                     end else if (rc < 16) begin
  387.                         //Change Endian of message
  388.                         w[rc] <= changeEndian(mem_read_data);
  389.  
  390.                         //Increment rc
  391.                         rc <= rc + 1;
  392.  
  393.                         //Read
  394.                         mem_we <= 0;
  395.                         mem_addr <= mem_addr + 1;
  396.  
  397.                         //Decrementing word_read
  398.                         count_words <= count_words - 1;
  399.  
  400.                         state <= BUFF_READ;
  401.                     end else begin
  402.                         //Done reading block
  403.                         rc <= 0;
  404.  
  405.                         state <= COMPUTE;
  406.                     end
  407.                 end
  408.                 COMPUTE: begin
  409.                     if (t < tmax) begin
  410.                         //Changing w[t] values
  411.                         if (t >= 16) begin
  412.                             case (opcode)
  413.                                 2'b00: w[t] = w[md5_w(t)];
  414.                                 2'b01: w[t] = leftrotate(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16]);
  415.                                 default: begin
  416.                                     s0 = rightrotate(w[t - 15], 7) ^ rightrotate(w[t - 15], 18) ^ (w[t - 15] >> 3);
  417.                                     s1 = rightrotate(w[t - 2], 17) ^ rightrotate(w[t - 2], 19) ^ (w[t - 2] >> 10);
  418.                                     w[t] = w[t - 16] + s0 + w[t - 7] + s1;
  419.                                 end
  420.                             endcase
  421.                         end
  422.  
  423.                         //Hashing
  424.                         case (opcode)
  425.                             2'b00: begin
  426.                                 {a, b, c, d} = md5_op(a, b, c, d, w[t], t);
  427.                                 //$display("t: %d | w[t] = %h | a = %h | b = %h | c = %h | d = %h", t, w[t], a, b, c, d);
  428.                             end
  429.                             2'b01: {a, b, c, d, e} = sha1_op(a, b, c, d, e, w[t], t);
  430.                             default: {a, b, c, d, e, f, g, h} = sha256_op(a, b, c, d, e, f, g, h, w[t], t);
  431.                         endcase
  432.  
  433.                         //Increment t
  434.                         t = t + 1;
  435.  
  436.                         state <= COMPUTE;
  437.                     end else begin
  438.                         //Update Results
  439.                         h0 = h0 + a;
  440.                         h1 = h1 + b;
  441.                         h2 = h2 + c;
  442.                         h3 = h3 + d;
  443.                         h4 = h4 + e;
  444.                         h5 = h5 + f;
  445.                         h6 = h6 + g;
  446.                         h7 = h7 + h;
  447.                    
  448.                         //Update a, b, c, d
  449.                         a = h0;
  450.                         b = h1;
  451.                         c = h2;
  452.                         d = h3;
  453.                         e = h4;
  454.                         f = h5;
  455.                         g = h6;
  456.                         h = h7;
  457.                        
  458.                         //Increment bc
  459.                         bc <= bc + 1;
  460.                        
  461.                         //Reset t
  462.                         t <= 0;
  463.  
  464.                         state <= BUFF_READ;
  465.                     end
  466.                 end
  467.                 BUFF_WRITE: begin
  468.                     state <= WRITE;
  469.                 end
  470.                 WRITE: begin
  471.                     if (wc < wmax) begin
  472.                         //Increment wc
  473.                         wc = wc + 1;
  474.  
  475.                         //Write
  476.                         mem_we = 1;
  477.                         mem_addr = mem_addr + 1;
  478.  
  479.                         //Write to Output
  480.                         case (opcode)
  481.                             2'b00: mem_write_data = md5_digest[127 - 32 * wc -: 32];
  482.                             2'b01: mem_write_data = sha1_digest[159 - 32 * wc -: 32];
  483.                             default: mem_write_data = sha256_digest[255 - 32 * wc -: 32];
  484.                         endcase
  485.  
  486.                         state <= BUFF_WRITE;
  487.                     end else begin
  488.                         done <= 1;
  489.                         state <= IDLE;
  490.                     end
  491.                 end
  492.             endcase
  493.         end
  494.     end
  495. endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement