9#include <botan/ed25519.h> 
   11#include <botan/ber_dec.h> 
   12#include <botan/der_enc.h> 
   13#include <botan/hash.h> 
   15#include <botan/internal/ct_utils.h> 
   16#include <botan/internal/ed25519_internal.h> 
   17#include <botan/internal/pk_ops_impl.h> 
   34   const uint8_t identity_element[32] = {1};
 
   40   const uint8_t modm_m[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
 
   41                               0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 
   42                               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
 
   44   const unsigned char zero[32] = {0};
 
   46   unsigned char pkcopy[32];
 
   49   pkcopy[31] ^= (1 << 7);  
 
 
   58   m_public.assign(pub_key, pub_key + pub_len);
 
 
   62   m_public.assign(key_bits.begin(), key_bits.end());
 
 
   78   return std::make_unique<Ed25519_PrivateKey>(rng);
 
 
   82   if(secret_key.size() == 64) {
 
   83      m_private.assign(secret_key.begin(), secret_key.end());
 
   84      m_public.assign(m_private.begin() + 32, m_private.end());
 
   85   } 
else if(secret_key.size() == 32) {
 
 
   96   BOTAN_ARG_CHECK(seed.size() == 32, 
"Ed25519 seed must be exactly 32 bytes long");
 
 
  102   BOTAN_ARG_CHECK(bytes.size() == 64, 
"Ed25519 private key must be exactly 64 bytes long");
 
 
  109   m_private.resize(64);
 
 
  117   if(bits.size() != 32) {
 
  121   m_private.resize(64);
 
 
  145      explicit Ed25519_Pure_Verify_Operation(
const Ed25519_PublicKey& key) : m_key(key.get_public_key()) {}
 
  147      void update(std::span<const uint8_t> msg)
 override { m_msg.insert(m_msg.end(), msg.begin(), msg.end()); }
 
  149      bool is_valid_signature(std::span<const uint8_t> sig)
 override {
 
  150         if(sig.size() != 64) {
 
  155         const bool ok = 
ed25519_verify(m_msg.data(), m_msg.size(), sig.data(), m_key.data(), 
nullptr, 0);
 
  160      std::string hash_function()
 const override { 
return "SHA-512"; }
 
  163      std::vector<uint8_t> m_msg;
 
  164      std::vector<uint8_t> m_key;
 
  172      Ed25519_Hashed_Verify_Operation(
const Ed25519_PublicKey& key, std::string_view hash, 
bool rfc8032) :
 
  173            m_key(key.get_public_key()) {
 
  177            m_domain_sep = {0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E,
 
  178                            0x6F, 0x20, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
 
  179                            0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73, 0x01, 0x00};
 
  183      void update(std::span<const uint8_t> msg)
 override { m_hash->update(msg); }
 
  185      bool is_valid_signature(std::span<const uint8_t> sig)
 override {
 
  186         if(sig.size() != 64) {
 
  189         std::vector<uint8_t> msg_hash(m_hash->output_length());
 
  190         m_hash->final(msg_hash.data());
 
  194            msg_hash.data(), msg_hash.size(), sig.data(), m_key.data(), m_domain_sep.data(), m_domain_sep.size());
 
  197      std::string hash_function()
 const override { 
return m_hash->name(); }
 
  200      std::unique_ptr<HashFunction> m_hash;
 
  201      std::vector<uint8_t> m_key;
 
  202      std::vector<uint8_t> m_domain_sep;
 
  210      explicit Ed25519_Pure_Sign_Operation(
const Ed25519_PrivateKey& key) : m_key(key.raw_private_key_bits()) {}
 
  212      void update(std::span<const uint8_t> msg)
 override { m_msg.insert(m_msg.end(), msg.begin(), msg.end()); }
 
  214      std::vector<uint8_t> sign(RandomNumberGenerator& )
 override {
 
  215         std::vector<uint8_t> sig(64);
 
  216         ed25519_sign(sig.data(), m_msg.data(), m_msg.size(), m_key.data(), 
nullptr, 0);
 
  221      size_t signature_length()
 const override { 
return 64; }
 
  223      AlgorithmIdentifier algorithm_identifier() 
const override;
 
  225      std::string hash_function()
 const override { 
return "SHA-512"; }
 
  228      std::vector<uint8_t> m_msg;
 
  233   return AlgorithmIdentifier(OID::from_string(
"Ed25519"), AlgorithmIdentifier::USE_EMPTY_PARAM);
 
  239class Ed25519_Hashed_Sign_Operation final : 
public PK_Ops::Signature {
 
  241      Ed25519_Hashed_Sign_Operation(
const Ed25519_PrivateKey& key, std::string_view hash, 
bool rfc8032) :
 
  242            m_key(key.raw_private_key_bits()) {
 
  243         m_hash = HashFunction::create_or_throw(hash);
 
  246            m_domain_sep = std::vector<uint8_t>{0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E,
 
  247                                                0x6F, 0x20, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F,
 
  248                                                0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73, 0x01, 0x00};
 
  252      size_t signature_length()
 const override { 
return 64; }
 
  254      void update(std::span<const uint8_t> msg)
 override { m_hash->update(msg); }
 
  256      std::vector<uint8_t> sign(RandomNumberGenerator& )
 override {
 
  257         std::vector<uint8_t> sig(64);
 
  258         std::vector<uint8_t> msg_hash(m_hash->output_length());
 
  259         m_hash->final(msg_hash.data());
 
  261            sig.data(), msg_hash.data(), msg_hash.size(), m_key.data(), m_domain_sep.data(), m_domain_sep.size());
 
  265      std::string hash_function()
 const override { 
return m_hash->name(); }
 
  268      std::unique_ptr<HashFunction> m_hash;
 
  269      secure_vector<uint8_t> m_key;
 
  270      std::vector<uint8_t> m_domain_sep;
 
  276                                                                                std::string_view provider)
 const {
 
  277   if(provider == 
"base" || provider.empty()) {
 
  278      if(params.empty() || params == 
"Identity" || params == 
"Pure") {
 
  279         return std::make_unique<Ed25519_Pure_Verify_Operation>(*
this);
 
  280      } 
else if(params == 
"Ed25519ph") {
 
  281         return std::make_unique<Ed25519_Hashed_Verify_Operation>(*
this, 
"SHA-512", 
true);
 
  283         return std::make_unique<Ed25519_Hashed_Verify_Operation>(*
this, params, 
false);
 
 
  290                                                                                     std::string_view provider)
 const {
 
  291   if(provider == 
"base" || provider.empty()) {
 
  293         throw Decoding_Error(
"Unexpected AlgorithmIdentifier for Ed25519 X509 signature");
 
  296      return std::make_unique<Ed25519_Pure_Verify_Operation>(*
this);
 
 
  302                                                                           std::string_view params,
 
  303                                                                           std::string_view provider)
 const {
 
  304   if(provider == 
"base" || provider.empty()) {
 
  305      if(params.empty() || params == 
"Identity" || params == 
"Pure") {
 
  306         return std::make_unique<Ed25519_Pure_Sign_Operation>(*
this);
 
  307      } 
else if(params == 
"Ed25519ph") {
 
  308         return std::make_unique<Ed25519_Hashed_Sign_Operation>(*
this, 
"SHA-512", 
true);
 
  310         return std::make_unique<Ed25519_Hashed_Sign_Operation>(*
this, params, 
false);
 
 
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
 
#define BOTAN_ARG_CHECK(expr, msg)
 
virtual OID object_identifier() const
 
BER_Decoder & decode(bool &out)
 
BER_Decoder & discard_remaining()
 
secure_vector< uint8_t > get_contents()
 
DER_Encoder & encode(bool b)
 
Ed25519_PrivateKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
 
static Ed25519_PrivateKey from_seed(std::span< const uint8_t > seed)
 
std::unique_ptr< Public_Key > public_key() const override
 
bool check_key(RandomNumberGenerator &rng, bool strong) const override
 
static Ed25519_PrivateKey from_bytes(std::span< const uint8_t > bytes)
 
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
 
secure_vector< uint8_t > private_key_bits() const override
 
std::vector< uint8_t > m_public
 
std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const override
 
std::unique_ptr< PK_Ops::Verification > create_x509_verification_op(const AlgorithmIdentifier &signature_algorithm, std::string_view provider) const override
 
const std::vector< uint8_t > & get_public_key() const
 
bool check_key(RandomNumberGenerator &rng, bool strong) const override
 
std::string algo_name() const override
 
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
 
Ed25519_PublicKey()=default
 
std::vector< uint8_t > public_key_bits() const override
 
AlgorithmIdentifier algorithm_identifier() const override
 
std::vector< uint8_t > raw_public_key_bits() const override
 
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
 
void random_vec(std::span< uint8_t > v)
 
constexpr CT::Mask< T > is_equal(const T x[], const T y[], size_t len)
 
constexpr void copy_mem(T *out, const T *in, size_t n)
 
void ed25519_sign(uint8_t sig[64], const uint8_t m[], size_t mlen, const uint8_t sk[64], const uint8_t domain_sep[], size_t domain_sep_len)
 
bool signature_check(std::span< const uint8_t, 32 > pk, const uint8_t h[32], const uint8_t r[32], const uint8_t s[32])
 
void ed25519_gen_keypair(uint8_t pk[32], uint8_t sk[64], const uint8_t seed[32])
 
std::vector< T, secure_allocator< T > > secure_vector
 
bool ed25519_verify(const uint8_t *m, size_t mlen, const uint8_t sig[64], const uint8_t *pk, const uint8_t domain_sep[], size_t domain_sep_len)