description: 任何一件事情,只要心甘情愿,总是能够变得简单。每天积累一点点儿。
化简 s = ( p o w ( p , q , n ) + p o w ( q , p , n ) ) m o d n , p , q 都 是 素 数 且 n = p ∗ q s = (pow(p, q, n) + pow(q, p, n))\textbf{ } mod\textbf{ } n,p,q都是素数且n=p*q s=(pow(p,q,n)+pow(q,p,n)) mod n,p,q都是素数且n=p∗q
s = ( p o w ( p , q , n ) + p o w ( q , p , n ) ) m o d n s = (pow(p, q, n) + pow(q, p, n))\textbf{ } mod\textbf{ } n s=(pow(p,q,n)+pow(q,p,n)) mod n
= p q m o d n + q p m o d n =p^{q}\textbf{ }mod\textbf{ }n+q^{p}\textbf{ }mod\textbf{ }n =pq mod n+qp mod n
= p q m o d ( p ∗ q ) + q p m o d ( p ∗ q ) =p^{q}\textbf{ }mod\textbf{ }(p*q)+q^{p}\textbf{ }mod\textbf{ }(p*q) =pq mod (p∗q)+qp mod (p∗q)
= ( p q m o d p + p q m o d q ) + ( q p m o d p + q p m o d q ) =(p^{q}\textbf{ }mod\textbf{ }p+p^{q}\textbf{ }mod\textbf{ }q)+(q^{p}\textbf{ }mod\textbf{ }p+q^{p}\textbf{ }mod\textbf{ }q) =(pq mod p+pq mod q)+(qp mod p+qp mod q)
= p q m o d q + q p m o d p =p^{q}\textbf{ }mod\textup{ }q+q^{p}\textup{ }mod\textbf{ }p =pq mod q+qp mod p
由费马小定理可知, a p − 1 = 1 m o d p , p 是 素 数 a^{p-1}=1\textbf{ }mod\textbf{ }p,p是素数 ap−1=1 mod p,p是素数
所以 p q m o d q = ( p q − 1 ) ∗ p m o d q = p m o d q p^{q}\textbf{ }mod\textbf{ }q=(p^{q-1})*p\textbf{ }mod\textbf{ }q=p\textbf{ }mod\textbf{ }q pq mod q=(pq−1)∗p mod q=p mod q
同理可得 q p m o d p = q m o d p q^{p}\textbf{ }mod\textbf{ }p=q\textbf{ }mod\textbf{ }p qp mod p=q mod p
综上, s = ( p o w ( p , q , n ) + p o w ( q , p , n ) ) m o d n = p + q s = (pow(p, q, n) + pow(q, p, n))\textbf{ } mod\textbf{ } n=p+q s=(pow(p,q,n)+pow(q,p,n)) mod n=p+q
爆破4位md5值脚本
from hashlib import md5
from itertools import product
table="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
tail="gcwJ"
_hash="f383dc8fd2157374dc2aec9df83df320"
for i in product(table, repeat=4):
head = ''.join(i)
t = md5((head + tail).encode()).hexdigest()
if t == _hash:
print(i)
十秒内出结果。
Python的排列组合函数
itertools模块下提供了一些用于生成排列组合的工具函数。
- product(p, q, … [repeat=1]):用序列p、q、…序列中的元素进行排列(元素会重复)。就相当于使用嵌套循环组合。
- permutations(p[, r]):从序列p中取出r个元素的组成全排列,组合得到元组作为新迭代器的元素。
- combinations(p, r):从序列p中取出r个元素组成全组合,元素不允许重复,组合得到元组作为新迭代器的元素。
- combinations_with_replacement(p, r),从序列p中取出r个元素组成全组合,元素允许重复,组合得到元组作为新迭代器的元素。
如下程序示范了上面4个函数的用法。
import itertools as it
# 使用两个序列进行排列组合
for e in it.product('AB', 'CD'):
print(''.join(e), end=', ') # AC, AD, BC, BD,
print('\n---------')
# 使用一个序列、重复2次进行全排列
for e in it.product('AB', repeat=2):
print(''.join(e), end=', ') # AA, AB, BA, BB,
print('\n---------')
# 从序列中取2个元素进行排列
for e in it.permutations('ABCD', 2):
print(''.join(e), end=', ') # AB, AC, AD, BA, BC, BD, CA, CB, CD, DA, DB, DC,
print('\n---------')
# 从序列中取2个元素进行组合、元素不允许重复
for e in it.combinations('ABCD', 2):
print(''.join(e), end=', ') # AB, AC, AD, BC, BD, CD,
print('\n---------')
# 从序列中取2个元素进行组合、元素允许重复
for e in it.combinations_with_replacement('ABCD', 2):
print(''.join(e), end=', ') # AA, AB, AC, AD, BB, BC, BD, CC, CD, DD,
上面程序用到了一个字符串的join()方法,该方法用于将元组的所有元素都连接成一个字符串。
RSA中已知phi和n分解n
from math import gcd
from math import isqrt
from random import randrange
from gmpy2 import is_prime
# from sage.all import is_prime
def factorize(N, phi):
"""
如果欧拉系数已知,则从模中恢复素因数。
此方法仅适用于由 2 个素数组成的模!
:param N: 模数
:param phi: 欧拉 totient,乘法群模 N 的阶数
:return: 包含素因数的元组,如果未找到因数则返回 None
"""
s = N + 1 - phi # p+q
d = s ** 2 - 4 * N # (p-q)^2
p = int(s - isqrt(d)) // 2
q = int(s + isqrt(d)) // 2
return p, q
def factorize_multi_prime(N, phi):
"""
Recovers the prime factors from a modulus if Euler's totient is known.
This method works for a modulus consisting of any number of primes, but is considerably be slower than factorize.
More information: Hinek M. J., Low M. K., Teske E., "On Some Attacks on Multi-prime RSA" (Section 3)
:param N: the modulus
:param phi: Euler's totient, the order of the multiplicative group modulo N
:return: a tuple containing the prime factors
"""
prime_factors = set()
factors = [N]
while len(factors) > 0:
# Element to factorize.
N = factors[0]
w = randrange(2, N - 1)
i = 1
while phi % (2 ** i) == 0:
sqrt_1 = pow(w, phi // (2 ** i), N)
if sqrt_1 > 1 and sqrt_1 != N - 1: # 计算非平凡平方根
# We can remove the element to factorize now, because we have a factorization.
factors = factors[1:]
p = gcd(N, sqrt_1 + 1)
q = N // p
if is_prime(p):
prime_factors.add(p)
elif p > 1:
factors.append(p)
if is_prime(q):
prime_factors.add(q)
elif q > 1:
factors.append(q)
# Continue in the outer loop
break
i += 1
return tuple(prime_factors)
N =
phi =
prime = factorize_multi_prime(N,phi)
print(prime)