blob: f09623bd9d7fdafee4d4fc83424f6bd851b0fe60 [file] [log] [blame]
`timescale 1ns/1ns
module fraserbc_simon (
io_in,
io_out
);
input wire [7:0] io_in;
output wire [7:0] io_out;
assign io_out[7:4] = 4'b0;
/* Instantiate main module */
simon simon0 (
.i_clk(io_in[0]),
.i_shift(io_in[1]),
.i_data(io_in[5:2]),
.o_data(io_out[3:0])
);
endmodule
module lfsr_z0(
i_clk,
i_rst,
o_data
);
input wire i_clk;
input wire i_rst;
output wire o_data;
reg [4:0] r_lfsr;
assign o_data = r_lfsr[0];
always @(posedge i_clk)
if(i_rst)
r_lfsr <= 5'b00001;
else begin
r_lfsr[4] <= r_lfsr[3];
r_lfsr[3] <= r_lfsr[2];
r_lfsr[2] <= r_lfsr[4] ^ r_lfsr[1];
r_lfsr[1] <= r_lfsr[0];
r_lfsr[0] <= r_lfsr[4] ^ r_lfsr[0];
end
endmodule
module simon (
i_clk,
i_shift,
i_data,
o_data
);
input wire i_clk;
input wire i_shift;
input wire [3:0] i_data;
output wire [3:0] o_data;
assign o_data = r_round[3:0];
/* z0 Sequence */
wire w_z0;
lfsr_z0 lfsr0 (
.i_clk(i_clk),
.i_rst(i_shift),
.o_data(w_z0)
);
/* Key Schedule */
reg [63:0] r_key;
wire [15:0] w_temp = r_key[31:16] ^ {r_key[50:48],r_key[63:51]}; // Right circular shift
always @(posedge i_clk) begin
if (i_shift)
r_key <= {i_data, r_key[63:4]};
else begin
r_key[15:0] <= r_key[31:16];
r_key[31:16] <= r_key[47:32];
r_key[47:32] <= r_key[63:48];
r_key[63:48] <= (2**16 - 4) ^ {{15{1'b0}}, w_z0} ^ w_temp ^ r_key[15:0] ^ {w_temp[0],w_temp[15:1]};
end
end
/* Encrypt */
reg [31:0] r_round;
always @(posedge i_clk) begin
if (i_shift)
r_round <= {r_key[3:0], r_round[31:4]};
else begin
r_round[15:0] <= r_round[31:16];
r_round[31:16] <= (({r_round[30:16],r_round[31]} & {r_round[23:16],r_round[31:24]})) ^ {r_round[29:16],r_round[31:30]} ^ r_key[15:0] ^ r_round[15:0];
end
end
endmodule