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(
183 std::nullopt,
184 "3005"
185 "0201FF"
186 "0200"));
187 BEAST_EXPECT(check(
188 std::nullopt,
189 "3006"
190 "020101"
191 "020202"));
192 BEAST_EXPECT(check(
193 std::nullopt,
194 "3006"
195 "020701"
196 "020102"));
197 BEAST_EXPECT(check(
198 std::nullopt,
199 "3006"
200 "020401"
201 "020102"));
202 BEAST_EXPECT(check(
203 std::nullopt,
204 "3006"
205 "020501"
206 "020102"));
207 BEAST_EXPECT(check(
208 std::nullopt,
209 "3006"
210 "020201"
211 "020102"));
212 BEAST_EXPECT(check(
213 std::nullopt,
214 "3006"
215 "020301"
216 "020202"));
217 BEAST_EXPECT(check(
218 std::nullopt,
219 "3006"
220 "020401"
221 "020202"));
222 BEAST_EXPECT(check(
223 std::nullopt,
224 "3047"
225 "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
226 "6105"
227 "022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e56"
228 "6695ed"));
229 BEAST_EXPECT(check(
230 std::nullopt,
231 "3144"
232 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
233 "05"
234 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
235 "ed"));
236 BEAST_EXPECT(check(
237 std::nullopt,
238 "3045"
239 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
240 "05"
241 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
242 "ed"));
243 BEAST_EXPECT(check(
244 std::nullopt,
245 "301F"
246 "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1"));
247 BEAST_EXPECT(check(
248 std::nullopt,
249 "3045"
250 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
251 "05"
252 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
253 "ed00"));
254 BEAST_EXPECT(check(
255 std::nullopt,
256 "3044"
257 "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
258 "05"
259 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
260 "ed"));
261 BEAST_EXPECT(check(
262 std::nullopt,
263 "3024"
264 "0200"
265 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
266 "ed"));
267 BEAST_EXPECT(check(
268 std::nullopt,
269 "3044"
270 "02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
271 "05"
272 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
273 "ed"));
274 BEAST_EXPECT(check(
275 std::nullopt,
276 "3045"
277 "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
278 "6105"
279 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
280 "ed"));
281 BEAST_EXPECT(check(
282 std::nullopt,
283 "3044"
284 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
285 "05012"
286 "02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695e"
287 "d"));
288 BEAST_EXPECT(check(
289 std::nullopt,
290 "3024"
291 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
292 "05"
293 "0200"));
294 BEAST_EXPECT(check(
295 std::nullopt,
296 "3044"
297 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
298 "05"
299 "0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
300 "ed"));
301 BEAST_EXPECT(check(
302 std::nullopt,
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)
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.
Definition: PublicKey.cpp:129
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:114
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
Definition: SecretKey.cpp:331
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
Definition: SecretKey.cpp:309
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.
Definition: SecretKey.cpp:299
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)