invmod.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.createInvmod = void 0;
  7. var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
  8. var _factory = require("../../utils/factory.js");
  9. var name = 'invmod';
  10. var dependencies = ['typed', 'config', 'BigNumber', 'xgcd', 'equal', 'smaller', 'mod', 'add', 'isInteger'];
  11. var createInvmod = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  12. var typed = _ref.typed,
  13. config = _ref.config,
  14. BigNumber = _ref.BigNumber,
  15. xgcd = _ref.xgcd,
  16. equal = _ref.equal,
  17. smaller = _ref.smaller,
  18. mod = _ref.mod,
  19. add = _ref.add,
  20. isInteger = _ref.isInteger;
  21. /**
  22. * Calculate the (modular) multiplicative inverse of a modulo b. Solution to the equation `ax ≣ 1 (mod b)`
  23. * See https://en.wikipedia.org/wiki/Modular_multiplicative_inverse.
  24. *
  25. * Syntax:
  26. *
  27. * math.invmod(a, b)
  28. *
  29. * Examples:
  30. *
  31. * math.invmod(8, 12) // returns NaN
  32. * math.invmod(7, 13) // returns 2
  33. * math.invmod(15151, 15122) // returns 10429
  34. *
  35. * See also:
  36. *
  37. * gcd, xgcd
  38. *
  39. * @param {number | BigNumber} a An integer number
  40. * @param {number | BigNumber} b An integer number
  41. * @return {number | BigNumber } Returns an integer number
  42. * where `invmod(a,b)*a ≣ 1 (mod b)`
  43. */
  44. return typed(name, {
  45. 'number, number': invmod,
  46. 'BigNumber, BigNumber': invmod
  47. });
  48. function invmod(a, b) {
  49. if (!isInteger(a) || !isInteger(b)) throw new Error('Parameters in function invmod must be integer numbers');
  50. a = mod(a, b);
  51. if (equal(b, 0)) throw new Error('Divisor must be non zero');
  52. var res = xgcd(a, b);
  53. res = res.valueOf();
  54. var _res = res,
  55. _res2 = (0, _slicedToArray2["default"])(_res, 2),
  56. gcd = _res2[0],
  57. inv = _res2[1];
  58. if (!equal(gcd, BigNumber(1))) return NaN;
  59. inv = mod(inv, b);
  60. if (smaller(inv, BigNumber(0))) inv = add(inv, b);
  61. return inv;
  62. }
  63. });
  64. exports.createInvmod = createInvmod;