International Association for Cryptologic Research

International Association
for Cryptologic Research

Transactions on Cryptographic Hardware and Embedded Systems 2026

High-Performance FPGA Accelerator for the Post-quantum Signature Scheme CROSS


README

CROSS Hardware Implementation

This repository hosts the Register Transfer Level (RTL) SystemVerilog code implementing a hardware accelerator for the Codes and Restricted Objects Signature Scheme (CROSS) (v2.2), including testbenches for behavioral simulation and utility scripts for the Vivado (FPGA) synthesis tool.

The repository structure is primarily designed to align with the specifications of the FuseSoC package manager, encouraging HDL code modularity and broad compatibility with EDA tools thanks to the underlying Edalize library.

Testing of hardware modules is automated via the GitHub Actions continuous integration (CI). Configuration files are in the .github/workflows folder.

The code is released under the Solderpad Hardware License v 2.1, excluding FIFO and spill register (Solderpad Hardware License v 0.51).

Repository structure

The tree below shows the first three levels of directories in the repository:

.
├── fusesoc
│   ├── designs
│   │   ├── axi
│   │   ├── cross
│   │   ├── misc
│   │   ├── modulo
│   │   └── sha3
│   ├── fpga
│   │   └── scripts
│   └── test
│       ├── lint
│       ├── rtl
│       ├── tcl
│       └── xdc
└── utils

User guide

Dependencies

System dependencies for Debian-based distributions are:

# apt install --no-install-recommends -y \
    git \
    build-essential \
    make \
    cmake \
    ninja-build \
    g++ \
    ccache \
    curl \
    bzip2

The following binaries are expected to be present in any of the $PATH directories:

Older versions of that software are not guaranteed to work correctly.

Python and other system dependencies are listed in the environment.yml file, which can be used by any conda-compatible package manager, like micromamba, to create the environment with the command

$ micromamba create --file environment.yml --yes

The environment is then cached and can be activated by calling

$ micromamba activate cross-hw-design

For the sake of reproducibility, the latest working (x86_64) environment can be rebuilt using the env_freeze.yml.

EDA tool execution

The code is managed by the FuseSoC repository manager, which:

All these steps are performed by analyzing the .core module definitions in the fusesoc directory.

The base command is:

$ fusesoc run --target <target> <VLNV> [<parameters> ...]

where <target> is typically either sim or synth depending on the operation to perform, <VLNV> is the colon-separated Vendor, Library, Name, and Version (VLNV) string identifying a module definition in a .core file.

You can list all the available cores, along with a short description, with the command fusesoc core list.

The <parameters> are dynamically generated depending on the content of the .core files gathered by the solved dependency graph, and can be listed by appending the --help argument.

See FuseSoC and Edalize documentation for further information.

Simulation target

To run the behavioral simulation of a module, use the sim target.

For example, this command runs the behavioral simulation of the exponentiation vector:

$ fusesoc run --target sim cross:arithmetic:exp_vector

This will create a working directory ./build containing the simulation report (e.g., report.html) and all files used during simulation. Using the --setup flag creates the working directory without starting the simulation.

There are several testbenches, targeting the internal submodules (e.g., the arithmetic units, the sampling units, the SHA-3 hash function) etc. When running the top-level test, keygen, sign and verify are tested for all parameter sets and different internal configurations of the width of the matrix multiplier and number of unrolled Keccak rounds. Top-level and sampling related tests are automatically checked against the C reference implementation of CROSS.

All currently available simulation targets are listed below:

Name Command
Mersenne prime modulo fusesoc run --target sim cross:modulo:mersenne
Crandall prime modulo fusesoc run --target sim cross:modulo:crandall
Keccak core fusesoc run --target sim hash:sha3:core
AXI stream asymmetric FIFO fusesoc run --target sim cross:axi:axis_asym_fifo
Vectorized addition/subtraction fusesoc run --target sim cross:arithmetic:add_sub_vector
Vectorized point-wise multiplication fusesoc run --target sim cross:arithmetic:mul_vector
Vector-Matrix multiplication fusesoc run --target sim cross:arithmetic:mul_vector_matrix
Vectorized exponentiation fusesoc run --target sim cross:arithmetic:exp_vector
Arithmetic unit fusesoc run --target sim cross:arithmetic:arithmetic_unit
Sample unit fusesoc run --target sim cross:sampling:sample_unit
F_z rejection sampler fusesoc run --target sim_zk_sample cross:sampling:sample_unit
Tree unit (fast version) fusesoc run --target sim cross:trees:no_tree_unit
Merkle tree addressing fusesoc run --target sim_mtree_addr cross:trees:tree_unit
Merkle tree interface fusesoc run --target sim_mtree_intf cross:trees:tree_unit
Seed tree addressing fusesoc run --target sim_stree_addr cross:trees:tree_unit
Seed tree interface fusesoc run --target sim_stree_intf cross:trees:tree_unit
Tree unit fusesoc run --target sim_tree_unit cross:trees:tree_unit
Pack fusesoc run --target sim cross:packing:packing_unit
TOP fusesoc run --target sim cross:top:top

More details are provided in the design Verification section.

FPGA synthesis target

The HDL files are FPGA manufacturer agnostic.

Here there is a command example which starts the synthesis/implementation of the CROSS vectorized exponentiation module setting the SystemVerilog define RSDP, CATEGORY_1 and FAST parameter choice:

$ fusesoc run --build --target synth cross:arithmetic:exp_vector --RSDP --CATEGORY_1 --FAST

The --build flag skips the automatic loading of the bitstream to the FPGA connected to the host. The --setup flag skips the synthesis and only creates the working directory containing .tcl scripts for Vivado.

The default synthesis tool is Vivado, but it can be overwritten by appending --tool <EDA_TOOL_NAME> to the previous command.

During the FPGA synthesis with the Vivado EDA tool, some environment variables are used to apply common configurations:

Note that for standalone synthesis/implementation runs, XLX_SYNTH_OOC must be set.

FPGA validation

The repository provides a test harness to run the design on a Digilent Nexys Video board. Required scripts and corresponding README can be found under ./utils.

Design Space Exploration (DSE)

The repository provides utilities to automate the Design Space Exploration (DSE) of the CROSS hardware implementation. These scripts evaluate performance (through simulation) and resource utilization (through synthesis/implementation).

However, the scripts require the artifact to be a git tree in order to run different versions/commits. Therefore, initialize the repository and create a branch as follows:

$ git init
$ git add .
$ git commit -m "Initial commit"

Now, to start the full automated DSE:

$ python3 utils/cross_dse.py --outputdir <DSE_OUTPUT_DIR> --repodir . --config <CONFIG_YAML> --jobs <NUM_JOBS>

This utility will run the simulations (determining the clock latency) and synthesis runs (determining area and maximum frequency) for each module and parameter configuration listed in the provided YAML configuration file. The results are gathered and reported in a pandas dataframe exported as CSV and HTML files.

For further details on additional DSE utilities and the configuration file format, please refer to the utils/README.md.

Available YAML configuration files:

Developer guide

Linting of the SystemVerilog code is performed with verible upon commit automatically by the git pre-commit hook using the verible-lint.py script.

Install the pre-commit hook running pre-commit install in a shell after having activated the conda environment

Manually run the hook with pre-commit run --all-files

Design Verification

The hardware modules undergo behavioral simulation, employing the open-source Verilator simulator. Verilator translates Verilog and SystemVerilog code into C++ sources.

Testbenches have been redesigned to utilize the Cocotb framework, which enables the rapid creation of cross-simulator testbenches using the Python language. For the top-level test as well as for several sampling modules, the output is automatically checked against the C reference implementation, which is made accessible in Python via ctypes. Therefore, the C files are compiled into shared objects (.so) when invoking fusesoc for the first time.

The development could be defining the following environment variables:

Note

To limit the number of workers available for the verification, set the environment variable PYTEST_XDIST_AUTO_NUM_WORKERS to the desired number of processes.

The GitHub Actions CI configurations can be tested locally with nektos' act, and immediately test a workflow or even a single job.

$ act --bind --workflows .github/workflows/<test>.yaml --rm --quiet

If you are using Podman, append --container-daemon-socket $XDG_RUNTIME_DIR/podman/podman.sock to the previous command.