rippled
Loading...
Searching...
No Matches
Seed.cpp
1#include <xrpl/basics/Blob.h>
2#include <xrpl/basics/Slice.h>
3#include <xrpl/basics/base_uint.h>
4#include <xrpl/basics/contract.h>
5#include <xrpl/beast/utility/rngfill.h>
6#include <xrpl/crypto/RFC1751.h>
7#include <xrpl/crypto/csprng.h>
8#include <xrpl/crypto/secure_erase.h>
9#include <xrpl/protocol/AccountID.h>
10#include <xrpl/protocol/PublicKey.h>
11#include <xrpl/protocol/SecretKey.h>
12#include <xrpl/protocol/Seed.h>
13#include <xrpl/protocol/digest.h>
14#include <xrpl/protocol/tokens.h>
15
16#include <algorithm>
17#include <array>
18#include <cstdint>
19#include <cstring>
20#include <iterator>
21#include <optional>
22
23namespace xrpl {
24
29
30Seed::Seed(Slice const& slice)
31{
32 if (slice.size() != buf_.size())
33 LogicError("Seed::Seed: invalid size");
34 std::memcpy(buf_.data(), slice.data(), buf_.size());
35}
36
37Seed::Seed(uint128 const& seed)
38{
39 if (seed.size() != buf_.size())
40 LogicError("Seed::Seed: invalid size");
41 std::memcpy(buf_.data(), seed.data(), buf_.size());
42}
43
44//------------------------------------------------------------------------------
45
46Seed
48{
50 beast::rngfill(buffer.data(), buffer.size(), crypto_prng());
51 Seed seed(makeSlice(buffer));
52 secure_erase(buffer.data(), buffer.size());
53 return seed;
54}
55
56Seed
57generateSeed(std::string const& passPhrase)
58{
60 h(passPhrase.data(), passPhrase.size());
62 return Seed({digest.data(), 16});
63}
64
65template <>
68{
69 auto const result = decodeBase58Token(s, TokenType::FamilySeed);
70 if (result.empty())
71 return std::nullopt;
72 if (result.size() != 16)
73 return std::nullopt;
74 return Seed(makeSlice(result));
75}
76
78parseGenericSeed(std::string const& str, bool rfc1751)
79{
80 if (str.empty())
81 return std::nullopt;
82
83 if (parseBase58<AccountID>(str) || parseBase58<PublicKey>(TokenType::NodePublic, str) ||
84 parseBase58<PublicKey>(TokenType::AccountPublic, str) || parseBase58<SecretKey>(TokenType::NodePrivate, str) ||
85 parseBase58<SecretKey>(TokenType::AccountSecret, str))
86 {
87 return std::nullopt;
88 }
89
90 {
91 uint128 seed;
92
93 if (seed.parseHex(str))
94 return Seed{Slice(seed.data(), seed.size())};
95 }
96
97 if (auto seed = parseBase58<Seed>(str))
98 return seed;
99
100 if (rfc1751)
101 {
102 std::string key;
103 if (RFC1751::getKeyFromEnglish(key, str) == 1)
104 {
105 Blob const blob(key.rbegin(), key.rend());
106 return Seed{uint128{blob}};
107 }
108 }
109
110 return generateSeed(str);
111}
112
114seedAs1751(Seed const& seed)
115{
116 std::string key;
117
118 std::reverse_copy(seed.data(), seed.data() + 16, std::back_inserter(key));
119
120 std::string encodedKey;
121 RFC1751::getEnglishFromKey(encodedKey, key);
122 return encodedKey;
123}
124
125} // namespace xrpl
T back_inserter(T... args)
static void getEnglishFromKey(std::string &strHuman, std::string const &strKey)
Convert to human from a 128 bit key in big-endian format.
Definition RFC1751.cpp:385
static int getKeyFromEnglish(std::string &strKey, std::string const &strHuman)
Convert words separated by spaces into a 128 bit key in big-endian format.
Definition RFC1751.cpp:356
Seeds are used to generate deterministic secret keys.
Definition Seed.h:15
Seed()=delete
std::array< uint8_t, 16 > buf_
Definition Seed.h:17
~Seed()
Destroy the seed.
Definition Seed.cpp:25
std::uint8_t const * data() const
Definition Seed.h:40
An immutable linear range of bytes.
Definition Slice.h:27
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:78
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:61
Integers of any length that is a multiple of 32-bits.
Definition base_uint.h:67
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:472
pointer data()
Definition base_uint.h:102
static constexpr std::size_t size()
Definition base_uint.h:495
T data(T... args)
T empty(T... args)
T is_same_v
T memcpy(T... args)
void rngfill(void *const buffer, std::size_t const bytes, Generator &g)
Definition rngfill.h:15
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition tokens.cpp:137
std::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
Seed randomSeed()
Create a seed using secure random numbers.
Definition Seed.cpp:47
void secure_erase(void *dest, std::size_t bytes)
Attempts to clear the given blob of memory.
std::string seedAs1751(Seed const &seed)
Encode a Seed in RFC1751 format.
Definition Seed.cpp:114
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition Seed.cpp:57
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:214
std::string decodeBase58Token(std::string const &s, TokenType type)
Definition tokens.cpp:186
std::optional< Seed > parseGenericSeed(std::string const &str, bool rfc1751=true)
Attempt to parse a string as a seed.
Definition Seed.cpp:78
T rbegin(T... args)
T rend(T... args)
T reverse_copy(T... args)
T size(T... args)
Returns the SHA512-Half digest of a message.
Definition digest.h:153