# picoCTF Play Nice Write Up
## Details:Points: 110
Jeopardy style CTF
Category: Cryptography
Comments: Not all ancient ciphers were so bad... The flag is not in standard format. nc mercury.picoctf.net 30568 playfair.py
## Write up:
Running the netcat command we get:
```nc mercury.picoctf.net 30568
Here is the alphabet: 0fkdwu6rp8zvsnlj3iytxmeh72ca9bg5o41qHere is the encrypted message: herfayo7oqxrz7jwxx15ie20p40u1iWhat is the plaintext message?```
Looking into the python script provided I first generated the matrix using the provided alphabet so that I had it to look at:
```python# [['0', 'f', 'k', 'd', 'w', 'u'], #  ['6', 'r', 'p', '8', 'z', 'v'], #  ['s', 'n', 'l', 'j', '3', 'i'], #  ['y', 't', 'x', 'm', 'e', 'h'], #  ['7', '2', 'c', 'a', '9', 'b'], #  ['g', '5', 'o', '4', '1', 'q']]```
I then started slowing reversing what the encryption did. From the encryption I saw that for each character one was added so the length would be the same. But that every pair relied on each other so I would need to iterate through two at a time:
```python# decrypt string functiondef decrypt_string(s, matrix):	# place to store result    result = ""     # Iterate through string two at a time	for i in range(0, len(s), 2):
        # pass the pairs to the decrypt_pair function		result += decrypt_pair(s[i:i+2], matrix)
    # return result	return result```
Next I looked at the encrypt pair function. I then looked at how the different cases were encrypted, checked for those cases and then decrypted:
```python# decrypt each pairdef decrypt_pair(pair, matrix):
    # get the indices in the matrix	p1 = get_index(pair[0], matrix)	p2 = get_index(pair[1], matrix)
    # if the first index is the same	if p1[0] == p2[0]:		return matrix[p1[0]][(p1[1]-1)%SQUARE_SIZE]+matrix[p2[0]][(p2[1]-1)%SQUARE_SIZE]
    # if the second index is the same	if p1[1] == p2[1]:		return matrix[(p1[0] - 1)  % SQUARE_SIZE][p1[1]] + matrix[(p2[0] - 1)  % SQUARE_SIZE][p2[1]]
    # else	return matrix[p1[0]][p2[1]] + matrix[p2[0]][p1[1]]```
This gave me the following script:
```python# alphabet for matrixalphabet = "0fkdwu6rp8zvsnlj3iytxmeh72ca9bg5o41q"
# square sizeSQUARE_SIZE = 6
def generate_square(alphabet):	assert len(alphabet) == pow(SQUARE_SIZE, 2)	matrix = []	for i, letter in enumerate(alphabet):		if i % SQUARE_SIZE == 0:			row = []		row.append(letter)		if i % SQUARE_SIZE == (SQUARE_SIZE - 1):			matrix.append(row)	return matrix
def get_index(letter, matrix):	for row in range(SQUARE_SIZE):		for col in range(SQUARE_SIZE):			if matrix[row][col] == letter:				return (row, col)	print("letter not found in matrix.")	exit()
# decrypt each pairdef decrypt_pair(pair, matrix):
	# get the indices in the matrix	p1 = get_index(pair[0], matrix)	p2 = get_index(pair[1], matrix)
	# if the first index is the same	if p1[0] == p2[0]:		return matrix[p1[0]][(p1[1]-1)%SQUARE_SIZE]+matrix[p2[0]][(p2[1]-1)%SQUARE_SIZE]
	# if the second index is the same	if p1[1] == p2[1]:		return matrix[(p1[0] - 1)  % SQUARE_SIZE][p1[1]] + matrix[(p2[0] - 1)  % SQUARE_SIZE][p2[1]]
	# else	return matrix[p1[0]][p2[1]] + matrix[p2[0]][p1[1]]
# decrypt string functiondef decrypt_string(s, matrix):	# place to store result	result = ""
	# Iterate through string two at a time	for i in range(0, len(s), 2):
		# pass the pairs to the decrypt_pair function		result += decrypt_pair(s[i:i+2], matrix)
	# return result	return result
# generate squarem = generate_square(alphabet)
# encrypted messageenc_msg = "herfayo7oqxrz7jwxx15ie20p40u1i"
# decrypt stringprint(decrypt_string(enc_msg, m))```
When run I got:
```emf57mgc51tp693dtt4g3h7f8ouwq3```
When put into the nc instance I got the flag:
```nc mercury.picoctf.net 30568
Here is the alphabet: 0fkdwu6rp8zvsnlj3iytxmeh72ca9bg5o41qHere is the encrypted message: herfayo7oqxrz7jwxx15ie20p40u1iWhat is the plaintext message? emf57mgc51tp693dtt4g3h7f8ouwq3Congratulations! Here's the flag: 007d0a696aaad7fb5ec21c7698e4f754```