NSSRound#11 Basic

ez_enc

ABAABBBAABABAABBABABAABBABAAAABBABABABAAABAAABBAABBBBABBABBABBABABABAABBAABBABAAABBAABBBABABABAAAABBAAABABAABABBABBBABBAAABBBAABABAABBAAAABBBAAAABAABBBAABBABABAABABAAAAABBBBABAABBBBAAAABBBBBAB

题目提示不是baconic,那就将A转成0,B转成1,然后用工具一把梭,发现是伏羲六十四卦加密,直接出flag

MyMessage

from Crypto.Util.number import *
import os

flag = os.getenv('FLAG')

e = 127

def sign():
    msg = input("Input message:")
    p = getPrime(512)
    q = getPrime(512)
    n = p*q
    c = pow(bytes_to_long((msg + flag).encode()), e, n)
    print(f"n: {n}")
    print(f"Token: {hex(c)}")

def main():
    while True:
        sign()

main()

这题主要是取多组n和c的值进行中国剩余定理求m

from pwn import *
import re
import binascii, gmpy2
from functools import reduce
import libnum

host = 'node2.anna.nssctf.cn'
port = 28395
conn = remote(host, port)


def interact_with_server(conn):
    conn.recvuntil("Input message:")
    conn.sendline("")

    data1 = conn.recvline().decode()
    data2 = conn.recvline().decode()

    n = int(re.findall(r'n: (\d+)', data1)[0])
    c = int(re.findall(r'Token: 0x(\w+)', data2)[0], 16)

    return n, c


n_values = []
c_values = []

for i in range(127):
    n, c = interact_with_server(conn)
    n_values.append(n)
    c_values.append(c)


def CRT(mi, ai):
    assert (reduce(gmpy2.gcd, mi) == 1)
    assert (isinstance(mi, list) and isinstance(ai, list))
    M = reduce(lambda x, y: x * y, mi)
    ai_ti_Mi = [a * (M // m) * gmpy2.invert(M // m, m) for (m, a) in zip(mi, ai)]
    return reduce(lambda x, y: x + y, ai_ti_Mi) % M


e = 127
n = n_values
c = c_values
m = gmpy2.iroot(CRT(n, c), e)[0]
print(m)
print(libnum.n2s(int(m)))

MyGame

from Crypto.Util.number import *
import os
import random
import string

flag = os.getenv('FLAG')

def menu():
    print('''=---menu---=
1. Guess
2. Encrypt
''')

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

def randommsg():
    return ''.join(random.choices(string.ascii_lowercase+string.digits, k=30))

mymsg = randommsg()
def guess():
    global mymsg
    msg = input()

    if msg == mymsg:
        print(flag)
    else:
        print(mymsg)
        mymsg = randommsg()

def encrypt():
    e = random.getrandbits(8)
    c = pow(bytes_to_long(mymsg.encode()), e, n)
    print(f'Cipher_{e}: {c}')

def main():
    print(f'n: {n}')
    while True:
        opt = int(input())

        if opt == 1:
            guess()
        elif opt == 2:
            encrypt()

main()

因为n是不变的,e是2^8内的随机数,你可以一直输入2去改变e的值,直到e出来的是3或者其他比较小的值,然后低指数加密攻击就可以出来了,这是非预期解吧。这里还是以官方的做法来讲。

因为你每次输入2,他们的n是不变的,c,e是变的,那么就可以使用共模攻击来求解,当然e1和e2必须互素才能解。

from gmpy2 import *
from Crypto.Util.number import *
from pwn import *
import re
import binascii,gmpy2
from functools import reduce
import libnum

# ------------ 交互部分 ------------
host = 'node1.anna.nssctf.cn'
port = 28576
conn = remote(host, port)
data1 = conn.recvline().decode()
n = int(re.findall(r'n: (\d+)', data1)[0])

def interact_with_server(conn):
    conn.sendline("2")
    data1 = conn.recvline().decode()
    print(data1)
    e,c = re.findall(r'Cipher_(\d+): (\d+)', data1)[0]
    e = int(e)
    c = int(c)
    
    return e, c
# ------------ 共模攻击 ------------
def attack():
    e1,c1 = interact_with_server(conn)
    e2,c2 = interact_with_server(conn)

    g,x,y = gcdext(e1,e2)

    m= pow(c1,x,n)*pow(c2,y,n)%n

    m = iroot(m,2)[0]

    return long_to_bytes(m)

def get_flag():
    m = attack()
    print(m)
    conn.sendline("1")
    conn.sendline(m)
    return conn.recvline().decode()

while True:
    flag = get_flag()
    if "NSS" in flag:
        print(flag)
        break

ez_signin

from Crypto.Util.number import *
from secret import flag

p = getPrime(512)
q = getPrime(512)
assert p > q
n = p*q
e = 65536
m = bytes_to_long(flag)
num1 = (pow(p,e,n)-pow(q,e,n)) % n
num2 = pow(p-q,e,n)
c = pow(m,e,n)

print("num1=",num1)
print("num2=",num2)
print("n=",n)
print("c=",c)

\[num1=(p^e-q^e)\pmod n \]

\[num2=(p-q)^e\pmod n \]

\[根据二项式定理展开:num2=(p^e+q^e)\pmod n \]

\[两边同时模p \]

\[num1=(-q^e)\pmod p \]

\[num2=q^e\pmod p \]

\[所以两式相加:num1+num2=0\pmod p \]

\[p=gcd(num1+num2,n) \]

因为e=65536=1<<16,p,q都是4k+3型素数,所以又用到了二次剩余的知识(我周报里写着有),拿出之前的脚本结合,最终wp:

#sage
from sympy.ntheory.modular import crt
from Crypto.Util.number import *

num1= 2775831354229923947744110222507863933574411897722478973469923299411546050474843856326024430074857133976354676857166554872257638426565724387179149171632416985944346489466965110670104990151999871783845959108955589945641517118400357360851865623071772324939539064047191924077951100016766658043724058872748766771
num2= 57822654736857646576418296007540106780276512153756277058855757547382961542492838819696805844716620913167153602856693831726152375890495103035701199247079645092619874561711749593253235666771101287537876783566448505829451706496439205282302119316936881497163266819067206207458038596600471668612939197588441024158
n= 129770519090525725810022018120533695628782431267983618019293084269987333756301607244113360793108640577661794258265039863902836204944419443322596944769367767508517074838227609729864864417275432373782879364663360618747786397730015510710663590152772498306166973852059266895770180830911596826648497480706503280849
c= 71310243822509976120541805309731185677956258041399575869667955731705691994150005919354168558022080451707878959264030784055792822048483199371829432059611371728850382785173978204635157492807325268890777921704824498293700056727016422076617851179126873615625382747399852661166946838768567204732697003229415668085
p=gmpy2.gcd(num2+num1,n)
q=n//p
def get_mm(p, e_factor):
    cp_list = [c % p]
    for i in e_factor:
        cpp_list = []
        for j in cp_list:
            R.<x> = Zmod(p)[]
            f = x^i - j
            mm = f.roots()
            cpp_list.extend([int(i[0]) for i in mm])
        cp_list = cpp_list
    return cpp_list
e_factor = [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]  #将e分解成16个2
cp_list = get_mm(p, e_factor)
cq_list = get_mm(q, e_factor)
for i in cp_list:
    for j in cq_list:
        m = crt([p,q],[i,j])
        for z in m:
            m1 = long_to_bytes(int(z))
            if b'NSS' in m1:
                print(m1)

NTR

好家伙,涉及新知识NTRU加密算法,直接去学习一手

NTRU是一个带有专利保护的开源公开密钥加密系统,使用基于格的加密算法来加密数据。它包括两部分算法:NTRUEncrypt用来加密,NTRUSign用来进行数字签名。与其他流行的公钥加密系统不同,它可以防止被Shor算法破解,并显著提升了性能。NTRU算法被认为可以抵抗量子攻击。
NTRU is based on the SVP or CVP in a lattice

算法流程如下:

在这里插入图片描述

文字描述:

\[初始化三个整数参数(N,p,q)和四个具有N-1阶多项式f、g、r、m,其中N为表数,p可以是多项式或整数,q为整数 \]

\[但要保证gcd(p,q)=1,多项式f、g、r中非0系数的个数分别用d_f,d_g,d_r表示 \]

\[密钥产生:Bob根据NTRU参数N,d_F,d_g,随机选取多项式F,g\in R,F中的非0系数的个数为d_F,计算多项式h: \]

\[f=1+p*F \]

\[f*f_q\equiv 1\pmod q \]

\[h\equiv p*g*f_q\pmod q \]

\[f_g表示f的模q逆,Bob的公开密钥为(N,p,q,h),私钥为(f,f_p) \]

加密:

\[假设A想发送信息 m\in L_m 给B,他将根据参数 d_{\phi} 随机选择一个 \phi \in L_{\phi},然后他利用B的公钥 h 计算 \]

\[e\equiv \phi *h+m\pmod q \]

\[A把密文e发送给B \]

解密:

\[当B收到密文 e 后,他首先利用私钥 f 计算 \]

\[a\equiv f*e\pmod q \]

\[选择 a 的系数位于 [−\frac{p−1}{2},\frac{p-1}{2}] 之间,然后计算 \]

\[b\equiv a\pmod p \]

\[c\equiv F_p*b\pmod p \]

\[则多项式c就是明文m \]

那么就要构造矩阵\(\begin{pmatrix} I & H\\ 0 & q \end{pmatrix}\)=\(\begin{pmatrix} \lambda & 0 & \cdots & 0 & h_0 & h_1 & \cdots & h_{N-1}\\ 0 & \lambda & \cdots & 0 & h_{N-1} & h_0 & \cdots & h_{N-2}\\ \vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \lambda & h_1 & h_2 & \cdots & h_0\\0 & 0 & \cdots & 0 & q & 0 & \cdots & 0\\0 & 0 & \cdots & 0 & 0 & q & \cdots & 0\\ \vdots & \vdots & \ddots & \vdots & \vdots & \vdots & \ddots & \vdots\\0 & 0 & \cdots & 0& 0 & 0 & \cdots & q\\ \end{pmatrix}\),其中 H 是根据公钥多项式的系数生成的循环矩阵。构建一个这样的矩阵,然后进行LLL算法得到解密密钥。

exp:

#sage
h = 0b111010101001111010101010101100000011001010001111010010101110110111011101110100001111110100100011110001110000100110011000011110010101110011100111010101001010000000010010001110000000010110011100000011110110100111000101110010100100111011000100000010101011010000101111011000011110101100111011000100001101100001110001011101111100001100011111010010010001001001111100011001100010001000010011110011001000101011011011001011010100010111110011000101100101100001110010011111000111000101111101111110001010111110111010110111110100100010000110111011101111101011110000100010000000100100110101111101100111011101001001010110000101001010111011011001011010101111010010110001011001010010000011111101110000111100001000111101000111110011001000101001011111110111110000100110101101111001000100100010010100010011011011000000111111110100011010001111111001111010111111110101101101110110000110101001100111110110101111001101111001101000001110011100100100100111000011110011000110101011110101110101001101000100010010110011001011110010110010001101110011011001110101110001010011010001011010011110111000100000000100010000101011101101101001011101100011010111001011011110100101110000100001111100101010010010100111101000011000111001011111110100010010100101100101001001001101101010110001111110000101110110101000101110011100100001011000100110001000111101111001001011011001110010101001010001011011000100100010011000111110001110001011111111110110000001011011110101111110111010000011001111100011010001000100001010000000000101000001011010100111001101111001110100001101101100011110101111101011110111010110101110100010100011010001011111011011101011100001001000110110011001100100100101010011000011010010010111000011101100001100101011011101101100001011110101000000101100111101000110001100100000000100011010111111001010100001001001010001111011000110001111101111110010111101101100110110101010101000101101100110010000010111101110111110110100001011000100011010001011011000000001111001100010011000011101101000000110101111010100011000011111010101011111010000111000011011000011001001111000010000100
p = 0b10001000111011111101101011011111100100100010010111010011100110011010111100101100111001111101100001111010000010100101111101100010111100000011011100010001011001001000011101100100011110110110100100000110101010100111001111101000101100001010110011000101101000110001101001101000000100001011100111110101011110001110001111111110010011001100100001001011100110010110100010101000101000001100101101010000100101010101111011000100010001100101011111000100000111000111101110011001001010010000111000011010101010110100111111110100101110111001110111011010101010000001101110000101010111000011001000110001100010011011111110001000110011101001011010001110001001001111110001011111011010100010001110111110011101111001000011000000100000101111010011110111111101111111000101100111101010001010011110101000010001000000010101010011010101000000000100011101001110111100010111100111111110001011100110001101010000011110000110001001111111000000100111000111010110111110110001100000010100110110001011000110010000100101001010101011001011001100101101101111010110001111010000100001001101101110010010111101011011001101100100011000111001110001100010111101010100111010101110010100111001011111000100100010000111011110010100001001110001001110111100000110000010110111001011111111100111011111011010101100011010010001001101010101010101101100011110000001000100111001111111010010100101010100010111110000011100010111101100010010110010111101010001110101101101001011010110000010101110011010110111011111111101101011101111001110010111110010000001000010010010100010101010010011011111101101111011001010100001101000000111111011111111100111101001010001110111111011110100101010000011111101110100111101111110001000000111100100110011010010010000001011110001000010000111001010010101001110010011001010001111010001111011110110001000111100001011100100011101110001111100101000011001001001011010101101111100111000010011100011010011011110001010010110111111100000010000000111100111010000111000011010110000111100011111000100001100000101000011100001010001000100010100000111000000111000011010010000101010100100100010110111
c = 0b11100000010101110010011110011100110100011000111100010011100010000011011111110010110011101010001110110010111001001111110111001011100110100100000000110110010100101000101110101100101110100011101111000010101010011001110111001011011001110111000010011010100101111110101100111000011110000110100111111110110000100010111010111010101001101000101000111011001100101011100000000110000100101010110000010101100110011111101110000000010001110000010001110101000110000100100101110111011100010100110001000101110010001101010110000001001110000001001011001111010001111010000110100110011110100011001100101100000101110100101111100111001100001000011100100001101110000011010000001011010010001101010000001010011000111110010101001000111000111101110100101110100001111111011100011101010111001101000101001111011011111111010000010110001011001100010001000011011000101001011111010100011001101001110100000011100100011100111110011010011011000000101011100001100011100100000111000010101101110101010001111110000100111111001100100000101010001111001111000010100011100101100011101110011100000101110001101001100011111110111000010111110011001110010111100101101110011000000111000111100001001001000101011100010010000001000001101001100001100111011011000111101101010000110100001010000000101011010010101110100111110011100010110010001001100010011111010000001001101110000110111100101111011010001111111111010000110101000100110100100111011110100010010000100010111110011001111001111100000010010101001000110001010011100001101001011110101000001011100010011111100010000011110001101001110111011001101100010000101011011010111000100101011010001000001111110110011100010001101000110010000110011111110010010111110001100101000010000011100001011111000110101110000100010100011111101001001111111100001100100000001011100001101101010010001000110101011001010100001110000010011100110000001101100001100010100010101010110010110111101010111011110000100010001111011010001101111011101010010111011110001001000011111111001110010100001011011100000010001000101111110000010010110010000010110001100010110001110011001000010111100
v1 = vector(ZZ, [1, h])
v2 = vector(ZZ, [0, p])
m = matrix([v1,v2])  #构造格
f, g = m.LLL()[0]
print(f, g)

a = f*c % p % g
m = a * inverse_mod(f, g) % g
print(bytes.fromhex(hex(m)[2:]))

ez_fac

from Crypto.Util.number import *
import random
from secret import flag,a0,a1,b0,b1

p = getPrime(512)
q = getPrime(512)
e = getPrime(128)
n = p*q
assert pow(a0,2) + e * pow(b0,2) == n
assert pow(a1,2) + e * pow(b1,2) == n
m = bytes_to_long(flag)
c = pow(m,e,n)

print("c=",c)
print("n=",n)
print("a0=",a0)
print("a1=",a1)
print("b0=",b0)
print("b1=",b1)

e=(pow(a1,2)-pow(a0,2))//(pow(b0,2)-pow(b1,2)),且e是素数,那么思路清晰了,只要能把n分解掉就行了。看wp吧

检索一下相关文献,比如这个:
A Note on Euler's Factoring Problem-Brillhart_Euler_factoring_2009

img

对于这个题目本身就没什么可说的了

文字描述:

\[设N> 1为奇数,用两种不同的方式表示为 \]

\[N=m*a^2+n*b^2=m*c^2+n*d^2 \]

\[其中a, b, c, d, m, n\in Z^+, b < d,和 gcd(m*a,n*b) = gcd(m*c, n*d) = 1.然后 \]

\[N=gcd(N,a*d-b*c)*\frac{N}{gcd(N,a*d-b*c)} \]

\[其中因子是重要的。 \]

所以\(a*d-b*c=a0*b1-a1*b0\).

exp:

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

c= 35365949784050829929861737789236020559135622198897625351353637445622956768233865962002277568692477708475206540271806542711843022878152143032364877838180739249214035959876599676088358907232330955234529703338468238427784663238111249828170368817450879581282130905777101291196257788568056540581712737620696888181
n= 60759060882959791909904396677188989949758090199603630243982902422381690538885036721260587316981956179159099537464766520810988299027308891716697721325694989187113132568281096643090555966502943628821584608317087986774067361766441006582461264783625589284748285132591500064467264821214540974749792006934616412217
a0= 7794809868300816476939749391923181660663599092817735689970830403880360740950291069966802056703842257352942487715953634294627774900178116901736408438781725
a1= 7794809868300816476939748778965768208814733337627617321244638924271232070361166330324980435743037906985498772947115676315756364476413563742000304770717475
b0= 19283995921825875899155714134110227538038032500196406129941198508864582000463560816723795975202107099295086076956040133684
b1= 172332404813056620110912939211150875333966617506319147214329967023854401850532359816888852973202924631133349299841944983684

temp=a0*b1-a1*b0
p=GCD(temp,n)

q=n//p
e=(pow(a1,2)-pow(a0,2))//(pow(b0,2)-pow(b1,2))

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

posted @ 2023-05-31 14:16  L00kback  阅读(84)  评论(0编辑  收藏  举报
Title