sensor sw1 switch1 @enabled sensor sw2 switch2 @enabled sensor sw3 switch3 @enabled sensor sw4 switch4 @enabled sensor sw5 switch5 @enabled sensor sw6 switch6 @enabled sensor sw7 switch7 @enabled sensor sw8 switch8 @enabled op shl t sw1 7 set number t op shl t sw2 6 op add number number t op shl t sw3 5 op add number number t op shl t sw4 4 op add number number t op shl t sw5 3 op add number number t op shl t sw6 2 op add number number t op shl t sw7 1 op add number number t set t sw8 op add number number t set en 0 set i 0 jump 33 greaterThanEq i 16 op pow fl0 i 2 jump 31 notEqual fl0 number set en 1 jump 33 always x false op add i i 1 jump 26 always x false op equal fl1 0 sw1 op equal fl2 0 sw6 op or fl3 fl1 fl2 jump 38 equal fl3 0 set en 0 control enabled generator1 en 0 0 0 control enabled panel1 en 0 0 0 end
我们需要将其翻译为更通俗易懂的python语言
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
switchs = [0,0,0,0,0,0,0,0] number = 0 for i inrange(switchs): t = switchs[i]<<(7-i) number += t en = 0 i = 0 while(i<16): fl0 = i**2 if fl0 != number: i += 1 continue en = 1 fl1 = (0==switchs[0]) fl2 = (0==switchs[5]) fl3 = fl1 or fl2 if fl3 ==0 : print("success!")
那么我们需要满足两个条件:en = 1且fl3!=0
前一个条件决定了number为一个平方数,而后一个条件则限制了sw1和sw6必须均为1
这里我们可以使用爆破脚本找到满足条件的开关序列
需要注意的是switch8也在右侧的处理器范围内,一旦置为1,右侧模块则会爆炸
我们可以为该部分编写如下爆破脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
import itertools import gmpy2
dic = '01' for x in itertools.product(dic, repeat=8): switchs = ''.join(x)
number = 0 for i inrange(8): t = int(switchs[i]) << (7 - i) number += t if gmpy2.iroot(number,2)[1] \ and gmpy2.iroot(number,2)[0]!=0 \ andint(switchs[0])==1 \ andint(switchs[5])==1 \ andint(switchs[7])==0: print(switchs) exit()
bound = 5 constraints = ((1, 1, 3), (1, 2, 2), (1, 2, 4), (1, 4, 4), (2, 2, 2), (2, 2, 3)) count = [3, 4, 2, 2, 2, 3] num_constraints = sum(count) num_dims = len(constraints[0]) arrange = [[[0for i inrange(3)] for j inrange(num_dims)] for k inrange(num_constraints)] print('Input a string:') s = (c for c ininput().strip()) for i inrange(num_constraints): for j inrange(num_dims): for k inrange(3): if k == 2: arrange[i][j][k] = -1 else: number = int(next(s)) assert0 <= number <= bound arrange[i][j][k] = number print('Stage 0 passed') assert arrange == list(sorted(arrange)) print('Stage 1 passed') for i inrange(num_constraints): for j inrange(num_constraints): if i == j: continue assertany((arrange[i][k][1] <= arrange[j][k][0] or arrange[j][k][1] <= arrange[i][k][0]) for k inrange(num_dims)) print('Stage 2 passed') for i inrange(num_constraints): for t inrange(len(constraints)): iftuple(sorted([arrange[i][j][1] - arrange[i][j][0] for j inrange(num_dims)])) == constraints[t]: count[t] -= 1 break assertnotany(count) print('Stage 3 passed') score = len(set((x, y, z) for i inrange(num_constraints) for x, y, z in itertools.product(*arrange[i]))) if score >= 157: print(open('/flag3').read()) elif score <= 136: print(open('/flag2').read()) else: print(open('/flag1').read())
for i inrange(num_constraints): for j inrange(num_constraints): if i == j: continue assertany((arrange[i][k][1] <= arrange[j][k][0] or arrange[j][k][1] <= arrange[i][k][0]) for k inrange(num_dims)) print('Stage 2 passed')
for i inrange(num_constraints): for t inrange(len(constraints)): iftuple(sorted([arrange[i][j][1] - arrange[i][j][0] for j inrange(num_dims)])) == constraints[t]: count[t] -= 1 break assertnotany(count) print('Stage 3 passed')
score = len(set((x, y, z) for i inrange(num_constraints) for x, y, z in itertools.product(*arrange[i]))) if score >= 157: print(open('/flag3').read()) elif score <= 136: print(open('/flag2').read()) else: print(open('/flag1').read())
import random import math from sympy import isprime
# You do know that we SCGY students can factor RSA, right? # So just give me p and q directly p = int(input('p: ')) q = int(input('q: ')) assert isprime(p) and isprime(q) and p != q
# Prove me that p, q are strong primes lfp = int(input('A large prime factor of p-1: ')) lfq = int(input('A large prime factor of q-1: ')) assert isprime(lfp) and isprime(lfq) assert (p-1) % lfp == 0and (q-1) % lfq == 0 assert lfp > 2**128and lfq > 2**128
N = p*q phi = (p-1)*(q-1) Nbits = N.bit_length() # N is large enough assert Nbits == 1024
e = int(input('e: ')) % phi d = pow(e, -1, phi) # No Low Private Exponent Attack assert d.bit_length() > 0.292*Nbits # No Low Public Exponent Attack k = Nbits - max(int(Nbits*2/e), 96)
# OK, we've got a safe RSA parameters state = random.SystemRandom().randint(2, N-1) randomNums = [] states = []
mission = int(input("Choose mission: ")) if mission == 1: for _ inrange(100): state = pow(state, e, N) randomNums.append(int(state) & ((1 << k) - 1)) states.append(state) elif mission == 2: for _ inrange(1): state = state >> k state = pow(state, e, N) randomNums.append(int(state) & ((1 << k) - 1)) states.append(state)
# Not a small loop for i inrange(len(states)-1): assert (math.gcd(states[i] - state, N) == 1)
from Crypto.Util.number import * import itertools from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality()
f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = PolynomialSequence([], f.parent()) for i inrange(m+1): power = N ^ (m-i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = power for variable, shift inzip(f.variables(), shifts): g *= variable ^ shift G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1/factor) B = B.change_ring(ZZ)
H = Sequence([], f.parent().change_ring(QQ)) for h in B*monomials: if h.is_zero(): continue H.append(h.change_ring(QQ)) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: V = I.variety(ring=ZZ) if V: roots = [] for root in V: root = map(R, map(root.__getitem__, f.variables())) roots.append(tuple(root)) return roots
return [] p = 8130783200765099079371905805653275305530953408368486972439144538377172762778724178293921761601331901642956558545531112904308756365058449689105893951902947 q = 11454088000212950190744304417071055599116596384509623856814663255888235693331192150623151438185124694138841377055326544017433007065922209282946188611202987 lfp = 556695256623252691766599489994025390137 lfq = 625845849695411279745162870674729131439 N = p*q e = -3
from Crypto.Util.number import * import itertools from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
defsmall_roots(f, bounds, m=1, d=None): ifnot d: d = f.degree()
R = f.base_ring() N = R.cardinality()
f /= f.coefficients().pop(0) f = f.change_ring(ZZ)
G = PolynomialSequence([], f.parent()) for i inrange(m+1): power = N ^ (m-i) * f ^ i for shifts in itertools.product(range(d), repeat=f.nvariables()): g = power for variable, shift inzip(f.variables(), shifts): g *= variable ^ shift G.append(g)
factors = [monomial(*bounds) for monomial in monomials] for i, factor inenumerate(factors): B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ) for i, factor inenumerate(factors): B.rescale_col(i, 1/factor) B = B.change_ring(ZZ)
H = Sequence([], f.parent().change_ring(QQ)) for h in B*monomials: if h.is_zero(): continue H.append(h.change_ring(QQ)) I = H.ideal() if I.dimension() == -1: H.pop() elif I.dimension() == 0: V = I.variety(ring=ZZ) if V: roots = [] for root in V: root = map(R, map(root.__getitem__, f.variables())) roots.append(tuple(root)) return roots
return [] p = 8130783200765099079371905805653275305530953408368486972439144538377172762778724178293921761601331901642956558545531112904308756365058449689105893951902947 q = 11454088000212950190744304417071055599116596384509623856814663255888235693331192150623151438185124694138841377055326544017433007065922209282946188611202987 lfp = 556695256623252691766599489994025390137 lfq = 625845849695411279745162870674729131439 N = p*q e = -3