From 7f0be5b42627441f9244d347ca4f20299b63c09c Mon Sep 17 00:00:00 2001 From: Dmitry Chestnykh Date: Sun, 10 May 2015 17:07:05 +0200 Subject: [PATCH 1/4] Add synchronous way to use scrypt. Now there are three general ways to call scrypt: scrypt(password, salt, logN, r, dkLen, interruptStep, callback, [encoding]) Derives a key from password and salt and calls callback with derived key as the only argument. The calculations are interrupted with zero setTimeout at the given interruptSteps to avoid freezing the browser. Encoding is optional. scrypt(password, salt, logN, r, dkLen, callback, [encoding]) Same as first, but uses default interruptStep (1000). Encoding is optional. scrypt(password, salt, logN, r, dkLen, [encoding]) -> returns result Synchronous: doesn't interrupt calculations and returns the result instead of passing it to callback. Encoding is optional. Perfect for use in web workers. --- README.md | 39 +++++++--- scrypt-async.js | 53 +++++++++---- scrypt-async.min.js | 2 +- test/unittests.js | 185 +++++++++++++++++++++++++++++++++----------- 4 files changed, 209 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 05be485..3d24e15 100644 --- a/README.md +++ b/README.md @@ -30,19 +30,28 @@ You can install it via a package manager: or [download source code](https://github.com/dchest/scrypt-async-js/releases). -Limitation ----------- +Usage +----- -Doesn't support parallelization parameter greater than 1. +There are three general ways to call scrypt: +### scrypt(password, salt, logN, r, dkLen, interruptStep, callback, [encoding]) -Usage ------ +Derives a key from password and salt and calls callback with derived key as the +only argument. The calculations are interrupted with zero setTimeout at the +given interruptSteps to avoid freezing the browser. Encoding is optional. -### scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encoding) - -Derives a key from password and salt and calls callback with derived -key as the only argument. +### scrypt(password, salt, logN, r, dkLen, callback, [encoding]) + +Same as first, but uses default interruptStep (1000). Encoding is optional. + +### scrypt(password, salt, logN, r, dkLen, [encoding]) -> returns result + +Synchronous: doesn't interrupt calculations and returns the result instead of +passing it to callback. Encoding is optional. Perfect for use in web workers. + + +#### Arguments: * *password* - password (string or array of bytes) * *salt* - salt (string or array of bytes) @@ -50,8 +59,16 @@ key as the only argument. * *r* - block size parameter * *dkLen* - length of derived key * *interruptStep* - steps to split calculation with timeouts (default 1000) -* *callback* - callback function (`function (string)`) -* *encoding* - (optional) result encoding (`"base64"`, `"hex"`, or `null`). +* *callback* - callback function (`function (array|string)`) +* *encoding* - result encoding (`"base64"`, `"hex"`, or `null`). + +When encoding is not set, the result is an `Array` of bytes. + + +Limitation +---------- + +Doesn't support parallelization parameter greater than 1. License diff --git a/scrypt-async.js b/scrypt-async.js index 2b8ef7b..32f8c21 100644 --- a/scrypt-async.js +++ b/scrypt-async.js @@ -427,23 +427,48 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin })(); } - // Note: step argument for interruptedFor must be divisible by - // two, since smixStepX work in increments of 2. - if (!interruptStep) interruptStep = 1000; - - smixStart(); - interruptedFor(0, N, interruptStep*2, smixStep1, function() { - interruptedFor(0, N, interruptStep*2, smixStep2, function () { - smixFinish(); + function getResult() { var result = PBKDF2_HMAC_SHA256_OneIter(password, B, dkLen); - if (encoding == "base64") - callback(bytesToBase64(result)); - else if (encoding == "hex") - callback(bytesToHex(result)); + if (encoding == 'base64') + return bytesToBase64(result); + else if (encoding == 'hex') + return bytesToHex(result); else - callback(result); + return result; + } + + var isSync = false; + if (typeof interruptStep === 'function') { + // Called as: scrypt(..., callback, [encoding]) + // shifting: scrypt(..., interruptStep, callback, [encoding]) + encoding = callback; + callback = interruptStep; + interruptStep = 1000; + } else if (typeof interruptStep === 'undefined' || typeof interruptStep === 'string') { + // Called as: scrypt(..., [encoding]) + // shifting: scrypt(..., interruptStep, callback, [encoding]) + isSync = true; + encoding = interruptStep; + } + + if (!isSync) { + // Async variant, calls callback with result. + smixStart(); + interruptedFor(0, N, interruptStep*2, smixStep1, function() { + interruptedFor(0, N, interruptStep*2, smixStep2, function () { + smixFinish(); + callback(getResult()); + }); }); - }); + + } else { + // Sync variant, returns result. + smixStart(); + smixStep1(0, N); + smixStep2(0, N); + smixFinish(); + return getResult(); + } } if (typeof module !== 'undefined') module.exports = scrypt; diff --git a/scrypt-async.min.js b/scrypt-async.min.js index f70b701..ea1577f 100644 --- a/scrypt-async.min.js +++ b/scrypt-async.min.js @@ -3,4 +3,4 @@ * Copyright (c) 2013-2014 Dmitry Chestnykh | BSD License * https://github.com/dchest/scrypt-async-js */ -function scrypt(a,b,c,d,e,f,g,h){"use strict";function i(a){function b(a){for(var b=0,m=a.length;m>=64;){var n,o,p,q,r,s=d,t=e,u=f,v=g,w=h,x=i,y=j,z=k;for(o=0;16>o;o++)p=b+4*o,l[o]=(255&a[p])<<24|(255&a[p+1])<<16|(255&a[p+2])<<8|255&a[p+3];for(o=16;64>o;o++)n=l[o-2],q=(n>>>17|n<<15)^(n>>>19|n<<13)^n>>>10,n=l[o-15],r=(n>>>7|n<<25)^(n>>>18|n<<14)^n>>>3,l[o]=(q+l[o-7]|0)+(r+l[o-16]|0)|0;for(o=0;64>o;o++)q=(((w>>>6|w<<26)^(w>>>11|w<<21)^(w>>>25|w<<7))+(w&x^~w&y)|0)+(z+(c[o]+l[o]|0)|0)|0,r=((s>>>2|s<<30)^(s>>>13|s<<19)^(s>>>22|s<<10))+(s&t^s&u^t&u)|0,z=y,y=x,x=w,w=v+q|0,v=u,u=t,t=s,s=q+r|0;d=d+s|0,e=e+t|0,f=f+u|0,g=g+v|0,h=h+w|0,i=i+x|0,j=j+y|0,k=k+z|0,b+=64,m-=64}}var c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d=1779033703,e=3144134277,f=1013904242,g=2773480762,h=1359893119,i=2600822924,j=528734635,k=1541459225,l=new Array(64);b(a);var m,n=a.length%64,o=a.length/536870912|0,p=a.length<<3,q=56>n?56:120,r=a.slice(a.length-n,a.length);for(r.push(128),m=n+1;q>m;m++)r.push(0);return r.push(o>>>24&255),r.push(o>>>16&255),r.push(o>>>8&255),r.push(o>>>0&255),r.push(p>>>24&255),r.push(p>>>16&255),r.push(p>>>8&255),r.push(p>>>0&255),b(r),[d>>>24&255,d>>>16&255,d>>>8&255,d>>>0&255,e>>>24&255,e>>>16&255,e>>>8&255,e>>>0&255,f>>>24&255,f>>>16&255,f>>>8&255,f>>>0&255,g>>>24&255,g>>>16&255,g>>>8&255,g>>>0&255,h>>>24&255,h>>>16&255,h>>>8&255,h>>>0&255,i>>>24&255,i>>>16&255,i>>>8&255,i>>>0&255,j>>>24&255,j>>>16&255,j>>>8&255,j>>>0&255,k>>>24&255,k>>>16&255,k>>>8&255,k>>>0&255]}function j(a,b,c){function d(){for(var a=f-1;a>=f-4;a--){if(g[a]++,g[a]<=255)return;g[a]=0}}a=a.length<=64?a:i(a);var e,f=64+b.length+4,g=new Array(f),h=new Array(64),j=[];for(e=0;64>e;e++)g[e]=54;for(e=0;ee;e++)g[e]=0;for(e=0;64>e;e++)h[e]=92;for(e=0;e=32;)d(),j=j.concat(i(h.concat(i(g)))),c-=32;return c>0&&(d(),j=j.concat(i(h.concat(i(g))).slice(0,c))),j}function k(a,b,c,d){var e,f,g=a[0]^b[c++],h=a[1]^b[c++],i=a[2]^b[c++],j=a[3]^b[c++],k=a[4]^b[c++],l=a[5]^b[c++],m=a[6]^b[c++],n=a[7]^b[c++],o=a[8]^b[c++],p=a[9]^b[c++],q=a[10]^b[c++],r=a[11]^b[c++],s=a[12]^b[c++],t=a[13]^b[c++],u=a[14]^b[c++],v=a[15]^b[c++],w=g,x=h,y=i,z=j,A=k,B=l,C=m,D=n,E=o,F=p,G=q,H=r,I=s,J=t,K=u,L=v;for(f=0;8>f;f+=2)e=w+I,A^=e<<7|e>>>25,e=A+w,E^=e<<9|e>>>23,e=E+A,I^=e<<13|e>>>19,e=I+E,w^=e<<18|e>>>14,e=B+x,F^=e<<7|e>>>25,e=F+B,J^=e<<9|e>>>23,e=J+F,x^=e<<13|e>>>19,e=x+J,B^=e<<18|e>>>14,e=G+C,K^=e<<7|e>>>25,e=K+G,y^=e<<9|e>>>23,e=y+K,C^=e<<13|e>>>19,e=C+y,G^=e<<18|e>>>14,e=L+H,z^=e<<7|e>>>25,e=z+L,D^=e<<9|e>>>23,e=D+z,H^=e<<13|e>>>19,e=H+D,L^=e<<18|e>>>14,e=w+z,x^=e<<7|e>>>25,e=x+w,y^=e<<9|e>>>23,e=y+x,z^=e<<13|e>>>19,e=z+y,w^=e<<18|e>>>14,e=B+A,C^=e<<7|e>>>25,e=C+B,D^=e<<9|e>>>23,e=D+C,A^=e<<13|e>>>19,e=A+D,B^=e<<18|e>>>14,e=G+F,H^=e<<7|e>>>25,e=H+G,E^=e<<9|e>>>23,e=E+H,F^=e<<13|e>>>19,e=F+E,G^=e<<18|e>>>14,e=L+K,I^=e<<7|e>>>25,e=I+L,J^=e<<9|e>>>23,e=J+I,K^=e<<13|e>>>19,e=K+J,L^=e<<18|e>>>14;b[d++]=a[0]=w+g|0,b[d++]=a[1]=x+h|0,b[d++]=a[2]=y+i|0,b[d++]=a[3]=z+j|0,b[d++]=a[4]=A+k|0,b[d++]=a[5]=B+l|0,b[d++]=a[6]=C+m|0,b[d++]=a[7]=D+n|0,b[d++]=a[8]=E+o|0,b[d++]=a[9]=F+p|0,b[d++]=a[10]=G+q|0,b[d++]=a[11]=H+r|0,b[d++]=a[12]=I+s|0,b[d++]=a[13]=J+t|0,b[d++]=a[14]=K+u|0,b[d++]=a[15]=L+v|0}function l(a,b,c,d,e){for(;e--;)a[b++]=c[d++]}function m(a,b,c,d,e){for(;e--;)a[b++]^=c[d++]}function n(a,b,c,d,e){l(a,0,b,c+16*(2*e-1),16);for(var f=0;2*e>f;f+=2)k(a,b,c+16*f,d+8*f),k(a,b,c+16*f+16,d+8*f+16*e)}function o(a,b,c){return a[b+16*(2*c-1)]}function p(a){for(var b=[],c=0;cd?b.push(d):d>127&&2048>d?(b.push(d>>6|192),b.push(63&d|128)):(b.push(d>>12|224),b.push(d>>6&63|128),b.push(63&d|128))}return b}function q(a){for(var b="0123456789abcdef".split(""),c=a.length,d=[],e=0;c>e;e++)d.push(b[a[e]>>>4&15]),d.push(b[a[e]>>>0&15]);return d.join("")}function r(a){for(var b,c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),g=a.length,h=[],i=0;g>i;)b=g>i?a[i++]:0,c=g>i?a[i++]:0,d=g>i?a[i++]:0,e=(b<<16)+(c<<8)+d,h.push(f[e>>>18&63]),h.push(f[e>>>12&63]),h.push(f[e>>>6&63]),h.push(f[e>>>0&63]);return g%3>0&&(h[h.length-1]="=",g%3==1&&(h[h.length-2]="=")),h.join("")}function s(){for(var a=0;32*d>a;a++){var b=4*a;y[E+a]=(255&A[b+3])<<24|(255&A[b+2])<<16|(255&A[b+1])<<8|(255&A[b+0])<<0}}function t(a,b){for(var c=a;b>c;c+=2)l(z,32*c*d,y,E,32*d),n(B,y,E,F,d),l(z,32*(c+1)*d,y,F,32*d),n(B,y,F,E,d)}function u(a,b){for(var c=a;b>c;c+=2){var e=o(y,E,d)&D-1;m(y,E,z,32*e*d,32*d),n(B,y,E,F,d),e=o(y,F,d)&D-1,m(y,F,z,32*e*d,32*d),n(B,y,F,E,d)}}function v(){for(var a=0;32*d>a;a++){var b=y[E+a];A[4*a+0]=b>>>0&255,A[4*a+1]=b>>>8&255,A[4*a+2]=b>>>16&255,A[4*a+3]=b>>>24&255}}function w(a,b,c,d,e){!function f(){setTimeout(function(){d(a,b>a+c?a+c:b),a+=c,b>a?f():e()},0)}()}var x=1;if(1>c||c>31)throw new Error("scrypt: logN not be between 1 and 31");var y,z,A,B,C=1<<31>>>0,D=1<>>0;if(d*x>=1<<30||d>C/128/x||d>C/256||D>C/128/d)throw new Error("scrypt: parameters are too large");"string"==typeof a&&(a=p(a)),"string"==typeof b&&(b=p(b)),"undefined"!=typeof Int32Array?(y=new Int32Array(64*d),z=new Int32Array(32*D*d),B=new Int32Array(16)):(y=[],z=[],B=new Array(16)),A=j(a,b,128*x*d);var E=0,F=32*d;f||(f=1e3),s(),w(0,D,2*f,t,function(){w(0,D,2*f,u,function(){v();var b=j(a,A,e);g("base64"==h?r(b):"hex"==h?q(b):b)})})}"undefined"!=typeof module&&(module.exports=scrypt); \ No newline at end of file +function scrypt(a,b,c,d,e,f,g,h){"use strict";function i(a){function b(a){for(var b=0,m=a.length;m>=64;){var n,o,p,q,r,s=d,t=e,u=f,v=g,w=h,x=i,y=j,z=k;for(o=0;16>o;o++)p=b+4*o,l[o]=(255&a[p])<<24|(255&a[p+1])<<16|(255&a[p+2])<<8|255&a[p+3];for(o=16;64>o;o++)n=l[o-2],q=(n>>>17|n<<15)^(n>>>19|n<<13)^n>>>10,n=l[o-15],r=(n>>>7|n<<25)^(n>>>18|n<<14)^n>>>3,l[o]=(q+l[o-7]|0)+(r+l[o-16]|0)|0;for(o=0;64>o;o++)q=(((w>>>6|w<<26)^(w>>>11|w<<21)^(w>>>25|w<<7))+(w&x^~w&y)|0)+(z+(c[o]+l[o]|0)|0)|0,r=((s>>>2|s<<30)^(s>>>13|s<<19)^(s>>>22|s<<10))+(s&t^s&u^t&u)|0,z=y,y=x,x=w,w=v+q|0,v=u,u=t,t=s,s=q+r|0;d=d+s|0,e=e+t|0,f=f+u|0,g=g+v|0,h=h+w|0,i=i+x|0,j=j+y|0,k=k+z|0,b+=64,m-=64}}var c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d=1779033703,e=3144134277,f=1013904242,g=2773480762,h=1359893119,i=2600822924,j=528734635,k=1541459225,l=new Array(64);b(a);var m,n=a.length%64,o=a.length/536870912|0,p=a.length<<3,q=56>n?56:120,r=a.slice(a.length-n,a.length);for(r.push(128),m=n+1;q>m;m++)r.push(0);return r.push(o>>>24&255),r.push(o>>>16&255),r.push(o>>>8&255),r.push(o>>>0&255),r.push(p>>>24&255),r.push(p>>>16&255),r.push(p>>>8&255),r.push(p>>>0&255),b(r),[d>>>24&255,d>>>16&255,d>>>8&255,d>>>0&255,e>>>24&255,e>>>16&255,e>>>8&255,e>>>0&255,f>>>24&255,f>>>16&255,f>>>8&255,f>>>0&255,g>>>24&255,g>>>16&255,g>>>8&255,g>>>0&255,h>>>24&255,h>>>16&255,h>>>8&255,h>>>0&255,i>>>24&255,i>>>16&255,i>>>8&255,i>>>0&255,j>>>24&255,j>>>16&255,j>>>8&255,j>>>0&255,k>>>24&255,k>>>16&255,k>>>8&255,k>>>0&255]}function j(a,b,c){function d(){for(var a=f-1;a>=f-4;a--){if(g[a]++,g[a]<=255)return;g[a]=0}}a=a.length<=64?a:i(a);var e,f=64+b.length+4,g=new Array(f),h=new Array(64),j=[];for(e=0;64>e;e++)g[e]=54;for(e=0;ee;e++)g[e]=0;for(e=0;64>e;e++)h[e]=92;for(e=0;e=32;)d(),j=j.concat(i(h.concat(i(g)))),c-=32;return c>0&&(d(),j=j.concat(i(h.concat(i(g))).slice(0,c))),j}function k(a,b,c,d){var e,f,g=a[0]^b[c++],h=a[1]^b[c++],i=a[2]^b[c++],j=a[3]^b[c++],k=a[4]^b[c++],l=a[5]^b[c++],m=a[6]^b[c++],n=a[7]^b[c++],o=a[8]^b[c++],p=a[9]^b[c++],q=a[10]^b[c++],r=a[11]^b[c++],s=a[12]^b[c++],t=a[13]^b[c++],u=a[14]^b[c++],v=a[15]^b[c++],w=g,x=h,y=i,z=j,A=k,B=l,C=m,D=n,E=o,F=p,G=q,H=r,I=s,J=t,K=u,L=v;for(f=0;8>f;f+=2)e=w+I,A^=e<<7|e>>>25,e=A+w,E^=e<<9|e>>>23,e=E+A,I^=e<<13|e>>>19,e=I+E,w^=e<<18|e>>>14,e=B+x,F^=e<<7|e>>>25,e=F+B,J^=e<<9|e>>>23,e=J+F,x^=e<<13|e>>>19,e=x+J,B^=e<<18|e>>>14,e=G+C,K^=e<<7|e>>>25,e=K+G,y^=e<<9|e>>>23,e=y+K,C^=e<<13|e>>>19,e=C+y,G^=e<<18|e>>>14,e=L+H,z^=e<<7|e>>>25,e=z+L,D^=e<<9|e>>>23,e=D+z,H^=e<<13|e>>>19,e=H+D,L^=e<<18|e>>>14,e=w+z,x^=e<<7|e>>>25,e=x+w,y^=e<<9|e>>>23,e=y+x,z^=e<<13|e>>>19,e=z+y,w^=e<<18|e>>>14,e=B+A,C^=e<<7|e>>>25,e=C+B,D^=e<<9|e>>>23,e=D+C,A^=e<<13|e>>>19,e=A+D,B^=e<<18|e>>>14,e=G+F,H^=e<<7|e>>>25,e=H+G,E^=e<<9|e>>>23,e=E+H,F^=e<<13|e>>>19,e=F+E,G^=e<<18|e>>>14,e=L+K,I^=e<<7|e>>>25,e=I+L,J^=e<<9|e>>>23,e=J+I,K^=e<<13|e>>>19,e=K+J,L^=e<<18|e>>>14;b[d++]=a[0]=w+g|0,b[d++]=a[1]=x+h|0,b[d++]=a[2]=y+i|0,b[d++]=a[3]=z+j|0,b[d++]=a[4]=A+k|0,b[d++]=a[5]=B+l|0,b[d++]=a[6]=C+m|0,b[d++]=a[7]=D+n|0,b[d++]=a[8]=E+o|0,b[d++]=a[9]=F+p|0,b[d++]=a[10]=G+q|0,b[d++]=a[11]=H+r|0,b[d++]=a[12]=I+s|0,b[d++]=a[13]=J+t|0,b[d++]=a[14]=K+u|0,b[d++]=a[15]=L+v|0}function l(a,b,c,d,e){for(;e--;)a[b++]=c[d++]}function m(a,b,c,d,e){for(;e--;)a[b++]^=c[d++]}function n(a,b,c,d,e){l(a,0,b,c+16*(2*e-1),16);for(var f=0;2*e>f;f+=2)k(a,b,c+16*f,d+8*f),k(a,b,c+16*f+16,d+8*f+16*e)}function o(a,b,c){return a[b+16*(2*c-1)]}function p(a){for(var b=[],c=0;cd?b.push(d):d>127&&2048>d?(b.push(d>>6|192),b.push(63&d|128)):(b.push(d>>12|224),b.push(d>>6&63|128),b.push(63&d|128))}return b}function q(a){for(var b="0123456789abcdef".split(""),c=a.length,d=[],e=0;c>e;e++)d.push(b[a[e]>>>4&15]),d.push(b[a[e]>>>0&15]);return d.join("")}function r(a){for(var b,c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),g=a.length,h=[],i=0;g>i;)b=g>i?a[i++]:0,c=g>i?a[i++]:0,d=g>i?a[i++]:0,e=(b<<16)+(c<<8)+d,h.push(f[e>>>18&63]),h.push(f[e>>>12&63]),h.push(f[e>>>6&63]),h.push(f[e>>>0&63]);return g%3>0&&(h[h.length-1]="=",g%3==1&&(h[h.length-2]="=")),h.join("")}function s(){for(var a=0;32*d>a;a++){var b=4*a;z[F+a]=(255&B[b+3])<<24|(255&B[b+2])<<16|(255&B[b+1])<<8|(255&B[b+0])<<0}}function t(a,b){for(var c=a;b>c;c+=2)l(A,32*c*d,z,F,32*d),n(C,z,F,G,d),l(A,32*(c+1)*d,z,G,32*d),n(C,z,G,F,d)}function u(a,b){for(var c=a;b>c;c+=2){var e=o(z,F,d)&E-1;m(z,F,A,32*e*d,32*d),n(C,z,F,G,d),e=o(z,G,d)&E-1,m(z,G,A,32*e*d,32*d),n(C,z,G,F,d)}}function v(){for(var a=0;32*d>a;a++){var b=z[F+a];B[4*a+0]=b>>>0&255,B[4*a+1]=b>>>8&255,B[4*a+2]=b>>>16&255,B[4*a+3]=b>>>24&255}}function w(a,b,c,d,e){!function f(){setTimeout(function(){d(a,b>a+c?a+c:b),a+=c,b>a?f():e()},0)}()}function x(){var b=j(a,B,e);return"base64"==h?r(b):"hex"==h?q(b):b}var y=1;if(1>c||c>31)throw new Error("scrypt: logN not be between 1 and 31");var z,A,B,C,D=1<<31>>>0,E=1<>>0;if(d*y>=1<<30||d>D/128/y||d>D/256||E>D/128/d)throw new Error("scrypt: parameters are too large");"string"==typeof a&&(a=p(a)),"string"==typeof b&&(b=p(b)),"undefined"!=typeof Int32Array?(z=new Int32Array(64*d),A=new Int32Array(32*E*d),C=new Int32Array(16)):(z=[],A=[],C=new Array(16)),B=j(a,b,128*y*d);var F=0,G=32*d,H=!1;return"function"==typeof f?(h=g,g=f,f=1e3):("undefined"==typeof f||"string"==typeof f)&&(H=!0,h=f),H?(s(),t(0,E),u(0,E),v(),x()):(s(),void w(0,E,2*f,t,function(){w(0,E,2*f,u,function(){v(),g(x())})}))}"undefined"!=typeof module&&(module.exports=scrypt); \ No newline at end of file diff --git a/test/unittests.js b/test/unittests.js index bad256c..bb268ed 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -2,15 +2,6 @@ var scrypt = require('../scrypt-async.js'); var assert = require("assert"); var inputs = [ - { - password: 'this is a long \x00 password', - salt: 'and this is a long \x00 salt', - logN: 14, - r: 8, - dkLen: 256, - encoding: 'hex', - result: 'c3f182ee2dec846e70a6942fb529985a3a09765ef04c612923b17f18555a37076deb2b9830d69de5492651e4506ae5776d96d40f67aaee37e1777b8ad5c3111432bb3b6f7e1264401879e641aea2bd0a21a124fd5c1ece0891338d2c44ba312e497bd93660fc053a5df35ade0ca48fd0f3c6c0f6143bb3548420a7cbf6ce7c82bc6b56c8e33adbf6fbac9e0ffc4aa9fb9fcd97fd393700b7d8eac55d45d4651bdb1a270c35c8d40a22e1b2429d6521c4c673e4ba7e7f4a9638ec3b1adbc6dcab64e211b5a26df8f274511be41228cd9a4fae3ada5236ebf39dfc6cd1864652a16516fb622502205d9fdbf09dc6fa964b57cc468ee8d98e4a00bf064222dafec8' - }, { password: 'p', salt: 's', @@ -47,15 +38,6 @@ var inputs = [ encoding: 'base64', result: 'd9ZXYjhleyA7GcpCwYoEl/FrSETjB0ro39/6P+3iFEL80Aad7QlI+DJqdToPyB8X6NPg+y4NNijPNeIMONGJBs5zIGZWz4werX9PZjDQra4f2IeLd8O0aduRnwFZf2E6wveK7FpcZ8JVgzEZ6z5mtpd+bn4y4IV7eW37vCfj4HbldcVfZhVjQy1EUkJ9iiGkv8D095UyGB0BHsvZ8hDjAbkl6CytuuwBXS2ksRIvUestefIuKLfhIEoV50H+v5uUUm1X5yd9eqEumsilj9TEL2kiRwFWy9J57BYZxXTUXEF3KGMigDxgRtixTB9sVrbi4i0HfgoxdLqddlqE9SsRzQ==' }, - { - password: 'pleaseletmein', - salt: 'SodiumChloride', - logN: 14, - r: 8, - dkLen: 256, - encoding: 'hex', - result: '7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887c3b5417f26036e90e9c1fe355d24ee3623c8b8bad9b9aa93286c6429dbc0bfa2e69326c0806f7dc5f825a6b9cc32d18483a117c1ea78e2f38675579c811c0b67c262dbab7fe2b6d989d07fac3443c859cf7b34fed8cc5b279f7bdbf6e0cd8d90a82fe56f3ac7a5b81f98275c9c5cb69f19c8bddc33db6bd7da847ec3197e13f33f70b00a46836b7c0a0379559160ef42c8332097f7ca265fe6ff972ce1ffb515ff7e4e715e4c92839113ea67f2515f311549fc7eee49804136fb0830abb943d3' - }, { password: 'пароль', salt: 'соль', @@ -74,18 +56,6 @@ var inputs = [ encoding: 'base64', result: 'FYjFuH0fb+qfG0Q0n5WFVQ==' }, - { - password: 'hello', - salt: 'world', - logN: 5, - r: 8, - dkLen: 48, - encoding: null, - result: [212, 108, 63, 108, 230, 193, 1, 5, 181, 168, 169, 234, 8, 53, 241, - 76, 44, 108, 85, 218, 223, 158, 113, 64, 94, 114, 7, 160, 1, 160, 174, - 43, 11, 22, 144, 102, 217, 198, 114, 226, 91, 245, 240, 80, 28, 210, 107, - 239] - }, { password: [104, 101, 108, 108, 111], // "hello" salt: [208, 188, 208, 184, 209, 128], // "мир" @@ -239,10 +209,111 @@ var inputs = [ dkLen: 16, encoding: 'hex', result: '518a355ac6468a4d98708adf03577df6' + }, + { + password: 'hello', + salt: 'world', + logN: 5, + r: 8, + dkLen: 48, + encoding: null, + result: [212, 108, 63, 108, 230, 193, 1, 5, 181, 168, 169, 234, 8, 53, 241, + 76, 44, 108, 85, 218, 223, 158, 113, 64, 94, 114, 7, 160, 1, 160, 174, + 43, 11, 22, 144, 102, 217, 198, 114, 226, 91, 245, 240, 80, 28, 210, 107, + 239] + }, + { + password: 'pleaseletmein', + salt: 'SodiumChloride', + logN: 14, + r: 8, + dkLen: 256, + encoding: 'hex', + result: '7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887c3b5417f26036e90e9c1fe355d24ee3623c8b8bad9b9aa93286c6429dbc0bfa2e69326c0806f7dc5f825a6b9cc32d18483a117c1ea78e2f38675579c811c0b67c262dbab7fe2b6d989d07fac3443c859cf7b34fed8cc5b279f7bdbf6e0cd8d90a82fe56f3ac7a5b81f98275c9c5cb69f19c8bddc33db6bd7da847ec3197e13f33f70b00a46836b7c0a0379559160ef42c8332097f7ca265fe6ff972ce1ffb515ff7e4e715e4c92839113ea67f2515f311549fc7eee49804136fb0830abb943d3' + }, + { + password: 'this is a long \x00 password', + salt: 'and this is a long \x00 salt', + logN: 14, + r: 8, + dkLen: 256, + encoding: 'hex', + result: 'c3f182ee2dec846e70a6942fb529985a3a09765ef04c612923b17f18555a37076deb2b9830d69de5492651e4506ae5776d96d40f67aaee37e1777b8ad5c3111432bb3b6f7e1264401879e641aea2bd0a21a124fd5c1ece0891338d2c44ba312e497bd93660fc053a5df35ade0ca48fd0f3c6c0f6143bb3548420a7cbf6ce7c82bc6b56c8e33adbf6fbac9e0ffc4aa9fb9fcd97fd393700b7d8eac55d45d4651bdb1a270c35c8d40a22e1b2429d6521c4c673e4ba7e7f4a9638ec3b1adbc6dcab64e211b5a26df8f274511be41228cd9a4fae3ada5236ebf39dfc6cd1864652a16516fb622502205d9fdbf09dc6fa964b57cc468ee8d98e4a00bf064222dafec8' } -] +]; + +var shortInput = { + password: 'password', + salt: 'salt', + logN: 1, + r: 1, + dkLen: 16, + hexResult: '6d1bb878eee9ce4a7b77d7a44103574d', + result: [109, 27, 184, 120, 238, 233, 206, 74, 123, 119, 215, 164, 65, 3, 87, 77] +}; + +describe('limits test', function() { + var v = shortInput; + + it('should throw with too small logN', function() { + assert.throws(function() { + scrypt(v.password, v.salt, 0, v.r, v.dkLen); + }, Error); + }); + + it('should throw with too big logN', function() { + assert.throws(function() { + scrypt(v.password, v.salt, 32, v.r, v.dkLen); + }, Error); + }); + + it('should throw with too large parameters', function() { + assert.throws(function() { + scrypt(v.password, v.salt, v.logN, 1<<31, v.dkLen); + }, Error); + }); + +}); + +describe('argument order test', function() { + this.timeout(100000); + + var v = shortInput; + + it('all arguments', function(done) { + scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, 1000, function(out) { + assert.equal(v.hexResult, out); + done(); + }, "hex"); + }); -var input_output_test = function(i, done) { + it('drop encoding', function(done) { + scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, 1000, function(out) { + assert.deepEqual(v.result, out); + done(); + }); + }); + + it('drop interruptStep, keep encoding', function(done) { + scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, function(out) { + assert.equal(v.hexResult, out); + done(); + }, 'hex'); + }); + + it('drop interruptStep and callback, keep encoding (sync)', function() { + var out = scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, 'hex'); + assert.equal(v.hexResult, out); + }); + + it('drop interruptStep, callback, and encoding (sync)', function() { + var out = scrypt(v.password, v.salt, v.logN, v.r, v.dkLen); + assert.deepEqual(v.result, out); + }); + +}); + +function async_test(i, done) { var v = inputs[i]; scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, 1000, function(out) { assert.deepEqual(v.result, out); @@ -250,41 +321,67 @@ var input_output_test = function(i, done) { }, v.encoding); } -describe('input/output test', function(){ +describe('async input/output test', function() { this.timeout(100000); it('input 0', function(done) { - input_output_test(0, done); + async_test(0, done); }); it('input 1', function(done) { - input_output_test(1, done); + async_test(1, done); }); it('input 2', function(done) { - input_output_test(2, done); + async_test(2, done); }); it('input 3', function(done) { - input_output_test(3, done); + async_test(3, done); }); it('input 4', function(done) { - input_output_test(4, done); + async_test(4, done); }); it('input 5', function(done) { - input_output_test(5, done); + async_test(5, done); }); it('input 6', function(done) { - input_output_test(6, done); + async_test(6, done); }); it('input 7', function(done) { - input_output_test(7, done); + async_test(7, done); }); it('input 8', function(done) { - input_output_test(8, done); + async_test(8, done); }); it('input 9', function(done) { - input_output_test(9, done); + async_test(9, done); }); it('input 10', function(done) { - input_output_test(10, done); + async_test(10, done); + }); + +}); + +function sync_test(i) { + var v = inputs[i]; + var out = scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, v.encoding); + assert.deepEqual(v.result, out); +} + +describe('sync input/output test', function() { + this.timeout(100000); + + // Only shorter tests: + + it('input 0', function() { + sync_test(0); + }); + it('input 1', function() { + sync_test(1); + }); + it('input 2', function() { + sync_test(2); + }); + it('input 3', function() { + sync_test(3); }); }); From 26bbe162bb2926a1b5ea2a98e94f3a67289bf0e1 Mon Sep 17 00:00:00 2001 From: Dmitry Chestnykh Date: Sun, 10 May 2015 17:23:12 +0200 Subject: [PATCH 2/4] Little tweaks. --- scrypt-async.js | 29 +++++++++++++---------------- scrypt-async.min.js | 4 ++-- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/scrypt-async.js b/scrypt-async.js index 32f8c21..569c850 100644 --- a/scrypt-async.js +++ b/scrypt-async.js @@ -1,6 +1,6 @@ /*! * Fast "async" scrypt implementation in JavaScript. - * Copyright (c) 2013-2014 Dmitry Chestnykh | BSD License + * Copyright (c) 2013-2015 Dmitry Chestnykh | BSD License * https://github.com/dchest/scrypt-async-js */ @@ -9,19 +9,16 @@ */ /** - * scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encoding) + * scrypt(password, salt, logN, r, dkLen, interruptStep, callback, [encoding]) + * scrypt(password, salt, logN, r, dkLen, callback, [encoding]) * - * Derives a key from password and salt and calls callback + * Async: derives a key from password and salt and calls callback * with derived key as the only argument. * - * @param {string|Array.} password Password. - * @param {string|Array.} salt Salt. - * @param {number} logN CPU/memory cost parameter (1 to 31). - * @param {number} r Block size parameter. - * @param {number} dkLen Length of derived key. - * @param {number} interruptStep Steps to split calculation with timeouts (default 1000). - * @param {function(string)} callback Callback function. - * @param {string?} encoding Result encoding ("base64", "hex", or null). + * scrypt(password, salt, logN, r, dkLen, [encoding]) -> returns result + * + * Sync: returns derived key. + * */ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encoding) { 'use strict'; @@ -333,7 +330,7 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin } if (len % 3 > 0) { arr[arr.length-1] = '='; - if (len % 3 == 1) arr[arr.length-2] = '='; + if (len % 3 === 1) arr[arr.length-2] = '='; } return arr.join(''); } @@ -355,9 +352,9 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin throw new Error('scrypt: parameters are too large'); // Decode strings. - if (typeof password == 'string') + if (typeof password === 'string') password = stringToUTF8Bytes(password); - if (typeof salt == 'string') + if (typeof salt === 'string') salt = stringToUTF8Bytes(salt); if (typeof Int32Array !== 'undefined') { @@ -429,9 +426,9 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin function getResult() { var result = PBKDF2_HMAC_SHA256_OneIter(password, B, dkLen); - if (encoding == 'base64') + if (encoding === 'base64') return bytesToBase64(result); - else if (encoding == 'hex') + else if (encoding === 'hex') return bytesToHex(result); else return result; diff --git a/scrypt-async.min.js b/scrypt-async.min.js index ea1577f..a29c6f2 100644 --- a/scrypt-async.min.js +++ b/scrypt-async.min.js @@ -1,6 +1,6 @@ /*! * Fast "async" scrypt implementation in JavaScript. - * Copyright (c) 2013-2014 Dmitry Chestnykh | BSD License + * Copyright (c) 2013-2015 Dmitry Chestnykh | BSD License * https://github.com/dchest/scrypt-async-js */ -function scrypt(a,b,c,d,e,f,g,h){"use strict";function i(a){function b(a){for(var b=0,m=a.length;m>=64;){var n,o,p,q,r,s=d,t=e,u=f,v=g,w=h,x=i,y=j,z=k;for(o=0;16>o;o++)p=b+4*o,l[o]=(255&a[p])<<24|(255&a[p+1])<<16|(255&a[p+2])<<8|255&a[p+3];for(o=16;64>o;o++)n=l[o-2],q=(n>>>17|n<<15)^(n>>>19|n<<13)^n>>>10,n=l[o-15],r=(n>>>7|n<<25)^(n>>>18|n<<14)^n>>>3,l[o]=(q+l[o-7]|0)+(r+l[o-16]|0)|0;for(o=0;64>o;o++)q=(((w>>>6|w<<26)^(w>>>11|w<<21)^(w>>>25|w<<7))+(w&x^~w&y)|0)+(z+(c[o]+l[o]|0)|0)|0,r=((s>>>2|s<<30)^(s>>>13|s<<19)^(s>>>22|s<<10))+(s&t^s&u^t&u)|0,z=y,y=x,x=w,w=v+q|0,v=u,u=t,t=s,s=q+r|0;d=d+s|0,e=e+t|0,f=f+u|0,g=g+v|0,h=h+w|0,i=i+x|0,j=j+y|0,k=k+z|0,b+=64,m-=64}}var c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d=1779033703,e=3144134277,f=1013904242,g=2773480762,h=1359893119,i=2600822924,j=528734635,k=1541459225,l=new Array(64);b(a);var m,n=a.length%64,o=a.length/536870912|0,p=a.length<<3,q=56>n?56:120,r=a.slice(a.length-n,a.length);for(r.push(128),m=n+1;q>m;m++)r.push(0);return r.push(o>>>24&255),r.push(o>>>16&255),r.push(o>>>8&255),r.push(o>>>0&255),r.push(p>>>24&255),r.push(p>>>16&255),r.push(p>>>8&255),r.push(p>>>0&255),b(r),[d>>>24&255,d>>>16&255,d>>>8&255,d>>>0&255,e>>>24&255,e>>>16&255,e>>>8&255,e>>>0&255,f>>>24&255,f>>>16&255,f>>>8&255,f>>>0&255,g>>>24&255,g>>>16&255,g>>>8&255,g>>>0&255,h>>>24&255,h>>>16&255,h>>>8&255,h>>>0&255,i>>>24&255,i>>>16&255,i>>>8&255,i>>>0&255,j>>>24&255,j>>>16&255,j>>>8&255,j>>>0&255,k>>>24&255,k>>>16&255,k>>>8&255,k>>>0&255]}function j(a,b,c){function d(){for(var a=f-1;a>=f-4;a--){if(g[a]++,g[a]<=255)return;g[a]=0}}a=a.length<=64?a:i(a);var e,f=64+b.length+4,g=new Array(f),h=new Array(64),j=[];for(e=0;64>e;e++)g[e]=54;for(e=0;ee;e++)g[e]=0;for(e=0;64>e;e++)h[e]=92;for(e=0;e=32;)d(),j=j.concat(i(h.concat(i(g)))),c-=32;return c>0&&(d(),j=j.concat(i(h.concat(i(g))).slice(0,c))),j}function k(a,b,c,d){var e,f,g=a[0]^b[c++],h=a[1]^b[c++],i=a[2]^b[c++],j=a[3]^b[c++],k=a[4]^b[c++],l=a[5]^b[c++],m=a[6]^b[c++],n=a[7]^b[c++],o=a[8]^b[c++],p=a[9]^b[c++],q=a[10]^b[c++],r=a[11]^b[c++],s=a[12]^b[c++],t=a[13]^b[c++],u=a[14]^b[c++],v=a[15]^b[c++],w=g,x=h,y=i,z=j,A=k,B=l,C=m,D=n,E=o,F=p,G=q,H=r,I=s,J=t,K=u,L=v;for(f=0;8>f;f+=2)e=w+I,A^=e<<7|e>>>25,e=A+w,E^=e<<9|e>>>23,e=E+A,I^=e<<13|e>>>19,e=I+E,w^=e<<18|e>>>14,e=B+x,F^=e<<7|e>>>25,e=F+B,J^=e<<9|e>>>23,e=J+F,x^=e<<13|e>>>19,e=x+J,B^=e<<18|e>>>14,e=G+C,K^=e<<7|e>>>25,e=K+G,y^=e<<9|e>>>23,e=y+K,C^=e<<13|e>>>19,e=C+y,G^=e<<18|e>>>14,e=L+H,z^=e<<7|e>>>25,e=z+L,D^=e<<9|e>>>23,e=D+z,H^=e<<13|e>>>19,e=H+D,L^=e<<18|e>>>14,e=w+z,x^=e<<7|e>>>25,e=x+w,y^=e<<9|e>>>23,e=y+x,z^=e<<13|e>>>19,e=z+y,w^=e<<18|e>>>14,e=B+A,C^=e<<7|e>>>25,e=C+B,D^=e<<9|e>>>23,e=D+C,A^=e<<13|e>>>19,e=A+D,B^=e<<18|e>>>14,e=G+F,H^=e<<7|e>>>25,e=H+G,E^=e<<9|e>>>23,e=E+H,F^=e<<13|e>>>19,e=F+E,G^=e<<18|e>>>14,e=L+K,I^=e<<7|e>>>25,e=I+L,J^=e<<9|e>>>23,e=J+I,K^=e<<13|e>>>19,e=K+J,L^=e<<18|e>>>14;b[d++]=a[0]=w+g|0,b[d++]=a[1]=x+h|0,b[d++]=a[2]=y+i|0,b[d++]=a[3]=z+j|0,b[d++]=a[4]=A+k|0,b[d++]=a[5]=B+l|0,b[d++]=a[6]=C+m|0,b[d++]=a[7]=D+n|0,b[d++]=a[8]=E+o|0,b[d++]=a[9]=F+p|0,b[d++]=a[10]=G+q|0,b[d++]=a[11]=H+r|0,b[d++]=a[12]=I+s|0,b[d++]=a[13]=J+t|0,b[d++]=a[14]=K+u|0,b[d++]=a[15]=L+v|0}function l(a,b,c,d,e){for(;e--;)a[b++]=c[d++]}function m(a,b,c,d,e){for(;e--;)a[b++]^=c[d++]}function n(a,b,c,d,e){l(a,0,b,c+16*(2*e-1),16);for(var f=0;2*e>f;f+=2)k(a,b,c+16*f,d+8*f),k(a,b,c+16*f+16,d+8*f+16*e)}function o(a,b,c){return a[b+16*(2*c-1)]}function p(a){for(var b=[],c=0;cd?b.push(d):d>127&&2048>d?(b.push(d>>6|192),b.push(63&d|128)):(b.push(d>>12|224),b.push(d>>6&63|128),b.push(63&d|128))}return b}function q(a){for(var b="0123456789abcdef".split(""),c=a.length,d=[],e=0;c>e;e++)d.push(b[a[e]>>>4&15]),d.push(b[a[e]>>>0&15]);return d.join("")}function r(a){for(var b,c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),g=a.length,h=[],i=0;g>i;)b=g>i?a[i++]:0,c=g>i?a[i++]:0,d=g>i?a[i++]:0,e=(b<<16)+(c<<8)+d,h.push(f[e>>>18&63]),h.push(f[e>>>12&63]),h.push(f[e>>>6&63]),h.push(f[e>>>0&63]);return g%3>0&&(h[h.length-1]="=",g%3==1&&(h[h.length-2]="=")),h.join("")}function s(){for(var a=0;32*d>a;a++){var b=4*a;z[F+a]=(255&B[b+3])<<24|(255&B[b+2])<<16|(255&B[b+1])<<8|(255&B[b+0])<<0}}function t(a,b){for(var c=a;b>c;c+=2)l(A,32*c*d,z,F,32*d),n(C,z,F,G,d),l(A,32*(c+1)*d,z,G,32*d),n(C,z,G,F,d)}function u(a,b){for(var c=a;b>c;c+=2){var e=o(z,F,d)&E-1;m(z,F,A,32*e*d,32*d),n(C,z,F,G,d),e=o(z,G,d)&E-1,m(z,G,A,32*e*d,32*d),n(C,z,G,F,d)}}function v(){for(var a=0;32*d>a;a++){var b=z[F+a];B[4*a+0]=b>>>0&255,B[4*a+1]=b>>>8&255,B[4*a+2]=b>>>16&255,B[4*a+3]=b>>>24&255}}function w(a,b,c,d,e){!function f(){setTimeout(function(){d(a,b>a+c?a+c:b),a+=c,b>a?f():e()},0)}()}function x(){var b=j(a,B,e);return"base64"==h?r(b):"hex"==h?q(b):b}var y=1;if(1>c||c>31)throw new Error("scrypt: logN not be between 1 and 31");var z,A,B,C,D=1<<31>>>0,E=1<>>0;if(d*y>=1<<30||d>D/128/y||d>D/256||E>D/128/d)throw new Error("scrypt: parameters are too large");"string"==typeof a&&(a=p(a)),"string"==typeof b&&(b=p(b)),"undefined"!=typeof Int32Array?(z=new Int32Array(64*d),A=new Int32Array(32*E*d),C=new Int32Array(16)):(z=[],A=[],C=new Array(16)),B=j(a,b,128*y*d);var F=0,G=32*d,H=!1;return"function"==typeof f?(h=g,g=f,f=1e3):("undefined"==typeof f||"string"==typeof f)&&(H=!0,h=f),H?(s(),t(0,E),u(0,E),v(),x()):(s(),void w(0,E,2*f,t,function(){w(0,E,2*f,u,function(){v(),g(x())})}))}"undefined"!=typeof module&&(module.exports=scrypt); \ No newline at end of file +function scrypt(a,b,c,d,e,f,g,h){"use strict";function i(a){function b(a){for(var b=0,m=a.length;m>=64;){var n,o,p,q,r,s=d,t=e,u=f,v=g,w=h,x=i,y=j,z=k;for(o=0;16>o;o++)p=b+4*o,l[o]=(255&a[p])<<24|(255&a[p+1])<<16|(255&a[p+2])<<8|255&a[p+3];for(o=16;64>o;o++)n=l[o-2],q=(n>>>17|n<<15)^(n>>>19|n<<13)^n>>>10,n=l[o-15],r=(n>>>7|n<<25)^(n>>>18|n<<14)^n>>>3,l[o]=(q+l[o-7]|0)+(r+l[o-16]|0)|0;for(o=0;64>o;o++)q=(((w>>>6|w<<26)^(w>>>11|w<<21)^(w>>>25|w<<7))+(w&x^~w&y)|0)+(z+(c[o]+l[o]|0)|0)|0,r=((s>>>2|s<<30)^(s>>>13|s<<19)^(s>>>22|s<<10))+(s&t^s&u^t&u)|0,z=y,y=x,x=w,w=v+q|0,v=u,u=t,t=s,s=q+r|0;d=d+s|0,e=e+t|0,f=f+u|0,g=g+v|0,h=h+w|0,i=i+x|0,j=j+y|0,k=k+z|0,b+=64,m-=64}}var c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d=1779033703,e=3144134277,f=1013904242,g=2773480762,h=1359893119,i=2600822924,j=528734635,k=1541459225,l=new Array(64);b(a);var m,n=a.length%64,o=a.length/536870912|0,p=a.length<<3,q=56>n?56:120,r=a.slice(a.length-n,a.length);for(r.push(128),m=n+1;q>m;m++)r.push(0);return r.push(o>>>24&255),r.push(o>>>16&255),r.push(o>>>8&255),r.push(o>>>0&255),r.push(p>>>24&255),r.push(p>>>16&255),r.push(p>>>8&255),r.push(p>>>0&255),b(r),[d>>>24&255,d>>>16&255,d>>>8&255,d>>>0&255,e>>>24&255,e>>>16&255,e>>>8&255,e>>>0&255,f>>>24&255,f>>>16&255,f>>>8&255,f>>>0&255,g>>>24&255,g>>>16&255,g>>>8&255,g>>>0&255,h>>>24&255,h>>>16&255,h>>>8&255,h>>>0&255,i>>>24&255,i>>>16&255,i>>>8&255,i>>>0&255,j>>>24&255,j>>>16&255,j>>>8&255,j>>>0&255,k>>>24&255,k>>>16&255,k>>>8&255,k>>>0&255]}function j(a,b,c){function d(){for(var a=f-1;a>=f-4;a--){if(g[a]++,g[a]<=255)return;g[a]=0}}a=a.length<=64?a:i(a);var e,f=64+b.length+4,g=new Array(f),h=new Array(64),j=[];for(e=0;64>e;e++)g[e]=54;for(e=0;ee;e++)g[e]=0;for(e=0;64>e;e++)h[e]=92;for(e=0;e=32;)d(),j=j.concat(i(h.concat(i(g)))),c-=32;return c>0&&(d(),j=j.concat(i(h.concat(i(g))).slice(0,c))),j}function k(a,b,c,d){var e,f,g=a[0]^b[c++],h=a[1]^b[c++],i=a[2]^b[c++],j=a[3]^b[c++],k=a[4]^b[c++],l=a[5]^b[c++],m=a[6]^b[c++],n=a[7]^b[c++],o=a[8]^b[c++],p=a[9]^b[c++],q=a[10]^b[c++],r=a[11]^b[c++],s=a[12]^b[c++],t=a[13]^b[c++],u=a[14]^b[c++],v=a[15]^b[c++],w=g,x=h,y=i,z=j,A=k,B=l,C=m,D=n,E=o,F=p,G=q,H=r,I=s,J=t,K=u,L=v;for(f=0;8>f;f+=2)e=w+I,A^=e<<7|e>>>25,e=A+w,E^=e<<9|e>>>23,e=E+A,I^=e<<13|e>>>19,e=I+E,w^=e<<18|e>>>14,e=B+x,F^=e<<7|e>>>25,e=F+B,J^=e<<9|e>>>23,e=J+F,x^=e<<13|e>>>19,e=x+J,B^=e<<18|e>>>14,e=G+C,K^=e<<7|e>>>25,e=K+G,y^=e<<9|e>>>23,e=y+K,C^=e<<13|e>>>19,e=C+y,G^=e<<18|e>>>14,e=L+H,z^=e<<7|e>>>25,e=z+L,D^=e<<9|e>>>23,e=D+z,H^=e<<13|e>>>19,e=H+D,L^=e<<18|e>>>14,e=w+z,x^=e<<7|e>>>25,e=x+w,y^=e<<9|e>>>23,e=y+x,z^=e<<13|e>>>19,e=z+y,w^=e<<18|e>>>14,e=B+A,C^=e<<7|e>>>25,e=C+B,D^=e<<9|e>>>23,e=D+C,A^=e<<13|e>>>19,e=A+D,B^=e<<18|e>>>14,e=G+F,H^=e<<7|e>>>25,e=H+G,E^=e<<9|e>>>23,e=E+H,F^=e<<13|e>>>19,e=F+E,G^=e<<18|e>>>14,e=L+K,I^=e<<7|e>>>25,e=I+L,J^=e<<9|e>>>23,e=J+I,K^=e<<13|e>>>19,e=K+J,L^=e<<18|e>>>14;b[d++]=a[0]=w+g|0,b[d++]=a[1]=x+h|0,b[d++]=a[2]=y+i|0,b[d++]=a[3]=z+j|0,b[d++]=a[4]=A+k|0,b[d++]=a[5]=B+l|0,b[d++]=a[6]=C+m|0,b[d++]=a[7]=D+n|0,b[d++]=a[8]=E+o|0,b[d++]=a[9]=F+p|0,b[d++]=a[10]=G+q|0,b[d++]=a[11]=H+r|0,b[d++]=a[12]=I+s|0,b[d++]=a[13]=J+t|0,b[d++]=a[14]=K+u|0,b[d++]=a[15]=L+v|0}function l(a,b,c,d,e){for(;e--;)a[b++]=c[d++]}function m(a,b,c,d,e){for(;e--;)a[b++]^=c[d++]}function n(a,b,c,d,e){l(a,0,b,c+16*(2*e-1),16);for(var f=0;2*e>f;f+=2)k(a,b,c+16*f,d+8*f),k(a,b,c+16*f+16,d+8*f+16*e)}function o(a,b,c){return a[b+16*(2*c-1)]}function p(a){for(var b=[],c=0;cd?b.push(d):d>127&&2048>d?(b.push(d>>6|192),b.push(63&d|128)):(b.push(d>>12|224),b.push(d>>6&63|128),b.push(63&d|128))}return b}function q(a){for(var b="0123456789abcdef".split(""),c=a.length,d=[],e=0;c>e;e++)d.push(b[a[e]>>>4&15]),d.push(b[a[e]>>>0&15]);return d.join("")}function r(a){for(var b,c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),g=a.length,h=[],i=0;g>i;)b=g>i?a[i++]:0,c=g>i?a[i++]:0,d=g>i?a[i++]:0,e=(b<<16)+(c<<8)+d,h.push(f[e>>>18&63]),h.push(f[e>>>12&63]),h.push(f[e>>>6&63]),h.push(f[e>>>0&63]);return g%3>0&&(h[h.length-1]="=",g%3===1&&(h[h.length-2]="=")),h.join("")}function s(){for(var a=0;32*d>a;a++){var b=4*a;z[F+a]=(255&B[b+3])<<24|(255&B[b+2])<<16|(255&B[b+1])<<8|(255&B[b+0])<<0}}function t(a,b){for(var c=a;b>c;c+=2)l(A,32*c*d,z,F,32*d),n(C,z,F,G,d),l(A,32*(c+1)*d,z,G,32*d),n(C,z,G,F,d)}function u(a,b){for(var c=a;b>c;c+=2){var e=o(z,F,d)&E-1;m(z,F,A,32*e*d,32*d),n(C,z,F,G,d),e=o(z,G,d)&E-1,m(z,G,A,32*e*d,32*d),n(C,z,G,F,d)}}function v(){for(var a=0;32*d>a;a++){var b=z[F+a];B[4*a+0]=b>>>0&255,B[4*a+1]=b>>>8&255,B[4*a+2]=b>>>16&255,B[4*a+3]=b>>>24&255}}function w(a,b,c,d,e){!function f(){setTimeout(function(){d(a,b>a+c?a+c:b),a+=c,b>a?f():e()},0)}()}function x(){var b=j(a,B,e);return"base64"===h?r(b):"hex"===h?q(b):b}var y=1;if(1>c||c>31)throw new Error("scrypt: logN not be between 1 and 31");var z,A,B,C,D=1<<31>>>0,E=1<>>0;if(d*y>=1<<30||d>D/128/y||d>D/256||E>D/128/d)throw new Error("scrypt: parameters are too large");"string"==typeof a&&(a=p(a)),"string"==typeof b&&(b=p(b)),"undefined"!=typeof Int32Array?(z=new Int32Array(64*d),A=new Int32Array(32*E*d),C=new Int32Array(16)):(z=[],A=[],C=new Array(16)),B=j(a,b,128*y*d);var F=0,G=32*d,H=!1;return"function"==typeof f?(h=g,g=f,f=1e3):("undefined"==typeof f||"string"==typeof f)&&(H=!0,h=f),H?(s(),t(0,E),u(0,E),v(),x()):(s(),void w(0,E,2*f,t,function(){w(0,E,2*f,u,function(){v(),g(x())})}))}"undefined"!=typeof module&&(module.exports=scrypt); \ No newline at end of file From c284e86f6b12ff7eab87bc938cd51df68b5e24ad Mon Sep 17 00:00:00 2001 From: Dmitry Chestnykh Date: Sun, 10 May 2015 19:31:59 +0200 Subject: [PATCH 3/4] Optimize for zero or negative interruptStep. If interruptStep is <= 0, avoid calling setTimeout, and calculate result immediately, passing it to callback. --- scrypt-async.js | 42 ++++++++++++++++++++++++++++-------------- test/unittests.js | 7 +++++++ 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/scrypt-async.js b/scrypt-async.js index 569c850..d863aa0 100644 --- a/scrypt-async.js +++ b/scrypt-async.js @@ -424,11 +424,11 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin })(); } - function getResult() { + function getResult(enc) { var result = PBKDF2_HMAC_SHA256_OneIter(password, B, dkLen); - if (encoding === 'base64') + if (enc === 'base64') return bytesToBase64(result); - else if (encoding === 'hex') + else if (enc === 'hex') return bytesToHex(result); else return result; @@ -448,23 +448,37 @@ function scrypt(password, salt, logN, r, dkLen, interruptStep, callback, encodin encoding = interruptStep; } - if (!isSync) { - // Async variant, calls callback with result. + if (isSync) { + // + // Sync variant, returns result. + // smixStart(); - interruptedFor(0, N, interruptStep*2, smixStep1, function() { - interruptedFor(0, N, interruptStep*2, smixStep2, function () { - smixFinish(); - callback(getResult()); - }); - }); + smixStep1(0, N); + smixStep2(0, N); + smixFinish(); + return getResult(encoding); - } else { - // Sync variant, returns result. + } else if (interruptStep <= 0) { + // + // Blocking async variant, calls callback. + // smixStart(); smixStep1(0, N); smixStep2(0, N); smixFinish(); - return getResult(); + callback(getResult(encoding)); + + } else { + // + // Async variant with interruptions, calls callback. + // + smixStart(); + interruptedFor(0, N, interruptStep*2, smixStep1, function() { + interruptedFor(0, N, interruptStep*2, smixStep2, function () { + smixFinish(); + callback(getResult(encoding)); + }); + }); } } diff --git a/test/unittests.js b/test/unittests.js index bb268ed..7178593 100644 --- a/test/unittests.js +++ b/test/unittests.js @@ -287,6 +287,13 @@ describe('argument order test', function() { }, "hex"); }); + it('all arguments, zero interruptStep', function(done) { + scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, 0, function(out) { + assert.equal(v.hexResult, out); + done(); + }, "hex"); + }); + it('drop encoding', function(done) { scrypt(v.password, v.salt, v.logN, v.r, v.dkLen, 1000, function(out) { assert.deepEqual(v.result, out); From 1762d5e3de7873d46338e5144c8ea874b1b3a341 Mon Sep 17 00:00:00 2001 From: Dmitry Chestnykh Date: Sun, 10 May 2015 20:24:00 +0200 Subject: [PATCH 4/4] Rebuild minified version. --- scrypt-async.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scrypt-async.min.js b/scrypt-async.min.js index a29c6f2..138e730 100644 --- a/scrypt-async.min.js +++ b/scrypt-async.min.js @@ -3,4 +3,4 @@ * Copyright (c) 2013-2015 Dmitry Chestnykh | BSD License * https://github.com/dchest/scrypt-async-js */ -function scrypt(a,b,c,d,e,f,g,h){"use strict";function i(a){function b(a){for(var b=0,m=a.length;m>=64;){var n,o,p,q,r,s=d,t=e,u=f,v=g,w=h,x=i,y=j,z=k;for(o=0;16>o;o++)p=b+4*o,l[o]=(255&a[p])<<24|(255&a[p+1])<<16|(255&a[p+2])<<8|255&a[p+3];for(o=16;64>o;o++)n=l[o-2],q=(n>>>17|n<<15)^(n>>>19|n<<13)^n>>>10,n=l[o-15],r=(n>>>7|n<<25)^(n>>>18|n<<14)^n>>>3,l[o]=(q+l[o-7]|0)+(r+l[o-16]|0)|0;for(o=0;64>o;o++)q=(((w>>>6|w<<26)^(w>>>11|w<<21)^(w>>>25|w<<7))+(w&x^~w&y)|0)+(z+(c[o]+l[o]|0)|0)|0,r=((s>>>2|s<<30)^(s>>>13|s<<19)^(s>>>22|s<<10))+(s&t^s&u^t&u)|0,z=y,y=x,x=w,w=v+q|0,v=u,u=t,t=s,s=q+r|0;d=d+s|0,e=e+t|0,f=f+u|0,g=g+v|0,h=h+w|0,i=i+x|0,j=j+y|0,k=k+z|0,b+=64,m-=64}}var c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d=1779033703,e=3144134277,f=1013904242,g=2773480762,h=1359893119,i=2600822924,j=528734635,k=1541459225,l=new Array(64);b(a);var m,n=a.length%64,o=a.length/536870912|0,p=a.length<<3,q=56>n?56:120,r=a.slice(a.length-n,a.length);for(r.push(128),m=n+1;q>m;m++)r.push(0);return r.push(o>>>24&255),r.push(o>>>16&255),r.push(o>>>8&255),r.push(o>>>0&255),r.push(p>>>24&255),r.push(p>>>16&255),r.push(p>>>8&255),r.push(p>>>0&255),b(r),[d>>>24&255,d>>>16&255,d>>>8&255,d>>>0&255,e>>>24&255,e>>>16&255,e>>>8&255,e>>>0&255,f>>>24&255,f>>>16&255,f>>>8&255,f>>>0&255,g>>>24&255,g>>>16&255,g>>>8&255,g>>>0&255,h>>>24&255,h>>>16&255,h>>>8&255,h>>>0&255,i>>>24&255,i>>>16&255,i>>>8&255,i>>>0&255,j>>>24&255,j>>>16&255,j>>>8&255,j>>>0&255,k>>>24&255,k>>>16&255,k>>>8&255,k>>>0&255]}function j(a,b,c){function d(){for(var a=f-1;a>=f-4;a--){if(g[a]++,g[a]<=255)return;g[a]=0}}a=a.length<=64?a:i(a);var e,f=64+b.length+4,g=new Array(f),h=new Array(64),j=[];for(e=0;64>e;e++)g[e]=54;for(e=0;ee;e++)g[e]=0;for(e=0;64>e;e++)h[e]=92;for(e=0;e=32;)d(),j=j.concat(i(h.concat(i(g)))),c-=32;return c>0&&(d(),j=j.concat(i(h.concat(i(g))).slice(0,c))),j}function k(a,b,c,d){var e,f,g=a[0]^b[c++],h=a[1]^b[c++],i=a[2]^b[c++],j=a[3]^b[c++],k=a[4]^b[c++],l=a[5]^b[c++],m=a[6]^b[c++],n=a[7]^b[c++],o=a[8]^b[c++],p=a[9]^b[c++],q=a[10]^b[c++],r=a[11]^b[c++],s=a[12]^b[c++],t=a[13]^b[c++],u=a[14]^b[c++],v=a[15]^b[c++],w=g,x=h,y=i,z=j,A=k,B=l,C=m,D=n,E=o,F=p,G=q,H=r,I=s,J=t,K=u,L=v;for(f=0;8>f;f+=2)e=w+I,A^=e<<7|e>>>25,e=A+w,E^=e<<9|e>>>23,e=E+A,I^=e<<13|e>>>19,e=I+E,w^=e<<18|e>>>14,e=B+x,F^=e<<7|e>>>25,e=F+B,J^=e<<9|e>>>23,e=J+F,x^=e<<13|e>>>19,e=x+J,B^=e<<18|e>>>14,e=G+C,K^=e<<7|e>>>25,e=K+G,y^=e<<9|e>>>23,e=y+K,C^=e<<13|e>>>19,e=C+y,G^=e<<18|e>>>14,e=L+H,z^=e<<7|e>>>25,e=z+L,D^=e<<9|e>>>23,e=D+z,H^=e<<13|e>>>19,e=H+D,L^=e<<18|e>>>14,e=w+z,x^=e<<7|e>>>25,e=x+w,y^=e<<9|e>>>23,e=y+x,z^=e<<13|e>>>19,e=z+y,w^=e<<18|e>>>14,e=B+A,C^=e<<7|e>>>25,e=C+B,D^=e<<9|e>>>23,e=D+C,A^=e<<13|e>>>19,e=A+D,B^=e<<18|e>>>14,e=G+F,H^=e<<7|e>>>25,e=H+G,E^=e<<9|e>>>23,e=E+H,F^=e<<13|e>>>19,e=F+E,G^=e<<18|e>>>14,e=L+K,I^=e<<7|e>>>25,e=I+L,J^=e<<9|e>>>23,e=J+I,K^=e<<13|e>>>19,e=K+J,L^=e<<18|e>>>14;b[d++]=a[0]=w+g|0,b[d++]=a[1]=x+h|0,b[d++]=a[2]=y+i|0,b[d++]=a[3]=z+j|0,b[d++]=a[4]=A+k|0,b[d++]=a[5]=B+l|0,b[d++]=a[6]=C+m|0,b[d++]=a[7]=D+n|0,b[d++]=a[8]=E+o|0,b[d++]=a[9]=F+p|0,b[d++]=a[10]=G+q|0,b[d++]=a[11]=H+r|0,b[d++]=a[12]=I+s|0,b[d++]=a[13]=J+t|0,b[d++]=a[14]=K+u|0,b[d++]=a[15]=L+v|0}function l(a,b,c,d,e){for(;e--;)a[b++]=c[d++]}function m(a,b,c,d,e){for(;e--;)a[b++]^=c[d++]}function n(a,b,c,d,e){l(a,0,b,c+16*(2*e-1),16);for(var f=0;2*e>f;f+=2)k(a,b,c+16*f,d+8*f),k(a,b,c+16*f+16,d+8*f+16*e)}function o(a,b,c){return a[b+16*(2*c-1)]}function p(a){for(var b=[],c=0;cd?b.push(d):d>127&&2048>d?(b.push(d>>6|192),b.push(63&d|128)):(b.push(d>>12|224),b.push(d>>6&63|128),b.push(63&d|128))}return b}function q(a){for(var b="0123456789abcdef".split(""),c=a.length,d=[],e=0;c>e;e++)d.push(b[a[e]>>>4&15]),d.push(b[a[e]>>>0&15]);return d.join("")}function r(a){for(var b,c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),g=a.length,h=[],i=0;g>i;)b=g>i?a[i++]:0,c=g>i?a[i++]:0,d=g>i?a[i++]:0,e=(b<<16)+(c<<8)+d,h.push(f[e>>>18&63]),h.push(f[e>>>12&63]),h.push(f[e>>>6&63]),h.push(f[e>>>0&63]);return g%3>0&&(h[h.length-1]="=",g%3===1&&(h[h.length-2]="=")),h.join("")}function s(){for(var a=0;32*d>a;a++){var b=4*a;z[F+a]=(255&B[b+3])<<24|(255&B[b+2])<<16|(255&B[b+1])<<8|(255&B[b+0])<<0}}function t(a,b){for(var c=a;b>c;c+=2)l(A,32*c*d,z,F,32*d),n(C,z,F,G,d),l(A,32*(c+1)*d,z,G,32*d),n(C,z,G,F,d)}function u(a,b){for(var c=a;b>c;c+=2){var e=o(z,F,d)&E-1;m(z,F,A,32*e*d,32*d),n(C,z,F,G,d),e=o(z,G,d)&E-1,m(z,G,A,32*e*d,32*d),n(C,z,G,F,d)}}function v(){for(var a=0;32*d>a;a++){var b=z[F+a];B[4*a+0]=b>>>0&255,B[4*a+1]=b>>>8&255,B[4*a+2]=b>>>16&255,B[4*a+3]=b>>>24&255}}function w(a,b,c,d,e){!function f(){setTimeout(function(){d(a,b>a+c?a+c:b),a+=c,b>a?f():e()},0)}()}function x(){var b=j(a,B,e);return"base64"===h?r(b):"hex"===h?q(b):b}var y=1;if(1>c||c>31)throw new Error("scrypt: logN not be between 1 and 31");var z,A,B,C,D=1<<31>>>0,E=1<>>0;if(d*y>=1<<30||d>D/128/y||d>D/256||E>D/128/d)throw new Error("scrypt: parameters are too large");"string"==typeof a&&(a=p(a)),"string"==typeof b&&(b=p(b)),"undefined"!=typeof Int32Array?(z=new Int32Array(64*d),A=new Int32Array(32*E*d),C=new Int32Array(16)):(z=[],A=[],C=new Array(16)),B=j(a,b,128*y*d);var F=0,G=32*d,H=!1;return"function"==typeof f?(h=g,g=f,f=1e3):("undefined"==typeof f||"string"==typeof f)&&(H=!0,h=f),H?(s(),t(0,E),u(0,E),v(),x()):(s(),void w(0,E,2*f,t,function(){w(0,E,2*f,u,function(){v(),g(x())})}))}"undefined"!=typeof module&&(module.exports=scrypt); \ No newline at end of file +function scrypt(a,b,c,d,e,f,g,h){"use strict";function i(a){function b(a){for(var b=0,m=a.length;m>=64;){var n,o,p,q,r,s=d,t=e,u=f,v=g,w=h,x=i,y=j,z=k;for(o=0;16>o;o++)p=b+4*o,l[o]=(255&a[p])<<24|(255&a[p+1])<<16|(255&a[p+2])<<8|255&a[p+3];for(o=16;64>o;o++)n=l[o-2],q=(n>>>17|n<<15)^(n>>>19|n<<13)^n>>>10,n=l[o-15],r=(n>>>7|n<<25)^(n>>>18|n<<14)^n>>>3,l[o]=(q+l[o-7]|0)+(r+l[o-16]|0)|0;for(o=0;64>o;o++)q=(((w>>>6|w<<26)^(w>>>11|w<<21)^(w>>>25|w<<7))+(w&x^~w&y)|0)+(z+(c[o]+l[o]|0)|0)|0,r=((s>>>2|s<<30)^(s>>>13|s<<19)^(s>>>22|s<<10))+(s&t^s&u^t&u)|0,z=y,y=x,x=w,w=v+q|0,v=u,u=t,t=s,s=q+r|0;d=d+s|0,e=e+t|0,f=f+u|0,g=g+v|0,h=h+w|0,i=i+x|0,j=j+y|0,k=k+z|0,b+=64,m-=64}}var c=[1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298],d=1779033703,e=3144134277,f=1013904242,g=2773480762,h=1359893119,i=2600822924,j=528734635,k=1541459225,l=new Array(64);b(a);var m,n=a.length%64,o=a.length/536870912|0,p=a.length<<3,q=56>n?56:120,r=a.slice(a.length-n,a.length);for(r.push(128),m=n+1;q>m;m++)r.push(0);return r.push(o>>>24&255),r.push(o>>>16&255),r.push(o>>>8&255),r.push(o>>>0&255),r.push(p>>>24&255),r.push(p>>>16&255),r.push(p>>>8&255),r.push(p>>>0&255),b(r),[d>>>24&255,d>>>16&255,d>>>8&255,d>>>0&255,e>>>24&255,e>>>16&255,e>>>8&255,e>>>0&255,f>>>24&255,f>>>16&255,f>>>8&255,f>>>0&255,g>>>24&255,g>>>16&255,g>>>8&255,g>>>0&255,h>>>24&255,h>>>16&255,h>>>8&255,h>>>0&255,i>>>24&255,i>>>16&255,i>>>8&255,i>>>0&255,j>>>24&255,j>>>16&255,j>>>8&255,j>>>0&255,k>>>24&255,k>>>16&255,k>>>8&255,k>>>0&255]}function j(a,b,c){function d(){for(var a=f-1;a>=f-4;a--){if(g[a]++,g[a]<=255)return;g[a]=0}}a=a.length<=64?a:i(a);var e,f=64+b.length+4,g=new Array(f),h=new Array(64),j=[];for(e=0;64>e;e++)g[e]=54;for(e=0;ee;e++)g[e]=0;for(e=0;64>e;e++)h[e]=92;for(e=0;e=32;)d(),j=j.concat(i(h.concat(i(g)))),c-=32;return c>0&&(d(),j=j.concat(i(h.concat(i(g))).slice(0,c))),j}function k(a,b,c,d){var e,f,g=a[0]^b[c++],h=a[1]^b[c++],i=a[2]^b[c++],j=a[3]^b[c++],k=a[4]^b[c++],l=a[5]^b[c++],m=a[6]^b[c++],n=a[7]^b[c++],o=a[8]^b[c++],p=a[9]^b[c++],q=a[10]^b[c++],r=a[11]^b[c++],s=a[12]^b[c++],t=a[13]^b[c++],u=a[14]^b[c++],v=a[15]^b[c++],w=g,x=h,y=i,z=j,A=k,B=l,C=m,D=n,E=o,F=p,G=q,H=r,I=s,J=t,K=u,L=v;for(f=0;8>f;f+=2)e=w+I,A^=e<<7|e>>>25,e=A+w,E^=e<<9|e>>>23,e=E+A,I^=e<<13|e>>>19,e=I+E,w^=e<<18|e>>>14,e=B+x,F^=e<<7|e>>>25,e=F+B,J^=e<<9|e>>>23,e=J+F,x^=e<<13|e>>>19,e=x+J,B^=e<<18|e>>>14,e=G+C,K^=e<<7|e>>>25,e=K+G,y^=e<<9|e>>>23,e=y+K,C^=e<<13|e>>>19,e=C+y,G^=e<<18|e>>>14,e=L+H,z^=e<<7|e>>>25,e=z+L,D^=e<<9|e>>>23,e=D+z,H^=e<<13|e>>>19,e=H+D,L^=e<<18|e>>>14,e=w+z,x^=e<<7|e>>>25,e=x+w,y^=e<<9|e>>>23,e=y+x,z^=e<<13|e>>>19,e=z+y,w^=e<<18|e>>>14,e=B+A,C^=e<<7|e>>>25,e=C+B,D^=e<<9|e>>>23,e=D+C,A^=e<<13|e>>>19,e=A+D,B^=e<<18|e>>>14,e=G+F,H^=e<<7|e>>>25,e=H+G,E^=e<<9|e>>>23,e=E+H,F^=e<<13|e>>>19,e=F+E,G^=e<<18|e>>>14,e=L+K,I^=e<<7|e>>>25,e=I+L,J^=e<<9|e>>>23,e=J+I,K^=e<<13|e>>>19,e=K+J,L^=e<<18|e>>>14;b[d++]=a[0]=w+g|0,b[d++]=a[1]=x+h|0,b[d++]=a[2]=y+i|0,b[d++]=a[3]=z+j|0,b[d++]=a[4]=A+k|0,b[d++]=a[5]=B+l|0,b[d++]=a[6]=C+m|0,b[d++]=a[7]=D+n|0,b[d++]=a[8]=E+o|0,b[d++]=a[9]=F+p|0,b[d++]=a[10]=G+q|0,b[d++]=a[11]=H+r|0,b[d++]=a[12]=I+s|0,b[d++]=a[13]=J+t|0,b[d++]=a[14]=K+u|0,b[d++]=a[15]=L+v|0}function l(a,b,c,d,e){for(;e--;)a[b++]=c[d++]}function m(a,b,c,d,e){for(;e--;)a[b++]^=c[d++]}function n(a,b,c,d,e){l(a,0,b,c+16*(2*e-1),16);for(var f=0;2*e>f;f+=2)k(a,b,c+16*f,d+8*f),k(a,b,c+16*f+16,d+8*f+16*e)}function o(a,b,c){return a[b+16*(2*c-1)]}function p(a){for(var b=[],c=0;cd?b.push(d):d>127&&2048>d?(b.push(d>>6|192),b.push(63&d|128)):(b.push(d>>12|224),b.push(d>>6&63|128),b.push(63&d|128))}return b}function q(a){for(var b="0123456789abcdef".split(""),c=a.length,d=[],e=0;c>e;e++)d.push(b[a[e]>>>4&15]),d.push(b[a[e]>>>0&15]);return d.join("")}function r(a){for(var b,c,d,e,f="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split(""),g=a.length,h=[],i=0;g>i;)b=g>i?a[i++]:0,c=g>i?a[i++]:0,d=g>i?a[i++]:0,e=(b<<16)+(c<<8)+d,h.push(f[e>>>18&63]),h.push(f[e>>>12&63]),h.push(f[e>>>6&63]),h.push(f[e>>>0&63]);return g%3>0&&(h[h.length-1]="=",g%3===1&&(h[h.length-2]="=")),h.join("")}function s(){for(var a=0;32*d>a;a++){var b=4*a;z[F+a]=(255&B[b+3])<<24|(255&B[b+2])<<16|(255&B[b+1])<<8|(255&B[b+0])<<0}}function t(a,b){for(var c=a;b>c;c+=2)l(A,32*c*d,z,F,32*d),n(C,z,F,G,d),l(A,32*(c+1)*d,z,G,32*d),n(C,z,G,F,d)}function u(a,b){for(var c=a;b>c;c+=2){var e=o(z,F,d)&E-1;m(z,F,A,32*e*d,32*d),n(C,z,F,G,d),e=o(z,G,d)&E-1,m(z,G,A,32*e*d,32*d),n(C,z,G,F,d)}}function v(){for(var a=0;32*d>a;a++){var b=z[F+a];B[4*a+0]=b>>>0&255,B[4*a+1]=b>>>8&255,B[4*a+2]=b>>>16&255,B[4*a+3]=b>>>24&255}}function w(a,b,c,d,e){!function f(){setTimeout(function(){d(a,b>a+c?a+c:b),a+=c,b>a?f():e()},0)}()}function x(b){var c=j(a,B,e);return"base64"===b?r(c):"hex"===b?q(c):c}var y=1;if(1>c||c>31)throw new Error("scrypt: logN not be between 1 and 31");var z,A,B,C,D=1<<31>>>0,E=1<>>0;if(d*y>=1<<30||d>D/128/y||d>D/256||E>D/128/d)throw new Error("scrypt: parameters are too large");"string"==typeof a&&(a=p(a)),"string"==typeof b&&(b=p(b)),"undefined"!=typeof Int32Array?(z=new Int32Array(64*d),A=new Int32Array(32*E*d),C=new Int32Array(16)):(z=[],A=[],C=new Array(16)),B=j(a,b,128*y*d);var F=0,G=32*d,H=!1;return"function"==typeof f?(h=g,g=f,f=1e3):("undefined"==typeof f||"string"==typeof f)&&(H=!0,h=f),H?(s(),t(0,E),u(0,E),v(),x(h)):void(0>=f?(s(),t(0,E),u(0,E),v(),g(x(h))):(s(),w(0,E,2*f,t,function(){w(0,E,2*f,u,function(){v(),g(x(h))})})))}"undefined"!=typeof module&&(module.exports=scrypt); \ No newline at end of file