gifVigen

png

Vigen is a Unicode UTF-8 encryption system based on the classic Tableau de Vigenère. Vigen is an experiment using this particular cypher, intended for those who are interesting in building their own encryption tables. Vigen can generate exceedingly strong cyphers that are probably unbreakable without the given keys and tables. Vigen might even generate military grade cyphers, although I make no claim as to the security of the cypher. Vigen is for encrypting UTF-8 TEXT files; it is not intended for encrypting binary files. Vigen is not a private/public key encryption system such as PGP (at least, not yet). Development snapshots can be found on the Vigen Download page. The following documentation is in progress.

The Program

Worked Examples

Beginnings

Vigen began as a Hypercard Stack that I wrote for the Macintosh Classic back in 1995, but at that time it was not Unicode compliant:

png

The original version had 5 different tables, for Greek, Latin, French and English alphabets, as well as an ASCII table. Instead of making just one pass through the table, three passes were made, with two different keys and an option to shift the table rows for the second pass. The idea was to make the cypher harder to crack.

Vigen has been re-coded in C++ and now works with Unicode. The cypher method itself is far more sophisted, but in order to explain how Vigen works, it is best to start with a simple example based on the ASCII alphabet...

Basic Principle

The Tableau de Vigenère is used in the following way. Suppose we want to encrypt the maxim:

IT IS BETTER TO GO TO THE FOUNTAIN HEAD THAN TO FOLLOW RIVULETS

To encrypt a message, a key word/phrase is required. In this example, the keyword is SUNLIGHT.

Write the Key word/phrase repeatedly over the original message:

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
IT IS BETTER TO GO TO THE FOUNTAIN HEAD THAN TO FOLLOW RIVULETS

Locate the key letter S in the left hand column, read across that row until you find the message letter I; now read up that column to get cypher letter Q.

png

Continue in this manner for the whole message. The encrypted result is:

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
IT IS BETTER TO GO TO THE FOUNTAIN HEAD THAN TO FOLLOW RIVULETS
QZ XK ULBZRG NH OU IG MOM SDMHMHQT WWUW BNNC NH NUYAGQ YQBHAWNL

To decrypt the message, first locate the cypher letter in the top row of the table. Then locate the key letter in the far left column. The intersection of the cypher column and the key row gives the original message letter.

There is a weak point in the above cypher. Can you spot it? The key letters “GH” map to the message letters “TO” twice in the cypher. Thus the cypher exhibits a clue:

png

This is best fixed by changing the key (making it longer and more complex) or by re-encrypting with additional keys/tables. Using Vigen, you can re-encrypt ad-infinitum.

A Trivial Code Example

A trivial code example in C++ for an ASCII table based on ABCDEFGHIJKLMNOPQRTUVWXYZ demonstrates the basic principle:


  1 #include <vector>
  2 #include <string>
  3 #include <iostream>
  4 #include <algorithm>
  5 
  6 /*
  7 Console Output should be:
  8 
  9 ABCDEFGHIJKLMNOPQRSTUVWXYZ
 10 BCDEFGHIJKLMNOPQRSTUVWXYZA
 11 CDEFGHIJKLMNOPQRSTUVWXYZAB
 12 DEFGHIJKLMNOPQRSTUVWXYZABC
 13 EFGHIJKLMNOPQRSTUVWXYZABCD
 14 FGHIJKLMNOPQRSTUVWXYZABCDE
 15 GHIJKLMNOPQRSTUVWXYZABCDEF
 16 HIJKLMNOPQRSTUVWXYZABCDEFG
 17 IJKLMNOPQRSTUVWXYZABCDEFGH
 18 JKLMNOPQRSTUVWXYZABCDEFGHI
 19 KLMNOPQRSTUVWXYZABCDEFGHIJ
 20 LMNOPQRSTUVWXYZABCDEFGHIJK
 21 MNOPQRSTUVWXYZABCDEFGHIJKL
 22 NOPQRSTUVWXYZABCDEFGHIJKLM
 23 OPQRSTUVWXYZABCDEFGHIJKLMN
 24 PQRSTUVWXYZABCDEFGHIJKLMNO
 25 QRSTUVWXYZABCDEFGHIJKLMNOP
 26 RSTUVWXYZABCDEFGHIJKLMNOPQ
 27 STUVWXYZABCDEFGHIJKLMNOPQR
 28 TUVWXYZABCDEFGHIJKLMNOPQRS
 29 UVWXYZABCDEFGHIJKLMNOPQRST
 30 VWXYZABCDEFGHIJKLMNOPQRSTU
 31 WXYZABCDEFGHIJKLMNOPQRSTUV
 32 XYZABCDEFGHIJKLMNOPQRSTUVW
 33 YZABCDEFGHIJKLMNOPQRSTUVWX
 34 ZABCDEFGHIJKLMNOPQRSTUVWXY
 35 
 36 Message: OUR FATHER WHO ART IN HEAVEN
 37     Key: PEACE
 38          ZQR BLPHCN SHM LNT EY HCWGAN
 39          OUR FATHER WHO ART IN HEAVEN
 40 
 41 Process returned 0 (0x0)   execution time : 0.344 s
 42 Press any key to continue.
 43 */
 44 
 45 std::vector<std::vector<std::string>> kTable;
 46 
 47 std::string EncryptStr(const std::string& rkKeyChar, const std::string& rkMessageChar)
 48 {
 49    // Locate the Key letter in the first vertical column.
 50    // This gives us the Alphabet row.
 51    // Reading across the Alphabet row, locate the message letter
 52    // Now read up that column to obtain the Cypher letter in the top row
 53 
 54    unsigned int uiRow = 0;
 55 
 56    // Locate the Key letter in the first vertical column.
 57    for (unsigned int i = 0; i < kTable.size(); i++)
 58    {
 59       std::vector<std::string> kRow = kTable.at(i);
 60       if (kRow[0] == rkKeyChar)
 61       {
 62          // This gives us the Alphabet row.
 63          uiRow = i;
 64          break;
 65       }
 66    }
 67 
 68    unsigned int uiTopPos = 0;
 69    std::vector<std::string> kRow = kTable.at(uiRow);
 70    for (unsigned int i = 0; i < kRow.size(); i++)
 71    {
 72       // Reading across the Alphabet row, locate the message letter
 73       if (kRow[i] == rkMessageChar)
 74       {
 75          uiTopPos = i;
 76          // Now read up that column to obtain the Cypher letter in the top row
 77          std::vector<std::string> kTopRow = kTable.at(0);
 78          return kTopRow[uiTopPos];
 79       }
 80    }
 81 
 82    return " ";
 83 }
 84 
 85 std::string DecryptStr(const std::string& rkKeyChar, const std::string& rkCypherChar)
 86 {
 87    // Work through the table in reverse fashion.
 88    // First find the Cypher letter in the top row.
 89    // Then find the Key letter in the first (far left) vertical column.
 90    // The intersection of the cypher column and the key letter row gives the original letter.
 91 
 92    // Look up the cypher letter in top row
 93    int iTopPos = -1;
 94    std::vector<std::string> kRow = kTable.at(0);
 95 
 96    for (unsigned int i = 0; i < kRow.size(); i++)
 97    {
 98       if (kRow[i] == rkCypherChar)
 99       {
100          iTopPos = (int)i;
101          break;
102       }
103    }
104 
105    if (iTopPos == -1)
106    {
107       // rkCypherChar was not found. Return a space for now.
108       return " ";
109    }
110 
111    // Find the Key letter in the first (far left) vertical column.
112    for (unsigned int i = 0; i < kTable.size(); i++)
113    {
114       std::vector<std::string> kRow = kTable.at(i);
115 
116       // The intersection of the cypher column and the key letter row gives the original letter.
117       if (kRow[0] == rkKeyChar)
118       {
119          return kRow[(unsigned int)iTopPos];
120          break;
121       }
122    }
123    return " ";
124 }
125 
126 int main(int argc, char **argv)
127 {
128    std::vector<std::string> kAlphabet;
129 
130    kAlphabet.push_back("A");
131    kAlphabet.push_back("B");
132    kAlphabet.push_back("C");
133    kAlphabet.push_back("D");
134    kAlphabet.push_back("E");
135    kAlphabet.push_back("F");
136    kAlphabet.push_back("G");
137    kAlphabet.push_back("H");
138    kAlphabet.push_back("I");
139    kAlphabet.push_back("J");
140    kAlphabet.push_back("K");
141    kAlphabet.push_back("L");
142    kAlphabet.push_back("M");
143    kAlphabet.push_back("N");
144    kAlphabet.push_back("O");
145    kAlphabet.push_back("P");
146    kAlphabet.push_back("Q");
147    kAlphabet.push_back("R");
148    kAlphabet.push_back("S");
149    kAlphabet.push_back("T");
150    kAlphabet.push_back("U");
151    kAlphabet.push_back("V");
152    kAlphabet.push_back("W");
153    kAlphabet.push_back("X");
154    kAlphabet.push_back("Y");
155    kAlphabet.push_back("Z");
156 
157    // This builds the encryption table
158    for (unsigned int i = 0; i < kAlphabet.size(); i++)
159    {
160       std::vector<std::string> kV;
161       for (unsigned int j = 0; j < kAlphabet.size(); j++)
162       {
163          kV.push_back(kAlphabet.at(j));
164       }
165 
166       // Simple rotation to the left
167       std::rotate(kV.begin(), kV.begin() + i, kV.end());
168       kTable.push_back(kV);
169    }
170 
171 
172    // This outputs the table
173    for (unsigned int i = 0; i < kTable.size(); i++)
174    {
175       std::vector<std::string> kV = kTable.at(i);
176       for (unsigned int j = 0; j < kV.size(); j++)
177       {
178          std::cout << kV.at(j);
179       }
180       std::cout << std::endl;
181    }
182 
183    // TEST TABLE ENCRYPTION
184    std::cout << std::endl;
185 
186    std::string kMessage("OUR FATHER WHO ART IN HEAVEN");
187    std::string kKey("PEACE");
188 
189    std::cout << "Message: " << kMessage << std::endl;
190    std::cout << "    Key: " << kKey << std::endl;
191 
192    std::string kEncryptStr;
193    std::string kDecryptStr;
194 
195    unsigned int uiKeyIndex = 0;
196    for (unsigned int i = 0; i < kMessage.length(); i++)
197    {
198       // Loop the key over all chars in the messgage
199       if (uiKeyIndex > kKey.length()-1)
200       {
201          uiKeyIndex = 0;
202       }
203 
204       std::string kKeyCharStr;
205       kKeyCharStr.assign(kKey,uiKeyIndex,1);
206 
207       std::string kMessageCharStr;
208       kMessageCharStr.assign(kMessage,i,1);
209       kEncryptStr.append(EncryptStr(kKeyCharStr,kMessageCharStr));
210 
211       uiKeyIndex++;
212    }
213 
214    std::cout << "         " << kEncryptStr << std::endl;
215 
216    // TEST TABLE DECRYPTION
217    uiKeyIndex = 0;
218    for (unsigned int i = 0; i < kEncryptStr.length(); i++)
219    {
220       // Loop the key over all chars in the message
221       if (uiKeyIndex > kKey.length()-1)
222       {
223          uiKeyIndex = 0;
224       }
225 
226       std::string kKeyCharStr;
227       kKeyCharStr.assign(kKey,uiKeyIndex,1);
228 
229       std::string kCypherCharStr;
230       kCypherCharStr.assign(kEncryptStr,i,1);
231       kDecryptStr.append(DecryptStr(kKeyCharStr,kCypherCharStr));
232 
233       uiKeyIndex++;
234    }
235 
236    std::cout << "         " << kDecryptStr << std::endl;
237 
238    return 0;
239 }

How strong is the encryption? Not very. For a start, the spaces are preserved, which gives away the word lengths. That might be what you want if you’re spy in 17th century France, or if you’re writing a cypher for a chapter in your unpublished novel, but modern brute force algorithms would soon crack the code. Longer keys, and multiple passes through the table using different keys, would increase the cypher strength considerably.

Towards Unicode

So much for the capital letters of the English alphabet. What about extending the table by including all ASCII characters? Or even better, why not use Unicode multilingual characters?

Taking this idea further, I thought about using customised Unicode tables for each pass. Thus the English alphabet can be mixed in with characters from any code chart, such as Greek and Coptic, Tamil, Runes, Mathematical symbols, Cuniform numbers, CJK Ideographs and Hangul Syllables:

png

About Unicode Codepoints

The Unicode character set is coded in terms of integer values, which are referred to as “Unicode Scalar Values” or USVs for short. By convention USVs are represented in hexadecimal notation, but with some modifications particular to Unicode. A Unicode code point is expressed as U+n, where n is four to six hexadecimal digits, using the digits 0–9 and uppercase letters A–F (for 10 through 15, respectively). Thus the decimal number 123 when converted to hexadecimal is 0x7B, but when using Unicode the base prefix 0x is dropped and replaced with U+, and the number is padded with leading zeros up to four digits. For example, 0x7B becomes U+007B. Leading zeros are always omitted, unless the code point has fewer than four hexadecimal digits (for example: U+0001, U+0012, U+0123, U+1234, U+12345, U+102345). The codepoint for 0x83A7 is always written as U+83A7, and never as U+083A7. Thus each USV has a hexadecimal “Codepoint” that uniquely identifies the character.

Here are a few Unicode Codepoints:

U+00D7 MULTIPLICATION SIGN
U+00D8 LATIN CAPITAL LETTER O WITH STROKE
U+00D9 LATIN CAPITAL LETTER U WITH GRAVE
U+00DA LATIN CAPITAL LETTER U WITH ACUTE
U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX
U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS

Note that Unicode convention also includes a description for each Codepoint written in capital letters. The description is shown as a tooltip when the mouse hovers over any button in the Tables.

The best online reference for all Unicode Codepoints is the Wikibooks Unicode Character Reference. As you will discover there, the Unicode codespace ranges from U+0000 to U+10FFFF which allows ‭1,114,112 characters. Some codepoints are reserved for special use or are unassigned. 66 codepoints are reserved for encoding non-characters, and 2,048 are reserved for surrogates which are used in UTF-16 encoding, leaving 1,111,998 assignable codepoints.

About Unicode Planes

As previously stated, the Unicode codespace consists of a single range of numeric values (USVs) from U+0000 to U+10FFFF. This codespace is subdivided into 17 planes of characters, each plane containing 64,000 (64K) Codepoints [64K=1024x64=65536 characters per plane]. The planes are grouped into four main allocation areas:

All other planes are reserved and no characters are assigned in them. The last two code positions of all planes are permanently set aside as noncharacters.

When designing Vigen, I decided maintain a strict correlation between the Unicode allocation system and the UI. Unicode’s 64K allocation Planes are accessed under the Planes menu which is used to load the code chart widget. Each 64K Plane is subdivided into 16 sectors of 4096K (0000-0FFF, 1000-1FFF, 2000-2FFF,... etc).

png

Hence the Planes menu provides an instant overview of the entire Unicode codespace. Note that very large character sets such as “CJK Unified Ideographs” and “Hangul Syllables”, are spread over multiple 4096K allocation blocks. Where this is the case, the menu entry is appended with [Part 1 of n] where n is the total number of parts. Thus:

png

To load all parts of a set simultaneously, hold down the Control key whilst selecting any part. For example, holding down the Control key whilst selecting the menu CJK Unified Ideographs [Part 3 of 6], will load all 6 parts into the code chart table, displaying the complete set for CJK Unified Ideographs.

Ref: The Unicode® Standard Version 13.0 – Core Specification, by The Unicode Consortium. Please consult this PDF document for further information on Unicode.

Outline of Operation

The user constructs encryption tables by selecting Codepoints from any code chart in the Unicode codespace. A seed row for the encryption table is then collated from the selections, and this row is then rotated n times, where n is the number of codepoints the row. This gives a Tableau de Vigenère for the selected characters. Multiple tables can be used for a single encryption, provided each new table contains all the characters of the previous table. In fact, a new table can be used for each character in the original message. This makes for an exceedinly strong encryption, because no character will ever map to the same cypher character twice. In other words the cypher is mutable, and unless the recipient knows the keys, tables, and rotations for each pass, the cypher is (virtually) impossible to crack.

Generating The Seed Row

png

To construct a table, you must first generate the Seed Row of the Tableau de Vigenère. The Seed Row is the top row of the table.

The Seed Row is made by selecting codepoints from any chart and clicking “Add Selection”. Only unique codepoints are added to the Seed Row (no character appears more than once). Click “Jumble” to randomise the Seed Row.

To remove a character from the Seed Row, right-click on its button and select “Remove” from the pop-up menu.

The seed row must contain, at a minimum, the characters occuring in both the message to encrypt, and the characters in the key. Additional characters will help to obsfucate the encryption even further. For example, you may add characters from another language, or symbols and “Dingbats”, so that the original message maps to obscure or unknown characters. If you do this, do not forget to “Jumble” the Seed Row.

Click “Show” to view the table generated from the Seed Row:

png

The numbers in the Tableau de Vigenère are indices to rows and columns: they are not Unicode codepoints!

Whilst you can encrypt/decrypt with tables of any dimension, the maximum dimension you can show in the UI is 1050x1050 which is table containing 1,102,500 buttons. Otherwise the UI becomes too slow.

You can select any valid codepoint in the Unicode codespace for Unicode Standard Version 13.0. Invalid, unassigned or reserved codepoints are disabled:

png

Only lit codepoints are included when clicking “Add Selection”. If a minimal number of codepoints are required it is easier to click “TABLE OFF” and then select codepoints individually. “RESET” sets the code chart back to its default state.

Generating the Cypher

Once you have generated the required Seed Row(s), click the Cypher tab. Use the large '+' and '-' buttons to add or remove tables as required. For each table, specify a Seed file and a Key phrase (which can be any length).

You can specify two seed files, A and B. But for the time being we shall just specify a single ‘Seed A’ file. ‘Seed B’ is for the SWAP feature which is discussed later.

Add as many encryption passes as desired by clicking the smaller '+' and '-' buttons (located above the Passes widget). Each pass may also Rotate the table by shifting rows Left a specified value. If you magine the row as a strip of paper joined end-to-end in a loop, or printed on the circumference of a wheel, you will have a better understanding of how the entire table rotates. A pass with a zero Rotation value uses the original table generated by the seed. Be aware that rotations are measured from the orginal seed position, and not from any previous rotation. For each particular pass you may examine the Tableau de Vigenère by clicking TABLE, or the encryption at that stage by clicking CYPHER. To generate trace files for each pass, check the box TRACE FILES.

Select a Unicode UTF-8 text file for encryption and click ENCRYPT.

You must select a valid UTF-8 text file, id est one that has been saved with UTF-8 encoding.

One of the most useful UTF-8 text editors is Notepad++ as it correctly displays control characters in the buffer:

png

The encrypted file is saved as a UTF-8 text file with the same name as the original file but with a ‘.vgn’ file extension which is short for ‘Vigen’. Thus if the original file name is ‘Whale.txt’ the encryped file name is ‘Whale.vgn’.

The decrypted file is saved as a UTF-8 text file with the same name as the encrypted file but appended with ‘-vgn-decrypt.txt’. Because there is no way of knowing the original extension of an encryped file, all Vigen decryptions are saved with a ‘.txt’ extension. The original file extension can usually be inferred from the decrypted file contents (eg ‘.htm’ or ‘.csv’, etc).

Verifying Encryptions

Vigen uses the “RSA Data Security, Inc. MD5 Message-Digest Algorithm” to verify that the decrypted file has the same MD5 hash sum as the original un-encrypted file. If the original file is ‘Whale.txt’, the decrypted file will be ‘Whale-vgn-decrypt.txt’. The MD5 sum displayed beside the ENCRYPT button is for the original un-encrypted file. The MD5 sum displayed by the DECRYPT button is for the decrypted file. Both sums should match. If they don’t, check the Log for any missing characters in the encryption seed(s) or key(s).

png

Error Reporting

Vigen keeps no record of the key(s) or seed(s) used to encrypt a file. These are kept private and known only to the sender and receiver. Therefore, when decrypting a Vigen (.vgn) file, you must use the same settings as used during encryption. The only errors Vigen can detect are missing characters in the table. And the table is generated from the seed. Therefore, if your seed does not contain the characters found in the key or message, an error will be recorded in the log. The missing characters are listed by their Unicode codepoint followed by the character itself.

Missing characters are replaced with defaults – either the Unicode codepoint U+FFFD �, or a space.

NOTE: If you are using a minimal seed of English uppercase letters, without the space character, then spaces in your original message won’t exist in table. In this case, the space characters just get turned back into spaces. If you intend preserving the space locations in the cypher, this does not imply an error, and you can safely ignore the warnings in the Log. Infact a seed without spaces was used to encrypt the first example:

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
IT IS BETTER TO GO TO THE FOUNTAIN HEAD THAN TO FOLLOW RIVULETS
QZ XK ULBZRG NH OU IG MOM SDMHMHQT WWUW BNNC NH NUYAGQ YQBHAWNL

Above: some key letters map to spaces in the message; the space character does not exist in the seed, so spaces are not encrypted. This results in the following Log warning where the codepoint for a space is listed as a missing character:

png

Missing seed characters are only reported when encrypting a message; they are not reported during decryption as this would constitute a security risk. When a missing key or seed character is detected, a red exclamation mark appears beside the Seed File entry field; this is a prompt to check the Log for details.

To add missing characters to the Seed, go back to the Tables Tab, and refer to the Unicode Codepoints in the Log. Add the missing characters from the appropriate code chart. Save the seed by rewriting the old seed file. Now go back to the Cypher Tab and ENCRYPT again.

Font Selection

The default font for displaying the Tables and Keys is Times New Roman because it appears to have the greatest number of Unicode characters. But Times New Roman doesn’t cover all codepoints. When table cell labels are drawn with blank boxes, it means codepoints are not represented by the current font. In this instance, select another font using the Fonts window:

png

Anyone familiar with FLTK will see that the Fonts UI is based on the FLTK test program “fonts” for displaying system fonts. You may optionally set the font not only for the Table and Seed Row but also for the Key entry fields.

Worked Exampes

Multiple Tables, Keys and Passes

Below: three tables have been set for the encryption, each using individual key phrases and seeds. Three passes are made through the first table, two passes through the second, and four through the third.

png

An example of using multiple passes and keys, with a table consisting of just upper and lower case letters and the space character is given below. Even with a basic table, the cypher soon becomes quite fiendish. The shifts ensure that each pass uses a different table:

Original Message: Melius est petere fontes quam sectari rivulos.

ENCRYPT
Table 1, pass 1, Shift  0: DQlOpaidsafcRYLrMvHfZtKniYtaTffRHaaZdciUvagWa
Table 1, pass 2, Shift  7: BJsBrPXjzORWLK yBxrdS ypXNzhHRZLuOhOfLgNBNiLP
Table 1, pass 3, Shift  4: x wmqBJmC ANCulBowXYIDioJ BltAQCd lAesbDFyhyB

Table 2, pass 1, Shift 11: ZUkVjLsygOYYQyofDgrPqRWQxEMrapZgADjviwZFwPKRM
Table 2, pass 2, Shift  5: axVdcfDXjMPjwDEortJSJbmHrdXqgaSjqyVEBymtEjtFX

Table 3, pass 1, Shift  5: BhR wGKNvQw QUKmIKfhzYzPJmIJXWrGzOOBErzXrvRPp
Table 3, pass 2, Shift  1: gzAYCzMCkMfBJduHKnfpXbgxbhyVETOUAqIIpDgHaktYt
Table 3, pass 3, Shift  7: YxOyytwdimatwVhex CBkWUJrAHseHlJXzVUcRUhoiSKI
Table 3, pass 4, Shift 12: OQCJqHcNubKFdGecOdQHkFhGujuTscuQARPTQshwruxWh

DECRYPT
Table 3, pass 4, Shift 12: YxOyytwdimatwVhex CBkWUJrAHseHlJXzVUcRUhoiSKI
Table 3, pass 3, Shift  7: gzAYCzMCkMfBJduHKnfpXbgxbhyVETOUAqIIpDgHaktYt
Table 3, pass 2, Shift  1: BhR wGKNvQw QUKmIKfhzYzPJmIJXWrGzOOBErzXrvRPp
Table 3, pass 1, Shift  5: axVdcfDXjMPjwDEortJSJbmHrdXqgaSjqyVEBymtEjtFX

Table 2, pass 2, Shift  5: ZUkVjLsygOYYQyofDgrPqRWQxEMrapZgADjviwZFwPKRM
Table 2, pass 1, Shift 11: x wmqBJmC ANCulBowXYIDioJ BltAQCd lAesbDFyhyB

Table 1, pass 3, Shift  4: BJsBrPXjzORWLK yBxrdS ypXNzhHRZLuOhOfLgNBNiLP
Table 1, pass 2, Shift  7: DQlOpaidsafcRYLrMvHfZtKniYtaTffRHaaZdciUvagWa
Table 1, pass 1, Shift  0: Melius est petere fontes quam sectari rivulos

An Examaple in Cyrillic

Okay, so that covers ASCII. What about Unicode? After all, that’s the whole point of the exercise. Unfortunately, I don’t speak Russian, but a little help from Google translate came up with the following phrase translations. I want to encrypt Встретимся под часами в полдень [Meet me under the clock at noon] using three tables with the following key phrases: Она любит цветы [She loves flowers]; Лес темный [The woods are dark]; and ПОЛНАЯ ЛУНА НАД МОСКВОЙ [FULL MOON OVER MOSCOW]. A seed row was generated containing all the Cyrillic characters, and many others from various code charts. This gave a table dimension of 831x831=690,561 codepoints.

Original Message: Встретимся под часами в полдень.

ENCRYPT
Table 1, pass 1, Shift  1: tЅГҠztЈЅЀү»ЎЊr¶ЪsВҐЂjÐz¿ҟxЊЀsrЯ
Table 1, pass 2, Shift  3: YJeԂB)YO@ԑȨ^W3ȞЏ9dӲIÿ¢EȰԁ5ZM4*Д
Table 1, pass 3, Shift  6: Aó;ķíÁ.ýäņǨ2(×Ǚvâ:ħô·ȧóǴĶÕ.þØÅ{

Table 2, pass 1, Shift 14: 4ÌèƤ¹ɊàΧěǛëÕdƥO´ëԚɪȀÀ±Ă®àÏɋɊn
Table 2, pass 2, Shift  9: " °ȌȰȞ­Ɋȕԛlj¿ɍэŬ#ȱ·ӘɉɈǔȸ9ӹȲ­ɋȉȚ\
Table 2, pass 3, Shift 13: ôȨȬÈǻǶȮȚǗӯƻɇșҹķÛȂȷҚȝȺƬȄЦӄȊȮțNjǮN

Table 3, pass 1, Shift  5: ÚȏȖ°ǰnjâȄƹӗưûȁҮĨ_ǫȞѾȈȭƓǰЌҫǴȖȐơ¢8
Table 3, pass 2, Shift  7: ÂǸȂɊǧƤhǰƝӁƧЂǫҥěцǖȇѤǵȢżǞsҔǠȀȇŹ($
Table 3, pass 3, Shift 35: ÆǽȊ ǺƘѫǸƝӇƺ҄DZҸĪӈǝȌѦǾȳƁǨwҙǨȆȚŭЫ,

DECRYPT
Table 3, pass 3, Shift 35: ÂǸȂɊǧƤhǰƝӁƧЂǫҥěцǖȇѤǵȢżǞsҔǠȀȇŹ($
Table 3, pass 2, Shift  7: ÚȏȖ°ǰnjâȄƹӗưûȁҮĨ_ǫȞѾȈȭƓǰЌҫǴȖȐơ¢8
Table 3, pass 1, Shift  5: ôȨȬÈǻǶȮȚǗӯƻɇșҹķÛȂȷҚȝȺƬȄЦӄȊȮțNjǮN


Table 2, pass 3, Shift 13: " °ȌȰȞ­Ɋȕԛlj¿ɍэŬ#ȱ·ӘɉɈǔȸ9ӹȲ­ɋȉȚ\
Table 2, pass 2, Shift  9: 4ÌèƤ¹ɊàΧěǛëÕdƥO´ëԚɪȀÀ±Ă®àÏɋɊn
Table 2, pass 1, Shift 14: Aó;ķíÁ.ýäņǨ2(×Ǚvâ:ħô·ȧóǴĶÕ.þØÅ{

Table 1, pass 3, Shift  6: YJeԂB)YO@ԑȨ^W3ȞЏ9dӲIÿ¢EȰԁ5ZM4*Д
Table 1, pass 2, Shift  3: tЅГҠztЈЅЀү»ЎЊr¶ЪsВҐЂjÐz¿ҟxЊЀsrЯ
Table 1, pass 1, Shift  1: Встретимся под часами в полдень

Tah Dah! It works.

png

Returning to The Fountain Head

png

Let us now revisit our first example that used a simple table of the English alphabet in upper case. In order to fix the weak point in the cypher, we shall use multiple passes and keys. First, using the keyword: SUNLIGHT. Note that despite multiple passes, the key letters “GH” always map to the same message/encryption position. Thus despite numerous re-encryptions, the weak point remains as a clue. This is best fixed by changing the key (making it longer and more complex) or by re-encrypting with an additional key/table:

Table 1 Pass 1, Rotate 0

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
IT IS BETTER TO GO TO THE FOUNTAIN HEAD THAN TO FOLLOW RIVULETS
QZ XK ULBZRG NH OU IG MOM SDMHMHQT WWUW BNNC NH NUYAGQ YQBHAWNL

Table 1 Pass 2, Rotate 4

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
QZ XK ULBZRG NH OU IG MOM SDMHMHQT WWUW BNNC NH NUYAGQ YQBHAWNL
CJ QG RWNJIZ LE AE BC JZY JWIFJSCD PSST NXEV LE ZEPTCO JCLYTSLI

Table 1 Pass 3, Rotate 6

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
CJ QG RWNJIZ LE AE BC JZY JWIFJSCD PSST NXEV LE ZEPTCO JCLYTSLI
QV LE QJBVBU LD OQ WA IMM CRGFIFQP KQSS BJXQ LD NQIOAO WQXROQLH

Table 1 Pass 4, Rotate 2

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
QV LE QJBVBU LD OQ WA IMM CRGFIFQP KQSS BJXQ LD NQIOAO WQXROQLH
AD CY LSLDQL HY YY NU DVW RIABDOAX BKON LRMH HY XYXFUK FAFGFKHC

And now for another three passes using the key word: WATER. This fixes the weak point in the cypher for the message word “TO”...

Table 2 Pass 1, Rotate 3

WATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWAT
AD CY LSLDQL HY YY NU DVW RIABDOAX BKON LRMH HY XYXFUK FAFGFKHC
HG BK OCKPXO GK BI ZB NUI USZNKRKW INYM SUWG OB WKEIEJ MDPFRRKM

Table 2 Pass 2, Rotate 1

WATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWAT
HG BK OCKPXO GK BI ZB NUI USZNKRKW INYM SUWG OB WKEIEJ MDPFRRKM
MH YU PKHZCP DU CQ JG VRS VAWXPSST NOGJ XVED TC TUJJMG REXCBWLU

Table 2 Pass 3, Rotate 9

WATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWATERWAT
QV LE QJBVBU LD OQ WA IMM CRGFIFQP KQSS BJXQ LD NQIOAO WQXROQLH
ZQ DM YAMRPY IM LG BT LWK EQBPCBIY AXWO KEUI GL YMWSCL ENNHTJUK

At this point, I thought about the possibilty of transposing the entire table into another with a different character set. A SWAP feature was implemented for this purpose...

Using The SWAP Feature

SWAP enables you to transpose one table into another. This is useful for replacing an entire character set. To use swap, you need to provide two separate seeds, A and B. Both seeds must have the same number of characters. The only restriction on using Swap is that the swapped table can contain only one pass; all subsequent tables can contain multiple passes. The key for a swapped table must be a subset of Seed A. The result of the encryption will contain a subset of Seed B.

As an example, SWAP is used to change the 26 upper case letters of the English Alphabet into Ethiopic characters, further obsfucating the message. All subsequent tables after the swaped table have keys in Ethiopic; although it is possible to swap again to another character set – perhaps one that only includes geometric shapes, etcetera.

png

ENCRYPT

Table 1 Pass 1, Rotate 0 SWAP ON. [Only 1 Pass is allowed for the Swap]. The swap is to Ethiopic characters.

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
IT IS BETTER TO GO TO THE FOUNTAIN HEAD THAN TO FOLLOW RIVULETS
QZ XK ULBZRG NH OU IG MOM SDMHMHQT WWUW BNNC NH NUYAGQ YQBHAWNL
ኆዹ ዥብ ዓቨሐዹኇራ ቸሴ ኃዓ ስራ ቴኃቴ ኻሒቴሴቴሴኆዊ ዙዙዓዙ ሐቸቸሑ ቸሴ ቸዓዩሂራኆ ዩኆሐሴሂዙቸቨ

Table 2 Pass 1, Rotate 0

ቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊ
ኆዹ ዥብ ዓቨሐዹኇራ ቸሴ ኃዓ ስራ ቴኃቴ ኻሒቴሴቴሴኆዊ ዙዙዓዙ ሐቸቸሑ ቸሴ ቸዓዩሂራኆ ዩኆሐሴሂዙቸቨ
ሒሣ ዥሢ ሐዩሴሐኇሂ ዓዓ ኆዓ ኻቸ ኻኆቴ ሑብዹቸኃሴብሒ ቕሑዙዙ ቨዓሂስ ቸሐ ዓሴሢሑራብ ሣሒሴቕሂኆዥኻ

Table 2 Pass 2, Rotate 3

ቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊ
ሒሣ ዥሢ ሐዩሴሐኇሂ ዓዓ ኆዓ ኻቸ ኻኆቴ ሑብዹቸኃሴብሒ ቕሑዙዙ ቨዓሂስ ቸሐ ዓሴሢሑራብ ሣሒሴቕሂኆዥኻ
ዊኃ ሂሐ ቨኃኆራዓዥ ሢብ ዕዥ ሣዥ ሐዕኄ ኄዓኄዙዊብሴኆ ዹቨሐዹ ዩሢኆኇ ኆዩ ሢዥቸሴቕሴ ኄዊኆኃሒቸብሑ

Table 2 Pass 3, Rotate 5

ቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊ
ዊኃ ሂሐ ቨኃኆራዓዥ ሢብ ዕዥ ሣዥ ሐዕኄ ኄዓኄዙዊብሴኆ ዹቨሐዹ ዩሢኆኇ ኆዩ ሢዥቸሴቕሴ ኄዊኆኃሒቸብሑ
ቨዹ ሣሂ ዥራሐቸዹዙ ኆሑ ሑሑ ዓቕ ቴሑዓ ሢራሴሴሂኄራሣ ኇዙስሢ ቸኆስሑ ዕዥ ኆኄዩኃኃራ ሐቨሐዕስቴዹኃ

Table 3 Pass 1, Rotate 1

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ቨዹ ሣሂ ዥራሐቸዹዙ ኆሑ ሑሑ ዓቕ ቴሑዓ ሢራሴሴሂኄራሣ ኇዙስሢ ቸኆስሑ ዕዥ ኆኄዩኃኃራ ሐቨሐዕስቴዹኃ
ሐዹ ኄራ ዥስቨዊኄዙ ሂስ ሑሢ ሂዹ ኃቴሂ ሢስኇቸኆኄስኄ ሴዙብኃ ሒኆብቴ ቨዥ ሂዕኃኃኆኆ ኇቨሒሣኃሑዹኆ

Table 3 Pass 2, Rotate 10

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ሐዹ ኄራ ዥስቨዊኄዙ ሂስ ሑሢ ሂዹ ኃቴሂ ሢስኇቸኆኄስኄ ሴዙብኃ ሒኆብቴ ቨዥ ሂዕኃኃኆኆ ኇቨሒሣኃሑዹኆ
ሂስ ስዕ ራዊሢስኃሣ ዊዥ ቨኄ ኄዩ ዹሣኄ ቸዊብሑኄዩዊስ ራሣዕሴ ሑዹዕሣ ብራ ዊብቸዥሐቕ ኆዓኃዩሒሐስሐ

Table 3 Pass 3, Rotate 3

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ሂስ ስዕ ራዊሢስኃሣ ዊዥ ቨኄ ኄዩ ዹሣኄ ቸዊብሑኄዩዊስ ራሣዕሴ ሑዹዕሣ ብራ ዊብቸዥሐቕ ኆዓኃዩሒሐስሐ
ኻብ ዓሒ ስዥኆኆራሴ ሣሣ ቸዊ ዥኆ ሒኇዥ ኄዥዙብሴሂዥዓ ዩሴዹዊ ዓሐዹኇ ሑስ ሣኻሣዹሣዕ ስዙኻብቨዊብሣ

Table 3 Pass 4, Rotate 10

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ሂስ ስዕ ራዊሢስኃሣ ዊዥ ቨኄ ኄዩ ዹሣኄ ቸዊብሑኄዩዊስ ራሣዕሴ ሑዹዕሣ ብራ ዊብቸዥሐቕ ኆዓኃዩሒሐስሐ
ኇዊ ቸኻ ኇስቕሣሣኆ ዩዓ ዙሢ ቴኄ ኃብቴ ዩስኄዹራቕስቸ ዥኆብቴ ዊብብብ ሐኇ ዩሴሢስኆኃ ሴሣሒሒሂኻዊኆ

DECRYPT

Table 3 Pass 4, Rotate 10

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ኇዊ ቸኻ ኇስቕሣሣኆ ዩዓ ዙሢ ቴኄ ኃብቴ ዩስኄዹራቕስቸ ዥኆብቴ ዊብብብ ሐኇ ዩሴሢስኆኃ ሴሣሒሒሂኻዊኆ
ኻብ ዓሒ ስዥኆኆራሴ ሣሣ ቸዊ ዥኆ ሒኇዥ ኄዥዙብሴሂዥዓ ዩሴዹዊ ዓሐዹኇ ሑስ ሣኻሣዹሣዕ ስዙኻብቨዊብሣ

Table 3 Pass 3, Rotate 3

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ኻብ ዓሒ ስዥኆኆራሴ ሣሣ ቸዊ ዥኆ ሒኇዥ ኄዥዙብሴሂዥዓ ዩሴዹዊ ዓሐዹኇ ሑስ ሣኻሣዹሣዕ ስዙኻብቨዊብሣ
ሂስ ስዕ ራዊሢስኃሣ ዊዥ ቨኄ ኄዩ ዹሣኄ ቸዊብሑኄዩዊስ ራሣዕሴ ሑዹዕሣ ብራ ዊብቸዥሐቕ ኆዓኃዩሒሐስሐ

Table 3 Pass 2, Rotate 10

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ሂስ ስዕ ራዊሢስኃሣ ዊዥ ቨኄ ኄዩ ዹሣኄ ቸዊብሑኄዩዊስ ራሣዕሴ ሑዹዕሣ ብራ ዊብቸዥሐቕ ኆዓኃዩሒሐስሐ
ሐዹ ኄራ ዥስቨዊኄዙ ሂስ ሑሢ ሂዹ ኃቴሂ ሢስኇቸኆኄስኄ ሴዙብኃ ሒኆብቴ ቨዥ ሂዕኃኃኆኆ ኇቨሒሣኃሑዹኆ

Table 3 Pass 1, Rotate 1

ቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹኇዕቨሐዹ
ሐዹ ኄራ ዥስቨዊኄዙ ሂስ ሑሢ ሂዹ ኃቴሂ ሢስኇቸኆኄስኄ ሴዙብኃ ሒኆብቴ ቨዥ ሂዕኃኃኆኆ ኇቨሒሣኃሑዹኆ
ቨዹ ሣሂ ዥራሐቸዹዙ ኆሑ ሑሑ ዓቕ ቴሑዓ ሢራሴሴሂኄራሣ ኇዙስሢ ቸኆስሑ ዕዥ ኆኄዩኃኃራ ሐቨሐዕስቴዹኃ

Table 2 Pass 3, Rotate 5

ቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊ
ቨዹ ሣሂ ዥራሐቸዹዙ ኆሑ ሑሑ ዓቕ ቴሑዓ ሢራሴሴሂኄራሣ ኇዙስሢ ቸኆስሑ ዕዥ ኆኄዩኃኃራ ሐቨሐዕስቴዹኃ
ዊኃ ሂሐ ቨኃኆራዓዥ ሢብ ዕዥ ሣዥ ሐዕኄ ኄዓኄዙዊብሴኆ ዹቨሐዹ ዩሢኆኇ ኆዩ ሢዥቸሴቕሴ ኄዊኆኃሒቸብሑ

Table 2 Pass 2, Rotate 3

ቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊ
ዊኃ ሂሐ ቨኃኆራዓዥ ሢብ ዕዥ ሣዥ ሐዕኄ ኄዓኄዙዊብሴኆ ዹቨሐዹ ዩሢኆኇ ኆዩ ሢዥቸሴቕሴ ኄዊኆኃሒቸብሑ
ሒሣ ዥሢ ሐዩሴሐኇሂ ዓዓ ኆዓ ኻቸ ኻኆቴ ሑብዹቸኃሴብሒ ቕሑዙዙ ቨዓሂስ ቸሐ ዓሴሢሑራብ ሣሒሴቕሂኆዥኻ

Table 2 Pass 1, Rotate 0

ቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊቸዓዩሂራኆዊ
ሒሣ ዥሢ ሐዩሴሐኇሂ ዓዓ ኆዓ ኻቸ ኻኆቴ ሑብዹቸኃሴብሒ ቕሑዙዙ ቨዓሂስ ቸሐ ዓሴሢሑራብ ሣሒሴቕሂኆዥኻ
ኆዹ ዥብ ዓቨሐዹኇራ ቸሴ ኃዓ ስራ ቴኃቴ ኻሒቴሴቴሴኆዊ ዙዙዓዙ ሐቸቸሑ ቸሴ ቸዓዩሂራኆ ዩኆሐሴሂዙቸቨ

Table 1 Pass 1, Rotate 0 SWAP ON. [Only 1 Pass is allowed for the Swap]. The swap is back from Ethiopic characters to English.

SUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGHTSUNLIGH
ኆዹ ዥብ ዓቨሐዹኇራ ቸሴ ኃዓ ስራ ቴኃቴ ኻሒቴሴቴሴኆዊ ዙዙዓዙ ሐቸቸሑ ቸሴ ቸዓዩሂራኆ ዩኆሐሴሂዙቸቨ
QZ XK ULBZRG NH OU IG MOM SDMHMHQT WWUW BNNC NH NUYAGQ YQBHAWNL
IT IS BETTER TO GO TO THE FOUNTAIN HEAD THAN TO FOLLOW RIVULETS

You might even use Swap to convert your encrypted message into Egyptian hieroglyphs...

png

THIS IS A VIGEN ENCRYPTED FILE

𓁗𓀐𓐢𓎹𓈠𓏩𓀋𓀈𓎹𓍺𓎠𓊦𓅮𓍑𓈎𓄢𓐣𓂧𓐈𓄼𓀬𓃍𓐛𓆠𓈤𓈟𓈍𓇙𓄯𓐩𓄰𓍝𓁺𓃫𓈌𓇗𓂟𓎷𓐐𓉦𓌬𓄵𓈌𓌅𓄕𓄾𓅝𓆾𓆨𓄞𓍌𓃏𓌇𓀛𓏭𓃼𓁠𓌺𓏕𓌈𓆪𓌭𓆎𓐛𓀞𓃐𓊲𓁍𓄪𓆔𓊹𓃱𓂎𓁷𓎡𓈷𓀓𓈚𓀠𓅀
𓉭𓏮𓏡𓎨𓎞𓁺𓅂𓅮𓀬𓏕𓀗𓎮𓉩𓎵𓍬𓉘𓉣𓇃𓏰𓌟𓀉𓌘𓊀𓀌𓁑𓏵𓇐𓁾𓆋𓌢𓋤𓇀𓐛𓄺𓃊𓍇𓌯𓃊𓈟𓏞𓂦𓌸𓅝𓆢𓋭𓄋𓈇𓁳𓐗𓍡𓎮𓌠𓉏𓋖𓏁𓊰𓌩𓌐𓏄𓁱𓄧𓀽𓇍𓅨𓋤𓈇𓄉𓅶𓈟𓉾𓐠𓉍𓂩𓌴𓁰𓃼𓈟𓏔𓐃𓌃
𓏖𓁃𓍈𓇺𓈇𓄉𓐗𓍳𓌅𓅀𓀟𓋩𓈆𓁷𓍀𓋙𓂞𓊞𓍒𓁦𓆱𓉉𓀷𓎨𓃜𓇲𓇄𓇿𓈋𓎾𓃓𓁫𓁮𓐮𓈌𓅗𓂎𓎇𓆍𓊓𓉥𓅌𓈍𓆮𓄋𓅒𓍘𓏚𓆕𓃵𓏯𓃕𓏛𓈟𓉧𓆜𓈡𓎉𓌲𓌗𓌚𓇖𓋋𓃕𓈝𓅆𓉹𓇏𓇠𓋄𓊽𓅀𓀛𓏮𓋩𓏐𓌃𓁩𓌗𓏽
𓉹𓎴𓉫𓊖𓁒𓃾𓌍𓍌𓊁𓉾𓇝𓉐𓎊𓈟𓆠𓋨𓁷𓇺𓈮𓀓𓉡𓂊𓅦𓅫𓆭𓆛𓃊𓐪𓃺𓐮𓀐𓁐𓀛𓎺𓌃𓀞𓁨𓌔𓂈𓎛𓃫𓅧𓍘𓐭𓎷𓃣𓐀𓄂𓈋𓎮𓎾𓃛𓉆𓋱𓅦𓂑𓀅𓇍𓏏𓂎𓅇𓆉𓈑𓅾𓊾𓋃𓎮𓀐𓇩𓎾𓎘𓁫𓃓𓄉𓆵𓄐𓉚𓈺𓎱𓋄
𓏜𓏸𓌍𓂡𓈚𓊽𓅄𓃞𓐣𓂼𓈮𓅎𓉺𓈬𓀷𓋸𓌬𓄋𓐆𓎞𓁻𓎾𓃄𓈺𓋠𓏌𓈟𓊸𓀅𓁫𓂴𓏑𓋝𓈠𓀻𓏓𓊟𓍕𓀅𓂻𓂤𓋣𓊀𓏰𓃓𓏽𓌂𓄝𓂃𓏄𓄋𓁗𓆽𓁾𓄉𓐕𓇞𓇩𓊈𓏞𓊼𓈇𓇿𓀮𓈝𓏂𓂖𓂪𓅄𓆾𓌗𓌳𓊽𓂲𓁔𓅚𓌯𓃊𓎾𓊫
𓇁𓁷𓍀𓐞𓎷𓁗𓈇𓇙𓄯𓐩𓁾𓄢𓆭𓅻𓀐𓊈𓎧𓆜𓏠𓈇𓁻𓆍𓈌𓂐𓇐𓀵𓌁𓁔𓌌𓎦𓈇𓄉𓐗𓈟𓇿𓆩𓎄𓁹𓏕𓁽𓈑𓅧𓍹𓐪𓃸𓌃𓅦𓌤𓉀𓆗𓐙𓉒𓍁𓉆𓄬𓅗𓄬𓏰𓀺𓈄𓉭𓉞𓏒𓊐𓆝𓌲𓎠𓁱𓃏𓉪𓋞𓂼𓉩𓎿𓏬𓉽𓇗𓁒𓐛𓍡
𓋴𓋤𓐀𓌃𓁑𓏲𓊞𓄧𓄂𓊩𓐉𓉾𓐛𓍎𓆲𓍇𓎃𓀮𓅩𓁐𓈠𓄟𓍐𓉤𓀸𓄻𓏯𓅋𓍵𓌟𓋶𓎶𓆷𓇟𓎛𓂴𓌧𓂟𓀳𓃴𓉹𓁆𓈼𓋔𓆑𓄾𓀍𓁛𓇩𓄗𓏨𓆌𓌴𓄾𓁥𓆩𓐫𓂖𓈕𓀈𓀋𓌸𓌗𓁙𓈇𓄉𓋞𓍳𓃺𓐮𓉧𓃊𓉆𓅐𓄓𓎐𓊷𓊞𓏕𓌃
𓂡𓀴𓇐𓊘𓃛𓃷𓀐𓇿𓊳𓆌𓈅𓋄𓊧𓅳𓋤𓈷𓈌𓇍𓁐𓂲𓃹𓐍𓆠𓍸𓐭𓋕𓇬𓉀𓆕𓂾𓃁𓀚𓂐𓁧𓌍𓎦𓇂𓆝𓍳𓎭𓉃𓊽𓉚𓍞𓈠𓉑𓎡𓁸𓍌𓂶𓇬𓈄𓂎𓍎𓀋𓃷𓉽𓈘𓍵𓊦𓏸𓅶𓀗𓊖𓆎𓏸𓎾𓐭𓊊𓀻𓁾𓏇𓄥𓋑𓎢𓉫𓈞𓄴𓉌𓁫
𓈽𓇔𓐉𓂬𓏽𓏂𓆭𓏺𓈔𓐛𓉇𓊏𓀛𓇇𓌩𓏪𓂑𓎥𓈩𓋲𓀔𓌶𓊄𓍛𓐍𓀡𓅍𓁔𓋕𓂼𓉧𓈌𓀃𓇲𓁊𓈿𓐭𓆾𓏅𓄓𓅌𓐞𓏨

DECRYPT 1

А%ädzгȶ¹ѣˮƤˌ1řȐÚѱқƐŊâ⁩ѐЩɍnjȭҫↁƱǢҫýɍŚdz⁞˩зxĥɍЩ⁍ǮТßўӣǮ⅓ ÎǾⅥťɎ6âůгRхğ?ЍŇłǮř ÎǾⅥťɎ⁀⁩ѐť⁍nj?⁉ʶ4Ǯ҅ßˬӨ⁩áǤˀ⁞ijŬ?ӥӈƌnjʽȐʳҟ˘ƐɎǮĶ⁩ß⁈ƛ҂ТǏƤпʼҫȐгx¤Ѓ<зⅺѻ⁞ⅺǢↇƲƤˌⅪҒƘ⁌ˬӨӚʼⅼⅥѐťĠↇ⅛⁋ӈƱз‖§ѐȳ⁩ĞӚğǾ⁝ß⁞Ġ⅛ӥҪȸnjҺњѐâхƐӚʼȳ˘ɍ⁞оƈűCîƴnjŶ§ųâů⁞OxÈɍťÔȗálX6ҫ§Ťʿdz˂фŚ⁩ɍťĠ6?ˮljӅʼ˻ⅳʳǾůĽʶ′ˬхÚɍƈТ҃ljƱЊ‖өßˬⅥbɎǮѱdzųЩɍӝ⅛҃¾ƌŬҺƬѐâǤ⁞ŊǪŘхß⁞‚ʼ‐ßîƌnjʽ⁧г⁀×˂ӚǪxʷгƐлʼↇ‖ŇȸғѴ§Ř҇ĽȟnjÈⅭƖɍ˞‐Ǐↁȸҫ§Îѽѽ˂Ҫʼx⁝гĞʼↇ‖ƤƌⅪ⅓Ƙųï҇ĽЬŬŚdzÚƐɍȗ?ȵĒӣ′ҒŪɍȷх⁈ЬⅪˬⅥŤ⁞ijŬ‐⁉ↁXⅪҒȹųĶ⁩Щƴ′Ǿ⁝°⁞‚ʼȭҫↁқ6⅓§ų¯È‏ɎnjѽѽɍťɍѴáǰʼҫ˥ɍˬdzЩʶ6ï҇ѐЩ`Ňßlƌ˅҅гŚǓ⁞ě҂Ǿ⁝ѐ‏–Ŵ⅛ľƤ©6±өɍˬⅥbɎŬǾÈгſǑǪ‐ӥŇ4′ҒđÚˬ˘ſцǮâǤгЩǑ¬ȭálX±ѯˀȳÈöƲDžĐӂӎRÀʼǭCѵӣǮҺњгƬ⁞ċǮʿdzÚĞ%Ȟħ҂ↁÐз‖өѐѱdzťʶʼxĥгʹĠ6ↇҫӐƌⅲ⅓ⅳųâů⁞ќŚʷʳťхnjуáŴÃƈ]⁧°Řę⁞Ь҂ŘхⅭĽ–ğ⅛CӐƌnjʽ⁧гѱⅥЃ<ÅŘ⁝Îſ¹′⅛ËÒˌÅҺ҅ʳŘ҇⁞ Ⅺ¯қⅭ‏ҹȗDZƿↁȄʼђȐÚѱÈ⁞ěʰˬӨˀ˂ɍǯ‐Ǐl҆ʼúⅭǠĩ⁩⁌ě¬áʷɍťĠ6њƿↁˆƲЄƚ‑˨

DECRYPT 2

˺ƛìⅷǑѦbʼnѽīnjˎŝV ǺiaѦƀʼnфä‑ɋ‑⁋҇˜Śƛ˚ȷŎрưⅷȄŧғ⅖ĺрɋҽƉ(Ē⁘҄ƉʿЃƧѼ¡Ѣx҂ф¿ǑƤ⅑˃⁃ìәƉVЃƧѼ¡Ѣxʼn˃ä‑Ӓҽ⁋⁃ÇȵĀƉuġƨʰȔҖ¸ʼn ȫʷ´‪И⁃ыⅪм⁋ӛ ‘˙ѦxƉ‴äƨҦʸu(ӹnjêŪȷ Ǒ⅖ǧĤ҃ғŰȯLj´ӑ˚ǴФnjˎŠòН‒ʰȔҖ″Ū¡‑ӒȣǾűďⅪƛғyȢ‑Õä⁣″˃Ѽņƨ´ȣʼnűы※ŭ⁋ȅd‑ф⁜Ѧ″ŪÕ˙р´ȤƕĩhƱ⁋~ȢƼф¿ȄҔʼn⅖ѴрӒӓ⁧Ɔ⁖Ↄë҂ȷȢˁÆⅷЛŌʼnưäрӒȣ҂⁃īĈÛŪŌǝ‘Ѽ¿ūßӐʰ⁜Ǻ˦‑Ȥ(˩Ĉƛķy ƨʰ¡ҼxƉiⅷƼɋ‑ȿű˩ћмИȅҶ‑фȫȄƀNjӾ⁜ƨ´ŪcĒhм⁋ӛ<Ǒ˃⁖Л″Nj⅖ⅪǑɁÔŪǴҤìŭǶ ȢӧӾҀūƫʼnǤѴÛŹ‑ņcӹŚŭʼnȷȢƧǐiЛiŪ⅖ņǑNjмŪǴҤnjмŠʿНƼȓҀūDZИưⅷǺɁ‑⁧⁃dž˰҄Ӑòȝрⅼ⁜ӻDZŠʰ¡ˁ´‪ИcÇŚëŠòûƼ‴äƽƘӐѼņ˒´Ū҇˜Śdz҂ʿȢƼ⅜ѴÕx⁋ǐiрӒ‑ʼnå⁖ ȀŪȷƧрʰⅷƽß҂ȓҀ‑ɋǵ⅜LJĒↃмӣßġǑư҈ȄDŽuѼņ‑Ю˨ҡű˺njҀ҂ĺ рʰ¡ҼxИѼѴǑ NjcыìĀӐòǚǺʰ˙ↁȺƉфȫǑɋѰ҇⁖ↃëʼnĺȻʷÕѴѣѠѼȯʷ‪ƤСŪÑĩĖ҄ƉȅdǑõȯȄ˸ƉÆⅷǺNjúŨңȸŚӜғy ‑iⅷѢßŪ⅖ĺǑ8ȣ҂Ǵ˜ŖмljʿǝƼф¿ȄↈʼnưⅪ‘Ӓ⅑⁋Ǜ⁖ǓнȤ<˒Ӿ‵ȄDZuӾ⁜ÛЁ˨˃űĩŖм⁋ӛ<Ǒi¡Ĥ҃⅜ӾņƧ bӐűȡ⁙ˎ⅜ȅġ‘ӾҀȄӥŠ⅜aÛЮƻ⁧ªⅯŚ⁇ŪӼ ǺiѴȄDŽ*ʰȔʷȘ‑ˉcӹↃíŪƕàĤ5äyDŽѰ ⅪрӒȣ҂ЈⅯŚˮ»/н˒ȯ

DECRYPT 3

⁒cȈѣŠґvǜƁ⁋ҵ҅ⅭiÙ>Îǁ˚ǜȩⅵӔĿ‰ Ёӥřo↉Ӷ¾⁂ҦѣьȊɎҠⅴ⁂ĿЊȹñӴö˛ȹŞĬFƖіŕҬⅽȩ⁂Šǯ⁂ ЇӓƨÞȹiĬFƖіŕҬǜѐⅵӔњЊ ЇõļȏȹѕѱɄ⅙Ъ“ƭǜӵ˿ҚÍŜђЇ⅚Ҿҡ ÙƂѶđҬȹӻⅵɄ‧ѻ¡ñҵÓ]ӶÙŠҠŸOôɎЛýↁÍ‱↉ⅣÝҵ҅Ȳӑ%r⅙Ъ“Ȝ]ĜіӔњƾʽ⁂ƒҾoɎĴ⁋Ӕ`ⅵ[Ȝ ƖäɄÍƾǜ⁂⅚ȦȂ ǀⅯӔȩⅥȜ]`đ⁂ÍųĘƏӀĚ⁅ Ⅱ⁋˓ȩ⁂ьȐǜҠ⅛⁂њWŗʶȥЗⅤⅽӶ⁋JтѣƁǜҦⅵ⁂њƾⅽЇ⁋Ђӏ]ƔøƂƖ⁂ңЌǗ⅙Ⅵ>ј‰Ęñ:Ђo.ĴȃɄ⅙іҶҬȹÎѣ˓Ŀ‰À⁂:ȶҡђǀƚӔȩ˿ь˚ӜǂⅥɄÍˉ]иӴĚҡ FŠѐǤƁȜӜҠ˲Š\ą]ⅣřƨȂȫˈ⁋ɈǂÄңѫǜ―⅛;Ҙ‰ȟиřȂǜӶ⁋F⁂xƁŪ]ҠäŠ&ǽ]ⅣřҵҡȲŞ%˓SÄңDžђҦѣ>\‰ŗЇÕǩ˛Ǘӑк⁂¶Ⅵ⅐DžȲ⅙іJÍŜђиõřⅤȲӑÀ˓ӻⅵ⁂˄ǗƖäЎÍˉ]Ёӥř⁞ⅽŞ⁋˓R⅛ҳҬ ⁂x⁂њ‰ǜ¿ȥȠu]Ӷ⁂⁂⅙ѣ⁂ЌⅽSÄӔĿ´Ŏ˱ӴЗҡҠ⁨ѱŠҦӞь⁁¡ƖäӔСÜĩ⁂íҵӷⅽʻȃ⁂⅙іҶҬђƖ⅛ŠӰӜи⅚ƨȏǗӑ7>⅙đĮҋȹȩ˿ŠĿӰ⁂ЁȥЗⅤǜʻѠҚ`⅛ǰƉł˔ųӆǯⅩ]ſӀ⁂˛ȹǀⅯŠȵýьїȹтѣ>&⁨­ȤОř‾ɎĴȃӔÎѣŕЌ]ҠⅴŠⅾƾⅽⅣӥ¹ҡǕŞø˓ȩ⁂ь<ǜҦ˲Ƃњ⁂ ӝȥЎ⁂ĘӚFЎǂ‸ьDž¡ǂⅥ;ƆÜ ⁂Ӏ¹ҡ FŠÎіOôŎǂäFvǗ⁂à⁠҅ŎǀѱƂǂÄьⅿȲRǁ;СҁŗŌnř˲]ↇÙ>Î⅛ь⁁Ũ⅙ЪҚȚ‰ȖиЗö]Гӱ⁤āⅵŅ⁁⁂ӵ˲⁂њƾⅽþnřѩƀ¸Ⅻo˙ý

DECRYPT 4 - Original Message

“The problem/condition is the extreme professionalisation and rigidification of institutions through which thought is supposed to occur... Extreme to the point, where it begins to contaminate the fluidity and looseness that freedom entails; fluidity and looseness of ideas – of having ideas – and the freedom to think. Velikovsky was not taken on by the establishment simply because of what he was saying – he was also taken on by the establishment (in my opinion) because of his audacity in having such thoughts.”

[Dr. William M. Birenbaum. President of Staten Island Community College, speaking in the documentary ‘Immanuel Velikovsky – Bonds of the Past’ (CBC Documentary 1972)].

How Vigen Might Be Used

The sender determines the table seeds and message keys. Keys may be based on words from the pages of a book, for example “Tess of The D’Urbervilles” by Thomas Hardy...

TABLE 1: Seed: Full_ASCII.bin
KEY: first seven words from paragraph 3 of Chapter 20:
Thus passed the leafy time when arborescence
Passes 5
Pass 1: Rotation: 3
Pass 2: Rotation: 12
Pass 3: Rotation: 7
Pass 4: Rotation: 41
Pass 5: Rotation: 15

TABLE 2: Seed: Full_ASCII_Plus_Cyrillic.bin
KEY: first six words from paragraph 3 of Chapter 25:
He sat on the east gate
Passes 3
Pass 1: Rotation: 4
Pass 2: Rotation: 23
Pass 3: Rotation: 17

TABLE 3: Seed: Full_ASCII_Plus_Cyrillic_Plus_Ethiopic.bin
KEY: first seven words from paragraph 3 of Chapter 2:
This fertile and sheltered tract of country
Passes 8
Pass 1: Rotation: 1
Pass 2: Rotation: 30
Pass 3: Rotation: 13
Pass 4: Rotation: 2
Pass 5: Rotation: 12
Pass 6: Rotation: 55
Pass 7: Rotation: 123
Pass 7: Rotation: 19

The sender then posts the seeds and key details on a flash drive via LAND MAIL, to the recipient. Encrypted messages may then be sent via email. NOTE: There are no public keys; only the sender and recipient can encrypt/decrypt messages.


About Surrogates

The Wikibooks Unicode Character Reference states:

START QUOTE

“ Unicode range D800–DFFF is used for surrogate pairs in UTF-16 (used by Windows) and CESU-8 transformation formats, allowing these encodings to represent the supplementary plane code points, whose values are too large to fit in 16 bits. A pair of 16-bit code points — the first from the high surrogate area (D800–DBFF), and the second from the low surrogate area (DC00–DFFF) — are combined to form a 32-bit code point from the supplementary planes.

Unicode and ISO/IEC 10646 do not assign actual characters to any of the code points in the D800–DFFF range — these code points only have meaning when used in surrogate pairs. Hence an individual code point from a surrogate pair does not represent a character, is invalid unless used in a surrogate pair, and is unconditionally invalid in UTF-32 and UTF-8 (if strict conformance to the standard is applied).”

END QUOTE