Fabcoin Core  0.16.2
P2P Digital Currency
crypto.cpp
Go to the documentation of this file.
1 /*
2  This file is part of cpp-ethereum.
3 
4  cpp-ethereum is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  cpp-ethereum is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16 */
24 #include <libdevcore/Guards.h>
25 #include <secp256k1.h>
26 #include <cryptopp/keccak.h>
27 #include <cryptopp/pwdbased.h>
28 #include <cryptopp/sha.h>
29 #include <cryptopp/modes.h>
30 #include <cryptopp/eccrypto.h>
31 #include <cryptopp/osrng.h>
32 #include <cryptopp/oids.h>
33 #include <cryptopp/dsa.h>
34 #include <libdevcore/Common.h>
35 #include <libdevcore/RLP.h>
36 #include <libdevcore/Log.h>
37 #include <boost/test/unit_test.hpp>
38 #include <libdevcore/SHA3.h>
39 #include <libdevcrypto/ECDHE.h>
40 #include <libdevcrypto/CryptoPP.h>
42 
43 using namespace std;
44 using namespace dev;
45 using namespace dev::test;
46 using namespace dev::crypto;
47 using namespace CryptoPP;
48 
49 BOOST_AUTO_TEST_SUITE(Crypto)
50 
52  DevcryptoTestFixture() : s_secp256k1(Secp256k1PP::get()) {}
53 
55 };
57 
58 static CryptoPP::AutoSeededRandomPool& rng()
59 {
60  static CryptoPP::AutoSeededRandomPool s_rng;
61  return s_rng;
62 }
63 
64 static CryptoPP::OID& curveOID()
65 {
66  static CryptoPP::OID s_curveOID(CryptoPP::ASN1::secp256k1());
67  return s_curveOID;
68 }
69 
70 static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP>& params()
71 {
72  static CryptoPP::DL_GroupParameters_EC<CryptoPP::ECP> s_params(curveOID());
73  return s_params;
74 }
75 
77 {
78  BOOST_REQUIRE_EQUAL(sha3(""), h256("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
79  BOOST_REQUIRE_EQUAL(sha3("hello"), h256("1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8"));
80 }
81 
82 BOOST_AUTO_TEST_CASE(emptySHA3Types)
83 {
84  h256 emptySHA3(fromHex("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"));
85  BOOST_REQUIRE_EQUAL(emptySHA3, EmptySHA3);
86 
87  h256 emptyListSHA3(fromHex("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"));
88  BOOST_REQUIRE_EQUAL(emptyListSHA3, EmptyListSHA3);
89 }
90 
91 BOOST_AUTO_TEST_CASE(pubkeyOfZero)
92 {
93  auto pub = toPublic({});
94  BOOST_REQUIRE_EQUAL(pub, Public{});
95 }
96 
98 {
99  KeyPair k = KeyPair::create();
100  BOOST_REQUIRE(!!k.secret());
101  BOOST_REQUIRE(!!k.pub());
102  Public test = toPublic(k.secret());
103  BOOST_CHECK_EQUAL(k.pub(), test);
104 }
105 
107 {
108  KeyPair p(Secret(fromHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4")));
109  BOOST_REQUIRE(p.pub() == Public(fromHex("97466f2b32bc3bb76d4741ae51cd1d8578b48d3f1e68da206d47321aec267ce78549b514e4453d74ef11b0cd5e4e4c364effddac8b51bcfc8de80682f952896f")));
110  BOOST_REQUIRE(p.address() == Address(fromHex("8a40bfaa73256b60764c1bf40675a99083efb075")));
111  eth::Transaction t(1000, 0, 0, h160(fromHex("944400f4b88ac9589a0f17ed4671da26bddb668b")), {}, 0, p.secret());
112  auto rlp = t.rlp(eth::WithoutSignature);
113  auto expectedRlp = "dc80808094944400f4b88ac9589a0f17ed4671da26bddb668b8203e880";
114  BOOST_CHECK_EQUAL(toHex(rlp), expectedRlp);
115  rlp = t.rlp(eth::WithSignature);
116  auto expectedRlp2 = "f85f80808094944400f4b88ac9589a0f17ed4671da26bddb668b8203e8801ca0bd2402a510c9c9afddf2a3f63c869573bd257475bea91d6f164638134a3386d6a0609ad9775fd2715e6a359c627e9338478e4adba65dd0dc6ef2bcbe6398378984";
117  BOOST_CHECK_EQUAL(toHex(rlp), expectedRlp2);
118  BOOST_CHECK_EQUAL(t.sender(), p.address());
119 }
120 
121 BOOST_AUTO_TEST_CASE(KeyPairVerifySecret)
122 {
123  auto keyPair = KeyPair::create();
125  BOOST_CHECK(secp256k1_ec_seckey_verify(ctx, keyPair.secret().data()));
127 }
128 
129 BOOST_AUTO_TEST_CASE(SignAndRecover)
130 {
131  // This basic test that compares **fixed** results. Useful to test new
132  // implementations or changes to implementations.
133  auto sec = Secret{sha3("sec")};
134  auto msg = sha3("msg");
135  auto sig = sign(sec, msg);
136  auto expectedSig = "b826808a8c41e00b7c5d71f211f005a84a7b97949d5e765831e1da4e34c9b8295d2a622eee50f25af78241c1cb7cfff11bcf2a13fe65dee1e3b86fd79a4e3ed000";
137  BOOST_CHECK_EQUAL(sig.hex(), expectedSig);
138 
139  auto pub = recover(sig, msg);
140  auto expectedPub = "e40930c838d6cca526795596e368d16083f0672f4ab61788277abfa23c3740e1cc84453b0b24f49086feba0bd978bb4446bae8dff1e79fcc1e9cf482ec2d07c3";
141  BOOST_CHECK_EQUAL(pub.hex(), expectedPub);
142 }
143 
144 BOOST_AUTO_TEST_CASE(SignAndRecoverLoop)
145 {
146  auto num = 13;
147  auto msg = h256::random();
148  while (--num)
149  {
150  msg = sha3(msg);
151  auto kp = KeyPair::create();
152  auto sig = sign(kp.secret(), msg);
153  BOOST_CHECK(verify(kp.pub(), sig, msg));
154  auto pub = recover(sig, msg);
155  BOOST_CHECK_EQUAL(kp.pub(), pub);
156  }
157 }
158 
159 BOOST_AUTO_TEST_CASE(cryptopp_patch)
160 {
161  KeyPair k = KeyPair::create();
162  bytes io_text;
163  s_secp256k1->decrypt(k.secret(), io_text);
164  BOOST_REQUIRE_EQUAL(io_text.size(), 0);
165 }
166 
167 BOOST_AUTO_TEST_CASE(verify_secert)
168 {
169  Secret empty;
170  KeyPair kNot(empty);
171  BOOST_REQUIRE(!kNot.address());
172  KeyPair k(sha3(empty));
173  BOOST_REQUIRE(k.address());
174 }
175 
176 BOOST_AUTO_TEST_CASE(common_encrypt_decrypt)
177 {
178  string message("Now is the time for all good persons to come to the aid of humanity.");
179  bytes m = asBytes(message);
180  bytesConstRef bcr(&m);
181 
182  KeyPair k = KeyPair::create();
183  bytes cipher;
184  encrypt(k.pub(), bcr, cipher);
185  BOOST_REQUIRE(cipher != asBytes(message) && cipher.size() > 0);
186 
187  bytes plain;
188  decrypt(k.secret(), bytesConstRef(&cipher), plain);
189 
190  BOOST_REQUIRE(asString(plain) == message);
191  BOOST_REQUIRE(plain == asBytes(message));
192 }
193 
194 BOOST_AUTO_TEST_CASE(sha3_norestart)
195 {
197  bytes input(asBytes("test"));
198  ctx.Update(input.data(), 4);
199  CryptoPP::Keccak_256 ctxCopy(ctx);
200  bytes interimDigest(32);
201  ctx.Final(interimDigest.data());
202  ctx.Update(input.data(), 4);
203  bytes firstDigest(32);
204  ctx.Final(firstDigest.data());
205  BOOST_REQUIRE(interimDigest == firstDigest);
206 
207  ctxCopy.Update(input.data(), 4);
208  bytes finalDigest(32);
209  ctxCopy.Final(interimDigest.data());
210  BOOST_REQUIRE(interimDigest != finalDigest);
211 
212  // we can do this another way -- copy the context for final
213  ctxCopy.Update(input.data(), 4);
214  ctxCopy.Update(input.data(), 4);
215  CryptoPP::Keccak_256 finalCtx(ctxCopy);
216  bytes finalDigest2(32);
217  finalCtx.Final(finalDigest2.data());
218  BOOST_REQUIRE(finalDigest2 == interimDigest);
219  ctxCopy.Update(input.data(), 4);
220  bytes finalDigest3(32);
221  finalCtx.Final(finalDigest3.data());
222  BOOST_REQUIRE(finalDigest2 != finalDigest3);
223 }
224 
226 {
227  KeyPair local = KeyPair::create();
228  KeyPair remote = KeyPair::create();
229  // nonce
230  Secret z1;
231  ecdh::agree(local.secret(), remote.pub(), z1);
232  auto key1 = s_secp256k1->eciesKDF(z1, bytes(), 64);
233  bytesConstRef eKey1 = bytesConstRef(&key1).cropped(0, 32);
234  bytesRef mKey1 = bytesRef(&key1).cropped(32, 32);
235  sha3(mKey1, mKey1);
236 
237  Secret z2;
238  ecdh::agree(remote.secret(), local.pub(), z2);
239  auto key2 = s_secp256k1->eciesKDF(z2, bytes(), 64);
240  bytesConstRef eKey2 = bytesConstRef(&key2).cropped(0, 32);
241  bytesRef mKey2 = bytesRef(&key2).cropped(32, 32);
242  sha3(mKey2, mKey2);
243 
244  BOOST_REQUIRE(eKey1.toBytes() == eKey2.toBytes());
245  BOOST_REQUIRE(mKey1.toBytes() == mKey2.toBytes());
246 
247  BOOST_REQUIRE(!!z1);
248  BOOST_REQUIRE(z1 == z2);
249 
250  BOOST_REQUIRE(key1.size() > 0 && ((u512)h512(key1)) > 0);
251  BOOST_REQUIRE(key1 == key2);
252 }
253 
254 BOOST_AUTO_TEST_CASE(ecies_standard)
255 {
256  KeyPair k = KeyPair::create();
257 
258  string message("Now is the time for all good persons to come to the aid of humanity.");
259  string original = message;
260  bytes b = asBytes(message);
261 
262  s_secp256k1->encryptECIES(k.pub(), b);
263  BOOST_REQUIRE(b != asBytes(original));
264  BOOST_REQUIRE(b.size() > 0 && b[0] == 0x04);
265 
266  s_secp256k1->decryptECIES(k.secret(), b);
267  BOOST_REQUIRE(bytesConstRef(&b).cropped(0, original.size()).toBytes() == asBytes(original));
268 }
269 
270 BOOST_AUTO_TEST_CASE(ecies_sharedMacData)
271 {
272  KeyPair k = KeyPair::create();
273 
274  string message("Now is the time for all good persons to come to the aid of humanity.");
275  string original = message;
276  bytes b = asBytes(message);
277 
278  string shared("shared MAC data");
279  string wrongShared("wrong shared MAC data");
280 
281  s_secp256k1->encryptECIES(k.pub(), shared, b);
282  BOOST_REQUIRE(b != asBytes(original));
283  BOOST_REQUIRE(b.size() > 0 && b[0] == 0x04);
284 
285  BOOST_REQUIRE(!s_secp256k1->decryptECIES(k.secret(), wrongShared, b));
286 
287  s_secp256k1->decryptECIES(k.secret(), shared, b);
288 
289  // Temporary disable this assertion, which is failing in TravisCI only for Ubuntu Trusty.
290  // See https://travis-ci.org/bobsummerwill/cpp-ethereum/jobs/143250866.
291  #if !defined(DISABLE_BROKEN_UNIT_TESTS_UNTIL_WE_FIX_THEM)
292  BOOST_REQUIRE(bytesConstRef(&b).cropped(0, original.size()).toBytes() == asBytes(original));
293  #endif // !defined(DISABLE_BROKEN_UNIT_TESTS_UNTIL_WE_FIX_THEM)
294 }
295 
296 BOOST_AUTO_TEST_CASE(ecies_eckeypair)
297 {
298  KeyPair k = KeyPair::create();
299 
300  string message("Now is the time for all good persons to come to the aid of humanity.");
301  string original = message;
302 
303  bytes b = asBytes(message);
304  s_secp256k1->encrypt(k.pub(), b);
305  BOOST_REQUIRE(b != asBytes(original));
306 
307  s_secp256k1->decrypt(k.secret(), b);
308  BOOST_REQUIRE(b == asBytes(original));
309 }
310 
311 BOOST_AUTO_TEST_CASE(ecdhCryptopp)
312 {
313  ECDH<ECP>::Domain dhLocal(curveOID());
314  SecByteBlock privLocal(dhLocal.PrivateKeyLength());
315  SecByteBlock pubLocal(dhLocal.PublicKeyLength());
316  dhLocal.GenerateKeyPair(rng(), privLocal, pubLocal);
317 
318  ECDH<ECP>::Domain dhRemote(curveOID());
319  SecByteBlock privRemote(dhRemote.PrivateKeyLength());
320  SecByteBlock pubRemote(dhRemote.PublicKeyLength());
321  dhRemote.GenerateKeyPair(rng(), privRemote, pubRemote);
322 
323  assert(dhLocal.AgreedValueLength() == dhRemote.AgreedValueLength());
324 
325  // local: send public to remote; remote: send public to local
326 
327  // Local
328  SecByteBlock sharedLocal(dhLocal.AgreedValueLength());
329  assert(dhLocal.Agree(sharedLocal, privLocal, pubRemote));
330 
331  // Remote
332  SecByteBlock sharedRemote(dhRemote.AgreedValueLength());
333  assert(dhRemote.Agree(sharedRemote, privRemote, pubLocal));
334 
335  // Test
336  Integer ssLocal, ssRemote;
337  ssLocal.Decode(sharedLocal.BytePtr(), sharedLocal.SizeInBytes());
338  ssRemote.Decode(sharedRemote.BytePtr(), sharedRemote.SizeInBytes());
339 
340  assert(ssLocal != 0);
341  assert(ssLocal == ssRemote);
342 
343 
344  // Now use our keys
345  KeyPair a = KeyPair::create();
346  byte puba[65] = {0x04};
347  memcpy(&puba[1], a.pub().data(), 64);
348 
349  KeyPair b = KeyPair::create();
350  byte pubb[65] = {0x04};
351  memcpy(&pubb[1], b.pub().data(), 64);
352 
353  ECDH<ECP>::Domain dhA(curveOID());
354  Secret shared;
355  BOOST_REQUIRE(dhA.Agree(shared.writable().data(), a.secret().data(), pubb));
356  BOOST_REQUIRE(shared);
357 }
358 
360 {
361  ECDHE local;
362  ECDHE remote;
363  BOOST_CHECK_NE(local.pubkey(), remote.pubkey());
364 
365  // local tx pubkey -> remote
366  Secret sremote;
367  remote.agree(local.pubkey(), sremote);
368 
369  // remote tx pbukey -> local
370  Secret slocal;
371  local.agree(remote.pubkey(), slocal);
372 
373  BOOST_REQUIRE(sremote);
374  BOOST_REQUIRE(slocal);
375  BOOST_CHECK_EQUAL(sremote, slocal);
376 }
377 
379 {
380  auto sec = Secret{sha3("ecdhAgree")};
381  auto pub = toPublic(sec);
382  Secret sharedSec;
383  ecdh::agree(sec, pub, sharedSec);
384  BOOST_CHECK(sharedSec);
385  auto expectedSharedSec = "8ac7e464348b85d9fdfc0a81f2fdc0bbbb8ee5fb3840de6ed60ad9372e718977";
386  BOOST_CHECK_EQUAL(sharedSec.makeInsecure().hex(), expectedSharedSec);
387 }
388 
389 BOOST_AUTO_TEST_CASE(handshakeNew)
390 {
391  // authInitiator -> E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0)
392  // authRecipient -> E(remote-pubk, ecdhe-random-pubk || nonce || 0x0)
393 
394  h256 base(sha3("privacy"));
395  sha3(base.ref(), base.ref());
396  Secret nodeAsecret(base);
397  KeyPair nodeA(nodeAsecret);
398  BOOST_REQUIRE(nodeA.pub());
399 
400  sha3(base.ref(), base.ref());
401  Secret nodeBsecret(base);
402  KeyPair nodeB(nodeBsecret);
403  BOOST_REQUIRE(nodeB.pub());
404 
405  BOOST_REQUIRE_NE(nodeA.secret(), nodeB.secret());
406 
407  // Initiator is Alice (nodeA)
408  ECDHE eA;
409  bytes nAbytes(fromHex("0xAAAA"));
410  h256 nonceA(sha3(nAbytes));
412  Secret ssA;
413  {
414  bytesRef sig(&auth[0], Signature::size);
415  bytesRef hepubk(&auth[Signature::size], h256::size);
416  bytesRef pubk(&auth[Signature::size + h256::size], Public::size);
417  bytesRef nonce(&auth[Signature::size + h256::size + Public::size], h256::size);
418 
419  crypto::ecdh::agree(nodeA.secret(), nodeB.pub(), ssA);
420  sign(eA.seckey(), (ssA ^ nonceA).makeInsecure()).ref().copyTo(sig);
421  sha3(eA.pubkey().ref(), hepubk);
422  nodeA.pub().ref().copyTo(pubk);
423  nonceA.ref().copyTo(nonce);
424  auth[auth.size() - 1] = 0x0;
425  }
426  bytes authcipher;
427  encrypt(nodeB.pub(), &auth, authcipher);
428  BOOST_REQUIRE_EQUAL(authcipher.size(), 279);
429 
430  // Receipient is Bob (nodeB)
431  ECDHE eB;
432  bytes nBbytes(fromHex("0xBBBB"));
433  h256 nonceB(sha3(nAbytes));
434  bytes ack(Public::size + h256::size + 1);
435  {
436  // todo: replace nodeA.pub() in encrypt()
437  // decrypt public key from auth
438  bytes authdecrypted;
439  decrypt(nodeB.secret(), &authcipher, authdecrypted);
440  Public node;
441  bytesConstRef pubk(&authdecrypted[Signature::size + h256::size], Public::size);
442  pubk.copyTo(node.ref());
443 
444  bytesRef epubk(&ack[0], Public::size);
445  bytesRef nonce(&ack[Public::size], h256::size);
446 
447  eB.pubkey().ref().copyTo(epubk);
448  nonceB.ref().copyTo(nonce);
449  auth[auth.size() - 1] = 0x0;
450  }
451  bytes ackcipher;
452  encrypt(nodeA.pub(), &ack, ackcipher);
453  BOOST_REQUIRE_EQUAL(ackcipher.size(), 182);
454 
455  BOOST_REQUIRE(eA.pubkey());
456  BOOST_REQUIRE(eB.pubkey());
457  BOOST_REQUIRE_NE(eA.seckey(), eB.seckey());
458 
460  Secret aEncryptK;
461  Secret aMacK;
462  Secret aEgressMac;
463  Secret aIngressMac;
464  {
465  bytes ackdecrypted;
466  decrypt(nodeA.secret(), &ackcipher, ackdecrypted);
467  BOOST_REQUIRE(ackdecrypted.size());
468  bytesConstRef ackRef(&ackdecrypted);
469  Public eBAck;
470  h256 nonceBAck;
471  ackRef.cropped(0, Public::size).copyTo(bytesRef(eBAck.data(), Public::size));
472  ackRef.cropped(Public::size, h256::size).copyTo(nonceBAck.ref());
473  BOOST_REQUIRE_EQUAL(eBAck, eB.pubkey());
474  BOOST_REQUIRE_EQUAL(nonceBAck, nonceB);
475 
476  // TODO: export ess and require equal to b
477 
478  bytes keyMaterialBytes(512);
479  bytesRef keyMaterial(&keyMaterialBytes);
480 
481  Secret ess;
482  // todo: ecdh-agree should be able to output bytes
483  eA.agree(eBAck, ess);
484  ess.ref().copyTo(keyMaterial.cropped(0, h256::size));
485  ssA.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
486 // auto token = sha3(ssA);
487  aEncryptK = sha3Secure(keyMaterial);
488  aEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
489  aMacK = sha3Secure(keyMaterial);
490 
491  keyMaterialBytes.resize(h256::size + authcipher.size());
492  keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
493  (aMacK ^ nonceBAck).ref().copyTo(keyMaterial);
494  bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size()));
495  aEgressMac = sha3Secure(keyMaterial);
496 
497  keyMaterialBytes.resize(h256::size + ackcipher.size());
498  keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
499  (aMacK ^ nonceA).ref().copyTo(keyMaterial);
500  bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size()));
501  aIngressMac = sha3Secure(keyMaterial);
502  }
503 
504 
506  Secret ssB;
507  crypto::ecdh::agree(nodeB.secret(), nodeA.pub(), ssB);
508  BOOST_REQUIRE_EQUAL(ssA, ssB);
509 
510  Secret bEncryptK;
511  Secret bMacK;
512  Secret bEgressMac;
513  Secret bIngressMac;
514  {
515  bytes authdecrypted;
516  decrypt(nodeB.secret(), &authcipher, authdecrypted);
517  BOOST_REQUIRE(authdecrypted.size());
518  bytesConstRef ackRef(&authdecrypted);
519  Signature sigAuth;
520  h256 heA;
521  Public eAAuth;
522  Public nodeAAuth;
523  h256 nonceAAuth;
524  bytesConstRef sig(&authdecrypted[0], Signature::size);
525  bytesConstRef hepubk(&authdecrypted[Signature::size], h256::size);
526  bytesConstRef pubk(&authdecrypted[Signature::size + h256::size], Public::size);
527  bytesConstRef nonce(&authdecrypted[Signature::size + h256::size + Public::size], h256::size);
528 
529  nonce.copyTo(nonceAAuth.ref());
530  pubk.copyTo(nodeAAuth.ref());
531  BOOST_REQUIRE(nonceAAuth);
532  BOOST_REQUIRE_EQUAL(nonceA, nonceAAuth);
533  BOOST_REQUIRE(nodeAAuth);
534  BOOST_REQUIRE_EQUAL(nodeA.pub(), nodeAAuth); // bad test, bad!!!
535  hepubk.copyTo(heA.ref());
536  sig.copyTo(sigAuth.ref());
537 
538  Secret ss;
539  ecdh::agree(nodeB.secret(), nodeAAuth, ss);
540  eAAuth = recover(sigAuth, (ss ^ nonceAAuth).makeInsecure());
541  // todo: test when this fails; means remote is bad or packet bits were flipped
542  BOOST_REQUIRE_EQUAL(heA, sha3(eAAuth));
543  BOOST_REQUIRE_EQUAL(eAAuth, eA.pubkey());
544 
545  bytes keyMaterialBytes(512);
546  bytesRef keyMaterial(&keyMaterialBytes);
547 
548  Secret ess;
549  // todo: ecdh-agree should be able to output bytes
550  eB.agree(eAAuth, ess);
551 // s_secp256k1->agree(eB.seckey(), eAAuth, ess);
552  ess.ref().copyTo(keyMaterial.cropped(0, h256::size));
553  ssB.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
554 // auto token = sha3(ssA);
555  bEncryptK = sha3Secure(keyMaterial);
556  bEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
557  bMacK = sha3Secure(keyMaterial);
558 
559  // todo: replace nonceB with decrypted nonceB
560  keyMaterialBytes.resize(h256::size + ackcipher.size());
561  keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
562  (bMacK ^ nonceAAuth).ref().copyTo(keyMaterial);
563  bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size()));
564  bEgressMac = sha3Secure(keyMaterial);
565 
566  keyMaterialBytes.resize(h256::size + authcipher.size());
567  keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
568  (bMacK ^ nonceB).ref().copyTo(keyMaterial);
569  bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size()));
570  bIngressMac = sha3Secure(keyMaterial);
571  }
572 
573  BOOST_REQUIRE_EQUAL(aEncryptK, bEncryptK);
574  BOOST_REQUIRE_EQUAL(aMacK, bMacK);
575  BOOST_REQUIRE_EQUAL(aEgressMac, bIngressMac);
576  BOOST_REQUIRE_EQUAL(bEgressMac, aIngressMac);
577 
578 
579 
580 }
581 
582 BOOST_AUTO_TEST_CASE(ecies_aes128_ctr_unaligned)
583 {
584  SecureFixedHash<16> encryptK(sha3("..."), h128::AlignLeft);
585  h256 egressMac(sha3("+++"));
586  // TESTING: send encrypt magic sequence
587  bytes magic {0x22,0x40,0x08,0x91};
588  bytes magicCipherAndMac;
589  magicCipherAndMac = encryptSymNoAuth(encryptK, h128(), &magic);
590 
591  magicCipherAndMac.resize(magicCipherAndMac.size() + 32);
592  sha3mac(egressMac.ref(), &magic, egressMac.ref());
593  egressMac.ref().copyTo(bytesRef(&magicCipherAndMac).cropped(magicCipherAndMac.size() - 32, 32));
594 
595  bytesConstRef cipher(&magicCipherAndMac[0], magicCipherAndMac.size() - 32);
596  bytes plaintext = decryptSymNoAuth(encryptK, h128(), cipher).makeInsecure();
597 
598  plaintext.resize(magic.size());
599  // @alex @subtly TODO: FIX: this check is pointless with the above line.
600  BOOST_REQUIRE(plaintext.size() > 0);
601  BOOST_REQUIRE(magic == plaintext);
602 }
603 
604 BOOST_AUTO_TEST_CASE(ecies_aes128_ctr)
605 {
606  SecureFixedHash<16> k(sha3("0xAAAA"), h128::AlignLeft);
607  string m = "AAAAAAAAAAAAAAAA";
608  bytesConstRef msg((byte*)m.data(), m.size());
609 
610  bytes ciphertext;
611  h128 iv;
612  tie(ciphertext, iv) = encryptSymNoAuth(k, msg);
613 
614  bytes plaintext = decryptSymNoAuth(k, iv, &ciphertext).makeInsecure();
615  BOOST_REQUIRE_EQUAL(asString(plaintext), m);
616 }
617 
618 BOOST_AUTO_TEST_CASE(cryptopp_aes128_ctr)
619 {
620  const int aesKeyLen = 16;
621  BOOST_REQUIRE(sizeof(char) == sizeof(byte));
622 
623  // generate test key
624  AutoSeededRandomPool rng;
625  SecByteBlock key(0x00, aesKeyLen);
626  rng.GenerateBlock(key, key.size());
627 
628  // cryptopp uses IV as nonce/counter which is same as using nonce w/0 ctr
630  rng.GenerateBlock(ctr.data(), sizeof(ctr));
631 
632  // used for decrypt
633  FixedHash<AES::BLOCKSIZE> ctrcopy(ctr);
634 
635  string text = "Now is the time for all good persons to come to the aid of humanity.";
636  unsigned char const* in = (unsigned char*)&text[0];
637  unsigned char* out = (unsigned char*)&text[0];
638  string original = text;
639  string doublespeak = text + text;
640 
641  string cipherCopy;
642  try
643  {
645  e.SetKeyWithIV(key, key.size(), ctr.data());
646 
647  // 68 % 255 should be difference of counter
648  e.ProcessData(out, in, text.size());
649  ctr = h128(u128(ctr) + text.size() / 16);
650 
651  BOOST_REQUIRE(text != original);
652  cipherCopy = text;
653  }
654  catch (CryptoPP::Exception& _e)
655  {
656  cerr << _e.what() << endl;
657  }
658 
659  try
660  {
662  d.SetKeyWithIV(key, key.size(), ctrcopy.data());
663  d.ProcessData(out, in, text.size());
664  BOOST_REQUIRE(text == original);
665  }
666  catch (CryptoPP::Exception& _e)
667  {
668  cerr << _e.what() << endl;
669  }
670 
671 
672  // reencrypt ciphertext...
673  try
674  {
675  BOOST_REQUIRE(cipherCopy != text);
676  in = (unsigned char*)&cipherCopy[0];
677  out = (unsigned char*)&cipherCopy[0];
678 
680  e.SetKeyWithIV(key, key.size(), ctrcopy.data());
681  e.ProcessData(out, in, text.size());
682 
683  // yep, ctr mode.
684  BOOST_REQUIRE(cipherCopy == original);
685  }
686  catch (CryptoPP::Exception& _e)
687  {
688  cerr << _e.what() << endl;
689  }
690 
691 }
692 
693 BOOST_AUTO_TEST_CASE(cryptopp_aes128_cbc)
694 {
695  const int aesKeyLen = 16;
696  BOOST_REQUIRE(sizeof(char) == sizeof(byte));
697 
698  AutoSeededRandomPool rng;
699  SecByteBlock key(0x00, aesKeyLen);
700  rng.GenerateBlock(key, key.size());
701 
702  // Generate random IV
703  byte iv[AES::BLOCKSIZE];
704  rng.GenerateBlock(iv, AES::BLOCKSIZE);
705 
706  string string128("AAAAAAAAAAAAAAAA");
707  string plainOriginal = string128;
708 
709  CryptoPP::CBC_Mode<Rijndael>::Encryption cbcEncryption(key, key.size(), iv);
710  cbcEncryption.ProcessData((byte*)&string128[0], (byte*)&string128[0], string128.size());
711  BOOST_REQUIRE(string128 != plainOriginal);
712 
713  CBC_Mode<Rijndael>::Decryption cbcDecryption(key, key.size(), iv);
714  cbcDecryption.ProcessData((byte*)&string128[0], (byte*)&string128[0], string128.size());
715  BOOST_REQUIRE(plainOriginal == string128);
716 
717 
718  // plaintext whose size isn't divisible by block size must use stream filter for padding
719  string string192("AAAAAAAAAAAAAAAABBBBBBBB");
720  plainOriginal = string192;
721 
722  string cipher;
723  StreamTransformationFilter* aesStream = new StreamTransformationFilter(cbcEncryption, new StringSink(cipher));
724  StringSource source(string192, true, aesStream);
725  BOOST_REQUIRE(cipher.size() == 32);
726 
727  byte* pOut = reinterpret_cast<byte*>(&string192[0]);
728  byte const* pIn = reinterpret_cast<byte const*>(cipher.data());
729  cbcDecryption.ProcessData(pOut, pIn, cipher.size());
730  BOOST_REQUIRE(string192 == plainOriginal);
731 }
732 
734 {
735  // base secret
736  Secret secret(sha3("privacy"));
737 
738  // we get ec params from signer
740 
741  // e := sha3(msg)
742  bytes e(fromHex("0x01"));
743  e.resize(32);
744  int tests = 13;
745  while (sha3(&e, &e), secret = sha3(secret), tests--)
746  {
747  KeyPair key(secret);
748  Public pkey = key.pub();
749  signer.AccessKey().Initialize(params(), Integer(secret.data(), Secret::size));
750 
751  h256 he(sha3(e));
752  Integer heInt(he.asBytes().data(), 32);
753  h256 k(crypto::kdf(secret, he));
754  Integer kInt(k.asBytes().data(), 32);
755  kInt %= params().GetSubgroupOrder()-1;
756 
757  ECP::Point rp = params().ExponentiateBase(kInt);
758  Integer const& q = params().GetGroupOrder();
759  Integer r = params().ConvertElementToInteger(rp);
760 
761  Integer kInv = kInt.InverseMod(q);
762  Integer s = (kInv * (Integer(secret.data(), 32) * r + heInt)) % q;
763  BOOST_REQUIRE(!!r && !!s);
764 
765  //try recover function on diffrent v values (should be invalid)
766  for (size_t i = 0; i < 10; i++)
767  {
768  Signature sig;
769  sig[64] = i;
770  r.Encode(sig.data(), 32);
771  s.Encode(sig.data() + 32, 32);
772 
773  Public p = dev::recover(sig, he);
774  size_t expectI = rp.y.IsOdd() ? 1 : 0;
775  if (i == expectI)
776  BOOST_REQUIRE(p == pkey);
777  else
778  BOOST_REQUIRE(p != pkey);
779  }
780  }
781 }
782 
785 
Append input to a string object.
union node node
h256 EmptySHA3
Definition: SHA3.cpp:35
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
Definition: CommonData.h:54
h256 EmptyListSHA3
Definition: SHA3.cpp:36
uint8_t byte
Definition: Common.h:57
vector_ref< _T const > ref(_T const &_t)
Definition: vector_ref.h:115
byte * data()
Definition: FixedHash.h:139
Elliptical Curve Point over GF(p), where p is prime.
Definition: ecpoint.h:21
void Encode(byte *output, size_t outputLen, Signedness sign=UNSIGNED) const
Encode in big-endian format.
Definition: integer.cpp:3369
byte const * data() const
Definition: FixedHash.h:293
Class file for modes of operation.
bool IsOdd() const
Determines if the Integer is odd parity.
Definition: integer.h:345
CryptoPP secp256k1 algorithms.
Definition: CryptoPP.h:39
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
Definition: RLP.h:467
Do include a signature.
Definition: Transaction.h:39
bytesSec decryptSymNoAuth(SecureFixedHash< 16 > const &_k, h128 const &_iv, bytesConstRef _cipher)
Decrypts payload with specified IV/ctr using AES128-CTR.
Definition: Common.h:129
bool verify(Public const &_k, Signature const &_s, h256 const &_hash)
Verify signature.
Definition: Common.cpp:255
Simple class that represents a "key pair".
Definition: Common.h:150
#define SECP256K1_CONTEXT_NONE
Definition: secp256k1.h:156
Classes for Keccak message digests.
h160 Address
An Ethereum address: 20 bytes.
Definition: Common.h:62
SecureFixedHash< 32 > sha3Secure(bytesConstRef _input)
Definition: SHA3.h:41
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
std::pair< bytes, h128 > encryptSymNoAuth(SecureFixedHash< 16 > const &_k, bytesConstRef _plain)
Encrypts payload with random IV/ctr using AES128-CTR.
Definition: Common.cpp:157
ASN.1 object identifiers for algorthms and schemes.
SecureFixedHash< 32 > Secret
Definition: Common.h:35
std::hash for asio::adress
Definition: Common.h:323
assert(len-trim+(2 *lenIndices)<=WIDTH)
Secret const & secret() const
Definition: Common.h:167
std::vector< T > const & makeInsecure() const
Definition: Common.h:102
vector_ref< _T > cropped(size_t _begin, size_t _count) const
Definition: vector_ref.h:62
void agree(Public const &_remoteEphemeral, Secret &o_sharedSecret) const
Input public key for dh agreement, output generated shared secret.
Definition: ECDHE.cpp:27
h512 Public
A public key: 64 bytes.
Definition: Common.h:39
FixedHash< 64 > h512
Definition: FixedHash.h:339
Public pubkey()
Public key sent to remote.
Definition: ECDHE.h:44
BOOST_AUTO_TEST_CASE(sha3general)
Definition: crypto.cpp:76
unsigned int PublicKeyLength() const
Provides the size of the public key.
Definition: pubkey.h:1865
SECP256K1_API void secp256k1_context_destroy(secp256k1_context *ctx)
Destroy a secp256k1 context object.
Definition: secp256k1.c:92
unsigned int AgreedValueLength() const
Provides the size of the agreed value.
Definition: pubkey.h:1863
void retarget(_T *_d, size_t _s)
Definition: vector_ref.h:65
Public toPublic(Secret const &_secret)
Convert a secret key into the public key equivalent.
Definition: Common.cpp:67
#define a(i)
Do not include a signature.
Definition: Transaction.h:38
bytesConstRef ref() const
Definition: FixedHash.h:292
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
Definition: CommonData.cpp:99
Public const & pub() const
Retrieve the public key.
Definition: Common.h:170
const char * source
Definition: rpcconsole.cpp:60
vector_ref< byte > bytesRef
Definition: Common.h:76
virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
Generate a private/public key pair.
Definition: cryptlib.cpp:930
bytesRef ref()
Definition: FixedHash.h:133
SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ec_seckey_verify(const secp256k1_context *ctx, const unsigned char *seckey) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2)
Verify an ECDSA secret key.
Definition: secp256k1.c:391
Block cipher mode of operation aggregate.
Definition: modes.h:285
FixedHash< T > const & makeInsecure() const
Definition: FixedHash.h:253
bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const
Derive agreed value.
Definition: pubkey.h:1882
Public recover(Signature const &_sig, h256 const &_hash)
Recovers Public key from signed message hash.
Definition: Common.cpp:203
std::vector< byte > bytes
Definition: Common.h:75
Multiple precision integer with arithmetic operations.
Definition: integer.h:43
std::vector< unsigned char > toBytes() const
Definition: vector_ref.h:45
vector_ref< byte const > bytesConstRef
Definition: Common.h:77
h256 kdf(Secret const &_priv, h256 const &_hash)
Key derivation.
Definition: Common.cpp:322
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 512, 512, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u512
Definition: Common.h:129
FixedHash< T > & writable()
Definition: FixedHash.h:254
bytes asBytes(std::string const &_b)
Converts a string to a byte array containing the string&#39;s (byte) data.
Definition: CommonData.h:92
FixedHash< 32 > h256
Definition: FixedHash.h:340
unsigned int PrivateKeyLength() const
Provides the size of the private key.
Definition: pubkey.h:1864
Classes for the DSA signature algorithm.
Secp256k1PP * s_secp256k1
Definition: crypto.cpp:54
Encodes a transaction, ready to be exported to or freshly imported from RLP.
Definition: Transaction.h:84
#define b(i, j)
Keccak_Final< 32 > Keccak_256
Definition: keccak.h:96
Diffie-Hellman domain.
Definition: dh.h:25
Address const & address() const
Retrieve the associated address of the public key.
Definition: Common.h:173
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 128, 128, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u128
Definition: Common.h:124
Classes for SHA-1 and SHA-2 family of message digests.
bytes asBytes() const
Definition: FixedHash.h:145
Signature sign(Secret const &_k, h256 const &_hash)
Returns siganture of message hash.
Definition: Common.cpp:233
Password based key derivation functions.
Filter wrapper for StreamTransformation.
Definition: filters.h:491
FixedHash< 16 > h128
Definition: FixedHash.h:342
#define BOOST_FIXTURE_TEST_SUITE(a, b)
Definition: object.cpp:14
void encrypt(Public const &_k, bytesConstRef _plain, bytes &o_cipher)
Encrypts plain text using Public key.
Definition: Common.cpp:102
uint8_t const size_t const size
Definition: sha3.h:20
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:18
void * memcpy(void *a, const void *b, size_t c)
void copyTo(vector_ref< typename std::remove_const< _T >::type > _t) const
Copies the contents of this vector_ref to the contents of _t, up to the max size of _t...
Definition: vector_ref.h:69
bool decrypt(Secret const &_k, bytesConstRef _cipher, bytes &o_plaintext)
Decrypts cipher using Secret key.
Definition: Common.cpp:109
void agree(Secret const &_s, Public const &_r, Secret &o_s)
Definition: Common.cpp:348
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
Integer InverseMod(const Integer &n) const
calculate multiplicative inverse of *this mod n
Definition: integer.cpp:4370
#define BOOST_AUTO_TEST_SUITE_END()
Definition: object.cpp:16
void Decode(const byte *input, size_t inputLen, Signedness sign=UNSIGNED)
Decode from big-endian byte array.
Definition: integer.cpp:3314
#define e(i)
Definition: sha.cpp:733
Classes and functions for Elliptic Curves over prime and binary fields.
FixedHash< 20 > h160
Definition: FixedHash.h:341
#define d(i)
Definition: sha.cpp:732
void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output)
Calculate SHA3-256 MAC.
Definition: SHA3.h:65
Derive DH shared secret from EC keypairs.
Definition: ECDHE.h:37
SECP256K1_API secp256k1_context * secp256k1_context_create(unsigned int flags) SECP256K1_WARN_UNUSED_RESULT
Create a secp256k1 context object.
Definition: secp256k1.c:58
std::string asString(bytes const &_b)
Converts byte array to a string containing the same (binary) data.
Definition: CommonData.h:79
Classes for access to the operating system&#39;s random number generators.
Integer y
Definition: ecpoint.h:46
Helper functions to work with json::spirit and test files.
#define BOOST_CHECK(expr)
Definition: object.cpp:17
std::string hex() const
Definition: FixedHash.h:130
Template implementing constructors for public key algorithm classes.
Definition: pubkey.h:1989