Compare commits
10 Commits
2fd1136154
...
f5e7b843b1
| Author | SHA1 | Date | |
|---|---|---|---|
| f5e7b843b1 | |||
| 89a8087003 | |||
| 885e1307f5 | |||
| 4f7ade81d0 | |||
| cedec1ed1f | |||
| 9b40c88673 | |||
|
|
d5035c6c81
|
||
|
|
2102cb41f4
|
||
|
|
d6a062baa0
|
||
|
|
ad257f4220
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,3 +1,6 @@
|
||||
[submodule "common/sim/sub/taxi"]
|
||||
path = common/sim/sub/taxi
|
||||
url = https://github.com/fpganinja/taxi.git
|
||||
[submodule "common/sim/sub/fifo"]
|
||||
path = common/sim/sub/fifo
|
||||
url = https://github.com/olofk/fifo.git
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<efxpt:design_db name="chacha20poly1305_timing_test" device_def="Ti375C529" version="2025.1.110" db_version="20251999" last_change_date="Mon Jul 27 19:31:51 2026" xmlns:efxpt="http://www.efinixinc.com/peri_design_db" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/peri_design_db peri_design_db.xsd ">
|
||||
<efxpt:device_info>
|
||||
<efxpt:iobank_info>
|
||||
<efxpt:iobank name="2A" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="2A_MODE_SEL"/>
|
||||
<efxpt:iobank name="2B" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="2B_MODE_SEL"/>
|
||||
<efxpt:iobank name="2C" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="2C_MODE_SEL"/>
|
||||
<efxpt:iobank name="2D" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="2D_MODE_SEL"/>
|
||||
<efxpt:iobank name="2E" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="2E_MODE_SEL"/>
|
||||
<efxpt:iobank name="4A_4B" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="4A_4B_MODE_SEL"/>
|
||||
<efxpt:iobank name="4C" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="4C_MODE_SEL"/>
|
||||
<efxpt:iobank name="4D" iostd="1.8 V LVCMOS" is_dyn_voltage="false" mode_sel_name="4D_MODE_SEL"/>
|
||||
<efxpt:iobank name="BL2_BL3" iostd="3.3 V LVCMOS" is_dyn_voltage="false">
|
||||
<efxpt:mode_sel_name>
|
||||
<efxpt:pin_name bank_name="BL2" value="BL2_MODE_SEL"/>
|
||||
<efxpt:pin_name bank_name="BL3" value="BL3_MODE_SEL"/>
|
||||
</efxpt:mode_sel_name>
|
||||
</efxpt:iobank>
|
||||
<efxpt:iobank name="BR0" iostd="3.3 V LVCMOS" is_dyn_voltage="false" mode_sel_name="BR0_MODE_SEL"/>
|
||||
<efxpt:iobank name="BR3_BR4" iostd="3.3 V LVCMOS" is_dyn_voltage="false">
|
||||
<efxpt:mode_sel_name>
|
||||
<efxpt:pin_name bank_name="BR3" value="BR3_MODE_SEL"/>
|
||||
<efxpt:pin_name bank_name="BR4" value="BR4_MODE_SEL"/>
|
||||
</efxpt:mode_sel_name>
|
||||
</efxpt:iobank>
|
||||
<efxpt:iobank name="TL1_TL5" iostd="3.3 V LVCMOS" is_dyn_voltage="false">
|
||||
<efxpt:mode_sel_name>
|
||||
<efxpt:pin_name bank_name="TL1" value="TL1_MODE_SEL"/>
|
||||
<efxpt:pin_name bank_name="TL5" value="TL5_MODE_SEL"/>
|
||||
</efxpt:mode_sel_name>
|
||||
</efxpt:iobank>
|
||||
<efxpt:iobank name="TR0" iostd="3.3 V LVCMOS" is_dyn_voltage="false" mode_sel_name="TR0_MODE_SEL"/>
|
||||
<efxpt:iobank name="TR1" iostd="3.3 V LVCMOS" is_dyn_voltage="false" mode_sel_name="TR1_MODE_SEL"/>
|
||||
<efxpt:iobank name="TR2" iostd="3.3 V LVCMOS" is_dyn_voltage="false" mode_sel_name="TR2_MODE_SEL"/>
|
||||
</efxpt:iobank_info>
|
||||
<efxpt:ctrl_info>
|
||||
<efxpt:ctrl name="cfg" ctrl_def="CONFIG_CTRL0" clock_name="" is_clk_invert="false" cbsel_bus_name="cfg_CBSEL" config_ctrl_name="cfg_CONFIG" ena_capture_name="cfg_ENA" error_status_name="cfg_ERROR" um_signal_status_name="cfg_USR_STATUS" is_remote_update_enable="false" is_user_mode_enable="false">
|
||||
<efxpt:gen_param>
|
||||
<efxpt:param name="remote_update_retries" value="0" value_type="int"/>
|
||||
</efxpt:gen_param>
|
||||
</efxpt:ctrl>
|
||||
</efxpt:ctrl_info>
|
||||
<efxpt:seu_info>
|
||||
<efxpt:seu name="seu" block_def="CONFIG_SEU0" mode="auto" ena_detect="false" wait_interval="16500000">
|
||||
<efxpt:gen_pin>
|
||||
<efxpt:pin name="seu_START" type_name="START" is_bus="false"/>
|
||||
<efxpt:pin name="seu_INJECT_ERROR" type_name="INJECT_ERROR" is_bus="false"/>
|
||||
<efxpt:pin name="seu_RST" type_name="RST" is_bus="false"/>
|
||||
<efxpt:pin name="seu_CONFIG" type_name="CONFIG" is_bus="false"/>
|
||||
<efxpt:pin name="seu_ERROR" type_name="ERROR" is_bus="false"/>
|
||||
<efxpt:pin name="seu_DONE" type_name="DONE" is_bus="false"/>
|
||||
</efxpt:gen_pin>
|
||||
</efxpt:seu>
|
||||
</efxpt:seu_info>
|
||||
<efxpt:clkmux_info>
|
||||
<efxpt:clkmux name="GCLKMUX_B" block_def="GCLKMUX_B" is_mux_bot0_dyn="false" is_mux_bot7_dyn="false">
|
||||
<efxpt:gen_pin>
|
||||
<efxpt:pin name="" type_name="ROUTE0" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE1" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE2" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE3" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_0" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_7" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_0" is_bus="true"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_7" is_bus="true"/>
|
||||
</efxpt:gen_pin>
|
||||
</efxpt:clkmux>
|
||||
<efxpt:clkmux name="GCLKMUX_L" block_def="GCLKMUX_L" is_mux_bot0_dyn="false" is_mux_bot7_dyn="false">
|
||||
<efxpt:gen_pin>
|
||||
<efxpt:pin name="" type_name="ROUTE0" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE1" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE2" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE3" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_0" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_7" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_0" is_bus="true"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_7" is_bus="true"/>
|
||||
</efxpt:gen_pin>
|
||||
</efxpt:clkmux>
|
||||
<efxpt:clkmux name="GCLKMUX_R" block_def="GCLKMUX_R" is_mux_bot0_dyn="false" is_mux_bot7_dyn="false">
|
||||
<efxpt:gen_pin>
|
||||
<efxpt:pin name="" type_name="ROUTE0" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE1" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE2" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE3" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_0" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_7" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_0" is_bus="true"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_7" is_bus="true"/>
|
||||
</efxpt:gen_pin>
|
||||
</efxpt:clkmux>
|
||||
<efxpt:clkmux name="GCLKMUX_T" block_def="GCLKMUX_T" is_mux_bot0_dyn="false" is_mux_bot7_dyn="false">
|
||||
<efxpt:gen_pin>
|
||||
<efxpt:pin name="" type_name="ROUTE0" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE1" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE2" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="ROUTE3" is_bus="false" is_clk="true" is_clk_invert="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_0" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_OUT_7" is_bus="false"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_0" is_bus="true"/>
|
||||
<efxpt:pin name="" type_name="DYN_MUX_SEL_7" is_bus="true"/>
|
||||
</efxpt:gen_pin>
|
||||
</efxpt:clkmux>
|
||||
</efxpt:clkmux_info>
|
||||
</efxpt:device_info>
|
||||
<efxpt:gpio_info>
|
||||
<efxpt:global_unused_config state="input with weak pullup"/>
|
||||
</efxpt:gpio_info>
|
||||
<efxpt:pll_info/>
|
||||
<efxpt:osc_info/>
|
||||
<efxpt:lvds_info/>
|
||||
<efxpt:jtag_info/>
|
||||
<efxpt:ddr_info/>
|
||||
<efxpt:mipi_dphy_info/>
|
||||
<efxpt:soc_info/>
|
||||
</efxpt:design_db>
|
||||
@@ -0,0 +1,48 @@
|
||||
module chacha20poly1305_timing_test(
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic [255:0] i_key,
|
||||
input logic [95:0] i_nonce,
|
||||
|
||||
input logic i_encrypt,
|
||||
|
||||
input logic [31:0] i_data,
|
||||
input logic [1:0] i_countm1,
|
||||
input logic i_last,
|
||||
|
||||
input logic i_valid,
|
||||
output logic o_ready,
|
||||
|
||||
output logic [31:0] o_data,
|
||||
output logic [1:0] o_data_countm1,
|
||||
output logic o_data_last,
|
||||
output logic o_data_valid,
|
||||
input logic i_data_ready,
|
||||
|
||||
// no backpressure for the poly1305 output
|
||||
output logic [127:0] o_mac,
|
||||
output logic o_mac_valid
|
||||
);
|
||||
|
||||
chacha20_poly1305_32_ll_core u_dut (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
.i_key (i_key),
|
||||
.i_nonce (i_nonce),
|
||||
.i_encrypt (i_encrypt),
|
||||
.i_data (i_data),
|
||||
.i_countm1 (i_countm1),
|
||||
.i_last (i_last),
|
||||
.i_valid (i_valid),
|
||||
.o_ready (o_ready),
|
||||
.o_data (o_data),
|
||||
.o_data_countm1 (o_data_countm1),
|
||||
.o_data_last (o_data_last),
|
||||
.o_data_valid (o_data_valid),
|
||||
.i_data_ready (i_data_ready),
|
||||
.o_mac (o_mac),
|
||||
.o_mac_valid (o_mac_valid)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<efx:project name="chacha20poly1305_timing_test" description="" last_change="1785208404" sw_version="2025.1.110" last_run_state="pass" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:device_info>
|
||||
<efx:family name="Titanium"/>
|
||||
<efx:device name="Ti375C529"/>
|
||||
<efx:timing_model name="C4"/>
|
||||
</efx:device_info>
|
||||
<efx:design_info def_veri_version="verilog_2k" def_vhdl_version="vhdl_2008" unified_flow="false">
|
||||
<efx:top_module name="chacha20poly1305_timing_test"/>
|
||||
<efx:design_file name="../src/poly1305_friendly_modulo.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_block.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_pipelined_block.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_width_convert_2.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_poly1305_32_ll_core.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_stage.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_friendly_modular_mult.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_ll_stage.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_width_convert_3.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/skidbuffer.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_width_convert.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_qr.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_core.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_pipelined_round.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_poly1305_64.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_poly1305_mid_fsm.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_poly1305_input_fsm.sv" version="default" library="default"/>
|
||||
<efx:design_file name="chacha20poly1305_timing_test.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../../common/sim/sub/fifo/rtl/verilog/fifo_fwft.v" version="default" library="default"/>
|
||||
<efx:design_file name="../../common/sim/sub/fifo/rtl/verilog/xilinx_fifoe1.v" version="default" library="default"/>
|
||||
<efx:design_file name="../../common/sim/sub/fifo/rtl/verilog/fifo.v" version="default" library="default"/>
|
||||
<efx:design_file name="../../common/sim/sub/fifo/rtl/verilog/dual_clock_fifo.v" version="default" library="default"/>
|
||||
<efx:design_file name="../../common/sim/sub/fifo/rtl/verilog/simple_dpram_sclk.v" version="default" library="default"/>
|
||||
<efx:design_file name="../../common/sim/sub/fifo/rtl/verilog/fifo_fwft_adapter.v" version="default" library="default"/>
|
||||
<efx:top_vhdl_arch name=""/>
|
||||
</efx:design_info>
|
||||
<efx:constraint_info>
|
||||
<efx:sdc_file name="constraints.sdc"/>
|
||||
<efx:inter_file name=""/>
|
||||
</efx:constraint_info>
|
||||
<efx:sim_info/>
|
||||
<efx:misc_info/>
|
||||
<efx:ip_info/>
|
||||
<efx:synthesis tool_name="efx_map">
|
||||
<efx:param name="work_dir" value="work_syn" value_type="e_string"/>
|
||||
<efx:param name="write_efx_verilog" value="on" value_type="e_bool"/>
|
||||
<efx:param name="allow-const-ram-index" value="0" value_type="e_option"/>
|
||||
<efx:param name="blackbox-error" value="1" value_type="e_option"/>
|
||||
<efx:param name="blast_const_operand_adders" value="1" value_type="e_option"/>
|
||||
<efx:param name="bram_output_regs_packing" value="1" value_type="e_option"/>
|
||||
<efx:param name="bram-push-tco-outreg" value="0" value_type="e_option"/>
|
||||
<efx:param name="create-onehot-fsms" value="0" value_type="e_option"/>
|
||||
<efx:param name="fanout-limit" value="0" value_type="e_integer"/>
|
||||
<efx:param name="hdl-compile-unit" value="1" value_type="e_option"/>
|
||||
<efx:param name="hdl-loop-limit" value="20000" value_type="e_integer"/>
|
||||
<efx:param name="infer-clk-enable" value="3" value_type="e_option"/>
|
||||
<efx:param name="infer-sync-set-reset" value="1" value_type="e_option"/>
|
||||
<efx:param name="enable-mark-debug" value="1" value_type="e_option"/>
|
||||
<efx:param name="max_ram" value="-1" value_type="e_integer"/>
|
||||
<efx:param name="max_mult" value="-1" value_type="e_integer"/>
|
||||
<efx:param name="max-bit-blast-mem-size" value="10240" value_type="e_integer"/>
|
||||
<efx:param name="min-sr-fanout" value="0" value_type="e_integer"/>
|
||||
<efx:param name="min-ce-fanout" value="0" value_type="e_integer"/>
|
||||
<efx:param name="mode" value="speed" value_type="e_option"/>
|
||||
<efx:param name="mult-auto-pipeline" value="0" value_type="e_integer"/>
|
||||
<efx:param name="mult-decomp-retime" value="0" value_type="e_option"/>
|
||||
<efx:param name="operator-sharing" value="0" value_type="e_option"/>
|
||||
<efx:param name="optimize-adder-tree" value="0" value_type="e_option"/>
|
||||
<efx:param name="optimize-zero-init-rom" value="1" value_type="e_option"/>
|
||||
<efx:param name="peri-syn-instantiation" value="0" value_type="e_option"/>
|
||||
<efx:param name="peri-syn-inference" value="0" value_type="e_option"/>
|
||||
<efx:param name="ram-decomp-mode" value="0" value_type="e_option"/>
|
||||
<efx:param name="retiming" value="1" value_type="e_option"/>
|
||||
<efx:param name="seq_opt" value="1" value_type="e_option"/>
|
||||
<efx:param name="seq-opt-sync-only" value="0" value_type="e_option"/>
|
||||
<efx:param name="use-logic-for-small-mem" value="64" value_type="e_integer"/>
|
||||
<efx:param name="use-logic-for-small-rom" value="64" value_type="e_integer"/>
|
||||
<efx:param name="max_threads" value="-1" value_type="e_integer"/>
|
||||
<efx:param name="dsp-input-regs-packing" value="1" value_type="e_option"/>
|
||||
<efx:param name="dsp-output-regs-packing" value="1" value_type="e_option"/>
|
||||
<efx:param name="dsp-mac-packing" value="1" value_type="e_option"/>
|
||||
<efx:param name="insert-carry-skip" value="0" value_type="e_option"/>
|
||||
<efx:param name="pack-luts-to-comb4" value="0" value_type="e_option"/>
|
||||
</efx:synthesis>
|
||||
<efx:place_and_route tool_name="efx_pnr">
|
||||
<efx:param name="work_dir" value="work_pnr" value_type="e_string"/>
|
||||
<efx:param name="verbose" value="off" value_type="e_bool"/>
|
||||
<efx:param name="load_delaym" value="on" value_type="e_bool"/>
|
||||
<efx:param name="optimization_level" value="NULL" value_type="e_option"/>
|
||||
<efx:param name="seed" value="1" value_type="e_integer"/>
|
||||
<efx:param name="placer_effort_level" value="2" value_type="e_option"/>
|
||||
<efx:param name="max_threads" value="-1" value_type="e_integer"/>
|
||||
<efx:param name="print_critical_path" value="10" value_type="e_integer"/>
|
||||
<efx:param name="classic_flow" value="off" value_type="e_noarg"/>
|
||||
<efx:param name="beneficial_skew" value="on" value_type="e_option"/>
|
||||
</efx:place_and_route>
|
||||
<efx:bitstream_generation tool_name="efx_pgm">
|
||||
<efx:param name="mode" value="active" value_type="e_option"/>
|
||||
<efx:param name="width" value="1" value_type="e_option"/>
|
||||
<efx:param name="enable_roms" value="smart" value_type="e_option"/>
|
||||
<efx:param name="spi_low_power_mode" value="on" value_type="e_bool"/>
|
||||
<efx:param name="io_weak_pullup" value="on" value_type="e_bool"/>
|
||||
<efx:param name="oscillator_clock_divider" value="DIV8" value_type="e_option"/>
|
||||
<efx:param name="bitstream_compression" value="on" value_type="e_bool"/>
|
||||
<efx:param name="enable_external_master_clock" value="off" value_type="e_bool"/>
|
||||
<efx:param name="active_capture_clk_edge" value="negedge" value_type="e_option"/>
|
||||
<efx:param name="jtag_usercode" value="0xFFFFFFFF" value_type="e_string"/>
|
||||
<efx:param name="release_tri_then_reset" value="on" value_type="e_bool"/>
|
||||
<efx:param name="four_byte_addressing" value="off" value_type="e_bool"/>
|
||||
<efx:param name="generate_bit" value="on" value_type="e_bool"/>
|
||||
<efx:param name="generate_bitbin" value="off" value_type="e_bool"/>
|
||||
<efx:param name="generate_hex" value="on" value_type="e_bool"/>
|
||||
<efx:param name="generate_hexbin" value="off" value_type="e_bool"/>
|
||||
<efx:param name="cold_boot" value="off" value_type="e_bool"/>
|
||||
<efx:param name="cascade" value="off" value_type="e_option"/>
|
||||
</efx:bitstream_generation>
|
||||
<efx:debugger>
|
||||
<efx:param name="work_dir" value="work_dbg" value_type="e_string"/>
|
||||
<efx:param name="auto_instantiation" value="off" value_type="e_bool"/>
|
||||
<efx:param name="profile" value="NONE" value_type="e_string"/>
|
||||
</efx:debugger>
|
||||
<efx:security>
|
||||
<efx:param name="randomize_iv_value" value="on" value_type="e_bool"/>
|
||||
<efx:param name="iv_value" value="" value_type="e_string"/>
|
||||
<efx:param name="enable_bitstream_encrypt" value="off" value_type="e_bool"/>
|
||||
<efx:param name="enable_bitstream_auth" value="off" value_type="e_bool"/>
|
||||
<efx:param name="encryption_key_file" value="NONE" value_type="e_string"/>
|
||||
<efx:param name="auth_key_file" value="NONE" value_type="e_string"/>
|
||||
</efx:security>
|
||||
</efx:project>
|
||||
@@ -0,0 +1 @@
|
||||
create_clock -period 20 -name clk [get_ports i_clk]
|
||||
132
ChaCha20_Poly1305_64/doc/friendly_modular_mult.drawio
Normal file
132
ChaCha20_Poly1305_64/doc/friendly_modular_mult.drawio
Normal file
@@ -0,0 +1,132 @@
|
||||
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
|
||||
<diagram name="Page-1" id="b4c9RxKzofB-lxyaVzG6">
|
||||
<mxGraphModel dx="289" dy="195" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-1" target="yBq3zbYGeky0_LNz2CMc-2">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="680" y="100" />
|
||||
<mxPoint x="580" y="100" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="760" y="140" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-29" value="result" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="yBq3zbYGeky0_LNz2CMc-28">
|
||||
<mxGeometry x="0.7628" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="25" y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-1" value="accumulator w/ wrap" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="640" y="120" width="80" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-2" target="yBq3zbYGeky0_LNz2CMc-1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-2" value="+" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="560" y="120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-5" target="yBq3zbYGeky0_LNz2CMc-2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-5" value="Friendly Modulo" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="80" width="160" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-7" target="yBq3zbYGeky0_LNz2CMc-13">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-7" value="X" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-8" target="yBq3zbYGeky0_LNz2CMc-7">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-8" value="Data (128 bit)" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="80" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-10" target="yBq3zbYGeky0_LNz2CMc-7">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-10" value="h (26x5 bit)" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="160" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-13" target="yBq3zbYGeky0_LNz2CMc-5">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-13" value="pipe reg" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-16" target="yBq3zbYGeky0_LNz2CMc-22">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-16" value="pipe reg" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="160" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-18" target="yBq3zbYGeky0_LNz2CMc-10">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-18" target="yBq3zbYGeky0_LNz2CMc-16">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="100" y="220" />
|
||||
<mxPoint x="260" y="220" />
|
||||
<mxPoint x="260" y="180" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-18" value="state counter" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="240" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.833;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-16" target="yBq3zbYGeky0_LNz2CMc-5">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-22" value="pipe reg" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-23" value="pipe reg" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-26" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-24" target="yBq3zbYGeky0_LNz2CMc-1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-27" value="reset" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="yBq3zbYGeky0_LNz2CMc-26">
|
||||
<mxGeometry x="-0.2" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="-10" y="-9" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-24" target="yBq3zbYGeky0_LNz2CMc-30">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="680" y="260" />
|
||||
<mxPoint x="680" y="200" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-24" value="pipe reg" style="whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="440" y="240" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-32" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="yBq3zbYGeky0_LNz2CMc-30">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="800" y="200" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="800" y="200" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-33" value="done flag" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="yBq3zbYGeky0_LNz2CMc-32">
|
||||
<mxGeometry x="0.1299" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="7" y="-19" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="yBq3zbYGeky0_LNz2CMc-30" value="==4?" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="700" y="180" width="60" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -33,4 +33,86 @@ we need
|
||||
|
||||
r\*r = r^2
|
||||
r\*r^2 = r^3 r^2\*r^2 = r^4
|
||||
r^4\*r = r^5 r^2\*r^4 = r^6 r^3\*r^4 = r^7 r^4\*r^4 = r^8
|
||||
r^4\*r = r^5 r^2\*r^4 = r^6 r^3\*r^4 = r^7 r^4\*r^4 = r^8
|
||||
|
||||
we can do all of these in parallel, so we 4 (n/2) multiply blocks that feed back
|
||||
on themselves, with some kind of FSM to control it. This can be done while another
|
||||
block is being hashed, but there will be a delay between when the key is ready from
|
||||
the chacha block and when the powers are ready, so there needs to be a fifo in between.
|
||||
|
||||
|
||||
Basically we have to wait until we see that the accumulator was written with our index.
|
||||
At reset though, the acumulator is unwritten? So we need to pretend that it was written
|
||||
|
||||
Lets just write out what we want to happen:
|
||||
|
||||
1. The index starts at 0. We accept new data, and send it through the pipeline
|
||||
2. We increment the index to 1.
|
||||
3. We accept new data and send it through the pipeline
|
||||
4. We increment the index to 2
|
||||
5. We need to wait until the index 0 is written before we can say we are ready
|
||||
6. If the index 1 is written then we still need to say we are ready though
|
||||
7. We can just use the 1 to indicate that is a valid write then?
|
||||
|
||||
So in the shift register we just need to say whether it is a valid write or not,
|
||||
so always 1?
|
||||
|
||||
But if we send in 0, then send in 1, then the current index will be 0
|
||||
and eventually the final index will always be 0. We need to store what
|
||||
the last written one is.
|
||||
|
||||
We can just say the last written one was 2 I guess
|
||||
|
||||
We also need an input that tells it to reset the accumulator
|
||||
|
||||
What if instead of calculating all the way up to R^16 I just calculated up to r^8
|
||||
and then just had 2 parallel blocks?
|
||||
|
||||
Lets think about the worst case throughput. The theoretical layout would have
|
||||
8 of these in parallel. A minimum size packet of 64 bytes for example, is 512
|
||||
bits. This is less than 128*8, so it would only take one round. Therefore, we
|
||||
take 16 cycles to do 64 bytes, or 32 bits per cycle. This is only 1/4 of our
|
||||
target throughput. In order to reach our target throughput of 128 bits per cycle,
|
||||
|
||||
If the packet is enough to fit into the second phase of the multiplier, then it
|
||||
can run in parallel and give up to 256 bits per 16 cycles. In order for this to
|
||||
happen, the packet size must be greater than 128*16, or 256 bytes. I would really
|
||||
like to be able to reach our target throughput with 64 byte packets, so we may
|
||||
need to have more smaller multipliers that can run in parallle, at the cost of
|
||||
latency for larger packets.
|
||||
|
||||
a 64 byte packet is 512 bytes, which takes up 4 128 bit lanes. If we have a group
|
||||
of 2 multipliers, they can do 128\*2\*2 bits per 16 cycles, or 512 bits per 16
|
||||
cycles, which is 32 bits per cycle as we said earlier. To hit our target of 128
|
||||
bits per cycle we just instantiate 4 of them. This results in the same number of
|
||||
multipliers (8), but configured differently to prioritize throughput over latency.
|
||||
|
||||
We need to have a demux or whatever go between the groups.
|
||||
|
||||
If we only do 4 effective lanes in parallel, then we only need to do the multiply
|
||||
loop twice
|
||||
|
||||
r->r^2
|
||||
|
||||
This will take 26 cycles, which is not ideal. Could we figure out a way to do all
|
||||
of these powers in one step, taking only 13 cycles?
|
||||
|
||||
Alternatively, we could only do a single parallel step and just calculate R^2. This
|
||||
would mean we have 8 different hashes going on at the same time, and would drastically
|
||||
increase latency, but I think that is a fair tradeoff
|
||||
|
||||
So basically we need to store incoming data as 128 bit words. We will first get
|
||||
r and s as 128 bit words. We store both and start work on squaring r. We will
|
||||
also be recieving data this whole time at 128 bits per cycle which we store in
|
||||
a FIFO. Once R^2 is calculated, we start running it through the multiplier, with
|
||||
a counter that tells us when we should be using R and when we should be using
|
||||
r^2. We only have 1 value to worry about, when we get the last value we only
|
||||
use R instead of R^2. we also need to remember to store the outputs on both
|
||||
last cycles. Since we are storing the data in a FIFO, we will know which is the
|
||||
last. There is also a possibility that the data will not be a full 128 bits, so
|
||||
we need to handle adding the leading 1 as well.
|
||||
|
||||
We can use 1 multiplier, 2 data fifos, 2 constant buffers.
|
||||
|
||||
The utilization of the multiplier is kinda low though since its only used
|
||||
once per packet instaead of every 16 bytes
|
||||
58
ChaCha20_Poly1305_64/doc/notes2.md
Normal file
58
ChaCha20_Poly1305_64/doc/notes2.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Requirements
|
||||
|
||||
* 2 Gbps operation
|
||||
* Handles both encrypt and decrypt
|
||||
|
||||
At reasonable FPGA speed of 250MHz, 2 Gbps requires a minimum width of 8 bits.
|
||||
|
||||
32 bits is a reasonable data width that would be common to see, and lets us
|
||||
have more breathing room while still maintaining line rate.
|
||||
|
||||
Module inputs and outputs
|
||||
|
||||
* clk
|
||||
* rst
|
||||
* data_in [31:0]
|
||||
* data_valid
|
||||
* data_ready
|
||||
* data_last
|
||||
* r [127:0]
|
||||
* s [127:0]
|
||||
* mac [127:0]
|
||||
* mac_valid
|
||||
|
||||
There is no output backpressure. since the result is just a single 128 bit number,
|
||||
we don't need to have a ready signal. if you want to add backpressure, add a register
|
||||
slice on the output outside of this module.
|
||||
|
||||
the real requirement was to get something that works...
|
||||
|
||||
|
||||
we can pipeline chacha20 as much as we want since it is trivially pipelined
|
||||
|
||||
since poly1305 takes in a 32 bit stream, we can redo chacha20 to work on 32 bits
|
||||
at a time instead of 256 bits. We could also reuse stages, so instead of needing
|
||||
all 20 stages we can just have 2 or something.
|
||||
|
||||
BUT since the number 1 requirement is to get it to work, lets just use what we already have.
|
||||
|
||||
okay they 512 bit chacha implementation is a bit crazy. the latency is too high. we need
|
||||
to come up with a way to do it 32 bits at a time.
|
||||
|
||||
each quarter round generates 128 bits, so we could do 1 quarter round at a time and get 128
|
||||
bits per clock cycle, which is plenty fast.
|
||||
|
||||
if we do 1 quarter round per clock cycle, There are 20 rounds, each of which is 4 quarter
|
||||
rounds, so it would take 80 cycles.
|
||||
|
||||
Compared to the current implementation which has 20 rounds, but each round takes 7 cycles,
|
||||
|
||||
|
||||
this has almost half the latency. We still need to store the full state between each round,
|
||||
which is 512 bits.
|
||||
|
||||
|
||||
OHHH there is a big different here with encrypt vs decrypt. basically, it is always
|
||||
the encrypted packet that goes through poly1305. If the packet is being encrypted then
|
||||
it needs to get xored before going into poly1305. If the packet is being decrypted, then it
|
||||
needs to go through poly1305 in parallel with being xored.
|
||||
217
ChaCha20_Poly1305_64/doc/notes3.md
Normal file
217
ChaCha20_Poly1305_64/doc/notes3.md
Normal file
@@ -0,0 +1,217 @@
|
||||
# Data from wireshark
|
||||
|
||||
Ok lets work this out by hand. The encyrpted packet matches exaactly, so we
|
||||
know that the chacha20 part is correct, and this must include the first block
|
||||
which is used for the keys.
|
||||
|
||||
84 bytes rounded to nearest multiple of 16 is 96 bytes. plus 16 for tag is 112.
|
||||
|
||||
so we do know that wireguard is including the tag.
|
||||
|
||||
|
||||
the first output of chacha20, which becomes the keys, is
|
||||
118b9bfd676a3bd991483cb1746252272e032bfbf2597dafec72576a54d9263ae32c815b30dbd75e7000d9ec14aac879075ada63f40d22180741336f9132e14a
|
||||
|
||||
The bottm 256 bits of that is
|
||||
|
||||
e32c815b30dbd75e7000d9ec14aac879075ada63f40d22180741336f9132e14a
|
||||
|
||||
splitting that into 128 bit sections, we get
|
||||
|
||||
0xe32c815b30dbd75e7000d9ec14aac879
|
||||
0x075ada63f40d22180741336f9132e14a
|
||||
|
||||
r_mask is 0x0ffffffc0ffffffc0ffffffc0fffffff
|
||||
|
||||
so out final values of r and s are
|
||||
|
||||
r = 0x075ada60040d22180741336c0132e14a
|
||||
s = 0xe32c815b30dbd75e7000d9ec14aac879
|
||||
|
||||
oh and p = 2**130-5
|
||||
|
||||
These values line up with what what we see in the hardware.
|
||||
|
||||
according to the spec, the algorithm for poly1305 is as follows:
|
||||
|
||||
```text
|
||||
a = 0 /* a is the accumulator */
|
||||
p = (1<<130)-5
|
||||
for i=1 upto ceil(msg length in bytes / 16)
|
||||
n = le_bytes_to_num(msg[((i-1)*16)..(i*16)] | [0x01])
|
||||
a += n
|
||||
a = (r * a) % p
|
||||
end
|
||||
a += s
|
||||
return num_to_16_le_bytes(a)
|
||||
end
|
||||
```
|
||||
|
||||
Here is the cipher, which is msg in this case
|
||||
b"\xa4\xeb\xc1.\xe3\xf9\x90\xda\x18\x03:\x07\x89\xc0N'\x00\xf6\xf5\xc2q\xd4*\xc4\xb4\xd6&.feI\xb4E\xa7Cn\x82\x9b\xff\xb6\xace\xf0VH\xbc\x0c9\x1f\xe7\xc5\x88Ht7a'\x16I@\x18\x8f\x03\xdb\xa6z\xf88\x8e\xaa\xb7lY6(\xbf\x9d\xc7\xbe\x034m\x91.\x91m\xad\x86%EEG\x016O-"
|
||||
|
||||
here it is split up into 16 byte chunks
|
||||
|
||||
b"\xa4\xeb\xc1.\xe3\xf9\x90\xda\x18\x03:\x07\x89\xc0N'"
|
||||
b'\x00\xf6\xf5\xc2q\xd4*\xc4\xb4\xd6&.feI\xb4'
|
||||
b'E\xa7Cn\x82\x9b\xff\xb6\xace\xf0VH\xbc\x0c9'
|
||||
b"\x1f\xe7\xc5\x88Ht7a'\x16I@\x18\x8f\x03\xdb"
|
||||
b'\xa6z\xf88\x8e\xaa\xb7lY6(\xbf\x9d\xc7\xbe\x03'
|
||||
b'4m\x91.\x91m\xad\x86%EEG\x016O-'
|
||||
|
||||
The length of the message is 96 bytes, so we have our 6 16 byte chunks.
|
||||
|
||||
the next step is to interpret these as little endian integers, then add a leading 1.
|
||||
|
||||
|
||||
0x1274ec089073a0318da90f9e32ec1eba4
|
||||
0x1b44965662e26d6b4c42ad471c2f5f600
|
||||
0x1390cbc4856f065acb6ff9b826e43a745
|
||||
0x1db038f18404916276137744888c5e71f
|
||||
0x103bec79dbf2836596cb7aa8e38f87aa6
|
||||
0x12d4f36014745452586ad6d912e916d34
|
||||
|
||||
DON'T FORGET ABOUT THE LENGTHS!
|
||||
The length of AAD is 0, and the length of the ciphertext is 96,
|
||||
that becomes
|
||||
|
||||
this is aad length, data_length
|
||||
be careful of the order, since aad length comes first, it is on the
|
||||
right side of this hex number, since its little endian.
|
||||
|
||||
0x100000000000000600000000000000000
|
||||
|
||||
And these also match the hardware, so we are doing good so far.
|
||||
|
||||
so after the first round, a = (r * n) % p, since a started at 0, a+=n is just n
|
||||
so a = 0xcfd86a9543d3377baf5be686c46d8491
|
||||
|
||||
ok looks good so far.
|
||||
|
||||
next is 0x312e451b2a526811c5bd976ce3c27d5e7, looks good as well. the next values in a row are
|
||||
|
||||
0x22097b74ef42792da5e02cf9dd8249776
|
||||
0x2586a4ee24499da642fb6392be59137b2
|
||||
0xff1ba4984e72db7199c786a00de9de1e
|
||||
0x2850e6cbbf9869bf410976e82e2ee9b04
|
||||
0x38878751382017086bc63eee8ba2cbdab
|
||||
|
||||
which all match still. So the final step is to add s,
|
||||
|
||||
0x46ba4f66eb2dd47e52c64c8d4ced78624
|
||||
|
||||
and truncate to 128 bits
|
||||
|
||||
6ba4f66eb2dd47e52c64c8d4ced78624
|
||||
|
||||
SO basically we need to appaned the length to the data when it is going through poly1305.
|
||||
poly1305 should be able to look at the input fifo and know when it is outputting the last
|
||||
valid beat. After this, we need to output the lengths.
|
||||
|
||||
|
||||
## Keepalive Packets
|
||||
|
||||
These packets have zero data. They will need to be handled separately.
|
||||
|
||||
After We can look at the UDP length to figure out if it is a keepalive packet,
|
||||
this only serves to tell software if the connection has failed. We will
|
||||
need to support sending and receiving these at some point, most likely in
|
||||
hardware since they need to be authenticated, but they have no data.
|
||||
perhaps some tuser flag can be passed in to bypass the crypto. We can
|
||||
send in 16 bytes of zeroes but the user flag says to not actually send
|
||||
this to poly1305, and the result can just be dropped after resetting some kind
|
||||
of counter, or we can drop the data and just encapsulate the poly1305 tag.
|
||||
|
||||
## Padding is not always 16 bytes
|
||||
|
||||
The packets are 16 byte aligned UNLESS this would bring the packet over the MTU.
|
||||
What this means in practice is that we might receive packets which are not 16
|
||||
byte aligned. If we are decrypting a packet, the length must be what the packet
|
||||
actually is and not rounded up. We also need to be careful when we are sending
|
||||
out packets that we can't always go up to 1500 bytes.
|
||||
|
||||
(Might have to tell end users to set their MTU to 1300 or something).
|
||||
|
||||
If we are decrypting then, the width convert should not round up.
|
||||
|
||||
Or... we can just put that in a different module and not have random rules in the
|
||||
crypto block itself.
|
||||
|
||||
This also breaks the poly1305, because it is expecting exactly 128 bits every time,
|
||||
so it has a specific cycle for the lengths. BUT if the incoming data is not 16 byte
|
||||
aligned, then the lengths will be added at the wrong time. So, based on the length
|
||||
of the packet, we need to be adding the lengths at a varying position at the end
|
||||
of the packet. It might be split over 2 cycles, depending on what the length is.
|
||||
we can figure this out easily by simply taking the length of the packet (which
|
||||
we have counted already) modulo 16, aka & 0xf. In this case, the length of the packet
|
||||
is 1420, so the counter is 12. What this means is that the last packet is only
|
||||
12 bytes, so we need to shift 4 bytes of the counter into the last data beat.
|
||||
|
||||
How do we know its the last data beat? the upconvert module gives us last. Technically
|
||||
we calulate the total length based on this output. whatever.
|
||||
|
||||
So in the sum state, we set the last flag based on upconvert_last. If this is true,
|
||||
we also need to check if upconvert_countm1 is 0xf, or if its smaller than that. if
|
||||
its 15, then we do what we normally do, just 1 extend the existing data. If it is not,
|
||||
then we need to do 15 - countm1 bytes of the length packet.
|
||||
|
||||
* padding2 -- the padding is up to 15 zero bytes, and it brings
|
||||
the total length so far to an integral multiple of 16. If the
|
||||
length of the ciphertext was already an integral multiple of 16
|
||||
bytes, this field is zero-length.
|
||||
|
||||
wait... we should still be adding this padding ourselves...
|
||||
|
||||
this is actually an embarassingly easy fix.
|
||||
|
||||
|
||||
1420 bytes of inner ip
|
||||
|
||||
16 bytes of wireguard header
|
||||
16 bytes of wireguard signature
|
||||
|
||||
8 bytes of udp
|
||||
|
||||
20 bytes of ipv4
|
||||
|
||||
14 bytes of ethernet
|
||||
|
||||
so if you are just looking at wireguard itself, its max is 1420 + 32?
|
||||
|
||||
or, is it that we set the MTU to 1420 which is the max sized of the
|
||||
encrypted packet, so we can't add any padding?
|
||||
|
||||
OK in the width expander we expand to 1420 max.
|
||||
|
||||
we could have a check at the begining that checks the
|
||||
total length. If it is larger than 1420 then we can
|
||||
send the packet to the CPU to fragment or do something with
|
||||
But really all computers that are on the network should
|
||||
have the MTU set to 1420 so that we can avoid this.
|
||||
|
||||
|
||||
One thing we still need to support is keepalive packets. These have
|
||||
no payload, but still need to be decrypted. The input FSM will take
|
||||
in just the encrypted wireguard packet, without the wireguard header.
|
||||
It will then strip off the tag and put it in a fifo for the output fsm
|
||||
to read. If it does this to a keepalive packet, there will be no data.
|
||||
If this happens, the input FSM will send in 64 bytes of dummy data,
|
||||
all zeroes, along with a keepalive signal. this signal will be stored
|
||||
along with the packet and when it is output to the output fsm, it will
|
||||
know to ignore the actual data.
|
||||
|
||||
I think this can be done entirely outside of the crypto block.
|
||||
|
||||
OK so that tells us what we need to do next, the pre and postformat FSM.
|
||||
|
||||
preformat FSM removes the tag, postformat FSM adds the tag back for encyrpt,
|
||||
or compares the tag with the expected tag for decrypt.
|
||||
|
||||
We need a metadata FIFO which tells us whether to encyrpt or decrypt.
|
||||
|
||||
ohhhh right. what I really wanted to do today was synthesize this block
|
||||
and see what the timing looks like.
|
||||
|
||||
|
||||
We pass timing at 67 MHz. Lets try to reduce the number of flop stages in
|
||||
chacha to see if we can reduce the number of flops we use.
|
||||
@@ -1,144 +1,128 @@
|
||||
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
|
||||
<diagram name="Page-1" id="gIy_vrPza4QP03Kn0wfk">
|
||||
<mxGraphModel dx="655" dy="442" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<diagram name="Page-1" id="b4c9RxKzofB-lxyaVzG6">
|
||||
<mxGraphModel dx="794" dy="536" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-1" target="GA09nmFLpfHeItamLD5O-21">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-1" target="FEGHAENOx_VuAQpIDQKO-15">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-25" value="r" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="GA09nmFLpfHeItamLD5O-24">
|
||||
<mxGeometry x="0.5579" y="-1" relative="1" as="geometry">
|
||||
<mxPoint x="9" y="5" as="offset" />
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-20" value="last" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="FEGHAENOx_VuAQpIDQKO-19">
|
||||
<mxGeometry x="-0.5549" y="-1" relative="1" as="geometry">
|
||||
<mxPoint y="9" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-1" target="GA09nmFLpfHeItamLD5O-34">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-1" value="data fifo" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="120" width="280" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.75;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-2" target="FEGHAENOx_VuAQpIDQKO-1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-38" value="s" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="GA09nmFLpfHeItamLD5O-35">
|
||||
<mxGeometry x="-0.6624" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="-9" y="-9" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-1" value="r/s" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="200" width="80" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-2" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" target="GA09nmFLpfHeItamLD5O-1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="320" y="210" as="sourcePoint" />
|
||||
<mxPoint x="410" y="270" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-3" value="otk" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="GA09nmFLpfHeItamLD5O-2">
|
||||
<mxGeometry x="-0.3946" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="-22" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-4" target="GA09nmFLpfHeItamLD5O-6">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-2" target="FEGHAENOx_VuAQpIDQKO-6">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-4" value="64-&gt;128" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="175" y="130" width="50" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-5" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="GA09nmFLpfHeItamLD5O-4">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="120" y="140" as="sourcePoint" />
|
||||
<mxPoint x="290" y="110" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-6" target="GA09nmFLpfHeItamLD5O-14">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-40" value="data_one_extended" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="GA09nmFLpfHeItamLD5O-15">
|
||||
<mxGeometry x="-0.3532" y="-1" relative="1" as="geometry">
|
||||
<mxPoint x="7" y="29" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-6" value="bit add" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="240" y="120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-8" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" target="GA09nmFLpfHeItamLD5O-6">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="260" y="80" as="sourcePoint" />
|
||||
<mxPoint x="290" y="70" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-9" value="tkeep" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="GA09nmFLpfHeItamLD5O-8">
|
||||
<mxGeometry x="-0.699" relative="1" as="geometry">
|
||||
<mxPoint y="-16" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-11" value="P" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="540" y="180" width="80" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-12" target="GA09nmFLpfHeItamLD5O-14">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-2" target="FEGHAENOx_VuAQpIDQKO-8">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="340" y="100" />
|
||||
<mxPoint x="100" y="210" />
|
||||
<mxPoint x="100" y="250" />
|
||||
<mxPoint x="260" y="250" />
|
||||
<mxPoint x="260" y="220" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-36" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-12" target="GA09nmFLpfHeItamLD5O-34">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-2" value="" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=-90;" vertex="1" parent="1">
|
||||
<mxGeometry y="160" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-4" target="FEGHAENOx_VuAQpIDQKO-27">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="400" y="60" />
|
||||
<mxPoint x="660" y="60" />
|
||||
<mxPoint x="420" y="260" />
|
||||
<mxPoint x="420" y="300" />
|
||||
<mxPoint x="780" y="300" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-12" value="acc" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="360" y="80" width="80" height="40" as="geometry" />
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-4" value="s" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="240" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-14" value="+" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="320" y="120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-32" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-21" target="GA09nmFLpfHeItamLD5O-31">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-21" value="*" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="440" y="120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-14" target="GA09nmFLpfHeItamLD5O-21">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="460" y="140" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-41" value="data_post_add" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="GA09nmFLpfHeItamLD5O-22">
|
||||
<mxGeometry x="-0.1925" y="-1" relative="1" as="geometry">
|
||||
<mxPoint x="8" y="19" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-26" value="%" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="560" y="120" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.51;entryY=1.007;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-11" target="GA09nmFLpfHeItamLD5O-26">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1.022;entryY=0.482;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-26" target="GA09nmFLpfHeItamLD5O-12">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-2" target="FEGHAENOx_VuAQpIDQKO-4">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="580" y="99" />
|
||||
<mxPoint x="100" y="210" />
|
||||
<mxPoint x="100" y="260" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-33" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-31" target="GA09nmFLpfHeItamLD5O-26">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-6" target="FEGHAENOx_VuAQpIDQKO-8">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-31" value="reg" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="500" y="130" width="40" height="20" as="geometry" />
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-6" value="multiplier" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="120" y="200" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-37" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="GA09nmFLpfHeItamLD5O-34">
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-8" target="FEGHAENOx_VuAQpIDQKO-15">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-22" value="r<sup>2</sup>" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="FEGHAENOx_VuAQpIDQKO-16">
|
||||
<mxGeometry x="-0.2366" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="2" y="-9" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-8" target="FEGHAENOx_VuAQpIDQKO-15">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-23" value="r" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="FEGHAENOx_VuAQpIDQKO-17">
|
||||
<mxGeometry x="-0.2762" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="3" y="11" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-8" value="r<sup>2</sup>/r" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="200" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-11" target="FEGHAENOx_VuAQpIDQKO-27">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-11" value="Poly1305 Stage" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="480" y="120" width="240" height="160" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.125;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-1" target="FEGHAENOx_VuAQpIDQKO-11">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-21" value="data" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="FEGHAENOx_VuAQpIDQKO-12">
|
||||
<mxGeometry x="-0.1705" relative="1" as="geometry">
|
||||
<mxPoint y="-10" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-15" value="" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=90;size=10;" vertex="1" parent="1">
|
||||
<mxGeometry x="410" y="210" width="40" height="20" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.625;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-15" target="FEGHAENOx_VuAQpIDQKO-11">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.125;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-1" target="FEGHAENOx_VuAQpIDQKO-11">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="720" y="140" as="targetPoint" />
|
||||
<Array as="points">
|
||||
<mxPoint x="410" y="130" />
|
||||
<mxPoint x="410" y="100" />
|
||||
<mxPoint x="510" y="100" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-39" value="tag" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="GA09nmFLpfHeItamLD5O-37">
|
||||
<mxGeometry x="0.6531" y="2" relative="1" as="geometry">
|
||||
<mxPoint x="17" y="2" as="offset" />
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-26" value="sop" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="FEGHAENOx_VuAQpIDQKO-25">
|
||||
<mxGeometry x="-0.0418" relative="1" as="geometry">
|
||||
<mxPoint x="13" y="-10" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="GA09nmFLpfHeItamLD5O-34" value="+" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="640" y="120" width="40" height="40" as="geometry" />
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-30" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="FEGHAENOx_VuAQpIDQKO-27">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="840" y="200" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-27" value="+" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="760" y="180" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="FEGHAENOx_VuAQpIDQKO-31" value="<h1 style="margin-top: 0px;">Poly1305</h1><p>Axi Stream&nbsp;</p>" style="text;html=1;whiteSpace=wrap;overflow=hidden;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="80" y="320" width="360" height="160" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
|
||||
102
ChaCha20_Poly1305_64/doc/poly1305_2.drawio
Normal file
102
ChaCha20_Poly1305_64/doc/poly1305_2.drawio
Normal file
@@ -0,0 +1,102 @@
|
||||
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/29.3.0 Chrome/140.0.7339.249 Electron/38.7.2 Safari/537.36" version="29.3.0">
|
||||
<diagram name="Page-1" id="k3McRs0H2XJFCpbK3g7K">
|
||||
<mxGraphModel dx="1008" dy="674" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-6" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-5">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-24" edge="1" parent="1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" target="EpKCKhKhuYmIKFkPyJMO-1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="79.99999999999989" y="260.0000000000001" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-25" connectable="0" parent="EpKCKhKhuYmIKFkPyJMO-24" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" value="din[31:0]" vertex="1">
|
||||
<mxGeometry relative="1" x="-0.8485" as="geometry">
|
||||
<mxPoint x="-33" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-1" parent="1" style="rounded=0;whiteSpace=wrap;html=1;" value="32 -&gt; 128&nbsp;<div>width convert</div>" vertex="1">
|
||||
<mxGeometry height="40" width="120" x="120" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-3" parent="1" style="rounded=0;whiteSpace=wrap;html=1;" value="h [129:0]" vertex="1">
|
||||
<mxGeometry height="40" width="80" x="360" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-11" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-8">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-5" parent="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" value="+" vertex="1">
|
||||
<mxGeometry height="40" width="40" x="280" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-7" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1.046;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" target="EpKCKhKhuYmIKFkPyJMO-5">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-14" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-13">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-8" parent="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" value="*" vertex="1">
|
||||
<mxGeometry height="40" width="40" x="280" y="320" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-10" edge="1" parent="1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-8">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="80" y="340" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-22" connectable="0" parent="EpKCKhKhuYmIKFkPyJMO-10" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" value="r [127:0]" vertex="1">
|
||||
<mxGeometry relative="1" x="-0.8764" y="-1" as="geometry">
|
||||
<mxPoint x="-42" y="-1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-15" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-3">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="460" y="340" />
|
||||
<mxPoint x="460" y="260" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-19" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-13" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-16">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="460" y="340" />
|
||||
<mxPoint x="460" y="260" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-13" parent="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" value="%" vertex="1">
|
||||
<mxGeometry height="40" width="40" x="380" y="320" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-21" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-20">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-16" parent="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" value="+" vertex="1">
|
||||
<mxGeometry height="40" width="40" x="480" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-18" edge="1" parent="1" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" target="EpKCKhKhuYmIKFkPyJMO-16">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="80" y="420" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-23" connectable="0" parent="EpKCKhKhuYmIKFkPyJMO-18" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" value="s [127:0]" vertex="1">
|
||||
<mxGeometry relative="1" x="-0.975" y="1" as="geometry">
|
||||
<mxPoint x="-37" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-26" edge="1" parent="1" source="EpKCKhKhuYmIKFkPyJMO-20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="640" y="260" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-27" connectable="0" parent="EpKCKhKhuYmIKFkPyJMO-26" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" value="mac [127:0]" vertex="1">
|
||||
<mxGeometry relative="1" x="0.7484" y="1" as="geometry">
|
||||
<mxPoint x="35" y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="EpKCKhKhuYmIKFkPyJMO-20" parent="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" value="%" vertex="1">
|
||||
<mxGeometry height="40" width="40" x="560" y="240" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
59
ChaCha20_Poly1305_64/doc/poly1305_second_attempt.drawio
Normal file
59
ChaCha20_Poly1305_64/doc/poly1305_second_attempt.drawio
Normal file
@@ -0,0 +1,59 @@
|
||||
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
|
||||
<diagram name="Page-1" id="b4c9RxKzofB-lxyaVzG6">
|
||||
<mxGraphModel dx="616" dy="416" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-7" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="3x5Ie6wAwAZYy6GZGmB0-1" target="3x5Ie6wAwAZYy6GZGmB0-6">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="500" y="160" />
|
||||
<mxPoint x="500" y="230" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="3x5Ie6wAwAZYy6GZGmB0-1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="560" y="160" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-1" value="Modular Multiplier (10 cycle latency)" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="280" y="120" width="200" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="3x5Ie6wAwAZYy6GZGmB0-6" target="3x5Ie6wAwAZYy6GZGmB0-10">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-6" value="H temp" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="345" y="210" width="80" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="3x5Ie6wAwAZYy6GZGmB0-10" target="3x5Ie6wAwAZYy6GZGmB0-1">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-10" value="+" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="160" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-13" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="3x5Ie6wAwAZYy6GZGmB0-10">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="160" y="180" as="sourcePoint" />
|
||||
<mxPoint x="170" y="140" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-14" value="message" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="3x5Ie6wAwAZYy6GZGmB0-13">
|
||||
<mxGeometry x="-0.1731" y="1" relative="1" as="geometry">
|
||||
<mxPoint x="-46" y="1" as="offset" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="3x5Ie6wAwAZYy6GZGmB0-15" target="3x5Ie6wAwAZYy6GZGmB0-1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="220" y="140" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="3x5Ie6wAwAZYy6GZGmB0-15" value="r" style="shape=trapezoid;perimeter=trapezoidPerimeter;whiteSpace=wrap;html=1;fixedSize=1;rotation=0;flipV=1;size=10;" vertex="1" parent="1">
|
||||
<mxGeometry x="190" y="90" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
29
ChaCha20_Poly1305_64/doc/sanity.py
Normal file
29
ChaCha20_Poly1305_64/doc/sanity.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import base64
|
||||
|
||||
data = base64.decodebytes(b"BAAAALme3iYDAAAAAAAAAK0SmHnTT056FRHPMd66WYNlCDTwvJhkJx79R5psrl+fL/89gBZYHL2mjT9C+55tJuUVjHXYKMYdEVgn2he8p65W7BheKppBmq3mKfRezs8pRpgGVO4yI03t5BponGYn8xC71VtMPWxpBYdy9HsHNiZj4jGT30O+WPrdQTL10beu6ao+qEXUUD1hVHSKcpgOGp/xll7AjPYs1OEt64exAfO8pFeZtQTp16cLuiPNqMld3EYh2p7lF/Ry9GO3lB9sp/PB6cfSOOvLViZ3wsiCF/Q7awYqFuCrcMjU1RQs7RPGW4fhiFazl9NsvSuBvWMII48keUCtkLnbqv9dBZM7BPCVePAwFW5iPZOa7vkxaPF6pqWDSgTwRiLICiix5wQL0a0cBpgMxryNCxmvyRKUyRdo1RFMayfXFOp+6DqmUrNbBr3dnDGE87XuAkOnx9m/DR/yBI/iiePSCnsxeyJVwtBVJeDdzwZAyrVR9vYFfyVRH4MirZYuw33VkTA98OEXcqrdTSOvsTn04JL/1DmKTjdj8HHjtuBism6vOofdrFRmVSREAiE5tI4HecIkZV/iu2345JIe8FTWZZVfvIVG9VamkHPLe0gBQR4eeLfUWIlRQrU+aiWQBaZKMxooyYwZPZGTlUtKmU/Q1/cJ9GeBKuD6Txge+/okOlqvPXgCHeyiAiSHVJ/2lWHTK7BPyPwcIik3q+dIUpIwL5/7doYDcezpnscB5o/KjAvBw3YwqAuNLyVuqFrMGti1eCTi1ll016slCEbDGRvHYielCtdzkw7vYhIPE+k37FxXByoJ3jg5NlOrbRoVvO25Hy2rP4SYMmQ3dEQNRDVkCy8yvQRSAI1UOknXnpDo+SU50FKcmdB94htpRM+ddADNUmJPD7JJAI8AFgkMN7Zujgq7v2ZSXNhpDX1MD+7zdYUwu8GsldMKTYtz+BaShoJtcSSmXYdAup8i12lGBtJJf7FxANSweg5bHgr3OE9VLJZq5JIKhY+0cIKRF8ymI5of9vXETGT7JQe26QVn8zekevI183yiqS5qbxqdt96eT1/W8mF/2TNCYBgiP135gKwVoS3ZY/0kWrx5oN0TXSGjMkRnhucEjsw5W18CFJo+labHkmuZUJ+rdVfEviady27EwgIcU2sGWPWn7jw+WPOG+709CBGtfw7/Ld6MDmNsvT9m7mvTKOVIHxJyaiA997y9P4FD4mjjlHbtncJRtUeqrW4GXrQouF9ur2+OIMAkmo1jz51j6UbyT2RUwr+ABWfwfHUxDzwxRuhj0rodw3a3ZiFtGqIXYeDavMOE3Okn/zSGETIHOnfTufGBddxSRaOUGGMv6xBXzzq+qja6JMLx/M15yhTQE2NpVrNevbrMBBE7TdOVyZP4AdvQOByO1AcTjKtOgKaPfUQeHjn21/43VO9VhnNqozlU5n1ud+xxE+CKwt7kQ9TOn4UVF/x4poIJdV851jIehBZNR+ntWFPr4wc6WMggOJ3//UWKiAvKXrsKk3YsJLdVKIqBnXD3tewpb324LVkizIaUNH1ZWWAxZa/B1Rn3K8fwKl73G+d6I6uNcz0RiiAEYKoEkN7Web3KmIQYIyT4UN2I4HfjRy0i0rXEuEevDarBbfww+fgefYf9lu3hgre4/XMuuuBnjKK4+3BNkT9ipmOzm0gH3LT470OWEDFqm+SaIVW//VdijHsWJkFiSdD8QFYQtjgII1+d1XWXmZdocWm2iDje+4CX/14b+ZQgpWWgHJ+RiYOjEWnNzRtNyy9FrkQxzzlCIgz6hu+E8eDQExP7qunniB6UBPTkmutaaNXhrG4/oWT4yBx0HAmI/VrA/M/AmsDlRpp8MO0zwFQuLbb6aXm1CO88TIeCkXbCsYiy13edfJbf0FsLhIp4P9ZqX07Ug6SKcT8ZjHkc")[16:-16]
|
||||
|
||||
r = 0xb92cdec04e0255000c2c598066eeefa
|
||||
s = 0xef4af5c5bed427d0e93cf8da2ffa5c6
|
||||
|
||||
p = 2**130 - 5
|
||||
|
||||
chunked_data = []
|
||||
while len(data) > 0:
|
||||
chunk_bytes = data[:16]
|
||||
chunk = int.from_bytes(chunk_bytes, "little")
|
||||
chunk |= 1 << (8*len(chunk_bytes))
|
||||
chunked_data.append(chunk)
|
||||
|
||||
data = data[16:]
|
||||
|
||||
a = 0
|
||||
|
||||
for chunk in chunked_data:
|
||||
a += chunk
|
||||
a = (r * a) % p
|
||||
|
||||
print(hex(a))
|
||||
|
||||
a += s
|
||||
|
||||
print(hex(a))
|
||||
@@ -1 +1 @@
|
||||
create_clock -period 2.5 -name clk [get_ports i_clk]
|
||||
create_clock -period 20 -name clk [get_ports i_clk]
|
||||
@@ -1,16 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<efx:project name="poly1305_timing_test" description="" last_change="1752448578" sw_version="2025.1.110" last_run_state="pass" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:project name="poly1305_timing_test" description="" last_change="1784047128" sw_version="2025.1.110" last_run_state="pass" last_run_flow="bitstream" config_result_in_sync="true" design_ood="sync" place_ood="sync" route_ood="sync" xmlns:efx="http://www.efinixinc.com/enf_proj" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.efinixinc.com/enf_proj enf_proj.xsd">
|
||||
<efx:device_info>
|
||||
<efx:family name="Titanium"/>
|
||||
<efx:device name="Ti375N1156"/>
|
||||
<efx:timing_model name="C4"/>
|
||||
</efx:device_info>
|
||||
<efx:design_info def_veri_version="sv_09" def_vhdl_version="vhdl_2008" unified_flow="false">
|
||||
<efx:top_module name="mult_timing_test"/>
|
||||
<efx:design_file name="../src/poly1305_core.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../../common/sim/sub/taxi/src/axis/rtl/taxi_axis_if.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../sim/poly1305_core_wrapper.sv" version="default" library="default"/>
|
||||
<efx:design_file name="mult_timing_test.sv" version="default" library="default"/>
|
||||
<efx:top_module name="chacha20_flat_qr"/>
|
||||
<efx:design_file name="../src/poly1305_ll_stage.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/poly1305_width_convert.sv" version="default" library="default"/>
|
||||
<efx:design_file name="../src/chacha20_flat_qr.sv" version="default" library="default"/>
|
||||
<efx:top_vhdl_arch name=""/>
|
||||
</efx:design_info>
|
||||
<efx:constraint_info>
|
||||
@@ -41,7 +40,7 @@
|
||||
<efx:param name="min-sr-fanout" value="0" value_type="e_integer"/>
|
||||
<efx:param name="min-ce-fanout" value="0" value_type="e_integer"/>
|
||||
<efx:param name="mode" value="speed" value_type="e_option"/>
|
||||
<efx:param name="mult-auto-pipeline" value="1" value_type="e_integer"/>
|
||||
<efx:param name="mult-auto-pipeline" value="0" value_type="e_integer"/>
|
||||
<efx:param name="mult-decomp-retime" value="1" value_type="e_option"/>
|
||||
<efx:param name="operator-sharing" value="1" value_type="e_option"/>
|
||||
<efx:param name="optimize-adder-tree" value="1" value_type="e_option"/>
|
||||
|
||||
344
ChaCha20_Poly1305_64/sim/chacha20_poly1305_32_ll_core.py
Normal file
344
ChaCha20_Poly1305_64/sim/chacha20_poly1305_32_ll_core.py
Normal file
@@ -0,0 +1,344 @@
|
||||
import cocotb
|
||||
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer, RisingEdge, FallingEdge
|
||||
from cocotb.handle import Immediate
|
||||
from cocotb.queue import Queue
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from chacha_helpers import chacha_block
|
||||
|
||||
import random
|
||||
|
||||
import base64
|
||||
|
||||
import struct
|
||||
|
||||
CLK_PERIOD = 20
|
||||
|
||||
NONCE_BYTES = b"\x00\x00\x00\x00\x00\x00\x00\x4a\x00\x00\x00\x00"
|
||||
KEY_BYTES = b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
|
||||
MSG_BYTES = b"Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."
|
||||
|
||||
|
||||
NONCE = int.from_bytes(NONCE_BYTES, "little")
|
||||
KEY = int.from_bytes(KEY_BYTES, "little")
|
||||
|
||||
CONSTANT = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574]
|
||||
|
||||
output_queue = Queue()
|
||||
|
||||
async def receieve_output(dut):
|
||||
packet = bytearray()
|
||||
while True:
|
||||
if dut.o_data_valid.value:
|
||||
packet.extend(int(dut.o_data.value).to_bytes(4, "little"))
|
||||
if dut.o_data_last.value:
|
||||
await output_queue.put(bytes(packet))
|
||||
packet = bytearray()
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
# @cocotb.test
|
||||
async def test_sanity(dut):
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
cocotb.start_soon(receieve_output(dut))
|
||||
|
||||
for counter in range(3):
|
||||
data_in = CONSTANT[:]
|
||||
data_in.extend(struct.unpack("8I", KEY_BYTES))
|
||||
data_in.extend(struct.unpack("1I", counter.to_bytes(4, "little")))
|
||||
data_in.extend(struct.unpack("3I", NONCE_BYTES))
|
||||
|
||||
data_out = chacha_block(data_in)
|
||||
|
||||
print([f"{data:x}" for data in data_out])
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_nonce.value = NONCE
|
||||
dut.i_key.value = KEY
|
||||
|
||||
dut.i_data_ready.value = 1
|
||||
|
||||
N_PKTS = 100
|
||||
|
||||
for _ in range(N_PKTS):
|
||||
dut.i_last.value = 0
|
||||
dut.i_valid.value = 1
|
||||
msg = MSG_BYTES
|
||||
while len(msg) > 0:
|
||||
part = msg[0:4]
|
||||
dut.i_data.value = int.from_bytes(part, "little")
|
||||
dut.i_countm1.value = len(part)-1
|
||||
if len(msg) < 4:
|
||||
dut.i_last.value = 1
|
||||
msg = msg[4:]
|
||||
await RisingEdge(dut.i_clk)
|
||||
while not dut.o_ready.value:
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
for _ in range(N_PKTS):
|
||||
packet = await output_queue.get()
|
||||
print(packet)
|
||||
|
||||
|
||||
@dataclass
|
||||
class CipherContext():
|
||||
key: int
|
||||
counter: int
|
||||
encrypt: int
|
||||
tag: int
|
||||
cipher: bytes
|
||||
clear: bytes
|
||||
|
||||
|
||||
MESSAGE_KEY_1_BYTES = base64.decodebytes(b"IA7buFUDsARj+YequW4OfQR3JsaE9M88dpXKrDjKzIs=")
|
||||
MESSAGE_KEY_2_BYTES = base64.decodebytes(b"3sZ+QBcwflnvE8t4jv9qgIqIOVaXXwO1bxRo9qWB1fM=")
|
||||
|
||||
MESSAGE_KEY_1 = int.from_bytes(MESSAGE_KEY_1_BYTES, "little")
|
||||
MESSAGE_KEY_2 = int.from_bytes(MESSAGE_KEY_2_BYTES, "little")
|
||||
|
||||
MESSAGE_KEY_3_BYTES = base64.decodebytes(b"LbEI5uiueAZ2LJEg41FbMw6l8ZM3ZtaTrKLOb3dT7QI=")
|
||||
MESSAGE_KEY_4_BYTES = base64.decodebytes(b"H8xSW7vRDaYfl5RilWIwkdF0ehDo30tEJO/IzJMTezY=")
|
||||
|
||||
MESSAGE_KEY_3 = int.from_bytes(MESSAGE_KEY_3_BYTES, "little")
|
||||
MESSAGE_KEY_4 = int.from_bytes(MESSAGE_KEY_4_BYTES, "little")
|
||||
|
||||
PACKETS = [
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_1,
|
||||
counter=0,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAAAb0fasAAAAAAAAAAKTrwS7j+ZDaGAM6B4nATicA9vXCcdQqxLTWJi5mZUm0RadDboKb/7asZfBWSLwMOR/nxYhIdDdhJxZJQBiPA9umevg4jqq3bFk2KL+dx74DNG2RLpFtrYYlRUVHATZPLSSG187UyGQs5Ufdsm72pGs=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAAAb0fasAAAAAAAAAAKTrwS7j+ZDaGAM6B4nATicA9vXCcdQqxLTWJi5mZUm0RadDboKb/7asZfBWSLwMOR/nxYhIdDdhJxZJQBiPA9umevg4jqq3bFk2KL+dx74DNG2RLpFtrYYlRUVHATZPLSSG187UyGQs5Ufdsm72pGs=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAVOVGQABAAUFMCgoAAgoKAAEIAPlcbAAAAG+tIvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_2,
|
||||
counter=0,
|
||||
encrypt=0,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAANg30DAAAAAAAAAAAG9PCA6fUmkbvpSFNfecE+1o8JFF1SPu2whyZfloCC9wc1cpJj7aYnx2g83AuAozVtlTbJ8OKHJ5e1yBcguguOpyM8bev58PvujxDsGJhbgkvzUPi4GA0Ipk5r6YEAiaw9E2PtXhKcoeBCXPfpSWVlk=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAANg30DAAAAAAAAAAAG9PCA6fUmkbvpSFNfecE+1o8JFF1SPu2whyZfloCC9wc1cpJj7aYnx2g83AuAozVtlTbJ8OKHJ5e1yBcguguOpyM8bev58PvujxDsGJhbgkvzUPi4GA0Ipk5r6YEAiaw9E2PtXhKcoeBCXPfpSWVlk=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAVKEdAABAAcV1CgoAAQoKAAIAAAFdbAAAAG+tIvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_1,
|
||||
counter=1,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAAAb0fasBAAAAAAAAAHzNKCSiKfzNFoU7Hv+UasxWNazSNhCJwxaXBs4Pz2LNqySyHtibW+QDk8FpLPp6KYHljK6RU0il+fyDPap6kagbUeVbtzLq3DhtalfmJbCSy1upQ/apOsaaBwHpnmAipi8Gbzy2IjKAkdrVnfE/bjM=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAAAb0fasBAAAAAAAAAHzNKCSiKfzNFoU7Hv+UasxWNazSNhCJwxaXBs4Pz2LNqySyHtibW+QDk8FpLPp6KYHljK6RU0il+fyDPap6kagbUeVbtzLq3DhtalfmJbCSy1upQ/apOsaaBwHpnmAipi8Gbzy2IjKAkdrVnfE/bjM=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAVOYnQABAAUBrCgoAAgoKAAEIALT9bAAAAaQLMvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_2,
|
||||
counter=1,
|
||||
encrypt=0,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAANg30DABAAAAAAAAAEnLMkirrPEmhurVsmRHh5lF0OHX0qYLVBL6ud2/nel70Iv6tf/m/76DfaEOzFYj9Muj7omVUEI90wZsW0+5sBoKcaivdUZhWC6g9ARJI0fqt/R+aXE2Kci0l8p5cgFBcLLDnZnBQcGf4VNr6+uPvyk=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAANg30DABAAAAAAAAAEnLMkirrPEmhurVsmRHh5lF0OHX0qYLVBL6ud2/nel70Iv6tf/m/76DfaEOzFYj9Muj7omVUEI90wZsW0+5sBoKcaivdUZhWC6g9ARJI0fqt/R+aXE2Kci0l8p5cgFBcLLDnZnBQcGf4VNr6+uPvyk=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAVKH6AABAAcSYCgoAAQoKAAIAALz9bAAAAaQLMvUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_1,
|
||||
counter=2,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAAAb0fasCAAAAAAAAAAK8hjcszyCKObdjMno0cMU0Iz0tMNJT26kI3GZUjL0WHPVq8pyYw5H5Cv+19Ks8qy7VQoPlhe14MGYbqoxpaSxmKvU3pAhRgOPhtIMZa/FXV7H68rtwMXO+O0wAaub4tGBBfxAZM+O3E5bImRe2MFQ=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAAAb0fasCAAAAAAAAAAK8hjcszyCKObdjMno0cMU0Iz0tMNJT26kI3GZUjL0WHPVq8pyYw5H5Cv+19Ks8qy7VQoPlhe14MGYbqoxpaSxmKvU3pAhRgOPhtIMZa/FXV7H68rtwMXO+O0wAaub4tGBBfxAZM+O3E5bImRe2MFQ=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAVOZ4QABAAUAaCgoAAgoKAAEIAPSqbAAAAlVdQfUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_2,
|
||||
counter=2,
|
||||
encrypt=0,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAANg30DACAAAAAAAAANVl/HO/AF3XLEDRkTrZ/V7iOIWpZXRUWt3Xaj5pZx+L05YcIMinZnsoR1gjA0KunMnQPjBLXRwx+zH541MWDl9kX2/iT6RisxvvhDdooyunZ+VWV/JIUS31WWE10cWyKk/j47mqdGGCj8ZDP/LlkvM=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAANg30DACAAAAAAAAANVl/HO/AF3XLEDRkTrZ/V7iOIWpZXRUWt3Xaj5pZx+L05YcIMinZnsoR1gjA0KunMnQPjBLXRwx+zH541MWDl9kX2/iT6RisxvvhDdooyunZ+VWV/JIUS31WWE10cWyKk/j47mqdGGCj8ZDP/LlkvM=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAVKKZAABAAcP5CgoAAQoKAAIAAPyqbAAAAlVdQfUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_2,
|
||||
counter=3,
|
||||
encrypt=0,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAANg30DADAAAAAAAAAPIVoyyT8QyqQd4enxQqF7LuwF57P7ArJTu0jKnZ04yUzfm7M5REwfdusioMH0qQDVMU+VSacW3qKTnW8QuQCLStPz1FDEcyFZzx31jXPEcB")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAANg30DADAAAAAAAAAPIVoyyT8QyqQd4enxQqF7LuwF57P7ArJTu0jKnZ04yUzfm7M5REwfdusioMH0qQDVMU+VSacW3qKTnW8QuQCLStPz1FDEcyFZzx31jXPEcB")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAO7tHQABAEXNeCgoAAQEBAQHO1gA1ACeG3RAHAQAAAQAAAAAAAApsZWtlbnN0ZXluAm5sAAABAAE=")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_2,
|
||||
counter=4,
|
||||
encrypt=0,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAANg30DAEAAAAAAAAABF9QjZR6eDhFtX+gZMGK7RgtG9rxhmQ4PuWsusUcIYPVdpQvQHpvyIytVN8rghjlXFTjQPJwnS/u0azC5Y4ibNZtQc2MvPGw2CtNZvjdctJ")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAANg30DAEAAAAAAAAABF9QjZR6eDhFtX+gZMGK7RgtG9rxhmQ4PuWsusUcIYPVdpQvQHpvyIytVN8rghjlXFTjQPJwnS/u0azC5Y4ibNZtQc2MvPGw2CtNZvjdctJ")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAO7tIQABAEXNdCgoAAQEBAQHO1gA1ACfptZIuAQAAAQAAAAAAAApsZWtlbnN0ZXluAm5sAAAcAAE=")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_1,
|
||||
counter=4,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAAAb0fasEAAAAAAAAABWYbKqqAh9E0OCEJSfZMrW0OjvWiMl6N1SSqbWOWlpzH/udELV5KSWtTc1/tc8zFwJLgxDy565wNIUvShAlls+Nj6KjHEZQU7rylH8u4iIOAlrs0XkD1ZIy/hxPxSjUuA==")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAAAb0fasEAAAAAAAAABWYbKqqAh9E0OCEJSfZMrW0OjvWiMl6N1SSqbWOWlpzH/udELV5KSWtTc1/tc8zFwJLgxDy565wNIUvShAlls+Nj6KjHEZQU7rylH8u4iIOAlrs0XkD1ZIy/hxPxSjUuA==")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAASwAAAAA/EW+WAQEBAQoKAAEANc7WADcuQhAHgYAAAQABAAAAAApsZWtlbnN0ZXluAm5sAAABAAHADAABAAEAABa0AASyFXD7")
|
||||
),
|
||||
|
||||
# # should be a keepalive packet here!
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_1,
|
||||
counter=5,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAAAb0fasFAAAAAAAAAHzSuzTFBRFN2GIycujWryZhjoTccbQKpugYmS8w5csSlEO35wpTpXn74TShqfQhNbHxTNwm45kLUL0pozLrNiiGz5U4G7m0lBYDj9b4eeZSfArymZOe0BfYt8w5dx0DUHs53v4xdEC2aBlsMBmv3k0=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAAAb0fasFAAAAAAAAAHzSuzTFBRFN2GIycujWryZhjoTccbQKpugYmS8w5csSlEO35wpTpXn74TShqfQhNbHxTNwm45kLUL0pozLrNiiGz5U4G7m0lBYDj9b4eeZSfArymZOe0BfYt8w5dx0DUHs53v4xdEC2aBlsMBmv3k0=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAVwABAAA/EW+JAQEBAQoKAAEANc7WAEMO1ZIugYAAAQABAAAAAApsZWtlbnN0ZXluAm5sAAAcAAHADAAcAAEAABa0ABAqAiMIAAAAAAAAA2AAAQAB")
|
||||
),
|
||||
|
||||
# Another keepalive here
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_4,
|
||||
counter=0,
|
||||
encrypt=0,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAAMVB/b8AAAAAAAAAAK/Th71y1FBFIYi8O6d3P0Dlyte5Dy3zQrD41/6Iiros3Rr6pibFKWWyujj0RpPWIvEWJtCUnKJP9dPZREqfmAuazNKRjiugpL4wSnjpHiz+=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAAMVB/b8AAAAAAAAAAK/Th71y1FBFIYi8O6d3P0Dlyte5Dy3zQrD41/6Iiros3Rr6pibFKWWyujj0RpPWIvEWJtCUnKJP9dPZREqfmAuazNKRjiugpL4wSnjpHiz+")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAPJioQABABnT4CgoAAbIVcPvBQAG7ixsUqAAAAACgAmvQUbcAAAIEBWQEAggKP6q7QwAAAAABAwMH")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_3,
|
||||
counter=1,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAALme3iYBAAAAAAAAAHmKtCxsplQ4V+bzmLxkrd9iIszgAclV26wj8hAtodPOi3wBBJXT5BZoBmhf76dAgwci+WAo8Neeizq/4Yu+pYQ=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAALme3iYBAAAAAAAAAHmKtCxsplQ4V+bzmLxkrd9iIszgAclV26wj8hAtodPOi3wBBJXT5BZoBmhf76dAgwci+WAo8Neeizq/4Yu+pYQ=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAALAACAAA/Bk6vshVw+woKAAEBu8FAAAD6AYsbFKlgEiAA7jgAAAIEBbQ=")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_4,
|
||||
counter=1,
|
||||
encrypt=0,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAAMVB/b8BAAAAAAAAAHvtESOQTU9ahgXtzw/OK8TvEsrjCkFEAnAcitOFqhqbeqmDtelwklfvLbxyLP9aRPReulhCY3luOLwB57MU6aw=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAAMVB/b8BAAAAAAAAAHvtESOQTU9ahgXtzw/OK8TvEsrjCkFEAnAcitOFqhqbeqmDtelwklfvLbxyLP9aRPReulhCY3luOLwB57MU6aw=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAKJipQABABnULCgoAAbIVcPvBQAG7ixsUqQAA+gJQEGvQuiUAAA==")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_3,
|
||||
counter=2,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAALme3iYCAAAAAAAAAMdVYbYHeBkuhSpOOkGEh/rIwcKv4a+17BEgv+T7DY4Ksivu3gNm0DXUh/hpgZ/lhqbgPT1+GUWUOQMypr/T1Nw=")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAALme3iYCAAAAAAAAAMdVYbYHeBkuhSpOOkGEh/rIwcKv4a+17BEgv+T7DY4Ksivu3gNm0DXUh/hpgZ/lhqbgPT1+GUWUOQMypr/T1Nw=")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAAKAADAAA/Bk6yshVw+woKAAEBu8FAAAD6AosbFYFQECI4AuYAAA==")
|
||||
),
|
||||
|
||||
CipherContext(
|
||||
key=MESSAGE_KEY_3,
|
||||
counter=3,
|
||||
encrypt=1,
|
||||
|
||||
tag=int.from_bytes(base64.decodebytes(b"BAAAALme3iYDAAAAAAAAAK0SmHnTT056FRHPMd66WYNlCDTwvJhkJx79R5psrl+fL/89gBZYHL2mjT9C+55tJuUVjHXYKMYdEVgn2he8p65W7BheKppBmq3mKfRezs8pRpgGVO4yI03t5BponGYn8xC71VtMPWxpBYdy9HsHNiZj4jGT30O+WPrdQTL10beu6ao+qEXUUD1hVHSKcpgOGp/xll7AjPYs1OEt64exAfO8pFeZtQTp16cLuiPNqMld3EYh2p7lF/Ry9GO3lB9sp/PB6cfSOOvLViZ3wsiCF/Q7awYqFuCrcMjU1RQs7RPGW4fhiFazl9NsvSuBvWMII48keUCtkLnbqv9dBZM7BPCVePAwFW5iPZOa7vkxaPF6pqWDSgTwRiLICiix5wQL0a0cBpgMxryNCxmvyRKUyRdo1RFMayfXFOp+6DqmUrNbBr3dnDGE87XuAkOnx9m/DR/yBI/iiePSCnsxeyJVwtBVJeDdzwZAyrVR9vYFfyVRH4MirZYuw33VkTA98OEXcqrdTSOvsTn04JL/1DmKTjdj8HHjtuBism6vOofdrFRmVSREAiE5tI4HecIkZV/iu2345JIe8FTWZZVfvIVG9VamkHPLe0gBQR4eeLfUWIlRQrU+aiWQBaZKMxooyYwZPZGTlUtKmU/Q1/cJ9GeBKuD6Txge+/okOlqvPXgCHeyiAiSHVJ/2lWHTK7BPyPwcIik3q+dIUpIwL5/7doYDcezpnscB5o/KjAvBw3YwqAuNLyVuqFrMGti1eCTi1ll016slCEbDGRvHYielCtdzkw7vYhIPE+k37FxXByoJ3jg5NlOrbRoVvO25Hy2rP4SYMmQ3dEQNRDVkCy8yvQRSAI1UOknXnpDo+SU50FKcmdB94htpRM+ddADNUmJPD7JJAI8AFgkMN7Zujgq7v2ZSXNhpDX1MD+7zdYUwu8GsldMKTYtz+BaShoJtcSSmXYdAup8i12lGBtJJf7FxANSweg5bHgr3OE9VLJZq5JIKhY+0cIKRF8ymI5of9vXETGT7JQe26QVn8zekevI183yiqS5qbxqdt96eT1/W8mF/2TNCYBgiP135gKwVoS3ZY/0kWrx5oN0TXSGjMkRnhucEjsw5W18CFJo+labHkmuZUJ+rdVfEviady27EwgIcU2sGWPWn7jw+WPOG+709CBGtfw7/Ld6MDmNsvT9m7mvTKOVIHxJyaiA997y9P4FD4mjjlHbtncJRtUeqrW4GXrQouF9ur2+OIMAkmo1jz51j6UbyT2RUwr+ABWfwfHUxDzwxRuhj0rodw3a3ZiFtGqIXYeDavMOE3Okn/zSGETIHOnfTufGBddxSRaOUGGMv6xBXzzq+qja6JMLx/M15yhTQE2NpVrNevbrMBBE7TdOVyZP4AdvQOByO1AcTjKtOgKaPfUQeHjn21/43VO9VhnNqozlU5n1ud+xxE+CKwt7kQ9TOn4UVF/x4poIJdV851jIehBZNR+ntWFPr4wc6WMggOJ3//UWKiAvKXrsKk3YsJLdVKIqBnXD3tewpb324LVkizIaUNH1ZWWAxZa/B1Rn3K8fwKl73G+d6I6uNcz0RiiAEYKoEkN7Web3KmIQYIyT4UN2I4HfjRy0i0rXEuEevDarBbfww+fgefYf9lu3hgre4/XMuuuBnjKK4+3BNkT9ipmOzm0gH3LT470OWEDFqm+SaIVW//VdijHsWJkFiSdD8QFYQtjgII1+d1XWXmZdocWm2iDje+4CX/14b+ZQgpWWgHJ+RiYOjEWnNzRtNyy9FrkQxzzlCIgz6hu+E8eDQExP7qunniB6UBPTkmutaaNXhrG4/oWT4yBx0HAmI/VrA/M/AmsDlRpp8MO0zwFQuLbb6aXm1CO88TIeCkXbCsYiy13edfJbf0FsLhIp4P9ZqX07Ug6SKcT8ZjHkc")[-16:], "little"),
|
||||
cipher=base64.decodebytes(b"BAAAALme3iYDAAAAAAAAAK0SmHnTT056FRHPMd66WYNlCDTwvJhkJx79R5psrl+fL/89gBZYHL2mjT9C+55tJuUVjHXYKMYdEVgn2he8p65W7BheKppBmq3mKfRezs8pRpgGVO4yI03t5BponGYn8xC71VtMPWxpBYdy9HsHNiZj4jGT30O+WPrdQTL10beu6ao+qEXUUD1hVHSKcpgOGp/xll7AjPYs1OEt64exAfO8pFeZtQTp16cLuiPNqMld3EYh2p7lF/Ry9GO3lB9sp/PB6cfSOOvLViZ3wsiCF/Q7awYqFuCrcMjU1RQs7RPGW4fhiFazl9NsvSuBvWMII48keUCtkLnbqv9dBZM7BPCVePAwFW5iPZOa7vkxaPF6pqWDSgTwRiLICiix5wQL0a0cBpgMxryNCxmvyRKUyRdo1RFMayfXFOp+6DqmUrNbBr3dnDGE87XuAkOnx9m/DR/yBI/iiePSCnsxeyJVwtBVJeDdzwZAyrVR9vYFfyVRH4MirZYuw33VkTA98OEXcqrdTSOvsTn04JL/1DmKTjdj8HHjtuBism6vOofdrFRmVSREAiE5tI4HecIkZV/iu2345JIe8FTWZZVfvIVG9VamkHPLe0gBQR4eeLfUWIlRQrU+aiWQBaZKMxooyYwZPZGTlUtKmU/Q1/cJ9GeBKuD6Txge+/okOlqvPXgCHeyiAiSHVJ/2lWHTK7BPyPwcIik3q+dIUpIwL5/7doYDcezpnscB5o/KjAvBw3YwqAuNLyVuqFrMGti1eCTi1ll016slCEbDGRvHYielCtdzkw7vYhIPE+k37FxXByoJ3jg5NlOrbRoVvO25Hy2rP4SYMmQ3dEQNRDVkCy8yvQRSAI1UOknXnpDo+SU50FKcmdB94htpRM+ddADNUmJPD7JJAI8AFgkMN7Zujgq7v2ZSXNhpDX1MD+7zdYUwu8GsldMKTYtz+BaShoJtcSSmXYdAup8i12lGBtJJf7FxANSweg5bHgr3OE9VLJZq5JIKhY+0cIKRF8ymI5of9vXETGT7JQe26QVn8zekevI183yiqS5qbxqdt96eT1/W8mF/2TNCYBgiP135gKwVoS3ZY/0kWrx5oN0TXSGjMkRnhucEjsw5W18CFJo+labHkmuZUJ+rdVfEviady27EwgIcU2sGWPWn7jw+WPOG+709CBGtfw7/Ld6MDmNsvT9m7mvTKOVIHxJyaiA997y9P4FD4mjjlHbtncJRtUeqrW4GXrQouF9ur2+OIMAkmo1jz51j6UbyT2RUwr+ABWfwfHUxDzwxRuhj0rodw3a3ZiFtGqIXYeDavMOE3Okn/zSGETIHOnfTufGBddxSRaOUGGMv6xBXzzq+qja6JMLx/M15yhTQE2NpVrNevbrMBBE7TdOVyZP4AdvQOByO1AcTjKtOgKaPfUQeHjn21/43VO9VhnNqozlU5n1ud+xxE+CKwt7kQ9TOn4UVF/x4poIJdV851jIehBZNR+ntWFPr4wc6WMggOJ3//UWKiAvKXrsKk3YsJLdVKIqBnXD3tewpb324LVkizIaUNH1ZWWAxZa/B1Rn3K8fwKl73G+d6I6uNcz0RiiAEYKoEkN7Web3KmIQYIyT4UN2I4HfjRy0i0rXEuEevDarBbfww+fgefYf9lu3hgre4/XMuuuBnjKK4+3BNkT9ipmOzm0gH3LT470OWEDFqm+SaIVW//VdijHsWJkFiSdD8QFYQtjgII1+d1XWXmZdocWm2iDje+4CX/14b+ZQgpWWgHJ+RiYOjEWnNzRtNyy9FrkQxzzlCIgz6hu+E8eDQExP7qunniB6UBPTkmutaaNXhrG4/oWT4yBx0HAmI/VrA/M/AmsDlRpp8MO0zwFQuLbb6aXm1CO88TIeCkXbCsYiy13edfJbf0FsLhIp4P9ZqX07Ug6SKcT8ZjHkc")[16:-16],
|
||||
clear=base64.decodebytes(b"RQAFjAAEIAA/BilNshVw+woKAAEBu8FAAAD6AosbFYFQECI4yD0AABYDAwBqAgAAZgMDqpKMTdCadtmNVjGh3gODkvSKTc0qQdGxOZTbaOOBJMIgQMCBb2mtCP0D7maJrcd1gyat2SYsDc5UpGvLnuGuF3vALwAAHgAAAAD/AQABAAALAAQDAAECM3QACQhodHRwLzEuMRYDAwq+CwAKugAKtwAGGzCCBhcwggT/oAMCAQICEgNjl8IYWbinreQPsgP6+V5FoDANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3MgRW5jcnlwdDEjMCEGA1UEAxMaTGV0J3MgRW5jcnlwdCBBdXRob3JpdHkgWDMwHhcNMTgwNzE1MjEwODM2WhcNMTgxMDEzMjEwODM2WjAYMRYwFAYDVQQDEw1sZWtlbnN0ZXluLm5sMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuVUnC61jiWQv+1/cA4RTj2AqZ5uVNlcpuWO+OEiuZyclfbXE+5w115ixULQhzI6nroJaF6T9SquuCrTxUcoKSlYpAkosCe5ne6BqY8jCJTiDhNhcIKjta/mbJzfCSJ0ZEo7sry3xOtnr50iOhmEJfXsfbDpHADCNZst/+G5YnXGEh5a0yuRo4v6CBHaNd0rO1+HxhhL//uFGy2EiP8J9xSQg8mmFIIBhKyYbw/0TvhiscsOozkoBT1E035IHeTXbdM8/EyWw60CEqgfucKbCW+Kd02hOIe3pduvVmsUKBq9ix5lgxfagWci48+Rw8LUfUlg3kxcbmM2oRpL1OZ5KmwIDAQABo4IDJzCCAyMwDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTh2YXInDbV8qE3u7gB+8X5THYuNjAfBgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBvBggrBgEFBQcBAQRjMGEwLgYIKwYBBQUHMAGGImh0dHA6Ly9vY3NwLmludC14My5sZXRzZW5jcnlwdC5vcmcwLwYIKwYBBQUHMAKGI2h0dHA6Ly9jZXJ0LmludC14My5sZXRzZW5jcnlwdC5vcmcvMCsGA1UdEQQkMCKCDWxla2Vuc3RleW4ubmyCEXd3dy5sZWtlbnN0ZXluLm5sMIH+BgNVHSAEgfYwgfMwCAYGZ4EMAQIBMIHmBgsrBgEEAYLfEwEBATCB1jAmBggrBgEFBQcCARYaaHR0cDovL2Nwcy5sZXRzZW5jcnlwdC5vcmcwgasGCCsGAQUFBwICMIGeDIGbVGhpcyBDZXJ0aWZpY2F0ZSBtYXkgb25seSBiZSByZWxpZWQgdXBvbiBieSBSZWx5aW5nIFBhcnRpZXMgYW5kIG9ubHkgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZSBDZXJ0aWZpY2F0ZSBQb2xpY3kgZm91bmQgYXQgaHR0cHM6Ly9sZXRzZW5jcnlwdC5vcmcvcmVwb3NpdG9yeS8wggEDBgorBgEEAdZ5AgQCBIH0BIHxAO8AdgApPFGWVMg5ZbqqUPxYB9S3b79Yeily3KTDDPTlRUf0eAAAAWSf/QPTAAAEAwBHMEUCIQDu0y+NGbIdvkKji76RH7MrpOuDhRpCbhBgwqEsKUPZFAIgGOq0Lyi2seniX907uqGuMAXdERxs9/NKutzK6GX43TIAdQBVgdTCFpA2AUrqC5tXPFPwwOQ4eHAlCBcvo6odBxPTDAAAAWSf/QdnAAAEAwBGMEQCIHz8RGU2c48kG9uZJdxNfE4ppp7xHMuYT22MAp1gM5nUAg==")
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
tag_queue = Queue()
|
||||
|
||||
async def tag_output_process(dut):
|
||||
while True:
|
||||
if dut.o_mac_valid.value:
|
||||
await tag_queue.put(int(dut.o_mac.value))
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
@cocotb.test
|
||||
async def test_real_packet(dut):
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
cocotb.start_soon(receieve_output(dut))
|
||||
cocotb.start_soon(tag_output_process(dut))
|
||||
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
for pkt in PACKETS:
|
||||
dut.i_nonce.value = pkt.counter << 32
|
||||
dut.i_key.value = pkt.key
|
||||
dut.i_encrypt.value = pkt.encrypt
|
||||
|
||||
msg = pkt.clear if pkt.encrypt else pkt.cipher
|
||||
dut.i_data_ready.value = 1
|
||||
|
||||
dut.i_last.value = 0
|
||||
dut.i_valid.value = 1
|
||||
while len(msg) > 0:
|
||||
part = msg[0:4]
|
||||
dut.i_data.value = int.from_bytes(part, "little")
|
||||
dut.i_countm1.value = len(part)-1
|
||||
if len(msg) <= 4:
|
||||
dut.i_last.value = 1
|
||||
msg = msg[4:]
|
||||
await RisingEdge(dut.i_clk)
|
||||
while not dut.o_ready.value:
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
dut.i_nonce.value = 0
|
||||
dut.i_key.value = 0
|
||||
|
||||
for i, pkt in enumerate(PACKETS):
|
||||
packet = await output_queue.get()
|
||||
|
||||
expected = pkt.cipher if pkt.encrypt else pkt.clear
|
||||
# The packet is rounded up to 16 bytes before encryption, but based on the IP length we
|
||||
# are supposed to truncate it. That would happen outside of this block though.
|
||||
if expected not in packet:
|
||||
print(f"{i}: Packets didn't match!")
|
||||
print(f"expected={expected} actual={packet}")
|
||||
|
||||
tag = await tag_queue.get()
|
||||
if tag != pkt.tag:
|
||||
print(f"{i}: Tags did not match!")
|
||||
print(f"expected={pkt.tag:x} actual={tag:x}")
|
||||
|
||||
|
||||
await Timer(10, "us")
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import List
|
||||
import random
|
||||
|
||||
from modulo_theory import friendly_modular_mult, friendly_modulo
|
||||
|
||||
@@ -111,11 +112,19 @@ def test_on_long_string():
|
||||
print(f"{regular_result:x}")
|
||||
print(f"{parallel_result:x}")
|
||||
|
||||
def test_random():
|
||||
r = mask_r(random.randint(0, 2**128-1))
|
||||
s = random.randint(0, 2**128-1)
|
||||
|
||||
msg = random.randbytes(random.randint(16, 1500))
|
||||
|
||||
parallel_poly1305(msg, r, s, 8)
|
||||
|
||||
def main():
|
||||
test_regular()
|
||||
test_parallel()
|
||||
test_on_long_string()
|
||||
test_random()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -57,7 +57,6 @@ def friendly_modular_mult(value_a: int, value_b: int) -> int:
|
||||
|
||||
mods = [friendly_modulo(prod, 26*i) for i, prod in enumerate(prods)]
|
||||
|
||||
|
||||
mod_sum = friendly_modulo(sum(mods), 0)
|
||||
|
||||
return mod_sum
|
||||
|
||||
@@ -5,9 +5,39 @@ tests:
|
||||
- "poly1305_core"
|
||||
sources: "sources.list"
|
||||
waves: True
|
||||
- name: "friendly_modulo"
|
||||
- name: "poly1305_friendly_modulo"
|
||||
toplevel: "poly1305_friendly_modulo"
|
||||
modules:
|
||||
- "poly1305_friendly_modulo"
|
||||
sources: sources.list
|
||||
waves: True
|
||||
- name: "poly1305_friendly_modular_mult"
|
||||
toplevel: "poly1305_friendly_modular_mult"
|
||||
modules:
|
||||
- "poly1305_friendly_modular_mult"
|
||||
sources: sources.list
|
||||
waves: True
|
||||
- name: "poly1305_stage"
|
||||
toplevel: "poly1305_stage"
|
||||
modules:
|
||||
- "poly1305_stage"
|
||||
sources: sources.list
|
||||
waves: True
|
||||
- name: "poly1305_width_convert"
|
||||
toplevel: "poly1305_width_convert"
|
||||
modules:
|
||||
- "poly1305_width_convert"
|
||||
sources: sources.list
|
||||
waves: True
|
||||
- name: "poly1305_ll_stage"
|
||||
toplevel: "poly1305_ll_stage"
|
||||
modules:
|
||||
- "poly1305_ll_stage"
|
||||
sources: sources.list
|
||||
waves: True
|
||||
- name: "chacha20_poly1305_32_ll_core"
|
||||
toplevel: "chacha20_poly1305_32_ll_core"
|
||||
modules:
|
||||
- "chacha20_poly1305_32_ll_core"
|
||||
sources: sources.list
|
||||
waves: True
|
||||
96
ChaCha20_Poly1305_64/sim/poly1305_friendly_modular_mult.py
Normal file
96
ChaCha20_Poly1305_64/sim/poly1305_friendly_modular_mult.py
Normal file
@@ -0,0 +1,96 @@
|
||||
import logging
|
||||
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer, RisingEdge, FallingEdge
|
||||
from cocotb.queue import Queue
|
||||
|
||||
from cocotbext.axi import AxiStreamBus, AxiStreamSource
|
||||
|
||||
from modulo_theory import friendly_modular_mult
|
||||
|
||||
import random
|
||||
|
||||
PRIME = 2**130-5
|
||||
|
||||
CLK_PERIOD = 4
|
||||
|
||||
|
||||
class TB:
|
||||
def __init__(self, dut):
|
||||
self.dut = dut
|
||||
|
||||
self.log = logging.getLogger("cocotb.tb")
|
||||
self.log.setLevel(logging.INFO)
|
||||
|
||||
self.input_queue = Queue()
|
||||
|
||||
self.expected_queue = Queue()
|
||||
self.output_queue = Queue()
|
||||
|
||||
cocotb.start_soon(Clock(self.dut.i_clk, CLK_PERIOD, units="ns").start())
|
||||
|
||||
cocotb.start_soon(self.run_input())
|
||||
cocotb.start_soon(self.run_output())
|
||||
|
||||
async def cycle_reset(self):
|
||||
await self._cycle_reset(self.dut.i_rst, self.dut.i_clk)
|
||||
|
||||
async def _cycle_reset(self, rst, clk):
|
||||
rst.setimmediatevalue(0)
|
||||
await RisingEdge(clk)
|
||||
await RisingEdge(clk)
|
||||
rst.value = 1
|
||||
await RisingEdge(clk)
|
||||
await RisingEdge(clk)
|
||||
rst.value = 0
|
||||
await RisingEdge(clk)
|
||||
await RisingEdge(clk)
|
||||
|
||||
async def write_input(self, data: int, h: int):
|
||||
await self.input_queue.put((data, h))
|
||||
await self.expected_queue.put(friendly_modular_mult(h, data))
|
||||
|
||||
async def run_input(self):
|
||||
while True:
|
||||
data, h = await self.input_queue.get()
|
||||
self.dut.i_valid.value = 1
|
||||
self.dut.i_data.value = data
|
||||
self.dut.i_accumulator.value = h
|
||||
while True:
|
||||
await RisingEdge(self.dut.i_clk)
|
||||
if (self.dut.o_ready.value == 1):
|
||||
break
|
||||
self.dut.i_valid.value = 0
|
||||
self.dut.i_data.value = 0
|
||||
self.dut.i_accumulator.value = 0
|
||||
|
||||
async def run_output(self):
|
||||
while True:
|
||||
await RisingEdge(self.dut.i_clk)
|
||||
if self.dut.o_valid.value:
|
||||
await self.output_queue.put(self.dut.o_result.value.integer)
|
||||
|
||||
@cocotb.test
|
||||
async def test_sanity(dut):
|
||||
tb = TB(dut)
|
||||
|
||||
await tb.cycle_reset()
|
||||
|
||||
count = 1
|
||||
|
||||
for _ in range(count):
|
||||
await tb.write_input(random.randint(1,2**128-1), random.randint(0, 2**130-6))
|
||||
|
||||
fail = False
|
||||
|
||||
for _ in range(count):
|
||||
sim_val = await tb.expected_queue.get()
|
||||
dut_val = await tb.output_queue.get()
|
||||
|
||||
if sim_val != dut_val:
|
||||
tb.log.info(f"{sim_val:x} -> {dut_val:x}")
|
||||
fail = True
|
||||
|
||||
assert not fail
|
||||
@@ -88,4 +88,23 @@ async def test_sanity(dut):
|
||||
tb.log.info(f"{sim_val:x} -> {dut_val:x}")
|
||||
fail = True
|
||||
|
||||
assert not fail
|
||||
|
||||
@cocotb.test
|
||||
async def test_directed(dut):
|
||||
tb = TB(dut)
|
||||
|
||||
await tb.cycle_reset()
|
||||
|
||||
await tb.write_input(0x14C0D69391E7116E057E7AD833B00B706AA2390C, 4)
|
||||
|
||||
fail = False
|
||||
|
||||
sim_val = await tb.expected_queue.get()
|
||||
dut_val = await tb.output_queue.get()
|
||||
|
||||
if sim_val != dut_val:
|
||||
tb.log.info(f"{sim_val:x} -> {dut_val:x}")
|
||||
fail = True
|
||||
|
||||
assert not fail
|
||||
73
ChaCha20_Poly1305_64/sim/poly1305_ll_stage.py
Normal file
73
ChaCha20_Poly1305_64/sim/poly1305_ll_stage.py
Normal file
@@ -0,0 +1,73 @@
|
||||
import cocotb
|
||||
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer, RisingEdge, FallingEdge
|
||||
from cocotb.handle import Immediate
|
||||
|
||||
import random
|
||||
|
||||
from array import array
|
||||
|
||||
CLK_PERIOD = 5
|
||||
|
||||
@cocotb.test
|
||||
async def test_sanity(dut):
|
||||
|
||||
data_bytes = b"Cryptographic Forum Research Group"
|
||||
|
||||
countm1 = [3 for _ in range(len(data_bytes)//4)]
|
||||
if len(data_bytes) % 4:
|
||||
countm1 += [len(data_bytes) % 4 -1]
|
||||
|
||||
print(len(data_bytes) % 4)
|
||||
print(len(data_bytes))
|
||||
print(countm1)
|
||||
|
||||
data_bytes += (len(data_bytes) - (len(data_bytes) //4 ) * 4) * b'\x00'
|
||||
data_in = array("I", data_bytes).tolist()
|
||||
|
||||
|
||||
print(data_in)
|
||||
|
||||
async def input_data():
|
||||
for _ in range(2):
|
||||
for count, word in zip(countm1, data_in[:-1]):
|
||||
dut.i_data.value = word
|
||||
dut.i_countm1.value = count
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 0
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while not dut.o_ready.value:
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_data.value = data_in[-1]
|
||||
dut.i_countm1.value = countm1[-1]
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 1
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_r.value = 0x806d5400e52447c036d555408bed685
|
||||
dut.i_s.value = 0x1bf54941aff6bf4afdb20dfb8a800301
|
||||
|
||||
cocotb.start_soon(input_data())
|
||||
|
||||
await Timer(1, "us")
|
||||
111
ChaCha20_Poly1305_64/sim/poly1305_stage.py
Normal file
111
ChaCha20_Poly1305_64/sim/poly1305_stage.py
Normal file
@@ -0,0 +1,111 @@
|
||||
import logging
|
||||
|
||||
|
||||
import cocotb
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer, RisingEdge, FallingEdge
|
||||
from cocotb.queue import Queue
|
||||
from cocotb.handle import Immediate
|
||||
|
||||
from cocotbext.axi import AxiStreamBus, AxiStreamSource
|
||||
|
||||
from modulo_theory import friendly_modular_mult
|
||||
|
||||
import random
|
||||
|
||||
PRIME = 2**130-5
|
||||
|
||||
CLK_PERIOD = 4
|
||||
|
||||
|
||||
class TB:
|
||||
def __init__(self, dut):
|
||||
self.dut = dut
|
||||
|
||||
self.log = logging.getLogger("cocotb.tb")
|
||||
self.log.setLevel(logging.INFO)
|
||||
|
||||
self.input_queue = Queue()
|
||||
|
||||
self.expected_queue = Queue()
|
||||
self.output_queue = Queue()
|
||||
|
||||
cocotb.start_soon(Clock(self.dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
cocotb.start_soon(self.run_input())
|
||||
cocotb.start_soon(self.run_output())
|
||||
|
||||
self.index = 0
|
||||
self.accumulators = [0, 0]
|
||||
|
||||
async def cycle_reset(self):
|
||||
await self._cycle_reset(self.dut.i_rst, self.dut.i_clk)
|
||||
|
||||
async def _cycle_reset(self, rst, clk):
|
||||
rst.value = Immediate(0)
|
||||
await RisingEdge(clk)
|
||||
await RisingEdge(clk)
|
||||
rst.value = 1
|
||||
await RisingEdge(clk)
|
||||
await RisingEdge(clk)
|
||||
rst.value = 0
|
||||
await RisingEdge(clk)
|
||||
await RisingEdge(clk)
|
||||
|
||||
async def write_input(self, msg: int, r_power: int, clear_acc: int):
|
||||
await self.input_queue.put((msg, r_power, clear_acc))
|
||||
if clear_acc:
|
||||
expected_result = friendly_modular_mult((msg) % PRIME, r_power)
|
||||
else:
|
||||
expected_result = friendly_modular_mult((msg + self.accumulators[self.index]) % PRIME, r_power)
|
||||
|
||||
self.accumulators[self.index] = expected_result
|
||||
await self.expected_queue.put(expected_result)
|
||||
self.index = 1 if self.index == 0 else 0
|
||||
|
||||
async def run_input(self):
|
||||
while True:
|
||||
msg, r_power, clear_acc = await self.input_queue.get()
|
||||
self.dut.i_valid.value = 1
|
||||
self.dut.i_r_power.value = r_power
|
||||
self.dut.i_message.value = msg
|
||||
self.dut.i_clear_acc.value = clear_acc
|
||||
while True:
|
||||
await RisingEdge(self.dut.i_clk)
|
||||
if (self.dut.o_ready.value == 1):
|
||||
break
|
||||
self.dut.i_valid.value = 0
|
||||
self.dut.i_r_power.value = 0
|
||||
self.dut.i_message.value = 0
|
||||
self.dut.i_clear_acc.value = 0
|
||||
|
||||
async def run_output(self):
|
||||
while True:
|
||||
await RisingEdge(self.dut.i_clk)
|
||||
if self.dut.o_valid.value:
|
||||
await self.output_queue.put(self.dut.o_result.value.to_unsigned())
|
||||
|
||||
@cocotb.test
|
||||
async def test_sanity(dut):
|
||||
|
||||
tb = TB(dut)
|
||||
|
||||
await tb.cycle_reset()
|
||||
|
||||
count = 1024
|
||||
|
||||
for _ in range(count):
|
||||
clr = 1 if random.randint(0,10) == 0 else 0
|
||||
await tb.write_input(random.randint(1,2**128-1), random.randint(0, 2**130-6), clr)
|
||||
|
||||
fail = False
|
||||
|
||||
for _ in range(count):
|
||||
sim_val = await tb.expected_queue.get()
|
||||
dut_val = await tb.output_queue.get()
|
||||
|
||||
if sim_val != dut_val:
|
||||
tb.log.info(f"{_} {sim_val:x} -> {dut_val:x}")
|
||||
fail = True
|
||||
|
||||
assert not fail
|
||||
480
ChaCha20_Poly1305_64/sim/poly1305_width_convert.py
Normal file
480
ChaCha20_Poly1305_64/sim/poly1305_width_convert.py
Normal file
@@ -0,0 +1,480 @@
|
||||
import cocotb
|
||||
|
||||
from cocotb.clock import Clock
|
||||
from cocotb.triggers import Timer, RisingEdge, FallingEdge
|
||||
from cocotb.handle import Immediate
|
||||
|
||||
import math
|
||||
|
||||
import random
|
||||
|
||||
CLK_PERIOD = 5
|
||||
|
||||
|
||||
@cocotb.test
|
||||
async def test_sanity(dut):
|
||||
|
||||
data_in = [random.randint(0, 2**32-1) for _ in range(32)]
|
||||
|
||||
async def input_data():
|
||||
for word in data_in[:-1]:
|
||||
dut.i_data.value = word
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 0
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_data.value = data_in[-1]
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 1
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
data_out = []
|
||||
|
||||
async def output_data():
|
||||
while True:
|
||||
if (dut.o_valid.value):
|
||||
data_out.append(int(dut.o_data.value))
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_ready.value = 1
|
||||
|
||||
cocotb.start_soon(input_data())
|
||||
cocotb.start_soon(output_data())
|
||||
|
||||
await RisingEdge(dut.o_last)
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
expected_data_out = []
|
||||
for i in range(math.ceil(len(data_in)/4)):
|
||||
vals = data_in[i*4:(i+1)*4]
|
||||
|
||||
converted = 0
|
||||
for i, val in enumerate(vals):
|
||||
converted |= val << (32*i)
|
||||
|
||||
expected_data_out.append(converted)
|
||||
|
||||
|
||||
assert data_out == expected_data_out
|
||||
|
||||
@cocotb.test
|
||||
async def test_incomplete_last(dut):
|
||||
data_in = [random.randint(0, 2**32-1) for _ in range(30)]
|
||||
|
||||
async def input_data():
|
||||
for word in data_in[:-1]:
|
||||
dut.i_data.value = word
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 0
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_data.value = data_in[-1]
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 1
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
data_out = []
|
||||
|
||||
async def output_data():
|
||||
while True:
|
||||
if (dut.o_valid.value):
|
||||
data_out.append(int(dut.o_data.value))
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_ready.value = 1
|
||||
|
||||
cocotb.start_soon(input_data())
|
||||
cocotb.start_soon(output_data())
|
||||
|
||||
await RisingEdge(dut.o_last)
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
expected_data_out = []
|
||||
for i in range(math.ceil(len(data_in)/4)):
|
||||
vals = data_in[i*4:(i+1)*4]
|
||||
|
||||
converted = 0
|
||||
for i, val in enumerate(vals):
|
||||
converted |= val << (32*i)
|
||||
|
||||
expected_data_out.append(converted)
|
||||
|
||||
|
||||
assert data_out == expected_data_out
|
||||
|
||||
|
||||
@cocotb.test
|
||||
async def test_output_backpressure(dut):
|
||||
data_in = [random.randint(0, 2**32-1) for _ in range(32)]
|
||||
|
||||
async def input_data():
|
||||
for word in data_in[:-1]:
|
||||
dut.i_data.value = word
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 0
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_data.value = data_in[-1]
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 1
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
data_out = []
|
||||
|
||||
async def output_data():
|
||||
while True:
|
||||
if (dut.o_valid.value and dut.i_ready.value):
|
||||
data_out.append(int(dut.o_data.value))
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
async def output_backpressure():
|
||||
while True:
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_ready.value = random.randint(0, 100) < 75
|
||||
|
||||
cocotb.start_soon(output_backpressure())
|
||||
cocotb.start_soon(input_data())
|
||||
cocotb.start_soon(output_data())
|
||||
|
||||
while True:
|
||||
await RisingEdge(dut.i_clk)
|
||||
if dut.o_last.value and dut.i_ready.value:
|
||||
break
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
|
||||
expected_data_out = []
|
||||
for i in range(math.ceil(len(data_in)/4)):
|
||||
vals = data_in[i*4:(i+1)*4]
|
||||
|
||||
converted = 0
|
||||
for i, val in enumerate(vals):
|
||||
converted |= val << (32*i)
|
||||
|
||||
expected_data_out.append(converted)
|
||||
|
||||
|
||||
if not data_out == expected_data_out:
|
||||
print(data_out)
|
||||
print(expected_data_out)
|
||||
|
||||
assert data_out == expected_data_out
|
||||
|
||||
@cocotb.test
|
||||
async def test_output_backpressure_nonfull(dut):
|
||||
data_in = [random.randint(0, 2**32-1) for _ in range(30)]
|
||||
|
||||
async def input_data():
|
||||
for word in data_in[:-1]:
|
||||
dut.i_data.value = word
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 0
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_data.value = data_in[-1]
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 1
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
data_out = []
|
||||
|
||||
async def output_data():
|
||||
while True:
|
||||
if (dut.o_valid.value and dut.i_ready.value):
|
||||
data_out.append(int(dut.o_data.value))
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
async def output_backpressure():
|
||||
while True:
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_ready.value = random.randint(0, 100) < 75
|
||||
|
||||
cocotb.start_soon(output_backpressure())
|
||||
cocotb.start_soon(input_data())
|
||||
cocotb.start_soon(output_data())
|
||||
|
||||
while True:
|
||||
await RisingEdge(dut.i_clk)
|
||||
if dut.o_last.value and dut.i_ready.value:
|
||||
break
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
|
||||
expected_data_out = []
|
||||
for i in range(math.ceil(len(data_in)/4)):
|
||||
vals = data_in[i*4:(i+1)*4]
|
||||
|
||||
converted = 0
|
||||
for i, val in enumerate(vals):
|
||||
converted |= val << (32*i)
|
||||
|
||||
expected_data_out.append(converted)
|
||||
|
||||
|
||||
if not data_out == expected_data_out:
|
||||
print(data_out)
|
||||
print(expected_data_out)
|
||||
|
||||
assert data_out == expected_data_out
|
||||
|
||||
|
||||
@cocotb.test
|
||||
async def test_input_nonvalid(dut):
|
||||
data_in = [random.randint(0, 2**32-1) for _ in range(32)]
|
||||
|
||||
async def input_data():
|
||||
for word in data_in[:-1]:
|
||||
dut.i_data.value = word
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 0
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
if random.randint(0, 10) > 7:
|
||||
dut.i_valid.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
|
||||
dut.i_data.value = data_in[-1]
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 1
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
data_out = []
|
||||
|
||||
async def output_data():
|
||||
while True:
|
||||
if (dut.o_valid.value and dut.i_ready.value):
|
||||
data_out.append(int(dut.o_data.value))
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_ready.value = 1
|
||||
|
||||
cocotb.start_soon(input_data())
|
||||
cocotb.start_soon(output_data())
|
||||
|
||||
while True:
|
||||
await RisingEdge(dut.i_clk)
|
||||
if dut.o_last.value and dut.i_ready.value:
|
||||
break
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
|
||||
expected_data_out = []
|
||||
for i in range(math.ceil(len(data_in)/4)):
|
||||
vals = data_in[i*4:(i+1)*4]
|
||||
|
||||
converted = 0
|
||||
for i, val in enumerate(vals):
|
||||
converted |= val << (32*i)
|
||||
|
||||
expected_data_out.append(converted)
|
||||
|
||||
|
||||
if not data_out == expected_data_out:
|
||||
print(data_out)
|
||||
print(expected_data_out)
|
||||
|
||||
assert data_out == expected_data_out
|
||||
|
||||
@cocotb.test
|
||||
async def test_input_nonvalid_output_nonready(dut):
|
||||
data_in = [random.randint(0, 2**32-1) for _ in range(30)]
|
||||
|
||||
async def input_data():
|
||||
for word in data_in[:-1]:
|
||||
dut.i_data.value = word
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 0
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
if random.randint(0, 10) > 7:
|
||||
dut.i_valid.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
|
||||
dut.i_data.value = data_in[-1]
|
||||
dut.i_valid.value = 1
|
||||
dut.i_last.value = 1
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
while (not dut.o_ready.value):
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_valid.value = 0
|
||||
dut.i_last.value = 0
|
||||
|
||||
data_out = []
|
||||
|
||||
async def output_data():
|
||||
while True:
|
||||
if (dut.o_valid.value and dut.i_ready.value):
|
||||
data_out.append(int(dut.o_data.value))
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
cocotb.start_soon(Clock(dut.i_clk, CLK_PERIOD, unit="ns").start())
|
||||
|
||||
|
||||
dut.i_rst.value = Immediate(0)
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 1
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
dut.i_rst.value = 0
|
||||
await RisingEdge(dut.i_clk)
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
async def output_backpressure():
|
||||
while True:
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
dut.i_ready.value = random.randint(0, 100) < 75
|
||||
|
||||
cocotb.start_soon(output_backpressure())
|
||||
cocotb.start_soon(input_data())
|
||||
cocotb.start_soon(output_data())
|
||||
|
||||
while True:
|
||||
await RisingEdge(dut.i_clk)
|
||||
if dut.o_last.value and dut.i_ready.value:
|
||||
break
|
||||
|
||||
await RisingEdge(dut.i_clk)
|
||||
|
||||
|
||||
expected_data_out = []
|
||||
for i in range(math.ceil(len(data_in)/4)):
|
||||
vals = data_in[i*4:(i+1)*4]
|
||||
|
||||
converted = 0
|
||||
for i, val in enumerate(vals):
|
||||
converted |= val << (32*i)
|
||||
|
||||
expected_data_out.append(converted)
|
||||
|
||||
|
||||
if not data_out == expected_data_out:
|
||||
print(data_out)
|
||||
print(expected_data_out)
|
||||
|
||||
assert data_out == expected_data_out
|
||||
@@ -2,3 +2,8 @@ poly1305_core_wrapper.sv
|
||||
|
||||
../src/sources.list
|
||||
../../common/sim/sub/taxi/src/axis/rtl/taxi_axis_if.sv
|
||||
|
||||
../../common/sim/sub/fifo/rtl/verilog/fifo_fwft_adapter.v
|
||||
../../common/sim/sub/fifo/rtl/verilog/fifo.v
|
||||
../../common/sim/sub/fifo/rtl/verilog/fifo_fwft.v
|
||||
../../common/sim/sub/fifo/rtl/verilog/simple_dpram_sclk.v
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module chacha20_block #(
|
||||
parameter KEY_SIZE = 256,
|
||||
parameter COUNTER_SIZE = 64,
|
||||
parameter NONCE_SIZE = 64,
|
||||
parameter COUNTER_SIZE = 32,
|
||||
parameter NONCE_SIZE = 96,
|
||||
parameter STATE_SIZE = 512,
|
||||
parameter ROUNDS = 20,
|
||||
parameter CONSTANT = 128'h657870616e642033322d62797465206b
|
||||
parameter CONSTANT = 128'h617078653320646e79622d326b206574
|
||||
)(
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
@@ -68,7 +68,7 @@ always_ff @(posedge i_clk) begin
|
||||
initial_state_rptr <= '0;
|
||||
initial_state_wptr <= '0;
|
||||
end else begin
|
||||
if (i_valid) begin
|
||||
if (i_valid & i_ready) begin
|
||||
initial_states[initial_state_wptr] <= write_initial_state;
|
||||
if (initial_state_wptr < PIPE_STAGES-1) begin
|
||||
initial_state_wptr <= initial_state_wptr + 1;
|
||||
@@ -77,9 +77,8 @@ always_ff @(posedge i_clk) begin
|
||||
end
|
||||
end
|
||||
|
||||
pre_add_valid <= valid[ROUNDS][0];
|
||||
|
||||
if (valid[ROUNDS][0]) begin
|
||||
if (valid[ROUNDS][0] & i_ready) begin
|
||||
read_initial_state <= initial_states[initial_state_rptr];
|
||||
if (initial_state_rptr < PIPE_STAGES-1) begin
|
||||
initial_state_rptr <= initial_state_rptr + 1;
|
||||
@@ -92,13 +91,16 @@ always_ff @(posedge i_clk) begin
|
||||
end
|
||||
|
||||
|
||||
o_valid <= pre_add_valid;
|
||||
if (i_ready) begin
|
||||
pre_add_valid <= valid[ROUNDS][0];
|
||||
o_valid <= pre_add_valid;
|
||||
|
||||
// We cannot just add state_pre_add and read_initial state
|
||||
// because the addition needs to be done wordwise, with no
|
||||
// carries between 32 bit groups.
|
||||
for (int i = 0; i < 16; i++) begin
|
||||
o_state[i*32 +: 32] <= state_pre_add[i*32 +: 32] + read_initial_state[i*32 +: 32];
|
||||
// We cannot just add state_pre_add and read_initial state
|
||||
// because the addition needs to be done wordwise, with no
|
||||
// carries between 32 bit groups.
|
||||
for (int i = 0; i < 16; i++) begin
|
||||
o_state[i*32 +: 32] <= state_pre_add[i*32 +: 32] + read_initial_state[i*32 +: 32];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -115,10 +117,10 @@ always_comb begin
|
||||
end
|
||||
|
||||
state[0][12] = i_counter[0 +: 32];
|
||||
state[0][13] = i_counter[32 +: 32];
|
||||
|
||||
state[0][14] = i_nonce[0 +: 32];
|
||||
state[0][15] = i_nonce[32 +: 32];
|
||||
|
||||
state[0][13] = i_nonce[0 +: 32];
|
||||
state[0][14] = i_nonce[32 +: 32];
|
||||
state[0][15] = i_nonce[64 +: 32];
|
||||
|
||||
|
||||
for (int i = 0; i < 4; i++) begin
|
||||
|
||||
324
ChaCha20_Poly1305_64/src/chacha20_poly1305_32_ll_core.sv
Normal file
324
ChaCha20_Poly1305_64/src/chacha20_poly1305_32_ll_core.sv
Normal file
@@ -0,0 +1,324 @@
|
||||
module chacha20_poly1305_32_ll_core (
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic [255:0] i_key,
|
||||
input logic [95:0] i_nonce,
|
||||
|
||||
input logic i_encrypt,
|
||||
|
||||
input logic [31:0] i_data,
|
||||
input logic [1:0] i_countm1,
|
||||
input logic i_last,
|
||||
|
||||
input logic i_valid,
|
||||
output logic o_ready,
|
||||
|
||||
output logic [31:0] o_data,
|
||||
output logic [1:0] o_data_countm1,
|
||||
output logic o_data_last,
|
||||
output logic o_data_valid,
|
||||
input logic i_data_ready,
|
||||
|
||||
// no backpressure for the poly1305 output
|
||||
output logic [127:0] o_mac,
|
||||
output logic o_mac_valid
|
||||
);
|
||||
|
||||
logic [255:0] chacha_key;
|
||||
logic [31:0] chacha_counter;
|
||||
logic [95:0] chacha_nonce;
|
||||
|
||||
logic chacha_i_valid;
|
||||
logic chacha_i_ready;
|
||||
|
||||
logic [511:0] chacha_state;
|
||||
logic chacha_o_valid;
|
||||
logic chacha_o_ready;
|
||||
|
||||
logic poly1305_i_valid;
|
||||
logic [1:0] poly1305_countm1;
|
||||
logic poly1305_i_ready;
|
||||
logic [31:0] poly1305_data;
|
||||
logic poly1305_last;
|
||||
logic [127:0] poly1305_r;
|
||||
logic [127:0] poly1305_s;
|
||||
|
||||
logic downconvert_i_valid;
|
||||
logic [1:0] downconvert_countm1;
|
||||
logic downconvert_i_ready;
|
||||
logic [31:0] downconvert_data;
|
||||
logic downconvert_last;
|
||||
|
||||
logic poly1305_o_valid;
|
||||
logic [127:0] poly1305_o_result;
|
||||
|
||||
logic [511:0] fifo_data;
|
||||
logic [5:0] fifo_countm1;
|
||||
logic fifo_last;
|
||||
|
||||
logic fifo_rd_en;
|
||||
logic fifo_empty;
|
||||
logic fifo_full;
|
||||
logic fifo_valid;
|
||||
|
||||
logic upconvert_ready;
|
||||
logic upconvert_valid;
|
||||
logic upconvert_last;
|
||||
logic [511:0] upconvert_data;
|
||||
logic [5:0] upconvert_countm1;
|
||||
|
||||
logic ciphertext_ready;
|
||||
logic ciphertext_valid;
|
||||
logic ciphertext_last;
|
||||
logic [511:0] ciphertext_data;
|
||||
logic [5:0] ciphertext_countm1;
|
||||
|
||||
logic ciphertext_skid_ready;
|
||||
logic ciphertext_skid_valid;
|
||||
logic ciphertext_skid_last;
|
||||
logic [511:0] ciphertext_skid_data;
|
||||
logic [5:0] ciphertext_skid_countm1;
|
||||
|
||||
logic [511:0] post_data;
|
||||
|
||||
logic post_skid_ready;
|
||||
logic post_skid_valid;
|
||||
logic post_skid_last;
|
||||
logic [511:0] post_skid_data;
|
||||
logic [5:0] post_skid_countm1;
|
||||
|
||||
logic meta_fifo_encrypt;
|
||||
logic meta_fifo_read;
|
||||
logic meta_fifo_empty;
|
||||
|
||||
logic input_fsm_short_packet;
|
||||
|
||||
assign chacha_nonce = i_nonce;
|
||||
assign chacha_key = i_key;
|
||||
|
||||
assign fifo_valid = ~fifo_empty;
|
||||
|
||||
assign o_mac_valid = poly1305_o_valid;
|
||||
assign o_mac = poly1305_o_result;
|
||||
|
||||
poly1305_width_convert_2 u_chacha_width_convert (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (i_valid),
|
||||
.i_countm1 (i_countm1),
|
||||
.o_ready (o_ready),
|
||||
.i_data (i_data),
|
||||
.i_last (i_last),
|
||||
|
||||
.o_valid (upconvert_valid),
|
||||
.o_countm1 (upconvert_countm1),
|
||||
.i_ready (upconvert_ready & chacha_o_ready & ~input_fsm_short_packet),
|
||||
.o_data (upconvert_data),
|
||||
.o_last (upconvert_last)
|
||||
);
|
||||
|
||||
assign upconvert_ready = ~fifo_full;
|
||||
|
||||
logic sop;
|
||||
logic in_pkt;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
in_pkt <= '0;
|
||||
end else begin
|
||||
if (i_valid & o_ready) begin
|
||||
if (i_last) begin
|
||||
in_pkt <= '0;
|
||||
end else begin
|
||||
in_pkt <= '1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign sop = i_valid & o_ready & ~in_pkt;
|
||||
|
||||
|
||||
fifo_fwft #(
|
||||
.DATA_WIDTH(512+6+1),
|
||||
.DEPTH_WIDTH(8)
|
||||
) u_input_fifo (
|
||||
.clk (i_clk),
|
||||
.rst (i_rst),
|
||||
.din ({upconvert_data, upconvert_countm1, upconvert_last}),
|
||||
.wr_en (upconvert_valid & chacha_o_ready & ~input_fsm_short_packet),
|
||||
.full (fifo_full), // probably wrong, think about this
|
||||
.dout ({fifo_data, fifo_countm1, fifo_last}),
|
||||
.rd_en (fifo_rd_en),
|
||||
.empty (fifo_empty)
|
||||
);
|
||||
|
||||
fifo_fwft #(
|
||||
.DATA_WIDTH(1), // can increase when we have more metadata
|
||||
.DEPTH_WIDTH(4)
|
||||
) u_meta_fifo (
|
||||
.clk (i_clk),
|
||||
.rst (i_rst),
|
||||
.din (i_encrypt),
|
||||
.wr_en (sop),
|
||||
.full (),
|
||||
.dout (meta_fifo_encrypt),
|
||||
.rd_en (meta_fifo_read),
|
||||
.empty (meta_fifo_empty)
|
||||
);
|
||||
|
||||
chacha20_poly1305_input_fsm u_chacha20_poly1305_input_fsm (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (upconvert_valid),
|
||||
.i_last (upconvert_last),
|
||||
|
||||
.o_short_packet (input_fsm_short_packet),
|
||||
|
||||
.o_counter (chacha_counter),
|
||||
.chacha_valid (chacha_i_valid),
|
||||
.chacha_ready (chacha_i_ready)
|
||||
);
|
||||
|
||||
chacha20_block u_chacha20_block (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_key (chacha_key),
|
||||
.i_counter (chacha_counter),
|
||||
.i_nonce (chacha_nonce),
|
||||
.i_valid (chacha_i_valid),
|
||||
.o_ready (chacha_i_ready),
|
||||
|
||||
.o_state (chacha_state),
|
||||
.o_valid (chacha_o_valid),
|
||||
.i_ready (chacha_o_ready)
|
||||
);
|
||||
|
||||
chacha20_poly1305_mid_fsm u_mid_fsm (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_chacha_state (chacha_state),
|
||||
.i_chacha_valid (chacha_o_valid),
|
||||
.o_chacha_ready (chacha_o_ready),
|
||||
|
||||
.i_metadata_din (meta_fifo_encrypt),
|
||||
.o_metadata_read (meta_fifo_read),
|
||||
|
||||
.i_fifo_data (fifo_data),
|
||||
.i_fifo_countm1 (fifo_countm1),
|
||||
.i_fifo_valid (fifo_valid),
|
||||
.i_fifo_last (fifo_last),
|
||||
|
||||
.o_fifo_rd_en (fifo_rd_en),
|
||||
|
||||
|
||||
.o_ciphertext (ciphertext_data),
|
||||
.o_post (post_data),
|
||||
.o_ciphertext_countm1 (ciphertext_countm1),
|
||||
.o_ciphertext_valid (ciphertext_valid),
|
||||
.o_ciphertext_last (ciphertext_last),
|
||||
.i_ciphertext_ready (ciphertext_ready),
|
||||
|
||||
// TODO this is most likely wrong.
|
||||
.o_r (poly1305_r),
|
||||
.o_s (poly1305_s)
|
||||
);
|
||||
|
||||
logic rstn;
|
||||
assign rstn = ~i_rst;
|
||||
|
||||
pipe_skid_buffer #(
|
||||
.DWIDTH(512+512+6+1)
|
||||
) u_ciphertext_skid_buffer (
|
||||
.clk (i_clk),
|
||||
.rstn (rstn),
|
||||
|
||||
.i_data ({post_data, ciphertext_data, ciphertext_countm1, ciphertext_last}),
|
||||
.i_valid (ciphertext_valid),
|
||||
.o_ready (ciphertext_ready),
|
||||
|
||||
.o_data ({post_skid_data, ciphertext_skid_data, ciphertext_skid_countm1, ciphertext_skid_last}),
|
||||
.o_valid (ciphertext_skid_valid),
|
||||
.i_ready (ciphertext_skid_ready)
|
||||
);
|
||||
|
||||
|
||||
poly1305_width_convert_3 u_pre_poly1305_width_convert (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (ciphertext_skid_valid),
|
||||
.i_countm1 (ciphertext_skid_countm1),
|
||||
.o_ready (ciphertext_skid_ready),
|
||||
.i_data (ciphertext_skid_data),
|
||||
.i_last (ciphertext_skid_last),
|
||||
|
||||
.o_valid (poly1305_i_valid),
|
||||
.o_countm1 (poly1305_countm1),
|
||||
.i_ready (poly1305_i_ready & ~output_fifo_full),
|
||||
.o_data (poly1305_data),
|
||||
.o_last (poly1305_last)
|
||||
);
|
||||
|
||||
poly1305_width_convert_3 u_output_width_convert (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (ciphertext_skid_valid),
|
||||
.i_countm1 (ciphertext_skid_countm1),
|
||||
.o_ready (),
|
||||
.i_data (post_skid_data),
|
||||
.i_last (ciphertext_skid_last),
|
||||
|
||||
.o_valid (downconvert_i_valid),
|
||||
.o_countm1 (downconvert_countm1),
|
||||
.i_ready (poly1305_i_ready & ~output_fifo_full),
|
||||
.o_data (downconvert_data),
|
||||
.o_last (downconvert_last)
|
||||
);
|
||||
|
||||
fifo_fwft #(
|
||||
.DATA_WIDTH(32+1),
|
||||
.DEPTH_WIDTH(4)
|
||||
) u_output_fifo (
|
||||
.clk (i_clk),
|
||||
.rst (i_rst),
|
||||
.din ({downconvert_data, downconvert_last}),
|
||||
.wr_en (downconvert_i_valid & poly1305_i_ready & ~output_fifo_full),
|
||||
.full (output_fifo_full),
|
||||
.dout ({o_data, o_data_last}),
|
||||
.rd_en (o_data_valid & i_data_ready),
|
||||
.empty (output_fifo_empty)
|
||||
);
|
||||
|
||||
assign o_data_valid = ~output_fifo_empty;
|
||||
|
||||
logic output_fifo_full;
|
||||
logic output_fifo_empty;
|
||||
|
||||
|
||||
// if output fifo is not ready, we need to backpressure poly1305
|
||||
|
||||
poly1305_ll_stage u_poly1305_ll_stage (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (poly1305_i_valid & ~output_fifo_full),
|
||||
.i_countm1 (poly1305_countm1),
|
||||
.o_ready (poly1305_i_ready),
|
||||
.i_data (poly1305_data),
|
||||
.i_last (poly1305_last),
|
||||
.i_r (poly1305_r),
|
||||
.i_s (poly1305_s),
|
||||
|
||||
.o_valid (poly1305_o_valid),
|
||||
.o_result (poly1305_o_result)
|
||||
);
|
||||
|
||||
|
||||
endmodule
|
||||
104
ChaCha20_Poly1305_64/src/chacha20_poly1305_input_fsm.sv
Normal file
104
ChaCha20_Poly1305_64/src/chacha20_poly1305_input_fsm.sv
Normal file
@@ -0,0 +1,104 @@
|
||||
module chacha20_poly1305_input_fsm (
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic i_valid,
|
||||
input logic i_last,
|
||||
|
||||
output logic [31:0] o_counter,
|
||||
|
||||
output logic o_short_packet,
|
||||
|
||||
output logic chacha_valid,
|
||||
input logic chacha_ready
|
||||
);
|
||||
|
||||
enum logic [1:0] {IDLE, ACTIVE1, ACTIVE2, ACTIVE3} state, state_next;
|
||||
|
||||
logic [31:0] counter, counter_next;
|
||||
|
||||
|
||||
// in case the first beat is also the last one.
|
||||
logic last_flag, last_flag_next;
|
||||
|
||||
assign o_counter = counter;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
state <= IDLE;
|
||||
counter <= '0;
|
||||
last_flag <= '0;
|
||||
end else begin
|
||||
state <= state_next;
|
||||
counter <= counter_next;
|
||||
last_flag <= last_flag_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
state_next = state;
|
||||
|
||||
counter_next = counter;
|
||||
|
||||
last_flag_next = '0;
|
||||
|
||||
chacha_valid = '0;
|
||||
|
||||
o_short_packet = '0;
|
||||
|
||||
case (state)
|
||||
IDLE: begin
|
||||
counter_next = '0;
|
||||
chacha_valid = '0;
|
||||
|
||||
if (i_valid) begin
|
||||
chacha_valid = '1;
|
||||
if (chacha_ready) begin
|
||||
state_next = ACTIVE1;
|
||||
counter_next = counter + 1;
|
||||
|
||||
last_flag_next = i_last;
|
||||
// if the first beat is also the last, then lower ready so that
|
||||
// we run chacha for 2 cycles instead of 1, and keep the key valid.
|
||||
if (i_last) begin
|
||||
o_short_packet = '1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ACTIVE1: begin
|
||||
chacha_valid = '1;
|
||||
if (chacha_ready) begin
|
||||
state_next = ACTIVE2;
|
||||
|
||||
counter_next = counter + 1;
|
||||
end
|
||||
|
||||
if (i_last || last_flag) begin
|
||||
state_next = IDLE;
|
||||
counter_next = '0;
|
||||
end
|
||||
end
|
||||
|
||||
ACTIVE2: begin
|
||||
if (i_valid) begin
|
||||
chacha_valid = '1;
|
||||
if (chacha_ready) begin
|
||||
counter_next = counter + 1;
|
||||
|
||||
if (i_last || last_flag) begin
|
||||
state_next = IDLE;
|
||||
counter_next = '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state_next = IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
114
ChaCha20_Poly1305_64/src/chacha20_poly1305_mid_fsm.sv
Normal file
114
ChaCha20_Poly1305_64/src/chacha20_poly1305_mid_fsm.sv
Normal file
@@ -0,0 +1,114 @@
|
||||
module chacha20_poly1305_mid_fsm (
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic [511:0] i_chacha_state,
|
||||
input logic i_chacha_valid,
|
||||
output logic o_chacha_ready,
|
||||
|
||||
input logic [511:0] i_fifo_data,
|
||||
input logic [5:0] i_fifo_countm1,
|
||||
input logic i_fifo_valid,
|
||||
input logic i_fifo_last,
|
||||
|
||||
output logic o_fifo_rd_en,
|
||||
|
||||
input logic [0:0] i_metadata_din,
|
||||
output logic o_metadata_read,
|
||||
|
||||
output logic [511:0] o_ciphertext,
|
||||
output logic [511:0] o_post,
|
||||
output logic [5:0] o_ciphertext_countm1,
|
||||
output logic o_ciphertext_valid,
|
||||
output logic o_ciphertext_last,
|
||||
input logic i_ciphertext_ready,
|
||||
|
||||
|
||||
output logic [127:0] o_r,
|
||||
output logic [127:0] o_s
|
||||
);
|
||||
|
||||
localparam R_MASK = 128'h0ffffffc0ffffffc0ffffffc0fffffff;
|
||||
|
||||
logic encrypt;
|
||||
|
||||
assign encrypt = i_metadata_din[0];
|
||||
|
||||
enum logic {IDLE, DATA} state, state_next;
|
||||
|
||||
logic [127:0] r, r_next;
|
||||
logic [127:0] s, s_next;
|
||||
|
||||
assign o_r = r;
|
||||
assign o_s = s;
|
||||
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
state <= IDLE;
|
||||
|
||||
r <= '0;
|
||||
s <= '0;
|
||||
end else begin
|
||||
state <= state_next;
|
||||
|
||||
r <= r_next;
|
||||
s <= s_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
state_next = state;
|
||||
|
||||
r_next = r;
|
||||
s_next = s;
|
||||
|
||||
o_fifo_rd_en = '0;
|
||||
|
||||
o_chacha_ready = i_ciphertext_ready;
|
||||
|
||||
o_ciphertext_valid = '0;
|
||||
o_ciphertext_last = '0;
|
||||
|
||||
o_metadata_read = '0;
|
||||
|
||||
o_ciphertext = '0;
|
||||
o_ciphertext_countm1 = '0;
|
||||
o_post = '0;
|
||||
|
||||
case (state)
|
||||
IDLE: begin
|
||||
if (i_chacha_valid) begin
|
||||
r_next = i_chacha_state[0 +: 128] & R_MASK;
|
||||
s_next = i_chacha_state[128 +: 128];
|
||||
|
||||
state_next = DATA;
|
||||
end
|
||||
end
|
||||
|
||||
DATA: begin
|
||||
if (encrypt) begin
|
||||
o_ciphertext = i_fifo_data ^ i_chacha_state;
|
||||
end else begin
|
||||
o_ciphertext = i_fifo_data;
|
||||
end
|
||||
|
||||
o_post = i_fifo_data ^ i_chacha_state;
|
||||
o_ciphertext_countm1 = i_fifo_countm1;
|
||||
o_ciphertext_last = i_fifo_last;
|
||||
o_ciphertext_valid = i_fifo_valid & i_chacha_valid;
|
||||
|
||||
if (i_ciphertext_ready & i_chacha_valid) begin
|
||||
o_chacha_ready = '1;
|
||||
o_fifo_rd_en = i_fifo_valid;
|
||||
|
||||
if (i_fifo_last) begin
|
||||
state_next = IDLE;
|
||||
o_metadata_read = '1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -18,12 +18,40 @@ module chacha20_qr #(
|
||||
output logic [31:0] a_o, b_o, c_o, d_o
|
||||
);
|
||||
|
||||
logic [31:0] a_int_0;
|
||||
logic [31:0] b_int_0;
|
||||
logic [31:0] c_int_0;
|
||||
logic [31:0] d_int_0;
|
||||
|
||||
logic [31:0] a_int_1;
|
||||
logic [31:0] b_int_1;
|
||||
logic [31:0] c_int_1;
|
||||
logic [31:0] d_int_1;
|
||||
|
||||
logic [31:0] a_int [7];
|
||||
logic [31:0] b_int [7];
|
||||
logic [31:0] c_int [7];
|
||||
logic [31:0] d_int [7];
|
||||
logic [31:0] a_int_2;
|
||||
logic [31:0] b_int_2;
|
||||
logic [31:0] c_int_2;
|
||||
logic [31:0] d_int_2;
|
||||
|
||||
logic [31:0] a_int_3;
|
||||
logic [31:0] b_int_3;
|
||||
logic [31:0] c_int_3;
|
||||
logic [31:0] d_int_3;
|
||||
|
||||
logic [31:0] a_int_4;
|
||||
logic [31:0] b_int_4;
|
||||
logic [31:0] c_int_4;
|
||||
logic [31:0] d_int_4;
|
||||
|
||||
logic [31:0] a_int_5;
|
||||
logic [31:0] b_int_5;
|
||||
logic [31:0] c_int_5;
|
||||
logic [31:0] d_int_5;
|
||||
|
||||
logic [31:0] a_int_6;
|
||||
logic [31:0] b_int_6;
|
||||
logic [31:0] c_int_6;
|
||||
logic [31:0] d_int_6;
|
||||
|
||||
logic [6:0] valid_sr;
|
||||
|
||||
@@ -33,62 +61,62 @@ logic [6:0] valid_sr;
|
||||
assign o_ready = i_ready;
|
||||
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
always @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
valid_sr <= '0;
|
||||
end else begin
|
||||
if (i_ready) begin
|
||||
// 1. Update A
|
||||
a_int[0] <= a_i + b_i;
|
||||
b_int[0] <= b_i;
|
||||
c_int[0] <= c_i;
|
||||
d_int[0] <= d_i;
|
||||
a_int_0 <= a_i + b_i;
|
||||
b_int_0 <= b_i;
|
||||
c_int_0 <= c_i;
|
||||
d_int_0 <= d_i;
|
||||
|
||||
// 2. Update D
|
||||
a_int[1] <= a_int[0];
|
||||
b_int[1] <= b_int[0];
|
||||
c_int[1] <= c_int[0];
|
||||
d_int[1] <= `ROTL(a_int[0], 16) ^ `ROTL(d_int[0], 16);
|
||||
a_int_1 = a_int_0;
|
||||
b_int_1 = b_int_0;
|
||||
c_int_1 = c_int_0;
|
||||
d_int_1 = `ROTL(a_int_0, 16) ^ `ROTL(d_int_0, 16);
|
||||
|
||||
// 3. Update C
|
||||
a_int[2] <= a_int[1];
|
||||
b_int[2] <= b_int[1];
|
||||
c_int[2] <= c_int[1] + d_int[1];
|
||||
d_int[2] <= d_int[1];
|
||||
a_int_2 = a_int_1;
|
||||
b_int_2 = b_int_1;
|
||||
c_int_2 = c_int_1 + d_int_1;
|
||||
d_int_2 = d_int_1;
|
||||
|
||||
// 4. Update B
|
||||
a_int[3] <= a_int[2];
|
||||
b_int[3] <= `ROTL(b_int[2], 12) ^ `ROTL(c_int[2], 12);
|
||||
c_int[3] <= c_int[2];
|
||||
d_int[3] <= d_int[2];
|
||||
a_int_3 = a_int_2;
|
||||
b_int_3 = `ROTL(b_int_2, 12) ^ `ROTL(c_int_2, 12);
|
||||
c_int_3 = c_int_2;
|
||||
d_int_3 = d_int_2;
|
||||
|
||||
// 5. Update A
|
||||
a_int[4] <= a_int[3] + b_int[3];
|
||||
b_int[4] <= b_int[3];
|
||||
c_int[4] <= c_int[3];
|
||||
d_int[4] <= d_int[3];
|
||||
a_int_4 = a_int_3 + b_int_3;
|
||||
b_int_4 = b_int_3;
|
||||
c_int_4 = c_int_3;
|
||||
d_int_4 = d_int_3;
|
||||
|
||||
// 6. Update D
|
||||
a_int[5] <= a_int[4];
|
||||
b_int[5] <= b_int[4];
|
||||
c_int[5] <= c_int[4];
|
||||
d_int[5] <= `ROTL(a_int[4], 8) ^ `ROTL(d_int[4], 8);
|
||||
a_int_5 = a_int_4;
|
||||
b_int_5 = b_int_4;
|
||||
c_int_5 = c_int_4;
|
||||
d_int_5 = `ROTL(a_int_4, 8) ^ `ROTL(d_int_4, 8);
|
||||
|
||||
// 7. Update C
|
||||
a_int[6] <= a_int[5];
|
||||
b_int[6] <= b_int[5];
|
||||
c_int[6] <= c_int[5] + d_int[5];
|
||||
d_int[6] <= d_int[5];
|
||||
a_int_6 = a_int_5;
|
||||
b_int_6 = b_int_5;
|
||||
c_int_6 = c_int_5 + d_int_5;
|
||||
d_int_6 = d_int_5;
|
||||
|
||||
// 8. Update B
|
||||
a_o <= a_int[6];
|
||||
b_o <= `ROTL(b_int[6], 7) ^ `ROTL(c_int[6], 7);
|
||||
c_o <= c_int[6];
|
||||
d_o <= d_int[6];
|
||||
a_o <= a_int_6;
|
||||
b_o <= `ROTL(b_int_6, 7) ^ `ROTL(c_int_6, 7);
|
||||
c_o <= c_int_6;
|
||||
d_o <= d_int_6;
|
||||
|
||||
// Simultaneously, update valid_sr;
|
||||
valid_sr <= {valid_sr[5:0], i_valid};
|
||||
o_valid <= valid_sr[6];
|
||||
o_valid <= valid_sr[0];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
112
ChaCha20_Poly1305_64/src/poly1305_friendly_modular_mult.sv
Normal file
112
ChaCha20_Poly1305_64/src/poly1305_friendly_modular_mult.sv
Normal file
@@ -0,0 +1,112 @@
|
||||
// FPGA Friendly modular multiplication. takes ~6 cycles
|
||||
|
||||
module poly1305_friendly_modular_mult #(
|
||||
parameter DATA_WIDTH = 130,
|
||||
parameter ACC_WIDTH = 130
|
||||
) (
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic i_valid,
|
||||
output logic o_ready,
|
||||
input logic [DATA_WIDTH-1:0] i_data,
|
||||
input logic [ACC_WIDTH-1:0] i_accumulator,
|
||||
|
||||
output logic o_valid,
|
||||
output logic [ACC_WIDTH-1:0] o_result
|
||||
);
|
||||
|
||||
localparam INT_ACC_WIDTH = ACC_WIDTH + 3; // $clog2(8)
|
||||
|
||||
localparam [129:0] PRIME = (1 << 130) - 5;
|
||||
|
||||
logic [2:0] state_counter, state_counter_next;
|
||||
|
||||
logic [2:0] state_counter_p [5];
|
||||
|
||||
logic [INT_ACC_WIDTH-1:0] accumulator, accumulator_next; // accumulator is outgoing
|
||||
logic [INT_ACC_WIDTH+1:0] accumulator_intermediate;
|
||||
|
||||
logic [DATA_WIDTH-1:0] data, data_next;
|
||||
logic [INT_ACC_WIDTH-1:0] h, h_next; // h is incoming
|
||||
|
||||
logic [DATA_WIDTH+26-1:0] mult_product, mult_product_next;
|
||||
|
||||
logic [ACC_WIDTH-1:0] modulo_result;
|
||||
|
||||
assign o_ready = state_counter >= 3'h4;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
state_counter <= 3'h5;
|
||||
state_counter_p <= '{default: 3'h5};
|
||||
end else begin
|
||||
state_counter <= state_counter_next;
|
||||
accumulator <= accumulator_next;
|
||||
data <= data_next;
|
||||
h <= h_next;
|
||||
mult_product <= mult_product_next;
|
||||
|
||||
state_counter_p[0] <= state_counter;
|
||||
|
||||
for (int i = 1; i < 5; i++) begin
|
||||
state_counter_p[i] <= state_counter_p[i-1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
data_next = data; // If neccesary, we can remove this state?
|
||||
h_next = h;
|
||||
|
||||
state_counter_next = state_counter;
|
||||
|
||||
accumulator_next = '0;
|
||||
mult_product_next = '0;
|
||||
accumulator_intermediate = '0;
|
||||
|
||||
|
||||
if (state_counter < 3'h5) begin
|
||||
mult_product_next = h[state_counter*26 +: 26] * data;
|
||||
state_counter_next = state_counter + 1;
|
||||
end
|
||||
|
||||
if (state_counter >= 3'h4 && i_valid) begin
|
||||
data_next = i_data;
|
||||
h_next = (INT_ACC_WIDTH)'(i_accumulator);
|
||||
state_counter_next = '0;
|
||||
end
|
||||
|
||||
if (state_counter_p[3] == '0) begin
|
||||
accumulator_next = (INT_ACC_WIDTH)'(modulo_result);
|
||||
end else begin
|
||||
accumulator_next = accumulator + (INT_ACC_WIDTH)'(modulo_result);
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
poly1305_friendly_modulo u_mult_modulo (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid ('1),
|
||||
.i_val ((2*ACC_WIDTH)'(mult_product)),
|
||||
.i_shift_amount (state_counter_p[0]),
|
||||
|
||||
.o_valid (),
|
||||
.o_result (modulo_result)
|
||||
);
|
||||
|
||||
poly1305_friendly_modulo u_sum_modulo (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (state_counter_p[4] == 3'h4),
|
||||
.i_val ({127'b0, accumulator}),
|
||||
.i_shift_amount ('0),
|
||||
|
||||
.o_valid (o_valid),
|
||||
.o_result (o_result)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -36,7 +36,7 @@ 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;
|
||||
high_part_1 <= WIDE_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;
|
||||
|
||||
262
ChaCha20_Poly1305_64/src/poly1305_ll_stage.sv
Normal file
262
ChaCha20_Poly1305_64/src/poly1305_ll_stage.sv
Normal file
@@ -0,0 +1,262 @@
|
||||
// Low latency poly1305 core
|
||||
//
|
||||
// Target 2 cycles per 128 bit block
|
||||
|
||||
module poly1305_ll_stage (
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic i_valid,
|
||||
input logic [1:0] i_countm1,
|
||||
output logic o_ready,
|
||||
input logic [31:0] i_data,
|
||||
input logic i_last,
|
||||
input logic [127:0] i_r,
|
||||
input logic [127:0] i_s,
|
||||
|
||||
output logic o_valid,
|
||||
output logic [127:0] o_result
|
||||
);
|
||||
|
||||
localparam [129:0] PRIME = 130'h3fffffffffffffffffffffffffffffffb;
|
||||
|
||||
logic upconvert_ready;
|
||||
logic upconvert_valid;
|
||||
logic upconvert_last;
|
||||
logic [127:0] upconvert_data;
|
||||
logic [3:0] upconvert_countm1;
|
||||
|
||||
|
||||
poly1305_width_convert u_width_convert(
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (i_valid),
|
||||
.i_countm1 (i_countm1),
|
||||
.o_ready (o_ready),
|
||||
.i_data (i_data),
|
||||
.i_last (i_last),
|
||||
|
||||
.o_valid (upconvert_valid),
|
||||
.o_countm1 (upconvert_countm1),
|
||||
.i_ready (upconvert_ready),
|
||||
.o_data (upconvert_data),
|
||||
.o_last (upconvert_last)
|
||||
);
|
||||
|
||||
logic [127:0] r_reg, s_reg, s_reg_2;
|
||||
logic [127:0] r_reg_next, s_reg_next, s_reg_2_next;;
|
||||
|
||||
enum logic [2:0] {IDLE, SUM, LENGTHS, MULT, MODULO_1, MODULO_2} state, state_next;
|
||||
|
||||
enum logic [1:0] {OUTPUT_IDLE, OUTPUT_ADD, OUTPUT_OUT} output_state, output_state_next;
|
||||
|
||||
logic [129:0] h, h_next;
|
||||
|
||||
logic [130:0] data_1extend;
|
||||
|
||||
logic [130:0] sum, sum_next;
|
||||
|
||||
logic [258:0] product, product_next;
|
||||
|
||||
logic [131:0] mod1;
|
||||
logic [131:0] mod2_upper, mod2_upper_next;
|
||||
logic [129:0] mod2_lower, mod2_lower_next;
|
||||
logic [131:0] mod2;
|
||||
logic [131:0] mod3;
|
||||
|
||||
|
||||
logic [130:0] final_sum, final_sum_next;
|
||||
logic [130:0] final_mod;
|
||||
|
||||
logic start_output;
|
||||
|
||||
logic last_flag, last_flag_next;
|
||||
logic length_flag, length_flag_next;
|
||||
|
||||
logic [63:0] data_len, data_len_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
r_reg <= '0;
|
||||
s_reg <= '0;
|
||||
s_reg_2 <= '0;
|
||||
|
||||
data_len <= '0;
|
||||
|
||||
last_flag <= '0;
|
||||
length_flag <= '0;
|
||||
|
||||
state <= IDLE;
|
||||
output_state <= OUTPUT_IDLE;
|
||||
end else begin
|
||||
r_reg <= r_reg_next;
|
||||
s_reg <= s_reg_next;
|
||||
s_reg_2 <= s_reg_2_next;
|
||||
|
||||
data_len <= data_len_next;
|
||||
|
||||
mod2_upper <= mod2_upper_next;
|
||||
mod2_lower <= mod2_lower_next;
|
||||
|
||||
h <= h_next;
|
||||
|
||||
sum <= sum_next;
|
||||
product <= product_next;
|
||||
|
||||
last_flag <= last_flag_next;
|
||||
length_flag <= length_flag_next;
|
||||
|
||||
state <= state_next;
|
||||
output_state <= output_state_next;
|
||||
|
||||
final_sum <= final_sum_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
h_next = h;
|
||||
|
||||
sum_next = '0;
|
||||
product_next = '0;
|
||||
|
||||
final_sum_next = '0;
|
||||
|
||||
r_reg_next = r_reg;
|
||||
s_reg_next = s_reg;
|
||||
s_reg_2_next = s_reg_2;
|
||||
|
||||
data_len_next = data_len;
|
||||
|
||||
upconvert_ready = '0;
|
||||
|
||||
last_flag_next = last_flag;
|
||||
length_flag_next = length_flag;
|
||||
|
||||
state_next = state;
|
||||
|
||||
mod1 = '0;
|
||||
mod2 = '0;
|
||||
mod2_upper_next = '0;
|
||||
mod2_lower_next = '0;
|
||||
mod3 = '0;
|
||||
|
||||
data_1extend = '0;
|
||||
|
||||
start_output = '0;
|
||||
|
||||
case (state)
|
||||
IDLE: begin
|
||||
upconvert_ready = '1;
|
||||
|
||||
if (upconvert_valid) begin
|
||||
data_1extend = {3'b0, upconvert_data} | (131'b1 << (8*(1+upconvert_countm1)));
|
||||
sum_next = data_1extend;
|
||||
|
||||
data_len_next = {60'd0, upconvert_countm1} + 1;
|
||||
|
||||
state_next = MULT;
|
||||
|
||||
r_reg_next = i_r;
|
||||
s_reg_next = i_s;
|
||||
end
|
||||
end
|
||||
|
||||
SUM: begin
|
||||
last_flag_next = upconvert_last;
|
||||
|
||||
upconvert_ready = '1;
|
||||
data_1extend = {3'b1, upconvert_data};
|
||||
sum_next = h + data_1extend;
|
||||
|
||||
data_len_next = data_len + {60'd0, upconvert_countm1} + 1;
|
||||
|
||||
state_next = MULT;
|
||||
end
|
||||
|
||||
LENGTHS: begin
|
||||
length_flag_next = '1;
|
||||
|
||||
data_1extend = {3'b0, data_len, 64'b0} | (131'b1 << 128);
|
||||
sum_next = h + data_1extend;
|
||||
|
||||
state_next = MULT;
|
||||
end
|
||||
|
||||
MULT: begin
|
||||
product_next = sum * r_reg;
|
||||
|
||||
state_next = MODULO_1;
|
||||
end
|
||||
|
||||
MODULO_1: begin
|
||||
mod1 = (product[258:130] * 5) + {2'b0, product[129:0]};
|
||||
mod2_upper_next = mod1[131:130] * 5;
|
||||
mod2_lower_next = mod1[129:0];
|
||||
|
||||
state_next = MODULO_2;
|
||||
end
|
||||
|
||||
MODULO_2: begin
|
||||
mod2 = mod2_upper + {2'b0, mod2_lower};
|
||||
mod3 = (mod2[131:130] * 5) + {2'b0, mod2[129:0]};
|
||||
|
||||
if (mod3[129:0] > PRIME) begin
|
||||
h_next = mod3[129:0] - PRIME;
|
||||
end else begin
|
||||
h_next = mod3[129:0];
|
||||
end
|
||||
|
||||
if (last_flag) begin
|
||||
state_next = LENGTHS;
|
||||
last_flag_next = '0;
|
||||
end else if (length_flag) begin
|
||||
length_flag_next = '0;
|
||||
s_reg_2_next = s_reg;
|
||||
start_output = '1;
|
||||
|
||||
data_len_next = '0;
|
||||
|
||||
state_next = IDLE;
|
||||
end else begin
|
||||
state_next = SUM;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
||||
end
|
||||
|
||||
endcase
|
||||
|
||||
output_state_next = output_state;
|
||||
|
||||
o_result = '0;
|
||||
o_valid = '0;
|
||||
|
||||
case (output_state)
|
||||
OUTPUT_IDLE: begin
|
||||
if (start_output) begin
|
||||
output_state_next = OUTPUT_ADD;
|
||||
end
|
||||
end
|
||||
|
||||
OUTPUT_ADD: begin
|
||||
final_sum_next = h + {3'b0, s_reg_2};
|
||||
output_state_next = OUTPUT_OUT;
|
||||
end
|
||||
|
||||
OUTPUT_OUT: begin
|
||||
o_valid = '1;
|
||||
o_result = final_sum[127:0];
|
||||
|
||||
output_state_next = OUTPUT_IDLE;
|
||||
end
|
||||
|
||||
default: begin
|
||||
output_state_next = OUTPUT_IDLE;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
145
ChaCha20_Poly1305_64/src/poly1305_stage.sv
Normal file
145
ChaCha20_Poly1305_64/src/poly1305_stage.sv
Normal file
@@ -0,0 +1,145 @@
|
||||
module poly1305_stage #(
|
||||
|
||||
) (
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic i_valid,
|
||||
output logic o_ready,
|
||||
input logic i_clear_acc,
|
||||
input logic [129:0] i_r_power,
|
||||
input logic [127:0] i_message,
|
||||
|
||||
output logic o_valid,
|
||||
output logic [129:0] o_result
|
||||
);
|
||||
|
||||
localparam [129:0] PRIME = (1 << 130) - 5;
|
||||
|
||||
logic mult_i_valid;
|
||||
logic mult_o_ready;
|
||||
logic [129:0] r_power, r_power_next;
|
||||
logic [130:0] mult_accumulator, mult_accumulator_next;
|
||||
|
||||
logic mult_valid;
|
||||
logic [129:0] mult_result;
|
||||
|
||||
logic [129:0] accumulators [2];
|
||||
logic [129:0] accumulators_next [2];
|
||||
|
||||
logic [1:0] ops_in_flight, ops_in_flight_next;
|
||||
|
||||
logic [1:0] index, index_next;
|
||||
|
||||
|
||||
logic [1:0] index_sr [16];
|
||||
logic [1:0] index_sr_next;
|
||||
|
||||
enum logic [1:0] {SUM1, SUM2, MUL, STORE} state, state_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
state <= SUM1;
|
||||
r_power <= '0;
|
||||
mult_accumulator <= '0;
|
||||
ops_in_flight <= 2'h0;
|
||||
index <= 2'h2;
|
||||
|
||||
index_sr <= '{default: '0};
|
||||
|
||||
for (int i = 0; i < 2; i++) begin
|
||||
accumulators[i] <= '0;
|
||||
end
|
||||
end else begin
|
||||
state <= state_next;
|
||||
r_power <= r_power_next;
|
||||
mult_accumulator <= mult_accumulator_next;
|
||||
index <= index_next;
|
||||
ops_in_flight <= ops_in_flight_next;
|
||||
|
||||
for (int i = 0; i < 2; i++) begin
|
||||
accumulators[i] <= accumulators_next[i];
|
||||
end
|
||||
|
||||
index_sr[0] <= index;
|
||||
for (int i = 1; i < 16; i++) begin
|
||||
index_sr[i] <= index_sr[i-1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
logic [1:0] ops_in_flight_state;
|
||||
assign ops_in_flight_state = {i_valid & o_ready, mult_valid};
|
||||
|
||||
always_comb begin
|
||||
state_next = state;
|
||||
o_ready = '0;
|
||||
mult_accumulator_next = mult_accumulator;
|
||||
mult_i_valid = '0;
|
||||
index_next = index;
|
||||
|
||||
if (mult_valid) begin
|
||||
accumulators_next[index_sr[12][0]] = mult_result;
|
||||
end
|
||||
|
||||
case (ops_in_flight_state)
|
||||
2'b00: ops_in_flight_next = ops_in_flight;
|
||||
2'b01: ops_in_flight_next = ops_in_flight - 1;
|
||||
2'b10: ops_in_flight_next = ops_in_flight + 1;
|
||||
2'b11: ops_in_flight_next = ops_in_flight;
|
||||
endcase
|
||||
|
||||
o_valid = mult_valid;
|
||||
o_result = mult_result;
|
||||
|
||||
case (state)
|
||||
SUM1: begin
|
||||
o_ready = ops_in_flight < 2;
|
||||
|
||||
if (i_valid && o_ready) begin
|
||||
r_power_next = i_r_power;
|
||||
if (i_clear_acc) begin
|
||||
mult_accumulator_next = {3'b0, i_message};
|
||||
end else begin
|
||||
mult_accumulator_next = accumulators[index[0]] + {3'b0, i_message};
|
||||
end
|
||||
state_next = SUM2;
|
||||
end
|
||||
end
|
||||
|
||||
SUM2: begin
|
||||
mult_accumulator_next = mult_accumulator >= 131'(PRIME) ? 131'(mult_accumulator - PRIME) : mult_accumulator;
|
||||
state_next = MUL;
|
||||
end
|
||||
|
||||
MUL: begin
|
||||
mult_i_valid = '1;
|
||||
|
||||
if (mult_o_ready) begin
|
||||
index_next = index + 1;
|
||||
|
||||
state_next = SUM1;
|
||||
end
|
||||
end
|
||||
|
||||
default: begin
|
||||
state_next = SUM1;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
|
||||
poly1305_friendly_modular_mult u_modular_mult (
|
||||
.i_clk (i_clk),
|
||||
.i_rst (i_rst),
|
||||
|
||||
.i_valid (mult_i_valid),
|
||||
.o_ready (mult_o_ready),
|
||||
.i_data (r_power),
|
||||
.i_accumulator (mult_accumulator[129:0]),
|
||||
|
||||
.o_valid (mult_valid),
|
||||
.o_result (mult_result)
|
||||
);
|
||||
|
||||
endmodule
|
||||
79
ChaCha20_Poly1305_64/src/poly1305_width_convert.sv
Normal file
79
ChaCha20_Poly1305_64/src/poly1305_width_convert.sv
Normal file
@@ -0,0 +1,79 @@
|
||||
module poly1305_width_convert(
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic i_valid,
|
||||
input logic [1:0] i_countm1,
|
||||
output logic o_ready,
|
||||
input logic [31:0] i_data,
|
||||
input logic i_last,
|
||||
|
||||
output logic o_valid,
|
||||
output logic [3:0] o_countm1,
|
||||
input logic i_ready,
|
||||
output logic [127:0] o_data,
|
||||
output logic o_last
|
||||
);
|
||||
|
||||
|
||||
logic [95:0] width_convert_save, width_convert_save_next;
|
||||
logic [1:0] width_convert_count, width_convert_count_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
width_convert_save <= '0;
|
||||
width_convert_count <= '0;
|
||||
end else begin
|
||||
width_convert_count <= width_convert_count_next;
|
||||
width_convert_save <= width_convert_save_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
width_convert_save_next = width_convert_save;
|
||||
width_convert_count_next = width_convert_count;
|
||||
|
||||
o_valid = '0;
|
||||
o_ready = '0;
|
||||
o_last = '0;
|
||||
|
||||
o_countm1 = '1;
|
||||
|
||||
if (width_convert_count < 3) begin
|
||||
o_data = {32'b0, width_convert_save};
|
||||
o_data[32*width_convert_count +: 32] = i_data;
|
||||
|
||||
if (i_last && i_valid) begin
|
||||
o_ready = i_ready;
|
||||
o_valid = '1;
|
||||
o_last = '1;
|
||||
|
||||
o_countm1 = width_convert_count*4 + {2'b0, i_countm1};
|
||||
|
||||
if (i_ready) begin
|
||||
width_convert_count_next = '0;
|
||||
width_convert_save_next = '0;
|
||||
end
|
||||
end else begin
|
||||
width_convert_save_next[32*width_convert_count +: 32] = i_data;
|
||||
if (i_valid) begin
|
||||
o_ready = '1;
|
||||
width_convert_count_next = width_convert_count + 2'd1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
o_ready = i_ready;
|
||||
o_valid = i_valid;
|
||||
o_data = {i_data, width_convert_save};
|
||||
o_last = i_last;
|
||||
|
||||
o_countm1 = 4'd12 + {2'b0, i_countm1};
|
||||
|
||||
if (i_valid && o_ready) begin
|
||||
width_convert_count_next = '0;
|
||||
width_convert_save_next = '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
109
ChaCha20_Poly1305_64/src/poly1305_width_convert_2.sv
Normal file
109
ChaCha20_Poly1305_64/src/poly1305_width_convert_2.sv
Normal file
@@ -0,0 +1,109 @@
|
||||
module poly1305_width_convert_2(
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic i_valid,
|
||||
input logic [1:0] i_countm1,
|
||||
output logic o_ready,
|
||||
input logic [31:0] i_data,
|
||||
input logic i_last,
|
||||
|
||||
output logic o_valid,
|
||||
output logic [5:0] o_countm1,
|
||||
input logic i_ready,
|
||||
output logic [511:0] o_data,
|
||||
output logic o_last
|
||||
);
|
||||
|
||||
// this could definitely be parameterized,
|
||||
// but that can be a future project for the intern
|
||||
|
||||
logic [11:0] pkt_len, pkt_len_next;
|
||||
|
||||
// make this an input
|
||||
logic [11:0] pkt_len_max;
|
||||
|
||||
assign pkt_len_max = 12'd1420;
|
||||
|
||||
|
||||
logic [479:0] width_convert_save, width_convert_save_next;
|
||||
logic [3:0] width_convert_count, width_convert_count_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
width_convert_save <= '0;
|
||||
width_convert_count <= '0;
|
||||
pkt_len <= '0;
|
||||
end else begin
|
||||
width_convert_count <= width_convert_count_next;
|
||||
width_convert_save <= width_convert_save_next;
|
||||
pkt_len <= pkt_len_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
width_convert_save_next = width_convert_save;
|
||||
width_convert_count_next = width_convert_count;
|
||||
|
||||
pkt_len_next = pkt_len;
|
||||
|
||||
o_valid = '0;
|
||||
o_ready = '0;
|
||||
o_last = '0;
|
||||
|
||||
o_countm1 = '1;
|
||||
|
||||
if (width_convert_count < 15) begin
|
||||
o_data = {32'b0, width_convert_save};
|
||||
o_data[32*width_convert_count +: 32] = i_data;
|
||||
|
||||
if (i_last && i_valid) begin
|
||||
o_ready = i_ready;
|
||||
o_valid = '1;
|
||||
o_last = '1;
|
||||
|
||||
pkt_len_next = '0;
|
||||
|
||||
// wireguard packets are rounded up to 16 bytes
|
||||
o_countm1 = width_convert_count*4 + {4'b0, i_countm1};
|
||||
if (o_countm1[3:0] != 0) begin
|
||||
o_countm1 = {o_countm1[5:4], 4'hf};
|
||||
end
|
||||
|
||||
if (pkt_len + 12'(o_countm1) + 1 > pkt_len_max) begin
|
||||
o_countm1 = 6'(pkt_len_max - pkt_len - 12'd1);
|
||||
end
|
||||
|
||||
if (i_ready) begin
|
||||
width_convert_count_next = '0;
|
||||
width_convert_save_next = '0;
|
||||
end
|
||||
end else begin
|
||||
width_convert_save_next[32*width_convert_count +: 32] = i_data;
|
||||
if (i_valid & i_ready) begin
|
||||
o_ready = '1;
|
||||
width_convert_count_next = width_convert_count + 4'd1;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
o_ready = i_ready;
|
||||
o_valid = i_valid;
|
||||
o_data = {i_data, width_convert_save};
|
||||
o_last = i_last;
|
||||
|
||||
// o_countm1 = 6'd63 + {4'b0, i_countm1};
|
||||
o_countm1 = 6'd63;
|
||||
|
||||
if (i_valid && o_ready) begin
|
||||
width_convert_count_next = '0;
|
||||
width_convert_save_next = '0;
|
||||
pkt_len_next = pkt_len + 12'(o_countm1) + 12'h1;
|
||||
|
||||
if (i_last) begin
|
||||
pkt_len_next = '0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
63
ChaCha20_Poly1305_64/src/poly1305_width_convert_3.sv
Normal file
63
ChaCha20_Poly1305_64/src/poly1305_width_convert_3.sv
Normal file
@@ -0,0 +1,63 @@
|
||||
// this one converts from 512 back to 32
|
||||
|
||||
module poly1305_width_convert_3(
|
||||
input logic i_clk,
|
||||
input logic i_rst,
|
||||
|
||||
input logic i_valid,
|
||||
input logic [5:0] i_countm1,
|
||||
output logic o_ready,
|
||||
input logic [511:0] i_data,
|
||||
input logic i_last,
|
||||
|
||||
output logic o_valid,
|
||||
output logic [1:0] o_countm1,
|
||||
input logic i_ready,
|
||||
output logic [31:0] o_data,
|
||||
output logic o_last
|
||||
);
|
||||
|
||||
logic [3:0] width_convert_count, width_convert_count_next;
|
||||
|
||||
always_ff @(posedge i_clk) begin
|
||||
if (i_rst) begin
|
||||
width_convert_count <= '0;
|
||||
end else begin
|
||||
width_convert_count <= width_convert_count_next;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
width_convert_count_next = width_convert_count;
|
||||
|
||||
o_valid = '0;
|
||||
o_last = '0;
|
||||
o_ready = '0;
|
||||
|
||||
o_data = i_data[width_convert_count*32 +: 32];
|
||||
o_countm1 = '0;
|
||||
|
||||
o_valid = i_valid;
|
||||
|
||||
if (i_valid && i_ready) begin
|
||||
width_convert_count_next = width_convert_count + 1;
|
||||
o_countm1 = '1;
|
||||
|
||||
if (width_convert_count == 15) begin
|
||||
o_ready = '1;
|
||||
end
|
||||
end
|
||||
|
||||
if (i_last && 6'(width_convert_count+1)*4 > i_countm1) begin
|
||||
o_last = '1;
|
||||
o_countm1 = (2)'(i_countm1 - width_convert_count*4);
|
||||
|
||||
if (i_valid && i_ready) begin
|
||||
o_ready = '1;
|
||||
width_convert_count_next = '0;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
||||
114
ChaCha20_Poly1305_64/src/skidbuffer.sv
Normal file
114
ChaCha20_Poly1305_64/src/skidbuffer.sv
Normal file
@@ -0,0 +1,114 @@
|
||||
/*===============================================================================================================================
|
||||
Module : Pipeline Skid Buffer
|
||||
|
||||
Description : Pipeline Skid Buffer is used as buffer in pipeline between two modules.
|
||||
- Smallest pipeline buffer; implemented with just two registers.
|
||||
- Simple valid-ready handshaking.
|
||||
- Latency = 1 cycle.
|
||||
- Configurable data width.
|
||||
|
||||
Developer : Mitu Raj, chip@chipmunklogic.com at Chipmunk Logic ™, https://chipmunklogic.com
|
||||
Notes : -
|
||||
License : Open-source.
|
||||
Date : Mar-26-2022
|
||||
===============================================================================================================================*/
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------
|
||||
P I P E S K I D B U F F E R
|
||||
-------------------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
module pipe_skid_buffer #(
|
||||
// Global Parameters
|
||||
parameter DWIDTH = 8 // Data width
|
||||
)
|
||||
(
|
||||
input logic clk , // Clock
|
||||
input logic rstn , // Active-low synchronous reset
|
||||
|
||||
// Input Interface
|
||||
input logic [DWIDTH-1 : 0] i_data , // Data in
|
||||
input logic i_valid , // Data in valid
|
||||
output logic o_ready , // Ready out
|
||||
|
||||
// Output Interface
|
||||
output logic [DWIDTH-1 : 0] o_data , // Data out
|
||||
output logic o_valid , // Data out valid
|
||||
input logic i_ready // Ready in
|
||||
) ;
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------
|
||||
Local Parameters
|
||||
-------------------------------------------------------------------------------------------------------------------------------*/
|
||||
// State encoding
|
||||
localparam PIPE = 1'b0 ;
|
||||
localparam SKID = 1'b1 ;
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------
|
||||
Internal Registers/Signals
|
||||
-------------------------------------------------------------------------------------------------------------------------------*/
|
||||
logic state_rg ; // State register
|
||||
logic [DWIDTH-1 : 0] data_rg, sparebuff_rg ; // Data buffer, Spare buffer
|
||||
logic valid_rg, ready_rg ; // Valid and Ready signals
|
||||
logic ready ; // Pipeline ready signal
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------
|
||||
Synchronous logic
|
||||
-------------------------------------------------------------------------------------------------------------------------------*/
|
||||
always @(posedge clk) begin
|
||||
// Reset
|
||||
if (!rstn) begin
|
||||
// Internal Registers
|
||||
state_rg <= PIPE ;
|
||||
data_rg <= '0 ;
|
||||
sparebuff_rg <= '0 ;
|
||||
valid_rg <= 1'b0 ;
|
||||
ready_rg <= 1'b0 ;
|
||||
end
|
||||
// Out of reset
|
||||
else begin
|
||||
case (state_rg)
|
||||
|
||||
/* Stage where data is piped out or stored to spare buffer */
|
||||
PIPE : begin
|
||||
// Pipe data out
|
||||
if (ready) begin
|
||||
data_rg <= i_data ;
|
||||
valid_rg <= i_valid ;
|
||||
ready_rg <= 1'b1 ;
|
||||
end
|
||||
// Pipeline stall, store input data to spare buffer (skid happened)
|
||||
else if (i_valid) begin
|
||||
sparebuff_rg <= i_data ;
|
||||
ready_rg <= 1'b0 ;
|
||||
state_rg <= SKID ;
|
||||
end
|
||||
end
|
||||
|
||||
/* Stage to wait after data skid happened */
|
||||
SKID : begin
|
||||
// Copy data from spare buffer to data buffer when downstream is ready, resume pipeline
|
||||
if (i_ready) begin
|
||||
data_rg <= sparebuff_rg ;
|
||||
valid_rg <= 1'b1 ;
|
||||
ready_rg <= 1'b1 ;
|
||||
state_rg <= PIPE ;
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------
|
||||
Continuous Assignments
|
||||
-------------------------------------------------------------------------------------------------------------------------------*/
|
||||
assign ready = i_ready || ~valid_rg ;
|
||||
assign o_ready = ready_rg ;
|
||||
assign o_data = data_rg ;
|
||||
assign o_valid = valid_rg ;
|
||||
|
||||
endmodule
|
||||
|
||||
/*-------------------------------------------------------------------------------------------------------------------------------
|
||||
P I P E S K I D B U F F E R
|
||||
-------------------------------------------------------------------------------------------------------------------------------*/
|
||||
@@ -4,4 +4,17 @@ chacha20_pipelined_round.sv
|
||||
chacha20_pipelined_block.sv
|
||||
|
||||
poly1305_core.sv
|
||||
poly1305_friendly_modulo.sv
|
||||
poly1305_friendly_modulo.sv
|
||||
poly1305_friendly_modular_mult.sv
|
||||
poly1305_stage.sv
|
||||
|
||||
poly1305_width_convert.sv
|
||||
poly1305_width_convert_2.sv
|
||||
poly1305_width_convert_3.sv
|
||||
poly1305_ll_stage.sv
|
||||
|
||||
skidbuffer.sv
|
||||
|
||||
chacha20_poly1305_32_ll_core.sv
|
||||
chacha20_poly1305_input_fsm.sv
|
||||
chacha20_poly1305_mid_fsm.sv
|
||||
1
common/sim/sub/fifo
Submodule
1
common/sim/sub/fifo
Submodule
Submodule common/sim/sub/fifo added at 9f35e490dc
0
mod_test.py
Normal file
0
mod_test.py
Normal file
Reference in New Issue
Block a user