Crypto: ML-DSA
The ML-DSA sample demonstrates how to use the PSA Crypto API to verify a message signature using the ML-DSA-65 post-quantum signature algorithm.
Requirements
The sample supports the following development kits:
Hardware platforms |
PCA |
Board name |
|
|---|---|---|---|
nRF54LV10 DK |
PCA10188 |
|
|
PCA10184 |
|
||
PCA10156 |
|
||
PCA10156 |
|
||
PCA10156 |
|
Overview
The sample enables PSA Crypto API and configures the following Kconfig options for the cryptographic features:
CONFIG_PSA_WANT_KEY_TYPE_ML_DSA_PUBLIC_KEY- Used to enable support for the ML-DSA public key type from among the supported cryptographic operations for Key types and key management.CONFIG_PSA_WANT_ALG_ML_DSA- Used to enable support for the ML-DSA signature algorithm from among the supported cryptographic operations for Asymmetric signature algorithms.CONFIG_PSA_WANT_ML_DSA_KEY_SIZE_65- Used to enable support for the ML-DSA-65 key type.CONFIG_PSA_WANT_ALG_SHAKE128andCONFIG_PSA_WANT_ALG_SHAKE256- Used to enable support for the XOF algorithms required internally by ML-DSA.
Once built and run, the sample performs the following operations:
Initialization:
The PSA Crypto API is initialized using the
psa_crypto_init()function.A known ML-DSA-65 public key is imported using the
psa_import_key()function. The public key is configured with usage flags for verification. The public key, the message, and the signature used in this sample are taken from a NIST ACVP ML-DSA signature verification test vector.
ML-DSA signature verification:
The signature is verified using the
psa_verify_message()function with the imported public key.Cleanup:
The public key is removed from the PSA crypto keystore using the
psa_destroy_key()function.
Building and running
This sample can be found under samples/crypto/ml_dsa in the nRF Connect SDK folder structure.
To build the sample, follow the instructions in Building an application for your preferred building environment. See also Programming an application for programming steps and Testing and optimization for general information about testing and debugging in the nRF Connect SDK.
Note
When building repository applications in the SDK repositories, building with sysbuild is enabled by default.
If you work with out-of-tree freestanding applications, you need to manually pass the --sysbuild parameter to every build command or configure west to always use it.
Testing
After programming the sample to your development kit, complete the following steps to test it:
Connect to the kit with a terminal emulator (for example, the Serial Terminal app). See Testing and optimization for the required settings and steps.
Build and program the application.
Observe the logs from the application using the terminal emulator. For example, the log output should look like this:
*** Booting nRF Connect SDK v3.4.99-baaa74699d09 ***
*** Using Zephyr OS v4.4.0-bc35f6fe0b34 ***
[00:00:00.003,144] <inf> ml_dsa: Starting ML-DSA example...
[00:00:00.003,152] <inf> ml_dsa: Importing an ML-DSA-65 public key...
[00:00:00.003,368] <inf> ml_dsa: ML-DSA-65 public key imported successfully!
[00:00:00.003,383] <inf> ml_dsa: ---- ML-DSA-65 public key (total len: 1952, printing 16 bytes): ----
[00:00:00.003,393] <inf> ml_dsa: Content:
91 52 c0 c6 86 77 60 8f 42 6f b1 6f 8f 75 f7 6c |.R...w`. Bo.o.u.l
[00:00:00.003,403] <inf> ml_dsa: ---- ML-DSA-65 public key end ----
[00:00:00.003,409] <inf> ml_dsa: Verifying the ML-DSA signature...
[00:00:00.138,565] <inf> ml_dsa: ---- Message (total len: 1554, printing 16 bytes): ----
[00:00:00.138,578] <inf> ml_dsa: Content:
88 45 ad 39 4b ce 60 b2 84 76 b2 13 99 b0 d4 72 |.E.9K.`. .v.....r
[00:00:00.138,588] <inf> ml_dsa: ---- Message end ----
[00:00:00.138,597] <inf> ml_dsa: ---- Signature (total len: 3309, printing 16 bytes): ----
[00:00:00.138,606] <inf> ml_dsa: Content:
6e 8c 4b 20 61 c2 cd f2 71 54 bf 70 85 f6 3c b1 |n.K a... qT.p..<.
[00:00:00.138,615] <inf> ml_dsa: ---- Signature end ----
[00:00:00.138,620] <inf> ml_dsa: Signature verification was successful!
[00:00:00.138,730] <inf> ml_dsa: Example finished successfully!