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/protocol/PublicKey.h>
21 #include <ripple/protocol/SecretKey.h>
22 #include <ripple/beast/unit_test.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
34  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 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
76  check (boost::optional<ECDSACanonicality> answer,
77  std::string const& s)
78  {
79  return ecdsaCanonicality(makeSlice(sig(s))) ==
80  answer;
81  }
82 
84  {
85  testcase ("Canonical");
86 
87  // Fully canonical
89  "3045"
90  "022100FF478110D1D4294471EC76E0157540C2181F47DEBD25D7F9E7DDCCCD47EEE905"
91  "0220078F07CDAE6C240855D084AD91D1479609533C147C93B0AEF19BC9724D003F28"));
93  "3045"
94  "0221009218248292F1762D8A51BE80F8A7F2CD288D810CE781D5955700DA1684DF1D2D"
95  "022041A1EE1746BFD72C9760CC93A7AAA8047D52C8833A03A20EAAE92EA19717B454"));
97  "3044"
98  "02206A9E43775F73B6D1EC420E4DDD222A80D4C6DF5D1BEECC431A91B63C928B7581"
99  "022023E9CC2D61DDA6F73EAA6BCB12688BEB0F434769276B3127E4044ED895C9D96B"));
101  "3044"
102  "022056E720007221F3CD4EFBB6352741D8E5A0968D48D8D032C2FBC4F6304AD1D04E"
103  "02201F39EB392C20D7801C3E8D81D487E742FA84A1665E923225BD6323847C71879F"));
105  "3045"
106  "022100FDFD5AD05518CEA0017A2DCB5C4DF61E7C73B6D3A38E7AE93210A1564E8C2F12"
107  "0220214FF061CCC123C81D0BB9D0EDEA04CD40D96BF1425D311DA62A7096BB18EA18"));
108 
109  // Canonical but not fully canonical
110  BEAST_EXPECT(check(ECDSACanonicality::canonical,
111  "3046"
112  "022100F477B3FA6F31C7CB3A0D1AD94A231FDD24B8D78862EE334CEA7CD08F6CBC0A1B"
113  "022100928E6BCF1ED2684679730C5414AEC48FD62282B090041C41453C1D064AF597A1"));
114  BEAST_EXPECT(check(ECDSACanonicality::canonical,
115  "3045"
116  "022063E7C7CA93CB2400E413A342C027D00665F8BAB9C22EF0A7B8AE3AAF092230B6"
117  "0221008F2E8BB7D09521ABBC277717B14B93170AE6465C5A1B36561099319C4BEB254C"));
118  BEAST_EXPECT(check(ECDSACanonicality::canonical,
119  "3046"
120  "02210099DCA1188663DDEA506A06A7B20C2B7D8C26AFF41DECE69D6C5F7C967D32625F"
121  "022100897658A6B1F9EEE5D140D7A332DA0BD73BB98974EA53F6201B01C1B594F286EA"));
122  BEAST_EXPECT(check(ECDSACanonicality::canonical,
123  "3045"
124  "02200855DE366E4E323AA2CE2A25674401A7D11F72EC432770D07F7B57DF7387AEC0"
125  "022100DA4C6ADDEA14888858DE2AC5B91ED9050D6972BB388DEF582628CEE32869AE35"));
126 
127  // valid
129  "3006"
130  "020101"
131  "020102"));
133  "3044"
134  "02203932c892e2e550f3af8ee4ce9c215a87f9bb831dcac87b2838e2c2eaa891df0c"
135  "022030b61dd36543125d56b9f9f3a1f53189e5af33cdda8d77a5209aec03978fa001"));
136  BEAST_EXPECT(check(ECDSACanonicality::canonical,
137  "3045"
138  "0220076045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
139  "0221008fffd599910eefe00bc803c688eca1d2ba7f6b180620eaa03488e6585db6ba01"));
140  BEAST_EXPECT(check(ECDSACanonicality::canonical,
141  "3046"
142  "022100876045be6f9eca28ff1ec606b833d0b87e70b2a630f5e3a496b110967a40f90a"
143  "0221008fffd599910eefe00bc803c688c2eca1d2ba7f6b180620eaa03488e6585db6ba"));
144 
145  BEAST_EXPECT(check(boost::none,
146  "3005"
147  "0201FF"
148  "0200"));
149  BEAST_EXPECT(check(boost::none,
150  "3006"
151  "020101"
152  "020202"));
153  BEAST_EXPECT(check(boost::none,
154  "3006"
155  "020701"
156  "020102"));
157  BEAST_EXPECT(check(boost::none,
158  "3006"
159  "020401"
160  "020102"));
161  BEAST_EXPECT(check(boost::none,
162  "3006"
163  "020501"
164  "020102"));
165  BEAST_EXPECT(check(boost::none,
166  "3006"
167  "020201"
168  "020102"));
169  BEAST_EXPECT(check(boost::none,
170  "3006"
171  "020301"
172  "020202"));
173  BEAST_EXPECT(check(boost::none,
174  "3006"
175  "020401"
176  "020202"));
177  BEAST_EXPECT(check(boost::none,
178  "3047"
179  "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
180  "022200002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
181  BEAST_EXPECT(check(boost::none,
182  "3144"
183  "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
184  "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
185  BEAST_EXPECT(check(boost::none,
186  "3045"
187  "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
188  "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
189  BEAST_EXPECT(check(boost::none,
190  "301F"
191  "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1"));
192  BEAST_EXPECT(check(boost::none,
193  "3045"
194  "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
195  "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed00"));
196  BEAST_EXPECT(check(boost::none,
197  "3044"
198  "01205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
199  "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
200  BEAST_EXPECT(check(boost::none,
201  "3024"
202  "0200"
203  "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
204  BEAST_EXPECT(check(boost::none,
205  "3044"
206  "02208990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
207  "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
208  BEAST_EXPECT(check(boost::none,
209  "3045"
210  "0221005990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
211  "02202d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
212  BEAST_EXPECT(check(boost::none,
213  "3044"
214  "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105012"
215  "02d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
216  BEAST_EXPECT(check(boost::none,
217  "3024"
218  "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
219  "0200"));
220  BEAST_EXPECT(check(boost::none,
221  "3044"
222  "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
223  "0220fd5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
224  BEAST_EXPECT(check(boost::none,
225  "3045"
226  "02205990e0584b2b238e1dfaad8d6ed69ecc1a4a13ac85fc0b31d0df395eb1ba6105"
227  "0221002d5876262c288beb511d061691bf26777344b702b00f8fe28621fe4e566695ed"));
228  }
229 
230  void testBase58 (KeyType keyType)
231  {
232  // Try converting short, long and malformed data
233  BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, ""));
234  BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, " "));
235  BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, "!ty89234gh45"));
236 
237  auto const good = toBase58 (
240  keyType,
241  randomSecretKey()));
242 
243  // Short (non-empty) strings
244  {
245  auto s = good;
246 
247  // Remove all characters from the string in random order:
249 
250  while (!s.empty())
251  {
252  s.erase (r(s) % s.size(), 1);
253  BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
254  }
255  }
256 
257  // Long strings
258  for (std::size_t i = 1; i != 16; i++)
259  {
260  auto s = good;
261  s.resize (s.size() + i, s[i % s.size()]);
262  BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
263  }
264 
265  // Strings with invalid Base58 characters
266  for (auto c : std::string ("0IOl"))
267  {
268  for (std::size_t i = 0; i != good.size(); ++i)
269  {
270  auto s = good;
271  s[i % s.size()] = c;
272  BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
273  }
274  }
275 
276  // Strings with incorrect prefix
277  {
278  auto s = good;
279 
280  for (auto c : std::string("apsrJqtv7"))
281  {
282  s[0] = c;
283  BEAST_EXPECT(!parseBase58<PublicKey> (TokenType::NodePublic, s));
284  }
285  }
286 
287  // Try some random secret keys
289 
290  for (std::size_t i = 0; i != keys.size(); ++i)
291  keys[i] = derivePublicKey (keyType, randomSecretKey());
292 
293  for (std::size_t i = 0; i != keys.size(); ++i)
294  {
295  auto const si = toBase58 (
297  keys[i]);
298  BEAST_EXPECT(!si.empty());
299 
300  auto const ski = parseBase58<PublicKey> (
302  BEAST_EXPECT(ski && (keys[i] == *ski));
303 
304  for (std::size_t j = i; j != keys.size(); ++j)
305  {
306  BEAST_EXPECT((keys[i] == keys[j]) == (i == j));
307 
308  auto const sj = toBase58 (
310  keys[j]);
311 
312  BEAST_EXPECT((si == sj) == (i == j));
313 
314  auto const skj = parseBase58<PublicKey> (
316  BEAST_EXPECT(skj && (keys[j] == *skj));
317 
318  BEAST_EXPECT((*ski == *skj) == (i == j));
319  }
320  }
321  }
322 
323  void testBase58 ()
324  {
325  testcase ("Base58: secp256k1");
326 
327  {
328  auto const pk1 = derivePublicKey (
332  generateSeed ("masterpassphrase")));
333 
334  auto const pk2 = parseBase58<PublicKey> (
336  "n94a1u4jAz288pZLtw6yFWVbi89YamiC6JBXPVUj5zmExe5fTVg9");
337  BEAST_EXPECT(pk2);
338 
339  BEAST_EXPECT(pk1 == *pk2);
340  }
341 
343 
344  testcase ("Base58: ed25519");
345 
346  {
347  auto const pk1 = derivePublicKey (
351  generateSeed ("masterpassphrase")));
352 
353  auto const pk2 = parseBase58<PublicKey> (
355  "nHUeeJCSY2dM71oxM8Cgjouf5ekTuev2mwDpc374aLMxzDLXNmjf");
356  BEAST_EXPECT(pk2);
357 
358  BEAST_EXPECT(pk1 == *pk2);
359  }
360 
362  }
363 
365  {
366  testcase ("Miscellaneous operations");
367 
368  auto const pk1 = derivePublicKey (
372  generateSeed ("masterpassphrase")));
373 
374  PublicKey pk2 (pk1);
375  BEAST_EXPECT(pk1 == pk2);
376  BEAST_EXPECT(pk2 == pk1);
377 
378  PublicKey pk3;
379  pk3 = pk2;
380  BEAST_EXPECT(pk3 == pk2);
381  BEAST_EXPECT(pk1 == pk3);
382  }
383 
384  void run() override
385  {
386  testBase58();
387  testCanonical();
389  }
390 };
391 
392 BEAST_DEFINE_TESTSUITE(PublicKey,protocol,ripple);
393 
394 } // 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:199
ripple::PublicKey_test::testCanonical
void testCanonical()
Definition: PublicKey_test.cpp:83
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:29
std::distance
T distance(T... args)
ripple::PublicKey_test::check
bool check(boost::optional< ECDSACanonicality > answer, std::string const &s)
Definition: PublicKey_test.cpp:76
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:228
ripple::PublicKey_test::testBase58
void testBase58(KeyType keyType)
Definition: PublicKey_test.cpp:230
std::array
STL class.
ripple::ecdsaCanonicality
boost::optional< ECDSACanonicality > ecdsaCanonicality(Slice const &sig)
Determine whether a signature is canonical.
Definition: PublicKey.cpp:116
ripple::generateSecretKey
SecretKey generateSecretKey(KeyType type, Seed const &seed)
Generate a new secret key deterministically.
Definition: SecretKey.cpp:199
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:74
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::PublicKey_test::hex_to_binary
static void hex_to_binary(FwdIter first, FwdIter last, Container &out)
Definition: PublicKey_test.cpp:35
ripple::TokenType::NodePublic
@ NodePublic
std::size_t
ripple::PublicKey_test::testBase58
void testBase58()
Definition: PublicKey_test.cpp:323
ripple::PublicKey_test::run
void run() override
Definition: PublicKey_test.cpp:384
ripple::PublicKey_test::testMiscOperations
void testMiscOperations()
Definition: PublicKey_test.cpp:364
ripple::randomSecretKey
SecretKey randomSecretKey()
Create a secret key using secure random numbers.
Definition: SecretKey.cpp:184
std::hash