[ReSnAd]-- iqmp ipmq e,c,\(\phi(n)\)
topic:
class Key:
PRIVATE_INFO = ['P', 'Q', 'D', 'DmP1', 'DmQ1']
def __init__(self, **kwargs):
for k, v in kwargs.items():
setattr(self, k, v)
assert self.bits % 8 == 0
def ispub(self):
return all(not hasattr(self, key) for key in self.PRIVATE_INFO)
def ispriv(self):
return all(hasattr(self, key) for key in self.PRIVATE_INFO)
def pub(self):
p = deepcopy(self)
for key in self.PRIVATE_INFO:
if hasattr(p, key):
delattr(p, key)
return p
def priv(self):
raise NotImplementedError()
def genkey(bits):
assert bits % 2 == 0
while True:
p = genprime(bits // 2)
q = genprime(bits // 2)
e = 65537
d, _, g = egcd(e, (p-1) * (q-1))
if g != 1: continue
iQmP, iPmQ, _ = egcd(q, p)
return Key(
N=p*q, P=p, Q=q, E=e, D=d%((p-1)*(q-1)), DmP1=d%(p-1), DmQ1=d%(q-1),
iQmP=iQmP%p, iPmQ=iPmQ%q, bits=bits,
)
def encrypt(key, data):
data = bytes2num(pad(data, key.bits))
assert 0 <= data and data < key.N
data = pow(data, key.E, key.N)
return num2bytes(data, key.bits // 8)
def decrypt(key, data):
assert key.ispriv() and len(data) * 8 == key.bits
data = bytes2num(data)
assert 0 <= data and data < key.N
v1 = pow(data, key.DmP1, key.P)
v2 = pow(data, key.DmQ1, key.Q)
data = (v2 * key.P * key.iPmQ + v1 * key.Q * key.iQmP) % key.N
return unpad(num2bytes(data, key.bits // 8))
Given variable \ (ipmd, iqmp, e, \ phi (n), c \)
Noticed ipmq,iqmp,_=egcd(p,q)
, get
\ (Ipmq \ cdot p \ equiv1 (\ q way) iqmp \\ \ cdot q \ equiv1 (\ way p) \)
The goal is to launchp,q
\(\begin{cases}ipmq\cdot p=k_1\cdot q+1\\iqmp\cdot q=k_2\cdot p+1\end{cases}\)
Adding the two equations to obtain
\(\because ipmq\cdot p\cdot iqmp\cdot q=k_1\cdot q\cdot k_2\cdot p+k_1\cdot q+k_2\cdot p+1\)
\(\therefore (ipmq\cdot iqmp-k_1\cdot k_2)\cdot n=k_1\cdot q +k_2\cdot p+1\)
Note againiqmp=iqmp%p,ipmq=ipmq%q
\(\begin{cases}iqmp\leq p\\ipmq\geq q\end{cases}\longrightarrow\begin{cases}0\leq k_1<p\\0\leq k_2<q\end{cases}\)
Take \ (k_1, k_2 \) is the right limit, into the front right-hand side
\((ipmq\cdot iqmp-k_1\cdot k_2)\cdot n<2n+1\)
So \ ((ipmq \ cdot iqmp- k_1 \ cdot k_2) \ cdot n \) only 1 or 2
2, the right side of \ (k_1, k_2 \) must take p, q, impossible. As a result, only 1
So \ (n = k_1 \ cdot q + k_2 \ cdot p + 1 \)
Prepared from 3,4 addition two \ (ipmq \ cdot p + iqmp \ cdot q = k_1 \ cdot q + k_2 \ cdot p + 2 = n + 1 \)
And \ (\ phi (n) = (p-1) \ cdot (q-1) = n- (q + p) +1 \)
Listed equations
\(\begin{cases}ipmq\cdot p+iqmp\cdot q=n+1\\\phi(n)=n-(p+q)+1\\\phi(n)=(p-1)\cdot(q-1)\end{cases}\)
Three unknowns n,p,q
, three equations, solvable
Z3 run just fine with
Exp:
from z3 import *
import gmpy2
from Crypto.Util.number import long_to_bytes
q=Int("q")
p=Int("p")
n=Int("n")
phi = 11177929896833318778267064419554047209804133035532602158237892469506082395935495256139136112194510151728917586404919115707761109072628761295860181662822356164160284726297946695851442119129722147684494637497443200139538149832495961915450185804086755272971387407998204100589137627495400914243828434106078332327997903842841517071021248147779935078071506489655500155896938283840729728572328660647233974344849571246788826036265850539775145330135792207209473452843737567371694666658091855216070403504619639510901644370971614286091867701992201923071041178318790575030522483839410855929335515391080189720203086802888683798400
iqmp = 91015809392527255523072044687980286577671138545257803641612547883387289541035388722157767029686572001797549231630088970758132893695316792508265294751302240594796242084165161239587935396541914404832318478070695600559420277875549100164011180835754613742632525637982101603421982448705454195363628987806367263766
ipmq = 10870198964186987138989651624057552405853366954080463316431710442091837631287759912193054100505356356476481503550009625275319473929512195371174525538642232600176213853601253377888749818545192155785873323173291991086758912490744417777560275318548708479769299122462125768416235737869558154549710389717852257846
s=Solver()
s.add(iqmp*q+ipmq*p==n+1)
s.add(phi==(p-1)*(q-1))
s.add(phi==n-(q+p)+1)
s.check()
#print(s.model())
p = 100920329311023043792405408005417242117374946885462223687244834540168939266980874513828622981269823935831791149302266474816959342903482904850705622841034674617774508046423149433115499066314613920674997684075319293745518393044329170181630440249931588961323218471139932722932324367911140345310018504720309693151
q = 110759942750329561983364096770824818957156636845110590823134362698749612147788955083351174879972411435569300696393151260960779092387966200431706198509584768247841937719219850118991339268977853455607397866025870712323459278215127588375709815956587698977630219989552045686550681692693762584298742938231996726337
c = 0x3ce4e91042f61e3b03537d825e7619a02b3f729a91e2de4fb724b95cabe8fb2a7a92c4270025d93aed94f1726ca761083328a7784806e1467f0bc204ef95484ce6b0d207574c6dba4fa91664db4c787e3df517bcfc370a0c5eed8a70b45be8d1e757a9d40eb410e66d2110ac9ece435f76d71e134e2bdbe565e8853e1100ae276211c2b9c49219bca8805ff697dcf84be00b071c3be01f35ba9a4ea1d8ef2c69044982a7fc021d2f6f93b8755948a606a8a376e74d995f439aeeb844ecf678a189916adca406197a1d2eaf2abe84ae6e794560537bcde43a1504f135874d5de9e0a2d95093e4ba7a87641e769e46a911c94ff60525b21c9c709068a89808b6bf
e=65537
d=gmpy2.invert(e,phi)
m=gmpy2.powmod(c,d,p*q)
print(long_to_bytes(m))
Flag:fductf{b97ba9e174d916d30609a6e8b3d78ca3}
[RoarCTF2019]babyRSA -- wilson
topic:
import sympy
import random
def myGetPrime():
A= getPrime(513)
print(A)
B=A-random.randint(1e3,1e5)
print(B)
return sympy.nextPrime((B!)%A)
p=myGetPrime()
#A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
#B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596
q=myGetPrime()
#A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
#B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026
r=myGetPrime()
n=p*q*r
#n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
c=pow(flag,e,n)
#e=0x1001
#c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428
#so,what is the flag?
Note thing B!
is not operational, is a b factorial
Wilson's Theorem \ ((p-1)!
\ Equiv-1 \ bmod p \) key step is to use Wilson's Theorem
\(b=a-x\)
\((a-x)!\cdot(a-x+1)\cdot(a-x+2)\cdot…(a-1)\equiv-1\bmod a\)
Even up by b + 1 to a-1, and inversion. Obtained -b!, B! = Ab!
Exp:
import gmpy2
from Crypto.Util.number import long_to_bytes
A1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467234407
B1=21856963452461630437348278434191434000066076750419027493852463513469865262064340836613831066602300959772632397773487317560339056658299954464169264467140596
A2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858418927
B2=16466113115839228119767887899308820025749260933863446888224167169857612178664139545726340867406790754560227516013796269941438076818194617030304851858351026
n=85492663786275292159831603391083876175149354309327673008716627650718160585639723100793347534649628330416631255660901307533909900431413447524262332232659153047067908693481947121069070451562822417357656432171870951184673132554213690123308042697361969986360375060954702920656364144154145812838558365334172935931441424096270206140691814662318562696925767991937369782627908408239087358033165410020690152067715711112732252038588432896758405898709010342467882264362733
e=0x1001
c=75700883021669577739329316795450706204502635802310731477156998834710820770245219468703245302009998932067080383977560299708060476222089630209972629755965140317526034680452483360917378812244365884527186056341888615564335560765053550155758362271622330017433403027261127561225585912484777829588501213961110690451987625502701331485141639684356427316905122995759825241133872734362716041819819948645662803292418802204430874521342108413623635150475963121220095236776428
def wilison(b,a):
p=1
b=b+1
while b<a:
p*=b
p%=a
b+=1
return a-p
p=gmpy2.next_prime(gmpy2.invert(wilison(B1,A1),A1))
q=gmpy2.next_prime(gmpy2.invert(wilison(B2,A2),A2))
r=n//q//p
phi=(p-1)*(q-1)*(r-1)
d=gmpy2.invert(e,phi)
m=gmpy2.powmod(c,d,n)
print(long_to_bytes(m))
[NCTF2019] childRSA - \ (\ Phi (Q), \ Phi (P) \) is a plurality of small multiplicative factor
topic:
from random import choice
from Crypto.Util.number import isPrime, sieve_base as primes
from flag import flag
def getPrime(bits):
while True:
n = 2
while n.bit_length() < bits:
n *= choice(primes)
if isPrime(n + 1):
return n + 1
e = 0x10001
m = int.from_bytes(flag.encode(), 'big')
p, q = [getPrime(2048) for _ in range(2)]
n = p * q
c = pow(m, e, n)
# n = 32849718197337581823002243717057659218502519004386996660885100592872201948834155543125924395614928962750579667346279456710633774501407292473006312537723894221717638059058796679686953564471994009285384798450493756900459225040360430847240975678450171551048783818642467506711424027848778367427338647282428667393241157151675410661015044633282064056800913282016363415202171926089293431012379261585078566301060173689328363696699811123592090204578098276704877408688525618732848817623879899628629300385790344366046641825507767709276622692835393219811283244303899850483748651722336996164724553364097066493953127153066970594638491950199605713033004684970381605908909693802373826516622872100822213645899846325022476318425889580091613323747640467299866189070780620292627043349618839126919699862580579994887507733838561768581933029077488033326056066378869170169389819542928899483936705521710423905128732013121538495096959944889076705471928490092476616709838980562233255542325528398956185421193665359897664110835645928646616337700617883946369110702443135980068553511927115723157704586595844927607636003501038871748639417378062348085980873502535098755568810971926925447913858894180171498580131088992227637341857123607600275137768132347158657063692388249513
# c = 26308018356739853895382240109968894175166731283702927002165268998773708335216338997058314157717147131083296551313334042509806229853341488461087009955203854253313827608275460592785607739091992591431080342664081962030557042784864074533380701014585315663218783130162376176094773010478159362434331787279303302718098735574605469803801873109982473258207444342330633191849040553550708886593340770753064322410889048135425025715982196600650740987076486540674090923181664281515197679745907830107684777248532278645343716263686014941081417914622724906314960249945105011301731247324601620886782967217339340393853616450077105125391982689986178342417223392217085276465471102737594719932347242482670320801063191869471318313514407997326350065187904154229557706351355052446027159972546737213451422978211055778164578782156428466626894026103053360431281644645515155471301826844754338802352846095293421718249819728205538534652212984831283642472071669494851823123552827380737798609829706225744376667082534026874483482483127491533474306552210039386256062116345785870668331513725792053302188276682550672663353937781055621860101624242216671635824311412793495965628876036344731733142759495348248970313655381407241457118743532311394697763283681852908564387282605279108%
Talk about the unexpected solution
From the encryption process to generate prime numbers can be seen p,q
to be very close, then you can try yafu factoring large prime number
But the command-line mode can not be entered is too long, we create a new n.txt
, value of n is written in it, pay attention to add the final wrap! And then use the command line command yafu-x64.exe "factor(@)" -batchfile n.txt
. Then after a few seconds to get the value of pq.
People thought the topic:
http://www.soreatu.com/ctf/writeups/Writeup%20for%20Crypto%20problems%20in%20NCTF%202019.html#childrsa
Other topics again after supplement ......