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>
23class Ed448_PublicKey_Data final {
25 explicit Ed448_PublicKey_Data(std::array<uint8_t, ED448_LEN> key) : m_key(key) {}
27 const std::array<uint8_t, ED448_LEN>& key()
const {
return m_key; }
30 std::array<uint8_t, ED448_LEN> m_key;
33class Ed448_PrivateKey_Data final {
44 const auto& sk = m_private->key();
45 return {sk.begin(), sk.end()};
65 throw Decoding_Error(
"Unexpected parameters for Ed448 public key");
73 std::array<uint8_t, ED448_LEN> pub{};
75 m_public = std::make_shared<const Ed448_PublicKey_Data>(pub);
80 return {pub.begin(), pub.end()};
88 return std::make_unique<Ed448_PrivateKey>(rng);
94 throw Decoding_Error(
"Unexpected parameters for Ed448 private key");
104 m_public = std::make_shared<const Ed448_PublicKey_Data>(pub);
105 m_private = std::make_shared<const Ed448_PrivateKey_Data>(std::move(bits));
115 std::array<uint8_t, ED448_LEN> pub{};
121 m_public = std::make_shared<const Ed448_PublicKey_Data>(pub);
122 m_private = std::make_shared<const Ed448_PrivateKey_Data>(std::move(sk));
130 const auto& sk = m_private->key();
136 const auto& sk = m_private->key();
141 return public_point ==
m_public->key();
149 virtual void update(std::span<const uint8_t> msg) = 0;
150 virtual std::vector<uint8_t> get_and_clear() = 0;
152 Ed448_Message() =
default;
153 virtual ~Ed448_Message() =
default;
154 Ed448_Message(
const Ed448_Message&) =
delete;
155 Ed448_Message& operator=(
const Ed448_Message&) =
delete;
156 Ed448_Message(Ed448_Message&&) =
delete;
157 Ed448_Message& operator=(Ed448_Message&&) =
delete;
160class Prehashed_Ed448_Message final :
public Ed448_Message {
162 void update(std::span<const uint8_t> msg)
override { m_hash->update(msg); }
164 std::vector<uint8_t> get_and_clear()
override {
return m_hash->final_stdvec(); }
166 explicit Prehashed_Ed448_Message(std::string_view hash) : m_hash(HashFunction::create_or_throw(hash)) {}
169 std::unique_ptr<HashFunction> m_hash;
172class Pure_Ed448_Message final :
public Ed448_Message {
174 void update(std::span<const uint8_t> msg)
override { m_msg.insert(m_msg.end(), msg.begin(), msg.end()); }
176 std::vector<uint8_t> get_and_clear()
override {
return std::exchange(m_msg, {}); }
179 std::vector<uint8_t> m_msg;
187 explicit Ed448_Verify_Operation(std::shared_ptr<const Ed448_PublicKey_Data> public_key,
188 std::optional<std::string> prehash_function = std::nullopt) :
189 m_public_key(std::move(public_key)), m_prehash_function(std::move(prehash_function)) {
190 if(m_prehash_function) {
191 m_message = std::make_unique<Prehashed_Ed448_Message>(*m_prehash_function);
193 m_message = std::make_unique<Pure_Ed448_Message>();
197 void update(std::span<const uint8_t> input)
override { m_message->update(input); }
199 bool is_valid_signature(std::span<const uint8_t> sig)
override {
200 const auto msg = m_message->get_and_clear();
203 std::span(m_public_key->key()).first<
ED448_LEN>(), m_prehash_function.has_value(), {}, sig, msg);
204 }
catch(Decoding_Error&) {
209 std::string hash_function()
const override {
return m_prehash_function.value_or(
"SHAKE-256(912)"); }
212 std::shared_ptr<const Ed448_PublicKey_Data> m_public_key;
213 std::unique_ptr<Ed448_Message> m_message;
214 std::optional<std::string> m_prehash_function;
222 Ed448_Sign_Operation(std::shared_ptr<const Ed448_PublicKey_Data> public_key,
223 std::shared_ptr<const Ed448_PrivateKey_Data> private_key,
224 std::optional<std::string> prehash_function = std::nullopt) :
225 m_public_key(std::move(public_key)),
226 m_private_key(std::move(private_key)),
227 m_prehash_function(std::move(prehash_function)) {
228 if(m_prehash_function) {
229 m_message = std::make_unique<Prehashed_Ed448_Message>(*m_prehash_function);
231 m_message = std::make_unique<Pure_Ed448_Message>();
235 void update(std::span<const uint8_t> input)
override { m_message->update(input); }
237 std::vector<uint8_t> sign(RandomNumberGenerator& )
override {
238 const auto& sk = m_private_key->key();
241 const auto sig =
sign_message(std::span(sk).first<ED448_LEN>(),
242 std::span(m_public_key->key()).first<
ED448_LEN>(),
243 m_prehash_function.has_value(),
245 m_message->get_and_clear());
247 return {sig.begin(), sig.end()};
250 size_t signature_length()
const override {
return 2 *
ED448_LEN; }
252 AlgorithmIdentifier algorithm_identifier()
const override;
254 std::string hash_function()
const override {
return m_prehash_function.value_or(
"SHAKE-256(912)"); }
257 std::shared_ptr<const Ed448_PublicKey_Data> m_public_key;
258 std::shared_ptr<const Ed448_PrivateKey_Data> m_private_key;
259 std::unique_ptr<Ed448_Message> m_message;
260 std::optional<std::string> m_prehash_function;
264 return AlgorithmIdentifier(OID::from_string(
"Ed448"), AlgorithmIdentifier::USE_EMPTY_PARAM);
270 std::string_view provider)
const {
271 if(provider ==
"base" || provider.empty()) {
272 if(params.empty() || params ==
"Identity" || params ==
"Pure" || params ==
"Ed448") {
273 return std::make_unique<Ed448_Verify_Operation>(
m_public);
274 }
else if(params ==
"Ed448ph") {
275 return std::make_unique<Ed448_Verify_Operation>(
m_public,
"SHAKE-256(512)");
277 return std::make_unique<Ed448_Verify_Operation>(
m_public, std::string(params));
284 std::string_view provider)
const {
285 if(provider ==
"base" || provider.empty()) {
287 throw Decoding_Error(
"Unexpected AlgorithmIdentifier for Ed448 X509 signature");
290 return std::make_unique<Ed448_Verify_Operation>(
m_public);
296 std::string_view params,
297 std::string_view provider)
const {
298 if(provider ==
"base" || provider.empty()) {
299 if(params.empty() || params ==
"Identity" || params ==
"Pure" || params ==
"Ed448") {
300 return std::make_unique<Ed448_Sign_Operation>(
m_public, m_private);
301 }
else if(params ==
"Ed448ph") {
302 return std::make_unique<Ed448_Sign_Operation>(
m_public, m_private,
"SHAKE-256(512)");
304 return std::make_unique<Ed448_Sign_Operation>(
m_public, m_private, std::string(params));
#define BOTAN_ASSERT_NOMSG(expr)
bool parameters_are_empty() const
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).
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 > raw_private_key_bits() const override
secure_vector< uint8_t > private_key_bits() const override
std::unique_ptr< Public_Key > public_key() const override
AlgorithmIdentifier algorithm_identifier() const override
std::string algo_name() 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::shared_ptr< const Ed448_PublicKey_Data > m_public
Ed448_PublicKey(const AlgorithmIdentifier &alg_id, std::span< const uint8_t > key_bits)
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
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).
constexpr size_t ED448_LEN
constexpr void copy_mem(T *out, const T *in, size_t n)
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).
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).