1 /** 2 * Copyright: Copyright (C) Thomas Dixon 2008. All rights reserved. 3 * License: BSD style: $(LICENSE) 4 * Authors: Thomas Dixon 5 * 6 * Note: This probably needs optimized. 7 */ 8 9 module tango.util.cipher.Blowfish; 10 11 private import tango.util.cipher.Cipher; 12 13 /** Implementation of the Blowfish cipher designed by Bruce Schneier. */ 14 class Blowfish : BlockCipher 15 { 16 private 17 { 18 __gshared immutable uint[1024] S_INIT = [ 19 0xd1310ba6u, 0x98dfb5acu, 0x2ffd72dbu, 0xd01adfb7u, 0xb8e1afedu, 0x6a267e96u, 20 0xba7c9045u, 0xf12c7f99u, 0x24a19947u, 0xb3916cf7u, 0x0801f2e2u, 0x858efc16u, 21 0x636920d8u, 0x71574e69u, 0xa458fea3u, 0xf4933d7eu, 0x0d95748fu, 0x728eb658u, 22 0x718bcd58u, 0x82154aeeu, 0x7b54a41du, 0xc25a59b5u, 0x9c30d539u, 0x2af26013u, 23 0xc5d1b023u, 0x286085f0u, 0xca417918u, 0xb8db38efu, 0x8e79dcb0u, 0x603a180eu, 24 0x6c9e0e8bu, 0xb01e8a3eu, 0xd71577c1u, 0xbd314b27u, 0x78af2fdau, 0x55605c60u, 25 0xe65525f3u, 0xaa55ab94u, 0x57489862u, 0x63e81440u, 0x55ca396au, 0x2aab10b6u, 26 0xb4cc5c34u, 0x1141e8ceu, 0xa15486afu, 0x7c72e993u, 0xb3ee1411u, 0x636fbc2au, 27 0x2ba9c55du, 0x741831f6u, 0xce5c3e16u, 0x9b87931eu, 0xafd6ba33u, 0x6c24cf5cu, 28 0x7a325381u, 0x28958677u, 0x3b8f4898u, 0x6b4bb9afu, 0xc4bfe81bu, 0x66282193u, 29 0x61d809ccu, 0xfb21a991u, 0x487cac60u, 0x5dec8032u, 0xef845d5du, 0xe98575b1u, 30 0xdc262302u, 0xeb651b88u, 0x23893e81u, 0xd396acc5u, 0x0f6d6ff3u, 0x83f44239u, 31 0x2e0b4482u, 0xa4842004u, 0x69c8f04au, 0x9e1f9b5eu, 0x21c66842u, 0xf6e96c9au, 32 0x670c9c61u, 0xabd388f0u, 0x6a51a0d2u, 0xd8542f68u, 0x960fa728u, 0xab5133a3u, 33 0x6eef0b6cu, 0x137a3be4u, 0xba3bf050u, 0x7efb2a98u, 0xa1f1651du, 0x39af0176u, 34 0x66ca593eu, 0x82430e88u, 0x8cee8619u, 0x456f9fb4u, 0x7d84a5c3u, 0x3b8b5ebeu, 35 0xe06f75d8u, 0x85c12073u, 0x401a449fu, 0x56c16aa6u, 0x4ed3aa62u, 0x363f7706u, 36 0x1bfedf72u, 0x429b023du, 0x37d0d724u, 0xd00a1248u, 0xdb0fead3u, 0x49f1c09bu, 37 0x075372c9u, 0x80991b7bu, 0x25d479d8u, 0xf6e8def7u, 0xe3fe501au, 0xb6794c3bu, 38 0x976ce0bdu, 0x04c006bau, 0xc1a94fb6u, 0x409f60c4u, 0x5e5c9ec2u, 0x196a2463u, 39 0x68fb6fafu, 0x3e6c53b5u, 0x1339b2ebu, 0x3b52ec6fu, 0x6dfc511fu, 0x9b30952cu, 40 0xcc814544u, 0xaf5ebd09u, 0xbee3d004u, 0xde334afdu, 0x660f2807u, 0x192e4bb3u, 41 0xc0cba857u, 0x45c8740fu, 0xd20b5f39u, 0xb9d3fbdbu, 0x5579c0bdu, 0x1a60320au, 42 0xd6a100c6u, 0x402c7279u, 0x679f25feu, 0xfb1fa3ccu, 0x8ea5e9f8u, 0xdb3222f8u, 43 0x3c7516dfu, 0xfd616b15u, 0x2f501ec8u, 0xad0552abu, 0x323db5fau, 0xfd238760u, 44 0x53317b48u, 0x3e00df82u, 0x9e5c57bbu, 0xca6f8ca0u, 0x1a87562eu, 0xdf1769dbu, 45 0xd542a8f6u, 0x287effc3u, 0xac6732c6u, 0x8c4f5573u, 0x695b27b0u, 0xbbca58c8u, 46 0xe1ffa35du, 0xb8f011a0u, 0x10fa3d98u, 0xfd2183b8u, 0x4afcb56cu, 0x2dd1d35bu, 47 0x9a53e479u, 0xb6f84565u, 0xd28e49bcu, 0x4bfb9790u, 0xe1ddf2dau, 0xa4cb7e33u, 48 0x62fb1341u, 0xcee4c6e8u, 0xef20cadau, 0x36774c01u, 0xd07e9efeu, 0x2bf11fb4u, 49 0x95dbda4du, 0xae909198u, 0xeaad8e71u, 0x6b93d5a0u, 0xd08ed1d0u, 0xafc725e0u, 50 0x8e3c5b2fu, 0x8e7594b7u, 0x8ff6e2fbu, 0xf2122b64u, 0x8888b812u, 0x900df01cu, 51 0x4fad5ea0u, 0x688fc31cu, 0xd1cff191u, 0xb3a8c1adu, 0x2f2f2218u, 0xbe0e1777u, 52 0xea752dfeu, 0x8b021fa1u, 0xe5a0cc0fu, 0xb56f74e8u, 0x18acf3d6u, 0xce89e299u, 53 0xb4a84fe0u, 0xfd13e0b7u, 0x7cc43b81u, 0xd2ada8d9u, 0x165fa266u, 0x80957705u, 54 0x93cc7314u, 0x211a1477u, 0xe6ad2065u, 0x77b5fa86u, 0xc75442f5u, 0xfb9d35cfu, 55 0xebcdaf0cu, 0x7b3e89a0u, 0xd6411bd3u, 0xae1e7e49u, 0x00250e2du, 0x2071b35eu, 56 0x226800bbu, 0x57b8e0afu, 0x2464369bu, 0xf009b91eu, 0x5563911du, 0x59dfa6aau, 57 0x78c14389u, 0xd95a537fu, 0x207d5ba2u, 0x02e5b9c5u, 0x83260376u, 0x6295cfa9u, 58 0x11c81968u, 0x4e734a41u, 0xb3472dcau, 0x7b14a94au, 0x1b510052u, 0x9a532915u, 59 0xd60f573fu, 0xbc9bc6e4u, 0x2b60a476u, 0x81e67400u, 0x08ba6fb5u, 0x571be91fu, 60 0xf296ec6bu, 0x2a0dd915u, 0xb6636521u, 0xe7b9f9b6u, 0xff34052eu, 0xc5855664u, 61 0x53b02d5du, 0xa99f8fa1u, 0x08ba4799u, 0x6e85076au, 62 63 0x4b7a70e9u, 0xb5b32944u, 0xdb75092eu, 0xc4192623u, 0xad6ea6b0u, 0x49a7df7du, 64 0x9cee60b8u, 0x8fedb266u, 0xecaa8c71u, 0x699a17ffu, 0x5664526cu, 0xc2b19ee1u, 65 0x193602a5u, 0x75094c29u, 0xa0591340u, 0xe4183a3eu, 0x3f54989au, 0x5b429d65u, 66 0x6b8fe4d6u, 0x99f73fd6u, 0xa1d29c07u, 0xefe830f5u, 0x4d2d38e6u, 0xf0255dc1u, 67 0x4cdd2086u, 0x8470eb26u, 0x6382e9c6u, 0x021ecc5eu, 0x09686b3fu, 0x3ebaefc9u, 68 0x3c971814u, 0x6b6a70a1u, 0x687f3584u, 0x52a0e286u, 0xb79c5305u, 0xaa500737u, 69 0x3e07841cu, 0x7fdeae5cu, 0x8e7d44ecu, 0x5716f2b8u, 0xb03ada37u, 0xf0500c0du, 70 0xf01c1f04u, 0x0200b3ffu, 0xae0cf51au, 0x3cb574b2u, 0x25837a58u, 0xdc0921bdu, 71 0xd19113f9u, 0x7ca92ff6u, 0x94324773u, 0x22f54701u, 0x3ae5e581u, 0x37c2dadcu, 72 0xc8b57634u, 0x9af3dda7u, 0xa9446146u, 0x0fd0030eu, 0xecc8c73eu, 0xa4751e41u, 73 0xe238cd99u, 0x3bea0e2fu, 0x3280bba1u, 0x183eb331u, 0x4e548b38u, 0x4f6db908u, 74 0x6f420d03u, 0xf60a04bfu, 0x2cb81290u, 0x24977c79u, 0x5679b072u, 0xbcaf89afu, 75 0xde9a771fu, 0xd9930810u, 0xb38bae12u, 0xdccf3f2eu, 0x5512721fu, 0x2e6b7124u, 76 0x501adde6u, 0x9f84cd87u, 0x7a584718u, 0x7408da17u, 0xbc9f9abcu, 0xe94b7d8cu, 77 0xec7aec3au, 0xdb851dfau, 0x63094366u, 0xc464c3d2u, 0xef1c1847u, 0x3215d908u, 78 0xdd433b37u, 0x24c2ba16u, 0x12a14d43u, 0x2a65c451u, 0x50940002u, 0x133ae4ddu, 79 0x71dff89eu, 0x10314e55u, 0x81ac77d6u, 0x5f11199bu, 0x043556f1u, 0xd7a3c76bu, 80 0x3c11183bu, 0x5924a509u, 0xf28fe6edu, 0x97f1fbfau, 0x9ebabf2cu, 0x1e153c6eu, 81 0x86e34570u, 0xeae96fb1u, 0x860e5e0au, 0x5a3e2ab3u, 0x771fe71cu, 0x4e3d06fau, 82 0x2965dcb9u, 0x99e71d0fu, 0x803e89d6u, 0x5266c825u, 0x2e4cc978u, 0x9c10b36au, 83 0xc6150ebau, 0x94e2ea78u, 0xa5fc3c53u, 0x1e0a2df4u, 0xf2f74ea7u, 0x361d2b3du, 84 0x1939260fu, 0x19c27960u, 0x5223a708u, 0xf71312b6u, 0xebadfe6eu, 0xeac31f66u, 85 0xe3bc4595u, 0xa67bc883u, 0xb17f37d1u, 0x018cff28u, 0xc332ddefu, 0xbe6c5aa5u, 86 0x65582185u, 0x68ab9802u, 0xeecea50fu, 0xdb2f953bu, 0x2aef7dadu, 0x5b6e2f84u, 87 0x1521b628u, 0x29076170u, 0xecdd4775u, 0x619f1510u, 0x13cca830u, 0xeb61bd96u, 88 0x0334fe1eu, 0xaa0363cfu, 0xb5735c90u, 0x4c70a239u, 0xd59e9e0bu, 0xcbaade14u, 89 0xeecc86bcu, 0x60622ca7u, 0x9cab5cabu, 0xb2f3846eu, 0x648b1eafu, 0x19bdf0cau, 90 0xa02369b9u, 0x655abb50u, 0x40685a32u, 0x3c2ab4b3u, 0x319ee9d5u, 0xc021b8f7u, 91 0x9b540b19u, 0x875fa099u, 0x95f7997eu, 0x623d7da8u, 0xf837889au, 0x97e32d77u, 92 0x11ed935fu, 0x16681281u, 0x0e358829u, 0xc7e61fd6u, 0x96dedfa1u, 0x7858ba99u, 93 0x57f584a5u, 0x1b227263u, 0x9b83c3ffu, 0x1ac24696u, 0xcdb30aebu, 0x532e3054u, 94 0x8fd948e4u, 0x6dbc3128u, 0x58ebf2efu, 0x34c6ffeau, 0xfe28ed61u, 0xee7c3c73u, 95 0x5d4a14d9u, 0xe864b7e3u, 0x42105d14u, 0x203e13e0u, 0x45eee2b6u, 0xa3aaabeau, 96 0xdb6c4f15u, 0xfacb4fd0u, 0xc742f442u, 0xef6abbb5u, 0x654f3b1du, 0x41cd2105u, 97 0xd81e799eu, 0x86854dc7u, 0xe44b476au, 0x3d816250u, 0xcf62a1f2u, 0x5b8d2646u, 98 0xfc8883a0u, 0xc1c7b6a3u, 0x7f1524c3u, 0x69cb7492u, 0x47848a0bu, 0x5692b285u, 99 0x095bbf00u, 0xad19489du, 0x1462b174u, 0x23820e00u, 0x58428d2au, 0x0c55f5eau, 100 0x1dadf43eu, 0x233f7061u, 0x3372f092u, 0x8d937e41u, 0xd65fecf1u, 0x6c223bdbu, 101 0x7cde3759u, 0xcbee7460u, 0x4085f2a7u, 0xce77326eu, 0xa6078084u, 0x19f8509eu, 102 0xe8efd855u, 0x61d99735u, 0xa969a7aau, 0xc50c06c2u, 0x5a04abfcu, 0x800bcadcu, 103 0x9e447a2eu, 0xc3453484u, 0xfdd56705u, 0x0e1e9ec9u, 0xdb73dbd3u, 0x105588cdu, 104 0x675fda79u, 0xe3674340u, 0xc5c43465u, 0x713e38d8u, 0x3d28f89eu, 0xf16dff20u, 105 0x153e21e7u, 0x8fb03d4au, 0xe6e39f2bu, 0xdb83adf7u, 106 107 0xe93d5a68u, 0x948140f7u, 0xf64c261cu, 0x94692934u, 0x411520f7u, 0x7602d4f7u, 108 0xbcf46b2eu, 0xd4a20068u, 0xd4082471u, 0x3320f46au, 0x43b7d4b7u, 0x500061afu, 109 0x1e39f62eu, 0x97244546u, 0x14214f74u, 0xbf8b8840u, 0x4d95fc1du, 0x96b591afu, 110 0x70f4ddd3u, 0x66a02f45u, 0xbfbc09ecu, 0x03bd9785u, 0x7fac6dd0u, 0x31cb8504u, 111 0x96eb27b3u, 0x55fd3941u, 0xda2547e6u, 0xabca0a9au, 0x28507825u, 0x530429f4u, 112 0x0a2c86dau, 0xe9b66dfbu, 0x68dc1462u, 0xd7486900u, 0x680ec0a4u, 0x27a18deeu, 113 0x4f3ffea2u, 0xe887ad8cu, 0xb58ce006u, 0x7af4d6b6u, 0xaace1e7cu, 0xd3375fecu, 114 0xce78a399u, 0x406b2a42u, 0x20fe9e35u, 0xd9f385b9u, 0xee39d7abu, 0x3b124e8bu, 115 0x1dc9faf7u, 0x4b6d1856u, 0x26a36631u, 0xeae397b2u, 0x3a6efa74u, 0xdd5b4332u, 116 0x6841e7f7u, 0xca7820fbu, 0xfb0af54eu, 0xd8feb397u, 0x454056acu, 0xba489527u, 117 0x55533a3au, 0x20838d87u, 0xfe6ba9b7u, 0xd096954bu, 0x55a867bcu, 0xa1159a58u, 118 0xcca92963u, 0x99e1db33u, 0xa62a4a56u, 0x3f3125f9u, 0x5ef47e1cu, 0x9029317cu, 119 0xfdf8e802u, 0x04272f70u, 0x80bb155cu, 0x05282ce3u, 0x95c11548u, 0xe4c66d22u, 120 0x48c1133fu, 0xc70f86dcu, 0x07f9c9eeu, 0x41041f0fu, 0x404779a4u, 0x5d886e17u, 121 0x325f51ebu, 0xd59bc0d1u, 0xf2bcc18fu, 0x41113564u, 0x257b7834u, 0x602a9c60u, 122 0xdff8e8a3u, 0x1f636c1bu, 0x0e12b4c2u, 0x02e1329eu, 0xaf664fd1u, 0xcad18115u, 123 0x6b2395e0u, 0x333e92e1u, 0x3b240b62u, 0xeebeb922u, 0x85b2a20eu, 0xe6ba0d99u, 124 0xde720c8cu, 0x2da2f728u, 0xd0127845u, 0x95b794fdu, 0x647d0862u, 0xe7ccf5f0u, 125 0x5449a36fu, 0x877d48fau, 0xc39dfd27u, 0xf33e8d1eu, 0x0a476341u, 0x992eff74u, 126 0x3a6f6eabu, 0xf4f8fd37u, 0xa812dc60u, 0xa1ebddf8u, 0x991be14cu, 0xdb6e6b0du, 127 0xc67b5510u, 0x6d672c37u, 0x2765d43bu, 0xdcd0e804u, 0xf1290dc7u, 0xcc00ffa3u, 128 0xb5390f92u, 0x690fed0bu, 0x667b9ffbu, 0xcedb7d9cu, 0xa091cf0bu, 0xd9155ea3u, 129 0xbb132f88u, 0x515bad24u, 0x7b9479bfu, 0x763bd6ebu, 0x37392eb3u, 0xcc115979u, 130 0x8026e297u, 0xf42e312du, 0x6842ada7u, 0xc66a2b3bu, 0x12754cccu, 0x782ef11cu, 131 0x6a124237u, 0xb79251e7u, 0x06a1bbe6u, 0x4bfb6350u, 0x1a6b1018u, 0x11caedfau, 132 0x3d25bdd8u, 0xe2e1c3c9u, 0x44421659u, 0x0a121386u, 0xd90cec6eu, 0xd5abea2au, 133 0x64af674eu, 0xda86a85fu, 0xbebfe988u, 0x64e4c3feu, 0x9dbc8057u, 0xf0f7c086u, 134 0x60787bf8u, 0x6003604du, 0xd1fd8346u, 0xf6381fb0u, 0x7745ae04u, 0xd736fcccu, 135 0x83426b33u, 0xf01eab71u, 0xb0804187u, 0x3c005e5fu, 0x77a057beu, 0xbde8ae24u, 136 0x55464299u, 0xbf582e61u, 0x4e58f48fu, 0xf2ddfda2u, 0xf474ef38u, 0x8789bdc2u, 137 0x5366f9c3u, 0xc8b38e74u, 0xb475f255u, 0x46fcd9b9u, 0x7aeb2661u, 0x8b1ddf84u, 138 0x846a0e79u, 0x915f95e2u, 0x466e598eu, 0x20b45770u, 0x8cd55591u, 0xc902de4cu, 139 0xb90bace1u, 0xbb8205d0u, 0x11a86248u, 0x7574a99eu, 0xb77f19b6u, 0xe0a9dc09u, 140 0x662d09a1u, 0xc4324633u, 0xe85a1f02u, 0x09f0be8cu, 0x4a99a025u, 0x1d6efe10u, 141 0x1ab93d1du, 0x0ba5a4dfu, 0xa186f20fu, 0x2868f169u, 0xdcb7da83u, 0x573906feu, 142 0xa1e2ce9bu, 0x4fcd7f52u, 0x50115e01u, 0xa70683fau, 0xa002b5c4u, 0x0de6d027u, 143 0x9af88c27u, 0x773f8641u, 0xc3604c06u, 0x61a806b5u, 0xf0177a28u, 0xc0f586e0u, 144 0x006058aau, 0x30dc7d62u, 0x11e69ed7u, 0x2338ea63u, 0x53c2dd94u, 0xc2c21634u, 145 0xbbcbee56u, 0x90bcb6deu, 0xebfc7da1u, 0xce591d76u, 0x6f05e409u, 0x4b7c0188u, 146 0x39720a3du, 0x7c927c24u, 0x86e3725fu, 0x724d9db9u, 0x1ac15bb4u, 0xd39eb8fcu, 147 0xed545578u, 0x08fca5b5u, 0xd83d7cd3u, 0x4dad0fc4u, 0x1e50ef5eu, 0xb161e6f8u, 148 0xa28514d9u, 0x6c51133cu, 0x6fd5c7e7u, 0x56e14ec4u, 0x362abfceu, 0xddc6c837u, 149 0xd79a3234u, 0x92638212u, 0x670efa8eu, 0x406000e0u, 150 151 0x3a39ce37u, 0xd3faf5cfu, 0xabc27737u, 0x5ac52d1bu, 0x5cb0679eu, 0x4fa33742u, 152 0xd3822740u, 0x99bc9bbeu, 0xd5118e9du, 0xbf0f7315u, 0xd62d1c7eu, 0xc700c47bu, 153 0xb78c1b6bu, 0x21a19045u, 0xb26eb1beu, 0x6a366eb4u, 0x5748ab2fu, 0xbc946e79u, 154 0xc6a376d2u, 0x6549c2c8u, 0x530ff8eeu, 0x468dde7du, 0xd5730a1du, 0x4cd04dc6u, 155 0x2939bbdbu, 0xa9ba4650u, 0xac9526e8u, 0xbe5ee304u, 0xa1fad5f0u, 0x6a2d519au, 156 0x63ef8ce2u, 0x9a86ee22u, 0xc089c2b8u, 0x43242ef6u, 0xa51e03aau, 0x9cf2d0a4u, 157 0x83c061bau, 0x9be96a4du, 0x8fe51550u, 0xba645bd6u, 0x2826a2f9u, 0xa73a3ae1u, 158 0x4ba99586u, 0xef5562e9u, 0xc72fefd3u, 0xf752f7dau, 0x3f046f69u, 0x77fa0a59u, 159 0x80e4a915u, 0x87b08601u, 0x9b09e6adu, 0x3b3ee593u, 0xe990fd5au, 0x9e34d797u, 160 0x2cf0b7d9u, 0x022b8b51u, 0x96d5ac3au, 0x017da67du, 0xd1cf3ed6u, 0x7c7d2d28u, 161 0x1f9f25cfu, 0xadf2b89bu, 0x5ad6b472u, 0x5a88f54cu, 0xe029ac71u, 0xe019a5e6u, 162 0x47b0acfdu, 0xed93fa9bu, 0xe8d3c48du, 0x283b57ccu, 0xf8d56629u, 0x79132e28u, 163 0x785f0191u, 0xed756055u, 0xf7960e44u, 0xe3d35e8cu, 0x15056dd4u, 0x88f46dbau, 164 0x03a16125u, 0x0564f0bdu, 0xc3eb9e15u, 0x3c9057a2u, 0x97271aecu, 0xa93a072au, 165 0x1b3f6d9bu, 0x1e6321f5u, 0xf59c66fbu, 0x26dcf319u, 0x7533d928u, 0xb155fdf5u, 166 0x03563482u, 0x8aba3cbbu, 0x28517711u, 0xc20ad9f8u, 0xabcc5167u, 0xccad925fu, 167 0x4de81751u, 0x3830dc8eu, 0x379d5862u, 0x9320f991u, 0xea7a90c2u, 0xfb3e7bceu, 168 0x5121ce64u, 0x774fbe32u, 0xa8b6e37eu, 0xc3293d46u, 0x48de5369u, 0x6413e680u, 169 0xa2ae0810u, 0xdd6db224u, 0x69852dfdu, 0x09072166u, 0xb39a460au, 0x6445c0ddu, 170 0x586cdecfu, 0x1c20c8aeu, 0x5bbef7ddu, 0x1b588d40u, 0xccd2017fu, 0x6bb4e3bbu, 171 0xdda26a7eu, 0x3a59ff45u, 0x3e350a44u, 0xbcb4cdd5u, 0x72eacea8u, 0xfa6484bbu, 172 0x8d6612aeu, 0xbf3c6f47u, 0xd29be463u, 0x542f5d9eu, 0xaec2771bu, 0xf64e6370u, 173 0x740e0d8du, 0xe75b1357u, 0xf8721671u, 0xaf537d5du, 0x4040cb08u, 0x4eb4e2ccu, 174 0x34d2466au, 0x0115af84u, 0xe1b00428u, 0x95983a1du, 0x06b89fb4u, 0xce6ea048u, 175 0x6f3f3b82u, 0x3520ab82u, 0x011a1d4bu, 0x277227f8u, 0x611560b1u, 0xe7933fdcu, 176 0xbb3a792bu, 0x344525bdu, 0xa08839e1u, 0x51ce794bu, 0x2f32c9b7u, 0xa01fbac9u, 177 0xe01cc87eu, 0xbcc7d1f6u, 0xcf0111c3u, 0xa1e8aac7u, 0x1a908749u, 0xd44fbd9au, 178 0xd0dadecbu, 0xd50ada38u, 0x0339c32au, 0xc6913667u, 0x8df9317cu, 0xe0b12b4fu, 179 0xf79e59b7u, 0x43f5bb3au, 0xf2d519ffu, 0x27d9459cu, 0xbf97222cu, 0x15e6fc2au, 180 0x0f91fc71u, 0x9b941525u, 0xfae59361u, 0xceb69cebu, 0xc2a86459u, 0x12baa8d1u, 181 0xb6c1075eu, 0xe3056a0cu, 0x10d25065u, 0xcb03a442u, 0xe0ec6e0eu, 0x1698db3bu, 182 0x4c98a0beu, 0x3278e964u, 0x9f1f9532u, 0xe0d392dfu, 0xd3a0342bu, 0x8971f21eu, 183 0x1b0a7441u, 0x4ba3348cu, 0xc5be7120u, 0xc37632d8u, 0xdf359f8du, 0x9b992f2eu, 184 0xe60b6f47u, 0x0fe3f11du, 0xe54cda54u, 0x1edad891u, 0xce6279cfu, 0xcd3e7e6fu, 185 0x1618b166u, 0xfd2c1d05u, 0x848fd2c5u, 0xf6fb2299u, 0xf523f357u, 0xa6327623u, 186 0x93a83531u, 0x56cccd02u, 0xacf08162u, 0x5a75ebb5u, 0x6e163697u, 0x88d273ccu, 187 0xde966292u, 0x81b949d0u, 0x4c50901bu, 0x71c65614u, 0xe6c6c7bdu, 0x327a140au, 188 0x45e1d006u, 0xc3f27b9au, 0xc9aa53fdu, 0x62a80f00u, 0xbb25bfe2u, 0x35bdd2f6u, 189 0x71126905u, 0xb2040222u, 0xb6cbcf7cu, 0xcd769c2bu, 0x53113ec0u, 0x1640e3d3u, 190 0x38abbd60u, 0x2547adf0u, 0xba38209cu, 0xf746ce76u, 0x77afa1c5u, 0x20756060u, 191 0x85cbfe4eu, 0x8ae88dd8u, 0x7aaaf9b0u, 0x4cf9aa7eu, 0x1948c25cu, 0x02fb8a8cu, 192 0x01c36ae4u, 0xd6ebe1f9u, 0x90d4f869u, 0xa65cdea0u, 0x3f09252du, 0xc208e69fu, 193 0xb74e6132u, 0xce77e25bu, 0x578fdfe3u, 0x3ac372e6u 194 ]; 195 196 __gshared immutable uint[18] P_INIT = [ 197 0x243f6a88u, 0x85a308d3u, 0x13198a2eu, 0x03707344u, 0xa4093822u, 0x299f31d0u, 198 0x082efa98u, 0xec4e6c89u, 0x452821e6u, 0x38d01377u, 0xbe5466cfu, 0x34e90c6cu, 199 0xc0ac29b7u, 0xc97c50ddu, 0x3f84d5b5u, 0xb5470917u, 0x9216d5d9u, 0x8979fb1bu 200 ]; 201 202 enum uint BLOCK_SIZE = 8, 203 ROUNDS = 16, 204 SBOX_SIZE = 256, 205 PBOX_SIZE = 18, 206 MAX_KEY_SIZE = 56, // 448 bits 207 MIN_KEY_SIZE = 4; // 32 bits 208 uint[18] P; 209 uint[256] S0, S1, S2, S3; 210 const(ubyte)[] workingKey; 211 } // end private 212 213 this() {} 214 this(bool encrypt, ubyte[] key) { 215 init(encrypt, key); 216 } 217 218 @property final override const(char[]) name() 219 { 220 return "Blowfish"; 221 } 222 223 @property final override const uint blockSize() 224 { 225 return BLOCK_SIZE; 226 } 227 228 final void init(bool encrypt, ubyte[] key) 229 { 230 _encrypt = encrypt; 231 232 size_t len = key.length; 233 if (len < MIN_KEY_SIZE || len > MAX_KEY_SIZE) 234 invalid(name()~": Invalid key length (requires 4-56 bytes)"); 235 236 workingKey = key; 237 238 // Yes, this is ghetto. I know. 239 _initialized = true; 240 241 setup(workingKey); 242 243 if (!_encrypt) 244 reverse(P[]); // Oh yes I did. 245 } 246 247 private uint F(uint x) 248 { 249 return (((S0[(x >> 24)] 250 + S1[cast(ubyte)(x >> 16)]) 251 ^ S2[cast(ubyte)(x >> 8)]) 252 + S3[cast(ubyte)x]); 253 } 254 255 final override uint update(const(void[]) input_, void[] output_) 256 { 257 if (!_initialized) 258 invalid(name()~": Cipher not initialized."); 259 260 ubyte[] input = cast(ubyte[]) input_, 261 output = cast(ubyte[]) output_; 262 263 if (input.length < BLOCK_SIZE) 264 invalid (name()~": Input buffer too short"); 265 266 if (output.length < BLOCK_SIZE) 267 invalid (name()~": Output buffer too short"); 268 269 uint xl = ByteConverter.BigEndian.to!(uint)(input[0..4]), 270 xr = ByteConverter.BigEndian.to!(uint)(input[4..8]), 271 i = 0; 272 273 xl ^= P[i++]; 274 for (; i < ROUNDS;) 275 { 276 xr ^= F(xl) ^ P[i++]; 277 xl ^= F(xr) ^ P[i++]; 278 } 279 xr ^= P[i]; 280 281 ByteConverter.BigEndian.from!(uint)(xr, output[0..4]); 282 ByteConverter.BigEndian.from!(uint)(xl, output[4..8]); 283 284 return BLOCK_SIZE; 285 } 286 287 final override void reset() 288 { 289 setup(workingKey); 290 } 291 292 private void setup(const(ubyte)[] key) 293 { 294 S0[] = S_INIT[0..256]; 295 S1[] = S_INIT[256..512]; 296 S2[] = S_INIT[512..768]; 297 S3[] = S_INIT[768..1024]; 298 P[] = P_INIT[]; 299 300 uint index = 0; 301 302 for (int i = 0; i < PBOX_SIZE; i++) 303 { 304 uint x = 0; 305 for (int j = 0; j < 4; j++) 306 { 307 x = (x << 8) | key[index++]; 308 if (index == key.length) 309 index = 0; 310 } 311 312 P[i] ^= x; 313 } 314 315 ubyte[] t = new ubyte[BLOCK_SIZE]; // Initialized to 0's 316 for (int i = 0; i < PBOX_SIZE;) 317 { 318 update(t, t); 319 P[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]); 320 P[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]); 321 } 322 323 for (int i = 0; i < SBOX_SIZE;) 324 { 325 update(t, t); 326 S0[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]); 327 S0[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]); 328 } 329 330 for (int i = 0; i < SBOX_SIZE;) 331 { 332 update(t, t); 333 S1[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]); 334 S1[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]); 335 } 336 337 for (int i = 0; i < SBOX_SIZE;) 338 { 339 update(t, t); 340 S2[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]); 341 S2[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]); 342 } 343 344 for (int i = 0; i < SBOX_SIZE;) 345 { 346 update(t, t); 347 S3[i++] = ByteConverter.BigEndian.to!(uint)(t[0..4]); 348 S3[i++] = ByteConverter.BigEndian.to!(uint)(t[4..8]); 349 } 350 } 351 352 353 } 354 355 /** Some Blowfish test vectors from Schneier's site. */ 356 debug (UnitTest) 357 { 358 unittest 359 { 360 __gshared immutable immutable(char)[][] test_keys = [ 361 "0000000000000000", 362 "ffffffffffffffff", 363 "57686f206973204a6f686e2047616c743f", // I don't know, do you? 364 "1111111111111111", 365 "0123456789abcdef", 366 "1111111111111111", 367 "fedcba9876543210" 368 ]; 369 370 __gshared immutable immutable(char)[][] test_plaintexts = [ 371 "0000000000000000", 372 "ffffffffffffffff", 373 "fedcba9876543210", 374 "1111111111111111", 375 "1111111111111111", 376 "0123456789abcdef", 377 "0123456789abcdef" 378 ]; 379 380 __gshared immutable immutable(char)[][] test_ciphertexts = [ 381 "4ef997456198dd78", 382 "51866fd5b85ecb8a", 383 "cc91732b8022f684", 384 "2466dd878b963c9d", 385 "61f9c3802281b096", 386 "7d0cc630afda1ec7", 387 "0aceab0fc6a0a28d" 388 ]; 389 390 Blowfish t = new Blowfish(); 391 foreach (uint i, immutable(char)[] test_key; test_keys) 392 { 393 ubyte[] buffer = new ubyte[t.blockSize]; 394 char[] result; 395 auto key = ByteConverter.hexDecode(test_key); 396 397 // Encryption 398 t.init(true, key); 399 t.update(ByteConverter.hexDecode(test_plaintexts[i]), buffer); 400 result = ByteConverter.hexEncode(buffer); 401 assert(result == test_ciphertexts[i], 402 t.name~": ("~result~") != ("~test_ciphertexts[i]~")"); 403 404 // Decryption 405 t.init(false, key); 406 t.update(ByteConverter.hexDecode(test_ciphertexts[i]), buffer); 407 result = ByteConverter.hexEncode(buffer); 408 assert(result == test_plaintexts[i], 409 t.name~": ("~result~") != ("~test_plaintexts[i]~")"); 410 } 411 } 412 }