• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

RSACrypt.cpp

Go to the documentation of this file.
00001 #if !defined(_XBOX) && !defined(X360)
00002 
00003 #include "RSACrypt.h"
00004 //#include "Random.hpp"
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         // Insure that p > q
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         // p1 = p-1
00085         uint32_t *p1 = (uint32_t *)alloca(factor_limbs*4);
00086         Set(p1, factor_limbs, p);
00087         Subtract32(p1, factor_limbs, 1);
00088 
00089         // q1 = q-1
00090         uint32_t *q1 = (uint32_t *)alloca(factor_limbs*4);
00091         Set(q1, factor_limbs, q);
00092         Subtract32(q1, factor_limbs, 1);
00093 
00094         // e = first number relatively prime to phi, starting at 65537
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         // modulus = p * q
00108         Multiply(factor_limbs, modulus, p, q);
00109 
00110         // dP = (1/e) mod (p-1)
00111         if (!InvMod(&e, 1, p1, factor_limbs, dP))
00112                 return false;
00113 
00114         // dQ = (1/e) mod (q-1)
00115         if (!InvMod(&e, 1, q1, factor_limbs, dQ))
00116                 return false;
00117 
00118         // qInv = (1/q) mod p
00119         if (!InvMod(q, factor_limbs, p, factor_limbs, qInv))
00120                 return false;
00121 
00122         // Prepare for Montgomery multiplication
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         // CRT method
00203 
00204         // s_p = c ^ dP mod p
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         // s_q = c ^ dQ mod q
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         // Garner's CRT recombination
00213 
00214         // s_p = qInv(s_p - s_q) mod p
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         // pt = s_q + s_p*q
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

Generated on Thu Sep 30 2010 01:27:28 for RakNet by  doxygen 1.7.1