Ищете divm или gmpy эквивалент для Ruby

В модуле расширения gmpy2 для Python есть целочисленный тип с множественной точностью, называемый mpz. Он содержит powmod(x, y, m) функция, и я скучал по этому в Ruby. Недавно я узнал, что Руби на самом деле имеет powmod, Это скрыто в модуле OpenSSL.

require 'openssl'
result = a_big_int.to_bn.mod_exp(exponent, modulo)

Другая функция, которая также есть в gmpy2, я пропустил divm(...),

divm (a, b, m) возвращает x такое, что b * x == по модулю m. Вызывает исключение ZeroDivisionError, если такого значения x не существует.

Знаете ли вы, что у модуля OpenSSL есть еще один сюрприз в рукаве или какой-либо драгоценный камень, который имеет такую ​​функцию? Было бы очень полезно, если бы это было быстро.

2 ответа

Быстрое погружение в код в GMP для divm(a, b, m) показывает, что это по существу делает это

б-1 * а% м

Где b-1 - модульный мультипликативный обратный. Существует некоторая резервная логика для случая, когда вызов invert завершается неудачно (мне неясно, когда это может произойти), но для большинства целей вы можете сделать это в Ruby примерно так (используя те же имена переменных, что и для divm подпись метода):

b.to_bn.mod_inverse(m).mod_mul(a, m).to_i

Я не уверен, насколько они доступны в Ruby или Python.


Он содержит powmod(x, y, m)...

int BN_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p,
    const BIGNUM *m, BN_CTX *ctx);

divm(a, b, m)...

int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *a,
    const BIGNUM *d, BN_CTX *ctx);

Вы можете увидеть полные документы в OpenSSL bn (3).

Другие вопросы по тегам