9#include <botan/ed448.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/ed448_internal.h>
17#include <botan/internal/pk_ops_impl.h>
55 return std::make_unique<Ed448_PrivateKey>(rng);
65 m_private = std::move(bits);
75 m_private.assign(key_bits.begin(), key_bits.end());
82 return std::make_unique<Ed448_PublicKey>(
m_public);
99 virtual void update(std::span<const uint8_t> msg) = 0;
100 virtual std::vector<uint8_t> get_and_clear() = 0;
102 Ed448_Message() =
default;
103 virtual ~Ed448_Message() =
default;
104 Ed448_Message(
const Ed448_Message&) =
delete;
105 Ed448_Message& operator=(
const Ed448_Message&) =
delete;
106 Ed448_Message(Ed448_Message&&) =
delete;
107 Ed448_Message& operator=(Ed448_Message&&) =
delete;
110class Prehashed_Ed448_Message
final :
public Ed448_Message {
112 void update(std::span<const uint8_t> msg)
override { m_hash->update(msg); }
114 std::vector<uint8_t> get_and_clear()
override {
return m_hash->final_stdvec(); }
116 Prehashed_Ed448_Message(std::string_view hash) : m_hash(HashFunction::create_or_throw(hash)) {}
119 std::unique_ptr<HashFunction> m_hash;
122class Pure_Ed448_Message
final :
public Ed448_Message {
124 void update(std::span<const uint8_t> msg)
override { m_msg.insert(m_msg.end(), msg.begin(), msg.end()); }
126 std::vector<uint8_t> get_and_clear()
override {
return std::exchange(m_msg, {}); }
129 std::vector<uint8_t> m_msg;
135class Ed448_Verify_Operation
final :
public PK_Ops::Verification {
137 explicit Ed448_Verify_Operation(
const Ed448_PublicKey& key,
138 std::optional<std::string> prehash_function = std::nullopt) :
139 m_prehash_function(std::move(prehash_function)) {
140 const auto pk_bits = key.public_key_bits();
141 copy_mem(m_pk, std::span(pk_bits).first<ED448_LEN>());
142 if(m_prehash_function) {
143 m_message = std::make_unique<Prehashed_Ed448_Message>(*m_prehash_function);
145 m_message = std::make_unique<Pure_Ed448_Message>();
149 void update(std::span<const uint8_t> input)
override { m_message->update(input); }
151 bool is_valid_signature(std::span<const uint8_t> sig)
override {
152 const auto msg = m_message->get_and_clear();
154 return verify_signature(m_pk, m_prehash_function.has_value(), {}, sig, msg);
155 }
catch(Decoding_Error&) {
160 std::string hash_function()
const override {
return m_prehash_function.value_or(
"SHAKE-256(912)"); }
163 std::array<uint8_t, ED448_LEN> m_pk;
164 std::unique_ptr<Ed448_Message> m_message;
165 std::optional<std::string> m_prehash_function;
171class Ed448_Sign_Operation
final :
public PK_Ops::Signature {
173 explicit Ed448_Sign_Operation(
const Ed448_PrivateKey& key,
174 std::optional<std::string> prehash_function = std::nullopt) :
175 m_prehash_function(std::move(prehash_function)) {
176 const auto pk_bits = key.public_key_bits();
177 copy_mem(m_pk, std::span(pk_bits).first<ED448_LEN>());
178 const auto sk_bits = key.raw_private_key_bits();
180 m_sk.assign(sk_bits.begin(), sk_bits.end());
181 if(m_prehash_function) {
182 m_message = std::make_unique<Prehashed_Ed448_Message>(*m_prehash_function);
184 m_message = std::make_unique<Pure_Ed448_Message>();
188 void update(std::span<const uint8_t> input)
override { m_message->update(input); }
190 std::vector<uint8_t> sign(RandomNumberGenerator& )
override {
194 std::span(m_sk).first<ED448_LEN>(), m_pk, m_prehash_function.has_value(), {}, m_message->get_and_clear());
196 return {sig.begin(), sig.end()};
199 size_t signature_length()
const override {
return 2 *
ED448_LEN; }
201 AlgorithmIdentifier algorithm_identifier()
const override;
203 std::string hash_function()
const override {
return m_prehash_function.value_or(
"SHAKE-256(912)"); }
206 std::array<uint8_t, ED448_LEN> m_pk;
208 std::unique_ptr<Ed448_Message> m_message;
209 std::optional<std::string> m_prehash_function;
212AlgorithmIdentifier Ed448_Sign_Operation::algorithm_identifier()
const {
213 return AlgorithmIdentifier(OID::from_string(
"Ed448"), AlgorithmIdentifier::USE_EMPTY_PARAM);
219 std::string_view provider)
const {
220 if(provider ==
"base" || provider.empty()) {
221 if(params.empty() || params ==
"Identity" || params ==
"Pure" || params ==
"Ed448") {
222 return std::make_unique<Ed448_Verify_Operation>(*
this);
223 }
else if(params ==
"Ed448ph") {
224 return std::make_unique<Ed448_Verify_Operation>(*
this,
"SHAKE-256(512)");
226 return std::make_unique<Ed448_Verify_Operation>(*
this, std::string(params));
233 std::string_view provider)
const {
234 if(provider ==
"base" || provider.empty()) {
235 if(alg_id != this->algorithm_identifier()) {
236 throw Decoding_Error(
"Unexpected AlgorithmIdentifier for Ed448 X509 signature");
239 return std::make_unique<Ed448_Verify_Operation>(*
this);
245 std::string_view params,
246 std::string_view provider)
const {
247 if(provider ==
"base" || provider.empty()) {
248 if(params.empty() || params ==
"Identity" || params ==
"Pure" || params ==
"Ed448") {
249 return std::make_unique<Ed448_Sign_Operation>(*
this);
250 }
else if(params ==
"Ed448ph") {
251 return std::make_unique<Ed448_Sign_Operation>(*
this,
"SHAKE-256(512)");
253 return std::make_unique<Ed448_Sign_Operation>(*
this, std::string(params));
#define BOTAN_ASSERT_NOMSG(expr)
virtual OID object_identifier() const
BER_Decoder & decode(bool &out)
BER_Decoder & verify_end()
secure_vector< uint8_t > get_contents()
DER_Encoder & encode(bool b)
static Ed448Point decode(std::span< const uint8_t, ED448_LEN > enc)
Decode a point from its 57-byte encoding (RFC 8032 5.2.3)
A private key for Ed448/Ed448ph according to RFC 8032.
Ed448_PrivateKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, std::string_view params, std::string_view provider) const override
bool check_key(RandomNumberGenerator &rng, bool strong) const override
secure_vector< uint8_t > private_key_bits() const override
std::unique_ptr< Public_Key > public_key() const override
A public key for Ed448/Ed448ph according to RFC 8032.
std::array< uint8_t, 57 > m_public
AlgorithmIdentifier algorithm_identifier() const override
std::unique_ptr< Private_Key > generate_another(RandomNumberGenerator &rng) const final
std::unique_ptr< PK_Ops::Verification > create_verification_op(std::string_view params, std::string_view provider) const override
std::vector< uint8_t > public_key_bits() const override
std::unique_ptr< PK_Ops::Verification > create_x509_verification_op(const AlgorithmIdentifier &signature_algorithm, std::string_view provider) const override
Ed448_PublicKey()=default
bool check_key(RandomNumberGenerator &rng, bool strong) const override
std::vector< uint8_t > raw_public_key_bits() const override
int(* update)(CTX *, const void *, CC_LONG len)
int(* final)(unsigned char *, CTX *)
constexpr auto scoped_poison(const Ts &... xs)
constexpr void unpoison(const T *p, size_t n)
std::array< uint8_t, ED448_LEN > create_pk_from_sk(std::span< const uint8_t, ED448_LEN > sk)
Create a public key point from a secret key (RFC 8032 5.2.5)
bool verify_signature(std::span< const uint8_t, ED448_LEN > pk, bool phflag, std::span< const uint8_t > context, std::span< const uint8_t > sig, std::span< const uint8_t > msg)
Verify a signature(RFC 8032 5.2.7)
constexpr size_t ED448_LEN
std::vector< T, secure_allocator< T > > secure_vector
std::array< uint8_t, 2 *ED448_LEN > sign_message(std::span< const uint8_t, ED448_LEN > sk, std::span< const uint8_t, ED448_LEN > pk, bool pgflag, std::span< const uint8_t > context, std::span< const uint8_t > msg)
Sign a message using a keypair (RFC 8032 5.2.6)
constexpr void copy_mem(T *out, const T *in, size_t n)