Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement uSaber KEM Variants #9

Merged
merged 18 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
9b152d1
remove `-mtune` optimization flag
itzmeanjan Oct 18, 2023
b7e86e7
compute minimum and maximum time required when benchmarking Saber KEM…
itzmeanjan Oct 18, 2023
0282521
implement sampling of secret vector `s` from centered uniform distrib…
itzmeanjan Oct 18, 2023
92f465c
extend definition of sampling of secret vector coefficients to also u…
itzmeanjan Oct 18, 2023
2de7242
make PKE, KEM more generic to accomodate for sampling option
itzmeanjan Oct 18, 2023
dea2477
update comment for secret vector sampler function
itzmeanjan Oct 18, 2023
9de0c71
instantiate uLightSaber KEM
itzmeanjan Oct 18, 2023
018b8a0
instantiate uSaber KEM
itzmeanjan Oct 18, 2023
b7cf04a
instantiate uFireSaber KEM
itzmeanjan Oct 18, 2023
bf1244d
serialize and deserialize polynomials with coefficients moduli 2^16; …
itzmeanjan Oct 19, 2023
928c324
rename namespace for underlying kem routines
itzmeanjan Oct 19, 2023
ce0d962
instantiate uniform sampling based KEM variants (all three security l…
itzmeanjan Oct 19, 2023
68137ee
add functional correctness tests for u-{LightSaber, Saber, FireSaber}…
itzmeanjan Oct 19, 2023
38eb09b
update benchmark routines to use new namespace and functions for KEM …
itzmeanjan Oct 19, 2023
a33466b
register uniform sampling based KEM variants for benchmarking
itzmeanjan Oct 19, 2023
dea4c44
reformat source
itzmeanjan Oct 20, 2023
3fe2e09
add known answer tests for uLightSaber, uSaber and uFireSaber KEM
itzmeanjan Oct 20, 2023
80afe4f
update project documentation to reflect latest state
itzmeanjan Oct 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 88
ColumnLimit: 176
CommentPragmas: '^ IWYU pragma:'
QualifierAlignment: Leave
CompactNamespaces: false
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
CXX = g++
CXX_FLAGS = -std=c++20
WARN_FLAGS = -Wall -Wextra -pedantic
OPT_FLAGS = -O3 -march=native -mtune=native
OPT_FLAGS = -O3 -march=native
LINK_FLAGS = -flto
I_FLAGS = -I ./include
DEP_IFLAGS = -I ./sha3/include -I ./subtle/include
Expand Down
402 changes: 290 additions & 112 deletions README.md

Large diffs are not rendered by default.

77 changes: 35 additions & 42 deletions benchmarks/bench_kem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@
#include <cassert>

// Benchmark Saber KEM key generation algorithm for various suggested parameters.
template<size_t L,
size_t EQ,
size_t EP,
size_t MU,
size_t seedBytes,
size_t noiseBytes,
size_t keyBytes>
template<size_t L, size_t EQ, size_t EP, size_t MU, size_t seedBytes, size_t noiseBytes, size_t keyBytes, bool uniform_sampling>
void
keygen(benchmark::State& state)
{
Expand All @@ -37,8 +31,7 @@ keygen(benchmark::State& state)
auto _skey = std::span<uint8_t, sklen>(skey);

for (auto _ : state) {
saber_kem::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes>(
_seedA, _seedS, _z, _pkey, _skey);
_saber_kem::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes, uniform_sampling>(_seedA, _seedS, _z, _pkey, _skey);

benchmark::DoNotOptimize(_seedA);
benchmark::DoNotOptimize(_seedS);
Expand All @@ -52,14 +45,7 @@ keygen(benchmark::State& state)
}

// Benchmark Saber KEM encapsulation algorithm for various suggested parameters.
template<size_t L,
size_t EQ,
size_t EP,
size_t ET,
size_t MU,
size_t seedBytes,
size_t noiseBytes,
size_t keyBytes>
template<size_t L, size_t EQ, size_t EP, size_t ET, size_t MU, size_t seedBytes, size_t noiseBytes, size_t keyBytes, bool uniform_sampling>
void
encaps(benchmark::State& state)
{
Expand Down Expand Up @@ -92,11 +78,10 @@ encaps(benchmark::State& state)
auto _ctxt = std::span<uint8_t, ctlen>(ctxt);
auto _seskey = std::span<uint8_t, sha3_256::DIGEST_LEN>(seskey);

saber_kem::keygen<L, EQ, EP, MU>(_seedA, _seedS, _z, _pkey, _skey);
_saber_kem::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes, uniform_sampling>(_seedA, _seedS, _z, _pkey, _skey);

for (auto _ : state) {
saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes, keyBytes>(
_m, _pkey, _ctxt, _seskey);
_saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling>(_m, _pkey, _ctxt, _seskey);

benchmark::DoNotOptimize(_m);
benchmark::DoNotOptimize(_pkey);
Expand All @@ -109,14 +94,7 @@ encaps(benchmark::State& state)
}

// Benchmark Saber KEM decapsulation algorithm for various suggested parameters.
template<size_t L,
size_t EQ,
size_t EP,
size_t ET,
size_t MU,
size_t seedBytes,
size_t noiseBytes,
size_t keyBytes>
template<size_t L, size_t EQ, size_t EP, size_t ET, size_t MU, size_t seedBytes, size_t noiseBytes, size_t keyBytes, bool uniform_sampling>
void
decaps(benchmark::State& state)
{
Expand Down Expand Up @@ -151,12 +129,11 @@ decaps(benchmark::State& state)
auto _seskey0 = std::span<uint8_t, sha3_256::DIGEST_LEN>(seskey0);
auto _seskey1 = std::span<uint8_t, sha3_256::DIGEST_LEN>(seskey1);

saber_kem::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes>(
_seedA, _seedS, _z, _pkey, _skey);
saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes, keyBytes>(_m, _pkey, _ctxt, _seskey0);
_saber_kem::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes, uniform_sampling>(_seedA, _seedS, _z, _pkey, _skey);
_saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling>(_m, _pkey, _ctxt, _seskey0);

for (auto _ : state) {
saber_kem::decaps<L, EQ, EP, ET, MU, seedBytes, keyBytes>(_ctxt, _skey, _seskey1);
_saber_kem::decaps<L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling>(_ctxt, _skey, _seskey1);

benchmark::DoNotOptimize(_ctxt);
benchmark::DoNotOptimize(_skey);
Expand All @@ -168,15 +145,31 @@ decaps(benchmark::State& state)
state.SetItemsProcessed(state.iterations());
}

// Register for benchmarking LightSaber, Saber and FireSaber KEM routines.
BENCHMARK(keygen<2, 13, 10, 10, 32, 32, 32>)->Name("lightsaber/keygen");
BENCHMARK(encaps<2, 13, 10, 3, 10, 32, 32, 32>)->Name("lightsaber/encaps");
BENCHMARK(decaps<2, 13, 10, 3, 10, 32, 32, 32>)->Name("lightsaber/decaps");
const auto compute_min = [](const std::vector<double>& v) -> double { return *std::min_element(v.begin(), v.end()); };
const auto compute_max = [](const std::vector<double>& v) -> double { return *std::max_element(v.begin(), v.end()); };

BENCHMARK(keygen<3, 13, 10, 8, 32, 32, 32>)->Name("saber/keygen");
BENCHMARK(encaps<3, 13, 10, 4, 8, 32, 32, 32>)->Name("saber/encaps");
BENCHMARK(decaps<3, 13, 10, 4, 8, 32, 32, 32>)->Name("saber/decaps");
// Register for benchmarking LightSaber, Saber, FireSaber, uLightSaber, uSaber and
// uFireSaber KEM routines.
BENCHMARK(keygen<2, 13, 10, 10, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("lightsaber/keygen");
BENCHMARK(encaps<2, 13, 10, 3, 10, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("lightsaber/encaps");
BENCHMARK(decaps<2, 13, 10, 3, 10, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("lightsaber/decaps");

BENCHMARK(keygen<4, 13, 10, 6, 32, 32, 32>)->Name("firesaber/keygen");
BENCHMARK(encaps<4, 13, 10, 6, 6, 32, 32, 32>)->Name("firesaber/encaps");
BENCHMARK(decaps<4, 13, 10, 6, 6, 32, 32, 32>)->Name("firesaber/decaps");
BENCHMARK(keygen<3, 13, 10, 8, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("saber/keygen");
BENCHMARK(encaps<3, 13, 10, 4, 8, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("saber/encaps");
BENCHMARK(decaps<3, 13, 10, 4, 8, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("saber/decaps");

BENCHMARK(keygen<4, 13, 10, 6, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("firesaber/keygen");
BENCHMARK(encaps<4, 13, 10, 6, 6, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("firesaber/encaps");
BENCHMARK(decaps<4, 13, 10, 6, 6, 32, 32, 32, false>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("firesaber/decaps");

BENCHMARK(keygen<2, 12, 10, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("ulightsaber/keygen");
BENCHMARK(encaps<2, 12, 10, 3, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("ulightsaber/encaps");
BENCHMARK(decaps<2, 12, 10, 3, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("ulightsaber/decaps");

BENCHMARK(keygen<3, 12, 10, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("usaber/keygen");
BENCHMARK(encaps<3, 12, 10, 4, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("usaber/encaps");
BENCHMARK(decaps<3, 12, 10, 4, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("usaber/decaps");

BENCHMARK(keygen<4, 12, 10, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("ufiresaber/keygen");
BENCHMARK(encaps<4, 12, 10, 6, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("ufiresaber/encaps");
BENCHMARK(decaps<4, 12, 10, 6, 2, 32, 32, 32, true>)->ComputeStatistics("min", compute_min)->ComputeStatistics("max", compute_max)->Name("ufiresaber/decaps");
16 changes: 6 additions & 10 deletions include/firesaber_kem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ constexpr size_t MU = 6;
constexpr size_t seedBytes = 32;
constexpr size_t noiseBytes = 32;
constexpr size_t keyBytes = 32;
constexpr bool uniform_sampling = false;

// 1312 -bytes FireSaber KEM public key
constexpr size_t PK_LEN = saber_utils::kem_pklen<L, EP, seedBytes>();
Expand All @@ -32,29 +33,24 @@ keygen(std::span<const uint8_t, seedBytes> seedA,
std::span<uint8_t, PK_LEN> pkey,
std::span<uint8_t, SK_LEN> skey)
{
saber_kem::keygen<L, EQ, EP, MU>(seedA, seedS, z, pkey, skey);
_saber_kem::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes, uniform_sampling>(seedA, seedS, z, pkey, skey);
}

// Given 32 -bytes random sampled `m` and 1312 -bytes FireSaber KEM public key, this
// routine generates a 1472 -bytes cipher text ( encapsulating fixed width message,
// which will be used for deriving shared secret key ) and 32 -bytes session key.
inline void
encaps(std::span<const uint8_t, keyBytes> m,
std::span<const uint8_t, PK_LEN> pkey,
std::span<uint8_t, CT_LEN> ctxt,
std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
encaps(std::span<const uint8_t, keyBytes> m, std::span<const uint8_t, PK_LEN> pkey, std::span<uint8_t, CT_LEN> ctxt, std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
{
saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes>(m, pkey, ctxt, seskey);
_saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling>(m, pkey, ctxt, seskey);
}

// Given 1472 -bytes cipher text and 3040 -bytes FireSaber KEM secret key, this routine
// can be used for decapsulating the cipher text, deriving 32 -bytes session key.
inline void
decaps(std::span<const uint8_t, CT_LEN> ctxt,
std::span<const uint8_t, SK_LEN> skey,
std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
decaps(std::span<const uint8_t, CT_LEN> ctxt, std::span<const uint8_t, SK_LEN> skey, std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
{
saber_kem::decaps<L, EQ, EP, ET, MU, seedBytes, keyBytes>(ctxt, skey, seskey);
_saber_kem::decaps<L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling>(ctxt, skey, seskey);
}

}
62 changes: 17 additions & 45 deletions include/kem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,21 @@
#include "utils.hpp"

// Algorithms related to Saber Key Encapsulation Mechanism
namespace saber_kem {
namespace _saber_kem {

// Given seedBytes `seedA` ( used for generating matrix A, in Saber PKE keygen algorithm
// ), noiseBytes `seedS` ( used for generating secret vector s, in Saber PKE keygen
// algorithm ) and keyBytes `z` ( random sampled bytes, used for randomizing Saber KEM
// secret key ), this routine can be used for generating a Saber KEM public/ private
// keypair, following algorithm 20 in section 8.5.1 of Saber spec.
template<size_t L,
size_t EQ,
size_t EP,
size_t MU,
size_t seedBytes,
size_t noiseBytes,
size_t keyBytes>
template<size_t L, size_t EQ, size_t EP, size_t MU, size_t seedBytes, size_t noiseBytes, size_t keyBytes, bool uniform_sampling>
inline void
keygen(
std::span<const uint8_t, seedBytes> seedA,
std::span<const uint8_t, noiseBytes> seedS,
std::span<const uint8_t, keyBytes> z,
std::span<uint8_t, saber_utils::kem_pklen<L, EP, seedBytes>()> pkey,
std::span<uint8_t, saber_utils::kem_sklen<L, EQ, EP, seedBytes, keyBytes>()> skey)
requires(saber_params::validate_kem_keygen_args(L,
EQ,
EP,
MU,
seedBytes,
noiseBytes,
keyBytes))
keygen(std::span<const uint8_t, seedBytes> seedA,
std::span<const uint8_t, noiseBytes> seedS,
std::span<const uint8_t, keyBytes> z,
std::span<uint8_t, saber_utils::kem_pklen<L, EP, seedBytes>()> pkey,
std::span<uint8_t, saber_utils::kem_sklen<L, EQ, EP, seedBytes, keyBytes>()> skey)
requires(saber_params::validate_kem_keygen_args(L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes, uniform_sampling))
{
constexpr size_t pke_pklen = saber_utils::pke_pklen<L, EP, seedBytes>();
constexpr size_t pke_sklen = saber_utils::pke_sklen<L, EQ>();
Expand All @@ -47,7 +34,7 @@ keygen(
auto sk_z = skey.template subspan<off2, keyBytes>();

// step 1
saber_pke::keygen<L, EQ, EP, MU>(seedA, seedS, pkey, sk_sk);
saber_pke::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, uniform_sampling>(seedA, seedS, pkey, sk_sk);
// step 4 ( partial )
std::memcpy(sk_pk.data(), pkey.data(), pkey.size());

Expand All @@ -65,20 +52,13 @@ keygen(
// Given keyBytes input `m` ( random sampled ) and Saber KEM public key, this routine
// can be used for generating a session key ( of 32 -bytes ) and Saber KEM cipher text.
// This is an implementation of algorithm 21 in section 8.5.2 of Saber spec.
template<size_t L,
size_t EQ,
size_t EP,
size_t ET,
size_t MU,
size_t seedBytes,
size_t keyBytes>
template<size_t L, size_t EQ, size_t EP, size_t ET, size_t MU, size_t seedBytes, size_t keyBytes, bool uniform_sampling>
inline void
encaps(std::span<const uint8_t, keyBytes> m, // step 1
std::span<const uint8_t, saber_utils::kem_pklen<L, EP, seedBytes>()> pkey,
std::span<uint8_t, saber_utils::kem_ctlen<L, EP, ET>()> ctxt,
std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
requires(
saber_params::validate_kem_encaps_args(L, EQ, EP, ET, MU, seedBytes, keyBytes))
requires(saber_params::validate_kem_encaps_args(L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling))
{
std::array<uint8_t, sha3_256::DIGEST_LEN> hashed_m;
std::array<uint8_t, sha3_256::DIGEST_LEN> hashed_pk;
Expand Down Expand Up @@ -113,7 +93,7 @@ encaps(std::span<const uint8_t, keyBytes> m, // step 1
// step 7
auto _hm = std::span<const uint8_t, hashed_m.size()>(hashed_m);
auto _r = std::span<const uint8_t, r.size()>(r);
saber_pke::encrypt<L, EQ, EP, ET, MU>(_hm, _r, pkey, ctxt);
saber_pke::encrypt<L, EQ, EP, ET, MU, seedBytes, uniform_sampling>(_hm, _r, pkey, ctxt);

// step 8
h256.absorb(ctxt);
Expand All @@ -132,20 +112,12 @@ encaps(std::span<const uint8_t, keyBytes> m, // step 1
// Given Saber KEM cipher text and Saber KEM secret key, this routine can be used for
// decapsulating the received cipher text, extracting a shared secret key of 32 -bytes.
// This is an implementation of algorithm 22 in section 8.5.3 of Saber spec.
template<size_t L,
size_t EQ,
size_t EP,
size_t ET,
size_t MU,
size_t seedBytes,
size_t keyBytes>
template<size_t L, size_t EQ, size_t EP, size_t ET, size_t MU, size_t seedBytes, size_t keyBytes, bool uniform_sampling>
inline void
decaps(std::span<const uint8_t, saber_utils::kem_ctlen<L, EP, ET>()> ctxt,
std::span<const uint8_t,
saber_utils::kem_sklen<L, EQ, EP, seedBytes, keyBytes>()> skey,
std::span<const uint8_t, saber_utils::kem_sklen<L, EQ, EP, seedBytes, keyBytes>()> skey,
std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
requires(
saber_params::validate_kem_decaps_args(L, EQ, EP, ET, MU, seedBytes, keyBytes))
requires(saber_params::validate_kem_decaps_args(L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling))
{
constexpr size_t pke_pklen = saber_utils::pke_pklen<L, EP, seedBytes>();
constexpr size_t pke_sklen = saber_utils::pke_sklen<L, EQ>();
Expand All @@ -166,7 +138,7 @@ decaps(std::span<const uint8_t, saber_utils::kem_ctlen<L, EP, ET>()> ctxt,
std::array<uint8_t, keyBytes> temp;

// step 2
saber_pke::decrypt<L, EQ, EP, ET, MU>(ctxt, sk, m);
saber_pke::decrypt<L, EQ, EP, ET, MU, uniform_sampling>(ctxt, sk, m);

// step 3, 4
sha3_512::sha3_512_t h512;
Expand All @@ -183,7 +155,7 @@ decaps(std::span<const uint8_t, saber_utils::kem_ctlen<L, EP, ET>()> ctxt,
// step 6
auto _m = std::span<const uint8_t, m.size()>(m);
auto _r = std::span<const uint8_t, r.size()>(r);
saber_pke::encrypt<L, EQ, EP, ET, MU>(_m, _r, pk, ctxt_prm);
saber_pke::encrypt<L, EQ, EP, ET, MU, seedBytes, uniform_sampling>(_m, _r, pk, ctxt_prm);

// step 7
auto c = saber_utils::ct_eq_bytes<ctxt.size()>(ctxt_prm, ctxt);
Expand Down
16 changes: 6 additions & 10 deletions include/lightsaber_kem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ constexpr size_t MU = 10;
constexpr size_t seedBytes = 32;
constexpr size_t noiseBytes = 32;
constexpr size_t keyBytes = 32;
constexpr bool uniform_sampling = false;

// 672 -bytes LightSaber KEM public key
constexpr size_t PK_LEN = saber_utils::kem_pklen<L, EP, seedBytes>();
Expand All @@ -32,29 +33,24 @@ keygen(std::span<const uint8_t, seedBytes> seedA,
std::span<uint8_t, PK_LEN> pkey,
std::span<uint8_t, SK_LEN> skey)
{
saber_kem::keygen<L, EQ, EP, MU>(seedA, seedS, z, pkey, skey);
_saber_kem::keygen<L, EQ, EP, MU, seedBytes, noiseBytes, keyBytes, uniform_sampling>(seedA, seedS, z, pkey, skey);
}

// Given 32 -bytes random sampled `m` and 672 -bytes LightSaber KEM public key, this
// routine generates a 736 -bytes cipher text ( encapsulating fixed width message, which
// will be used for deriving shared secret key ) and 32 -bytes session key.
inline void
encaps(std::span<const uint8_t, keyBytes> m,
std::span<const uint8_t, PK_LEN> pkey,
std::span<uint8_t, CT_LEN> ctxt,
std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
encaps(std::span<const uint8_t, keyBytes> m, std::span<const uint8_t, PK_LEN> pkey, std::span<uint8_t, CT_LEN> ctxt, std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
{
saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes>(m, pkey, ctxt, seskey);
_saber_kem::encaps<L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling>(m, pkey, ctxt, seskey);
}

// Given 736 -bytes cipher text and 1568 -bytes LightSaber KEM secret key, this routine
// can be used for decapsulating the cipher text, deriving 32 -bytes session key.
inline void
decaps(std::span<const uint8_t, CT_LEN> ctxt,
std::span<const uint8_t, SK_LEN> skey,
std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
decaps(std::span<const uint8_t, CT_LEN> ctxt, std::span<const uint8_t, SK_LEN> skey, std::span<uint8_t, sha3_256::DIGEST_LEN> seskey)
{
saber_kem::decaps<L, EQ, EP, ET, MU, seedBytes, keyBytes>(ctxt, skey, seskey);
_saber_kem::decaps<L, EQ, EP, ET, MU, seedBytes, keyBytes, uniform_sampling>(ctxt, skey, seskey);
}

}
Loading