picoCTF 2021 Crypto (4) New Caesar

New Caesar
| 60 points
Tags:
AUTHOR: MADSTACKS

Description
We found a brand new type of encryption, can you break the secret code? (Wrap with picoCTF{}) lkmjkemjmkiekeijiiigljlhilihliikiliginliljimiklligljiflhiniiiniiihlhilimlhijil new_caesar.py

new_caesar.py

import string

LOWERCASE_OFFSET = ord("a")
ALPHABET = string.ascii_lowercase[:16]

def b16_encode(plain):
	enc = ""
	for c in plain:
		binary = "{0:08b}".format(ord(c))
		enc += ALPHABET[int(binary[:4], 2)]
		enc += ALPHABET[int(binary[4:], 2)]
	return enc

def shift(c, k):
	t1 = ord(c) - LOWERCASE_OFFSET
	t2 = ord(k) - LOWERCASE_OFFSET
	return ALPHABET[(t1 + t2) % len(ALPHABET)]

flag = "redacted"
key = "redacted"
assert all([k in ALPHABET for k in key])
assert len(key) == 1

b16 = b16_encode(flag)
enc = ""
for i, c in enumerate(b16):
	enc += shift(c, key[i % len(key)])
print(enc)

平文にb16_encodeした後、keyでシフトしている。
b16_encodeは、平文の文字コードを4ビットごとに分けて、それぞれを英小文字の[a-p]に割り当てているみたい。
keyは、assert文から、[a-p]のいずれか。
なので、keyを総当たりでデコードしてみる。

import string

LOWERCASE_OFFSET = ord("a")
ALPHABET = string.ascii_lowercase[:16]

def deshift(c, k):
	t1 = ord(c) - LOWERCASE_OFFSET
	t2 = ord(k) - LOWERCASE_OFFSET
	return ALPHABET[(t1 - t2) % len(ALPHABET)]

def b16_decode(enc):

    ### b16_encode
    # def b16_encode(plain):
	# enc = ""
	# for c in plain:
	# 	binary = "{0:08b}".format(ord(c))
	# 	enc += ALPHABET[int(binary[:4], 2)]
	# 	enc += ALPHABET[int(binary[4:], 2)]
	# return enc

    plain = ""
    for i, c in enumerate(enc):
        if i % 2 == 0:
            upper_byte = ord(c) - LOWERCASE_OFFSET
        else:
            lower_byte = ord(c) - LOWERCASE_OFFSET
            plain += chr(upper_byte * 16 + lower_byte)

    return plain

c = "lkmjkemjmkiekeijiiigljlhilihliikiliginliljimiklligljiflhiniiiniiihlhilimlhijil "

for k in ALPHABET:
    _c = ""
    for _ in c:
        _c += deshift(_, k)
    #print(_c)
    plain = b16_decode(_c)
    print("key '{}': {}".format(k, plain))
# python3 exploit.py 
key 'a': ºÉ¤ÉÊ
              ¤¹·¸¸¹»¹
···
key 'b': ©¸¸¹sxwu¨¦zv§yzu|§¨{yªu¨t¦|w|wv¦z{¦xz
key 'c': §¨bgfdiehidkjhdckfkfeijgi
key 'd': qQqVUS
               XT
WXSZ
YWSR
    ZUZUT
         XY
           VX
key 'e': v
`
@`EDBusGCtFGBItuHFwBuAsIDIDCsGHsEG
key 'f': et_tu?_431db62c5618cd75f1d0b83832b67b46
key 'g': TcNcd.N#" SQ%!R$% 'RS&$U S/Q'"'"!Q%&Q#%
key 'h': CR=RS=B@AABDB@@@
key 'i': 2A,AB
???           ,1?00131
key 'j': !01ûÿý .òþ/ñòýô/ óñ"ý ü.ôÿôÿþ.òó.ðò
key 'k': /
/ ê
ïîìáíàáìãâàìëãîãîíáâïá
key 'l': ùÙùÞÝÛ
ÑßÛÚ           ÐÜ
    ÒÝÒÝÜ
         ÐÑ
           ÞÐ
ÈèÍÌÊýûÏËüÎÏÊÁüýÀÎÿÊýÉûÁÌÁÌËûÏÀûÍÏ
key 'n': íü×üý·×¼»¹ì꾺뽾¹°ë쿽î¹ì¸ê°»°»ºê¾¿ê¼¾
key 'o': ÜëÆëì¦Æ«ª¨ÛÙ­©Ú¬­¨¯ÚÛ®¬Ý¨Û§Ù¯ª¯ª©Ù­®Ù«­
key 'p': ËÚµÚÛµÊÈÊÊÈ

よくわからないが、

key 'f': et_tu?_431db62c5618cd75f1d0b83832b67b46

自然言語っぽい("et tu?"の部分がフランス語)ので、これを入れてみると通った。