(data: string, salt: Uint8Array, iterations: number, cryptoMethod: CryptoMethod)
| 308 | }; |
| 309 | |
| 310 | async function HI(data: string, salt: Uint8Array, iterations: number, cryptoMethod: CryptoMethod) { |
| 311 | // omit the work if already generated |
| 312 | const key = [data, ByteUtils.toBase64(salt), iterations].join('_'); |
| 313 | if (_hiCache[key] != null) { |
| 314 | return _hiCache[key]; |
| 315 | } |
| 316 | |
| 317 | const keyMaterial = await crypto.subtle.importKey( |
| 318 | 'raw', |
| 319 | new TextEncoder().encode(data), |
| 320 | { name: 'PBKDF2' }, |
| 321 | false, |
| 322 | ['deriveBits'] |
| 323 | ); |
| 324 | const params = { |
| 325 | name: 'PBKDF2', |
| 326 | salt: salt, |
| 327 | iterations: iterations, |
| 328 | hash: { name: cryptoMethod === 'sha256' ? 'SHA-256' : 'SHA-1' } |
| 329 | }; |
| 330 | const derivedBits = await crypto.subtle.deriveBits( |
| 331 | params, |
| 332 | keyMaterial, |
| 333 | hiLengthMap[cryptoMethod] * 8 |
| 334 | ); |
| 335 | const saltedData = new Uint8Array(derivedBits); |
| 336 | |
| 337 | // cache a copy to speed up the next lookup, but prevent unbounded cache growth |
| 338 | if (_hiCacheCount >= 200) { |
| 339 | _hiCachePurge(); |
| 340 | } |
| 341 | |
| 342 | _hiCache[key] = saltedData; |
| 343 | _hiCacheCount += 1; |
| 344 | return saltedData; |
| 345 | } |
| 346 | |
| 347 | function compareDigest(lhs: Uint8Array, rhs: Uint8Array) { |
| 348 | if (lhs.length !== rhs.length) { |
no test coverage detected