From 0fb7dd4dffa9c64ccd02f605e7d7d583fa1857d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sun, 6 Mar 2022 12:25:37 +0000 Subject: [PATCH] crypto: add crypto.hash Refs: https://github.com/nodejs/node/issues/26748 --- benchmark/crypto/oneshot-hash.js | 33 ++++++++++++++++++++++++++++++++ lib/crypto.js | 4 +++- lib/internal/crypto/hash.js | 19 ++++++++++++++++++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 benchmark/crypto/oneshot-hash.js diff --git a/benchmark/crypto/oneshot-hash.js b/benchmark/crypto/oneshot-hash.js new file mode 100644 index 00000000000000..695857e50bf9cf --- /dev/null +++ b/benchmark/crypto/oneshot-hash.js @@ -0,0 +1,33 @@ +'use strict'; +const common = require('../common.js'); +const { hash, createHash } = require('crypto'); + +const bench = common.createBenchmark(main, { + mode: ['oneshot', 'stateful'], + algo: ['sha1', 'sha256', 'sha512'], + len: [2, 128, 1024, 64 * 1024], + n: [1e5], +}); + +function testOneshot(algo, data, n) { + bench.start(); + for (let i = 0; i < n; i++) + hash(algo, data); + bench.end(n); +} + +function testStateful(algo, data, n) { + bench.start(); + for (let i = 0; i < n; i++) + createHash(algo).update(data).digest(); + bench.end(n); +} + +function main({ mode, algo, len, n }) { + const data = Buffer.alloc(len); + if (mode === 'oneshot') { + testOneshot(algo, data, n); + } else { + testStateful(algo, data, n); + } +} diff --git a/lib/crypto.js b/lib/crypto.js index a839f5fe27b029..eb4d80a9798864 100644 --- a/lib/crypto.js +++ b/lib/crypto.js @@ -107,7 +107,8 @@ const { } = require('internal/crypto/sig'); const { Hash, - Hmac + Hmac, + hash } = require('internal/crypto/hash'); const { X509Certificate @@ -199,6 +200,7 @@ module.exports = { getCurves, getDiffieHellman: createDiffieHellmanGroup, getHashes, + hash, hkdf, hkdfSync, pbkdf2, diff --git a/lib/internal/crypto/hash.js b/lib/internal/crypto/hash.js index 6c502f52b66503..cb9b76514b6f68 100644 --- a/lib/internal/crypto/hash.js +++ b/lib/internal/crypto/hash.js @@ -11,6 +11,7 @@ const { HashJob, Hmac: _Hmac, kCryptoJobAsync, + kCryptoJobSync, } = internalBinding('crypto'); const { @@ -161,6 +162,23 @@ Hmac.prototype.digest = function digest(outputEncoding) { Hmac.prototype._flush = Hash.prototype._flush; Hmac.prototype._transform = Hash.prototype._transform; +function hash(algorithm, data, options) { + validateString(algorithm, 'algorithm'); + if (!isArrayBufferView(data)) { + throw new ERR_INVALID_ARG_TYPE( + 'data', ['Buffer', 'TypedArray', 'DataView'], data); + } + const xofLen = typeof options === 'object' && options !== null ? + options.outputLength : undefined; + if (xofLen !== undefined) + validateUint32(xofLen, 'options.outputLength'); + const { 0: err, 1: digest } = + new HashJob(kCryptoJobSync, algorithm, data, xofLen).run(); + if (err !== undefined) + throw err; + return digest; +} + // Implementation for WebCrypto subtle.digest() async function asyncDigest(algorithm, data) { @@ -181,5 +199,6 @@ async function asyncDigest(algorithm, data) { module.exports = { Hash, Hmac, + hash, asyncDigest, };