//generate 10 keys, 10 at a time, 4 rounds in the state machine module key_gen40(clk,rst,signal_done,signal_next, match, plain_txt, k0,k1,k2,k3,k4,k5,k6,k7,k8,k9,k10, k11,k12,k13,k14,k15,k16,k17,k18,k19, k20,k21,k22,k23,k24,k25,k26,k27,k28,k29, k30,k31,k32,k33,k34,k35,k36,k37,k38,k39); /**add control for ledg progress**/ input wire rst,clk; wire [6:0] b1[9:0]; wire [6:0] b2[9:0]; wire [6:0] b3[9:0]; wire [6:0] b4[9:0]; wire [6:0] b5[9:0]; wire [6:0] b6[9:0]; wire [6:0] b7[9:0]; wire c1,c2,c3,c4,c5; input wire signal_done; output reg signal_next; wire signal_match; input wire [39:0] match; // match vector from the DES units output reg [55:0] plain_txt; // store the key when brute-force attack has found it reg [63:0] ascii[9:0][3:0]; //first dimension is the 10 parallel keys (left),right // dimension is the for the 5 founds of the state machine reg [63:0] ascii_next[9:0][3:0]; output wire [63:0] k0,k1,k2,k3,k4,k5,k6,k7,k8,k9,k10, k11,k12,k13,k14,k15,k16,k17,k18,k19, k20,k21,k22,k23,k24,k25,k26,k27,k28,k29, k30,k31,k32,k33,k34,k35,k36,k37,k38,k39; // generated keys assign k0 = ascii[0][0]; // 10 keys from round 1 assign k1 = ascii[1][0]; assign k2 = ascii[2][0]; assign k3 = ascii[3][0]; assign k4 = ascii[4][0]; assign k5 = ascii[5][0]; assign k6 = ascii[6][0]; assign k7 = ascii[7][0]; assign k8 = ascii[8][0]; assign k9 = ascii[9][0]; assign k10 = ascii[0][1]; // 10 keys from round 2 assign k11 = ascii[1][1]; assign k12 = ascii[2][1]; assign k13 = ascii[3][1]; assign k14 = ascii[4][1]; assign k15 = ascii[5][1]; assign k16 = ascii[6][1]; assign k17 = ascii[7][1]; assign k18 = ascii[8][1]; assign k19 = ascii[9][1]; assign k20 = ascii[0][2]; // 10 keys from round 3 etc... assign k21 = ascii[1][2]; assign k22 = ascii[2][2]; assign k23 = ascii[3][2]; assign k24 = ascii[4][2]; assign k25 = ascii[5][2]; assign k26 = ascii[6][2]; assign k27 = ascii[7][2]; assign k28 = ascii[8][2]; assign k29 = ascii[9][2]; assign k30 = ascii[0][3]; assign k31 = ascii[1][3]; assign k32 = ascii[2][3]; assign k33 = ascii[3][3]; assign k34 = ascii[4][3]; assign k35 = ascii[5][3]; assign k36 = ascii[6][3]; assign k37 = ascii[7][3]; assign k38 = ascii[8][3]; assign k39 = ascii[9][3]; reg [7:0] state; //8bits supports 0-255 or 256 parallelizations reg [7:0] cnt; wire [55:0] nk[9:0]; // new key from the LUT and key generating counters reg c_clk; // signal to increment the 0-69 counters reg [7:0] i; // index to keep track of which key we're generating (n keys) reg [7:0] unit; //counter; used to find which DES unit found the key count count0(b1[0],b2[0],b3[0],b4[0],b5[0],b6[0],b7[0],c_clk,rst,7'd0); count count1(b1[1],b2[1],b3[1],b4[1],b5[1],b6[1],b7[1],c_clk,rst,7'd1); count count2(b1[2],b2[2],b3[2],b4[2],b5[2],b6[2],b7[2],c_clk,rst,7'd2); count count3(b1[3],b2[3],b3[3],b4[3],b5[3],b6[3],b7[3],c_clk,rst,7'd3); count count4(b1[4],b2[4],b3[4],b4[4],b5[4],b6[4],b7[4],c_clk,rst,7'd4); count count5(b1[5],b2[5],b3[5],b4[5],b5[5],b6[5],b7[5],c_clk,rst,7'd5); count count6(b1[6],b2[6],b3[6],b4[6],b5[6],b6[6],b7[6],c_clk,rst,7'd6); count count7(b1[7],b2[7],b3[7],b4[7],b5[7],b6[7],b7[7],c_clk,rst,7'd7); count count8(b1[8],b2[8],b3[8],b4[8],b5[8],b6[8],b7[8],c_clk,rst,7'd8); count count9(b1[9],b2[9],b3[9],b4[9],b5[9],b6[9],b7[9],c_clk,rst,7'd9); char_space_lut lut0(b1[0],b2[0],b3[0],b4[0],b5[0],b6[0],b7[0],nk[0]); char_space_lut lut1(b1[1],b2[1],b3[1],b4[1],b5[1],b6[1],b7[1],nk[1]); char_space_lut lut2(b1[2],b2[2],b3[2],b4[2],b5[2],b6[2],b7[2],nk[2]); char_space_lut lut3(b1[3],b2[3],b3[3],b4[3],b5[3],b6[3],b7[3],nk[3]); char_space_lut lut4(b1[4],b2[4],b3[4],b4[4],b5[4],b6[4],b7[4],nk[4]); char_space_lut lut5(b1[5],b2[5],b3[5],b4[5],b5[5],b6[5],b7[5],nk[5]); char_space_lut lut6(b1[6],b2[6],b3[6],b4[6],b5[6],b6[6],b7[6],nk[6]); char_space_lut lut7(b1[7],b2[7],b3[7],b4[7],b5[7],b6[7],b7[7],nk[7]); char_space_lut lut8(b1[8],b2[8],b3[8],b4[8],b5[8],b6[8],b7[8],nk[8]); char_space_lut lut9(b1[9],b2[9],b3[9],b4[9],b5[9],b6[9],b7[9],nk[9]); assign signal_match = |match; wire [6:0] l_index, r_index; assign r_index = (unit - unit%10)/10; assign l_index = unit%10; always@(posedge clk or posedge rst)//add or reset begin if(rst) begin plain_txt = 56'b0; signal_next = 1'b0; c_clk = 1'b0; state = 8'd0; i=8'd1; //upon reset, the first key is already available. ascii_next[0][0]={nk[0][55:49],1'b0, // pad with dummy parity bit nk[0][48:42],1'b0, nk[0][41:35],1'b0, nk[0][34:28],1'b0, nk[0][27:21],1'b0, nk[0][20:14],1'b0, nk[0][13:7],1'b0, nk[0][6:0],1'b0}; ascii_next[1][0]={nk[1][55:49],1'b0, // pad with dummy parity bit nk[1][48:42],1'b0, nk[1][41:35],1'b0, nk[1][34:28],1'b0, nk[1][27:21],1'b0, nk[1][20:14],1'b0, nk[1][13:7],1'b0, nk[1][6:0],1'b0}; ascii_next[2][0]={nk[2][55:49],1'b0, // pad with dummy parity bit nk[2][48:42],1'b0, nk[2][41:35],1'b0, nk[2][34:28],1'b0, nk[2][27:21],1'b0, nk[2][20:14],1'b0, nk[2][13:7],1'b0, nk[2][6:0],1'b0}; ascii_next[3][0]={nk[3][55:49],1'b0, // pad with dummy parity bit nk[3][48:42],1'b0, nk[3][41:35],1'b0, nk[3][34:28],1'b0, nk[3][27:21],1'b0, nk[3][20:14],1'b0, nk[3][13:7],1'b0, nk[3][6:0],1'b0}; ascii_next[4][0]={nk[4][55:49],1'b0, // pad with dummy parity bit nk[4][48:42],1'b0, nk[4][41:35],1'b0, nk[4][34:28],1'b0, nk[4][27:21],1'b0, nk[4][20:14],1'b0, nk[4][13:7],1'b0, nk[4][6:0],1'b0}; ascii_next[5][0]={nk[5][55:49],1'b0, // pad with dummy parity bit nk[5][48:42],1'b0, nk[5][41:35],1'b0, nk[5][34:28],1'b0, nk[5][27:21],1'b0, nk[5][20:14],1'b0, nk[5][13:7],1'b0, nk[5][6:0],1'b0}; ascii_next[6][0]={nk[6][55:49],1'b0, // pad with dummy parity bit nk[6][48:42],1'b0, nk[6][41:35],1'b0, nk[6][34:28],1'b0, nk[6][27:21],1'b0, nk[6][20:14],1'b0, nk[6][13:7],1'b0, nk[6][6:0],1'b0}; ascii_next[7][0]={nk[7][55:49],1'b0, // pad with dummy parity bit nk[7][48:42],1'b0, nk[7][41:35],1'b0, nk[7][34:28],1'b0, nk[7][27:21],1'b0, nk[7][20:14],1'b0, nk[7][13:7],1'b0, nk[7][6:0],1'b0}; ascii_next[8][0]={nk[8][55:49],1'b0, // pad with dummy parity bit nk[8][48:42],1'b0, nk[8][41:35],1'b0, nk[8][34:28],1'b0, nk[8][27:21],1'b0, nk[8][20:14],1'b0, nk[8][13:7],1'b0, nk[8][6:0],1'b0}; ascii_next[9][0]={nk[9][55:49],1'b0, // pad with dummy parity bit nk[9][48:42],1'b0, nk[9][41:35],1'b0, nk[9][34:28],1'b0, nk[9][27:21],1'b0, nk[9][20:14],1'b0, nk[9][13:7],1'b0, nk[9][6:0],1'b0}; end else begin case(state) 0: begin c_clk=1'b1; // create posedge to advance the counters state=8'd1; end 1: begin ascii_next[0][i]={nk[0][55:49],1'b0, // pad with dummy parity bit nk[0][48:42],1'b0, nk[0][41:35],1'b0, nk[0][34:28],1'b0, nk[0][27:21],1'b0, nk[0][20:14],1'b0, nk[0][13:7],1'b0, nk[0][6:0],1'b0}; ascii_next[1][i]={nk[1][55:49],1'b0, // pad with dummy parity bit nk[1][48:42],1'b0, nk[1][41:35],1'b0, nk[1][34:28],1'b0, nk[1][27:21],1'b0, nk[1][20:14],1'b0, nk[1][13:7],1'b0, nk[1][6:0],1'b0}; ascii_next[2][i]={nk[2][55:49],1'b0, // pad with dummy parity bit nk[2][48:42],1'b0, nk[2][41:35],1'b0, nk[2][34:28],1'b0, nk[2][27:21],1'b0, nk[2][20:14],1'b0, nk[2][13:7],1'b0, nk[2][6:0],1'b0}; ascii_next[3][i]={nk[3][55:49],1'b0, // pad with dummy parity bit nk[3][48:42],1'b0, nk[3][41:35],1'b0, nk[3][34:28],1'b0, nk[3][27:21],1'b0, nk[3][20:14],1'b0, nk[3][13:7],1'b0, nk[3][6:0],1'b0}; ascii_next[4][i]={nk[4][55:49],1'b0, // pad with dummy parity bit nk[4][48:42],1'b0, nk[4][41:35],1'b0, nk[4][34:28],1'b0, nk[4][27:21],1'b0, nk[4][20:14],1'b0, nk[4][13:7],1'b0, nk[4][6:0],1'b0}; ascii_next[5][i]={nk[5][55:49],1'b0, // pad with dummy parity bit nk[5][48:42],1'b0, nk[5][41:35],1'b0, nk[5][34:28],1'b0, nk[5][27:21],1'b0, nk[5][20:14],1'b0, nk[5][13:7],1'b0, nk[5][6:0],1'b0}; ascii_next[6][i]={nk[6][55:49],1'b0, // pad with dummy parity bit nk[6][48:42],1'b0, nk[6][41:35],1'b0, nk[6][34:28],1'b0, nk[6][27:21],1'b0, nk[6][20:14],1'b0, nk[6][13:7],1'b0, nk[6][6:0],1'b0}; ascii_next[7][i]={nk[7][55:49],1'b0, // pad with dummy parity bit nk[7][48:42],1'b0, nk[7][41:35],1'b0, nk[7][34:28],1'b0, nk[7][27:21],1'b0, nk[7][20:14],1'b0, nk[7][13:7],1'b0, nk[7][6:0],1'b0}; ascii_next[8][i]={nk[8][55:49],1'b0, // pad with dummy parity bit nk[8][48:42],1'b0, nk[8][41:35],1'b0, nk[8][34:28],1'b0, nk[8][27:21],1'b0, nk[8][20:14],1'b0, nk[8][13:7],1'b0, nk[8][6:0],1'b0}; ascii_next[9][i]={nk[9][55:49],1'b0, // pad with dummy parity bit nk[9][48:42],1'b0, nk[9][41:35],1'b0, nk[9][34:28],1'b0, nk[9][27:21],1'b0, nk[9][20:14],1'b0, nk[9][13:7],1'b0, nk[9][6:0],1'b0}; c_clk=1'b0; // create negedge i=i+8'd1; if(i=='d4) // 4 rounds begin state=8'd2; // done generating key for all the n DES units end else begin state=8'd0; // generate next key end end // case: 1 2: // signal_done? begin if(signal_done) begin state=8'd3; end end // case: 0 3: begin if(signal_match) // or all the bits of match begin state=8'd6; // a unit found the key unit=8'd0; // reset the counter for state6 end else begin ascii[0][0]=ascii_next[0][0]; // swap in the new keys ascii[1][0]=ascii_next[1][0]; ascii[2][0]=ascii_next[2][0]; ascii[3][0]=ascii_next[3][0]; ascii[4][0]=ascii_next[4][0]; ascii[5][0]=ascii_next[5][0]; ascii[6][0]=ascii_next[6][0]; ascii[7][0]=ascii_next[7][0]; ascii[8][0]=ascii_next[8][0]; ascii[9][0]=ascii_next[9][0]; ascii[0][1]=ascii_next[0][1]; ascii[1][1]=ascii_next[1][1]; ascii[2][1]=ascii_next[2][1]; ascii[3][1]=ascii_next[3][1]; ascii[4][1]=ascii_next[4][1]; ascii[5][1]=ascii_next[5][1]; ascii[6][1]=ascii_next[6][1]; ascii[7][1]=ascii_next[7][1]; ascii[8][1]=ascii_next[8][1]; ascii[9][1]=ascii_next[9][1]; ascii[0][2]=ascii_next[0][2]; ascii[1][2]=ascii_next[1][2]; ascii[2][2]=ascii_next[2][2]; ascii[3][2]=ascii_next[3][2]; ascii[4][2]=ascii_next[4][2]; ascii[5][2]=ascii_next[5][2]; ascii[6][2]=ascii_next[6][2]; ascii[7][2]=ascii_next[7][2]; ascii[8][2]=ascii_next[8][2]; ascii[9][2]=ascii_next[9][2]; ascii[0][3]=ascii_next[0][3]; ascii[1][3]=ascii_next[1][3]; ascii[2][3]=ascii_next[2][3]; ascii[3][3]=ascii_next[3][3]; ascii[4][3]=ascii_next[4][3]; ascii[5][3]=ascii_next[5][3]; ascii[6][3]=ascii_next[6][3]; ascii[7][3]=ascii_next[7][3]; ascii[8][3]=ascii_next[8][3]; ascii[9][3]=ascii_next[9][3]; state=8'd4; // start next round of computations end end 4: begin signal_next=1'b1; // posedge signal to start DES calculations state=8'd5; end 5: begin signal_next=1'b0; // negedge deactivate i=8'd0; // reset the counter for key generation state=8'd0; // getnerate the next set of keys end 6: // figure out which unit found the key begin if(match[unit]==1'b0) begin unit = unit + 8'd1; end else begin //strip parity bits to obtain ascii values plain_txt = {ascii[l_index][r_index][63:57], ascii[l_index][r_index][55:49], ascii[l_index][r_index][47:41], ascii[l_index][r_index][39:33], ascii[l_index][r_index][31:25], ascii[l_index][r_index][23:17], ascii[l_index][r_index][15:9], ascii[l_index][r_index][7:1]}; // store the password that generated the correct hash state = 8'd7; end end 7: // trap state; begin end endcase // case (state) end end endmodule // key_gen