The Vigenère cipher is named after Blaise de Vigenère, a sixteenth century diplomat and cryptographer, by a historical accident. Vigene`re actually invented a different and more complicated cipher. The so-called “Vigenère cipher” cipher was actually invented by Giovan Batista Belaso in 1553. In any case, it is this cipher which we shall discuss here first.
This cipher has been re-invented by several authors, such as author and mathematician Charles Lutwidge Dodgson (Lewis Carroll) who claimed his 1868 “The Alphabet Cipher” was unbreakable. Several others claimed the so-called Vigenère cipher was unbreakable (e.g., the Scientific American magazine in 1917). However, Friedrich Kasiski and Charles Babbage broke the cipher in the 1800’s . This cipher was used in the 1700’s, for example, during the American Civil War. The Confederacy used a brass cipher disk to implement the Vigenère cipher (now on display in the NSA Museum in Fort Meade) .
The so-called Vigenère cipher is a generalization of the Cesaer shift cipher. Whereas the shift cipher shifts each letter by the same amount (that amount being the key of the shift cipher) the so-called Vigenère cipher shifts a letter by an amount determined by the key, which is a word or phrase known only to the sender and receiver).
For example, if the key was a single letter, such as “C”, then the so-called Vigenère cipher is actually a shift cipher with a shift of 2 (since “C” is the 2-nd letter of the alphabet, if you start counting at 0). If the key was a word with two letters, such as “CA”, then the so-called Vigenère cipher will shift letters in even positions by 2 and letters in odd positions are left alone (or shifted by 0, since “A” is the 0-th letter, if you start counting at 0).
 Wikipedia article on the Vigenere cipher.
Using Sage, let’s look at a message (a chant at football games between rivals USNA and West Point):
sage: AS = AlphabeticStrings() sage: A = AS.alphabet() sage: VC = VigenereCryptosystem(AS, 1) # sets the key length to be = 1 sage: m = VC.encoding("Beat Army!"); m # trivial example BEATARMY
Now, we choose for illustration a simple key of length 1, and encipher this message:
sage: key = AS("D") sage: c = VC.enciphering(key, m) sage: c # a trivial example EHDWDUPB
You see here that in this case the cipher boils down to the Caesar/shift cipher (shifting by 3).
Deciphering is easy:
sage: VC.deciphering(key, c) BEATARMY
Next, we choose for illustration a simple key of length 2, and encipher the same message:
sage: VC = VigenereCryptosystem(AS, 2) sage: key = AS("CA") sage: m = VC.encoding("Beat Army!"); m BEATARMY sage: c = VC.enciphering(key, m); c DECTCROY
Since one of the key letters is “A” (which shifts by 0), half the plaintext is unchanged in going to the ciphertext.
Here is the algorithmic description of the above (so-called) Vigenère cipher:
ALGORITHM: INPUT: key - a string of upper-case letters (the secret "key") m - string of upper-case letters (the "plaintext" message) OUTPUT: c - string of upper-case letters (the "ciphertext" message) Identify the alphabet A, ..., Z with the integers 0, ..., 25. Step 1: Compute from the string key a list L1 of corresponding integers. Let n1 = len(L1). Step 2: Compute from the string m a list L2 of corresponding integers. Let n2 = len(L2). Step 3: Break L2 up sequencially into sublists of size n1, and one sublist at the end of size <=n1. Step 4: For each of these sublists L of L2, compute a new list C given by C[i] = L[i]+L1[i] (mod 26) to the i-th element in the sublist, for each i. Step 5: Assemble these lists C by concatenation into a new list of length n2. Step 6: Compute from the new list a string c of corresponding letters.
Once it is known that the key is, say, n characters long, frequency analysis can be applied to every n-th letter of the ciphertext to determine the plaintext. This method is called “Kasiski examination“, or the “Kasiski attack” (although it was first discovered by Charles Babbage).
The cipher Vigenère actually discovered is an “auto-key cipher” described as follows.
ALGORITHM: INPUT: key - a string of upper-case letters (the secret "key") m - string of upper-case letters (the "plaintext" message) OUTPUT: c - string of upper-case letters (the "ciphertext" message) Identify the alphabet A, ..., Z with the integers 0, ..., 25. Step 1: Compute from the string m a list L2 of corresponding integers. Let n2 = len(L2). Step 2: Let n1 be the length of the key. Concatenate the string key with the first n2-n1 characters of the plaintext message. Compute from this string of length n2 a list L1 of corresponding integers. Note n2 = len(L1). Step 3: Compute a new list C given by C[i] = L1[i]+L2[i] (mod 26), for each i. Note n2 = len(C). Step 5: Compute from the new list a string c of corresponding letters.
Note how the key is mixed with the plaintext to create the enciphering of the plaintext to ciphertext in Steps 2 and 3.
A screencast describing this has been posted to vimeo.