ML-KEM并非Diffie-Hellman密钥交换:ML-KEM分步指南

本文介绍了ML-KEM(Module-Learning Key Encapsulation Mechanism),一种后量子密码学中的密钥封装方法,旨在替代传统的Diffie-Hellman密钥交换。文章通过逐步指南,阐述了ML-KEM的原理,包括密钥生成、封装和解封装过程,并提供了使用wolfCrypt库进行ML-KEM-512实现的示例代码。

ML-KEM 不是 Diffie-Hellman 密钥交换:ML-KEM 逐步指南

在技术领域,每隔一段时间,就会出现一些改变整个领域的东西。后量子密码学现在就属于这种情况,我们将删除 RSA 和 ECC 公钥密码学领域的教学内容,并用量子稳健的方法取而代之。其中一个将被淘汰的领域是 Diffie-Hellman 密钥交换方法的使用。它现在已经有大约 49 年的历史,并且一直做得很好,但是需要用 KEM(密钥封装方法)代替。基本上,KEM 更像是公钥加密,而不是密钥交换方法。

从 DH 到 ML-KEM

如果你从事网络安全工作,你可能已经了解了神奇的 Diffie-Hellman 方法。使用此方法,Bob 和 Alice 各自创建一个密钥(分别为 b 和 a),然后共享其密钥的公共版本:

最后,他们可以生成相同的密钥。对于 ML-KEM(又名 Kyber),我们获取 Alice 的公钥,然后将其传递给 Bob。然后,Bob 将使用此密钥来封装密钥。此操作的输出是 ctss。Bob 会将 ct 发送给 Alice,然后可以解码 ss 的值以显示共享密钥。然后,Alice 将解封装 ct 的值以显示共享密钥:

使用 wolfCrypt,最初,Alice 将创建一个密钥对:

// Alice creates a key pair
    printf("Alice creates an ML-KEM-512 key pair\n\n");

ret = wc_InitRng(&rng);
    ret = wc_MlKemKey_Init(&AliceKey, WC_ML_KEM_512,0, INVALID_DEVID);
    int ss_size;
    wc_KyberKey_SharedSecretSize(&AliceKey, &ss_size);
    ret = wc_MlKemKey_MakeKey(&AliceKey, &rng);

这将包含一个公钥和一个私钥。然后,她可以为 Bob 编码公钥:

byte Alicepub[WC_ML_KEM_512_PUBLIC_KEY_SIZE];
    ret = wc_MlKemKey_EncodePublicKey(&AliceKey, Alicepub, WC_ML_KEM_512_PUBLIC_KEY_SIZE);

AlicePub 的字节数组将包含她的编码后的公钥,她将发送给 Bob。然后,Bob 可以解码此公钥并将其放入 AliceKey

ret = wc_MlKemKey_DecodePublicKey(&AliceKey, Alicepub, WC_ML_KEM_512_PUBLIC_KEY_SIZE);

使用 Alice 的公钥,Bob 将生成密文,该密文封装共享密钥:

byte ct[WC_ML_KEM_512_CIPHER_TEXT_SIZE], ss[WC_ML_KEM_512_CIPHER_TEXT_SIZE];
    ret = wc_MlKemKey_Encapsulate(&AliceKey, ct, ss, &rng);

然后,他可以将密文 ( ct) 发送给 Alice。然后,Alice 可以使用以下命令显示共享密钥 ( sharedsecretAlice):

ret = wc_MlKemKey_Decapsulate(&AliceKey,ct, shared_secretAlice, &rng);

Bob 应该使用以下命令获得相同的共享密钥:

wc_MlKemKey_DecodePrivateKey(&AliceKey, shared_secretBob,&ss_size);

以下定义了 Kyber、SABER、NTRU 和 McEliece 的密钥大小:

Type      Public key size (B)   Secret key size (B)  Ciphertext size (B)
------------------------------------------------------------------------
ML-KEM-512              800              1,632                  768  Learning with errors (Lattice)
ML-KEM-738            1,184              2,400                1,088  Learning with errors (Lattice)
ML-KEM-1024           1,568              3,168                1,568  Learning with errors (Lattice)

LightSABER            672              1,568                  736  Learning with rounding (Lattice)
SABER                 992              2,304                1,088  Learning with rounding (Lattice)
FireSABER           1,312              3,040                1,472  Learning with rounding (Lattice)

McEliece348864    261,120              6,452                  128  Code based
McEliece460896    524,160             13,568                  188  Code based
McEliece6688128 1,044,992             13,892                  240  Code based
McEliece6960119 1,047,319             13,948                  226  Code based
McEliece8192128 1,357,824             14,120                  240  Code based
NTRUhps2048509        699                935                  699  Lattice
NTRUhps2048677        930              1,234                  930  Lattice
NTRUhps4096821      1,230              1,590                1,230  Lattice

SIKEp434              330                 44                  346  Isogeny
SIKEp503              378                 56                  402  Isogeny
SIKEp751              564                 80                  596  Isogeny

SIDH                  564                 48                  596  Isogeny

编码

此代码位于 [ 这里]:

##include <stdio.h>
##include <stdlib.h>
##include <stdint.h>
##include <wolfssl/wolfcrypt/mlkem.h>
##include <wolfssl/wolfcrypt/wc_mlkem.h>
##include <wolfssl/wolfcrypt/random.h>
char* to_hex_string(const unsigned char* array, size_t length)
{
    char* outstr = malloc(2 * length + 1);
    if (!outstr) return outstr;
    char* p = outstr;
    for (size_t i = 0; i < length; ++i) {
        p += sprintf(p, "%02hhx", array[i]);
    }
    return outstr;
}

int main(int argc, char** argv)
{
    MlKemKey      AliceKey;
    int ret = 0;
    WC_RNG rng;
    // Alice creates a key pair
    printf("Alice creates an ML-KEM-512 key pair\n\n");
    ret = wc_InitRng(&rng);
    ret = wc_MlKemKey_Init(&AliceKey, WC_ML_KEM_512,0, INVALID_DEVID);
    int ss_size;
    wc_KyberKey_SharedSecretSize(&AliceKey, &ss_size);
    ret = wc_MlKemKey_MakeKey(&AliceKey, &rng);
    byte Alicepub[WC_ML_KEM_512_PUBLIC_KEY_SIZE];
    ret = wc_MlKemKey_EncodePublicKey(&AliceKey, Alicepub, WC_ML_KEM_512_PUBLIC_KEY_SIZE);
    // Bob receives the key
    printf("Bob receives public key (size=%d)  [displaying first 100 bytes]: %s\n\n", WC_ML_KEM_512_PUBLIC_KEY_SIZE, to_hex_string(Alicepub, 200));
    ret = wc_MlKemKey_DecodePublicKey(&AliceKey, Alicepub, WC_ML_KEM_512_PUBLIC_KEY_SIZE);

    byte ct[WC_ML_KEM_512_CIPHER_TEXT_SIZE], ss[WC_ML_KEM_512_CIPHER_TEXT_SIZE];
    ret = wc_MlKemKey_Encapsulate(&AliceKey, ct, ss, &rng);
    int len = WC_ML_KEM_512_CIPHER_TEXT_SIZE;
    printf("Bob Encapsulates secret (Size=%d) [displaying first 100 bytes]: %s\n\n",len, to_hex_string(ct,200));
    byte shared_secretAlice[WC_ML_KEM_512_CIPHER_TEXT_SIZE];
    // Alice receives ct
    ret = wc_MlKemKey_Decapsulate(&AliceKey,ct, shared_secretAlice, &rng);
    printf("Alice Decapsulated Shared Secret: %s\n\n", to_hex_string(shared_secretAlice, ss_size));
    // Bob determines Shared Secret
    byte shared_secretBob[WC_ML_KEM_512_PRIVATE_KEY_SIZE];
    wc_MlKemKey_DecodePrivateKey(&AliceKey, shared_secretBob,&ss_size);
    printf("Bob Secret Share (Recovered): %s\n\n", to_hex_string(shared_secretBob, ss_size));
    wc_MlKemKey_Free(&AliceKey);

    return 0;
}

一个示例运行 [ 这里]:

Alice creates an ML-KEM-512 key pair

Bob receives public key (size=800)  [displaying first 100 bytes]: 44b5732a66c56460839dab1324502bf72c6b3c7963f2985928fcb88d8762452517d20077d912ac72d4a28f084a2981a968e440ce08973fd81738a80dfe207d9ada8442aa937a222633b623fd294a2b5a9effca5c020063472b1c441651bb50c199031041016dbd683e6e92243a6a916a9c5aaf2ca8c5d1ca62617eeae8ada3f226928a68e0562345d544a55811c7443250e418f74604da113a1579a67ed97e59e03b463080206356875647e83c6787a53c3d5920d984ce5d35631b0c2a12e73c2009a96d244244f7
Bob Encapsulates secret (Size=768) [displaying first 100 bytes]: 15c34de118e9a63af1567ede7a0ecf75a158e25826916ce0ce4a32e98cd8e4e2d6b287c4a47f9c43ea81d6e72ffad8e0cf5a6a34e80f950ed05b8b8e89bdbf96268fa673575da47da2b90200774ed44ee8e7d5d4987e96749524b56565b0f172447f9637b8358d87044fec0cdbbfe11cbf932ff566a2b452aa622361cd5f5d1528bbdec7f6632cb96a8e539e1092f534bddc658e419ea13939f2260757ddec871fad7276a6481b56733ddf3e43c1b78aaffc27b1152aaf896f3c66f61dd4b3115d201f77c5b421a2
Alice Decapsulated Shared Secret: eac883ac387604b9d07187a9ae91fc4889fb2439a01168775987a19af5477185
Bob Secret Share (Recovered): eac883ac387604b9d07187a9ae91fc4889fb2439a01168775987a19af5477185

结论

因此,与 ECDH 说声再见,并向 ML-KEM 问好。

  • 原文链接: billatnapier.medium.com/...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
billatnapier
billatnapier
江湖只有他的大名,没有他的介绍。