Shadowrun: Awakened 29 September 2011 - Build 871
ChaCha.hpp
Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2009-2010 Christopher A. Taylor.  All rights reserved.
00003 
00004     Redistribution and use in source and binary forms, with or without
00005     modification, are permitted provided that the following conditions are met:
00006 
00007     * Redistributions of source code must retain the above copyright notice,
00008       this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice,
00010       this list of conditions and the following disclaimer in the documentation
00011       and/or other materials provided with the distribution.
00012     * Neither the name of LibCat nor the names of its contributors may be used
00013       to endorse or promote products derived from this software without
00014       specific prior written permission.
00015 
00016     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017     AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020     LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026     POSSIBILITY OF SUCH DAMAGE.
00027 */
00028 
00029 /*
00030     The ChaCha cipher is a symmetric stream cipher based on Salsa20.
00031     http://cr.yp.to/chacha.html
00032 */
00033 
00034 #ifndef CAT_CHACHA_HPP
00035 #define CAT_CHACHA_HPP
00036 
00037 #include <cat/Platform.hpp>
00038 
00039 namespace cat {
00040 
00041 /*
00042     To initialize the ChaCha cipher, you must specify a 256-bit key.
00043 
00044     Code example:
00045 
00046         ChaChaKey cck;
00047         char key[32]; // fill key here
00048 
00049         cck.Key(key, sizeof(key));
00050 
00051     Before each encryption or decryption with the ChaCha cipher,
00052     a 64-bit Initialization Vector (IV) must be specified.  Every
00053     time a message is encrypted, the IV must be incremented by 1.
00054     The IV is then sent along with the encrypted message.
00055 
00056     Encryption code example:
00057 
00058         char message[19], ciphertext[19]; // message filled here
00059         u64 iv = 125125;
00060         u64 message_iv = iv;
00061         iv = iv + 1;
00062 
00063         ChaChaOutput cco(cck, message_iv);
00064         cco.Crypt(message, ciphertext, sizeof(ciphertext));
00065 
00066     Decryption code example:
00067 
00068         char ciphertext[19], decrypted[19]; // ciphertext filled here
00069 
00070         ChaChaOutput cco(cck, message_iv);
00071         cco.Crypt(ciphertext, decrypted, sizeof(decrypted));
00072 
00073     Sending all 8 bytes of the IV in every packet is not necessary.
00074     Instead, only a few of the low bits of the IV need to be sent,
00075     if the IV is incremented by 1 each time.
00076 
00077     How many?  It depends on how many messages can get lost.
00078     If < 32768 messages can get lost in a row, then CAT_IV_BITS = 16 (default)
00079 
00080     I have provided a function to handle rollover/rollunder of the IV,
00081     which also works if the same IV is sent twice for some reason.
00082     It needs to know how many of the low bits are sent across, so be sure
00083     to change CAT_IV_BITS in this header if you send more or less than 16.
00084 
00085     Code example:
00086 
00087         u64 last_accepted_iv;
00088         u32 new_iv_low_bits;
00089 
00090         u64 new_iv = ChaCha::ReconstructIV(last_accepted_iv, new_iv_low_bits);
00091 
00092     -------------------------READ THIS BEFORE USING--------------------------
00093 
00094     Never use the same IV twice.
00095         Otherwise: An attacker can recover the plaintext without the key.
00096 
00097     Never use the same key twice.
00098         Otherwise: An attacker can recover the plaintext without the key.
00099 
00100     If you have two hosts talking to eachother securely with ChaCha encryption,
00101     then be sure that each host is encrypting with a DIFFERENT key.
00102         Otherwise: An attacker can recover the plaintext without the key.
00103 
00104     Remember that an attacker can impersonate the remote computer, so be
00105     sure not to accept the new IV until the message authentication code has
00106     been verified if your protocol uses a message authentication code (MAC).
00107         Otherwise: An attacker could desynchronize the IVs.
00108 */
00109 
00110 
00112 
00113 class ChaChaKey
00114 {
00115     friend class ChaChaOutput;
00116     u32 state[16];
00117 
00118 public:
00119     ~ChaChaKey();
00120 
00121     // Key up to 384 bits
00122     void Set(const void *key, int bytes);
00123 };
00124 
00125 
00127 
00128 class ChaChaOutput
00129 {
00130     u32 state[16];
00131 
00132     void GenerateKeyStream(u32 *out);
00133 
00134 public:
00135     ChaChaOutput(const ChaChaKey &key, u64 iv);
00136     ~ChaChaOutput();
00137 
00138     // Message with any number of bytes
00139     void Crypt(const void *in, void *out, int bytes);
00140 };
00141 
00142 
00143 } // namespace cat
00144 
00145 #endif // CAT_CHACHA_HPP

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net