rippled
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 <ripple/beast/unit_test.h>
21 #include <ripple/protocol/PublicKey.h>
22 #include <ripple/protocol/SecretKey.h>
23 #include <vector>
24 
25 namespace ripple {
26 
27 class PublicKey_test : public beast::unit_test::suite
28 {
29 public:
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)
370  keys.emplace_back(derivePublicKey(keyType, randomSecretKey()));
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();
466  testCanonical();
468  }
469 };
470 
472 
473 } // namespace ripple
ripple::PublicKey_test
Definition: PublicKey_test.cpp:27
ripple::makeSlice
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:241
ripple::PublicKey_test::testCanonical
void testCanonical()
Definition: PublicKey_test.cpp:82
std::string
STL class.
ripple::PublicKey_test::sig
blob sig(std::string const &hex)
Definition: PublicKey_test.cpp:68
ripple::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(AccountTxPaging, app, ripple)
std::vector::reserve
T reserve(T... args)
vector
std::vector::size
T size(T... args)
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
std::distance
T distance(T... args)
ripple::PublicKey_test::blob
std::vector< std::uint8_t > blob
Definition: PublicKey_test.cpp:30
ripple::ECDSACanonicality::fullyCanonical
@ fullyCanonical
std::fill
T fill(T... args)
ripple::KeyType::ed25519
@ ed25519
std::vector::capacity
T capacity(T... args)
ripple::QualityDirection::out
@ out
ripple::PublicKey
A public key.
Definition: PublicKey.h:61
ripple::derivePublicKey
PublicKey derivePublicKey(KeyType type, SecretKey const &sk)
Derive the public key from a secret key.
Definition: SecretKey.cpp:313
ripple::PublicKey_test::testBase58
void testBase58(KeyType keyType)
Definition: PublicKey_test.cpp:310
ripple::ecdsaCanonicality
std::optional< ECDSACanonicality > ecdsaCanonicality(Slice const &sig)
Determine whether a signature is canonical.
Definition: PublicKey.cpp:113
ripple::generateSecretKey
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
Definition: SecretKey.cpp:291
ripple::PublicKey_test::check
bool check(std::optional< ECDSACanonicality > answer, std::string const &s)
Definition: PublicKey_test.cpp:76
ripple::ECDSACanonicality::canonical
@ canonical
ripple::KeyType
KeyType
Definition: KeyType.h:28
ripple::KeyType::secp256k1
@ secp256k1
ripple::generateSeed
Seed generateSeed(std::string const &passPhrase)
Generate a seed deterministically.
Definition: Seed.cpp:69
std::vector::emplace_back
T emplace_back(T... args)
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
protocol
Definition: ValidatorList.h:38
ripple::PublicKey_test::hex_to_binary
static void hex_to_binary(FwdIter first, FwdIter last, Container &out)
Definition: PublicKey_test.cpp:34
ripple::TokenType::NodePublic
@ NodePublic
std::optional
std::size_t
ripple::PublicKey_test::testBase58
void testBase58()
Definition: PublicKey_test.cpp:399
ripple::PublicKey_test::run
void run() override
Definition: PublicKey_test.cpp:463
ripple::PublicKey_test::testMiscOperations
void testMiscOperations()
Definition: PublicKey_test.cpp:439
ripple::randomSecretKey
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
Definition: SecretKey.cpp:281
std::hash