# HGAME Crypto WEEK1-4

## HGAME Crypto

### WEEK1

#### Easy RSA

from Crypto.Util.number import*
r=[(12433, 149, 197, 104), (8147, 131, 167, 6633), (10687, 211, 197, 35594), (19681, 131, 211, 15710), (33577, 251, 211, 38798), (30241, 157, 251, 35973), (293, 211, 157, 31548), (26459, 179, 149, 4778), (27479, 149, 223, 32728), (9029, 223, 137, 20696), (4649, 149, 151, 13418), (11783, 223, 251, 14239), (13537, 179, 137, 11702), (3835, 167, 139, 20051), (30983, 149, 227, 23928), (17581, 157, 131, 5855), (35381, 223, 179, 37774), (2357, 151, 223, 1849), (22649, 211, 229, 7348), (1151, 179, 223, 17982), (8431, 251, 163, 30226), (38501, 193, 211, 30559), (14549, 211, 151, 21143), (24781, 239, 241, 45604), (8051, 179, 131, 7994), (863, 181, 131, 11493), (1117, 239, 157, 12579), (7561, 149, 199, 8960), (19813, 239, 229, 53463), (4943, 131, 157, 14606), (29077, 191, 181, 33446), (18583, 211, 163, 31800), (30643, 173, 191, 27293), (11617, 223, 251, 13448), (19051, 191, 151, 21676), (18367, 179, 157, 14139), (18861, 149, 191, 5139), (9581, 211, 193, 25595)]
flag=''
for i in r:
e,p,q,c=i
phi=(p-1)*(q-1)
d=inverse(e,phi)
m=pow(c,d,p*q)
flag+=chr(m)
print(flag)


#### English Novel

b=" if Rqesysz', bvjv bjxsh szr uaaxivjd zlcdbc mnirb."
a=" of England', with which the meetings always ended."
k=[]
for i in range(len(a)):
if(a[i]<='z' and a[i]>='a') or (a[i]<='Z' and a[i]>='A'):
x=ord(b[i])-ord(a[i])+26
x%=26
k.append(x)
else:
k.append(-1)
print(k)


k=[16, 20, 0, 10, 13, 3, 24, 7, 24, 5, 22, 17, 17, 18, 5, 13, 16, 14, 9, 5, 2, 15, 16, 0, 20, 25, 18, 13, 7, 8, 22, 22, 4, 0, 8, 3, 11, 23, 25, 0, 6, 3, 3, 10, 2, 8, 0, 5, 13, 24, 0]
def decrypt(data, key):
assert len(data) <= len(key)
result = ""
for i in range(len(data)):
if data[i].isupper():
result += chr((ord(data[i]) - ord('A') - key[i]) % 26 + ord('A'))
elif data[i].islower():
result += chr((ord(data[i]) - ord('a') - key[i]) % 26 + ord('a'))
else:
result += data[i]
return result
f="xaawr{B0_d0l_cs0m_'Pp0mn-odn1vpabt_deqzcq'?}"
f=decrypt(f,k)
print(f)


### WEEK2

#### RSA Attack

factordb分解$$n$$得到$$p,q$$

#### Chinese Character Encryption

陉萏俦蘭貑謠祥冄剏髯簧凰蕆秉僦笆鼣雔耿睺渺仦殣櫤鄽偟壮褃劳充迧蝔镁樷萾懴雈踺猳钔緲螩蝒醢徣纒漐



from pypinyin import lazy_pinyin, Style
a='陉萏俦蘭貑謠祥冄剏髯簧凰蕆秉僦笆鼣雔耿睺渺仦殣櫤鄽偟壮褃劳充迧蝔镁樷萾懴雈踺猳钔緲螩蝒醢徣纒漐'
flag=""
style = Style.TONE3
py=(lazy_pinyin(a, style=style))
for pinyin in py:
sum=0
for c in pinyin:
sum+=ord(c)
flag+=chr(sum%128)
print(flag)


#### The Password Plus Pro Max Ultra

SageMath进行矩阵的运算（代码嫖了hx

D=[2656224875120172108 , [8, 35],
1261711348908201279 , [19, 29, 30, 45],
18219282869614004824 , [6, 16, 18, 21, 44, 55],
15279054981769814589 , [10, 26, 30, 46, 51, 54, 58, 63],
7966355346882200701 , [5, 13, 25, 29, 37, 39, 43, 52, 53, 59],
5641592208539483808 , [1, 26, 31, 39, 40, 41, 43, 45, 49, 52, 54, 62],
1502927090219059154 , [8, 12, 19, 20, 30, 32, 34, 40, 41, 45, 46, 49, 55, 58],
3996223120734273799 , [2, 3, 5, 6, 8, 10, 15, 19, 26, 27, 33, 40, 42, 47, 52, 61],
18295033054788808618 , [1, 16, 17, 27, 28, 30, 32, 36, 37, 38, 39, 48, 49, 51, 55, 57, 59, 62],
18126228466291248047 , [5, 11, 12, 20, 22, 23, 25, 27, 31, 32, 33, 37, 44, 45, 49, 52, 53, 59, 61, 62],
9413762634844369954 , [2, 7, 10, 12, 18, 19, 20, 22, 26, 29, 33, 34, 38, 40, 41, 45, 46, 51, 54, 56, 57, 60],
8964324149921197550 , [3, 4, 5, 9, 12, 13, 18, 19, 21, 23, 24, 25, 30, 33, 34, 35, 37, 39, 43, 44, 46, 49, 50, 53],
6962485320551449848 , [1, 3, 6, 7, 10, 11, 13, 14, 23, 27, 32, 33, 35, 37, 39, 41, 46, 48, 49, 50, 51, 53, 54, 56, 58, 62],
]
def movematrix(n):
n=(n+64)%64
E=[[0 for i in range(64)] for j in range(64)]
for i in range(64):
E[i][i]=1
M=[]
for i in range(64):
M.append(E[(i+n)%64])
return matrix(GF(2),M)
def decrypt(C,L):
M=[[0 for i in range(64)] for j in range(64)]
for i in range(64):
M[i][i]=1
M=matrix(GF(2),M)
for i in L:
M+=movematrix(i)
v=[]
for i in range(64):
v.append(1 if C&(1<<i)!=0 else 0)
v=vector(GF(2),v)
v=v*(M**-1)
M=0
v=vector(ZZ,v)
for i in range(64):
M+=v[i]*(1<<i)
return M

f=[]
for i in range(13):
f.append(decrypt(D[2*i],D[2*i+1]))
print(f)


from Crypto.Util.number import*
f=[7523088825027614799, 8249559255509004879, 7817203812207576402, 6423086823251996526, 3045112109557445445, 2616398305166447721, 5723558670868965747, 2697452167550086213, 5639438386741921138, 4991160919341822841, 5570219726961468223, 7308888588581631049, 5197437]
flag=b""
for i in f:
flag+=long_to_bytes(i)
print(flag)


### WEEK3

#### Block Cipher

import operator

def xor(a, b):
assert len(a) == len(b)
print(bytes(map(operator.xor, a, b)))
return bytes(map(operator.xor, a, b))

flag=b''
iv = b'Up\x14\x98r\x14%\xb9'
key = b'\r\xe8\xb86\x9c33^'

parts = [b'0\xff\xcd\xc3\x8b\\T\x8b', b'RT\x1e\x89t&\x17\xbd', b'\x1a\xee\x8d\xd6\x9b>w\x8c', b'9CT\xb3^pF\xd0']
parts[3]=reduce(xor,[parts[2],parts[3],key])
parts[2]=reduce(xor,[parts[1],parts[2],key])
parts[1]=reduce(xor,[parts[0],parts[1],key])
parts[0]=reduce(xor,[parts[0],iv,key])
for i in parts:
flag+=i
print(flag)


#### Multi Prime RSA

$$n=p_1^{k_1}p_2^{k_2}...p_r^{k_r}$$

$$φ(n)=\prod_{i=1}^rp_i^{k_i-1}(p_i-1)$$

from Crypto.Util.number import*

p = 109056753224725357860050862987465749131702509174531265860789564184166504627089
q = 64871884070495743485110397060920534297122908609816622599229579748089451488127
r = 73817195552029165561107245309535744382442021553254903166961729774806232509583
s = 89907870347457693114161779597928900080173728317019344960807644151097370118553
n = 337945247991531188630780631650822497552908401425959508214145019590891175999570651678385514599227649321033438265588883204645721459926338248032512615537333971869461679586403649697114789385472197685140603238299768873935137939123021910982793481655218061907401584383081422244812725080939394854989735528833013780919908024635812696998644603525843637686545709789908672408993923182946718279531020289767042649725545073526307769817097790005360720650079676982379162926484355121626302801800589993422729725583400678081766553017405965706770238634252836827793877622715474210575752508172785712202444441372140501379422725172250199713113954442223362073485143579617841236442644760494913432967541691532709842303408702693199269606594116690052170245340072114122287646793344327315326489574192325790848798131621842606487734721409882742631176999703502149639410263361145441889337623403361569958342141903891414217371443118527025041591219747780100510414268546884029077010164415049298406632069845430841542680166802473749172801804659277821899576403669845353379213803866969800665351300325701817179936198902427032684058452719607840314873315299975603264092020097224735237221994922702705781103002327285724125001893421030923788361576161461965707958695720464547129911053732747399113017747456439027947305796290572816318795181398935020951025833913
e = 65537
c = 281020926647419736778465777714512241989738235339105762863874725870511725155101862585192241287617168165290485944476735304459717602798728005687755713662466866091315959960168862035396245078850168822145228676116894754613436735897122137945552880864031115366493898382809812977280234389519365119627504653135151731589924405933589175425427189436855517194951589952822691774400942764910734054237756669945324833759799471068481769516338068810710333940167779043544371586185132920304774984746129764220081092726473696111126293966890901487735046101991609292612206984184161394385767762455321150541601949740631911175736268756408775307673610842645555513631617648877296855194327486811545670357137463942744122553468603244298691801028147147418563982169678640270746871085722092365159546820433098926679284504740402248142173715649451061037156261913601096905601577932894877435316535261789072594174871292814951406337447799051502635390866434813419165738873787323716033378045850292413169255965421404580559241351577058726176436504950558398769061998430771982995850759810867299728407860522399699076192754977454139708618158667289120827143703464056583125568576691058753072898162981956883451252542611323974071518397220203389962420073122776649094369816178685947397943358134020598211306649724455966463885765977564934172273334309312046278116760547

phi=p*(p-1)*q**2*(q-1)*r**4*(r-1)*s**6*(s-1)
d=inverse(e,phi)
m=pow(c,d,n)
print(long_to_bytes(m))


#### RSA Attack 3

$$d$$很小$$e$$很大猜测是$$Wiener's attack$$

import gmpy2
from Crypto.Util.number import*
def transform(x,y):       #使用辗转相处将分数 x/y 转为连分数的形式
res=[]
while y:
res.append(x//y)
x,y=y,x%y
return res

def continued_fraction(sub_res):
numerator,denominator=1,0
for i in sub_res[::-1]:      #从sublist的后面往前循环
denominator,numerator=numerator,i*numerator+denominator
return denominator,numerator   #得到渐进分数的分母和分子，并返回

#求解每个渐进分数
def sub_fraction(x,y):
res=transform(x,y)
res=list(map(continued_fraction,(res[0:i] for i in range(1,len(res)))))  #将连分数的结果逐一截取以求渐进分数
return res

def get_pq(a,b,c):      #由p+q和pq的值通过维达定理来求解p和q
par=gmpy2.isqrt(b*b-4*a*c)   #由上述可得，开根号一定是整数，因为有解
x1,x2=(-b+par)//(2*a),(-b-par)//(2*a)
return x1,x2

def wienerAttack(e,n):
for (d,k) in sub_fraction(e,n):  #用一个for循环来注意试探e/n的连续函数的渐进分数，直到找到一个满足条件的渐进分数
if k==0:                     #可能会出现连分数的第一个为0的情况，排除
continue
if (e*d-1)%k!=0:             #ed=1 (mod φ(n)) 因此如果找到了d的话，(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n)
continue

phi=(e*d-1)//k               #这个结果就是 φ(n)
px,qy=get_pq(1,n-phi+1,n)
if px*qy==n:
p,q=abs(int(px)),abs(int(qy))     #可能会得到两个负数，负负得正未尝不会出现
d=gmpy2.invert(e,(p-1)*(q-1))     #求ed=1 (mod  φ(n))的结果，也就是e关于 φ(n)的乘法逆元d
return d
print("该方法不适用")

e = 77310199867448677782081572109343472783781135641712597643597122591443011229091533516758925238949755491395489408922437493670252550920826641442189683907973926843505436730014899918587477913032286153545247063493885982941194996251799882984145155733050069564485120660716110828110738784644223519725613280140006783618393995138076030616463398284819550627612102010214315235269945251741407899692274978642663650687157736417831290404871181902463904311095448368498432147292938825418930527188720696497596867575843476810225152659244529481480993843168383016583068747733118703000287423374094051895724494193455175131120243097065270804457787026492578916584536863548445813916819417857064037664101684455000184987531252344582899589746272173970083733130106407810619258077266603898529285634495710846838011858287024329514491058790557305041389614650730267774482954666726949886313386881066593946789460028399523245777171320319444673551268379126203862576627540177888290265714418064334752499940587750374552330008143708562065940245637685833371348603338834447212248648869514585047871442060412622164276894766238383894693759347590977926306581080390685360615407766600573527565016914830132066428454738135380178959590692145577418811677639050929791996313180297924833690095
n = 507419170088344932990702256911694788408493968749527614421614568612944144764889717229444020813658893362983714454159980719026366361318789415279417172858536381938870379267670180128174798344744371725609827872339512302232610590888649555446972990419313445687852636305518801236132032618350847705234643521557851434711389664130274468354405273873218264222293858509477860634889001898462547712800153111774564939279190835857445378261920532206352364005840238252284065587291779196975457288580812526597185332036342330147250312262816994625317482869849388424397437470502449815132000588425028055964432298176942124697105509057090546600330760364385753313923003549670107599757996810939165300581847068233156887269181096893089415302163770884312255957584660964506028002922164767453287973102961910781312351686488047510932997937700597992705557881172640175117476017503918294534205898046483981707558521558992058512940087192655700351675718815723840568640509355338482631416345193176708501897458649841539192993142790402734898948352382350766125000186026261167277014748183012844440603384989647664190074853086693408529737767147592432979469020671772152652865219092597717869942730499507426269170189547020660681363276871874469322437194397171763927907099922324375991793759
d=wienerAttack(e,n)
print("d=",d)
f=pow(165251729917394529793163344300848992394021337429474789711805041655116845722480301677817165053253655027459227404782607373107477419083333844871948673626672704233977397989843349633720167495862807995411682262559392496273163155214888276398332204954185252030616473235814999366132031184631541209554169938146205402400412307638567132128690379079483633171535375278689326189057930259534983374296873110199636558962144635514392282351103900375366360933088605794654279480277782805401749872568584335215630740265944133347038070337891035560658434763924576508969938866566235926587685108811154229747423410476421860059769485356567301897413767088823807510568561254627099309752215808220067495561412081320541540679503218232020279947159175547517811501280846596226165148013762293861131544331444165070186672186027410082671602892508739473724143698396105392623164025712124329254933353509384748403154342322725203183050328143736631333990445537119855865348221215277608372952942702104088940952142851523651639574409075484106857403651453121036577767672430612728022444370874223001778580387635197325043524719396707713385963432915855227152371800527536048555551237729690663544828830627192867570345853910196397851763591543484023134551876591248557980182981967782409054277224,d,n)
print(long_to_bytes(f))



### WEEK4

#### ECC

from Crypto.Util.number import getPrime
from libnum import s2n
from secret import flag

p = 74997021559434065975272431626618720725838473091721936616560359000648651891507
a = 61739043730332859978236469007948666997510544212362386629062032094925353519657
b = 87821782818477817609882526316479721490919815013668096771992360002467657827319
E = EllipticCurve(GF(p),[a,b])
m = E.random_point()
G = E.random_point()
k = 93653874272176107584459982058527081604083871182797816204772644509623271061231
K = k * G
r = getPrime(256)
c1 = m + r * K
c2 = r * G
cipher_left = s2n(flag[:len(flag)//2]) * m[0]
cipher_right = s2n(flag[len(flag)//2:]) * m[1]

print(f"p = {p}")
print(f"a = {a}")
print(f"b = {b}")
print(f"k = {k}")
print(f"E = {E}")
print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f"cipher_left = {cipher_left}")
print(f"cipher_right= {cipher_right}")


（什么为什么我会解释这个？因为真的有人闲着没事在$$m[0]，m[1]$$前面加了个$$int()$$

#### PRNG

posted @ 2022-02-21 08:45  上辰  阅读(264)  评论(0编辑  收藏  举报