aboutsummaryrefslogtreecommitdiffstats
path: root/src/cipher/turing
diff options
context:
space:
mode:
Diffstat (limited to 'src/cipher/turing')
-rw-r--r--src/cipher/turing/modinfo.txt11
-rw-r--r--src/cipher/turing/tur_tab.cpp104
-rw-r--r--src/cipher/turing/turing.cpp274
-rw-r--r--src/cipher/turing/turing.h46
4 files changed, 435 insertions, 0 deletions
diff --git a/src/cipher/turing/modinfo.txt b/src/cipher/turing/modinfo.txt
new file mode 100644
index 000000000..95ae2cf48
--- /dev/null
+++ b/src/cipher/turing/modinfo.txt
@@ -0,0 +1,11 @@
+realname "Turing"
+
+define TURING
+
+load_on auto
+
+<add>
+tur_tab.cpp
+turing.cpp
+turing.h
+</add>
diff --git a/src/cipher/turing/tur_tab.cpp b/src/cipher/turing/tur_tab.cpp
new file mode 100644
index 000000000..08793f59d
--- /dev/null
+++ b/src/cipher/turing/tur_tab.cpp
@@ -0,0 +1,104 @@
+/*************************************************
+* Tables for Turing *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/turing.h>
+
+namespace Botan {
+
+const byte Turing::SBOX[256] = {
+ 0x61, 0x51, 0xEB, 0x19, 0xB9, 0x5D, 0x60, 0x38, 0x7C, 0xB2, 0x06, 0x12,
+ 0xC4, 0x5B, 0x16, 0x3B, 0x2B, 0x18, 0x83, 0xB0, 0x7F, 0x75, 0xFA, 0xA0,
+ 0xE9, 0xDD, 0x6D, 0x7A, 0x6B, 0x68, 0x2D, 0x49, 0xB5, 0x1C, 0x90, 0xF7,
+ 0xED, 0x9F, 0xE8, 0xCE, 0xAE, 0x77, 0xC2, 0x13, 0xFD, 0xCD, 0x3E, 0xCF,
+ 0x37, 0x6A, 0xD4, 0xDB, 0x8E, 0x65, 0x1F, 0x1A, 0x87, 0xCB, 0x40, 0x15,
+ 0x88, 0x0D, 0x35, 0xB3, 0x11, 0x0F, 0xD0, 0x30, 0x48, 0xF9, 0xA8, 0xAC,
+ 0x85, 0x27, 0x0E, 0x8A, 0xE0, 0x50, 0x64, 0xA7, 0xCC, 0xE4, 0xF1, 0x98,
+ 0xFF, 0xA1, 0x04, 0xDA, 0xD5, 0xBC, 0x1B, 0xBB, 0xD1, 0xFE, 0x31, 0xCA,
+ 0xBA, 0xD9, 0x2E, 0xF3, 0x1D, 0x47, 0x4A, 0x3D, 0x71, 0x4C, 0xAB, 0x7D,
+ 0x8D, 0xC7, 0x59, 0xB8, 0xC1, 0x96, 0x1E, 0xFC, 0x44, 0xC8, 0x7B, 0xDC,
+ 0x5C, 0x78, 0x2A, 0x9D, 0xA5, 0xF0, 0x73, 0x22, 0x89, 0x05, 0xF4, 0x07,
+ 0x21, 0x52, 0xA6, 0x28, 0x9A, 0x92, 0x69, 0x8F, 0xC5, 0xC3, 0xF5, 0xE1,
+ 0xDE, 0xEC, 0x09, 0xF2, 0xD3, 0xAF, 0x34, 0x23, 0xAA, 0xDF, 0x7E, 0x82,
+ 0x29, 0xC0, 0x24, 0x14, 0x03, 0x32, 0x4E, 0x39, 0x6F, 0xC6, 0xB1, 0x9B,
+ 0xEA, 0x72, 0x79, 0x41, 0xD8, 0x26, 0x6C, 0x5E, 0x2C, 0xB4, 0xA2, 0x53,
+ 0x57, 0xE2, 0x9C, 0x86, 0x54, 0x95, 0xB6, 0x80, 0x8C, 0x36, 0x67, 0xBD,
+ 0x08, 0x93, 0x2F, 0x99, 0x5A, 0xF8, 0x3A, 0xD7, 0x56, 0x84, 0xD2, 0x01,
+ 0xF6, 0x66, 0x4D, 0x55, 0x8B, 0x0C, 0x0B, 0x46, 0xB7, 0x3C, 0x45, 0x91,
+ 0xA4, 0xE3, 0x70, 0xD6, 0xFB, 0xE6, 0x10, 0xA9, 0xC9, 0x00, 0x9E, 0xE7,
+ 0x4F, 0x76, 0x25, 0x3F, 0x5F, 0xA3, 0x33, 0x20, 0x02, 0xEF, 0x62, 0x74,
+ 0xEE, 0x17, 0x81, 0x42, 0x58, 0x0A, 0x4B, 0x63, 0xE5, 0xBE, 0x6E, 0xAD,
+ 0xBF, 0x43, 0x94, 0x97 };
+
+const byte Turing::OFFSETS[272] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x0C, 0x0E, 0x0F,
+ 0x10, 0x00, 0x00, 0x00, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
+ 0x0D, 0x00, 0x02, 0x03, 0x04, 0x00, 0x00, 0x00, 0x0A, 0x0B, 0x0C, 0x0D,
+ 0x0E, 0x0F, 0x10, 0x00, 0x01, 0x05, 0x07, 0x08, 0x09, 0x00, 0x00, 0x00,
+ 0x0F, 0x10, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0A, 0x0C, 0x0D,
+ 0x0E, 0x00, 0x00, 0x00, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
+ 0x0B, 0x0F, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x08, 0x09, 0x0A, 0x0B,
+ 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x03, 0x05, 0x06, 0x07, 0x00, 0x00, 0x00,
+ 0x0D, 0x0E, 0x0F, 0x10, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08, 0x0A, 0x0B,
+ 0x0C, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0D, 0x0F, 0x10, 0x00, 0x00, 0x00, 0x00, 0x06, 0x07, 0x08, 0x09,
+ 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x01, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00,
+ 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x00, 0x01, 0x02, 0x06, 0x08, 0x09,
+ 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+ 0x07, 0x0B, 0x0D, 0x0E, 0x0F, 0x00, 0x00, 0x00, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x10, 0x01, 0x02, 0x03, 0x00, 0x00, 0x00,
+ 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x00, 0x04, 0x06, 0x07,
+ 0x08, 0x00, 0x00, 0x00, 0x0E, 0x0F, 0x10, 0x00, 0x01, 0x02, 0x03, 0x04,
+ 0x05, 0x09, 0x0B, 0x0C, 0x0D, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x05,
+ 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0E, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x02, 0x04, 0x05,
+ 0x06, 0x00, 0x00, 0x00, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x00, 0x01, 0x02,
+ 0x03, 0x07, 0x09, 0x0A, 0x0B, 0x00, 0x00, 0x00 };
+
+const u32bit Turing::Q_BOX[256] = {
+ 0x1FAA1887, 0x4E5E435C, 0x9165C042, 0x250E6EF4, 0x5957EE20, 0xD484FED3,
+ 0xA666C502, 0x7E54E8AE, 0xD12EE9D9, 0xFC1F38D4, 0x49829B5D, 0x1B5CDF3C,
+ 0x74864249, 0xDA2E3963, 0x28F4429F, 0xC8432C35, 0x4AF40325, 0x9FC0DD70,
+ 0xD8973DED, 0x1A02DC5E, 0xCD175B42, 0xF10012BF, 0x6694D78C, 0xACAAB26B,
+ 0x4EC11B9A, 0x3F168146, 0xC0EA8EC5, 0xB38AC28F, 0x1FED5C0F, 0xAAB4101C,
+ 0xEA2DB082, 0x470929E1, 0xE71843DE, 0x508299FC, 0xE72FBC4B, 0x2E3915DD,
+ 0x9FA803FA, 0x9546B2DE, 0x3C233342, 0x0FCEE7C3, 0x24D607EF, 0x8F97EBAB,
+ 0xF37F859B, 0xCD1F2E2F, 0xC25B71DA, 0x75E2269A, 0x1E39C3D1, 0xEDA56B36,
+ 0xF8C9DEF2, 0x46C9FC5F, 0x1827B3A3, 0x70A56DDF, 0x0D25B510, 0x000F85A7,
+ 0xB2E82E71, 0x68CB8816, 0x8F951E2A, 0x72F5F6AF, 0xE4CBC2B3, 0xD34FF55D,
+ 0x2E6B6214, 0x220B83E3, 0xD39EA6F5, 0x6FE041AF, 0x6B2F1F17, 0xAD3B99EE,
+ 0x16A65EC0, 0x757016C6, 0xBA7709A4, 0xB0326E01, 0xF4B280D9, 0x4BFB1418,
+ 0xD6AFF227, 0xFD548203, 0xF56B9D96, 0x6717A8C0, 0x00D5BF6E, 0x10EE7888,
+ 0xEDFCFE64, 0x1BA193CD, 0x4B0D0184, 0x89AE4930, 0x1C014F36, 0x82A87088,
+ 0x5EAD6C2A, 0xEF22C678, 0x31204DE7, 0xC9C2E759, 0xD200248E, 0x303B446B,
+ 0xB00D9FC2, 0x9914A895, 0x906CC3A1, 0x54FEF170, 0x34C19155, 0xE27B8A66,
+ 0x131B5E69, 0xC3A8623E, 0x27BDFA35, 0x97F068CC, 0xCA3A6ACD, 0x4B55E936,
+ 0x86602DB9, 0x51DF13C1, 0x390BB16D, 0x5A80B83C, 0x22B23763, 0x39D8A911,
+ 0x2CB6BC13, 0xBF5579D7, 0x6C5C2FA8, 0xA8F4196E, 0xBCDB5476, 0x6864A866,
+ 0x416E16AD, 0x897FC515, 0x956FEB3C, 0xF6C8A306, 0x216799D9, 0x171A9133,
+ 0x6C2466DD, 0x75EB5DCD, 0xDF118F50, 0xE4AFB226, 0x26B9CEF3, 0xADB36189,
+ 0x8A7A19B1, 0xE2C73084, 0xF77DED5C, 0x8B8BC58F, 0x06DDE421, 0xB41E47FB,
+ 0xB1CC715E, 0x68C0FF99, 0x5D122F0F, 0xA4D25184, 0x097A5E6C, 0x0CBF18BC,
+ 0xC2D7C6E0, 0x8BB7E420, 0xA11F523F, 0x35D9B8A2, 0x03DA1A6B, 0x06888C02,
+ 0x7DD1E354, 0x6BBA7D79, 0x32CC7753, 0xE52D9655, 0xA9829DA1, 0x301590A7,
+ 0x9BC1C149, 0x13537F1C, 0xD3779B69, 0x2D71F2B7, 0x183C58FA, 0xACDC4418,
+ 0x8D8C8C76, 0x2620D9F0, 0x71A80D4D, 0x7A74C473, 0x449410E9, 0xA20E4211,
+ 0xF9C8082B, 0x0A6B334A, 0xB5F68ED2, 0x8243CC1B, 0x453C0FF3, 0x9BE564A0,
+ 0x4FF55A4F, 0x8740F8E7, 0xCCA7F15F, 0xE300FE21, 0x786D37D6, 0xDFD506F1,
+ 0x8EE00973, 0x17BBDE36, 0x7A670FA8, 0x5C31AB9E, 0xD4DAB618, 0xCC1F52F5,
+ 0xE358EB4F, 0x19B9E343, 0x3A8D77DD, 0xCDB93DA6, 0x140FD52D, 0x395412F8,
+ 0x2BA63360, 0x37E53AD0, 0x80700F1C, 0x7624ED0B, 0x703DC1EC, 0xB7366795,
+ 0xD6549D15, 0x66CE46D7, 0xD17ABE76, 0xA448E0A0, 0x28F07C02, 0xC31249B7,
+ 0x6E9ED6BA, 0xEAA47F78, 0xBBCFFFBD, 0xC507CA84, 0xE965F4DA, 0x8E9F35DA,
+ 0x6AD2AA44, 0x577452AC, 0xB5D674A7, 0x5461A46A, 0x6763152A, 0x9C12B7AA,
+ 0x12615927, 0x7B4FB118, 0xC351758D, 0x7E81687B, 0x5F52F0B3, 0x2D4254ED,
+ 0xD4C77271, 0x0431ACAB, 0xBEF94AEC, 0xFEE994CD, 0x9C4D9E81, 0xED623730,
+ 0xCF8A21E8, 0x51917F0B, 0xA7A9B5D6, 0xB297ADF8, 0xEED30431, 0x68CAC921,
+ 0xF1B35D46, 0x7A430A36, 0x51194022, 0x9ABCA65E, 0x85EC70BA, 0x39AEA8CC,
+ 0x737BAE8B, 0x582924D5, 0x03098A5A, 0x92396B81, 0x18DE2522, 0x745C1CB8,
+ 0xA1B8FE1D, 0x5DB3C697, 0x29164F83, 0x97C16376, 0x8419224C, 0x21203B35,
+ 0x833AC0FE, 0xD966A19A, 0xAAF0B24F, 0x40FDA998, 0xE7D52D71, 0x390896A8,
+ 0xCEE6053F, 0xD0B0D300, 0xFF99CBCC, 0x065E3D40 };
+
+}
diff --git a/src/cipher/turing/turing.cpp b/src/cipher/turing/turing.cpp
new file mode 100644
index 000000000..017b5cf1d
--- /dev/null
+++ b/src/cipher/turing/turing.cpp
@@ -0,0 +1,274 @@
+/*************************************************
+* Turing Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/turing.h>
+#include <botan/loadstor.h>
+#include <botan/xor_buf.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Perform an N-way PHT *
+*************************************************/
+inline void PHT(MemoryRegion<u32bit>& buf)
+ {
+ u32bit sum = 0;
+ for(u32bit j = 0; j < buf.size() - 1; ++j)
+ sum += buf[j];
+ buf[buf.size()-1] += sum;
+ sum = buf[buf.size()-1];
+ for(u32bit j = 0; j < buf.size() - 1; ++j)
+ buf[j] += sum;
+ }
+
+/*************************************************
+* Turing's polynomial multiplication *
+*************************************************/
+inline u32bit mul(u32bit X)
+ {
+ static const u32bit MULT_TAB[256] = {
+ 0x00000000, 0xD02B4367, 0xED5686CE, 0x3D7DC5A9, 0x97AC41D1, 0x478702B6,
+ 0x7AFAC71F, 0xAAD18478, 0x631582EF, 0xB33EC188, 0x8E430421, 0x5E684746,
+ 0xF4B9C33E, 0x24928059, 0x19EF45F0, 0xC9C40697, 0xC62A4993, 0x16010AF4,
+ 0x2B7CCF5D, 0xFB578C3A, 0x51860842, 0x81AD4B25, 0xBCD08E8C, 0x6CFBCDEB,
+ 0xA53FCB7C, 0x7514881B, 0x48694DB2, 0x98420ED5, 0x32938AAD, 0xE2B8C9CA,
+ 0xDFC50C63, 0x0FEE4F04, 0xC154926B, 0x117FD10C, 0x2C0214A5, 0xFC2957C2,
+ 0x56F8D3BA, 0x86D390DD, 0xBBAE5574, 0x6B851613, 0xA2411084, 0x726A53E3,
+ 0x4F17964A, 0x9F3CD52D, 0x35ED5155, 0xE5C61232, 0xD8BBD79B, 0x089094FC,
+ 0x077EDBF8, 0xD755989F, 0xEA285D36, 0x3A031E51, 0x90D29A29, 0x40F9D94E,
+ 0x7D841CE7, 0xADAF5F80, 0x646B5917, 0xB4401A70, 0x893DDFD9, 0x59169CBE,
+ 0xF3C718C6, 0x23EC5BA1, 0x1E919E08, 0xCEBADD6F, 0xCFA869D6, 0x1F832AB1,
+ 0x22FEEF18, 0xF2D5AC7F, 0x58042807, 0x882F6B60, 0xB552AEC9, 0x6579EDAE,
+ 0xACBDEB39, 0x7C96A85E, 0x41EB6DF7, 0x91C02E90, 0x3B11AAE8, 0xEB3AE98F,
+ 0xD6472C26, 0x066C6F41, 0x09822045, 0xD9A96322, 0xE4D4A68B, 0x34FFE5EC,
+ 0x9E2E6194, 0x4E0522F3, 0x7378E75A, 0xA353A43D, 0x6A97A2AA, 0xBABCE1CD,
+ 0x87C12464, 0x57EA6703, 0xFD3BE37B, 0x2D10A01C, 0x106D65B5, 0xC04626D2,
+ 0x0EFCFBBD, 0xDED7B8DA, 0xE3AA7D73, 0x33813E14, 0x9950BA6C, 0x497BF90B,
+ 0x74063CA2, 0xA42D7FC5, 0x6DE97952, 0xBDC23A35, 0x80BFFF9C, 0x5094BCFB,
+ 0xFA453883, 0x2A6E7BE4, 0x1713BE4D, 0xC738FD2A, 0xC8D6B22E, 0x18FDF149,
+ 0x258034E0, 0xF5AB7787, 0x5F7AF3FF, 0x8F51B098, 0xB22C7531, 0x62073656,
+ 0xABC330C1, 0x7BE873A6, 0x4695B60F, 0x96BEF568, 0x3C6F7110, 0xEC443277,
+ 0xD139F7DE, 0x0112B4B9, 0xD31DD2E1, 0x03369186, 0x3E4B542F, 0xEE601748,
+ 0x44B19330, 0x949AD057, 0xA9E715FE, 0x79CC5699, 0xB008500E, 0x60231369,
+ 0x5D5ED6C0, 0x8D7595A7, 0x27A411DF, 0xF78F52B8, 0xCAF29711, 0x1AD9D476,
+ 0x15379B72, 0xC51CD815, 0xF8611DBC, 0x284A5EDB, 0x829BDAA3, 0x52B099C4,
+ 0x6FCD5C6D, 0xBFE61F0A, 0x7622199D, 0xA6095AFA, 0x9B749F53, 0x4B5FDC34,
+ 0xE18E584C, 0x31A51B2B, 0x0CD8DE82, 0xDCF39DE5, 0x1249408A, 0xC26203ED,
+ 0xFF1FC644, 0x2F348523, 0x85E5015B, 0x55CE423C, 0x68B38795, 0xB898C4F2,
+ 0x715CC265, 0xA1778102, 0x9C0A44AB, 0x4C2107CC, 0xE6F083B4, 0x36DBC0D3,
+ 0x0BA6057A, 0xDB8D461D, 0xD4630919, 0x04484A7E, 0x39358FD7, 0xE91ECCB0,
+ 0x43CF48C8, 0x93E40BAF, 0xAE99CE06, 0x7EB28D61, 0xB7768BF6, 0x675DC891,
+ 0x5A200D38, 0x8A0B4E5F, 0x20DACA27, 0xF0F18940, 0xCD8C4CE9, 0x1DA70F8E,
+ 0x1CB5BB37, 0xCC9EF850, 0xF1E33DF9, 0x21C87E9E, 0x8B19FAE6, 0x5B32B981,
+ 0x664F7C28, 0xB6643F4F, 0x7FA039D8, 0xAF8B7ABF, 0x92F6BF16, 0x42DDFC71,
+ 0xE80C7809, 0x38273B6E, 0x055AFEC7, 0xD571BDA0, 0xDA9FF2A4, 0x0AB4B1C3,
+ 0x37C9746A, 0xE7E2370D, 0x4D33B375, 0x9D18F012, 0xA06535BB, 0x704E76DC,
+ 0xB98A704B, 0x69A1332C, 0x54DCF685, 0x84F7B5E2, 0x2E26319A, 0xFE0D72FD,
+ 0xC370B754, 0x135BF433, 0xDDE1295C, 0x0DCA6A3B, 0x30B7AF92, 0xE09CECF5,
+ 0x4A4D688D, 0x9A662BEA, 0xA71BEE43, 0x7730AD24, 0xBEF4ABB3, 0x6EDFE8D4,
+ 0x53A22D7D, 0x83896E1A, 0x2958EA62, 0xF973A905, 0xC40E6CAC, 0x14252FCB,
+ 0x1BCB60CF, 0xCBE023A8, 0xF69DE601, 0x26B6A566, 0x8C67211E, 0x5C4C6279,
+ 0x6131A7D0, 0xB11AE4B7, 0x78DEE220, 0xA8F5A147, 0x958864EE, 0x45A32789,
+ 0xEF72A3F1, 0x3F59E096, 0x0224253F, 0xD20F6658 };
+
+ return (X << 8) ^ MULT_TAB[(X >> 24) & 0xFF];
+ }
+
+}
+
+/*************************************************
+* Combine cipher stream with message *
+*************************************************/
+void Turing::cipher(const byte in[], byte out[], u32bit length)
+ {
+ while(length >= buffer.size() - position)
+ {
+ xor_buf(out, in, buffer.begin() + position, buffer.size() - position);
+ length -= (buffer.size() - position);
+ in += (buffer.size() - position);
+ out += (buffer.size() - position);
+ generate();
+ }
+ xor_buf(out, in, buffer.begin() + position, length);
+ position += length;
+ }
+
+/*************************************************
+* Generate cipher stream *
+*************************************************/
+void Turing::generate()
+ {
+ for(u32bit j = 0; j != 17; ++j)
+ {
+ const u32bit idx_0 = OFFSETS[16*j];
+ const u32bit idx_1 = OFFSETS[16*j+1];
+ const u32bit idx_2 = OFFSETS[16*j+2];
+ const u32bit idx_3 = OFFSETS[16*j+3];
+ const u32bit idx_4 = OFFSETS[16*j+4];
+ const u32bit idx_5 = OFFSETS[16*j+5];
+ const u32bit idx_6 = OFFSETS[16*j+6];
+ const u32bit idx_7 = OFFSETS[16*j+7];
+ const u32bit idx_8 = OFFSETS[16*j+8];
+ const u32bit idx_12 = OFFSETS[16*j+9];
+ const u32bit idx_14 = OFFSETS[16*j+10];
+ const u32bit idx_15 = OFFSETS[16*j+11];
+ const u32bit idx_16 = OFFSETS[16*j+12];
+
+ R[idx_0] = mul(R[idx_0]) ^ R[idx_15] ^ R[idx_4];
+
+ u32bit A = R[idx_0];
+ u32bit B = R[idx_14];
+ u32bit C = R[idx_7];
+ u32bit D = R[idx_2];
+ u32bit E = R[idx_1];
+
+ E += A + B + C + D;
+ A += E; B += E; C += E; D += E;
+
+ A = S0[get_byte(0, A)] ^ S1[get_byte(1, A)] ^
+ S2[get_byte(2, A)] ^ S3[get_byte(3, A)];
+ B = S0[get_byte(1, B)] ^ S1[get_byte(2, B)] ^
+ S2[get_byte(3, B)] ^ S3[get_byte(0, B)];
+ C = S0[get_byte(2, C)] ^ S1[get_byte(3, C)] ^
+ S2[get_byte(0, C)] ^ S3[get_byte(1, C)];
+ D = S0[get_byte(3, D)] ^ S1[get_byte(0, D)] ^
+ S2[get_byte(1, D)] ^ S3[get_byte(2, D)];
+ E = S0[get_byte(0, E)] ^ S1[get_byte(1, E)] ^
+ S2[get_byte(2, E)] ^ S3[get_byte(3, E)];
+
+ E += A + B + C + D;
+ A += E; B += E; C += E; D += E;
+
+ R[idx_1] = mul(R[idx_1]) ^ R[idx_16] ^ R[idx_5];
+ R[idx_2] = mul(R[idx_2]) ^ R[idx_0] ^ R[idx_6];
+ R[idx_3] = mul(R[idx_3]) ^ R[idx_1] ^ R[idx_7];
+
+ E += R[idx_4];
+
+ R[idx_4] = mul(R[idx_4]) ^ R[idx_2] ^ R[idx_8];
+
+ A += R[idx_1];
+ B += R[idx_16];
+ C += R[idx_12];
+ D += R[idx_5];
+
+ for(u32bit k = 0; k != 4; ++k)
+ {
+ buffer[20*j+k ] = get_byte(k, A);
+ buffer[20*j+k+ 4] = get_byte(k, B);
+ buffer[20*j+k+ 8] = get_byte(k, C);
+ buffer[20*j+k+12] = get_byte(k, D);
+ buffer[20*j+k+16] = get_byte(k, E);
+ }
+ }
+
+ position = 0;
+ }
+
+/*************************************************
+* Turing's byte mixing step *
+*************************************************/
+u32bit Turing::fixedS(u32bit W)
+ {
+ for(u32bit j = 0; j != 4; ++j)
+ {
+ byte B = SBOX[get_byte(j, W)];
+ W ^= rotate_left(Q_BOX[B], j*8);
+ W &= rotate_right(0x00FFFFFF, j*8);
+ W |= B << (24-j*8);
+ }
+ return W;
+ }
+
+/*************************************************
+* Generate the expanded Turing Sbox tables *
+*************************************************/
+void Turing::gen_sbox(MemoryRegion<u32bit>& S, u32bit which,
+ const MemoryRegion<u32bit>& K)
+ {
+ for(u32bit j = 0; j != 256; ++j)
+ {
+ u32bit W = 0, C = j;
+
+ for(u32bit k = 0; k < K.size(); ++k)
+ {
+ C = SBOX[get_byte(which, K[k]) ^ C];
+ W ^= rotate_left(Q_BOX[C], k + 8*which);
+ }
+ S[j] = (W & rotate_right(0x00FFFFFF, 8*which)) | (C << (24 - 8*which));
+ }
+ }
+
+/*************************************************
+* Turing Key Schedule *
+*************************************************/
+void Turing::key(const byte key[], u32bit length)
+ {
+ K.create(length / 4);
+ for(u32bit j = 0; j != length; ++j)
+ K[j/4] = (K[j/4] << 8) + key[j];
+
+ for(u32bit j = 0; j != K.size(); ++j)
+ K[j] = fixedS(K[j]);
+
+ PHT(K);
+
+ gen_sbox(S0, 0, K);
+ gen_sbox(S1, 1, K);
+ gen_sbox(S2, 2, K);
+ gen_sbox(S3, 3, K);
+
+ resync(0, 0);
+ }
+
+/*************************************************
+* Resynchronization *
+*************************************************/
+void Turing::resync(const byte iv[], u32bit length)
+ {
+ if(length % 4 != 0 || length > 16)
+ throw Invalid_IV_Length(name(), length);
+
+ SecureVector<u32bit> IV(length / 4);
+ for(u32bit j = 0; j != length; ++j)
+ IV[j/4] = (IV[j/4] << 8) + iv[j];
+
+ for(u32bit j = 0; j != IV.size(); ++j)
+ R[j] = IV[j] = fixedS(IV[j]);
+
+ for(u32bit j = 0; j != K.size(); ++j)
+ R[j+IV.size()] = K[j];
+
+ R[K.size() + IV.size()] = (0x010203 << 8) | (K.size() << 4) | IV.size();
+
+ for(u32bit j = K.size() + IV.size() + 1; j != 17; ++j)
+ {
+ const u32bit W = R[j-K.size()-IV.size()-1] + R[j-1];
+ R[j] = S0[get_byte(0, W)] ^ S1[get_byte(1, W)] ^
+ S2[get_byte(2, W)] ^ S3[get_byte(3, W)];
+ }
+
+ PHT(R);
+
+ generate();
+ }
+
+/*************************************************
+* Clear memory of sensitive data *
+*************************************************/
+void Turing::clear() throw()
+ {
+ S0.clear();
+ S1.clear();
+ S2.clear();
+ S3.clear();
+
+ buffer.clear();
+ position = 0;
+ }
+
+}
diff --git a/src/cipher/turing/turing.h b/src/cipher/turing/turing.h
new file mode 100644
index 000000000..14b2e6fd6
--- /dev/null
+++ b/src/cipher/turing/turing.h
@@ -0,0 +1,46 @@
+/*************************************************
+* Turing Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_TURING_H__
+#define BOTAN_TURING_H__
+
+#include <botan/base.h>
+
+namespace Botan {
+
+/*************************************************
+* Turing *
+*************************************************/
+class BOTAN_DLL Turing : public StreamCipher
+ {
+ public:
+ void clear() throw();
+ std::string name() const { return "Turing"; }
+ StreamCipher* clone() const { return new Turing; }
+ Turing() : StreamCipher(4, 32, 4) { position = 0; }
+ private:
+ void cipher(const byte[], byte[], u32bit);
+ void key(const byte[], u32bit);
+ void resync(const byte[], u32bit);
+ void generate();
+
+ static u32bit fixedS(u32bit);
+ static void gen_sbox(MemoryRegion<u32bit>&, u32bit,
+ const MemoryRegion<u32bit>&);
+
+ static const u32bit Q_BOX[256];
+ static const byte SBOX[256];
+ static const byte OFFSETS[272];
+
+ SecureBuffer<u32bit, 256> S0, S1, S2, S3;
+ SecureBuffer<u32bit, 17> R;
+ SecureVector<u32bit> K;
+ SecureBuffer<byte, 340> buffer;
+ u32bit position;
+ };
+
+}
+
+#endif