7
\$\begingroup\$

I came across a question asked here and here on the Crypto Stack Exchange site, and decided to analyze it as a kind of case study. To demonstrate the concept, I wrote a short python script depicting the proposed encryption scheme. It's mostly list comprehensions or generator expressions and bitwise operations.

$$C=E_k(m)$$ $$C_\alpha = C\oplus m$$ $$C_\beta = \overline{C}$$ $$C_\Omega = C_\alpha\ ^\frown\ C_\beta$$

#!/usr/bin/env python3

from Crypto.Cipher import DES

m = b'secret!!'
k = b'qwerty!!'
E = DES.new(k, DES.MODE_ECB)
C = E.encrypt(m)

C_alpha = int('0b'+''.join([f"{x:08b}" for x in C]), 2) ^ \
          int('0b'+''.join([f"{x:08b}" for x in m]), 2)

C_beta  = int('0b'+''.join([f"{x:08b}" for x in C]), 2) ^ \
          int('0b' + '1' * len(''.join([f"{x:08b}" for x in C])), 2)

C_omega = f"{C_alpha:064b}" + f"{C_beta:064b}"

if __name__ == '__main__':
    print(C_omega)

Then I ended up with this alternative version. If you want to try it out, save it as bad_scheme.py so it can work properly with the next script:

#!/usr/bin/env python3

from Crypto.Cipher import DES

m = b'secret!!'
k = b'qwerty!!'
E = DES.new(k, DES.MODE_ECB)
C = E.encrypt(m)

def bitwise_xor(bits_a, bits_b):
    bits_out = ''.join([str(int(x)^int(y)) for x, y in zip(bits_a, bits_b)])
    return(bits_out)

def bitwise_complement(bits_in):
    bits_out = ''.join([str(~int(x)+2) for x in bits_in])
    return(bits_out)

def C_alpha():
    bits_out = bitwise_xor(''.join([f"{x:08b}" for x in C]),
                           ''.join([f"{x:08b}" for x in m]))
    return(bits_out)

def C_beta():
    bits_out = bitwise_complement(''.join([f"{x:08b}" for x in C]))
    return(bits_out)

def C_omega():
    bits_out = C_alpha() + C_beta()
    return(bits_out)

if __name__ == '__main__':
    print(C_omega())

And here's what is essentially a working exploit of the (hypothetical) proposed encryption scheme's vulnerability; demonstrating the plaintext can be revealed without the key. It imports the final ciphertext and the bitwise functions from the first script, and works backwards, and complements \$C_\beta\$ to get \$C\$ (because \$C_\beta\$ is essentially just \$\overline{C}\$), then \$C \oplus C_\alpha\$ to reveal \$m\$ without requiring \$k\$. So:

$$\overline{C_\beta}=C$$ $$C_\alpha \oplus C=m$$

#!/usr/bin/env python3

from bad_scheme import C_omega, bitwise_xor, bitwise_complement

def C_alpha():
    bits_out = C_omega()[:int(len(C_omega())/2)]
    return(bits_out)

def C_beta:
    bits_out = C_omega()[int(len(C_omega())/2):]
    return(bits_out)

def C():
    bits_out = bitwise_complement(C_beta())
    return(bits_out)

def m():
    bits_out = bitwise_xor(C_alpha(), C_beta())
    return(bits_out)

if __name__ == '__main__':
    print(''.join([chr(int(m()[i:i+8],2)) for i in range(0,len(m()),8)]))

So, there it is. Just thought I'd put it out there and see what everyone thinks, which style is better, what's good about it, what's bad about it, and what I can do to improve it. It's not a real encryption scheme or anything, I'm mainly interested in feedback regarding design and execution, the handling of bitwise operations, and the general layout and structure of the code. I tried implementing a class and a few things to make it more robust and useful, but I couldn't pull it off. Also, is it better organized as functions? Or doing the same thing in fewer lines, just defining and operating on variables, and declaring no functions at all.

\$\endgroup\$
  • 1
    \$\begingroup\$ To get LaTeX, use \$ (notice a backslash). \$\endgroup\$ – vnp May 27 at 19:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.