Rating: 5.0

ruby
require 'json'
require 'openssl'

p = OpenSSL::BN::generate_prime(1024).to_i
q = OpenSSL::BN::generate_prime(1024).to_i

while true
d = OpenSSL::BN::generate_prime(1024).to_i
break if ((p - 1) * (q - 1)).gcd(d) == 1 && ((p - 1) * (q - 1)).gcd(d + 2) == 1
end

e1 = OpenSSL::BN.new(d).mod_inverse(OpenSSL::BN.new((p - 1) * (q - 1))).to_i
e2 = OpenSSL::BN.new(d + 2).mod_inverse(OpenSSL::BN.new((p - 1) * (q - 1))).to_i

msg = OpenSSL::BN.new(flag.unpack1("H*").to_i(16))
n = OpenSSL::BN.new(p * q)
enc = msg.mod_exp(OpenSSL::BN.new(e1), n)

puts ({ n: (p*q).to_s, e1: e1.to_s, e2: e2.to_s, enc: enc.to_s }).to_json


We get $e_1$, $e_2$ such that
$$e_1d \equiv e_2(d+2) \equiv 1 \pmod{\phi(n)}$$
Rearranging, we obtain
$$e_1d - e_2d \equiv 2e_2$$
$$(e_1 - e_2)d \equiv 2e_2$$
Multiplying both sides by $e_1$,
$$(e_1 - e_2)e_1d \equiv 2e_2e_1$$
Recall that $e_1d \equiv 1$:
$$(e_1 - e_2) \equiv 2e_2e_1$$
$$e_1 - e_2 - 2e_2e_1 \equiv 0 \pmod{\phi(n)}$$
$$e_1 - e_2 - 2e_2e_1 = k\phi(n) \qquad k \in \mathbb Z$$

Thus, we can calculate a multiple of $\phi(n)$ and use it to get a $d'$ such that
$$e_1d' \equiv 1 \pmod{k\phi(n)}$$
$$\Rightarrow d \equiv d' \pmod{\phi(n)}$$

As such, we can use $c^{d'} \bmod n$ will also result in $m$.

python
import binascii
n = 26524843197458127443771133945229625523754949369487014791599807627467226519111599787153382777120140612738257288082433176299499326592447109018282964262146097640978728687735075346441171264146957020277385391199481846763287915008056667746576399729177879290302450987806685085618443327429255304452228199990620148364422757098951306559334815707120477401429317136913170569164607984049390008219435634838332608692894777468452421086790570305857094650986635845598625452629832435775350210325954240744747531362581445612743502972321327204242178398155653455971801057422863549217930378414742792722104721392516098829240589964116113253433
e1 = 3288342258818750594497789899280507988608009422632301901890863784763217616490701057613228052043090509927547686042501854377982072935093691324981837282735741669355268200192971934847782966333731663681875702538275775308496023428187962287009210326890218776373213535570853144732649365499644400757341574136352057674421661851071361132160580465606353235714126225246121979148071634839325793257419779891687075215244608092289326285092057290933330050466351755345025419017436852718353794641136454223794422184912845557812856838827270018279670751739019476000437382608054677808858153944204833144150494295177481906551158333784518167127
e2 = 20586777123945902753490294897129768995688830255152547498458791228840609956344138109339907853963357359541404633422300744201016345576195555604505930482179414108021094847896856094422857747050686108352530347664803839802347635174893144994932647157839626260092064101372096750666679214484068961156588820385019879979501182685765627312099064118600537936317964839371569513285434610671748047822599856396277714859626710571781608350664514470335146001120348208741966215074474578729244549563565178792603028804198318917007000826819363089407804185394528341886863297204719881851691620496202698379571497376834290321022681400643083508905
enc = 18719581313246346528221007858250620803088488607301313701590826442983941607809029805859628525891876064099979252513624998960822412974893002313208591462294684272954861105670518560956910898293761859372361017063600846481279095019009757152999533708737044666388054242961589273716178835651726686400826461459109341300219348927332096859088013848939302909121485953178179602997183289130409653008932258951903333059085283520324025705948839786487207249399025027249604682539137261225462015608695527914414053262360726764369412756336163681981689249905722741130346915738453436534240104046172205962351316149136700091558138836774987886046

kphi = e1 - e2 - 2*e2*e1
dd = pow(e1, -1, kphi)
msg = pow(enc, dd, n)
print(binascii.unhexlify(hex(msg)[2:]))