Realtime Price(实时价格):

什么是模逆元

作者:aaron67

时间:2020年10月11日 00:50:38

来源:https://blog.csdn.net/aaron67/article/details/109006977

整数 a 除以整数 b,若得到的余数是 r,则记作

a   mod   b = r

例如

5   mod   3 = 2

− 5   mod   3 = 1

模运算的部分性质如下:

( a + b )   mod   c = ( ( a   mod   c ) + ( b   mod   c ) )   mod   c

( a ⋅ b )   mod   c = ( ( a   mod   c ) ⋅ ( b   mod   c ) )   mod   c

a^b   mod   c = ( a   mod   c )^b   mod   c

如果你对模运算还不太熟悉,推荐先阅读 Khan Academy 的入门课程

同余

两个整数 a、b,若它们除以正整数 n 所得的余数相等,即 a   mod   n = b   mod   n,则称 a 和 b 对于模 n 同余,记作

a ≡ b ( mod n )

读作 a 同余于 b 模 n,或 a 和 b 关于模 n 同余。例如

2 ≡ 8 ( mod 6 )

当 k 为整数(k ∈ Z)时,同余关系有如下性质。

a ≡ b ( mod n ) ⇒ ak ≡ bk ( mod n )

当 k、n 互质时,有

ak ≡ bk ( mod n ) ⇒ a ≡ b ( mod n )

模逆元

参考倒数(xy = 1)的定义,对整数 a 和 b,若

ab ≡ 1 ( mod n )

则称 a 和 b 关于模 n 互为模倒数,也叫模反元素或模逆元(modular multiplicative inverse),还可以记作

b ≡ 1/a ( mod n ) 或 b ≡ a^(−1) ( mod n )

类似于实数除法,在模 n 下的除法可以用和对应模逆元的乘法来表达。”分数取模”,等价于求分母的模逆元。

当 a、b 关于模 n 互为模逆元时,b   mod   n = 1/a   mod   n

c/a   mod   n = ( c ⋅ 1/a )   mod   n = ( ( c   mod   n ) ⋅ ( 1/a   mod   n ) )   mod   n = ( ( c   mod   n ) ⋅ ( b   mod   n ) )   mod   n = ( c ⋅ b )   mod   n

例如

20/3   mod   7 = ( ( 20   mod   7 ) ⋅ ( 1/3   mod   7 ) )   mod   7 = ( 6 × 5 )   mod   7 = 2

根据定义,求 a 关于模 n 的模逆元,若 b 是解,k ∈ Z,则 b + k n也都是解,且最小的非负整数解小于 n,例如

2 × 3 ≡ 1 ( mod 5 )

2 × 8 ≡ 1 ( mod 5 )

即 3 和 8 都是 2 关于模 5 的模逆元,其中 3 是最小的非负整数解。所以求模逆元可以通过遍历 0 ~ n 来确定。

# find modular multiplicative inverse of ‘a’ under modulo ‘n’
def modular_multiplicative_inverse(a: int, n: int) -> int:
for i in range(n):
if (a * i) % n == 1:
return i
raise ValueError(‘{} has no multiplicative inverse under modulo {}’.format(a, n))

但这种方法在 n 取值很大时效率不高。你可以参考文章 Modular multiplicative inverse,使用扩展欧几里得算法或费马小定理改进。

def extended_euclid_gcd(a: int, b: int) -> list:
“””
Returns [gcd(a, b), x, y] where ax + by = gcd(a, b)
“””
s, old_s = 0, 1
t, old_t = 1, 0
r, old_r = b, a
while r != 0:
quotient = old_r // r
old_r, r = r, old_r – quotient * r
old_s, s = s, old_s – quotient * s
old_t, t = t, old_t – quotient * t
return [old_r, old_s, old_t]

def modular_multiplicative_inverse(a: int, n: int) -> int:
“””
Assumes that a and n are co-prime, returns modular multiplicative inverse of a under n
“””
# Find gcd using Extended Euclid’s Algorithm
gcd, x, y = extended_euclid_gcd(a, n)
# In case x is negative, we handle it by adding extra n
# Because we know that modular multiplicative inverse of a in range n lies in the range [0, n-1]
if x < 0:
x += n
return x

已知整数 a、n,使用扩展欧几里得算法可以求出整数 x、y、g 满足下式。

ax + ny = g

其中,g 是 a 和 n 的最大公约数。上式两边同模 n,有

( ax + ny )   mod   n = ( ax   mod   n ) + ( ny   mod   n ) = ax   mod   n = g   mod   n

ax ≡ g ( mod n )

当 a、n 互质时,g = 1,此时 x 就是解。当 g ≠ 1 时, a 关于模 n 的模逆元不存在。

两数互质的充分必要条件是两数的最大公约数为 1。也就是说,a 关于模 n 的模逆元存在的充分必要条件是 a 和 n 互质。

完整代码
modular_inverse.py

相关文章:

比特币布道者

比特币的坚定信仰者!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注