pqm4 ships with a curated set of NIST-standardized schemes, but you can extend it with additional algorithms. You might want to do this to evaluate an experimental scheme, test a custom Cortex-M4 assembly optimization, or contribute a new implementation to the community.
A scheme in pqm4 is a self-contained cryptographic algorithm implementation. Each scheme lives in its own directory under crypto_kem/, and pqm4’s build system automatically discovers and compiles it alongside the existing schemes.
In this section, you’ll use NewHope-512-CPA-KEM as a concrete example of a scheme. NewHope is a lattice-based KEM that was a candidate in the NIST PQC standardization process. Although NewHope was not selected for standardization, it remains a useful example because it shares structural similarities with ML-KEM. It also has a clean, well-documented reference implementation. The following steps apply equally to any KEM that follows the NIST/SUPERCOP/PQClean API.
Clone the NewHope reference implementation from the pqm4 root directory:
git clone https://github.com/newhopecrypto/newhope.git
The source files you need are in newhope/ref/.
Inside the pqm4 repository, create a directory for the new scheme:
mkdir -p crypto_kem/newhope512cpa/m4
Copy the following files from newhope/ref/ into crypto_kem/newhope512cpa/m4/:
cp newhope/ref/poly.c crypto_kem/newhope512cpa/m4/
cp newhope/ref/poly.h crypto_kem/newhope512cpa/m4/
cp newhope/ref/ntt.c crypto_kem/newhope512cpa/m4/
cp newhope/ref/ntt.h crypto_kem/newhope512cpa/m4/
cp newhope/ref/reduce.c crypto_kem/newhope512cpa/m4/
cp newhope/ref/reduce.h crypto_kem/newhope512cpa/m4/
cp newhope/ref/cpapke.c crypto_kem/newhope512cpa/m4/
cp newhope/ref/cpapke.h crypto_kem/newhope512cpa/m4/
cp newhope/ref/cpakem.c crypto_kem/newhope512cpa/m4/
cp newhope/ref/cpakem.h crypto_kem/newhope512cpa/m4/
cp newhope/ref/params.h crypto_kem/newhope512cpa/m4/
cp newhope/ref/precomp.c crypto_kem/newhope512cpa/m4/
cp newhope/ref/verify.c crypto_kem/newhope512cpa/m4/
cp newhope/ref/verify.h crypto_kem/newhope512cpa/m4/
Don’t copy the following files:
randombytes.c and randombytes.h, rng.c and rng.h — pqm4 provides its own RNGfips202.c and fips202.h — use mupq/common/fips202.h insteadccakem.c and ccakem.h — this Learning Path uses the CPA variant onlyPQCgenKAT_kem.cspeed.c and test_newhope.c.o filesCreate crypto_kem/newhope512cpa/m4/api.h and define the required constants and function declarations. Use the values from params.h in the NewHope reference implementation for the byte sizes:
#ifndef API_H
#define API_H
#define CRYPTO_SECRETKEYBYTES 3680
#define CRYPTO_PUBLICKEYBYTES 1824
#define CRYPTO_CIPHERTEXTBYTES 2208
#define CRYPTO_BYTES 32
#define CRYPTO_ALGNAME "NewHope512-CPA"
int crypto_kem_keypair(unsigned char *pk, unsigned char *sk);
int crypto_kem_enc(unsigned char *ct, unsigned char *ss, const unsigned char *pk);
int crypto_kem_dec(unsigned char *ss, const unsigned char *ct, const unsigned char *sk);
#endif
Clean and rebuild pqm4 with your target platform.
To clean and rebuild pqm4 on a physical board:
make clean
make -j4 PLATFORM=nucleo-l476rg
To clean and rebuild pqm4 on QEMU:
make clean
make -j4 PLATFORM=mps2-an386
After cleaning and rebuilding, check that the new binaries were generated:
ls elf/ | grep newhope512cpa | grep '\.elf$'
The output is similar to:
crypto_kem_newhope512cpa_m4_hashing.elf
crypto_kem_newhope512cpa_m4_speed.elf
crypto_kem_newhope512cpa_m4_stack.elf
crypto_kem_newhope512cpa_m4_test.elf
crypto_kem_newhope512cpa_m4_testvectors.elf
Make sure your virtual environment is active, then run the automated test script to verify correctness.
Run the automated test script on a physical board:
python3 test.py -p nucleo-l476rg --uart /dev/tty.usbmodemXXXX newhope512cpa
Run the automated test script on QEMU:
python3 test.py -p mps2-an386 newhope512cpa
The output is similar to:
newhope512cpa - m4 SUCCESSFUL
pqm4 provides optimized implementations of common primitives that you should use instead of bundling your own:
mupq/common/fips202.hsha2.hcommon/aes.hThe NewHope-512-CPA-KEM example uses the optimized Keccak code from mupq/common/fips202.h.
After your implementation is working and tested, you can contribute it upstream:
You’ve now set up the pqm4 environment, run tests and benchmarks for a NIST-standardized post-quantum KEM on Arm Cortex-M4, and integrated a new scheme into the framework.
You can now create your own post-quantum cryptography algorithm implementations for pqm4 and contribute them upstream.