Skip to content

Commit 885cfd6

Browse files
authored
Merge pull request #529 from anhu/ml_kem_example
An example of how to use ML-KEM.
2 parents 3738841 + 785001f commit 885cfd6

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

pq/ml_kem/README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Description
2+
3+
Simple example of wolfCrypt ML-KEM keygen, encapsulation, and decapsulation.
4+
5+
Requires wolfSSL is built with:
6+
7+
```sh
8+
$ ./autogen.sh
9+
$ ./configure --enable-mlkem
10+
$ make
11+
$ sudo make install
12+
$ sudo ldconfig
13+
```
14+
15+
Build the ML-KEM example:
16+
17+
```sh
18+
$ gcc -o ml_kem ml_kem.c -I/usr/local/include -L/usr/local/lib -lwolfssl
19+
```
20+
21+
# Usage
22+
23+
```
24+
./ml_kem
25+
```
26+
27+
Alice will generate a public key and private key pair. The operation is known as
28+
key generation.
29+
30+
Bob will use only Alice's public key to generate a shared secret and an
31+
ecapsulated instance of the shared secret; this is known as the ciphertext. The
32+
operation is known as encapsulation.
33+
34+
Alice will use Bob's ciphertext and her private key to obtain the same shared
35+
secret. The operation is known as decapsulation.
36+
37+
# Credit
38+
39+
The wolfSSL Team would like to thank Professor Bill Buchanan of Edinburgh Napier
40+
University for initially creating this example.

pq/ml_kem/ml_kem.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* ml_kem.c
2+
*
3+
* Copyright (C) 2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfSSL. (formerly known as CyaSSL)
6+
*
7+
* wolfSSL is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfSSL is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
/* Credit goes to Professor Bill Buchanan of Edinburgh Napier University for
23+
* creating this example and contributing it back to wolfSSL. */
24+
25+
#ifndef WOLFSSL_USER_SETTINGS
26+
#include <wolfssl/options.h>
27+
#endif
28+
#include <wolfssl/wolfcrypt/settings.h>
29+
#include <wolfssl/wolfcrypt/mlkem.h>
30+
#include <wolfssl/wolfcrypt/wc_mlkem.h>
31+
#include <wolfssl/wolfcrypt/random.h>
32+
33+
#include <stdio.h>
34+
#include <stdlib.h>
35+
#include <stdint.h>
36+
37+
char* to_hex_string(const unsigned char* array, size_t length)
38+
{
39+
char* outstr = malloc(2 * length + 1);
40+
if (!outstr) return outstr;
41+
42+
char* p = outstr;
43+
for (size_t i = 0; i < length; ++i) {
44+
p += sprintf(p, "%02hhx", array[i]);
45+
}
46+
47+
return outstr;
48+
}
49+
50+
51+
int main(int argc, char** argv)
52+
{
53+
MlKemKey AliceKey;
54+
MlKemKey BobKey;
55+
int ret = 0;
56+
WC_RNG rng;
57+
byte alice_pub[WC_ML_KEM_512_PUBLIC_KEY_SIZE];
58+
byte bob_ct[WC_ML_KEM_512_CIPHER_TEXT_SIZE];
59+
byte alice_ss[WC_ML_KEM_SS_SZ];
60+
byte bob_ss[WC_ML_KEM_SS_SZ];
61+
62+
printf("Alice creates an ML-KEM-512 key pair\n\n");
63+
64+
ret = wc_InitRng(&rng);
65+
66+
if (ret == 0)
67+
ret = wc_MlKemKey_Init(&AliceKey, WC_ML_KEM_512, 0, INVALID_DEVID);
68+
69+
if (ret == 0)
70+
ret = wc_MlKemKey_Init(&BobKey, WC_ML_KEM_512, 0, INVALID_DEVID);
71+
72+
if (ret == 0)
73+
ret = wc_MlKemKey_MakeKey(&AliceKey, &rng);
74+
75+
if (ret == 0)
76+
ret = wc_MlKemKey_EncodePublicKey(&AliceKey, alice_pub, WC_ML_KEM_512_PUBLIC_KEY_SIZE);
77+
78+
if (ret == 0)
79+
printf("Bob receives public key (size=%d): %s\n\n", WC_ML_KEM_512_PUBLIC_KEY_SIZE, to_hex_string(alice_pub, WC_ML_KEM_512_PUBLIC_KEY_SIZE));
80+
81+
if (ret == 0)
82+
ret = wc_MlKemKey_DecodePublicKey(&BobKey, alice_pub, WC_ML_KEM_512_PUBLIC_KEY_SIZE);
83+
84+
if (ret == 0)
85+
ret = wc_MlKemKey_Encapsulate(&BobKey, bob_ct, bob_ss, &rng);
86+
87+
if (ret == 0)
88+
printf("Bob Encapsulates secret (Size=%d): %s\n\n", WC_ML_KEM_512_CIPHER_TEXT_SIZE, to_hex_string(bob_ct, WC_ML_KEM_512_CIPHER_TEXT_SIZE));
89+
90+
if (ret == 0)
91+
printf("Alice receives the ciphertext\n");
92+
93+
if (ret == 0)
94+
ret = wc_MlKemKey_Decapsulate(&AliceKey, alice_ss, bob_ct, WC_ML_KEM_512_CIPHER_TEXT_SIZE);
95+
96+
if (ret == 0) {
97+
printf("Alice's Shared Secret: %s\n\n", to_hex_string(alice_ss, WC_ML_KEM_SS_SZ));
98+
printf(" Bob's Shared Secret: %s\n\n", to_hex_string(bob_ss, WC_ML_KEM_SS_SZ));
99+
} else {
100+
printf("An error occurred\n");
101+
}
102+
103+
wc_MlKemKey_Free(&AliceKey);
104+
wc_MlKemKey_Free(&BobKey);
105+
wc_FreeRng(&rng);
106+
return ret;
107+
}
108+

0 commit comments

Comments
 (0)