From 57cc248883c69a7d7944b57a5c0ac2355658e165 Mon Sep 17 00:00:00 2001 From: devgianlu Date: Sun, 15 Dec 2024 16:16:17 +0100 Subject: [PATCH] LibCrypto: Add optimized RSA decryption with CRT method The textbook RSA decryption method of `c^d % n` is quite slow. If the necessary parameters are present, the CRT variant will be used. Performing RSA decryption this way is ~3 times faster. --- Libraries/LibCrypto/PK/RSA.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/Libraries/LibCrypto/PK/RSA.cpp b/Libraries/LibCrypto/PK/RSA.cpp index ebba1ebca70..c4c5d1569bb 100644 --- a/Libraries/LibCrypto/PK/RSA.cpp +++ b/Libraries/LibCrypto/PK/RSA.cpp @@ -133,12 +133,24 @@ void RSA::encrypt(ReadonlyBytes in, Bytes& out) void RSA::decrypt(ReadonlyBytes in, Bytes& out) { - // FIXME: Actually use the private key properly - auto in_integer = UnsignedBigInteger::import_data(in.data(), in.size()); - auto exp = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus()); - auto size = exp.export_data(out); + UnsignedBigInteger m; + if (m_private_key.prime1().is_zero() || m_private_key.prime2().is_zero()) { + m = NumberTheory::ModularPower(in_integer, m_private_key.private_exponent(), m_private_key.modulus()); + } else { + auto m1 = NumberTheory::ModularPower(in_integer, m_private_key.exponent1(), m_private_key.prime1()); + auto m2 = NumberTheory::ModularPower(in_integer, m_private_key.exponent2(), m_private_key.prime2()); + if (m1 < m2) + m1 = m1.plus(m_private_key.prime1()); + + VERIFY(m1 >= m2); + + auto h = NumberTheory::Mod(m1.minus(m2).multiplied_by(m_private_key.coefficient()), m_private_key.prime1()); + m = m2.plus(h.multiplied_by(m_private_key.prime2())); + } + + auto size = m.export_data(out); auto align = m_private_key.length(); auto aligned_size = (size + align - 1) / align * align;