import { Sha1 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha1/sha1';import { Sha256 } from '@openpgp/asmcrypto.js/dist_es8/hash/sha256/sha256';import sha224 from 'hash.js/lib/hash/sha/224';import sha384 from 'hash.js/lib/hash/sha/384';import sha512 from 'hash.js/lib/hash/sha/512';import { ripemd160 } from 'hash.js/lib/hash/ripemd';import * as stream from '@openpgp/web-stream-tools';import md5 from './md5';import util from '../../util';import defaultConfig from '../../config';import enums from '../../enums';
const webCrypto = util.getWebCrypto();const nodeCrypto = util.getNodeCrypto();
function nodeHash(type) { return async function (data) { const shasum = nodeCrypto.createHash(type); return stream.transform(data, value => { shasum.update(value); }, () => new Uint8Array(shasum.digest())); };}
function hashjsHash(hash, webCryptoHash) { return async function(data, config = defaultConfig) { if (stream.isArrayStream(data)) { data = await stream.readToEnd(data); } if (!util.isStream(data) && webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) { return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); } const hashInstance = hash(); return stream.transform(data, value => { hashInstance.update(value); }, () => new Uint8Array(hashInstance.digest())); };}
function asmcryptoHash(hash, webCryptoHash) { return async function(data, config = defaultConfig) { if (stream.isArrayStream(data)) { data = await stream.readToEnd(data); } if (util.isStream(data)) { const hashInstance = new hash(); return stream.transform(data, value => { hashInstance.process(value); }, () => hashInstance.finish().result); } else if (webCrypto && webCryptoHash && data.length >= config.minBytesForWebCrypto) { return new Uint8Array(await webCrypto.digest(webCryptoHash, data)); } else { return hash.bytes(data); } };}
let hashFunctions;if (nodeCrypto) { hashFunctions = { md5: nodeHash('md5'), sha1: nodeHash('sha1'), sha224: nodeHash('sha224'), sha256: nodeHash('sha256'), sha384: nodeHash('sha384'), sha512: nodeHash('sha512'), ripemd: nodeHash('ripemd160') };} else { hashFunctions = { md5: md5, sha1: asmcryptoHash(Sha1, 'SHA-1'), sha224: hashjsHash(sha224), sha256: asmcryptoHash(Sha256, 'SHA-256'), sha384: hashjsHash(sha384, 'SHA-384'), sha512: hashjsHash(sha512, 'SHA-512'), ripemd: hashjsHash(ripemd160) };}
export default {
md5: hashFunctions.md5, sha1: hashFunctions.sha1, sha224: hashFunctions.sha224, sha256: hashFunctions.sha256, sha384: hashFunctions.sha384, sha512: hashFunctions.sha512, ripemd: hashFunctions.ripemd,
digest: function(algo, data) { switch (algo) { case enums.hash.md5: return this.md5(data); case enums.hash.sha1: return this.sha1(data); case enums.hash.ripemd: return this.ripemd(data); case enums.hash.sha256: return this.sha256(data); case enums.hash.sha384: return this.sha384(data); case enums.hash.sha512: return this.sha512(data); case enums.hash.sha224: return this.sha224(data); default: throw new Error('Invalid hash function.'); } },
getHashByteLength: function(algo) { switch (algo) { case enums.hash.md5: return 16; case enums.hash.sha1: case enums.hash.ripemd: return 20; case enums.hash.sha256: return 32; case enums.hash.sha384: return 48; case enums.hash.sha512: return 64; case enums.hash.sha224: return 28; default: throw new Error('Invalid hash algorithm.'); } }};