Skip to content

Saber: Post-Quantum Key Encapsulation Mechanism

License

Notifications You must be signed in to change notification settings

itzmeanjan/saber

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

saber

Saber: Post-Quantum Key Encapsulation Mechanism

Warning This header-only library implementation of Saber KEM is made to behave constant-time though it's not yet audited. If you consider using it in production environment, be careful !

Overview

Saber is a family of cryptographic primitives that rely on the hardness of the Module Learning With Rounding (Mod-LWR) problem. Saber offers an IND-CPA secure public key encryption algorithm, which is transformed to an IND-CCA secure key encapsulation mechanism, using a version of Fujisaki-Okamoto transform.

It's a header-only C++ library implementation of Saber KEM scheme(s), as described in specification https://www.esat.kuleuven.be/cosic/pqcrypto/saber/files/saberspecround3.pdf and instantiating all parameter sets, suggested

  • (a) In section 8.1, on table 8 [Samples from Centered Binomial Distribution]
  • (b) In section A.2, on table 9 [Samples from Centered Uniform Distribution]

of the Saber specification.

Sampling of secret vector ? KEM Implemented
From Centered Binomial Distribution LightSaber, Saber and FireSaber
From Centered Uniform Distribution uLightSaber, uSaber and uFireSaber

Warning This library doesn't implement -90s variants of KEM, only SHAKE-based variants are implemented.

KEM schemes offer three main algorithms.

Algorithm Input Output How is it used ?
keygen 32 -bytes random seed seedA, 32 -bytes random noise seedS and 32 -bytes random key z Public and private keypair Imagine two parties peer0 & peer1, want to securely ( using symmetric key encryption i.e. some AEAD scheme ) communicate over insecure channel. One of them, say peer0, generates an ephemeral KEM keypair and publish its public key to other peer i.e. peer1.
encaps 32 -bytes random seed m and receiver's public key Cipher text and 32 -bytes session key Peer1 encapsulates 32 -bytes message inside cipher text, using peer0's public key. And then it shares the cipher text with peer0, over insecure channel. Finally peer1 also derives a 32 -bytes session key, which it can now use with symmetric key constructions.
decaps Cipher text and receiver's private key 32 -bytes session key Peer0 uses its private key for decapsulating the cipher text it received from peer1, deriving the same 32 -bytes session key. Now both of the parties have same 32 -bytes session key, they can use it for enciphering their communication.

For learning more about Saber, follow their website @ https://www.esat.kuleuven.be/cosic/pqcrypto/saber. Also note that Saber was a round 3 finalist of NIST PQC standardization effort, more @ https://csrc.nist.gov/Projects/post-quantum-cryptography/post-quantum-cryptography-standardization/round-3-submissions.

Prerequisites

  • A C++ compiler with C++20 standard library.
$ g++ --version
g++ (Ubuntu 13.2.0-4ubuntu3) 13.2.0

$ clang++ --version
Ubuntu clang version 17.0.2 (1~exp1ubuntu2.1)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
  • Build tools.
$ make --version
GNU Make 4.3
Built for x86_64-pc-linux-gnu

$ cmake --version
cmake version 3.27.4
  • For testing functional correctness of Saber KEM and its components, you need to globally install google-test headers and library. Follow this guide.
  • For benchmarking Saber KEM algorithms, you need to globally install google-benchmark headers and library. Follow this guide.

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

  • Saber KEM has two dependencies ( i.e. sha3 and subtle ), managed by git submodule. After cloning this repository, you must run following command inside root of this repository, so that you can test/ benchmark/ use it.
git clone https://github.com/itzmeanjan/saber.git
pushd saber
git submodule update --init # <-- Import dependencies
popd

# Or just clone it like
git clone https://github.com/itzmeanjan/saber.git --recurse-submodules

Testing

For testing functional correctness and ensuring that this implementation is conforming to the Saber KEM specification, issue following command.

Warning Conformance to the specification is ensured by using known answer test files, generated by following instructions @ https://gist.github.com/itzmeanjan/e499eba2b8c42f150a795d9e1c3c5dea. Generated known answer test files live under kats directory.

make -j
[==========] Running 20 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 20 tests from SaberKEM
[ RUN      ] SaberKEM.LightSaberKeyEncapsulationMechanism
[       OK ] SaberKEM.LightSaberKeyEncapsulationMechanism (0 ms)
[ RUN      ] SaberKEM.SaberKeyEncapsulationMechanism
[       OK ] SaberKEM.SaberKeyEncapsulationMechanism (0 ms)
[ RUN      ] SaberKEM.FireSaberKeyEncapsulationMechanism
[       OK ] SaberKEM.FireSaberKeyEncapsulationMechanism (0 ms)
[ RUN      ] SaberKEM.uLightSaberKeyEncapsulationMechanism
[       OK ] SaberKEM.uLightSaberKeyEncapsulationMechanism (0 ms)
[ RUN      ] SaberKEM.uSaberKeyEncapsulationMechanism
[       OK ] SaberKEM.uSaberKeyEncapsulationMechanism (0 ms)
[ RUN      ] SaberKEM.uFireSaberKeyEncapsulationMechanism
[       OK ] SaberKEM.uFireSaberKeyEncapsulationMechanism (0 ms)
[ RUN      ] SaberKEM.LightSaberKnownAnswerTests
[       OK ] SaberKEM.LightSaberKnownAnswerTests (19 ms)
[ RUN      ] SaberKEM.SaberKnownAnswerTests
[       OK ] SaberKEM.SaberKnownAnswerTests (37 ms)
[ RUN      ] SaberKEM.FireSaberKnownAnswerTests
[       OK ] SaberKEM.FireSaberKnownAnswerTests (61 ms)
[ RUN      ] SaberKEM.uLightSaberKnownAnswerTests
[       OK ] SaberKEM.uLightSaberKnownAnswerTests (19 ms)
[ RUN      ] SaberKEM.uSaberKnownAnswerTests
[       OK ] SaberKEM.uSaberKnownAnswerTests (38 ms)
[ RUN      ] SaberKEM.uFireSaberKnownAnswerTests
[       OK ] SaberKEM.uFireSaberKnownAnswerTests (63 ms)
[ RUN      ] SaberKEM.LightSaberPublicKeyEncryption
[       OK ] SaberKEM.LightSaberPublicKeyEncryption (0 ms)
[ RUN      ] SaberKEM.SaberPublicKeyEncryption
[       OK ] SaberKEM.SaberPublicKeyEncryption (0 ms)
[ RUN      ] SaberKEM.FireSaberPublicKeyEncryption
[       OK ] SaberKEM.FireSaberPublicKeyEncryption (0 ms)
[ RUN      ] SaberKEM.uLightSaberPublicKeyEncryption
[       OK ] SaberKEM.uLightSaberPublicKeyEncryption (0 ms)
[ RUN      ] SaberKEM.uSaberPublicKeyEncryption
[       OK ] SaberKEM.uSaberPublicKeyEncryption (0 ms)
[ RUN      ] SaberKEM.uFireSaberPublicKeyEncryption
[       OK ] SaberKEM.uFireSaberPublicKeyEncryption (0 ms)
[ RUN      ] SaberKEM.PolynomialMatrixConversion
[       OK ] SaberKEM.PolynomialMatrixConversion (0 ms)
[ RUN      ] SaberKEM.PolynomialConversion
[       OK ] SaberKEM.PolynomialConversion (0 ms)
[----------] 20 tests from SaberKEM (244 ms total)

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

Benchmarking

For benchmarking Saber KEM algorithms ( i.e. keygen, encaps and decaps ), instantiated with various suggested parameters, targeting CPU systems, issue following command.

Warning When benchmarking, ensure that you've disabled CPU frequency scaling, by following this guide.

Note make perf - was issued when collecting following benchmarks. Notice, CYCLES column, denoting latency of Saber KEM routines. Follow this for more details.

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

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

2023-10-20T22:49:28+04:00
Running ./build/perf.out
Run on (16 X 3698.59 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.45, 0.42, 0.45
------------------------------------------------------------------------------------------------
Benchmark                          Time             CPU   Iterations     CYCLES items_per_second
------------------------------------------------------------------------------------------------
firesaber/decaps_mean           84.4 us         84.4 us            8   382.872k        11.851k/s
firesaber/decaps_median         84.6 us         84.6 us            8   382.598k       11.8185k/s
firesaber/decaps_stddev         1.05 us         1.06 us            8    835.441        150.718/s
firesaber/decaps_cv             1.25 %          1.25 %             8      0.22%            1.27%
firesaber/decaps_min            82.1 us         82.1 us            8   382.111k       11.6945k/s
firesaber/decaps_max            85.5 us         85.5 us            8   384.602k       12.1856k/s
saber/keygen_mean               34.0 us         34.0 us            8   154.762k       29.3921k/s
saber/keygen_median             33.9 us         33.9 us            8   154.676k       29.4594k/s
saber/keygen_stddev            0.553 us        0.553 us            8    294.139          477.5/s
saber/keygen_cv                 1.62 %          1.62 %             8      0.19%            1.62%
saber/keygen_min                33.2 us         33.2 us            8   154.461k       28.7492k/s
saber/keygen_max                34.8 us         34.8 us            8   155.396k       30.1616k/s
lightsaber/decaps_mean          29.0 us         29.0 us            8   131.401k       34.4513k/s
lightsaber/decaps_median        29.0 us         29.0 us            8   131.343k       34.4486k/s
lightsaber/decaps_stddev       0.495 us        0.496 us            8     254.65        591.838/s
lightsaber/decaps_cv            1.71 %          1.71 %             8      0.19%            1.72%
lightsaber/decaps_min           28.2 us         28.2 us            8   131.093k       33.7379k/s
lightsaber/decaps_max           29.6 us         29.6 us            8   131.927k       35.4728k/s
firesaber/encaps_mean           74.4 us         74.4 us            8   336.196k       13.4449k/s
firesaber/encaps_median         74.4 us         74.4 us            8    336.23k        13.436k/s
firesaber/encaps_stddev        0.844 us        0.844 us            8    242.034        152.866/s
firesaber/encaps_cv             1.13 %          1.13 %             8      0.07%            1.14%
firesaber/encaps_min            73.2 us         73.2 us            8   335.804k       13.2467k/s
firesaber/encaps_max            75.5 us         75.5 us            8   336.599k       13.6657k/s
ulightsaber/keygen_mean         15.9 us         15.9 us            8   73.0721k        62.829k/s
ulightsaber/keygen_median       15.9 us         15.9 us            8   73.0414k       62.8434k/s
ulightsaber/keygen_stddev      0.185 us        0.185 us            8      134.7        723.397/s
ulightsaber/keygen_cv           1.16 %          1.16 %             8      0.18%            1.15%
ulightsaber/keygen_min          15.7 us         15.7 us            8   72.9107k       61.3224k/s
ulightsaber/keygen_max          16.3 us         16.3 us            8   73.3453k       63.8755k/s
saber/decaps_mean               54.8 us         54.8 us            8   249.765k       18.2472k/s
saber/decaps_median             55.0 us         55.0 us            8   249.684k       18.1819k/s
saber/decaps_stddev            0.723 us        0.720 us            8    275.253        240.849/s
saber/decaps_cv                 1.32 %          1.31 %             8      0.11%            1.32%
saber/decaps_min                53.7 us         53.7 us            8   249.425k       17.9502k/s
saber/decaps_max                55.7 us         55.7 us            8   250.185k       18.6314k/s
ufiresaber/decaps_mean          83.2 us         83.2 us            8   376.946k        12.015k/s
ufiresaber/decaps_median        83.1 us         83.1 us            8   376.767k       12.0328k/s
ufiresaber/decaps_stddev       0.941 us        0.936 us            8    459.823        132.987/s
ufiresaber/decaps_cv            1.13 %          1.12 %             8      0.12%            1.11%
ufiresaber/decaps_min           82.3 us         82.3 us            8   376.597k       11.7139k/s
ufiresaber/decaps_max           85.4 us         85.4 us            8    377.83k       12.1555k/s
ulightsaber/decaps_mean         28.4 us         28.4 us            8   128.592k        35.163k/s
ulightsaber/decaps_median       28.5 us         28.5 us            8   128.581k       35.0827k/s
ulightsaber/decaps_stddev      0.289 us        0.289 us            8    92.3866        357.559/s
ulightsaber/decaps_cv           1.02 %          1.02 %             8      0.07%            1.02%
ulightsaber/decaps_min          28.0 us         28.0 us            8   128.499k       34.6127k/s
ulightsaber/decaps_max          28.9 us         28.9 us            8   128.799k       35.6822k/s
firesaber/keygen_mean           61.1 us         61.1 us            8   280.316k        16.363k/s
firesaber/keygen_median         61.0 us         60.9 us            8   280.301k        16.407k/s
firesaber/keygen_stddev        0.722 us        0.722 us            8    246.267        190.759/s
firesaber/keygen_cv             1.18 %          1.18 %             8      0.09%            1.17%
firesaber/keygen_min            60.4 us         60.4 us            8   280.066k       15.9561k/s
firesaber/keygen_max            62.7 us         62.7 us            8   280.831k       16.5517k/s
usaber/encaps_mean              45.6 us         45.6 us            8   206.792k       21.9454k/s
usaber/encaps_median            45.5 us         45.5 us            8   206.737k        21.984k/s
usaber/encaps_stddev           0.779 us        0.778 us            8     307.03        374.398/s
usaber/encaps_cv                1.71 %          1.71 %             8      0.15%            1.71%
usaber/encaps_min               44.3 us         44.3 us            8   206.427k       21.3903k/s
usaber/encaps_max               46.8 us         46.8 us            8   207.455k       22.5701k/s
usaber/decaps_mean              54.8 us         54.8 us            8   249.357k       18.2674k/s
usaber/decaps_median            54.7 us         54.7 us            8   249.186k        18.274k/s
usaber/decaps_stddev           0.823 us        0.821 us            8    463.525        274.743/s
usaber/decaps_cv                1.50 %          1.50 %             8      0.19%            1.50%
usaber/decaps_min               53.5 us         53.5 us            8   248.922k       17.9813k/s
usaber/decaps_max               55.6 us         55.6 us            8   250.404k       18.6809k/s
ufiresaber/keygen_mean          59.7 us         59.7 us            8   273.819k       16.7587k/s
ufiresaber/keygen_median        59.9 us         59.9 us            8   273.828k       16.6901k/s
ufiresaber/keygen_stddev       0.865 us        0.858 us            8    196.044        242.142/s
ufiresaber/keygen_cv            1.45 %          1.44 %             8      0.07%            1.44%
ufiresaber/keygen_min           58.4 us         58.4 us            8   273.527k       16.4175k/s
ufiresaber/keygen_max           60.9 us         60.9 us            8   274.147k       17.1309k/s
saber/encaps_mean               46.0 us         46.0 us            8   208.958k       21.7341k/s
saber/encaps_median             46.0 us         46.0 us            8   208.882k       21.7243k/s
saber/encaps_stddev            0.679 us        0.679 us            8    370.735        322.816/s
saber/encaps_cv                 1.48 %          1.47 %             8      0.18%            1.49%
saber/encaps_min                44.8 us         44.8 us            8   208.502k        21.276k/s
saber/encaps_max                47.0 us         47.0 us            8   209.704k       22.3444k/s
usaber/keygen_mean              33.7 us         33.7 us            8   151.209k       29.7017k/s
usaber/keygen_median            33.5 us         33.5 us            8   151.157k        29.825k/s
usaber/keygen_stddev           0.482 us        0.483 us            8    179.085        423.323/s
usaber/keygen_cv                1.43 %          1.43 %             8      0.12%            1.43%
usaber/keygen_min               33.1 us         33.1 us            8   151.049k       29.0304k/s
usaber/keygen_max               34.4 us         34.4 us            8   151.544k       30.1965k/s
lightsaber/keygen_mean          17.7 us         17.7 us            8   79.7241k       56.5706k/s
lightsaber/keygen_median        17.8 us         17.8 us            8   79.6325k       56.2462k/s
lightsaber/keygen_stddev       0.288 us        0.286 us            8    248.664        929.261/s
lightsaber/keygen_cv            1.63 %          1.62 %             8      0.31%            1.64%
lightsaber/keygen_min           17.1 us         17.1 us            8   79.4854k       55.6024k/s
lightsaber/keygen_max           18.0 us         18.0 us            8   80.2012k       58.3852k/s
ufiresaber/encaps_mean          73.5 us         73.5 us            8   330.533k       13.6167k/s
ufiresaber/encaps_median        73.5 us         73.5 us            8    330.58k       13.6155k/s
ufiresaber/encaps_stddev        1.38 us         1.38 us            8    321.261         258.24/s
ufiresaber/encaps_cv            1.88 %          1.89 %             8      0.10%            1.90%
ufiresaber/encaps_min           71.1 us         71.1 us            8   329.901k       13.2973k/s
ufiresaber/encaps_max           75.2 us         75.2 us            8    331.03k       14.0679k/s
ulightsaber/encaps_mean         23.7 us         23.7 us            8   106.835k       42.2998k/s
ulightsaber/encaps_median       23.8 us         23.7 us            8   106.787k       42.1096k/s
ulightsaber/encaps_stddev      0.528 us        0.528 us            8    205.977        953.679/s
ulightsaber/encaps_cv           2.23 %          2.23 %             8      0.19%            2.25%
ulightsaber/encaps_min          22.9 us         22.9 us            8   106.609k       41.1247k/s
ulightsaber/encaps_max          24.3 us         24.3 us            8    107.14k       43.7573k/s
lightsaber/encaps_mean          24.3 us         24.3 us            8   109.841k       41.2444k/s
lightsaber/encaps_median        24.3 us         24.3 us            8   109.778k       41.0825k/s
lightsaber/encaps_stddev       0.579 us        0.575 us            8    168.173        983.847/s
lightsaber/encaps_cv            2.39 %          2.37 %             8      0.15%            2.39%
lightsaber/encaps_min           23.5 us         23.5 us            8   109.663k       40.2215k/s
lightsaber/encaps_max           24.9 us         24.9 us            8   110.168k       42.6162k/s

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

2023-10-20T22:47:01+04:00
Running ./build/perf.out
Run on (16 X 4651.3 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.37, 0.38, 0.44
------------------------------------------------------------------------------------------------
Benchmark                          Time             CPU   Iterations     CYCLES items_per_second
------------------------------------------------------------------------------------------------
firesaber/keygen_mean            158 us          158 us            8   737.234k       6.34113k/s
firesaber/keygen_median          158 us          158 us            8   737.256k       6.34506k/s
firesaber/keygen_stddev        0.215 us        0.217 us            8    440.175           8.72/s
firesaber/keygen_cv             0.14 %          0.14 %             8      0.06%            0.14%
firesaber/keygen_min             158 us          158 us            8   736.606k       6.32183k/s
firesaber/keygen_max             158 us          158 us            8    738.03k       6.34719k/s
usaber/encaps_mean               121 us          121 us            8   563.495k       8.29283k/s
usaber/encaps_median             120 us          120 us            8   563.463k       8.29954k/s
usaber/encaps_stddev           0.246 us        0.247 us            8    189.434        16.9884/s
usaber/encaps_cv                0.20 %          0.21 %             8      0.03%            0.20%
usaber/encaps_min                120 us          120 us            8   563.285k       8.26525k/s
usaber/encaps_max                121 us          121 us            8   563.788k       8.30771k/s
ufiresaber/decaps_mean           235 us          235 us            8   1.09752M       4.25653k/s
ufiresaber/decaps_median         235 us          235 us            8   1.09747M       4.25813k/s
ufiresaber/decaps_stddev       0.354 us        0.356 us            8    382.907        6.43838/s
ufiresaber/decaps_cv            0.15 %          0.15 %             8      0.03%            0.15%
ufiresaber/decaps_min            235 us          235 us            8   1.09706M       4.24625k/s
ufiresaber/decaps_max            236 us          236 us            8   1.09824M       4.26329k/s
lightsaber/keygen_mean          42.0 us         42.0 us            8   196.399k       23.8367k/s
lightsaber/keygen_median        41.9 us         41.9 us            8   196.397k       23.8428k/s
lightsaber/keygen_stddev       0.062 us        0.063 us            8    171.763        35.6318/s
lightsaber/keygen_cv            0.15 %          0.15 %             8      0.09%            0.15%
lightsaber/keygen_min           41.9 us         41.9 us            8    196.14k       23.7586k/s
lightsaber/keygen_max           42.1 us         42.1 us            8   196.694k       23.8782k/s
saber/encaps_mean                118 us          118 us            8   552.242k       8.44651k/s
saber/encaps_median              118 us          118 us            8   553.194k       8.46011k/s
saber/encaps_stddev            0.515 us        0.512 us            8   2.95137k        36.2085/s
saber/encaps_cv                 0.44 %          0.43 %             8      0.53%            0.43%
saber/encaps_min                 118 us          118 us            8   544.953k       8.35746k/s
saber/encaps_max                 120 us          120 us            8   553.701k       8.46366k/s
saber/keygen_mean               89.5 us         89.5 us            8   418.371k       11.1757k/s
saber/keygen_median             89.5 us         89.5 us            8   418.393k       11.1724k/s
saber/keygen_stddev            0.117 us        0.121 us            8    337.487        15.1486/s
saber/keygen_cv                 0.13 %          0.14 %             8      0.08%            0.14%
saber/keygen_min                89.3 us         89.3 us            8   417.956k       11.1508k/s
saber/keygen_max                89.7 us         89.7 us            8   418.742k       11.1996k/s
ulightsaber/encaps_mean         61.4 us         61.4 us            8   287.266k       16.2776k/s
ulightsaber/encaps_median       61.3 us         61.3 us            8   286.919k       16.3108k/s
ulightsaber/encaps_stddev      0.372 us        0.373 us            8   1.06354k         97.637/s
ulightsaber/encaps_cv           0.61 %          0.61 %             8      0.37%            0.60%
ulightsaber/encaps_min          61.2 us         61.2 us            8   286.516k       16.0377k/s
ulightsaber/encaps_max          62.4 us         62.4 us            8   289.859k       16.3319k/s
firesaber/encaps_mean            196 us          196 us            8   914.876k          5.11k/s
firesaber/encaps_median          196 us          196 us            8   914.912k       5.11091k/s
firesaber/encaps_stddev        0.321 us        0.320 us            8    536.681        8.34906/s
firesaber/encaps_cv             0.16 %          0.16 %             8      0.06%            0.16%
firesaber/encaps_min             195 us          195 us            8   914.135k       5.09122k/s
firesaber/encaps_max             196 us          196 us            8   915.669k       5.11782k/s
ulightsaber/decaps_mean         79.3 us         79.3 us            8   370.856k       12.6077k/s
ulightsaber/decaps_median       79.3 us         79.3 us            8   370.846k       12.6147k/s
ulightsaber/decaps_stddev      0.119 us        0.120 us            8    171.552        19.0279/s
ulightsaber/decaps_cv           0.15 %          0.15 %             8      0.05%            0.15%
ulightsaber/decaps_min          79.2 us         79.2 us            8   370.676k        12.572k/s
ulightsaber/decaps_max          79.5 us         79.5 us            8   371.212k       12.6255k/s
ufiresaber/encaps_mean           199 us          199 us            8   929.823k       5.02799k/s
ufiresaber/encaps_median         199 us          199 us            8   929.522k       5.02952k/s
ufiresaber/encaps_stddev       0.246 us        0.244 us            8    905.644        6.17132/s
ufiresaber/encaps_cv            0.12 %          0.12 %             8      0.10%            0.12%
ufiresaber/encaps_min            199 us          199 us            8   929.199k       5.01484k/s
ufiresaber/encaps_max            199 us          199 us            8   931.993k       5.03363k/s
usaber/decaps_mean               147 us          147 us            8   687.526k       6.80119k/s
usaber/decaps_median             147 us          147 us            8   687.515k       6.79988k/s
usaber/decaps_stddev           0.115 us        0.086 us            8    182.306        4.00027/s
usaber/decaps_cv                0.08 %          0.06 %             8      0.03%            0.06%
usaber/decaps_min                147 us          147 us            8   687.278k        6.7959k/s
usaber/decaps_max                147 us          147 us            8   687.789k       6.80719k/s
ulightsaber/keygen_mean         41.6 us         41.6 us            8   194.699k       24.0248k/s
ulightsaber/keygen_median       41.6 us         41.6 us            8   194.721k       24.0364k/s
ulightsaber/keygen_stddev      0.088 us        0.082 us            8     213.95        47.3521/s
ulightsaber/keygen_cv           0.21 %          0.20 %             8      0.11%            0.20%
ulightsaber/keygen_min          41.5 us         41.5 us            8   194.378k       23.9326k/s
ulightsaber/keygen_max          41.8 us         41.8 us            8   195.058k       24.0686k/s
ufiresaber/keygen_mean           160 us          160 us            8   749.899k       6.23375k/s
ufiresaber/keygen_median         160 us          160 us            8   749.656k       6.23642k/s
ufiresaber/keygen_stddev       0.265 us        0.268 us            8    709.261         10.374/s
ufiresaber/keygen_cv            0.17 %          0.17 %             8      0.09%            0.17%
ufiresaber/keygen_min            160 us          160 us            8   749.418k        6.2094k/s
ufiresaber/keygen_max            161 us          161 us            8   751.596k       6.24275k/s
firesaber/decaps_mean            230 us          230 us            8   1.07534M       4.34691k/s
firesaber/decaps_median          230 us          230 us            8   1.07525M       4.34991k/s
firesaber/decaps_stddev        0.490 us        0.493 us            8    501.356        9.29772/s
firesaber/decaps_cv             0.21 %          0.21 %             8      0.05%            0.21%
firesaber/decaps_min             230 us          230 us            8   1.07488M       4.32803k/s
firesaber/decaps_max             231 us          231 us            8   1.07652M       4.35439k/s
saber/decaps_mean                143 us          143 us            8   671.358k       6.97545k/s
saber/decaps_median              143 us          143 us            8   671.327k        6.9754k/s
saber/decaps_stddev            0.076 us        0.073 us            8    183.137        3.55688/s
saber/decaps_cv                 0.05 %          0.05 %             8      0.03%            0.05%
saber/decaps_min                 143 us          143 us            8    671.11k       6.97164k/s
saber/decaps_max                 143 us          143 us            8    671.69k       6.98306k/s
usaber/keygen_mean              91.3 us         91.3 us            8     426.7k       10.9555k/s
usaber/keygen_median            91.2 us         91.2 us            8   426.712k       10.9596k/s
usaber/keygen_stddev           0.131 us        0.128 us            8    180.262        15.3317/s
usaber/keygen_cv                0.14 %          0.14 %             8      0.04%            0.14%
usaber/keygen_min               91.2 us         91.2 us            8   426.499k       10.9194k/s
usaber/keygen_max               91.6 us         91.6 us            8   426.947k       10.9659k/s
lightsaber/decaps_mean          78.7 us         78.7 us            8   367.573k       12.7129k/s
lightsaber/decaps_median        78.7 us         78.7 us            8   367.525k       12.7134k/s
lightsaber/decaps_stddev       0.086 us        0.053 us            8    218.962        8.59515/s
lightsaber/decaps_cv            0.11 %          0.07 %             8      0.06%            0.07%
lightsaber/decaps_min           78.6 us         78.6 us            8   367.296k       12.7001k/s
lightsaber/decaps_max           78.8 us         78.7 us            8   368.016k       12.7257k/s
lightsaber/encaps_mean          61.5 us         61.5 us            8    287.72k       16.2575k/s
lightsaber/encaps_median        61.5 us         61.5 us            8   287.665k       16.2688k/s
lightsaber/encaps_stddev       0.125 us        0.131 us            8    264.066         34.695/s
lightsaber/encaps_cv            0.20 %          0.21 %             8      0.09%            0.21%
lightsaber/encaps_min           61.4 us         61.4 us            8   287.371k       16.1999k/s
lightsaber/encaps_max           61.7 us         61.7 us            8   288.147k        16.294k/s

Usage

Saber is a header-only C++ library, implementing key encapsulation mechanism i.e.

  • Key Generation
  • Encapsulation
  • Decapsulation

Getting started with using Saber in your project is fairly easy.

  • Clone Saber repository under $HOME.
cd
git clone https://github.com/itzmeanjan/saber.git --recurse-submodules
  • Include proper header file in your program and use functions, constants etc. living inside respective namespace.
Scheme of Interest Header Namespace
LightSaber KEM include/lightsaber_kem.hpp lightsaber_kem::
Saber KEM include/saber_kem.hpp saber_kem::
FireSaber KEM include/firesaber_kem.hpp firesaber_kem::
uLightSaber KEM include/ulightsaber_kem.hpp ulightsaber_kem::
uSaber KEM include/usaber_kem.hpp usaber_kem::
uFireSaber KEM include/ufiresaber_kem.hpp ufiresaber_kem::
// main.cpp
#include "saber_kem.hpp"
#include "prng.hpp"
#include <cassert>

int main() {
    std::vector<uint8_t> seedA(saber_kem::seedBytes);
    std::vector<uint8_t> seedS(saber_kem::noiseBytes);
    std::vector<uint8_t> z(saber_kem::keyBytes);
    std::vector<uint8_t> m(saber_kem::keyBytes);
    std::vector<uint8_t> pkey(saber_kem::PK_LEN);
    std::vector<uint8_t> skey(saber_kem::SK_LEN);
    std::vector<uint8_t> ctxt(saber_kem::CT_LEN);
    std::vector<uint8_t> sskey_peer0(sha3_256::DIGEST_LEN);
    std::vector<uint8_t> sskey_peer1(sha3_256::DIGEST_LEN);

    // Create non-owning interfaces over heap allocated vectors
    // More @ https://en.cppreference.com/w/cpp/container/span
    auto _seedA = std::span<uint8_t, saber_kem::seedBytes>(seedA);
    auto _seedS = std::span<uint8_t, saber_kem::noiseBytes>(seedS);
    auto _z = std::span<uint8_t, saber_kem::keyBytes>(z);
    auto _m = std::span<uint8_t, saber_kem::keyBytes>(m);
    auto _pkey = std::span<uint8_t, saber_kem::PK_LEN>(pkey);
    auto _skey = std::span<uint8_t, saber_kem::SK_LEN>(skey);
    auto _ctxt = std::span<uint8_t, saber_kem::CT_LEN>(ctxt);
    auto _sskey_peer0 = std::span<uint8_t, sha3_256::DIGEST_LEN>(sskey_peer0);
    auto _sskey_peer1 = std::span<uint8_t, sha3_256::DIGEST_LEN>(sskey_peer1);

    // Random sample seeds using PRNG backed by SHAKE128 Xof
    //
    // !!! I strongly advice you to go through comments in include/prng.hpp
    // header file before you start using it in production for sampling randomness. !!!
    prng::prng_t prng;

    prng.read(_seedA);
    prng.read(_seedS);
    prng.read(_z);
    prng.read(_m);

    // Peer-1 generates a Saber KEM keypair.
    saber_kem::keygen(_seedA, _seedS, _z, _pkey, _skey);
    // Peer-0 uses Peer-1's public key for encapsulating a key, also producing session key.
    saber_kem::encaps(_m, _pkey, _ctxt, _sskey_peer0);
    // Peer-1 uses its private key to decapsulate cipher text, producing same session key.
    saber_kem::decaps(_ctxt, _skey, _sskey_peer1);

    // Both peers must arrive at same session key.
    assert(std::ranges::equal(_sskey_peer0, _sskey_peer1));
    return 0;
}
  • When it's time to compile your program, let your compiler know where it can find Saber KEM headers ( ./include directory ) along with Sha3 and Subtle headers, respectively living in ./sha3/include and ./subtle/include.
SABER_HEADERS=~/saber/include
SHA3_HEADERS=~/saber/sha3/include
SUBTLE_HEADERS=~/saber/subtle/include

g++ -std=c++20 -Wall -O3 -march=native -I $SABER_HEADERS -I $SHA3_HEADERS -I $SUBTLE_HEADERS main.cpp

I maintain an example program, demonstrating usage of Saber KEM API. Just like that one can use LightSaber or FireSaber or any of the uniform sampling based KEM variant's API, while just updating header file and namespace.

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

Public Key  : 3bdf4809d5dd79700910e80ebcc98f1d68f20ef0efaadf594bb5c15ccce18418116bc77ae1bbafef275f9f224c4c2481ca6d8d7053a8933c5fd8ffebfc1415a94faee5d5b15010f81c1df7accb45df45cb7b8351988c9f381ee5073998097488763c61684d909ae255fe920cd2ee1a15267c6f758a0429af964edd24ee2d0154369f5cd7526bbae9649b3c1c6e64fe229ddaadb26ec6b6808ef072dc6a281c9a7ae64e6590f194198bd9b60f3404c7d9340fc910fc1ee4a93a1a21f09ebb3d099d8c0850330809a12a4cea5a89c6d93e3cf73beab33e27c1ff1908508a92c7e055593a737d416752eba99f066f3c7bc1d436ec94438f1db8f180e0b595effcbd2df50639f5a7f9fde1d0cd923e1dc524f696d3682c3ce540175b275882f27fc30ca306080899517115183cd423ba93a9c8734e5e3e38366163d91a120fc0499902b0917b3131cdd83e8b14415c93f11879583c337b54b515d494bb1dc1236856ed7a0a99611acedcfd8e528d0310d3fac98eba8cfa0d679f9d38df31ffc11b3349c4d89a8696f8b560ad92b38bb201dda0be8b15d5b8aa303c727654ecf3d9d0c7b547bccfef963c00dbf0af825e3e1430d8853befbfbae8aadbdea192ac92cac98e02241a5edc4c3df9a8df5fd13e2e5fc4d9312d6b1509629f9a3c0c5674f886c547a5cc8061e1e175460791bc1b4aa5b98164fcfa40a12d14b774b7e9f815d043c47cc839cfe973a1d118c933d7ec008a4c5811114c4eca24706b8228c794b0a53519368b670b0076ad4c6430225664376d149f8101b3ceb07cb93fbf70cdd97ec55592bfc4ae8d7e153456a7ba1ebfcf1bb75b1a5ee0e448d12816ade6c512f93546e7ccd29fc677ea4599e1fe5a3ef7fb2dc7ace1fb4780a9b28ba18536775413e7eeaf947ed3c8c5373a6204f788164ea08b21e2502b84dd5240c38c48781fa1f1ddf965bed87ace3e20da27e1a9d827c72b59b6238efe392df88dcf0e635c83b26073830583d35acafd63ef52667d2cab4452104418d3ff3d5aaab55b7e6a1c1e5d885c45a2b79fcc81a1268b45c2207d642cb3a5bab85e80e1e0a5c8b68f8a448ec51926c0e4433053b14f17a3e0b55e3127fbc4a98209da6bd6b9e29cbf17491ce20ac3e20a82b7ae417fb95b0005ae5417a04341c481e81a2b9fb9ef930faef3b22995c23da685341c46d1c216e9ae36da20f14dc0e503bb44e9e8745c2972e57786519a77e472dde716c4245fc44ca388b6320eeb4fe154ecdfd7fd2c94a7a280bb65f96aae4a2c76653bc8e5bf84a012aecb1f80d3d63866c5475eb3ef333413964f64cfe2567d8504be374021dc1dca686a1d8b6cf1532d7b1eb7c701d4d46bf48fd12dea72c4a92eee3dc335e294248fcd1cae1df3c9e33c29
Secret Key  : bbdb28be86156fe2bd1126ddc742bdc47865927fe477b50d0d902c360c1a2470055bdf2ef37e5ad8fffd65de17d90d6a0d35df792e912f47b1dea9c299503b0e3bdf4809d5dd79700910e80ebcc98f1d68f20ef0efaadf594bb5c15ccce18418116bc77ae1bbafef275f9f224c4c2481ca6d8d7053a8933c5fd8ffebfc1415a94faee5d5b15010f81c1df7accb45df45cb7b8351988c9f381ee5073998097488763c61684d909ae255fe920cd2ee1a15267c6f758a0429af964edd24ee2d0154369f5cd7526bbae9649b3c1c6e64fe229ddaadb26ec6b6808ef072dc6a281c9a7ae64e6590f194198bd9b60f3404c7d9340fc910fc1ee4a93a1a21f09ebb3d099d8c0850330809a12a4cea5a89c6d93e3cf73beab33e27c1ff1908508a92c7e055593a737d416752eba99f066f3c7bc1d436ec94438f1db8f180e0b595effcbd2df50639f5a7f9fde1d0cd923e1dc524f696d3682c3ce540175b275882f27fc30ca306080899517115183cd423ba93a9c8734e5e3e38366163d91a120fc0499902b0917b3131cdd83e8b14415c93f11879583c337b54b515d494bb1dc1236856ed7a0a99611acedcfd8e528d0310d3fac98eba8cfa0d679f9d38df31ffc11b3349c4d89a8696f8b560ad92b38bb201dda0be8b15d5b8aa303c727654ecf3d9d0c7b547bccfef963c00dbf0af825e3e1430d8853befbfbae8aadbdea192ac92cac98e02241a5edc4c3df9a8df5fd13e2e5fc4d9312d6b1509629f9a3c0c5674f886c547a5cc8061e1e175460791bc1b4aa5b98164fcfa40a12d14b774b7e9f815d043c47cc839cfe973a1d118c933d7ec008a4c5811114c4eca24706b8228c794b0a53519368b670b0076ad4c6430225664376d149f8101b3ceb07cb93fbf70cdd97ec55592bfc4ae8d7e153456a7ba1ebfcf1bb75b1a5ee0e448d12816ade6c512f93546e7ccd29fc677ea4599e1fe5a3ef7fb2dc7ace1fb4780a9b28ba18536775413e7eeaf947ed3c8c5373a6204f788164ea08b21e2502b84dd5240c38c48781fa1f1ddf965bed87ace3e20da27e1a9d827c72b59b6238efe392df88dcf0e635c83b26073830583d35acafd63ef52667d2cab4452104418d3ff3d5aaab55b7e6a1c1e5d885c45a2b79fcc81a1268b45c2207d642cb3a5bab85e80e1e0a5c8b68f8a448ec51926c0e4433053b14f17a3e0b55e3127fbc4a98209da6bd6b9e29cbf17491ce20ac3e20a82b7ae417fb95b0005ae5417a04341c481e81a2b9fb9ef930faef3b22995c23da685341c46d1c216e9ae36da20f14dc0e503bb44e9e8745c2972e57786519a77e472dde716c4245fc44ca388b6320eeb4fe154ecdfd7fd2c94a7a280bb65f96aae4a2c76653bc8e5bf84a012aecb1f80d3d63866c5475eb3ef333413964f64cfe2567d8504be374021dc1dca686a1d8b6cf1532d7b1eb7c701d4d46bf48fd12dea72c4a92eee3dc335e294248fcd1cae1df3c9e33c2902c0ffff7f00f0ff038000f8fffe3f000080ff1f00fe3f00f8ffff3f000000ff0f0000c0ff1f00002000000000f0ff0180ff0f00012000fcff00e0fffdff00100001a0fffb7fffffff0380fff7ff000000040001f0ff030000000000c0ff078000000000000010000340000080ffdfff01000000000320000480ff4f00fc7f00000001e0ff0f0001f0ff05c0fff7ff000000fcff00000002c0ff0700fe1f000480fe0f00084000000000400000800000000040000800fdffff0300000000024000f8ffffffff0380ff1f0002c0ff0f00002000040001f0fffdbffff7fffe1f00f4ffffeffffdbfff070001e0ff07800010000240000800ffffff0700000000febf000000000000f87f001000064000f8ff00c0ff0780ffefff01c0fff7ff0200000480ff1f00fe7f000000012000fcff0110000000000000fc1f00040000e0ff038000f0ff0300000400001000fc7f000800fe1f00008000f0ff0380ff170000e0ff03000120000080ff0700ff1f00000001e0ff0180ff1700012000fc7f010000fc3f00e8ffff3f00f87f0000000200001800004000000001f0ff014000f0ff0220000480ffffffff3f00f8ff0100000c00001000024000080003e0ff038000f0ff0340000000fedffffb7f00e0ff050000e8ff00e0ffff7f01f0fffdffff170001e0ffffff00e0fff9ffff17000100000000002000febfff1f00fe5f00f87f00f0ffff3f0008000100000400001000feffff0700010000000001e0ffffffff0f00010000000000f0ff07c0fff7ff0100000880002000feffff0f00ff1f000480ffffffff3f000000ff3f000480ffffff03c0ffffff00e0ff0b000000000440000800fe3f0000000020000440000000fd3f00f8ffffefff054000f8ff002000fcff001000008000f0ffff1f00fc7f00000000c0ff0f00ff5f000000ff1f00040000080000c0ff0300ffefff0140001000fe1f000c0000f0ff01c000e8ff02000000800100000280ff1700fe3f00008000f0ffffbf001000020000000001f0fffdffff070000e0ff0b80002000febf00f8ff0200000880ff0f00004000f8ff0120000400ffffff014000f8fffedfff0f8000f0ff01c0ffefffff1f00040001000002c0fffffffe3f00fcffff0f00fe7f00f8ff020000f8ff001000fe3f00100001c0ff078000f0ff0300000000ffdffffbff000000fe3f00000001c0fffb7f00d0fffb7f0008000020000080ff0f00024000080001e0ff0b0000f0ffffbfff0700feffff078000e0ffff3f00000002c0fffb7f002000febf00000000000004000020000280ff0f0000e0fffb7f002000048000100000c0ff070001e0ff01c0ffffff0300000480ff0f00040000f8ff0140000480000000004000f0ff010000f87fffffffff7fff0700012000fcffffefffffffff0f00000000fc7f000000060000000001e0fff7ff002000fafffffffffd1f000080011000feffff0700ff1f000080ff3f00020000f0ffffdfff078000000004c000f8ff024000088000f0ff050000000001e0ff070000100006c0ff0700024000f87f001000fe3f011000002000048000100000400000000000000080ff0f0004c0ff070001c0ff0780ff1f00fc7f000800004000fcffff0f000400001000fd5f000080ff0f0000c0ff0f00fe1f00f4fffe1f00faffffffff012000008001f0fffd7f00f8fffe5f000000002000fe7f00000001e0ff0700ff1f000280ff170000a0ff0780ffffff078000f8ff
Cipher Text : f0af922faecdcbcd728c0e1016e008757c761d395fe357f1f7fa91b0dded3e45c0def52a19d5690da3a5712f0d16bc26d9ac7687ebda4936ede50d1ea58c9fb1bc9ef083cbd589527a4d27313af5f936d7c451097df750d0f8117e6ed70d5bea97cd9bec5b59b58cf8cf265237e6e353efe36efc2bb7780d762f17b91819194036a2aeb48871738be906a13711eda41c02d57266f574a169395a25537083f921154644b8b896e5fa1b56f00ac8e980b038fedcffa5f2ccc04a249a9b4db02dab9764d483220ad5f1f64692c5fa3980c9079ff6b65a4cd2339119796aafc51ae55486e2ab473c518cb95d8b94c52b501e4faf5eb4c1328d13584ac337ba02a76bd39643762ac880fecb210609fc399c8836da1c3baeeef257e334d9755bce1b784757820e3b09c8d1273a6dbdc6b1e7d561b33ccafea6d79cd5743d1f85f506c834a04596c8819a8caba4d4d0686a381ddf64d19749fdf32ee805d1505f5eea8d45d211cea4f9ed4b212d7ae8c81235d14ed872635f04b416417255c5b45eca6c9c027ce7892d5d446feea136c2b99b9b6ff1a9585d2d81fe0f351f06bbdf0b1a043167bf262875085437d0db0578d4731dd2ec767eeb0aeeda535f0cb1ba8ea4319a05d06035692ce35ae763229731dac0d725cf357bdf96ad1e8d77744e8900d08b67609dee50229a34ef1b355a8b14c9bb742784972f18ff5416f83a53d7a7d3e8a21abf091218c5bfb755f2d21d775bd690a21053a6838eb935eae23e99bbd6ca802169ed0386bf8241782e69f452a0055230c7c5f4537df0132b43458a80a422a12c407ac8ceb9e608e40b48d23c714a4c01a6e80ed77a48bfcbd7282e1822688eb699f9b1b1fde3f98c4d02e634e2c15402643abb6a91efcedd0d5fad19f7e20b2e7da007c4cbdf23f73b54f16c97aac7a7f7bac5930a498b0134764c203b5bd7638ba78898ebdc0d4964efa3a91afe6ad45e6ea861a88354060ab6b54898acc48d19b2288da0ae1753deffb17c19c6af98061dfebff9eb8eeed95da7df14d5f6dd9e368550e2d2f9b3e2cbd8ba59b68161b49c0b4c508756e6fc60285baa64965201f6e7d53d257a884d5d195edbd8385519032c98b4c1f7d388ad23ff2f2be63f8d11b38fdf4a8d454683952f6dc1ca51c5324561edfab65f5382090bb75b4fb8d3bd6b088d1ac4cd0ec30e4b76779704bb8c32a7749096e77a117cf336e6ee1f743e4bd0cfa12bb67be1c39bb27ee3527b9fa2ab1c4e35087104d68d8821ecca8bdb6a142b6d9e617c135fd309cdab06bf88ded02b0d4ffc4c5c3f917d90f5cc45b3fe45c12ac33d9cd391efc1a348449e6bb394d98b74488cd79a602c786a0e0aa04b1d952c85624f2e9bf68e9a09079fcddd37482ad3727d5897f1391606b267b1e860e881bcacecf1767fed251eadeb9d96b56be5f88bfd37fc4f3e16ccf33af59476610e304578d21e25e1c310552899e1dc2411c87fce4d6b1fa4bebc89c986d5297de07884e523788117f1c930615887a36a19e36eb6572aa9
Session Key : eb8b0fce5ee3f0d15755f7b72726d61a1f11cad9bddeb15b049884bda7eb8b92