Implementation of Shamir's trick (working in progress).
[crypto_lab3.git] / src / RsaCrt.cpp
1 #include "RsaCrt.h"
2
3 using namespace std;
4
5 #include "Rand.h"
6 #include "Utils.h"
7
8 pair<Rsa::KeyPub, RsaCrt::KeyPriv> RsaCrt::generateRSAKeys(uint exponent, uint keySizeBits)
9 {
10 mpz_class phi, d;
11 Rsa::KeyPub kPub;
12 KeyPriv kPriv;
13
14 do
15 {
16 kPub.e = exponent;
17 kPriv.p = Rand::randPrime(keySizeBits / 2);
18 kPriv.q = Rand::randPrime(keySizeBits / 2);
19
20 kPub.n = kPriv.p * kPriv.q;
21 phi = (kPriv.p - 1) * (kPriv.q - 1);
22
23 // d = e^-1 (mode phi).
24 } while (mpz_invert(d.get_mpz_t(), kPub.e.get_mpz_t(), phi.get_mpz_t()) == 0);
25
26 kPriv.dp = d % (kPriv.p - 1);
27 kPriv.dq = d % (kPriv.q - 1);
28
29 // qInv = q^-1 (mod p)
30 mpz_invert(kPriv.qInv.get_mpz_t(), kPriv.q.get_mpz_t(), kPriv.p.get_mpz_t());
31
32 return make_pair(kPub, kPriv);
33 }
34
35 mpz_class RsaCrt::sign(const mpz_class& m, const KeyPriv& kPriv)
36 {
37 mpz_class sp, sq;
38
39 mpz_powm_sec(sp.get_mpz_t(), m.get_mpz_t(), kPriv.dp.get_mpz_t(), kPriv.p.get_mpz_t());
40 mpz_powm_sec(sq.get_mpz_t(), m.get_mpz_t(), kPriv.dq.get_mpz_t(), kPriv.q.get_mpz_t());
41
42 return sq + ((kPriv.qInv * (sp - sq)) % kPriv.p) * kPriv.q;
43 }
44
45 mpz_class RsaCrt::signWithFaultySp(const mpz_class& m, const KeyPriv& kPriv)
46 {
47 mpz_class sp, sq;
48
49 mpz_powm_sec(sp.get_mpz_t(), m.get_mpz_t(), kPriv.dp.get_mpz_t(), kPriv.p.get_mpz_t());
50 mpz_powm_sec(sq.get_mpz_t(), m.get_mpz_t(), kPriv.dq.get_mpz_t(), kPriv.q.get_mpz_t());
51
52 mpz_combit(sp.get_mpz_t(), 42); // Flip the fourty second bit.
53
54 return sq + ((kPriv.qInv * (sp - sq)) % kPriv.p) * kPriv.q;
55 }