2023-12-20 17:33:13 +04:00
2022-09-19 12:58:02 +04:00
2023-12-17 16:36:41 +04:00

Caution

This Kyber implementation is conformant with Kyber specification https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf and I also try to make it constant-time but be informed that it is not yet audited. If you consider using it in production, be careful !

kyber

CRYSTALS-Kyber: Post-Quantum Public-key Encryption & Key-establishment Algorithm

Motivation

Kyber is being standardized by NIST as post-quantum secure key encapsulation mechanism (KEM), which can be used for key establishment.

Kyber offers an IND-CCA2-secure Key Encapsulation Mechanism - its security is based on the hardness of solving the learning-with-errors (LWE) problem in module (i.e. structured) lattices.

Kyber Key Encapsulation Mechanism is built on top of IND-CPA-secure Kyber Public Key Encryption, where two communicating parties, both generating their key pairs, while publishing their public keys to each other, can encrypt fixed length ( = 32 -bytes ) message using peer's public key. Cipher text can be decrypted by corresponding secret key ( which is private to the keypair owner ) and 32 -bytes message can be recovered back. Then a slightly tweaked FujisakiOkamoto (FO) transform is applied on IND-CPA-secure Kyber PKE - giving us the IND-CCA2-secure KEM construction. In KEM scheme, two parties interested in establishing a secure communication channel over public & insecure channel, can generate a shared secret key ( of arbitrary byte length ) from a key derivation function ( i.e. KDF which is SHAKE256 Xof in this context ) which is obtained by both of these parties as result of seeding SHAKE256 Xof with same secret. This secret is 32 -bytes and that's what is communicated by sender to receiver using underlying Kyber PKE scheme.

Algorithm Input Output
KEM KeyGen - Public Key and Secret Key
Encapsulation Public Key Cipher Text and SHAKE256 KDF
Decapsulation Secret Key and Cipher Text SHAKE256 KDF

Here I'm maintaining kyber - a header-only and easy-to-use ( see more in usage ) C++ library implementing Kyber KEM, supporting Kyber-{512, 768, 1024} parameter sets, as defined in table 1 of Kyber specification. sha3 and subtle are two dependencies of this library, which are pinned to specific git commits, using git submodule.

Note

Find Kyber specification https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf - this is the document that I followed when implementing Kyber. I suggest you go through the specification to get an in-depth understanding of Kyber PQC suite.

Note

Find progress of NIST PQC standardization effort @ https://csrc.nist.gov/projects/post-quantum-cryptography.

Prerequisites

  • A C++ compiler with C++20 standard library such as clang++/ g++.
$ clang++ --version
Ubuntu clang version 17.0.2 (1~exp1ubuntu2.1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

$  g++ --version
g++ (Ubuntu 13.2.0-4ubuntu3) 13.2.0
  • Build tools such as make, cmake.
$ make --version
GNU Make 4.3

$ cmake --version
cmake version 3.25.1
  • For testing Kyber KEM implementation, you need to globally install google-test library and headers. Follow this guide, if you don't have it installed.
  • For benchmarking Kyber KEM implementation, targeting CPU systems, you'll need to have google-benchmark header and library globally installed. I found guide @ https://github.com/google/benchmark#installation helpful.

Note

If you are on a machine running GNU/Linux kernel and you want to obtain CPU cycle count for KEM routines, you should consider building google-benchmark library with libPFM support, following https://gist.github.com/itzmeanjan/05dc3e946f635d00c5e0b21aae6203a7, a step-by-step guide. Find more about libPFM @ https://perfmon2.sourceforge.net.

Tip

Git submodule based dependencies will mostly be imported automatically, but in case that doesn't work, you can manually initialize and update them by issuing $ git submodule update --init from inside the root of this repository.

Testing

For testing functional correctness and conformance with Kyber specification, you have to issue

Note

Known Answer Test (KAT) files living in this directory are generated by following (reproducible) steps, described in https://gist.github.com/itzmeanjan/c8f5bc9640d0f0bdd2437dfe364d7710.

make -j            # Run tests without any sort of sanitizers
make asan_test -j  # Run tests with AddressSanitizer enabled
make ubsan_test -j # Run tests with UndefinedBehaviourSanitizer enabled
Note: Randomizing tests' orders with a seed of 61247 .
[==========] Running 10 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 10 tests from KyberKEM
[ RUN      ] KyberKEM.ArithmeticOverZq
[       OK ] KyberKEM.ArithmeticOverZq (116 ms)
[ RUN      ] KyberKEM.NumberTheoreticTransform
[       OK ] KyberKEM.NumberTheoreticTransform (0 ms)
[ RUN      ] KyberKEM.Kyber768KnownAnswerTests
[       OK ] KyberKEM.Kyber768KnownAnswerTests (8 ms)
[ RUN      ] KyberKEM.Kyber512KnownAnswerTests
[       OK ] KyberKEM.Kyber512KnownAnswerTests (5 ms)
[ RUN      ] KyberKEM.CompressDecompressZq
[       OK ] KyberKEM.CompressDecompressZq (94 ms)
[ RUN      ] KyberKEM.Kyber1024KnownAnswerTests
[       OK ] KyberKEM.Kyber1024KnownAnswerTests (13 ms)
[ RUN      ] KyberKEM.Kyber768KeygenEncapsDecaps
[       OK ] KyberKEM.Kyber768KeygenEncapsDecaps (0 ms)
[ RUN      ] KyberKEM.Kyber512KeygenEncapsDecaps
[       OK ] KyberKEM.Kyber512KeygenEncapsDecaps (0 ms)
[ RUN      ] KyberKEM.PolynomialSerialization
[       OK ] KyberKEM.PolynomialSerialization (0 ms)
[ RUN      ] KyberKEM.Kyber1024KeygenEncapsDecaps
[       OK ] KyberKEM.Kyber1024KeygenEncapsDecaps (0 ms)
[----------] 10 tests from KyberKEM (238 ms total)

[----------] Global test environment tear-down
[==========] 10 tests from 1 test suite ran. (238 ms total)
[  PASSED  ] 10 tests.

Benchmarking

For benchmarking Kyber KEM routines ( i.e. keygen, encaps and decaps ) for various suggested parameter sets, you have to issue.

make benchmark  # If you haven't built google-benchmark library with libPFM support.
make perf       # If you have built google-benchmark library with libPFM support.

Note

Benchmarking expects presence of google-benchmark header and library in global namespace ( so that it can be found by the compiler ).

Caution

When benchmarking, ensure that you've disabled CPU frequency scaling, by following guide @ https://github.com/google/benchmark/blob/main/docs/reducing_variance.md.

Note

make perf - was issued when collecting following benchmarks. Notice, cycles column, denoting cost of executing Kyber KEM routines in terms of CPU cycles. Follow this for more details.

On 12th Gen Intel(R) Core(TM) i7-1260P ( compiled with Clang-17.0.2 )

2023-12-17T16:35:19+04:00
Running ./build/perf.out
Run on (16 X 648.989 MHz CPU s)
CPU Caches:
  L1 Data 48 KiB (x8)
  L1 Instruction 32 KiB (x8)
  L2 Unified 1280 KiB (x8)
  L3 Unified 18432 KiB (x1)
Load Average: 0.63, 0.49, 0.35
----------------------------------------------------------------------------------------------
Benchmark                        Time             CPU   Iterations     CYCLES items_per_second
----------------------------------------------------------------------------------------------
kyber512/decap_mean           16.8 us         16.8 us           10   78.2371k       59.3682k/s
kyber512/decap_median         16.8 us         16.8 us           10   78.0903k       59.5332k/s
kyber512/decap_stddev        0.213 us        0.213 us           10   1.61104k        748.863/s
kyber512/decap_cv             1.26 %          1.26 %            10      2.06%            1.26%
kyber512/decap_min            16.5 us         16.5 us           10   75.9006k       58.3612k/s
kyber512/decap_max            17.1 us         17.1 us           10   80.2234k       60.4726k/s
kyber512/keygen_mean          12.0 us         12.0 us           10   55.2343k       83.4374k/s
kyber512/keygen_median        12.0 us         12.0 us           10   55.2033k       83.3267k/s
kyber512/keygen_stddev       0.143 us        0.143 us           10    910.895        988.689/s
kyber512/keygen_cv            1.19 %          1.20 %            10      1.65%            1.18%
kyber512/keygen_min           11.8 us         11.8 us           10   54.1517k       81.2428k/s
kyber512/keygen_max           12.3 us         12.3 us           10   57.0565k       84.7691k/s
kyber768/keygen_mean          19.9 us         19.9 us           10   91.4059k       50.2463k/s
kyber768/keygen_median        19.9 us         19.9 us           10   91.0785k       50.1954k/s
kyber768/keygen_stddev       0.180 us        0.181 us           10   1.05886k        457.283/s
kyber768/keygen_cv            0.91 %          0.91 %            10      1.16%            0.91%
kyber768/keygen_min           19.6 us         19.6 us           10   90.2107k       49.5364k/s
kyber768/keygen_max           20.2 us         20.2 us           10   93.7315k       50.9569k/s
kyber768/encap_mean           26.3 us         26.3 us           10   119.902k       38.0206k/s
kyber768/encap_median         26.3 us         26.3 us           10    119.44k       37.9685k/s
kyber768/encap_stddev        0.225 us        0.225 us           10    2.0148k        326.026/s
kyber768/encap_cv             0.85 %          0.85 %            10      1.68%            0.86%
kyber768/encap_min            25.9 us         25.9 us           10   117.959k       37.5131k/s
kyber768/encap_max            26.7 us         26.7 us           10   124.856k       38.6767k/s
kyber1024/encap_mean          40.1 us         40.1 us           10   183.584k       24.9219k/s
kyber1024/encap_median        40.0 us         40.0 us           10   182.834k        25.005k/s
kyber1024/encap_stddev       0.462 us        0.462 us           10   2.02064k        285.263/s
kyber1024/encap_cv            1.15 %          1.15 %            10      1.10%            1.14%
kyber1024/encap_min           39.4 us         39.4 us           10   180.861k       24.4381k/s
kyber1024/encap_max           40.9 us         40.9 us           10   187.784k        25.367k/s
kyber1024/keygen_mean         31.3 us         31.3 us           10   142.994k       32.0037k/s
kyber1024/keygen_median       31.2 us         31.2 us           10   141.812k       32.0502k/s
kyber1024/keygen_stddev      0.468 us        0.467 us           10   3.09301k        476.014/s
kyber1024/keygen_cv           1.50 %          1.50 %            10      2.16%            1.49%
kyber1024/keygen_min          30.5 us         30.5 us           10   139.185k       31.0694k/s
kyber1024/keygen_max          32.2 us         32.2 us           10   148.231k       32.7634k/s
kyber1024/decap_mean          42.5 us         42.5 us           10   195.395k       23.5308k/s
kyber1024/decap_median        42.5 us         42.5 us           10   194.307k       23.5284k/s
kyber1024/decap_stddev       0.341 us        0.342 us           10   2.27441k        188.876/s
kyber1024/decap_cv            0.80 %          0.80 %            10      1.16%            0.80%
kyber1024/decap_min           42.0 us         42.0 us           10   192.669k        23.198k/s
kyber1024/decap_max           43.1 us         43.1 us           10   198.878k       23.8111k/s
kyber512/encap_mean           15.4 us         15.4 us           10   70.3054k       65.0965k/s
kyber512/encap_median         15.4 us         15.4 us           10   69.6619k       65.1279k/s
kyber512/encap_stddev        0.225 us        0.226 us           10   1.99248k        957.196/s
kyber512/encap_cv             1.47 %          1.47 %            10      2.83%            1.47%
kyber512/encap_min            15.0 us         15.0 us           10   68.2471k       63.7025k/s
kyber512/encap_max            15.7 us         15.7 us           10   73.4948k       66.8462k/s
kyber768/decap_mean           28.1 us         28.1 us           10   129.269k       35.6001k/s
kyber768/decap_median         28.1 us         28.1 us           10   128.604k       35.5936k/s
kyber768/decap_stddev        0.159 us        0.159 us           10   1.61556k        200.417/s
kyber768/decap_cv             0.57 %          0.56 %            10      1.25%            0.56%
kyber768/decap_min            27.8 us         27.8 us           10   127.678k       35.1656k/s
kyber768/decap_max            28.4 us         28.4 us           10   131.651k       35.9414k/s

On ARM Cortex-A72 i.e. Raspberry Pi 4B ( compiled with Clang-17.0.2 )

2023-12-17T18:03:53+05:30
Running ./build/perf.out
Run on (4 X 1800 MHz CPU s)
CPU Caches:
  L1 Data 32 KiB (x4)
  L1 Instruction 48 KiB (x4)
  L2 Unified 1024 KiB (x1)
Load Average: 0.48, 1.44, 1.61
Performance counters not supported.
-----------------------------------------------------------------------------------
Benchmark                        Time             CPU   Iterations items_per_second
-----------------------------------------------------------------------------------
kyber768/encap_mean            194 us          194 us           10       5.16056k/s
kyber768/encap_median          193 us          193 us           10       5.17224k/s
kyber768/encap_stddev         1.31 us         1.29 us           10        34.0107/s
kyber768/encap_cv             0.67 %          0.66 %            10            0.66%
kyber768/encap_min             193 us          193 us           10       5.09692k/s
kyber768/encap_max             196 us          196 us           10       5.19123k/s
kyber1024/keygen_mean          254 us          254 us           10       3.93486k/s
kyber1024/keygen_median        254 us          254 us           10       3.93138k/s
kyber1024/keygen_stddev      0.713 us        0.712 us           10        11.0375/s
kyber1024/keygen_cv           0.28 %          0.28 %            10            0.28%
kyber1024/keygen_min           253 us          253 us           10       3.92136k/s
kyber1024/keygen_max           255 us          255 us           10       3.95326k/s
kyber1024/encap_mean           296 us          296 us           10       3.38308k/s
kyber1024/encap_median         296 us          296 us           10       3.38211k/s
kyber1024/encap_stddev       0.574 us        0.586 us           10        6.71083/s
kyber1024/encap_cv            0.19 %          0.20 %            10            0.20%
kyber1024/encap_min            295 us          295 us           10       3.37455k/s
kyber1024/encap_max            296 us          296 us           10       3.39256k/s
kyber768/decap_mean            212 us          212 us           10       4.71816k/s
kyber768/decap_median          212 us          212 us           10       4.71786k/s
kyber768/decap_stddev        0.741 us        0.744 us           10         16.577/s
kyber768/decap_cv             0.35 %          0.35 %            10            0.35%
kyber768/decap_min             211 us          211 us           10       4.69116k/s
kyber768/decap_max             213 us          213 us           10       4.74494k/s
kyber768/keygen_mean           158 us          158 us           10       6.31632k/s
kyber768/keygen_median         158 us          158 us           10       6.31299k/s
kyber768/keygen_stddev       0.453 us        0.445 us           10        17.7648/s
kyber768/keygen_cv            0.29 %          0.28 %            10            0.28%
kyber768/keygen_min            158 us          158 us           10       6.29411k/s
kyber768/keygen_max            159 us          159 us           10       6.34639k/s
kyber1024/decap_mean           321 us          321 us           10       3.11987k/s
kyber1024/decap_median         321 us          321 us           10       3.11851k/s
kyber1024/decap_stddev       0.564 us        0.569 us           10        5.53764/s
kyber1024/decap_cv            0.18 %          0.18 %            10            0.18%
kyber1024/decap_min            320 us          320 us           10        3.1111k/s
kyber1024/decap_max            321 us          321 us           10       3.12971k/s
kyber512/decap_mean            129 us          129 us           10       7.74209k/s
kyber512/decap_median          129 us          129 us           10       7.75584k/s
kyber512/decap_stddev        0.869 us        0.858 us           10        50.8408/s
kyber512/decap_cv             0.67 %          0.66 %            10            0.66%
kyber512/decap_min             128 us          128 us           10       7.60927k/s
kyber512/decap_max             131 us          131 us           10       7.79796k/s
kyber512/encap_mean            116 us          116 us           10       8.63463k/s
kyber512/encap_median          116 us          116 us           10       8.63491k/s
kyber512/encap_stddev        0.318 us        0.316 us           10        23.5414/s
kyber512/encap_cv             0.27 %          0.27 %            10            0.27%
kyber512/encap_min             115 us          115 us           10        8.6006k/s
kyber512/encap_max             116 us          116 us           10       8.66881k/s
kyber512/keygen_mean          92.7 us         92.7 us           10       10.7837k/s
kyber512/keygen_median        92.6 us         92.6 us           10       10.7982k/s
kyber512/keygen_stddev       0.750 us        0.753 us           10        86.1452/s
kyber512/keygen_cv            0.81 %          0.81 %            10            0.80%
kyber512/keygen_min           92.1 us         92.0 us           10       10.5513k/s
kyber512/keygen_max           94.8 us         94.8 us           10       10.8653k/s

Usage

kyber is written as a header-only C++ library, majorly targeting 64 -bit platforms and it's pretty easy to get started with. All you need to do is following.

  • Clone kyber repository.
cd

# Multi-step cloning and importing of submodules
git clone https://github.com/itzmeanjan/kyber.git && pushd kyber && git submodule update --init && popd
# Or do single step cloning and importing of submodules
git clone https://github.com/itzmeanjan/kyber.git --recurse-submodules
  • Write your program while including proper header files ( based on which variant of Kyber KEM you want to use, see include directory ), which includes declarations ( and definitions ) of all required KEM routines and constants ( such as byte length of public/ private keys and cipher text ).
// main.cpp

#include "kyber512_kem.hpp"
#include <algorithm>
#include <array>
#include <cassert>

int
main()
{
  std::array<uint8_t, 32> d{}; // seed
  std::array<uint8_t, 32> z{}; // seed
  std::array<uint8_t, kyber512_kem::PKEY_LEN> pkey{};
  std::array<uint8_t, kyber512_kem::SKEY_LEN> skey{};
  std::array<uint8_t, 32> m{}; // seed
  std::array<uint8_t, kyber512_kem::CIPHER_LEN> cipher{};

  // Be careful !
  //
  // Read API documentation in include/prng.hpp
  prng::prng_t prng;

  prng.read(d);
  prng.read(z);
  prng.read(m);

  kyber512_kem::keygen(d, z, pkey, skey);
  auto skdf = kyber512_kem::encapsulate(m, pkey, cipher);
  auto rkdf = kyber512_kem::decapsulate(skey, cipher);

  std::array<uint8_t, 32> sender_key{};
  skdf.squeeze(sender_key);

  std::array<uint8_t, 32> receiver_key{};
  rkdf.squeeze(receiver_key);

  assert(std::ranges::equal(sender_key, receiver_key));
  return 0;
}
  • When compiling your program, let your compiler know where it can find kyber, sha3 and subtle headers, which includes their definitions ( kyber being a header-only library ) too.
# Assuming `kyber` was cloned just under $HOME

KYBER_HEADERS=~/kyber/include
SHA3_HEADERS=~/kyber/sha3/include
SUBTLE_HEADERS=~/kyber/subtle/include

g++ -std=c++20 -Wall -O3 -march=native -I $KYBER_HEADERS -I $SHA3_HEADERS -I $SUBTLE_HEADERS main.cpp
Kyber KEM Variant Namespace Header
Kyber512 KEM Routines kyber512_kem:: include/kyber512_kem.hpp
Kyber768 KEM Routines kyber768_kem:: include/kyber768_kem.hpp
Kyber1024 KEM Routines kyber1024_kem:: include/kyber1024_kem.hpp

Note

Kyber parameter sets are selected from table 1 of Kyber specification https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf.

See example program, where I show how to use Kyber512 KEM API. You can almost similarly use Kyber768 or Kyber1024 KEM API, by just importing correct header file and using KEM functions/ constants from respective namespace.

g++ -std=c++20 -Wall -Wextra -pedantic -O3 -march=native -I ./include -I ./sha3/include -I ./subtle/include/ examples/kyber512_kem.cpp && ./a.out
Kyber512 KEM

pubkey        : 175782d35b2666833aee098617626d88dbcc47091a011882d52105acc218c9287a95276a3259a6a94aa386d8148886abdcc1841f39260ce4754ebacc1fd36102905d4c623d0b27930b4c249ee7380758c0ac5982b0e932eda95184a40f55c451d835861ca2b314dbce97829f1b92752dda592d8960b2540f464988ea1c974c63467c439b1de540490b0af0491a6507951ebc971887bd2b4a11327381d99586f10668c83abe92fb649b113da7ec666729bc1cc38a1de137dd3cc4e3a6abb9881a2ee63e7df3ad6cb680664ba1559ca17448c968b7c867ac5f324911ffd43993b8a7b8f57094c786877c1208fa7f53e51d6f1a46ae71bc81f78ebe5808d48200b7e1bc81ec3d31070a6993aa5db237eb3a4c592aa559a73bd769583a0ad095ec1669b952be4a71fe8603f5d597f007a048cc9d7fea6735383b6b8bbf896b74dc48a21840a92c497a9bc7434b0241a9e42e6428515d477c4e0b3678fab1d619b794f01b828648e7577bb2e5297915b9fdf33cb291a37de51b51c7aca6f07994193bd981134da2340c23a93cda8b68e429ac801d3748b8d112b57e388511e3305e50a51184b623607447468be94351cd0b9111a119b4b3c6f270c1cfea749a2ac89455590280c369163946481dbaeb4693dbb376202db2d8464c61aea6411cd887080f5c59e1587da01510cd1b0e8b030a5c200639ba26376134e88279891b90373cc92e7a76c0aaa33d084ab3f61e175010996652e441300ad5aefda9cc88f17fef2102b643179e0a49a60c47ce06c5b1a0b150b09ca4593e5dd48a9b1979d103ba862c43ed354d2ec99575b70e741808288aa0e1cb792c0a458d4584ddfa1870d7b797e2aac7d4cc08916015401338d8841d226d9656661cda93f53343e0f906b82bce8f25428b02a639a47f7dda5b946a3785656fb6d083df5a5ec7493cc017a2469b1f43c96f2e3bbc9d6cb07bec82d721a4cfba6ca2c59b0e01bda98585692b9da753923f830b52c843b6d963f959ad60189f42d61df7808f4d131c4d233e246c4735193e516452061701e6114cf1587a54c79105f48fdce9c2134bb60550b242945ea011ec54c570054b93d96f072426b7c9b524db8d2f136b7db2d1f38897
seckey        : a598a250c2008688af8f71a285abae5b528a19479acf915cd2f92a7365bc757c670accc4b2190aa77b7d0c76355962a0ea9b6a1f4400be77797a6851776815032307913aa475b733a1ba698b2134ea25a57bd9b979e2bcb7d99f24f06ee760227486ae1cdaba79065bc3180d79a0906c514e5b973435c00f34b87e882643ef6b42bcbca4a3b65207abb5dca76e49a9be7a6013d256bc09b1211b70bb28e2151200c6c1e00082e88634600a29e3cf5ff541051c703ac373a91228a6d30491221df6749e22b21429612ed4ba07a7d7789717809e498f2e3a1b8a6a40afe0a7d2460350074a2a5127cc20c0b03446977a612a096324337cd5bc455f77cdbe4600e147b02fe58bc9c383b1e84ea3bc5755d3a87ce515b07c96741a72d9eb702d445acc3374531c70ef221216db2c9198110d83084f7b508da18fd34b8ee9f45d1204a627609d09a89c73e8bfc1f987c6bc906fac0d01720b169061b3d8015a5121a0d3beab454a03cc24a9bc5725e6c4aaf44d8f8b7242443f289c0751226448ec794a02a1ba411caeabb99f7a90510b8812a91a0ad69f1476408940381724a1dbfb7f69642788267b068c585bf41bf3f857fd14bcd9506b95b6a257d7481a07628004944e136a4c97842c13451e960cf4e08a8b6666e17a6aac016d701c1a00c82072939a092397c7104d7fd6332b860034f2ace5191e2792cf10e21f5166304bf329696128d63640b7882809b750f1f89e5d513fa08a8439e1ad5fe0affd887b0f06ab91798c35d48f39261af3dab7ddbc899be21d1f751b8d317b8e280f400b637ac6a471b4065973a6253235c94117e22083562b715ce680fafb78da9113f0f52692c52625ea8e1c24a1d8837beb963a5ab078455c8a43cbab68dc4eaa4c7646c9bb45803442250e935738944c7228aa3f7137567eb1231c63bff7552a7858525b92bdca832a41cb20fb24647a62af1da27e50c41f3cd070ed8c1d1213c22b1540a5c1412d67ab4ff334c2e5217c06a5f8a93c0637bd0fb4736c19591f67c378aa80f7c9587b346bbfe81eff8574c7e0acc3164c3df048019639a80377b97457175782d35b2666833aee098617626d88dbcc47091a011882d52105acc218c9287a95276a3259a6a94aa386d8148886abdcc1841f39260ce4754ebacc1fd36102905d4c623d0b27930b4c249ee7380758c0ac5982b0e932eda95184a40f55c451d835861ca2b314dbce97829f1b92752dda592d8960b2540f464988ea1c974c63467c439b1de540490b0af0491a6507951ebc971887bd2b4a11327381d99586f10668c83abe92fb649b113da7ec666729bc1cc38a1de137dd3cc4e3a6abb9881a2ee63e7df3ad6cb680664ba1559ca17448c968b7c867ac5f324911ffd43993b8a7b8f57094c786877c1208fa7f53e51d6f1a46ae71bc81f78ebe5808d48200b7e1bc81ec3d31070a6993aa5db237eb3a4c592aa559a73bd769583a0ad095ec1669b952be4a71fe8603f5d597f007a048cc9d7fea6735383b6b8bbf896b74dc48a21840a92c497a9bc7434b0241a9e42e6428515d477c4e0b3678fab1d619b794f01b828648e7577bb2e5297915b9fdf33cb291a37de51b51c7aca6f07994193bd981134da2340c23a93cda8b68e429ac801d3748b8d112b57e388511e3305e50a51184b623607447468be94351cd0b9111a119b4b3c6f270c1cfea749a2ac89455590280c369163946481dbaeb4693dbb376202db2d8464c61aea6411cd887080f5c59e1587da01510cd1b0e8b030a5c200639ba26376134e88279891b90373cc92e7a76c0aaa33d084ab3f61e175010996652e441300ad5aefda9cc88f17fef2102b643179e0a49a60c47ce06c5b1a0b150b09ca4593e5dd48a9b1979d103ba862c43ed354d2ec99575b70e741808288aa0e1cb792c0a458d4584ddfa1870d7b797e2aac7d4cc08916015401338d8841d226d9656661cda93f53343e0f906b82bce8f25428b02a639a47f7dda5b946a3785656fb6d083df5a5ec7493cc017a2469b1f43c96f2e3bbc9d6cb07bec82d721a4cfba6ca2c59b0e01bda98585692b9da753923f830b52c843b6d963f959ad60189f42d61df7808f4d131c4d233e246c4735193e516452061701e6114cf1587a54c79105f48fdce9c2134bb60550b242945ea011ec54c570054b93d96f072426b7c9b524db8d2f136b7db2d1f3889778f791d583227a702cdfa4a9f95014df019495f14e02318b3704dc3794af523705be75f29753f47b2888ceef235d82caca9f983b40bf10b29672da272113a973
cipher        : bcee459c896ea378dcc458a532c35c029eff6b8cf8adc83f484fb6f9bfe32612f7c936cbf4dbd7c5262288dc3966a0d769f94a0bd57913a60a71efae09321c22c53839d836cef5fb8bf5c630bd3b3d657492eabfc7e67a42a631c95391656f0fce607a181e418144dff3d97f1192a2825a94da5113bcffc2e5f3e043f7583e6159902ddd009f8bcb18046a05695917bdef48accc2e3708f8536aabb420a7fd7989c60bca6c1941af45eac2f03cf71c8506721f8cd69bd3c573f036e3e8ae72b85632d06e0cab6fa1fea078d84aa1a116ac58ee632a0542b2d0e6a7026ae814ceeb46478d1cefd082c9b19efa7bb6ddd7abda8e43eab7b5a5204449273ea056b36d3797371f855d0c7ff0436279b21b831ad0970c26cc39f8627deb932689b8df48e73b1b5893987fa4dbc65571a78287f1573beeb85db52a3edbad6f50725bcbfa40423e3ce1ab00c16ea3922bc42e6782ce224ccfb3c978d8704584b9768a8edb6a950c0208b1c1c9a6a4e0d6300a9cfe788389697460efc41308448e9752d2022dfdecd118440346e2fabb07559b76301943f3b186adaaba09828efb28db1cd4a5e82e01f360451cb3c487f371af05725ea0e7d61932a8dc38108e99182e9b50d2aa828a773a2e18f5271ac75e5a5c50b9221f893e5f7076732beb0ffb9e4b82e1c0648192c9547870372b78c6a3e3a1b00d904a4a1492d5944e0510acee62e40c78cecef97922b04807cdd47d4d403a7bb16316598e6eee760b257382d9648c9920c3395717d8ac829bd37465c0f3e7f0c7e6fc351aac802edb722200776906eb36f622c0b8702958e44317961f583265a83b8cfcd9eed80f15b9ef848ebb7355df9718a60c532e20074854797685b3e4a25f929fce9ad02a5af114f92210abd3b73fddf28f116c2d4c27ceda6428a3892eb0c18fc12b07596e4153f2a3df9aa440957704bc56bbbee06cd99def3218c046344b4c5a811840a088bcbbad76fca4a20b9bf608873b2830afd6097b05022e8b1d42af3e5e4f00303adc9f130a84cdde3fef9335ccd1120b3f2050f17ef0c10fd226268965cbfc13738ada0632
shared secret : 508ac79bf97e90d75267159ba5189b73c48ab41a91aec0f32edd6cd1e66465b5

Caution

Before you consider using Psuedo Random Number Generator which comes with this library implementation, I strongly advice you to go through include/prng.hpp.

Note

Looking at API documentation, in header files, can give you good idea of how to use Kyber KEM API. Note, this library doesn't expose any raw pointer based interface, rather everything is wrapped under statically defined std::span - which one can easily create from std::{array, vector}. I opt for using statically defined std::span based function interfaces because we always know, at compile-time, how many bytes the seeds/ keys/ cipher-texts/ shared-secrets are, for various different Kyber KEM parameters. This gives much better type safety and compile-time error reporting.

Description
No description provided
Readme BSD-3-Clause 7.1 MiB
Languages
C++ 90.4%
Makefile 6.1%
Python 2.9%
Shell 0.6%