初识威尔逊定理
什么是威尔逊定理,即对于一个质数p来说,有
(p-1)! ≡ -1 (mod p)
恒成立,其逆定理也成立,即对于一个数p来说若满足上式,则p一定是素数。
于是通过这个性质我们能够得到素数分布的函数:
f(n) = sin(π*((n-1)!+1)/n)
当函数值为0时,对应n就是一个素数,但好像没用(确信。
推广有
(p-2)! ≡ 1 (mod p)
至于证明,因为此处主要讨论威尔逊定理的含义和应用,所以不再赘述证明过程。
例题:[长安杯 2021]checkin
附件:
from Crypto.Util.number import *
from secret import flag
p = getPrime(1024)
q = getPrime(16)
n = p*q
m = bytes_to_long(flag)
for i in range(1,p-q):
m = m*i%n
e = 1049
print(pow(2,e,n))
print(pow(m,e,n))
#4513855932190587780512692251070948513905472536079140708186519998265613363916408288602023081671609336332823271976169443708346965729874135535872958782973382975364993581165018591335971709648749814573285241290480406050308656233944927823668976933579733318618949138978777831374262042028072274386196484449175052332019377
#3303523331971096467930886326777599963627226774247658707743111351666869650815726173155008595010291772118253071226982001526457616278548388482820628617705073304972902604395335278436888382882457685710065067829657299760804647364231959804889954665450340608878490911738748836150745677968305248021749608323124958372559270
思路:
由2**e得出kn,再去爆破q,kn//q得到kp,分解kp得到p(根据比特大概看看就行),mm = m*(p-q-1)!,要消去这个阶乘,所以把m乘到(p-1)!,得到m*(p-1)!≡ -m (mod p) ,最后逆元消-1。
exp:
from Crypto.Util.number import *
from gmpy2 import *
from sympy import *
e = 1049
c = 3303523331971096467930886326777599963627226774247658707743111351666869650815726173155008595010291772118253071226982001526457616278548388482820628617705073304972902604395335278436888382882457685710065067829657299760804647364231959804889954665450340608878490911738748836150745677968305248021749608323124958372559270
c2 = 4513855932190587780512692251070948513905472536079140708186519998265613363916408288602023081671609336332823271976169443708346965729874135535872958782973382975364993581165018591335971709648749814573285241290480406050308656233944927823668976933579733318618949138978777831374262042028072274386196484449175052332019377
kn = 2**e - c2
for i in range(2**15,2**16):
if(isprime(i)):
if(kn%i == 0):
q = i
kp = kn//i
break
p = 170229264879724117919007372149468684565431232721075153274808454126426741324966131188484635914814926870341378228417496808202497615585946352638507704855332363766887139815236730403246238633855524068161116748612090155595549964229654262432946553891601975628848891407847198187453488358420350203927771308228162321231
n = p*q
phi = (p-1)*(q-1)
d = inverse(e,phi)
m = pow(c,d,n)
for i in range(p - q , p ):
m = ( m * i ) % p
m = m * inverse(-1,p) % p
print(long_to_bytes(m))