Crypt_DES.php 112 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Pure-PHP implementation of DES.
  5. *
  6. * Uses mcrypt, if available, and an internal implementation, otherwise.
  7. *
  8. * PHP versions 4 and 5
  9. *
  10. * Useful resources are as follows:
  11. *
  12. * - {@link http://en.wikipedia.org/wiki/DES_supplementary_material Wikipedia: DES supplementary material}
  13. * - {@link http://www.itl.nist.gov/fipspubs/fip46-2.htm FIPS 46-2 - (DES), Data Encryption Standard}
  14. * - {@link http://www.cs.eku.edu/faculty/styer/460/Encrypt/JS-DES.html JavaScript DES Example}
  15. *
  16. * Here's a short example of how to use this library:
  17. * <code>
  18. * <?php
  19. * include('Crypt/DES.php');
  20. *
  21. * $des = new Crypt_DES();
  22. *
  23. * $des->setKey('abcdefgh');
  24. *
  25. * $size = 10 * 1024;
  26. * $plaintext = '';
  27. * for ($i = 0; $i < $size; $i++) {
  28. * $plaintext.= 'a';
  29. * }
  30. *
  31. * echo $des->decrypt($des->encrypt($plaintext));
  32. * ?>
  33. * </code>
  34. *
  35. * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
  36. * of this software and associated documentation files (the "Software"), to deal
  37. * in the Software without restriction, including without limitation the rights
  38. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  39. * copies of the Software, and to permit persons to whom the Software is
  40. * furnished to do so, subject to the following conditions:
  41. *
  42. * The above copyright notice and this permission notice shall be included in
  43. * all copies or substantial portions of the Software.
  44. *
  45. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  46. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  47. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  48. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  49. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  50. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  51. * THE SOFTWARE.
  52. *
  53. * @category Crypt
  54. * @package Crypt_DES
  55. * @author Jim Wigginton <terrafrost@php.net>
  56. * @copyright MMVII Jim Wigginton
  57. * @license http://www.opensource.org/licenses/mit-license.html MIT License
  58. * @link http://phpseclib.sourceforge.net
  59. */
  60. /**#@+
  61. * @access private
  62. * @see Crypt_DES::_prepareKey()
  63. * @see Crypt_DES::_processBlock()
  64. */
  65. /**
  66. * Contains array_reverse($keys[CRYPT_DES_DECRYPT])
  67. */
  68. define('CRYPT_DES_ENCRYPT', 0);
  69. /**
  70. * Contains array_reverse($keys[CRYPT_DES_ENCRYPT])
  71. */
  72. define('CRYPT_DES_DECRYPT', 1);
  73. /**
  74. * Contains $keys[CRYPT_DES_ENCRYPT] as 1-dim array
  75. */
  76. define('CRYPT_DES_ENCRYPT_1DIM', 2);
  77. /**
  78. * Contains $keys[CRYPT_DES_DECRYPT] as 1-dim array
  79. */
  80. define('CRYPT_DES_DECRYPT_1DIM', 3);
  81. /**#@-*/
  82. /**#@+
  83. * @access public
  84. * @see Crypt_DES::encrypt()
  85. * @see Crypt_DES::decrypt()
  86. */
  87. /**
  88. * Encrypt / decrypt using the Counter mode.
  89. *
  90. * Set to -1 since that's what Crypt/Random.php uses to index the CTR mode.
  91. *
  92. * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Counter_.28CTR.29
  93. */
  94. define('CRYPT_DES_MODE_CTR', -1);
  95. /**
  96. * Encrypt / decrypt using the Electronic Code Book mode.
  97. *
  98. * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29
  99. */
  100. define('CRYPT_DES_MODE_ECB', 1);
  101. /**
  102. * Encrypt / decrypt using the Code Book Chaining mode.
  103. *
  104. * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher-block_chaining_.28CBC.29
  105. */
  106. define('CRYPT_DES_MODE_CBC', 2);
  107. /**
  108. * Encrypt / decrypt using the Cipher Feedback mode.
  109. *
  110. * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Cipher_feedback_.28CFB.29
  111. */
  112. define('CRYPT_DES_MODE_CFB', 3);
  113. /**
  114. * Encrypt / decrypt using the Cipher Feedback mode.
  115. *
  116. * @link http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Output_feedback_.28OFB.29
  117. */
  118. define('CRYPT_DES_MODE_OFB', 4);
  119. /**#@-*/
  120. /**#@+
  121. * @access private
  122. * @see Crypt_DES::Crypt_DES()
  123. */
  124. /**
  125. * Toggles the internal implementation
  126. */
  127. define('CRYPT_DES_MODE_INTERNAL', 1);
  128. /**
  129. * Toggles the mcrypt implementation
  130. */
  131. define('CRYPT_DES_MODE_MCRYPT', 2);
  132. /**#@-*/
  133. /**
  134. * Pure-PHP implementation of DES.
  135. *
  136. * @author Jim Wigginton <terrafrost@php.net>
  137. * @version 0.1.0
  138. * @access public
  139. * @package Crypt_DES
  140. */
  141. class Crypt_DES {
  142. /**
  143. * The Key Schedule
  144. *
  145. * @see Crypt_DES::setKey()
  146. * @var Array
  147. * @access private
  148. */
  149. var $keys = "\0\0\0\0\0\0\0\0";
  150. /**
  151. * The Encryption Mode
  152. *
  153. * @see Crypt_DES::Crypt_DES()
  154. * @var Integer
  155. * @access private
  156. */
  157. var $mode;
  158. /**
  159. * Continuous Buffer status
  160. *
  161. * @see Crypt_DES::enableContinuousBuffer()
  162. * @var Boolean
  163. * @access private
  164. */
  165. var $continuousBuffer = false;
  166. /**
  167. * Padding status
  168. *
  169. * @see Crypt_DES::enablePadding()
  170. * @var Boolean
  171. * @access private
  172. */
  173. var $padding = true;
  174. /**
  175. * The Initialization Vector
  176. *
  177. * @see Crypt_DES::setIV()
  178. * @var String
  179. * @access private
  180. */
  181. var $iv = "\0\0\0\0\0\0\0\0";
  182. /**
  183. * A "sliding" Initialization Vector
  184. *
  185. * @see Crypt_DES::enableContinuousBuffer()
  186. * @var String
  187. * @access private
  188. */
  189. var $encryptIV = "\0\0\0\0\0\0\0\0";
  190. /**
  191. * A "sliding" Initialization Vector
  192. *
  193. * @see Crypt_DES::enableContinuousBuffer()
  194. * @var String
  195. * @access private
  196. */
  197. var $decryptIV = "\0\0\0\0\0\0\0\0";
  198. /**
  199. * mcrypt resource for encryption
  200. *
  201. * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
  202. * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
  203. *
  204. * @see Crypt_DES::encrypt()
  205. * @var String
  206. * @access private
  207. */
  208. var $enmcrypt;
  209. /**
  210. * mcrypt resource for decryption
  211. *
  212. * The mcrypt resource can be recreated every time something needs to be created or it can be created just once.
  213. * Since mcrypt operates in continuous mode, by default, it'll need to be recreated when in non-continuous mode.
  214. *
  215. * @see Crypt_DES::decrypt()
  216. * @var String
  217. * @access private
  218. */
  219. var $demcrypt;
  220. /**
  221. * Does the enmcrypt resource need to be (re)initialized?
  222. *
  223. * @see Crypt_DES::setKey()
  224. * @see Crypt_DES::setIV()
  225. * @var Boolean
  226. * @access private
  227. */
  228. var $enchanged = true;
  229. /**
  230. * Does the demcrypt resource need to be (re)initialized?
  231. *
  232. * @see Crypt_DES::setKey()
  233. * @see Crypt_DES::setIV()
  234. * @var Boolean
  235. * @access private
  236. */
  237. var $dechanged = true;
  238. /**
  239. * Is the mode one that is paddable?
  240. *
  241. * @see Crypt_DES::Crypt_DES()
  242. * @var Boolean
  243. * @access private
  244. */
  245. var $paddable = false;
  246. /**
  247. * Encryption buffer for CTR, OFB and CFB modes
  248. *
  249. * @see Crypt_DES::encrypt()
  250. * @var Array
  251. * @access private
  252. */
  253. var $enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
  254. /**
  255. * Decryption buffer for CTR, OFB and CFB modes
  256. *
  257. * @see Crypt_DES::decrypt()
  258. * @var Array
  259. * @access private
  260. */
  261. var $debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
  262. /**
  263. * mcrypt resource for CFB mode
  264. *
  265. * @see Crypt_DES::encrypt()
  266. * @see Crypt_DES::decrypt()
  267. * @var String
  268. * @access private
  269. */
  270. var $ecb;
  271. /**
  272. * Performance-optimized callback function for en/decrypt()
  273. *
  274. * @var Callback
  275. * @access private
  276. */
  277. var $inline_crypt;
  278. /**
  279. * Holds whether performance-optimized $inline_crypt should be used or not.
  280. *
  281. * @var Boolean
  282. * @access private
  283. */
  284. var $use_inline_crypt = false;
  285. /**
  286. * Shuffle table.
  287. *
  288. * For each byte value index, the entry holds an 8-byte string
  289. * with each byte containing all bits in the same state as the
  290. * corresponding bit in the index value.
  291. *
  292. * @see Crypt_DES::_processBlock()
  293. * @see Crypt_DES::_prepareKey()
  294. * @var Array
  295. * @access private
  296. */
  297. var $shuffle = array(
  298. "\x00\x00\x00\x00\x00\x00\x00\x00", "\x00\x00\x00\x00\x00\x00\x00\xFF",
  299. "\x00\x00\x00\x00\x00\x00\xFF\x00", "\x00\x00\x00\x00\x00\x00\xFF\xFF",
  300. "\x00\x00\x00\x00\x00\xFF\x00\x00", "\x00\x00\x00\x00\x00\xFF\x00\xFF",
  301. "\x00\x00\x00\x00\x00\xFF\xFF\x00", "\x00\x00\x00\x00\x00\xFF\xFF\xFF",
  302. "\x00\x00\x00\x00\xFF\x00\x00\x00", "\x00\x00\x00\x00\xFF\x00\x00\xFF",
  303. "\x00\x00\x00\x00\xFF\x00\xFF\x00", "\x00\x00\x00\x00\xFF\x00\xFF\xFF",
  304. "\x00\x00\x00\x00\xFF\xFF\x00\x00", "\x00\x00\x00\x00\xFF\xFF\x00\xFF",
  305. "\x00\x00\x00\x00\xFF\xFF\xFF\x00", "\x00\x00\x00\x00\xFF\xFF\xFF\xFF",
  306. "\x00\x00\x00\xFF\x00\x00\x00\x00", "\x00\x00\x00\xFF\x00\x00\x00\xFF",
  307. "\x00\x00\x00\xFF\x00\x00\xFF\x00", "\x00\x00\x00\xFF\x00\x00\xFF\xFF",
  308. "\x00\x00\x00\xFF\x00\xFF\x00\x00", "\x00\x00\x00\xFF\x00\xFF\x00\xFF",
  309. "\x00\x00\x00\xFF\x00\xFF\xFF\x00", "\x00\x00\x00\xFF\x00\xFF\xFF\xFF",
  310. "\x00\x00\x00\xFF\xFF\x00\x00\x00", "\x00\x00\x00\xFF\xFF\x00\x00\xFF",
  311. "\x00\x00\x00\xFF\xFF\x00\xFF\x00", "\x00\x00\x00\xFF\xFF\x00\xFF\xFF",
  312. "\x00\x00\x00\xFF\xFF\xFF\x00\x00", "\x00\x00\x00\xFF\xFF\xFF\x00\xFF",
  313. "\x00\x00\x00\xFF\xFF\xFF\xFF\x00", "\x00\x00\x00\xFF\xFF\xFF\xFF\xFF",
  314. "\x00\x00\xFF\x00\x00\x00\x00\x00", "\x00\x00\xFF\x00\x00\x00\x00\xFF",
  315. "\x00\x00\xFF\x00\x00\x00\xFF\x00", "\x00\x00\xFF\x00\x00\x00\xFF\xFF",
  316. "\x00\x00\xFF\x00\x00\xFF\x00\x00", "\x00\x00\xFF\x00\x00\xFF\x00\xFF",
  317. "\x00\x00\xFF\x00\x00\xFF\xFF\x00", "\x00\x00\xFF\x00\x00\xFF\xFF\xFF",
  318. "\x00\x00\xFF\x00\xFF\x00\x00\x00", "\x00\x00\xFF\x00\xFF\x00\x00\xFF",
  319. "\x00\x00\xFF\x00\xFF\x00\xFF\x00", "\x00\x00\xFF\x00\xFF\x00\xFF\xFF",
  320. "\x00\x00\xFF\x00\xFF\xFF\x00\x00", "\x00\x00\xFF\x00\xFF\xFF\x00\xFF",
  321. "\x00\x00\xFF\x00\xFF\xFF\xFF\x00", "\x00\x00\xFF\x00\xFF\xFF\xFF\xFF",
  322. "\x00\x00\xFF\xFF\x00\x00\x00\x00", "\x00\x00\xFF\xFF\x00\x00\x00\xFF",
  323. "\x00\x00\xFF\xFF\x00\x00\xFF\x00", "\x00\x00\xFF\xFF\x00\x00\xFF\xFF",
  324. "\x00\x00\xFF\xFF\x00\xFF\x00\x00", "\x00\x00\xFF\xFF\x00\xFF\x00\xFF",
  325. "\x00\x00\xFF\xFF\x00\xFF\xFF\x00", "\x00\x00\xFF\xFF\x00\xFF\xFF\xFF",
  326. "\x00\x00\xFF\xFF\xFF\x00\x00\x00", "\x00\x00\xFF\xFF\xFF\x00\x00\xFF",
  327. "\x00\x00\xFF\xFF\xFF\x00\xFF\x00", "\x00\x00\xFF\xFF\xFF\x00\xFF\xFF",
  328. "\x00\x00\xFF\xFF\xFF\xFF\x00\x00", "\x00\x00\xFF\xFF\xFF\xFF\x00\xFF",
  329. "\x00\x00\xFF\xFF\xFF\xFF\xFF\x00", "\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF",
  330. "\x00\xFF\x00\x00\x00\x00\x00\x00", "\x00\xFF\x00\x00\x00\x00\x00\xFF",
  331. "\x00\xFF\x00\x00\x00\x00\xFF\x00", "\x00\xFF\x00\x00\x00\x00\xFF\xFF",
  332. "\x00\xFF\x00\x00\x00\xFF\x00\x00", "\x00\xFF\x00\x00\x00\xFF\x00\xFF",
  333. "\x00\xFF\x00\x00\x00\xFF\xFF\x00", "\x00\xFF\x00\x00\x00\xFF\xFF\xFF",
  334. "\x00\xFF\x00\x00\xFF\x00\x00\x00", "\x00\xFF\x00\x00\xFF\x00\x00\xFF",
  335. "\x00\xFF\x00\x00\xFF\x00\xFF\x00", "\x00\xFF\x00\x00\xFF\x00\xFF\xFF",
  336. "\x00\xFF\x00\x00\xFF\xFF\x00\x00", "\x00\xFF\x00\x00\xFF\xFF\x00\xFF",
  337. "\x00\xFF\x00\x00\xFF\xFF\xFF\x00", "\x00\xFF\x00\x00\xFF\xFF\xFF\xFF",
  338. "\x00\xFF\x00\xFF\x00\x00\x00\x00", "\x00\xFF\x00\xFF\x00\x00\x00\xFF",
  339. "\x00\xFF\x00\xFF\x00\x00\xFF\x00", "\x00\xFF\x00\xFF\x00\x00\xFF\xFF",
  340. "\x00\xFF\x00\xFF\x00\xFF\x00\x00", "\x00\xFF\x00\xFF\x00\xFF\x00\xFF",
  341. "\x00\xFF\x00\xFF\x00\xFF\xFF\x00", "\x00\xFF\x00\xFF\x00\xFF\xFF\xFF",
  342. "\x00\xFF\x00\xFF\xFF\x00\x00\x00", "\x00\xFF\x00\xFF\xFF\x00\x00\xFF",
  343. "\x00\xFF\x00\xFF\xFF\x00\xFF\x00", "\x00\xFF\x00\xFF\xFF\x00\xFF\xFF",
  344. "\x00\xFF\x00\xFF\xFF\xFF\x00\x00", "\x00\xFF\x00\xFF\xFF\xFF\x00\xFF",
  345. "\x00\xFF\x00\xFF\xFF\xFF\xFF\x00", "\x00\xFF\x00\xFF\xFF\xFF\xFF\xFF",
  346. "\x00\xFF\xFF\x00\x00\x00\x00\x00", "\x00\xFF\xFF\x00\x00\x00\x00\xFF",
  347. "\x00\xFF\xFF\x00\x00\x00\xFF\x00", "\x00\xFF\xFF\x00\x00\x00\xFF\xFF",
  348. "\x00\xFF\xFF\x00\x00\xFF\x00\x00", "\x00\xFF\xFF\x00\x00\xFF\x00\xFF",
  349. "\x00\xFF\xFF\x00\x00\xFF\xFF\x00", "\x00\xFF\xFF\x00\x00\xFF\xFF\xFF",
  350. "\x00\xFF\xFF\x00\xFF\x00\x00\x00", "\x00\xFF\xFF\x00\xFF\x00\x00\xFF",
  351. "\x00\xFF\xFF\x00\xFF\x00\xFF\x00", "\x00\xFF\xFF\x00\xFF\x00\xFF\xFF",
  352. "\x00\xFF\xFF\x00\xFF\xFF\x00\x00", "\x00\xFF\xFF\x00\xFF\xFF\x00\xFF",
  353. "\x00\xFF\xFF\x00\xFF\xFF\xFF\x00", "\x00\xFF\xFF\x00\xFF\xFF\xFF\xFF",
  354. "\x00\xFF\xFF\xFF\x00\x00\x00\x00", "\x00\xFF\xFF\xFF\x00\x00\x00\xFF",
  355. "\x00\xFF\xFF\xFF\x00\x00\xFF\x00", "\x00\xFF\xFF\xFF\x00\x00\xFF\xFF",
  356. "\x00\xFF\xFF\xFF\x00\xFF\x00\x00", "\x00\xFF\xFF\xFF\x00\xFF\x00\xFF",
  357. "\x00\xFF\xFF\xFF\x00\xFF\xFF\x00", "\x00\xFF\xFF\xFF\x00\xFF\xFF\xFF",
  358. "\x00\xFF\xFF\xFF\xFF\x00\x00\x00", "\x00\xFF\xFF\xFF\xFF\x00\x00\xFF",
  359. "\x00\xFF\xFF\xFF\xFF\x00\xFF\x00", "\x00\xFF\xFF\xFF\xFF\x00\xFF\xFF",
  360. "\x00\xFF\xFF\xFF\xFF\xFF\x00\x00", "\x00\xFF\xFF\xFF\xFF\xFF\x00\xFF",
  361. "\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
  362. "\xFF\x00\x00\x00\x00\x00\x00\x00", "\xFF\x00\x00\x00\x00\x00\x00\xFF",
  363. "\xFF\x00\x00\x00\x00\x00\xFF\x00", "\xFF\x00\x00\x00\x00\x00\xFF\xFF",
  364. "\xFF\x00\x00\x00\x00\xFF\x00\x00", "\xFF\x00\x00\x00\x00\xFF\x00\xFF",
  365. "\xFF\x00\x00\x00\x00\xFF\xFF\x00", "\xFF\x00\x00\x00\x00\xFF\xFF\xFF",
  366. "\xFF\x00\x00\x00\xFF\x00\x00\x00", "\xFF\x00\x00\x00\xFF\x00\x00\xFF",
  367. "\xFF\x00\x00\x00\xFF\x00\xFF\x00", "\xFF\x00\x00\x00\xFF\x00\xFF\xFF",
  368. "\xFF\x00\x00\x00\xFF\xFF\x00\x00", "\xFF\x00\x00\x00\xFF\xFF\x00\xFF",
  369. "\xFF\x00\x00\x00\xFF\xFF\xFF\x00", "\xFF\x00\x00\x00\xFF\xFF\xFF\xFF",
  370. "\xFF\x00\x00\xFF\x00\x00\x00\x00", "\xFF\x00\x00\xFF\x00\x00\x00\xFF",
  371. "\xFF\x00\x00\xFF\x00\x00\xFF\x00", "\xFF\x00\x00\xFF\x00\x00\xFF\xFF",
  372. "\xFF\x00\x00\xFF\x00\xFF\x00\x00", "\xFF\x00\x00\xFF\x00\xFF\x00\xFF",
  373. "\xFF\x00\x00\xFF\x00\xFF\xFF\x00", "\xFF\x00\x00\xFF\x00\xFF\xFF\xFF",
  374. "\xFF\x00\x00\xFF\xFF\x00\x00\x00", "\xFF\x00\x00\xFF\xFF\x00\x00\xFF",
  375. "\xFF\x00\x00\xFF\xFF\x00\xFF\x00", "\xFF\x00\x00\xFF\xFF\x00\xFF\xFF",
  376. "\xFF\x00\x00\xFF\xFF\xFF\x00\x00", "\xFF\x00\x00\xFF\xFF\xFF\x00\xFF",
  377. "\xFF\x00\x00\xFF\xFF\xFF\xFF\x00", "\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF",
  378. "\xFF\x00\xFF\x00\x00\x00\x00\x00", "\xFF\x00\xFF\x00\x00\x00\x00\xFF",
  379. "\xFF\x00\xFF\x00\x00\x00\xFF\x00", "\xFF\x00\xFF\x00\x00\x00\xFF\xFF",
  380. "\xFF\x00\xFF\x00\x00\xFF\x00\x00", "\xFF\x00\xFF\x00\x00\xFF\x00\xFF",
  381. "\xFF\x00\xFF\x00\x00\xFF\xFF\x00", "\xFF\x00\xFF\x00\x00\xFF\xFF\xFF",
  382. "\xFF\x00\xFF\x00\xFF\x00\x00\x00", "\xFF\x00\xFF\x00\xFF\x00\x00\xFF",
  383. "\xFF\x00\xFF\x00\xFF\x00\xFF\x00", "\xFF\x00\xFF\x00\xFF\x00\xFF\xFF",
  384. "\xFF\x00\xFF\x00\xFF\xFF\x00\x00", "\xFF\x00\xFF\x00\xFF\xFF\x00\xFF",
  385. "\xFF\x00\xFF\x00\xFF\xFF\xFF\x00", "\xFF\x00\xFF\x00\xFF\xFF\xFF\xFF",
  386. "\xFF\x00\xFF\xFF\x00\x00\x00\x00", "\xFF\x00\xFF\xFF\x00\x00\x00\xFF",
  387. "\xFF\x00\xFF\xFF\x00\x00\xFF\x00", "\xFF\x00\xFF\xFF\x00\x00\xFF\xFF",
  388. "\xFF\x00\xFF\xFF\x00\xFF\x00\x00", "\xFF\x00\xFF\xFF\x00\xFF\x00\xFF",
  389. "\xFF\x00\xFF\xFF\x00\xFF\xFF\x00", "\xFF\x00\xFF\xFF\x00\xFF\xFF\xFF",
  390. "\xFF\x00\xFF\xFF\xFF\x00\x00\x00", "\xFF\x00\xFF\xFF\xFF\x00\x00\xFF",
  391. "\xFF\x00\xFF\xFF\xFF\x00\xFF\x00", "\xFF\x00\xFF\xFF\xFF\x00\xFF\xFF",
  392. "\xFF\x00\xFF\xFF\xFF\xFF\x00\x00", "\xFF\x00\xFF\xFF\xFF\xFF\x00\xFF",
  393. "\xFF\x00\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\x00\xFF\xFF\xFF\xFF\xFF\xFF",
  394. "\xFF\xFF\x00\x00\x00\x00\x00\x00", "\xFF\xFF\x00\x00\x00\x00\x00\xFF",
  395. "\xFF\xFF\x00\x00\x00\x00\xFF\x00", "\xFF\xFF\x00\x00\x00\x00\xFF\xFF",
  396. "\xFF\xFF\x00\x00\x00\xFF\x00\x00", "\xFF\xFF\x00\x00\x00\xFF\x00\xFF",
  397. "\xFF\xFF\x00\x00\x00\xFF\xFF\x00", "\xFF\xFF\x00\x00\x00\xFF\xFF\xFF",
  398. "\xFF\xFF\x00\x00\xFF\x00\x00\x00", "\xFF\xFF\x00\x00\xFF\x00\x00\xFF",
  399. "\xFF\xFF\x00\x00\xFF\x00\xFF\x00", "\xFF\xFF\x00\x00\xFF\x00\xFF\xFF",
  400. "\xFF\xFF\x00\x00\xFF\xFF\x00\x00", "\xFF\xFF\x00\x00\xFF\xFF\x00\xFF",
  401. "\xFF\xFF\x00\x00\xFF\xFF\xFF\x00", "\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF",
  402. "\xFF\xFF\x00\xFF\x00\x00\x00\x00", "\xFF\xFF\x00\xFF\x00\x00\x00\xFF",
  403. "\xFF\xFF\x00\xFF\x00\x00\xFF\x00", "\xFF\xFF\x00\xFF\x00\x00\xFF\xFF",
  404. "\xFF\xFF\x00\xFF\x00\xFF\x00\x00", "\xFF\xFF\x00\xFF\x00\xFF\x00\xFF",
  405. "\xFF\xFF\x00\xFF\x00\xFF\xFF\x00", "\xFF\xFF\x00\xFF\x00\xFF\xFF\xFF",
  406. "\xFF\xFF\x00\xFF\xFF\x00\x00\x00", "\xFF\xFF\x00\xFF\xFF\x00\x00\xFF",
  407. "\xFF\xFF\x00\xFF\xFF\x00\xFF\x00", "\xFF\xFF\x00\xFF\xFF\x00\xFF\xFF",
  408. "\xFF\xFF\x00\xFF\xFF\xFF\x00\x00", "\xFF\xFF\x00\xFF\xFF\xFF\x00\xFF",
  409. "\xFF\xFF\x00\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\x00\xFF\xFF\xFF\xFF\xFF",
  410. "\xFF\xFF\xFF\x00\x00\x00\x00\x00", "\xFF\xFF\xFF\x00\x00\x00\x00\xFF",
  411. "\xFF\xFF\xFF\x00\x00\x00\xFF\x00", "\xFF\xFF\xFF\x00\x00\x00\xFF\xFF",
  412. "\xFF\xFF\xFF\x00\x00\xFF\x00\x00", "\xFF\xFF\xFF\x00\x00\xFF\x00\xFF",
  413. "\xFF\xFF\xFF\x00\x00\xFF\xFF\x00", "\xFF\xFF\xFF\x00\x00\xFF\xFF\xFF",
  414. "\xFF\xFF\xFF\x00\xFF\x00\x00\x00", "\xFF\xFF\xFF\x00\xFF\x00\x00\xFF",
  415. "\xFF\xFF\xFF\x00\xFF\x00\xFF\x00", "\xFF\xFF\xFF\x00\xFF\x00\xFF\xFF",
  416. "\xFF\xFF\xFF\x00\xFF\xFF\x00\x00", "\xFF\xFF\xFF\x00\xFF\xFF\x00\xFF",
  417. "\xFF\xFF\xFF\x00\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF",
  418. "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", "\xFF\xFF\xFF\xFF\x00\x00\x00\xFF",
  419. "\xFF\xFF\xFF\xFF\x00\x00\xFF\x00", "\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF",
  420. "\xFF\xFF\xFF\xFF\x00\xFF\x00\x00", "\xFF\xFF\xFF\xFF\x00\xFF\x00\xFF",
  421. "\xFF\xFF\xFF\xFF\x00\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF",
  422. "\xFF\xFF\xFF\xFF\xFF\x00\x00\x00", "\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF",
  423. "\xFF\xFF\xFF\xFF\xFF\x00\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF",
  424. "\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF",
  425. "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00", "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
  426. );
  427. /**
  428. * IP mapping helper table.
  429. *
  430. * Indexing this table with each source byte performs the initial bit permutation.
  431. *
  432. * @var Array
  433. * @access private
  434. */
  435. var $ipmap = array(
  436. 0x00, 0x10, 0x01, 0x11, 0x20, 0x30, 0x21, 0x31,
  437. 0x02, 0x12, 0x03, 0x13, 0x22, 0x32, 0x23, 0x33,
  438. 0x40, 0x50, 0x41, 0x51, 0x60, 0x70, 0x61, 0x71,
  439. 0x42, 0x52, 0x43, 0x53, 0x62, 0x72, 0x63, 0x73,
  440. 0x04, 0x14, 0x05, 0x15, 0x24, 0x34, 0x25, 0x35,
  441. 0x06, 0x16, 0x07, 0x17, 0x26, 0x36, 0x27, 0x37,
  442. 0x44, 0x54, 0x45, 0x55, 0x64, 0x74, 0x65, 0x75,
  443. 0x46, 0x56, 0x47, 0x57, 0x66, 0x76, 0x67, 0x77,
  444. 0x80, 0x90, 0x81, 0x91, 0xA0, 0xB0, 0xA1, 0xB1,
  445. 0x82, 0x92, 0x83, 0x93, 0xA2, 0xB2, 0xA3, 0xB3,
  446. 0xC0, 0xD0, 0xC1, 0xD1, 0xE0, 0xF0, 0xE1, 0xF1,
  447. 0xC2, 0xD2, 0xC3, 0xD3, 0xE2, 0xF2, 0xE3, 0xF3,
  448. 0x84, 0x94, 0x85, 0x95, 0xA4, 0xB4, 0xA5, 0xB5,
  449. 0x86, 0x96, 0x87, 0x97, 0xA6, 0xB6, 0xA7, 0xB7,
  450. 0xC4, 0xD4, 0xC5, 0xD5, 0xE4, 0xF4, 0xE5, 0xF5,
  451. 0xC6, 0xD6, 0xC7, 0xD7, 0xE6, 0xF6, 0xE7, 0xF7,
  452. 0x08, 0x18, 0x09, 0x19, 0x28, 0x38, 0x29, 0x39,
  453. 0x0A, 0x1A, 0x0B, 0x1B, 0x2A, 0x3A, 0x2B, 0x3B,
  454. 0x48, 0x58, 0x49, 0x59, 0x68, 0x78, 0x69, 0x79,
  455. 0x4A, 0x5A, 0x4B, 0x5B, 0x6A, 0x7A, 0x6B, 0x7B,
  456. 0x0C, 0x1C, 0x0D, 0x1D, 0x2C, 0x3C, 0x2D, 0x3D,
  457. 0x0E, 0x1E, 0x0F, 0x1F, 0x2E, 0x3E, 0x2F, 0x3F,
  458. 0x4C, 0x5C, 0x4D, 0x5D, 0x6C, 0x7C, 0x6D, 0x7D,
  459. 0x4E, 0x5E, 0x4F, 0x5F, 0x6E, 0x7E, 0x6F, 0x7F,
  460. 0x88, 0x98, 0x89, 0x99, 0xA8, 0xB8, 0xA9, 0xB9,
  461. 0x8A, 0x9A, 0x8B, 0x9B, 0xAA, 0xBA, 0xAB, 0xBB,
  462. 0xC8, 0xD8, 0xC9, 0xD9, 0xE8, 0xF8, 0xE9, 0xF9,
  463. 0xCA, 0xDA, 0xCB, 0xDB, 0xEA, 0xFA, 0xEB, 0xFB,
  464. 0x8C, 0x9C, 0x8D, 0x9D, 0xAC, 0xBC, 0xAD, 0xBD,
  465. 0x8E, 0x9E, 0x8F, 0x9F, 0xAE, 0xBE, 0xAF, 0xBF,
  466. 0xCC, 0xDC, 0xCD, 0xDD, 0xEC, 0xFC, 0xED, 0xFD,
  467. 0xCE, 0xDE, 0xCF, 0xDF, 0xEE, 0xFE, 0xEF, 0xFF
  468. );
  469. /**
  470. * Inverse IP mapping helper table.
  471. * Indexing this table with a byte value reverses the bit order.
  472. *
  473. * @var Array
  474. * @access private
  475. */
  476. var $invipmap = array(
  477. 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
  478. 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
  479. 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
  480. 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
  481. 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
  482. 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
  483. 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
  484. 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
  485. 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
  486. 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
  487. 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
  488. 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
  489. 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
  490. 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
  491. 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
  492. 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
  493. 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
  494. 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
  495. 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
  496. 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
  497. 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
  498. 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
  499. 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
  500. 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
  501. 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
  502. 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
  503. 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
  504. 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
  505. 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
  506. 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
  507. 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
  508. 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
  509. );
  510. /**
  511. * Pre-permuted S-box1
  512. *
  513. * Each box ($sbox1-$sbox8) has been vectorized, then each value pre-permuted using the
  514. * P table: concatenation can then be replaced by exclusive ORs.
  515. *
  516. * @var Array
  517. * @access private
  518. */
  519. var $sbox1 = array(
  520. 0x00808200, 0x00000000, 0x00008000, 0x00808202,
  521. 0x00808002, 0x00008202, 0x00000002, 0x00008000,
  522. 0x00000200, 0x00808200, 0x00808202, 0x00000200,
  523. 0x00800202, 0x00808002, 0x00800000, 0x00000002,
  524. 0x00000202, 0x00800200, 0x00800200, 0x00008200,
  525. 0x00008200, 0x00808000, 0x00808000, 0x00800202,
  526. 0x00008002, 0x00800002, 0x00800002, 0x00008002,
  527. 0x00000000, 0x00000202, 0x00008202, 0x00800000,
  528. 0x00008000, 0x00808202, 0x00000002, 0x00808000,
  529. 0x00808200, 0x00800000, 0x00800000, 0x00000200,
  530. 0x00808002, 0x00008000, 0x00008200, 0x00800002,
  531. 0x00000200, 0x00000002, 0x00800202, 0x00008202,
  532. 0x00808202, 0x00008002, 0x00808000, 0x00800202,
  533. 0x00800002, 0x00000202, 0x00008202, 0x00808200,
  534. 0x00000202, 0x00800200, 0x00800200, 0x00000000,
  535. 0x00008002, 0x00008200, 0x00000000, 0x00808002
  536. );
  537. /**
  538. * Pre-permuted S-box2
  539. *
  540. * @var Array
  541. * @access private
  542. */
  543. var $sbox2 = array(
  544. 0x40084010, 0x40004000, 0x00004000, 0x00084010,
  545. 0x00080000, 0x00000010, 0x40080010, 0x40004010,
  546. 0x40000010, 0x40084010, 0x40084000, 0x40000000,
  547. 0x40004000, 0x00080000, 0x00000010, 0x40080010,
  548. 0x00084000, 0x00080010, 0x40004010, 0x00000000,
  549. 0x40000000, 0x00004000, 0x00084010, 0x40080000,
  550. 0x00080010, 0x40000010, 0x00000000, 0x00084000,
  551. 0x00004010, 0x40084000, 0x40080000, 0x00004010,
  552. 0x00000000, 0x00084010, 0x40080010, 0x00080000,
  553. 0x40004010, 0x40080000, 0x40084000, 0x00004000,
  554. 0x40080000, 0x40004000, 0x00000010, 0x40084010,
  555. 0x00084010, 0x00000010, 0x00004000, 0x40000000,
  556. 0x00004010, 0x40084000, 0x00080000, 0x40000010,
  557. 0x00080010, 0x40004010, 0x40000010, 0x00080010,
  558. 0x00084000, 0x00000000, 0x40004000, 0x00004010,
  559. 0x40000000, 0x40080010, 0x40084010, 0x00084000
  560. );
  561. /**
  562. * Pre-permuted S-box3
  563. *
  564. * @var Array
  565. * @access private
  566. */
  567. var $sbox3 = array(
  568. 0x00000104, 0x04010100, 0x00000000, 0x04010004,
  569. 0x04000100, 0x00000000, 0x00010104, 0x04000100,
  570. 0x00010004, 0x04000004, 0x04000004, 0x00010000,
  571. 0x04010104, 0x00010004, 0x04010000, 0x00000104,
  572. 0x04000000, 0x00000004, 0x04010100, 0x00000100,
  573. 0x00010100, 0x04010000, 0x04010004, 0x00010104,
  574. 0x04000104, 0x00010100, 0x00010000, 0x04000104,
  575. 0x00000004, 0x04010104, 0x00000100, 0x04000000,
  576. 0x04010100, 0x04000000, 0x00010004, 0x00000104,
  577. 0x00010000, 0x04010100, 0x04000100, 0x00000000,
  578. 0x00000100, 0x00010004, 0x04010104, 0x04000100,
  579. 0x04000004, 0x00000100, 0x00000000, 0x04010004,
  580. 0x04000104, 0x00010000, 0x04000000, 0x04010104,
  581. 0x00000004, 0x00010104, 0x00010100, 0x04000004,
  582. 0x04010000, 0x04000104, 0x00000104, 0x04010000,
  583. 0x00010104, 0x00000004, 0x04010004, 0x00010100
  584. );
  585. /**
  586. * Pre-permuted S-box4
  587. *
  588. * @var Array
  589. * @access private
  590. */
  591. var $sbox4 = array(
  592. 0x80401000, 0x80001040, 0x80001040, 0x00000040,
  593. 0x00401040, 0x80400040, 0x80400000, 0x80001000,
  594. 0x00000000, 0x00401000, 0x00401000, 0x80401040,
  595. 0x80000040, 0x00000000, 0x00400040, 0x80400000,
  596. 0x80000000, 0x00001000, 0x00400000, 0x80401000,
  597. 0x00000040, 0x00400000, 0x80001000, 0x00001040,
  598. 0x80400040, 0x80000000, 0x00001040, 0x00400040,
  599. 0x00001000, 0x00401040, 0x80401040, 0x80000040,
  600. 0x00400040, 0x80400000, 0x00401000, 0x80401040,
  601. 0x80000040, 0x00000000, 0x00000000, 0x00401000,
  602. 0x00001040, 0x00400040, 0x80400040, 0x80000000,
  603. 0x80401000, 0x80001040, 0x80001040, 0x00000040,
  604. 0x80401040, 0x80000040, 0x80000000, 0x00001000,
  605. 0x80400000, 0x80001000, 0x00401040, 0x80400040,
  606. 0x80001000, 0x00001040, 0x00400000, 0x80401000,
  607. 0x00000040, 0x00400000, 0x00001000, 0x00401040
  608. );
  609. /**
  610. * Pre-permuted S-box5
  611. *
  612. * @var Array
  613. * @access private
  614. */
  615. var $sbox5 = array(
  616. 0x00000080, 0x01040080, 0x01040000, 0x21000080,
  617. 0x00040000, 0x00000080, 0x20000000, 0x01040000,
  618. 0x20040080, 0x00040000, 0x01000080, 0x20040080,
  619. 0x21000080, 0x21040000, 0x00040080, 0x20000000,
  620. 0x01000000, 0x20040000, 0x20040000, 0x00000000,
  621. 0x20000080, 0x21040080, 0x21040080, 0x01000080,
  622. 0x21040000, 0x20000080, 0x00000000, 0x21000000,
  623. 0x01040080, 0x01000000, 0x21000000, 0x00040080,
  624. 0x00040000, 0x21000080, 0x00000080, 0x01000000,
  625. 0x20000000, 0x01040000, 0x21000080, 0x20040080,
  626. 0x01000080, 0x20000000, 0x21040000, 0x01040080,
  627. 0x20040080, 0x00000080, 0x01000000, 0x21040000,
  628. 0x21040080, 0x00040080, 0x21000000, 0x21040080,
  629. 0x01040000, 0x00000000, 0x20040000, 0x21000000,
  630. 0x00040080, 0x01000080, 0x20000080, 0x00040000,
  631. 0x00000000, 0x20040000, 0x01040080, 0x20000080
  632. );
  633. /**
  634. * Pre-permuted S-box6
  635. *
  636. * @var Array
  637. * @access private
  638. */
  639. var $sbox6 = array(
  640. 0x10000008, 0x10200000, 0x00002000, 0x10202008,
  641. 0x10200000, 0x00000008, 0x10202008, 0x00200000,
  642. 0x10002000, 0x00202008, 0x00200000, 0x10000008,
  643. 0x00200008, 0x10002000, 0x10000000, 0x00002008,
  644. 0x00000000, 0x00200008, 0x10002008, 0x00002000,
  645. 0x00202000, 0x10002008, 0x00000008, 0x10200008,
  646. 0x10200008, 0x00000000, 0x00202008, 0x10202000,
  647. 0x00002008, 0x00202000, 0x10202000, 0x10000000,
  648. 0x10002000, 0x00000008, 0x10200008, 0x00202000,
  649. 0x10202008, 0x00200000, 0x00002008, 0x10000008,
  650. 0x00200000, 0x10002000, 0x10000000, 0x00002008,
  651. 0x10000008, 0x10202008, 0x00202000, 0x10200000,
  652. 0x00202008, 0x10202000, 0x00000000, 0x10200008,
  653. 0x00000008, 0x00002000, 0x10200000, 0x00202008,
  654. 0x00002000, 0x00200008, 0x10002008, 0x00000000,
  655. 0x10202000, 0x10000000, 0x00200008, 0x10002008
  656. );
  657. /**
  658. * Pre-permuted S-box7
  659. *
  660. * @var Array
  661. * @access private
  662. */
  663. var $sbox7 = array(
  664. 0x00100000, 0x02100001, 0x02000401, 0x00000000,
  665. 0x00000400, 0x02000401, 0x00100401, 0x02100400,
  666. 0x02100401, 0x00100000, 0x00000000, 0x02000001,
  667. 0x00000001, 0x02000000, 0x02100001, 0x00000401,
  668. 0x02000400, 0x00100401, 0x00100001, 0x02000400,
  669. 0x02000001, 0x02100000, 0x02100400, 0x00100001,
  670. 0x02100000, 0x00000400, 0x00000401, 0x02100401,
  671. 0x00100400, 0x00000001, 0x02000000, 0x00100400,
  672. 0x02000000, 0x00100400, 0x00100000, 0x02000401,
  673. 0x02000401, 0x02100001, 0x02100001, 0x00000001,
  674. 0x00100001, 0x02000000, 0x02000400, 0x00100000,
  675. 0x02100400, 0x00000401, 0x00100401, 0x02100400,
  676. 0x00000401, 0x02000001, 0x02100401, 0x02100000,
  677. 0x00100400, 0x00000000, 0x00000001, 0x02100401,
  678. 0x00000000, 0x00100401, 0x02100000, 0x00000400,
  679. 0x02000001, 0x02000400, 0x00000400, 0x00100001
  680. );
  681. /**
  682. * Pre-permuted S-box8
  683. *
  684. * @var Array
  685. * @access private
  686. */
  687. var $sbox8 = array(
  688. 0x08000820, 0x00000800, 0x00020000, 0x08020820,
  689. 0x08000000, 0x08000820, 0x00000020, 0x08000000,
  690. 0x00020020, 0x08020000, 0x08020820, 0x00020800,
  691. 0x08020800, 0x00020820, 0x00000800, 0x00000020,
  692. 0x08020000, 0x08000020, 0x08000800, 0x00000820,
  693. 0x00020800, 0x00020020, 0x08020020, 0x08020800,
  694. 0x00000820, 0x00000000, 0x00000000, 0x08020020,
  695. 0x08000020, 0x08000800, 0x00020820, 0x00020000,
  696. 0x00020820, 0x00020000, 0x08020800, 0x00000800,
  697. 0x00000020, 0x08020020, 0x00000800, 0x00020820,
  698. 0x08000800, 0x00000020, 0x08000020, 0x08020000,
  699. 0x08020020, 0x08000000, 0x00020000, 0x08000820,
  700. 0x00000000, 0x08020820, 0x00020020, 0x08000020,
  701. 0x08020000, 0x08000800, 0x08000820, 0x00000000,
  702. 0x08020820, 0x00020800, 0x00020800, 0x00000820,
  703. 0x00000820, 0x00020020, 0x08000000, 0x08020800
  704. );
  705. /**
  706. * Default Constructor.
  707. *
  708. * Determines whether or not the mcrypt extension should be used. $mode should only, at present, be
  709. * CRYPT_DES_MODE_ECB or CRYPT_DES_MODE_CBC. If not explictly set, CRYPT_DES_MODE_CBC will be used.
  710. *
  711. * @param optional Integer $mode
  712. * @return Crypt_DES
  713. * @access public
  714. */
  715. function Crypt_DES($mode = CRYPT_DES_MODE_CBC)
  716. {
  717. if ( !defined('CRYPT_DES_MODE') ) {
  718. switch (true) {
  719. case extension_loaded('mcrypt') && in_array('des', mcrypt_list_algorithms()):
  720. define('CRYPT_DES_MODE', CRYPT_DES_MODE_MCRYPT);
  721. break;
  722. default:
  723. define('CRYPT_DES_MODE', CRYPT_DES_MODE_INTERNAL);
  724. }
  725. }
  726. switch ( CRYPT_DES_MODE ) {
  727. case CRYPT_DES_MODE_MCRYPT:
  728. switch ($mode) {
  729. case CRYPT_DES_MODE_ECB:
  730. $this->paddable = true;
  731. $this->mode = MCRYPT_MODE_ECB;
  732. break;
  733. case CRYPT_DES_MODE_CTR:
  734. $this->mode = 'ctr';
  735. //$this->mode = in_array('ctr', mcrypt_list_modes()) ? 'ctr' : CRYPT_DES_MODE_CTR;
  736. break;
  737. case CRYPT_DES_MODE_CFB:
  738. $this->mode = 'ncfb';
  739. $this->ecb = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_ECB, '');
  740. break;
  741. case CRYPT_DES_MODE_OFB:
  742. $this->mode = MCRYPT_MODE_NOFB;
  743. break;
  744. case CRYPT_DES_MODE_CBC:
  745. default:
  746. $this->paddable = true;
  747. $this->mode = MCRYPT_MODE_CBC;
  748. }
  749. $this->enmcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
  750. $this->demcrypt = mcrypt_module_open(MCRYPT_DES, '', $this->mode, '');
  751. break;
  752. default:
  753. switch ($mode) {
  754. case CRYPT_DES_MODE_ECB:
  755. case CRYPT_DES_MODE_CBC:
  756. $this->paddable = true;
  757. $this->mode = $mode;
  758. break;
  759. case CRYPT_DES_MODE_CTR:
  760. case CRYPT_DES_MODE_CFB:
  761. case CRYPT_DES_MODE_OFB:
  762. $this->mode = $mode;
  763. break;
  764. default:
  765. $this->paddable = true;
  766. $this->mode = CRYPT_DES_MODE_CBC;
  767. }
  768. if (function_exists('create_function') && is_callable('create_function')) {
  769. $this->inline_crypt_setup();
  770. $this->use_inline_crypt = true;
  771. }
  772. }
  773. }
  774. /**
  775. * Sets the key.
  776. *
  777. * Keys can be of any length. DES, itself, uses 64-bit keys (eg. strlen($key) == 8), however, we
  778. * only use the first eight, if $key has more then eight characters in it, and pad $key with the
  779. * null byte if it is less then eight characters long.
  780. *
  781. * DES also requires that every eighth bit be a parity bit, however, we'll ignore that.
  782. *
  783. * If the key is not explicitly set, it'll be assumed to be all zero's.
  784. *
  785. * @access public
  786. * @param String $key
  787. */
  788. function setKey($key)
  789. {
  790. $this->keys = ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) ? str_pad(substr($key, 0, 8), 8, chr(0)) : $this->_prepareKey($key);
  791. $this->enchanged = true;
  792. $this->dechanged = true;
  793. }
  794. /**
  795. * Sets the password.
  796. *
  797. * Depending on what $method is set to, setPassword()'s (optional) parameters are as follows:
  798. * {@link http://en.wikipedia.org/wiki/PBKDF2 pbkdf2}:
  799. * $hash, $salt, $count
  800. *
  801. * @param String $password
  802. * @param optional String $method
  803. * @access public
  804. */
  805. function setPassword($password, $method = 'pbkdf2')
  806. {
  807. $key = '';
  808. switch ($method) {
  809. default: // 'pbkdf2'
  810. list(, , $hash, $salt, $count) = func_get_args();
  811. if (!isset($hash)) {
  812. $hash = 'sha1';
  813. }
  814. // WPA and WPA2 use the SSID as the salt
  815. if (!isset($salt)) {
  816. $salt = 'phpseclib/salt';
  817. }
  818. // RFC2898#section-4.2 uses 1,000 iterations by default
  819. // WPA and WPA2 use 4,096.
  820. if (!isset($count)) {
  821. $count = 1000;
  822. }
  823. if (!class_exists('Crypt_Hash')) {
  824. require_once('Crypt/Hash.php');
  825. }
  826. $i = 1;
  827. while (strlen($key) < 8) { // $dkLen == 8
  828. //$dk.= $this->_pbkdf($password, $salt, $count, $i++);
  829. $hmac = new Crypt_Hash();
  830. $hmac->setHash($hash);
  831. $hmac->setKey($password);
  832. $f = $u = $hmac->hash($salt . pack('N', $i++));
  833. for ($j = 2; $j <= $count; $j++) {
  834. $u = $hmac->hash($u);
  835. $f^= $u;
  836. }
  837. $key.= $f;
  838. }
  839. }
  840. $this->setKey($key);
  841. }
  842. /**
  843. * Sets the initialization vector. (optional)
  844. *
  845. * SetIV is not required when CRYPT_DES_MODE_ECB is being used. If not explictly set, it'll be assumed
  846. * to be all zero's.
  847. *
  848. * @access public
  849. * @param String $iv
  850. */
  851. function setIV($iv)
  852. {
  853. $this->encryptIV = $this->decryptIV = $this->iv = str_pad(substr($iv, 0, 8), 8, chr(0));
  854. $this->enchanged = true;
  855. $this->dechanged = true;
  856. }
  857. /**
  858. * Generate CTR XOR encryption key
  859. *
  860. * Encrypt the output of this and XOR it against the ciphertext / plaintext to get the
  861. * plaintext / ciphertext in CTR mode.
  862. *
  863. * @see Crypt_DES::decrypt()
  864. * @see Crypt_DES::encrypt()
  865. * @access public
  866. * @param String $iv
  867. */
  868. function _generate_xor(&$iv)
  869. {
  870. $xor = $iv;
  871. for ($j = 4; $j <= 8; $j+=4) {
  872. $temp = substr($iv, -$j, 4);
  873. switch ($temp) {
  874. case "\xFF\xFF\xFF\xFF":
  875. $iv = substr_replace($iv, "\x00\x00\x00\x00", -$j, 4);
  876. break;
  877. case "\x7F\xFF\xFF\xFF":
  878. $iv = substr_replace($iv, "\x80\x00\x00\x00", -$j, 4);
  879. break 2;
  880. default:
  881. // Edit by yeepayMPay
  882. // extract(unpack('Ncount', $temp));
  883. // $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
  884. $_unpack = unpack('Ncount', $temp);
  885. $iv = substr_replace($iv, pack('N', $_unpack['count'] + 1), -$j, 4);
  886. break 2;
  887. }
  888. }
  889. return $xor;
  890. }
  891. /**
  892. * Encrypts a message.
  893. *
  894. * $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
  895. * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
  896. * URL:
  897. *
  898. * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
  899. *
  900. * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
  901. * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
  902. * length.
  903. *
  904. * @see Crypt_DES::decrypt()
  905. * @access public
  906. * @param String $plaintext
  907. */
  908. function encrypt($plaintext)
  909. {
  910. if ($this->paddable) {
  911. $plaintext = $this->_pad($plaintext);
  912. }
  913. if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
  914. if ($this->enchanged) {
  915. mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
  916. if ($this->mode == 'ncfb') {
  917. mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
  918. }
  919. $this->enchanged = false;
  920. }
  921. if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
  922. $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
  923. } else {
  924. $iv = &$this->encryptIV;
  925. $pos = &$this->enbuffer['pos'];
  926. $len = strlen($plaintext);
  927. $ciphertext = '';
  928. $i = 0;
  929. if ($pos) {
  930. $orig_pos = $pos;
  931. $max = 8 - $pos;
  932. if ($len >= $max) {
  933. $i = $max;
  934. $len-= $max;
  935. $pos = 0;
  936. } else {
  937. $i = $len;
  938. $pos+= $len;
  939. $len = 0;
  940. }
  941. $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
  942. $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
  943. $this->enbuffer['enmcrypt_init'] = true;
  944. }
  945. if ($len >= 8) {
  946. if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
  947. if ($this->enbuffer['enmcrypt_init'] === true) {
  948. mcrypt_generic_init($this->enmcrypt, $this->keys, $iv);
  949. $this->enbuffer['enmcrypt_init'] = false;
  950. }
  951. $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));
  952. $iv = substr($ciphertext, -8);
  953. $len%= 8;
  954. } else {
  955. while ($len >= 8) {
  956. $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);
  957. $ciphertext.= $iv;
  958. $len-= 8;
  959. $i+= 8;
  960. }
  961. }
  962. }
  963. if ($len) {
  964. $iv = mcrypt_generic($this->ecb, $iv);
  965. $block = $iv ^ substr($plaintext, -$len);
  966. $iv = substr_replace($iv, $block, 0, $len);
  967. $ciphertext.= $block;
  968. $pos = $len;
  969. }
  970. return $ciphertext;
  971. }
  972. if (!$this->continuousBuffer) {
  973. mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
  974. }
  975. return $ciphertext;
  976. }
  977. if (!is_array($this->keys)) {
  978. $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
  979. }
  980. if ($this->use_inline_crypt) {
  981. $inline = $this->inline_crypt;
  982. return $inline('encrypt', $this, $plaintext);
  983. }
  984. $buffer = &$this->enbuffer;
  985. $continuousBuffer = $this->continuousBuffer;
  986. $ciphertext = '';
  987. switch ($this->mode) {
  988. case CRYPT_DES_MODE_ECB:
  989. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  990. $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
  991. }
  992. break;
  993. case CRYPT_DES_MODE_CBC:
  994. $xor = $this->encryptIV;
  995. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  996. $block = substr($plaintext, $i, 8);
  997. $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
  998. $xor = $block;
  999. $ciphertext.= $block;
  1000. }
  1001. if ($this->continuousBuffer) {
  1002. $this->encryptIV = $xor;
  1003. }
  1004. break;
  1005. case CRYPT_DES_MODE_CTR:
  1006. $xor = $this->encryptIV;
  1007. if (strlen($buffer['encrypted'])) {
  1008. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1009. $block = substr($plaintext, $i, 8);
  1010. if (strlen($block) > strlen($buffer['encrypted'])) {
  1011. $buffer['encrypted'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1012. }
  1013. $key = $this->_string_shift($buffer['encrypted']);
  1014. $ciphertext.= $block ^ $key;
  1015. }
  1016. } else {
  1017. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1018. $block = substr($plaintext, $i, 8);
  1019. $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1020. $ciphertext.= $block ^ $key;
  1021. }
  1022. }
  1023. if ($this->continuousBuffer) {
  1024. $this->encryptIV = $xor;
  1025. // Edit by yeepayMPay
  1026. // if ($start = strlen($plaintext) & 7) {
  1027. $start = strlen($plaintext);
  1028. if ($start & 7) {
  1029. $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];
  1030. }
  1031. }
  1032. break;
  1033. case CRYPT_DES_MODE_CFB:
  1034. if ($this->continuousBuffer) {
  1035. $iv = &$this->encryptIV;
  1036. $pos = &$buffer['pos'];
  1037. } else {
  1038. $iv = $this->encryptIV;
  1039. $pos = 0;
  1040. }
  1041. $len = strlen($plaintext);
  1042. $i = 0;
  1043. if ($pos) {
  1044. $orig_pos = $pos;
  1045. $max = 8 - $pos;
  1046. if ($len >= $max) {
  1047. $i = $max;
  1048. $len-= $max;
  1049. $pos = 0;
  1050. } else {
  1051. $i = $len;
  1052. $pos+= $len;
  1053. $len = 0;
  1054. }
  1055. $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
  1056. $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
  1057. }
  1058. while ($len >= 8) {
  1059. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT) ^ substr($plaintext, $i, 8);
  1060. $ciphertext.= $iv;
  1061. $len-= 8;
  1062. $i+= 8;
  1063. }
  1064. if ($len) {
  1065. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
  1066. $block = $iv ^ substr($plaintext, $i);
  1067. $iv = substr_replace($iv, $block, 0, $len);
  1068. $ciphertext.= $block;
  1069. $pos = $len;
  1070. }
  1071. return $ciphertext;
  1072. case CRYPT_DES_MODE_OFB:
  1073. $xor = $this->encryptIV;
  1074. if (strlen($buffer['xor'])) {
  1075. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1076. $block = substr($plaintext, $i, 8);
  1077. if (strlen($block) > strlen($buffer['xor'])) {
  1078. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1079. $buffer['xor'].= $xor;
  1080. }
  1081. $key = $this->_string_shift($buffer['xor']);
  1082. $ciphertext.= $block ^ $key;
  1083. }
  1084. } else {
  1085. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1086. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1087. $ciphertext.= substr($plaintext, $i, 8) ^ $xor;
  1088. }
  1089. $key = $xor;
  1090. }
  1091. if ($this->continuousBuffer) {
  1092. $this->encryptIV = $xor;
  1093. // Edit by yeepayMPay
  1094. // if ($start = strlen($plaintext) & 7) {
  1095. $start = strlen($plaintext);
  1096. if ($start & 7) {
  1097. $buffer['xor'] = substr($key, $start) . $buffer['xor'];
  1098. }
  1099. }
  1100. }
  1101. return $ciphertext;
  1102. }
  1103. /**
  1104. * Decrypts a message.
  1105. *
  1106. * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
  1107. *
  1108. * @see Crypt_DES::encrypt()
  1109. * @access public
  1110. * @param String $ciphertext
  1111. */
  1112. function decrypt($ciphertext)
  1113. {
  1114. if ($this->paddable) {
  1115. // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
  1116. // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
  1117. $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
  1118. }
  1119. if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
  1120. if ($this->dechanged) {
  1121. mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
  1122. if ($this->mode == 'ncfb') {
  1123. mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
  1124. }
  1125. $this->dechanged = false;
  1126. }
  1127. if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
  1128. $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
  1129. } else {
  1130. $iv = &$this->decryptIV;
  1131. $pos = &$this->debuffer['pos'];
  1132. $len = strlen($ciphertext);
  1133. $plaintext = '';
  1134. $i = 0;
  1135. if ($pos) {
  1136. $orig_pos = $pos;
  1137. $max = 8 - $pos;
  1138. if ($len >= $max) {
  1139. $i = $max;
  1140. $len-= $max;
  1141. $pos = 0;
  1142. } else {
  1143. $i = $len;
  1144. $pos+= $len;
  1145. $len = 0;
  1146. }
  1147. $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
  1148. $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
  1149. }
  1150. if ($len >= 8) {
  1151. $cb = substr($ciphertext, $i, $len - $len % 8);
  1152. $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
  1153. $iv = substr($cb, -8);
  1154. $len%= 8;
  1155. }
  1156. if ($len) {
  1157. $iv = mcrypt_generic($this->ecb, $iv);
  1158. $plaintext.= $iv ^ substr($ciphertext, -$len);
  1159. $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
  1160. $pos = $len;
  1161. }
  1162. return $plaintext;
  1163. }
  1164. if (!$this->continuousBuffer) {
  1165. mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
  1166. }
  1167. return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
  1168. }
  1169. if (!is_array($this->keys)) {
  1170. $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
  1171. }
  1172. if ($this->use_inline_crypt) {
  1173. $inline = $this->inline_crypt;
  1174. return $inline('decrypt', $this, $ciphertext);
  1175. }
  1176. $buffer = &$this->debuffer;
  1177. $continuousBuffer = $this->continuousBuffer;
  1178. $plaintext = '';
  1179. switch ($this->mode) {
  1180. case CRYPT_DES_MODE_ECB:
  1181. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1182. $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
  1183. }
  1184. break;
  1185. case CRYPT_DES_MODE_CBC:
  1186. $xor = $this->decryptIV;
  1187. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1188. $block = substr($ciphertext, $i, 8);
  1189. $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
  1190. $xor = $block;
  1191. }
  1192. if ($this->continuousBuffer) {
  1193. $this->decryptIV = $xor;
  1194. }
  1195. break;
  1196. case CRYPT_DES_MODE_CTR:
  1197. $xor = $this->decryptIV;
  1198. if (strlen($buffer['ciphertext'])) {
  1199. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1200. $block = substr($ciphertext, $i, 8);
  1201. if (strlen($block) > strlen($buffer['ciphertext'])) {
  1202. $buffer['ciphertext'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1203. }
  1204. $key = $this->_string_shift($buffer['ciphertext']);
  1205. $plaintext.= $block ^ $key;
  1206. }
  1207. } else {
  1208. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1209. $block = substr($ciphertext, $i, 8);
  1210. $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1211. $plaintext.= $block ^ $key;
  1212. }
  1213. }
  1214. if ($this->continuousBuffer) {
  1215. $this->decryptIV = $xor;
  1216. // Edit By yeepayMPay
  1217. // if ($start = strlen($ciphertext) % 8) {
  1218. $start = strlen($ciphertext) % 8;
  1219. if($start){
  1220. $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
  1221. }
  1222. }
  1223. break;
  1224. case CRYPT_DES_MODE_CFB:
  1225. if ($this->continuousBuffer) {
  1226. $iv = &$this->decryptIV;
  1227. $pos = &$buffer['pos'];
  1228. } else {
  1229. $iv = $this->decryptIV;
  1230. $pos = 0;
  1231. }
  1232. $len = strlen($ciphertext);
  1233. $i = 0;
  1234. if ($pos) {
  1235. $orig_pos = $pos;
  1236. $max = 8 - $pos;
  1237. if ($len >= $max) {
  1238. $i = $max;
  1239. $len-= $max;
  1240. $pos = 0;
  1241. } else {
  1242. $i = $len;
  1243. $pos+= $len;
  1244. $len = 0;
  1245. }
  1246. $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
  1247. $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
  1248. }
  1249. while ($len >= 8) {
  1250. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
  1251. $cb = substr($ciphertext, $i, 8);
  1252. $plaintext.= $iv ^ $cb;
  1253. $iv = $cb;
  1254. $len-= 8;
  1255. $i+= 8;
  1256. }
  1257. if ($len) {
  1258. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
  1259. $plaintext.= $iv ^ substr($ciphertext, $i);
  1260. $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
  1261. $pos = $len;
  1262. }
  1263. return $plaintext;
  1264. case CRYPT_DES_MODE_OFB:
  1265. $xor = $this->decryptIV;
  1266. if (strlen($buffer['xor'])) {
  1267. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1268. $block = substr($ciphertext, $i, 8);
  1269. if (strlen($block) > strlen($buffer['xor'])) {
  1270. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1271. $buffer['xor'].= $xor;
  1272. }
  1273. $key = $this->_string_shift($buffer['xor']);
  1274. $plaintext.= $block ^ $key;
  1275. }
  1276. } else {
  1277. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1278. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1279. $plaintext.= substr($ciphertext, $i, 8) ^ $xor;
  1280. }
  1281. $key = $xor;
  1282. }
  1283. if ($this->continuousBuffer) {
  1284. $this->decryptIV = $xor;
  1285. // Edity By yeepayMPay
  1286. // if ($start = strlen($ciphertext) % 8) {
  1287. $start = strlen($ciphertext) % 8;
  1288. if($start){
  1289. $buffer['xor'] = substr($key, $start) . $buffer['xor'];
  1290. }
  1291. }
  1292. }
  1293. return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
  1294. }
  1295. /**
  1296. * Treat consecutive "packets" as if they are a continuous buffer.
  1297. *
  1298. * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
  1299. * will yield different outputs:
  1300. *
  1301. * <code>
  1302. * echo $des->encrypt(substr($plaintext, 0, 8));
  1303. * echo $des->encrypt(substr($plaintext, 8, 8));
  1304. * </code>
  1305. * <code>
  1306. * echo $des->encrypt($plaintext);
  1307. * </code>
  1308. *
  1309. * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
  1310. * another, as demonstrated with the following:
  1311. *
  1312. * <code>
  1313. * $des->encrypt(substr($plaintext, 0, 8));
  1314. * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
  1315. * </code>
  1316. * <code>
  1317. * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
  1318. * </code>
  1319. *
  1320. * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
  1321. * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
  1322. * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
  1323. *
  1324. * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
  1325. * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
  1326. * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
  1327. * however, they are also less intuitive and more likely to cause you problems.
  1328. *
  1329. * @see Crypt_DES::disableContinuousBuffer()
  1330. * @access public
  1331. */
  1332. function enableContinuousBuffer()
  1333. {
  1334. $this->continuousBuffer = true;
  1335. }
  1336. /**
  1337. * Treat consecutive packets as if they are a discontinuous buffer.
  1338. *
  1339. * The default behavior.
  1340. *
  1341. * @see Crypt_DES::enableContinuousBuffer()
  1342. * @access public
  1343. */
  1344. function disableContinuousBuffer()
  1345. {
  1346. $this->continuousBuffer = false;
  1347. $this->encryptIV = $this->iv;
  1348. $this->decryptIV = $this->iv;
  1349. $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
  1350. $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
  1351. if (CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT) {
  1352. mcrypt_generic_init($this->enmcrypt, $this->keys, $this->iv);
  1353. mcrypt_generic_init($this->demcrypt, $this->keys, $this->iv);
  1354. }
  1355. }
  1356. /**
  1357. * Pad "packets".
  1358. *
  1359. * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
  1360. * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
  1361. *
  1362. * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
  1363. * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
  1364. * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
  1365. * transmitted separately)
  1366. *
  1367. * @see Crypt_DES::disablePadding()
  1368. * @access public
  1369. */
  1370. function enablePadding()
  1371. {
  1372. $this->padding = true;
  1373. }
  1374. /**
  1375. * Do not pad packets.
  1376. *
  1377. * @see Crypt_DES::enablePadding()
  1378. * @access public
  1379. */
  1380. function disablePadding()
  1381. {
  1382. $this->padding = false;
  1383. }
  1384. /**
  1385. * Pads a string
  1386. *
  1387. * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
  1388. * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
  1389. *
  1390. * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
  1391. * and padding will, hence forth, be enabled.
  1392. *
  1393. * @see Crypt_DES::_unpad()
  1394. * @access private
  1395. */
  1396. function _pad($text)
  1397. {
  1398. $length = strlen($text);
  1399. if (!$this->padding) {
  1400. if (($length & 7) == 0) {
  1401. return $text;
  1402. } else {
  1403. user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
  1404. $this->padding = true;
  1405. }
  1406. }
  1407. $pad = 8 - ($length & 7);
  1408. return str_pad($text, $length + $pad, chr($pad));
  1409. }
  1410. /**
  1411. * Unpads a string
  1412. *
  1413. * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
  1414. * and false will be returned.
  1415. *
  1416. * @see Crypt_DES::_pad()
  1417. * @access private
  1418. */
  1419. function _unpad($text)
  1420. {
  1421. if (!$this->padding) {
  1422. return $text;
  1423. }
  1424. $length = ord($text[strlen($text) - 1]);
  1425. if (!$length || $length > 8) {
  1426. return false;
  1427. }
  1428. return substr($text, 0, -$length);
  1429. }
  1430. /**
  1431. * Encrypts or decrypts a 64-bit block
  1432. *
  1433. * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
  1434. * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
  1435. * idea of what this function does.
  1436. *
  1437. * @access private
  1438. * @param String $block
  1439. * @param Integer $mode
  1440. * @return String
  1441. */
  1442. function _processBlock($block, $mode)
  1443. {
  1444. $shuffle = $this->shuffle;
  1445. $invipmap = $this->invipmap;
  1446. $ipmap = $this->ipmap;
  1447. $sbox1 = $this->sbox1;
  1448. $sbox2 = $this->sbox2;
  1449. $sbox3 = $this->sbox3;
  1450. $sbox4 = $this->sbox4;
  1451. $sbox5 = $this->sbox5;
  1452. $sbox6 = $this->sbox6;
  1453. $sbox7 = $this->sbox7;
  1454. $sbox8 = $this->sbox8;
  1455. $keys = $this->keys[$mode];
  1456. // Do the initial IP permutation.
  1457. $t = unpack('Nl/Nr', $block);
  1458. list($l, $r) = array($t['l'], $t['r']);
  1459. $block = ($shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  1460. ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  1461. ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  1462. ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  1463. ($shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  1464. ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  1465. ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  1466. ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
  1467. // Extract L0 and R0.
  1468. $t = unpack('Nl/Nr', $block);
  1469. list($l, $r) = array($t['l'], $t['r']);
  1470. // Perform the 16 steps.
  1471. for ($i = 0; $i < 16; $i++) {
  1472. // start of "the Feistel (F) function" - see the following URL:
  1473. // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
  1474. // Merge key schedule.
  1475. $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[$i][0];
  1476. $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[$i][1];
  1477. // S-box indexing.
  1478. $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
  1479. $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
  1480. $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
  1481. $sbox7[$b1 & 0x3F] ^ $sbox8[$b2 & 0x3F] ^ $l;
  1482. // end of "the Feistel (F) function"
  1483. $l = $r;
  1484. $r = $t;
  1485. }
  1486. // Perform the inverse IP permutation.
  1487. return ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  1488. ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  1489. ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  1490. ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  1491. ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  1492. ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  1493. ($shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  1494. ($shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
  1495. }
  1496. /**
  1497. * Creates the key schedule.
  1498. *
  1499. * @access private
  1500. * @param String $key
  1501. * @return Array
  1502. */
  1503. function _prepareKey($key)
  1504. {
  1505. static $shifts = array( // number of key bits shifted per round
  1506. 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
  1507. );
  1508. static $pc1map = array(
  1509. 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
  1510. 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
  1511. 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
  1512. 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
  1513. 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
  1514. 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
  1515. 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
  1516. 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
  1517. 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
  1518. 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
  1519. 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
  1520. 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
  1521. 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
  1522. 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
  1523. 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
  1524. 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
  1525. 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
  1526. 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
  1527. 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
  1528. 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
  1529. 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
  1530. 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
  1531. 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
  1532. 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
  1533. 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
  1534. 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
  1535. 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
  1536. 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
  1537. 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
  1538. 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
  1539. 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
  1540. 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
  1541. );
  1542. // Mapping tables for the PC-2 transformation.
  1543. static $pc2mapc1 = array(
  1544. 0x00000000, 0x00000400, 0x00200000, 0x00200400,
  1545. 0x00000001, 0x00000401, 0x00200001, 0x00200401,
  1546. 0x02000000, 0x02000400, 0x02200000, 0x02200400,
  1547. 0x02000001, 0x02000401, 0x02200001, 0x02200401
  1548. );
  1549. static $pc2mapc2 = array(
  1550. 0x00000000, 0x00000800, 0x08000000, 0x08000800,
  1551. 0x00010000, 0x00010800, 0x08010000, 0x08010800,
  1552. 0x00000000, 0x00000800, 0x08000000, 0x08000800,
  1553. 0x00010000, 0x00010800, 0x08010000, 0x08010800,
  1554. 0x00000100, 0x00000900, 0x08000100, 0x08000900,
  1555. 0x00010100, 0x00010900, 0x08010100, 0x08010900,
  1556. 0x00000100, 0x00000900, 0x08000100, 0x08000900,
  1557. 0x00010100, 0x00010900, 0x08010100, 0x08010900,
  1558. 0x00000010, 0x00000810, 0x08000010, 0x08000810,
  1559. 0x00010010, 0x00010810, 0x08010010, 0x08010810,
  1560. 0x00000010, 0x00000810, 0x08000010, 0x08000810,
  1561. 0x00010010, 0x00010810, 0x08010010, 0x08010810,
  1562. 0x00000110, 0x00000910, 0x08000110, 0x08000910,
  1563. 0x00010110, 0x00010910, 0x08010110, 0x08010910,
  1564. 0x00000110, 0x00000910, 0x08000110, 0x08000910,
  1565. 0x00010110, 0x00010910, 0x08010110, 0x08010910,
  1566. 0x00040000, 0x00040800, 0x08040000, 0x08040800,
  1567. 0x00050000, 0x00050800, 0x08050000, 0x08050800,
  1568. 0x00040000, 0x00040800, 0x08040000, 0x08040800,
  1569. 0x00050000, 0x00050800, 0x08050000, 0x08050800,
  1570. 0x00040100, 0x00040900, 0x08040100, 0x08040900,
  1571. 0x00050100, 0x00050900, 0x08050100, 0x08050900,
  1572. 0x00040100, 0x00040900, 0x08040100, 0x08040900,
  1573. 0x00050100, 0x00050900, 0x08050100, 0x08050900,
  1574. 0x00040010, 0x00040810, 0x08040010, 0x08040810,
  1575. 0x00050010, 0x00050810, 0x08050010, 0x08050810,
  1576. 0x00040010, 0x00040810, 0x08040010, 0x08040810,
  1577. 0x00050010, 0x00050810, 0x08050010, 0x08050810,
  1578. 0x00040110, 0x00040910, 0x08040110, 0x08040910,
  1579. 0x00050110, 0x00050910, 0x08050110, 0x08050910,
  1580. 0x00040110, 0x00040910, 0x08040110, 0x08040910,
  1581. 0x00050110, 0x00050910, 0x08050110, 0x08050910,
  1582. 0x01000000, 0x01000800, 0x09000000, 0x09000800,
  1583. 0x01010000, 0x01010800, 0x09010000, 0x09010800,
  1584. 0x01000000, 0x01000800, 0x09000000, 0x09000800,
  1585. 0x01010000, 0x01010800, 0x09010000, 0x09010800,
  1586. 0x01000100, 0x01000900, 0x09000100, 0x09000900,
  1587. 0x01010100, 0x01010900, 0x09010100, 0x09010900,
  1588. 0x01000100, 0x01000900, 0x09000100, 0x09000900,
  1589. 0x01010100, 0x01010900, 0x09010100, 0x09010900,
  1590. 0x01000010, 0x01000810, 0x09000010, 0x09000810,
  1591. 0x01010010, 0x01010810, 0x09010010, 0x09010810,
  1592. 0x01000010, 0x01000810, 0x09000010, 0x09000810,
  1593. 0x01010010, 0x01010810, 0x09010010, 0x09010810,
  1594. 0x01000110, 0x01000910, 0x09000110, 0x09000910,
  1595. 0x01010110, 0x01010910, 0x09010110, 0x09010910,
  1596. 0x01000110, 0x01000910, 0x09000110, 0x09000910,
  1597. 0x01010110, 0x01010910, 0x09010110, 0x09010910,
  1598. 0x01040000, 0x01040800, 0x09040000, 0x09040800,
  1599. 0x01050000, 0x01050800, 0x09050000, 0x09050800,
  1600. 0x01040000, 0x01040800, 0x09040000, 0x09040800,
  1601. 0x01050000, 0x01050800, 0x09050000, 0x09050800,
  1602. 0x01040100, 0x01040900, 0x09040100, 0x09040900,
  1603. 0x01050100, 0x01050900, 0x09050100, 0x09050900,
  1604. 0x01040100, 0x01040900, 0x09040100, 0x09040900,
  1605. 0x01050100, 0x01050900, 0x09050100, 0x09050900,
  1606. 0x01040010, 0x01040810, 0x09040010, 0x09040810,
  1607. 0x01050010, 0x01050810, 0x09050010, 0x09050810,
  1608. 0x01040010, 0x01040810, 0x09040010, 0x09040810,
  1609. 0x01050010, 0x01050810, 0x09050010, 0x09050810,
  1610. 0x01040110, 0x01040910, 0x09040110, 0x09040910,
  1611. 0x01050110, 0x01050910, 0x09050110, 0x09050910,
  1612. 0x01040110, 0x01040910, 0x09040110, 0x09040910,
  1613. 0x01050110, 0x01050910, 0x09050110, 0x09050910
  1614. );
  1615. static $pc2mapc3 = array(
  1616. 0x00000000, 0x00000004, 0x00001000, 0x00001004,
  1617. 0x00000000, 0x00000004, 0x00001000, 0x00001004,
  1618. 0x10000000, 0x10000004, 0x10001000, 0x10001004,
  1619. 0x10000000, 0x10000004, 0x10001000, 0x10001004,
  1620. 0x00000020, 0x00000024, 0x00001020, 0x00001024,
  1621. 0x00000020, 0x00000024, 0x00001020, 0x00001024,
  1622. 0x10000020, 0x10000024, 0x10001020, 0x10001024,
  1623. 0x10000020, 0x10000024, 0x10001020, 0x10001024,
  1624. 0x00080000, 0x00080004, 0x00081000, 0x00081004,
  1625. 0x00080000, 0x00080004, 0x00081000, 0x00081004,
  1626. 0x10080000, 0x10080004, 0x10081000, 0x10081004,
  1627. 0x10080000, 0x10080004, 0x10081000, 0x10081004,
  1628. 0x00080020, 0x00080024, 0x00081020, 0x00081024,
  1629. 0x00080020, 0x00080024, 0x00081020, 0x00081024,
  1630. 0x10080020, 0x10080024, 0x10081020, 0x10081024,
  1631. 0x10080020, 0x10080024, 0x10081020, 0x10081024,
  1632. 0x20000000, 0x20000004, 0x20001000, 0x20001004,
  1633. 0x20000000, 0x20000004, 0x20001000, 0x20001004,
  1634. 0x30000000, 0x30000004, 0x30001000, 0x30001004,
  1635. 0x30000000, 0x30000004, 0x30001000, 0x30001004,
  1636. 0x20000020, 0x20000024, 0x20001020, 0x20001024,
  1637. 0x20000020, 0x20000024, 0x20001020, 0x20001024,
  1638. 0x30000020, 0x30000024, 0x30001020, 0x30001024,
  1639. 0x30000020, 0x30000024, 0x30001020, 0x30001024,
  1640. 0x20080000, 0x20080004, 0x20081000, 0x20081004,
  1641. 0x20080000, 0x20080004, 0x20081000, 0x20081004,
  1642. 0x30080000, 0x30080004, 0x30081000, 0x30081004,
  1643. 0x30080000, 0x30080004, 0x30081000, 0x30081004,
  1644. 0x20080020, 0x20080024, 0x20081020, 0x20081024,
  1645. 0x20080020, 0x20080024, 0x20081020, 0x20081024,
  1646. 0x30080020, 0x30080024, 0x30081020, 0x30081024,
  1647. 0x30080020, 0x30080024, 0x30081020, 0x30081024,
  1648. 0x00000002, 0x00000006, 0x00001002, 0x00001006,
  1649. 0x00000002, 0x00000006, 0x00001002, 0x00001006,
  1650. 0x10000002, 0x10000006, 0x10001002, 0x10001006,
  1651. 0x10000002, 0x10000006, 0x10001002, 0x10001006,
  1652. 0x00000022, 0x00000026, 0x00001022, 0x00001026,
  1653. 0x00000022, 0x00000026, 0x00001022, 0x00001026,
  1654. 0x10000022, 0x10000026, 0x10001022, 0x10001026,
  1655. 0x10000022, 0x10000026, 0x10001022, 0x10001026,
  1656. 0x00080002, 0x00080006, 0x00081002, 0x00081006,
  1657. 0x00080002, 0x00080006, 0x00081002, 0x00081006,
  1658. 0x10080002, 0x10080006, 0x10081002, 0x10081006,
  1659. 0x10080002, 0x10080006, 0x10081002, 0x10081006,
  1660. 0x00080022, 0x00080026, 0x00081022, 0x00081026,
  1661. 0x00080022, 0x00080026, 0x00081022, 0x00081026,
  1662. 0x10080022, 0x10080026, 0x10081022, 0x10081026,
  1663. 0x10080022, 0x10080026, 0x10081022, 0x10081026,
  1664. 0x20000002, 0x20000006, 0x20001002, 0x20001006,
  1665. 0x20000002, 0x20000006, 0x20001002, 0x20001006,
  1666. 0x30000002, 0x30000006, 0x30001002, 0x30001006,
  1667. 0x30000002, 0x30000006, 0x30001002, 0x30001006,
  1668. 0x20000022, 0x20000026, 0x20001022, 0x20001026,
  1669. 0x20000022, 0x20000026, 0x20001022, 0x20001026,
  1670. 0x30000022, 0x30000026, 0x30001022, 0x30001026,
  1671. 0x30000022, 0x30000026, 0x30001022, 0x30001026,
  1672. 0x20080002, 0x20080006, 0x20081002, 0x20081006,
  1673. 0x20080002, 0x20080006, 0x20081002, 0x20081006,
  1674. 0x30080002, 0x30080006, 0x30081002, 0x30081006,
  1675. 0x30080002, 0x30080006, 0x30081002, 0x30081006,
  1676. 0x20080022, 0x20080026, 0x20081022, 0x20081026,
  1677. 0x20080022, 0x20080026, 0x20081022, 0x20081026,
  1678. 0x30080022, 0x30080026, 0x30081022, 0x30081026,
  1679. 0x30080022, 0x30080026, 0x30081022, 0x30081026
  1680. );
  1681. static $pc2mapc4 = array(
  1682. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1683. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1684. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1685. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1686. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1687. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1688. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1689. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1690. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1691. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1692. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1693. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1694. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1695. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1696. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1697. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1698. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1699. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1700. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1701. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1702. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1703. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1704. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1705. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1706. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1707. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1708. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1709. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1710. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1711. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1712. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1713. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1714. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1715. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1716. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1717. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1718. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1719. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1720. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1721. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1722. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1723. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1724. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1725. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1726. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1727. 0x04022200, 0x04122200, 0x04022208, 0x04122208,
  1728. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1729. 0x04022200, 0x04122200, 0x04022208, 0x04122208,
  1730. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1731. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1732. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1733. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1734. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1735. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1736. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1737. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1738. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1739. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1740. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1741. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1742. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1743. 0x04022200, 0x04122200, 0x04022208, 0x04122208,
  1744. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1745. 0x04022200, 0x04122200, 0x04022208, 0x04122208
  1746. );
  1747. static $pc2mapd1 = array(
  1748. 0x00000000, 0x00000001, 0x08000000, 0x08000001,
  1749. 0x00200000, 0x00200001, 0x08200000, 0x08200001,
  1750. 0x00000002, 0x00000003, 0x08000002, 0x08000003,
  1751. 0x00200002, 0x00200003, 0x08200002, 0x08200003
  1752. );
  1753. static $pc2mapd2 = array(
  1754. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1755. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1756. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1757. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1758. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1759. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1760. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1761. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1762. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1763. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1764. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1765. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1766. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1767. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1768. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1769. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1770. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1771. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1772. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1773. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1774. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1775. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1776. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1777. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1778. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1779. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1780. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1781. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1782. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1783. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1784. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1785. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1786. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1787. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1788. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1789. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1790. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1791. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1792. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1793. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1794. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1795. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1796. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1797. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1798. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1799. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1800. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1801. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1802. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1803. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1804. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1805. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1806. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1807. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1808. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
  1809. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
  1810. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1811. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1812. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1813. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1814. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1815. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1816. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
  1817. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04
  1818. );
  1819. static $pc2mapd3 = array(
  1820. 0x00000000, 0x00010000, 0x02000000, 0x02010000,
  1821. 0x00000020, 0x00010020, 0x02000020, 0x02010020,
  1822. 0x00040000, 0x00050000, 0x02040000, 0x02050000,
  1823. 0x00040020, 0x00050020, 0x02040020, 0x02050020,
  1824. 0x00002000, 0x00012000, 0x02002000, 0x02012000,
  1825. 0x00002020, 0x00012020, 0x02002020, 0x02012020,
  1826. 0x00042000, 0x00052000, 0x02042000, 0x02052000,
  1827. 0x00042020, 0x00052020, 0x02042020, 0x02052020,
  1828. 0x00000000, 0x00010000, 0x02000000, 0x02010000,
  1829. 0x00000020, 0x00010020, 0x02000020, 0x02010020,
  1830. 0x00040000, 0x00050000, 0x02040000, 0x02050000,
  1831. 0x00040020, 0x00050020, 0x02040020, 0x02050020,
  1832. 0x00002000, 0x00012000, 0x02002000, 0x02012000,
  1833. 0x00002020, 0x00012020, 0x02002020, 0x02012020,
  1834. 0x00042000, 0x00052000, 0x02042000, 0x02052000,
  1835. 0x00042020, 0x00052020, 0x02042020, 0x02052020,
  1836. 0x00000010, 0x00010010, 0x02000010, 0x02010010,
  1837. 0x00000030, 0x00010030, 0x02000030, 0x02010030,
  1838. 0x00040010, 0x00050010, 0x02040010, 0x02050010,
  1839. 0x00040030, 0x00050030, 0x02040030, 0x02050030,
  1840. 0x00002010, 0x00012010, 0x02002010, 0x02012010,
  1841. 0x00002030, 0x00012030, 0x02002030, 0x02012030,
  1842. 0x00042010, 0x00052010, 0x02042010, 0x02052010,
  1843. 0x00042030, 0x00052030, 0x02042030, 0x02052030,
  1844. 0x00000010, 0x00010010, 0x02000010, 0x02010010,
  1845. 0x00000030, 0x00010030, 0x02000030, 0x02010030,
  1846. 0x00040010, 0x00050010, 0x02040010, 0x02050010,
  1847. 0x00040030, 0x00050030, 0x02040030, 0x02050030,
  1848. 0x00002010, 0x00012010, 0x02002010, 0x02012010,
  1849. 0x00002030, 0x00012030, 0x02002030, 0x02012030,
  1850. 0x00042010, 0x00052010, 0x02042010, 0x02052010,
  1851. 0x00042030, 0x00052030, 0x02042030, 0x02052030,
  1852. 0x20000000, 0x20010000, 0x22000000, 0x22010000,
  1853. 0x20000020, 0x20010020, 0x22000020, 0x22010020,
  1854. 0x20040000, 0x20050000, 0x22040000, 0x22050000,
  1855. 0x20040020, 0x20050020, 0x22040020, 0x22050020,
  1856. 0x20002000, 0x20012000, 0x22002000, 0x22012000,
  1857. 0x20002020, 0x20012020, 0x22002020, 0x22012020,
  1858. 0x20042000, 0x20052000, 0x22042000, 0x22052000,
  1859. 0x20042020, 0x20052020, 0x22042020, 0x22052020,
  1860. 0x20000000, 0x20010000, 0x22000000, 0x22010000,
  1861. 0x20000020, 0x20010020, 0x22000020, 0x22010020,
  1862. 0x20040000, 0x20050000, 0x22040000, 0x22050000,
  1863. 0x20040020, 0x20050020, 0x22040020, 0x22050020,
  1864. 0x20002000, 0x20012000, 0x22002000, 0x22012000,
  1865. 0x20002020, 0x20012020, 0x22002020, 0x22012020,
  1866. 0x20042000, 0x20052000, 0x22042000, 0x22052000,
  1867. 0x20042020, 0x20052020, 0x22042020, 0x22052020,
  1868. 0x20000010, 0x20010010, 0x22000010, 0x22010010,
  1869. 0x20000030, 0x20010030, 0x22000030, 0x22010030,
  1870. 0x20040010, 0x20050010, 0x22040010, 0x22050010,
  1871. 0x20040030, 0x20050030, 0x22040030, 0x22050030,
  1872. 0x20002010, 0x20012010, 0x22002010, 0x22012010,
  1873. 0x20002030, 0x20012030, 0x22002030, 0x22012030,
  1874. 0x20042010, 0x20052010, 0x22042010, 0x22052010,
  1875. 0x20042030, 0x20052030, 0x22042030, 0x22052030,
  1876. 0x20000010, 0x20010010, 0x22000010, 0x22010010,
  1877. 0x20000030, 0x20010030, 0x22000030, 0x22010030,
  1878. 0x20040010, 0x20050010, 0x22040010, 0x22050010,
  1879. 0x20040030, 0x20050030, 0x22040030, 0x22050030,
  1880. 0x20002010, 0x20012010, 0x22002010, 0x22012010,
  1881. 0x20002030, 0x20012030, 0x22002030, 0x22012030,
  1882. 0x20042010, 0x20052010, 0x22042010, 0x22052010,
  1883. 0x20042030, 0x20052030, 0x22042030, 0x22052030
  1884. );
  1885. static $pc2mapd4 = array(
  1886. 0x00000000, 0x00000400, 0x01000000, 0x01000400,
  1887. 0x00000000, 0x00000400, 0x01000000, 0x01000400,
  1888. 0x00000100, 0x00000500, 0x01000100, 0x01000500,
  1889. 0x00000100, 0x00000500, 0x01000100, 0x01000500,
  1890. 0x10000000, 0x10000400, 0x11000000, 0x11000400,
  1891. 0x10000000, 0x10000400, 0x11000000, 0x11000400,
  1892. 0x10000100, 0x10000500, 0x11000100, 0x11000500,
  1893. 0x10000100, 0x10000500, 0x11000100, 0x11000500,
  1894. 0x00080000, 0x00080400, 0x01080000, 0x01080400,
  1895. 0x00080000, 0x00080400, 0x01080000, 0x01080400,
  1896. 0x00080100, 0x00080500, 0x01080100, 0x01080500,
  1897. 0x00080100, 0x00080500, 0x01080100, 0x01080500,
  1898. 0x10080000, 0x10080400, 0x11080000, 0x11080400,
  1899. 0x10080000, 0x10080400, 0x11080000, 0x11080400,
  1900. 0x10080100, 0x10080500, 0x11080100, 0x11080500,
  1901. 0x10080100, 0x10080500, 0x11080100, 0x11080500,
  1902. 0x00000008, 0x00000408, 0x01000008, 0x01000408,
  1903. 0x00000008, 0x00000408, 0x01000008, 0x01000408,
  1904. 0x00000108, 0x00000508, 0x01000108, 0x01000508,
  1905. 0x00000108, 0x00000508, 0x01000108, 0x01000508,
  1906. 0x10000008, 0x10000408, 0x11000008, 0x11000408,
  1907. 0x10000008, 0x10000408, 0x11000008, 0x11000408,
  1908. 0x10000108, 0x10000508, 0x11000108, 0x11000508,
  1909. 0x10000108, 0x10000508, 0x11000108, 0x11000508,
  1910. 0x00080008, 0x00080408, 0x01080008, 0x01080408,
  1911. 0x00080008, 0x00080408, 0x01080008, 0x01080408,
  1912. 0x00080108, 0x00080508, 0x01080108, 0x01080508,
  1913. 0x00080108, 0x00080508, 0x01080108, 0x01080508,
  1914. 0x10080008, 0x10080408, 0x11080008, 0x11080408,
  1915. 0x10080008, 0x10080408, 0x11080008, 0x11080408,
  1916. 0x10080108, 0x10080508, 0x11080108, 0x11080508,
  1917. 0x10080108, 0x10080508, 0x11080108, 0x11080508,
  1918. 0x00001000, 0x00001400, 0x01001000, 0x01001400,
  1919. 0x00001000, 0x00001400, 0x01001000, 0x01001400,
  1920. 0x00001100, 0x00001500, 0x01001100, 0x01001500,
  1921. 0x00001100, 0x00001500, 0x01001100, 0x01001500,
  1922. 0x10001000, 0x10001400, 0x11001000, 0x11001400,
  1923. 0x10001000, 0x10001400, 0x11001000, 0x11001400,
  1924. 0x10001100, 0x10001500, 0x11001100, 0x11001500,
  1925. 0x10001100, 0x10001500, 0x11001100, 0x11001500,
  1926. 0x00081000, 0x00081400, 0x01081000, 0x01081400,
  1927. 0x00081000, 0x00081400, 0x01081000, 0x01081400,
  1928. 0x00081100, 0x00081500, 0x01081100, 0x01081500,
  1929. 0x00081100, 0x00081500, 0x01081100, 0x01081500,
  1930. 0x10081000, 0x10081400, 0x11081000, 0x11081400,
  1931. 0x10081000, 0x10081400, 0x11081000, 0x11081400,
  1932. 0x10081100, 0x10081500, 0x11081100, 0x11081500,
  1933. 0x10081100, 0x10081500, 0x11081100, 0x11081500,
  1934. 0x00001008, 0x00001408, 0x01001008, 0x01001408,
  1935. 0x00001008, 0x00001408, 0x01001008, 0x01001408,
  1936. 0x00001108, 0x00001508, 0x01001108, 0x01001508,
  1937. 0x00001108, 0x00001508, 0x01001108, 0x01001508,
  1938. 0x10001008, 0x10001408, 0x11001008, 0x11001408,
  1939. 0x10001008, 0x10001408, 0x11001008, 0x11001408,
  1940. 0x10001108, 0x10001508, 0x11001108, 0x11001508,
  1941. 0x10001108, 0x10001508, 0x11001108, 0x11001508,
  1942. 0x00081008, 0x00081408, 0x01081008, 0x01081408,
  1943. 0x00081008, 0x00081408, 0x01081008, 0x01081408,
  1944. 0x00081108, 0x00081508, 0x01081108, 0x01081508,
  1945. 0x00081108, 0x00081508, 0x01081108, 0x01081508,
  1946. 0x10081008, 0x10081408, 0x11081008, 0x11081408,
  1947. 0x10081008, 0x10081408, 0x11081008, 0x11081408,
  1948. 0x10081108, 0x10081508, 0x11081108, 0x11081508,
  1949. 0x10081108, 0x10081508, 0x11081108, 0x11081508
  1950. );
  1951. // pad the key and remove extra characters as appropriate.
  1952. $key = str_pad(substr($key, 0, 8), 8, chr(0));
  1953. // Perform the PC/1 transformation and compute C and D.
  1954. $t = unpack('Nl/Nr', $key);
  1955. list($l, $r) = array($t['l'], $t['r']);
  1956. $key = ($this->shuffle[$pc1map[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
  1957. ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
  1958. ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
  1959. ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
  1960. ($this->shuffle[$pc1map[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
  1961. ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
  1962. ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
  1963. ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
  1964. $key = unpack('Nc/Nd', $key);
  1965. $c = ($key['c'] >> 4) & 0x0FFFFFFF;
  1966. $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
  1967. $keys = array();
  1968. for ($i = 0; $i < 16; $i++) {
  1969. $c <<= $shifts[$i];
  1970. $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
  1971. $d <<= $shifts[$i];
  1972. $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
  1973. // Perform the PC-2 transformation.
  1974. $cp = $pc2mapc1[$c >> 24] | $pc2mapc2[($c >> 16) & 0xFF] |
  1975. $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[$c & 0xFF];
  1976. $dp = $pc2mapd1[$d >> 24] | $pc2mapd2[($d >> 16) & 0xFF] |
  1977. $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[$d & 0xFF];
  1978. // Reorder: odd bytes/even bytes. Push the result in key schedule.
  1979. $keys[] = array(
  1980. ($cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
  1981. (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF),
  1982. (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
  1983. (($dp >> 8) & 0x0000FF00) | ($dp & 0x000000FF)
  1984. );
  1985. }
  1986. $keys = array(
  1987. CRYPT_DES_ENCRYPT => $keys,
  1988. CRYPT_DES_DECRYPT => array_reverse($keys),
  1989. CRYPT_DES_ENCRYPT_1DIM => array(),
  1990. CRYPT_DES_DECRYPT_1DIM => array()
  1991. );
  1992. // Generate 1-dim arrays for inline en/decrypting
  1993. for ($i = 0; $i < 16; ++$i) {
  1994. $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][0];
  1995. $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][1];
  1996. $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][0];
  1997. $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][1];
  1998. }
  1999. return $keys;
  2000. }
  2001. /**
  2002. * String Shift
  2003. *
  2004. * Inspired by array_shift
  2005. *
  2006. * @param String $string
  2007. * @return String
  2008. * @access private
  2009. */
  2010. function _string_shift(&$string)
  2011. {
  2012. $substr = substr($string, 0, 8);
  2013. $string = substr($string, 8);
  2014. return $substr;
  2015. }
  2016. /**
  2017. * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
  2018. *
  2019. * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES)
  2020. * @access private
  2021. */
  2022. function inline_crypt_setup($des_rounds = 1)
  2023. {
  2024. $lambda_functions =& Crypt_DES::get_lambda_functions();
  2025. $block_size = 8;
  2026. $mode = $this->mode;
  2027. $code_hash = "$mode,$des_rounds";
  2028. if (!isset($lambda_functions[$code_hash])) {
  2029. // Generating encrypt code:
  2030. $ki = -1;
  2031. $init_cryptBlock = '
  2032. $shuffle = $self->shuffle;
  2033. $invipmap = $self->invipmap;
  2034. $ipmap = $self->ipmap;
  2035. $sbox1 = $self->sbox1;
  2036. $sbox2 = $self->sbox2;
  2037. $sbox3 = $self->sbox3;
  2038. $sbox4 = $self->sbox4;
  2039. $sbox5 = $self->sbox5;
  2040. $sbox6 = $self->sbox6;
  2041. $sbox7 = $self->sbox7;
  2042. $sbox8 = $self->sbox8;
  2043. ';
  2044. $_cryptBlock = '$in = unpack("N*", $in);'."\n";
  2045. // Do the initial IP permutation.
  2046. $_cryptBlock .= '
  2047. $l = $in[1];
  2048. $r = $in[2];
  2049. $in = unpack("N*",
  2050. ($shuffle[$ipmap[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  2051. ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  2052. ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  2053. ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  2054. ($shuffle[$ipmap[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  2055. ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  2056. ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  2057. ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
  2058. );
  2059. '.'' /* Extract L0 and R0 */ .'
  2060. $l = $in[1];
  2061. $r = $in[2];
  2062. ';
  2063. $l = 'l';
  2064. $r = 'r';
  2065. for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
  2066. // Perform the 16 steps.
  2067. // start of "the Feistel (F) function" - see the following URL:
  2068. // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
  2069. // Merge key schedule.
  2070. for ($i = 0; $i < 8; ++$i) {
  2071. $_cryptBlock .= '
  2072. $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).';
  2073. $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_'.(++$ki).';
  2074. $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
  2075. $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
  2076. $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
  2077. $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . ';
  2078. $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).';
  2079. $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_'.(++$ki).';
  2080. $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
  2081. $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
  2082. $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
  2083. $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . ';
  2084. ';
  2085. }
  2086. // Last step should not permute L & R.
  2087. $t = $l;
  2088. $l = $r;
  2089. $r = $t;
  2090. }
  2091. // Perform the inverse IP permutation.
  2092. $_cryptBlock .= '$in = (
  2093. ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  2094. ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  2095. ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  2096. ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  2097. ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  2098. ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  2099. ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  2100. ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
  2101. );
  2102. ';
  2103. // Generating mode of operation code:
  2104. switch ($mode) {
  2105. case CRYPT_DES_MODE_ECB:
  2106. $encrypt = $init_cryptBlock . '
  2107. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2108. $ciphertext = "";
  2109. $plaintext_len = strlen($text);
  2110. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2111. $in = substr($text, $i, '.$block_size.');
  2112. '.$_cryptBlock.'
  2113. $ciphertext.= $in;
  2114. }
  2115. return $ciphertext;
  2116. ';
  2117. $decrypt = $init_cryptBlock . '
  2118. extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2119. $plaintext = "";
  2120. $ciphertext_len = strlen($text);
  2121. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2122. $in = substr($text, $i, '.$block_size.');
  2123. '.$_cryptBlock.'
  2124. $plaintext.= $in;
  2125. }
  2126. return $self->_unpad($plaintext);
  2127. ';
  2128. break;
  2129. case CRYPT_DES_MODE_CBC:
  2130. $encrypt = $init_cryptBlock . '
  2131. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2132. $ciphertext = "";
  2133. $plaintext_len = strlen($text);
  2134. $in = $self->encryptIV;
  2135. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2136. $in = substr($text, $i, '.$block_size.') ^ $in;
  2137. '.$_cryptBlock.'
  2138. $ciphertext.= $in;
  2139. }
  2140. if ($self->continuousBuffer) {
  2141. $self->encryptIV = $in;
  2142. }
  2143. return $ciphertext;
  2144. ';
  2145. $decrypt = $init_cryptBlock . '
  2146. extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2147. $plaintext = "";
  2148. $ciphertext_len = strlen($text);
  2149. $iv = $self->decryptIV;
  2150. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2151. $in = $block = substr($text, $i, '.$block_size.');
  2152. '.$_cryptBlock.'
  2153. $plaintext.= $in ^ $iv;
  2154. $iv = $block;
  2155. }
  2156. if ($self->continuousBuffer) {
  2157. $self->decryptIV = $iv;
  2158. }
  2159. return $self->_unpad($plaintext);
  2160. ';
  2161. break;
  2162. case CRYPT_DES_MODE_CTR:
  2163. $encrypt = $init_cryptBlock . '
  2164. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2165. $ciphertext = "";
  2166. $plaintext_len = strlen($text);
  2167. $xor = $self->encryptIV;
  2168. $buffer = &$self->enbuffer;
  2169. if (strlen($buffer["encrypted"])) {
  2170. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2171. $block = substr($text, $i, '.$block_size.');
  2172. if (strlen($block) > strlen($buffer["encrypted"])) {
  2173. $in = $self->_generate_xor($xor);
  2174. '.$_cryptBlock.'
  2175. $buffer["encrypted"].= $in;
  2176. }
  2177. $key = $self->_string_shift($buffer["encrypted"]);
  2178. $ciphertext.= $block ^ $key;
  2179. }
  2180. } else {
  2181. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2182. $block = substr($text, $i, '.$block_size.');
  2183. $in = $self->_generate_xor($xor);
  2184. '.$_cryptBlock.'
  2185. $key = $in;
  2186. $ciphertext.= $block ^ $key;
  2187. }
  2188. }
  2189. if ($self->continuousBuffer) {
  2190. $self->encryptIV = $xor;
  2191. if ($start = $plaintext_len % '.$block_size.') {
  2192. $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
  2193. }
  2194. }
  2195. return $ciphertext;
  2196. ';
  2197. $decrypt = $init_cryptBlock . '
  2198. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2199. $plaintext = "";
  2200. $ciphertext_len = strlen($text);
  2201. $xor = $self->decryptIV;
  2202. $buffer = &$self->debuffer;
  2203. if (strlen($buffer["ciphertext"])) {
  2204. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2205. $block = substr($text, $i, '.$block_size.');
  2206. if (strlen($block) > strlen($buffer["ciphertext"])) {
  2207. $in = $self->_generate_xor($xor);
  2208. '.$_cryptBlock.'
  2209. $buffer["ciphertext"].= $in;
  2210. }
  2211. $key = $self->_string_shift($buffer["ciphertext"]);
  2212. $plaintext.= $block ^ $key;
  2213. }
  2214. } else {
  2215. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2216. $block = substr($text, $i, '.$block_size.');
  2217. $in = $self->_generate_xor($xor);
  2218. '.$_cryptBlock.'
  2219. $key = $in;
  2220. $plaintext.= $block ^ $key;
  2221. }
  2222. }
  2223. if ($self->continuousBuffer) {
  2224. $self->decryptIV = $xor;
  2225. if ($start = $ciphertext_len % '.$block_size.') {
  2226. $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];
  2227. }
  2228. }
  2229. return $plaintext;
  2230. ';
  2231. break;
  2232. case CRYPT_DES_MODE_CFB:
  2233. $encrypt = $init_cryptBlock . '
  2234. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2235. $ciphertext = "";
  2236. $buffer = &$self->enbuffer;
  2237. if ($self->continuousBuffer) {
  2238. $iv = &$self->encryptIV;
  2239. $pos = &$buffer["pos"];
  2240. } else {
  2241. $iv = $self->encryptIV;
  2242. $pos = 0;
  2243. }
  2244. $len = strlen($text);
  2245. $i = 0;
  2246. if ($pos) {
  2247. $orig_pos = $pos;
  2248. $max = '.$block_size.' - $pos;
  2249. if ($len >= $max) {
  2250. $i = $max;
  2251. $len-= $max;
  2252. $pos = 0;
  2253. } else {
  2254. $i = $len;
  2255. $pos+= $len;
  2256. $len = 0;
  2257. }
  2258. $ciphertext = substr($iv, $orig_pos) ^ $text;
  2259. $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
  2260. }
  2261. while ($len >= '.$block_size.') {
  2262. $in = $iv;
  2263. '.$_cryptBlock.';
  2264. $iv = $in ^ substr($text, $i, '.$block_size.');
  2265. $ciphertext.= $iv;
  2266. $len-= '.$block_size.';
  2267. $i+= '.$block_size.';
  2268. }
  2269. if ($len) {
  2270. $in = $iv;
  2271. '.$_cryptBlock.'
  2272. $iv = $in;
  2273. $block = $iv ^ substr($text, $i);
  2274. $iv = substr_replace($iv, $block, 0, $len);
  2275. $ciphertext.= $block;
  2276. $pos = $len;
  2277. }
  2278. return $ciphertext;
  2279. ';
  2280. $decrypt = $init_cryptBlock . '
  2281. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2282. $plaintext = "";
  2283. $buffer = &$self->debuffer;
  2284. if ($self->continuousBuffer) {
  2285. $iv = &$self->decryptIV;
  2286. $pos = &$buffer["pos"];
  2287. } else {
  2288. $iv = $self->decryptIV;
  2289. $pos = 0;
  2290. }
  2291. $len = strlen($text);
  2292. $i = 0;
  2293. if ($pos) {
  2294. $orig_pos = $pos;
  2295. $max = '.$block_size.' - $pos;
  2296. if ($len >= $max) {
  2297. $i = $max;
  2298. $len-= $max;
  2299. $pos = 0;
  2300. } else {
  2301. $i = $len;
  2302. $pos+= $len;
  2303. $len = 0;
  2304. }
  2305. $plaintext = substr($iv, $orig_pos) ^ $text;
  2306. $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);
  2307. }
  2308. while ($len >= '.$block_size.') {
  2309. $in = $iv;
  2310. '.$_cryptBlock.'
  2311. $iv = $in;
  2312. $cb = substr($text, $i, '.$block_size.');
  2313. $plaintext.= $iv ^ $cb;
  2314. $iv = $cb;
  2315. $len-= '.$block_size.';
  2316. $i+= '.$block_size.';
  2317. }
  2318. if ($len) {
  2319. $in = $iv;
  2320. '.$_cryptBlock.'
  2321. $iv = $in;
  2322. $plaintext.= $iv ^ substr($text, $i);
  2323. $iv = substr_replace($iv, substr($text, $i), 0, $len);
  2324. $pos = $len;
  2325. }
  2326. return $plaintext;
  2327. ';
  2328. break;
  2329. case CRYPT_DES_MODE_OFB:
  2330. $encrypt = $init_cryptBlock . '
  2331. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2332. $ciphertext = "";
  2333. $plaintext_len = strlen($text);
  2334. $xor = $self->encryptIV;
  2335. $buffer = &$self->enbuffer;
  2336. if (strlen($buffer["xor"])) {
  2337. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2338. $block = substr($text, $i, '.$block_size.');
  2339. if (strlen($block) > strlen($buffer["xor"])) {
  2340. $in = $xor;
  2341. '.$_cryptBlock.'
  2342. $xor = $in;
  2343. $buffer["xor"].= $xor;
  2344. }
  2345. $key = $self->_string_shift($buffer["xor"]);
  2346. $ciphertext.= $block ^ $key;
  2347. }
  2348. } else {
  2349. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2350. $in = $xor;
  2351. '.$_cryptBlock.'
  2352. $xor = $in;
  2353. $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;
  2354. }
  2355. $key = $xor;
  2356. }
  2357. if ($self->continuousBuffer) {
  2358. $self->encryptIV = $xor;
  2359. if ($start = $plaintext_len % '.$block_size.') {
  2360. $buffer["xor"] = substr($key, $start) . $buffer["xor"];
  2361. }
  2362. }
  2363. return $ciphertext;
  2364. ';
  2365. $decrypt = $init_cryptBlock . '
  2366. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2367. $plaintext = "";
  2368. $ciphertext_len = strlen($text);
  2369. $xor = $self->decryptIV;
  2370. $buffer = &$self->debuffer;
  2371. if (strlen($buffer["xor"])) {
  2372. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2373. $block = substr($text, $i, '.$block_size.');
  2374. if (strlen($block) > strlen($buffer["xor"])) {
  2375. $in = $xor;
  2376. '.$_cryptBlock.'
  2377. $xor = $in;
  2378. $buffer["xor"].= $xor;
  2379. }
  2380. $key = $self->_string_shift($buffer["xor"]);
  2381. $plaintext.= $block ^ $key;
  2382. }
  2383. } else {
  2384. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2385. $in = $xor;
  2386. '.$_cryptBlock.'
  2387. $xor = $in;
  2388. $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;
  2389. }
  2390. $key = $xor;
  2391. }
  2392. if ($self->continuousBuffer) {
  2393. $self->decryptIV = $xor;
  2394. if ($start = $ciphertext_len % '.$block_size.') {
  2395. $buffer["xor"] = substr($key, $start) . $buffer["xor"];
  2396. }
  2397. }
  2398. return $plaintext;
  2399. ';
  2400. break;
  2401. }
  2402. $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }');
  2403. }
  2404. $this->inline_crypt = $lambda_functions[$code_hash];
  2405. }
  2406. /**
  2407. * Holds the lambda_functions table (classwide)
  2408. *
  2409. * @see inline_crypt_setup()
  2410. * @return Array
  2411. * @access private
  2412. */
  2413. function &get_lambda_functions()
  2414. {
  2415. static $functions = array();
  2416. return $functions;
  2417. }
  2418. }
  2419. ?>