From 06992986337cb2e86916a259a493b9e5e02c342a Mon Sep 17 00:00:00 2001 From: Paul Shapiro Date: Mon, 27 Aug 2018 20:19:04 -0400 Subject: [PATCH] preventing calls to Math.random given existence (but probable unreachability) of emscripten call; added window.crypto-based impl of 0-1 float getRandom --- cryptonote_utils/cryptonote_utils.js | 7 ++++- monero_utils/monero_sendingFunds_utils.js | 34 ++++++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/cryptonote_utils/cryptonote_utils.js b/cryptonote_utils/cryptonote_utils.js index 4f6002f..f49a65f 100644 --- a/cryptonote_utils/cryptonote_utils.js +++ b/cryptonote_utils/cryptonote_utils.js @@ -34,7 +34,12 @@ const JSBigInt = require("./biginteger").BigInteger; const mnemonic = require("./mnemonic"); const nettype_utils = require("./nettype"); - +// +Math.random = function() +{ + throw "Math.random calls are disallowed (cryptonote_utils) until emscripten has support to override fallback when (!crypto) - see randomFloat_unit() or remove this in fork" +} +// var cnUtil = function(currencyConfig) { const currency_amount_format_utils = require("../cryptonote_utils/money_format_utils")(currencyConfig) diff --git a/monero_utils/monero_sendingFunds_utils.js b/monero_utils/monero_sendingFunds_utils.js index 63b1573..08eee02 100644 --- a/monero_utils/monero_sendingFunds_utils.js +++ b/monero_utils/monero_sendingFunds_utils.js @@ -901,8 +901,40 @@ function new_moneroReadyTargetDescriptions_fromTargetDescriptions( ); } // +function randomFloat_unit() +{ // https://stackoverflow.com/questions/34575635/cryptographically-secure-float?answertab=oldest#tab-top + // I've produced this function to replace Math.random, which we are black-holing to prevent emscripten from ever being able to call it (not that it is) + let buffer = new ArrayBuffer(8); // A buffer with just the right size to convert to Float64 + let ints = new Int8Array(buffer); // View it as an Int8Array and fill it with 8 random ints + window.crypto.getRandomValues(ints); + // + // Set the sign (ints[7][7]) to 0 and the + // exponent (ints[7][6]-[6][5]) to just the right size + // (all ones except for the highest bit) + ints[7] = 63; + ints[6] |= 0xf0; + // + // Now view it as a Float64Array, and read the one float from it + let float = new DataView(buffer).getFloat64(0, true) - 1; + // + return float; + +// Probably another way of doing this if the above is not good enough: +/* + if (typeof crypto !== "undefined") { + var randomBuffer = new Uint8Array(1); + crypto.getRandomValues(randomBuffer); + // + return randomBuffer[0] / 256.0; + } else if (ENVIRONMENT_IS_NODE) { + return require("crypto")["randomBytes"](1)[0] / 256.0 + } else { + throw "Unable to support randomFloat_unit without window.crypto or a \"crypto\" module" + } +*/ +} function __randomIndex(list) { - return Math.floor(Math.random() * list.length); + return Math.floor(randomFloat_unit() * list.length); } function _popAndReturnRandomElementFromList(list) { var idx = __randomIndex(list);