Commit | Line | Data |
---|---|---|
14d4f286 S |
1 | <?php |
2 | /** | |
3 | * An implementation of the DES cipher, using the phpseclib implementation | |
4 | * | |
5 | * This was forked from phpseclib and modified to use CryptLib conventions | |
6 | * | |
7 | * PHP version 5.3 | |
8 | * | |
9 | * @category PHPCryptLib | |
10 | * @package Cipher | |
11 | * @subpackage Block | |
12 | * @author Anthony Ferrara <ircmaxell@ircmaxell.com> | |
13 | * @author Jim Wigginton <terrafrost@php.net> | |
14 | * @copyright 2011 The Authors | |
15 | * @license http://www.opensource.org/licenses/mit-license.html MIT License | |
16 | * @version Build @@version@@ | |
17 | */ | |
18 | ||
19 | namespace CryptLib\Cipher\Block\Cipher; | |
20 | ||
21 | /** | |
22 | * An implementation of the DES cipher, using the phpseclib implementation | |
23 | * | |
24 | * @category PHPCryptLib | |
25 | * @package Cipher | |
26 | * @subpackage Block | |
27 | * @author Anthony Ferrara <ircmaxell@ircmaxell.com> | |
28 | */ | |
29 | class DES extends \CryptLib\Cipher\Block\AbstractCipher { | |
30 | ||
31 | /** | |
32 | * @var int The block size for the cipher | |
33 | */ | |
34 | protected $blockSize = 8; | |
35 | ||
36 | /** | |
37 | * @var int The key size for the cipher | |
38 | */ | |
39 | protected $keySize = 8; | |
40 | ||
41 | /** | |
42 | * @var array The prepared key schedule | |
43 | */ | |
44 | protected $preparedKeys = array(); | |
45 | ||
46 | /** | |
47 | * In the official DES docs, they're described as being matrices that one | |
48 | * accesses by using the first and last bits to determine the row and the | |
49 | * middle four bits to determine the column. in this implementation, | |
50 | * they've been converted to vectors | |
51 | * | |
52 | * @var array The S-boxes | |
53 | */ | |
54 | protected static $sbox = array( | |
55 | array( | |
56 | 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, | |
57 | 3, 10 ,10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8, | |
58 | 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, | |
59 | 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13 | |
60 | ), | |
61 | array( | |
62 | 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14, | |
63 | 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, | |
64 | 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2, | |
65 | 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9 | |
66 | ), | |
67 | array( | |
68 | 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10, | |
69 | 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, | |
70 | 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, | |
71 | 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12 | |
72 | ), | |
73 | array( | |
74 | 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, | |
75 | 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9, | |
76 | 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, | |
77 | 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14 | |
78 | ), | |
79 | array( | |
80 | 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1, | |
81 | 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, | |
82 | 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13, | |
83 | 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3 | |
84 | ), | |
85 | array( | |
86 | 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5, | |
87 | 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8, | |
88 | 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, | |
89 | 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13 | |
90 | ), | |
91 | array( | |
92 | 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, | |
93 | 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6, | |
94 | 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7, | |
95 | 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12 | |
96 | ), | |
97 | array( | |
98 | 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4, | |
99 | 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, | |
100 | 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, | |
101 | 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11 | |
102 | ) | |
103 | ); | |
104 | ||
105 | /** | |
106 | * @var array The key shift sequence for shifts per round of DES block | |
107 | */ | |
108 | protected static $keyShifts = array( | |
109 | 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 | |
110 | ); | |
111 | ||
112 | /** | |
113 | * Get a list of supported ciphers for this class implementation | |
114 | * | |
115 | * @return array A list of supported ciphers | |
116 | */ | |
117 | public static function getSupportedCiphers() { | |
118 | return array('des'); | |
119 | } | |
120 | ||
121 | /** | |
122 | * Decrypt a block of data using the supplied string key | |
123 | * | |
124 | * Note that the supplied data should be the same size as the block size of | |
125 | * the cipher being used. | |
126 | * | |
127 | * @param string $data The data to decrypt | |
128 | * | |
129 | * @return string The result decrypted data | |
130 | */ | |
131 | protected function decryptBlockData($data) { | |
132 | $keys = array_reverse($this->preparedKeys); | |
133 | return $this->processBlock($data, $keys); | |
134 | } | |
135 | ||
136 | /** | |
137 | * Encrypt a block of data using the supplied string key | |
138 | * | |
139 | * Note that the supplied data should be the same size as the block size of | |
140 | * the cipher being used. | |
141 | * | |
142 | * @param string $data The data to encrypt | |
143 | * | |
144 | * @return string The result encrypted data | |
145 | */ | |
146 | protected function encryptBlockData($data) { | |
147 | return $this->processBlock($data, $this->preparedKeys); | |
148 | } | |
149 | ||
150 | /** | |
151 | * Initialize the cipher by preparing the key | |
152 | * | |
153 | * @return boolean The status of the initialization | |
154 | */ | |
155 | protected function initialize() { | |
156 | $this->preparedKeys = $this->prepareKey($this->key); | |
157 | return true; | |
158 | } | |
159 | ||
160 | /** | |
161 | * Compute the keys necessary to execute the block cipher | |
162 | * | |
163 | * @param string $key The key to prepare | |
164 | * | |
165 | * @return array The prepared keys | |
166 | */ | |
167 | private function prepareKey($key) { | |
168 | // pad the key and remove extra characters as appropriate. | |
169 | $key = str_pad(substr($key, 0, 8), 8, chr(0)); | |
170 | ||
171 | $temp = unpack('Na/Nb', $key); | |
172 | $key = array($temp['a'], $temp['b']); | |
173 | $msb = array( | |
174 | ($key[0] >> 31) & 1, | |
175 | ($key[1] >> 31) & 1 | |
176 | ); | |
177 | $key[0] &= 0x7FFFFFFF; | |
178 | $key[1] &= 0x7FFFFFFF; | |
179 | ||
180 | $key = array( | |
181 | (($key[1] & 0x00000002) << 26) | (($key[1] & 0x00000204) << 17) | | |
182 | (($key[1] & 0x00020408) << 8) | (($key[1] & 0x02040800) >> 1) | | |
183 | (($key[0] & 0x00000002) << 22) | (($key[0] & 0x00000204) << 13) | | |
184 | (($key[0] & 0x00020408) << 4) | (($key[0] & 0x02040800) >> 5) | | |
185 | (($key[1] & 0x04080000) >> 10) | (($key[0] & 0x04080000) >> 14) | | |
186 | (($key[1] & 0x08000000) >> 19) | (($key[0] & 0x08000000) >> 23) | | |
187 | (($key[0] & 0x00000010) >> 1) | (($key[0] & 0x00001000) >> 10) | | |
188 | (($key[0] & 0x00100000) >> 19) | (($key[0] & 0x10000000) >> 28), | |
189 | (($key[1] & 0x00000080) << 20) | (($key[1] & 0x00008000) << 11) | | |
190 | (($key[1] & 0x00800000) << 2) | (($key[0] & 0x00000080) << 16) | | |
191 | (($key[0] & 0x00008000) << 7) | (($key[0] & 0x00800000) >> 2) | | |
192 | (($key[1] & 0x00000040) << 13) | (($key[1] & 0x00004000) << 4) | | |
193 | (($key[1] & 0x00400000) >> 5) | (($key[1] & 0x40000000) >> 14) | | |
194 | (($key[0] & 0x00000040) << 9) | ( $key[0] & 0x00004000 ) | | |
195 | (($key[0] & 0x00400000) >> 9) | (($key[0] & 0x40000000) >> 18) | | |
196 | (($key[1] & 0x00000020) << 6) | (($key[1] & 0x00002000) >> 3) | | |
197 | (($key[1] & 0x00200000) >> 12) | (($key[1] & 0x20000000) >> 21) | | |
198 | (($key[0] & 0x00000020) << 2) | (($key[0] & 0x00002000) >> 7) | | |
199 | (($key[0] & 0x00200000) >> 16) | (($key[0] & 0x20000000) >> 25) | | |
200 | (($key[1] & 0x00000010) >> 1) | (($key[1] & 0x00001000) >> 10) | | |
201 | (($key[1] & 0x00100000) >> 19) | (($key[1] & 0x10000000) >> 28) | | |
202 | ($msb[1] << 24) | ($msb[0] << 20) | |
203 | ); | |
204 | ||
205 | $keys = array(); | |
206 | for ($i = 0; $i < 16; $i++) { | |
207 | $key[0] <<= static::$keyShifts[$i]; | |
208 | $temp = ($key[0] & 0xF0000000) >> 28; | |
209 | $key[0] = ($key[0] | $temp) & 0x0FFFFFFF; | |
210 | ||
211 | $key[1] <<= static::$keyShifts[$i]; | |
212 | $temp = ($key[1] & 0xF0000000) >> 28; | |
213 | $key[1] = ($key[1] | $temp) & 0x0FFFFFFF; | |
214 | ||
215 | $temp = array( | |
216 | (($key[1] & 0x00004000) >> 9) | (($key[1] & 0x00000800) >> 7) | | |
217 | (($key[1] & 0x00020000) >> 14) | (($key[1] & 0x00000010) >> 2) | | |
218 | (($key[1] & 0x08000000) >> 26) | (($key[1] & 0x00800000) >> 23), | |
219 | (($key[1] & 0x02400000) >> 20) | (($key[1] & 0x00000001) << 4) | | |
220 | (($key[1] & 0x00002000) >> 10) | (($key[1] & 0x00040000) >> 18) | | |
221 | (($key[1] & 0x00000080) >> 6), | |
222 | ( $key[1] & 0x00000020 ) | (($key[1] & 0x00000200) >> 5) | | |
223 | (($key[1] & 0x00010000) >> 13) | (($key[1] & 0x01000000) >> 22) | | |
224 | (($key[1] & 0x00000004) >> 1) | (($key[1] & 0x00100000) >> 20), | |
225 | (($key[1] & 0x00001000) >> 7) | (($key[1] & 0x00200000) >> 17) | | |
226 | (($key[1] & 0x00000002) << 2) | (($key[1] & 0x00000100) >> 6) | | |
227 | (($key[1] & 0x00008000) >> 14) | (($key[1] & 0x04000000) >> 26), | |
228 | (($key[0] & 0x00008000) >> 10) | ( $key[0] & 0x00000010 ) | | |
229 | (($key[0] & 0x02000000) >> 22) | (($key[0] & 0x00080000) >> 17) | | |
230 | (($key[0] & 0x00000200) >> 8) | (($key[0] & 0x00000002) >> 1), | |
231 | (($key[0] & 0x04000000) >> 21) | (($key[0] & 0x00010000) >> 12) | | |
232 | (($key[0] & 0x00000020) >> 2) | (($key[0] & 0x00000800) >> 9) | | |
233 | (($key[0] & 0x00800000) >> 22) | (($key[0] & 0x00000100) >> 8), | |
234 | (($key[0] & 0x00001000) >> 7) | (($key[0] & 0x00000088) >> 3) | | |
235 | (($key[0] & 0x00020000) >> 14) | (($key[0] & 0x00000001) << 2) | | |
236 | (($key[0] & 0x00400000) >> 21), | |
237 | (($key[0] & 0x00000400) >> 5) | (($key[0] & 0x00004000) >> 10) | | |
238 | (($key[0] & 0x00000040) >> 3) | (($key[0] & 0x00100000) >> 18) | | |
239 | (($key[0] & 0x08000000) >> 26) | (($key[0] & 0x01000000) >> 24) | |
240 | ); | |
241 | ||
242 | $keys[] = $temp; | |
243 | } | |
244 | ||
245 | return $keys; | |
246 | } | |
247 | ||
248 | /** | |
249 | * Process a block of data and encrypt (or decrypt depending upon key sequence) | |
250 | * | |
251 | * @param string $block The block of data to process | |
252 | * @param array $keys The array of prepared keys to use | |
253 | * | |
254 | * @return string The processed block data | |
255 | */ | |
256 | protected function processBlock($block, array $keys) { | |
257 | $temp = unpack('Na/Nb', $block); | |
258 | $block = array($temp['a'], $temp['b']); | |
259 | ||
260 | /** | |
261 | * Because php does arithmetic right shifts, if the most significant bits | |
262 | * are set, right shifting those into the correct position will add 1's - | |
263 | * not 0's. this will intefere with the | operation unless a second & is | |
264 | * done. so we isolate these bits and left shift them into place. we | |
265 | * then & each block with 0x7FFFFFFF to prevennt 1's from being added for | |
266 | * any other shifts. | |
267 | */ | |
268 | $msb = array( | |
269 | ($block[0] >> 31) & 1, | |
270 | ($block[1] >> 31) & 1 | |
271 | ); | |
272 | $block[0] &= 0x7FFFFFFF; | |
273 | $block[1] &= 0x7FFFFFFF; | |
274 | ||
275 | /** | |
276 | * We isolate the appropriate bit in the appropriate integer and shift as | |
277 | * appropriate. In some cases, there are going to be multiple bits in the | |
278 | * same integer that need to be shifted in the same way. we combine those | |
279 | * into one shift operation. | |
280 | */ | |
281 | $block = array( | |
282 | (($block[1] & 0x00000040) << 25) | (($block[1] & 0x00004000) << 16) | | |
283 | (($block[1] & 0x00400001) << 7) | (($block[1] & 0x40000100) >> 2) | | |
284 | (($block[0] & 0x00000040) << 21) | (($block[0] & 0x00004000) << 12) | | |
285 | (($block[0] & 0x00400001) << 3) | (($block[0] & 0x40000100) >> 6) | | |
286 | (($block[1] & 0x00000010) << 19) | (($block[1] & 0x00001000) << 10) | | |
287 | (($block[1] & 0x00100000) << 1) | (($block[1] & 0x10000000) >> 8) | | |
288 | (($block[0] & 0x00000010) << 15) | (($block[0] & 0x00001000) << 6) | | |
289 | (($block[0] & 0x00100000) >> 3) | (($block[0] & 0x10000000) >> 12) | | |
290 | (($block[1] & 0x00000004) << 13) | (($block[1] & 0x00000400) << 4) | | |
291 | (($block[1] & 0x00040000) >> 5) | (($block[1] & 0x04000000) >> 14) | | |
292 | (($block[0] & 0x00000004) << 9) | ( $block[0] & 0x00000400 ) | | |
293 | (($block[0] & 0x00040000) >> 9) | (($block[0] & 0x04000000) >> 18) | | |
294 | (($block[1] & 0x00010000) >> 11) | (($block[1] & 0x01000000) >> 20) | | |
295 | (($block[0] & 0x00010000) >> 15) | (($block[0] & 0x01000000) >> 24), | |
296 | (($block[1] & 0x00000080) << 24) | (($block[1] & 0x00008000) << 15) | | |
297 | (($block[1] & 0x00800002) << 6) | (($block[0] & 0x00000080) << 20) | | |
298 | (($block[0] & 0x00008000) << 11) | (($block[0] & 0x00800002) << 2) | | |
299 | (($block[1] & 0x00000020) << 18) | (($block[1] & 0x00002000) << 9) | | |
300 | ( $block[1] & 0x00200000 ) | (($block[1] & 0x20000000) >> 9) | | |
301 | (($block[0] & 0x00000020) << 14) | (($block[0] & 0x00002000) << 5) | | |
302 | (($block[0] & 0x00200000) >> 4) | (($block[0] & 0x20000000) >> 13) | | |
303 | (($block[1] & 0x00000008) << 12) | (($block[1] & 0x00000800) << 3) | | |
304 | (($block[1] & 0x00080000) >> 6) | (($block[1] & 0x08000000) >> 15) | | |
305 | (($block[0] & 0x00000008) << 8) | (($block[0] & 0x00000800) >> 1) | | |
306 | (($block[0] & 0x00080000) >> 10) | (($block[0] & 0x08000000) >> 19) | | |
307 | (($block[1] & 0x00000200) >> 3) | (($block[0] & 0x00000200) >> 7) | | |
308 | (($block[1] & 0x00020000) >> 12) | (($block[1] & 0x02000000) >> 21) | | |
309 | (($block[0] & 0x00020000) >> 16) | (($block[0] & 0x02000000) >> 25) | | |
310 | ($msb[1] << 28) | ($msb[0] << 24) | |
311 | ); | |
312 | ||
313 | for ($i = 0; $i < 16; $i++) { | |
314 | // start of "the Feistel (F) function" | |
315 | $key = ((($block[1] >> 27) & 0x1F) | |
316 | | (($block[1] & 1) << 5)) ^ $keys[$i][0]; | |
317 | $temp = ((static::$sbox[0][$key]) << 28); | |
318 | $key = (($block[1] & 0x1F800000) >> 23) ^ $keys[$i][1]; | |
319 | $temp |= ((static::$sbox[1][$key]) << 24); | |
320 | $key = (($block[1] & 0x01F80000) >> 19) ^ $keys[$i][2]; | |
321 | $temp |= ((static::$sbox[2][$key]) << 20); | |
322 | $key = (($block[1] & 0x001F8000) >> 15) ^ $keys[$i][3]; | |
323 | $temp |= ((static::$sbox[3][$key]) << 16); | |
324 | $key = (($block[1] & 0x0001F800) >> 11) ^ $keys[$i][4]; | |
325 | $temp |= ((static::$sbox[4][$key]) << 12); | |
326 | $key = (($block[1] & 0x00001F80) >> 7) ^ $keys[$i][5]; | |
327 | $temp |= ((static::$sbox[5][$key]) << 8); | |
328 | $key = (($block[1] & 0x000001F8) >> 3) ^ $keys[$i][6]; | |
329 | $temp |= ((static::$sbox[6][$key]) << 4); | |
330 | $key = ((($block[1] & 0x1F) << 1) | |
331 | | (($block[1] >> 31) & 1)) ^ $keys[$i][7]; | |
332 | $temp |= ( static::$sbox[7][$key]); | |
333 | ||
334 | $msb = ($temp >> 31) & 1; | |
335 | $temp &= 0x7FFFFFFF; | |
336 | $nwB = (($temp & 0x00010000) << 15) | (($temp & 0x02020120) << 5); | |
337 | $nwB |= (($temp & 0x00001800) << 17) | (($temp & 0x01000000) >> 10); | |
338 | $nwB |= (($temp & 0x00000008) << 24) | (($temp & 0x00100000) << 6); | |
339 | $nwB |= (($temp & 0x00000010) << 21) | (($temp & 0x00008000) << 9); | |
340 | $nwB |= (($temp & 0x00000200) << 12) | (($temp & 0x10000000) >> 27); | |
341 | $nwB |= (($temp & 0x00000040) << 14) | (($temp & 0x08000000) >> 8); | |
342 | $nwB |= (($temp & 0x00004000) << 4) | (($temp & 0x00000002) << 16); | |
343 | $nwB |= (($temp & 0x00442000) >> 6) | (($temp & 0x40800000) >> 15); | |
344 | $nwB |= (($temp & 0x00000001) << 11) | (($temp & 0x20000000) >> 20); | |
345 | $nwB |= (($temp & 0x00080000) >> 13) | (($temp & 0x00000004) << 3); | |
346 | $nwB |= (($temp & 0x04000000) >> 22) | (($temp & 0x00000480) >> 7); | |
347 | $nwB |= (($temp & 0x00200000) >> 19) | ($msb << 23); | |
348 | // end of "the Feistel (F) function" - $newBlock is F's output | |
349 | ||
350 | $temp = $block[1]; | |
351 | $block[1] = $block[0] ^ $nwB; | |
352 | $block[0] = $temp; | |
353 | } | |
354 | ||
355 | $msb = array( | |
356 | ($block[0] >> 31) & 1, | |
357 | ($block[1] >> 31) & 1 | |
358 | ); | |
359 | $block[0] &= 0x7FFFFFFF; | |
360 | $block[1] &= 0x7FFFFFFF; | |
361 | ||
362 | $block = array( | |
363 | (($block[0] & 0x01000004) << 7) | (($block[1] & 0x01000004) << 6) | | |
364 | (($block[0] & 0x00010000) << 13) | (($block[1] & 0x00010000) << 12) | | |
365 | (($block[0] & 0x00000100) << 19) | (($block[1] & 0x00000100) << 18) | | |
366 | (($block[0] & 0x00000001) << 25) | (($block[1] & 0x00000001) << 24) | | |
367 | (($block[0] & 0x02000008) >> 2) | (($block[1] & 0x02000008) >> 3) | | |
368 | (($block[0] & 0x00020000) << 4) | (($block[1] & 0x00020000) << 3) | | |
369 | (($block[0] & 0x00000200) << 10) | (($block[1] & 0x00000200) << 9) | | |
370 | (($block[0] & 0x00000002) << 16) | (($block[1] & 0x00000002) << 15) | | |
371 | (($block[0] & 0x04000000) >> 11) | (($block[1] & 0x04000000) >> 12) | | |
372 | (($block[0] & 0x00040000) >> 5) | (($block[1] & 0x00040000) >> 6) | | |
373 | (($block[0] & 0x00000400) << 1) | ( $block[1] & 0x00000400 ) | | |
374 | (($block[0] & 0x08000000) >> 20) | (($block[1] & 0x08000000) >> 21) | | |
375 | (($block[0] & 0x00080000) >> 14) | (($block[1] & 0x00080000) >> 15) | | |
376 | (($block[0] & 0x00000800) >> 8) | (($block[1] & 0x00000800) >> 9), | |
377 | (($block[0] & 0x10000040) << 3) | (($block[1] & 0x10000040) << 2) | | |
378 | (($block[0] & 0x00100000) << 9) | (($block[1] & 0x00100000) << 8) | | |
379 | (($block[0] & 0x00001000) << 15) | (($block[1] & 0x00001000) << 14) | | |
380 | (($block[0] & 0x00000010) << 21) | (($block[1] & 0x00000010) << 20) | | |
381 | (($block[0] & 0x20000080) >> 6) | (($block[1] & 0x20000080) >> 7) | | |
382 | ( $block[0] & 0x00200000 ) | (($block[1] & 0x00200000) >> 1) | | |
383 | (($block[0] & 0x00002000) << 6) | (($block[1] & 0x00002000) << 5) | | |
384 | (($block[0] & 0x00000020) << 12) | (($block[1] & 0x00000020) << 11) | | |
385 | (($block[0] & 0x40000000) >> 15) | (($block[1] & 0x40000000) >> 16) | | |
386 | (($block[0] & 0x00400000) >> 9) | (($block[1] & 0x00400000) >> 10) | | |
387 | (($block[0] & 0x00004000) >> 3) | (($block[1] & 0x00004000) >> 4) | | |
388 | (($block[0] & 0x00800000) >> 18) | (($block[1] & 0x00800000) >> 19) | | |
389 | (($block[0] & 0x00008000) >> 12) | (($block[1] & 0x00008000) >> 13) | | |
390 | ($msb[0] << 7) | ($msb[1] << 6) | |
391 | ); | |
392 | ||
393 | return pack('NN', $block[0], $block[1]); | |
394 | } | |
395 | ||
396 | } |