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#include <vector>
24
25namespace ripple {
26
28{
29public:
31
32 template <class FwdIter, class Container>
33 static void
34 hex_to_binary(FwdIter first, FwdIter last, Container& out)
35 {
36 struct Table
37 {
38 int val[256];
39 Table()
40 {
41 std::fill(val, val + 256, 0);
42 for (int i = 0; i < 10; ++i)
43 val['0' + i] = i;
44 for (int i = 0; i < 6; ++i)
45 {
46 val['A' + i] = 10 + i;
47 val['a' + i] = 10 + i;
48 }
49 }
50 int
51 operator[](int i)
52 {
53 return val[i];
54 }
55 };
56
57 static Table lut;
58 out.reserve(std::distance(first, last) / 2);
59 while (first != last)
60 {
61 auto const hi(lut[(*first++)]);
62 auto const lo(lut[(*first++)]);
63 out.push_back((hi * 16) + lo);
64 }
65 }
66
67 blob
68 sig(std::string const& hex)
69 {
70 blob b;
71 hex_to_binary(hex.begin(), hex.end(), b);
72 return b;
73 }
74
75 bool
77 {
78 return ecdsaCanonicality(makeSlice(sig(s))) == answer;
79 }
80
81 void
83 {
84 testcase("Canonical");
85
86 // Fully canonical
87 BEAST_EXPECT(check(
89 "3045"
90 "022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EE"
91 "E905"
92 "0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F"
93 "28"));
94 BEAST_EXPECT(check(
96 "3045"
97 "0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF"
98 "1D2D"
99 "022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B4"
100 "54"));
101 BEAST_EXPECT(check(
103 "3044"
104 "02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B75"
105 "81"
106 "022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D9"
107 "6B"));
108 BEAST_EXPECT(check(
110 "3044"
111 "022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D0"
112 "4E"
113 "02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C7187"
114 "9F"));
115 BEAST_EXPECT(check(
117 "3045"
118 "022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C"
119 "2F12"
120 "0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA"
121 "18"));
122
123 // Canonical but not fully canonical
124 BEAST_EXPECT(check(
126 "3046"
127 "022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC"
128 "0A1B"
129 "022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF5"
130 "97A1"));
131 BEAST_EXPECT(check(
133 "3045"
134 "022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230"
135 "B6"
136 "0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB"
137 "254C"));
138 BEAST_EXPECT(check(
140 "3046"
141 "02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32"
142 "625F"
143 "022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F2"
144 "86EA"));
145 BEAST_EXPECT(check(
147 "3045"
148 "02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AE"
149 "C0"
150 "022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869"
151 "AE35"));
152
153 // valid
154 BEAST_EXPECT(check(
156 "3006"
157 "020101"
158 "020102"));
159 BEAST_EXPECT(check(
161 "3044"
162 "02203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df"
163 "0c"
164 "022030b61dd36543125d56b9f9f3a1f53189e5af33cdda8d77a5209aec03978fa0"
165 "01"));
166 BEAST_EXPECT(check(
168 "3045"
169 "0220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f9"
170 "0a"
171 "0221008fffd599910eefe00bc803c688eca1d2ba7f6b180620eaa03488e6585db6"
172 "ba01"));
173 BEAST_EXPECT(check(
175 "3046"
176 "022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40"
177 "f90a"
178 "0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585d"
179 "b6ba"));
180
181 BEAST_EXPECT(check(
182 std::nullopt,
183 "3005"
184 "0201FF"
185 "0200"));
186 BEAST_EXPECT(check(
187 std::nullopt,
188 "3006"
189 "020101"
190 "020202"));
191 BEAST_EXPECT(check(
192 std::nullopt,
193 "3006"
194 "020701"
195 "020102"));
196 BEAST_EXPECT(check(
197 std::nullopt,
198 "3006"
199 "020401"
200 "020102"));
201 BEAST_EXPECT(check(
202 std::nullopt,
203 "3006"
204 "020501"
205 "020102"));
206 BEAST_EXPECT(check(
207 std::nullopt,
208 "3006"
209 "020201"
210 "020102"));
211 BEAST_EXPECT(check(
212 std::nullopt,
213 "3006"
214 "020301"
215 "020202"));
216 BEAST_EXPECT(check(
217 std::nullopt,
218 "3006"
219 "020401"
220 "020202"));
221 BEAST_EXPECT(check(
222 std::nullopt,
223 "3047"
224 "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
225 "6105"
226 "022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e56"
227 "6695ed"));
228 BEAST_EXPECT(check(
229 std::nullopt,
230 "3144"
231 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
232 "05"
233 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
234 "ed"));
235 BEAST_EXPECT(check(
236 std::nullopt,
237 "3045"
238 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
239 "05"
240 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
241 "ed"));
242 BEAST_EXPECT(check(
243 std::nullopt,
244 "301F"
245 "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1"));
246 BEAST_EXPECT(check(
247 std::nullopt,
248 "3045"
249 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
250 "05"
251 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
252 "ed00"));
253 BEAST_EXPECT(check(
254 std::nullopt,
255 "3044"
256 "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
257 "05"
258 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
259 "ed"));
260 BEAST_EXPECT(check(
261 std::nullopt,
262 "3024"
263 "0200"
264 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
265 "ed"));
266 BEAST_EXPECT(check(
267 std::nullopt,
268 "3044"
269 "02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
270 "05"
271 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
272 "ed"));
273 BEAST_EXPECT(check(
274 std::nullopt,
275 "3045"
276 "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba"
277 "6105"
278 "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
279 "ed"));
280 BEAST_EXPECT(check(
281 std::nullopt,
282 "3044"
283 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
284 "05012"
285 "02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695e"
286 "d"));
287 BEAST_EXPECT(check(
288 std::nullopt,
289 "3024"
290 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
291 "05"
292 "0200"));
293 BEAST_EXPECT(check(
294 std::nullopt,
295 "3044"
296 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
297 "05"
298 "0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695"
299 "ed"));
300 BEAST_EXPECT(check(
301 std::nullopt,
302 "3045"
303 "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba61"
304 "05"
305 "0221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e5666"
306 "95ed"));
307 }
308
309 void
311 {
312 // Try converting short, long and malformed data
313 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, ""));
314 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, " "));
315 BEAST_EXPECT(
316 !parseBase58<PublicKey>(TokenType::NodePublic, "!ty89234gh45"));
317
318 auto const good = toBase58(
320
321 // Short (non-empty) strings
322 {
323 auto s = good;
324
325 // Remove all characters from the string in random order:
327
328 while (!s.empty())
329 {
330 s.erase(r(s) % s.size(), 1);
331 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
332 }
333 }
334
335 // Long strings
336 for (std::size_t i = 1; i != 16; i++)
337 {
338 auto s = good;
339 s.resize(s.size() + i, s[i % s.size()]);
340 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
341 }
342
343 // Strings with invalid Base58 characters
344 for (auto c : std::string("0IOl"))
345 {
346 for (std::size_t i = 0; i != good.size(); ++i)
347 {
348 auto s = good;
349 s[i % s.size()] = c;
350 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
351 }
352 }
353
354 // Strings with incorrect prefix
355 {
356 auto s = good;
357
358 for (auto c : std::string("apsrJqtv7"))
359 {
360 s[0] = c;
361 BEAST_EXPECT(!parseBase58<PublicKey>(TokenType::NodePublic, s));
362 }
363 }
364
365 // Try some random secret keys
367 keys.reserve(32);
368
369 for (std::size_t i = 0; i != keys.capacity(); ++i)
371 BEAST_EXPECT(keys.size() == 32);
372
373 for (std::size_t i = 0; i != keys.size(); ++i)
374 {
375 auto const si = toBase58(TokenType::NodePublic, keys[i]);
376 BEAST_EXPECT(!si.empty());
377
378 auto const ski = parseBase58<PublicKey>(TokenType::NodePublic, si);
379 BEAST_EXPECT(ski && (keys[i] == *ski));
380
381 for (std::size_t j = i; j != keys.size(); ++j)
382 {
383 BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
384
385 auto const sj = toBase58(TokenType::NodePublic, keys[j]);
386
387 BEAST_EXPECT((si == sj) == (i == j));
388
389 auto const skj =
390 parseBase58<PublicKey>(TokenType::NodePublic, sj);
391 BEAST_EXPECT(skj && (keys[j] == *skj));
392
393 BEAST_EXPECT((*ski == *skj) == (i == j));
394 }
395 }
396 }
397
398 void
400 {
401 testcase("Base58: secp256k1");
402
403 {
404 auto const pk1 = derivePublicKey(
407 KeyType::secp256k1, generateSeed("masterpassphrase")));
408
409 auto const pk2 = parseBase58<PublicKey>(
411 "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
412 BEAST_EXPECT(pk2);
413
414 BEAST_EXPECT(pk1 == *pk2);
415 }
416
418
419 testcase("Base58: ed25519");
420
421 {
422 auto const pk1 = derivePublicKey(
425 KeyType::ed25519, generateSeed("masterpassphrase")));
426
427 auto const pk2 = parseBase58<PublicKey>(
429 "nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
430 BEAST_EXPECT(pk2);
431
432 BEAST_EXPECT(pk1 == *pk2);
433 }
434
436 }
437
438 void
440 {
441 testcase("Miscellaneous operations");
442
443 auto const pk1 = derivePublicKey(
446 KeyType::secp256k1, generateSeed("masterpassphrase")));
447
448 PublicKey pk2(pk1);
449 BEAST_EXPECT(pk1 == pk2);
450 BEAST_EXPECT(pk2 == pk1);
451
455 KeyType::secp256k1, generateSeed("arbitraryPassPhrase")));
456 // Testing the copy assignment operation of PublicKey class
457 pk3 = pk2;
458 BEAST_EXPECT(pk3 == pk2);
459 BEAST_EXPECT(pk1 == pk3);
460 }
461
462 void
463 run() override
464 {
465 testBase58();
468 }
469};
470
471BEAST_DEFINE_TESTSUITE(PublicKey, protocol, ripple);
472
473} // namespace ripple
T capacity(T... args)
A testsuite class.
Definition: suite.h:53
testcase_t testcase
Memberspace for declaring test cases.
Definition: suite.h:153
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:62
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:26
std::optional< ECDSACanonicality > ecdsaCanonicality(Slice const &sig)
Determines the canonicality of a signature.
Definition: PublicKey.cpp:113
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:106
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
Definition: SecretKey.cpp:313
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
Definition: SecretKey.cpp:291
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:243
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
Definition: SecretKey.cpp:281
KeyType
Definition: KeyType.h:28
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition: Seed.cpp:69
T reserve(T... args)
T size(T... args)