We have two methods to handle this challenge.
1、This crypto algorithm processes 12 bits at one time with ECB mode. And the length of the ciphertext is just 6 bytes. It's feasible to brute-force 24 bits or 3 bytes at one time.
2、Following the designing art of DES, we can build up the decryption algorihm by reversing the subkey order and exchanging the left and right part of the input and the output of the fiestel network.
Following is the code,```def S1box(S1):    box = [[0b101, 0b010, 0b001, 0b110, 0b011, 0b100, 0b111, 0b000],             [0b001, 0b100, 0b110, 0b010, 0b000, 0b111, 0b101, 0b011]]    return box[(S1>>3) & 0x1][S1 & 0x7]
def S2box(S2):    box = [[0b100, 0b000, 0b110, 0b101, 0b111, 0b001, 0b011, 0b010],             [0b101, 0b011, 0b000, 0b111, 0b110, 0b010, 0b001, 0b100]]    return box[(S2>>3) & 0x1][S2 & 0x7]
def getsubkey(key, index, n):    result = 0    for i in range(8):        tmp = (((key >> ((n - 1 - (index + i)) % n) & 1) << (7 - i)))        result = result | tmp    return result def encrypt(s, key, offset):    #1, Choose a plaintext that is divisible into 12bit 'blocks'    plain = s
    #2, Choose a key at least 8bits in length
    #3, For each block from i=0 while i<N perform the following operations    # Currently no padding    N = len(plain) * 8 / 12    R = 2    result = 0    pint = int(plain.encode('hex'), 16)    for i in range(N):    #4, Repeat the following operations on block i, from r=0 while r<R        p = (pint >> (12 * (N - 1 - i))) & 0xfff        Lr = (p >> 6) & 0x3f        Rr = p & 0x3f        for r in range(R):            tmp = ((Rr << 2) & 0xc0) | (Rr & 0x3) | ((Rr & 0x8) << 1) | ((Rr & 0x8) >> 1) | ((Rr & 0x4) << 1) | ((Rr & 0x4) << 3)            subkey = getsubkey(int(key.encode('hex'),16), (i + offset) * R + r, len(key) * 8)            tmp = tmp ^ subkey            S1 = (tmp >> 4) & 0xf            S2 = tmp & 0xf            tmp = (S1box(S1) << 3) | S2box(S2)            tmp = tmp ^ Lr            Lr = Rr            Rr = tmp        result = (result << 12) | ((Lr << 6) | Rr)    return getstr(result)
def decrypt(s, key):    plain = s    N = len(plain) * 8 / 12    R = 2    result = 0    pint = int(plain.encode('hex'), 16)    for i in range(N):        p = (pint >> (12 * (N - 1 - i))) & 0xfff        Rr = (p >> 6) & 0x3f # exchange the left and right part        Lr = p & 0x3f        for r in range(R - 1, -1, -1): # reverse subkey order            tmp = ((Rr << 2) & 0xc0) | (Rr & 0x3) | ((Rr & 0x8) << 1) | ((Rr & 0x8) >> 1) | ((Rr & 0x4) << 1) | ((Rr & 0x4) << 3)            subkey = getsubkey(int(key.encode('hex'),16), i * R + r, len(key) * 8)            tmp = tmp ^ subkey            S1 = (tmp >> 4) & 0xf            S2 = tmp & 0xf            tmp = (S1box(S1) << 3) | S2box(S2)            tmp = tmp ^ Lr            Lr = Rr            Rr = tmp        result = (result << 12) | ((Rr << 6) | Lr) # exchange the left and right part    return getstr(result)
def getstr(intnum):    intstr = hex(intnum).lstrip('0x').rstrip('L')    if len(intstr) % 2 == 1:        intstr = '0' + intstr    intstr = intstr.decode('hex')    return intstr
enc = 0b011001010010001010001100010110000001000110000101encstr = getstr(enc)
import string, itertools, time
# method 1, brute forceflag = ''time1 = time.time()for i in range(2):    for item in itertools.product(string.printable, repeat=3):        if encrypt(''.join(item), 'Mu', i * 2) == getstr((enc >> (1 - i) * 24) & 0xffffff):            flag += ''.join(item)            breaktime2 = time.time()print 'method 1: flag is Gigem{' + flag + '}, passed time:', time2 - time1
# method 2, decrypttime1 = time.time()flag = decrypt(encstr, 'Mu')time2 = time.time()print 'method 2: flag is Gigem{' + flag + '}, passed time:', time2 - time1
```
Output , ```C:\>python solver.pymethod 1: flag is Gigem{MiN0n!}, passed time: 25.5679998398method 2: flag is Gigem{MiN0n!}, passed time: 0.00100016593933```