1#include <test/jtx/TestSuite.h>
3#include <xrpld/rpc/detail/RPCHelpers.h>
4#include <xrpld/rpc/handlers/admin/keygen/WalletPropose.h>
6#include <xrpl/beast/unit_test/suite.h>
7#include <xrpl/json/json_value.h>
8#include <xrpl/json/json_writer.h>
9#include <xrpl/protocol/AccountID.h>
10#include <xrpl/protocol/ErrorCodes.h>
11#include <xrpl/protocol/PublicKey.h>
12#include <xrpl/protocol/jss.h>
13#include <xrpl/protocol/tokens.h>
35static char const*
gMasterKey =
"SCAT BERN ISLE FOR ROIL BUS SOAK AQUA FREE FOR DRAM BRIG";
36static char const*
gMasterSeed =
"snMwVWs2hZzfDUF3p2tHZ3EgmyhFs";
41 .accountId =
"r4Vtj2jrfmTVZGfSP3gH9hQPMqFPQFin8f",
45 .publicKey =
"aBQxK2YFNqzmAaXNczYcjqDjfiKkLsJUizsr1UBf44RCF8FHdrmX",
46 .publicKeyHex =
"038AAE247B2344B1837FBED8F57389C8C11774510A3F7D784F2A09F0CB6843236C",
47 .secretKeyHex =
"1949ECD889EA71324BC7A30C8E81F4E93CB73EE19D59E9082111E78CC3DDABC2",
50 "This wallet was generated using a user-supplied "
51 "passphrase that has low entropy and is vulnerable "
52 "to brute-force attacks.",
56 .accountId =
"r4qV6xTXerqaZav3MJfSY79ynmc1BSBev1",
60 .publicKey =
"aKEQmgLMyZPMruJFejUuedp169LgW6DbJt1rej1DJ5hWUMH4pHJ7",
61 .publicKeyHex =
"ED54C3F5BEDA8BD588B203D23A27398FAD9D20F88A974007D6994659CD7273FE1D",
62 .secretKeyHex =
"77AAED2698D56D6676323629160F4EEF21CFD9EE3D0745CC78FA291461F98278",
65 "This wallet was generated using a user-supplied "
66 "passphrase that has low entropy and is vulnerable "
67 "to brute-force attacks.",
71 .accountId =
"rBcvXmNb7KPkNdMkpckdWPpbvkWgcV3nir",
72 .masterKey =
"TED AVON CAVE HOUR BRAG JEFF RIFT NEAL TOLD FAT SEW SAN",
73 .masterSeed =
"shKdhWka8hS7Es3bpctCZXBiAwfUN",
74 .masterSeedHex =
"74BA8389B44F98CF41E795CD91F9C93F",
75 .publicKey =
"aBRL2sqVuzrsM6zikPB4v8UBHGn1aKkrsxhYEffhcQxB2LKyywE5",
76 .publicKeyHex =
"03BD334FB9E06C58D69603E9922686528B18A754BC2F2E1ADA095FFE67DE952C64",
77 .secretKeyHex =
"84262FB16AA25BE407174C7EDAB531220C30FA4D8A28AA9D564673FB3D34502C",
78 .passphrase =
"A4yKIRGdzrw0YQ$2%TFKYG9HP*&ok^!sy7E@RwICs",
80 "This wallet was generated using a user-supplied "
81 "passphrase. It may be vulnerable to brute-force "
93 params[jss::key_type] = *keyType;
97 BEAST_EXPECT(result.
isMember(jss::account_id));
98 BEAST_EXPECT(result.
isMember(jss::master_seed));
99 BEAST_EXPECT(result.
isMember(jss::master_seed_hex));
100 BEAST_EXPECT(result.
isMember(jss::public_key));
101 BEAST_EXPECT(result.
isMember(jss::public_key_hex));
102 BEAST_EXPECT(result.
isMember(jss::key_type));
105 result[jss::key_type],
106 params.
isMember(jss::key_type) ? params[jss::key_type] :
"secp256k1");
107 BEAST_EXPECT(!result.
isMember(jss::warning));
114 BEAST_EXPECT(result[jss::master_seed].asString() != seed);
129 result[jss::key_type],
130 params.
isMember(jss::key_type) ? params[jss::key_type] :
"secp256k1");
141 params[jss::key_type] = *keyType;
145 BEAST_EXPECT(!wallet.isMember(jss::warning));
155 params[jss::key_type] = *keyType;
159 BEAST_EXPECT(!wallet.isMember(jss::warning));
170 params[jss::key_type] = *keyType;
171 params[jss::passphrase] = value;
180 BEAST_EXPECT(!wallet.isMember(jss::warning));
198 testcase(keyType ? *keyType :
"no key_type");
207 params[jss::key_type] = *keyType;
223 params[jss::key_type] =
"secp256k1";
224 params[jss::passphrase] = 20160506;
227 BEAST_EXPECT(result[jss::error_message] ==
"Invalid field 'passphrase', not string.");
232 params[jss::key_type] =
"secp256k1";
236 BEAST_EXPECT(result[jss::error_message] ==
"Invalid field 'seed', not string.");
241 params[jss::key_type] =
"ed25519";
245 BEAST_EXPECT(result[jss::error_message] ==
"Invalid field 'seed_hex', not string.");
251 params[jss::key_type] =
"secp256k1";
258 result[jss::error_message] ==
259 "Exactly one of the following must be specified: passphrase, "
266 params[jss::key_type] =
"prime256v1";
270 BEAST_EXPECT(result[jss::error_message] ==
"Invalid parameters.");
279 BEAST_EXPECT(result[jss::error_message] ==
"Invalid field 'key_type', not string.");
288 BEAST_EXPECT(result[jss::error_message] ==
"Invalid field 'key_type', not string.");
295 testcase(
"keypairForSignature - " + (keyType ? *keyType :
"no key_type"));
298 BEAST_EXPECT(publicKey);
309 if (BEAST_EXPECT(ret); ret.has_value())
311 BEAST_EXPECT(ret->first.size() != 0);
312 BEAST_EXPECT(ret->first == publicKey);
323 if (BEAST_EXPECT(ret); ret.has_value())
325 BEAST_EXPECT(ret->first.size() != 0);
326 BEAST_EXPECT(ret->first == publicKey);
337 if (BEAST_EXPECT(ret); ret.has_value())
339 BEAST_EXPECT(ret->first.size() != 0);
340 BEAST_EXPECT(ret->first == publicKey);
351 params[jss::key_type] = *keyType;
356 if (BEAST_EXPECT(ret); ret.has_value())
358 BEAST_EXPECT(ret->first.size() != 0);
359 BEAST_EXPECT(ret->first == publicKey);
367 params[jss::key_type] = *keyType;
372 if (BEAST_EXPECT(ret); ret.has_value())
374 BEAST_EXPECT(ret->first.size() != 0);
375 BEAST_EXPECT(ret->first == publicKey);
383 params[jss::key_type] = *keyType;
384 params[jss::passphrase] = strings.
masterKey;
388 if (BEAST_EXPECT(ret); ret.has_value())
390 BEAST_EXPECT(ret->first.size() != 0);
391 BEAST_EXPECT(ret->first == publicKey);
403 params[jss::secret] = 314159265;
407 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'secret', not string.");
414 params[jss::secret].
append(
"array:0");
419 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'secret', not string.");
426 params[jss::secret][
"string"] =
"string";
427 params[jss::secret][
"number"] = 702;
432 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'secret', not string.");
439 params[jss::key_type] =
"ed25519";
446 error[jss::error_message] ==
447 "The secret field is not allowed if key_type is used.");
454 params[jss::key_type] =
"prime256v1";
460 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'key_type'.");
472 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'key_type', not string.");
484 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'key_type', not string.");
491 params[jss::key_type] =
"secp256k1";
492 params[jss::passphrase] = 1234567890;
497 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'passphrase', not string.");
503 params[jss::key_type] =
"secp256k1";
509 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'passphrase', not string.");
515 params[jss::key_type] =
"secp256k1";
521 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'passphrase', not string.");
527 params[jss::key_type] =
"secp256k1";
528 params[jss::passphrase] =
"";
533 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
540 params[jss::key_type] =
"secp256k1";
541 params[jss::seed] = 443556;
546 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'seed', not string.");
552 params[jss::key_type] =
"secp256k1";
558 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'seed', not string.");
564 params[jss::key_type] =
"secp256k1";
570 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'seed', not string.");
576 params[jss::key_type] =
"secp256k1";
577 params[jss::seed] =
"";
582 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
588 params[jss::key_type] =
"secp256k1";
589 params[jss::seed] =
"s M V s h z D F p t Z E m h s";
594 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
600 params[jss::key_type] =
"secp256k1";
601 params[jss::seed] =
"pnnjkbnobnml43679nbvjdsklnbjs";
606 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
613 params[jss::key_type] =
"secp256k1";
614 params[jss::seed_hex] = 443556;
619 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'seed_hex', not string.");
625 params[jss::key_type] =
"secp256k1";
631 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'seed_hex', not string.");
637 params[jss::key_type] =
"secp256k1";
643 BEAST_EXPECT(error[jss::error_message] ==
"Invalid field 'seed_hex', not string.");
649 params[jss::key_type] =
"secp256k1";
650 params[jss::seed_hex] =
"";
655 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
661 params[jss::key_type] =
"secp256k1";
662 params[jss::seed_hex] =
"A670A19B";
667 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
673 params[jss::key_type] =
"secp256k1";
679 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
685 params[jss::key_type] =
"secp256k1";
686 params[jss::seed_hex] =
"BE6A670A19B209E112146D0A7ED2AAD72567D0FC913";
691 BEAST_EXPECT(error[jss::error_message] ==
"Disallowed seed.");
698 testcase(
"XrplLib encoded Ed25519 keys");
700 auto test = [
this](
char const* seed,
char const* addr) {
705 params[jss::passphrase] = seed;
710 if (BEAST_EXPECT(ret); ret.has_value())
712 BEAST_EXPECT(ret->first.size() != 0);
721 params[jss::key_type] =
"secp256k1";
722 params[jss::passphrase] = seed;
728 error[jss::error_message] ==
"Specified seed is for an Ed25519 wallet.");
735 params[jss::key_type] =
"ed25519";
736 params[jss::seed] = seed;
741 if (BEAST_EXPECT(ret); ret.has_value())
743 BEAST_EXPECT(ret->first.size() != 0);
752 params[jss::key_type] =
"secp256k1";
753 params[jss::seed] = seed;
759 error[jss::error_message] ==
"Specified seed is for an Ed25519 wallet.");
763 test(
"sEdVWZmeUDgQdMEFKTK9kYVX71FKB7o",
"r34XnDB2zS11NZ1wKJzpU1mjWExGVugTaQ");
764 test(
"sEd7zJoVnqg1FxB9EuaHC1AB5UPfHWz",
"rDw51qRrBEeMw7Na1Nh79LN7HYZDo7nZFE");
765 test(
"sEdSxVntbihdLyabbfttMCqsaaucVR9",
"rwiyBDfAYegXZyaQcN2L1vAbKRYn2wNFMq");
766 test(
"sEdSVwJjEXTYCztqDK4JD9WByH3otDX",
"rQJ4hZzNGkLQhLtKPCmu1ywEw1ai2vgUJN");
767 test(
"sEdV3jXjKuUoQTSr1Rb4yw8Kyn9r46U",
"rERRw2Pxbau4tevE61V5vZUwD7Rus5Y6vW");
768 test(
"sEdVeUZjuYT47Uy51FQCnzivsuWyiwB",
"rszewT5gRjUgWNEmnfMjvVYzJCkhvWY32i");
769 test(
"sEd7MHTewdw4tFYeS7rk7XT4qHiA9jH",
"rBB2rvnf4ztwjgNhinFXQJ91nAZjkFgR3p");
770 test(
"sEd7A5jFBSdWbNeKGriQvLr1thBScJh",
"rLAXz8Nz7aDivz7PwThsLFqaKrizepNCdA");
771 test(
"sEdVPU9M2uyzVNT4Yb5Dn4tUtYjbFAw",
"rHbHRFPCxD5fnn98TBzsQHJ7SsRq7eHkRj");
772 test(
"sEdVfF2zhAmS8gfMYzJ4yWBMeR4BZKc",
"r9PsneKHcAE7kUfiTixomM5Mnwi28tCc7h");
773 test(
"sEdTjRtcsQkwthDXUSLi9DHNyJcR8GW",
"rM4soF4XS3wZrmLurvE6ZmudG16Lk5Dur5");
774 test(
"sEdVNKeu1Lhpfh7Nf6tRDbxnmMyZ4Dv",
"r4ZwJxq6FDtWjapDtCGhjG6mtNm1nWdJcD");
775 test(
"sEd7bK4gf5BHJ1WbaEWx8pKMA9MLHpC",
"rD6tnn51m4o1uXeEK9CFrZ3HR7DcFhiYnp");
776 test(
"sEd7jCh3ppnQMsLdGcZ6TZayZaHhBLg",
"rTcBkiRQ1EfFQ4FCCwqXNHpn1yUTAACkj");
777 test(
"sEdTFJezurQwSJAbkLygj2gQXBut2wh",
"rnXaMacNbRwcJddbbPbqdcpSUQcfzFmrR8");
778 test(
"sEdSWajfQAAWFuDvVZF3AiGucReByLt",
"rBJtow6V3GTdsWMamrxetRDwWs6wwTxcKa");
TestcaseT testcase
Memberspace for declaring test cases.
Value & append(Value const &value)
Append value to array at the end.
std::string asString() const
Returns the unquoted string value.
bool isMember(char const *key) const
Return true if the object has a member named key.
void testKeypairForSignature(std::optional< std::string > keyType, KeyStrings const &strings)
json::Value testSecretWallet(json::Value const ¶ms, KeyStrings const &s)
void testRandomWallet(std::optional< std::string > const &keyType)
void testKeyType(std::optional< std::string > const &keyType, KeyStrings const &strings)
void testXrplLibEd25519()
void testLegacyPassphrase(char const *value, std::optional< std::string > const &keyType, KeyStrings const &strings)
void run() override
Runs the suite.
void testSeedHex(std::optional< std::string > const &keyType, KeyStrings const &strings)
void testSeed(std::optional< std::string > const &keyType, KeyStrings const &strings)
void testKeypairForSignatureErrors()
void testLegacyPassphrase(std::optional< std::string > const &keyType, KeyStrings const &strings)
bool expectEquals(S actual, T expected, std::string const &message="")
@ Array
array value (ordered list)
@ Object
object value (collection of name/value pairs).
static char const * gMasterKey
static char const * gPassphrase
static char const * gMasterSeedHex
static char const * gMasterSeed
API version numbers used in later API versions.
std::optional< std::pair< PublicKey, SecretKey > > keypairForSignature(json::Value const ¶ms, json::Value &error, unsigned int apiVersion)
Generates a keypair for signature from RPC parameters.
static KeyStrings const kStrongBrainStrings
BEAST_DEFINE_TESTSUITE(AccountLines, rpc, xrpl)
bool containsError(json::Value const &json)
Returns true if the json contains an rpc error specification.
static KeyStrings const kED25519Strings
static KeyStrings const kSecP256K1Strings
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::optional< AccountID > parseBase58(std::string const &s)
Parse AccountID from checked, base58 string.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
json::Value walletPropose(json::Value const ¶ms)
AccountID calcAccountID(PublicKey const &pk)
char const * secretKeyHex
char const * publicKeyHex
char const * passphraseWarning
char const * masterSeedHex