MD5 VHDL 파이프 라인


10

이 링크 에 따라 3 단계 MD5 파이프 라인을 구현하려고합니다 . 특히 31 페이지의 알고리즘 . 데이터 전달을 설명하는 다른 문서 도 있습니다 . 이것은 FPGA (Terasic DE2-115)에서 수행됩니다. 이 프로젝트에는 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;

이 코드를 사용하면 b라운드 0의 첫 번째 단계에서 올바른 값을 얻지 만 그 이후에는 아무것도 맞지 않는 것 같습니다. 이 시뮬레이션에서 볼 수 있듯이 라운드 0의 첫 번째 단계는 정확하지만 그 이후에는 그렇지 않습니다. 이 a표현식에서 사용할 때입니다 .

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

시뮬레이션

그러나 ... 두 번째 문서를 올바르게 이해하면 (데이터 전달) c대신 사용해야합니다 a. 그러나 라운드 0의 첫 번째 단계는 작동하지 않습니다. 즉, 이것을하면 라운드 0의 첫 번째 단계에서도 잘못된 숫자를 얻습니다.

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

코드의 특정 문자열 ( helloo)에 대해 다음 값이 정확합니다 (처음 0의 3 단계).

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

그건 그렇고, AKM문서 akw에는 코드가 있습니다.

나를 올바른 방향으로 인도하는 데 대한 조언이나 제안은 대단히 감사하겠습니다. 코드가 이상적입니다. 확실치 않은 부분이 있으면 질문을 수정하고 수정하려고합니다.


마이크로 컨트롤러로 그렇게하고 있습니까? 어떤 종류? 당신의 설정은 무엇입니까? 회로도? 자세한 정보를 제공하십시오 :-)

더 많은 정보를 추가했습니다. 더 개선 할 수 있는지 알려주십시오.
jgr

나는 당신이 여기에서 요구하는 것을 완전히 이해하지 못한다고 생각합니다. 파이프 라인 구축과 단계 간의 데이터 종속성 처리 및 단계를 올바르게 초기화하는 것과 같은 관련 문제에 익숙하지 않은 것 같습니다. 웹 페이지가 아닌 책이 필요한 교육. 그리고 이미이 알고리즘의 파이프 라인 구현을 한 사람이라면 누구나 무료로 알고리즘을 제공 할 것입니다. 이와 같은 지적 재산은 실제 가치가 있습니다.
Dave Tweed 님이

그럴 수 있지. 물론 그렇습니다. 저는 파이프 라인 구축에 익숙하지 않고 VHDL에 대한 경험이 6 개월 밖에 없습니다. 솔직히 말해서 나는 많은 것을 기대하지 않았지만 도움을 요구할 때 항상 좋은 옵션처럼 보입니다.
jgr

답변:


5

알고리즘을 파이프 라이닝하는 것에 대한 논문의 저자의 의견을 오해했다고 생각합니다. 나머지 프로세스를 파이프 라이닝하지 않고 B에 대한 계산을 파이프 라인 할 수는 없습니다.

시작하기 위해 파이프 라인 접근 방식을 잊어 버리고 파이프 라인이 아닌 B 계산 구현으로 알고리즘을 작동시키는 것이 좋습니다.

올바른 결과를 얻고 더 많은 성능이 필요하면 파이프 라이닝을 살펴볼 수 있습니다. 그런 다음 각 클럭 사이클에서 중간 결과가 어떻게 정렬되는지와 동기화 상태를 유지하는 데 필요한 결과를 확인할 수 있습니다.


답변 주셔서 감사합니다. 이미 파이프 라인이 아닌 버전을 사용하고 있으며 f (max)에 대한 결론은 b의 계산입니다. 내가 이해하는 것처럼, b의 파이프 라인을 계산하면 충분하지만 그것을 다시 읽어야한다고 생각합니다.
jgr

예. 관련된 모든 변수에 대한 파이프 라인의 단계를 나타내는 모든 변수의 i-1, i, i + 1, i + 2 등 아래 첨자에 특히주의하십시오. 또한, 논문의 표 2.1에는 몇 가지 오류가 있습니다. 세 번째 방정식에서 은 여야합니다 (이는 변수를 AK라고합니다). 두 번째 방정식에서 은 이어야합니다 . A i + 2 M i + 1 M i + 1Bi1Ai+2Mi+1Mi+1
Dave Tweed 님이

감사합니다! 당신은 그냥 파이프 라인 수 없음을 언급 할 때 나는 다시 읽어 b, 당신은 그들이 (의 용지에 전달 된 데이터를 부르는 의미 않았다 A)?
jgr

그렇습니다. 예를 들어, 의 값은 와 . C의 Ai+2Ci
Dave Tweed 님이

좋아, AK정말 CK. 이것은 점점 더 복잡해집니다 : /
jgr
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.