Files
crypto/ChaCha20_Poly1305_64/src/poly1305_core.sv
Byron Lathi 80e3faeae6 ramblings
2025-07-14 11:10:43 -07:00

101 lines
2.3 KiB
Systemverilog

module poly1305_core #(
) (
input i_clk,
input i_rst,
input [255:0] i_otk,
input i_otk_valid,
output [127:0] o_tag,
output o_tag_valid,
taxi_axis_if.snk s_data_axis
);
// incoming data must be 128 bit and packed, i.e. tkeep is 1 except for the last beat with no gaps
localparam R_MASK = 128'h0ffffffc0ffffffc0ffffffc0fffffff;
localparam P130M5 = 258'h3fffffffffffffffffffffffffffffffb;
logic [127:0] poly1305_r, poly1305_s;
logic [129:0] accumulator, accumulator_next;
logic [129:0] data_one_extended;
logic [130:0] data_post_add, data_post_add_reg;
logic [257:0] data_post_mul, data_post_mul_reg;
logic [257:0] modulo_stage, modulo_stage_next;
logic [2:0] phase;
logic [3:0] valid_sr;
function logic [129:0] tkeep_expand (input [15:0] tkeep);
tkeep_expand = '0;
for (int i = 0; i < 16; i++) begin
tkeep_expand[i*8 +: 8] = {8{tkeep[i]}};
end
endfunction
// only ready in phase 0
assign s_data_axis.tready = phase == 0;
assign o_tag_valid = valid_sr[3];
always_ff @(posedge i_clk) begin
if (i_rst) begin
phase <= '0;
valid_sr <= '0;
end
valid_sr <= {valid_sr[2:0], s_data_axis.tlast & s_data_axis.tvalid & s_data_axis.tready & (phase == 0)};
data_post_add_reg <= data_post_add;
data_post_mul_reg <= data_post_mul;
modulo_stage <= modulo_stage_next;
if (i_otk_valid) begin
poly1305_r <= i_otk[255:128] & R_MASK;
poly1305_s <= i_otk[127:0];
end
if (s_data_axis.tvalid && phase == 0) begin
phase <= 1;
end
if (phase == 1) begin
phase <= 2;
end
if (phase == 2) begin
phase <= 3;
end
if (phase == 3) begin
accumulator <= accumulator_next;
phase <= '0;
end
end
always_comb begin
accumulator_next = accumulator;
data_post_mul = '0;
// phase == 0
data_one_extended = (tkeep_expand(s_data_axis.tkeep) + 1) | {2'b0, s_data_axis.tdata};
data_post_add = data_one_extended + accumulator;
// phase == 1
data_post_mul = data_post_add_reg * poly1305_r;
// phase == 2
modulo_stage_next = (data_post_mul_reg[257:130] * 5) + 258'(data_post_mul_reg[129:0]);
// phase == 3
accumulator_next = 130'((modulo_stage[257:130] * 5) + 258'(modulo_stage[129:0]));
end
assign o_tag = accumulator[127:0] + poly1305_s;
endmodule