#include #include #include #include #include "base64.h" #include "numalgo.h" #include "primes.h" #include "rng.h" #include "rsa.h" using namespace std; namespace RSA{ Bigint encrypt(Bigint msg,const Key &pubkey){ assert(msg>1&&msg genkeys(int nbits,Rng &rng){ pair pq=genprimepair(rng,nbits); Key pubkey,privkey; pubkey.mod=privkey.mod=pq.first*pq.second; pubkey.exp=65537; Bigint x; Bigint phi((pq.first-Bigint::one)*(pq.second-Bigint::one)); assert(egcd(phi,pubkey.exp,x,privkey.exp)==1); privkey.exp=privkey.exp.divmod(phi).second; // cerr<<"pubkey = {"< genkeys(int nbits){ CryptoRng rng; return genkeys(nbits,rng); } pair genkeys(int nbits,const string &password){ KeyRng rng(password); return genkeys(nbits,rng); } string exportKey(const Key &key){ string modser=key.mod.serialiseMantissa(); int32_t modlen=modser.size(); string modlenstr{(char)((modlen>>24)&0xff),(char)((modlen>>16)&0xff),(char)((modlen>>8)&0xff),(char)(modlen&0xff)}; return Base64::encode(modlenstr + modser + key.exp.serialiseMantissa()); } Key importKey(const string &repr){ string deser=Base64::decode(repr); if(deser.size()<=4)throw invalid_argument("Invalid key string length"); int modlen=((uint8_t)deser[0]<<24)+((uint8_t)deser[1]<<16)+ ((uint8_t)deser[2]<<8)+(uint8_t)deser[3]; if((int)deser.size()-4-modlen<=0)throw invalid_argument("Key string incomplete"); Key key; key.mod.deserialiseMantissa(string(deser.begin()+4,deser.begin()+(4+modlen))); key.exp.deserialiseMantissa(string(deser.begin()+(4+modlen),deser.end())); return key; } }