mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Changes for secp256k1
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
@@ -98,6 +99,11 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** Print the public key to a stream.
|
||||
*/
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, PublicKey const& pk);
|
||||
|
||||
inline
|
||||
bool
|
||||
operator== (PublicKey const& lhs,
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <ripple/protocol/Seed.h>
|
||||
#include <ripple/protocol/tokens.h>
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -57,6 +58,14 @@ public:
|
||||
{
|
||||
return sizeof(buf_);
|
||||
}
|
||||
|
||||
/** Convert the secret key to a hexadecimal string.
|
||||
|
||||
@note The operator<< function is deliberately omitted
|
||||
to avoid accidental exposure of secret key material.
|
||||
*/
|
||||
std::string
|
||||
to_string() const;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/impl/secp256k1.h>
|
||||
#include <ripple/basics/contract.h>
|
||||
#include <ripple/basics/strHex.h>
|
||||
#include <ripple/beast/core/ByteOrder.h>
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#include <ed25519-donna/ed25519.h>
|
||||
@@ -29,6 +30,13 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, PublicKey const& pk)
|
||||
{
|
||||
os << strHex(pk.data(), pk.size());
|
||||
return os;
|
||||
}
|
||||
|
||||
using uint264 = boost::multiprecision::number<
|
||||
boost::multiprecision::cpp_int_backend<
|
||||
264, 264, boost::multiprecision::signed_magnitude,
|
||||
@@ -219,17 +227,51 @@ verifyDigest (PublicKey const& publicKey,
|
||||
{
|
||||
if (publicKeyType(publicKey) != KeyType::secp256k1)
|
||||
LogicError("sign: secp256k1 required for digest signing");
|
||||
|
||||
auto const canonicality = ecdsaCanonicality(sig);
|
||||
if (! canonicality)
|
||||
return false;
|
||||
if (mustBeFullyCanonical &&
|
||||
(*canonicality != ECDSACanonicality::fullyCanonical))
|
||||
return false;
|
||||
|
||||
secp256k1_pubkey pubkey_imp;
|
||||
if(secp256k1_ec_pubkey_parse(
|
||||
secp256k1Context(),
|
||||
&pubkey_imp,
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
publicKey.data()),
|
||||
publicKey.size()) != 1)
|
||||
return false;
|
||||
|
||||
secp256k1_ecdsa_signature sig_imp;
|
||||
if(secp256k1_ecdsa_signature_parse_der(
|
||||
secp256k1Context(),
|
||||
&sig_imp,
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
sig.data()),
|
||||
sig.size()) != 1)
|
||||
return false;
|
||||
if (*canonicality != ECDSACanonicality::fullyCanonical)
|
||||
{
|
||||
secp256k1_ecdsa_signature sig_norm;
|
||||
if(secp256k1_ecdsa_signature_normalize(
|
||||
secp256k1Context(),
|
||||
&sig_norm,
|
||||
&sig_imp) != 1)
|
||||
return false;
|
||||
return secp256k1_ecdsa_verify(
|
||||
secp256k1Context(),
|
||||
&sig_norm,
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
digest.data()),
|
||||
&pubkey_imp) == 1;
|
||||
}
|
||||
return secp256k1_ecdsa_verify(
|
||||
secp256k1Context(), secpp(digest.data()),
|
||||
secpp(sig.data()), sig.size(),
|
||||
secpp(publicKey.data()), publicKey.size()) == 1;
|
||||
secp256k1Context(),
|
||||
&sig_imp,
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
digest.data()),
|
||||
&pubkey_imp) == 1;
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <BeastConfig.h>
|
||||
#include <ripple/basics/strHex.h>
|
||||
#include <ripple/protocol/SecretKey.h>
|
||||
#include <ripple/protocol/digest.h>
|
||||
#include <ripple/protocol/impl/secp256k1.h>
|
||||
@@ -48,6 +49,12 @@ SecretKey::SecretKey (Slice const& slice)
|
||||
std::memcpy(buf_, slice.data(), sizeof(buf_));
|
||||
}
|
||||
|
||||
std::string
|
||||
SecretKey::to_string() const
|
||||
{
|
||||
return strHex(data(), size());
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Generator::Generator (Seed const& seed)
|
||||
@@ -88,16 +95,29 @@ signDigest (PublicKey const& pk, SecretKey const& sk,
|
||||
if (publicKeyType(pk.slice()) != KeyType::secp256k1)
|
||||
LogicError("sign: secp256k1 required for digest signing");
|
||||
|
||||
int siglen = 72;
|
||||
unsigned char sig[72];
|
||||
auto const result = secp256k1_ecdsa_sign(
|
||||
secp256k1Context(),
|
||||
digest.data(), sig, &siglen,
|
||||
sk.data(), secp256k1_nonce_function_rfc6979,
|
||||
nullptr);
|
||||
if (result != 1)
|
||||
BOOST_ASSERT(sk.size() == 32);
|
||||
secp256k1_ecdsa_signature sig_imp;
|
||||
if(secp256k1_ecdsa_sign(
|
||||
secp256k1Context(),
|
||||
&sig_imp,
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
digest.data()),
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
sk.data()),
|
||||
secp256k1_nonce_function_rfc6979,
|
||||
nullptr) != 1)
|
||||
LogicError("sign: secp256k1_ecdsa_sign failed");
|
||||
return Buffer(sig, siglen);
|
||||
|
||||
unsigned char sig[72];
|
||||
size_t len = sizeof(sig);
|
||||
if(secp256k1_ecdsa_signature_serialize_der(
|
||||
secp256k1Context(),
|
||||
sig,
|
||||
&len,
|
||||
&sig_imp) != 1)
|
||||
LogicError("sign: secp256k1_ecdsa_signature_serialize_der failed");
|
||||
|
||||
return Buffer{sig, len};
|
||||
}
|
||||
|
||||
Buffer
|
||||
@@ -123,16 +143,29 @@ sign (PublicKey const& pk,
|
||||
h(m.data(), m.size());
|
||||
auto const digest =
|
||||
sha512_half_hasher::result_type(h);
|
||||
int siglen = 72;
|
||||
unsigned char sig[72];
|
||||
auto const result = secp256k1_ecdsa_sign(
|
||||
secp256k1Context(),
|
||||
digest.data(), sig, &siglen,
|
||||
sk.data(), secp256k1_nonce_function_rfc6979,
|
||||
nullptr);
|
||||
if (result != 1)
|
||||
|
||||
secp256k1_ecdsa_signature sig_imp;
|
||||
if(secp256k1_ecdsa_sign(
|
||||
secp256k1Context(),
|
||||
&sig_imp,
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
digest.data()),
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
sk.data()),
|
||||
secp256k1_nonce_function_rfc6979,
|
||||
nullptr) != 1)
|
||||
LogicError("sign: secp256k1_ecdsa_sign failed");
|
||||
return Buffer(sig, siglen);
|
||||
|
||||
unsigned char sig[72];
|
||||
size_t len = sizeof(sig);
|
||||
if(secp256k1_ecdsa_signature_serialize_der(
|
||||
secp256k1Context(),
|
||||
sig,
|
||||
&len,
|
||||
&sig_imp) != 1)
|
||||
LogicError("sign: secp256k1_ecdsa_signature_serialize_der failed");
|
||||
|
||||
return Buffer{sig, len};
|
||||
}
|
||||
default:
|
||||
LogicError("sign: invalid type");
|
||||
@@ -184,16 +217,26 @@ derivePublicKey (KeyType type, SecretKey const& sk)
|
||||
{
|
||||
case KeyType::secp256k1:
|
||||
{
|
||||
int len;
|
||||
unsigned char buf[33];
|
||||
auto const result =
|
||||
secp256k1_ec_pubkey_create(
|
||||
secp256k1_pubkey pubkey_imp;
|
||||
if(secp256k1_ec_pubkey_create(
|
||||
secp256k1Context(),
|
||||
buf, &len, sk.data(), 1);
|
||||
if (result != 1)
|
||||
LogicError("derivePublicKey: failure");
|
||||
return PublicKey(Slice{ buf,
|
||||
static_cast<std::size_t>(len) });
|
||||
&pubkey_imp,
|
||||
reinterpret_cast<unsigned char const*>(
|
||||
sk.data())) != 1)
|
||||
LogicError("derivePublicKey: secp256k1_ec_pubkey_create failed");
|
||||
|
||||
unsigned char pubkey[33];
|
||||
size_t len = sizeof(pubkey);
|
||||
if(secp256k1_ec_pubkey_serialize(
|
||||
secp256k1Context(),
|
||||
pubkey,
|
||||
&len,
|
||||
&pubkey_imp,
|
||||
SECP256K1_EC_COMPRESSED) != 1)
|
||||
LogicError("derivePublicKey: secp256k1_ec_pubkey_serialize failed");
|
||||
|
||||
return PublicKey{Slice{pubkey,
|
||||
static_cast<std::size_t>(len)}};
|
||||
}
|
||||
case KeyType::ed25519:
|
||||
{
|
||||
|
||||
@@ -25,15 +25,15 @@
|
||||
namespace ripple {
|
||||
|
||||
template <class = void>
|
||||
secp256k1_context_t const*
|
||||
secp256k1_context const*
|
||||
secp256k1Context()
|
||||
{
|
||||
struct holder
|
||||
{
|
||||
secp256k1_context_t* impl;
|
||||
secp256k1_context* impl;
|
||||
holder()
|
||||
: impl (secp256k1_context_create(
|
||||
SECP256K1_CONTEXT_VERIFY +
|
||||
SECP256K1_CONTEXT_VERIFY |
|
||||
SECP256K1_CONTEXT_SIGN))
|
||||
{
|
||||
}
|
||||
@@ -47,13 +47,6 @@ secp256k1Context()
|
||||
return h.impl;
|
||||
}
|
||||
|
||||
inline
|
||||
unsigned char const*
|
||||
secpp(void const* p)
|
||||
{
|
||||
return static_cast<unsigned char const*>(p);
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user