Simon and Speck Block Ciphers¶
These are a pair of sister lightweight block ciphers.
Simon Block Cipher¶
Basic Introduction¶
The Simon block cipher algorithm was published by the NSA in June 2013 and is primarily optimized for hardware implementation.
Simon Block Cipher is a balanced Feistel cipher. It has two blocks; if each block size is n bits, then the plaintext size is 2n bits. In general, the key length used in this cipher is an integer multiple of the block size, such as 2n, 4n, etc. Common Simon cipher configurations are:

Generally, the Simon algorithm is referred to as Simon 2n/nm, where n is the block size and m is the ratio between the key size and the block size. For example, Simon 48/96 refers to an encryption algorithm with a 48-bit plaintext and a 96-bit key.
Furthermore, for the Simon block cipher, the encryption process in each round is the same, as shown below:

Of course, for each round and different values of m, the key schedule also differs:
Here, z_j is generated by a Linear Feedback Shift Register (LFSR). Although the logic differs for different z_j, the initial vectors are fixed.
| Constant |
|---|
| z_{0}=11111010001001010110000111001101111101000100101011000011100110 |
| z_{1}=10001110111110010011000010110101000111011111001001100001011010 |
| z_{2}=10101111011100000011010010011000101000010001111110010110110011 |
| z_{3}=11011011101011000110010111100000010010001010011100110100001111 |
| z_{4}=11010001111001101011011000100000010111000011001010010011101111 |
2017 SECCON Simon and Speck Block Ciphers¶
The challenge description is as follows:
Simon and Speck Block Ciphers
https://eprint.iacr.org/2013/404.pdf Simon_96_64, ECB, key="SECCON{xxxx}", plain=0x6d564d37426e6e71, cipher=0xbb5d12ba422834b5
From the name we can see the key is 96 bits (12 bytes) and the plaintext is 64 bits (8 bytes). The key already has 8 bytes given, with only four bytes unknown. So we can use brute force. Here we obtained a Simon encryption implementation from https://github.com/bozhu/NSA-ciphers/blob/master/simon.py.
The specific solution is as follows:
from pwn import *
from simon import SIMON
plain = 0x6d564d37426e6e71
cipher = 0xbb5d12ba422834b5
def compare(key):
key = "SECCON{" + key + "}"
key = key.encode('hex')
key = int(key, 16)
my_simon = SIMON(64, 96, key)
test = my_simon.encrypt(plain)
if test == cipher:
return True
else:
return False
def solve():
visible = string.uppercase + string.lowercase + string.digits + string.punctuation + " "
key = pwnlib.util.iters.mbruteforce(compare, visible, 4, method="fixed")
print key
if __name__ == "__main__":
solve()
The result is as follows:
➜ 2017_seccon_simon_and_speck_block_ciphers git:(master) python exp.py
[+] MBruteforcing: Found key: "6Pz0"