Skip to content

Commit db90b83

Browse files
committed
Support ML-KEM
1 parent 0d345aa commit db90b83

File tree

4 files changed

+1003
-2
lines changed

4 files changed

+1003
-2
lines changed

docs/asymmetric.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,35 @@ ECC
8181
.. autoclass:: EccPrivate
8282
:members:
8383
:inherited-members:
84+
85+
ML-KEM
86+
------
87+
88+
.. autoclass:: MlKemType
89+
:show-inheritance:
90+
91+
.. autoclass:: MlKemPublic
92+
:private-members:
93+
:members:
94+
:inherited-members:
95+
96+
.. autoclass:: MlKemPrivate
97+
:members:
98+
:inherited-members:
99+
100+
**Example:**
101+
102+
>>> from wolfcrypt.ciphers import MlKemType, MlKemPrivate, MlKemPublic
103+
>>>
104+
>>> mlkem_type = MlKemType.ML_KEM_512
105+
>>>
106+
>>> mlkem_priv = MlKemPrivate.make_key(mlkem_type)
107+
>>> pub_key = mlkem_priv.encode_pub_key()
108+
>>>
109+
>>> mlkem_pub = MlKemPublic(mlkem_type)
110+
>>> mlkem_pub.decode_key(pub_key)
111+
>>> ss_send, ct = mlkem_pub.encapsulate()
112+
>>>
113+
>>> ss_recv = mlkem_priv.decapsulate(ct)
114+
>>> ss_send == ss_recv
115+
True

scripts/build_ffi.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,10 @@ def make_flags(prefix, fips):
232232
flags.append("--enable-pwdbased")
233233
flags.append("--enable-pkcs7")
234234

235+
# ML-KEM
236+
flags.append("--enable-experimental")
237+
flags.append("--enable-kyber")
238+
235239
# disabling other configs enabled by default
236240
flags.append("--disable-oldtls")
237241
flags.append("--disable-oldnames")
@@ -442,6 +446,8 @@ def build_ffi(local_wolfssl, features):
442446
#include <wolfssl/wolfcrypt/curve25519.h>
443447
#include <wolfssl/wolfcrypt/poly1305.h>
444448
#include <wolfssl/wolfcrypt/chacha20_poly1305.h>
449+
#include <wolfssl/wolfcrypt/kyber.h>
450+
#include <wolfssl/wolfcrypt/wc_kyber.h>
445451
"""
446452

447453
init_source_string = """
@@ -478,6 +484,7 @@ def build_ffi(local_wolfssl, features):
478484
int AESGCM_STREAM_ENABLED = """ + str(features["AESGCM_STREAM"]) + """;
479485
int RSA_PSS_ENABLED = """ + str(features["RSA_PSS"]) + """;
480486
int CHACHA20_POLY1305_ENABLED = """ + str(features["CHACHA20_POLY1305"]) + """;
487+
int ML_KEM_ENABLED = """ + str(features["ML_KEM"]) + """;
481488
"""
482489

483490
ffibuilder.set_source( "wolfcrypt._ffi", init_source_string,
@@ -513,6 +520,7 @@ def build_ffi(local_wolfssl, features):
513520
extern int AESGCM_STREAM_ENABLED;
514521
extern int RSA_PSS_ENABLED;
515522
extern int CHACHA20_POLY1305_ENABLED;
523+
extern int ML_KEM_ENABLED;
516524
517525
typedef unsigned char byte;
518526
typedef unsigned int word32;
@@ -922,6 +930,30 @@ def build_ffi(local_wolfssl, features):
922930
int wolfCrypt_GetPrivateKeyReadEnable_fips(enum wc_KeyType);
923931
"""
924932

933+
if features["ML_KEM"]:
934+
cdef += """
935+
static const int WC_ML_KEM_512;
936+
static const int WC_ML_KEM_768;
937+
static const int WC_ML_KEM_1024;
938+
static const int INVALID_DEVID;
939+
typedef struct {...; } KyberKey;
940+
int wc_KyberKey_CipherTextSize(KyberKey* key, word32* len);
941+
int wc_KyberKey_SharedSecretSize(KyberKey* key, word32* len);
942+
int wc_KyberKey_PrivateKeySize(KyberKey* key, word32* len);
943+
int wc_KyberKey_PublicKeySize(KyberKey* key, word32* len);
944+
int wc_KyberKey_Init(int type, KyberKey* key, void* heap, int devId);
945+
void wc_KyberKey_Free(KyberKey* key);
946+
int wc_KyberKey_MakeKey(KyberKey* key, WC_RNG* rng);
947+
int wc_KyberKey_MakeKeyWithRandom(KyberKey* key, const unsigned char* rand, int len);
948+
int wc_KyberKey_EncodePublicKey(KyberKey* key, unsigned char* out, word32 len);
949+
int wc_KyberKey_DecodePublicKey(KyberKey* key, const unsigned char* in, word32 len);
950+
int wc_KyberKey_Encapsulate(KyberKey* key, unsigned char* ct, unsigned char* ss, WC_RNG* rng);
951+
int wc_KyberKey_EncapsulateWithRandom(KyberKey* key, unsigned char* ct, unsigned char* ss, const unsigned char* rand, int len);
952+
int wc_KyberKey_Decapsulate(KyberKey* key, unsigned char* ss, const unsigned char* ct, word32 len);
953+
int wc_KyberKey_EncodePrivateKey(KyberKey* key, unsigned char* out, word32 len);
954+
int wc_KyberKey_DecodePrivateKey(KyberKey* key, const unsigned char* in, word32 len);
955+
"""
956+
925957
ffibuilder.cdef(cdef)
926958

927959
def main(ffibuilder):
@@ -951,7 +983,8 @@ def main(ffibuilder):
951983
"WC_RNG_SEED_CB": 0,
952984
"AESGCM_STREAM": 1,
953985
"RSA_PSS": 1,
954-
"CHACHA20_POLY1305": 1
986+
"CHACHA20_POLY1305": 1,
987+
"ML_KEM": 1
955988
}
956989

957990
# Ed448 requires SHAKE256, which isn't part of the Windows build, yet.

0 commit comments

Comments
 (0)