Đường ống MD5 VHDL


10

Tôi đang cố gắng thực hiện một đường ống MD5 3 giai đoạn theo liên kết này . Cụ thể là algoritms trên trang 31. Ngoài ra còn có một tài liệu khác mô tả chuyển tiếp dữ liệu. Điều này được thực hiện trong một đồ họa (Terasic DE2-115). Không có sơ đồ trong dự án này, chỉ có mã VHDL.

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity md5core is
    port (
        CLOCK_50        : in std_logic;
        SW              : in std_logic_vector(17 downto 17)
    );
end entity md5core;

architecture md5core_rtl of md5core is
type r_array is array(0 to 64) of std_logic_vector(7 downto 0);
constant R        : r_array := ( x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", x"16", x"07", x"0c", x"11", 
                                 x"16", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09", x"0e", x"14", x"05", x"09",
                                 x"0e", x"14", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04", x"0b", x"10", x"17", x"04",
                                 x"0b", x"10", x"17", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15", x"06", x"0a", x"0f", x"15",
                                 x"06", x"0a", x"0f", x"15", others => x"00");

type k_array is array(0 to 66) of std_logic_vector(31 downto 0);
constant K        : k_array := (x"d76aa478", x"e8c7b756", x"242070db", x"c1bdceee",
                                x"f57c0faf", x"4787c62a", x"a8304613", x"fd469501",
                                x"698098d8", x"8b44f7af", x"ffff5bb1", x"895cd7be",
                                x"6b901122", x"fd987193", x"a679438e", x"49b40821", 
                                x"f61e2562", x"c040b340", x"265e5a51", x"e9b6c7aa",
                                x"d62f105d", x"02441453", x"d8a1e681", x"e7d3fbc8",
                                x"21e1cde6", x"c33707d6", x"f4d50d87", x"455a14ed",
                                x"a9e3e905", x"fcefa3f8", x"676f02d9", x"8d2a4c8a",
                                x"fffa3942", x"8771f681", x"6d9d6122", x"fde5380c",
                                x"a4beea44", x"4bdecfa9", x"f6bb4b60", x"bebfbc70",
                                x"289b7ec6", x"eaa127fa", x"d4ef3085", x"04881d05",
                                x"d9d4d039", x"e6db99e5", x"1fa27cf8", x"c4ac5665",
                                x"f4292244", x"432aff97", x"ab9423a7", x"fc93a039",
                                x"655b59c3", x"8f0ccc92", x"ffeff47d", x"85845dd1",
                                x"6fa87e4f", x"fe2ce6e0", x"a3014314", x"4e0811a1",
                                x"f7537e82", x"bd3af235", x"2ad7d2bb", x"eb86d391", others => x"00000000");

type g_array is array(0 to 64) of integer range 0 to 15;
constant g_arr      : g_array := (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
                                          1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
                                          5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
                                          0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, 0);                                               

type w_array is array(0 to 15) of std_logic_vector(31 downto 0);
signal W            : w_array;

constant AA        : std_logic_vector(31 downto 0) := x"67452301";
constant BB        : std_logic_vector(31 downto 0) := x"EFCDAB89";
constant CC        : std_logic_vector(31 downto 0) := x"98BADCFE";
constant DD        : std_logic_vector(31 downto 0) := x"10325476";

signal res_A    : std_logic_vector(31 downto 0) := x"00000000";
signal res_B    : std_logic_vector(31 downto 0) := x"00000000";
signal res_C    : std_logic_vector(31 downto 0) := x"00000000";
signal res_D    : std_logic_vector(31 downto 0) := x"00000000";

type in_str_t is array(0 to 5) of std_logic_vector(7 downto 0);
constant in_str    : in_str_t := (x"68", x"65", x"6c", x"6c", x"6f", x"6f");

type pad_str_t    is array(0 to 63) of std_logic_vector(7 downto 0);
signal pad_str    : pad_str_t;

type state_t is (start, padding, init_w, state_1, state_2, state_3, state_4, done);
signal state    : state_t;

signal a, b, c, d, f    : std_logic_vector(31 downto 0) := x"00000000";
signal i                : integer range 0 to 64 := 0;
signal g                        : integer range 0 to 15 := 0;
--signal tmp_b              : std_logic_vector(31 downto 0);

signal akw                  : std_logic_vector(31 downto 0);
signal ak                   : std_logic_vector(31 downto 0);
signal b_tmp                : std_logic_vector(31 downto 0);
begin

    --tmp_b <= std_logic_vector(unsigned(b) + rotate_left(unsigned(a) + unsigned(f) + unsigned(K(i)) + unsigned(W(g)), to_integer(unsigned(R(i)))));

    pipe_p : process(CLOCK_50, SW, a, b, c, d, i)
    begin
        if SW(17) = '0' then
--          ak <= std_logic_vector(unsigned(K(2)) + unsigned(BB));
--          akw <= std_logic_vector(unsigned(W(0)) + 1 + unsigned(K(2)) + unsigned(BB));
            b_tmp <= BB;
        elsif rising_edge(CLOCK_50) and state = state_1 then
            if i = 0 then
                ak <= std_logic_vector(unsigned(K(0)) + unsigned(a));
            elsif i = 1 then
                ak <= std_logic_vector(unsigned(K(1)) + unsigned(a));
                akw <= std_logic_vector(unsigned(W(0)) + unsigned(ak));
            elsif i = 2 then
                ak <= std_logic_vector(unsigned(K(2)) + unsigned(a));
                akw <= std_logic_vector(unsigned(W(1)) + unsigned(ak));
                b_tmp <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(0))))));
            else
                ak <= std_logic_vector(unsigned(K(i)) + unsigned(a));
                akw <= std_logic_vector(unsigned(W(g_arr(i-1))) + unsigned(ak));
                b_tmp <= std_logic_vector(unsigned(b) + (rotate_left(unsigned(akw) + unsigned(f), to_integer(unsigned(R(i-2))))));
            end if;
        end if;
    end process pipe_p;


    md5_f_p : process(state, a, b, c, d, i)
    begin 
        case state is
            when state_1 =>
                if i = 0 or i > 4 then
                    f <= (b and c) or ((not b) and d);
                    g <= g_arr(i);
                end if;

            when state_2 =>
            f <= (d and b) or ((not d) and c);
                g <= g_arr(i);

            when state_3 =>
                f <= b xor c xor d;
            g <= g_arr(i);

            when state_4 =>
                f <= c xor (b or (not d));
            g <= g_arr(i);

            when others =>
                f <= x"00000000";
                g <= 0;             

        end case;
    end process md5_f_p;

     md5_p : process(CLOCK_50, SW, a, b, c, d, f, g)
     begin
        if SW(17) = '0' then
            state <= start;
                i <= 0;
                a <= AA;
            b <= BB;
            c <= CC;
            d <= DD;                
            W <= (others => x"00000000");
                pad_str <= (others => x"00");
                --tmp_b := BB;
        elsif rising_edge(CLOCK_50) then
            case state is            
                when start =>

                    pad_str(0) <= in_str(0);
                    pad_str(1) <= in_str(1);
                    pad_str(2) <= in_str(2);
                    pad_str(3) <= in_str(3);
                    pad_str(4) <= in_str(4);
                    pad_str(5) <= in_str(5);
                    state <= padding;

                when padding =>
                    pad_str(6) <= "10000000";
                    pad_str(56) <= std_logic_vector(to_unsigned(in_str'length*8, 8));
                          state <= init_w;

                when init_w =>                
                    W(0) <= pad_str(3) & pad_str(2) & pad_str(1) & pad_str(0);
                    W(1) <= pad_str(7) & pad_str(6) & pad_str(5) & pad_str(4);
                    W(14) <= pad_str(59) & pad_str(58) & pad_str(57) & pad_str(56);
                          state <= state_1;

                when state_1 =>
                          if i = 16 then
                              state <= state_2;
                          else 
                        if i > 2 then
                                    --tmp_b := b;
                                    a <= d;
                                    c <= b;
                                    d <= c;
                                    b <= b_tmp;

--                                  d <= c;
--                                  b <= b_tmp;
--                                  c <= b;
--                                  a <= d;
                                end if;
                                i <= i + 1;
                    end if;

                when state_2 =>
                    if i = 32 then
                        state <= state_3;
                          else                  
                        d <= c;
                        b <= b_tmp;
                                c <= b;
                        a <= d;
                        i <= i + 1;
                    end if;

                when state_3 =>
                    if i = 48 then
                                state <= state_4;
                          else
                        d <= c;
                        b <= b_tmp;
                                c <= b;
                        a <= d;
                        i <= i + 1;
                    end if;

                when state_4 =>
                    if i = 64 then
                                res_A <= std_logic_vector(unsigned(AA) + unsigned(a));
                                res_B <= std_logic_vector(unsigned(BB) + unsigned(b));
                                res_C <= std_logic_vector(unsigned(CC) + unsigned(c));
                                res_D <= std_logic_vector(unsigned(DD) + unsigned(d));
                                state <= done;
                    else
                        d <= c;
                        c <= b;
                                b <= b_tmp;
                        a <= d;
                        i <= i + 1;
                    end if;

                when done =>
                    state <= done;

                when others =>
                    state <= done;

            end case;
        end if;
    end process md5_p;
end architecture md5core_rtl;

Sử dụng mã này, tôi nhận được các giá trị chính xác btrong giai đoạn đầu tiên của vòng 0, nhưng sau đó dường như không có gì phù hợp. Như đã thấy trong mô phỏng này, giai đoạn đầu tiên trong vòng 0 là chính xác, nhưng sau đó thì không. Đây là khi sử dụng atrong biểu thức này:

ak <= std_logic_vector(unsigned(K(0)) + unsigned(a)); -- using a

mô phỏng

Nhưng ... Nếu tôi hiểu đúng tài liệu thứ hai, tôi nên sử dụng cthay vì a(chuyển tiếp dữ liệu), nhưng sau đó, giai đoạn đầu tiên trong vòng 0 cũng không hoạt động. Tức là khi tôi làm điều này, giai đoạn đầu tiên trong vòng 0 cũng nhận được những con số sai.

ak <= std_logic_vector(unsigned(K(0)) + unsigned(c)); -- changed to c

Đối với chuỗi cụ thể trong mã ( helloo), các giá trị sau là chính xác (3 giai đoạn đầu của vòng 0).

i:0 => a:271733878, b:3679623978, c:4023233417, d:2562383102, f:2562383102, g:0
i:1 => a:2562383102, b:268703616, c:3679623978, d:4023233417, f:3421032412, g:1
i:2 => a:4023233417, b:566857930, c:268703616, d:3679623978, f:4291410697, g:2

Nhân tiện, AKMtrong tài liệu là akwtrong mã.

Bất kỳ lời khuyên hoặc đề xuất về việc đưa tôi đi đúng hướng sẽ được đánh giá rất cao. Mã sẽ là lý tưởng. Nếu có gì đó không rõ ràng, tôi sẽ chỉnh sửa câu hỏi và cố gắng khắc phục điều đó.


Bạn đang làm điều đó với một vi điều khiển? Loại nào? Thiết lập của bạn là gì? Sơ đồ? Vui lòng cung cấp thêm thông tin :-)

Tôi đã thêm một số thông tin, xin vui lòng cho tôi biết nếu tôi có thể cải thiện thêm.
JGR

Tôi không nghĩ bạn hoàn toàn hiểu những gì bạn yêu cầu ở đây. Có vẻ như bạn không thực sự quen thuộc với việc xây dựng các đường ống và các vấn đề liên quan như xử lý các phụ thuộc dữ liệu giữa các giai đoạn và có được các giai đoạn được khởi tạo đúng cách. Dạy bạn rằng sẽ cần một cuốn sách, không phải một trang web. Và tôi nghi ngờ rằng bất cứ ai đã thực hiện một cách thực hiện thuật toán này sẽ chỉ cung cấp miễn phí cho bạn. Sở hữu trí tuệ như thế có giá trị thực sự.
Dave Tweed

Đủ công bằng. Bạn tất nhiên là đúng. Tôi không quen thuộc với việc xây dựng đường ống, chỉ có 6 tháng kinh nghiệm với VHDL. Thành thật mà nói tôi cũng không hy vọng gì nhiều, nhưng khi bạn bế tắc, yêu cầu giúp đỡ luôn có vẻ là một lựa chọn tốt.
JGR

Câu trả lời:


5

Tôi nghĩ rằng bạn đã hiểu nhầm ý kiến ​​của tác giả bài báo về việc sắp xếp thuật toán. Bạn không thể chỉ đường ống tính toán cho B mà không cần đường ống cho phần còn lại của quá trình.

Tôi muốn giới thiệu, với mục đích bắt đầu, bạn nên quên hoàn toàn cách tiếp cận đường ống và chỉ cần làm cho thuật toán hoạt động với việc thực hiện tính toán B không theo đường ống.

Khi bạn nhận được kết quả chính xác và nếu bạn cần hiệu suất cao hơn, thì bạn có thể xem xét đường ống dẫn nó. Sau đó, bạn sẽ có thể xem kết quả trung gian xếp hàng trên mỗi chu kỳ đồng hồ và những gì cần thiết để giữ chúng đồng bộ.


Cảm ơn câu trả lời của bạn. Tôi đã có một phiên bản không hoạt động, và việc nắm giữ liên quan đến f (max) là tính toán của b. Theo tôi hiểu, mặc dù việc tính toán b sẽ là đủ, nhưng tôi đoán tôi sẽ phải đọc nó (một lần nữa).
JGR

Bi1Ai+2Mi+1Mi+1

Cảm ơn bạn! Tôi đã đọc lại nó một lần nữa, khi bạn đề cập rằng tôi không thể chỉ đường ống b, ý bạn là họ gọi chuyển tiếp dữ liệu trong bài báo là Agì?
JGR

Ai+2Ci

Ok, AKthực sự là như vậy CK. Điều này ngày càng phức tạp hơn: /
jgr
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.