00001 #if !defined(_XBOX) && !defined(X360)
00002
00003 #include "RSACrypt.h"
00004
00005 #include "Rand.h"
00006 #include "BigInt.h"
00007 #include "RakAlloca.h"
00008 #include "RakMemoryOverride.h"
00009 using namespace big;
00010
00011
00012 RSACrypt::RSACrypt()
00013 {
00014 p = 0;
00015 q = 0;
00016 qInv = 0;
00017 dP = 0;
00018 dQ = 0;
00019 modulus = 0;
00020
00021 p_inv = 0;
00022 q_inv = 0;
00023 mod_inv = 0;
00024 mod_limbs = 0;
00025 factor_limbs = 0;
00026 e = 0;
00027 }
00028
00029 RSACrypt::~RSACrypt()
00030 {
00031 cleanup();
00032 }
00033
00034 void RSACrypt::cleanup()
00035 {
00036 if (p) RakNet::OP_DELETE_ARRAY(p, __FILE__, __LINE__);
00037 p = 0;
00038 if (q)RakNet::OP_DELETE_ARRAY(q, __FILE__, __LINE__);
00039 q = 0;
00040 if (qInv) RakNet::OP_DELETE_ARRAY(qInv, __FILE__, __LINE__);
00041 qInv = 0;
00042 if (dQ) RakNet::OP_DELETE_ARRAY(dQ, __FILE__, __LINE__);
00043 dQ = 0;
00044 if (dP) RakNet::OP_DELETE_ARRAY(dP, __FILE__, __LINE__);
00045 dP = 0;
00046 if (modulus) RakNet::OP_DELETE_ARRAY(modulus, __FILE__, __LINE__);
00047 modulus = 0;
00048
00049 p_inv = 0;
00050 q_inv = 0;
00051 mod_inv = 0;
00052 mod_limbs = 0;
00053 factor_limbs = 0;
00054 e = 0;
00055 }
00056
00057 bool RSACrypt::setPrivateKey(const uint32_t *pi, const uint32_t *qi, int halfFactorLimbs)
00058 {
00059 cleanup();
00060
00061 factor_limbs = halfFactorLimbs;
00062 mod_limbs = factor_limbs * 2;
00063
00064 p = RakNet::OP_NEW_ARRAY<uint32_t>(factor_limbs, __FILE__, __LINE__ );
00065 q = RakNet::OP_NEW_ARRAY<uint32_t>(factor_limbs, __FILE__, __LINE__ );
00066 dP = RakNet::OP_NEW_ARRAY<uint32_t>(factor_limbs, __FILE__, __LINE__ );
00067 dQ = RakNet::OP_NEW_ARRAY<uint32_t>(factor_limbs, __FILE__, __LINE__ );
00068 qInv = RakNet::OP_NEW_ARRAY<uint32_t>(factor_limbs, __FILE__, __LINE__ );
00069 modulus = RakNet::OP_NEW_ARRAY<uint32_t>(mod_limbs, __FILE__, __LINE__ );
00070 if (!p || !q || !qInv || !dP || !dQ || !modulus) return false;
00071
00072
00073 if (Greater(factor_limbs, pi, qi))
00074 {
00075 Set(p, factor_limbs, pi);
00076 Set(q, factor_limbs, qi);
00077 }
00078 else
00079 {
00080 Set(q, factor_limbs, pi);
00081 Set(p, factor_limbs, qi);
00082 }
00083
00084
00085 uint32_t *p1 = (uint32_t *)alloca(factor_limbs*4);
00086 Set(p1, factor_limbs, p);
00087 Subtract32(p1, factor_limbs, 1);
00088
00089
00090 uint32_t *q1 = (uint32_t *)alloca(factor_limbs*4);
00091 Set(q1, factor_limbs, q);
00092 Subtract32(q1, factor_limbs, 1);
00093
00094
00095 e = 65537-2;
00096
00097 uint32_t r;
00098 do {
00099 e += 2;
00100 GCD(&e, 1, p1, factor_limbs, &r);
00101 if (r != 1) continue;
00102 GCD(&e, 1, q1, factor_limbs, &r);
00103 } while (r != 1 && e >= 65537);
00104
00105 if (r != 1) return false;
00106
00107
00108 Multiply(factor_limbs, modulus, p, q);
00109
00110
00111 if (!InvMod(&e, 1, p1, factor_limbs, dP))
00112 return false;
00113
00114
00115 if (!InvMod(&e, 1, q1, factor_limbs, dQ))
00116 return false;
00117
00118
00119 if (!InvMod(q, factor_limbs, p, factor_limbs, qInv))
00120 return false;
00121
00122
00123 p_inv = MonReducePrecomp(p[0]);
00124 q_inv = MonReducePrecomp(q[0]);
00125 mod_inv = MonReducePrecomp(modulus[0]);
00126
00127 return true;
00128 }
00129
00130 bool RSACrypt::setPublicKey(const uint32_t *modulusi, int mod_limbsi, uint32_t ei)
00131 {
00132 cleanup();
00133
00134 e = ei;
00135
00136 mod_limbs = mod_limbsi;
00137
00138 modulus = RakNet::OP_NEW_ARRAY<uint32_t>(mod_limbs, __FILE__, __LINE__ );
00139 if (!modulus) return false;
00140
00141 Set(modulus, mod_limbs, modulusi);
00142
00143 mod_inv = MonReducePrecomp(modulus[0]);
00144
00145 return true;
00146 }
00147
00148 bool RSACrypt::generatePrivateKey(uint32_t limbs)
00149 {
00150 uint32_t *pf = (uint32_t *)alloca(limbs*4);
00151 GenerateStrongPseudoPrime(pf, limbs/2);
00152
00153 uint32_t *qf = (uint32_t *)alloca(limbs*4);
00154 GenerateStrongPseudoPrime(qf, limbs/2);
00155
00156 return setPrivateKey(pf, qf, limbs/2);
00157 }
00158
00159 uint32_t RSACrypt::getFactorLimbs()
00160 {
00161 return factor_limbs;
00162 }
00163
00164 void RSACrypt::getPrivateP(uint32_t *po)
00165 {
00166 Set(po, factor_limbs, p);
00167 }
00168
00169 void RSACrypt::getPrivateQ(uint32_t *qo)
00170 {
00171 Set(qo, factor_limbs, q);
00172 }
00173
00174 uint32_t RSACrypt::getModLimbs()
00175 {
00176 return mod_limbs;
00177 }
00178
00179 void RSACrypt::getPublicModulus(uint32_t *moduluso)
00180 {
00181 Set(moduluso, mod_limbs, modulus);
00182 }
00183
00184 uint32_t RSACrypt::getPublicExponent()
00185 {
00186 return e;
00187 }
00188
00189 bool RSACrypt::encrypt(uint32_t *ct, const uint32_t *pt)
00190 {
00191 if (!e) return false;
00192
00193 ExpMod(pt, mod_limbs, &e, 1, modulus, mod_limbs, mod_inv, ct);
00194
00195 return true;
00196 }
00197
00198 bool RSACrypt::decrypt(uint32_t *pt, const uint32_t *ct)
00199 {
00200 if (!e) return false;
00201
00202
00203
00204
00205 uint32_t *s_p = (uint32_t*)alloca(factor_limbs*4);
00206 ExpMod(ct, mod_limbs, dP, factor_limbs, p, factor_limbs, p_inv, s_p);
00207
00208
00209 uint32_t *s_q = (uint32_t*)alloca(factor_limbs*4);
00210 ExpMod(ct, mod_limbs, dQ, factor_limbs, q, factor_limbs, q_inv, s_q);
00211
00212
00213
00214
00215 if (Subtract(s_p, factor_limbs, s_q, factor_limbs))
00216 Add(s_p, factor_limbs, p, factor_limbs);
00217 MulMod(factor_limbs, qInv, s_p, p, s_p);
00218
00219
00220 Multiply(factor_limbs, pt, s_p, q);
00221 Add(pt, mod_limbs, s_q, factor_limbs);
00222
00223 return true;
00224 }
00225
00226 #endif