summaryrefslogtreecommitdiffstats
path: root/libcommuni/src/3rdparty/qblowfish
diff options
context:
space:
mode:
Diffstat (limited to 'libcommuni/src/3rdparty/qblowfish')
-rw-r--r--libcommuni/src/3rdparty/qblowfish/LICENSE23
-rw-r--r--libcommuni/src/3rdparty/qblowfish/README.md28
-rw-r--r--libcommuni/src/3rdparty/qblowfish/qblowfish.cpp277
-rw-r--r--libcommuni/src/3rdparty/qblowfish/qblowfish.h46
-rw-r--r--libcommuni/src/3rdparty/qblowfish/qblowfish.pri11
-rw-r--r--libcommuni/src/3rdparty/qblowfish/qblowfish_p.h201
6 files changed, 586 insertions, 0 deletions
diff --git a/libcommuni/src/3rdparty/qblowfish/LICENSE b/libcommuni/src/3rdparty/qblowfish/LICENSE
new file mode 100644
index 0000000..db148cb
--- /dev/null
+++ b/libcommuni/src/3rdparty/qblowfish/LICENSE
@@ -0,0 +1,23 @@
+QBlowfish is licensed under the MIT License
+
+Copyright © 2012 Roopesh Chander <roop@forwardbias.in>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject
+to the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/libcommuni/src/3rdparty/qblowfish/README.md b/libcommuni/src/3rdparty/qblowfish/README.md
new file mode 100644
index 0000000..fb961bb
--- /dev/null
+++ b/libcommuni/src/3rdparty/qblowfish/README.md
@@ -0,0 +1,28 @@
+# QBlowfish
+
+QBlowfish is a [Qt](http://qt.nokia.com/) implementation of the [Blowfish](http://www.schneier.com/blowfish.html) encryption algorithm, as described in the original Blowfish [paper](http://www.schneier.com/paper-blowfish-fse.html) by Bruce Schneier.
+
+The Blowfish algorithm requires the input in 8-byte blocks. To simplify usage, QBlowfish can optionally add [PKCS5 padding](http://tools.ietf.org/html/rfc5652#section-6.3) to the input data. (For example, if the input is only 60 bytes long, 4 bytes will be padded to bring the bytecount to a multiple of 8.) When padding is enabled during decryption, QBlowfish will also remove the padded bytes from the output.
+
+You only need to add 3 files (src/*) to your project. You can then use the QBlowfish class to encrypt and decrypt stuff.
+
+ QByteArray secretKey("This is a secret")
+ QString clearText("Stuff to encrypt");
+
+ QBlowfish bf(secretKey);
+ bf.setPaddingEnabled(true);
+ QByteArray encryptedBa = bf.encrypted(clearText.toUtf8());
+
+A more detailed example is included in the repo.
+
+QBlowfish is not optimized for speed. It processes the data in bytes (most other Blowfish implementations seem to work on 4-byte words) and is endianness-agnostic.
+
+### Tests
+
+Unit tests are written using QTestLib. Tests include [the official test vectors](http://www.schneier.com/code/vectors.txt).
+
+QBlowfish has been tested with Qt 4.8 on Windows and Linux.
+
+### License
+
+QBlowfish is published under the MIT license.
diff --git a/libcommuni/src/3rdparty/qblowfish/qblowfish.cpp b/libcommuni/src/3rdparty/qblowfish/qblowfish.cpp
new file mode 100644
index 0000000..605ff24
--- /dev/null
+++ b/libcommuni/src/3rdparty/qblowfish/qblowfish.cpp
@@ -0,0 +1,277 @@
+/*
+ This file is part of QBlowfish and is licensed under the MIT License
+
+ Copyright (C) 2012 Roopesh Chander <roop@forwardbias.in>
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject
+ to the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+*/
+
+#include "qblowfish.h"
+#include "qblowfish_p.h"
+#include <QtEndian>
+#include <QDebug>
+
+QBlowfish::QBlowfish(const QByteArray &key)
+ : m_key(key)
+ , m_initialized(false)
+ , m_paddingEnabled(false)
+{
+}
+
+void QBlowfish::setPaddingEnabled(bool enabled)
+{
+ m_paddingEnabled = enabled;
+}
+
+bool QBlowfish::isPaddingEnabled() const
+{
+ return m_paddingEnabled;
+}
+
+QByteArray QBlowfish::encrypted(const QByteArray &_clearText)
+{
+ QByteArray clearText(_clearText);
+ if (clearText.isEmpty()) {
+ return QByteArray();
+ }
+
+ if (isPaddingEnabled()) {
+ // Add padding as per PKCS5
+ // Ref: RFC 5652 http://tools.ietf.org/html/rfc5652#section-6.3
+ quint8 paddingLength = 8 - (clearText.size() % 8);
+ QByteArray paddingBa(paddingLength, static_cast<char>(paddingLength));
+ clearText.append(paddingBa);
+ } else {
+ if (clearText.size() % 8 != 0) {
+ qWarning("Cannot encrypt. Clear-text length is not a multiple of 8 and padding is not enabled.");
+ return QByteArray();
+ }
+ }
+
+ Q_ASSERT(clearText.size() % 8 == 0);
+ if ((clearText.size() % 8 == 0) && init()) {
+
+ QByteArray copyBa(clearText.constData(), clearText.size());
+ for (int i = 0; i < clearText.size(); i += 8) {
+ coreEncrypt(copyBa.data() + i);
+ }
+ return copyBa;
+
+ }
+ return QByteArray();
+}
+
+QByteArray QBlowfish::decrypted(const QByteArray &cipherText)
+{
+ if (cipherText.isEmpty()) {
+ return QByteArray();
+ }
+
+ Q_ASSERT(cipherText.size() % 8 == 0);
+ if ((cipherText.size() % 8 == 0) && init()) {
+
+ QByteArray copyBa(cipherText.constData(), cipherText.size());
+ for (int i = 0; i < cipherText.size(); i += 8) {
+ coreDecrypt(copyBa.data() + i);
+ }
+
+ if (isPaddingEnabled()) {
+ // Remove padding as per PKCS5
+ quint8 paddingLength = static_cast<quint8>(copyBa.right(1).at(0));
+ QByteArray paddingBa(paddingLength, static_cast<char>(paddingLength));
+ if (copyBa.right(paddingLength) == paddingBa) {
+ return copyBa.left(copyBa.length() - paddingLength);
+ }
+ return QByteArray();
+ }
+ return copyBa;
+ }
+ return QByteArray();
+}
+
+/*
+ Core encryption code follows. This is an implementation of the Blowfish algorithm as described at:
+ http://www.schneier.com/paper-blowfish-fse.html
+*/
+
+bool QBlowfish::init()
+{
+ if (m_initialized) {
+ return true;
+ }
+
+ if (m_key.isEmpty()) {
+ qWarning("Cannot init. Key is empty.");
+ return false;
+ }
+
+ m_sbox1 = QByteArray::fromHex(QByteArray::fromRawData(sbox0, SBOX_SIZE_BYTES * 2));
+ m_sbox2 = QByteArray::fromHex(QByteArray::fromRawData(sbox1, SBOX_SIZE_BYTES * 2));
+ m_sbox3 = QByteArray::fromHex(QByteArray::fromRawData(sbox2, SBOX_SIZE_BYTES * 2));
+ m_sbox4 = QByteArray::fromHex(QByteArray::fromRawData(sbox3, SBOX_SIZE_BYTES * 2));
+ m_parray = QByteArray::fromHex(QByteArray::fromRawData(parray, PARRAY_SIZE_BYTES * 2));
+
+ const QByteArray &key = m_key;
+ int keyLength = key.length();
+ for (int i = 0; i < PARRAY_SIZE_BYTES; i++) {
+ m_parray[i] = static_cast<char>(static_cast<quint8>(m_parray[i]) ^ static_cast<quint8>(key[i % keyLength]));
+ }
+
+ char seed[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ // Update p-array
+ for (int i = 0; i < (PARRAY_SIZE_BYTES / 4); i += 2) {
+ coreEncrypt(seed);
+ for (int j = 0; j < 8; j++) {
+ // P1 = xL; P2 = xR
+ m_parray[i * 4 + j] = seed[j];
+ }
+ }
+
+ // Update s-boxes
+ for (int sboxIndex = 1; sboxIndex <= 4; sboxIndex++) {
+ QByteArray *sbox = 0;
+ switch (sboxIndex) {
+ case 1: sbox = &m_sbox1; break;
+ case 2: sbox = &m_sbox2; break;
+ case 3: sbox = &m_sbox3; break;
+ case 4: sbox = &m_sbox4; break;
+ default: Q_ASSERT(false);
+ }
+ Q_ASSERT(sbox != 0);
+
+ for (int i = 0; i < (SBOX_SIZE_BYTES / 4); i += 2) {
+ coreEncrypt(seed);
+ for (int j = 0; j < 8; j++) {
+ // S1,1 = xL; S1,2 = xR
+ sbox->operator[](i * 4 + j) = seed[j];
+ }
+ }
+ }
+
+ m_initialized = true;
+ return true;
+}
+
+void QBlowfish::coreEncrypt(char *x) // encrypts 8 bytes pointed to by x, result is written to the same location
+{
+ // Divide x into two 32-bit halves: xL, xR
+ char *xL = x;
+ char *xR = x + 4;
+ uchar f_xL_bytes[4] = { 0, 0, 0, 0 };
+
+ for (int i = 0; i < 16; i++) {
+
+ // xL = xL XOR Pi
+ for (int j = 0; j < 4; j++) {
+ // quint8 old_xL = xL[j];
+ xL[j] = static_cast<char>(static_cast<quint8>(xL[j]) ^ static_cast<quint8>(m_parray[i * 4 + j]));
+ }
+
+ // Divide xL into four eight-bit quarters: a, b, c, and d
+ quint8 a = static_cast<quint8>(xL[0]);
+ quint8 b = static_cast<quint8>(xL[1]);
+ quint8 c = static_cast<quint8>(xL[2]);
+ quint8 d = static_cast<quint8>(xL[3]);
+
+ // F(xL) = ((S1,a + S2,b mod 2**32) XOR S3,c) + S4,d mod 2**32
+ quint32 s1a = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox1.constData() + a * 4));
+ quint32 s2b = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox2.constData() + b * 4));
+ quint32 s3c = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox3.constData() + c * 4));
+ quint32 s4d = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox4.constData() + d * 4));
+ quint32 f_xL = ((((s1a + s2b) & 0xffffffff) ^ s3c) + s4d) & 0xffffffff;
+ qToBigEndian<quint32>(f_xL, f_xL_bytes);
+
+ // xR = F(xL) XOR xR
+ for (int j = 0; j < 4; j++) {
+ xR[j] = static_cast<char>(static_cast<quint8>(f_xL_bytes[j]) ^ static_cast<quint8>(xR[j]));
+ }
+
+ // Swap xL and xR, but not in the last iteration
+ if (i != 15) {
+ for (int j = 0; j < 4; j++) {
+ char temp = xL[j];
+ xL[j] = xR[j];
+ xR[j] = temp;
+ }
+ }
+
+ }
+
+ // xR = xR XOR P17
+ // xL = xL XOR P18
+ for (int j = 0; j < 4; j++) {
+ xR[j] = static_cast<char>(static_cast<quint8>(xR[j]) ^ static_cast<quint8>(m_parray[16 * 4 + j]));
+ xL[j] = static_cast<char>(static_cast<quint8>(xL[j]) ^ static_cast<quint8>(m_parray[17 * 4 + j]));
+ }
+}
+
+void QBlowfish::coreDecrypt(char *x) // decrypts 8 bytes pointed to by x, result is written to the same location
+{
+ // Divide x into two 32-bit halves: xL, xR
+ char *xL = x;
+ char *xR = x + 4;
+ uchar f_xL_bytes[4] = { 0, 0, 0, 0 };
+
+ // xL = xL XOR P18
+ // xR = xR XOR P17
+ for (int j = 0; j < 4; j++) {
+ xL[j] = static_cast<char>(static_cast<quint8>(xL[j]) ^ static_cast<quint8>(m_parray[17 * 4 + j]));
+ xR[j] = static_cast<char>(static_cast<quint8>(xR[j]) ^ static_cast<quint8>(m_parray[16 * 4 + j]));
+ }
+
+ for (int i = 15; i >= 0; i--) {
+
+ // Swap xL and xR, but not in the first iteration
+ if (i != 15) {
+ for (int j = 0; j < 4; j++) {
+ char temp = xL[j];
+ xL[j] = xR[j];
+ xR[j] = temp;
+ }
+ }
+
+ // Divide xL into four eight-bit quarters: a, b, c, and d
+ quint8 a = static_cast<quint8>(xL[0]);
+ quint8 b = static_cast<quint8>(xL[1]);
+ quint8 c = static_cast<quint8>(xL[2]);
+ quint8 d = static_cast<quint8>(xL[3]);
+
+ // F(xL) = ((S1,a + S2,b mod 2**32) XOR S3,c) + S4,d mod 2**32
+ quint32 s1a = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox1.constData() + a * 4));
+ quint32 s2b = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox2.constData() + b * 4));
+ quint32 s3c = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox3.constData() + c * 4));
+ quint32 s4d = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(m_sbox4.constData() + d * 4));
+ quint32 f_xL = ((((s1a + s2b) & 0xffffffff) ^ s3c) + s4d) & 0xffffffff;
+ qToBigEndian<quint32>(f_xL, f_xL_bytes);
+
+ // xR = F(xL) XOR xR
+ for (int j = 0; j < 4; j++) {
+ xR[j] = static_cast<char>(static_cast<quint8>(f_xL_bytes[j]) ^ static_cast<quint8>(xR[j]));
+ }
+
+ // xL = xL XOR Pi
+ for (int j = 0; j < 4; j++) {
+ xL[j] = static_cast<char>(static_cast<quint8>(xL[j]) ^ static_cast<quint8>(m_parray[i * 4 + j]));
+ }
+
+ }
+}
diff --git a/libcommuni/src/3rdparty/qblowfish/qblowfish.h b/libcommuni/src/3rdparty/qblowfish/qblowfish.h
new file mode 100644
index 0000000..100a2e6
--- /dev/null
+++ b/libcommuni/src/3rdparty/qblowfish/qblowfish.h
@@ -0,0 +1,46 @@
+#ifndef QBLOWFISH_H
+#define QBLOWFISH_H
+
+#include <QByteArray>
+
+class QBlowfish
+{
+public:
+ QBlowfish(const QByteArray &key);
+ bool init();
+
+ // Padding:
+ //
+ // Blowfish works on 8-byte blocks. Padding makes it usable even
+ // in case where the input size is not in exact 8-byte blocks.
+ //
+ // If padding is disabled (the default), encrypted() will work only if the
+ // input size (in bytes) is a multiple of 8. (If it's not a multiple of 8,
+ // encrypted() will return a null bytearray.)
+ //
+ // If padding is enabled, we increase the input length to a multiple of 8
+ // by padding bytes as per PKCS5
+ //
+ // If padding was enabled during encryption, it should be enabled during
+ // decryption for correct decryption (and vice versa).
+
+ void setPaddingEnabled(bool enabled);
+ bool isPaddingEnabled() const;
+
+ // Encrypt / decrypt
+ QByteArray encrypted(const QByteArray &clearText);
+ QByteArray decrypted(const QByteArray &cipherText);
+
+private:
+ // core encrypt/decrypt methods, encrypts/decrypts in-place
+ void coreEncrypt(char *x);
+ void coreDecrypt(char *x);
+
+ QByteArray m_key;
+ bool m_initialized;
+ bool m_paddingEnabled;
+ QByteArray m_parray;
+ QByteArray m_sbox1, m_sbox2, m_sbox3, m_sbox4;
+};
+
+#endif // QBLOWFISH_H
diff --git a/libcommuni/src/3rdparty/qblowfish/qblowfish.pri b/libcommuni/src/3rdparty/qblowfish/qblowfish.pri
new file mode 100644
index 0000000..5d01670
--- /dev/null
+++ b/libcommuni/src/3rdparty/qblowfish/qblowfish.pri
@@ -0,0 +1,11 @@
+######################################################################
+# Communi
+######################################################################
+
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+
+HEADERS += $$PWD/qblowfish.h
+HEADERS += $$PWD/qblowfish_p.h
+
+SOURCES += $$PWD/qblowfish.cpp
diff --git a/libcommuni/src/3rdparty/qblowfish/qblowfish_p.h b/libcommuni/src/3rdparty/qblowfish/qblowfish_p.h
new file mode 100644
index 0000000..3e15083
--- /dev/null
+++ b/libcommuni/src/3rdparty/qblowfish/qblowfish_p.h
@@ -0,0 +1,201 @@
+/*
+ Source: http://www.schneier.com/code/constants.txt
+*/
+
+#ifndef Q_BLOWFISH_P_H
+#define Q_BLOWFISH_P_H
+
+#define SBOX_SIZE_BYTES (256 * 4)
+#define PARRAY_SIZE_BYTES (18 * 4)
+
+char sbox0[] =
+ "d1310ba698dfb5ac2ffd72dbd01adfb7b8e1afed6a267e96"
+ "ba7c9045f12c7f9924a19947b3916cf70801f2e2858efc16"
+ "636920d871574e69a458fea3f4933d7e0d95748f728eb658"
+ "718bcd5882154aee7b54a41dc25a59b59c30d5392af26013"
+ "c5d1b023286085f0ca417918b8db38ef8e79dcb0603a180e"
+ "6c9e0e8bb01e8a3ed71577c1bd314b2778af2fda55605c60"
+ "e65525f3aa55ab945748986263e8144055ca396a2aab10b6"
+ "b4cc5c341141e8cea15486af7c72e993b3ee1411636fbc2a"
+ "2ba9c55d741831f6ce5c3e169b87931eafd6ba336c24cf5c"
+ "7a325381289586773b8f48986b4bb9afc4bfe81b66282193"
+ "61d809ccfb21a991487cac605dec8032ef845d5de98575b1"
+ "dc262302eb651b8823893e81d396acc50f6d6ff383f44239"
+ "2e0b4482a484200469c8f04a9e1f9b5e21c66842f6e96c9a"
+ "670c9c61abd388f06a51a0d2d8542f68960fa728ab5133a3"
+ "6eef0b6c137a3be4ba3bf0507efb2a98a1f1651d39af0176"
+ "66ca593e82430e888cee8619456f9fb47d84a5c33b8b5ebe"
+ "e06f75d885c12073401a449f56c16aa64ed3aa62363f7706"
+ "1bfedf72429b023d37d0d724d00a1248db0fead349f1c09b"
+ "075372c980991b7b25d479d8f6e8def7e3fe501ab6794c3b"
+ "976ce0bd04c006bac1a94fb6409f60c45e5c9ec2196a2463"
+ "68fb6faf3e6c53b51339b2eb3b52ec6f6dfc511f9b30952c"
+ "cc814544af5ebd09bee3d004de334afd660f2807192e4bb3"
+ "c0cba85745c8740fd20b5f39b9d3fbdb5579c0bd1a60320a"
+ "d6a100c6402c7279679f25fefb1fa3cc8ea5e9f8db3222f8"
+ "3c7516dffd616b152f501ec8ad0552ab323db5fafd238760"
+ "53317b483e00df829e5c57bbca6f8ca01a87562edf1769db"
+ "d542a8f6287effc3ac6732c68c4f5573695b27b0bbca58c8"
+ "e1ffa35db8f011a010fa3d98fd2183b84afcb56c2dd1d35b"
+ "9a53e479b6f84565d28e49bc4bfb9790e1ddf2daa4cb7e33"
+ "62fb1341cee4c6e8ef20cada36774c01d07e9efe2bf11fb4"
+ "95dbda4dae909198eaad8e716b93d5a0d08ed1d0afc725e0"
+ "8e3c5b2f8e7594b78ff6e2fbf2122b648888b812900df01c"
+ "4fad5ea0688fc31cd1cff191b3a8c1ad2f2f2218be0e1777"
+ "ea752dfe8b021fa1e5a0cc0fb56f74e818acf3d6ce89e299"
+ "b4a84fe0fd13e0b77cc43b81d2ada8d9165fa26680957705"
+ "93cc7314211a1477e6ad206577b5fa86c75442f5fb9d35cf"
+ "ebcdaf0c7b3e89a0d6411bd3ae1e7e4900250e2d2071b35e"
+ "226800bb57b8e0af2464369bf009b91e5563911d59dfa6aa"
+ "78c14389d95a537f207d5ba202e5b9c5832603766295cfa9"
+ "11c819684e734a41b3472dca7b14a94a1b5100529a532915"
+ "d60f573fbc9bc6e42b60a47681e6740008ba6fb5571be91f"
+ "f296ec6b2a0dd915b6636521e7b9f9b6ff34052ec5855664"
+ "53b02d5da99f8fa108ba47996e85076a"
+;
+
+char sbox1[] =
+ "4b7a70e9b5b32944db75092ec4192623ad6ea6b049a7df7d"
+ "9cee60b88fedb266ecaa8c71699a17ff5664526cc2b19ee1"
+ "193602a575094c29a0591340e4183a3e3f54989a5b429d65"
+ "6b8fe4d699f73fd6a1d29c07efe830f54d2d38e6f0255dc1"
+ "4cdd20868470eb266382e9c6021ecc5e09686b3f3ebaefc9"
+ "3c9718146b6a70a1687f358452a0e286b79c5305aa500737"
+ "3e07841c7fdeae5c8e7d44ec5716f2b8b03ada37f0500c0d"
+ "f01c1f040200b3ffae0cf51a3cb574b225837a58dc0921bd"
+ "d19113f97ca92ff69432477322f547013ae5e58137c2dadc"
+ "c8b576349af3dda7a94461460fd0030eecc8c73ea4751e41"
+ "e238cd993bea0e2f3280bba1183eb3314e548b384f6db908"
+ "6f420d03f60a04bf2cb8129024977c795679b072bcaf89af"
+ "de9a771fd9930810b38bae12dccf3f2e5512721f2e6b7124"
+ "501adde69f84cd877a5847187408da17bc9f9abce94b7d8c"
+ "ec7aec3adb851dfa63094366c464c3d2ef1c18473215d908"
+ "dd433b3724c2ba1612a14d432a65c45150940002133ae4dd"
+ "71dff89e10314e5581ac77d65f11199b043556f1d7a3c76b"
+ "3c11183b5924a509f28fe6ed97f1fbfa9ebabf2c1e153c6e"
+ "86e34570eae96fb1860e5e0a5a3e2ab3771fe71c4e3d06fa"
+ "2965dcb999e71d0f803e89d65266c8252e4cc9789c10b36a"
+ "c6150eba94e2ea78a5fc3c531e0a2df4f2f74ea7361d2b3d"
+ "1939260f19c279605223a708f71312b6ebadfe6eeac31f66"
+ "e3bc4595a67bc883b17f37d1018cff28c332ddefbe6c5aa5"
+ "6558218568ab9802eecea50fdb2f953b2aef7dad5b6e2f84"
+ "1521b62829076170ecdd4775619f151013cca830eb61bd96"
+ "0334fe1eaa0363cfb5735c904c70a239d59e9e0bcbaade14"
+ "eecc86bc60622ca79cab5cabb2f3846e648b1eaf19bdf0ca"
+ "a02369b9655abb5040685a323c2ab4b3319ee9d5c021b8f7"
+ "9b540b19875fa09995f7997e623d7da8f837889a97e32d77"
+ "11ed935f166812810e358829c7e61fd696dedfa17858ba99"
+ "57f584a51b2272639b83c3ff1ac24696cdb30aeb532e3054"
+ "8fd948e46dbc312858ebf2ef34c6ffeafe28ed61ee7c3c73"
+ "5d4a14d9e864b7e342105d14203e13e045eee2b6a3aaabea"
+ "db6c4f15facb4fd0c742f442ef6abbb5654f3b1d41cd2105"
+ "d81e799e86854dc7e44b476a3d816250cf62a1f25b8d2646"
+ "fc8883a0c1c7b6a37f1524c369cb749247848a0b5692b285"
+ "095bbf00ad19489d1462b17423820e0058428d2a0c55f5ea"
+ "1dadf43e233f70613372f0928d937e41d65fecf16c223bdb"
+ "7cde3759cbee74604085f2a7ce77326ea607808419f8509e"
+ "e8efd85561d99735a969a7aac50c06c25a04abfc800bcadc"
+ "9e447a2ec3453484fdd567050e1e9ec9db73dbd3105588cd"
+ "675fda79e3674340c5c43465713e38d83d28f89ef16dff20"
+ "153e21e78fb03d4ae6e39f2bdb83adf7"
+;
+
+char sbox2[] =
+ "e93d5a68948140f7f64c261c94692934411520f77602d4f7"
+ "bcf46b2ed4a20068d40824713320f46a43b7d4b7500061af"
+ "1e39f62e9724454614214f74bf8b88404d95fc1d96b591af"
+ "70f4ddd366a02f45bfbc09ec03bd97857fac6dd031cb8504"
+ "96eb27b355fd3941da2547e6abca0a9a28507825530429f4"
+ "0a2c86dae9b66dfb68dc1462d7486900680ec0a427a18dee"
+ "4f3ffea2e887ad8cb58ce0067af4d6b6aace1e7cd3375fec"
+ "ce78a399406b2a4220fe9e35d9f385b9ee39d7ab3b124e8b"
+ "1dc9faf74b6d185626a36631eae397b23a6efa74dd5b4332"
+ "6841e7f7ca7820fbfb0af54ed8feb397454056acba489527"
+ "55533a3a20838d87fe6ba9b7d096954b55a867bca1159a58"
+ "cca9296399e1db33a62a4a563f3125f95ef47e1c9029317c"
+ "fdf8e80204272f7080bb155c05282ce395c11548e4c66d22"
+ "48c1133fc70f86dc07f9c9ee41041f0f404779a45d886e17"
+ "325f51ebd59bc0d1f2bcc18f41113564257b7834602a9c60"
+ "dff8e8a31f636c1b0e12b4c202e1329eaf664fd1cad18115"
+ "6b2395e0333e92e13b240b62eebeb92285b2a20ee6ba0d99"
+ "de720c8c2da2f728d012784595b794fd647d0862e7ccf5f0"
+ "5449a36f877d48fac39dfd27f33e8d1e0a476341992eff74"
+ "3a6f6eabf4f8fd37a812dc60a1ebddf8991be14cdb6e6b0d"
+ "c67b55106d672c372765d43bdcd0e804f1290dc7cc00ffa3"
+ "b5390f92690fed0b667b9ffbcedb7d9ca091cf0bd9155ea3"
+ "bb132f88515bad247b9479bf763bd6eb37392eb3cc115979"
+ "8026e297f42e312d6842ada7c66a2b3b12754ccc782ef11c"
+ "6a124237b79251e706a1bbe64bfb63501a6b101811caedfa"
+ "3d25bdd8e2e1c3c9444216590a121386d90cec6ed5abea2a"
+ "64af674eda86a85fbebfe98864e4c3fe9dbc8057f0f7c086"
+ "60787bf86003604dd1fd8346f6381fb07745ae04d736fccc"
+ "83426b33f01eab71b08041873c005e5f77a057bebde8ae24"
+ "55464299bf582e614e58f48ff2ddfda2f474ef388789bdc2"
+ "5366f9c3c8b38e74b475f25546fcd9b97aeb26618b1ddf84"
+ "846a0e79915f95e2466e598e20b457708cd55591c902de4c"
+ "b90bace1bb8205d011a862487574a99eb77f19b6e0a9dc09"
+ "662d09a1c4324633e85a1f0209f0be8c4a99a0251d6efe10"
+ "1ab93d1d0ba5a4dfa186f20f2868f169dcb7da83573906fe"
+ "a1e2ce9b4fcd7f5250115e01a70683faa002b5c40de6d027"
+ "9af88c27773f8641c3604c0661a806b5f0177a28c0f586e0"
+ "006058aa30dc7d6211e69ed72338ea6353c2dd94c2c21634"
+ "bbcbee5690bcb6deebfc7da1ce591d766f05e4094b7c0188"
+ "39720a3d7c927c2486e3725f724d9db91ac15bb4d39eb8fc"
+ "ed54557808fca5b5d83d7cd34dad0fc41e50ef5eb161e6f8"
+ "a28514d96c51133c6fd5c7e756e14ec4362abfceddc6c837"
+ "d79a323492638212670efa8e406000e0"
+;
+
+char sbox3[] =
+ "3a39ce37d3faf5cfabc277375ac52d1b5cb0679e4fa33742"
+ "d382274099bc9bbed5118e9dbf0f7315d62d1c7ec700c47b"
+ "b78c1b6b21a19045b26eb1be6a366eb45748ab2fbc946e79"
+ "c6a376d26549c2c8530ff8ee468dde7dd5730a1d4cd04dc6"
+ "2939bbdba9ba4650ac9526e8be5ee304a1fad5f06a2d519a"
+ "63ef8ce29a86ee22c089c2b843242ef6a51e03aa9cf2d0a4"
+ "83c061ba9be96a4d8fe51550ba645bd62826a2f9a73a3ae1"
+ "4ba99586ef5562e9c72fefd3f752f7da3f046f6977fa0a59"
+ "80e4a91587b086019b09e6ad3b3ee593e990fd5a9e34d797"
+ "2cf0b7d9022b8b5196d5ac3a017da67dd1cf3ed67c7d2d28"
+ "1f9f25cfadf2b89b5ad6b4725a88f54ce029ac71e019a5e6"
+ "47b0acfded93fa9be8d3c48d283b57ccf8d5662979132e28"
+ "785f0191ed756055f7960e44e3d35e8c15056dd488f46dba"
+ "03a161250564f0bdc3eb9e153c9057a297271aeca93a072a"
+ "1b3f6d9b1e6321f5f59c66fb26dcf3197533d928b155fdf5"
+ "035634828aba3cbb28517711c20ad9f8abcc5167ccad925f"
+ "4de817513830dc8e379d58629320f991ea7a90c2fb3e7bce"
+ "5121ce64774fbe32a8b6e37ec3293d4648de53696413e680"
+ "a2ae0810dd6db22469852dfd09072166b39a460a6445c0dd"
+ "586cdecf1c20c8ae5bbef7dd1b588d40ccd2017f6bb4e3bb"
+ "dda26a7e3a59ff453e350a44bcb4cdd572eacea8fa6484bb"
+ "8d6612aebf3c6f47d29be463542f5d9eaec2771bf64e6370"
+ "740e0d8de75b1357f8721671af537d5d4040cb084eb4e2cc"
+ "34d2466a0115af84e1b0042895983a1d06b89fb4ce6ea048"
+ "6f3f3b823520ab82011a1d4b277227f8611560b1e7933fdc"
+ "bb3a792b344525bda08839e151ce794b2f32c9b7a01fbac9"
+ "e01cc87ebcc7d1f6cf0111c3a1e8aac71a908749d44fbd9a"
+ "d0dadecbd50ada380339c32ac69136678df9317ce0b12b4f"
+ "f79e59b743f5bb3af2d519ff27d9459cbf97222c15e6fc2a"
+ "0f91fc719b941525fae59361ceb69cebc2a8645912baa8d1"
+ "b6c1075ee3056a0c10d25065cb03a442e0ec6e0e1698db3b"
+ "4c98a0be3278e9649f1f9532e0d392dfd3a0342b8971f21e"
+ "1b0a74414ba3348cc5be7120c37632d8df359f8d9b992f2e"
+ "e60b6f470fe3f11de54cda541edad891ce6279cfcd3e7e6f"
+ "1618b166fd2c1d05848fd2c5f6fb2299f523f357a6327623"
+ "93a8353156cccd02acf081625a75ebb56e16369788d273cc"
+ "de96629281b949d04c50901b71c65614e6c6c7bd327a140a"
+ "45e1d006c3f27b9ac9aa53fd62a80f00bb25bfe235bdd2f6"
+ "71126905b2040222b6cbcf7ccd769c2b53113ec01640e3d3"
+ "38abbd602547adf0ba38209cf746ce7677afa1c520756060"
+ "85cbfe4e8ae88dd87aaaf9b04cf9aa7e1948c25c02fb8a8c"
+ "01c36ae4d6ebe1f990d4f869a65cdea03f09252dc208e69f"
+ "b74e6132ce77e25b578fdfe33ac372e6"
+;
+
+char parray[] =
+ "243f6a8885a308d313198a2e03707344a4093822299f31d0"
+ "082efa98ec4e6c89452821e638d01377be5466cf34e90c6c"
+ "c0ac29b7c97c50dd3f84d5b5b54709179216d5d98979fb1b"
+;
+
+#endif // Q_BLOWFISH_P_H