fix calendar css, take 2. (#213)
[openemr.git] / interface / modules / zend_modules / library / Zend / Crypt / Key / Derivation / Scrypt.php
blobfe8a539744b0b62e3246c51ee7f29e2c449ad03e
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Crypt\Key\Derivation;
12 /**
13 * Scrypt key derivation function
15 * @see http://www.tarsnap.com/scrypt.html
16 * @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01
18 abstract class Scrypt
20 /**
21 * Execute the scrypt algorithm
23 * @param string $password
24 * @param string $salt
25 * @param int $n CPU cost
26 * @param int $r Memory cost
27 * @param int $p parallelization cost
28 * @param int $length size of the output key
29 * @return string
31 public static function calc($password, $salt, $n, $r, $p, $length)
33 if ($n == 0 || ($n & ($n - 1)) != 0) {
34 throw new Exception\InvalidArgumentException("N must be > 0 and a power of 2");
36 if ($n > PHP_INT_MAX / 128 / $r) {
37 throw new Exception\InvalidArgumentException("Parameter n is too large");
39 if ($r > PHP_INT_MAX / 128 / $p) {
40 throw new Exception\InvalidArgumentException("Parameter r is too large");
43 if (extension_loaded('Scrypt')) {
44 if ($length < 16) {
45 throw new Exception\InvalidArgumentException("Key length is too low, must be greater or equal to 16");
47 return self::hex2bin(scrypt($password, $salt, $n, $r, $p, $length));
50 $b = Pbkdf2::calc('sha256', $password, $salt, 1, $p * 128 * $r);
52 $s = '';
53 for ($i = 0; $i < $p; $i++) {
54 $s .= self::scryptROMix(substr($b, $i * 128 * $r, 128 * $r), $n, $r);
57 return Pbkdf2::calc('sha256', $password, $s, 1, $length);
60 /**
61 * scryptROMix
63 * @param string $b
64 * @param int $n
65 * @param int $r
66 * @return string
67 * @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-4
69 protected static function scryptROMix($b, $n, $r)
71 $x = $b;
72 $v = array();
73 for ($i = 0; $i < $n; $i++) {
74 $v[$i] = $x;
75 $x = self::scryptBlockMix($x, $r);
77 for ($i = 0; $i < $n; $i++) {
78 $j = self::integerify($x) % $n;
79 $t = $x ^ $v[$j];
80 $x = self::scryptBlockMix($t, $r);
82 return $x;
85 /**
86 * scryptBlockMix
88 * @param string $b
89 * @param int $r
90 * @return string
91 * @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-3
93 protected static function scryptBlockMix($b, $r)
95 $x = substr($b, -64);
96 $even = '';
97 $odd = '';
98 $len = 2 * $r;
100 for ($i = 0; $i < $len; $i++) {
101 if (PHP_INT_SIZE === 4) {
102 $x = self::salsa208Core32($x ^ substr($b, 64 * $i, 64));
103 } else {
104 $x = self::salsa208Core64($x ^ substr($b, 64 * $i, 64));
106 if ($i % 2 == 0) {
107 $even .= $x;
108 } else {
109 $odd .= $x;
112 return $even . $odd;
116 * Salsa 20/8 core (32 bit version)
118 * @param string $b
119 * @return string
120 * @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-2
121 * @see http://cr.yp.to/salsa20.html
123 protected static function salsa208Core32($b)
125 $b32 = array();
126 for ($i = 0; $i < 16; $i++) {
127 list(, $b32[$i]) = unpack("V", substr($b, $i * 4, 4));
130 $x = $b32;
131 for ($i = 0; $i < 8; $i += 2) {
132 $a = ($x[ 0] + $x[12]);
133 $x[ 4] ^= ($a << 7) | ($a >> 25) & 0x7f;
134 $a = ($x[ 4] + $x[ 0]);
135 $x[ 8] ^= ($a << 9) | ($a >> 23) & 0x1ff;
136 $a = ($x[ 8] + $x[ 4]);
137 $x[12] ^= ($a << 13) | ($a >> 19) & 0x1fff;
138 $a = ($x[12] + $x[ 8]);
139 $x[ 0] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
140 $a = ($x[ 5] + $x[ 1]);
141 $x[ 9] ^= ($a << 7) | ($a >> 25) & 0x7f;
142 $a = ($x[ 9] + $x[ 5]);
143 $x[13] ^= ($a << 9) | ($a >> 23) & 0x1ff;
144 $a = ($x[13] + $x[ 9]);
145 $x[ 1] ^= ($a << 13) | ($a >> 19) & 0x1fff;
146 $a = ($x[ 1] + $x[13]);
147 $x[ 5] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
148 $a = ($x[10] + $x[ 6]);
149 $x[14] ^= ($a << 7) | ($a >> 25) & 0x7f;
150 $a = ($x[14] + $x[10]);
151 $x[ 2] ^= ($a << 9) | ($a >> 23) & 0x1ff;
152 $a = ($x[ 2] + $x[14]);
153 $x[ 6] ^= ($a << 13) | ($a >> 19) & 0x1fff;
154 $a = ($x[ 6] + $x[ 2]);
155 $x[10] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
156 $a = ($x[15] + $x[11]);
157 $x[ 3] ^= ($a << 7) | ($a >> 25) & 0x7f;
158 $a = ($x[ 3] + $x[15]);
159 $x[ 7] ^= ($a << 9) | ($a >> 23) & 0x1ff;
160 $a = ($x[ 7] + $x[ 3]);
161 $x[11] ^= ($a << 13) | ($a >> 19) & 0x1fff;
162 $a = ($x[11] + $x[ 7]);
163 $x[15] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
164 $a = ($x[ 0] + $x[ 3]);
165 $x[ 1] ^= ($a << 7) | ($a >> 25) & 0x7f;
166 $a = ($x[ 1] + $x[ 0]);
167 $x[ 2] ^= ($a << 9) | ($a >> 23) & 0x1ff;
168 $a = ($x[ 2] + $x[ 1]);
169 $x[ 3] ^= ($a << 13) | ($a >> 19) & 0x1fff;
170 $a = ($x[ 3] + $x[ 2]);
171 $x[ 0] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
172 $a = ($x[ 5] + $x[ 4]);
173 $x[ 6] ^= ($a << 7) | ($a >> 25) & 0x7f;
174 $a = ($x[ 6] + $x[ 5]);
175 $x[ 7] ^= ($a << 9) | ($a >> 23) & 0x1ff;
176 $a = ($x[ 7] + $x[ 6]);
177 $x[ 4] ^= ($a << 13) | ($a >> 19) & 0x1fff;
178 $a = ($x[ 4] + $x[ 7]);
179 $x[ 5] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
180 $a = ($x[10] + $x[ 9]);
181 $x[11] ^= ($a << 7) | ($a >> 25) & 0x7f;
182 $a = ($x[11] + $x[10]);
183 $x[ 8] ^= ($a << 9) | ($a >> 23) & 0x1ff;
184 $a = ($x[ 8] + $x[11]);
185 $x[ 9] ^= ($a << 13) | ($a >> 19) & 0x1fff;
186 $a = ($x[ 9] + $x[ 8]);
187 $x[10] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
188 $a = ($x[15] + $x[14]);
189 $x[12] ^= ($a << 7) | ($a >> 25) & 0x7f;
190 $a = ($x[12] + $x[15]);
191 $x[13] ^= ($a << 9) | ($a >> 23) & 0x1ff;
192 $a = ($x[13] + $x[12]);
193 $x[14] ^= ($a << 13) | ($a >> 19) & 0x1fff;
194 $a = ($x[14] + $x[13]);
195 $x[15] ^= ($a << 18) | ($a >> 14) & 0x3ffff;
197 for ($i = 0; $i < 16; $i++) {
198 $b32[$i] = $b32[$i] + $x[$i];
200 $result = '';
201 for ($i = 0; $i < 16; $i++) {
202 $result .= pack("V", $b32[$i]);
205 return $result;
209 * Salsa 20/8 core (64 bit version)
211 * @param string $b
212 * @return string
213 * @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-2
214 * @see http://cr.yp.to/salsa20.html
216 protected static function salsa208Core64($b)
218 $b32 = array();
219 for ($i = 0; $i < 16; $i++) {
220 list(, $b32[$i]) = unpack("V", substr($b, $i * 4, 4));
223 $x = $b32;
224 for ($i = 0; $i < 8; $i += 2) {
225 $a = ($x[ 0] + $x[12]) & 0xffffffff;
226 $x[ 4] ^= ($a << 7) | ($a >> 25);
227 $a = ($x[ 4] + $x[ 0]) & 0xffffffff;
228 $x[ 8] ^= ($a << 9) | ($a >> 23);
229 $a = ($x[ 8] + $x[ 4]) & 0xffffffff;
230 $x[12] ^= ($a << 13) | ($a >> 19);
231 $a = ($x[12] + $x[ 8]) & 0xffffffff;
232 $x[ 0] ^= ($a << 18) | ($a >> 14);
233 $a = ($x[ 5] + $x[ 1]) & 0xffffffff;
234 $x[ 9] ^= ($a << 7) | ($a >> 25);
235 $a = ($x[ 9] + $x[ 5]) & 0xffffffff;
236 $x[13] ^= ($a << 9) | ($a >> 23);
237 $a = ($x[13] + $x[ 9]) & 0xffffffff;
238 $x[ 1] ^= ($a << 13) | ($a >> 19);
239 $a = ($x[ 1] + $x[13]) & 0xffffffff;
240 $x[ 5] ^= ($a << 18) | ($a >> 14);
241 $a = ($x[10] + $x[ 6]) & 0xffffffff;
242 $x[14] ^= ($a << 7) | ($a >> 25);
243 $a = ($x[14] + $x[10]) & 0xffffffff;
244 $x[ 2] ^= ($a << 9) | ($a >> 23);
245 $a = ($x[ 2] + $x[14]) & 0xffffffff;
246 $x[ 6] ^= ($a << 13) | ($a >> 19);
247 $a = ($x[ 6] + $x[ 2]) & 0xffffffff;
248 $x[10] ^= ($a << 18) | ($a >> 14);
249 $a = ($x[15] + $x[11]) & 0xffffffff;
250 $x[ 3] ^= ($a << 7) | ($a >> 25);
251 $a = ($x[ 3] + $x[15]) & 0xffffffff;
252 $x[ 7] ^= ($a << 9) | ($a >> 23);
253 $a = ($x[ 7] + $x[ 3]) & 0xffffffff;
254 $x[11] ^= ($a << 13) | ($a >> 19);
255 $a = ($x[11] + $x[ 7]) & 0xffffffff;
256 $x[15] ^= ($a << 18) | ($a >> 14);
257 $a = ($x[ 0] + $x[ 3]) & 0xffffffff;
258 $x[ 1] ^= ($a << 7) | ($a >> 25);
259 $a = ($x[ 1] + $x[ 0]) & 0xffffffff;
260 $x[ 2] ^= ($a << 9) | ($a >> 23);
261 $a = ($x[ 2] + $x[ 1]) & 0xffffffff;
262 $x[ 3] ^= ($a << 13) | ($a >> 19);
263 $a = ($x[ 3] + $x[ 2]) & 0xffffffff;
264 $x[ 0] ^= ($a << 18) | ($a >> 14);
265 $a = ($x[ 5] + $x[ 4]) & 0xffffffff;
266 $x[ 6] ^= ($a << 7) | ($a >> 25);
267 $a = ($x[ 6] + $x[ 5]) & 0xffffffff;
268 $x[ 7] ^= ($a << 9) | ($a >> 23);
269 $a = ($x[ 7] + $x[ 6]) & 0xffffffff;
270 $x[ 4] ^= ($a << 13) | ($a >> 19);
271 $a = ($x[ 4] + $x[ 7]) & 0xffffffff;
272 $x[ 5] ^= ($a << 18) | ($a >> 14);
273 $a = ($x[10] + $x[ 9]) & 0xffffffff;
274 $x[11] ^= ($a << 7) | ($a >> 25);
275 $a = ($x[11] + $x[10]) & 0xffffffff;
276 $x[ 8] ^= ($a << 9) | ($a >> 23);
277 $a = ($x[ 8] + $x[11]) & 0xffffffff;
278 $x[ 9] ^= ($a << 13) | ($a >> 19);
279 $a = ($x[ 9] + $x[ 8]) & 0xffffffff;
280 $x[10] ^= ($a << 18) | ($a >> 14);
281 $a = ($x[15] + $x[14]) & 0xffffffff;
282 $x[12] ^= ($a << 7) | ($a >> 25);
283 $a = ($x[12] + $x[15]) & 0xffffffff;
284 $x[13] ^= ($a << 9) | ($a >> 23);
285 $a = ($x[13] + $x[12]) & 0xffffffff;
286 $x[14] ^= ($a << 13) | ($a >> 19);
287 $a = ($x[14] + $x[13]) & 0xffffffff;
288 $x[15] ^= ($a << 18) | ($a >> 14);
290 for ($i = 0; $i < 16; $i++) {
291 $b32[$i] = ($b32[$i] + $x[$i]) & 0xffffffff;
293 $result = '';
294 for ($i = 0; $i < 16; $i++) {
295 $result .= pack("V", $b32[$i]);
298 return $result;
302 * Integerify
304 * Integerify (B[0] ... B[2 * r - 1]) is defined as the result
305 * of interpreting B[2 * r - 1] as a little-endian integer.
306 * Each block B is a string of 64 bytes.
308 * @param string $b
309 * @return int
310 * @see https://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01#section-4
312 protected static function integerify($b)
314 $v = 'v';
315 if (PHP_INT_SIZE === 8) {
316 $v = 'V';
318 list(, $n) = unpack($v, substr($b, -64));
319 return $n;
323 * Convert hex string in a binary string
325 * @param string $hex
326 * @return string
328 protected static function hex2bin($hex)
330 if (PHP_VERSION_ID >= 50400) {
331 return hex2bin($hex);
333 $len = strlen($hex);
334 $result = '';
335 for ($i = 0; $i < $len; $i+=2) {
336 $result .= chr(hexdec($hex[$i] . $hex[$i+1]));
338 return $result;