fork download
  1. #ifndef KECCAK_DETAIL_HPP
  2. #define KECCAK_DETAIL_HPP
  3.  
  4. #include <cstddef>
  5. #include <cstdint>
  6. #include <cstring>
  7. #include <array>
  8.  
  9. namespace keccak
  10. {
  11. namespace detail
  12. {
  13. template <unsigned long long A, unsigned long long B>
  14. struct static_max
  15. {
  16. static const auto value = A > B ? A : B;
  17. };
  18.  
  19. template <unsigned N, unsigned C = 0>
  20. struct static_log2
  21. {
  22. static const unsigned value = static_log2<N / 2, C + 1>::value;
  23. };
  24.  
  25. template <unsigned C>
  26. struct static_log2<1, C>
  27. {
  28. static const unsigned value = C;
  29. };
  30.  
  31. template <unsigned C>
  32. struct static_log2<0, C>
  33. {
  34. static_assert(C >= 1, "Log2 result is not an integer.");
  35. static_assert(C < 1, "Log2 result is not an integer.");
  36. };
  37.  
  38. template <typename StateType, typename LaneType>
  39. void round(StateType& s, LaneType round_constant);
  40.  
  41. template <unsigned Rounds, typename StateType>
  42. void keccak_f(StateType& state);
  43.  
  44. template <typename LaneType, std::size_t Capacity>
  45. class keccak_state
  46. {
  47. public:
  48. typedef LaneType lane_type;
  49. typedef lane_type plane_type[5];
  50. typedef std::array<plane_type, 5> state_type;
  51.  
  52. static const std::size_t byte_bits = 8;
  53.  
  54. static const auto width = sizeof(lane_type) * byte_bits;
  55. static const auto capacity = Capacity;
  56. static const auto rate = 25 * width - capacity;
  57.  
  58. static const auto byte_width = width / byte_bits;
  59. static const auto byte_capacity = capacity / byte_bits;
  60. static const auto byte_rate = rate / byte_bits;
  61.  
  62. static const auto rounds = 12 + 2 * static_log2<width>::value;
  63.  
  64. static_assert(width % byte_bits == 0, "Sub-byte hacks are not supported.");
  65. static_assert(capacity % byte_bits == 0, "Sub-byte hacks are not supported.");
  66. static_assert(rate % byte_bits == 0, "Sub-byte hacks are not supported.");
  67.  
  68. static_assert(rate % width == 0, "Rate / width combination impossible.");
  69. static_assert(byte_rate % byte_width == 0, "Rate / width combination not supported.");
  70.  
  71. static_assert(capacity < 25 * width, "Capacity too high.");
  72.  
  73. private:
  74. state_type state_;
  75.  
  76. public:
  77. keccak_state()
  78. : state_()
  79. {}
  80.  
  81. const plane_type& operator [] (std::size_t i) const
  82. {
  83. return state_[i];
  84. }
  85.  
  86. plane_type& operator [] (std::size_t i)
  87. {
  88. return state_[i];
  89. }
  90.  
  91. const lane_type* data() const
  92. {
  93. return state_.data()[0];
  94. }
  95.  
  96. lane_type* data()
  97. {
  98. return state_.data()[0];
  99. }
  100.  
  101. void transform()
  102. {
  103. keccak_f<rounds>(state_);
  104. }
  105. };
  106.  
  107. template <typename StateType>
  108. class sponge_absorber
  109. {
  110. public:
  111. typedef StateType state_type;
  112. typedef typename state_type::lane_type lane_type;
  113.  
  114. private:
  115. state_type state_;
  116. std::size_t bytes_absorbed_;
  117.  
  118. public:
  119. sponge_absorber()
  120. : bytes_absorbed_()
  121. {}
  122.  
  123. sponge_absorber(const void* data, std::size_t size)
  124. : bytes_absorbed_()
  125. {
  126. (*this)(data, size);
  127. }
  128.  
  129. void operator () (const void* data, std::size_t size)
  130. {
  131. auto data_bytes = static_cast<const std::uint8_t*>(data);
  132.  
  133. while (size != 0)
  134. {
  135. while (bytes_absorbed_ == 0 && size >= state_type::byte_rate)
  136. {
  137. for (std::size_t i = 0; i != state_type::byte_rate / state_type::byte_width; ++i)
  138. {
  139. lane_type lane;
  140. std::memcpy(&lane, data_bytes + i * state_type::byte_width, state_type::byte_width);
  141. *(state_[0] + i) ^= lane;
  142. }
  143.  
  144. data_bytes += state_type::byte_rate;
  145. size -= state_type::byte_rate;
  146.  
  147. state_.transform();
  148. }
  149.  
  150. if (size != 0)
  151. {
  152. reinterpret_cast<std::uint8_t*>(state_.data())[bytes_absorbed_] ^= *data_bytes;
  153.  
  154. ++data_bytes;
  155. --size;
  156.  
  157. if (++bytes_absorbed_ == state_type::byte_rate)
  158. {
  159. state_.transform();
  160. bytes_absorbed_ = 0;
  161. }
  162. }
  163. }
  164. }
  165.  
  166. std::size_t bytes_absorbed() const
  167. {
  168. return bytes_absorbed_;
  169. }
  170.  
  171. const state_type& internal_state() const
  172. {
  173. return state_;
  174. }
  175.  
  176. state_type& internal_state()
  177. {
  178. return state_;
  179. }
  180. };
  181.  
  182. template <typename StateType>
  183. class sponge_squeezer
  184. {
  185. public:
  186. typedef StateType state_type;
  187. typedef typename state_type::lane_type lane_type;
  188.  
  189. private:
  190. state_type state_;
  191. std::size_t bytes_squeezed_;
  192.  
  193. public:
  194. sponge_squeezer(sponge_absorber<state_type> absorber)
  195. : state_(absorber.internal_state())
  196. , bytes_squeezed_()
  197. {
  198. reinterpret_cast<std::uint8_t*>(state_.data())[absorber.bytes_absorbed()] ^= 1u;
  199. reinterpret_cast<std::uint8_t*>(state_.data())[state_type::byte_rate - 1] ^= 128u;
  200. state_.transform();
  201. }
  202.  
  203. void operator () (void* buf, std::size_t size)
  204. {
  205. auto buf_bytes = static_cast<std::uint8_t*>(buf);
  206.  
  207. while (size != 0)
  208. {
  209. while (bytes_squeezed_ == 0 && size >= state_type::byte_rate)
  210. {
  211. std::memcpy(buf_bytes, state_.data(), state_type::byte_rate);
  212.  
  213. buf_bytes += state_type::byte_rate;
  214. size -= state_type::byte_rate;
  215.  
  216. state_.transform();
  217. }
  218.  
  219. if (size != 0)
  220. {
  221. const auto copy_size = std::min(size, state_type::byte_rate - bytes_squeezed_);
  222. const auto state_bytes = reinterpret_cast<std::uint8_t*>(state_.data());
  223.  
  224. std::memcpy(buf_bytes, state_bytes + bytes_squeezed_, copy_size);
  225.  
  226. buf_bytes += copy_size;
  227. size -= copy_size;
  228. bytes_squeezed_ += copy_size;
  229.  
  230. if (bytes_squeezed_ == state_type::byte_rate)
  231. {
  232. state_.transform();
  233. bytes_squeezed_ = 0;
  234. }
  235. }
  236. }
  237. }
  238.  
  239. std::size_t bytes_squeezed() const
  240. {
  241. return bytes_squeezed_;
  242. }
  243.  
  244. const state_type& internal_state() const
  245. {
  246. return state_;
  247. }
  248.  
  249. state_type& internal_state()
  250. {
  251. return state_;
  252. }
  253. };
  254.  
  255. const std::uint64_t round_constants[24] =
  256. {
  257. 0x0000000000000001ull,
  258. 0x0000000000008082ull,
  259. 0x800000000000808Aull,
  260. 0x8000000080008000ull,
  261. 0x000000000000808Bull,
  262. 0x0000000080000001ull,
  263. 0x8000000080008081ull,
  264. 0x8000000000008009ull,
  265. 0x000000000000008Aull,
  266. 0x0000000000000088ull,
  267. 0x0000000080008009ull,
  268. 0x000000008000000Aull,
  269. 0x000000008000808Bull,
  270. 0x800000000000008Bull,
  271. 0x8000000000008089ull,
  272. 0x8000000000008003ull,
  273. 0x8000000000008002ull,
  274. 0x8000000000000080ull,
  275. 0x000000000000800Aull,
  276. 0x800000008000000Aull,
  277. 0x8000000080008081ull,
  278. 0x8000000000008080ull,
  279. 0x0000000080000001ull,
  280. 0x8000000080008008ull,
  281. };
  282.  
  283. template <unsigned Rounds, typename StateType>
  284. void keccak_f(StateType& state)
  285. {
  286. for (unsigned i = 0; i != Rounds; ++i)
  287. {
  288. round(state, round_constants[i]);
  289. }
  290. }
  291.  
  292. template <unsigned N, typename Word>
  293. Word shl(Word w)
  294. {
  295. return w << (N);
  296. }
  297.  
  298. template <unsigned N, typename Word>
  299. Word shr(Word w)
  300. {
  301. return w >> (N);
  302. }
  303.  
  304. template <unsigned N, typename Word>
  305. Word rotr(Word w)
  306. {
  307. return shr<N>(w) | shl<sizeof(Word) * 8 - N>(w);
  308. }
  309.  
  310. template <unsigned N, typename Word>
  311. Word rotl(Word w)
  312. {
  313. return shl<N>(w) | shr<sizeof(Word) * 8 - N>(w);
  314. }
  315.  
  316. template <typename Word>
  317. Word rotr(Word w, unsigned n)
  318. {
  319. return (w >> n) | (w << (sizeof(Word) * 8 - n));
  320. }
  321.  
  322. template <typename Word>
  323. Word rotl(Word w, unsigned n)
  324. {
  325. return (w << n) | (w >> (sizeof(Word) * 8 - n));
  326. }
  327.  
  328. typedef unsigned rotation_offset_type;
  329.  
  330. const rotation_offset_type roffset_0_0 = 0;
  331. const rotation_offset_type roffset_0_1 = 36;
  332. const rotation_offset_type roffset_0_2 = 3;
  333. const rotation_offset_type roffset_0_3 = 41;
  334. const rotation_offset_type roffset_0_4 = 18;
  335.  
  336. const rotation_offset_type roffset_1_0 = 1;
  337. const rotation_offset_type roffset_1_1 = 44;
  338. const rotation_offset_type roffset_1_2 = 10;
  339. const rotation_offset_type roffset_1_3 = 45;
  340. const rotation_offset_type roffset_1_4 = 2;
  341.  
  342. const rotation_offset_type roffset_2_0 = 62;
  343. const rotation_offset_type roffset_2_1 = 6;
  344. const rotation_offset_type roffset_2_2 = 43;
  345. const rotation_offset_type roffset_2_3 = 15;
  346. const rotation_offset_type roffset_2_4 = 61;
  347.  
  348. const rotation_offset_type roffset_3_0 = 28;
  349. const rotation_offset_type roffset_3_1 = 55;
  350. const rotation_offset_type roffset_3_2 = 25;
  351. const rotation_offset_type roffset_3_3 = 21;
  352. const rotation_offset_type roffset_3_4 = 56;
  353.  
  354. const rotation_offset_type roffset_4_0 = 27;
  355. const rotation_offset_type roffset_4_1 = 20;
  356. const rotation_offset_type roffset_4_2 = 39;
  357. const rotation_offset_type roffset_4_3 = 8;
  358. const rotation_offset_type roffset_4_4 = 14;
  359.  
  360. template <typename StateType, typename LaneType>
  361. void round(StateType& s, LaneType round_constant)
  362. {
  363. auto c0 = s[0][0] ^ s[1][0] ^ s[2][0] ^ s[3][0] ^ s[4][0];
  364. auto c1 = s[0][1] ^ s[1][1] ^ s[2][1] ^ s[3][1] ^ s[4][1];
  365. auto c2 = s[0][2] ^ s[1][2] ^ s[2][2] ^ s[3][2] ^ s[4][2];
  366. auto c3 = s[0][3] ^ s[1][3] ^ s[2][3] ^ s[3][3] ^ s[4][3];
  367. auto c4 = s[0][4] ^ s[1][4] ^ s[2][4] ^ s[3][4] ^ s[4][4];
  368.  
  369. auto d0 = c4 ^ rotl<1>(c1);
  370. auto d1 = c0 ^ rotl<1>(c2);
  371. auto d2 = c1 ^ rotl<1>(c3);
  372. auto d3 = c2 ^ rotl<1>(c4);
  373. auto d4 = c3 ^ rotl<1>(c0);
  374.  
  375. s[0][0] ^= d0;
  376. s[0][1] ^= d1;
  377. s[0][2] ^= d2;
  378. s[0][3] ^= d3;
  379.  
  380. auto s00 = (s[0][0]); /* rotl<roffset_0_0> */
  381. auto s20 = rotl<roffset_1_0>(s[0][1]);
  382. auto s40 = rotl<roffset_2_0>(s[0][2]);
  383. auto s10 = rotl<roffset_3_0>(s[0][3]);
  384.  
  385. s[0][4] ^= d4;
  386. s[1][0] ^= d0;
  387. s[1][1] ^= d1;
  388. s[1][2] ^= d2;
  389.  
  390. auto s30 = rotl<roffset_4_0>(s[0][4]);
  391. auto s31 = rotl<roffset_0_1>(s[1][0]);
  392. auto s01 = rotl<roffset_1_1>(s[1][1]);
  393. auto s21 = rotl<roffset_2_1>(s[1][2]);
  394.  
  395. s[1][3] ^= d3;
  396. s[1][4] ^= d4;
  397. s[2][0] ^= d0;
  398. s[2][1] ^= d1;
  399.  
  400. auto s41 = rotl<roffset_3_1>(s[1][3]);
  401. auto s11 = rotl<roffset_4_1>(s[1][4]);
  402. auto s12 = rotl<roffset_0_2>(s[2][0]);
  403. auto s32 = rotl<roffset_1_2>(s[2][1]);
  404.  
  405. s[2][2] ^= d2;
  406. s[2][3] ^= d3;
  407. s[2][4] ^= d4;
  408. s[3][0] ^= d0;
  409.  
  410. auto s02 = rotl<roffset_2_2>(s[2][2]);
  411. auto s22 = rotl<roffset_3_2>(s[2][3]);
  412. auto s42 = rotl<roffset_4_2>(s[2][4]);
  413. auto s43 = rotl<roffset_0_3>(s[3][0]);
  414.  
  415. s[3][1] ^= d1;
  416. s[3][2] ^= d2;
  417. s[3][3] ^= d3;
  418. s[3][4] ^= d4;
  419.  
  420. auto s13 = rotl<roffset_1_3>(s[3][1]);
  421. auto s33 = rotl<roffset_2_3>(s[3][2]);
  422. auto s03 = rotl<roffset_3_3>(s[3][3]);
  423. auto s23 = rotl<roffset_4_3>(s[3][4]);
  424.  
  425. s[4][0] ^= d0;
  426. s[4][1] ^= d1;
  427. s[4][2] ^= d2;
  428. s[4][3] ^= d3;
  429.  
  430. auto s24 = rotl<roffset_0_4>(s[4][0]);
  431. auto s44 = rotl<roffset_1_4>(s[4][1]);
  432. auto s14 = rotl<roffset_2_4>(s[4][2]);
  433. auto s34 = rotl<roffset_3_4>(s[4][3]);
  434.  
  435. s[4][4] ^= d4;
  436. auto s04 = rotl<roffset_4_4>(s[4][4]);
  437.  
  438. //
  439. s[0][0] = s00 ^ (~s01 & s02);
  440. s[0][1] = s01 ^ (~s02 & s03);
  441. s[0][2] = s02 ^ (~s03 & s04);
  442. s[0][3] = s03 ^ (~s04 & s00);
  443. s[0][4] = s04 ^ (~s00 & s01);
  444.  
  445. s[1][0] = s10 ^ (~s11 & s12);
  446. s[1][1] = s11 ^ (~s12 & s13);
  447. s[1][2] = s12 ^ (~s13 & s14);
  448. s[1][3] = s13 ^ (~s14 & s10);
  449. s[1][4] = s14 ^ (~s10 & s11);
  450.  
  451. s[2][0] = s20 ^ (~s21 & s22);
  452. s[2][1] = s21 ^ (~s22 & s23);
  453. s[2][2] = s22 ^ (~s23 & s24);
  454. s[2][3] = s23 ^ (~s24 & s20);
  455. s[2][4] = s24 ^ (~s20 & s21);
  456.  
  457. s[3][0] = s30 ^ (~s31 & s32);
  458. s[3][1] = s31 ^ (~s32 & s33);
  459. s[3][2] = s32 ^ (~s33 & s34);
  460. s[3][3] = s33 ^ (~s34 & s30);
  461. s[3][4] = s34 ^ (~s30 & s31);
  462.  
  463. s[4][0] = s40 ^ (~s41 & s42);
  464. s[4][1] = s41 ^ (~s42 & s43);
  465. s[4][2] = s42 ^ (~s43 & s44);
  466. s[4][3] = s43 ^ (~s44 & s40);
  467. s[4][4] = s44 ^ (~s40 & s41);
  468.  
  469. s[0][0] ^= round_constant;
  470. }
  471. }
  472. }
  473.  
  474. #endif
  475.  
  476.  
  477.  
  478.  
  479. #ifndef KECCAK_HPP
  480. #define KECCAK_HPP
  481.  
  482. #include <array>
  483. #include <cstdint>
  484. #include <limits>
  485.  
  486. //#include "keccak_detail.hpp"
  487.  
  488. namespace keccak
  489. {
  490. template <std::size_t CollisionResistance, std::size_t PreimageResistance>
  491. class basic_hasher
  492. {
  493. public:
  494. static const auto collision_resistance = CollisionResistance;
  495. static const auto preimage_resistance = PreimageResistance;
  496.  
  497. static const auto capacity = detail::static_max<collision_resistance * 2, preimage_resistance * 2>::value;
  498. static const auto hash_size = detail::static_max<collision_resistance * 2 / 8, preimage_resistance / 8>::value;
  499.  
  500. typedef detail::keccak_state<std::uint64_t, capacity> state_type;
  501.  
  502. typedef std::array<std::uint8_t, hash_size> hash_type;
  503.  
  504. private:
  505. detail::sponge_absorber<state_type> absorb_;
  506.  
  507. public:
  508. void update(const void* data, std::size_t size)
  509. {
  510. absorb_(data, size);
  511. }
  512.  
  513. void finish(void* buf, std::size_t size)
  514. {
  515. detail::sponge_squeezer<state_type> squeeze(std::move(absorb_));
  516. squeeze(buf, size);
  517. *this = basic_hasher();
  518. }
  519.  
  520. hash_type finish()
  521. {
  522. hash_type hash;
  523. finish(hash.data(), hash.size());
  524. return hash;
  525. }
  526. };
  527.  
  528. typedef basic_hasher<112, 224> sha3_244_hasher;
  529. typedef basic_hasher<128, 256> sha3_256_hasher;
  530. typedef basic_hasher<192, 384> sha3_384_hasher;
  531. typedef basic_hasher<256, 512> sha3_512_hasher;
  532.  
  533. typedef basic_hasher<112, 112> s112_hasher;
  534. typedef basic_hasher<128, 128> s128_hasher;
  535. typedef basic_hasher<192, 192> s192_hasher;
  536. typedef basic_hasher<256, 256> s256_hasher;
  537.  
  538. template <std::size_t SecurityStrength>
  539. class basic_stream_crypter
  540. {
  541. public:
  542. static const auto security_strength = SecurityStrength;
  543.  
  544. typedef detail::keccak_state<std::uint64_t, security_strength * 2> state_type;
  545. typedef typename state_type::lane_type lane_type;
  546.  
  547. private:
  548. detail::sponge_squeezer<state_type> squeeze_;
  549.  
  550. public:
  551. basic_stream_crypter(const void* key, std::size_t keylen)
  552. : squeeze_(detail::sponge_absorber<state_type>(key, keylen))
  553. {}
  554.  
  555. void operator () (void* buf, const void* data, std::size_t size)
  556. {
  557. auto dptr = static_cast<const std::uint8_t*>(data);
  558. auto bptr = static_cast<std::uint8_t*>(buf);
  559. auto msize = size / sizeof(lane_type);
  560. auto rsize = size % sizeof(lane_type);
  561.  
  562. auto shift = apply<lane_type>(bptr, dptr, msize);
  563. apply<std::uint8_t>(bptr + shift, dptr + shift, rsize);
  564. }
  565.  
  566. private:
  567. template <typename LaneType>
  568. std::size_t apply(void* buf, const void* data, std::size_t size)
  569. {
  570. auto dptr = static_cast<const std::uint8_t*>(data);
  571. auto bptr = static_cast<std::uint8_t*>(buf);
  572.  
  573. for (auto i = 0; i != size; ++i)
  574. {
  575. LaneType l1, l2;
  576.  
  577. squeeze_(&l1, sizeof l1);
  578. std::memcpy(&l2, dptr + i * sizeof(LaneType), sizeof l2);
  579.  
  580. l1 ^= l2;
  581.  
  582. std::memcpy(bptr + i * sizeof(LaneType), &l1, sizeof l1);
  583. }
  584.  
  585. return size * sizeof(LaneType);
  586. }
  587. };
  588. }
  589.  
  590. #endif
  591.  
  592.  
  593.  
  594.  
  595. #include <iostream>
  596. #include <string>
  597.  
  598. void dump(const void* memory, std::size_t size)
  599. {
  600. static const char table[256][3] =
  601. {
  602. "00", "01", "02", "03", "04", "05", "06", "07",
  603. "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
  604. "10", "11", "12", "13", "14", "15", "16", "17",
  605. "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
  606. "20", "21", "22", "23", "24", "25", "26", "27",
  607. "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
  608. "30", "31", "32", "33", "34", "35", "36", "37",
  609. "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
  610. "40", "41", "42", "43", "44", "45", "46", "47",
  611. "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
  612. "50", "51", "52", "53", "54", "55", "56", "57",
  613. "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
  614. "60", "61", "62", "63", "64", "65", "66", "67",
  615. "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
  616. "70", "71", "72", "73", "74", "75", "76", "77",
  617. "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
  618. "80", "81", "82", "83", "84", "85", "86", "87",
  619. "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
  620. "90", "91", "92", "93", "94", "95", "96", "97",
  621. "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
  622. "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
  623. "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
  624. "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7",
  625. "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
  626. "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7",
  627. "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
  628. "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  629. "d8", "d9", "da", "db", "dc", "dd", "de", "df",
  630. "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7",
  631. "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
  632. "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
  633. "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
  634. };
  635.  
  636. const unsigned char* p = static_cast<const unsigned char*>(memory);
  637.  
  638. for (; size--; ++p)
  639. std::cout << table[*p];
  640.  
  641. std::cout << '\n';
  642. }
  643.  
  644. int main()
  645. {
  646. std::cout << "Key: ";
  647. std::string key;
  648. std::getline(std::cin, key);
  649.  
  650. keccak::basic_stream_crypter<128> encrypt(key.data(), key.size());
  651. keccak::basic_stream_crypter<128> decrypt(key.data(), key.size());
  652.  
  653. std::string msg;
  654. while (std::cout << "Message: " && std::getline(std::cin, msg))
  655. {
  656. std::string enc(msg.size(), ' ');
  657. encrypt(&enc[0], msg.data(), msg.size());
  658. std::cout << "Encrypted: ";
  659. dump(enc.data(), enc.size());
  660.  
  661. std::string dec(msg.size(), ' ');
  662.  
  663. decrypt(&dec[0], enc.data(), enc.size());
  664. std::cout << "Decrypted: " << dec << '\n';
  665. }
  666. }
Success #stdin #stdout 0s 3444KB
stdin
ThisIsMySuperSecretPassword
Hello, Kitty!
a
a
a
aa
aaa
aaaa
aaaaa
aaaaaa
aaaaaaa
aaaaaaaa
It Works!
stdout
Key: Message: Encrypted: cb0edeeb75a6f8e2827b4ca62c
Decrypted: Hello, Kitty!
Message: Encrypted: 49
Decrypted: a
Message: Encrypted: 85
Decrypted: a
Message: Encrypted: eb
Decrypted: a
Message: Encrypted: 808f
Decrypted: aa
Message: Encrypted: 7c5244
Decrypted: aaa
Message: Encrypted: cddaee33
Decrypted: aaaa
Message: Encrypted: e8bdfe1340
Decrypted: aaaaa
Message: Encrypted: fb7b39eeb5a3
Decrypted: aaaaaa
Message: Encrypted: 12ab25804e84dd
Decrypted: aaaaaaa
Message: Encrypted: 3d0af4a0ea223deb
Decrypted: aaaaaaaa
Message: Encrypted: 37d6a34ccaad6c6652
Decrypted: It Works!
Message: