tApply(LazyTransform, this, [options]); } ObjectSetPrototypeOf(Hash.prototype, LazyTransform.prototype); ObjectSetPrototypeOf(Hash, LazyTransform); Hash.prototype.copy = function copy(options) { const state = this[kState]; if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); return new Hash(this[kHandle], options); }; Hash.prototype._transform = function _transform(chunk, encoding, callback) { this[kHandle].update(chunk, encoding); callback(); }; Hash.prototype._flush = function _flush(callback) { this.push(this[kHandle].digest()); callback(); }; Hash.prototype.update = function update(data, encoding) { encoding = encoding || getDefaultEncoding(); const state = this[kState]; if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); if (typeof data === 'string') { validateEncoding(data, encoding); } else if (!isArrayBufferView(data)) { throw new ERR_INVALID_ARG_TYPE( 'data', ['string', 'Buffer', 'TypedArray', 'DataView'], data); } if (!this[kHandle].update(data, encoding)) throw new ERR_CRYPTO_HASH_UPDATE_FAILED(); return this; }; Hash.prototype.digest = function digest(outputEncoding) { const state = this[kState]; if (state[kFinalized]) throw new ERR_CRYPTO_HASH_FINALIZED(); outputEncoding = outputEncoding || getDefaultEncoding(); // Explicit conversion for backward compatibility. const ret = this[kHandle].digest(`${outputEncoding}`); state[kFinalized] = true; return ret; }; function Hmac(hmac, key, options) { if (!(this instanceof Hmac)) return new Hmac(hmac, key, options); validateString(hmac, 'hmac'); const encoding = getStringOption(options, 'encoding'); key = prepareSecretKey(key, encoding); this[kHandle] = new _Hmac(); this[kHandle].init(hmac, key); this[kState] = { [kFinalized]: false }; ReflectApply(LazyTransform, this, [options]); } ObjectSetPrototypeOf(Hmac.prototype, LazyTransform.prototype); ObjectSetPrototypeOf(Hmac, LazyTransform); Hmac.prototype.update = Hash.prototype.update; Hmac.prototype.digest = function digest(outputEncoding) { const state = this[kState]; outputEncoding = outputEncoding || getDefaultEncoding(); if (state[kFinalized]) { const buf = Buffer.from(''); return outputEncoding === 'buffer' ? buf : buf.toString(outputEncoding); } // Explicit conversion for backward compatibility. const ret = this[kHandle].digest(`${outputEncoding}`); state[kFinalized] = true; return ret; }; Hmac.prototype._flush = Hash.prototype._flush; Hmac.prototype._transform = Hash.prototype._transform; // Implementation for WebCrypto subtle.digest() async function asyncDigest(algorithm, data) { algorithm = normalizeAlgorithm(algorithm); data = getArrayBufferOrView(data, 'data'); validateMaxBufferLength(data, 'data'); if (algorithm.length !== undefined) validateUint32(algorithm.length, 'algorithm.length'); return jobPromise(new HashJob( kCryptoJobAsync, normalizeHashName(algorithm.name), data, algorithm.length)); } module.exports = { Hash, Hmac, asyncDigest, };