+ cout << N * nbKeys << " x RSA CRT Shamir's trick: " << timeRsaCRTShamirsTrick << " ms" << endl;
+ cout << "Speedup for CRT: " << (double(timeRsaStd) / double(timeRsaCRT)) << endl;
+ cout << "Speedup for CRT with Shamir's trick: " << (double(timeRsaStd) / double(timeRsaCRT)) << endl;
+}
+
+void Tests::doAttack()
+{
+ const auto& keys = RsaCrt::generateRSAKeys(RSA_PUBLIC_EXPONENT, KEY_SIZE_BITS);
+ const auto& kPub = keys.first;
+ const auto& kPriv = keys.second;
+
+ mpz_class message = Rand::randSize(128);
+ mpz_class faultySignature = RsaCrt::signWithFaultySp(message, kPriv);
+ mpz_class correctSignature = RsaCrt::sign(message, kPriv);
+
+ bool attackSuccessful = true;
+
+ cout << "Original:" << endl;
+ cout << " p = " << kPriv.p << endl;
+ cout << " q = " << kPriv.q << endl;
+
+ // At this point the attacker doesn't know the private key but he has intercepted the message and the faulty signature.
+ {
+ mpz_class faultySignaturePowerE;
+ mpz_pow_ui(faultySignaturePowerE.get_mpz_t(), faultySignature.get_mpz_t(), RSA_PUBLIC_EXPONENT);
+ mpz_class messageMinuxFaultySignaturePowerE = message - faultySignaturePowerE;
+ mpz_class q;
+ mpz_gcd(q.get_mpz_t(), messageMinuxFaultySignaturePowerE.get_mpz_t(), kPub.n.get_mpz_t());
+ mpz_class p = kPub.n / q;
+
+ cout << "Found with a faulty signature:" << endl;
+ cout << " p = " << p << endl;
+ cout << " q = " << q << endl;
+
+ attackSuccessful = attackSuccessful && kPriv.p == p && kPriv.q == q; // With p and q we can recreate the original private key.
+ }
+
+ // Try the attack with a correct signature.
+ {
+ mpz_class correctSignaturePowerE;
+ mpz_pow_ui(correctSignaturePowerE.get_mpz_t(), correctSignature.get_mpz_t(), RSA_PUBLIC_EXPONENT);
+ mpz_class messageMinuxCorrectSignaturePowerE = message - correctSignaturePowerE;
+ mpz_class q;
+ mpz_gcd(q.get_mpz_t(), messageMinuxCorrectSignaturePowerE.get_mpz_t(), kPub.n.get_mpz_t());
+ mpz_class p = kPub.n / q;
+
+ cout << "Found with a correct signature:" << endl;
+ cout << " p = " << p << endl; // Equal to 1.
+ cout << " q = " << q << endl; // Equal to n.
+
+ attackSuccessful = attackSuccessful && kPriv.p != p && kPriv.q != q;
+ }
+
+ if (attackSuccessful)
+ cout << "Attack successful" << endl;
+ else
+ cout << "Attack failed" << endl;
+}
+
+void Tests::doAttackFixed()
+{
+ const auto& keys = RsaCrt::generateRSAKeys(RSA_PUBLIC_EXPONENT, KEY_SIZE_BITS);
+ const auto& kPub = keys.first;
+ const auto& kPriv = keys.second;