Files
crypto/ChaCha20_Poly1305_64/src/poly1305_friendly_modulo.sv
2025-10-27 19:19:43 -07:00

48 lines
1.3 KiB
Systemverilog

module poly1305_friendly_modulo #(
parameter WIDTH = 130,
parameter MDIFF = 5, // modulo difference
parameter SHIFT_SIZE = 26
) (
input logic i_clk,
input logic i_rst,
input logic i_valid,
input logic [2*WIDTH-1:0] i_val,
input logic [2:0] i_shift_amount,
output logic o_valid,
output logic [WIDTH-1:0] o_result
);
localparam WIDE_WIDTH = WIDTH + $clog2(MDIFF);
localparam [WIDTH-1:0] PRIME = (1 << WIDTH) - MDIFF;
logic [WIDE_WIDTH-1:0] high_part_1, high_part_2;
logic [WIDTH-1:0] low_part_1, low_part_2;
logic [WIDE_WIDTH-1:0] intermediate_val;
logic [WIDTH-1:0] final_val;
logic [2:0] unused_final;
logic [2:0] valid_sr;
assign intermediate_val = high_part_1 + WIDE_WIDTH'(low_part_1);
assign o_result = (final_val >= PRIME) ? final_val - PRIME : final_val;
assign o_valid = valid_sr[2];
always_ff @(posedge i_clk) begin
valid_sr <= {valid_sr[1:0], i_valid};
high_part_1 <= WIDTH'({3'b0, i_val} >> (130 - (i_shift_amount*SHIFT_SIZE))) * MDIFF;
low_part_1 <= WIDTH'(i_val << (i_shift_amount*SHIFT_SIZE));
high_part_2 <= (intermediate_val >> WIDTH) * 5;
low_part_2 <= intermediate_val[WIDTH-1:0];
{unused_final, final_val} <= high_part_2 + WIDE_WIDTH'(low_part_2);
end
endmodule