DES.php 111 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536
  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. extract(unpack('Ncount', $temp));
  882. $iv = substr_replace($iv, pack('N', $count + 1), -$j, 4);
  883. break 2;
  884. }
  885. }
  886. return $xor;
  887. }
  888. /**
  889. * Encrypts a message.
  890. *
  891. * $plaintext will be padded with up to 8 additional bytes. Other DES implementations may or may not pad in the
  892. * same manner. Other common approaches to padding and the reasons why it's necessary are discussed in the following
  893. * URL:
  894. *
  895. * {@link http://www.di-mgt.com.au/cryptopad.html http://www.di-mgt.com.au/cryptopad.html}
  896. *
  897. * An alternative to padding is to, separately, send the length of the file. This is what SSH, in fact, does.
  898. * strlen($plaintext) will still need to be a multiple of 8, however, arbitrary values can be added to make it that
  899. * length.
  900. *
  901. * @see Crypt_DES::decrypt()
  902. * @access public
  903. * @param String $plaintext
  904. */
  905. function encrypt($plaintext)
  906. {
  907. if ($this->paddable) {
  908. $plaintext = $this->_pad($plaintext);
  909. }
  910. if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
  911. if ($this->enchanged) {
  912. mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
  913. if ($this->mode == 'ncfb') {
  914. mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
  915. }
  916. $this->enchanged = false;
  917. }
  918. if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
  919. $ciphertext = mcrypt_generic($this->enmcrypt, $plaintext);
  920. } else {
  921. $iv = &$this->encryptIV;
  922. $pos = &$this->enbuffer['pos'];
  923. $len = strlen($plaintext);
  924. $ciphertext = '';
  925. $i = 0;
  926. if ($pos) {
  927. $orig_pos = $pos;
  928. $max = 8 - $pos;
  929. if ($len >= $max) {
  930. $i = $max;
  931. $len-= $max;
  932. $pos = 0;
  933. } else {
  934. $i = $len;
  935. $pos+= $len;
  936. $len = 0;
  937. }
  938. $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
  939. $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
  940. $this->enbuffer['enmcrypt_init'] = true;
  941. }
  942. if ($len >= 8) {
  943. if ($this->enbuffer['enmcrypt_init'] === false || $len > 600) {
  944. if ($this->enbuffer['enmcrypt_init'] === true) {
  945. mcrypt_generic_init($this->enmcrypt, $this->keys, $iv);
  946. $this->enbuffer['enmcrypt_init'] = false;
  947. }
  948. $ciphertext.= mcrypt_generic($this->enmcrypt, substr($plaintext, $i, $len - $len % 8));
  949. $iv = substr($ciphertext, -8);
  950. $len%= 8;
  951. } else {
  952. while ($len >= 8) {
  953. $iv = mcrypt_generic($this->ecb, $iv) ^ substr($plaintext, $i, 8);
  954. $ciphertext.= $iv;
  955. $len-= 8;
  956. $i+= 8;
  957. }
  958. }
  959. }
  960. if ($len) {
  961. $iv = mcrypt_generic($this->ecb, $iv);
  962. $block = $iv ^ substr($plaintext, -$len);
  963. $iv = substr_replace($iv, $block, 0, $len);
  964. $ciphertext.= $block;
  965. $pos = $len;
  966. }
  967. return $ciphertext;
  968. }
  969. if (!$this->continuousBuffer) {
  970. mcrypt_generic_init($this->enmcrypt, $this->keys, $this->encryptIV);
  971. }
  972. return $ciphertext;
  973. }
  974. if (!is_array($this->keys)) {
  975. $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
  976. }
  977. if ($this->use_inline_crypt) {
  978. $inline = $this->inline_crypt;
  979. return $inline('encrypt', $this, $plaintext);
  980. }
  981. $buffer = &$this->enbuffer;
  982. $continuousBuffer = $this->continuousBuffer;
  983. $ciphertext = '';
  984. switch ($this->mode) {
  985. case CRYPT_DES_MODE_ECB:
  986. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  987. $ciphertext.= $this->_processBlock(substr($plaintext, $i, 8), CRYPT_DES_ENCRYPT);
  988. }
  989. break;
  990. case CRYPT_DES_MODE_CBC:
  991. $xor = $this->encryptIV;
  992. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  993. $block = substr($plaintext, $i, 8);
  994. $block = $this->_processBlock($block ^ $xor, CRYPT_DES_ENCRYPT);
  995. $xor = $block;
  996. $ciphertext.= $block;
  997. }
  998. if ($this->continuousBuffer) {
  999. $this->encryptIV = $xor;
  1000. }
  1001. break;
  1002. case CRYPT_DES_MODE_CTR:
  1003. $xor = $this->encryptIV;
  1004. if (strlen($buffer['encrypted'])) {
  1005. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1006. $block = substr($plaintext, $i, 8);
  1007. if (strlen($block) > strlen($buffer['encrypted'])) {
  1008. $buffer['encrypted'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1009. }
  1010. $key = $this->_string_shift($buffer['encrypted']);
  1011. $ciphertext.= $block ^ $key;
  1012. }
  1013. } else {
  1014. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1015. $block = substr($plaintext, $i, 8);
  1016. $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1017. $ciphertext.= $block ^ $key;
  1018. }
  1019. }
  1020. if ($this->continuousBuffer) {
  1021. $this->encryptIV = $xor;
  1022. if ($start = strlen($plaintext) & 7) {
  1023. $buffer['encrypted'] = substr($key, $start) . $buffer['encrypted'];
  1024. }
  1025. }
  1026. break;
  1027. case CRYPT_DES_MODE_CFB:
  1028. if ($this->continuousBuffer) {
  1029. $iv = &$this->encryptIV;
  1030. $pos = &$buffer['pos'];
  1031. } else {
  1032. $iv = $this->encryptIV;
  1033. $pos = 0;
  1034. }
  1035. $len = strlen($plaintext);
  1036. $i = 0;
  1037. if ($pos) {
  1038. $orig_pos = $pos;
  1039. $max = 8 - $pos;
  1040. if ($len >= $max) {
  1041. $i = $max;
  1042. $len-= $max;
  1043. $pos = 0;
  1044. } else {
  1045. $i = $len;
  1046. $pos+= $len;
  1047. $len = 0;
  1048. }
  1049. $ciphertext = substr($iv, $orig_pos) ^ $plaintext;
  1050. $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
  1051. }
  1052. while ($len >= 8) {
  1053. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT) ^ substr($plaintext, $i, 8);
  1054. $ciphertext.= $iv;
  1055. $len-= 8;
  1056. $i+= 8;
  1057. }
  1058. if ($len) {
  1059. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
  1060. $block = $iv ^ substr($plaintext, $i);
  1061. $iv = substr_replace($iv, $block, 0, $len);
  1062. $ciphertext.= $block;
  1063. $pos = $len;
  1064. }
  1065. return $ciphertext;
  1066. case CRYPT_DES_MODE_OFB:
  1067. $xor = $this->encryptIV;
  1068. if (strlen($buffer['xor'])) {
  1069. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1070. $block = substr($plaintext, $i, 8);
  1071. if (strlen($block) > strlen($buffer['xor'])) {
  1072. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1073. $buffer['xor'].= $xor;
  1074. }
  1075. $key = $this->_string_shift($buffer['xor']);
  1076. $ciphertext.= $block ^ $key;
  1077. }
  1078. } else {
  1079. for ($i = 0; $i < strlen($plaintext); $i+=8) {
  1080. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1081. $ciphertext.= substr($plaintext, $i, 8) ^ $xor;
  1082. }
  1083. $key = $xor;
  1084. }
  1085. if ($this->continuousBuffer) {
  1086. $this->encryptIV = $xor;
  1087. if ($start = strlen($plaintext) & 7) {
  1088. $buffer['xor'] = substr($key, $start) . $buffer['xor'];
  1089. }
  1090. }
  1091. }
  1092. return $ciphertext;
  1093. }
  1094. /**
  1095. * Decrypts a message.
  1096. *
  1097. * If strlen($ciphertext) is not a multiple of 8, null bytes will be added to the end of the string until it is.
  1098. *
  1099. * @see Crypt_DES::encrypt()
  1100. * @access public
  1101. * @param String $ciphertext
  1102. */
  1103. function decrypt($ciphertext)
  1104. {
  1105. if ($this->paddable) {
  1106. // we pad with chr(0) since that's what mcrypt_generic does. to quote from http://php.net/function.mcrypt-generic :
  1107. // "The data is padded with "\0" to make sure the length of the data is n * blocksize."
  1108. $ciphertext = str_pad($ciphertext, (strlen($ciphertext) + 7) & 0xFFFFFFF8, chr(0));
  1109. }
  1110. if ( CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT ) {
  1111. if ($this->dechanged) {
  1112. mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
  1113. if ($this->mode == 'ncfb') {
  1114. mcrypt_generic_init($this->ecb, $this->keys, "\0\0\0\0\0\0\0\0");
  1115. }
  1116. $this->dechanged = false;
  1117. }
  1118. if ($this->mode != 'ncfb' || !$this->continuousBuffer) {
  1119. $plaintext = mdecrypt_generic($this->demcrypt, $ciphertext);
  1120. } else {
  1121. $iv = &$this->decryptIV;
  1122. $pos = &$this->debuffer['pos'];
  1123. $len = strlen($ciphertext);
  1124. $plaintext = '';
  1125. $i = 0;
  1126. if ($pos) {
  1127. $orig_pos = $pos;
  1128. $max = 8 - $pos;
  1129. if ($len >= $max) {
  1130. $i = $max;
  1131. $len-= $max;
  1132. $pos = 0;
  1133. } else {
  1134. $i = $len;
  1135. $pos+= $len;
  1136. $len = 0;
  1137. }
  1138. $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
  1139. $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
  1140. }
  1141. if ($len >= 8) {
  1142. $cb = substr($ciphertext, $i, $len - $len % 8);
  1143. $plaintext.= mcrypt_generic($this->ecb, $iv . $cb) ^ $cb;
  1144. $iv = substr($cb, -8);
  1145. $len%= 8;
  1146. }
  1147. if ($len) {
  1148. $iv = mcrypt_generic($this->ecb, $iv);
  1149. $plaintext.= $iv ^ substr($ciphertext, -$len);
  1150. $iv = substr_replace($iv, substr($ciphertext, -$len), 0, $len);
  1151. $pos = $len;
  1152. }
  1153. return $plaintext;
  1154. }
  1155. if (!$this->continuousBuffer) {
  1156. mcrypt_generic_init($this->demcrypt, $this->keys, $this->decryptIV);
  1157. }
  1158. return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
  1159. }
  1160. if (!is_array($this->keys)) {
  1161. $this->keys = $this->_prepareKey("\0\0\0\0\0\0\0\0");
  1162. }
  1163. if ($this->use_inline_crypt) {
  1164. $inline = $this->inline_crypt;
  1165. return $inline('decrypt', $this, $ciphertext);
  1166. }
  1167. $buffer = &$this->debuffer;
  1168. $continuousBuffer = $this->continuousBuffer;
  1169. $plaintext = '';
  1170. switch ($this->mode) {
  1171. case CRYPT_DES_MODE_ECB:
  1172. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1173. $plaintext.= $this->_processBlock(substr($ciphertext, $i, 8), CRYPT_DES_DECRYPT);
  1174. }
  1175. break;
  1176. case CRYPT_DES_MODE_CBC:
  1177. $xor = $this->decryptIV;
  1178. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1179. $block = substr($ciphertext, $i, 8);
  1180. $plaintext.= $this->_processBlock($block, CRYPT_DES_DECRYPT) ^ $xor;
  1181. $xor = $block;
  1182. }
  1183. if ($this->continuousBuffer) {
  1184. $this->decryptIV = $xor;
  1185. }
  1186. break;
  1187. case CRYPT_DES_MODE_CTR:
  1188. $xor = $this->decryptIV;
  1189. if (strlen($buffer['ciphertext'])) {
  1190. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1191. $block = substr($ciphertext, $i, 8);
  1192. if (strlen($block) > strlen($buffer['ciphertext'])) {
  1193. $buffer['ciphertext'].= $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1194. }
  1195. $key = $this->_string_shift($buffer['ciphertext']);
  1196. $plaintext.= $block ^ $key;
  1197. }
  1198. } else {
  1199. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1200. $block = substr($ciphertext, $i, 8);
  1201. $key = $this->_processBlock($this->_generate_xor($xor), CRYPT_DES_ENCRYPT);
  1202. $plaintext.= $block ^ $key;
  1203. }
  1204. }
  1205. if ($this->continuousBuffer) {
  1206. $this->decryptIV = $xor;
  1207. if ($start = strlen($ciphertext) % 8) {
  1208. $buffer['ciphertext'] = substr($key, $start) . $buffer['ciphertext'];
  1209. }
  1210. }
  1211. break;
  1212. case CRYPT_DES_MODE_CFB:
  1213. if ($this->continuousBuffer) {
  1214. $iv = &$this->decryptIV;
  1215. $pos = &$buffer['pos'];
  1216. } else {
  1217. $iv = $this->decryptIV;
  1218. $pos = 0;
  1219. }
  1220. $len = strlen($ciphertext);
  1221. $i = 0;
  1222. if ($pos) {
  1223. $orig_pos = $pos;
  1224. $max = 8 - $pos;
  1225. if ($len >= $max) {
  1226. $i = $max;
  1227. $len-= $max;
  1228. $pos = 0;
  1229. } else {
  1230. $i = $len;
  1231. $pos+= $len;
  1232. $len = 0;
  1233. }
  1234. $plaintext = substr($iv, $orig_pos) ^ $ciphertext;
  1235. $iv = substr_replace($iv, substr($ciphertext, 0, $i), $orig_pos, $i);
  1236. }
  1237. while ($len >= 8) {
  1238. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
  1239. $cb = substr($ciphertext, $i, 8);
  1240. $plaintext.= $iv ^ $cb;
  1241. $iv = $cb;
  1242. $len-= 8;
  1243. $i+= 8;
  1244. }
  1245. if ($len) {
  1246. $iv = $this->_processBlock($iv, CRYPT_DES_ENCRYPT);
  1247. $plaintext.= $iv ^ substr($ciphertext, $i);
  1248. $iv = substr_replace($iv, substr($ciphertext, $i), 0, $len);
  1249. $pos = $len;
  1250. }
  1251. return $plaintext;
  1252. case CRYPT_DES_MODE_OFB:
  1253. $xor = $this->decryptIV;
  1254. if (strlen($buffer['xor'])) {
  1255. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1256. $block = substr($ciphertext, $i, 8);
  1257. if (strlen($block) > strlen($buffer['xor'])) {
  1258. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1259. $buffer['xor'].= $xor;
  1260. }
  1261. $key = $this->_string_shift($buffer['xor']);
  1262. $plaintext.= $block ^ $key;
  1263. }
  1264. } else {
  1265. for ($i = 0; $i < strlen($ciphertext); $i+=8) {
  1266. $xor = $this->_processBlock($xor, CRYPT_DES_ENCRYPT);
  1267. $plaintext.= substr($ciphertext, $i, 8) ^ $xor;
  1268. }
  1269. $key = $xor;
  1270. }
  1271. if ($this->continuousBuffer) {
  1272. $this->decryptIV = $xor;
  1273. if ($start = strlen($ciphertext) % 8) {
  1274. $buffer['xor'] = substr($key, $start) . $buffer['xor'];
  1275. }
  1276. }
  1277. }
  1278. return $this->paddable ? $this->_unpad($plaintext) : $plaintext;
  1279. }
  1280. /**
  1281. * Treat consecutive "packets" as if they are a continuous buffer.
  1282. *
  1283. * Say you have a 16-byte plaintext $plaintext. Using the default behavior, the two following code snippets
  1284. * will yield different outputs:
  1285. *
  1286. * <code>
  1287. * echo $des->encrypt(substr($plaintext, 0, 8));
  1288. * echo $des->encrypt(substr($plaintext, 8, 8));
  1289. * </code>
  1290. * <code>
  1291. * echo $des->encrypt($plaintext);
  1292. * </code>
  1293. *
  1294. * The solution is to enable the continuous buffer. Although this will resolve the above discrepancy, it creates
  1295. * another, as demonstrated with the following:
  1296. *
  1297. * <code>
  1298. * $des->encrypt(substr($plaintext, 0, 8));
  1299. * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
  1300. * </code>
  1301. * <code>
  1302. * echo $des->decrypt($des->encrypt(substr($plaintext, 8, 8)));
  1303. * </code>
  1304. *
  1305. * With the continuous buffer disabled, these would yield the same output. With it enabled, they yield different
  1306. * outputs. The reason is due to the fact that the initialization vector's change after every encryption /
  1307. * decryption round when the continuous buffer is enabled. When it's disabled, they remain constant.
  1308. *
  1309. * Put another way, when the continuous buffer is enabled, the state of the Crypt_DES() object changes after each
  1310. * encryption / decryption round, whereas otherwise, it'd remain constant. For this reason, it's recommended that
  1311. * continuous buffers not be used. They do offer better security and are, in fact, sometimes required (SSH uses them),
  1312. * however, they are also less intuitive and more likely to cause you problems.
  1313. *
  1314. * @see Crypt_DES::disableContinuousBuffer()
  1315. * @access public
  1316. */
  1317. function enableContinuousBuffer()
  1318. {
  1319. $this->continuousBuffer = true;
  1320. }
  1321. /**
  1322. * Treat consecutive packets as if they are a discontinuous buffer.
  1323. *
  1324. * The default behavior.
  1325. *
  1326. * @see Crypt_DES::enableContinuousBuffer()
  1327. * @access public
  1328. */
  1329. function disableContinuousBuffer()
  1330. {
  1331. $this->continuousBuffer = false;
  1332. $this->encryptIV = $this->iv;
  1333. $this->decryptIV = $this->iv;
  1334. $this->enbuffer = array('encrypted' => '', 'xor' => '', 'pos' => 0, 'enmcrypt_init' => true);
  1335. $this->debuffer = array('ciphertext' => '', 'xor' => '', 'pos' => 0, 'demcrypt_init' => true);
  1336. if (CRYPT_DES_MODE == CRYPT_DES_MODE_MCRYPT) {
  1337. mcrypt_generic_init($this->enmcrypt, $this->keys, $this->iv);
  1338. mcrypt_generic_init($this->demcrypt, $this->keys, $this->iv);
  1339. }
  1340. }
  1341. /**
  1342. * Pad "packets".
  1343. *
  1344. * DES works by encrypting eight bytes at a time. If you ever need to encrypt or decrypt something that's not
  1345. * a multiple of eight, it becomes necessary to pad the input so that it's length is a multiple of eight.
  1346. *
  1347. * Padding is enabled by default. Sometimes, however, it is undesirable to pad strings. Such is the case in SSH1,
  1348. * where "packets" are padded with random bytes before being encrypted. Unpad these packets and you risk stripping
  1349. * away characters that shouldn't be stripped away. (SSH knows how many bytes are added because the length is
  1350. * transmitted separately)
  1351. *
  1352. * @see Crypt_DES::disablePadding()
  1353. * @access public
  1354. */
  1355. function enablePadding()
  1356. {
  1357. $this->padding = true;
  1358. }
  1359. /**
  1360. * Do not pad packets.
  1361. *
  1362. * @see Crypt_DES::enablePadding()
  1363. * @access public
  1364. */
  1365. function disablePadding()
  1366. {
  1367. $this->padding = false;
  1368. }
  1369. /**
  1370. * Pads a string
  1371. *
  1372. * Pads a string using the RSA PKCS padding standards so that its length is a multiple of the blocksize (8).
  1373. * 8 - (strlen($text) & 7) bytes are added, each of which is equal to chr(8 - (strlen($text) & 7)
  1374. *
  1375. * If padding is disabled and $text is not a multiple of the blocksize, the string will be padded regardless
  1376. * and padding will, hence forth, be enabled.
  1377. *
  1378. * @see Crypt_DES::_unpad()
  1379. * @access private
  1380. */
  1381. function _pad($text)
  1382. {
  1383. $length = strlen($text);
  1384. if (!$this->padding) {
  1385. if (($length & 7) == 0) {
  1386. return $text;
  1387. } else {
  1388. user_error("The plaintext's length ($length) is not a multiple of the block size (8)");
  1389. $this->padding = true;
  1390. }
  1391. }
  1392. $pad = 8 - ($length & 7);
  1393. return str_pad($text, $length + $pad, chr($pad));
  1394. }
  1395. /**
  1396. * Unpads a string
  1397. *
  1398. * If padding is enabled and the reported padding length is invalid the encryption key will be assumed to be wrong
  1399. * and false will be returned.
  1400. *
  1401. * @see Crypt_DES::_pad()
  1402. * @access private
  1403. */
  1404. function _unpad($text)
  1405. {
  1406. if (!$this->padding) {
  1407. return $text;
  1408. }
  1409. $length = ord($text[strlen($text) - 1]);
  1410. if (!$length || $length > 8) {
  1411. return false;
  1412. }
  1413. return substr($text, 0, -$length);
  1414. }
  1415. /**
  1416. * Encrypts or decrypts a 64-bit block
  1417. *
  1418. * $mode should be either CRYPT_DES_ENCRYPT or CRYPT_DES_DECRYPT. See
  1419. * {@link http://en.wikipedia.org/wiki/Image:Feistel.png Feistel.png} to get a general
  1420. * idea of what this function does.
  1421. *
  1422. * @access private
  1423. * @param String $block
  1424. * @param Integer $mode
  1425. * @return String
  1426. */
  1427. function _processBlock($block, $mode)
  1428. {
  1429. $shuffle = $this->shuffle;
  1430. $invipmap = $this->invipmap;
  1431. $ipmap = $this->ipmap;
  1432. $sbox1 = $this->sbox1;
  1433. $sbox2 = $this->sbox2;
  1434. $sbox3 = $this->sbox3;
  1435. $sbox4 = $this->sbox4;
  1436. $sbox5 = $this->sbox5;
  1437. $sbox6 = $this->sbox6;
  1438. $sbox7 = $this->sbox7;
  1439. $sbox8 = $this->sbox8;
  1440. $keys = $this->keys[$mode];
  1441. // Do the initial IP permutation.
  1442. $t = unpack('Nl/Nr', $block);
  1443. list($l, $r) = array($t['l'], $t['r']);
  1444. $block = ($shuffle[$ipmap[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  1445. ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  1446. ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  1447. ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  1448. ($shuffle[$ipmap[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  1449. ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  1450. ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  1451. ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
  1452. // Extract L0 and R0.
  1453. $t = unpack('Nl/Nr', $block);
  1454. list($l, $r) = array($t['l'], $t['r']);
  1455. // Perform the 16 steps.
  1456. for ($i = 0; $i < 16; $i++) {
  1457. // start of "the Feistel (F) function" - see the following URL:
  1458. // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
  1459. // Merge key schedule.
  1460. $b1 = (($r >> 3) & 0x1FFFFFFF) ^ ($r << 29) ^ $keys[$i][0];
  1461. $b2 = (($r >> 31) & 0x00000001) ^ ($r << 1) ^ $keys[$i][1];
  1462. // S-box indexing.
  1463. $t = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
  1464. $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
  1465. $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
  1466. $sbox7[$b1 & 0x3F] ^ $sbox8[$b2 & 0x3F] ^ $l;
  1467. // end of "the Feistel (F) function"
  1468. $l = $r;
  1469. $r = $t;
  1470. }
  1471. // Perform the inverse IP permutation.
  1472. return ($shuffle[$invipmap[($l >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  1473. ($shuffle[$invipmap[($r >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  1474. ($shuffle[$invipmap[($l >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  1475. ($shuffle[$invipmap[($r >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  1476. ($shuffle[$invipmap[($l >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  1477. ($shuffle[$invipmap[($r >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  1478. ($shuffle[$invipmap[$l & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  1479. ($shuffle[$invipmap[$r & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01");
  1480. }
  1481. /**
  1482. * Creates the key schedule.
  1483. *
  1484. * @access private
  1485. * @param String $key
  1486. * @return Array
  1487. */
  1488. function _prepareKey($key)
  1489. {
  1490. static $shifts = array( // number of key bits shifted per round
  1491. 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
  1492. );
  1493. static $pc1map = array(
  1494. 0x00, 0x00, 0x08, 0x08, 0x04, 0x04, 0x0C, 0x0C,
  1495. 0x02, 0x02, 0x0A, 0x0A, 0x06, 0x06, 0x0E, 0x0E,
  1496. 0x10, 0x10, 0x18, 0x18, 0x14, 0x14, 0x1C, 0x1C,
  1497. 0x12, 0x12, 0x1A, 0x1A, 0x16, 0x16, 0x1E, 0x1E,
  1498. 0x20, 0x20, 0x28, 0x28, 0x24, 0x24, 0x2C, 0x2C,
  1499. 0x22, 0x22, 0x2A, 0x2A, 0x26, 0x26, 0x2E, 0x2E,
  1500. 0x30, 0x30, 0x38, 0x38, 0x34, 0x34, 0x3C, 0x3C,
  1501. 0x32, 0x32, 0x3A, 0x3A, 0x36, 0x36, 0x3E, 0x3E,
  1502. 0x40, 0x40, 0x48, 0x48, 0x44, 0x44, 0x4C, 0x4C,
  1503. 0x42, 0x42, 0x4A, 0x4A, 0x46, 0x46, 0x4E, 0x4E,
  1504. 0x50, 0x50, 0x58, 0x58, 0x54, 0x54, 0x5C, 0x5C,
  1505. 0x52, 0x52, 0x5A, 0x5A, 0x56, 0x56, 0x5E, 0x5E,
  1506. 0x60, 0x60, 0x68, 0x68, 0x64, 0x64, 0x6C, 0x6C,
  1507. 0x62, 0x62, 0x6A, 0x6A, 0x66, 0x66, 0x6E, 0x6E,
  1508. 0x70, 0x70, 0x78, 0x78, 0x74, 0x74, 0x7C, 0x7C,
  1509. 0x72, 0x72, 0x7A, 0x7A, 0x76, 0x76, 0x7E, 0x7E,
  1510. 0x80, 0x80, 0x88, 0x88, 0x84, 0x84, 0x8C, 0x8C,
  1511. 0x82, 0x82, 0x8A, 0x8A, 0x86, 0x86, 0x8E, 0x8E,
  1512. 0x90, 0x90, 0x98, 0x98, 0x94, 0x94, 0x9C, 0x9C,
  1513. 0x92, 0x92, 0x9A, 0x9A, 0x96, 0x96, 0x9E, 0x9E,
  1514. 0xA0, 0xA0, 0xA8, 0xA8, 0xA4, 0xA4, 0xAC, 0xAC,
  1515. 0xA2, 0xA2, 0xAA, 0xAA, 0xA6, 0xA6, 0xAE, 0xAE,
  1516. 0xB0, 0xB0, 0xB8, 0xB8, 0xB4, 0xB4, 0xBC, 0xBC,
  1517. 0xB2, 0xB2, 0xBA, 0xBA, 0xB6, 0xB6, 0xBE, 0xBE,
  1518. 0xC0, 0xC0, 0xC8, 0xC8, 0xC4, 0xC4, 0xCC, 0xCC,
  1519. 0xC2, 0xC2, 0xCA, 0xCA, 0xC6, 0xC6, 0xCE, 0xCE,
  1520. 0xD0, 0xD0, 0xD8, 0xD8, 0xD4, 0xD4, 0xDC, 0xDC,
  1521. 0xD2, 0xD2, 0xDA, 0xDA, 0xD6, 0xD6, 0xDE, 0xDE,
  1522. 0xE0, 0xE0, 0xE8, 0xE8, 0xE4, 0xE4, 0xEC, 0xEC,
  1523. 0xE2, 0xE2, 0xEA, 0xEA, 0xE6, 0xE6, 0xEE, 0xEE,
  1524. 0xF0, 0xF0, 0xF8, 0xF8, 0xF4, 0xF4, 0xFC, 0xFC,
  1525. 0xF2, 0xF2, 0xFA, 0xFA, 0xF6, 0xF6, 0xFE, 0xFE
  1526. );
  1527. // Mapping tables for the PC-2 transformation.
  1528. static $pc2mapc1 = array(
  1529. 0x00000000, 0x00000400, 0x00200000, 0x00200400,
  1530. 0x00000001, 0x00000401, 0x00200001, 0x00200401,
  1531. 0x02000000, 0x02000400, 0x02200000, 0x02200400,
  1532. 0x02000001, 0x02000401, 0x02200001, 0x02200401
  1533. );
  1534. static $pc2mapc2 = array(
  1535. 0x00000000, 0x00000800, 0x08000000, 0x08000800,
  1536. 0x00010000, 0x00010800, 0x08010000, 0x08010800,
  1537. 0x00000000, 0x00000800, 0x08000000, 0x08000800,
  1538. 0x00010000, 0x00010800, 0x08010000, 0x08010800,
  1539. 0x00000100, 0x00000900, 0x08000100, 0x08000900,
  1540. 0x00010100, 0x00010900, 0x08010100, 0x08010900,
  1541. 0x00000100, 0x00000900, 0x08000100, 0x08000900,
  1542. 0x00010100, 0x00010900, 0x08010100, 0x08010900,
  1543. 0x00000010, 0x00000810, 0x08000010, 0x08000810,
  1544. 0x00010010, 0x00010810, 0x08010010, 0x08010810,
  1545. 0x00000010, 0x00000810, 0x08000010, 0x08000810,
  1546. 0x00010010, 0x00010810, 0x08010010, 0x08010810,
  1547. 0x00000110, 0x00000910, 0x08000110, 0x08000910,
  1548. 0x00010110, 0x00010910, 0x08010110, 0x08010910,
  1549. 0x00000110, 0x00000910, 0x08000110, 0x08000910,
  1550. 0x00010110, 0x00010910, 0x08010110, 0x08010910,
  1551. 0x00040000, 0x00040800, 0x08040000, 0x08040800,
  1552. 0x00050000, 0x00050800, 0x08050000, 0x08050800,
  1553. 0x00040000, 0x00040800, 0x08040000, 0x08040800,
  1554. 0x00050000, 0x00050800, 0x08050000, 0x08050800,
  1555. 0x00040100, 0x00040900, 0x08040100, 0x08040900,
  1556. 0x00050100, 0x00050900, 0x08050100, 0x08050900,
  1557. 0x00040100, 0x00040900, 0x08040100, 0x08040900,
  1558. 0x00050100, 0x00050900, 0x08050100, 0x08050900,
  1559. 0x00040010, 0x00040810, 0x08040010, 0x08040810,
  1560. 0x00050010, 0x00050810, 0x08050010, 0x08050810,
  1561. 0x00040010, 0x00040810, 0x08040010, 0x08040810,
  1562. 0x00050010, 0x00050810, 0x08050010, 0x08050810,
  1563. 0x00040110, 0x00040910, 0x08040110, 0x08040910,
  1564. 0x00050110, 0x00050910, 0x08050110, 0x08050910,
  1565. 0x00040110, 0x00040910, 0x08040110, 0x08040910,
  1566. 0x00050110, 0x00050910, 0x08050110, 0x08050910,
  1567. 0x01000000, 0x01000800, 0x09000000, 0x09000800,
  1568. 0x01010000, 0x01010800, 0x09010000, 0x09010800,
  1569. 0x01000000, 0x01000800, 0x09000000, 0x09000800,
  1570. 0x01010000, 0x01010800, 0x09010000, 0x09010800,
  1571. 0x01000100, 0x01000900, 0x09000100, 0x09000900,
  1572. 0x01010100, 0x01010900, 0x09010100, 0x09010900,
  1573. 0x01000100, 0x01000900, 0x09000100, 0x09000900,
  1574. 0x01010100, 0x01010900, 0x09010100, 0x09010900,
  1575. 0x01000010, 0x01000810, 0x09000010, 0x09000810,
  1576. 0x01010010, 0x01010810, 0x09010010, 0x09010810,
  1577. 0x01000010, 0x01000810, 0x09000010, 0x09000810,
  1578. 0x01010010, 0x01010810, 0x09010010, 0x09010810,
  1579. 0x01000110, 0x01000910, 0x09000110, 0x09000910,
  1580. 0x01010110, 0x01010910, 0x09010110, 0x09010910,
  1581. 0x01000110, 0x01000910, 0x09000110, 0x09000910,
  1582. 0x01010110, 0x01010910, 0x09010110, 0x09010910,
  1583. 0x01040000, 0x01040800, 0x09040000, 0x09040800,
  1584. 0x01050000, 0x01050800, 0x09050000, 0x09050800,
  1585. 0x01040000, 0x01040800, 0x09040000, 0x09040800,
  1586. 0x01050000, 0x01050800, 0x09050000, 0x09050800,
  1587. 0x01040100, 0x01040900, 0x09040100, 0x09040900,
  1588. 0x01050100, 0x01050900, 0x09050100, 0x09050900,
  1589. 0x01040100, 0x01040900, 0x09040100, 0x09040900,
  1590. 0x01050100, 0x01050900, 0x09050100, 0x09050900,
  1591. 0x01040010, 0x01040810, 0x09040010, 0x09040810,
  1592. 0x01050010, 0x01050810, 0x09050010, 0x09050810,
  1593. 0x01040010, 0x01040810, 0x09040010, 0x09040810,
  1594. 0x01050010, 0x01050810, 0x09050010, 0x09050810,
  1595. 0x01040110, 0x01040910, 0x09040110, 0x09040910,
  1596. 0x01050110, 0x01050910, 0x09050110, 0x09050910,
  1597. 0x01040110, 0x01040910, 0x09040110, 0x09040910,
  1598. 0x01050110, 0x01050910, 0x09050110, 0x09050910
  1599. );
  1600. static $pc2mapc3 = array(
  1601. 0x00000000, 0x00000004, 0x00001000, 0x00001004,
  1602. 0x00000000, 0x00000004, 0x00001000, 0x00001004,
  1603. 0x10000000, 0x10000004, 0x10001000, 0x10001004,
  1604. 0x10000000, 0x10000004, 0x10001000, 0x10001004,
  1605. 0x00000020, 0x00000024, 0x00001020, 0x00001024,
  1606. 0x00000020, 0x00000024, 0x00001020, 0x00001024,
  1607. 0x10000020, 0x10000024, 0x10001020, 0x10001024,
  1608. 0x10000020, 0x10000024, 0x10001020, 0x10001024,
  1609. 0x00080000, 0x00080004, 0x00081000, 0x00081004,
  1610. 0x00080000, 0x00080004, 0x00081000, 0x00081004,
  1611. 0x10080000, 0x10080004, 0x10081000, 0x10081004,
  1612. 0x10080000, 0x10080004, 0x10081000, 0x10081004,
  1613. 0x00080020, 0x00080024, 0x00081020, 0x00081024,
  1614. 0x00080020, 0x00080024, 0x00081020, 0x00081024,
  1615. 0x10080020, 0x10080024, 0x10081020, 0x10081024,
  1616. 0x10080020, 0x10080024, 0x10081020, 0x10081024,
  1617. 0x20000000, 0x20000004, 0x20001000, 0x20001004,
  1618. 0x20000000, 0x20000004, 0x20001000, 0x20001004,
  1619. 0x30000000, 0x30000004, 0x30001000, 0x30001004,
  1620. 0x30000000, 0x30000004, 0x30001000, 0x30001004,
  1621. 0x20000020, 0x20000024, 0x20001020, 0x20001024,
  1622. 0x20000020, 0x20000024, 0x20001020, 0x20001024,
  1623. 0x30000020, 0x30000024, 0x30001020, 0x30001024,
  1624. 0x30000020, 0x30000024, 0x30001020, 0x30001024,
  1625. 0x20080000, 0x20080004, 0x20081000, 0x20081004,
  1626. 0x20080000, 0x20080004, 0x20081000, 0x20081004,
  1627. 0x30080000, 0x30080004, 0x30081000, 0x30081004,
  1628. 0x30080000, 0x30080004, 0x30081000, 0x30081004,
  1629. 0x20080020, 0x20080024, 0x20081020, 0x20081024,
  1630. 0x20080020, 0x20080024, 0x20081020, 0x20081024,
  1631. 0x30080020, 0x30080024, 0x30081020, 0x30081024,
  1632. 0x30080020, 0x30080024, 0x30081020, 0x30081024,
  1633. 0x00000002, 0x00000006, 0x00001002, 0x00001006,
  1634. 0x00000002, 0x00000006, 0x00001002, 0x00001006,
  1635. 0x10000002, 0x10000006, 0x10001002, 0x10001006,
  1636. 0x10000002, 0x10000006, 0x10001002, 0x10001006,
  1637. 0x00000022, 0x00000026, 0x00001022, 0x00001026,
  1638. 0x00000022, 0x00000026, 0x00001022, 0x00001026,
  1639. 0x10000022, 0x10000026, 0x10001022, 0x10001026,
  1640. 0x10000022, 0x10000026, 0x10001022, 0x10001026,
  1641. 0x00080002, 0x00080006, 0x00081002, 0x00081006,
  1642. 0x00080002, 0x00080006, 0x00081002, 0x00081006,
  1643. 0x10080002, 0x10080006, 0x10081002, 0x10081006,
  1644. 0x10080002, 0x10080006, 0x10081002, 0x10081006,
  1645. 0x00080022, 0x00080026, 0x00081022, 0x00081026,
  1646. 0x00080022, 0x00080026, 0x00081022, 0x00081026,
  1647. 0x10080022, 0x10080026, 0x10081022, 0x10081026,
  1648. 0x10080022, 0x10080026, 0x10081022, 0x10081026,
  1649. 0x20000002, 0x20000006, 0x20001002, 0x20001006,
  1650. 0x20000002, 0x20000006, 0x20001002, 0x20001006,
  1651. 0x30000002, 0x30000006, 0x30001002, 0x30001006,
  1652. 0x30000002, 0x30000006, 0x30001002, 0x30001006,
  1653. 0x20000022, 0x20000026, 0x20001022, 0x20001026,
  1654. 0x20000022, 0x20000026, 0x20001022, 0x20001026,
  1655. 0x30000022, 0x30000026, 0x30001022, 0x30001026,
  1656. 0x30000022, 0x30000026, 0x30001022, 0x30001026,
  1657. 0x20080002, 0x20080006, 0x20081002, 0x20081006,
  1658. 0x20080002, 0x20080006, 0x20081002, 0x20081006,
  1659. 0x30080002, 0x30080006, 0x30081002, 0x30081006,
  1660. 0x30080002, 0x30080006, 0x30081002, 0x30081006,
  1661. 0x20080022, 0x20080026, 0x20081022, 0x20081026,
  1662. 0x20080022, 0x20080026, 0x20081022, 0x20081026,
  1663. 0x30080022, 0x30080026, 0x30081022, 0x30081026,
  1664. 0x30080022, 0x30080026, 0x30081022, 0x30081026
  1665. );
  1666. static $pc2mapc4 = array(
  1667. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1668. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1669. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1670. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1671. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1672. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1673. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1674. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1675. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1676. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1677. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1678. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1679. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1680. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1681. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1682. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1683. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1684. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1685. 0x00000000, 0x00100000, 0x00000008, 0x00100008,
  1686. 0x00000200, 0x00100200, 0x00000208, 0x00100208,
  1687. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1688. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1689. 0x04000000, 0x04100000, 0x04000008, 0x04100008,
  1690. 0x04000200, 0x04100200, 0x04000208, 0x04100208,
  1691. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1692. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1693. 0x00002000, 0x00102000, 0x00002008, 0x00102008,
  1694. 0x00002200, 0x00102200, 0x00002208, 0x00102208,
  1695. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1696. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1697. 0x04002000, 0x04102000, 0x04002008, 0x04102008,
  1698. 0x04002200, 0x04102200, 0x04002208, 0x04102208,
  1699. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1700. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1701. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1702. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1703. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1704. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1705. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1706. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1707. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1708. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1709. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1710. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1711. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1712. 0x04022200, 0x04122200, 0x04022208, 0x04122208,
  1713. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1714. 0x04022200, 0x04122200, 0x04022208, 0x04122208,
  1715. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1716. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1717. 0x00020000, 0x00120000, 0x00020008, 0x00120008,
  1718. 0x00020200, 0x00120200, 0x00020208, 0x00120208,
  1719. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1720. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1721. 0x04020000, 0x04120000, 0x04020008, 0x04120008,
  1722. 0x04020200, 0x04120200, 0x04020208, 0x04120208,
  1723. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1724. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1725. 0x00022000, 0x00122000, 0x00022008, 0x00122008,
  1726. 0x00022200, 0x00122200, 0x00022208, 0x00122208,
  1727. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1728. 0x04022200, 0x04122200, 0x04022208, 0x04122208,
  1729. 0x04022000, 0x04122000, 0x04022008, 0x04122008,
  1730. 0x04022200, 0x04122200, 0x04022208, 0x04122208
  1731. );
  1732. static $pc2mapd1 = array(
  1733. 0x00000000, 0x00000001, 0x08000000, 0x08000001,
  1734. 0x00200000, 0x00200001, 0x08200000, 0x08200001,
  1735. 0x00000002, 0x00000003, 0x08000002, 0x08000003,
  1736. 0x00200002, 0x00200003, 0x08200002, 0x08200003
  1737. );
  1738. static $pc2mapd2 = array(
  1739. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1740. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1741. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1742. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1743. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1744. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1745. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1746. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1747. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1748. 0x00000000, 0x00100000, 0x00000800, 0x00100800,
  1749. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1750. 0x04000000, 0x04100000, 0x04000800, 0x04100800,
  1751. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1752. 0x00000004, 0x00100004, 0x00000804, 0x00100804,
  1753. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1754. 0x04000004, 0x04100004, 0x04000804, 0x04100804,
  1755. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1756. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1757. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1758. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1759. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1760. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1761. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1762. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1763. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1764. 0x00000200, 0x00100200, 0x00000A00, 0x00100A00,
  1765. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1766. 0x04000200, 0x04100200, 0x04000A00, 0x04100A00,
  1767. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1768. 0x00000204, 0x00100204, 0x00000A04, 0x00100A04,
  1769. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1770. 0x04000204, 0x04100204, 0x04000A04, 0x04100A04,
  1771. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1772. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1773. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1774. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1775. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1776. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1777. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1778. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1779. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1780. 0x00020000, 0x00120000, 0x00020800, 0x00120800,
  1781. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1782. 0x04020000, 0x04120000, 0x04020800, 0x04120800,
  1783. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1784. 0x00020004, 0x00120004, 0x00020804, 0x00120804,
  1785. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1786. 0x04020004, 0x04120004, 0x04020804, 0x04120804,
  1787. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1788. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1789. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1790. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1791. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1792. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1793. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
  1794. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
  1795. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1796. 0x00020200, 0x00120200, 0x00020A00, 0x00120A00,
  1797. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1798. 0x04020200, 0x04120200, 0x04020A00, 0x04120A00,
  1799. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1800. 0x00020204, 0x00120204, 0x00020A04, 0x00120A04,
  1801. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04,
  1802. 0x04020204, 0x04120204, 0x04020A04, 0x04120A04
  1803. );
  1804. static $pc2mapd3 = array(
  1805. 0x00000000, 0x00010000, 0x02000000, 0x02010000,
  1806. 0x00000020, 0x00010020, 0x02000020, 0x02010020,
  1807. 0x00040000, 0x00050000, 0x02040000, 0x02050000,
  1808. 0x00040020, 0x00050020, 0x02040020, 0x02050020,
  1809. 0x00002000, 0x00012000, 0x02002000, 0x02012000,
  1810. 0x00002020, 0x00012020, 0x02002020, 0x02012020,
  1811. 0x00042000, 0x00052000, 0x02042000, 0x02052000,
  1812. 0x00042020, 0x00052020, 0x02042020, 0x02052020,
  1813. 0x00000000, 0x00010000, 0x02000000, 0x02010000,
  1814. 0x00000020, 0x00010020, 0x02000020, 0x02010020,
  1815. 0x00040000, 0x00050000, 0x02040000, 0x02050000,
  1816. 0x00040020, 0x00050020, 0x02040020, 0x02050020,
  1817. 0x00002000, 0x00012000, 0x02002000, 0x02012000,
  1818. 0x00002020, 0x00012020, 0x02002020, 0x02012020,
  1819. 0x00042000, 0x00052000, 0x02042000, 0x02052000,
  1820. 0x00042020, 0x00052020, 0x02042020, 0x02052020,
  1821. 0x00000010, 0x00010010, 0x02000010, 0x02010010,
  1822. 0x00000030, 0x00010030, 0x02000030, 0x02010030,
  1823. 0x00040010, 0x00050010, 0x02040010, 0x02050010,
  1824. 0x00040030, 0x00050030, 0x02040030, 0x02050030,
  1825. 0x00002010, 0x00012010, 0x02002010, 0x02012010,
  1826. 0x00002030, 0x00012030, 0x02002030, 0x02012030,
  1827. 0x00042010, 0x00052010, 0x02042010, 0x02052010,
  1828. 0x00042030, 0x00052030, 0x02042030, 0x02052030,
  1829. 0x00000010, 0x00010010, 0x02000010, 0x02010010,
  1830. 0x00000030, 0x00010030, 0x02000030, 0x02010030,
  1831. 0x00040010, 0x00050010, 0x02040010, 0x02050010,
  1832. 0x00040030, 0x00050030, 0x02040030, 0x02050030,
  1833. 0x00002010, 0x00012010, 0x02002010, 0x02012010,
  1834. 0x00002030, 0x00012030, 0x02002030, 0x02012030,
  1835. 0x00042010, 0x00052010, 0x02042010, 0x02052010,
  1836. 0x00042030, 0x00052030, 0x02042030, 0x02052030,
  1837. 0x20000000, 0x20010000, 0x22000000, 0x22010000,
  1838. 0x20000020, 0x20010020, 0x22000020, 0x22010020,
  1839. 0x20040000, 0x20050000, 0x22040000, 0x22050000,
  1840. 0x20040020, 0x20050020, 0x22040020, 0x22050020,
  1841. 0x20002000, 0x20012000, 0x22002000, 0x22012000,
  1842. 0x20002020, 0x20012020, 0x22002020, 0x22012020,
  1843. 0x20042000, 0x20052000, 0x22042000, 0x22052000,
  1844. 0x20042020, 0x20052020, 0x22042020, 0x22052020,
  1845. 0x20000000, 0x20010000, 0x22000000, 0x22010000,
  1846. 0x20000020, 0x20010020, 0x22000020, 0x22010020,
  1847. 0x20040000, 0x20050000, 0x22040000, 0x22050000,
  1848. 0x20040020, 0x20050020, 0x22040020, 0x22050020,
  1849. 0x20002000, 0x20012000, 0x22002000, 0x22012000,
  1850. 0x20002020, 0x20012020, 0x22002020, 0x22012020,
  1851. 0x20042000, 0x20052000, 0x22042000, 0x22052000,
  1852. 0x20042020, 0x20052020, 0x22042020, 0x22052020,
  1853. 0x20000010, 0x20010010, 0x22000010, 0x22010010,
  1854. 0x20000030, 0x20010030, 0x22000030, 0x22010030,
  1855. 0x20040010, 0x20050010, 0x22040010, 0x22050010,
  1856. 0x20040030, 0x20050030, 0x22040030, 0x22050030,
  1857. 0x20002010, 0x20012010, 0x22002010, 0x22012010,
  1858. 0x20002030, 0x20012030, 0x22002030, 0x22012030,
  1859. 0x20042010, 0x20052010, 0x22042010, 0x22052010,
  1860. 0x20042030, 0x20052030, 0x22042030, 0x22052030,
  1861. 0x20000010, 0x20010010, 0x22000010, 0x22010010,
  1862. 0x20000030, 0x20010030, 0x22000030, 0x22010030,
  1863. 0x20040010, 0x20050010, 0x22040010, 0x22050010,
  1864. 0x20040030, 0x20050030, 0x22040030, 0x22050030,
  1865. 0x20002010, 0x20012010, 0x22002010, 0x22012010,
  1866. 0x20002030, 0x20012030, 0x22002030, 0x22012030,
  1867. 0x20042010, 0x20052010, 0x22042010, 0x22052010,
  1868. 0x20042030, 0x20052030, 0x22042030, 0x22052030
  1869. );
  1870. static $pc2mapd4 = array(
  1871. 0x00000000, 0x00000400, 0x01000000, 0x01000400,
  1872. 0x00000000, 0x00000400, 0x01000000, 0x01000400,
  1873. 0x00000100, 0x00000500, 0x01000100, 0x01000500,
  1874. 0x00000100, 0x00000500, 0x01000100, 0x01000500,
  1875. 0x10000000, 0x10000400, 0x11000000, 0x11000400,
  1876. 0x10000000, 0x10000400, 0x11000000, 0x11000400,
  1877. 0x10000100, 0x10000500, 0x11000100, 0x11000500,
  1878. 0x10000100, 0x10000500, 0x11000100, 0x11000500,
  1879. 0x00080000, 0x00080400, 0x01080000, 0x01080400,
  1880. 0x00080000, 0x00080400, 0x01080000, 0x01080400,
  1881. 0x00080100, 0x00080500, 0x01080100, 0x01080500,
  1882. 0x00080100, 0x00080500, 0x01080100, 0x01080500,
  1883. 0x10080000, 0x10080400, 0x11080000, 0x11080400,
  1884. 0x10080000, 0x10080400, 0x11080000, 0x11080400,
  1885. 0x10080100, 0x10080500, 0x11080100, 0x11080500,
  1886. 0x10080100, 0x10080500, 0x11080100, 0x11080500,
  1887. 0x00000008, 0x00000408, 0x01000008, 0x01000408,
  1888. 0x00000008, 0x00000408, 0x01000008, 0x01000408,
  1889. 0x00000108, 0x00000508, 0x01000108, 0x01000508,
  1890. 0x00000108, 0x00000508, 0x01000108, 0x01000508,
  1891. 0x10000008, 0x10000408, 0x11000008, 0x11000408,
  1892. 0x10000008, 0x10000408, 0x11000008, 0x11000408,
  1893. 0x10000108, 0x10000508, 0x11000108, 0x11000508,
  1894. 0x10000108, 0x10000508, 0x11000108, 0x11000508,
  1895. 0x00080008, 0x00080408, 0x01080008, 0x01080408,
  1896. 0x00080008, 0x00080408, 0x01080008, 0x01080408,
  1897. 0x00080108, 0x00080508, 0x01080108, 0x01080508,
  1898. 0x00080108, 0x00080508, 0x01080108, 0x01080508,
  1899. 0x10080008, 0x10080408, 0x11080008, 0x11080408,
  1900. 0x10080008, 0x10080408, 0x11080008, 0x11080408,
  1901. 0x10080108, 0x10080508, 0x11080108, 0x11080508,
  1902. 0x10080108, 0x10080508, 0x11080108, 0x11080508,
  1903. 0x00001000, 0x00001400, 0x01001000, 0x01001400,
  1904. 0x00001000, 0x00001400, 0x01001000, 0x01001400,
  1905. 0x00001100, 0x00001500, 0x01001100, 0x01001500,
  1906. 0x00001100, 0x00001500, 0x01001100, 0x01001500,
  1907. 0x10001000, 0x10001400, 0x11001000, 0x11001400,
  1908. 0x10001000, 0x10001400, 0x11001000, 0x11001400,
  1909. 0x10001100, 0x10001500, 0x11001100, 0x11001500,
  1910. 0x10001100, 0x10001500, 0x11001100, 0x11001500,
  1911. 0x00081000, 0x00081400, 0x01081000, 0x01081400,
  1912. 0x00081000, 0x00081400, 0x01081000, 0x01081400,
  1913. 0x00081100, 0x00081500, 0x01081100, 0x01081500,
  1914. 0x00081100, 0x00081500, 0x01081100, 0x01081500,
  1915. 0x10081000, 0x10081400, 0x11081000, 0x11081400,
  1916. 0x10081000, 0x10081400, 0x11081000, 0x11081400,
  1917. 0x10081100, 0x10081500, 0x11081100, 0x11081500,
  1918. 0x10081100, 0x10081500, 0x11081100, 0x11081500,
  1919. 0x00001008, 0x00001408, 0x01001008, 0x01001408,
  1920. 0x00001008, 0x00001408, 0x01001008, 0x01001408,
  1921. 0x00001108, 0x00001508, 0x01001108, 0x01001508,
  1922. 0x00001108, 0x00001508, 0x01001108, 0x01001508,
  1923. 0x10001008, 0x10001408, 0x11001008, 0x11001408,
  1924. 0x10001008, 0x10001408, 0x11001008, 0x11001408,
  1925. 0x10001108, 0x10001508, 0x11001108, 0x11001508,
  1926. 0x10001108, 0x10001508, 0x11001108, 0x11001508,
  1927. 0x00081008, 0x00081408, 0x01081008, 0x01081408,
  1928. 0x00081008, 0x00081408, 0x01081008, 0x01081408,
  1929. 0x00081108, 0x00081508, 0x01081108, 0x01081508,
  1930. 0x00081108, 0x00081508, 0x01081108, 0x01081508,
  1931. 0x10081008, 0x10081408, 0x11081008, 0x11081408,
  1932. 0x10081008, 0x10081408, 0x11081008, 0x11081408,
  1933. 0x10081108, 0x10081508, 0x11081108, 0x11081508,
  1934. 0x10081108, 0x10081508, 0x11081108, 0x11081508
  1935. );
  1936. // pad the key and remove extra characters as appropriate.
  1937. $key = str_pad(substr($key, 0, 8), 8, chr(0));
  1938. // Perform the PC/1 transformation and compute C and D.
  1939. $t = unpack('Nl/Nr', $key);
  1940. list($l, $r) = array($t['l'], $t['r']);
  1941. $key = ($this->shuffle[$pc1map[$r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x00") |
  1942. ($this->shuffle[$pc1map[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x00") |
  1943. ($this->shuffle[$pc1map[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x00") |
  1944. ($this->shuffle[$pc1map[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x00") |
  1945. ($this->shuffle[$pc1map[$l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x00") |
  1946. ($this->shuffle[$pc1map[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x00") |
  1947. ($this->shuffle[$pc1map[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x00") |
  1948. ($this->shuffle[$pc1map[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x00");
  1949. $key = unpack('Nc/Nd', $key);
  1950. $c = ($key['c'] >> 4) & 0x0FFFFFFF;
  1951. $d = (($key['d'] >> 4) & 0x0FFFFFF0) | ($key['c'] & 0x0F);
  1952. $keys = array();
  1953. for ($i = 0; $i < 16; $i++) {
  1954. $c <<= $shifts[$i];
  1955. $c = ($c | ($c >> 28)) & 0x0FFFFFFF;
  1956. $d <<= $shifts[$i];
  1957. $d = ($d | ($d >> 28)) & 0x0FFFFFFF;
  1958. // Perform the PC-2 transformation.
  1959. $cp = $pc2mapc1[$c >> 24] | $pc2mapc2[($c >> 16) & 0xFF] |
  1960. $pc2mapc3[($c >> 8) & 0xFF] | $pc2mapc4[$c & 0xFF];
  1961. $dp = $pc2mapd1[$d >> 24] | $pc2mapd2[($d >> 16) & 0xFF] |
  1962. $pc2mapd3[($d >> 8) & 0xFF] | $pc2mapd4[$d & 0xFF];
  1963. // Reorder: odd bytes/even bytes. Push the result in key schedule.
  1964. $keys[] = array(
  1965. ($cp & 0xFF000000) | (($cp << 8) & 0x00FF0000) |
  1966. (($dp >> 16) & 0x0000FF00) | (($dp >> 8) & 0x000000FF),
  1967. (($cp << 8) & 0xFF000000) | (($cp << 16) & 0x00FF0000) |
  1968. (($dp >> 8) & 0x0000FF00) | ($dp & 0x000000FF)
  1969. );
  1970. }
  1971. $keys = array(
  1972. CRYPT_DES_ENCRYPT => $keys,
  1973. CRYPT_DES_DECRYPT => array_reverse($keys),
  1974. CRYPT_DES_ENCRYPT_1DIM => array(),
  1975. CRYPT_DES_DECRYPT_1DIM => array()
  1976. );
  1977. // Generate 1-dim arrays for inline en/decrypting
  1978. for ($i = 0; $i < 16; ++$i) {
  1979. $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][0];
  1980. $keys[CRYPT_DES_ENCRYPT_1DIM][] = $keys[CRYPT_DES_ENCRYPT][$i][1];
  1981. $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][0];
  1982. $keys[CRYPT_DES_DECRYPT_1DIM][] = $keys[CRYPT_DES_DECRYPT][$i][1];
  1983. }
  1984. return $keys;
  1985. }
  1986. /**
  1987. * String Shift
  1988. *
  1989. * Inspired by array_shift
  1990. *
  1991. * @param String $string
  1992. * @return String
  1993. * @access private
  1994. */
  1995. function _string_shift(&$string)
  1996. {
  1997. $substr = substr($string, 0, 8);
  1998. $string = substr($string, 8);
  1999. return $substr;
  2000. }
  2001. /**
  2002. * Creates performance-optimized function for de/encrypt(), storing it in $this->inline_crypt
  2003. *
  2004. * @param optional Integer $des_rounds (1 = DES[default], 3 = TribleDES)
  2005. * @access private
  2006. */
  2007. function inline_crypt_setup($des_rounds = 1)
  2008. {
  2009. $lambda_functions =& Crypt_DES::get_lambda_functions();
  2010. $block_size = 8;
  2011. $mode = $this->mode;
  2012. $code_hash = "$mode,$des_rounds";
  2013. if (!isset($lambda_functions[$code_hash])) {
  2014. // Generating encrypt code:
  2015. $ki = -1;
  2016. $init_cryptBlock = '
  2017. $shuffle = $self->shuffle;
  2018. $invipmap = $self->invipmap;
  2019. $ipmap = $self->ipmap;
  2020. $sbox1 = $self->sbox1;
  2021. $sbox2 = $self->sbox2;
  2022. $sbox3 = $self->sbox3;
  2023. $sbox4 = $self->sbox4;
  2024. $sbox5 = $self->sbox5;
  2025. $sbox6 = $self->sbox6;
  2026. $sbox7 = $self->sbox7;
  2027. $sbox8 = $self->sbox8;
  2028. ';
  2029. $_cryptBlock = '$in = unpack("N*", $in);'."\n";
  2030. // Do the initial IP permutation.
  2031. $_cryptBlock .= '
  2032. $l = $in[1];
  2033. $r = $in[2];
  2034. $in = unpack("N*",
  2035. ($shuffle[$ipmap[ $r & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  2036. ($shuffle[$ipmap[($r >> 8) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  2037. ($shuffle[$ipmap[($r >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  2038. ($shuffle[$ipmap[($r >> 24) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  2039. ($shuffle[$ipmap[ $l & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  2040. ($shuffle[$ipmap[($l >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  2041. ($shuffle[$ipmap[($l >> 16) & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  2042. ($shuffle[$ipmap[($l >> 24) & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
  2043. );
  2044. '.'' /* Extract L0 and R0 */ .'
  2045. $l = $in[1];
  2046. $r = $in[2];
  2047. ';
  2048. $l = 'l';
  2049. $r = 'r';
  2050. for ($des_round = 0; $des_round < $des_rounds; ++$des_round) {
  2051. // Perform the 16 steps.
  2052. // start of "the Feistel (F) function" - see the following URL:
  2053. // http://en.wikipedia.org/wiki/Image:Data_Encryption_Standard_InfoBox_Diagram.png
  2054. // Merge key schedule.
  2055. for ($i = 0; $i < 8; ++$i) {
  2056. $_cryptBlock .= '
  2057. $b1 = (($' . $r . ' >> 3) & 0x1FFFFFFF) ^ ($' . $r . ' << 29) ^ $k_'.(++$ki).';
  2058. $b2 = (($' . $r . ' >> 31) & 0x00000001) ^ ($' . $r . ' << 1) ^ $k_'.(++$ki).';
  2059. $' . $l . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
  2060. $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
  2061. $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
  2062. $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $l . ';
  2063. $b1 = (($' . $l . ' >> 3) & 0x1FFFFFFF) ^ ($' . $l . ' << 29) ^ $k_'.(++$ki).';
  2064. $b2 = (($' . $l . ' >> 31) & 0x00000001) ^ ($' . $l . ' << 1) ^ $k_'.(++$ki).';
  2065. $' . $r . ' = $sbox1[($b1 >> 24) & 0x3F] ^ $sbox2[($b2 >> 24) & 0x3F] ^
  2066. $sbox3[($b1 >> 16) & 0x3F] ^ $sbox4[($b2 >> 16) & 0x3F] ^
  2067. $sbox5[($b1 >> 8) & 0x3F] ^ $sbox6[($b2 >> 8) & 0x3F] ^
  2068. $sbox7[ $b1 & 0x3F] ^ $sbox8[ $b2 & 0x3F] ^ $' . $r . ';
  2069. ';
  2070. }
  2071. // Last step should not permute L & R.
  2072. $t = $l;
  2073. $l = $r;
  2074. $r = $t;
  2075. }
  2076. // Perform the inverse IP permutation.
  2077. $_cryptBlock .= '$in = (
  2078. ($shuffle[$invipmap[($' . $r . ' >> 24) & 0xFF]] & "\x80\x80\x80\x80\x80\x80\x80\x80") |
  2079. ($shuffle[$invipmap[($' . $l . ' >> 24) & 0xFF]] & "\x40\x40\x40\x40\x40\x40\x40\x40") |
  2080. ($shuffle[$invipmap[($' . $r . ' >> 16) & 0xFF]] & "\x20\x20\x20\x20\x20\x20\x20\x20") |
  2081. ($shuffle[$invipmap[($' . $l . ' >> 16) & 0xFF]] & "\x10\x10\x10\x10\x10\x10\x10\x10") |
  2082. ($shuffle[$invipmap[($' . $r . ' >> 8) & 0xFF]] & "\x08\x08\x08\x08\x08\x08\x08\x08") |
  2083. ($shuffle[$invipmap[($' . $l . ' >> 8) & 0xFF]] & "\x04\x04\x04\x04\x04\x04\x04\x04") |
  2084. ($shuffle[$invipmap[ $' . $r . ' & 0xFF]] & "\x02\x02\x02\x02\x02\x02\x02\x02") |
  2085. ($shuffle[$invipmap[ $' . $l . ' & 0xFF]] & "\x01\x01\x01\x01\x01\x01\x01\x01")
  2086. );
  2087. ';
  2088. // Generating mode of operation code:
  2089. switch ($mode) {
  2090. case CRYPT_DES_MODE_ECB:
  2091. $encrypt = $init_cryptBlock . '
  2092. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2093. $ciphertext = "";
  2094. $plaintext_len = strlen($text);
  2095. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2096. $in = substr($text, $i, '.$block_size.');
  2097. '.$_cryptBlock.'
  2098. $ciphertext.= $in;
  2099. }
  2100. return $ciphertext;
  2101. ';
  2102. $decrypt = $init_cryptBlock . '
  2103. extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2104. $plaintext = "";
  2105. $ciphertext_len = strlen($text);
  2106. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2107. $in = substr($text, $i, '.$block_size.');
  2108. '.$_cryptBlock.'
  2109. $plaintext.= $in;
  2110. }
  2111. return $self->_unpad($plaintext);
  2112. ';
  2113. break;
  2114. case CRYPT_DES_MODE_CBC:
  2115. $encrypt = $init_cryptBlock . '
  2116. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2117. $ciphertext = "";
  2118. $plaintext_len = strlen($text);
  2119. $in = $self->encryptIV;
  2120. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2121. $in = substr($text, $i, '.$block_size.') ^ $in;
  2122. '.$_cryptBlock.'
  2123. $ciphertext.= $in;
  2124. }
  2125. if ($self->continuousBuffer) {
  2126. $self->encryptIV = $in;
  2127. }
  2128. return $ciphertext;
  2129. ';
  2130. $decrypt = $init_cryptBlock . '
  2131. extract($self->keys[CRYPT_DES_DECRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2132. $plaintext = "";
  2133. $ciphertext_len = strlen($text);
  2134. $iv = $self->decryptIV;
  2135. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2136. $in = $block = substr($text, $i, '.$block_size.');
  2137. '.$_cryptBlock.'
  2138. $plaintext.= $in ^ $iv;
  2139. $iv = $block;
  2140. }
  2141. if ($self->continuousBuffer) {
  2142. $self->decryptIV = $iv;
  2143. }
  2144. return $self->_unpad($plaintext);
  2145. ';
  2146. break;
  2147. case CRYPT_DES_MODE_CTR:
  2148. $encrypt = $init_cryptBlock . '
  2149. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2150. $ciphertext = "";
  2151. $plaintext_len = strlen($text);
  2152. $xor = $self->encryptIV;
  2153. $buffer = &$self->enbuffer;
  2154. if (strlen($buffer["encrypted"])) {
  2155. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2156. $block = substr($text, $i, '.$block_size.');
  2157. if (strlen($block) > strlen($buffer["encrypted"])) {
  2158. $in = $self->_generate_xor($xor);
  2159. '.$_cryptBlock.'
  2160. $buffer["encrypted"].= $in;
  2161. }
  2162. $key = $self->_string_shift($buffer["encrypted"]);
  2163. $ciphertext.= $block ^ $key;
  2164. }
  2165. } else {
  2166. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2167. $block = substr($text, $i, '.$block_size.');
  2168. $in = $self->_generate_xor($xor);
  2169. '.$_cryptBlock.'
  2170. $key = $in;
  2171. $ciphertext.= $block ^ $key;
  2172. }
  2173. }
  2174. if ($self->continuousBuffer) {
  2175. $self->encryptIV = $xor;
  2176. if ($start = $plaintext_len % '.$block_size.') {
  2177. $buffer["encrypted"] = substr($key, $start) . $buffer["encrypted"];
  2178. }
  2179. }
  2180. return $ciphertext;
  2181. ';
  2182. $decrypt = $init_cryptBlock . '
  2183. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2184. $plaintext = "";
  2185. $ciphertext_len = strlen($text);
  2186. $xor = $self->decryptIV;
  2187. $buffer = &$self->debuffer;
  2188. if (strlen($buffer["ciphertext"])) {
  2189. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2190. $block = substr($text, $i, '.$block_size.');
  2191. if (strlen($block) > strlen($buffer["ciphertext"])) {
  2192. $in = $self->_generate_xor($xor);
  2193. '.$_cryptBlock.'
  2194. $buffer["ciphertext"].= $in;
  2195. }
  2196. $key = $self->_string_shift($buffer["ciphertext"]);
  2197. $plaintext.= $block ^ $key;
  2198. }
  2199. } else {
  2200. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2201. $block = substr($text, $i, '.$block_size.');
  2202. $in = $self->_generate_xor($xor);
  2203. '.$_cryptBlock.'
  2204. $key = $in;
  2205. $plaintext.= $block ^ $key;
  2206. }
  2207. }
  2208. if ($self->continuousBuffer) {
  2209. $self->decryptIV = $xor;
  2210. if ($start = $ciphertext_len % '.$block_size.') {
  2211. $buffer["ciphertext"] = substr($key, $start) . $buffer["ciphertext"];
  2212. }
  2213. }
  2214. return $plaintext;
  2215. ';
  2216. break;
  2217. case CRYPT_DES_MODE_CFB:
  2218. $encrypt = $init_cryptBlock . '
  2219. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2220. $ciphertext = "";
  2221. $buffer = &$self->enbuffer;
  2222. if ($self->continuousBuffer) {
  2223. $iv = &$self->encryptIV;
  2224. $pos = &$buffer["pos"];
  2225. } else {
  2226. $iv = $self->encryptIV;
  2227. $pos = 0;
  2228. }
  2229. $len = strlen($text);
  2230. $i = 0;
  2231. if ($pos) {
  2232. $orig_pos = $pos;
  2233. $max = '.$block_size.' - $pos;
  2234. if ($len >= $max) {
  2235. $i = $max;
  2236. $len-= $max;
  2237. $pos = 0;
  2238. } else {
  2239. $i = $len;
  2240. $pos+= $len;
  2241. $len = 0;
  2242. }
  2243. $ciphertext = substr($iv, $orig_pos) ^ $text;
  2244. $iv = substr_replace($iv, $ciphertext, $orig_pos, $i);
  2245. }
  2246. while ($len >= '.$block_size.') {
  2247. $in = $iv;
  2248. '.$_cryptBlock.';
  2249. $iv = $in ^ substr($text, $i, '.$block_size.');
  2250. $ciphertext.= $iv;
  2251. $len-= '.$block_size.';
  2252. $i+= '.$block_size.';
  2253. }
  2254. if ($len) {
  2255. $in = $iv;
  2256. '.$_cryptBlock.'
  2257. $iv = $in;
  2258. $block = $iv ^ substr($text, $i);
  2259. $iv = substr_replace($iv, $block, 0, $len);
  2260. $ciphertext.= $block;
  2261. $pos = $len;
  2262. }
  2263. return $ciphertext;
  2264. ';
  2265. $decrypt = $init_cryptBlock . '
  2266. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2267. $plaintext = "";
  2268. $buffer = &$self->debuffer;
  2269. if ($self->continuousBuffer) {
  2270. $iv = &$self->decryptIV;
  2271. $pos = &$buffer["pos"];
  2272. } else {
  2273. $iv = $self->decryptIV;
  2274. $pos = 0;
  2275. }
  2276. $len = strlen($text);
  2277. $i = 0;
  2278. if ($pos) {
  2279. $orig_pos = $pos;
  2280. $max = '.$block_size.' - $pos;
  2281. if ($len >= $max) {
  2282. $i = $max;
  2283. $len-= $max;
  2284. $pos = 0;
  2285. } else {
  2286. $i = $len;
  2287. $pos+= $len;
  2288. $len = 0;
  2289. }
  2290. $plaintext = substr($iv, $orig_pos) ^ $text;
  2291. $iv = substr_replace($iv, substr($text, 0, $i), $orig_pos, $i);
  2292. }
  2293. while ($len >= '.$block_size.') {
  2294. $in = $iv;
  2295. '.$_cryptBlock.'
  2296. $iv = $in;
  2297. $cb = substr($text, $i, '.$block_size.');
  2298. $plaintext.= $iv ^ $cb;
  2299. $iv = $cb;
  2300. $len-= '.$block_size.';
  2301. $i+= '.$block_size.';
  2302. }
  2303. if ($len) {
  2304. $in = $iv;
  2305. '.$_cryptBlock.'
  2306. $iv = $in;
  2307. $plaintext.= $iv ^ substr($text, $i);
  2308. $iv = substr_replace($iv, substr($text, $i), 0, $len);
  2309. $pos = $len;
  2310. }
  2311. return $plaintext;
  2312. ';
  2313. break;
  2314. case CRYPT_DES_MODE_OFB:
  2315. $encrypt = $init_cryptBlock . '
  2316. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2317. $ciphertext = "";
  2318. $plaintext_len = strlen($text);
  2319. $xor = $self->encryptIV;
  2320. $buffer = &$self->enbuffer;
  2321. if (strlen($buffer["xor"])) {
  2322. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2323. $block = substr($text, $i, '.$block_size.');
  2324. if (strlen($block) > strlen($buffer["xor"])) {
  2325. $in = $xor;
  2326. '.$_cryptBlock.'
  2327. $xor = $in;
  2328. $buffer["xor"].= $xor;
  2329. }
  2330. $key = $self->_string_shift($buffer["xor"]);
  2331. $ciphertext.= $block ^ $key;
  2332. }
  2333. } else {
  2334. for ($i = 0; $i < $plaintext_len; $i+= '.$block_size.') {
  2335. $in = $xor;
  2336. '.$_cryptBlock.'
  2337. $xor = $in;
  2338. $ciphertext.= substr($text, $i, '.$block_size.') ^ $xor;
  2339. }
  2340. $key = $xor;
  2341. }
  2342. if ($self->continuousBuffer) {
  2343. $self->encryptIV = $xor;
  2344. if ($start = $plaintext_len % '.$block_size.') {
  2345. $buffer["xor"] = substr($key, $start) . $buffer["xor"];
  2346. }
  2347. }
  2348. return $ciphertext;
  2349. ';
  2350. $decrypt = $init_cryptBlock . '
  2351. extract($self->keys[CRYPT_DES_ENCRYPT_1DIM], EXTR_PREFIX_ALL, "k");
  2352. $plaintext = "";
  2353. $ciphertext_len = strlen($text);
  2354. $xor = $self->decryptIV;
  2355. $buffer = &$self->debuffer;
  2356. if (strlen($buffer["xor"])) {
  2357. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2358. $block = substr($text, $i, '.$block_size.');
  2359. if (strlen($block) > strlen($buffer["xor"])) {
  2360. $in = $xor;
  2361. '.$_cryptBlock.'
  2362. $xor = $in;
  2363. $buffer["xor"].= $xor;
  2364. }
  2365. $key = $self->_string_shift($buffer["xor"]);
  2366. $plaintext.= $block ^ $key;
  2367. }
  2368. } else {
  2369. for ($i = 0; $i < $ciphertext_len; $i+= '.$block_size.') {
  2370. $in = $xor;
  2371. '.$_cryptBlock.'
  2372. $xor = $in;
  2373. $plaintext.= substr($text, $i, '.$block_size.') ^ $xor;
  2374. }
  2375. $key = $xor;
  2376. }
  2377. if ($self->continuousBuffer) {
  2378. $self->decryptIV = $xor;
  2379. if ($start = $ciphertext_len % '.$block_size.') {
  2380. $buffer["xor"] = substr($key, $start) . $buffer["xor"];
  2381. }
  2382. }
  2383. return $plaintext;
  2384. ';
  2385. break;
  2386. }
  2387. $lambda_functions[$code_hash] = create_function('$action, &$self, $text', 'if ($action == "encrypt") { '.$encrypt.' } else { '.$decrypt.' }');
  2388. }
  2389. $this->inline_crypt = $lambda_functions[$code_hash];
  2390. }
  2391. /**
  2392. * Holds the lambda_functions table (classwide)
  2393. *
  2394. * @see inline_crypt_setup()
  2395. * @return Array
  2396. * @access private
  2397. */
  2398. function &get_lambda_functions()
  2399. {
  2400. static $functions = array();
  2401. return $functions;
  2402. }
  2403. }
  2404. // vim: ts=4:sw=4:et:
  2405. // vim6: fdl=1: