import time
# 计算x除以2的k次幂函数
def mod_2_k(x, k):
result = x & ((1 << k) - 1)
return result
# Montgomery 模幂函数
def montgomery_power(base, exponent, n, k):
result = 1
while exponent > 0:
if exponent % 2 == 1:
result = montgomery_multiply(result, base, n, k) % n
exponent >>= 1
base = montgomery_multiply(base, base, n, k) % n
return result
# Montgomery 乘法函数
def montgomery_multiply(a, b, n, k):
r = 2 ** k
a_bar = a * r % n
b_bar = b * r % n
n_bar = -pow(n, -1, r) % r
r_bar = pow(r, -1, n)
c = (a_bar * b_bar + mod_2_k(a_bar * b_bar * n_bar, k) * n) >> k
if c >= n:
c = c - n
return c * r_bar % n
# binary 模幂函数
def binary_power(base, exponent, modulus):
"""
二进制模幂
"""
result = 1
base = base % modulus
while exponent > 0:
if exponent % 2 == 1:
result = (result * base) % modulus
exponent >>= 1
base = (base * base) % modulus
return result
# 测试结果,注意n为大素数且2 ** k > n
a = 154
b = 4589412432456775214
n = 123456791153132159454121
k = 20
start_time = time.perf_counter()
result_montgomery = montgomery_power(a, b, n, k)
end_time = time.perf_counter()
execution_time = end_time - start_time
print("montgomery result: ", result_montgomery)
print("using time: ", execution_time)
start_time = time.perf_counter()
result_binary = binary_power(a, b, n)
end_time = time.perf_counter()
execution_time = end_time - start_time
print("binary result: ", result_binary)
print("using time: ", execution_time)