1#include <xrpl/protocol/PublicKey.h>
3#include <xrpl/basics/Slice.h>
4#include <xrpl/basics/base_uint.h>
5#include <xrpl/basics/contract.h>
6#include <xrpl/basics/strHex.h>
7#include <xrpl/protocol/KeyType.h>
8#include <xrpl/protocol/Protocol.h>
9#include <xrpl/protocol/UintTypes.h>
10#include <xrpl/protocol/detail/secp256k1.h>
11#include <xrpl/protocol/digest.h>
12#include <xrpl/protocol/tokens.h>
14#include <boost/multiprecision/number.hpp>
53 if (buf.
size() < 3 || buf[0] != 0x02)
55 auto const len = buf[1];
57 if (len > buf.
size() || len < 1 || len > 33)
60 if ((buf[0] & 0x80) != 0)
68 if ((buf[1] & 0x80) == 0)
80 if ((slice[0] & 0x80) != 0)
90 for (
int i = 0; i < slice.
size(); ++i)
92 static constexpr char kHex[] =
"0123456789ABCDEF";
93 s += kHex[((slice[i] & 0xf0) >> 4)];
94 s += kHex[((slice[i] & 0x0f) >> 0)];
114 using uint264 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<
117 boost::multiprecision::signed_magnitude,
118 boost::multiprecision::unchecked,
121 static uint264
const kG(
122 "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
126 if ((sig.
size() < 8) || (sig.
size() > 72))
128 if ((sig[0] != 0x30) || (sig[1] != (sig.
size() - 2)))
133 if (!r || !s || !p.
empty())
146 auto const Sp = kG - sNum;
155 if (sig.
size() != 64)
160 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xDE, 0xF9, 0xDE, 0xA2, 0xF7,
162 0x9C, 0xD6, 0x58, 0x12, 0x63, 0x1A, 0x5C, 0xF5, 0xD3, 0xED,
166 auto const le = sig.
data() + 32;
180 "PublicKey::PublicKey - Input slice cannot be an undersized "
185 logicError(
"PublicKey::PublicKey invalid type");
210 if (slice.
size() == 33)
212 if (slice[0] == 0xED)
227 bool mustBeFullyCanonical)
noexcept
230 logicError(
"sign: secp256k1 required for digest signing");
237 secp256k1_pubkey pubkeyImp;
238 if (secp256k1_ec_pubkey_parse(
241 reinterpret_cast<unsigned char const*
>(publicKey.data()),
242 publicKey.size()) != 1)
245 secp256k1_ecdsa_signature sigImp;
246 if (secp256k1_ecdsa_signature_parse_der(
249 reinterpret_cast<unsigned char const*
>(sig.data()),
254 secp256k1_ecdsa_signature sigNorm;
255 if (secp256k1_ecdsa_signature_normalize(
secp256k1Context(), &sigNorm, &sigImp) != 1)
257 return secp256k1_ecdsa_verify(
260 reinterpret_cast<unsigned char const*
>(
digest.data()),
263 return secp256k1_ecdsa_verify(
266 reinterpret_cast<unsigned char const*
>(
digest.data()),
288 return ed25519_sign_open(m.data(), m.size(), publicKey.data() + 1, sig.data()) == 0;
static BaseUInt fromRaw(Container const &c)
static constexpr std::size_t kBytes
std::uint8_t const * data() const noexcept
static std::size_t size() noexcept
static constexpr std::size_t kSize
Slice slice() const noexcept
PublicKey & operator=(PublicKey const &other)
An immutable linear range of bytes.
bool empty() const noexcept
Return true if the byte range is empty.
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
std::size_t size() const noexcept
Returns the number of bytes in the storage.
T lexicographical_compare(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::uint8_t kEcCompressedPrefixEvenY
Compressed EC point prefix for even y-coordinate.
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
static bool ed25519Canonical(Slice const &sig)
bool verifyDigest(PublicKey const &publicKey, uint256 const &digest, Slice const &sig, bool mustBeFullyCanonical=true) noexcept
Verify a secp256k1 signature on the digest of a message.
sha512_half_hasher::result_type sha512Half(Args const &... args)
Returns the SHA512-Half of a series of objects.
std::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
std::string strHex(FwdIt begin, FwdIt end)
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig) noexcept
Verify a signature on a message.
constexpr std::uint8_t kEcCompressedPrefixOddY
Compressed EC point prefix for odd y-coordinate.
std::optional< ECDSACanonicality > ecdsaCanonicality(Slice const &sig)
Determines the canonicality of a signature.
std::ostream & operator<<(std::ostream &out, BaseUInt< Bits, Tag > const &u)
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
NodeID calcNodeID(PublicKey const &)
Calculate the 160-bit node ID from a node public key.
static std::optional< Slice > sigPart(Slice &buf)
secp256k1_context const * secp256k1Context()
static std::string sliceToHex(Slice const &slice)
std::string decodeBase58Token(std::string const &s, TokenType type)
std::enable_if_t< std::is_same_v< T, char >||std::is_same_v< T, unsigned char >, Slice > makeSlice(std::array< T, N > const &a)
BaseUInt< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
T reverse_copy(T... args)
Returns the RIPEMD-160 digest of the SHA256 hash of the message.
std::array< std::uint8_t, 20 > result_type