xrpld
Loading...
Searching...
No Matches
KeyGeneration_test.cpp
1#include <test/jtx/TestSuite.h>
2
3#include <xrpld/rpc/detail/RPCHelpers.h>
4#include <xrpld/rpc/handlers/admin/keygen/WalletPropose.h>
5
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>
14
15#include <optional>
16#include <string>
17
18namespace xrpl::RPC {
19
21{
22 char const* accountId;
23 char const* masterKey;
24 char const* masterSeed;
25 char const* masterSeedHex;
26 char const* publicKey;
27 char const* publicKeyHex;
28 char const* secretKeyHex;
29 char const* passphrase;
30 char const* passphraseWarning;
31};
32
33namespace common {
34static char const* gPassphrase = "REINDEER FLOTILLA";
35static char const* gMasterKey = "SCAT BERN ISLE FOR ROIL BUS SOAK AQUA FREE FOR DRAM BRIG";
36static char const* gMasterSeed = "snMwVWs2hZzfDUF3p2tHZ3EgmyhFs";
37static char const* gMasterSeedHex = "BE6A670A19B209E112146D0A7ED2AAD7";
38} // namespace common
39
41 .accountId = "r4Vtj2jrfmTVZGfSP3gH9hQPMqFPQFin8f",
42 .masterKey = common::gMasterKey,
43 .masterSeed = common::gMasterSeed,
44 .masterSeedHex = common::gMasterSeedHex,
45 .publicKey = "aBQxK2YFNqzmAaXNczYcjqDjfiKkLsJUizsr1UBf44RCF8FHdrmX",
46 .publicKeyHex = "038AAE247B2344B1837FBED8F57389C8C11774510A3F7D784F2A09F0CB6843236C",
47 .secretKeyHex = "1949ECD889EA71324BC7A30C8E81F4E93CB73EE19D59E9082111E78CC3DDABC2",
48 .passphrase = common::gPassphrase,
49 .passphraseWarning =
50 "This wallet was generated using a user-supplied "
51 "passphrase that has low entropy and is vulnerable "
52 "to brute-force attacks.",
53};
54
56 .accountId = "r4qV6xTXerqaZav3MJfSY79ynmc1BSBev1",
57 .masterKey = common::gMasterKey,
58 .masterSeed = common::gMasterSeed,
59 .masterSeedHex = common::gMasterSeedHex,
60 .publicKey = "aKEQmgLMyZPMruJFejUuedp169LgW6DbJt1rej1DJ5hWUMH4pHJ7",
61 .publicKeyHex = "ED54C3F5BEDA8BD588B203D23A27398FAD9D20F88A974007D6994659CD7273FE1D",
62 .secretKeyHex = "77AAED2698D56D6676323629160F4EEF21CFD9EE3D0745CC78FA291461F98278",
63 .passphrase = common::gPassphrase,
64 .passphraseWarning =
65 "This wallet was generated using a user-supplied "
66 "passphrase that has low entropy and is vulnerable "
67 "to brute-force attacks.",
68};
69
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",
79 .passphraseWarning =
80 "This wallet was generated using a user-supplied "
81 "passphrase. It may be vulnerable to brute-force "
82 "attacks.",
83};
84
86{
87public:
88 void
90 {
91 json::Value params;
92 if (keyType)
93 params[jss::key_type] = *keyType;
94 json::Value result = walletPropose(params);
95
96 BEAST_EXPECT(!containsError(result));
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));
103
105 result[jss::key_type],
106 params.isMember(jss::key_type) ? params[jss::key_type] : "secp256k1");
107 BEAST_EXPECT(!result.isMember(jss::warning));
108
109 std::string const seed = result[jss::master_seed].asString();
110
111 result = walletPropose(params);
112
113 // We asked for two random seeds, so they shouldn't match.
114 BEAST_EXPECT(result[jss::master_seed].asString() != seed);
115 }
116
118 testSecretWallet(json::Value const& params, KeyStrings const& s)
119 {
120 json::Value result = walletPropose(params);
121
122 BEAST_EXPECT(!containsError(result));
123 expectEquals(result[jss::account_id], s.accountId);
124 expectEquals(result[jss::master_seed], s.masterSeed);
125 expectEquals(result[jss::master_seed_hex], s.masterSeedHex);
126 expectEquals(result[jss::public_key], s.publicKey);
127 expectEquals(result[jss::public_key_hex], s.publicKeyHex);
129 result[jss::key_type],
130 params.isMember(jss::key_type) ? params[jss::key_type] : "secp256k1");
131 return result;
132 }
133
134 void
135 testSeed(std::optional<std::string> const& keyType, KeyStrings const& strings)
136 {
137 testcase("seed");
138
139 json::Value params;
140 if (keyType)
141 params[jss::key_type] = *keyType;
142 params[jss::seed] = strings.masterSeed;
143
144 auto const wallet = testSecretWallet(params, strings);
145 BEAST_EXPECT(!wallet.isMember(jss::warning));
146 }
147
148 void
149 testSeedHex(std::optional<std::string> const& keyType, KeyStrings const& strings)
150 {
151 testcase("seed_hex");
152
153 json::Value params;
154 if (keyType)
155 params[jss::key_type] = *keyType;
156 params[jss::seed_hex] = strings.masterSeedHex;
157
158 auto const wallet = testSecretWallet(params, strings);
159 BEAST_EXPECT(!wallet.isMember(jss::warning));
160 }
161
162 void
164 char const* value,
165 std::optional<std::string> const& keyType,
166 KeyStrings const& strings)
167 {
168 json::Value params;
169 if (keyType)
170 params[jss::key_type] = *keyType;
171 params[jss::passphrase] = value;
172
173 auto const wallet = testSecretWallet(params, strings);
174 if (value == strings.passphrase)
175 {
176 BEAST_EXPECT(wallet[jss::warning] == strings.passphraseWarning);
177 }
178 else
179 {
180 BEAST_EXPECT(!wallet.isMember(jss::warning));
181 }
182 }
183
184 void
186 {
187 testcase("passphrase");
188
189 testLegacyPassphrase(strings.passphrase, keyType, strings);
190 testLegacyPassphrase(strings.masterKey, keyType, strings);
191 testLegacyPassphrase(strings.masterSeed, keyType, strings);
192 testLegacyPassphrase(strings.masterSeedHex, keyType, strings);
193 }
194
195 void
196 testKeyType(std::optional<std::string> const& keyType, KeyStrings const& strings)
197 {
198 testcase(keyType ? *keyType : "no key_type");
199
200 testRandomWallet(keyType);
201 testSeed(keyType, strings);
202 testSeedHex(keyType, strings);
203 testLegacyPassphrase(keyType, strings);
204
205 json::Value params;
206 if (keyType)
207 params[jss::key_type] = *keyType;
208 params[jss::seed] = strings.masterSeed;
209 params[jss::seed_hex] = strings.masterSeedHex;
210
211 // Secret fields are mutually exclusive.
212 BEAST_EXPECT(containsError(walletPropose(params)));
213 }
214
215 void
217 {
218 testcase("Bad inputs");
219
220 // Passing non-strings where strings are required
221 {
222 json::Value params;
223 params[jss::key_type] = "secp256k1";
224 params[jss::passphrase] = 20160506;
225 auto result = walletPropose(params);
226 BEAST_EXPECT(containsError(result));
227 BEAST_EXPECT(result[jss::error_message] == "Invalid field 'passphrase', not string.");
228 }
229
230 {
231 json::Value params;
232 params[jss::key_type] = "secp256k1";
233 params[jss::seed] = json::ValueType::Object;
234 auto result = walletPropose(params);
235 BEAST_EXPECT(containsError(result));
236 BEAST_EXPECT(result[jss::error_message] == "Invalid field 'seed', not string.");
237 }
238
239 {
240 json::Value params;
241 params[jss::key_type] = "ed25519";
242 params[jss::seed_hex] = json::ValueType::Array;
243 auto result = walletPropose(params);
244 BEAST_EXPECT(containsError(result));
245 BEAST_EXPECT(result[jss::error_message] == "Invalid field 'seed_hex', not string.");
246 }
247
248 // Specifying multiple items at once
249 {
250 json::Value params;
251 params[jss::key_type] = "secp256k1";
252 params[jss::passphrase] = common::gMasterKey;
253 params[jss::seed_hex] = common::gMasterSeedHex;
254 params[jss::seed] = common::gMasterSeed;
255 auto result = walletPropose(params);
256 BEAST_EXPECT(containsError(result));
257 BEAST_EXPECT(
258 result[jss::error_message] ==
259 "Exactly one of the following must be specified: passphrase, "
260 "seed or seed_hex");
261 }
262
263 // Specifying bad key types:
264 {
265 json::Value params;
266 params[jss::key_type] = "prime256v1";
267 params[jss::passphrase] = common::gMasterKey;
268 auto result = walletPropose(params);
269 BEAST_EXPECT(containsError(result));
270 BEAST_EXPECT(result[jss::error_message] == "Invalid parameters.");
271 }
272
273 {
274 json::Value params;
275 params[jss::key_type] = json::ValueType::Object;
276 params[jss::seed_hex] = common::gMasterSeedHex;
277 auto result = walletPropose(params);
278 BEAST_EXPECT(containsError(result));
279 BEAST_EXPECT(result[jss::error_message] == "Invalid field 'key_type', not string.");
280 }
281
282 {
283 json::Value params;
284 params[jss::key_type] = json::ValueType::Array;
285 params[jss::seed] = common::gMasterSeed;
286 auto result = walletPropose(params);
287 BEAST_EXPECT(containsError(result));
288 BEAST_EXPECT(result[jss::error_message] == "Invalid field 'key_type', not string.");
289 }
290 }
291
292 void
294 {
295 testcase("keypairForSignature - " + (keyType ? *keyType : "no key_type"));
296
297 auto const publicKey = parseBase58<PublicKey>(TokenType::AccountPublic, strings.publicKey);
298 BEAST_EXPECT(publicKey);
299
300 if (!keyType)
301 {
302 {
303 json::Value params;
304 json::Value error;
305 params[jss::secret] = strings.masterSeed;
306
307 auto ret = keypairForSignature(params, error);
308 BEAST_EXPECT(!containsError(error));
309 if (BEAST_EXPECT(ret); ret.has_value())
310 {
311 BEAST_EXPECT(ret->first.size() != 0);
312 BEAST_EXPECT(ret->first == publicKey);
313 }
314 }
315
316 {
317 json::Value params;
318 json::Value error;
319 params[jss::secret] = strings.masterSeedHex;
320
321 auto ret = keypairForSignature(params, error);
322 BEAST_EXPECT(!containsError(error));
323 if (BEAST_EXPECT(ret); ret.has_value())
324 {
325 BEAST_EXPECT(ret->first.size() != 0);
326 BEAST_EXPECT(ret->first == publicKey);
327 }
328 }
329
330 {
331 json::Value params;
332 json::Value error;
333 params[jss::secret] = strings.masterKey;
334
335 auto ret = keypairForSignature(params, error);
336 BEAST_EXPECT(!containsError(error));
337 if (BEAST_EXPECT(ret); ret.has_value())
338 {
339 BEAST_EXPECT(ret->first.size() != 0);
340 BEAST_EXPECT(ret->first == publicKey);
341 }
342 }
343
344 keyType.emplace("secp256k1");
345 }
346
347 {
348 json::Value params;
349 json::Value error;
350
351 params[jss::key_type] = *keyType;
352 params[jss::seed] = strings.masterSeed;
353
354 auto ret = keypairForSignature(params, error);
355 BEAST_EXPECT(!containsError(error));
356 if (BEAST_EXPECT(ret); ret.has_value())
357 {
358 BEAST_EXPECT(ret->first.size() != 0);
359 BEAST_EXPECT(ret->first == publicKey);
360 }
361 }
362
363 {
364 json::Value params;
365 json::Value error;
366
367 params[jss::key_type] = *keyType;
368 params[jss::seed_hex] = strings.masterSeedHex;
369
370 auto ret = keypairForSignature(params, error);
371 BEAST_EXPECT(!containsError(error));
372 if (BEAST_EXPECT(ret); ret.has_value())
373 {
374 BEAST_EXPECT(ret->first.size() != 0);
375 BEAST_EXPECT(ret->first == publicKey);
376 }
377 }
378
379 {
380 json::Value params;
381 json::Value error;
382
383 params[jss::key_type] = *keyType;
384 params[jss::passphrase] = strings.masterKey;
385
386 auto ret = keypairForSignature(params, error);
387 BEAST_EXPECT(!containsError(error));
388 if (BEAST_EXPECT(ret); ret.has_value())
389 {
390 BEAST_EXPECT(ret->first.size() != 0);
391 BEAST_EXPECT(ret->first == publicKey);
392 }
393 }
394 }
395
396 void
398 {
399 // Specify invalid "secret"
400 {
401 json::Value params;
402 json::Value error;
403 params[jss::secret] = 314159265;
404 auto ret = keypairForSignature(params, error);
405 BEAST_EXPECT(containsError(error));
406 BEAST_EXPECT(!ret);
407 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'secret', not string.");
408 }
409
410 {
411 json::Value params;
412 json::Value error;
413 params[jss::secret] = json::ValueType::Array;
414 params[jss::secret].append("array:0");
415
416 auto ret = keypairForSignature(params, error);
417 BEAST_EXPECT(containsError(error));
418 BEAST_EXPECT(!ret);
419 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'secret', not string.");
420 }
421
422 {
423 json::Value params;
424 json::Value error;
425 params[jss::secret] = json::ValueType::Object;
426 params[jss::secret]["string"] = "string";
427 params[jss::secret]["number"] = 702;
428
429 auto ret = keypairForSignature(params, error);
430 BEAST_EXPECT(containsError(error));
431 BEAST_EXPECT(!ret);
432 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'secret', not string.");
433 }
434
435 // Specify "secret" and "key_type"
436 {
437 json::Value params;
438 json::Value error;
439 params[jss::key_type] = "ed25519";
440 params[jss::secret] = common::gMasterSeed;
441
442 auto ret = keypairForSignature(params, error);
443 BEAST_EXPECT(containsError(error));
444 BEAST_EXPECT(!ret);
445 BEAST_EXPECT(
446 error[jss::error_message] ==
447 "The secret field is not allowed if key_type is used.");
448 }
449
450 // Specify unknown or bad "key_type"
451 {
452 json::Value params;
453 json::Value error;
454 params[jss::key_type] = "prime256v1";
455 params[jss::passphrase] = common::gMasterKey;
456
457 auto ret = keypairForSignature(params, error);
458 BEAST_EXPECT(containsError(error));
459 BEAST_EXPECT(!ret);
460 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'key_type'.");
461 }
462
463 {
464 json::Value params;
465 json::Value error;
466 params[jss::key_type] = json::ValueType::Object;
467 params[jss::seed_hex] = common::gMasterSeedHex;
468
469 auto ret = keypairForSignature(params, error);
470 BEAST_EXPECT(containsError(error));
471 BEAST_EXPECT(!ret);
472 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'key_type', not string.");
473 }
474
475 {
476 json::Value params;
477 json::Value error;
478 params[jss::key_type] = json::ValueType::Array;
479 params[jss::seed] = common::gMasterSeed;
480
481 auto ret = keypairForSignature(params, error);
482 BEAST_EXPECT(containsError(error));
483 BEAST_EXPECT(!ret);
484 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'key_type', not string.");
485 }
486
487 // Specify non-string passphrase
488 { // not a passphrase: number
489 json::Value params;
490 json::Value error;
491 params[jss::key_type] = "secp256k1";
492 params[jss::passphrase] = 1234567890;
493
494 auto ret = keypairForSignature(params, error);
495 BEAST_EXPECT(containsError(error));
496 BEAST_EXPECT(!ret);
497 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'passphrase', not string.");
498 }
499
500 { // not a passphrase: object
501 json::Value params;
502 json::Value error;
503 params[jss::key_type] = "secp256k1";
504 params[jss::passphrase] = json::ValueType::Object;
505
506 auto ret = keypairForSignature(params, error);
507 BEAST_EXPECT(containsError(error));
508 BEAST_EXPECT(!ret);
509 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'passphrase', not string.");
510 }
511
512 { // not a passphrase: array
513 json::Value params;
514 json::Value error;
515 params[jss::key_type] = "secp256k1";
516 params[jss::passphrase] = json::ValueType::Array;
517
518 auto ret = keypairForSignature(params, error);
519 BEAST_EXPECT(containsError(error));
520 BEAST_EXPECT(!ret);
521 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'passphrase', not string.");
522 }
523
524 { // not a passphrase: empty string
525 json::Value params;
526 json::Value error;
527 params[jss::key_type] = "secp256k1";
528 params[jss::passphrase] = "";
529
530 auto ret = keypairForSignature(params, error);
531 BEAST_EXPECT(containsError(error));
532 BEAST_EXPECT(!ret);
533 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
534 }
535
536 // Specify non-string or invalid seed
537 { // not a seed: number
538 json::Value params;
539 json::Value error;
540 params[jss::key_type] = "secp256k1";
541 params[jss::seed] = 443556;
542
543 auto ret = keypairForSignature(params, error);
544 BEAST_EXPECT(containsError(error));
545 BEAST_EXPECT(!ret);
546 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed', not string.");
547 }
548
549 { // not a string: object
550 json::Value params;
551 json::Value error;
552 params[jss::key_type] = "secp256k1";
553 params[jss::seed] = json::ValueType::Object;
554
555 auto ret = keypairForSignature(params, error);
556 BEAST_EXPECT(containsError(error));
557 BEAST_EXPECT(!ret);
558 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed', not string.");
559 }
560
561 { // not a string: array
562 json::Value params;
563 json::Value error;
564 params[jss::key_type] = "secp256k1";
565 params[jss::seed] = json::ValueType::Array;
566
567 auto ret = keypairForSignature(params, error);
568 BEAST_EXPECT(containsError(error));
569 BEAST_EXPECT(!ret);
570 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed', not string.");
571 }
572
573 { // not a seed: empty
574 json::Value params;
575 json::Value error;
576 params[jss::key_type] = "secp256k1";
577 params[jss::seed] = "";
578
579 auto ret = keypairForSignature(params, error);
580 BEAST_EXPECT(containsError(error));
581 BEAST_EXPECT(!ret);
582 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
583 }
584
585 { // not a seed: invalid characters
586 json::Value params;
587 json::Value error;
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";
590
591 auto ret = keypairForSignature(params, error);
592 BEAST_EXPECT(containsError(error));
593 BEAST_EXPECT(!ret);
594 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
595 }
596
597 { // not a seed: random string
598 json::Value params;
599 json::Value error;
600 params[jss::key_type] = "secp256k1";
601 params[jss::seed] = "pnnjkbnobnml43679nbvjdsklnbjs";
602
603 auto ret = keypairForSignature(params, error);
604 BEAST_EXPECT(containsError(error));
605 BEAST_EXPECT(!ret);
606 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
607 }
608
609 // Specify non-string or invalid seed_hex
610 { // not a string: number
611 json::Value params;
612 json::Value error;
613 params[jss::key_type] = "secp256k1";
614 params[jss::seed_hex] = 443556;
615
616 auto ret = keypairForSignature(params, error);
617 BEAST_EXPECT(containsError(error));
618 BEAST_EXPECT(!ret);
619 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed_hex', not string.");
620 }
621
622 { // not a string: object
623 json::Value params;
624 json::Value error;
625 params[jss::key_type] = "secp256k1";
626 params[jss::seed_hex] = json::ValueType::Object;
627
628 auto ret = keypairForSignature(params, error);
629 BEAST_EXPECT(containsError(error));
630 BEAST_EXPECT(!ret);
631 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed_hex', not string.");
632 }
633
634 { // not a string: array
635 json::Value params;
636 json::Value error;
637 params[jss::key_type] = "secp256k1";
638 params[jss::seed_hex] = json::ValueType::Array;
639
640 auto ret = keypairForSignature(params, error);
641 BEAST_EXPECT(containsError(error));
642 BEAST_EXPECT(!ret);
643 BEAST_EXPECT(error[jss::error_message] == "Invalid field 'seed_hex', not string.");
644 }
645
646 { // empty
647 json::Value params;
648 json::Value error;
649 params[jss::key_type] = "secp256k1";
650 params[jss::seed_hex] = "";
651
652 auto ret = keypairForSignature(params, error);
653 BEAST_EXPECT(containsError(error));
654 BEAST_EXPECT(!ret);
655 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
656 }
657
658 { // short
659 json::Value params;
660 json::Value error;
661 params[jss::key_type] = "secp256k1";
662 params[jss::seed_hex] = "A670A19B";
663
664 auto ret = keypairForSignature(params, error);
665 BEAST_EXPECT(containsError(error));
666 BEAST_EXPECT(!ret);
667 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
668 }
669
670 { // not hex
671 json::Value params;
672 json::Value error;
673 params[jss::key_type] = "secp256k1";
674 params[jss::seed_hex] = common::gPassphrase;
675
676 auto ret = keypairForSignature(params, error);
677 BEAST_EXPECT(containsError(error));
678 BEAST_EXPECT(!ret);
679 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
680 }
681
682 { // overlong
683 json::Value params;
684 json::Value error;
685 params[jss::key_type] = "secp256k1";
686 params[jss::seed_hex] = "BE6A670A19B209E112146D0A7ED2AAD72567D0FC913";
687
688 auto ret = keypairForSignature(params, error);
689 BEAST_EXPECT(containsError(error));
690 BEAST_EXPECT(!ret);
691 BEAST_EXPECT(error[jss::error_message] == "Disallowed seed.");
692 }
693 }
694
695 void
697 {
698 testcase("XrplLib encoded Ed25519 keys");
699
700 auto test = [this](char const* seed, char const* addr) {
701 {
702 json::Value params;
703 json::Value error;
704
705 params[jss::passphrase] = seed;
706
707 auto ret = keypairForSignature(params, error);
708
709 BEAST_EXPECT(!containsError(error));
710 if (BEAST_EXPECT(ret); ret.has_value())
711 {
712 BEAST_EXPECT(ret->first.size() != 0);
713 BEAST_EXPECT(toBase58(calcAccountID(ret->first)) == addr);
714 }
715 }
716
717 {
718 json::Value params;
719 json::Value error;
720
721 params[jss::key_type] = "secp256k1";
722 params[jss::passphrase] = seed;
723
724 auto ret = keypairForSignature(params, error);
725
726 BEAST_EXPECT(containsError(error));
727 BEAST_EXPECT(
728 error[jss::error_message] == "Specified seed is for an Ed25519 wallet.");
729 }
730
731 {
732 json::Value params;
733 json::Value error;
734
735 params[jss::key_type] = "ed25519";
736 params[jss::seed] = seed;
737
738 auto ret = keypairForSignature(params, error);
739
740 BEAST_EXPECT(!containsError(error));
741 if (BEAST_EXPECT(ret); ret.has_value())
742 {
743 BEAST_EXPECT(ret->first.size() != 0);
744 BEAST_EXPECT(toBase58(calcAccountID(ret->first)) == addr);
745 }
746 }
747
748 {
749 json::Value params;
750 json::Value error;
751
752 params[jss::key_type] = "secp256k1";
753 params[jss::seed] = seed;
754
755 auto ret = keypairForSignature(params, error);
756
757 BEAST_EXPECT(containsError(error));
758 BEAST_EXPECT(
759 error[jss::error_message] == "Specified seed is for an Ed25519 wallet.");
760 }
761 };
762
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");
779 }
780
781 void
799};
800
801BEAST_DEFINE_TESTSUITE(WalletPropose, rpc, xrpl);
802
803} // namespace xrpl::RPC
TestcaseT testcase
Memberspace for declaring test cases.
Definition suite.h:149
Represents a JSON value.
Definition json_value.h:130
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 &params, KeyStrings const &s)
void testRandomWallet(std::optional< std::string > const &keyType)
void testKeyType(std::optional< std::string > const &keyType, KeyStrings const &strings)
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 testLegacyPassphrase(std::optional< std::string > const &keyType, KeyStrings const &strings)
bool expectEquals(S actual, T expected, std::string const &message="")
Definition TestSuite.h:14
T emplace(T... args)
@ Array
array value (ordered list)
Definition json_value.h:25
@ Object
object value (collection of name/value pairs).
Definition json_value.h:26
static char const * gMasterKey
static char const * gPassphrase
static char const * gMasterSeedHex
static char const * gMasterSeed
API version numbers used in later API versions.
Definition ApiVersion.h:35
std::optional< std::pair< PublicKey, SecretKey > > keypairForSignature(json::Value const &params, 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.
Definition algorithm.h:5
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.
Definition AccountID.cpp:93
json::Value walletPropose(json::Value const &params)
AccountID calcAccountID(PublicKey const &pk)