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 ripple {
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) ||
84 parseBase58<PublicKey>(TokenType::NodePublic, str) ||
85 parseBase58<PublicKey>(TokenType::AccountPublic, str) ||
86 parseBase58<SecretKey>(TokenType::NodePrivate, str) ||
87 parseBase58<SecretKey>(TokenType::AccountSecret, str))
88 {
89 return std::nullopt;
90 }
91
92 {
93 uint128 seed;
94
95 if (seed.parseHex(str))
96 return Seed{Slice(seed.data(), seed.size())};
97 }
98
99 if (auto seed = parseBase58<Seed>(str))
100 return seed;
101
102 if (rfc1751)
103 {
104 std::string key;
105 if (RFC1751::getKeyFromEnglish(key, str) == 1)
106 {
107 Blob const blob(key.rbegin(), key.rend());
108 return Seed{uint128{blob}};
109 }
110 }
111
112 return generateSeed(str);
113}
114
116seedAs1751(Seed const& seed)
117{
118 std::string key;
119
120 std::reverse_copy(seed.data(), seed.data() + 16, std::back_inserter(key));
121
122 std::string encodedKey;
123 RFC1751::getEnglishFromKey(encodedKey, key);
124 return encodedKey;
125}
126
127} // namespace ripple
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:477
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:444
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:79
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:62
Integers of any length that is a multiple of 32-bits.
Definition base_uint.h:67
static constexpr std::size_t size()
Definition base_uint.h:507
constexpr bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
Definition base_uint.h:484
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
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
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
std::string seedAs1751(Seed const &seed)
Encode a Seed in RFC1751 format.
Definition Seed.cpp:116
std::string decodeBase58Token(std::string const &s, TokenType type)
Definition tokens.cpp:191
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition tokens.cpp:138
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:225
std::optional< Seed > parseGenericSeed(std::string const &str, bool rfc1751=true)
Attempt to parse a string as a seed.
Definition Seed.cpp:78
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition Seed.cpp:57
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
void secure_erase(void *dest, std::size_t bytes)
Attempts to clear the given blob of memory.
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