11#include <botan/ed25519.h>
12#include <botan/internal/pk_ops_impl.h>
13#include <botan/internal/ed25519_internal.h>
14#include <botan/hash.h>
15#include <botan/ber_dec.h>
16#include <botan/der_enc.h>
35 const uint8_t identity_element[32] = { 1 };
40 const uint8_t modm_m[32] = {
41 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
42 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
46 const unsigned char zero[32] = {0};
48 unsigned char pkcopy[32];
59 if(!
same_mem(result, identity_element, 32))
69 m_public.assign(pub_key, pub_key + pub_len);
73 const std::vector<uint8_t>& key_bits)
88 if(secret_key.size() == 64)
90 m_private = secret_key;
91 m_public.assign(m_private.begin() + 32, m_private.end());
93 else if(secret_key.size() == 32)
107 m_private.resize(64);
117 if(bits.size() != 32)
120 m_private.resize(64);
148 explicit Ed25519_Pure_Verify_Operation(
const Ed25519_PublicKey& key) : m_key(key)
152 void update(
const uint8_t msg[],
size_t msg_len)
override
154 m_msg.insert(m_msg.end(), msg, msg + msg_len);
157 bool is_valid_signature(
const uint8_t sig[],
size_t sig_len)
override
162 const std::vector<uint8_t>& pub_key = m_key.get_public_key();
164 const bool ok =
ed25519_verify(m_msg.data(), m_msg.size(), sig, pub_key.data(),
nullptr, 0);
170 std::vector<uint8_t> m_msg;
171 const Ed25519_PublicKey& m_key;
177class Ed25519_Hashed_Verify_Operation
final :
public PK_Ops::Verification
180 Ed25519_Hashed_Verify_Operation(
const Ed25519_PublicKey& key,
const std::string&
hash,
bool rfc8032) :
188 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
189 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
194 void update(
const uint8_t msg[],
size_t msg_len)
override
196 m_hash->update(msg, msg_len);
199 bool is_valid_signature(
const uint8_t sig[],
size_t sig_len)
override
203 std::vector<uint8_t> msg_hash(m_hash->output_length());
204 m_hash->final(msg_hash.data());
206 const std::vector<uint8_t>& pub_key = m_key.get_public_key();
208 return ed25519_verify(msg_hash.data(), msg_hash.size(), sig, pub_key.data(), m_domain_sep.data(), m_domain_sep.size());
212 std::unique_ptr<HashFunction> m_hash;
213 const Ed25519_PublicKey& m_key;
214 std::vector<uint8_t> m_domain_sep;
220class Ed25519_Pure_Sign_Operation
final :
public PK_Ops::Signature
223 explicit Ed25519_Pure_Sign_Operation(
const Ed25519_PrivateKey& key) : m_key(key)
227 void update(
const uint8_t msg[],
size_t msg_len)
override
229 m_msg.insert(m_msg.end(), msg, msg + msg_len);
232 secure_vector<uint8_t> sign(RandomNumberGenerator& )
override
234 secure_vector<uint8_t> sig(64);
235 ed25519_sign(sig.data(), m_msg.data(), m_msg.size(), m_key.get_private_key().data(),
nullptr, 0);
240 size_t signature_length()
const override {
return 64; }
243 std::vector<uint8_t> m_msg;
244 const Ed25519_PrivateKey& m_key;
250class Ed25519_Hashed_Sign_Operation
final :
public PK_Ops::Signature
253 Ed25519_Hashed_Sign_Operation(
const Ed25519_PrivateKey& key,
const std::string&
hash,
bool rfc8032) :
260 m_domain_sep = std::vector<uint8_t>{
261 0x53, 0x69, 0x67, 0x45, 0x64, 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x6E, 0x6F, 0x20, 0x45, 0x64,
262 0x32, 0x35, 0x35, 0x31, 0x39, 0x20, 0x63, 0x6F, 0x6C, 0x6C, 0x69, 0x73, 0x69, 0x6F, 0x6E, 0x73,
267 size_t signature_length()
const override {
return 64; }
269 void update(
const uint8_t msg[],
size_t msg_len)
override
271 m_hash->update(msg, msg_len);
274 secure_vector<uint8_t> sign(RandomNumberGenerator& )
override
276 secure_vector<uint8_t> sig(64);
277 std::vector<uint8_t> msg_hash(m_hash->output_length());
278 m_hash->final(msg_hash.data());
280 msg_hash.data(), msg_hash.size(),
281 m_key.get_private_key().data(),
282 m_domain_sep.data(), m_domain_sep.size());
287 std::unique_ptr<HashFunction> m_hash;
288 const Ed25519_PrivateKey& m_key;
289 std::vector<uint8_t> m_domain_sep;
294std::unique_ptr<PK_Ops::Verification>
296 const std::string& provider)
const
298 if(provider ==
"base" || provider.empty())
300 if(params.empty() || params ==
"Identity" || params ==
"Pure")
301 return std::make_unique<Ed25519_Pure_Verify_Operation>(*
this);
302 else if(params ==
"Ed25519ph")
303 return std::make_unique<Ed25519_Hashed_Verify_Operation>(*
this,
"SHA-512",
true);
305 return std::make_unique<Ed25519_Hashed_Verify_Operation>(*
this, params,
false);
310std::unique_ptr<PK_Ops::Signature>
312 const std::string& params,
313 const std::string& provider)
const
315 if(provider ==
"base" || provider.empty())
317 if(params.empty() || params ==
"Identity" || params ==
"Pure")
318 return std::make_unique<Ed25519_Pure_Sign_Operation>(*
this);
319 else if(params ==
"Ed25519ph")
320 return std::make_unique<Ed25519_Hashed_Sign_Operation>(*
this,
"SHA-512",
true);
322 return std::make_unique<Ed25519_Hashed_Sign_Operation>(*
this, params,
false);
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
BER_Decoder & decode(bool &out)
BER_Decoder & discard_remaining()
secure_vector< uint8_t > get_contents()
DER_Encoder & encode(bool b)
std::unique_ptr< PK_Ops::Signature > create_signature_op(RandomNumberGenerator &rng, const std::string ¶ms, const std::string &provider) const override
std::unique_ptr< Public_Key > public_key() const override
Ed25519_PrivateKey(const AlgorithmIdentifier &alg_id, const secure_vector< uint8_t > &key_bits)
bool check_key(RandomNumberGenerator &rng, bool strong) const override
secure_vector< uint8_t > private_key_bits() const override
std::vector< uint8_t > m_public
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< PK_Ops::Verification > create_verification_op(const std::string ¶ms, const std::string &provider) const override
Ed25519_PublicKey()=default
std::vector< uint8_t > public_key_bits() const override
AlgorithmIdentifier algorithm_identifier() const override
static std::unique_ptr< HashFunction > create_or_throw(const std::string &algo_spec, const std::string &provider="")
virtual OID get_oid() const
secure_vector< uint8_t > random_vec(size_t bytes)
int(* update)(CTX *, const void *, CC_LONG len)
int(* final)(unsigned char *, CTX *)
int ge_frombytes_negate_vartime(ge_p3 *v, const uint8_t *)
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)
void ed25519_gen_keypair(uint8_t *pk, uint8_t *sk, const uint8_t seed[32])
constexpr void copy_mem(T *out, const T *in, size_t n)
bool same_mem(const T *p1, const T *p2, size_t n)
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)
std::vector< T, secure_allocator< T > > secure_vector
void ge_double_scalarmult_vartime(uint8_t out[32], const uint8_t a[], const ge_p3 *A, const uint8_t b[])