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 
368  for (std::size_t i = 0; i != keys.size(); ++i)
369  keys[i] = derivePublicKey(keyType, randomSecretKey());
370 
371  for (std::size_t i = 0; i != keys.size(); ++i)
372  {
373  auto const si = toBase58(TokenType::NodePublic, keys[i]);
374  BEAST_EXPECT(!si.empty());
375 
376  auto const ski = parseBase58<PublicKey>(TokenType::NodePublic, si);
377  BEAST_EXPECT(ski && (keys[i] == *ski));
378 
379  for (std::size_t j = i; j != keys.size(); ++j)
380  {
381  BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
382 
383  auto const sj = toBase58(TokenType::NodePublic, keys[j]);
384 
385  BEAST_EXPECT((si == sj) == (i == j));
386 
387  auto const skj =
388  parseBase58<PublicKey>(TokenType::NodePublic, sj);
389  BEAST_EXPECT(skj && (keys[j] == *skj));
390 
391  BEAST_EXPECT((*ski == *skj) == (i == j));
392  }
393  }
394  }
395 
396  void
398  {
399  testcase("Base58: secp256k1");
400 
401  {
402  auto const pk1 = derivePublicKey(
405  KeyType::secp256k1, generateSeed("masterpassphrase")));
406 
407  auto const pk2 = parseBase58<PublicKey>(
409  "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
410  BEAST_EXPECT(pk2);
411 
412  BEAST_EXPECT(pk1 == *pk2);
413  }
414 
416 
417  testcase("Base58: ed25519");
418 
419  {
420  auto const pk1 = derivePublicKey(
423  KeyType::ed25519, generateSeed("masterpassphrase")));
424 
425  auto const pk2 = parseBase58<PublicKey>(
427  "nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
428  BEAST_EXPECT(pk2);
429 
430  BEAST_EXPECT(pk1 == *pk2);
431  }
432 
434  }
435 
436  void
438  {
439  testcase("Miscellaneous operations");
440 
441  auto const pk1 = derivePublicKey(
444  KeyType::secp256k1, generateSeed("masterpassphrase")));
445 
446  PublicKey pk2(pk1);
447  BEAST_EXPECT(pk1 == pk2);
448  BEAST_EXPECT(pk2 == pk1);
449 
450  PublicKey pk3;
451  pk3 = pk2;
452  BEAST_EXPECT(pk3 == pk2);
453  BEAST_EXPECT(pk1 == pk3);
454  }
455 
456  void
457  run() override
458  {
459  testBase58();
460  testCanonical();
462  }
463 };
464 
466 
467 } // 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)
vector
std::array::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
ripple::QualityDirection::out
@ out
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
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:114
std::array
STL class.
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
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:397
ripple::PublicKey_test::run
void run() override
Definition: PublicKey_test.cpp:457
ripple::PublicKey_test::testMiscOperations
void testMiscOperations()
Definition: PublicKey_test.cpp:437
ripple::randomSecretKey
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
Definition: SecretKey.cpp:281
std::hash