[This challenges had a mountainous flavor text, now lost to history.]
In short, the task is to provide vectors flipping specific bits in an encryption scheme resembling ring learning with errors.
1 solve / 500 points
chall.sage
import random
q = 3329
R = Zmod(q)
N = 32
l = 2
d = 11
Rx.<x> = PolynomialRing(R)
Rq.<u> = Rx.quotient(x^N + 1)
# My not so secret keys
# Static keys so you can precompute part of the solution to spare our poor VPS some load
t = vector(Rq, [3299*u^31 + 3045*u^30 + 2395*u^29 + 742*u^28 + 2092*u^27 + 22*u^26 + 2323*u^25 + 506*u^24 + 2532*u^23 + 5*u^22 + 1565*u^21 + 704*u^20 + 355*u^19 + 1766*u^18 + 1307*u^17 + 1148*u^16 + 1194*u^15 + 2260*u^14 + 1999*u^13 + 1188*u^12 + 731*u^11 + 68*u^10 + 847*u^9 + 2090*u^8 + 2514*u^7 + 3252*u^6 + 997*u^5 + 2271*u^4 + 731*u^3 + 1937*u^2 + 7*u + 2574, 2383*u^31 + 3121*u^30 + 963*u^29 + 1495*u^28 + 2776*u^27 + 2541*u^26 + 2516*u^25 + 2667*u^24 + 2772*u^23 + 114*u^22 + 1762*u^21 + 366*u^20 + 1343*u^19 + 2521*u^18 + 1678*u^17 + 3224*u^16 + 510*u^15 + 1594*u^14 + 3020*u^13 + 3145*u^12 + 1114*u^11 + 1823*u^10 + 1081*u^9 + 1737*u^8 + 2821*u^7 + 2202*u^6 + 2355*u^5 + 2238*u^4 + 745*u^3 + 266*u^2 + 887*u + 2731])
rh = 3428567257
s = vector(Rq, [4*u^31 + u^30 + 2*u^29 + u^28 + 4*u^27 + u^26 + 3*u^25 + 4*u^24 + 3*u^23 + u^22 + 2*u^21 + 4*u^20 + 3*u^19 + u^18 + u^17 + 3*u^16 + 2*u^15 + 2*u^14 + 4*u^13 + 4*u^12 + 2*u^11 + u^10 + u^9 + u^8 + u^7 + 2*u^6 + 4*u^5 + 2*u^4 + 3*u^3 + 4*u^2 + 3*u + 2, 4*u^31 + u^30 + 2*u^29 + 4*u^28 + u^27 + 3*u^26 + 2*u^25 + u^24 + u^23 + 3*u^22 + 4*u^21 + u^20 + u^19 + 4*u^18 + 3*u^17 + u^16 + u^15 + 3*u^14 + 3*u^13 + 3*u^12 + 3*u^11 + 3*u^10 + u^9 + 4*u^8 + 3*u^7 + 4*u^6 + 2*u^5 + 2*u^4 + u^3 + u^2 + 4*u + 4])
e = vector(Rq, [3325*u^31 + 5*u^30 + 3325*u^29 + 3325*u^28 + 3324*u^27 + 4*u^26 + 5*u^25 + 3324*u^24 + 3324*u^23 + 3324*u^22 + 5*u^21 + 3325*u^20 + 5*u^19 + 3325*u^18 + 5*u^17 + 3325*u^16 + 3326*u^15 + 3325*u^14 + 3328*u^13 + 3327*u^12 + 3325*u^11 + 3326*u^10 + 3327*u^9 + 3328*u^8 + 3327*u^7 + 3325*u^6 + 3325*u^5 + 3327*u^4 + 3326*u^3 + 3328*u^2 + 3328*u + 3325, 3325*u^31 + 5*u^30 + 5*u^29 + 3325*u^28 + 3325*u^27 + 4*u^26 + 3324*u^25 + 3325*u^24 + 3325*u^23 + 3324*u^22 + 3325*u^21 + 4*u^20 + 4*u^19 + 3325*u^18 + 3324*u^17 + 4*u^16 + 3325*u^15 + 4*u^14 + 5*u^13 + 4*u^12 + 3324*u^11 + 5*u^10 + 5*u^9 + 3324*u^8 + 5*u^7 + 4*u^6 + 5*u^5 + 3324*u^4 + 4*u^3 + 3324*u^2 + 5*u + 3325])
pk = (t, rh)
sk = (s, e)
def genA(base_ring, r, l):
random.seed(r)
A = Matrix(base_ring, [[base_ring([Integer(random.randint(0, q-1)) for _ in range(N)]) for _ in range(l)] for _ in range(l)])
return A
def decode(base_ring, v):
v = list(v).copy()
for i, p in enumerate(v):
coefs = p.list()
for j, a in enumerate(coefs):
coefs[j] = round((2/q)*Integer(a))%2
v[i] = base_ring(coefs)
return v
def small_secret():
return Rq([randint(1, 4) for _ in range(N)])
def small_error():
return Rq([randint(-4, -1) for _ in range(N)])
# In case you plebs think testing it locally will make it any easier
def keygen():
global l
r = Integer(random.getrandbits(N))
A = genA(Rq, r, l)
s = vector(Rq, [small_secret() for _ in range(l)])
e = vector(Rq, [small_error() for _ in range(l)])
t = A*s + e
return (t, r), (s, e)
def encrypt(pk, m, r, e1):
t, rh = pk
t = vector(Rq, t)
A = genA(Rq, rh, l)
m = list(map(int, bin(m)[2:][::-1]))
m = Rq(m)
e2 = small_error()
u = A.transpose()*r + e1
v = t*r + e2 + (q//2)*m
return (u, v)
def decrypt(sk, ct):
u, v = ct
m = decode(Rq, [v - sk*u])[0]
m = m.list()[::-1]
return int(''.join(map(str, m)), 2)
def verify_small_vector(v):
return all([-6 <= i <= 6 for i in v[:-1]])
def flatten(u):
b = []
for i in u:
j = i.list()
j = j + [0]*(N-len(j))
b += j
return vector(R, b)
def unflatten(base_ring, v):
v = list(v)
return vector(base_ring, [base_ring(v[i*N: (i+1)*N]) for i in range(len(v)//N)])
def receive_vector():
"""
What you want to input here is a vector of dimension l over Rq.
The way to do that is to create your vector, call the function "flatten" on it,
and then send the resulting list as comma separated integers
e.g: if your vector is v, you need to send str(flatten(v)).replace("[", "").replace("]", "")
"""
a = input("Enter vector: ")
a = list(map(Integer, a.split(",")))
if len(a) != N*l:
print ("It's just a simple math challenge, no pwn trickery please")
exit()
if not verify_small_vector(a):
print ("Is an error even an error if it's not small")
exit()
return unflatten(Rq, a)
for _ in range(5):
pt = randint(0, 2^11)
print ("plaintext: ", pt)
challenge = 2^randint(0, 11)
print ("challenge: ", challenge)
r = receive_vector()
e1 = receive_vector()
dif = decrypt(sk[0], encrypt(pk, pt, r, e1))^^pt
if dif != challenge:
print ("So much for perfect correctness")
exit()
print ("OK, you win. Here's your flag")
Computations are in the ring
We are given constants genA
) with
encrypt
takes vectors verify_small_vector
), i.e., the coefficients of entries are in the range encrypt
returns small_error
with coefficients in
decrypt
then computes 1
iff it is closer to
Why does this work?
Substituting, we get
Our challenge is now to provide
Though
Note that the only thing we can control is the term
Recall that the coefficients of
Baring any mathematical insight, we used brute force, which miraculously did work quite well.
It is straightforward to implement the computation of
typedef int V[2][N];
void multiply(const int *a, const int *b, int *c) {
std::fill(c, c + N, 0);
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j) {
int d = i + j;
int sig = d >= N ? -1 : 1;
c[d % N] += a[i] * b[j] * sig;
}
}
void comp(V &r, V &e1, int *out) { // e*r - s*e1
int a[N]{};
int b[N]{};
int c[N]{};
int d[N]{};
multiply(e[0], r[0], a);
multiply(e[1], r[1], b);
multiply(s[0], e1[0], c);
multiply(s[1], e1[1], d);
for (int i = 0; i < N; ++i) {
out[i] = ((a[i] + b[i] - c[i] - d[i]) % q + q) % q;
}
}
We choose all coefficients comp
output appears to have at most one big (q/4 + 4 < c < q*3/4 - 4
) coefficient (with high probability?), which is exactly what we need!
Searching with 32 threads, we find
Bruteforce in C++, output to all.txt
.
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cassert>
#include <thread>
#include <mutex>
#include <random>
constexpr int N = 32;
constexpr int q = 3329;
typedef int V[2][N];
constexpr V s = {{2, 3, 4, 3, 2, 4, 2, 1, 1, 1, 1, 2, 4, 4, 2, 2, 3, 1, 1, 3, 4, 2, 1, 3, 4, 3, 1, 4, 1, 2, 1, 4},
{4, 4, 1, 1, 2, 2, 4, 3, 4, 1, 3, 3, 3, 3, 3, 1, 1, 3, 4, 1, 1, 4, 3, 1, 1, 2, 3, 1, 4, 2, 1, 4}};
constexpr V e = {{3325, 3328, 3328, 3326, 3327, 3325, 3325, 3327, 3328, 3327, 3326, 3325, 3327, 3328, 3325, 3326, 3325, 5, 3325, 5, 3325, 5, 3324, 3324, 3324, 5, 4, 3324, 3325, 3325, 5, 3325},
{3325, 5, 3324, 4, 3324, 5, 4, 5, 3324, 5, 5, 3324, 4, 5, 4, 3325, 4, 3324, 3325, 4, 4, 3325, 3324, 3325, 3325, 3324, 4, 3325, 3325, 5, 5, 3325}};
void multiply(const int *a, const int *b, int *c) {
std::fill(c, c + N, 0);
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j) {
int d = i + j;
int sig = d >= N ? -1 : 1;
c[d % N] += a[i] * b[j] * sig;
}
}
void comp(V &r, V &e1, int *out) { // e*r - s*e1
int a[N]{};
int b[N]{};
int c[N]{};
int d[N]{};
multiply(e[0], r[0], a);
multiply(e[1], r[1], b);
multiply(s[0], e1[0], c);
multiply(s[1], e1[1], d);
for (int i = 0; i < N; ++i) {
out[i] = ((a[i] + b[i] - c[i] - d[i]) % q + q) % q;
}
}
void printV(const V &v) {
printf("tovec([");
for (int j = 0; j < 2; ++j) {
printf("[");
for (int k = 0; k < N; ++k) {
printf("%d, ", v[j][k]);
}
printf("], ");
}
printf("])");
}
void print_arr(const int *a) {
for (int i = 0; i < N; ++i) {
auto c = a[i];
printf("%d, ", c > q / 2 ? c - q : c);
}
puts("");
}
bool found[N];
int found_count = 0;
std::mutex found_mutex;
void search() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> distrib(-6, 6);
V r;
V e1;
int x[N];
for (size_t i = 0; i < (1ull << 40); ++i) {
//if ((i & 0xfffff) == 0) {
// printf("%lx\n", i);
//}
for (int j = 0; j < N; ++j) {
r[0][j] = distrib(gen);
r[1][j] = distrib(gen);
e1[0][j] = distrib(gen);
e1[1][j] = distrib(gen);
}
comp(r, e1, x);
int big_count{};
int big_j{};
constexpr int LO = q / 4 + 4, HI = q * 3 / 4 - 4;
for (int j = 0; j < N; ++j) {
int c = x[j];
if (LO < c && c < HI) {
big_j = j;
big_count++;
}
}
if (big_count == 1) {
std::lock_guard g(found_mutex);
if (!found[big_j]) {
found[big_j] = true;
found_count++;
printf("%d: (", big_j);
printV(r);
printf(", ");
printV(e1);
printf("),\n# ");
print_arr(x);
puts("");
}
}
if (found_count == N) return;
}
}
void test() {
V r{{3325, 3327, 4, 6, 3, 4, 2, 3327, 3324, 2, 3326, 6, 1, 1, 3325, 0, 1, 2, 3328, 1, 3327, 3328, 2, 1, 3327, 3, 0, 6, 3, 1, 4, 3328},
{3323, 5, 0, 3, 3, 3324, 1, 6, 3327, 3327, 5, 3323, 4, 2, 3326, 6, 2, 3, 3324, 4, 2, 3328, 4, 0, 3327, 3328, 3, 3328, 3325, 6, 1, 2}};
V e1{{3325, 3324, 3323, 6, 0, 3325, 0, 6, 3323, 3327, 6, 1, 3327, 3327, 3328, 6, 4, 3, 2, 1, 3326, 2, 3326, 3325, 1, 3, 2, 3328, 3, 2, 3323, 5},
{6, 6, 6, 3327, 3, 3328, 0, 0, 3328, 3327, 3328, 6, 3324, 3328, 3323, 2, 3328, 2, 0, 1, 0, 4, 3328, 0, 3327, 3328, 3325, 2, 3, 0, 3, 3324}};
int c[]{3250, 86, 267, 3309, 3144, 175, 62, 3269, 220, 3320, 3249, 20, 3286, 90, 3326, 59, 39, 3218, 3317, 3217, 103,
3257, 229, 3275, 134, 3326, 61, 3169, 3297, 3278, 3187, 3152};
int out[N]{};
comp(r, e1, out);
for (int i = 0; i < N; ++i) {
assert(c[i] == out[i]);
}
}
int main() {
//test();
constexpr int TC = 32;
std::vector<std::thread> threads;
for (int i = 0; i < TC; ++i) {
threads.emplace_back(search);
}
for (auto &t: threads) {
t.join();
}
search();
return 0;
}
Convert all.txt
to python array (add code to chall.sage
):
def tovec(v):
return vector([Rq(v[0]), Rq(v[1])])
D = eval("{" + open('all.txt').read() + "}")
print([(flatten(D[i][0]), flatten(D[i][1])) for i in range(N)])
Final solution script:
from pwn import *
context(log_level='debug')
q = 3329
N = 32
l = 2
# p = process(['sage', 'chall.sage'])
p = remote('52.172.254.231', 7905)
D = [((2, 6, 3326, 3328, 3, 5, 1, 3323, 6, 2, 2, 3326, 4, 3323, 3, 3324, 5, 3, 3, 0, 3324, 5, 0, 0, 4, 5, 4, 4, 5, 4, 3326, 0, 3327, 3, 4, 3328, 6, 5, 1, 6, 6, 2, 3, 3326, 3327, 3324, 0, 2, 1, 3328, 3324, 3327, 3, 3, 3323, 3326, 2, 3324, 3328, 4, 6, 3327, 3326, 3323),
(3323, 3323, 3328, 3326, 3328, 2, 3325, 3, 6, 4, 3325, 3323, 6, 6, 3324, 1, 5, 0, 6, 3325, 3, 4, 6, 3323, 2, 3, 3328, 3, 5, 3328, 6, 1, 1, 2, 2, 3328, 6, 3326, 3328, 6, 3326, 4, 3327, 1, 2, 1, 6, 2, 3326, 5, 1, 4, 4, 3328, 3, 0, 4, 3323, 4, 6, 3323, 3324, 6, 6)),
((0, 1, 3, 3323, 3325, 3327, 3326, 6, 5, 0, 3325, 3323, 0, 3328, 4, 3325, 4, 3326, 3326, 4, 3324, 3324, 5, 4, 2, 3323, 3325, 3327, 3323, 1, 3, 0, 3323, 6, 3326, 4, 5, 3324, 3328, 4, 3327, 1, 3327, 3326, 3326, 2, 5, 0, 3328, 4, 6, 4, 3328, 3326, 3323, 3324, 3327, 3324, 5, 6, 5, 3323, 6, 3328),
(3, 0, 3326, 0, 3, 5, 3325, 5, 3323, 3326, 4, 0, 3324, 3323, 2, 3, 2, 3325, 3, 6, 0, 3323, 3, 3, 4, 3324, 3323, 3, 1, 2, 3323, 3323, 1, 3, 3324, 5, 0, 3323, 3327, 3323, 3327, 0, 3323, 3327, 3325, 3327, 3326, 0, 3328, 6, 3324, 3323, 3323, 1, 3323, 3324, 1, 4, 3326, 3324, 3324, 3327, 3324, 6)),
((3324, 4, 6, 3327, 3325, 3324, 3326, 0, 6, 1, 3323, 0, 3327, 4, 3323, 6, 3325, 3325, 3328, 5, 3, 6, 2, 5, 3326, 3326, 5, 5, 3327, 3328, 4, 5, 3, 3, 4, 3323, 6, 6, 3323, 3327, 6, 3327, 0, 3328, 3, 3323, 6, 1, 3323, 3324, 4, 3327, 6, 6, 3, 4, 5, 6, 6, 3328, 3, 4, 3324, 4),
(6, 2, 1, 1, 3325, 3324, 3328, 4, 3, 3323, 3328, 3327, 2, 3325, 3323, 3328, 3326, 3323, 3326, 3324, 3325, 3323, 3324, 5, 3323, 1, 3326, 3323, 3323, 3324, 1, 1, 3326, 5, 2, 3323, 3325, 3323, 3328, 3326, 3324, 3326, 3328, 3328, 0, 3328, 3325, 5, 3327, 3323, 3325, 4, 1, 6, 6, 3323, 3323, 4, 0, 3326, 3323, 3323, 3327, 3324)),
((1, 3327, 3327, 3325, 3324, 2, 3, 3328, 3326, 2, 0, 3328, 3326, 3325, 4, 6, 0, 2, 5, 3326, 0, 3323, 3325, 3325, 3324, 5, 3323, 0, 3325, 1, 1, 3325, 3323, 6, 3327, 6, 3326, 3328, 3323, 3328, 3324, 6, 3324, 3326, 3323, 3323, 1, 3324, 3, 3325, 3327, 4, 1, 5, 6, 5, 3327, 0, 5, 3323, 5, 2, 0, 3324),
(1, 0, 3325, 4, 3325, 1, 3324, 4, 3328, 1, 4, 3324, 3324, 3323, 3, 3324, 4, 5, 0, 3328, 3323, 3324, 3326, 5, 3326, 3326, 6, 3326, 3327, 3327, 3327, 2, 3326, 3325, 0, 2, 3323, 0, 3327, 3325, 3, 3323, 3327, 0, 3327, 3323, 6, 6, 3325, 3325, 3323, 3327, 1, 3323, 3324, 3328, 3324, 3323, 5, 3327, 3326, 3, 3323, 3325)),
((2, 6, 4, 1, 6, 3328, 4, 3324, 3328, 3324, 3323, 4, 3324, 3325, 3, 4, 3328, 4, 4, 1, 3327, 3323, 3328, 3327, 3323, 0, 1, 3326, 3328, 3328, 3323, 3328, 3328, 3325, 1, 3323, 4, 3325, 3327, 5, 1, 3324, 4, 3324, 3323, 1, 3323, 3323, 1, 4, 3324, 3326, 6, 3326, 3324, 4, 3, 3327, 6, 3, 5, 3, 3, 4),
(1, 4, 3328, 3328, 1, 1, 3324, 0, 3325, 3324, 3, 3, 3324, 4, 3323, 1, 3327, 1, 3324, 4, 3323, 2, 2, 3323, 3323, 0, 3327, 3324, 3327, 3327, 4, 3324, 3323, 0, 3325, 5, 3326, 3328, 0, 3326, 3323, 3325, 3, 1, 0, 3325, 3327, 4, 3327, 3324, 3326, 3325, 3325, 3323, 3323, 3323, 3323, 5, 3327, 5, 1, 3327, 3324, 3)),
((6, 4, 6, 3324, 3327, 3, 3325, 6, 3324, 2, 6, 6, 5, 3, 3323, 3323, 1, 1, 5, 3323, 1, 3327, 3, 1, 3324, 3325, 3, 3325, 3328, 3323, 4, 3328, 3324, 4, 3324, 5, 3326, 4, 3325, 3, 6, 6, 3324, 3325, 3324, 0, 3323, 3325, 0, 4, 0, 2, 3328, 1, 3325, 1, 6, 6, 3326, 5, 3, 3328, 5, 3326),
(5, 3, 0, 2, 4, 4, 3323, 3328, 1, 2, 2, 3328, 3325, 3327, 3327, 3, 2, 3326, 1, 3327, 3326, 1, 3326, 3325, 3326, 3328, 3324, 1, 3324, 3326, 5, 2, 3323, 6, 6, 3328, 5, 3328, 3324, 3326, 3324, 3326, 3323, 3324, 3327, 4, 5, 3324, 3, 2, 3326, 3326, 3, 3324, 3325, 5, 3, 3328, 3327, 3326, 3325, 6, 3328, 0)),
((0, 6, 3, 3326, 3, 2, 2, 3327, 4, 3328, 2, 3, 3, 4, 3325, 3327, 3326, 5, 3323, 3327, 3325, 2, 2, 3326, 3, 3326, 3327, 3326, 0, 3326, 3323, 1, 0, 3324, 6, 3325, 0, 0, 2, 2, 6, 6, 3324, 3326, 3326, 5, 3328, 2, 3323, 3326, 5, 4, 3325, 0, 5, 3324, 0, 5, 0, 3327, 1, 2, 3324, 6),
(6, 3327, 4, 1, 5, 1, 4, 3326, 3324, 3326, 4, 3326, 2, 3326, 3325, 3326, 3327, 3323, 3326, 3327, 0, 3327, 3324, 3326, 3326, 3325, 3324, 3326, 3323, 2, 3323, 6, 2, 4, 3328, 3327, 3323, 0, 5, 3323, 3326, 3324, 4, 3324, 3328, 3328, 3328, 3325, 3328, 2, 3327, 5, 3323, 5, 5, 0, 3324, 3328, 5, 5, 6, 3327, 3324, 3325)),
((3324, 3325, 3323, 3, 3327, 4, 3328, 3325, 2, 3323, 3, 3328, 3325, 3, 3328, 2, 6, 2, 1, 3323, 3324, 6, 1, 3323, 0, 4, 3325, 3, 4, 5, 6, 3326, 5, 4, 5, 3323, 2, 3326, 5, 3323, 5, 3323, 3324, 6, 3324, 6, 6, 3, 5, 2, 6, 3328, 3327, 6, 5, 3324, 3324, 0, 3324, 3325, 0, 3323, 4, 3),
(2, 1, 3325, 2, 3327, 3323, 3326, 5, 3, 3326, 3326, 1, 3326, 6, 1, 6, 1, 3327, 4, 5, 1, 1, 3327, 1, 3324, 5, 2, 5, 3325, 3, 2, 3328, 3325, 3323, 0, 3325, 3326, 3327, 3327, 3323, 3, 3327, 3323, 4, 3327, 5, 3327, 0, 0, 2, 3, 3327, 3, 0, 6, 3, 5, 3, 3323, 5, 3, 1, 5, 3323)),
((3325, 3325, 3323, 3328, 3328, 5, 4, 3326, 3327, 6, 3323, 0, 6, 4, 3326, 3324, 3, 2, 6, 3323, 2, 3328, 1, 6, 6, 3327, 3, 6, 3, 3, 6, 4, 3324, 3, 4, 5, 1, 2, 3323, 3326, 3325, 0, 3326, 3324, 1, 3, 3324, 1, 0, 3327, 2, 4, 3323, 1, 3, 6, 2, 6, 3325, 3324, 3325, 5, 3325, 3325),
(6, 5, 2, 3327, 3326, 3323, 3327, 3323, 6, 3, 3328, 3328, 3327, 6, 3323, 0, 6, 2, 3327, 3324, 6, 5, 5, 3325, 6, 4, 3323, 4, 3327, 3325, 3323, 3323, 3326, 3328, 3323, 3328, 0, 3327, 2, 3323, 2, 3326, 0, 3328, 3328, 5, 2, 5, 3324, 3325, 3328, 0, 3, 5, 3326, 3326, 3328, 1, 3, 3327, 6, 5, 3327, 0)),
((3326, 2, 0, 6, 3323, 6, 0, 3328, 0, 5, 3325, 6, 3326, 3324, 3323, 3328, 5, 4, 6, 3323, 5, 3323, 3326, 3323, 1, 0, 3327, 2, 3324, 3328, 2, 5, 3327, 3, 3, 3324, 3325, 3328, 4, 3, 3324, 0, 3324, 4, 0, 1, 3324, 6, 3326, 3324, 3326, 3326, 3326, 4, 5, 3328, 3327, 0, 3324, 5, 4, 2, 5, 2),
(3327, 3, 2, 4, 3, 4, 5, 6, 3324, 4, 3324, 1, 2, 3, 3326, 3324, 1, 3323, 3323, 3323, 3326, 3323, 3326, 3323, 3328, 3327, 3328, 3323, 3326, 3326, 5, 3327, 3324, 6, 5, 2, 0, 3325, 0, 3, 5, 1, 0, 0, 3326, 3327, 1, 3326, 3323, 3327, 3325, 3328, 0, 3328, 6, 3327, 5, 3325, 3323, 5, 3323, 3327, 3327, 3324)),
((3326, 3324, 5, 0, 1, 3326, 3326, 6, 3, 4, 3327, 5, 3326, 5, 5, 5, 3327, 3, 3, 3326, 3328, 3327, 2, 3327, 5, 2, 3, 3324, 0, 6, 3323, 3328, 2, 5, 3327, 6, 3324, 6, 3326, 3327, 3324, 2, 3, 3, 3323, 3324, 2, 3328, 3323, 5, 0, 6, 1, 0, 3323, 3326, 1, 4, 3323, 6, 3, 3328, 3324, 5),
(4, 3328, 6, 3327, 3323, 0, 3, 3326, 3325, 2, 5, 6, 2, 0, 3325, 3, 3327, 1, 6, 5, 2, 0, 3328, 4, 6, 3328, 3327, 6, 3, 6, 3327, 3327, 3323, 1, 3325, 3323, 3323, 6, 3324, 0, 3323, 3323, 3324, 5, 3328, 6, 3, 5, 6, 3324, 3, 2, 5, 3327, 3, 3, 1, 1, 6, 3, 3, 3324, 3326, 2)),
((3324, 3324, 3324, 0, 2, 3323, 3326, 3327, 3, 1, 3324, 3326, 3325, 3324, 5, 5, 1, 3326, 3, 5, 2, 5, 3, 6, 3327, 1, 3325, 5, 3, 1, 6, 0, 3323, 2, 2, 3326, 5, 3, 6, 5, 4, 3324, 4, 3324, 4, 3325, 3, 3, 4, 0, 6, 4, 3325, 0, 2, 3323, 3327, 3328, 3328, 3326, 5, 2, 2, 3324),
(3324, 6, 0, 1, 1, 1, 5, 2, 0, 3326, 3323, 3326, 5, 1, 3324, 3326, 5, 5, 1, 3327, 2, 3326, 5, 6, 1, 1, 6, 5, 3325, 5, 6, 3323, 3325, 3328, 3323, 3323, 0, 3324, 3326, 3326, 3323, 4, 0, 3324, 6, 3325, 2, 1, 4, 3327, 3324, 3325, 0, 3328, 6, 3325, 4, 6, 3323, 3327, 1, 3323, 4, 4)),
((3327, 3325, 1, 5, 1, 6, 4, 5, 6, 4, 6, 4, 6, 3324, 6, 3324, 3327, 3326, 1, 3, 3325, 1, 2, 3328, 3325, 6, 3327, 4, 6, 1, 3325, 1, 3326, 3328, 3323, 3323, 5, 0, 2, 3323, 3328, 3326, 1, 1, 5, 3326, 6, 1, 3325, 3324, 2, 0, 3324, 3327, 3324, 3326, 3323, 2, 3327, 1, 5, 3327, 5, 5),
(3324, 4, 5, 1, 3325, 4, 5, 6, 3326, 2, 6, 1, 6, 1, 2, 0, 4, 3325, 1, 4, 0, 3327, 5, 1, 0, 2, 3324, 6, 3324, 3, 3324, 3324, 3, 2, 2, 5, 6, 1, 3326, 1, 5, 1, 5, 3325, 4, 3327, 3324, 3325, 3327, 0, 3, 6, 3327, 3, 5, 3323, 3323, 1, 3324, 3327, 3, 3323, 3323, 3326)),
((1, 6, 3, 6, 3328, 6, 3, 3326, 0, 3324, 5, 3327, 6, 6, 6, 2, 5, 3323, 3326, 5, 5, 2, 3324, 3323, 2, 3324, 5, 4, 5, 5, 2, 3327, 3327, 3327, 3, 3327, 5, 6, 3327, 3325, 3326, 6, 1, 4, 3326, 6, 3326, 2, 6, 1, 4, 5, 3323, 1, 3328, 3323, 3325, 5, 3328, 3324, 3323, 4, 3323, 3324),
(4, 3325, 3328, 6, 3, 5, 1, 3324, 6, 5, 0, 2, 3326, 0, 3325, 3326, 6, 3324, 0, 3325, 3328, 3327, 3325, 4, 3324, 3328, 3325, 2, 3, 3326, 1, 0, 3325, 6, 3327, 5, 3323, 3, 1, 5, 3, 6, 2, 6, 4, 0, 6, 3, 3326, 3325, 3328, 0, 3324, 5, 3327, 3325, 3327, 5, 3326, 3323, 3324, 1, 3326, 2)),
((6, 5, 3327, 5, 6, 3, 6, 6, 0, 3327, 6, 5, 3, 6, 4, 3323, 2, 3325, 3326, 3325, 1, 4, 3326, 3323, 4, 6, 3323, 2, 3328, 6, 3323, 0, 1, 6, 3327, 1, 3326, 3327, 5, 3323, 3324, 3326, 4, 3326, 1, 3323, 4, 3324, 6, 6, 2, 3325, 3328, 3327, 6, 3325, 2, 3325, 3324, 3, 5, 3327, 4, 3328),
(2, 5, 5, 5, 3324, 3328, 3328, 3328, 3328, 3327, 2, 3325, 1, 0, 3327, 3324, 3327, 3325, 6, 3327, 3327, 3328, 3323, 2, 3324, 4, 0, 3325, 3326, 6, 3328, 6, 3323, 4, 2, 5, 3327, 2, 4, 4, 0, 2, 3326, 3, 3328, 6, 6, 4, 5, 1, 3323, 3323, 3327, 3324, 6, 1, 3323, 5, 3325, 1, 1, 3323, 3326, 3328)),
((1, 6, 3328, 1, 0, 3328, 3324, 3323, 0, 6, 4, 3323, 6, 3327, 6, 3325, 3323, 5, 0, 3325, 3327, 4, 4, 0, 3323, 3324, 3328, 3327, 2, 3324, 3327, 3325, 0, 3328, 5, 3324, 6, 3324, 3327, 5, 3324, 3326, 3326, 6, 3326, 3, 3327, 3326, 5, 2, 0, 3327, 3323, 2, 3323, 3324, 3326, 3325, 3326, 2, 3, 3323, 3325, 4),
(3326, 6, 6, 3, 1, 0, 6, 1, 4, 3327, 0, 3325, 6, 5, 3, 3323, 3324, 3323, 3323, 1, 3324, 3323, 5, 3326, 4, 3325, 3324, 3325, 1, 3, 6, 3325, 2, 4, 3325, 3324, 3327, 3327, 3327, 3, 5, 3324, 3325, 3326, 2, 5, 4, 6, 3325, 5, 3327, 6, 3323, 3326, 3, 5, 3325, 3325, 3327, 0, 3328, 2, 3323, 3)),
((2, 4, 3, 5, 3327, 3326, 1, 3323, 3325, 3327, 3, 3325, 3323, 3323, 3327, 3328, 3327, 6, 3326, 6, 3327, 1, 3327, 3325, 3, 3328, 6, 3327, 4, 6, 6, 3323, 3327, 0, 6, 6, 1, 3323, 6, 5, 4, 5, 4, 2, 3326, 5, 3327, 4, 3323, 3324, 4, 3326, 3328, 3323, 3326, 3328, 3326, 4, 4, 3, 3324, 3324, 5, 4),
(0, 3325, 3324, 3325, 3324, 3327, 1, 3325, 3327, 3325, 1, 3326, 3325, 6, 5, 0, 3324, 3, 3325, 3326, 0, 3328, 1, 4, 5, 0, 6, 5, 5, 2, 5, 6, 6, 0, 2, 3323, 3325, 3323, 3324, 3324, 3327, 3325, 5, 3324, 3326, 3328, 3328, 3323, 3324, 5, 1, 2, 4, 6, 4, 1, 5, 4, 3327, 6, 3323, 0, 3325, 4)),
((6, 3323, 4, 0, 6, 3323, 3323, 3323, 5, 3324, 3327, 3325, 2, 3323, 3324, 3327, 3326, 3326, 3, 3326, 0, 4, 6, 3327, 3324, 2, 3, 3327, 3324, 5, 3327, 0, 3323, 6, 3326, 4, 3324, 4, 3325, 5, 2, 6, 3323, 3323, 0, 3324, 6, 3323, 4, 3324, 5, 3324, 3323, 3323, 3327, 0, 3, 3326, 4, 5, 6, 3323, 0, 5),
(3323, 3324, 3328, 3328, 3328, 0, 1, 0, 3327, 3323, 1, 1, 3326, 2, 0, 1, 3323, 2, 3324, 1, 3, 1, 5, 1, 3328, 4, 3325, 2, 3, 3328, 5, 5, 3327, 0, 0, 2, 3328, 3326, 0, 1, 3325, 3325, 3324, 3324, 3323, 3325, 1, 3, 3325, 3324, 3328, 3326, 3327, 0, 4, 1, 3327, 6, 3326, 3328, 3, 3327, 5, 6)),
((3325, 1, 5, 0, 0, 3323, 3328, 3323, 3323, 3326, 3327, 3324, 3324, 2, 0, 3324, 3324, 3323, 0, 1, 2, 5, 4, 6, 3, 3326, 1, 3327, 6, 3323, 2, 3328, 3328, 3324, 6, 1, 3328, 6, 6, 3325, 3326, 4, 3324, 3328, 2, 1, 3323, 5, 3326, 6, 3326, 5, 3326, 6, 3, 5, 3323, 3327, 6, 2, 1, 0, 3, 3324),
(4, 3323, 3324, 6, 3, 3324, 3324, 3324, 1, 3327, 3326, 3323, 5, 0, 3323, 3328, 3328, 3326, 2, 1, 3328, 3, 3327, 3327, 3323, 1, 4, 3327, 6, 3327, 3, 6, 4, 3325, 3327, 3323, 2, 3325, 1, 3323, 3324, 3324, 1, 3327, 3327, 3327, 3327, 3325, 3325, 3324, 3327, 2, 5, 3328, 4, 6, 3328, 0, 0, 6, 3327, 0, 0, 6)),
((3, 3328, 2, 4, 1, 3326, 0, 3327, 3327, 3326, 3, 6, 3324, 0, 3324, 3327, 5, 3323, 3327, 3325, 0, 3325, 6, 6, 5, 3328, 3327, 4, 5, 2, 4, 3328, 3326, 3326, 3327, 3325, 3327, 5, 3, 6, 0, 2, 4, 3323, 6, 6, 5, 3325, 5, 3328, 3326, 3328, 6, 3324, 2, 1, 4, 2, 1, 5, 3326, 5, 0, 3328),
(3328, 1, 3326, 6, 3323, 3327, 3324, 3325, 2, 3, 0, 3324, 2, 3328, 3326, 0, 3328, 3328, 2, 0, 5, 6, 0, 2, 6, 0, 4, 6, 6, 3, 4, 1, 0, 3323, 2, 3325, 3325, 3323, 5, 2, 3325, 3324, 5, 3324, 4, 3325, 6, 3327, 1, 0, 3323, 3, 3326, 6, 6, 6, 3327, 6, 4, 3, 2, 3327, 2, 1)),
((2, 0, 3323, 3, 5, 3325, 3324, 3327, 1, 3328, 3325, 0, 3326, 3, 3323, 0, 3327, 3325, 0, 3326, 3325, 3, 3323, 4, 3, 5, 3327, 1, 4, 3328, 4, 3327, 4, 2, 0, 3327, 2, 1, 4, 3323, 6, 3326, 1, 6, 3326, 3, 6, 3327, 3323, 6, 3324, 3324, 1, 5, 3323, 3327, 3328, 1, 3325, 5, 5, 6, 1, 0),
(2, 5, 3323, 3328, 2, 3325, 3323, 3327, 6, 3326, 3325, 4, 3326, 2, 1, 3324, 3323, 3327, 3324, 3324, 3324, 3325, 6, 4, 2, 4, 4, 0, 5, 0, 4, 2, 3323, 4, 3323, 3324, 4, 3, 3328, 3326, 0, 3323, 3325, 3325, 3, 3326, 3327, 3, 6, 3328, 3325, 3327, 3323, 1, 3328, 1, 6, 5, 2, 3326, 0, 2, 3323, 3)),
((3323, 5, 3323, 4, 3323, 3328, 1, 3, 3326, 6, 1, 3326, 3327, 3328, 5, 4, 3328, 3, 3327, 3323, 2, 3326, 3323, 3327, 3326, 3326, 1, 6, 3, 3323, 3324, 3326, 6, 3324, 3324, 3328, 0, 3325, 3325, 0, 2, 3323, 4, 3324, 2, 6, 3325, 3328, 0, 2, 3323, 4, 3324, 2, 3328, 6, 6, 3328, 3327, 3, 3327, 3325, 3328, 3323),
(4, 5, 0, 4, 3, 3327, 3324, 2, 5, 1, 2, 0, 3324, 5, 1, 2, 0, 3, 4, 3326, 3325, 6, 3323, 3, 4, 6, 3327, 5, 6, 3324, 3328, 3323, 3326, 2, 6, 1, 1, 3, 4, 6, 3324, 2, 5, 4, 3325, 6, 2, 3325, 3325, 0, 3, 6, 2, 5, 2, 3325, 0, 3, 3325, 3326, 3326, 3324, 6, 1)),
((3323, 4, 3327, 2, 3326, 5, 3327, 2, 3324, 3328, 0, 2, 4, 5, 3324, 3, 3327, 3327, 6, 0, 4, 3325, 5, 3, 3325, 4, 5, 1, 3323, 3323, 1, 6, 3324, 3328, 6, 6, 1, 3323, 3328, 3324, 0, 5, 6, 3325, 6, 5, 3325, 6, 3328, 5, 3325, 3, 3326, 2, 2, 3328, 3325, 3324, 5, 1, 3328, 0, 4, 3325),
(3324, 2, 3323, 2, 3323, 3328, 3328, 2, 3328, 3326, 6, 3328, 3325, 3323, 3323, 3325, 5, 2, 0, 3326, 3326, 3325, 3327, 5, 1, 4, 3324, 1, 3, 5, 3323, 4, 3325, 5, 3323, 0, 3326, 3325, 3, 4, 3324, 3325, 3325, 3323, 5, 3325, 3323, 3323, 3, 3323, 3324, 2, 3325, 3325, 3328, 3327, 3327, 4, 3, 2, 1, 1, 3, 6)),
((3323, 1, 3, 3327, 6, 3323, 1, 3326, 3325, 3328, 3325, 2, 3323, 3325, 3327, 0, 2, 3323, 3327, 3326, 3328, 5, 0, 3326, 6, 5, 5, 6, 5, 3325, 3325, 3324, 1, 3323, 3323, 3, 1, 3324, 3323, 1, 5, 5, 3, 3328, 2, 5, 5, 3324, 2, 6, 4, 0, 4, 3, 2, 3, 0, 1, 5, 5, 6, 3327, 3326, 2),
(3326, 3324, 3328, 3325, 3, 3, 3326, 0, 4, 3328, 3325, 3323, 0, 0, 0, 3323, 3326, 3327, 3323, 3328, 6, 3325, 3324, 0, 3, 3327, 2, 6, 0, 6, 5, 3325, 6, 1, 3326, 3324, 4, 0, 3323, 3324, 3, 1, 3324, 3323, 3323, 3, 3324, 3324, 3327, 1, 3328, 3, 3325, 5, 3323, 4, 6, 0, 6, 6, 3326, 3324, 3, 1)),
((3328, 0, 3326, 5, 3326, 3, 4, 5, 3327, 0, 5, 3324, 3326, 3325, 3323, 0, 3326, 3328, 3328, 3328, 3326, 3326, 3326, 5, 3323, 6, 3326, 2, 5, 6, 3323, 0, 2, 2, 3327, 3328, 4, 3328, 0, 3325, 6, 3327, 3328, 1, 3328, 3328, 3, 5, 4, 3, 6, 6, 3325, 3324, 3323, 3, 3325, 3328, 3323, 3325, 4, 6, 3325, 6),
(3326, 3324, 3326, 0, 3323, 3328, 4, 3325, 3, 2, 3326, 3326, 3325, 3327, 3325, 5, 3324, 3326, 2, 3323, 1, 3326, 3325, 3323, 3, 5, 3323, 1, 1, 5, 3328, 4, 0, 3325, 3324, 0, 3328, 3327, 3325, 3327, 3323, 5, 6, 3326, 3, 3323, 6, 3324, 3327, 3328, 5, 3324, 2, 2, 3325, 3, 3327, 1, 1, 3323, 0, 2, 0, 3326)),
((4, 3323, 3324, 0, 3327, 3326, 5, 3325, 6, 3327, 3328, 3323, 4, 6, 3327, 3325, 3324, 3328, 3328, 3323, 3324, 3328, 3, 3, 3328, 3, 3, 6, 3326, 6, 3327, 3324, 1, 3327, 3327, 3324, 3325, 1, 3328, 2, 3328, 3328, 3328, 1, 5, 4, 3326, 6, 6, 3323, 5, 3325, 6, 4, 6, 3323, 3323, 3326, 5, 3326, 5, 6, 3323, 3326),
(3323, 1, 3323, 4, 3327, 3324, 2, 3323, 3323, 3326, 3328, 3324, 3324, 3328, 3324, 1, 1, 3327, 3325, 3327, 3327, 3326, 3327, 6, 3328, 3323, 0, 3324, 1, 5, 3, 6, 3326, 2, 3327, 3324, 3323, 3325, 3324, 3324, 3327, 6, 5, 3325, 3324, 3325, 3323, 3325, 6, 3, 3325, 3327, 3326, 3328, 3, 3, 3324, 3327, 5, 3327, 3327, 1, 3, 0)),
((3326, 3326, 5, 3, 5, 3325, 2, 2, 2, 3325, 3, 3328, 1, 0, 6, 3, 0, 5, 4, 0, 4, 1, 6, 3328, 4, 1, 4, 3327, 5, 3325, 3325, 3323, 3325, 5, 3, 6, 5, 3328, 2, 2, 5, 1, 0, 3, 3, 3328, 3325, 6, 3323, 3325, 4, 0, 3328, 3326, 2, 5, 6, 3328, 5, 0, 6, 2, 3328, 4),
(2, 2, 4, 3327, 5, 5, 3325, 2, 3, 1, 4, 3325, 2, 3, 6, 3327, 0, 2, 3327, 6, 4, 6, 1, 6, 2, 4, 5, 4, 3327, 3323, 3328, 0, 3326, 5, 3324, 3, 6, 4, 4, 3328, 3327, 3, 1, 2, 3, 3328, 0, 3328, 4, 3323, 2, 0, 3324, 3324, 2, 4, 2, 4, 0, 2, 3328, 2, 3327, 4)),
((3325, 3325, 3327, 3323, 0, 2, 3323, 0, 3327, 6, 3323, 4, 4, 3, 6, 2, 5, 6, 6, 3323, 0, 2, 3323, 3328, 3323, 0, 4, 0, 3324, 5, 3328, 3328, 0, 3327, 6, 0, 4, 6, 3323, 3328, 3328, 3, 3328, 6, 3328, 3323, 3323, 1, 4, 3324, 4, 0, 3323, 3, 3326, 6, 3327, 4, 3327, 4, 3325, 2, 4, 3323),
(2, 3323, 4, 3, 3325, 1, 4, 1, 5, 1, 0, 2, 5, 2, 6, 6, 3323, 2, 3327, 3328, 1, 3328, 6, 2, 5, 6, 3326, 3326, 3324, 3324, 2, 3324, 1, 2, 4, 3327, 3323, 0, 4, 6, 0, 6, 1, 6, 5, 3325, 5, 4, 3327, 3326, 5, 1, 3326, 4, 6, 3, 6, 6, 6, 6, 3323, 1, 3324, 3327)),
((3323, 3323, 3, 6, 3324, 3324, 3323, 3323, 3325, 3, 3, 3326, 3327, 3325, 2, 3328, 3327, 3, 3323, 3327, 3328, 6, 3326, 3323, 3324, 3, 3328, 0, 3323, 6, 3326, 3, 0, 3324, 5, 3327, 3324, 3327, 3327, 6, 3, 3326, 3323, 4, 3, 3324, 5, 6, 6, 3325, 1, 5, 3324, 5, 5, 1, 3323, 3327, 4, 3, 3327, 5, 3323, 3324),
(2, 4, 3326, 3323, 5, 3323, 3323, 3327, 3328, 3326, 3327, 0, 4, 1, 3, 3323, 2, 3324, 3325, 3325, 3324, 6, 1, 1, 1, 3325, 3323, 3325, 0, 0, 3323, 3325, 3323, 3325, 3324, 3324, 3325, 2, 3325, 3326, 1, 3324, 3323, 3324, 6, 3328, 3327, 4, 3326, 1, 5, 3325, 3324, 4, 5, 1, 3324, 3326, 3327, 3325, 3327, 3325, 5, 2)),
((3323, 5, 4, 3323, 3326, 3328, 3328, 3, 3323, 5, 3325, 2, 3327, 6, 1, 6, 3, 3325, 6, 3, 3327, 2, 4, 1, 4, 3325, 4, 2, 3327, 3324, 3323, 2, 3324, 3328, 3, 3325, 3324, 2, 1, 6, 2, 1, 3325, 3327, 5, 5, 0, 1, 3323, 3328, 3, 3328, 3323, 3, 3323, 3325, 3327, 4, 5, 4, 3323, 3327, 3, 2),
(3, 5, 2, 3323, 5, 4, 2, 3323, 3327, 6, 6, 3326, 6, 3328, 3, 3328, 4, 5, 1, 3328, 0, 4, 0, 3, 3325, 3325, 3328, 3, 6, 3, 3323, 3323, 3325, 5, 1, 4, 3326, 3325, 2, 0, 6, 4, 5, 4, 5, 2, 3323, 3327, 5, 0, 5, 3327, 0, 4, 5, 3325, 3328, 2, 3, 4, 3326, 6, 3327, 5)),
((6, 3327, 3327, 3326, 1, 0, 3328, 0, 3323, 3328, 4, 5, 3326, 3326, 3328, 3324, 3325, 6, 2, 3324, 3325, 6, 5, 3324, 6, 3323, 3327, 3323, 3325, 3328, 3327, 1, 0, 3328, 3325, 3323, 2, 3327, 3323, 2, 3326, 2, 5, 3323, 3323, 3324, 3325, 3323, 3, 5, 5, 3326, 2, 6, 3326, 3326, 1, 4, 3328, 6, 3324, 2, 3, 5),
(3, 3325, 4, 3324, 3324, 3323, 1, 3328, 3323, 3326, 3326, 2, 5, 5, 3326, 3328, 3326, 0, 3327, 3326, 3327, 3323, 4, 0, 3325, 3324, 2, 2, 3328, 3323, 3326, 6, 2, 1, 3327, 3326, 3324, 3328, 3325, 3326, 3327, 2, 1, 3325, 3324, 2, 3323, 2, 3323, 3324, 3326, 6, 3323, 0, 5, 3325, 3326, 3, 3327, 3327, 3328, 3324, 3324, 6)),
((3, 6, 3325, 3324, 3326, 0, 0, 3326, 3, 3, 4, 3324, 5, 3327, 3, 3, 0, 3324, 3326, 4, 1, 5, 3323, 2, 1, 3323, 3324, 3328, 3326, 2, 3328, 3, 3325, 3, 4, 3323, 3325, 3328, 3327, 3323, 3325, 3323, 3325, 5, 6, 3324, 4, 6, 0, 5, 3326, 2, 2, 6, 3, 3326, 6, 6, 3327, 6, 0, 3325, 5, 3325),
(3323, 2, 3323, 6, 3325, 3328, 2, 3326, 0, 3323, 4, 3324, 3323, 3325, 3323, 3327, 3325, 3323, 3326, 3327, 4, 3324, 3, 3328, 3326, 1, 3326, 3327, 3, 1, 0, 3327, 0, 3326, 3328, 3326, 3327, 3326, 3323, 3323, 6, 3323, 3323, 5, 6, 3324, 3323, 3324, 3324, 3327, 3, 3325, 3324, 5, 4, 3324, 3327, 3324, 3324, 4, 3328, 3328, 3327, 3327))]
def send_vec(v):
v = [(c if c < q // 2 else c - q) for c in v]
p.sendline(str(v)[1:-1].encode())
for _ in range(5):
c = int(p.recvline_startswith(b'challenge').split()[1].decode())
r, e1 = D[c.bit_length() - 1]
send_vec(r)
send_vec(e1)
p.recvline()
flag = p.recvline(False)
print(flag)
print(hashlib.sha256(flag).hexdigest())