Crypto - Shuffling as a Service
You'll be 'shuffed to bits after trying the Krusty Krab's new bit shuffling service™!
Last updated
You'll be 'shuffed to bits after trying the Krusty Krab's new bit shuffling service™!
Last updated
First, we see how the bits are being shuffled
First, a list perm is created with values from 1 to 1024, and is shuffled (key length is 1024)
This loop basically takes the (1024-x) th bit of the input, and places it in the location of the value of perm[x] For example, the last bit of the input will go to the perm[0] location of the shuffled integer. By knowing all the values of perm, we can then map the shuffled bits to the original bits and hence decrypt the ciphertext.
The flag is then padded so we can't rely on any known plaintext attacks
The challenge uses a server which encrypts the flag and gives us three inputs which the server encrypts and gives us the encrypted outputs.
To fully understand how the bits are being shuffled, lets take a smaller input, with only 8 bits
From this example
Since everything is kept constant, we can conclude that the last bit is shifted to the second to last bit position
However, this approach is really inefficient, so we need some other way to figure out how its being shuffled. We can make a few observations from the example First, the same input returns the same output so there's no point using the same inputs Similarly, the same substrings used at the same location in two different inputs return the same output at that location
The idea is to make the inputs as unique as possible, so that we won't have any repeating input or any part of the inputs repeating so as to gain new information everytime.
One method to do this is to take half 1 , half 0 then quarter 1 quarter 0 quarter 1 quarter 0 and keep dividing it in this manner. The purpose of this is to make sure that we have no repeating substrings in the same locations for any of our inputs For example,
But how do we get the shift pattern from these inputs?
We divide the input and outputs as column vectors of this format
Notice how all the vectors are unique from each other. This is due to the construction of the input. The reason for grouping all the column vectors is because they all shift to the same location. From this, we can now easily map the input to the output. For example, the last column vector in the input (0,0,0) is shifted once to the left in the output, and due to the all the vectors being unique, we ensure that (0,0,0) appears once only once and therefore figure out that that any bit in that position will be shifted once to the left. In other words, perm[0] = 1 (Here 1 represents the total shift amount from the right, where 0 is the number of bits to skip from the right). Similarly, we can map the rest of the vectors and we get perm value as [1,6,0,7,4,3,2,5] Also we require 3 inputs to do this. If we had 2 inputs for example, then atleast two of the vectors would have matched and we cant tell which is vector is being shifted. We require 3 inputs for 8 bits since 2^3 is 8 , which gives us all unique combinations. Similarly, for 1024 bits we require 2^10 = 1024 or 10 inputs , which is the number of trials provided by the server.
First, we have to construct the inputs with alternating 0 s and 1 s
The general formulation is
where i is from 1 to 11
We get the outputs and pad them to ensure 1024 length
We then map the output to the input and declare a variable to map the message from the encrypted flag
Finally, we reverse the bits since we considered the MSB to be the 0th bit and the LSB to be the 1023rd bit and decrypt the ciphertext