rippled
Loading...
Searching...
No Matches
PublicKey_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/beast/unit_test.h>
21#include <xrpl/protocol/PublicKey.h>
22#include <xrpl/protocol/SecretKey.h>
23
24#include <vector>
25
26namespace ripple {
27
29{
30public:
32
33 template <class FwdIter, class Container>
34 static void
35 hex_to_binary(FwdIter first, FwdIter last, Container& out)
36 {
37 struct Table
38 {
39 int val[256];
40 Table()
41 {
42 std::fill(val, val + 256, 0);
43 for (int i = 0; i < 10; ++i)
44 val['0' + i] = i;
45 for (int i = 0; i < 6; ++i)
46 {
47 val['A' + i] = 10 + i;
48 val['a' + i] = 10 + i;
49 }
50 }
51 int
52 operator[](int i)
53 {
54 return val[i];
55 }
56 };
57
58 static Table lut;
59 out.reserve(std::distance(first, last) / 2);
60 while (first != last)
61 {
62 auto const hi(lut[(*first++)]);
63 auto const lo(lut[(*first++)]);
64 out.push_back((hi * 16) + lo);
65 }
66 }
67
68 blob
69 sig(std::string const& hex)
70 {
71 blob b;
72 hex_to_binary(hex.begin(), hex.end(), b);
73 return b;
74 }
75
76 bool
78 {
79 return ecdsaCanonicality(makeSlice(sig(s))) == answer;
80 }
81
82 void
84 {
85 testcase("Canonical");
86
87 // Fully canonical
88 BEAST_EXPECT(check(
90 "3045"
91 "022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EE"
92 "E905"
93 "0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F"
94 "28"));
95 BEAST_EXPECT(check(
97 "3045"
98 "0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF"
99 "1D2D"
100 "022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B4"
101 "54"));
102 BEAST_EXPECT(check(
104 "3044"
105 "02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B75"
106 "81"
107 "022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D9"
108 "6B"));
109 BEAST_EXPECT(check(
111 "3044"
112 "022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D0"
113 "4E"
114 "02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C7187"
115 "9F"));
116 BEAST_EXPECT(check(
118 "3045"
119 "022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C"
120 "2F12"
121 "0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA"
122 "18"));
123
124 // Canonical but not fully canonical
125 BEAST_EXPECT(check(
127 "3046"
128 "022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC"
129 "0A1B"
130 "022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF5"
131 "97A1"));
132 BEAST_EXPECT(check(
134 "3045"
135 "022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230"
136 "B6"
137 "0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB"
138 "254C"));
139 BEAST_EXPECT(check(
141 "3046"
142 "02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32"
143 "625F"
144 "022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F2"
145 "86EA"));
146 BEAST_EXPECT(check(
148 "3045"
149 "02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AE"
150 "C0"
151 "022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869"
152 "AE35"));
153
154 // valid
155 BEAST_EXPECT(check(
157 "3006"
158 "020101"
159 "020102"));
160 BEAST_EXPECT(check(
162 "3044"
163 "02203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df"
164 "0c"
165 "022030b61dd36543125d56b9f9f3a1f53189e5af33cdda8d77a5209aec03978fa0"
166 "01"));
167 BEAST_EXPECT(check(
169 "3045"
170 "0220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f9"
171 "0a"
172 "0221008fffd599910eefe00bc803c688eca1d2ba7f6b180620eaa03488e6585db6"
173 "ba01"));
174 BEAST_EXPECT(check(
176 "3046"
177 "022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40"
178 "f90a"
179 "0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585d"
180 "b6ba"));
181
182 BEAST_EXPECT(check(
184 "3005"
185 "0201FF"
186 "0200"));
187 BEAST_EXPECT(check(
189 "3006"
190 "020101"
191 "020202"));
192 BEAST_EXPECT(check(
194 "3006"
195 "020701"
196 "020102"));
197 BEAST_EXPECT(check(
199 "3006"
200 "020401"
201 "020102"));
202 BEAST_EXPECT(check(
204 "3006"
205 "020501"
206 "020102"));
207 BEAST_EXPECT(check(
209 "3006"
210 "020201"
211 "020102"));
212 BEAST_EXPECT(check(
214 "3006"
215 "020301"
216 "020202"));
217 BEAST_EXPECT(check(
219 "3006"
220 "020401"
221 "020202"));
222 BEAST_EXPECT(check(
224 "3047"
225 "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
226 "6105"
227 "022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e56"
228 "6695ed"));
229 BEAST_EXPECT(check(
231 "3144"
232 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
233 "05"
234 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
235 "ed"));
236 BEAST_EXPECT(check(
238 "3045"
239 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
240 "05"
241 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
242 "ed"));
243 BEAST_EXPECT(check(
245 "301F"
246 "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1"));
247 BEAST_EXPECT(check(
249 "3045"
250 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
251 "05"
252 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
253 "ed00"));
254 BEAST_EXPECT(check(
256 "3044"
257 "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
258 "05"
259 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
260 "ed"));
261 BEAST_EXPECT(check(
263 "3024"
264 "0200"
265 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
266 "ed"));
267 BEAST_EXPECT(check(
269 "3044"
270 "02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
271 "05"
272 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
273 "ed"));
274 BEAST_EXPECT(check(
276 "3045"
277 "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
278 "6105"
279 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
280 "ed"));
281 BEAST_EXPECT(check(
283 "3044"
284 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
285 "05012"
286 "02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695e"
287 "d"));
288 BEAST_EXPECT(check(
290 "3024"
291 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
292 "05"
293 "0200"));
294 BEAST_EXPECT(check(
296 "3044"
297 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
298 "05"
299 "0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
300 "ed"));
301 BEAST_EXPECT(check(
303 "3045"
304 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
305 "05"
306 "0221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e5666"
307 "95ed"));
308 }
309
310 void
312 {
313 // Try converting short, long and malformed data
314 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, ""));
315 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, " "));
316 BEAST_EXPECT(
317 !parseBase58<PublicKey>(TokenType::NodePublic, "!ty89234gh45"));
318
319 auto const good = toBase58(
321
322 // Short (non-empty) strings
323 {
324 auto s = good;
325
326 // Remove all characters from the string in random order:
328
329 while (!s.empty())
330 {
331 s.erase(r(s) % s.size(), 1);
332 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
333 }
334 }
335
336 // Long strings
337 for (std::size_t i = 1; i != 16; i++)
338 {
339 auto s = good;
340 s.resize(s.size() + i, s[i % s.size()]);
341 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
342 }
343
344 // Strings with invalid Base58 characters
345 for (auto c : std::string("0IOl"))
346 {
347 for (std::size_t i = 0; i != good.size(); ++i)
348 {
349 auto s = good;
350 s[i % s.size()] = c;
351 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
352 }
353 }
354
355 // Strings with incorrect prefix
356 {
357 auto s = good;
358
359 for (auto c : std::string("apsrJqtv7"))
360 {
361 s[0] = c;
362 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
363 }
364 }
365
366 // Try some random secret keys
368 keys.reserve(32);
369
370 for (std::size_t i = 0; i != keys.capacity(); ++i)
372 BEAST_EXPECT(keys.size() == 32);
373
374 for (std::size_t i = 0; i != keys.size(); ++i)
375 {
376 auto const si = toBase58(TokenType::NodePublic, keys[i]);
377 BEAST_EXPECT(!si.empty());
378
379 auto const ski = parseBase58<PublicKey>(TokenType::NodePublic, si);
380 BEAST_EXPECT(ski && (keys[i] == *ski));
381
382 for (std::size_t j = i; j != keys.size(); ++j)
383 {
384 BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
385
386 auto const sj = toBase58(TokenType::NodePublic, keys[j]);
387
388 BEAST_EXPECT((si == sj) == (i == j));
389
390 auto const skj =
391 parseBase58<PublicKey>(TokenType::NodePublic, sj);
392 BEAST_EXPECT(skj && (keys[j] == *skj));
393
394 BEAST_EXPECT((*ski == *skj) == (i == j));
395 }
396 }
397 }
398
399 void
401 {
402 testcase("Base58: secp256k1");
403
404 {
405 auto const pk1 = derivePublicKey(
408 KeyType::secp256k1, generateSeed("masterpassphrase")));
409
410 auto const pk2 = parseBase58<PublicKey>(
412 "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
413 BEAST_EXPECT(pk2);
414
415 BEAST_EXPECT(pk1 == *pk2);
416 }
417
419
420 testcase("Base58: ed25519");
421
422 {
423 auto const pk1 = derivePublicKey(
426 KeyType::ed25519, generateSeed("masterpassphrase")));
427
428 auto const pk2 = parseBase58<PublicKey>(
430 "nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
431 BEAST_EXPECT(pk2);
432
433 BEAST_EXPECT(pk1 == *pk2);
434 }
435
437 }
438
439 void
441 {
442 testcase("Miscellaneous operations");
443
444 auto const pk1 = derivePublicKey(
447 KeyType::secp256k1, generateSeed("masterpassphrase")));
448
449 PublicKey pk2(pk1);
450 BEAST_EXPECT(pk1 == pk2);
451 BEAST_EXPECT(pk2 == pk1);
452
456 KeyType::secp256k1, generateSeed("arbitraryPassPhrase")));
457 // Testing the copy assignment operation of PublicKey class
458 pk3 = pk2;
459 BEAST_EXPECT(pk3 == pk2);
460 BEAST_EXPECT(pk1 == pk3);
461 }
462
463 void
464 run() override
465 {
466 testBase58();
469 }
470};
471
472BEAST_DEFINE_TESTSUITE(PublicKey, protocol, ripple);
473
474} // namespace ripple
T capacity(T... args)
A testsuite class.
Definition suite.h:55
testcase_t testcase
Memberspace for declaring test cases.
Definition suite.h:155
void testBase58(KeyType keyType)
std::vector< std::uint8_t > blob
blob sig(std::string const &hex)
void run() override
Runs the suite.
static void hex_to_binary(FwdIter first, FwdIter last, Container &out)
bool check(std::optional< ECDSACanonicality > answer, std::string const &s)
A public key.
Definition PublicKey.h:61
T distance(T... args)
T emplace_back(T... args)
T fill(T... args)
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25
std::optional< ECDSACanonicality > ecdsaCanonicality(Slice const &sig)
Determines the canonicality of a signature.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
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:244
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
KeyType
Definition KeyType.h:28
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition Seed.cpp:76
T reserve(T... args)
T size(T... args)