From f40489aa43d55de1fce9fbd2845e8731af32790d Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Mon, 9 Apr 2018 14:50:07 +0200 Subject: [PATCH] Implement getLeftNBits, shiftLeft and shiftRight for Uint8Arrays --- src/crypto/public_key/dsa.js | 10 +++---- src/util.js | 53 +++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/src/crypto/public_key/dsa.js b/src/crypto/public_key/dsa.js index c686b7f6..a6c1da95 100644 --- a/src/crypto/public_key/dsa.js +++ b/src/crypto/public_key/dsa.js @@ -67,9 +67,8 @@ export default { // truncated) hash function result is treated as a number and used // directly in the DSA signature algorithm. const h = new BN( - util.str_to_Uint8Array( - util.getLeftNBits( - util.Uint8Array_to_str(hash.digest(hash_algo, m)), q.bitLength()))); + util.getLeftNBits( + hash.digest(hash_algo, m), q.bitLength())); // FIPS-186-4, section 4.6: // The values of r and s shall be checked to determine if r = 0 or s = 0. // If either r = 0 or s = 0, a new value of k shall be generated, and the @@ -116,9 +115,8 @@ export default { const redp = new BN.red(p); const redq = new BN.red(q); const h = new BN( - util.str_to_Uint8Array( - util.getLeftNBits( - util.Uint8Array_to_str(hash.digest(hash_algo, m)), q.bitLength()))); + util.getLeftNBits( + hash.digest(hash_algo, m), q.bitLength())); const w = s.toRed(redq).redInvm(); // s**-1 mod q if (zero.cmp(w) === 0) { util.print_debug("invalid DSA Signature"); diff --git a/src/util.js b/src/util.js index cd3bf2d1..ca062489 100644 --- a/src/util.js +++ b/src/util.js @@ -388,14 +388,13 @@ export default { } }, - // TODO rewrite getLeftNBits to work with Uint8Arrays - getLeftNBits: function (string, bitcount) { + getLeftNBits: function (array, bitcount) { const rest = bitcount % 8; if (rest === 0) { - return string.substring(0, bitcount / 8); + return array.subarray(0, bitcount / 8); } const bytes = (bitcount - rest) / 8 + 1; - const result = string.substring(0, bytes); + const result = array.subarray(0, bytes); return util.shiftRight(result, 8 - rest); // +String.fromCharCode(string.charCodeAt(bytes -1) << (8-rest) & 0xFF); }, @@ -431,25 +430,41 @@ export default { }, /** - * Shifting a string to n bits right - * @param {String} value The string to shift - * @param {Integer} bitcount Amount of bits to shift (MUST be smaller - * than 9) - * @returns {String} Resulting string. + * Shift a Uint8Array to the left by n bits + * @param {Uint8Array} array The array to shift + * @param {Integer} bits Amount of bits to shift (MUST be smaller + * than 8) + * @returns {String} Resulting array. */ - shiftRight: function (value, bitcount) { - const temp = util.str_to_Uint8Array(value); - if (bitcount % 8 !== 0) { - for (let i = temp.length - 1; i >= 0; i--) { - temp[i] >>= bitcount % 8; - if (i > 0) { - temp[i] |= (temp[i - 1] << (8 - (bitcount % 8))) & 0xFF; + shiftLeft: function (array, bits) { + if (bits) { + for (let i = 0; i < array.length; i++) { + array[i] <<= bits; + if (i + 1 < array.length) { + array[i] |= array[i + 1] >> (8 - bits); } } - } else { - return value; } - return util.Uint8Array_to_str(temp); + return array; + }, + + /** + * Shift a Uint8Array to the right by n bits + * @param {Uint8Array} array The array to shift + * @param {Integer} bits Amount of bits to shift (MUST be smaller + * than 8) + * @returns {String} Resulting array. + */ + shiftRight: function (array, bits) { + if (bits) { + for (let i = array.length - 1; i >= 0; i--) { + array[i] >>= bits; + if (i > 0) { + array[i] |= (array[i - 1] << (8 - bits)); + } + } + } + return array; }, /**