ModularInverse.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. * Copyright (c) 2020-2021, Dex♪ <dexes.ttp@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "UnsignedBigIntegerAlgorithms.h"
  8. namespace Crypto {
  9. void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation(
  10. UnsignedBigInteger const& a,
  11. UnsignedBigInteger const& b,
  12. UnsignedBigInteger& temp_1,
  13. UnsignedBigInteger& temp_2,
  14. UnsignedBigInteger& temp_3,
  15. UnsignedBigInteger& temp_4,
  16. UnsignedBigInteger& temp_minus,
  17. UnsignedBigInteger& temp_quotient,
  18. UnsignedBigInteger& temp_d,
  19. UnsignedBigInteger& temp_u,
  20. UnsignedBigInteger& temp_v,
  21. UnsignedBigInteger& temp_x,
  22. UnsignedBigInteger& result)
  23. {
  24. UnsignedBigInteger one { 1 };
  25. temp_u.set_to(a);
  26. if (a.words()[0] % 2 == 0) {
  27. // u += b
  28. add_into_accumulator_without_allocation(temp_u, b);
  29. }
  30. temp_v.set_to(b);
  31. temp_x.set_to(0);
  32. // d = b - 1
  33. subtract_without_allocation(b, one, temp_d);
  34. while (!(temp_v == 1)) {
  35. while (temp_v < temp_u) {
  36. // u -= v
  37. subtract_without_allocation(temp_u, temp_v, temp_minus);
  38. temp_u.set_to(temp_minus);
  39. // d += x
  40. add_into_accumulator_without_allocation(temp_d, temp_x);
  41. while (temp_u.words()[0] % 2 == 0) {
  42. if (temp_d.words()[0] % 2 == 1) {
  43. // d += b
  44. add_into_accumulator_without_allocation(temp_d, b);
  45. }
  46. // u /= 2
  47. divide_u16_without_allocation(temp_u, 2, temp_quotient, temp_1);
  48. temp_u.set_to(temp_quotient);
  49. // d /= 2
  50. divide_u16_without_allocation(temp_d, 2, temp_quotient, temp_1);
  51. temp_d.set_to(temp_quotient);
  52. }
  53. }
  54. // v -= u
  55. subtract_without_allocation(temp_v, temp_u, temp_minus);
  56. temp_v.set_to(temp_minus);
  57. // x += d
  58. add_into_accumulator_without_allocation(temp_x, temp_d);
  59. while (temp_v.words()[0] % 2 == 0) {
  60. if (temp_x.words()[0] % 2 == 1) {
  61. // x += b
  62. add_into_accumulator_without_allocation(temp_x, b);
  63. }
  64. // v /= 2
  65. divide_u16_without_allocation(temp_v, 2, temp_quotient, temp_1);
  66. temp_v.set_to(temp_quotient);
  67. // x /= 2
  68. divide_u16_without_allocation(temp_x, 2, temp_quotient, temp_1);
  69. temp_x.set_to(temp_quotient);
  70. }
  71. }
  72. // return x % b
  73. divide_without_allocation(temp_x, b, temp_1, temp_2, temp_3, temp_4, temp_quotient, result);
  74. }
  75. }