Post-quantum masked crypto library for the ARM Cortex-M4 based on pqm4.
The pqm4_masked library is based on pqm4 and adds masked implementations of selected algorithms. These implementations are intended as reference code, demonstrating how the algorithms can be masked.
/!\These implementations have not been subjected to leakage assessment nor to formal verification, and are therefore likely to have weaknesses./!\
Implemented algorithms:
- KEM (research paper)
kyber768(v3.02)- saber (round 3)
- Signature (research paper)
dilithium3(v3.1)
Differences from research papers:
- Fix weaknesses identified by Zeitschner et al..
- Fresh re-implementation of dilithium.
For the version evaluated in the first paper, see the tches tag.
This code has not been optimized. Simple programming tricks can improve the performances, especially for small number of shares.
See the code at:
crypto_kem/kyber768/m4fspeed_maskedcrypto_kem/saber/m4fspeed_maskedcrypto_sign/dilithium3/m4f_masked
Same as pqm4.
For the purpose of simple testing and benchmarking, the pqm4_masked library uses the NIST/SUPERCOP/PQClean API. (See pqm4.)
/!\As a result, the secret key is stored unmasked, which is insecure./!\
/!\The epheremal (encapsulated) key is also unprotected similarly as this paper./!\
pqm4_masked has been tested exclusively on the nucleo-l4r5zi target.
In addition to pqm4 common testing (testvectors.py and benchmarking benchmarking.py), pqm4_masked supports:
- testing a single implementation (e.g.
kyber768/m4fspeed_maskedas command-line parameter) - benchmarking components of the masked implementation
subspeedinbenchmarks.py
Before running any code, run cd libopencm3; make; cd .., otherwise the scripts fail.
# Testvectors
CFLAGS="-DNSHARES=2" python3 testvectors.py -p nucleo-l4r5zi --uart /dev/ttyACM0 kyber768/m4fspeed_masked
# Benchmark whole
CFLAGS="-DNSHARES=2 -DBENCH=0" python3 benchmarks.py -p nucleo-l4r5zi --uart /dev/ttyACM0 kyber768/m4fspeed_masked --speed
# Benchmark components
CFLAGS="-DNSHARES=2 -DBENCH=1" python3 benchmarks.py -p nucleo-l4r5zi --uart /dev/ttyACM0 kyber768/m4fspeed_masked --subspeed(Replace kyber768/m4fspeed_masked with saber/m4fspeed_masked or dilithium3/m4f_masked for the other algorithms.)
By default, the implementations use a mix of C and Assembly (implementation
S3 and K3 in the research paper). In order to enforce the usage of pure C
implementation, the CFLAGS must contain -DUSEC. With the USEC defined,
the implementations S2 and K2 are used.
You can run all the benchmarks for saber or kyber768, then show a plot of
the results by runing:
./run_bench.sh kyber768
python3 parse_bench.py kyber768 asm
python3 parse_bench.py kyber768 cWe provide a profiling framework that measures the execution time of
sub-parts of the implementations.
To configure the measured parts, first edit BENCH_CASES in
common/bench.h (we provide a reasonable default).
Example (to measure my_function and my_other_function):
#define BENCH_CASES X(my_function) X(my_other_function)Then you increase the performance counter of that part where it is called:
start_bench(my_function);
my_function(...); // This can be any block of code you want to measure.
stop_bench(my_function);See also common/bench.c and common/speed_sub.c for additional details about
the profiling framework.
Note that the profiling framework can be configured with defines (e.g. using
CFLAGS configuration).
To activate the profiling framework, the flag BENCH=1 must be defined.
In order to measure randomness usage instead of cycle count, BENCH_RND=1 must be defined.
When referring to this framework in academic literature, please consider using the following bibTeX excerpts:
@article{DBLP:journals/tches/BronchainC22,
author = {Olivier Bronchain and
Ga{\"{e}}tan Cassiers},
title = {Bitslicing Arithmetic/Boolean Masking Conversions for Fun and Profit
with Application to Lattice-Based KEMs},
journal = {{IACR} Trans. Cryptogr. Hardw. Embed. Syst.},
volume = {2022},
number = {4},
pages = {553--588},
year = {2022}
}
@article{DBLP:journals/tches/AzouaouiBCHKRSSSV23,
author = {Melissa Azouaoui and
Olivier Bronchain and
Ga{\"{e}}tan Cassiers and
Cl{\'{e}}ment Hoffmann and
Yulia Kuzovkova and
Joost Renes and
Tobias Schneider and
Markus Sch{\"{o}}nauer and
Fran{\c{c}}ois{-}Xavier Standaert and
Christine van Vredendaal},
title = {Protecting Dilithium against Leakage Revisited Sensitivity Analysis
and Improved Implementations},
journal = {{IACR} Trans. Cryptogr. Hardw. Embed. Syst.},
volume = {2023},
number = {4},
pages = {58--79},
year = {2023}
}
Different parts of pqm4_masked have different licenses. Each subdirectory containing implementations contains a LICENSE or COPYING file stating under what license that specific implementation is released. The files in common contain licensing information at the top of the file (and are currently either public domain or MIT). All other code in this repository is released under the conditions of CC0.
Note: masked implementations are released under the conditions of the GPLv3.