From b35764da0e5c5a2f12dee6f09e3a93f95a567f3a Mon Sep 17 00:00:00 2001 From: devgianlu Date: Sun, 15 Dec 2024 16:04:20 +0100 Subject: [PATCH] LibCrypto: Add extended GCD algorithm --- Libraries/LibCrypto/BigInt/Algorithms/GCD.cpp | 57 +++++++++++++++++++ .../Algorithms/UnsignedBigIntegerAlgorithms.h | 1 + 2 files changed, 58 insertions(+) diff --git a/Libraries/LibCrypto/BigInt/Algorithms/GCD.cpp b/Libraries/LibCrypto/BigInt/Algorithms/GCD.cpp index 9b9e3e867b4..173dac99249 100644 --- a/Libraries/LibCrypto/BigInt/Algorithms/GCD.cpp +++ b/Libraries/LibCrypto/BigInt/Algorithms/GCD.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2020, Ali Mohammad Pur * Copyright (c) 2020-2021, Dex♪ + * Copyright (c) 2024, Altomani Gianluca * * SPDX-License-Identifier: BSD-2-Clause */ @@ -36,4 +37,60 @@ void UnsignedBigIntegerAlgorithms::destructive_GCD_without_allocation( } } +void UnsignedBigIntegerAlgorithms::extended_GCD_without_allocation( + UnsignedBigInteger const& a, + UnsignedBigInteger const& b, + UnsignedBigInteger& x, + UnsignedBigInteger& y, + UnsignedBigInteger& gcd, + UnsignedBigInteger& temp_quotient, + UnsignedBigInteger& temp_1, + UnsignedBigInteger& temp_2, + UnsignedBigInteger& temp_shift_result, + UnsignedBigInteger& temp_shift_plus, + UnsignedBigInteger& temp_shift, + UnsignedBigInteger& temp_r, + UnsignedBigInteger& temp_s, + UnsignedBigInteger& temp_t) +{ + gcd.set_to(a); + x.set_to(1); + y.set_to(0); + + temp_r.set_to(b); + temp_s.set_to_0(); + temp_t.set_to(1); + + while (temp_r != 0) { + // quotient := old_r div r + divide_without_allocation(gcd, temp_r, temp_quotient, temp_1); + + temp_2.set_to(temp_r); + multiply_without_allocation(temp_quotient, temp_r, temp_shift_result, temp_shift_plus, temp_shift, temp_1); + while (gcd < temp_1) { + add_into_accumulator_without_allocation(gcd, b); + } + subtract_without_allocation(gcd, temp_1, temp_r); + gcd.set_to(temp_2); + + // (old_s, s) := (s, old_s − quotient × s) + temp_2.set_to(temp_s); + multiply_without_allocation(temp_quotient, temp_s, temp_shift_result, temp_shift_plus, temp_shift, temp_1); + while (x < temp_1) { + add_into_accumulator_without_allocation(x, b); + } + subtract_without_allocation(x, temp_1, temp_s); + x.set_to(temp_2); + + // (old_t, t) := (t, old_t − quotient × t) + temp_2.set_to(temp_t); + multiply_without_allocation(temp_quotient, temp_t, temp_shift_result, temp_shift_plus, temp_shift, temp_1); + while (y < temp_1) { + add_into_accumulator_without_allocation(y, b); + } + subtract_without_allocation(y, temp_1, temp_t); + y.set_to(temp_2); + } +} + } diff --git a/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h b/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h index 53c89118681..2b8b80aaf0c 100644 --- a/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h +++ b/Libraries/LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h @@ -27,6 +27,7 @@ public: static void divide_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger const& denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder); static void divide_u16_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger::Word denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder); + static void extended_GCD_without_allocation(UnsignedBigInteger const& a, UnsignedBigInteger const& b, UnsignedBigInteger& x, UnsignedBigInteger& y, UnsignedBigInteger& gcd, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_r, UnsignedBigInteger& temp_s, UnsignedBigInteger& temp_t); static void destructive_GCD_without_allocation(UnsignedBigInteger& temp_a, UnsignedBigInteger& temp_b, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& output); static void modular_inverse_without_allocation(UnsignedBigInteger const& a_, UnsignedBigInteger const& b, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_minus, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_d, UnsignedBigInteger& temp_u, UnsignedBigInteger& temp_v, UnsignedBigInteger& temp_x, UnsignedBigInteger& result); static void destructive_modular_power_without_allocation(UnsignedBigInteger& ep, UnsignedBigInteger& base, UnsignedBigInteger const& m, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_3, UnsignedBigInteger& temp_multiply, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& result);