## Hyper Normal### Challenge> Being normal is hard these days because of Corona virus pandemic!
```python#!/usr/bin/env python3
import randomfrom flag import FLAG
p = 8443
def transpose(x):    result = [[x[j][i] for j in range(len(x))] for i in range(len(x[0]))]    return result
def vsum(u, v):    assert len(u) == len(v)    l, w = len(u), []    for i in range(l):        w += [(u[i] + v[i]) % p]    return w
def sprod(a, u):    w = []    for i in range(len(u)):        w += [a*u[i] % p]    return w
def encrypt(msg):    l = len(msg)    hyper = [ord(m)*(i+1) for (m, i) in zip(list(msg), range(l))]    V, W = [], []    for i in range(l):        v = [0]*i + [hyper[i]] + [0]*(l - i - 1)        V.append(v)    random.shuffle(V)    for _ in range(l):        R, v = [random.randint(0, 126) for _ in range(l)], [0]*l        for j in range(l):            v = vsum(v, sprod(R[j], V[j]))        W.append(v)    random.shuffle(transpose(W))    return W
enc = encrypt(FLAG)print(enc)```
### Solution
This challenge gives a strange encryption scheme. This encryption algorithm actually does this. For an input of length $l$, the algorithm first multiplies each character of the input by the corresponding index to obtain a vector $x$. Then the algorithm loops $l$ times, each time outputs a vector $v$. Each number in the vector $v$ is a random number between 0 and 126 multiplied by the corresponding number in the vector $x$. All these operations are performed modulo 8443.
It is worth noting that `random.shuffle` on line 38 of the program actually has no effect on the output, because the `transpose` function returns a new object.
Solving for the input is intuitive. For the i-th byte of the input, we simply iterate through all printable characters, multiply $i$ by those characters, and multiply 0 through 126 to get all possible results. If column $i$ of the program output happens to be a subset of the possible results generated by a character $c$, then the i-th byte of the input is likely to be $c$.
```python#!/usr/bin/env python3
from string import printable
p = 8443
with open('output.txt', 'r') as f:    enc = eval(f.read())
results = []
for i in range(len(enc[0])):    tmp = []    for j in enc:        tmp.append(j[i])    results.append(tmp)
flag = ''for idx, result in enumerate(results):    for c in printable:        possibilities = [ord(c)*i*(idx+1) % p for i in range(127)]        if all([i in possibilities for i in result]):            flag += c            breakprint(flag)```
##### Flag`CCTF{H0w_f1Nd_th3_4lL_3I9EnV4Lu35_iN_FiN173_Fi3lD5!???}`