@@ -146,6 +146,7 @@ function scryptInit(password: KDFInput, salt: KDFInput, _opts?: ScryptOpts) {
146146 const B32 = u32 ( B ) ;
147147 // Re-used between parallel iterations. Array(iterations) of B
148148 const V = u32 ( new Uint8Array ( blockSize * N ) ) ;
149+ const V0 = new Uint32Array ( V . buffer , V . byteOffset , blockSize32 ) ;
149150 const tmp = u32 ( new Uint8Array ( blockSize ) ) ;
150151 let blockMixCb = ( ) => { } ;
151152 if ( onProgress ) {
@@ -160,7 +161,7 @@ function scryptInit(password: KDFInput, salt: KDFInput, _opts?: ScryptOpts) {
160161 onProgress ( blockMixCnt / totalBlockMix ) ;
161162 } ;
162163 }
163- return { N, r, p, dkLen, blockSize32, V, B32 , B, tmp, blockMixCb, asyncTick } ;
164+ return { N, r, p, dkLen, blockSize32, V, V0 , B32 , B, tmp, blockMixCb, asyncTick } ;
164165}
165166
166167function scryptOutput (
@@ -181,15 +182,16 @@ function scryptOutput(
181182 * scrypt('password', 'salt', { N: 2**18, r: 8, p: 1, dkLen: 32 });
182183 */
183184export function scrypt ( password : KDFInput , salt : KDFInput , opts : ScryptOpts ) : Uint8Array {
184- const { N, r, p, dkLen, blockSize32, V, B32 , B, tmp, blockMixCb } = scryptInit (
185+ const { N, r, p, dkLen, blockSize32, V, V0 , B32 , B, tmp, blockMixCb } = scryptInit (
185186 password ,
186187 salt ,
187188 opts
188189 ) ;
189190 swap32IfBE ( B32 ) ;
190191 for ( let pi = 0 ; pi < p ; pi ++ ) {
191192 const Pi = blockSize32 * pi ;
192- for ( let i = 0 ; i < blockSize32 ; i ++ ) V [ i ] = B32 [ Pi + i ] ; // V[0] = B[i]
193+ const B32pi = new Uint32Array ( B . buffer , B . byteOffset + Pi * 4 , blockSize32 ) ;
194+ V0 . set ( B32pi ) ; // V[0] = B[i]
193195 for ( let i = 0 , pos = 0 ; i < N - 1 ; i ++ ) {
194196 BlockMix ( V , pos , V , ( pos += blockSize32 ) , r ) ; // V[i] = BlockMix(V[i-1]);
195197 blockMixCb ( ) ;
@@ -200,7 +202,8 @@ export function scrypt(password: KDFInput, salt: KDFInput, opts: ScryptOpts): Ui
200202 // First u32 of the last 64-byte block (u32 is LE)
201203 // & (N - 1) is % N as N is a power of 2, N & (N - 1) = 0 is checked above; >>> 0 for unsigned, input fits in u32
202204 const j = ( B32 [ Pi + blockSize32 - 16 ] & ( N - 1 ) ) >>> 0 ; // j = Integrify(X) % iterations
203- for ( let k = 0 ; k < blockSize32 ; k ++ ) tmp [ k ] = B32 [ Pi + k ] ^ V [ j * blockSize32 + k ] ; // tmp = B ^ V[j]
205+ tmp . set ( B32pi ) ; // tmp = B
206+ for ( let k = 0 ; k < blockSize32 ; k ++ ) tmp [ k ] ^= V [ j * blockSize32 + k ] ; // tmp = B ^ V[j]
204207 BlockMix ( tmp , 0 , B32 , Pi , r ) ; // B = BlockMix(B ^ V[j])
205208 blockMixCb ( ) ;
206209 }
@@ -219,15 +222,16 @@ export async function scryptAsync(
219222 salt : KDFInput ,
220223 opts : ScryptOpts
221224) : Promise < Uint8Array > {
222- const { N, r, p, dkLen, blockSize32, V, B32 , B, tmp, blockMixCb, asyncTick } = scryptInit (
225+ const { N, r, p, dkLen, blockSize32, V, V0 , B32 , B, tmp, blockMixCb, asyncTick } = scryptInit (
223226 password ,
224227 salt ,
225228 opts
226229 ) ;
227230 swap32IfBE ( B32 ) ;
228231 for ( let pi = 0 ; pi < p ; pi ++ ) {
229232 const Pi = blockSize32 * pi ;
230- for ( let i = 0 ; i < blockSize32 ; i ++ ) V [ i ] = B32 [ Pi + i ] ; // V[0] = B[i]
233+ const B32pi = new Uint32Array ( B . buffer , B . byteOffset + Pi * 4 , blockSize32 ) ;
234+ V0 . set ( B32pi ) ; // V[0] = B[i]
231235 let pos = 0 ;
232236 await asyncLoop ( N - 1 , asyncTick , ( ) => {
233237 BlockMix ( V , pos , V , ( pos += blockSize32 ) , r ) ; // V[i] = BlockMix(V[i-1]);
@@ -239,7 +243,8 @@ export async function scryptAsync(
239243 // First u32 of the last 64-byte block (u32 is LE)
240244 // & (N - 1) is % N as N is a power of 2, N & (N - 1) = 0 is checked above; >>> 0 for unsigned, input fits in u32
241245 const j = ( B32 [ Pi + blockSize32 - 16 ] & ( N - 1 ) ) >>> 0 ; // j = Integrify(X) % iterations
242- for ( let k = 0 ; k < blockSize32 ; k ++ ) tmp [ k ] = B32 [ Pi + k ] ^ V [ j * blockSize32 + k ] ; // tmp = B ^ V[j]
246+ tmp . set ( B32pi ) ; // tmp = B
247+ for ( let k = 0 ; k < blockSize32 ; k ++ ) tmp [ k ] ^= V [ j * blockSize32 + k ] ; // tmp = B ^ V[j]
243248 BlockMix ( tmp , 0 , B32 , Pi , r ) ; // B = BlockMix(B ^ V[j])
244249 blockMixCb ( ) ;
245250 } ) ;
0 commit comments