@@ -275,19 +275,113 @@ function _encipher(lr, off, P, S) { // This is our bottleneck: 1714/1905 ticks /
275275 r = lr [ off + 1 ] ;
276276
277277 l ^= P [ 0 ] ;
278+
279+ /*
278280 for (var i=0, k=BLOWFISH_NUM_ROUNDS-2; i<=k;)
279281 // Feistel substitution on left word
280- n = S [ ( l >> 24 ) & 0xff ] ,
282+ n = S[l >>> 24],
281283 n += S[0x100 | ((l >> 16) & 0xff)],
282284 n ^= S[0x200 | ((l >> 8) & 0xff)],
283285 n += S[0x300 | (l & 0xff)],
284286 r ^= n ^ P[++i],
285287 // Feistel substitution on right word
286- n = S [ ( r >> 24 ) & 0xff ] ,
288+ n = S[r >>> 24],
287289 n += S[0x100 | ((r >> 16) & 0xff)],
288290 n ^= S[0x200 | ((r >> 8) & 0xff)],
289291 n += S[0x300 | (r & 0xff)],
290292 l ^= n ^ P[++i];
293+ */
294+
295+ //The following is an unrolled version of the above loop.
296+ //Iteration 0
297+ n = S [ l >>> 24 ] ;
298+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
299+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
300+ n += S [ 0x300 | ( l & 0xff ) ] ;
301+ r ^= n ^ P [ 1 ] ;
302+ n = S [ r >>> 24 ] ;
303+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
304+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
305+ n += S [ 0x300 | ( r & 0xff ) ] ;
306+ l ^= n ^ P [ 2 ] ;
307+ //Iteration 1
308+ n = S [ l >>> 24 ] ;
309+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
310+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
311+ n += S [ 0x300 | ( l & 0xff ) ] ;
312+ r ^= n ^ P [ 3 ] ;
313+ n = S [ r >>> 24 ] ;
314+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
315+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
316+ n += S [ 0x300 | ( r & 0xff ) ] ;
317+ l ^= n ^ P [ 4 ] ;
318+ //Iteration 2
319+ n = S [ l >>> 24 ] ;
320+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
321+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
322+ n += S [ 0x300 | ( l & 0xff ) ] ;
323+ r ^= n ^ P [ 5 ] ;
324+ n = S [ r >>> 24 ] ;
325+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
326+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
327+ n += S [ 0x300 | ( r & 0xff ) ] ;
328+ l ^= n ^ P [ 6 ] ;
329+ //Iteration 3
330+ n = S [ l >>> 24 ] ;
331+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
332+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
333+ n += S [ 0x300 | ( l & 0xff ) ] ;
334+ r ^= n ^ P [ 7 ] ;
335+ n = S [ r >>> 24 ] ;
336+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
337+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
338+ n += S [ 0x300 | ( r & 0xff ) ] ;
339+ l ^= n ^ P [ 8 ] ;
340+ //Iteration 4
341+ n = S [ l >>> 24 ] ;
342+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
343+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
344+ n += S [ 0x300 | ( l & 0xff ) ] ;
345+ r ^= n ^ P [ 9 ] ;
346+ n = S [ r >>> 24 ] ;
347+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
348+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
349+ n += S [ 0x300 | ( r & 0xff ) ] ;
350+ l ^= n ^ P [ 10 ] ;
351+ //Iteration 5
352+ n = S [ l >>> 24 ] ;
353+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
354+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
355+ n += S [ 0x300 | ( l & 0xff ) ] ;
356+ r ^= n ^ P [ 11 ] ;
357+ n = S [ r >>> 24 ] ;
358+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
359+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
360+ n += S [ 0x300 | ( r & 0xff ) ] ;
361+ l ^= n ^ P [ 12 ] ;
362+ //Iteration 6
363+ n = S [ l >>> 24 ] ;
364+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
365+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
366+ n += S [ 0x300 | ( l & 0xff ) ] ;
367+ r ^= n ^ P [ 13 ] ;
368+ n = S [ r >>> 24 ] ;
369+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
370+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
371+ n += S [ 0x300 | ( r & 0xff ) ] ;
372+ l ^= n ^ P [ 14 ] ;
373+ //Iteration 7
374+ n = S [ l >>> 24 ] ;
375+ n += S [ 0x100 | ( ( l >> 16 ) & 0xff ) ] ;
376+ n ^= S [ 0x200 | ( ( l >> 8 ) & 0xff ) ] ;
377+ n += S [ 0x300 | ( l & 0xff ) ] ;
378+ r ^= n ^ P [ 15 ] ;
379+ n = S [ r >>> 24 ] ;
380+ n += S [ 0x100 | ( ( r >> 16 ) & 0xff ) ] ;
381+ n ^= S [ 0x200 | ( ( r >> 8 ) & 0xff ) ] ;
382+ n += S [ 0x300 | ( r & 0xff ) ] ;
383+ l ^= n ^ P [ 16 ] ;
384+
291385 lr [ off ] = r ^ P [ BLOWFISH_NUM_ROUNDS + 1 ] ;
292386 lr [ off + 1 ] = l ;
293387 return lr ;
@@ -407,9 +501,18 @@ function _crypt(b, salt, rounds, callback, progressCallback) {
407501 throw err ;
408502 }
409503 rounds = ( 1 << rounds ) >>> 0 ;
410- var P = P_ORIG . slice ( ) ,
411- S = S_ORIG . slice ( ) ,
412- i = 0 , j ;
504+
505+ var P , S , i = 0 , j ;
506+
507+ //Use typed arrays when available - huge speedup!
508+ if ( Int32Array ) {
509+ P = new Int32Array ( P_ORIG ) ;
510+ S = new Int32Array ( S_ORIG ) ;
511+ } else {
512+ P = P_ORIG . slice ( ) ;
513+ S = S_ORIG . slice ( ) ;
514+ }
515+
413516 _ekskey ( salt , b , P , S ) ;
414517
415518 /**
0 commit comments