aboutsummaryrefslogtreecommitdiff
path: root/src/multicrack.sv
diff options
context:
space:
mode:
authorWarrick Lo <wlo@warricklo.net>2026-04-08 14:05:11 -0700
committerWarrick Lo <wlo@warricklo.net>2026-04-08 14:05:11 -0700
commit4d43ba2b048e4a5bc46c72032c3bfe7a2f062ec3 (patch)
tree2d2f5d9cef5881016d0799bfeb8d5bad4be7a2e4 /src/multicrack.sv
parentAdd output file of 108 core cracking (diff)
downloadrc4-decrypt-4d43ba2b048e4a5bc46c72032c3bfe7a2f062ec3.tar.xz
rc4-decrypt-4d43ba2b048e4a5bc46c72032c3bfe7a2f062ec3.zip
Add muli-core ARC4 cracking
Signed-off-by: Warrick Lo <wlo@warricklo.net>
Diffstat (limited to 'src/multicrack.sv')
-rw-r--r--src/multicrack.sv226
1 files changed, 226 insertions, 0 deletions
diff --git a/src/multicrack.sv b/src/multicrack.sv
new file mode 100644
index 0000000..c3f1aef
--- /dev/null
+++ b/src/multicrack.sv
@@ -0,0 +1,226 @@
+module multicrack (
+ input logic clk,
+ input logic rst_n,
+ input logic en,
+ output logic rdy,
+ output logic [23:0] key,
+ output logic key_valid,
+ output logic [7:0] ct_addr,
+ input logic [7:0] ct_rddata
+);
+
+ localparam int NUM_CORES = 108;
+ localparam int WINNER_W = $clog2(NUM_CORES);
+ localparam logic [23:0] KEY_INCREMENT = 24'd108;
+
+ logic c_en;
+
+ logic [NUM_CORES-1:0] core_rdy, core_key_valid;
+ logic [NUM_CORES-1:0][7:0] core_ct_addr;
+ logic [NUM_CORES-1:0][7:0] core_pt_addr;
+ logic [NUM_CORES-1:0][7:0] core_pt_rddata;
+ logic [NUM_CORES-1:0][23:0] core_key;
+
+ logic [NUM_CORES-1:0] ct_core_wren;
+ logic [NUM_CORES-1:0][7:0] ct_core_addr;
+ logic [NUM_CORES-1:0][7:0] ct_core_wrdata, ct_core_rddata;
+
+ logic pt_wren;
+ logic [7:0] pt_addr;
+ logic [7:0] pt_wrdata, pt_rddata;
+
+ logic [7:0] ct_copy_idx_d, ct_copy_idx_q;
+ logic [7:0] pt_copy_idx_d, pt_copy_idx_q;
+ logic [WINNER_W-1:0] winner_d, winner_q;
+
+ logic all_cores_rdy;
+ logic winning_core_valid;
+ logic [WINNER_W-1:0] winning_core_idx;
+ logic [23:0] winner_key;
+ logic [7:0] winner_pt_rddata;
+
+ typedef enum logic [2:0] {
+ IDLE,
+ CT_FETCH,
+ CT_WRITE,
+ CRACK_START,
+ CRACK,
+ PT_FETCH,
+ PT_WRITE,
+ DONE
+ } state_t;
+
+ state_t state_d, state_q;
+
+ pt_mem pt (
+ .address(pt_addr),
+ .clock(clk),
+ .data(pt_wrdata),
+ .wren(pt_wren),
+ .q(pt_rddata)
+ );
+
+ genvar i;
+ generate
+ for (i = 0; i < NUM_CORES; i++) begin : gen_cores
+ ct_core_mem ct (
+ .address(ct_core_addr[i]),
+ .clock(clk),
+ .data(ct_core_wrdata[i]),
+ .wren(ct_core_wren[i]),
+ .q(ct_core_rddata[i])
+ );
+
+ crack #(
+ .KeyStart(i),
+ .KeyIncrement(KEY_INCREMENT)
+ ) core (
+ .clk,
+ .rst_n,
+ .en(c_en),
+ .rdy(core_rdy[i]),
+ .key(core_key[i]),
+ .key_valid(core_key_valid[i]),
+ .ct_addr(core_ct_addr[i]),
+ .ct_rddata(ct_core_rddata[i]),
+ .pt_addr_ext(core_pt_addr[i]),
+ .pt_rddata_ext(core_pt_rddata[i])
+ );
+ end
+ endgenerate
+
+ always_comb begin
+ all_cores_rdy = 1'b1;
+ winning_core_valid = 1'b0;
+ winning_core_idx = '0;
+
+ for (int j = 0; j < NUM_CORES; j++) begin
+ all_cores_rdy &= core_rdy[j];
+ if (!winning_core_valid && core_rdy[j] && core_key_valid[j]) begin
+ winning_core_valid = 1'b1;
+ winning_core_idx = WINNER_W'(j);
+ end
+ end
+ end
+
+ assign winner_key = core_key[winner_q];
+ assign winner_pt_rddata = core_pt_rddata[winner_q];
+
+ always_ff @(posedge clk) begin
+ if (~rst_n) begin
+ state_q <= IDLE;
+ ct_copy_idx_q <= '0;
+ pt_copy_idx_q <= '0;
+ winner_q <= '0;
+ end else begin
+ state_q <= state_d;
+ ct_copy_idx_q <= ct_copy_idx_d;
+ pt_copy_idx_q <= pt_copy_idx_d;
+ winner_q <= winner_d;
+ end
+ end
+
+ always_comb begin
+ state_d = state_q;
+ ct_copy_idx_d = ct_copy_idx_q;
+ pt_copy_idx_d = pt_copy_idx_q;
+ winner_d = winner_q;
+
+ unique case (state_q)
+ IDLE: begin
+ if (en) begin
+ state_d = CT_FETCH;
+ ct_copy_idx_d = '0;
+ pt_copy_idx_d = '0;
+ winner_d = '0;
+ end
+ end
+ CT_FETCH: state_d = CT_WRITE;
+ CT_WRITE: begin
+ if (ct_copy_idx_q == 8'hFF) begin
+ state_d = CRACK_START;
+ end else begin
+ state_d = CT_FETCH;
+ ct_copy_idx_d = ct_copy_idx_q + 8'd1;
+ end
+ end
+ CRACK_START: begin
+ if (all_cores_rdy) state_d = CRACK;
+ end
+ CRACK: begin
+ if (winning_core_valid) begin
+ state_d = PT_FETCH;
+ pt_copy_idx_d = '0;
+ winner_d = winning_core_idx;
+ end else if (all_cores_rdy) begin
+ state_d = DONE;
+ end
+ end
+ PT_FETCH: state_d = PT_WRITE;
+ PT_WRITE: begin
+ if (pt_copy_idx_q == 8'hFF) begin
+ state_d = DONE;
+ end else begin
+ state_d = PT_FETCH;
+ pt_copy_idx_d = pt_copy_idx_q + 8'd1;
+ end
+ end
+ DONE: state_d = DONE;
+ default: state_d = IDLE;
+ endcase
+ end
+
+ always_comb begin
+ rdy = '0;
+ key_valid = '0;
+ key = '0;
+
+ c_en = '0;
+
+ ct_addr = '0;
+
+ pt_addr = '0;
+ pt_wrdata = '0;
+ pt_wren = '0;
+
+ for (int j = 0; j < NUM_CORES; j++) begin
+ ct_core_addr[j] = core_ct_addr[j];
+ ct_core_wrdata[j] = '0;
+ ct_core_wren[j] = '0;
+ core_pt_addr[j] = pt_copy_idx_q;
+ end
+
+ unique case (state_q)
+ IDLE: rdy = '1;
+ CT_FETCH: begin
+ ct_addr = ct_copy_idx_q;
+ end
+ CT_WRITE: begin
+ for (int j = 0; j < NUM_CORES; j++) begin
+ ct_core_addr[j] = ct_copy_idx_q;
+ ct_core_wrdata[j] = ct_rddata;
+ ct_core_wren[j] = '1;
+ end
+ end
+ CRACK_START: begin
+ c_en = all_cores_rdy;
+ end
+ CRACK: begin end
+ PT_FETCH: begin end
+ PT_WRITE: begin
+ pt_addr = pt_copy_idx_q;
+ pt_wren = '1;
+ pt_wrdata = winner_pt_rddata;
+ end
+ DONE: begin
+ rdy = '1;
+ if (core_key_valid[winner_q]) begin
+ key_valid = '1;
+ key = winner_key;
+ end
+ end
+ default: begin end
+ endcase
+ end
+
+endmodule: multicrack