ModularInverse.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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_plus,
  17. UnsignedBigInteger& temp_minus,
  18. UnsignedBigInteger& temp_quotient,
  19. UnsignedBigInteger& temp_d,
  20. UnsignedBigInteger& temp_u,
  21. UnsignedBigInteger& temp_v,
  22. UnsignedBigInteger& temp_x,
  23. UnsignedBigInteger& result)
  24. {
  25. UnsignedBigInteger one { 1 };
  26. temp_u.set_to(a);
  27. if (a.words()[0] % 2 == 0) {
  28. // u += b
  29. add_without_allocation(temp_u, b, temp_plus);
  30. temp_u.set_to(temp_plus);
  31. }
  32. temp_v.set_to(b);
  33. temp_x.set_to(0);
  34. // d = b - 1
  35. subtract_without_allocation(b, one, temp_d);
  36. while (!(temp_v == 1)) {
  37. while (temp_v < temp_u) {
  38. // u -= v
  39. subtract_without_allocation(temp_u, temp_v, temp_minus);
  40. temp_u.set_to(temp_minus);
  41. // d += x
  42. add_without_allocation(temp_d, temp_x, temp_plus);
  43. temp_d.set_to(temp_plus);
  44. while (temp_u.words()[0] % 2 == 0) {
  45. if (temp_d.words()[0] % 2 == 1) {
  46. // d += b
  47. add_without_allocation(temp_d, b, temp_plus);
  48. temp_d.set_to(temp_plus);
  49. }
  50. // u /= 2
  51. divide_u16_without_allocation(temp_u, 2, temp_quotient, temp_1);
  52. temp_u.set_to(temp_quotient);
  53. // d /= 2
  54. divide_u16_without_allocation(temp_d, 2, temp_quotient, temp_1);
  55. temp_d.set_to(temp_quotient);
  56. }
  57. }
  58. // v -= u
  59. subtract_without_allocation(temp_v, temp_u, temp_minus);
  60. temp_v.set_to(temp_minus);
  61. // x += d
  62. add_without_allocation(temp_x, temp_d, temp_plus);
  63. temp_x.set_to(temp_plus);
  64. while (temp_v.words()[0] % 2 == 0) {
  65. if (temp_x.words()[0] % 2 == 1) {
  66. // x += b
  67. add_without_allocation(temp_x, b, temp_plus);
  68. temp_x.set_to(temp_plus);
  69. }
  70. // v /= 2
  71. divide_u16_without_allocation(temp_v, 2, temp_quotient, temp_1);
  72. temp_v.set_to(temp_quotient);
  73. // x /= 2
  74. divide_u16_without_allocation(temp_x, 2, temp_quotient, temp_1);
  75. temp_x.set_to(temp_quotient);
  76. }
  77. }
  78. // return x % b
  79. divide_without_allocation(temp_x, b, temp_1, temp_2, temp_3, temp_4, temp_quotient, result);
  80. }
  81. }