1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <cstdint>
#include <cassert>
#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 PublicKey &pubkey){
// cerr<<"msg="<<msg<<endl;
// cerr<<"mod="<<pubkey.mod<<endl;
assert(msg>1&&msg<pubkey.mod);
return expmod(msg,pubkey.exp,pubkey.mod);
}
Bigint decrypt(Bigint encr,const PrivateKey &privkey){
return expmod(encr,privkey.pexp,privkey.pub.mod);
}
PrivateKey genkey(int nbits,Rng &rng){
pair<Bigint,Bigint> pq=genprimepair(rng,nbits);
PrivateKey key;
key.pub.mod=pq.first*pq.second;
key.pub.exp=65537;
Bigint x;
egcd((pq.first-Bigint::one)*(pq.second-Bigint::one),key.pub.exp,x,key.pexp);
return key;
}
PrivateKey genkey(int nbits){
CryptoRng rng;
return genkey(nbits,rng);
}
PrivateKey genkey(int nbits,const string &password){
KeyRng rng(password);
return genkey(nbits,rng);
}
pair<string,string> exportkey(const PrivateKey &key){
string modser=key.pub.mod.serialiseMantissa();
int32_t modlen=modser.size();
string modlenstr{(char)(modlen&0xff),(char)((modlen>>8)&0xff),(char)((modlen>>16)&0xff),(char)((modlen>>24)&0xff)};
return make_pair(
Base64::encode(modlenstr + modser + key.pub.exp.serialiseMantissa()),
Base64::encode(modlenstr + modser + key.pexp.serialiseMantissa()));
}
PrivateKey importkey(const string &pub,const string &priv){
string pubdeser=Base64::decode(pub);
assert(pubdeser.size()>4);
int modlen=(unsigned char)(pubdeser[0])+(unsigned char)(pubdeser[1]<<8)+
(unsigned char)(pubdeser[2]<<16)+(unsigned char)(pubdeser[3]<<24);
assert((int)pubdeser.size()-4>modlen);
PrivateKey key;
key.pub.mod.deserialiseMantissa(string(pubdeser.begin()+4,pubdeser.begin()+(4+modlen)));
key.pub.exp.deserialiseMantissa(string(pubdeser.begin()+(4+modlen),pubdeser.end()));
string privdeser=Base64::decode(priv);
key.pexp.deserialiseMantissa(string(privdeser.begin()+(4+modlen),privdeser.end()));
return key;
}
}
|