ezeoke encryption

synopsis of a peculiar encryption algorithm I first made 7 years ago.

C0ONeqUl4gjUIMJJMIOakNqe4wxVLzf0myHJNqenKC3QAwNzKnCNqenCKQ3AZwrr7uqeNrwZur7LzVYJlnKCqNeKygeeRqshMe9kqWt3SuaP1ufZMJf5HsqhauP5fHqWkuvtvQckLQkWquPaLk0pS3tXPMZJkQLg3zhqsMe9fu1fRIuPafDacvQXEXVa0GINdGxGINUO09OQl3kGIN1aNJUkLyYGIN12FQO98XJdWFLyY7MhIGN0VaOU0WdFNsSIGNOQ9LyY3lkING0UOq0DZZlOTX06dAerW4cqbKvRBreA60dPUvDrSKbqW4crAex4qPSWd06erASP106d1SgTn3AerEw9BmV

DEMO

It may seem as if that is a random mash of characters, which it is, but I assure you it has meaning. Though, that is not the only block of character which means that. I made a particular algorithm to answer the question, “How can you randomly encrypt text?” The methodology behind the algorithm includes such concepts from dictionaries to the Fundamental Theorem of Arithmetic. The data presented is translated exactly as

Ezeoke Encryption takes in a limited range of ASCII characters, those useful in communication, and outputs encrypted data that can’t be interpreted. The output itself is 100% ASCII as well. The quirk of this algorithm is that it is nondeterministic: the same input text doesn't output the same encrypted data. However, that ciphertext can always decrypt to the same input.

The first hurdle when making an algorithm like this is deciding which characters to include. I settled on the upper and lowercase alphabet, punctuation marks, and every symbol I deemed useful or common enough to be included. For the sake of simplicity, the set of possible inputs to the algorithm will be referred to as P.

Method

The first task is to generate values for each element in P (with cryptographically safe random number generation of course). These values are what our input text will be converted to. We will call the set of possible characters in the ciphertext R. Example showing a some possible inputs P mapping to valid outputs:

figure showing how inputs can be mapped to random outputs

or X -> Q s.t. X ⊂ P, Q = {(i,j,k) i,j,k ∈ R}, |Q| = |X|

We will continue use Q to mean an example instantiation of cipher text.

We must also define a mapping for these values of Q. We always use a=2, b=3, c=5 and so on, mapping every possible output (ASCII lowercase, uppercas, then digits) to a prime number. The algorithm is essentially impossible without some type of constant.

showing prime mappings

Encryption

So far, the algorithm has generated two dictionaries: elements of P to three random characters (Q), such that each character is an element of R, and elements of R to prime numbers. The algorithm goes through the P -> Q mapping, and using each of the three characters, plugs them into the prime number dictionary (see Figure 2.), and multiples them before returning the product of the three prime numbers. Like so:

showing keygen

These products make up the key. Each product, according to the Fundamental Theorem of Arithmetic can only be written in terms of the three unique prime numbers that were multiplied to get it.

We append the complete key to the message, using character delimiters for the products, that have the ordered products for every elemnent of P (possible inputs). By assembling the map from every character in P to the random triplet like so

showing keygen

We can now take the random output back to our plaintext!


Thus far is the (altered) write up I made a few years back when I didn’t have a direction for this project. You may have noticed that we algorithm described is closer to obfuscation considering you send the key with the message. This means that with knowledge of the algorithm, you could easily decrypt messages.

Recently, though, I made some additions to the algorithm that’s solve this problem so it can actually be called encryption:

For one, instead of randomly generating, the triplet set Q, the two messengers share a private key that the RNG is seeded from. After sending a message you increment the seed so that the next exchange is not the same as last.

This is mediated using the message metadata. Since the ordering of the triplets doesn’t matter, we use the lexicographical ordering permutation to encode a secret message that stores this index:

ciphertext -> ascii triplet -> ordinal ranking -> lexicographical encoding -> base 6 number

The meta number is the truncated SHA256 hash of the mutual seed, multiplied by the message index. Two mutual parties with the same seed can recover this index by hashing the seed, dividing the Meta number by this hash to retrieve the message index, and add that to the seed to generate the correct Q set. Note that you don't need the seed to recover this meta number, it is just derived from the ciphertext triplet ordering.

One more addition to this algorithm, for every 30 characters a message has, we increment the index once more and regenerate the key dictionary so that the algorithm is resistant to frequency attacks. This is all in the demo as well.

Quite shiest, I know.