diff --git a/modules/crypto/src/lib/crc32-hash.ts b/modules/crypto/src/lib/crc32-hash.ts index 25bf76eba1..70b73a170e 100644 --- a/modules/crypto/src/lib/crc32-hash.ts +++ b/modules/crypto/src/lib/crc32-hash.ts @@ -12,12 +12,10 @@ export class CRC32Hash extends Hash { readonly name = 'crc32'; options; - private _hash: CRC32; constructor(options = {}) { super(); this.options = {crypto: {}, ...options}; - this._hash = new CRC32(); this.hashBatches = this.hashBatches.bind(this); } @@ -30,8 +28,9 @@ export class CRC32Hash extends Hash { } hashSync(input: ArrayBuffer, encoding: 'hex' | 'base64'): string { - this._hash.update(input); - const digest = this._hash.finalize(); + const hash = new CRC32(); + hash.update(input); + const digest = hash.finalize(); return encodeNumber(digest, encoding); } @@ -39,12 +38,12 @@ export class CRC32Hash extends Hash { asyncIterator: AsyncIterable | Iterable, encoding: 'hex' | 'base64' = 'base64' ): AsyncIterable { + const hash = new CRC32(); for await (const chunk of asyncIterator) { - this._hash.update(chunk); + hash.update(chunk); yield chunk; } - const digest = this._hash.finalize(); - const hash = encodeNumber(digest, encoding); - this.options.crypto?.onEnd?.({hash}); + const digest = hash.finalize(); + this.options.crypto?.onEnd?.({hash: encodeNumber(digest, encoding)}); } } diff --git a/modules/crypto/src/lib/crc32c-hash.ts b/modules/crypto/src/lib/crc32c-hash.ts index 9a623a04e2..245279a6cb 100644 --- a/modules/crypto/src/lib/crc32c-hash.ts +++ b/modules/crypto/src/lib/crc32c-hash.ts @@ -12,7 +12,6 @@ export class CRC32CHash extends Hash { readonly name = 'crc32c'; options; - private _hash: CRC32C; /** * Atomic hash calculation @@ -21,7 +20,6 @@ export class CRC32CHash extends Hash { constructor(options = {}) { super(); this.options = {crypto: {}, ...options}; - this._hash = new CRC32C(options); } /** @@ -33,8 +31,9 @@ export class CRC32CHash extends Hash { } hashSync(input: ArrayBuffer, encoding: 'hex' | 'base64'): string { - this._hash.update(input); - const digest = this._hash.finalize(); + const hash = new CRC32C(this.options); + hash.update(input); + const digest = hash.finalize(); return encodeNumber(digest, encoding); } @@ -44,12 +43,12 @@ export class CRC32CHash extends Hash { asyncIterator: AsyncIterable | Iterable, encoding: 'hex' | 'base64' = 'base64' ): AsyncIterable { + const hash = new CRC32C(this.options); for await (const chunk of asyncIterator) { - this._hash.update(chunk); + hash.update(chunk); yield chunk; } - const digest = this._hash.finalize(); - const hash = encodeNumber(digest, encoding); - this.options.crypto?.onEnd?.({hash}); + const digest = hash.finalize(); + this.options.crypto?.onEnd?.({hash: encodeNumber(digest, encoding)}); } } diff --git a/modules/crypto/src/lib/crypto-hash.ts b/modules/crypto/src/lib/crypto-hash.ts index 98f58171fd..2887515327 100644 --- a/modules/crypto/src/lib/crypto-hash.ts +++ b/modules/crypto/src/lib/crypto-hash.ts @@ -18,8 +18,10 @@ export class CryptoHash extends Hash { readonly name; options: CryptoHashOptions; + /** Name of digest algorithm */ private _algorithm; - private _hash; + /** CryptoJS algorithm */ + private _algo; constructor(options: CryptoHashOptions) { super(); @@ -38,13 +40,7 @@ export class CryptoHash extends Hash { if (!CryptoJS) { throw new Error(this.name); } - if (!this._hash) { - const algo = CryptoJS.algo[this._algorithm]; - this._hash = algo.create(); - } - if (!this._hash) { - throw new Error(this.name); - } + this._algo = CryptoJS.algo[this._algorithm]; } /** @@ -53,12 +49,18 @@ export class CryptoHash extends Hash { */ async hash(input: ArrayBuffer, encoding: 'hex' | 'base64'): Promise { await this.preload(); + + const hash = this._algo.create(); + if (!hash) { + throw new Error(this.name); + } + // arrayBuffer is accepted, even though types and docs say no // https://stackoverflow.com/questions/25567468/how-to-decrypt-an-arraybuffer const typedWordArray = CryptoJS.lib.WordArray.create(input); // Map our encoding constant to Crypto library const enc = encoding === 'base64' ? CryptoJS.enc.Base64 : CryptoJS.enc.Hex; - return this._hash.update(typedWordArray).finalize().toString(enc); + return hash.update(typedWordArray).finalize().toString(enc); } async *hashBatches( @@ -66,16 +68,23 @@ export class CryptoHash extends Hash { encoding: 'hex' | 'base64' = 'base64' ): AsyncIterable { await this.preload(); + + const hash = this._algo.create(); + if (!hash) { + throw new Error(this.name); + } + for await (const chunk of asyncIterator) { // arrayBuffer is accepted, even though types and docs say no // https://stackoverflow.com/questions/25567468/how-to-decrypt-an-arraybuffer const typedWordArray = CryptoJS.lib.WordArray.create(chunk); - this._hash.update(typedWordArray); + hash.update(typedWordArray); yield chunk; } + // Map our encoding constant to Crypto library const enc = encoding === 'base64' ? CryptoJS.enc.Base64 : CryptoJS.enc.Hex; - const digest = this._hash.finalize().toString(enc); + const digest = hash.finalize().toString(enc); this.options?.crypto?.onEnd?.({hash: digest}); } }