ancient

Base58 → Base62 → Base45 → Base85 → Base32 → Base64
按照这个顺序加密的,对着反向解密即可

密文:

1
RzVJVFlaSkZGUk1HV1daWkdOQ0RFNEpJSE5RWEdOS05ISlNHSTNCT0daWVVXS1pDRzQzV01UQ0NISkVTNElKQkdKUkZFUEpYRjVIVk0zMlpIQVpXNjQyTkdaSlRBNFMzR1pKVENPMllIVjJWWVRMQ0daTERDTVpYR0JURk1TMlpHQlRWR0xDWkdaS1ZRWUo1R0ZURVFRSlNHQlRGNFQyTUc1SVRHUURFSFU3REVZSkVHNVdFS1FEUEdKUEVJS1NYRzQ0RkNRU0lITkNIQ1NaUEdWWlc0UlJZR1pZSEdRVFBHSVVXSVMzQkc0M0RHMkJIRzQ0R1lLU0VHQlFBPT09PQ==

1
flag{cl@ss1cal_c1pher_@re_really_1nterest1ng}

sign_in

题目:

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
from Crypto.Util.number import *
from gmpy2 import *
import random

get_context().precision = 2048

L = 5
S = getPrime(144)
a = getPrime(32)
b = random.randint(0, S - 1)

def split_and_pad_single_char_rule(msg, L):
segments = []
assert L >= 1
pad_len = L - 1
for char_idx, char_byte in enumerate(msg):
char_ascii = char_byte
pad_bytes = bytes([(char_ascii + i + 1) % 256 for i in range(pad_len)])
seg_bytes = bytes([char_byte]) + pad_bytes
segments.append(bytes_to_long(seg_bytes))
return segments

def encrypt_segment(m_i, a, b, M):
return (a * m_i + b) % M

flag = "flag{___________________}"
msg_bytes = flag.encode()
m_segments = split_and_pad_single_char_rule(msg_bytes, L)
c_segments = [encrypt_segment(mi, a, b, S) for mi in m_segments]

print(f"a = {a}")
print(f"S = {S}")
print(f"L = {L}")
print(f"C = {c_segments}")
print(f'M = {m_segments}')

'''
a = 3517115977
S = 13338196046628817705384101887069807236659077
L = 5
C = [6399813929853868574459915097120849511644924, 6399813929853868574460006087942330564102834, 6399813929853868574459839271436281967929999, 6399813929853868574459930262257763020387909, 6399813929853868574460233564996033195247609, 6399813929853868574460112243900725125303729, 6399813929853868574459111344864433548266719, 6399813929853868574459930262257763020387909, 6399813929853868574460036418216157581588804, 6399813929853868574459808941162454950444029, 6399813929853868574459111344864433548266719, 6399813929853868574460036418216157581588804, 6399813929853868574459808941162454950444029, 6399813929853868574460127409037638634046714, 6399813929853868574459096179727520039523734, 6399813929853868574459930262257763020387909, 6399813929853868574459899931983936002901939, 6399813929853868574460127409037638634046714, 6399813929853868574459945427394676529130894, 6399813929853868574459172005412087583238659, 6399813929853868574460097078763811616560744, 6399813929853868574459808941162454950444029, 6399813929853868574460188069585292669018654, 6399813929853868574459960592531590037873879, 6399813929853868574460188069585292669018654, 6399813929853868574459960592531590037873879, 6399813929853868574460263895269860212733579]
'''

解题思路:

很直白的一个题,把flag的每个字符都处理为长度5的字节段,填充字节的规则为:

  • 第一个字节为flag的第i个字符
  • 后面的字节为flag的第i个字符的ascii码加i再对256取模

然后对每个字节段 ( m_i ) 进行线性变换:

给出了$a、S、L、C$,因为我们已知flag头,所以我们可以据此来回推出$b$,从而得到$M$。

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
#python
from Crypto.Util.number import *

a = 3517115977
S = 13338196046628817705384101887069807236659077
L = 5
C = [6399813929853868574459915097120849511644924, 6399813929853868574460006087942330564102834, 6399813929853868574459839271436281967929999, 6399813929853868574459930262257763020387909, 6399813929853868574460233564996033195247609, 6399813929853868574460112243900725125303729, 6399813929853868574459111344864433548266719, 6399813929853868574459930262257763020387909, 6399813929853868574460036418216157581588804, 6399813929853868574459808941162454950444029, 6399813929853868574459111344864433548266719, 6399813929853868574460036418216157581588804, 6399813929853868574459808941162454950444029, 6399813929853868574460127409037638634046714, 6399813929853868574459096179727520039523734, 6399813929853868574459930262257763020387909, 6399813929853868574459899931983936002901939, 6399813929853868574460127409037638634046714, 6399813929853868574459945427394676529130894, 6399813929853868574459172005412087583238659, 6399813929853868574460097078763811616560744, 6399813929853868574459808941162454950444029, 6399813929853868574460188069585292669018654, 6399813929853868574459960592531590037873879, 6399813929853868574460188069585292669018654, 6399813929853868574459960592531590037873879, 6399813929853868574460263895269860212733579]

def construct_m_from_char(char, L):
char_ascii = ord(char)
pad_len = L - 1
pad_bytes = bytes([(char_ascii + i + 1) % 256 for i in range(pad_len)])
seg_bytes = bytes([ord(char)]) + pad_bytes
return bytes_to_long(seg_bytes)


known_chars = ['f', 'l', 'a', 'g']
derived_b = []
for idx, char in enumerate(known_chars):
m_i = construct_m_from_char(char, L)
b = (C[idx] - a * m_i) % S
derived_b.append(b)


b = derived_b[0]
print(f"推导出的私钥b = {b}")

a_inv = inverse(a, S)

flag = ""
M = []
for c in C:
m_i = ((c - b) % S) * a_inv % S
M.append(m_i)
seg_bytes = long_to_bytes(m_i)
original_char = chr(seg_bytes[0])
flag += original_char

print(flag)
#flag{s1gn_1n_t0geth5r_xixi}

where

题目:

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
from Crypto.Util.number import *
import random

flag = "flag{_______________________________}"
m = bin(bytes_to_long(flag.encode()))[2:]
p = getPrime(300)
q = getPrime(300)
n = p * q

R.<x> = PolynomialRing(Zmod(n))

def gen(m):
C = []
for bit in m:
if bit == '0':
C.append(random.randint(1, n-1))
else:
x = random.randint(1, 2^80)
y = random.randint(1, p-1)
val = 65537 + x*(1-x) +(q - x)*y + (y + x)*(q + x)
C.append(R(val))
return C

c = gen(m)
print(f"n = {n}")
print(f"c = {c}")

output.txt太长了就不放出来了,想要的师傅可以去hscctf的靶场下载(虽然可能还没更新)

解题思路:
一个小decision:

1
2
0: c_i为mod(n)的随机数
1: c_i为65537 + x*(1-x) +(q - x)*y + (y + x)*(q + x) --> 65537 + qx + 2qy + x

我们可以发现对于1的方程模q下,会有一个80bit的小根x,所以copper会有解,而0则没有,所以我们可以以此做出decision

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#sage
from Crypto.Util.number import *
n =
c =
flag = ""

PR.<x> = PolynomialRing(Zmod(n))
for i in range(len(c)):
f = x - c[i]
res = f.small_roots(X=2^80,beta=0.49)
if(res != []):
flag += "1"
else:
flag += "0"


print(long_to_bytes(int(flag,2)))
#flag{where_1s_th5_flag_where}

stillRSA

题目:

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
from Crypto.Util.number import *
from gmpy2 import *


def gen():
while(1):
p1 = getPrime(128)
p2 = getPrime(512)
q2 = getPrime(512)
s = q2 & ((1 << 56) - 1)
q1 = 2 * p1 + s
r1 = 2 * q1 + s
if is_prime(q1) and is_prime(r1):
n1 = p1 * q1 * r1
n2 = p2 * q2
break
return n1,n2,p1,p2


n1,n2, p1, p2 = gen()
e = 65537

flag = "flag{---------------------------------------}".encode()
m1 = bytes_to_long(flag[: (len(flag)+1) // 2])
m2 = bytes_to_long(flag[(len(flag)+1) // 2 :])

c1 = powmod(m1, e, n1)
c2 = powmod(m2, e, n2)

gift = p2 >> 262

print(f"e = {e}")
print(f"n1 = {n1}")
print(f"n2 = {n2}")
print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f"p1 = {p1}")
print(f"gift = {gift}")

'''
e = 65537
n1 = 153535945724301761635048132162798014938917969845079448489545851494873442295873133893384411532854581537976576911336083
n2 = 84803188245030813883191077133506154725049469687779805365997839479650548017159380111143407950887981137367898417071670318175553216747909857623397932606557900805065642334402683077054566841962022705300815246585360967197421835628665369002004215185956537117678561509558467837953178340079218753108643544534307300779
c1 = 91344805342373294041484814707589753503672726499268929615405258196853851463816933913580106446612439099622637694719344
c2 = 65030067863230521561732635665855986696538207379818716373900645903663706519394086998921178373079966943522635174648820466855368885032783946013202871621053763074374114131710373913193434831822631037825109588592562599802388631816046111419285162200967000421088941791542557891726383026274591733889350668008350880276
p1 = 267735952598198080786845163083151774667
gift = 1068605981024067598428983610552162240530726981658336444437430658822896756780
'''

解题思路:
可以观察到这是一个双重RSA:

  • p1是一个128位的素数,p2和q2是一个512位的素数
  • s是q2的低56位
  • q1 = 2 * p1 + s
  • r1 = 2 * q1 + s
  1. 已知 $n_1$ 和 $p_1$,且 $q_1$、$r_1$ 均与 $p_1$ 相关,可在 $\mod(n_1 // p_1)$ 下通过 Copper 算法求解 $s$,进而还原 $q_1$ 和 $r_1$;
  2. 已知 $gift = p_2 >> 262$,且 $s$ 为 $q_2$ 的低 56 位,可通过以下方式还原 $p_2$ 的低 56 位:
    $n_2 \times \text{inverse}(s, 2^{56}) \mod 2^{56}$
  3. 基于上述结果,再次通过 Copper 算法还原 $p_2$;
  4. 最终分别解两个 RSA 即可完成解题。

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
#sage
from Crypto.Util.number import *
from gmpy2 import *

e = 65537
n1 = 153535945724301761635048132162798014938917969845079448489545851494873442295873133893384411532854581537976576911336083
n2 = 84803188245030813883191077133506154725049469687779805365997839479650548017159380111143407950887981137367898417071670318175553216747909857623397932606557900805065642334402683077054566841962022705300815246585360967197421835628665369002004215185956537117678561509558467837953178340079218753108643544534307300779
c1 = 91344805342373294041484814707589753503672726499268929615405258196853851463816933913580106446612439099622637694719344
c2 = 65030067863230521561732635665855986696538207379818716373900645903663706519394086998921178373079966943522635174648820466855368885032783946013202871621053763074374114131710373913193434831822631037825109588592562599802388631816046111419285162200967000421088941791542557891726383026274591733889350668008350880276
p1 = 267735952598198080786845163083151774667
gift = 1068605981024067598428983610552162240530726981658336444437430658822896756780

PR.<x> = PolynomialRing(Zmod(n1//p1))
f = (2*p1 + x)*(4*p1 + 3*x)
res1 = f.monic().small_roots(X=2^56,beta=0.4)
print(res1)
s = int(res1[0])
q1 = 2 * p1 + s
r1 = 2 * q1 + s
d1 = inverse(e , (p1 - 1)*(q1 - 1) * (r1 - 1))
m1 = powmod(c1, d1, n1)


p2l = n2 * inverse(s, 2 ** 56) % 2 ** 56
PR.<x> = PolynomialRing(Zmod(n2))
g = gift * (2 ** 262) + x * 2 ** 56 + p2l
res2 = g.monic().small_roots(X=2^206,beta=0.4)
print(res2)
p2 = gift * (2 ** 262) + int(res2[0]) * 2 ** 56 + p2l
q2 = n2 // p2
d2 = inverse(e, (p2-1)*(q2-1))
m2 = powmod(c2, d2, n2)

print(long_to_bytes(m1) + long_to_bytes(m2))
#flag{Im_a_fw_that_only_crafts_RSA_challenges}

EZRSA

题目:

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
from Crypto.Util.number import *

def tran(n):
s_bin = bin(n)[2:]
bit_map = {'0': '10', '1': '01'}
p_bin = '11' + ''.join([bit_map[bit] for bit in s_bin[1:]])
return int(p_bin, 2)

def keygen(nbit):
while True:
s = getPrime(nbit)
p = tran(s)
if not isPrime(p):
continue
s_bin = bin(s)[2:].zfill(nbit)
q_bin = (s_bin[:nbit // 2]
+ '1' * (nbit // 2)
+ s_bin[nbit // 2:]
+ '1' * (nbit // 2))
q = int(q_bin, 2)
if isPrime(q):
return p,q

flag = "flag{____________________________}"
nbit = 256
p, q = keygen(nbit)
m = bytes_to_long(flag.encode())
e= 65537
n = p * q
c = pow(m, e, n)

print(f'n = {n}')
print(f'c = {c}')

"""
n = 97500437901440388417198788454954892885829765317271438600836638419723842224011100091990654907349042873594131382232421640267091732569264390052236076620148372084122607139079558728860385251369576795723604753566616558793072715394596559965112752835650808765911364805382628147988309718393764596614456741590220757591
c = 7738615614182124736230909980262535479827406389377664909203540758689122759528168600427345931034997504030657746278863273550729288326235414854206217548620396163736109673531409510422631464901846302450760457216706035370273167926580473904029057693564485585891556568420324605915383565319685765532478198539656924536
"""

我们可以发现:

  • 先生成256位的素数s
  • p由256位的s,通过0变成10,1变成01的方式拓展成的512位的素数,其中首两位是11
  • q是前128的s+128位的1+后128位的s+128位的1得到的

解题思路:

很明显是一个剪枝问题,按照生成方式约束一下深搜即可

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
61
62
63
64
65
66
#python

from Crypto.Util.number import *

nbit = 256
e = 65537
n = 97500437901440388417198788454954892885829765317271438600836638419723842224011100091990654907349042873594131382232421640267091732569264390052236076620148372084122607139079558728860385251369576795723604753566616558793072715394596559965112752835650808765911364805382628147988309718393764596614456741590220757591
c = 7738615614182124736230909980262535479827406389377664909203540758689122759528168600427345931034997504030657746278863273550729288326235414854206217548620396163736109673531409510422631464901846302450760457216706035370273167926580473904029057693564485585891556568420324605915383565319685765532478198539656924536


def dfs(h, s_prefix, p_prefix):
p_remain = 2 * nbit - len(p_prefix)
p_max = int(p_prefix + "1" * p_remain, 2)
p_min = int(p_prefix + "0" * p_remain, 2)

s_half = nbit // 2
s_len = len(s_prefix)
s_remain = nbit - s_len

if s_len <= s_half:
q_pre0 = (s_prefix + "0" * (s_half - s_len)
+ "1" * s_half
+ "0" * s_half
+ "1" * s_half)
q_pre1 = (s_prefix + "1" * (s_half - s_len)
+ "1" * s_half
+ "1" * s_half
+ "1" * s_half)
else:
s_pre128 = s_prefix[:s_half]
s_suf_cur = s_prefix[s_half:]
q_pre0 = (s_pre128 + "1" * s_half
+ s_suf_cur + "0" * (s_half - (s_len - s_half))
+ "1" * s_half)
q_pre1 = (s_pre128 + "1" * s_half
+ s_suf_cur + "1" * (s_half - (s_len - s_half))
+ "1" * s_half)

q_max = int(q_pre1, 2)
q_min = int(q_pre0, 2)

if q_max * p_max < n or q_min * p_min > n:
return

if h == nbit:
p = p_max
q = int(s_prefix[:s_half] + "1" * s_half + s_prefix[s_half:] + "1" * s_half, 2)

if p * q != n:
return
if isPrime(p) and isPrime(q):
phi = (p - 1) * (q - 1)
d = inverse(e, phi)
flag = long_to_bytes(pow(c, d, n))
print(f"flag: {flag.decode()}")
print(f"p = {p}")
print(f"q = {q}")
exit()
return

dfs(h + 1, s_prefix + "0", p_prefix + "10")
dfs(h + 1, s_prefix + "1", p_prefix + "01")


dfs(1, s_prefix="1", p_prefix="11")
#flag{n1ce_th1s_RSA_I_can_do_it}

abg

题目:

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
from Crypto.Util.number import *

def ECC(bit):
g = getPrime(bit)
a = getPrime(bit)
b = getPrime(bit)

E = EllipticCurve(GF(g),[a,b])
J = E.random_point()
K = E.random_point()
L = E.random_point()

r = getPrime(bit // 2)
k = getPrime(16)

s = r * J
s1 = r * J + k * L
s2 = r * k * J

return L.xy(), s.xy(), s1.xy(), s2.xy(), K.xy()

def RSA(m, s, bit):
p = getPrime(bit)
q = getPrime(bit)
rr = getPrime(bit)
n = p * q

gift = pow(rr, rr * (p-1), n)
enc = pow(m, int(s), n)

return gift, n, enc

flag = "flag{--------------------------------}"
m = bytes_to_long(flag.encode())

L, s, s1, s2, K = ECC(256)
gift, n, enc = RSA(m, abs(int(s[0] - s[1])), 512)

print("L =", L)
print("s1 =", s1)
print("s2 =", s2)
print("K =", K)
print("enc =", enc)
print("gift =", gift)
print("n =", n)

'''
L = (5612832632021037413595021905856059690922175615680426850888866965067320107819, 44286844991960812568914524464365492264373223903614475371204877844888511445056)
s1 = (3105425529931638108939225244969805843864193431777172585017902596003213488900, 21204057924591170352686471525538286905154747896755584173932333298433282086561)
s2 = (17163600514231693116809112204202083823354850361231568034507586407851022654385, 54523130652066750636213932541583111123904814992668862332727980305098543395332)
K = (84626796737477467367556465702814556148204747766624017939626441693356336891461, 20412858373065309258609569831347478221615957387864164638932871773748933195219)
enc = 77779248799562415787538731320739960822457760506615718084036279480880899171418681853821326436404494983875803921684003465855970542931724878457768817162166413967384579329072032251210520838992258491716245608876204830909672245330785235016998427930933850050898878548191256398496024681498083646200326639489612460844
gift = 27203859362379532209762716293585970661584968016465564915669656593570376250661463300469214869975225133883120425672896040102408082124157996563344160198308488970094544684114508100388704667496464400261830996514109943777210955076236899363247079300339008914936852187908757699066223721473477803084358704291887973927
n = 99350851709648177478181442570691890135193362203180628334780894515389735176666242281991349782055218048443285160186921692026870729324336754641181928398906259668775047724023372863155472201773397077316170491389813660679924150036914095032544796724427607899057109320556570067643629947815982002736525967748207154359
'''

解题思路:
其实就是很直白的ECC+RSA,其中flag本质上是被RSA加密了,其中隐藏了加密指数为ECC上的一个点s的横纵坐标之差的绝对值
虽然没有给出abg,但是给出了四个点L, s1, s2, K,所以我们可以通过任意取两个点有:

之后我们可以通过$gcd(k_1, k_2)$再消除一些小因子来得到g,之后再还原a和b
又因为给出了,根据费马小定理我们可以得到
所以我们可以通过$gcd(gift-1, n)$来得到p,之后解RSA即可

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
#sage
from Crypto.Util.number import *


L = (5612832632021037413595021905856059690922175615680426850888866965067320107819, 44286844991960812568914524464365492264373223903614475371204877844888511445056)
s1 = (3105425529931638108939225244969805843864193431777172585017902596003213488900, 21204057924591170352686471525538286905154747896755584173932333298433282086561)
s2 = (17163600514231693116809112204202083823354850361231568034507586407851022654385, 54523130652066750636213932541583111123904814992668862332727980305098543395332)
K = (84626796737477467367556465702814556148204747766624017939626441693356336891461, 20412858373065309258609569831347478221615957387864164638932871773748933195219)
enc = 77779248799562415787538731320739960822457760506615718084036279480880899171418681853821326436404494983875803921684003465855970542931724878457768817162166413967384579329072032251210520838992258491716245608876204830909672245330785235016998427930933850050898878548191256398496024681498083646200326639489612460844
gift = 27203859362379532209762716293585970661584968016465564915669656593570376250661463300469214869975225133883120425672896040102408082124157996563344160198308488970094544684114508100388704667496464400261830996514109943777210955076236899363247079300339008914936852187908757699066223721473477803084358704291887973927
n = 99350851709648177478181442570691890135193362203180628334780894515389735176666242281991349782055218048443285160186921692026870729324336754641181928398906259668775047724023372863155472201773397077316170491389813660679924150036914095032544796724427607899057109320556570067643629947815982002736525967748207154359

temp1 = (s2[1] ** 2 - s1[1] ** 2 - s2[0] ** 3 + s1[0] ** 3)
temp2 = (L[1] ** 2 - s2[1] ** 2 - L[0] ** 3 + s2[0] ** 3)
temp3 = (K[1] ** 2 - L[1] ** 2 - K[0] ** 3 + L[0] ** 3)
k1g = temp1 * (L[0] - s2[0]) - temp2 * (s2[0] - s1[0])
k2g = temp2 * (K[0] - L[0]) - temp3 * (L[0] - s2[0])
k3g = temp1 * (K[0] - L[0]) - temp3 * (s2[0] - s1[0])
g = GCD(k1g, k2g)
g = GCD(g, k3g)

for i in range(2,1000):
while(g % i == 0):
g //= i
a = inverse(s2[0]-s1[0],g)*temp1 % g
b = (s1[1] ** 2 - s1[0]**3-a*s1[0]) % g

E = EllipticCurve(GF(g),[a,b])
L = E(L)
s1 = E(s1)
s2 = E(s2)

base = L
k = 0
for j in range(2, 1000000):
base += L
if (s1 - base) * j == s2:
k = j
break
assert (s1 - k * L) * j == s2

s = s1 - k * L

e = abs(int(s[0] - s[1]))
p = GCD((gift - 1), n)
q = n // p
d = inverse(e, (p-1)*(q-1))
m = pow(enc, d, n)
print(long_to_bytes(int(m)))
#flag{this_1s_a_so_EZ_Ecc_and_RSA_}

math

题目:

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
from Crypto.Util.number import *


def gen_rev_sum(m,p):
sum = 0
round = 0
while m > 0:
digit = m % p
if round % 2 == 0:
sum -= digit
else:
sum += digit
m = m // p
round += 1
return sum // 2025


e = 65537
p = getPrime(256)
q = getPrime(256)
n = p*q

m1 = getRandomNBitInteger(2048)
m2 = getRandomNBitInteger(2048)
sum1 = gen_rev_sum(m1, p)
sum2 = gen_rev_sum(m2, p)

flag = "flag{--------------------------}"
m = bytes_to_long(flag.encode())

print("m1 =",m1)
print("m2 =",m2)
print("sum1 =",sum1)
print("sum2 =",sum2)
print("n =",n)
print("c =",pow(m,e,n))

'''
m1 = 17322548249387769406385507000191215801044910756841784387283679508067232037647009879640247663005640315645559929483973978388785385751219073137080976227046261663059832428571101292873255962114141666488474602734594597852331665601154571683480014721045567844719377268571343706508041194359642732322649799872642255094259428635455750138217286588825326703937255171250131117864604764478573786940615096044575610751081788573681131616312486987096717266320380202191909867687322859634487150465591581523036586129341984826904474237818210411872793917742756628712320922128969576851582027757934655202892557206052328142121974846460835879379
m2 = 29770749505949559271464509877642735633388289947852331255230201935471628731047838190019590503471311260422939188831886032391799282413808339483805109656799786202448656409753608524222447399741340441803183979217817801933166848028113568228217090419247166878248450792302177597130681740006379413412297487888656975884867850858832779733076818160854085244264177562471933684902341628858046181331683501978826962693104997686104748486850900546849316714934730338449894336151567737740558472664876717516650156395237362632196760323299658988296623556674223583771795447537227301625104687705109034611911834940501083977979641467845119043780
sum1 = -108877560874638575191632670246326227208412819991287356983577291185528002487
sum2 = -47122048431044787786292644180145597499319125719652288525187634667738055282
n = 9020951256034058214321622067945640395058903219618790136239198219605516437223449048642101160150934286238922049363203171871230111420670637737169565825694393
c = 3323425622556846027480153848276857423081641901016156494250966280342935316300495906916254739461788219592704051961044937129981786472345610933524261214506540
e = 65537
'''

解题思路:

题目把两个随机数m1,m2表示为:

因为 $p \equiv -1 \pmod{p+1}$
那么m可以表示为:

那么就有 $m + sum = k*p$,所以只需要求一下gcd即可,由于给出的sum//2025,可能会有误差还原的时候还需要进行一下小爆破即可

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
#python
from Crypto.Util.number import *
from tqdm import *

m1 = 17322548249387769406385507000191215801044910756841784387283679508067232037647009879640247663005640315645559929483973978388785385751219073137080976227046261663059832428571101292873255962114141666488474602734594597852331665601154571683480014721045567844719377268571343706508041194359642732322649799872642255094259428635455750138217286588825326703937255171250131117864604764478573786940615096044575610751081788573681131616312486987096717266320380202191909867687322859634487150465591581523036586129341984826904474237818210411872793917742756628712320922128969576851582027757934655202892557206052328142121974846460835879379
m2 = 29770749505949559271464509877642735633388289947852331255230201935471628731047838190019590503471311260422939188831886032391799282413808339483805109656799786202448656409753608524222447399741340441803183979217817801933166848028113568228217090419247166878248450792302177597130681740006379413412297487888656975884867850858832779733076818160854085244264177562471933684902341628858046181331683501978826962693104997686104748486850900546849316714934730338449894336151567737740558472664876717516650156395237362632196760323299658988296623556674223583771795447537227301625104687705109034611911834940501083977979641467845119043780
sum1 = -108877560874638575191632670246326227208412819991287356983577291185528002487
sum2 = -47122048431044787786292644180145597499319125719652288525187634667738055282
n = 9020951256034058214321622067945640395058903219618790136239198219605516437223449048642101160150934286238922049363203171871230111420670637737169565825694393
c = 3323425622556846027480153848276857423081641901016156494250966280342935316300495906916254739461788219592704051961044937129981786472345610933524261214506540
e = 65537

for i in trange(2025):
for j in range(2025):
sum1_ = sum1*2025+i
sum2_ = sum2*2025+j
kp = GCD(m1 + sum1_, m2 + sum2_)
if kp > 2 ** 255:
for k in range(1, 10000):
if (kp % k == 0):
p = kp // k - 1
if (isPrime(p) and len(bin(p)[2:]) == 256):
q = n // p
d = inverse(e, (p - 1) * (q - 1))
print(long_to_bytes(pow(c, d, n)))
break
#flag{Reverse_Sum_Mod_p+i_GCD_2025!}

1ZRSA

题目:

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
from Crypto.Util.number import *
from gmpy2 import *
import random

def RSA(m,nbit):
while True:
p, q, e = getPrime(nbit), getPrime(nbit), getPrime(nbit)
n = p * q
phi_n = (p - 1) * (q - 1)
d = int(inverse(e, phi_n))
if len(bin(d)[2:]) == 1024:
break

keep_bits = nbit * 2 - 100
mask = int((1 << keep_bits) - 1)
d_ = d & mask
c = powmod(m, e, n)
return c,n,e,d_

def gen(nbit):

c, n, e, d_ = RSA(m, nbit)
N = getPrime(nbit * 2)
t = random.randint(1, nbit * 2 - 1)
C = [random.randint(0, N - 1) for _ in range(t - 1)] + [powmod(d_,1,N)]
R.<x> = GF(N)[]
f = R(0)
for i in range(t):
f += x ** (t - i - 1) * C[i]
enc = [(a, f(a)) for a in [random.randint(1, N - 1) for _ in range(t)]]

with open("output.txt", "w", encoding="utf-8") as f_out:
f_out.write(f"c = {c}\n")
f_out.write(f"n = {n}\n")
f_out.write(f"e = {e}\n")
f_out.write(f"N = {N}\n")
f_out.write(f"enc = {enc}\n")

flag = "flag{-------------------------------}"
m = bytes_to_long(flag.encode())

if __name__ == "__main__":
gen(512)

output.txt太长了就不放出来了,想要的师傅可以去hscctf的靶场下载(虽然可能还没更新)

有空再补