title: Blowfish encryption sub-key generation
body: <p>Okay, so I'm doing a little blowfish implementation in PHP as a programming exercise for myself, and to get to know that encryption method better. I arrived at a set of functions that work, in that I can encrypt data and decrypt it again, but the <a href="http://www.schneier.com/code/vectors.txt" rel="nofollow noreferrer">test vectors</a> I found don't agree with my encrypted values... Since the encode/decode seems to work, I'm guessing the error is in my function's setup of applying the secret key to the P array and S-boxes, arriving at a different set of P values and S-box values, so the encoded values are different. Can someone find where my logic is going awry?</p>
  
  <p>For the test case of a key of 0x0000000000000000 and a text input of 0x0000000000000000, the first step is to XOR the key with the P array, but with a key of all zeroes, that will result in the P array being unchanged, so will still have the hex values of pi that it starts with. Then a 64-byte text string (0x0000000000000000) is encoded using the current P array and S-boxes, and the result gets split to replace P1 and P2. Then that same output is encoded again (using the new P1 and P2 values) to get another output, which is used to replace P3 and P4. This continues until all the P values are changed, and the S-boxes. Doing that process, I get the following (original values on the left, value after propagating through the secret key process on the right):</p>
  
  <pre><code>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
  </code></pre>
  
  <p>When I encode 0x0000000000000000 with that data set, I get 0x3b8a9fa06e840430, but the test case says I should get 0x4ef997456198dd78. </p>
  
  <p>Can you see where I'm going awry?</p>
  
  <p><strong>EDIT; Detailed enciphering, after fixing 32-bit integer issue</strong>
  Here's how I interpret (and I think my program is interpreting) the way that the blowfish enciphering happens. Given a P array and S-box set initialized with the hex values of pi and the P array XORed with a null key (so it's still the same), I do the following:</p>
  
  <p>0x0000000000000000 input gets split into two, the left half becomes L0, and the right half becomes R0:</p>
  
  <pre><code>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...
  </code></pre>