数论小芝士

欧拉定理:https://oi-wiki.org/math/number-theory/fermat/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#[LitCTF 2023]Euler
from Crypto.Util.number import *
from secret import flag

m = bytes_to_long(flag)
p = getPrime(512)
q = getPrime(512)
n = p*q
c = pow(m,n-p-q+3,n)
print(f'n = {n}')
print(f'c = {c}')
"""
n =
c =
"""

,故 ,由欧拉定理可得

直接开根即可

1
2
3
4
import gmpy2
from Crypto.Util.number import long_to_bytes
c =
print( long_to_bytes(gmpy2.iroot(c,2)[0]) )

威尔逊定理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#[长安杯 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

第一步爆破n:

1
2
3
4
5
6
7
hint1 = 
hint2 =
e = 1049
for k in range( 1 , 1000000 ):
if ( 2**e - hint1 ) % k == 0:
n = ( 2**e - hint1 ) // k
print( k , n.bit_length() , n )

得到 ,直接分解得到

第二步:

已知

因为 ,所以 (放缩)

得到方程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import gmpy2
from Crypto.Util.number import long_to_bytes

hint2 = 33035...
e = 1049
n = 58237...

p = 17022...
q = 34211

phi = (p-1)*(q-1)
assert p*q == n
d = gmpy2.invert( e , phi )
m = pow( hint2 , d , n )
print( m )
m = -1*m
for i in range( p-q , p ):
m = m * i % p
print( long_to_bytes(m) )