Skip to content

Instantly share code, notes, and snippets.

@plugnburn
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save plugnburn/6b50ceee3a89893a9e48 to your computer and use it in GitHub Desktop.
Save plugnburn/6b50ceee3a89893a9e48 to your computer and use it in GitHub Desktop.
SMSPP: Short Message Security

SMSPP: Short Message Security

Overview

SMSPP (stands for Short Message Security - Pencil and Paper) is a simple, pencil-and-paper based protocol to exchange very short encrypted messages via commonly available communication channels with a limited character set (such as SMS, hence the name).

SMSPP Workflow

  1. Both sender and recipient get the same secret keytable: a 5x5 letter grid of 25 single-case Latin letters (J is usually excluded), permutated with a special rule (see Generating keytables section for more information). This kind of tables is also known as Polybius square.
  2. Each time the sender wants to send the message, he encrypts it with a modified variant of Bifid cipher (see the next section) using the keytable and sends the message to the recipient. Optionally the sender can encode the encrypted message to the tap-code (knock code) following the rules from the Using SMSPP as a tap-code system section.
  3. The recipient gets the message, decodes the tap-code if needed, and decrypts the message with a modified variant of Bifid cipher using the keytable.

Message encryption and decryption

Message encryption and decryption in SMSPP are based on a simple cipher that allows you to encode short messages relatively fast using just pencil and paper. It's called the Bifid cipher. To make the protocol stronger, a slight modification of this cipher is used.

We will use the following keytable for all the examples below (warning: it's trivial and non-permutated, so never ever use it in real encryption):

ABCDE
FGHIK
LMNOP
QRSTU
VWXYZ

Encryption

  1. Prepare your message by uppercasing it, removing all punctuation, replacing J with I and spaces with X (these are common rules but you may choose another method of getting the 25-letter charset). Example: Putin Huilo becomes PUTINXHUILO.

  2. For each letter in the prepared message, locate its coordinates (from 1 to 5) in the keytable using the straight rule (the first digit is the row, the second is the column). For each message letter, just write the second digit (column number) below the first (row number). Example:

     PUTINXHUILO
     34423524233 <-- row numbers for each letter
     55343335414 <-- column numbers for each letter
    
  3. Next, read both lines as one horizontally and split by two digits. For example, the above becomes:

     34 42 35 24 23 35 53 43 33 54 14
    
  4. For each digit pair, find the appropriate letter in the keytable with the inverted rule (the first digit is the column, the second is the row), and you're done. For example, the above becomes:

     SIXRMXPONUQ
    

Encryption (mental version)

This is an adaptation of the above Bifid modification that gives you absolutely the same results but involves no handwriting (you still need to look at your keytable though). Using this method, you can write your ciphertext almost immediately. We'll use the same example as above.

  1. Prepare your message just the same as in the above section.

  2. Read the message by two letters. For each pair of letters, locate their row numbers in your keytable and use the first number as the column number of the ciphertext letter, the second number as the row number of the ciphertext letter . Write down each ciphertext letter using the same rule.

     PU=>34=>S TI=>42=>I NX=>35=>X HU=>24=>R IL=>23=>M O=>??? (see next step)
    

    So, we have the first half of example ciphertext: SIXRM.

  3. If you're left with an odd letter (just like in the above example), use the row number of this letter as the column number of the ciphertext letter, and the column number of the first plaintext letter as the row number of the ciphertext letter. In this case, you must omit the first plaintext letter in the next step.

     OP=>35=>X
    

    So, we have another ciphertext letter, and our example ciphertext becomes SIXRMX.

  4. Read the message by two letters again (if you had to do the step 3, you must omit the first letter, as it is already used), but then use the column numbers of each letter to form ciphertext with the same rule: the first is the column number of the ciphertext letter, the second is the row number of the ciphertext letter. This way all remaining ciphertext is formed.

     UT=>53=>P IN=>43=>O XH=>33=>N UI=>54=>U LO=>14=>Q
    

    So, our final example ciphertext becomes SIXRMXPONUQ, just as in the previous section.

Decryption

As Bifid is a symmetrical cipher, and SMSPP is based on Bifid, the decryption process is the inversion of encryption process:

  1. Convert encrypted message to a set of digit pairs using your keytable with the inverted rule (the first digit is the column, the second is the row) and write them down with no spaces:

     SIXRMXPONUQ => 3442352423355343335414
    
  2. Split this digit string into 2 equal parts and write the second part below the first. Using the straight rule (the first digit is the row, the second is the column), locate each letter of the plaintext in your keytable:

     34423524233
     55343335414
     PUTINXHUILO
    

    Unfortunately, unlike encryption, decryption process cannot be easily simplified for mental operation. You have to write down intermediate results anyway. Please leave a comment if you have any ideas on this.

Generating keytables

This section describes a method to generate keytables for SMSPP/Bifid using just paper and pencil. This can be useful if you're unable to use a computer to generate random alphabet permutations. Unlike the encryption/decryption process, keytable generation in SMSPP may seem complicated, but if you practice a bit and will not use long callsigns and passphrases, you'll be able to generate new keytables just as fast as you encrypt your short messages. Nevertheless, you won't need to do it very often.

  1. First, make up an initialization string. It can consist of sender callsign, recipient callsign and the secret passphrase. Use the same conversion rules as with preparing the message for encryption. For example, if the sender callsign is Alice, recipient callsign is Bob and the passphrase is "hackers unite", the init string would be ALICEBOBHACKERSXUNITE.

  2. Write down the trivial keytable (the same one we used for encryption examples):

     ABCDE
     FGHIK
     LMNOP
     QRSTU
     VWXYZ
    

    Use this keytable as current for the first iteration.

  3. Encrypt your initialization string with usual SMSPP encryption using the current keytable:

     ALICEBOBHACKERSXUNITE
     132111312112144543241 => 13 21 11 31 21 12 14 45 43 24 11 14 35 24 23 13 55 23 35 34 45 => LBACBFQYORAQXRMLZMXSY
     114352423135523353445
    
  4. Remove all duplicate letters from the cryptogram, leaving only the first occurrence of each letter:

     LBACBFQYORAQXRMLZMXSY => LBACFQYORXMZS
    
  5. Make up a new 5x5 keytable from the remaining cryptogram letters by writing them row-by-row and then adding the missing letters in the alphabetic order:

     LBACF
     QYORX
     MZSDE
     GHIKN
     PTUVW
    
  6. If you think resulting keytable is not random enough, use it as current keytable and go to step 3. Otherwise, go to the next step.

  7. Revert the second and the fourth row of the keytable and then transpose the result (write its rows as columns). That's it, you just generated a ready keytable you can use for encryption between your callsigns.

     LBACF    LBACF    LXMNP
     QYORX    XROYQ    BRZKT
     MZSDE => MZSDE => AOSIU
     GHIKN    NKIHG    CYDHV
     PTUVW    PTUVW    FQEGW
    

Using SMSPP as a tap-code system

To convert encrypted message to a tap code, just use the keytable on it with a straight rule. Every digit you get is the number of knocks. The recipient then converts the knock digits to the encrypted message again and then uses the standard decryption procedure to read the message.

Possible improvements

This protocol can be transparently extended to larger character set and square grid sizes (6x6, 7x7 etc). The metod of reading and writing encoded digits can also be changed: in reverse, snake-like etc. Moreover, the simplicity of this method allows to combine it with other obfuscation techniques used in short messages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment