A polyalphabetic substitution cipher invented by Blaise de Vigenère in the 1500's. It has N different cipher alphabets, where N is the number of letters in the alphabet, each shifted by one letter with respect to the previous alphabet. A grid is drawn NxN. The first row is a cipher alphabet with a Caesar shift of one. The second has a Caesar shift of two and so on.

Next a key is selected. The letters of the key define which rows to use and in what order. So when encrypting plaintext the first letter of the plaintext is encrypted using the cipher alphabet specified by the first letter of the key (the row that starts with the first letter of the key). The second letter of the plaintext is encrypted using the row that starts with the second letter of the key and so on until you have used every letter in the key then you start over at the beginning of the key.

For many years it was believed that this cipher was unbreakable. Then in the 1800's, sometime prior to 1854, Charles Babbage managed to tackle the beast. Yet since he never published his findings it wouldn't be until 1863 before the world would know the square was breakable. In 1863 Friedrich Kasiski independently discovered the same technique Babbage found. (see Breaking the Vigenère cipher)

This square can be used as the basis for a One-time Pad. The difference is that the key of a One-time Pad has a length of at least the plaintext, so there is no repetition, and the letters that make up the key are generated at random to avoid any unintended repetition. By using a key this long that doesn't contain repetition it isn't susceptible to the codebreaking technique developed by Babbage and Kasiski.

The Vigenère Square for English:

         A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

     B   B C D E F G H I J K L M N O P Q R S T U V W X Y Z A 
     C   C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
     D   D E F G H I J K L M N O P Q R S T U V W X Y Z A B C 
     E   E F G H I J K L M N O P Q R S T U V W X Y Z A B C D 
     F   F G H I J K L M N O P Q R S T U V W X Y Z A B C D E 
     G   G H I J K L M N O P Q R S T U V W X Y Z A B C D E F 
     H   H I J K L M N O P Q R S T U V W X Y Z A B C D E F G 
     I   I J K L M N O P Q R S T U V W X Y Z A B C D E F G H 
     J   J K L M N O P Q R S T U V W X Y Z A B C D E F G H I 
     K   K L M N O P Q R S T U V W X Y Z A B C D E F G H I J 
     L   L M N O P Q R S T U V W X Y Z A B C D E F G H I J K 
     M   M N O P Q R S T U V W X Y Z A B C D E F G H I J K L 
     N   N O P Q R S T U V W X Y Z A B C D E F G H I J K L M 
     O   O P Q R S T U V W X Y Z A B C D E F G H I J K L M N 
     P   P Q R S T U V W X Y Z A B C D E F G H I J K L M N O 
     Q   Q R S T U V W X Y Z A B C D E F G H I J K L M N O P 
     R   R S T U V W X Y Z A B C D E F G H I J K L M N O P Q 
     S   S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
     T   T U V W X Y Z A B C D E F G H I J K L M N O P Q R S 
     U   U V W X Y Z A B C D E F G H I J K L M N O P Q R S T 
     V   V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
     W   W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
     X   X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
     Y   Y Z A B C D E F G H I J K L M N O P Q R S T U V W X 
     Z   Z A B C D E F G H I J K L M N O P Q R S T U V W X Y
     A   A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

A Vigenère square in javascript

This is is a javascript version of the Vigenère cipher. It uses the characters that can be found on a US keyboard as it's alphabet. I can't guarantee it to be bug free, but it encrypted and decrypted itself successfully. It keeps case and can handle numbers and special chars. Almost anything you can type with your keyboard. If it can't encode a char it should just pass through without interrupting the encrypting of the rest of the message. All tabs (\t and \v) and newlines (\f, \n, and \r) are trimmed out and replaced with a single space. I've tried to make this as usable in the real world as possible.

To see it in action go to http://www.babelfeesh.com/crypto/vigenere.html.

Thank wharfinger for the e2 source code formatter. And for more info see Breaking the Vigenère cipher and One-Time Pad.

Cryptology Meta-Node


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<title>Vigenère Square in Javascript</title>
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<script type="text/javascript">

// produce our cipher alphabet for vigenere square
var soup = new Array();
var cnt=0;
soup[cnt++] = " ";
soup[cnt++] = "a";
soup[cnt++] = "b";
soup[cnt++] = "c";
soup[cnt++] = "d";
soup[cnt++] = "e";
soup[cnt++] = "f";
soup[cnt++] = "g";
soup[cnt++] = "h";
soup[cnt++] = "i";
soup[cnt++] = "j";
soup[cnt++] = "k";
soup[cnt++] = "l";
soup[cnt++] = "m";
soup[cnt++] = "n";
soup[cnt++] = "o";
soup[cnt++] = "p";
soup[cnt++] = "q";
soup[cnt++] = "r";
soup[cnt++] = "s";
soup[cnt++] = "t";
soup[cnt++] = "u";
soup[cnt++] = "v";
soup[cnt++] = "w";
soup[cnt++] = "x";
soup[cnt++] = "y";
soup[cnt++] = "z";
soup[cnt++] = "A";
soup[cnt++] = "B";
soup[cnt++] = "C";
soup[cnt++] = "D";
soup[cnt++] = "E";
soup[cnt++] = "F";
soup[cnt++] = "G";
soup[cnt++] = "H";
soup[cnt++] = "I";
soup[cnt++] = "J";
soup[cnt++] = "K";
soup[cnt++] = "L";
soup[cnt++] = "M";
soup[cnt++] = "N";
soup[cnt++] = "O";
soup[cnt++] = "P";
soup[cnt++] = "Q";
soup[cnt++] = "R";
soup[cnt++] = "S";
soup[cnt++] = "T";
soup[cnt++] = "U";
soup[cnt++] = "V";
soup[cnt++] = "W";
soup[cnt++] = "X";
soup[cnt++] = "Y";
soup[cnt++] = "Z";
soup[cnt++] = "`";
soup[cnt++] = "1";
soup[cnt++] = "2";
soup[cnt++] = "3";
soup[cnt++] = "4";
soup[cnt++] = "5";
soup[cnt++] = "6";
soup[cnt++] = "7";
soup[cnt++] = "8";
soup[cnt++] = "9";
soup[cnt++] = "0";
soup[cnt++] = "-";
soup[cnt++] = "=";
soup[cnt++] = "[";
soup[cnt++] = "]";
soup[cnt++] = "\\";
soup[cnt++] = ";";
soup[cnt++] = "'";
soup[cnt++] = ",";
soup[cnt++] = ".";
soup[cnt++] = "/";
soup[cnt++] = "~";
soup[cnt++] = "!";
soup[cnt++] = "@";
soup[cnt++] = "#";
soup[cnt++] = "$";
soup[cnt++] = "%";
soup[cnt++] = "^";
soup[cnt++] = "&";
soup[cnt++] = "*";
soup[cnt++] = "(";
soup[cnt++] = ")";
soup[cnt++] = "_";
soup[cnt++] = "+";
soup[cnt++] = "{";
soup[cnt++] = "}";
soup[cnt++] = "|";
soup[cnt++] = ":";
soup[cnt++] = "\"";
soup[cnt++] = "<";
soup[cnt++] = ">";
soup[cnt++] = "?";

// setup the vigenere square
var encvigsq = new Array();
for (var vi=0; vi < soup.length; vi++) {
    encvigsq[soup[vi]] = new Array();
    for (var vj=0; vj < soup.length; vj++) {
        var letter = vi+vj;
        if (vi+vj > (soup.length - 1)) {
            letter = vi+vj-soup.length;
        }
        encvigsq[soup[vi]][soup[vj]] = soup[letter];
    }
}

// setup an array for decoding the vigenere square
var decvigsq = new Array();
for (var di=0; di < soup.length; di++) {
    decvigsq[soup[di]] = new Array();
    for(var dj=0; dj < soup.length; dj++) {
        decvigsq[soup[di]][encvigsq[soup[di]][soup[dj]]] = soup[dj];
    }
}

/*///////////////////////// encode using the vigenere square ///////////////////*/

function encodevig() {
    // comments 
    var sourceString = document.getElementById("source").value;
    sourceString = sourceString.replace(/[\t\f\n\r\v]+/g, " ");
    var outputString = "";
    var keyString = document.getElementById("vigkey").value;
    keyString = keyString.replace(/[\t\f\n\r\v]+/g, " ");
    var keyidx = 0;
    for (var i = 0; i < sourceString.length; i++) {
        if (encvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)] != null) {
            outputString += encvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)];
            if (keyidx == (keyString.length - 1)) {
                keyidx = 0;
            } else {
                keyidx++;
            }
        } else {
            outputString += sourceString.charAt(i);
        }
    }
    document.getElementById("destination").value = outputString;
}

/*///////////////////////// decode using the vigenere square ///////////////////*/

function decodevig() {
    // comments 
    var sourceString = document.getElementById("source").value;
    sourceString = sourceString.replace(/[\t\f\n\r]+/g, " ");
    var outputString = "";
    var keyString = document.getElementById("vigkey").value;
    keyString = keyString.replace(/[\t\f\n\r\v]+/g, " ");
    var keyidx = 0;
    for (var i = 0; i < sourceString.length; i++){
        if (decvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)]) {
            outputString += decvigsq[keyString.charAt(keyidx)][sourceString.charAt(i)];
            if (keyidx == (keyString.length - 1)) {
                keyidx = 0;
            } else {
                keyidx++;
            }
        } else {
            outputString += sourceString.charAt(i);
        }
    }
    document.getElementById("destination").value = outputString;
}


</script>
</head>

<body>
<h1 align="center">A Vigenère Square in Javascript</h1>
Note: I've used a larger alphabet than most implementations I've found.
It keeps case and can handle numbers and special chars.  Almost anything you
can type with your keyboard.  If it can't encode a char it should just pass
through without interrupting the encrypting of the rest of the message. All
tabs (\t and \v) and newlines (\f, \n, and \r) are trimmed out and replaced
with a single space.
<p>
Disclaimer: I don't promise this to be bug free. It is also a well known
algorithm and is not difficult to crack.  Do not use for actual secure
communications.  But if it is bug free it can be used as a One Time Pad which is very secure.
<p>
<textarea id="source" cols=70 rows=10></textarea><br />
<button id="dovig" onclick="encodevig()">Encode (Vigenere Sq)</button>
<button id="undovig" onclick="decodevig()">Decode (Vigenere Sq)</button>
<b>Key:</b> <input id="vigkey" size="20" value="default">
<br />
<textarea id="destination" cols=70 rows=10></textarea>
</body>
</html>

This effect can also be achieved with a code wheel. Some prefer the wheel because it is less eye bending. On the other hand, it requires manual labor to operate.

Either way, they turn the alphabet into a cyclic group and add the key to the clear text message to achieve encryption.

If one is not using a one-time-key, then it may be useful to use a different group than the one shown above. One can reorder the letters, or put them into two cycles (changing the group from C26 to the Cartesian product of C2 and C13). This will make the number of possible keys effectively larger by a factor of 26!/6 as far as your adversary is concerned, and so make cracking the code more difficult. The problem with relying on this is that your adversary may be able to accumulate data over time as you use different keys, and determine what group you are using. Once that has been done, there is no further advantage to using a different square over using the original. However, this can throw off a cracker for some time.

Note that the improvement factor is less than 2*26! because for any cyclic group you choose, it is isomorphic to the same group with a different generator. For example, instead of (0,1,2,3,4...23,24,25,0) one could count (0,3,6,... 24,1,4,7,... 25,2,5,8,... 20,23,0) which would produce the same cryptographic effect but have a different ordering. C26 has 12 generators (all the odd numbers except 13). Therefore, we lose a factor of 12. Then we regain a factor of 2 because there is the same number of groups of the form C2xC13.

Cypher system invented in the mid 16-th Century by French diplomat Blaise de Vigeneres. To use the cypher, you first need a copy of the following table (from which the cypher takes its name):

  | a b c d e f g h i j k l m n o p q r s t u v w x y z 
--------------------------------------------------------
1 | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A
2 | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B 
3 | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
4 | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
5 | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
6 | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
7 | H I J K L M N O P Q R S T U C W X Y Z A B C D E F G 
8 | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H 
9 | J K L M N O P Q R S T Y V W X Y Z A B C D E F G H I
10| K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
11| L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
12| M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
13| N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
14| O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
15| P Q R S T U V W X Y Z A B C D E F G H I J K L M N O 
16| Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
17| R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
18| S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
19| T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
20| U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
21| V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
22| W X Y Z A B C D E F G H I J K L M N O P Q R S T U V 
23| X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
24| Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
25| Z A B C D E F G H I J K L M N O P Q R S T U V W X Y
26| A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

Each line in this table represents an alphabet with a different caesar shift. You also need to choose a keyword, which defines which alphabet you use for a given letter in the message - the first letter in the plaintext is encoded according to the alphabet which begins with the first letter of the keyword, and so on.

For instance, to encrypt the first line of Byron's poem The Destruction of Sennacherib using the keyword "nothing":


Key  : nothingnothingnothingnothingnothingno
Plain: TheAssyriancamedownlikeawolfonthefold
code : GVXHAFENWTUKNSRRHDVYOXSTDWYLBBMOMSUYR

To decrypt the message, simply re-apply the cypher in the opposite direction.

Prior to the introduction of computers, the Vigeneres cypher was a reasonably secure method of encryption for short messages (i.e. no more than a few repetitions of the keyword).In 1854, however, Charles Babbage was able to demonstrate that, when the cypher is used to encrypt a long message, the length of the keyword can be determined by analysis of repeating patterns in the text.

For instance, if a particular three-letter sequence occurs twice in the text, 95 letters apart, then we assume that the two occurrances are encryptions of the same three-letter word, and the keyword is a factor of 95 (i.e. 5 or 19) letters long. Analysis of other repeating patterns should more completly describe the length of the keyword, and once this is known the cypher is vulnerable to frequency analysis.

Introduction

A Vigenere cipher is, in its simplest form, encoding a message with a Caesar shift cipher, but using a different shift for every letter of the plaintext. Let’s take, for example, the message AAAAAAAAAA (the letter ‘A’ repeated 10 times).

Under a regular Caesar shift, you “move” your characters down the alphabet by a specific amount. For instance, with a shift of 1, the message becomes BBBBBBBBBB. With a shift of 2, it becomes CCCCCCCCCC and so on. As you might imagine, this kind of cipher can be attacked by analysing letter frequency, because the same letter in plaintext is always encoded as the same letter in the ciphertext.

A way around this limitation is to use a different shift for every letter of the plaintext. This, in essence, is the Vigenère cipher.

Let’s imagine, then, that we will shift our message by 0 units for the first letter, 1 unit for the second one and so on. The shift then, could be established as 0-1-2-3-4-5-6-7-8-9. The ciphertext, in this case, would be ABCDEFGHIJ.

What, then, if you want to shift by more than 9 units? Well, you could turn to hexadecimal, but it would be easier to just use the 26 letters of the alphabet to represent these shifts, from 0–25. Then, in order to encode and decode a Vigenère cipher, you need not just the message, but a code word (keyword) that will be used repeatedly to encode and decode.


A mathematical approach

It’s easy to see now that the Vigenère cipher can be understood as a simple operation of modular addition or subtraction, repeated for every letter of the plaintext, with shifts determined by the keyword.

Simple, isn’t it?

Well, this simplicity does have its drawbacks, as others have written here. The most important one is that it can still be attacked by either frequency analysis or key elimination.

Kasiski examination

The main idea is that, if your message is long enough, there is a high chance for a single letter to be encoded with the same key-letter more than once. This could result in the ciphertext having short strings of repeated characters. This in turn can be used to deduce the keyword length n, and from there it’s possible to break down the message in n-long columns, which greatly speeds up regular frequency analysis.


A naive Vigenère implementation in Python 3.x

# -*- coding: utf-8 -*-
"""
Created on Thu Aug  8 00:25:37 2019

@author: Andy

Vigenere cypher, naive approach.

Assume both plaintext and cypher are in all caps. The Vigenere cypher is
done algebraically with additions modulo 26, 'adding' the letters from
column (plaintext_i) and the letters from row (key_i).

***For demonstration purposes only***: This module stores message, key and
encoded text in plain text.

'alpha' is the basis for the Vigenere square. Originally, you'd use only the
26 letters of the Latin alphabet, but by extending this string with symbols
you could extend this 
"""

import math
import re

alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
plain = input('What is your message? > ')
plain = re.sub('[\W]+', '', plain)
plain = str.upper(plain)
cypher = input('What is your cypher code? > ')
cypher = re.sub('[\W]+', '', cypher)
cypher = str.upper(cypher)

# Using ceiling function to ensure a longer than necessary key
times = math.ceil(len(plain) / len(cypher))
proto_key = cypher * times
key = proto_key[:len(plain)]
# Store the encoded message
encoded = ''
# Calculate addition modulo 26
for idx, letter in enumerate(plain):
    new = (alpha.index(plain[idx]) + alpha.index(key[idx])) % len(alpha)
    encoded += alpha[new]
print(plain)    # test: ATTACKATDAWN
print(key)      # test: LEMON
print(encoded)  # test: LXFOPVEFRNHR

THE IRON NODER CHALLENGE XII: WE'LL RUST WHEN WE'RE DEAD


Log in or register to write something here or to contact authors.