The SG1 Cipher

by

OSIN

CHEVRON 1 ENGAGED:

Here is the source code:

genkeys.java
sg1.java

Several years ago I foolishly embarked on a project to create my own encryption scheme. The problem with doing that is that unless you're a hotshot mathematician, which I'm not, you're bound to fail miserably. However, a few weeks ago while watching too many chevrons fly across the screen during SciFi Friday, I became over-stimulated and couldn't get the thought of obfuscating everyday text out of my mind. I use the word "obfuscation" because I don't think this method qualifies as true encryption, but then, I don't work for the NSA. And I doubt my idea is original. Anyway, if I'm not mistaken, this technique is similar to producing a symmetric cipher in which the same key is used to encrypt and decrypt plain text files. However, this method uses a pass phrase to choose the keys, which I refer to as key lines, that will be used to obfuscate plain text messages. For lack of a better name, I will refer to this cipher as the SG1 Cipher.

CHEVRON 2 ENGAGED:

Before I get into how the encoding and decoding of SG1 works, let's talk about generating the key which will be used to obfuscate a plain text file. The key file format consists of two parts. The first part is a single key line of 93 ASCII characters generated randomly and in which no character is repeated more than once. I will refer to this line from now on as the "passphrasekey" line. This line is crucial in obfuscating a passphrase and the plain text that will be used in this example. After that will be a blank space, then after that 93 unique key lines are generated in a random sequence like the first line, with the first character of each key line not repeated as the first character in any other key lines.

At this point I should mention the proof of concept code is written in Java. And yes, I know I'll be condemned to deprecation hell for using techniques the Java Developer's Mafia persecute others of my ilk for using. The point is the SG1 cipher can easily be rewritten into any other programming language, but if anyone out there wants to slap lipstick on this pig, go right ahead.

The code that generates the keys and does the encode/decode routines depend on a string variable called "charlist". In the code example the value of this variable is set to the following:

charlist="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*+-<>.,?/|][_={}:()~;' \"";

Note the use of the '\' to escape the double quotes. Depending on the programming language used, you may need it. Here is the code flow that generates the SG1 cipher:

GENERATING PASSPHRASEKEY:
1. for (int i=0;i<charlist.length();i++)
2. Generate a random number from 0 to charlist.length-1. Keep in mind that most programming languages use zero-based indexing.
3. Pull out a char from charlist that is located at that random number index.
4. Check to make sure that char hasn't been chosen yet.
5. If it hasn't add to this key line. If it has, decrement the counter variable i and redo.
6. Print out the passphrasekey to standard out.

The code above is the same code used to generate the key lines for the SG1 cipher block. The only difference is that for each new key line, the first char must be checked to make sure it hasn't been used in a previous key line. Each keyline will begin with its own unique char that will be used to identify it. So, you will have an "L" key line, a "2" key line, a "!" key line and so forth. Also, the number of key lines will always equal the number of chars in "charlist".

CHEVRON 3 ENGAGED:

How does the SG1 cipher work? Basically, the first thing you need is a pass phrase. The longer the pass phrase and the more unique the characters in it will determine just how difficult the obfuscation will be. That's because a longer pass phrase will diminish the chances of a letter or symbol being encoded with the same character each time. So, chose a fairly long one with non-repeating characters. For this article, I'll be using this one: "D4n1el,ItsWhatw3d0". Of course, we'll need a message to encode. Let's say both Samantha Carter and Jack O'Neill share many things, one being this cipher key, and O'Neill (that's 2 Ls) wants to send Carter this message that he's saved in a flat text file:

Dearest Samantha. I cannot stand it any longer. Though the powers that be keep jerking us around, I cannot wait another 8 seasons to hold you in my arms. Meet me in the Gate Room at midnight. Warmest Regards- MacGyver.

The first thing that must take place is that the pass phrase we chose above must be encoded. For instance, let's take the first char 'D'. It is encoded by finding it's numerical index position in the passphrasekey line and pulling out the char in the 'D' key line in the SG1 cipher block at the same numerical index. For these purposes, let's say the answer is 42 (hg2g >:P). The char at index 42 in the 'D' key line for this example might be 'l'. The passphrase is encoded char by char in that manner and might look like this:

D4n1el,ItsWhatw3d0 => l;#aGbOUf2z/3hAtPR

Those chars in the new encoded passphrase will become the list of key lines repeating in that sequence to encode each char in the message. For instance, the first letter in our message is 'D'. We already established that its index is 42 in the passphrasekey line. But, instead of looking to the 'D' key line, we go to the 'l' key line and pull out that char at numerical index 42 to represent 'D'. We move to the next key line listed, which is ';' and do the same for the next char in the original message, which is 'e', and so on until the message is encoded. But let's not encode the message just yet. It's not enough to encode our plain text file which may be easily decoded. Let's pad the message with random chars before and after our pre-encoded message to further obfuscate what encoded chars represent our message. In my java example I use between 150-300 random number of chars, randomly generated, to prepend and append to the message. I also use delimeters to mark the beginning and end of the message before encoding the entire thing using the previously describe method. But, one word of caution- choose your delimiters carefully! In my java proof-of-concept code, this is the command that one runs when encoding:

java sg1 -e [cleartext.txt] [sg1keyfile] [encodedtext.txt]

CHEVRON 4 ENGAGED:

The decoding of the encoded file is just reversing what took place above. Basically, the first encoded char's index would be pulled from the key line of the first key dictated by the encoded pass phrase. Then the real char is pulled from the passphrasekey at the same index. Of course, the decoded file still has the padding left over, but anyone with a fair amount of programming skills should be able to pull them out. Still, the original text message should be readable despite their presence. The java proof-of-concept code that does the encoding also does the decoding when run this way:

java sg1 -d [encodedtext.txt] [sg1keyfile] [cleartext.txt]

This is just an exercise in obfuscation. You probably should not use the SG1 cipher in real life since my guess is that it would be easily broken. There are also other issues involved such as using a long pass phrase, protecting the pass phrase itself, and protecting the key file, all of which would have to be taken into account. But let's continue the dialing sequence.

CHEVRON 5 ENGAGED:

You might be thinking, why stop at 93 characters when Unicode is our oyster? Can this be done? The answer is yes, it can. My java proof-of-concept code takes into account the possibility of using a character string list of different sizes. And it works just the same as above. For instance, here is an example of the variable "charlist" with 143 characters used:

charlist="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*+-<>.,?/|][_={}:()\~;' È�[8;1HÐÛÔíäû£ÜÊÖ¼Òïºö°ÉìùÃ˾ݵÀóþâÚêÕýçÓú½ñÑᢱÁð¡Äÿ¿\"";
(Warning, the line above may not display correctly in your browser)

When generating the key, this will result in key line lengths of 143 chars with 143 key lines in the main SG1 cipher block. My guess is you can extend that range to the full complement of Unicode characters that are available. As for the java code, you only need to update the "charlist" variable and recompile the code. You must keep in mind that the keys you generate must use the same characters that you use to encode/decode data, which means that the "charlist" variable must be the same in both java programs that generate the key file and the one that actually does the encoding/decoding.

CHEVRON 6 ENGAGED:

At this point I could've stopped the dialing sequence, but I like jerking Star Gate Command around. So, let's say Carter wants to send back a reply to this O'Neill/MacGyver hybrid. Now, she could do the same thing he did, probably by sending it through email, but Carter has more brains than that. Not only does she NOT want to be subjected to another lecture from Daniel Jackson or the knowing glances of Teal'c, but she knows that fraternization is an Article 15 punishable offense in the Air Force. She would want to use some sort of steganography to hide the encoded data, but she also knows that "The O'Neill" may not be swift enough to figure it out, so she decides to hide the encoded data in the comments section of a jpeg. At this point, she finds that by using the 93 keylength SG1 cipher block and encoding her message with that, the encoded data can be easily added to the comments section of a jpeg image via The Gimp. But, when she tries to use those Unicode characters in the 143 character keys, they get converted to an unholy format and her message is ruined. Not to worry. The Asgaard have just released the latest version of "uuencode" and by converting her encoded message to Base64, that will easily fit into the comments section of a jpeg without getting ruined. But her aspirations and goals become even more grandiose! Carter decides to use Yahoo! Photos as her Alpha storage site, so that her message can be retrieved over the Internet.

CHEVRON 7 WILL NOT ENGAGE:

I know what you're thinking. Why would any company allow unlimited photo uploads without asking anything in return? It's downright unnatural, that is. Anyway, when O'Neill downloads the jpeg with the encoded message in the comments section of the image from Carter, he finds it's gone. WTF?! It turns out that Yahoo! Photos removes ALL comments in ALL jpegs that are uploaded to their photos section, probably a prerequisite for some sort of prostration-substitute for the Orii. As they say, all's fair in love and war. I'll close for now and hopefully you're over-stimulated. Hallowed are the Orii.