Shadowrun: Awakened 29 September 2011 - Build 871
KeyAgreement.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 #ifndef CAT_KEY_AGREEMENT_HPP
00030 #define CAT_KEY_AGREEMENT_HPP
00031 
00032 #include <cat/math/BigTwistedEdwards.hpp>
00033 #include <cat/crypt/rand/Fortuna.hpp>
00034 
00035 namespace cat {
00036 
00037 
00038 /*
00039     Tunnel Key Agreement "Tabby" protocol:
00040     An unauthenticated Diffie-Hellman key agreement protocol with forward secrecy
00041     Immune to active attacks (man-in-the-middle) if server key is known ahead of time
00042 
00043     Using Elliptic Curve Cryptography over finite field Fp, p = 2^n - c, c small
00044     Shape of curve: a' * x^2 + y^2 = 1 + d' * x^2 * y^2, a' = -1 (square in Fp)
00045     d' (non square in Fp) -> order of curve = q * cofactor h, order of generator point = q
00046     Curves satisfy MOV conditions and are not anomalous
00047     Point operations performed with Extended Twisted Edwards group laws
00048     See BigTwistedEdwards.hpp for more information
00049 
00050     H: Skein-Key, either 256-bit or 512-bit based on security level
00051     MAC: Skein-MAC, keyed from output of H()
00052 
00053     Here the protocol initiator is the (c)lient, and the responder is the (s)erver:
00054 
00055         s: long-term private key 1 < b < q, long-term public key B = b * G
00056 
00057         256-bit security: B = 64 bytes for public key,  b = 32 bytes for private key
00058         384-bit security: B = 96 bytes for public key,  b = 48 bytes for private key
00059         512-bit security: B = 128 bytes for public key, b = 64 bytes for private key
00060 
00061         c: Client already knows the server's public key B before Key Agreement
00062         c: ephemeral private key 1 < a < q, ephemeral public key A = a * G
00063 
00064     Initiator Challenge: c2s A
00065 
00066         256-bit security: A = 64 bytes
00067         384-bit security: A = 96 bytes
00068         512-bit security: A = 128 bytes
00069 
00070         s: validate A, ignore invalid
00071         Invalid A(x,y) would be the additive identity x=0 or any point not on the curve
00072 
00073         s: ephemeral private key 1 < y < q, ephemeral public key Y = y * G
00074         Ephemeral key is re-used for several connections before being regenerated
00075 
00076         s: hA = h * A
00077         s: random n-bit number r
00078         s: d = H(A,B,Y,r)
00079         Repeat the previous two steps until d >= 1000
00080 
00081         s: e = b + d*y (mod q)
00082         s: T = AffineX(e * hA)
00083         s: k = H(d,T)
00084 
00085     Responder Answer: s2c Y || r || MAC(k) {"responder proof"}
00086 
00087         256-bit security: Y(64by)  r(32by) MAC(32by) = 128 bytes
00088         384-bit security: Y(96by)  r(48by) MAC(48by) = 192 bytes
00089         512-bit security: Y(128by) r(64by) MAC(64by) = 256 bytes
00090 
00091         c: validate Y, ignore invalid
00092         Invalid Y(x,y) would be the additive identity x=0 or any point not on the curve
00093 
00094         c: hY = h * Y
00095         c: d = H(A,B,Y,r)
00096         c: Verify d >= 1000
00097         c: T = AffineX(a * hB + d*a * hY)
00098         c: k = H(d,T)
00099 
00100         c: validate MAC, ignore invalid
00101 
00102     Initiator Proof: c2s MAC(k) {"initiator proof"}
00103 
00104         This packet can also include the client's first encrypted message
00105 
00106         256-bit security: MAC(32by) = 32 bytes
00107         384-bit security: MAC(48by) = 48 bytes
00108         512-bit security: MAC(64by) = 64 bytes
00109 
00110         s: validate MAC, ignore invalid
00111 
00112     Notes:
00113 
00114         The strategy of this protocol is to perform two EC Diffie-Hellman exchanges,
00115         one with the long-term server key and the second with an ephemeral key that
00116         should be much harder to obtain by an attacker.  The resulting two shared
00117         secret points are added together into one point that is used for the key.
00118 
00119         It is perfectly acceptable to re-use an ephemeral key for several runs of
00120         the protocol.  This means that most of the processing done by the server is
00121         just one point multiplication.
00122 */
00123 
00124 
00125 /*
00126     Schnorr signatures:
00127 
00128     For signing, the signer reuses its Key Agreement key pair (b,B)
00129 
00130     H: Skein-Key, either 256-bit or 512-bit based on security level
00131 
00132     To sign a message M, signer computes:
00133 
00134         ephemeral secret random 1 < k < q, ephemeral point K = k * G
00135         e = H(M || K)
00136         s = k - b*e (mod q)
00137 
00138         This process is repeated until e and s are non-zero
00139 
00140     Signature: s2c e || s
00141 
00142         256-bit security: e(32by) s(32by) = 64 bytes
00143         384-bit security: e(48by) s(48by) = 96 bytes
00144         512-bit security: e(64by) s(64by) = 128 bytes
00145 
00146     To verify a signature:
00147 
00148         Check e, s are in the range [1,q-1]
00149 
00150         K' = s*G + e*B
00151         e' = H(M || K')
00152 
00153         The signature is verified if e == e'
00154 
00155     Notes:
00156 
00157         K ?= K'
00158            = s*G + e*B
00159            = (k - b*e)*G + e*(b*G)
00160            = k*G - b*e*G + e*b*G
00161            = K
00162 */
00163 
00164 
00165 // If CAT_DETERMINISTIC_KEY_GENERATION is undefined, the time to generate a
00166 // key is unbounded, but tends to be 1 try.  I think this is a good thing
00167 // because it randomizes the runtime and helps avoid timing attacks
00168 //#define CAT_DETERMINISTIC_KEY_GENERATION
00169 
00170 // If CAT_USER_ERROR_CHECKING is defined, the key agreement objects will
00171 // check to make sure that the input parameters are all the right length
00172 // and that the math and prng objects are not null
00173 #define CAT_USER_ERROR_CHECKING
00174 
00175 class KeyAgreementCommon
00176 {
00177 public:
00178     static BigTwistedEdwards *InstantiateMath(int bits);
00179 
00180     // Math library register usage
00181     static const int ECC_REG_OVERHEAD = 21;
00182 
00183     // c: field prime modulus p = 2^bits - C, p = 5 mod 8 s.t. a=-1 is a square in Fp
00184     // d: curve coefficient (yy-xx=1+Dxxyy), not a square in Fp
00185     static const int EDWARD_C_256 = 435;
00186     static const int EDWARD_D_256 = 31720;
00187     static const int EDWARD_C_384 = 2147;
00188     static const int EDWARD_D_384 = 13036;
00189     static const int EDWARD_C_512 = 875;
00190     static const int EDWARD_D_512 = 32;
00191 
00192     // Limits on field prime
00193     static const int MAX_BITS = 512;
00194     static const int MAX_BYTES = MAX_BITS / 8;
00195     static const int MAX_LEGS = MAX_BYTES / sizeof(Leg);
00196 
00197 protected:
00198     int KeyBits, KeyBytes, KeyLegs;
00199 
00200     bool Initialize(int bits);
00201 
00202 public:
00203     // Generates an unbiased random key in the range 1 < key < q
00204     void GenerateKey(BigTwistedEdwards *math, IRandom *prng, Leg *key);
00205 };
00206 
00207 
00208 } // namespace cat
00209 
00210 #endif // CAT_KEY_AGREEMENT_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