Skip to content

Instantly share code, notes, and snippets.

@MidnightLightning
Last active February 10, 2016 19:32
Show Gist options
  • Select an option

  • Save MidnightLightning/6d74fda28f7dd2179842 to your computer and use it in GitHub Desktop.

Select an option

Save MidnightLightning/6d74fda28f7dd2179842 to your computer and use it in GitHub Desktop.
Blowfish encryption
<?php
/**
* Utilize the Blowfish encryption algorithm without using mcrypt extension
* @package Encryption
* @author Brooks Boyd <[email protected]>
* @version 1.0
*/
/**
* Object for holding encryption key schedule and processing
* @package Encryption
*/
class cryptBlowfish {
/**
* Holds the P array and S-Boxes needed for the Blowfish encryption
* @var array First 18 entries are the P array, the rest are the four S-boxes
*/
private $key_schedule = array();
/**
* Fills {@link cryptBlowfish::key_schedule} with default values
* Used in {@link cryptBlowfish::__construct()} to initialize the object
* @uses $key_schedule
*/
function default_schedule() {
$this->key_schedule = array(0 => 0x243f6a88, 1 => 0x85a308d3, 2 => 0x13198a2e, 3 => 0x03707344, 4 => 0xa4093822, 5 => 0x299f31d0, 6 => 0x082efa98, 7 => 0xec4e6c89, 8 => 0x452821e6, 9 => 0x38d01377, 10 => 0xbe5466cf, 11 => 0x34e90c6c, 12 => 0xc0ac29b7, 13 => 0xc97c50dd, 14 => 0x3f84d5b5, 15 => 0xb5470917, 16 => 0x9216d5d9, 17 => 0x8979fb1b, 18 => 0xd1310ba6, 19 => 0x98dfb5ac, 20 => 0x2ffd72db, 21 => 0xd01adfb7, 22 => 0xb8e1afed, 23 => 0x6a267e96, 24 => 0xba7c9045, 25 => 0xf12c7f99, 26 => 0x24a19947, 27 => 0xb3916cf7, 28 => 0x0801f2e2, 29 => 0x858efc16, 30 => 0x636920d8, 31 => 0x71574e69, 32 => 0xa458fea3, 33 => 0xf4933d7e, 34 => 0x0d95748f, 35 => 0x728eb658, 36 => 0x718bcd58, 37 => 0x82154aee, 38 => 0x7b54a41d, 39 => 0xc25a59b5, 40 => 0x9c30d539, 41 => 0x2af26013, 42 => 0xc5d1b023, 43 => 0x286085f0, 44 => 0xca417918, 45 => 0xb8db38ef, 46 => 0x8e79dcb0, 47 => 0x603a180e, 48 => 0x6c9e0e8b, 49 => 0xb01e8a3e, 50 => 0xd71577c1, 51 => 0xbd314b27, 52 => 0x78af2fda, 53 => 0x55605c60, 54 => 0xe65525f3, 55 => 0xaa55ab94, 56 => 0x57489862, 57 => 0x63e81440, 58 => 0x55ca396a, 59 => 0x2aab10b6, 60 => 0xb4cc5c34, 61 => 0x1141e8ce, 62 => 0xa15486af, 63 => 0x7c72e993, 64 => 0xb3ee1411, 65 => 0x636fbc2a, 66 => 0x2ba9c55d, 67 => 0x741831f6, 68 => 0xce5c3e16, 69 => 0x9b87931e, 70 => 0xafd6ba33, 71 => 0x6c24cf5c, 72 => 0x7a325381, 73 => 0x28958677, 74 => 0x3b8f4898, 75 => 0x6b4bb9af, 76 => 0xc4bfe81b, 77 => 0x66282193, 78 => 0x61d809cc, 79 => 0xfb21a991, 80 => 0x487cac60, 81 => 0x5dec8032, 82 => 0xef845d5d, 83 => 0xe98575b1, 84 => 0xdc262302, 85 => 0xeb651b88, 86 => 0x23893e81, 87 => 0xd396acc5, 88 => 0x0f6d6ff3, 89 => 0x83f44239, 90 => 0x2e0b4482, 91 => 0xa4842004, 92 => 0x69c8f04a, 93 => 0x9e1f9b5e, 94 => 0x21c66842, 95 => 0xf6e96c9a, 96 => 0x670c9c61, 97 => 0xabd388f0, 98 => 0x6a51a0d2, 99 => 0xd8542f68, 100 => 0x960fa728, 101 => 0xab5133a3, 102 => 0x6eef0b6c, 103 => 0x137a3be4, 104 => 0xba3bf050, 105 => 0x7efb2a98, 106 => 0xa1f1651d, 107 => 0x39af0176, 108 => 0x66ca593e, 109 => 0x82430e88, 110 => 0x8cee8619, 111 => 0x456f9fb4, 112 => 0x7d84a5c3, 113 => 0x3b8b5ebe, 114 => 0xe06f75d8, 115 => 0x85c12073, 116 => 0x401a449f, 117 => 0x56c16aa6, 118 => 0x4ed3aa62, 119 => 0x363f7706, 120 => 0x1bfedf72, 121 => 0x429b023d, 122 => 0x37d0d724, 123 => 0xd00a1248, 124 => 0xdb0fead3, 125 => 0x49f1c09b, 126 => 0x075372c9, 127 => 0x80991b7b, 128 => 0x25d479d8, 129 => 0xf6e8def7, 130 => 0xe3fe501a, 131 => 0xb6794c3b, 132 => 0x976ce0bd, 133 => 0x04c006ba, 134 => 0xc1a94fb6, 135 => 0x409f60c4, 136 => 0x5e5c9ec2, 137 => 0x196a2463, 138 => 0x68fb6faf, 139 => 0x3e6c53b5, 140 => 0x1339b2eb, 141 => 0x3b52ec6f, 142 => 0x6dfc511f, 143 => 0x9b30952c, 144 => 0xcc814544, 145 => 0xaf5ebd09, 146 => 0xbee3d004, 147 => 0xde334afd, 148 => 0x660f2807, 149 => 0x192e4bb3, 150 => 0xc0cba857, 151 => 0x45c8740f, 152 => 0xd20b5f39, 153 => 0xb9d3fbdb, 154 => 0x5579c0bd, 155 => 0x1a60320a, 156 => 0xd6a100c6, 157 => 0x402c7279, 158 => 0x679f25fe, 159 => 0xfb1fa3cc, 160 => 0x8ea5e9f8, 161 => 0xdb3222f8, 162 => 0x3c7516df, 163 => 0xfd616b15, 164 => 0x2f501ec8, 165 => 0xad0552ab, 166 => 0x323db5fa, 167 => 0xfd238760, 168 => 0x53317b48, 169 => 0x3e00df82, 170 => 0x9e5c57bb, 171 => 0xca6f8ca0, 172 => 0x1a87562e, 173 => 0xdf1769db, 174 => 0xd542a8f6, 175 => 0x287effc3, 176 => 0xac6732c6, 177 => 0x8c4f5573, 178 => 0x695b27b0, 179 => 0xbbca58c8, 180 => 0xe1ffa35d, 181 => 0xb8f011a0, 182 => 0x10fa3d98, 183 => 0xfd2183b8, 184 => 0x4afcb56c, 185 => 0x2dd1d35b, 186 => 0x9a53e479, 187 => 0xb6f84565, 188 => 0xd28e49bc, 189 => 0x4bfb9790, 190 => 0xe1ddf2da, 191 => 0xa4cb7e33, 192 => 0x62fb1341, 193 => 0xcee4c6e8, 194 => 0xef20cada, 195 => 0x36774c01, 196 => 0xd07e9efe, 197 => 0x2bf11fb4, 198 => 0x95dbda4d, 199 => 0xae909198, 200 => 0xeaad8e71, 201 => 0x6b93d5a0, 202 => 0xd08ed1d0, 203 => 0xafc725e0, 204 => 0x8e3c5b2f, 205 => 0x8e7594b7, 206 => 0x8ff6e2fb, 207 => 0xf2122b64, 208 => 0x8888b812, 209 => 0x900df01c, 210 => 0x4fad5ea0, 211 => 0x688fc31c, 212 => 0xd1cff191, 213 => 0xb3a8c1ad, 214 => 0x2f2f2218, 215 => 0xbe0e1777, 216 => 0xea752dfe, 217 => 0x8b021fa1, 218 => 0xe5a0cc0f, 219 => 0xb56f74e8, 220 => 0x18acf3d6, 221 => 0xce89e299, 222 => 0xb4a84fe0, 223 => 0xfd13e0b7, 224 => 0x7cc43b81, 225 => 0xd2ada8d9, 226 => 0x165fa266, 227 => 0x80957705, 228 => 0x93cc7314, 229 => 0x211a1477, 230 => 0xe6ad2065, 231 => 0x77b5fa86, 232 => 0xc75442f5, 233 => 0xfb9d35cf, 234 => 0xebcdaf0c, 235 => 0x7b3e89a0, 236 => 0xd6411bd3, 237 => 0xae1e7e49, 238 => 0x00250e2d, 239 => 0x2071b35e, 240 => 0x226800bb, 241 => 0x57b8e0af, 242 => 0x2464369b, 243 => 0xf009b91e, 244 => 0x5563911d, 245 => 0x59dfa6aa, 246 => 0x78c14389, 247 => 0xd95a537f, 248 => 0x207d5ba2, 249 => 0x02e5b9c5, 250 => 0x83260376, 251 => 0x6295cfa9, 252 => 0x11c81968, 253 => 0x4e734a41, 254 => 0xb3472dca, 255 => 0x7b14a94a, 256 => 0x1b510052, 257 => 0x9a532915, 258 => 0xd60f573f, 259 => 0xbc9bc6e4, 260 => 0x2b60a476, 261 => 0x81e67400, 262 => 0x08ba6fb5, 263 => 0x571be91f, 264 => 0xf296ec6b, 265 => 0x2a0dd915, 266 => 0xb6636521, 267 => 0xe7b9f9b6, 268 => 0xff34052e, 269 => 0xc5855664, 270 => 0x53b02d5d, 271 => 0xa99f8fa1, 272 => 0x08ba4799, 273 => 0x6e85076a, 274 => 0x4b7a70e9, 275 => 0xb5b32944, 276 => 0xdb75092e, 277 => 0xc4192623, 278 => 0xad6ea6b0, 279 => 0x49a7df7d, 280 => 0x9cee60b8, 281 => 0x8fedb266, 282 => 0xecaa8c71, 283 => 0x699a17ff, 284 => 0x5664526c, 285 => 0xc2b19ee1, 286 => 0x193602a5, 287 => 0x75094c29, 288 => 0xa0591340, 289 => 0xe4183a3e, 290 => 0x3f54989a, 291 => 0x5b429d65, 292 => 0x6b8fe4d6, 293 => 0x99f73fd6, 294 => 0xa1d29c07, 295 => 0xefe830f5, 296 => 0x4d2d38e6, 297 => 0xf0255dc1, 298 => 0x4cdd2086, 299 => 0x8470eb26, 300 => 0x6382e9c6, 301 => 0x021ecc5e, 302 => 0x09686b3f, 303 => 0x3ebaefc9, 304 => 0x3c971814, 305 => 0x6b6a70a1, 306 => 0x687f3584, 307 => 0x52a0e286, 308 => 0xb79c5305, 309 => 0xaa500737, 310 => 0x3e07841c, 311 => 0x7fdeae5c, 312 => 0x8e7d44ec, 313 => 0x5716f2b8, 314 => 0xb03ada37, 315 => 0xf0500c0d, 316 => 0xf01c1f04, 317 => 0x0200b3ff, 318 => 0xae0cf51a, 319 => 0x3cb574b2, 320 => 0x25837a58, 321 => 0xdc0921bd, 322 => 0xd19113f9, 323 => 0x7ca92ff6, 324 => 0x94324773, 325 => 0x22f54701, 326 => 0x3ae5e581, 327 => 0x37c2dadc, 328 => 0xc8b57634, 329 => 0x9af3dda7, 330 => 0xa9446146, 331 => 0x0fd0030e, 332 => 0xecc8c73e, 333 => 0xa4751e41, 334 => 0xe238cd99, 335 => 0x3bea0e2f, 336 => 0x3280bba1, 337 => 0x183eb331, 338 => 0x4e548b38, 339 => 0x4f6db908, 340 => 0x6f420d03, 341 => 0xf60a04bf, 342 => 0x2cb81290, 343 => 0x24977c79, 344 => 0x5679b072, 345 => 0xbcaf89af, 346 => 0xde9a771f, 347 => 0xd9930810, 348 => 0xb38bae12, 349 => 0xdccf3f2e, 350 => 0x5512721f, 351 => 0x2e6b7124, 352 => 0x501adde6, 353 => 0x9f84cd87, 354 => 0x7a584718, 355 => 0x7408da17, 356 => 0xbc9f9abc, 357 => 0xe94b7d8c, 358 => 0xec7aec3a, 359 => 0xdb851dfa, 360 => 0x63094366, 361 => 0xc464c3d2, 362 => 0xef1c1847, 363 => 0x3215d908, 364 => 0xdd433b37, 365 => 0x24c2ba16, 366 => 0x12a14d43, 367 => 0x2a65c451, 368 => 0x50940002, 369 => 0x133ae4dd, 370 => 0x71dff89e, 371 => 0x10314e55, 372 => 0x81ac77d6, 373 => 0x5f11199b, 374 => 0x043556f1, 375 => 0xd7a3c76b, 376 => 0x3c11183b, 377 => 0x5924a509, 378 => 0xf28fe6ed, 379 => 0x97f1fbfa, 380 => 0x9ebabf2c, 381 => 0x1e153c6e, 382 => 0x86e34570, 383 => 0xeae96fb1, 384 => 0x860e5e0a, 385 => 0x5a3e2ab3, 386 => 0x771fe71c, 387 => 0x4e3d06fa, 388 => 0x2965dcb9, 389 => 0x99e71d0f, 390 => 0x803e89d6, 391 => 0x5266c825, 392 => 0x2e4cc978, 393 => 0x9c10b36a, 394 => 0xc6150eba, 395 => 0x94e2ea78, 396 => 0xa5fc3c53, 397 => 0x1e0a2df4, 398 => 0xf2f74ea7, 399 => 0x361d2b3d, 400 => 0x1939260f, 401 => 0x19c27960, 402 => 0x5223a708, 403 => 0xf71312b6, 404 => 0xebadfe6e, 405 => 0xeac31f66, 406 => 0xe3bc4595, 407 => 0xa67bc883, 408 => 0xb17f37d1, 409 => 0x018cff28, 410 => 0xc332ddef, 411 => 0xbe6c5aa5, 412 => 0x65582185, 413 => 0x68ab9802, 414 => 0xeecea50f, 415 => 0xdb2f953b, 416 => 0x2aef7dad, 417 => 0x5b6e2f84, 418 => 0x1521b628, 419 => 0x29076170, 420 => 0xecdd4775, 421 => 0x619f1510, 422 => 0x13cca830, 423 => 0xeb61bd96, 424 => 0x0334fe1e, 425 => 0xaa0363cf, 426 => 0xb5735c90, 427 => 0x4c70a239, 428 => 0xd59e9e0b, 429 => 0xcbaade14, 430 => 0xeecc86bc, 431 => 0x60622ca7, 432 => 0x9cab5cab, 433 => 0xb2f3846e, 434 => 0x648b1eaf, 435 => 0x19bdf0ca, 436 => 0xa02369b9, 437 => 0x655abb50, 438 => 0x40685a32, 439 => 0x3c2ab4b3, 440 => 0x319ee9d5, 441 => 0xc021b8f7, 442 => 0x9b540b19, 443 => 0x875fa099, 444 => 0x95f7997e, 445 => 0x623d7da8, 446 => 0xf837889a, 447 => 0x97e32d77, 448 => 0x11ed935f, 449 => 0x16681281, 450 => 0x0e358829, 451 => 0xc7e61fd6, 452 => 0x96dedfa1, 453 => 0x7858ba99, 454 => 0x57f584a5, 455 => 0x1b227263, 456 => 0x9b83c3ff, 457 => 0x1ac24696, 458 => 0xcdb30aeb, 459 => 0x532e3054, 460 => 0x8fd948e4, 461 => 0x6dbc3128, 462 => 0x58ebf2ef, 463 => 0x34c6ffea, 464 => 0xfe28ed61, 465 => 0xee7c3c73, 466 => 0x5d4a14d9, 467 => 0xe864b7e3, 468 => 0x42105d14, 469 => 0x203e13e0, 470 => 0x45eee2b6, 471 => 0xa3aaabea, 472 => 0xdb6c4f15, 473 => 0xfacb4fd0, 474 => 0xc742f442, 475 => 0xef6abbb5, 476 => 0x654f3b1d, 477 => 0x41cd2105, 478 => 0xd81e799e, 479 => 0x86854dc7, 480 => 0xe44b476a, 481 => 0x3d816250, 482 => 0xcf62a1f2, 483 => 0x5b8d2646, 484 => 0xfc8883a0, 485 => 0xc1c7b6a3, 486 => 0x7f1524c3, 487 => 0x69cb7492, 488 => 0x47848a0b, 489 => 0x5692b285, 490 => 0x095bbf00, 491 => 0xad19489d, 492 => 0x1462b174, 493 => 0x23820e00, 494 => 0x58428d2a, 495 => 0x0c55f5ea, 496 => 0x1dadf43e, 497 => 0x233f7061, 498 => 0x3372f092, 499 => 0x8d937e41, 500 => 0xd65fecf1, 501 => 0x6c223bdb, 502 => 0x7cde3759, 503 => 0xcbee7460, 504 => 0x4085f2a7, 505 => 0xce77326e, 506 => 0xa6078084, 507 => 0x19f8509e, 508 => 0xe8efd855, 509 => 0x61d99735, 510 => 0xa969a7aa, 511 => 0xc50c06c2, 512 => 0x5a04abfc, 513 => 0x800bcadc, 514 => 0x9e447a2e, 515 => 0xc3453484, 516 => 0xfdd56705, 517 => 0x0e1e9ec9, 518 => 0xdb73dbd3, 519 => 0x105588cd, 520 => 0x675fda79, 521 => 0xe3674340, 522 => 0xc5c43465, 523 => 0x713e38d8, 524 => 0x3d28f89e, 525 => 0xf16dff20, 526 => 0x153e21e7, 527 => 0x8fb03d4a, 528 => 0xe6e39f2b, 529 => 0xdb83adf7, 530 => 0xe93d5a68, 531 => 0x948140f7, 532 => 0xf64c261c, 533 => 0x94692934, 534 => 0x411520f7, 535 => 0x7602d4f7, 536 => 0xbcf46b2e, 537 => 0xd4a20068, 538 => 0xd4082471, 539 => 0x3320f46a, 540 => 0x43b7d4b7, 541 => 0x500061af, 542 => 0x1e39f62e, 543 => 0x97244546, 544 => 0x14214f74, 545 => 0xbf8b8840, 546 => 0x4d95fc1d, 547 => 0x96b591af, 548 => 0x70f4ddd3, 549 => 0x66a02f45, 550 => 0xbfbc09ec, 551 => 0x03bd9785, 552 => 0x7fac6dd0, 553 => 0x31cb8504, 554 => 0x96eb27b3, 555 => 0x55fd3941, 556 => 0xda2547e6, 557 => 0xabca0a9a, 558 => 0x28507825, 559 => 0x530429f4, 560 => 0x0a2c86da, 561 => 0xe9b66dfb, 562 => 0x68dc1462, 563 => 0xd7486900, 564 => 0x680ec0a4, 565 => 0x27a18dee, 566 => 0x4f3ffea2, 567 => 0xe887ad8c, 568 => 0xb58ce006, 569 => 0x7af4d6b6, 570 => 0xaace1e7c, 571 => 0xd3375fec, 572 => 0xce78a399, 573 => 0x406b2a42, 574 => 0x20fe9e35, 575 => 0xd9f385b9, 576 => 0xee39d7ab, 577 => 0x3b124e8b, 578 => 0x1dc9faf7, 579 => 0x4b6d1856, 580 => 0x26a36631, 581 => 0xeae397b2, 582 => 0x3a6efa74, 583 => 0xdd5b4332, 584 => 0x6841e7f7, 585 => 0xca7820fb, 586 => 0xfb0af54e, 587 => 0xd8feb397, 588 => 0x454056ac, 589 => 0xba489527, 590 => 0x55533a3a, 591 => 0x20838d87, 592 => 0xfe6ba9b7, 593 => 0xd096954b, 594 => 0x55a867bc, 595 => 0xa1159a58, 596 => 0xcca92963, 597 => 0x99e1db33, 598 => 0xa62a4a56, 599 => 0x3f3125f9, 600 => 0x5ef47e1c, 601 => 0x9029317c, 602 => 0xfdf8e802, 603 => 0x04272f70, 604 => 0x80bb155c, 605 => 0x05282ce3, 606 => 0x95c11548, 607 => 0xe4c66d22, 608 => 0x48c1133f, 609 => 0xc70f86dc, 610 => 0x07f9c9ee, 611 => 0x41041f0f, 612 => 0x404779a4, 613 => 0x5d886e17, 614 => 0x325f51eb, 615 => 0xd59bc0d1, 616 => 0xf2bcc18f, 617 => 0x41113564, 618 => 0x257b7834, 619 => 0x602a9c60, 620 => 0xdff8e8a3, 621 => 0x1f636c1b, 622 => 0x0e12b4c2, 623 => 0x02e1329e, 624 => 0xaf664fd1, 625 => 0xcad18115, 626 => 0x6b2395e0, 627 => 0x333e92e1, 628 => 0x3b240b62, 629 => 0xeebeb922, 630 => 0x85b2a20e, 631 => 0xe6ba0d99, 632 => 0xde720c8c, 633 => 0x2da2f728, 634 => 0xd0127845, 635 => 0x95b794fd, 636 => 0x647d0862, 637 => 0xe7ccf5f0, 638 => 0x5449a36f, 639 => 0x877d48fa, 640 => 0xc39dfd27, 641 => 0xf33e8d1e, 642 => 0x0a476341, 643 => 0x992eff74, 644 => 0x3a6f6eab, 645 => 0xf4f8fd37, 646 => 0xa812dc60, 647 => 0xa1ebddf8, 648 => 0x991be14c, 649 => 0xdb6e6b0d, 650 => 0xc67b5510, 651 => 0x6d672c37, 652 => 0x2765d43b, 653 => 0xdcd0e804, 654 => 0xf1290dc7, 655 => 0xcc00ffa3, 656 => 0xb5390f92, 657 => 0x690fed0b, 658 => 0x667b9ffb, 659 => 0xcedb7d9c, 660 => 0xa091cf0b, 661 => 0xd9155ea3, 662 => 0xbb132f88, 663 => 0x515bad24, 664 => 0x7b9479bf, 665 => 0x763bd6eb, 666 => 0x37392eb3, 667 => 0xcc115979, 668 => 0x8026e297, 669 => 0xf42e312d, 670 => 0x6842ada7, 671 => 0xc66a2b3b, 672 => 0x12754ccc, 673 => 0x782ef11c, 674 => 0x6a124237, 675 => 0xb79251e7, 676 => 0x06a1bbe6, 677 => 0x4bfb6350, 678 => 0x1a6b1018, 679 => 0x11caedfa, 680 => 0x3d25bdd8, 681 => 0xe2e1c3c9, 682 => 0x44421659, 683 => 0x0a121386, 684 => 0xd90cec6e, 685 => 0xd5abea2a, 686 => 0x64af674e, 687 => 0xda86a85f, 688 => 0xbebfe988, 689 => 0x64e4c3fe, 690 => 0x9dbc8057, 691 => 0xf0f7c086, 692 => 0x60787bf8, 693 => 0x6003604d, 694 => 0xd1fd8346, 695 => 0xf6381fb0, 696 => 0x7745ae04, 697 => 0xd736fccc, 698 => 0x83426b33, 699 => 0xf01eab71, 700 => 0xb0804187, 701 => 0x3c005e5f, 702 => 0x77a057be, 703 => 0xbde8ae24, 704 => 0x55464299, 705 => 0xbf582e61, 706 => 0x4e58f48f, 707 => 0xf2ddfda2, 708 => 0xf474ef38, 709 => 0x8789bdc2, 710 => 0x5366f9c3, 711 => 0xc8b38e74, 712 => 0xb475f255, 713 => 0x46fcd9b9, 714 => 0x7aeb2661, 715 => 0x8b1ddf84, 716 => 0x846a0e79, 717 => 0x915f95e2, 718 => 0x466e598e, 719 => 0x20b45770, 720 => 0x8cd55591, 721 => 0xc902de4c, 722 => 0xb90bace1, 723 => 0xbb8205d0, 724 => 0x11a86248, 725 => 0x7574a99e, 726 => 0xb77f19b6, 727 => 0xe0a9dc09, 728 => 0x662d09a1, 729 => 0xc4324633, 730 => 0xe85a1f02, 731 => 0x09f0be8c, 732 => 0x4a99a025, 733 => 0x1d6efe10, 734 => 0x1ab93d1d, 735 => 0x0ba5a4df, 736 => 0xa186f20f, 737 => 0x2868f169, 738 => 0xdcb7da83, 739 => 0x573906fe, 740 => 0xa1e2ce9b, 741 => 0x4fcd7f52, 742 => 0x50115e01, 743 => 0xa70683fa, 744 => 0xa002b5c4, 745 => 0x0de6d027, 746 => 0x9af88c27, 747 => 0x773f8641, 748 => 0xc3604c06, 749 => 0x61a806b5, 750 => 0xf0177a28, 751 => 0xc0f586e0, 752 => 0x006058aa, 753 => 0x30dc7d62, 754 => 0x11e69ed7, 755 => 0x2338ea63, 756 => 0x53c2dd94, 757 => 0xc2c21634, 758 => 0xbbcbee56, 759 => 0x90bcb6de, 760 => 0xebfc7da1, 761 => 0xce591d76, 762 => 0x6f05e409, 763 => 0x4b7c0188, 764 => 0x39720a3d, 765 => 0x7c927c24, 766 => 0x86e3725f, 767 => 0x724d9db9, 768 => 0x1ac15bb4, 769 => 0xd39eb8fc, 770 => 0xed545578, 771 => 0x08fca5b5, 772 => 0xd83d7cd3, 773 => 0x4dad0fc4, 774 => 0x1e50ef5e, 775 => 0xb161e6f8, 776 => 0xa28514d9, 777 => 0x6c51133c, 778 => 0x6fd5c7e7, 779 => 0x56e14ec4, 780 => 0x362abfce, 781 => 0xddc6c837, 782 => 0xd79a3234, 783 => 0x92638212, 784 => 0x670efa8e, 785 => 0x406000e0, 786 => 0x3a39ce37, 787 => 0xd3faf5cf, 788 => 0xabc27737, 789 => 0x5ac52d1b, 790 => 0x5cb0679e, 791 => 0x4fa33742, 792 => 0xd3822740, 793 => 0x99bc9bbe, 794 => 0xd5118e9d, 795 => 0xbf0f7315, 796 => 0xd62d1c7e, 797 => 0xc700c47b, 798 => 0xb78c1b6b, 799 => 0x21a19045, 800 => 0xb26eb1be, 801 => 0x6a366eb4, 802 => 0x5748ab2f, 803 => 0xbc946e79, 804 => 0xc6a376d2, 805 => 0x6549c2c8, 806 => 0x530ff8ee, 807 => 0x468dde7d, 808 => 0xd5730a1d, 809 => 0x4cd04dc6, 810 => 0x2939bbdb, 811 => 0xa9ba4650, 812 => 0xac9526e8, 813 => 0xbe5ee304, 814 => 0xa1fad5f0, 815 => 0x6a2d519a, 816 => 0x63ef8ce2, 817 => 0x9a86ee22, 818 => 0xc089c2b8, 819 => 0x43242ef6, 820 => 0xa51e03aa, 821 => 0x9cf2d0a4, 822 => 0x83c061ba, 823 => 0x9be96a4d, 824 => 0x8fe51550, 825 => 0xba645bd6, 826 => 0x2826a2f9, 827 => 0xa73a3ae1, 828 => 0x4ba99586, 829 => 0xef5562e9, 830 => 0xc72fefd3, 831 => 0xf752f7da, 832 => 0x3f046f69, 833 => 0x77fa0a59, 834 => 0x80e4a915, 835 => 0x87b08601, 836 => 0x9b09e6ad, 837 => 0x3b3ee593, 838 => 0xe990fd5a, 839 => 0x9e34d797, 840 => 0x2cf0b7d9, 841 => 0x022b8b51, 842 => 0x96d5ac3a, 843 => 0x017da67d, 844 => 0xd1cf3ed6, 845 => 0x7c7d2d28, 846 => 0x1f9f25cf, 847 => 0xadf2b89b, 848 => 0x5ad6b472, 849 => 0x5a88f54c, 850 => 0xe029ac71, 851 => 0xe019a5e6, 852 => 0x47b0acfd, 853 => 0xed93fa9b, 854 => 0xe8d3c48d, 855 => 0x283b57cc, 856 => 0xf8d56629, 857 => 0x79132e28, 858 => 0x785f0191, 859 => 0xed756055, 860 => 0xf7960e44, 861 => 0xe3d35e8c, 862 => 0x15056dd4, 863 => 0x88f46dba, 864 => 0x03a16125, 865 => 0x0564f0bd, 866 => 0xc3eb9e15, 867 => 0x3c9057a2, 868 => 0x97271aec, 869 => 0xa93a072a, 870 => 0x1b3f6d9b, 871 => 0x1e6321f5, 872 => 0xf59c66fb, 873 => 0x26dcf319, 874 => 0x7533d928, 875 => 0xb155fdf5, 876 => 0x03563482, 877 => 0x8aba3cbb, 878 => 0x28517711, 879 => 0xc20ad9f8, 880 => 0xabcc5167, 881 => 0xccad925f, 882 => 0x4de81751, 883 => 0x3830dc8e, 884 => 0x379d5862, 885 => 0x9320f991, 886 => 0xea7a90c2, 887 => 0xfb3e7bce, 888 => 0x5121ce64, 889 => 0x774fbe32, 890 => 0xa8b6e37e, 891 => 0xc3293d46, 892 => 0x48de5369, 893 => 0x6413e680, 894 => 0xa2ae0810, 895 => 0xdd6db224, 896 => 0x69852dfd, 897 => 0x09072166, 898 => 0xb39a460a, 899 => 0x6445c0dd, 900 => 0x586cdecf, 901 => 0x1c20c8ae, 902 => 0x5bbef7dd, 903 => 0x1b588d40, 904 => 0xccd2017f, 905 => 0x6bb4e3bb, 906 => 0xdda26a7e, 907 => 0x3a59ff45, 908 => 0x3e350a44, 909 => 0xbcb4cdd5, 910 => 0x72eacea8, 911 => 0xfa6484bb, 912 => 0x8d6612ae, 913 => 0xbf3c6f47, 914 => 0xd29be463, 915 => 0x542f5d9e, 916 => 0xaec2771b, 917 => 0xf64e6370, 918 => 0x740e0d8d, 919 => 0xe75b1357, 920 => 0xf8721671, 921 => 0xaf537d5d, 922 => 0x4040cb08, 923 => 0x4eb4e2cc, 924 => 0x34d2466a, 925 => 0x0115af84, 926 => 0xe1b00428, 927 => 0x95983a1d, 928 => 0x06b89fb4, 929 => 0xce6ea048, 930 => 0x6f3f3b82, 931 => 0x3520ab82, 932 => 0x011a1d4b, 933 => 0x277227f8, 934 => 0x611560b1, 935 => 0xe7933fdc, 936 => 0xbb3a792b, 937 => 0x344525bd, 938 => 0xa08839e1, 939 => 0x51ce794b, 940 => 0x2f32c9b7, 941 => 0xa01fbac9, 942 => 0xe01cc87e, 943 => 0xbcc7d1f6, 944 => 0xcf0111c3, 945 => 0xa1e8aac7, 946 => 0x1a908749, 947 => 0xd44fbd9a, 948 => 0xd0dadecb, 949 => 0xd50ada38, 950 => 0x0339c32a, 951 => 0xc6913667, 952 => 0x8df9317c, 953 => 0xe0b12b4f, 954 => 0xf79e59b7, 955 => 0x43f5bb3a, 956 => 0xf2d519ff, 957 => 0x27d9459c, 958 => 0xbf97222c, 959 => 0x15e6fc2a, 960 => 0x0f91fc71, 961 => 0x9b941525, 962 => 0xfae59361, 963 => 0xceb69ceb, 964 => 0xc2a86459, 965 => 0x12baa8d1, 966 => 0xb6c1075e, 967 => 0xe3056a0c, 968 => 0x10d25065, 969 => 0xcb03a442, 970 => 0xe0ec6e0e, 971 => 0x1698db3b, 972 => 0x4c98a0be, 973 => 0x3278e964, 974 => 0x9f1f9532, 975 => 0xe0d392df, 976 => 0xd3a0342b, 977 => 0x8971f21e, 978 => 0x1b0a7441, 979 => 0x4ba3348c, 980 => 0xc5be7120, 981 => 0xc37632d8, 982 => 0xdf359f8d, 983 => 0x9b992f2e, 984 => 0xe60b6f47, 985 => 0x0fe3f11d, 986 => 0xe54cda54, 987 => 0x1edad891, 988 => 0xce6279cf, 989 => 0xcd3e7e6f, 990 => 0x1618b166, 991 => 0xfd2c1d05, 992 => 0x848fd2c5, 993 => 0xf6fb2299, 994 => 0xf523f357, 995 => 0xa6327623, 996 => 0x93a83531, 997 => 0x56cccd02, 998 => 0xacf08162, 999 => 0x5a75ebb5, 1000 => 0x6e163697, 1001 => 0x88d273cc, 1002 => 0xde966292, 1003 => 0x81b949d0, 1004 => 0x4c50901b, 1005 => 0x71c65614, 1006 => 0xe6c6c7bd, 1007 => 0x327a140a, 1008 => 0x45e1d006, 1009 => 0xc3f27b9a, 1010 => 0xc9aa53fd, 1011 => 0x62a80f00, 1012 => 0xbb25bfe2, 1013 => 0x35bdd2f6, 1014 => 0x71126905, 1015 => 0xb2040222, 1016 => 0xb6cbcf7c, 1017 => 0xcd769c2b, 1018 => 0x53113ec0, 1019 => 0x1640e3d3, 1020 => 0x38abbd60, 1021 => 0x2547adf0, 1022 => 0xba38209c, 1023 => 0xf746ce76, 1024 => 0x77afa1c5, 1025 => 0x20756060, 1026 => 0x85cbfe4e, 1027 => 0x8ae88dd8, 1028 => 0x7aaaf9b0, 1029 => 0x4cf9aa7e, 1030 => 0x1948c25c, 1031 => 0x02fb8a8c, 1032 => 0x01c36ae4, 1033 => 0xd6ebe1f9, 1034 => 0x90d4f869, 1035 => 0xa65cdea0, 1036 => 0x3f09252d, 1037 => 0xc208e69f, 1038 => 0xb74e6132, 1039 => 0xce77e25b, 1040 => 0x578fdfe3, 1041 => 0x3ac372e6);
}
/**
* Construct the encryption structure
* @param string $key Because blowfish key can be up to 144 bytes, and a int can only hold 32, must be passed as a string, where each character of the string is the ASCII representation of the desired number. Since ASCII represents 0-255 (0x00-0xFF) in one character, string must be 72 characters or less
* @uses default_schedule()
* @uses set_key()
*/
function __construct($key) {
if (strlen($key) > 72) throw new Exception("Key cannot be longer than a 72-character string! Truncate or otherwise shorten your key.");
$this->default_schedule();
if (strlen($key) > 0) $this->set_key($key); // If no key is passed, keep the original key schedule
}
/**
* Takes a given secret key and modifies the key schedule to set up the blowfish encryption
* Private function used principally by {@link cryptBlowfish::__construct()} function to initialize the object
* @param string $key
* @uses $key_schedule
*/
private function set_key($key) {
$len = strlen($key);
$k = 0;
for($i=0; $i<18; $i++) { // Loop through P array
// Take 8-byte chunks of the key; 4 characters
$piece = 0;
for($j=3; $j>=0; $j--) {
$piece += ord($key{$k}) << 8*$j;
$k = ($k+1) % $len;
}
$this->key_schedule[$i] ^= $piece;
}
$L = 0;
$R = 0;
for($i=0; $i<count($this->key_schedule); $i+=2) {
list($L, $R) = $this->encode($L, $R);
$this->key_schedule[$i] = $L;
$this->key_schedule[$i+1] = $R;
}
}
/**
* Encode the supplied data
* Data is input as two 32-bit integers (both because Blowfish uses its 64-bit input in two halves, and returns it the same way, and because 32-bit systems can't have a single 64-bit integer as a single parameter
* @param integer $L
* @param integer $R
* @uses thirtytwobit()
* @uses $key_schedule
*/
function encode($L, $R) {
for ($i = 0; $i < 16; $i++) {
$temp = $L ^ $this->key_schedule[$i];
$s1 = $this->key_schedule[(($temp>>24) & 255) + 18];
$s2 = $this->key_schedule[(($temp>>16) & 255) + 18 + 256];
$s3 = $this->key_schedule[(($temp>>8) & 255) + 18 + 512];
$s4 = $this->key_schedule[( $temp & 255) + 18 + 768];
$F = $this->thirtytwobit(($this->thirtytwobit($s1 + $s2) ^ $s3) + $s4);
$L = $F ^ $R;
$R = $temp;
}
$R = $L ^ $this->key_schedule[16];
$L = $temp ^ $this->key_schedule[17];
return array($L, $R);
}
/**
* Decode the supplied data
* Reverse the encryption proces to get back the original data. Data is input as two 32-bit integers (both because Blowfish uses its 64-bit input in two halves, and returns it the same way, and because 32-bit systems can't have a single 64-bit integer as a single parameter
* @param integer $L
* @param integer $R
* @uses thirtytwobit()
* @uses $key_schedule
*/
function decode($L, $R, $log = false) {
for ($i = 17; $i > 1; $i--) {
$temp = $L ^ $this->key_schedule[$i];
$s1 = $this->key_schedule[(($temp>>24) & 255) + 18];
$s2 = $this->key_schedule[(($temp>>16) & 255) + 18 + 256];
$s3 = $this->key_schedule[(($temp>>8) & 255) + 18 + 512];
$s4 = $this->key_schedule[( $temp & 255) + 18 + 768];
$F = $this->thirtytwobit(($this->thirtytwobit($s1 + $s2) ^ $s3) + $s4);
$L = $F ^ $R;
$R = $temp;
}
$R = $L ^ $this->key_schedule[1];
$L = $temp ^ $this->key_schedule[0];
return array($L, $R);
}
/**
* Export the key schedule as hex
* A pretty way to show off the key schedule, in hex as it's easier to interpret
* @param string $glue How to separate the lines of the key schedule listing. Defaults to '\n'.
* @param integer $start What index value to start listing at. Defaults to '0'.
* @param integer $end What index value to stop listing at. Defaults to '1041'.
* @uses $key_schedule
*/
function show_keys($glue = "\n", $start = 0, $end = 1041) {
for($i=$start; $i<=$end; $i++) {
echo "<strong>".sprintf("%4s",$i).": </strong>".sprintf("0x%08x", $this->key_schedule[$i]).$glue;
}
return true;
}
/**
* Fix various PHP platform issues with adding 32-bit integers and having them wrap
* If the supplied integer is larger than a 32-bit integer, the modulo 2^32 is calculated and returned
* @param integer $int
* @return integer A maximum of a 32-bit integer
*/
private function thirtytwobit($int) {
if ($int < -2147483648) {
return -(-($int) & 0xffffffff);
} elseif ($int > 4294967295) {
return ($int - 4294967296);
} else {
return $int;
}
}
}
echo "<pre>";
echo "key: 0x00000000\n";
$b = new cryptBlowfish(pack("c*", 0x00, 0x00, 0x00, 0x00));
$b->show_keys("\n", 0, 17);
echo "clear: 0x0000000000000000\n";
list($L, $R) = $b->encode(0x00000000,0x00000000);
echo "encoded: 0x".sprintf("%08x", $L).sprintf("%08x", $R)."\n";
list($L, $R) = $b->decode($L, $R);
echo "decoded: 0x".sprintf("%08x", $L).sprintf("%08x", $R)."\n";
echo "\nkey: 0xffffffff\n";
$b = new cryptBlowfish(pack("c*", 0xff, 0xff, 0xff, 0xff));
echo "clear: 0xffffffffffffffff\n";
list($L, $R) = $b->encode(0xffffffff,0xffffffff);
echo "encoded: 0x".sprintf("%08x", $L).sprintf("%08x", $R)."\n";
list($L, $R) = $b->decode($L, $R);
echo "decoded: 0x".sprintf("%08x", $L).sprintf("%08x", $R)."\n";
echo "</pre>";
<?php echo '<?xml version="1.0" encoding="utf-8"?>'."\n"; ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Visualize the Blowfish encryption method</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<meta http-equiv="content-style-type" content="text/css" />
<link rel="shortcut icon" href="img/dialog-warning.png" />
<style type="text/css">
body, p { font-size:10pt; }
h1, h2, h3 { margin-bottom: 0; }
h1 {font-size:2em; }
h2 {font-size:1.5em; border-style:solid; border-color:#000; border-width:0 0 1px 0; }
h3 {font-size:1.0em; border-style:solid; border-color:#000; border-width:0 0 1px 0; }
.code { font-family: courier new, monospace; font-size:0.8em; white-space:pre; }
table.grid { border-style:solid; }
table.grid th { border-style:outset; border-color:#FF3; border-width:2px; background-color:#FC3; padding: 1px 5px; }
table.grid td { padding: 3px 5px; border-style:solid; border-color:#000; border-width:0 1px 1px 0;}
table.grid td:first-child { border-left-width:1px; }
</style>
</head>
<body>
<h1>Visualizing the Blowfish encryption</h1>
<p><a href="http://en.wikipedia.org/wiki/Blowfish_cipher">Blowfish</a> is a keyed, symetric block cypher with a 64-bit block size and variable key length (32 to 448 bits). It is a 16-round <a href="http://en.wikipedia.org/wiki/Feistel_cipher">Feistel cipher</a> with large key-dependent S-boxes.</p>
<p>To illustrate this process, let's imaging an average guy named Joe. He's none too bright, so usually picks a password of "password" to secure anything. Now, Joe has a crush on Sue, so writes a text files with the text "I love Sue." in it. But he's not ready to tell Sue, so he's going to encode that text with the blowfish cypher to keep it safe.</p>
<p>Blowfish works by creating an 'engine' based on a secret key. Then any data can be passed through this engine to encode it, or backwards to decode it. This has several benefits including:</p>
<ul>
<li>If you have the 'engine' in memory (i.e. the data tables for the cypher), you don't need to know the key to encode/decode data</li>
<li>Setting up the 'engine' is rather processor-intensive, while the encode/decode process is fairly easy. So anyone attempting to do a brute-force key attack would have to devote much more processing power to it than for other cyphers</li>
</ul>
<h2>Default structure</h2>
<p>The blowfish algorithm needs to seed the values of the P array and the S-blocks, and does so from the fractional values of pi. So first we need the value of pi in hexadecimal. Expressing fractions in hexadecimal is not something usually done, but here's how. Given a decimal fraction, like: 3.1415926535, first convert the integer-portion to hexadecimal (0x3). Then take the fractional portion and multiply by 16: 2.265482456. Take the integral portion and convert it to hexidecimal, adding it to the existing string (0x3.2). Take the fractional portion of the previous result and multiply it by 16 again: 4.247719296 (0x3.24). Repeat the process until you run out of numbers. Note, however that even though we started with only ten digits to the right of the decimal point in decimal, we can continue indefinitely in hex.</p>
<p>So, we need 8&times;18 = 144 digits for the P array, and 256&times;8 = 2048 values for each of 4 S-boxes, for a total of 8336 hex digits of pi. In order to accurately calculate that from the decimal version of pi, we need 10,040 digits. Here's 10,040 characters after the decimal point of pi, in decimal (100 characters per line):</p>
<p class="code">
<?php
//$pi_dec = bcpi(10040);
$pi_dec = "3.14159265358979323846264338327950288419716939937510582097494459230781640628620899862803482534211706798214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196442881097566593344612847564823378678316527120190914564856692346034861045432664821339360726024914127372458700660631558817488152092096282925409171536436789259036001133053054882046652138414695194151160943305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912983367336244065664308602139494639522473719070217986094370277053921717629317675238467481846766940513200056812714526356082778577134275778960917363717872146844090122495343014654958537105079227968925892354201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859502445945534690830264252230825334468503526193118817101000313783875288658753320838142061717766914730359825349042875546873115956286388235378759375195778185778053217122680661300192787661119590921642019893809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151557485724245415069595082953311686172785588907509838175463746493931925506040092770167113900984882401285836160356370766010471018194295559619894676783744944825537977472684710404753464620804668425906949129331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279678235478163600934172164121992458631503028618297455570674983850549458858692699569092721079750930295532116534498720275596023648066549911988183479775356636980742654252786255181841757467289097777279380008164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333454776241686251898356948556209921922218427255025425688767179049460165346680498862723279178608578438382796797668145410095388378636095068006422512520511739298489608412848862694560424196528502221066118630674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009946576407895126946839835259570982582262052248940772671947826848260147699090264013639443745530506820349625245174939965143142980919065925093722169646151570985838741059788595977297549893016175392846813826868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388439045124413654976278079771569143599770012961608944169486855584840635342207222582848864815845602850601684273945226746767889525213852254995466672782398645659611635488623057745649803559363456817432411251507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858900971490967598526136554978189312978482168299894872265880485756401427047755513237964145152374623436454285844479526586782105114135473573952311342716610213596953623144295248493718711014576540359027993440374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927819119793995206141966342875444064374512371819217999839101591956181467514269123974894090718649423196156794520809514655022523160388193014209376213785595663893778708303906979207734672218256259966150142150306803844773454920260541466592520149744285073251866600213243408819071048633173464965145390579626856100550810665879699816357473638405257145910289706414011097120628043903975951567715770042033786993600723055876317635942187312514712053292819182618612586732157919841484882916447060957527069572209175671167229109816909152801735067127485832228718352093539657251210835791513698820914442100675103346711031412671113699086585163983150197016515116851714376576183515565088490998985998238734552833163550764791853589322618548963213293308985706420467525907091548141654985946163718027098199430992448895757128289059232332609729971208443357326548938239119325974636673058360414281388303203824903758985243744170291327656180937734440307074692112019130203303801976211011004492932151608424448596376698389522868478312355265821314495768572624334418930396864262434107732269780280731891544110104468232527162010526522721116603966655730925471105578537634668206531098965269186205647693125705863566201855810072936065987648611791045334885034611365768675324944166803962657978771855608455296541266540853061434443185867697514566140680070023787765913440171274947042056223053899456131407112700040785473326993908145466464588079727082668306343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923099079654737612551765675135751782966645477917450112996148903046399471329621073404375189573596145890193897131117904297828564750320319869151402870808599048010941214722131794764777262241425485454033215718530614228813758504306332175182979866223717215916077166925474873898665494945011465406284336639379003976926567214638530673609657120918076383271664162748888007869256029022847210403172118608204190004229661711963779213375751149595015660496318629472654736425230817703675159067350235072835405670403867435136222247715891504953098444893330963408780769325993978054193414473774418426312986080998886874132604721569516239658645730216315981931951673538129741677294786724229246543668009806769282382806899640048243540370141631496589794092432378969070697794223625082216889573837986230015937764716512289357860158816175578297352334460428151262720373431465319777741603199066554187639792933441952154134189948544473456738316249934191318148092777710386387734317720754565453220777092120190516609628049092636019759882816133231666365286193266863360627356763035447762803504507772355471058595487027908143562401451718062464362679456127531813407833033625423278394497538243720583531147711992606381334677687969597030983391307710987040859133746414428227726346594704745878477872019277152807317679077071572134447306057007334924369311383504931631284042512192565179806941135280131470130478164378851852909285452011658393419656213491434159562586586557055269049652098580338507224264829397285847831630577775606888764462482468579260395352773480304802900587607582510474709164396136267604492562742042083208566119062545433721315359584506877246029016187667952406163425225771954291629919306455377991403734043287526288896399587947572917464263574552540790914513571113694109119393251910760208252026187985318877058429725916778131496990090192116971737278476847268608490033770242429165130050051683233643503895170298939223345172201381280696501178440874519601212285993716231301711444846409038906449544400619869075485160263275052983491874078668088183385102283345085048608250393021332197155184306354550076682829493041377655279397517546139539846833936383047461199665385815384205685338621867252334028308711232827892125077126294632295639898989358211674562701021835646220134967151881909730381198004973407239610368540664319395097901906996395524530054505806855019567302292191393391856803449039820595510022635353619204199474553859381023439554495977837790237421617271117236434354394782218185286240851400666044332588856986705431547069657474585503323233421073015459405165537906866273337995851156257843229882737231989875714159578111963583300594087306812160287649628674460477464915995054973742562690104903778198683593814657412680492564879855614537234786733039046883834363465537949864192705638729317487233208376011230299113679386270894387993620162951541337142489283072201269014754668476535761647737946752004907571555278196536213239264061601363581559074220202031872776052772190055614842555187925303435139844253223415762336106425063904975008656271095359194658975141310348227693062474353632569160781547818115284366795706110861533150445212747392454494542368288606134084148637767009612071512491404302725386076482363414334623518975766452164137679690314950191085759844239198629164219399490723623464684411739403265918404437805133389452574239950829659122850855582157250310712570126683024029295252201187267675622041542051618416348475651699981161410100299607838690929160302884002691041407928862150784245167090870006992821206604183718065355672525325675328612910424877618258297651579598470356222629348600341587229805349896502262917487882027342092222453398562647669149055628425039127577102840279980663658254889264880254566101729670266407655904290994568150652653053718294127033693137851786090407086671149655834343476933857817113864558736781230145876871266034891390956200993936103102916161528813843790990423174733639480457593149314052976347574811935670911013775172100803155902485309066920376719220332290943346768514221447737939375170344366199104033751117354719185504644902636551281622882446257591633303910722538374218214088350865739177150968288747826569959957449066175834413752239709683408005355984917541738188399944697486762655165827658483588453142775687900290951702835297163445621296404352311760066510124120065975585127617858382920419748442360800719304576189323492292796501987518721272675079812554709589045563579212210333466974992356302549478024901141952123828153091140790738602515227429958180724716259166854513331239480494707911915326734302824418604142636395480004480026704962482017928964766975831832713142517029692348896276684403232609275249603579964692565049368183609003238092934595889706953653494060340216654437558900456328822505452556405644824651518754711962184439658253375438856909411303150952617937800297412076651479394259029896959469955657612186561967337862362561252163208628692221032748892186543648022967807057656151446320469279068212073883778142335628236089632080682224680122482611771858963814091839036736722208883215137556003727983940041529700287830766709444745601345564172543709069793961225714298946715435784687886144458123145935719849225284716050492212424701412147805734551050080190869960330276347870810817545011930714122339086639383395294257869050764310063835198343893415961318543475464955697810382930971646514384070070736041123735998434522516105070270562352660127648483084076118301305279320542746286540360367453286510570658748822569815793678976697422057505968344086973502014102067235850200724522563265134105592401902742162484391403599895353945909440704691209140938700126456001623742880210927645793106579229552498872758461012648369998922569596881592056001016552563756785667227966198857827948488558343975187445";
$lines = str_split(substr($pi_dec,2), 100);
for($i = 0; $i<count($lines); $i++) {
echo "<strong>".sprintf("%05d", $i*100).": </strong>";
echo chunk_split($lines[$i], 10, "&nbsp;")."\n";
}
unset($lines); // Done with this huge array; free up the memory
?>
</p>
<p>Convert that to hex (using a precision of 10,040 digits, when multiplying by 16), and here's the first 8336 characters of the result (in 8-digit chunks, 16 chunks (128 digits) per row):</p>
<p class="code">
<?php
$pi_hex = "";
$tmp = bcsub($pi_dec,3, 10040);
unset($pi_dec); // Done with this huge number; free up the memory
for($i=0; $i<8336; $i++) {
$tmp = bcmul($tmp,16,10040);
$pi_hex .= dechex(intval($tmp));
$tmp = bcsub($tmp, intval($tmp), 10040);
}
unset($tmp); // Done with this huge number; free up the memory
$lines = str_split($pi_hex, 128);
for ($i=0; $i<count($lines); $i++) {
echo "<strong>".sprintf("0x%04x", $i*128).": </strong>";
echo chunk_split($lines[$i], 8, "&nbsp;")."\n";
}
unset($lines); // Done with this huge array; free up the memory
?>
<p>That's all the bits we need to seed the generator to begin. The default values get laid out into the P Array, and S-Boxes like so:</p>
<table class="grid" cellspacing="0" border="0">
<tr><th colspan="3">P Array</th></tr>
<tr><th>ID</th><th>Hex</th><th>Binary</th></tr>
<?php
$pi_data = str_split($pi_hex, 8);
unset($pi_hex); // Done with this huge number; free up the memory
for($i=0; $i<18; $i++) {
$id = $i+1;
echo "<tr><td>P<sub>{$id}</sub></td><td class=\"code\">{$pi_data[$i]}</td><td class=\"code\">".sprintf("%032b", hexdec($pi_data[$i]))."</td></tr>\n";
}
?>
</table>
<?php
for ($s = 0; $s<4; $s++) {
echo "<table class=\"grid\" cellspacing=\"0\" border=\"0\" style=\"margin-top:12pt;\">\n";
echo "<tr><th colspan=\"17\">S-Box ".($s+1)."</th></tr>\n";
echo "<tr><th>&nbsp;</th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>a</th><th>b</th><th>c</th><th>d</th><th>e</th><th>f</th></tr>\n";
for ($x=0; $x < 16; $x++) {
echo "<tr><th>".sprintf("%02x", $x*16)."</th>";
for ($y=0; $y < 16; $y++) {
$i = $s*256+$x*16+$y+18;
echo "<td class=\"code\">".$pi_data[$i]."</td>";
}
echo "</tr>\n";
}
echo "</table>\n";
}
$blowfish = $pi_data;
?>
<p>This is the default setup for the blowfish cypher, but in order to actually encode anything, we must first apply our secret key.</p>
<h2>Applying secret key</h2>
<p>The blowfish cypher encodes data using a set of data tables (P array and S-Boxes). We could encode something with the data tables set up as they are, but that would require only knowledge of the blowfish cypher's default data tables to decode. So, we first select a secret phrase; Joe's not that creative, nor <em>that</em> concerned about security, so he chooses a password of 'password'. We convert that to ASCII (hex values), and arrive at <span class="code">0x70617373776F7264</span>. Using an actual passWORD for a blowfish key weakens the encryption, since you're self-limiting the possible values of the hex key to the range of 0x20-0x7E (94 possibilities), rather than 0x00-0xFF (256 possibilities), making a brute-force attack easier to accomplish.</p>
<p>Next we take that phrase and repeat it as often as necessary to match the size of the P array (hence the longest key that can be used with blowfish is 144 bits long, since that's the length of the P array):</p>
<pre>
Key: 70617373 776f7264 70617373 ... 70617373 776f7264
P array: 243f6a88 85a308d3 13198a2e ... 9216d5d9 8979fb1b
</pre>
<p>Then for each element of the P array, perform an exclusive-or (XOR) on the key and P element, arriving at a third element. Store this in the P array in place of the old element. In order to visualize this, we must expand the hexadecimal out to binary bits:
<pre>
Key: 70617373 776f7264 ...
01110000011000010111001101110011 01110111011011110111001001100100 ...
P array: 243f6a88 85a308d3 ...
00100100001111110110101010001000 10000101101000110000100011010011 ...
XOR: 01010100010111100001100111111011 11110010100011000111101010110111 ...
545e19fb f2cc7ab7
</pre>
<p>The XOR result is a zero if both or neither of the input bits are zero, and is one if one and only one of the input bits is one. After XOR-ing the entire P array, the new P array looks like:</p>
<table class="grid" cellspacing="0" border="0">
<tr><th colspan="3">P Array</th></tr>
<tr><th>ID</th><th>Hex</th><th>Binary</th></tr>
<?php
$key = array("70617373", "776F7264", "70617373", "776F7264", "70617373", "776F7264", "70617373", "776F7264", "70617373", "776F7264", "70617373", "776F7264", "70617373", "776F7264", "70617373", "776F7264", "70617373", "776F7264");
for($i=0; $i<18; $i++) {
$id = $i+1;
$xor = dechex(hexdec($blowfish[$i]) ^ hexdec($key[$i]));
echo "<tr><td>P<sub>{$id}</sub></td><td class=\"code\">{$xor}</td><td class=\"code\">".sprintf("%032b", hexdec($xor))."</td></tr>\n";
$blowfish[$i] = $xor; // Save the new key;
}
?>
</table>
<p>This is not the final values of the P array, but is an intermediary step to ensure that the next step is more random. To st up the final values of the P array and S-boxes for encryption, the new P array is used to generate the new values. This process is fairly repetitive and processor-intensive, and is one of blowfish's benefits, to resist brute-force attack. We must now take a 64-byte block of all zeroes (<span class="code">0x0000000000000000</span>) and encrypt it using the standard blowfish method, using the new P array and original S-boxes.</p>
<p><img src="http://upload.wikimedia.org/wikipedia/en/3/34/BlowfishDiagram.png" alt="" style="float:right" />To encode a 64-bit block, first the block is split in half, the highest-order bits being stored as the first input into the Left side of the Feistel structure (L<sub>0</sub>), and the lower-order bits being the Right side (R<sub>0</sub>). L<sub>0</sub> is XORed with P<sub>1</sub> and stored as R<sub>1</sub>, and fed through the F function. The F function splits the 32-bit input into four pieces. From highest to lowest, they get replaced with their values from S-box 1 through 4. Then the highest-order piece gets added to the second-highest piece (and bits higher than 32 get dropped), then XORed with the third piece, and finally added to the smallest piece (dropping bits higher than 32). That output from the F function is XORed with R<sub>0</sub> and stored as L<sub>1</sub>. You now have L<sub>1</sub> and R<sub>1</sub>; repeat the cycle until you have L<sub>14</sub> and R<sub>14</sub>. On the last round, the halves don't change places, so L<sub>14</sub> is XORed with P<sub>15</sub>, and is both passed through the F function to be XORed with R<sub>14</sub>, and is stored still as L<sub>14</sub>. Then L<sub>14</sub> is XORed with P<sub>18</sub> and R<sub>14</sub> is XORed with P<sub>17</sub>, then re-merged into one 64-bit string to be the final encrypted string.</p>
<p>Put more concisely, R<sub>i</sub> = L<sub>i-1</sub> &oplus; P<sub>i</sub>, L<sub>i</sub> = R<sub>i-1</sub> &oplus; F(L<sub>i-1</sub> &oplus; P<sub>i</sub>)</p>
<p>So, we start with L<sub>0</sub> = <span class="code">0x00000000</span>, R<sub>0</sub> = <span class="code">0x00000000</span><br />
L<sub>0</sub> &oplus; P<sub>1</sub> = <span class="code">0x00000000</span> &oplus; <span class="code">0x545e19fb</span> = <span class="code">0x545e19fb</span> = R<sub>1</sub><br />
F(L<sub>0</sub> &oplus; P<sub>1</sub>) = F(<span class="code">0x545e19fb</span>)</p>
<p>Applying the F function to <span class="code">0x545e19fb</span>, it first gets split into four pieces, <span class="code">0x54</span>, <span class="code">0x5e</span>, <span class="code">0x19</span>, and <span class="code">0xfb</span>. Since each S-box has 256 entries, we can convert these pieces to decimal, and take that entry from the S-box as the new value. So, the <span class="code">0x54</span>th element of S-box 1 is <span class="code">0x6eef0b6c</span>, the <span class="code">0x5e</span> element from S-box 2 is <span class="code">0x50940002</span>, <span class="code">0x19</span> from S-box 3 is <span class="code">0x55fd3941</span>, and <span class="code">0xfb</span> from S-box 4 is <span class="code">0xc208e69f</span>.<br />
<span class="code">0x6eef0b6c</span> + <span class="code">0x50940002</span> = <span class="code">0xbf830b6e</span><br />
<span class="code">0xbf830b6e</span> &oplus; <span class="code">0x55fd3941</span> = <span class="code">0xea7e322f</span><br />
<span class="code">0xea7e322f</span> + <span class="code">0xc208e69f</span> = <span class="code">0xac8718ce</span><br />
F(L<sub>0</sub> &oplus; P<sub>1</sub>) = F(<span class="code">0x545e19fb</span>) = <span class="code">0xac8718ce</span></p>
<p>R<sub>0</sub> &oplus; F(L<sub>0</sub> &oplus; P<sub>1</sub>) = <span class="code">0x00000000</span> &oplus; <span class="code">0xac8718ce</span> = <span class="code">0xac8718ce</span> = L<sub>1</sub></p>
<?php $rs = blowfish_enc(0, true); ?>
<p>So, the output from the blowfish encryption of <span class="code">0x00000000</span> is <span class="code">0x<?php echo $rs; ?></span>. This gets split in half and replaces the first two entries in the P array. Then that same output is fed in as input to the engine, and a new result is output, which will become the third and fourth entries in the P array. This continues until the P array is replaced, then S-box 1, through S-box 4. A total of 521 encodings needs to happen to generate enough data for this. After doing that whole process, the blowfish engine now looks like this:</p>
<?php
$input = 0;
for ($i=0; $i<count($blowfish); $i+=2) {
$rs = blowfish_enc($input);
$blowfish[$i] = substr($rs,0,8);
$blowfish[$i+1] = substr($rs,8);
$input = $rs;
}
?>
<table class="grid" cellspacing="0" border="0">
<tr><th colspan="3">P Array</th></tr>
<tr><th>ID</th><th>Hex</th><th>Binary</th></tr>
<?php
for($i=0; $i<18; $i++) {
$id = $i+1;
echo "<tr><td>P<sub>{$id}</sub></td><td class=\"code\">{$blowfish[$i]}</td><td class=\"code\">".sprintf("%032b", hexdec($blowfish[$i]))."</td></tr>\n";
}
?>
</table>
<?php
for ($s = 0; $s<4; $s++) {
echo "<table class=\"grid\" cellspacing=\"0\" border=\"0\" style=\"margin-top:12pt;\">\n";
echo "<tr><th colspan=\"17\">S-Box ".($s+1)."</th></tr>\n";
echo "<tr><th>&nbsp;</th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>a</th><th>b</th><th>c</th><th>d</th><th>e</th><th>f</th></tr>\n";
for ($x=0; $x < 16; $x++) {
echo "<tr><th>".sprintf("%02x", $x*16)."</th>";
for ($y=0; $y < 16; $y++) {
$i = $s*256+$x*16+$y+18;
echo "<td class=\"code\">".$blowfish[$i]."</td>";
}
echo "</tr>\n";
}
echo "</table>\n";
}
?>
<p>Now, with this data, we are ready to encode data. Once this set of data has been generated, it can be used to encode <strong>and</strong> decode data.</p>
<h2>Encode data</h2>
<p>Encoding data is done in 64-byte blocks, the same as during the key generation. Now Joe wants to encode the text message "I love Sue.". First that text gets converted to its ASCII format (hex) to arrive at <span class="code">0x49206c6f7665205375652e</span>. This has to be broken into 64-byte blocks, so we have to encode <span class="code">0x49206c6f76652053</span> and <span class="code">0x75652e0000000000</span> separately.
<?php
$rs = blowfish_enc('49206c6f76652053');
echo "<p>enc(<span class=\"code\">0x49206c6f76652053</span>) = <span class=\"code\">0x{$rs}</span><br />\n";
$rs = blowfish_enc('75652e0000000000');
echo "enc(<span class=\"code\">0x75652e0000000000</span>) = <span class=\"code\">0x{$rs}</span></p\n";
?>
<p>Thus, "I love Sue." encodes to <span class="code">0x69792f41cf50b1bce5e162589cc68432</span></p>
<h2>Decode data</h2>
<p>Now Sue (quite different than Joe), is quite the smart cookie, and pretty well versed at social engineering, so knows that Joe often picks a password of 'password', so can generate the blowfish data necessary to encode/decode Joe's messages without any other input from him. Taking a peek on his computer (his user account there also has a password of 'password'), she finds the encoded text file with data of <span class="code">0x754dc5f20737dafafffc0dd9181261a4</span>. In order to decode this content, the process is exactly the same as encryption, except the P array is used in the reverse order.</p>
<?php
$rs = blowfish_dec('69792f41cf50b1bc');
echo "<p>dec(<span class=\"code\">0x69792f41cf50b1bc</span>) = <span class=\"code\">0x{$rs}</span><br />\n";
$rs = blowfish_dec('e5e162589cc68432');
echo "dec(<span class=\"code\">0xe5e162589cc68432</span>) = <span class=\"code\">0x{$rs}</span></p\n";
?>
<p>Melding those two strings together, she is able to decode his message to "I love Sue.", and she propmtly goes and thumps him on the head for being so forward with his affections!</p>
<h2>Test Cases</h2>
<p>Proving this implementation of blowfish arrives at the same results as the original design.</p>
<h3>Key: 0x0000000000000000, Data: 0x0000000000000000</h3>
<?php
$blowfish = $pi_data; // Reset to original values
// XOR the key value with the P array
$key = array("00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000", "00000000");
for($i=0; $i<18; $i++) {
$id = $i+1;
$xor = sprintf("%08x", hexdec($blowfish[$i]) ^ hexdec($key[$i]));
$blowfish[$i] = $xor; // Save the new key;
}
// Generate the key-dependant P array and S-boxes
$input = 0;
$old = $blowfish;
for ($i=0; $i<count($blowfish); $i+=2) {
$log = false;
$rs = blowfish_enc($input, $log);
$blowfish[$i] = substr($rs,0,8);
$blowfish[$i+1] = substr($rs,8);
$input = $rs;
if ($log) {
echo "$i: {$old[$i]} &rArr; {$blowfish[$i]}<br />";
echo ($i+1).": {$old[$i+1]} &rArr; {$blowfish[$i+1]}<br />";
}
}
// Encode data
$rs = blowfish_enc('0000000000000000');
echo "<p>Encoded content: $rs<br />\n";
// Decode data
$rs = blowfish_dec($rs);
echo "Decoded content: $rs</p>\n";
?>
<h3>Key: 0xFFFFFFFFFFFFFFFF, Data: 0xFFFFFFFFFFFFFFFF</h3>
<?php
$blowfish = $pi_data; // Reset to original values
// XOR the key value with the P array
$key = array("FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF", "FFFFFFFF");
for($i=0; $i<18; $i++) {
$id = $i+1;
$xor = sprintf("%08x", hexdec($blowfish[$i]) ^ hexdec($key[$i]));
$blowfish[$i] = $xor; // Save the new key;
}
// Generate the key-dependant P array and S-boxes
$input = 0;
$old = $blowfish;
for ($i=0; $i<count($blowfish); $i+=2) {
$rs = blowfish_enc($input);
$blowfish[$i] = substr($rs,0,8);
$blowfish[$i+1] = substr($rs,8);
$input = $rs;
//echo "$i: {$old[$i]} &rArr; {$blowfish[$i]}<br />";
//echo ($i+1).": {$old[$i+1]} &rArr; {$blowfish[$i+1]}<br />";
}
// Encode data
$rs = blowfish_enc('FFFFFFFFFFFFFFFF');
echo "<p>Encoded content: $rs<br />\n";
// Decode data
$rs = blowfish_dec($rs);
echo "Decoded content: $rs</p>\n";
?>
</body>
</html>
<?php
function bcpi($precision){
bcscale($precision+6);
$a = bcsqrt(2);
$b = 0;
$p = bcadd(2, $a);
$i = 0;
$count = ceil(log($precision+6)/log(2))-1;
while($i < $count){
set_time_limit(20); // reset time limit
$sqrt_a = bcsqrt($a);
$a1 = $a;
$a = bcdiv(bcadd($sqrt_a,bcdiv(1,$sqrt_a)),2);
$b_up = bcmul($sqrt_a,bcadd(1,$b));
$b_down = bcadd($a1,$b);
$b = bcdiv($b_up, $b_down);
$p_up = bcmul(bcmul($p,$b),bcadd(1,$a));
$p_down = bcadd(1, $b);
$p = bcdiv($p_up, $p_down);
++$i;
}
return bcadd($p,0,$precision);
}
// input is 16-character string representing a 64-bit hex number
function blowfish_enc($input, $log = false) {
global $blowfish;
$L = array();
$R = array();
$L[0] = hexdec(substr($input,0,8));
$R[0] = hexdec(substr($input,8));
if ($log) echo "<p>Encoding L<sub>0</sub> = <span class=\"code\">0x".sprintf("%08x", $L[0])."</span>, R<sub>0</sub> = <span class=\"code\">0x".sprintf("%08x", $R[0])."</span><br />";
for ($i=1; $i<=16; $i++) {
$n = $i-1;
$R[$i] = $L[$i-1] ^ hexdec($blowfish[$i-1]);
if ($log) {
echo "<span class=\"code\">L<sub>$n</sub> = ".sprintf("%012d", $L[$n])." = ".sprintf("0x%08x", $L[$n])." = ".sprintf("0b%032b", $L[$n])."\n";
echo "B<sub>$n</sub> = ".sprintf("%012d", hexdec($blowfish[$n]))." = ".sprintf("0x%08x", hexdec($blowfish[$n]))." = ".sprintf("0b%032b", hexdec($blowfish[$n]))."\n";
echo "R<sub>$i</sub> = ".sprintf("%012d", $R[$i])." = ".sprintf("0x%08x", $R[$i])." = ".sprintf("0b%032b", $R[$i])."</span><br />\n";
}
$L[$i] = $R[$i-1] ^ hexdec(blowfish_f(sprintf("%08x", $R[$i]), $log));
if ($log) {
echo "<span class=\"code\">R<sub>$n</sub> = ".sprintf("%012d", $R[$n])." = ".sprintf("0x%08x", $R[$n])." = ".sprintf("0b%032b", $R[$n])."\n";
$tmp = blowfish_f(sprintf("%08x", $R[$i]));
//echo "TMP = $tmp\n";
echo "F(R<sub>$i</sub>) = ".sprintf("%012d", hexdec($tmp))." = ".sprintf("0x%08x", hexdec($tmp))." = ".sprintf("0b%032b", hexdec($tmp))."\n";
echo "L<sub>$i</sub> = ".sprintf("%012d", $L[$i])." = ".sprintf("0x%08x", $L[$i])." = ".sprintf("0b%032b", $L[$i])."</span><br />\n";
}
if ($log) echo "After round $i, we end up with L<sub>$i</sub> = <span class=\"code\">0x".sprintf("%08x", $L[$i])."</span>, R<sub>$i</sub> = <span class=\"code\">0x".sprintf("%08x", $R[$i])."</span><br />\n";
}
$R_final = $L[16] ^ hexdec($blowfish[16]);
$L_final = $R[16] ^ hexdec($blowfish[17]);
if ($log) echo "After the final round, we end up with L<sub>f</sub> = <span class=\"code\">0x".sprintf("%08x", $L_final)."</span>, R<sub>f</sub> = <span class=\"code\">0x".sprintf("%08x", $R_final)."</span>.</p>\n";
return sprintf("%08x",$L_final).sprintf("%08x", $R_final);
}
function blowfish_dec($input, $log = false) {
global $blowfish;
$L = array();
$R = array();
$L[0] = hexdec(substr($input,0,8));
$R[0] = hexdec(substr($input,8));
if ($log) echo "<p>Decoding L<sub>0</sub> = <span class=\"code\">0x".sprintf("%08x", $L[0])."</span>, R<sub>0</sub> = <span class=\"code\">0x".sprintf("%08x", $R[0])."</span><br />";
for ($i=1; $i<=16; $i++) {
$R[$i] = $L[$i-1] ^ hexdec($blowfish[18-$i]);
$L[$i] = $R[$i-1] ^ hexdec(blowfish_f(sprintf("%08x", $R[$i]), $log));
if ($log) echo "After round $i, we end up with L<sub>$i</sub> = <span class=\"code\">0x".sprintf("%08x", $L[$i])."</span>, R<sub>$i</sub> = <span class=\"code\">0x".sprintf("%08x", $R[$i])."</span><br />\n";
}
$L_final = $R[16] ^ hexdec($blowfish[0]);
$R_final = $L[16] ^ hexdec($blowfish[1]);
if ($log) echo "After the final round, we end up with L<sub>f</sub> = <span class=\"code\">0x".sprintf("%08x", $L_final)."</span>, R<sub>f</sub> = <span class=\"code\">0x".sprintf("%08x", $R_final)."</span>.</p>\n";
return sprintf("%08x",$L_final).sprintf("%08x", $R_final);
}
// input is 8-character string representing a 32-bit hex number
function blowfish_f($input, $log = false) {
global $blowfish; // array of subkeys
$pieces = str_split($input, 2);
if (count($pieces) != 4) throw new Exception("Split failed!");
if ($log) {
echo "Input to F function: $input<br />\n";
foreach($pieces as $index => $piece) {
$sbox_id = $index+1;
$i = $index*256+hexdec($piece)+18;
echo "item 0x$piece (".hexdec($piece).") from S-box $sbox_id is ".$blowfish[$i]." ($i)<br />\n";
}
}
$pieces[0] = hexdec($blowfish[hexdec($pieces[0])+18]); // Replace with S-box 1
$pieces[1] = hexdec($blowfish[256+hexdec($pieces[1])+18]); // Replace with S-box 2
$pieces[2] = hexdec($blowfish[512+hexdec($pieces[2])+18]); // Replace with S-box 3
$pieces[3] = hexdec($blowfish[768+hexdec($pieces[3])+18]); // Replace with S-box 4
$tmp = $pieces[0] + $pieces[1];
if ($tmp > 4294967296) $tmp -= 4294967296; // Shift down into 32-bit range
if ($log) {
echo "<span class=\"code\">P1 = ".sprintf("0x%09x", $pieces[0])." = ".sprintf("0b%033b", $pieces[0])."\n";
echo "P2 = ".sprintf("0x%09x", $pieces[1])." = ".sprintf("0b%033b", $pieces[1])."\n";
echo "TMP = $tmp = ".sprintf("0x%09x", $tmp)." = ".sprintf("0b-%033b", $tmp)."</span><br />\n";
}
$tmp = $tmp ^ $pieces[2];
if ($log) {
echo "<span class=\"code\">P3 = ".sprintf("0x%09x", $pieces[2])." = ".sprintf("0b%033b", $pieces[2])."\n";
echo "TMP = ".sprintf("0x%09x", $tmp)." = ".sprintf("0b-%033b", $tmp)."</span><br />\n";
}
$tmp = $tmp + $pieces[3];
if ($tmp > 4294967296) $tmp -= 4294967296; // Shift down into 32-bit range
if ($log) {
echo "<span class=\"code\">P4 = ".sprintf("0x%09x", $pieces[3])." = ".sprintf("0b%033b", $pieces[3])."\n";
echo "TMP = ".sprintf("0x%09x", $tmp)." = ".sprintf("0b-%033b", $tmp)."</span><br />\n";
}
return sprintf("%08x", $tmp); // return hex
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment