//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