![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
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.