2021V&N 公开赛,因为个人原因(咕咕咕🕊所以只做了一个签到

在补上了在补上了额👾👾👾

WhiteGive

呜呜呜,白给题不会做

题目描述如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
from Crypto.Util.number import *
from secret import url
from gmpy2 import *

m = bytes_to_long(url)
p = getPrime(512)
q = getPrime(512)
n = p * q
d = getPrime(256)
e = inverse(d,(p-1)*(q-1))
c = pow(m,e,n)

print(n)
print(c)

m = e
p = getPrime(512)
q = getPrime(512)
n = p * p * q
e = 0x10001
d = inverse(e,lcm(p,lcm(p-1,q-1)))
c = pow(m,e,n)
hint = pow(d,e,n)

print(n)
print(c)
print(hint)

'''
97814568264814384858194701955408461509880555772006698372422205341758322175891474378211599333051180365254844248340812534463000531890490435018379585036704801177155418066770861143206836558793774360498040810255823235715535487716966004194143204900564413879660115112965484824906920141847149888933004740523449213441
86143311788363675684674113699193046781796638913243016152555572150858159500527674063754694514501999791875561142925154991000532628799185608465062814546108160434468098898040769021072007374156546314975240583347468026001633652940408779155579339470960571067652924814623371177901052302005289155305089588204204313261
1246903000089073759886267722667196003041462505274526737638837808213476294697746018085346623497511017543801377442390781101585650581984057653018703031659844145960721073451379508212905335383758157379301019575213158532070229897587088955814288202279949391608732448294591675986989254272257059551622461096394217684402667140362275595245430242117193793913872208576714597860532581116390903216389172132085635891741189355461016795362341416848534340615825023292174042406128959
952508462840095293368043281511747192551431448088755251878915582522463097721381421883702408853564036431155676272901680250701398946525803160765527940151587567521509500006089852079864042238196362897144754722623523621230744820970423076092319608853809407595863195726851921082224085255808985329769890887863865121647796115540376158135632760785321953364738008064130705467326745546629505023549047992509562623348749056757848144371814157305011884825502144329268299851210747
788785744509676701442642497798353940704045062680685297430840370664093043099033424646382070232242765761123110381200239132310785932203252095093993313010883982078216697297202940152563278231011836966627537170460186597134847633828107444548759805274516431300662852153808962421740187067058018192457264083227110866080267684557127718769967184710395811547902947248700889674967381917907905535103547918375731341071557144999864774198881339085314424766509424492349867615604684

'''

先把最外层的套娃给解了:

$d*e=k_1*p*lcm(p-1,q-1)+1 \tag{1.1} $

$d^e=k_2*p^2*q+hint \tag{1.2} $

给(1,1)式做一个e次方,(1,2)式乘一个e^e,就可以搞成一个东西:

$
k_3*p*lcm(p-1,q-1)+1=k_4*p^2*q+hint*e^e \tag{1.3}
$

再化:

$
p\mid hint*e^e-1 \tag{1.4}
$

将这个式子和n求公约数可以直接导出p,接下来正常步骤做完第一层套娃,得到e
然后可以发现这个e奇大无比,普通wiener搞不定,使用Boneh_Durfee attack(或者魔改wiener),扔进脚本直接解出url,下载得到最后一层套娃:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Wow, you got here!
# This is the last task, trust me!
from Crypto.Util.number import *
from secret import flag,padding
from gmpy2 import *

m = bytes_to_long(flag)
e = 7

p = getPrime(512)
q = getPrime(512)
n = p * q

c1 = pow(m,e,n)
c2 = pow(m+padding,e,n)

print(n)
print(c1)
print(c2)

'''
143224951702807798608353389056046982493788310072914995404719898237226283884553121669729599925829562704800197375580487019006702401282671268969358774635337351738915083955659230582177495821699251999928502338923489031347921151957398310960671307216790020399224115377846788378990638367296298663795893865325304226511
74797173657575640598140788410852016843612519588375968190579734420951374103129570637822547217967978911328419808529204143522454142303138959013220811558490951614314306849367068478190797885056922705403028856734095288522290055309880572321557493798362056216783777593386133347693892941928131945986087712737862263761
9209695919437085323423940852135308337887271742988391422139555924185234849146079306139570263602339983687993333013333937719071267190971983543492940032646907167417161479697805991443259327402389097539126399994414628326218438416138199892253597375493026563369334352434282120293396846427418323600336867792587721214

'''

非常显然的coppersmith short_padding_attack加上related_message_attack,扔进脚本直接解出flag

EXP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
from gmpy2 import *
from Crypto.Util.number import long_to_bytes
# 第一层
e = 65537
h = 788785744509676701442642497798353940704045062680685297430840370664093043099033424646382070232242765761123110381200239132310785932203252095093993313010883982078216697297202940152563278231011836966627537170460186597134847633828107444548759805274516431300662852153808962421740187067058018192457264083227110866080267684557127718769967184710395811547902947248700889674967381917907905535103547918375731341071557144999864774198881339085314424766509424492349867615604684
n = 1246903000089073759886267722667196003041462505274526737638837808213476294697746018085346623497511017543801377442390781101585650581984057653018703031659844145960721073451379508212905335383758157379301019575213158532070229897587088955814288202279949391608732448294591675986989254272257059551622461096394217684402667140362275595245430242117193793913872208576714597860532581116390903216389172132085635891741189355461016795362341416848534340615825023292174042406128959
c = 952508462840095293368043281511747192551431448088755251878915582522463097721381421883702408853564036431155676272901680250701398946525803160765527940151587567521509500006089852079864042238196362897144754722623523621230744820970423076092319608853809407595863195726851921082224085255808985329769890887863865121647796115540376158135632760785321953364738008064130705467326745546629505023549047992509562623348749056757848144371814157305011884825502144329268299851210747
ee = pow(e, e)
p = gcd(ee * h - 1, n)
q = n // p ** 2
phi = (p - 1) * p * (q - 1)
d = invert(e,phi)
e = pow(c, d, n)
print(e)

# 第二层
# Boneh_Durfee attack出的结果
# 脚本在https://github.com/mimoo/RSA-and-LLL-attacks/blob/master/boneh_durfee.sage
d = 103079922798932082066165266087442072203677117380612800709240732626110126828541
n = 97814568264814384858194701955408461509880555772006698372422205341758322175891474378211599333051180365254844248340812534463000531890490435018379585036704801177155418066770861143206836558793774360498040810255823235715535487716966004194143204900564413879660115112965484824906920141847149888933004740523449213441
assert pow(pow(3,e,n),d,n) == 3

c = 86143311788363675684674113699193046781796638913243016152555572150858159500527674063754694514501999791875561142925154991000532628799185608465062814546108160434468098898040769021072007374156546314975240583347468026001633652940408779155579339470960571067652924814623371177901052302005289155305089588204204313261
print(long_to_bytes(pow(c,d,n)))

# 第三层
def short_pad_attack(c1, c2, e, n):
PRxy.<x,y> = PolynomialRing(Zmod(n))
PRx.<xn> = PolynomialRing(Zmod(n))
PRZZ.<xz,yz> = PolynomialRing(Zmod(n))
g1 = x^e - c1
g2 = (x+y)^e - c2
q1 = g1.change_ring(PRZZ)
q2 = g2.change_ring(PRZZ)
h = q2.resultant(q1)
h = h.univariate_polynomial()
h = h.change_ring(PRx).subs(y=xn)
h = h.monic()
kbits = n.nbits()//(2*e*e)
diff = h.small_roots(X=2^kbits, beta=0.4)[0]
return diff
def related_message_attack(c1, c2, diff, e, n):
PRx.<x> = PolynomialRing(Zmod(n))
g1 = x^e - c1
g2 = (x+diff)^e - c2
def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()
return -gcd(g1, g2)[0]

n = 143224951702807798608353389056046982493788310072914995404719898237226283884553121669729599925829562704800197375580487019006702401282671268969358774635337351738915083955659230582177495821699251999928502338923489031347921151957398310960671307216790020399224115377846788378990638367296298663795893865325304226511
e = 7
c1 = 74797173657575640598140788410852016843612519588375968190579734420951374103129570637822547217967978911328419808529204143522454142303138959013220811558490951614314306849367068478190797885056922705403028856734095288522290055309880572321557493798362056216783777593386133347693892941928131945986087712737862263761
c2 = 9209695919437085323423940852135308337887271742988391422139555924185234849146079306139570263602339983687993333013333937719071267190971983543492940032646907167417161479697805991443259327402389097539126399994414628326218438416138199892253597375493026563369334352434282120293396846427418323600336867792587721214
diff = short_pad_attack(c1, c2, e, n)
m1 = related_message_attack(c1, c2, diff, e, n)
long_to_bytes(m1)

# VNCTF{H4ppyNeWy34r!2021_V&N_figHt1ng!}