基于蒙哥马利实现大数模密的算法的硬件实现

基于大数蒙哥马利的模乘的硬件实现上一篇博客蒙哥马利基2的算法的Verilog 硬件实现(大数模乘)

下面介绍基于蒙哥马利算法实现大数模幂的硬件verilog语言实现



module modular_me_v1 #(parameter WIDTH=1024)
(
	input               clk,
	input               rst_n,
	input               me_start,
	input  [WIDTH-1:0]  M,
	input  [WIDTH-1:0]  E,
	input  [WIDTH-1:0]  Z,
	input  [WIDTH-1:0]  N,
	output [WIDTH-1:0]  result_C,
	output              done_flg
	
);
	
    reg [WIDTH-1:0]         M_r,E_r,Z_r,N_r,C_r;
    
    reg [WIDTH-1:0]         m0_a,m0_b; 
    reg [WIDTH-1:0]         m1_a,m1_b; 
    
    wire [WIDTH-1:0]         result_m0,result_m1; 
    
    reg [10:0]              cnt_i;   
      
    wire                    done0,done1;
    
    parameter CNT_LENGTH    = WIDTH; 
    
    
    //reg cm_done;
    //reg mm_done;
    reg me_done;
    reg [WIDTH-1:0] C;
    reg [2:0] current_state;
    reg [2:0] next_state;
    reg done_flg0,done_flg1;

    parameter   IDLE                  = 3'b000,
                READY1                = 3'b001,
                WAIT_CALCU1           = 3'b010,
                READY2                = 3'b011,
                WAIT_CALCU2           = 3'b100,
                READY3                = 3'b101,
                WAIT_CALCU3           = 3'b110,
                DONE                  = 3'b111;
    
    wire             start;
    reg                 start_dly;

    always@(posedge clk or negedge rst_n)
    begin 
	    if(!rst_n)
            start_dly <= 0;
        else
            start_dly <= me_start;
    end

    assign start = me_start & (!start_dly);

    always@(posedge clk or negedge rst_n)begin 
    	if(!rst_n)begin 
    	    E_r<=0;
    	    Z_r<=0;
    	    N_r<=0;
    	end 
    	else if(start==1'b1)
    	begin 
    	    E_r<=E;
    	    Z_r<=Z;
    	    N_r<=N;
    	end 
    end 
    
    always@(posedge clk or negedge rst_n)begin 
    	if(!rst_n)
        begin 
    	    M_r<=0;
            C_r<=1;
    	end 
    	else if(start==1'b1)
    	begin 
    	    M_r<=M;
            C_r<=1;
    	end 
        else if (current_state == WAIT_CALCU3 & next_state == READY1)
        begin
            M_r<=result_m0;
            C_r<=result_m1;
        end
    end 
    
    //cnt
    always@(posedge clk or negedge rst_n)
    begin 
    	if(!rst_n)
            cnt_i <= 0;
        else if (current_state == DONE | current_state == IDLE)
            cnt_i <= 0;
        else if (current_state == WAIT_CALCU3 & next_state == READY1)
            cnt_i <= cnt_i + 1'b1;
    end

    /*
    reg            done_dly0;
    reg            done_dly1;
    
    
    //delay
    always@(posedge clk or negedge rst_n)
    begin 
	    if(!rst_n)
        begin
            done_dly0 <= 0;
            done_dly1 <= 0;
        end
        else
        begin
            done_dly0 <= done0;
            done_dly1 <= done1;
        end
    end
    */

    //fsm_ctl
    always@(posedge clk or negedge rst_n)
    begin 
    	if(!rst_n)
    	current_state   <=  3'b000;
    	else
    	current_state   <=  next_state;
    end 
    
    
    always@(*)
    begin 
    	case(current_state)
            IDLE:           begin
    			                if(start==1'b1)
    			                    next_state  =  READY1;
    			                else 
    			                    next_state  =  IDLE;
                            end
    
    		READY1:          begin 
    			                if(cnt_i != (WIDTH))   
    			                    next_state  =  WAIT_CALCU1;
    			                else 
    			                    next_state  =  DONE;
    			
    			            end 
            
    		WAIT_CALCU1:    begin
                                if(done_flg0 == 1'b1 & done_flg1 == 1'b1)
    			                    next_state  =  READY2;
                                else
                                    next_state  =  WAIT_CALCU1;
    		        	    end
    
            READY2:         begin
                                next_state = WAIT_CALCU2;
                            end
    
    		WAIT_CALCU2:    begin 
                                if(done_flg0 == 1'b1 & done_flg1 == 1'b1)
    			                    next_state  =  READY3;
                                else
                                    next_state  =  WAIT_CALCU2;
    		        	    end
    
            READY3:         begin
                                next_state = WAIT_CALCU3;
                            end
    
    		WAIT_CALCU3:    begin 
                                if(done_flg0 == 1'b1 & done_flg1 == 1'b1)
    			                    next_state  =  READY1;
                                else
                                    next_state  =  WAIT_CALCU3;
    		        	    end
    
            DONE:           begin
                                next_state      =  IDLE;
                            end
    
    		default:        begin
    			                next_state      =  IDLE;
    		                end
    	
    	endcase
    end 



    reg             start_mm_en0;
    reg             start_cm_en1;

    //flag_start
    always@(*)
    begin 
    	if(!rst_n)
            begin
                start_cm_en1 = 1'b0;
                m1_a        = 0;
                m1_b        = 0;
            end
        else 
            begin
                if (E_r[cnt_i]  == 1'b1)
                begin
                    if (current_state == READY1)
                        begin
                            start_cm_en1 = 1'b1;
                            m1_a         = C_r;
                            m1_b         = Z_r;
                        end
                    else if (current_state == READY2)
                        begin
                            start_cm_en1 = 1'b1;
                            m1_a         = result_m1;
                            m1_b         = result_m0;
                        end
                    else if (current_state == READY3)
                        begin
                            start_cm_en1 = 1'b1;
                            m1_a         = result_m1;
                            m1_b         = 1;
                        end
                    else if (current_state == WAIT_CALCU1 | current_state == WAIT_CALCU2 | current_state == WAIT_CALCU3 )
                        start_cm_en1     = 1'b0;
                end
                else
                    start_cm_en1         = 1'b0;
    
            end
    end
    
    always@(*)
    begin 
    	if(!rst_n)
            begin
                start_mm_en0 = 1'b0;
                m0_a        = 0;
                m0_b        = 0;
            end
        else if (current_state == READY1)
            begin
                start_mm_en0 = 1'b1;
                m0_a        = M_r;
                m0_b        = Z_r;
            end
        else if (current_state == READY2)
            begin
                start_mm_en0 = 1'b1;
                m0_a        = result_m0;
                m0_b        = result_m0;
            end
        else if (current_state == READY3)
            begin
                start_mm_en0 = 1'b1;
                m0_a        = result_m0;
                m0_b        = 1;
            end
        else if (current_state == WAIT_CALCU1 | current_state == WAIT_CALCU2 | current_state == WAIT_CALCU3 )
            start_mm_en0 <= 1'b0;
    end        

            
    always@(posedge clk or negedge rst_n)
    begin 
	    if(!rst_n)
            me_done     <=  1'b0;
        else if (current_state == READY1)
            me_done     <=  1'b0;
        else if (current_state == DONE)
            me_done     <=  1'b1;
    end
    
    
    always@(posedge clk or negedge rst_n)
    begin 
	    if(!rst_n)
            C     <=  0;
        else if (current_state == DONE)
            C     <=  result_m1;
    end
    
    assign done_flg = me_done;
    assign result_C = C;

    montgomery #(.WIDTH(WIDTH)) u_mont_cm(
    	.clk            (clk),
    	.rstn           (rst_n),
    	.start_flag     (start_cm_en1),
    	.in_a           (m1_a),
    	.in_b           (m1_b),
    	.in_m           (N_r),
    	.result         (result_m1),
    	.done_flag      (done1)
    	);
    
    montgomery #(.WIDTH(WIDTH)) u_mont_mm(
    	.clk            (clk),
    	.rstn           (rst_n),
    	.start_flag     (start_mm_en0),
    	.in_a           (m0_a),
    	.in_b           (m0_b),
    	.in_m           (N_r),
    	.result         (result_m0),
    	.done_flag      (done0)
    	);
    

    always@(posedge clk or negedge rst_n)
        begin
            if (!rst_n)
            begin
                done_flg0<=1'b0;
                done_flg1<=1'b0;
            end
            else if (current_state == READY1 | current_state == READY2 | current_state == READY3 )
            begin
                done_flg0<=1'b0;
                done_flg1<=1'b0;
            end
            else 
            begin
                done_flg0<=done0;
                done_flg1<=done1;
            end
        end

endmodule 

你可能感兴趣的:(数字安全)