本文介绍了后量子密码学中的签名算法ML-DSA,以及如何使用wolfCrypt/wolfSSL库在C语言中实现该算法。ML-DSA是NIST推荐的替代ECDSA、Ed25519和RSA等传统签名算法的方案,它在面对量子计算机的攻击时更安全,并且wolfCrypt提供了高效的实现,尤其适用于嵌入式设备。
我必须承认,编写 C 代码对灵魂有益。它是我第一个正经的编程语言,而且我仍然觉得它能让我最大程度地控制程序的运行。虽然 Rust 和 Golang 很棒,但你仍然会觉得 C 在编写代码方面给你最大的灵活性。
所以,不管你喜不喜欢,Shor 算法已经表明,我们现有的公钥密码学方法将被大规模构建的量子计算机破解。幸运的是,NIST 已经在这方面研究了一段时间,并提出了一个迁移路径:
对于 ECDSA、Ed25519、RSA PSS 和 RSAPKCS1 1.5,我们需要迁移到 ML-DSA (Dilithium)、SLH-DSS (SPHINCS+) 或 FN-DSA (FALCON)。最流行的方法是 ML-DSA,它适用于三个安全级别(ML-DSA-44、ML-DSA-65 和 ML-DSA-87):
Method Public key size Private key size Signature size Security level
------------------------------------------------------------------------------------------------------
ML-DSA-44 1,312 2,528 2,420 2 (128-bit) Lattice
ML-DSA-65 1,952 4,000 3,293 3 (192-bit) Lattice
ML-DSA-87 2,592 4,864 4,595 5 (256-bit) Lattice
虽然有多种语言的实现,但 C 代码实现可能给我们最快的实现,并且可以移植到各种系统。wolfCrypt/wolfSSL 是周围最好的库之一。在这种情况下,我们将使用 wolfCrypto 实现 ML-DSA。
使用 wolfCrypt 的代码实现是 [ 这里 ]:
##include <stdio.h>
##include <stdlib.h>
##include <stdint.h>
##include <wolfssl /wolfcrypt/dilithium.h>
##include <wolfssl /wolfcrypt/random.h>
##include <wolfssl /wolfcrypt/sha3.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)
{
int ret = 0;
int opt = 0;
MlDsaKey key;
WC_RNG rng;
byte* priv = NULL;
byte* pub = NULL;
byte* sig = NULL;
word32 priv_len = 0;
word32 pub_len = 0;
word32 sig_len = 0;
int ml_dsa_priv_len = 0;
int ml_dsa_pub_len = 0;
int ml_dsa_sig_len = 0;
const char* msg = "Hello";
int verify_res = 0;
int sec_cat = 2;
if (argc > 1) msg = argv[1];
if (argc > 2) sec_cat = atoi(argv[2]); // 2, 3 or 5
wc_InitRng(&rng);
ret = wc_MlDsaKey_Init(&key, NULL, INVALID_DEVID);
ret = wc_MlDsaKey_SetParams(&key, sec_cat);
ret = wc_MlDsaKey_MakeKey(&key, &rng);
ret = wc_MlDsaKey_GetSigLen(&key, &ml_dsa_sig_len);
sig_len = (word32)ml_dsa_sig_len;
ret = wc_MlDsaKey_GetPubLen(&key, &ml_dsa_pub_len);
ret = wc_MlDsaKey_GetPrivLen(&key, &ml_dsa_priv_len);
printf("Message: %s\n",msg);
printf("Security level: %d\n", sec_cat);
printf("Signature length: %d\n", ml_dsa_sig_len);
printf("Public key length: %d\n", ml_dsa_pub_len);
printf("Private key length: %d\n", ml_dsa_priv_len);
priv = malloc(ml_dsa_priv_len);
pub = malloc(ml_dsa_pub_len);
sig = malloc(ml_dsa_sig_len);
pub_len = (word32)ml_dsa_pub_len;
priv_len = (word32)ml_dsa_priv_len;
ret = wc_MlDsaKey_ExportPubRaw(&key, pub, &pub_len);
char* pub_hex = to_hex_string(pub, pub_len); pub_hex[400] = '\0';
printf("Public key (first 200 bytes) : %s\n\n", pub_hex);
ret = wc_MlDsaKey_ExportPrivRaw(&key, priv, &priv_len);
char* priv_hex = to_hex_string(priv, priv_len); priv_hex[400] = '\0';
printf("Private key (first 200 bytes): %s\n\n", priv_hex);
ret = wc_MlDsaKey_Sign(&key, sig, &sig_len, (const byte*)msg, strlen(msg), &rng);
char* sig_hex = to_hex_string(sig, sig_len); sig_hex[400] = '\0';
printf("Signature (first 200 bytes): %s\n", sig_hex);
ret = wc_MlDsaKey_Verify(&key, sig, sig_len, (const byte*)msg, strlen(msg), &verify_res);
if (ret==0 && verify_res == 1) {
printf("\nSignature verified\n");
}
return 0;
}
对于 Level 2 (ML-DSA-44),我们得到 [ 这里 ]:
Message: dfdf
Security level: 2
Signature length: 2420
Public key length: 1312
Private key length: 3872
Public key (first 200 bytes) : cfebf682a028ce6a9e1bf3178b68e725083b965504b260314e96449d7fa826bb15c735821077e6a3778a679d29877d052b03a08ea5730058183689afd3627dc10a9cc2515cec6e80d5e1b41a1149127514f81c7eef6fb60d29c5c7e474af769e8ae73013a95c010af38c1f521d50cd981074f9adf8755daae7b311e77dee413510b5203f7c8c5290cb151d2f71c0633466eadc85d7bf3541da9aa491793d5fc592c5fca4f8d1815e3c1378cf661fc4e5700f89c7c30b55ee5785097da96a6474d98e18c656598c01
Private key (first 200 bytes): cfebf682a028ce6a9e1bf3178b68e725083b965504b260314e96449d7fa826bb8ceea5ee86ad1852cb36653d0a7b0e0ddfa4227241521872764753d1d2425d8ed52cf0597cb14bdf215fb516ad32c09fe46435050e840e7defe8d07ce0d7e375326d2c73ba0943cef072c3de05aeaf2113871a9844d455de02eea77897211342d30609128100c9a68561b41198b66d0cb260c2322e1a0762491268a3a2081c064c84204d1aa1610c3209db287211b1714b440cd18471540689c31200580066d1a48920418a491621
Signature (first 200 bytes): 149eea064f67c552803459105f255fbb96cb9fecd16074db3a0fb79c63ba56918016a0ab219aebdb6447f36193df4117f6cbe9b120f61ba155de5132f15a60f391f7a1706de0d9621157203e3e621cfbf9faf9ea7dd87ec3f202914f9cf41e6ff05ae99c6051365ad37c18104dce483980078aa47a79baa0a4119a2888c42ca35342683a705a167a94c9297d5eef988debe78c4182f80f718fbb3fc05a0234b5f3a6f0517c468c70fc32f34a50f4557ef5ca6660d855cc82e30d33ea13d22a9f7152a7184adf2d0a
Signature verified
对于 Level 3 (ML-DSA-65),我们得到 [ 这里 ]:
Message: 3
Security level: 2
Signature length: 2420
Public key length: 1312
Private key length: 3872
Public key (first 200 bytes) : 0089d3ce511ef701e2574343b8a13d4e57b9c543d297557abc9f851b95307d5c2c91ff2ca8829fedfeefd128aac3d0b6f30f701b74fc83812119a6ac0b6d75dae922430310e3aac12b4bfa94e4dcc8409ec1fe74c9b5d5714f62c00487d4ffd8f8bdb9d535c6c8fdc1eb22ad45aabf71bb8b149bde2c4005050e9e9fd73f5eb7b1776fe5e4a896d701b0e65a39710ff8c3ee4b142513501138dd2ac344739d67c50d7b09102810eb6fffbdf9e22e3f6025e230f69e01c123070f243667533fa20dbcbcf19ee8f993
Private key (first 200 bytes): 0089d3ce511ef701e2574343b8a13d4e57b9c543d297557abc9f851b95307d5cbf8890233ca8bfa78c71c978de50b9dda0c3497de06f2fa13ff5f71ceef60f883e5741a093491dae42c84c2b82108bf4c0f75ecdbf5e32540c281099593437f32b0361822c7c4ab66374623d9a447531a19dc106bf0cc252318de44ef373c3378184215aa451d8220894366e08c34d2047311ac80dd3186411964c88164dccb2488084200b9004e10684c1a860e0b27191b01093444810866110236d49882803244503816540c630
Signature (first 200 bytes): e287a5721d0196ff97eae96b9e592f187393d65fb65b6b06ad12987c0b108361f7ebd888ecb9b4d4fed9753f25b71fc9efc31263d9dd511edab9798670313b20a67a715d0d9bb87410559d5470f306dd92766408f64b3ff00342b9dbf549dcdfd231bfc1024b8afbed10cde9628dce1f1ac4462f740341c525d992800a209237ab8ceb28f52cac993cf8b842c4420176d14524cfdb487a4bb2eedfab305fc5476e750678a5ae6d7239f3d96e26e22a02a9926ba231e35618ffc521614d1396dff043b8590bf86ba1
Signature verified
对于 Level 5 (ML-DSA-87):
Message: 5
Security level: 2
Signature length: 2420
Public key length: 1312
Private key length: 3872
Public key (first 200 bytes) : 87d61b2e24a0b3e080d9e2eecf1d93e5f027aa79d6f4ab927298d93ec72e2175bbbe958a28cab7c4773cb7b66f5d769abe16fe827a57647a4e735f00f2c4c2252970ccc7464f495bac2714510be4a0e22c5536bd795ede4085dadc27dfbbf43896a1468cee55fbe282e6885b82705b3b8c71bc501371aea9c6fb406434d62c3193dbb3b114dea2686d34b34b77137bf08e86fe34d2c30783d82874fab8aed3c85751c5e45373b4f75982a7f9ea8f38d58caff0b97e375e4c6caa01e7f6505f69ab3b15d8cfd15b6a
Private key (first 200 bytes): 87d61b2e24a0b3e080d9e2eecf1d93e5f027aa79d6f4ab927298d93ec72e21757e05cda5f94df26016870d5ca0a3246e1e7836e72a63149d60d28cdecf3b0214fae24bbf6da9a5c31b22fcbbe92a5acc4ee295b8e963188ae6f396c8439fcc80b304a9b7d08631f049982583fcd192b98c0d3f1f551a6b6052e1e85172f4d0b9c9b8710422848a4832c4802dd904708c886d60344681c84524c63119a18502066011174962224c121911d036000913054410911b494291b024cc980d4b9805998890d3384520354c
Signature (first 200 bytes): d6a338afc37e85b497d2bf6caeebe9147f620bbc561a058d00cb1d09d73a2395b437264bf7a9365074e08214e198b50506dbd64cb9cbaa33c88b67e0b76231fc938c234715888e47b1ad74a6e120792308734e376ed2ed32ffcf650df73eaac87816f933cfa907b98f14e2023a9adadd0858022378930397b45043f8870ccde1f055fbf5e2cbd02fb93e0fbfcc1362f6171a781c31b12a730c6c1d11332763a2f60e090a0d94823fa2c47f11f900f59e242fcbce31f5fadd5bc3d1bdff0be7e1d91ecb0a789db076
Signature verified
演示在这里:
使用 wolfSSL/wolfCrypt 和 C 的 ML-DSA (FIPS 204)
RSA 签名已经存在了近五年,它们的时代即将结束。此外,ECDSA 和 Ed25519 为我们提供了高效的签名方法,可用于物联网设备和区块链,但我们将不得不告别它们。ML-DSA 为它们的替代提供了一个很好的迁移路径,特别是使用 wolfCrypt 到嵌入式设备。它超级快速和高效。
- 原文链接: medium.com/asecuritysite...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!