SimpleDRBG定義了一個簡單的(不符合FIPS的)DRBG,它基本上只是使用一系列HMAC值的NIST HMAC_Generate函數。請注意,請求1個字節,其次是另一個與同時詢問2個字節不同。
的RandomInt類是可以從類或從crypto
模塊Node.js的的使用兩randomBytes
類它創建任何隨機有限數字或範圍內的數字。
boundedRandomNumber
函數首先計算需要多少字節,這比要求的字節數量要高一點。這些字節然後被轉換爲一個大整數,稱爲candidate
。然後這個值返回,模數的界限。
while循環確保沒有偏向光譜的低端,因爲最高的candidate
值可能會返回介於0和X之間的值,其中X <在執行模bound
後被綁定。在那種情況下請求更多的字節。在目前的實現中,循環不止一次的機會並不是很高,所以這些函數應該是相對有效的。
所以文件simpledrbg.js
應包含:
crypto = require('crypto');
exports.SimpleDRBG = function (k) {
this.k = k;
this.v = new Buffer(0);
}
exports.SimpleDRBG.prototype.randomBytes = function(bytes) {
var result = new Buffer(0);
var generatedBytes = 0;
while (generatedBytes < bytes) {
this.hmac = crypto.createHmac('sha512', this.k);
this.hmac.update(this.v);
this.v = this.hmac.digest();
var tocopy = Math.min(this.v.length, bytes - generatedBytes);
if (tocopy == this.v.length) {
result = Buffer.concat([result, this.v]);
} else {
var vslice = this.v.slice(0, tocopy);
result = Buffer.concat([result, vslice]);
}
generatedBytes += tocopy;
}
return result;
}
和randomint.js
應包含:
crypto = require('crypto'),
bigint = require('bigint');
drbg = require('./simpledrbg');
function RandomInt(randomizer) {
this.randomizer = randomizer;
}
/**
* Returns a bounded random number, i.e. in the range [0..bound).
* The highest possible value that may be returned is bound - 1.
* Use boundedRandomNumber (bound + 1) if you want the bound value to
* be the highest possible value that can be returned.
*/
RandomInt.prototype.boundedRandomNumber = function (bound) {
BYTE_SIZE = 8;
bigBound = bigint(bound);
bigBoundLen = bigint(bigBound.bitLength());
// request a higher number of bytes just to be sure that
// the candidates are selected with high probability
bytesToRequest = bigBoundLen.add(BYTE_SIZE).sub(1).div(BYTE_SIZE).add(1);
// bigBound won't fit an integral number of times in the max value returned
// so if it is higher than the largest n times bigBound, we need to try
// again
maxCandidateExcl = bigint(0x100).pow(bytesToRequest).div(bigBound).mul(bigBound);
// just an assignment that will skip the initial test
candidate = maxCandidateExcl;
while (candidate.ge(maxCandidateExcl)) {
bytes = this.randomizer.randomBytes(bytesToRequest.toNumber());
candidate = bigint.fromBuffer(bytes);
}
// return the well distributed candidate % bound
return candidate.mod(bigBound).toNumber();
}
/**
* Returns a ranged random number, i.e. in the range [lowerBound..upperBound).
* The highest possible value that may be returned is upperBound - 1.
* Use rangedRandomNumber (lowerBound, upperBound + 1) if you want the upperBound value to
* be the highest possible value that can be returned.
*/
RandomInt.prototype.rangedRandomNumber = function (lowerBound, upperBound) {
return lowerBound + boundedRandomNumber (upperBound - lowerBound);
}
var randomIntTRNG = new RandomInt(crypto);
var testTRNG = randomIntTRNG.boundedRandomNumber(1000000);
console.log(testTRNG);
var randomIntDRNG = new RandomInt(new drbg.SimpleDRBG('seed'));
var testDRNG = randomIntDRNG.boundedRandomNumber(1000000);
console.log(testDRNG);
你爲什麼使用createHmac()?有更好的工具,這不是createHmac()的用途。試試crypto.randomBytes() – dandavis 2014-10-18 19:05:25
你能指點我其他工具嗎?我正在使用哈希函數,因爲我需要證明這個數字不是由我或某人操縱的。 – Lazy 2014-10-18 19:07:56
如果你想要一個散列,使用散列,就像md5或更好的東西,但我不會得到隨機部分進來的地方... – dandavis 2014-10-18 19:10:11