codeconnaiseur

miscbjörnctf2024jsprogramming

Discovery

We are given a programming challenge. We can only use the literals -0 and 0, the * and + operators as well as array indexing of two existing variables a and b and brackets. We need to come up with code that only uses the specified constructs and create an implementation of an 8bit adder.

Since we can only use addition and multiplication operators on 0 and 0, let’s look at what results we get with addition:

 0 +  0 =  0
-0 +  0 =  0
 0 + -0 =  0
-0 + -0 = -0

If we substitute -0 with 1, we have the truth table for the AND gate! Let’s see what multiplication gives us:

 0 *  0 =  0
 0 * -0 = -0
-0 *  0 = -0
-0 * -0 =  0

If we again substitue -0 with 1, we get the truth table for the XOR gate! A quick google search then tells us that it’s possible to build an 8 bit adder using those two gates.

Solution

Since it is impossible for us to use variables to store the results of carry flags between the bits, we need to re-use existing calculations as part of the calculation of the result for the next bit. To do this, I have created a small python script:

c_out = "0"
lines = []
for i in range(8):
    j = 7-i
    c_in = c_out
    t = f"a[{j}] * b[{j}]"
    c_out = f"(a[{j}] + b[{j}]) * ({c_in} + ({t}))"
    s = f"({t}) * ({c_in})"
    lines.append(s)
print("return [")
for l in reversed(lines):
    print("   ", l, end=",\n")
print("]")

What the script does can be better understood by looking at the diagram of a full adder (variable names match with the python code):

1 bit full adder

When we run the python script that generates our javascript code, we get the following result:

return [
    (a[0] * b[0]) * ((a[1] + b[1]) * ((a[2] + b[2]) * ((a[3] + b[3]) * ((a[4] + b[4]) * ((a[5] + b[5]) * ((a[6] + b[6]) * ((a[7] + b[7]) * (0 + (a[7] * b[7])) + (a[6] * b[6])) + (a[5] * b[5])) + (a[4] * b[4])) + (a[3] * b[3])) + (a[2] * b[2])) + (a[1] * b[1]))),
    (a[1] * b[1]) * ((a[2] + b[2]) * ((a[3] + b[3]) * ((a[4] + b[4]) * ((a[5] + b[5]) * ((a[6] + b[6]) * ((a[7] + b[7]) * (0 + (a[7] * b[7])) + (a[6] * b[6])) + (a[5] * b[5])) + (a[4] * b[4])) + (a[3] * b[3])) + (a[2] * b[2]))),
    (a[2] * b[2]) * ((a[3] + b[3]) * ((a[4] + b[4]) * ((a[5] + b[5]) * ((a[6] + b[6]) * ((a[7] + b[7]) * (0 + (a[7] * b[7])) + (a[6] * b[6])) + (a[5] * b[5])) + (a[4] * b[4])) + (a[3] * b[3]))),
    (a[3] * b[3]) * ((a[4] + b[4]) * ((a[5] + b[5]) * ((a[6] + b[6]) * ((a[7] + b[7]) * (0 + (a[7] * b[7])) + (a[6] * b[6])) + (a[5] * b[5])) + (a[4] * b[4]))),
    (a[4] * b[4]) * ((a[5] + b[5]) * ((a[6] + b[6]) * ((a[7] + b[7]) * (0 + (a[7] * b[7])) + (a[6] * b[6])) + (a[5] * b[5]))),
    (a[5] * b[5]) * ((a[6] + b[6]) * ((a[7] + b[7]) * (0 + (a[7] * b[7])) + (a[6] * b[6]))),
    (a[6] * b[6]) * ((a[7] + b[7]) * (0 + (a[7] * b[7]))),
    (a[7] * b[7]) * (0),
]

Submitting the code gets us the flag!

flagbot{I_hate_ecmascript_6.1.6.1.20_now_go_make_minecraft_in_minecraft}