Skip to content

Commit bfba82c

Browse files
authored
Merge pull request #53 from cruxic/darn-fast
Huge speedup!
2 parents 2ab0521 + 0b7c11a commit bfba82c

File tree

1 file changed

+108
-5
lines changed

1 file changed

+108
-5
lines changed

src/bcrypt/impl.js

Lines changed: 108 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)