From 6ddfca5f1452bfd4c2f77b7155ce7ffa6601bc2a Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Fri, 8 Nov 2019 19:45:57 +0100 Subject: [PATCH] Refactor S2K function --- src/type/s2k.js | 70 ++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/src/type/s2k.js b/src/type/s2k.js index e7771763..dac6d817 100644 --- a/src/type/s2k.js +++ b/src/type/s2k.js @@ -151,55 +151,41 @@ S2K.prototype.write = function () { */ S2K.prototype.produce_key = async function (passphrase, numBytes) { passphrase = util.encode_utf8(passphrase); - - async function round(prefix, s2k) { - const algorithm = enums.write(enums.hash, s2k.algorithm); - - switch (s2k.type) { - case 'simple': - return crypto.hash.digest(algorithm, util.concatUint8Array([prefix, passphrase])); - - case 'salted': - return crypto.hash.digest( - algorithm, - util.concatUint8Array([prefix, s2k.salt, passphrase]) - ); - - case 'iterated': { - const count = s2k.get_count(); - const data = util.concatUint8Array([s2k.salt, passphrase]); - let datalen = data.length; - const prefixlen = prefix.length; - const isp = new Uint8Array(prefixlen + count); - isp.set(prefix); - isp.set(data, prefixlen); - for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) { - isp.copyWithin(pos, prefixlen, pos); - } - return crypto.hash.digest(algorithm, isp); - } - case 'gnu': - throw new Error("GNU s2k type not supported."); - - default: - throw new Error("Unknown s2k type."); - } - } + const algorithm = enums.write(enums.hash, this.algorithm); const arr = []; let rlength = 0; - const prefix = new Uint8Array(numBytes); - for (let i = 0; i < numBytes; i++) { - prefix[i] = 0; - } - - let i = 0; + let prefixlen = 0; while (rlength < numBytes) { - const result = await round(prefix.subarray(0, i), this); + let toHash; + switch (this.type) { + case 'simple': + toHash = util.concatUint8Array([new Uint8Array(prefixlen), passphrase]); + break; + case 'salted': + toHash = util.concatUint8Array([new Uint8Array(prefixlen), this.salt, passphrase]); + break; + case 'iterated': { + const count = this.get_count(); + const data = util.concatUint8Array([this.salt, passphrase]); + let datalen = data.length; + toHash = new Uint8Array(prefixlen + count); + toHash.set(data, prefixlen); + for (let pos = prefixlen + datalen; pos < count; pos += datalen, datalen *= 2) { + toHash.copyWithin(pos, prefixlen, pos); + } + break; + } + case 'gnu': + throw new Error("GNU s2k type not supported."); + default: + throw new Error("Unknown s2k type."); + } + const result = await crypto.hash.digest(algorithm, toHash); arr.push(result); rlength += result.length; - i++; + prefixlen++; } return util.concatUint8Array(arr).subarray(0, numBytes);