威尔逊定理

初识威尔逊定理

什么是威尔逊定理,即对于一个质数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))

 

啊啊啊啊啊啊数论啊啊啊啊啊啊啊

posted @ 2024-10-09 16:32  打盹  阅读(17)  评论(0编辑  收藏  举报