Crypto

EZDORSA_Lv1

ChatGPT

EZDORSA_Lv2

$e$ が小さいので RSA の運用的にまずい.RSA の暗号化において $C=M^e\mod N$ だが,ここで $e$ が小さいと $M^e$ も小さくなる. このとき $M < \sqrt[e]{N}$ なら, $M^e < N$ より $\mod N$ が関係なくなる. すると $C=M^e$ になるので $M = \sqrt[e]{C}$ でOK

import gmpy2
from Crypto.Util.number import *

# 提供されたoutput.txtの内容
n = 25465155563758206895066841861765043433123515683929678836771513150236561026403556218533356199716126886534636140138011492220383199259698843686404371838391552265338889731646514381163372557117810929108511770402714925176885202763093259342499269455170147345039944516036024012941454077732406677284099700251496952610206410882558915139338028865987662513205888226312662854651278789627761068396974718364971326708407660719074895819282719926846208152543027213930660768288888225218585766787196064375064791353928495547610416240104448796600658154887110324794829898687050358437213471256328628898047810990674288648843902560125175884381
e = 7
c = 25698620825203955726406636922651025698352297732240406264195352419509234001004314759538513429877629840120788601561708588875481322614217122171252931383755532418804613411060596533561164202974971066750469395973334342059753025595923003869173026000225212644208274792300263293810627008900461621613776905408937385021630685411263655118479604274100095236252655616342234938221521847275384288728127863512191256713582669212904042760962348375314008470370142418921777238693948675063438713550567626953125

tmp = pow(5, 100, n)
c = c // tmp
print(tmp)
print(c)

m,result = gmpy2.iroot(c,e)

print(m)
print(long_to_bytes(int(m)))

EZDORSA_Lv3

$n$ はせいぜい 25 bit の素数同士の積なので素因数分解ができる

factor(22853745492099501680331664851090320356693194409008912025285744113835548896248217185831291330674631560895489397035632880512495471869393924928607517703027867997952256338572057344701745432226462452353867866296639971341288543996228186264749237402695216818617849365772782382922244491233481888238637900175603398017437566222189935795252157020184127789181937056800379848056404436489263973129205961926308919968863129747209990332443435222720181603813970833927388815341855668346125633604430285047377051152115484994149044131179539756676817864797135547696579371951953180363238381472700874666975466580602256195404619923451450273257882787750175913048168063212919624027302498230648845775927955852432398205465850252125246910345918941770675939776107116419037)

単純に複数の素数からなる RSA になるので,復号すればいい

from math import gcd
from functools import reduce
from Crypto.Util.number import *

n = 22853745492099501680331664851090320356693194409008912025285744113835548896248217185831291330674631560895489397035632880512495471869393924928607517703027867997952256338572057344701745432226462452353867866296639971341288543996228186264749237402695216818617849365772782382922244491233481888238637900175603398017437566222189935795252157020184127789181937056800379848056404436489263973129205961926308919968863129747209990332443435222720181603813970833927388815341855668346125633604430285047377051152115484994149044131179539756676817864797135547696579371951953180363238381472700874666975466580602256195404619923451450273257882787750175913048168063212919624027302498230648845775927955852432398205465850252125246910345918941770675939776107116419037
e = 65537
c = 1357660325421905236173040941411359338802736250800006453031581109522066541737601274287649030380468751950238635436299480021037135774086215029644430055129816920963535754048879496768378328297643616038615858752932646595502076461279037451286883763676521826626519164192498162380913887982222099942381717597401448235443261041226997589294010823575492744373719750855298498634721551685392041038543683791451582869246173665336693939707987213605159100603271763053357945861234455083292258819529224561475560233877987367901524658639475366193596173475396592940122909195266605662802525380504108772561699333131036953048249731269239187358174358868432968163122096583278089556057323541680931742580937874598712243278738519121974022211539212142588629508573342020495

a_array=[]
n_array=[]
divisors = [16969003, 17009203, 17027027, 17045117, 17137009, 17151529, 17495507, 17685739, 17933647, 18206689, 18230213, 18505933, 18613019, 18868781, 18901951, 18947729, 19022077, 19148609, 19574987, 19803209, 20590697, 20690983, 21425317, 21499631, 21580043, 21622099, 21707797, 21781139, 21792359, 21982481, 22101437, 22367311, 22374509, 22407799, 22491913, 22537409, 22542229, 22550677, 22733041, 23033441, 23049673, 23083759, 23179243, 23342663, 23563571, 23611043, 23869933, 24027973, 24089029, 24436597, 24454291, 24468209, 24848633, 25564219, 25888721, 26055889, 26119147, 26839909, 27152267, 27304777, 27316717, 27491137, 27647687, 27801167, 28082749, 28103563, 28151399, 28620611, 29035709, 29738689, 29891363, 29979379, 30007841, 30013391, 30049171, 30162343, 30419063, 30461393, 30625601, 31004861, 31108043, 31123457, 31269479, 31384663, 31387957, 31390189, 31469279, 32307589, 32432339, 32514061, 32628367, 32687509, 32703337, 32709977, 32715343, 32737429, 32831261, 33388603, 33418129, 33472771]

def mul_inv(a, b):
    b0 = b
    x0, x1 = 0, 1
    if b == 1: return 1
    while a > 1:
        q = a // b
        a, b = b, a%b
        x0, x1 = x1 - q * x0, x0
    if x1 < 0: x1 += b0
    return x1

def CRT(n, a):
    sum = 0
    prod = reduce(lambda a, b: a*b, n)
    for ni, ai in zip(n,a):
        p=prod // ni
        sum += ai * mul_inv(p, ni) * p
    return sum % prod

for p in divisors:
    phi = p-1
    d = mul_inv(e, phi)
    mk = pow(c, d, p)
    n_array.append(p)
    a_array.append(mk)

print(n_array)
print(a_array)

m = CRT(n_array, a_array)
print(long_to_bytes(int(m)))

こんな CRT とかしなくても素朴に実装すれば OK

from math import gcd
from functools import reduce
from Crypto.Util.number import *

n = 22853745492099501680331664851090320356693194409008912025285744113835548896248217185831291330674631560895489397035632880512495471869393924928607517703027867997952256338572057344701745432226462452353867866296639971341288543996228186264749237402695216818617849365772782382922244491233481888238637900175603398017437566222189935795252157020184127789181937056800379848056404436489263973129205961926308919968863129747209990332443435222720181603813970833927388815341855668346125633604430285047377051152115484994149044131179539756676817864797135547696579371951953180363238381472700874666975466580602256195404619923451450273257882787750175913048168063212919624027302498230648845775927955852432398205465850252125246910345918941770675939776107116419037
e = 65537
c = 1357660325421905236173040941411359338802736250800006453031581109522066541737601274287649030380468751950238635436299480021037135774086215029644430055129816920963535754048879496768378328297643616038615858752932646595502076461279037451286883763676521826626519164192498162380913887982222099942381717597401448235443261041226997589294010823575492744373719750855298498634721551685392041038543683791451582869246173665336693939707987213605159100603271763053357945861234455083292258819529224561475560233877987367901524658639475366193596173475396592940122909195266605662802525380504108772561699333131036953048249731269239187358174358868432968163122096583278089556057323541680931742580937874598712243278738519121974022211539212142588629508573342020495

a_array=[]
n_array=[]
divisors = [16969003, 17009203, 17027027, 17045117, 17137009, 17151529, 17495507, 17685739, 17933647, 18206689, 18230213, 18505933, 18613019, 18868781, 18901951, 18947729, 19022077, 19148609, 19574987, 19803209, 20590697, 20690983, 21425317, 21499631, 21580043, 21622099, 21707797, 21781139, 21792359, 21982481, 22101437, 22367311, 22374509, 22407799, 22491913, 22537409, 22542229, 22550677, 22733041, 23033441, 23049673, 23083759, 23179243, 23342663, 23563571, 23611043, 23869933, 24027973, 24089029, 24436597, 24454291, 24468209, 24848633, 25564219, 25888721, 26055889, 26119147, 26839909, 27152267, 27304777, 27316717, 27491137, 27647687, 27801167, 28082749, 28103563, 28151399, 28620611, 29035709, 29738689, 29891363, 29979379, 30007841, 30013391, 30049171, 30162343, 30419063, 30461393, 30625601, 31004861, 31108043, 31123457, 31269479, 31384663, 31387957, 31390189, 31469279, 32307589, 32432339, 32514061, 32628367, 32687509, 32703337, 32709977, 32715343, 32737429, 32831261, 33388603, 33418129, 33472771]

phi = 1

for i in divisors:
    phi *= (i-1)

d = pow(e, -1, phi)
m = pow(c, d, n)
print(long_to_bytes(int(m)))

pqqp

$s=p^q + q^p\mod n$ がリークしているので,これから RSA を復号しようみたいな問題.

$$ s = p^q + q^p mod n\\ s = p^q + q^p + kn = p^q + q^p + k(pq)

$$

フェルマーの小定理を使う

$$ s = q^p \mod q = p \mod q\\ s = p^q \mod p = q \mod p\\ s = p+q \mod pq $$

よって $s=p+q, n=pq$ で p, q を知れればOK

import gmpy2
from Crypto.Util.number import *
from sympy import *

n=31091873146151684702346697466440613735531637654275447575291598179592628060572504006592135492973043411815280891993199034777719870850799089897168085047048378272819058803065113379019008507510986769455940142811531136852870338791250795366205893855348781371512284111378891370478371411301254489215000780458922500687478483283322613251724695102723186321742517119591901360757969517310504966575430365399690954997486594218980759733095291730584373437650522970915694757258900454543353223174171853107240771137143529755378972874283257666907453865488035224546093536708315002894545985583989999371144395769770808331516837626499129978673
e=65537
c=8684906481438508573968896111659984335865272165432265041057101157430256966786557751789191602935468100847192376663008622284826181320172683198164506759845864516469802014329598451852239038384416618987741292207766327548154266633297700915040296215377667970132408099403332011754465837054374292852328207923589678536677872566937644721634580238023851454550310188983635594839900790613037364784226067124711011860626624755116537552485825032787844602819348195953433376940798931002512240466327027245293290482539610349984475078766298749218537656506613924572126356742596543967759702604297374075452829941316449560673537151923549844071
s=352657755607663100038622776859029499529417617019439696287530095700910959137402713559381875825340037254723667371717152486958935653311880986170756144651263966436545612682410692937049160751729509952242950101025748701560375826993882594934424780117827552101647884709187711590428804826054603956840883672204048820926

p = symbols("p")
q = symbols("q")

eq = [p*q-n, p+q-s]
result = list(nonlinsolve(eq,[p,q]))

p,q=int(result[1][0]), int(result[1][1])

phi=(p-1)*(q-1)
d = gmpy2.invert(e,phi)
m=pow(c,d,n)

flag = long_to_bytes(m)
print(flag)