Related: [Kyber KEM][Kyber KEX][Dilithium Dig Sig Speed][Factoring signature (ECC)][Factoring signature (Logs)][Falcon Digital Signature][Rainbow Digital Signature][Dilithium Digital Signature][SPHINCS+]
CRYSTALS-KYBER (Lattice) - Key Encapsulation Mechanism (KEM)
[Lattice Home][Home]
CRYSTALS (Cryptographic Suite for Algebraic Lattices) supports two quantum robust mechanisms: Kyber for key-encapsulation mechanism (KEM) and key exchange; and Dilithium for a digital signature algorithm. CRYSTALS-Kyber uses LWE (Learning with Errors) with lattice methods. A new lattice attack was discovered within the period of the assessment [1], but it is hoped that an updated version of Kyber can be produced for the final assessment. NIST have some worried about its side-channel robustness, but is a strong contender for KEM. Overall a KEM allows a symmetric key to be passed using public key methods. In this case, Alice will generate her key pair of a public key (\(pk\)) and a private key (\(sk\)). She then passes her public key to Bob, and then Bob creates a cipher text (\(ct\)) with Alice's public key. He passes the ciphertext to Alice, and who decrypts with her private key. This will reveal the key that Bob wants Alice to use. Kyber512 has a security level of AES-128, Kyber738 maps to AES-192, and Keyber1024 to AES-256.
[Kyber KEM]
[SABER KEM]
[NTRU KEM]
[McEliece KEM]
Related: [Kyber KEM][Kyber KEX][Dilithium Dig Sig Speed][Factoring signature (ECC)][Factoring signature (Logs)][Falcon Digital Signature][Rainbow Digital Signature][Dilithium Digital Signature][SPHINCS+] |
The following defines the key sizes for Kyber, SABER, NTRU and McEliece:
Type Public key size (B) Secret key size (B) Ciphertext size (B) ------------------------------------------------------------------------ Kyber512 800 1,632 768 Kyber738 1,184 2,400 1,088 Kyber1024 1,568 3,168 1,568 LightSABER 672 1,568 736 SABER 992 2,304 1,088 FireSABER 1,312 3,040 1,472 McEliece348864 261,120 6,452 128 McEliece460896 524,160 13,568 188 McEliece6688128 1,044,992 13,892 240 McEliece6960119 1,047,319 13,948 226 McEliece8192128 1,357,824 14,120 240 NTRUhps2048509 699 935 699 NTRUhps2048677 930 1,234 930 NTRUhps4096821 1,230 1,590 1,230
Note: LightSABER has a security level of AES-128, SABER maps to AES-192, and FireSABER to AES-256. Kyber512 has a security level of AES-128, Kyber738 maps to AES-192, and Keyber1024 to AES-256. NTRUhps2048509 has a security level of AES-128, NTRUhps2048677 maps to AES-192, and NTRUhps4096821 to AES-256.
In terms of performance on an ARM Cortex-M4 (32-bit RISC processor), the following is the number of cycles taken for various operations for key generation, key encapulation and key decapsulation [1]:
scheme (implementation) level key generation encapsulation decapsulation ---------------------------------------------------------------------------- frodokem640aes (m4) 1 48,348,105 47,130 922 46,594,383 kyber512 (m4) 1 463,343 566,744 525,141 kyber768 (m4) 3 763,979 923,856 862,176 lightsaber (m4f) 1 361,687 513,581 498,590 saber (m4f) 3 654,407 862,856 835,122 ntruhps2048509 (m4f) 1 79,658,656 564,411 537,473 ntruhps2048677 (m4f) 3 143,734,184 821,524 815,516 sikep434 (m4) 1 48,264,129 78,911,465 84,276,911 sikep610 (m4) 3 119,480,622 219,632,058 221,029,700 mceliece348864f 1 1,430,811,294 582,199 2,706,681 mceliece348864 1 2,146,932,033 582,199 2,706,681
The code is:
#include stddef.h #include stdio.h #include string.h #include stdlib.h #include "kem.h" #include "randombytes.h" char *showhex(uint8_t a[], int size) ; char *showhex(uint8_t a[], int size) { char *s = malloc(size * 2 + 1); for (int i = 0; i < size; i++) sprintf(s + i * 2, "%02x", a[i]); return(s); } int main(void) { uint8_t pk[CRYPTO_PUBLICKEYBYTES]; uint8_t sk[CRYPTO_SECRETKEYBYTES]; uint8_t ct[CRYPTO_CIPHERTEXTBYTES]; uint8_t key_a[CRYPTO_BYTES]; uint8_t key_b[CRYPTO_BYTES]; int rtn; //Alice generates a public key crypto_kem_keypair(pk, sk); //Bob derives a secret key and creates a response crypto_kem_enc(ct, key_b, pk); //Alice uses Bobs response to get her shared key crypto_kem_dec(key_a, ct, sk); printf("Public key size: %d\nSecret key size: %d\nCiphertext size: %d\n",CRYPTO_PUBLICKEYBYTES,CRYPTO_SECRETKEYBYTES,CRYPTO_BYTES); printf("Public key (only showing 1/8 of key): %s\n",showhex(pk,CRYPTO_PUBLICKEYBYTES/8)); printf("Secret key (only showing 1/8 of key): %s\n",showhex(sk,CRYPTO_SECRETKEYBYTES/8)); printf("Cipher text: %s\n",showhex(ct,CRYPTO_CIPHERTEXTBYTES)); printf("Key (A): %s\n",showhex(key_a,CRYPTO_BYTES)); printf("Key (B): %s\n",showhex(key_b,CRYPTO_BYTES)); rtn=memcmp(key_a, key_b, CRYPTO_BYTES); if (rtn==0) { printf("Keys are the same");} else printf("Error in the keys!"); return 0; }
A sample run of Kyber512 shows that the public key size is 800 bytes, the secret key is 1,632 bytes, and the ciphertext size is 768 bytes:
Public key size: 800 Secret key size: 1632 Ciphertext size: 768 Public key (only showing 1/8 of key): c3d641fb38b90151c2eb513476babe69936a9aa744ace776466961d9f084acbab3833690b4839872aa87ac40a1a814655ff6aee0a9b0d373ac9dab6411c2c889437f66b1bce5340d4fd941f39874e1e2b4564635d68a1981616c836c8da0a04f929251f4 Secret key (only showing 1/8 of key): 30030e6a765234393aab9758b6ec5a20b5a043830042a62d9b364d784398b7187d2d8729c2d47da0a9ba476c2fc2269a7d0b395d58648b3c932c035ab270ccd5e099172142394192aff06d28e4a208a232756105da6c04e1d9bfdbe826b8123d8eba03ba8bb42d49250eb26ae9393750000a5ca5a5d356c20dc591d9e72e51e606b156a7709b07f090b2dfa102898485c0e09697ac811c93007a98310f621124d79db24182eb08a25abcc20bc0ae81bbbb68ec91ab454bc106597ec40db0964f846b32c09c98867b85bbd536 Cipher text: 64c41e748aa892a2a10346fb6c7b75a665e930e91f099a8f0ed066dc5e8529e2482dda4a03d3bfba21d0859dc2332fe5ebe8d5a2f18ee832f089e0c5b510523db52f7f243193c4d8d0dc00dc9239f35e6bf80d86b25ee1388f1914a1e36f6458dedc157778b5cadd72229495aa6a9b1f78af5ac6f94f5f31b58bc77701962596cd275cf73d141c81e0669f034b0a1d352c5d59eef210451ced41b771ab1e05cff77aefe855a8ef3daa11b35b8d35bf9b7ebce9fb90c217710960c9611b5247a8483cb2c787ec9f88d910b7fb5ec0ddc4d706b08d9b368f145af736afc4b703c6b1f2f1c63a87d5b95ff1ef9a833360f921d459dcae230f18fe149109b4c849fa366083e4b9191775ffe145a2b2dde14a835c1226ed8b6d13c03837147dca7bc9359f15551638fce87456af236623c8acb5a9622a228fdba56443210d424a9dab1ac524e62f250fafc329797b3d64fb2b7ab0316d6ec016c353877c5e8af84a4c0cbab27b9261bcfef63436763e18aed252a0300cc92572515ff574d6fcc7487700902df1777bd555e8a438c70d9f9103d860b036c641ba3bb725bde4eaed9ae587f583c02cb308647f8f4a9b4252f73389d331e732a749f158619046f359decb0ec97f420c142d9c74fbcfad96978b6669e2441331119eda0deed00b3c9d56615df583af08b6ed8799b31891b756d3f5f492088f8fa15c260f2e9e6cd8241e9f029507241a3effe351009bb77d0d9eea10c6c42b000b69c8bf73d07aed1dedbf4e93fe63268cdcca9cc0fa5f4d7d3957623dc5693b7b6ed7c777d223fd8742a77b2e21868863470822d4955c66baba1b8cd0f95d5af935e3c907c40d6967c1177f9f326c9b0edbf13cb7e4bd658f2409e423682b809343ce554041294d4f7c8558e1dd724d29169558714dbb23d172f8e23bbdff9cf70f2e96e884b711c62cefc9906442d842b0876bb4e889f65418549779c46366d855dd38d543872196b5d4d6712bdf3c57b77e1b261104770f69948096da5b1989f3be23c094c6cc36446f6495dc295e2e4d44990a9d2aaacedbcc4be2423bb192c46ab9745e2db910adb2 Key (A): a02433b3097638b64fc53fdb315a31b838a72497caa161a65d0e176632dd785c Key (B): a02433b3097638b64fc53fdb315a31b838a72497caa161a65d0e176632dd785c
The code compiles to “test_kyber512”, and which is a Linux build. To run just run the executable:
[1] Chen, M. S., & Chou, T. Classic McEliece on the ARM Cortex-M4 [here].