13#include <botan/frodokem.h> 
   15#include <botan/assert.h> 
   19#include <botan/internal/ct_utils.h> 
   20#include <botan/internal/frodo_constants.h> 
   21#include <botan/internal/frodo_matrix.h> 
   22#include <botan/internal/frodo_types.h> 
   23#include <botan/internal/loadstor.h> 
   24#include <botan/internal/pk_ops_impl.h> 
   25#include <botan/internal/stl_util.h> 
   34class FrodoKEM_PublicKeyInternal {
 
   36      FrodoKEM_PublicKeyInternal(FrodoKEMConstants constants, 
FrodoSeedA seed_a, FrodoMatrix b) :
 
   37            m_constants(std::move(constants)), m_seed_a(std::move(seed_a)), m_b(std::move(b)) {
 
   38         auto& shake = m_constants.SHAKE_XOF();
 
   39         shake.update(serialize());
 
   43      const FrodoKEMConstants& constants()
 const { 
return m_constants; }
 
   45      const FrodoSeedA& seed_a()
 const { 
return m_seed_a; }
 
   47      const FrodoMatrix& b()
 const { 
return m_b; }
 
   54      FrodoKEMConstants m_constants;
 
   60class FrodoKEM_PrivateKeyInternal {
 
   62      FrodoKEM_PrivateKeyInternal(
FrodoSeedS s, FrodoMatrix s_trans) :
 
   63            m_s(std::move(s)), m_s_trans(std::move(s_trans)) {}
 
   67      const FrodoMatrix& s_trans()
 const { 
return m_s_trans; }
 
   69      constexpr void _const_time_poison()
 const { 
CT::poison_all(m_s, m_s_trans); }
 
   71      constexpr void _const_time_unpoison()
 const { 
CT::unpoison_all(m_s, m_s_trans); }
 
   75      FrodoMatrix m_s_trans;
 
   84      Frodo_KEM_Encryptor(std::shared_ptr<FrodoKEM_PublicKeyInternal> key, std::string_view kdf) :
 
   91      void raw_kem_encrypt(std::span<uint8_t> out_encapsulated_key,
 
   92                           std::span<uint8_t> out_shared_key,
 
   93                           RandomNumberGenerator& rng)
 override {
 
   94         const auto& consts = m_public_key->constants();
 
   95         auto& shake = consts.SHAKE_XOF();
 
   98         BufferStuffer out_ct_bs(out_encapsulated_key);
 
  102         auto salt = out_ct_bs.next<
FrodoSalt>(consts.len_salt_bytes());
 
  106         const auto u = rng.random_vec<
FrodoPlaintext>(consts.len_sec_bytes());
 
  111         shake.update(m_public_key->hash());
 
  114         const auto seed_se = shake.output<
FrodoSeedSE>(consts.len_se_bytes());
 
  118         shake.update(consts.encapsulation_domain_separator());
 
  119         shake.update(seed_se);
 
  121         const auto s_p = sample_generator(std::tuple(consts.n_bar(), consts.n()));
 
  123         const auto e_p = sample_generator(std::tuple(consts.n_bar(), consts.n()));
 
  127         b_p.pack(consts, c_1);
 
  129         const auto e_pp = sample_generator(std::tuple(consts.n_bar(), consts.n_bar()));
 
  140         shake.update(out_encapsulated_key);
 
  142         shake.output(out_shared_key);
 
  148      std::shared_ptr<FrodoKEM_PublicKeyInternal> m_public_key;
 
  153      Frodo_KEM_Decryptor(std::shared_ptr<FrodoKEM_PublicKeyInternal> public_key,
 
  154                          std::shared_ptr<FrodoKEM_PrivateKeyInternal> private_key,
 
  155                          std::string_view kdf) :
 
  162      void raw_kem_decrypt(std::span<uint8_t> out_shared_key, std::span<const uint8_t> encapsulated_key)
 override {
 
  165         const auto& consts = m_public_key->constants();
 
  166         auto& shake = consts.SHAKE_XOF();
 
  169         if(encapsulated_key.size() != consts.len_ct_bytes()) {
 
  170            throw Invalid_Argument(
"FrodoKEM ciphertext does not have the correct byte count");
 
  173         BufferSlicer ct_bs(encapsulated_key);
 
  176         auto salt = ct_bs.take<
FrodoSalt>(consts.len_salt_bytes());
 
  185         const auto seed_u_p = m.decode(consts);
 
  187         shake.update(m_public_key->hash());
 
  188         shake.update(seed_u_p);
 
  191         const auto seed_se_p = shake.output<
FrodoSeedSE>(consts.len_se_bytes());
 
  195         shake.update(consts.encapsulation_domain_separator());
 
  196         shake.update(seed_se_p);
 
  197         const auto s_p = sample_generator(std::tuple(consts.n_bar(), consts.n()));
 
  199         const auto e_p = sample_generator(std::tuple(consts.n_bar(), consts.n()));
 
  203         const auto e_pp = sample_generator(std::tuple(consts.n_bar(), consts.n_bar()));
 
  220         const auto cmp = b_p.constant_time_compare(b_pp) & c.constant_time_compare(c_p);
 
  222         std::vector<uint8_t> k_bar(consts.len_sec_bytes(), 0);
 
  225         shake.update(encapsulated_key);
 
  227         shake.output(out_shared_key);
 
  233      std::shared_ptr<FrodoKEM_PublicKeyInternal> m_public_key;
 
  234      std::shared_ptr<FrodoKEM_PrivateKeyInternal> m_private_key;
 
  244      throw Invalid_Argument(
"FrodoKEM public key does not have the correct byte count");
 
  254   m_public = std::make_shared<FrodoKEM_PublicKeyInternal>(std::move(consts), std::move(seed_a), std::move(b));
 
 
  261   m_public = std::make_shared<FrodoKEM_PublicKeyInternal>(
 
 
  267      m_public = std::make_shared<FrodoKEM_PublicKeyInternal>(
 
 
  278   return m_public->constants().mode().object_identifier();
 
 
  286   return m_public->constants().estimated_strength();
 
 
  304   return std::make_unique<FrodoKEM_PrivateKey>(rng, 
m_public->constants().mode());
 
 
  308                                                                                     std::string_view provider)
 const {
 
  309   if(provider.empty() || provider == 
"base") {
 
  310      return std::make_unique<Frodo_KEM_Encryptor>(
m_public, params);
 
 
  334   shake.update(seed_se);
 
  337   auto s_trans = sample_generator(std::tuple(consts.
n_bar(), consts.
n()));
 
  338   auto e = sample_generator(std::tuple(consts.
n(), consts.
n_bar()));
 
  345   m_public = std::make_shared<FrodoKEM_PublicKeyInternal>(std::move(consts), std::move(seed_a), std::move(b));
 
  346   m_private = std::make_shared<FrodoKEM_PrivateKeyInternal>(std::move(s), std::move(s_trans));
 
 
  353      throw Invalid_Argument(
"FrodoKEM private key does not have the correct byte count");
 
  367   m_public = std::make_shared<FrodoKEM_PublicKeyInternal>(std::move(consts), std::move(seed_a), std::move(b));
 
  368   m_private = std::make_shared<FrodoKEM_PrivateKeyInternal>(std::move(s), std::move(s_trans));
 
 
  377   return std::make_unique<FrodoKEM_PublicKey>(*
this);
 
 
  388                                         m_private->s_trans().serialize(),
 
 
  393                                                                                      std::string_view params,
 
  394                                                                                      std::string_view provider)
 const {
 
  396   if(provider.empty() || provider == 
"base") {
 
  397      return std::make_unique<Frodo_KEM_Decryptor>(
m_public, m_private, params);
 
 
#define BOTAN_ASSERT_NOMSG(expr)
 
#define BOTAN_STATE_CHECK(expr)
 
auto copy(const size_t count)
 
std::span< const uint8_t > take(const size_t count)
 
FrodoDomainSeparator keygen_domain_separator() const
 
size_t len_private_key_bytes() const
 
size_t len_public_key_bytes() const
 
size_t len_sec_bytes() const
 
size_t len_se_bytes() const
 
size_t len_a_bytes() const
 
FrodoKEM_PrivateKey(RandomNumberGenerator &rng, FrodoKEMMode mode)
 
std::unique_ptr< PK_Ops::KEM_Decryption > create_kem_decryption_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
 
secure_vector< uint8_t > raw_private_key_bits() const override
 
secure_vector< uint8_t > private_key_bits() const override
 
std::unique_ptr< Public_Key > public_key() const override
 
size_t estimated_strength() const override
 
AlgorithmIdentifier algorithm_identifier() const override
 
std::unique_ptr< PK_Ops::KEM_Encryption > create_kem_encryption_op(std::string_view params, std::string_view provider) const override
 
size_t key_length() const override
 
std::shared_ptr< FrodoKEM_PublicKeyInternal > m_public
 
FrodoKEM_PublicKey(std::span< const uint8_t > pub_key, FrodoKEMMode mode)
 
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
 
std::vector< uint8_t > public_key_bits() const override
 
FrodoKEM_PublicKey & operator=(const FrodoKEM_PublicKey &other)
 
std::string algo_name() const override
 
bool check_key(RandomNumberGenerator &rng, bool strong) const override
 
std::vector< uint8_t > raw_public_key_bits() const override
 
FrodoKEM_PublicKey()=default
 
OID object_identifier() const override
 
static FrodoMatrix mul_add_sa_plus_e(const FrodoKEMConstants &constants, const FrodoMatrix &s, const FrodoMatrix &e, StrongSpan< const FrodoSeedA > seed_a)
 
static std::function< FrodoMatrix(const Dimensions &dimensions)> make_sample_generator(const FrodoKEMConstants &constants, Botan::XOF &shake)
 
static FrodoMatrix mul_add_sb_plus_e(const FrodoKEMConstants &constants, const FrodoMatrix &b, const FrodoMatrix &s, const FrodoMatrix &e)
 
static FrodoMatrix mul_add_as_plus_e(const FrodoKEMConstants &constants, const FrodoMatrix &s, const FrodoMatrix &e, StrongSpan< const FrodoSeedA > seed_a)
 
static FrodoMatrix sub(const FrodoKEMConstants &constants, const FrodoMatrix &a, const FrodoMatrix &b)
 
static FrodoMatrix add(const FrodoKEMConstants &constants, const FrodoMatrix &a, const FrodoMatrix &b)
 
static FrodoMatrix encode(const FrodoKEMConstants &constants, StrongSpan< const FrodoPlaintext > in)
 
static FrodoMatrix unpack(const FrodoKEMConstants &constants, const Dimensions &dimensions, StrongSpan< const FrodoPackedMatrix > packed_bytes)
 
static FrodoMatrix mul_bs(const FrodoKEMConstants &constants, const FrodoMatrix &b_p, const FrodoMatrix &s)
 
static FrodoMatrix deserialize(const Dimensions &dimensions, StrongSpan< const FrodoSerializedMatrix > bytes)
 
KEM_Decryption_with_KDF(std::string_view kdf)
 
virtual size_t raw_kem_shared_key_length() const =0
 
virtual size_t encapsulated_key_length() const =0
 
virtual size_t raw_kem_shared_key_length() const =0
 
KEM_Encryption_with_KDF(std::string_view kdf)
 
virtual size_t encapsulated_key_length() const =0
 
void random_vec(std::span< uint8_t > v)
 
constexpr void poison_all(const Ts &... ts)
 
constexpr Mask< T > conditional_copy_mem(Mask< T > mask, T *dest, const T *if_set, const T *if_unset, size_t elems)
 
constexpr auto scoped_poison(const Ts &... xs)
 
constexpr void unpoison_all(const Ts &... ts)
 
constexpr void unpoison(const T *p, size_t n)
 
constexpr void poison(const T *p, size_t n)
 
Strong< secure_vector< uint8_t >, struct FrodoSeedSE_ > FrodoSeedSE
 
Strong< secure_vector< uint8_t >, struct FrodoSerializedMatrix_ > FrodoSerializedMatrix
 
Strong< std::vector< uint8_t >, struct FrodoSeedZ_ > FrodoSeedZ
 
Strong< secure_vector< uint8_t >, struct FrodoIntermediateSharedSecret_ > FrodoIntermediateSharedSecret
 
Strong< std::vector< uint8_t >, struct FrodoPublicKeyHash_ > FrodoPublicKeyHash
 
constexpr auto concat(Rs &&... ranges)
 
std::vector< T, secure_allocator< T > > secure_vector
 
Strong< std::vector< uint8_t >, struct FrodoSeedA_ > FrodoSeedA
 
Strong< secure_vector< uint8_t >, struct FrodoPlaintext_ > FrodoPlaintext
 
Strong< std::vector< uint8_t >, struct FrodoSalt_ > FrodoSalt
 
Strong< std::vector< uint8_t >, struct FrodoPackedMatrix_ > FrodoPackedMatrix
 
Strong< secure_vector< uint8_t >, struct FrodoSeedS_ > FrodoSeedS