Хорошо, поэтому я делаю небольшую реализацию Blowfish в PHP как упражнение для себя и познакомлюсь с этим методом шифрования лучше. Я пришел к набору функций, которые работают, в том смысле, что я могу зашифровать данные и снова расшифровать их, но тестовые векторы я обнаружил, что не согласен с моими зашифрованными значениями ... Так как кодирование / декодирование кажется для работы, я предполагаю, что ошибка в настройке моей функции применения секретного ключа к массиву P и S-блокам, получая другой набор значений P и значений S-блоков, поэтому закодированные значения различны. Может кто-нибудь найти, где моя логика идет не так, как надо?
Для тестового случая ключа 0x0000000000000000 и ввода текста 0x0000000000000000 первым шагом является XOR ключа с массивом P, но с ключом всех нулей, что приведет к неизменности массива P, поэтому все равно будет иметь шестнадцатеричные значения числа пи, с которых он начинается. Затем 64-байтовая текстовая строка (0x0000000000000000) кодируется с использованием текущего массива P и S-блоков, и результат разделяется для замены P1 и P2. Затем тот же самый выход снова кодируется (используя новые значения P1 и P2), чтобы получить другой выход, который используется для замены P3 и P4. Это продолжается до тех пор, пока не будут изменены все значения P и S-блоки. Делая этот процесс, я получаю следующее (исходные значения слева, значение после распространения через процесс секретного ключа справа):
P1: 243f6a88 ⇒ 99f2ff37
P2: 85a308d3 ⇒ 9ce5cb96
P3: 13198a2e ⇒ d8bf7d9a
P4: 03707344 ⇒ eba1db37
P5: a4093822 ⇒ 5954010a
P6: 299f31d0 ⇒ 2b121658
P7: 082efa98 ⇒ e7a5b7ed
P8: ec4e6c89 ⇒ 21a6717f
P9: 452821e6 ⇒ b2bb1bf8
P10: 38d01377 ⇒ 937f0244
P11: be5466cf ⇒ e111a3da
P12: 34e90c6c ⇒ 67170ab6
P13: c0ac29b7 ⇒ 5d1db61b
P14: c97c50dd ⇒ cdf63d96
P15: 3f84d5b5 ⇒ c4935141
P16: b5470917 ⇒ ad859868
P17: 9216d5d9 ⇒ 0ca32381
P18: 8979fb1b ⇒ 50964a67
S1,0: d1310ba6 ⇒ a96eceb6
S1,1: 98dfb5ac ⇒ 3480051c
S1,2: 2ffd72db ⇒ 8d315fa7
S1,3: d01adfb7 ⇒ 936c585a
S1,4: b8e1afed ⇒ cd9cd593
...
S4,251: c208e69f ⇒ cc091e06
S4,252: b74e6132 ⇒ 2e7b8ad3
S4,253: ce77e25b ⇒ dc3d8ec5
S4,254: 578fdfe3 ⇒ c52e90ab
S4,255: 3ac372e6 ⇒ e1866c06
Когда я кодирую 0x0000000000000000 с этим набором данных, я получаю 0x3b8a9fa06e840430, но тестовый пример говорит, что я должен получить 0x4ef997456198dd78.
Ты видишь, куда я иду?
EDIT; Подробное шифрование после исправления 32-битного целочисленного значения
Вот как я интерпретирую (и я думаю, что моя программа интерпретирует) способ, которым происходит шифрование blowfish. Учитывая массив P и набор S-блоков, инициализированные шестнадцатеричными значениями pi, и массив P, XORed с нулевым ключом (так что он все тот же), я делаю следующее:
0x0000000000000000 ввод делится на две части, левая половина становится L0, а правая половина становится R0:
L0 = 0x00000000
R0 = 0x00000000
R1 = L0 ^ P1 = 0x00000000 ^ 0x243f6a88 = 0x243f6a88
L1 = F(R1) ^ R0 = F(0x243f6a88) ^ 0x00000000 = 0xdb2f9c4e ^ 0x00000000 = 0xdb2f9c4e
R2 = L1 ^ P2 = 0xdb2f9c4e ^ 0x85a308d3 = 0x5e8c949d
L2 = F(R2) ^ R1 = F(0x5e8c949d) ^ 0x243f6a88 = 0x33002cc0 ^ 0x243f6a88 = 0x173f4648
R3 = L2 ^ P3 = 0x173f4648 ^ 0x13198a2e = 0x426cc66
L3 = F(R3) ^ R2 = F(0x426cc66) ^ 0x5e8c949d = 0xd8a68913 ^ 0x5e8c949d = 0x862a1d8e
....
R16 = L15 ^ P16 = 0xf5e1fd40 ^ 0xb5470917 = 0x40a6f457
L16 = F(R16) ^ R15 = F(0x40a6f457) ^ 0xea27e3cc = 0x66509b85 ^ 0xea27e3cc = 0x8c777849
Now untwist and apply final P values
R_final = L16 ^ P17 = 0x8c777849 ^ 0x9216d5d9 = 0x1e61ad90
L_final = R16 ^ P18 = 0x40a6f457 ^ 0x8979fb1b = 0xc9df0f4c
Final ciphered output: 0xc9df0f4c1e61ad90, should be 0x706d9fcc1792d23a...