11 #include "RsaCrtShamirsTrick.h"
13 Tests::Tests(uint keySizeBits
, uint rsaPublicExponent
) :
14 KEY_SIZE_BITS(keySizeBits
),
15 RSA_PUBLIC_EXPONENT(rsaPublicExponent
)
19 void Tests::runTests()
21 if (this->rsaStandard())
22 cout
<< "RSA standard OK" << endl
;
24 cout
<< "RSA standard failed!" << endl
;
27 cout
<< "RSA CRT OK" << endl
;
29 cout
<< "RSA CRT failed!" << endl
;
32 void Tests::runTestsWithShamirsTrick()
34 if (this->rsaCrtWithShamirsTrick())
35 cout
<< "RSA CRT with shamir's trick OK" << endl
;
37 cout
<< "RSA CRT with shamir's trick failed!" << endl
;
40 void Tests::runTimeMeasures()
43 const int nbKeys
= 20; // Number of different generated key.
47 int timeRsaCRTShamirsTrick
= 0;
49 for (int k
= 0; k
< nbKeys
; ++k
)
51 timeRsaStd
+= timeSignRsaStd(N
);
52 timeRsaCRT
+= timeSignRsaCRT(N
);
53 timeRsaCRTShamirsTrick
+= timeSignRsaCRTShamirsTrick(N
);
56 cout
<< N
* nbKeys
<< " x RSA standard: " << timeRsaStd
<< " ms" << endl
;
57 cout
<< N
* nbKeys
<< " x RSA CRT: " << timeRsaCRT
<< " ms" << endl
;
58 cout
<< N
* nbKeys
<< " x RSA CRT Shamir's trick: " << timeRsaCRTShamirsTrick
<< " ms" << endl
;
59 cout
<< "Speedup for CRT: " << (double(timeRsaStd
) / double(timeRsaCRT
)) << endl
;
60 cout
<< "Speedup for CRT with Shamir's trick: " << (double(timeRsaStd
) / double(timeRsaCRT
)) << endl
;
63 void Tests::doAttack()
65 const auto& keys
= RsaCrt::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
66 const auto& kPub
= keys
.first
;
67 const auto& kPriv
= keys
.second
;
69 mpz_class message
= Rand::randSize(128);
70 mpz_class faultySignature
= RsaCrt::signWithFaultySp(message
, kPriv
);
71 mpz_class correctSignature
= RsaCrt::sign(message
, kPriv
);
73 bool attackSuccessful
= true;
75 cout
<< "Original:" << endl
;
76 cout
<< " p = " << kPriv
.p
<< endl
;
77 cout
<< " q = " << kPriv
.q
<< endl
;
79 // At this point the attacker doesn't know the private key but he has intercepted the message and the faulty signature.
81 mpz_class faultySignaturePowerE
;
82 mpz_pow_ui(faultySignaturePowerE
.get_mpz_t(), faultySignature
.get_mpz_t(), RSA_PUBLIC_EXPONENT
);
83 mpz_class messageMinuxFaultySignaturePowerE
= message
- faultySignaturePowerE
;
85 mpz_gcd(q
.get_mpz_t(), messageMinuxFaultySignaturePowerE
.get_mpz_t(), kPub
.n
.get_mpz_t());
86 mpz_class p
= kPub
.n
/ q
;
88 cout
<< "Found with a faulty signature:" << endl
;
89 cout
<< " p = " << p
<< endl
;
90 cout
<< " q = " << q
<< endl
;
92 attackSuccessful
= attackSuccessful
&& kPriv
.p
== p
&& kPriv
.q
== q
; // With p and q we can recreate the original private key.
95 // Try the attack with a correct signature.
97 mpz_class correctSignaturePowerE
;
98 mpz_pow_ui(correctSignaturePowerE
.get_mpz_t(), correctSignature
.get_mpz_t(), RSA_PUBLIC_EXPONENT
);
99 mpz_class messageMinuxCorrectSignaturePowerE
= message
- correctSignaturePowerE
;
101 mpz_gcd(q
.get_mpz_t(), messageMinuxCorrectSignaturePowerE
.get_mpz_t(), kPub
.n
.get_mpz_t());
102 mpz_class p
= kPub
.n
/ q
;
104 cout
<< "Found with a correct signature:" << endl
;
105 cout
<< " p = " << p
<< endl
; // Equal to 1.
106 cout
<< " q = " << q
<< endl
; // Equal to n.
108 attackSuccessful
= attackSuccessful
&& kPriv
.p
!= p
&& kPriv
.q
!= q
;
111 if (attackSuccessful
)
112 cout
<< "Attack successful" << endl
;
114 cout
<< "Attack failed" << endl
;
117 void Tests::doAttackFixed()
119 const auto& keys
= RsaCrt::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
120 const auto& kPub
= keys
.first
;
121 const auto& kPriv
= keys
.second
;
124 bool Tests::rsaStandard()
126 const auto& keys
= RsaStd::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
127 const auto& kPub
= keys
.first
;
128 const auto& kPriv
= keys
.second
;
131 mpz_class message
= kPriv
.n
;
132 mpz_class signature
= RsaStd::sign(message
, kPriv
);
133 if (Rsa::verifySignature(message
, signature
, kPub
)) // Must not be able to signe message greater than kPriv.n.
138 mpz_class message
= kPriv
.n
- 1;
139 mpz_class signature
= RsaStd::sign(message
, kPriv
);
140 if (!Rsa::verifySignature(message
, signature
, kPub
) || Rsa::verifySignature(message
+ 1, signature
, kPub
))
145 mpz_class message
= kPriv
.n
/ 2;
146 mpz_class signature
= RsaStd::sign(message
, kPriv
);
147 if (!Rsa::verifySignature(message
, signature
, kPub
) || Rsa::verifySignature(message
+ 1, signature
, kPub
))
156 const auto& keys
= RsaCrt::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
157 const auto& kPub
= keys
.first
;
158 const auto& kPriv
= keys
.second
;
161 mpz_class message
= kPub
.n
;
162 mpz_class signature
= RsaCrt::sign(message
, kPriv
);
163 if (Rsa::verifySignature(message
, signature
, kPub
)) // Must not be able to signe message greater than kPub.n.
168 mpz_class message
= kPub
.n
- 1;
169 mpz_class signature
= RsaCrt::sign(message
, kPriv
);
170 if (!Rsa::verifySignature(message
, signature
, kPub
) || Rsa::verifySignature(message
+ 1, signature
, kPub
))
175 mpz_class message
= kPub
.n
/ 2;
176 mpz_class signature
= RsaCrt::sign(message
, kPriv
);
177 if (!Rsa::verifySignature(message
, signature
, kPub
) || Rsa::verifySignature(message
+ 1, signature
, kPub
))
184 bool Tests::rsaCrtWithShamirsTrick()
186 const auto& keys
= RsaCrtShamirsTrick::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
187 const auto& kPub
= keys
.first
;
188 const auto& kPriv
= keys
.second
;
191 mpz_class message
= kPub
.n
;
192 mpz_class signature
= RsaCrtShamirsTrick::sign(message
, kPriv
);
193 if (Rsa::verifySignature(message
, signature
, kPub
)) // Must not be able to signe message greater than kPub.n.
198 mpz_class message
= kPub
.n
- 1;
199 mpz_class signature
= RsaCrtShamirsTrick::sign(message
, kPriv
);
200 if (!Rsa::verifySignature(message
, signature
, kPub
) || Rsa::verifySignature(message
+ 1, signature
, kPub
))
205 mpz_class message
= kPub
.n
/ 2;
206 mpz_class signature
= RsaCrtShamirsTrick::sign(message
, kPriv
);
207 if (!Rsa::verifySignature(message
, signature
, kPub
) || Rsa::verifySignature(message
+ 1, signature
, kPub
))
214 int Tests::timeSignRsaStd(int N
)
217 const auto& keys
= RsaStd::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
219 mpz_class message
= Rand::randSize(KEY_SIZE_BITS
/ 2);
220 for (int i
= 0; i
< N
; i
++)
221 RsaStd::sign(message
, keys
.second
);
226 int Tests::timeSignRsaCRT(int N
)
229 const auto& keys
= RsaCrt::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
231 mpz_class message
= Rand::randSize(KEY_SIZE_BITS
/ 2);
232 for (int i
= 0; i
< N
; i
++)
233 RsaCrt::sign(message
, keys
.second
);
238 int Tests::timeSignRsaCRTShamirsTrick(int N
)
241 const auto& keys
= RsaCrtShamirsTrick::generateRSAKeys(RSA_PUBLIC_EXPONENT
, KEY_SIZE_BITS
);
243 mpz_class message
= Rand::randSize(KEY_SIZE_BITS
/ 2);
244 for (int i
= 0; i
< N
; i
++)
245 RsaCrtShamirsTrick::sign(message
, keys
.second
);