## The XOR cipher

A while back, I had the idea to design reversible noise, where the function *f* used for both encrypting and decrypting is the same, so that *f(text, password) = f(encrypted, password)*.

### ROT-13 Encryption

Reciprocal ciphers have been around for ages. A classic example is the ROT-13 Cipher, which rotates a letter 13 positions in the alphabet. With an alphabet of 26 letters (excluding ñ), repeating this operation brings you back to the original letter: A -> N and N -> A.

### XOR Encryption

My aim was to create a *somewhat* more secure cipher that requires a password for encryption/decryption. This is where XOR Encryption comes into play, based on the XOR (⊕) logical operation, eXclusive OR:

A | B | A⊕B |
---|---|---|

0 | 0 | 0 |

0 | 1 | 1 |

1 | 0 | 1 |

1 | 1 | 0 |

This operation can be applied to a number at the bit level. For example, 220 ⊕ 153 = 69.

220 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 |

153 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 |

69 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 |

The beauty of XOR is its reciprocity: just as 220 ⊕ 153 = 69, 220 ⊕ 69 = 153. Given any number A, the operation A ⊕ P = B and B ⊕ P = A. Thus, we can define a password P, enabling us to reversibly encrypt any string by assigning a number to each letter.

For example, if our string is "HELLO WORLD", our password is "PASSWORD", and we assign each letter a position in the alphabet (0 for space), we get the encrypted string "IFMMP XPSME".

A | 8 | 5 | 12 | 12 | 15 | 0 | 23 | 15 | 18 | 12 | 4 |

P | 16 | 1 | 19 | 19 | 23 | 15 | 18 | 4 | 0 | 18 | 4 |

B | 24 | 6 | 6 | 7 | 6 | 15 | 3 | 19 | 18 | 6 | 0 |

Reapplying the operation with "PASSWORD" and "IFMMP XPSME", we get back our original string. However, two issues remain:

- What if the input string and the password have different lengths?
- If someone has an unencrypted string and its encrypted version, how do we ensure they can't figure out our password?

### Handling Different Length Strings

A simple solution is to pad the password with spaces until it matches the text length. However, this changes nothing, as A ⊕ 0 = A. For instance, with "HELLO WORLD THIS IS A TEST", we get "IFMMP XPSME THIS IS A TEST".

Another option is to pad the password with a non-space symbol. Or, for less predictability, loop the password. In this way, for "HELLO WORLD THIS IS A TEST", using "PASSWORDPASSWO" as the password, the encrypted result is "IFMMP XPSMETHIS IS A TEST".

However, this solution is also insecure, as encrypting long texts would make it easy to spot frequently repeating letter combinations, allowing password guessing through frequency analysis. But there's still a trick up our sleeve.

### Hash Functions

In cryptography, hash functions are techniques that encrypt a string at low cost but with a prohibitively high decryption cost, sometimes taking millennia.

This is the case with the SHA-256 function. Using this function, we can encrypt the password and safely apply XOR encryption. To create a longer password, we would use a list of salts. I won't go into detail on this to keep the post brief, but feel free to ask more in the comments.

### Conclusions

After all this, we have achieved a moderately secure reciprocal cipher and, more importantly, learned a bit about cryptography.

If you're interested, you can try this cipher yourself on this page. It's a version to which I've added more characters.

## Comentarios

## Leave a comment