NRIC goes Global!
Files given:
The challenge is to predict 100 checksums in a row. The algorithm for computing a checksum is:
constants = [0] * LEN_GRIC
sbox = list('ABCDEFGHJKLMRTXYZ')
def setup():
global constants, sbox
constants = [random.randint(0, 17) for x in range(LEN_GRIC)]
random.shuffle(sbox)
def get_checksum(n): return sbox[sum(map(lambda x: int(x[0]) * int(x[1]), zip(n, constants))) % len(sbox)]
This algorithm is a rather simple linear checksum. It multiplies each digit by a random coefficient, then the final result is taken mod
The difficulty here lies in the fact we can only get 25 checksums before the server refuses to give anymore to us.
We can assign each letter a number from
We can represent each equation as a row of a matrix
sage: M.right_kernel()
Vector space of degree 27 and dimension 4 over Finite Field of size 17
Basis matrix:
[ 1 12 15 10 7 5 10 1 0 16 0 3 0 7 10 5 0 2 15 16 6 11 0 4 9 8 12]
[ 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0]
[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0]
Here we immediately see the unknown coefficients have a unique solution
Note that we can arbitrarily multiply our solutions by any number. However since the constants and letters are changed accordingly, the output will remain the same.
With this, we eventually get the flag:
Wow you did it. Congratulations! Here flag!
CTFSG{NRIC_m3meS_F0R_GRIC_7eENs}
The solution script can be found at solve.py and the script to compute the kernel can be found at ker.sage
Flag:
CTFSG{}