एमडी 5 वीएचडीएल पाइपलाइन


10

मैं इस लिंक के अनुसार एक 3-चरण एमडी 5 पाइपलाइन को लागू करने की कोशिश कर रहा हूं । विशेष रूप से पृष्ठ ३१ पर बीजगणित। एक अन्य दस्तावेज भी है जो डेटा अग्रेषण का वर्णन करता है। यह एक 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) निम्नलिखित मान सही हैं (पहले दौर के 3 चरण 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

वैसे, AKMदस्तावेज़ akwमें कोड में है।

मुझे सही दिशा में लाने के किसी भी सुझाव या सुझाव की बहुत सराहना की जाएगी। कोड आदर्श होगा। यदि कुछ स्पष्ट नहीं है, तो मैं प्रश्न को संपादित करूँगा और उसे ठीक करने का प्रयास करूँगा।


क्या आप एक माइक्रोकंट्रोलर के साथ कर रहे हैं? किस प्रकार? आपका सेटअप क्या है? Schematics? कृपया अधिक जानकारी प्रदान करें :-)

मैंने कुछ और जानकारी जोड़ी है, कृपया मुझे बताएं कि क्या मैं इसे और बेहतर बना सकता हूं।
JGR

मुझे नहीं लगता कि आप पूरी तरह से समझते हैं कि आप यहाँ क्या माँग रहे हैं। ऐसा लगता है कि आप वास्तव में सभी पाइपलाइनों और संबंधित मुद्दों से परिचित नहीं हैं जैसे कि चरणों के बीच डेटा निर्भरता से निपटने और चरणों को ठीक से प्रारंभ करना। आपको पढ़ाने के लिए एक पुस्तक की आवश्यकता होगी, न कि वेब पेज की। और मुझे संदेह है कि जिस किसी ने भी पहले से ही इस एल्गोरिथ्म का एक पाइपलाइन कार्यान्वयन किया है, वह आपको मुफ्त में देने जा रहा है। उस जैसी बौद्धिक संपदा का वास्तविक मूल्य है।
डेव ट्वीड

काफी उचित। आप बिल्कुल सही हैं। मैं पाइपलाइन निर्माण से परिचित नहीं हूं, केवल VHDL के साथ 6 महीने का अनुभव है। बहुत ईमानदार हो मैं उम्मीद भी नहीं कर रहा था, लेकिन जब आप मदद के लिए पूछ रहे हैं तो हमेशा एक अच्छा विकल्प लगता है।
JGR

जवाबों:


5

मुझे लगता है कि आपको एल्गोरिथ्म को पाइपलाइन करने पर कागज के लेखक की टिप्पणियों को गलत समझा। आप सिर्फ बी के लिए कम्प्यूटेशन को पाइपलाइन नहीं कर सकते हैं, बाकी की प्रक्रिया को भी पाइपलाइन किए बिना।

मैं शुरू करने के उद्देश्यों के लिए सिफारिश करूंगा, कि आप पाइप लाइन के दृष्टिकोण के बारे में पूरी तरह से भूल जाएं, और बस बी कम्प्यूटेशन के एक गैर-पाइपलाइन किए गए कार्यान्वयन के साथ काम करने वाले एल्गोरिदम को प्राप्त करें।

एक बार जब आप सही परिणाम प्राप्त कर रहे होते हैं, और यदि आपको अधिक प्रदर्शन की आवश्यकता होती है, तो आप इसे पाइपलाइन कर सकते हैं। फिर, आप यह देख पाएंगे कि प्रत्येक घड़ी चक्र पर मध्यवर्ती परिणाम कैसे रेखाबद्ध होते हैं और उन्हें सिंक में रखने में क्या लगता है।


आपके उत्तर के लिए धन्यवाद। मेरे पास पहले से ही एक गैर-पाइपलाइन संस्करण है, और f (अधिकतम) के बारे में होल्डअप b की गणना है। जैसा कि मुझे समझ में आता है, क्या यह है कि बी की गणना को कम करने के लिए पर्याप्त होगा, लेकिन मुझे लगता है कि मुझे इसे (फिर से) पढ़ना होगा।
JGR

हाँ। I-1, i, i + 1, i + 2, आदि पर विशेष ध्यान दें, सभी चर पर सदस्यता लेते हैं, जो कि शामिल सभी चर के लिए पाइपलाइन में चरणों का प्रतिनिधित्व करते हैं। साथ ही, कागज में तालिका 2.1 में कई त्रुटियां हैं। तीसरे समीकरण में, होना चाहिए (यही कारण है कि चर को AK कहा जाता है)। और दूसरे समीकरण में होना चाहिए । A i + 2 M i + 1 M i + 1Bi1Ai+2Mi+1Mi+1
डेव ट्वीड

धन्यवाद! मैं इसके माध्यम से फिर से पढ़ता हूं, जब आपने उल्लेख किया था कि मैं सिर्फ पाइपलाइन नहीं कर सकता b, तो क्या आपका मतलब है कि वे कागज (फॉर A) में डेटा अग्रेषण कहते हैं ?
JGR

हां, वह इसका हिस्सा है। उदाहरण के लिए, का के समान है । C iAi+2Ci
डेव ट्वीड

ठीक है, तो AKवास्तव में है CK। यह अधिक से अधिक जटिल हो जाता है: /
jgr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.