Post-kvantová kryptografia v C#

Marec 2024

Tento blog má byť taký malý praktický ťahák ku post-kvantovej kryptografii v C#. Nie je to ani prehľad, sú to len poznámky, príklady a zjednodušenia.

Post-kvantová kryptografia

Post-kvantová kryptografia je klasická kryptografia, ktorá je odolná voči útokom kvantových počítačov.

Momentálne máme vymyslené algoritmy pre kvantové počítače, ktoré dokážu lámať asymetrickú kryptografiu - teda RSA a EC (eliptické krivky dokonca z trikrát menšou námahou ako RSA rovnakej bitovej bezpečnosti). Pre to sa už dlhšiu dobu vymýšľajú algoritmy asymetrickej kryptografie založené na iných problémoch ako faktorizácia prvočísiel alebo problém diskrétneho logaritmu.

Štandardné algoritmy symetrického šifrovania a kryptografických hashov ako AES (256), SHA2, SHA3, PBKDF2,… sa zatiaľ zdajú odolné voči útokom pomocou kvantových počítačov.

Algoritmy pre enakapsuláciu (KEM)

Tieto algoritmy sa používajú ako náhrada za asymetrické šifrovanie (RSA) alebo Diffie–Hellmanovu výmenu kľúčov (ECDH), no fungujú trochu inak. Pomocou verejného kľúča ide vytvoriť náhodné tajomstvo a jeho zašifrovanú podobu, ktorá ide rozšifrovať verejným kľúčom.

Momentálne je organizáciou NIST schválený algoritmus ML-KEN (CRYSTALS-Kyber). Algoritmy HQC, BikeClassic Mceliece sú v procese schvalovania.

Nasledujúca tabuľka ukazuje parametre jednotlivých algoritmov.

AlgoritmusVeľkosť verejného kľúčaVeľkosť súkromného kľúčaZašifrované dáta
ML-KEM 512800 B1 632 B768 B
ML-KEM 7381 184 B2 400 B1 088 B
ML-KEM 10241 568 B3 168 B1 568 B
Bike1281 541 B3 114 B1 573 B
Bike1923 083 B6 198 B3 115 B
Bike2565 122 B10 276 B5 154 B
HQC1282 249 B2 289 B4 497 B
HQC1924 522 B4 562 B9 042 B
HQC2567 245 B7 285 B14 485 B
McEliece348864261 120 B6 492 B196 B
McEliece460896524 160 B13 608 B156 B
McEliece66881281 044 992 B13 932 B208 B
McEliece69601191 047 319 B13 948 B194 B
McEliece81921281 357 824 B14 120 B208 B
NTRUhps2048509699 B935 B699 B
NTRUhps2048677930 B1 234 B930 B
NTRUhps40968211 230 B1 590 B1 230 B
SIKEp434330 B44 B346 B
SIKEp503378 B56 B402 B
SIKEp751564 B80 B596 B
SIDH564 B48 B596 B
LightSABER672 B1 568 B736 B
SABER992 B2 304 B1 088 B
FireSABER1 312 B3 040 B1 472 B

Nasledujúci kód zobrazuje ukážku použitia algoritmu ML_KEM (podľa FIPS 203, pôvodne Kyber) v C# pomocou knižnice BouncyCastle.

Ostatné dostupné algoritmy využívajú takmer rovnaký kód jediný rozdiel je v názvoch použitých tried.

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Kems;

SecureRandom random = new SecureRandom();

MLKemKeyGenerationParameters keyGenParameters = new MLKemKeyGenerationParameters(random, MLKemParameters.ml_kem_512);
MLKemKeyPairGenerator kyberKeyPairGenerator = new MLKemKeyPairGenerator();
kyberKeyPairGenerator.Init(keyGenParameters);

// Ganerovanie klucoveho paru pre Alicu
AsymmetricCipherKeyPair aliceKeyPair = kyberKeyPairGenerator.GenerateKeyPair();

// Zobrazenie klucov
MLKemPublicKeyParameters alicePublic = (MLKemPublicKeyParameters)aliceKeyPair.Public;
MLKemPrivateKeyParameters alicePrivate = (MLKemPrivateKeyParameters)aliceKeyPair.Private;
byte[] pubEncoded = alicePublic.GetEncoded();
byte[] privateEncoded = alicePrivate.GetEncoded();
Console.WriteLine($"Alice's Public key: {PrintData(pubEncoded)}");
Console.WriteLine($"Alice's Private key: {PrintData(privateEncoded)}");

// Bob enakpsuluje secret a pomocou verejneho klucu Alice
MLKemEncapsulator bobKyberKemGenerator = new MLKemEncapsulator(MLKemParameters.ml_kem_512);
bobKyberKemGenerator.Init(new ParametersWithRandom(alicePublic, random));

byte[] encodedBytes = new byte[bobKyberKemGenerator.EncapsulationLength];
byte[] bobSecret = new byte[bobKyberKemGenerator.SecretLength];
bobKyberKemGenerator.Encapsulate(encodedBytes, 0, encodedBytes.Length, bobSecret, 0, bobSecret.Length);

Console.WriteLine($"Encoded secret from Bob: {PrintData(encodedBytes)}");
Console.WriteLine($"Bob secret: {PrintData(bobSecret)}");

// Alice dekapsuluje secret a pomocou svojho privatneho klucu
MLKemDecapsulator decapsulator = new MLKemDecapsulator(MLKemParameters.ml_kem_512);
decapsulator.Init(alicePrivate);

byte[] aliceSecret = new byte[decapsulator.SecretLength];
decapsulator.Decapsulate(encodedBytes, 0, encodedBytes.Length, aliceSecret, 0, aliceSecret.Length);

Console.WriteLine($"Alice secret: {PrintData(aliceSecret)}");

Algoritmy pre podpis

Tieto algoritmy sú pre podpis dát privátnym kľúčom a overenie podpisu verejným kľúčom.

Momentálne sú NIST-om schválené algoritmy ML-DSA (Dilithium), FalconSLH-DSA (SPHINCS+).

Nasledujúca tabuľka ukazuje parametre jednotlivých algoritmov.

AlgoritmusVeľkosť verejného kľúčaVeľkosť súkromného kľúčaVeľkosť podpisuSecurity
ML-DSA 2 (Lattice)1 312 B2 528 B2 420 B128-bit
ML-DSA 31 952 B4 000 B3 293 B192-bit
ML-DSA 52 592 B4 864 B4 595 B256-bit
Falcon 512 (Lattice)897 B1 281 B690 B128-bit
Falcon 10241 793 B2 305 B1 330 B256-bit
Rainbow Level Ia (Oil-and-Vineger)161 600 B103 648 B66 B128-bit
Rainbow Level IIIa861 400 B611 300 B164 B192-bit
Rainbow Level Vc1 885 400 B1 375 700 B204 B256-bit
Sphincs SHA256-128f Simple32 B64 B17 088 B128-bit
Sphincs SHA256-192f Simple48 B96 B35 664 B192-bit
Sphincs SHA256-256f Simple64 B128 B49 856 B256-bit
Picnic 3 Full49 B73 B71 179 B192-bit
GeMSS 128352 188 B16 B33 B128-bit
GeMSS 1921 237 964 B24 B53 B128-bit

Nasledujúci kód zobrazuje ukážku použitia algoritmu ML-DSA (podľa FIPS 204, pôvodne Crystals Dilithium) v C# pomocou knižnice BouncyCastle.

Ostatné dostupné algoritmy využívajú takmer rovnaký kód jediný rozdiel je v názvoch použitých tried.

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Signers;

SecureRandom random = new SecureRandom();

//Data na podpis
byte[] data = new byte[32];
random.NextBytes(data);

MLDsaKeyPairGenerator kpg = new MLDsaKeyPairGenerator();
kpg.Init(new MLDsaKeyGenerationParameters(random, MLDsaParameters.ml_dsa_65));

AsymmetricCipherKeyPair kp = kpg.GenerateKeyPair();
MLDsaPublicKeyParameters publicKey = (MLDsaPublicKeyParameters)kp.Public;
MLDsaPrivateKeyParameters privateKey = (MLDsaPrivateKeyParameters)kp.Private;

Console.WriteLine($"Public key: {PrintData(publicKey.GetEncoded())}");
Console.WriteLine($"Private key: {PrintData(privateKey.GetEncoded())}");

MLDsaSigner signer = new MLDsaSigner(MLDsaParameters.ml_dsa_65, false);
signer.Init(true, privateKey);
signer.BlockUpdate(data);
byte[] signature = signer.GenerateSignature();

Console.WriteLine($"Signature: {PrintData(signature)}");

MLDsaSigner verifitier = new MLDsaSigner(MLDsaParameters.ml_dsa_65, false);
verifitier.Init(false, publicKey);
verifitier.BlockUpdate(data);

bool signatureIsVerified = verifitier.VerifySignature(signature);

Console.WriteLine($"Signature is verified: {signatureIsVerified}");

Metóda na výpis dát:

private static string PrintData(byte[] bytes)
{
    string base64 = Convert.ToBase64String(bytes);
    return (base64.Length > 50)
        ? $"({bytes.Length}B) {base64[..25]}…{base64[^25..]}"
        : $"({bytes.Length}B) {base64}";
}

Upozornenie

Nie som odborník na interné fungovanie týchto algoritmov a ako pri inej kryptografii, treba sa riadiť odporúčaním organizácií venujúcim sa kryptografii. Takže použitie na vlastné riziko.

BouncyCastle má zatiaľ experimentálne implementácie CRYSTALS-Dilithium, CRYSTALS-Kyber, Falcon, SPHINCS+, Classic McEliece, FrodoKEM, NTRU, NTRU Prime, Picnic, Saber, BIKESIKE. Pričom algoritmus SIKE bude odstránený.

Pre ďalšie čítanie odporúčam nasledujúce zdroje.

Update maerc 2025

  • FIPS 203 premenoval CRYSTALS-Kyber na ML-KEM
  • FIPS 204 premenoval CRYSTALS-Dilithium na ML-DSA
  • FIPS 205 premenoval Sphincs+ na SLH-DSA

Tieto algoritmy boli aj schválené.

Zdroje

  1. https://www.nist.gov/news-events/news/2022/07/nist-announces-first-four-quantum-resistant-cryptographic-algorithms
  2. https://billatnapier.medium.com/post-quantum-cryptography-pqc-with-bouncy-castle-and-c-4424dea684ec
  3. https://www.strathweb.com/2023/02/post-quantum-cryptography-in-net/
  4. https://medium.com/asecuritysite-when-bob-met-alice/goodbye-ecdh-and-hello-to-kyber-46415ef23d30
  5. https://github.com/filipw?tab=repositories&q=&type=source&language=c%23&sort=
  6. https://www.youtube.com/watch?v=JcfcSmwlFZ0