ChaCha.hpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. Copyright (c) 2009-2010 Christopher A. Taylor. All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions are met:
  5. * Redistributions of source code must retain the above copyright notice,
  6. this list of conditions and the following disclaimer.
  7. * Redistributions in binary form must reproduce the above copyright notice,
  8. this list of conditions and the following disclaimer in the documentation
  9. and/or other materials provided with the distribution.
  10. * Neither the name of LibCat nor the names of its contributors may be used
  11. to endorse or promote products derived from this software without
  12. specific prior written permission.
  13. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  14. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  17. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  23. POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. /*
  26. The ChaCha cipher is a symmetric stream cipher based on Salsa20.
  27. http://cr.yp.to/chacha.html
  28. */
  29. #ifndef CAT_CHACHA_HPP
  30. #define CAT_CHACHA_HPP
  31. #include <cat/Platform.hpp>
  32. namespace cat {
  33. /*
  34. To initialize the ChaCha cipher, you must specify a 256-bit key.
  35. Code example:
  36. ChaChaKey cck;
  37. char key[32]; // fill key here
  38. cck.Key(key, sizeof(key));
  39. Before each encryption or decryption with the ChaCha cipher,
  40. a 64-bit Initialization Vector (IV) must be specified. Every
  41. time a message is encrypted, the IV must be incremented by 1.
  42. The IV is then sent along with the encrypted message.
  43. Encryption code example:
  44. char message[19], ciphertext[19]; // message filled here
  45. u64 iv = 125125;
  46. u64 message_iv = iv;
  47. iv = iv + 1;
  48. ChaChaOutput cco(cck, message_iv);
  49. cco.Crypt(message, ciphertext, sizeof(ciphertext));
  50. Decryption code example:
  51. char ciphertext[19], decrypted[19]; // ciphertext filled here
  52. ChaChaOutput cco(cck, message_iv);
  53. cco.Crypt(ciphertext, decrypted, sizeof(decrypted));
  54. Sending all 8 bytes of the IV in every packet is not necessary.
  55. Instead, only a few of the low bits of the IV need to be sent,
  56. if the IV is incremented by 1 each time.
  57. How many? It depends on how many messages can get lost.
  58. If < 32768 messages can get lost in a row, then CAT_IV_BITS = 16 (default)
  59. I have provided a function to handle rollover/rollunder of the IV,
  60. which also works if the same IV is sent twice for some reason.
  61. It needs to know how many of the low bits are sent across, so be sure
  62. to change CAT_IV_BITS in this header if you send more or less than 16.
  63. Code example:
  64. u64 last_accepted_iv;
  65. u32 new_iv_low_bits;
  66. u64 new_iv = ChaCha::ReconstructIV(last_accepted_iv, new_iv_low_bits);
  67. -------------------------READ THIS BEFORE USING--------------------------
  68. Never use the same IV twice.
  69. Otherwise: An attacker can recover the plaintext without the key.
  70. Never use the same key twice.
  71. Otherwise: An attacker can recover the plaintext without the key.
  72. If you have two hosts talking to eachother securely with ChaCha encryption,
  73. then be sure that each host is encrypting with a DIFFERENT key.
  74. Otherwise: An attacker can recover the plaintext without the key.
  75. Remember that an attacker can impersonate the remote computer, so be
  76. sure not to accept the new IV until the message authentication code has
  77. been verified if your protocol uses a message authentication code (MAC).
  78. Otherwise: An attacker could desynchronize the IVs.
  79. */
  80. //// ChaChaKey
  81. class CAT_EXPORT ChaChaKey
  82. {
  83. friend class ChaChaOutput;
  84. u32 state[16];
  85. public:
  86. ~ChaChaKey();
  87. // Key up to 384 bits
  88. void Set(const void *key, int bytes);
  89. };
  90. //// ChaChaOutput
  91. class CAT_EXPORT ChaChaOutput
  92. {
  93. u32 state[16];
  94. void GenerateKeyStream(u32 *out);
  95. public:
  96. ChaChaOutput(const ChaChaKey &key, u64 iv);
  97. ~ChaChaOutput();
  98. // Message with any number of bytes
  99. void Crypt(const void *in, void *out, int bytes);
  100. };
  101. } // namespace cat
  102. #endif // CAT_CHACHA_HPP
粤ICP备19079148号