International Association for Cryptologic Research

International Association
for Cryptologic Research

Transactions on Cryptographic Hardware and Embedded Systems 2026

Lightening CROSS:

Memory Optimized Implementations of CROSS


README

LightCROSS

Overview

An efficient and memory optimised implementation of the CROSS signature scheme. This repository is a fork of the pqm4 library with just the optimised CROSSv2.1 implementations included in crypto_sign and mupq/crypto_sign. The code in the crypto_sign and mupq/crypto_sign is exactly the same, the only difference is in the crypto_sign/crossv2.0-sha3-r-sdp-1-small/light/parameters.h the OPT_DSP flag is turned off for the mupq/crypto_sign variant to prevent it being platform specific. Thus the mupq/crypto_sign implementations are generic C optimisations, whereas the crypto_sign implementation is M4 specific.

There are two variants of the optimised CROSS implementation in this repository, light and ultra(light). The main difference being that light tries to match or beat the speed of the reference, whereas ultra attempts to use minimal memory, while allowing for some speed losses. This only difference is apparent in Signing.

This implementation achieves the following improvements over the reference:

Memory:

Speed:

Note the speed measurements are with the DSP optimisations. The optimisations can be customised by turning various compiler flags in the parameters.h file on or off.

Instructions

Note: All of the scripts were written and run with python-3.12.11. Some parts of the scripts require features only available in python-3.12 or later. Please check your python version if you have any errors.

Requirements

If in doubt about setting the environment up, see the original pqm4 library.

Running a Single Implementation

For running a single implementation on the board use the command:

make clean && ./scripts/load.sh elf/<path separated by underscores>_(test|stack|speed).elf

e.g.

To run the cross-1-small light variant in mupq for speed:

make clean && ./scripts/load.sh elf/mupq_crypto_sign_crossv2.0-sha3-r-sdp-1-small_light_speed.elf

Note: If there is an error with the make no target clean or something to that effect. That just means the directory is already cleaned. All you need to do is omit the make clean command (start the command from ./scripts/load.sh).

Benchmarking

  1. Activate the python environment defined by requirements.txt, can be done with:

    python3 -m venv venv
    source venv/bin/activate
    pip install -r requirements.txt
    
  2. Connect the nucleo-l4r5zi board to your computer

  3. Verify the serial connection, check which port it is on (e.g. /dev/ttyACM0)

  4. Run ./scripts/benchmark.sh. N.B. If it is not correctly connecting to the serial port with the device, make sure to check /dev/ttyACM0 is correct (and adjust in the script if not)

  5. Run python3 ./convert_benchmarks.py csv > results/<result_file_name>.csv

  6. Run python3 ./results/process-data.py -f ./results/<result_file_name>.csv

Debugging Benchmarking

serial.serialutil.SerialException: [Errno 2] could not open port /dev/ttyACM<number>: This means that the board is not connected at the expected port. Please check that the correct port is in the script and it matches the one that the board shows up on your computer.

Lots of Permission denied errors: This can happen when trying to compile from a zip file. The easiest way to deal with this is by just setting user permissions on everything, sudo chmod u+rwx -R ..

Compilation error expected identifier or '(' before '.' token: Especially if it shows what look like relative paths in the error body. This means that the symlinks are broken in the repository. Usually it will be in two places the mupq/crypto_sign and crypto_sign directories. Run python3 ./scripts/fix-symlink.py -d ./mupq/crypto_sign and python3 ./scripts/fix-symlink.py -d ./crypto_sign and check if that has repaired the symlinks. Unsure if this works on Windows.

Explanation of Optimisation Flags

You can adjust the optimisations by commenting or uncommenting the various optimisation flags in the parameters.h file. To the OPT_U_PRIME_EPH differentiates the light and ultralight variant.