New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cryptohat

Package Overview
Dependencies
Maintainers
3
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cryptohat - npm Package Compare versions

Comparing version 1.0.0 to 1.0.1

test/index.html

182

index.js

@@ -0,1 +1,3 @@

(function(root) {
/**

@@ -26,3 +28,3 @@ * Cryptographically strong, hat-compatible, pseudo-random number generator

*/
var randomBufferSize = 1024;
var randomBufferSize = 4096;
/**

@@ -43,4 +45,37 @@ * The first unused byte in the random data buffer.

if (typeof(process) === "object" && typeof(process.versions) === "object" &&
typeof(process.versions["node"]) === "string") {
/**
* Generates a random identifier.
*
* This implements hat's API. Take a look at {@link crypto.numberGenerator} for
* a higher-performance API.
*
* @param {number} bits the desired number of bits of randomness
* @param {number} base the base/radix used to represent the random number;
* must be between 2 and 36
* @returns {string} a randomly generated identifier that meets the constraints
* above; the identifiers generated for a given base and number of bits are
* guaranteed to have the same length; in order to satisfy this constraint,
* the returned identifier might have leading zeros
* @alias cryptohat
*/
var cryptohat = function(bits, base) {
bits = bits || 128;
if (!base && base !== 0)
base = 16;
return cryptohat.generator(bits, base)();
};
if (typeof(module) !== "undefined" && "exports" in module) {
// Common.js environment.
module.exports = cryptohat;
} else {
// Browser.
if (typeof(global) !== "undefined")
root = global;
root.cryptohat = cryptohat;
}
if (typeof(process) !== "undefined" &&
typeof((process.versions || {}).node) === "string") {
// Node.js implementation based on crypto.randomBytes()

@@ -57,15 +92,25 @@ var crypto = require("crypto");

};
} else if (typeof(window.crypto) === "object" &&
typeof(window.crypto.getRandomBytes) === "function") {
// Modern browser implementation based on window.crypto.getRandomValues()
randomBuffer = new Uint32Array(randomBufferSize / 4);
// NOTE: This is exported for manual testing.
cryptohat._engine = "crypto.randomBytes()";
} else if (typeof(((root || {}).crypto || {}).getRandomValues) ===
"function") {
// Modern browser implementation based on the W3C Crypto API
// NOTE: Using the root object instead of window lets us find the Crypto API
// in Web workers.
randomBufferSize /= 4;
randomBuffer = new Uint32Array(randomBufferSize);
randomBufferOffset = randomBufferSize;
random32 = function() {
if (randomBufferOffset === randomBufferSize) {
randomBufferOffset = 0;
window.crypto.getRandomValues(randomBuffer);
root.crypto.getRandomValues(randomBuffer);
}
var returnValue = randomBuffer.readUInt32LE(randomBufferOffset);
randomBufferOffset += 4;
return randomBuffer[randomBufferOffset++];
var returnValue = randomBuffer[randomBufferOffset];
randomBufferOffset += 1;
return returnValue;
};
// NOTE: This is exported for manual testing.
cryptohat._engine = "window.crypto.getRandomValues()";
} else {

@@ -80,28 +125,10 @@ // Compatibility implementation for old browsers.

// better chance to implement the multiplication as << 32.
return Math.random() * 4294967296;
return Math.floor(Math.random() * 4294967296);
};
// NOTE: This is exported for manual testing.
cryptohat._engine = "Math.random()";
}
/**
* Generates a random identifier.
*
* This implements hat's API. Take a look at {@link crypto.numberGenerator} for
* a higher-performance API.
*
* @param {number} bits the desired number of bits of randomness
* @param {number} base the base/radix used to represent the random number;
* must be between 2 and 36
* @returns {string} a randomly generated identifier that meets the constraints
* above; the identifiers generated for a given base and number of bits are
* guaranteed to have the same length; in order to satisfy this constraint,
* the returned identifier might have leading zeros
*/
module.exports = function(bits, base) {
bits = bits || 128;
if (!base && base !== 0)
base = 16;
return module.exports.generator(bits, base)();
};
/**
* Cache for the generator functions produced by this module.

@@ -132,3 +159,3 @@ *

*/
module.exports.generator = function(bits, base) {
cryptohat.generator = function(bits, base) {
var cacheKey = (base) ? bits.toString() + "." + base.toString() :

@@ -240,3 +267,3 @@ bits.toString();

// NOTE: This is exported for testing.
module.exports._array32ToString = array32ToString;
cryptohat._array32ToString = array32ToString;

@@ -246,19 +273,19 @@ /**

*
* @param {string} string the string to be repeated
* @param {number} count the number of times to repeat the string
* @return {string} "string", repeated "count" times
* @return {string} a string consisting of count zero ("0") characters
* @private
*/
var stringRepeat = null;
var zeroRepeat = null;
if (typeof(String.prototype.repeat) === "function") {
// Fast path for node.js >= 4 and modern browsers.
stringRepeat = function(string, count) {
return string.repeat(count);
zeroRepeat = function(count) {
return "0".repeat(count);
};
} else {
// Slow path for node.js <= 0.12 and old browsers.
stringRepeat = function(string, count) {
zeroRepeat = function(count) {
var result = "";
for (var i = 0; i < count; ++i)
result += string;
result += "0";
return result;

@@ -268,5 +295,57 @@ };

// NOTE: This is exported for testing.
module.exports._stringRepeat = stringRepeat;
cryptohat._zeroRepeat = zeroRepeat;
/**
* Pads a string with zeros until it reaches a desired length.
*
* @param {string} string the string to be padded
* @param {number} the desired string length
* @return {string} a string that has at least the desired length; the returned
* string will consist of some zero ("0") characters, followed by the given
* string
* @private
*/
var zeroPad = function(string, length) {
var digitsNeeded = length - string.length;
if (digitsNeeded > 0)
string = zeroRepeat(digitsNeeded) + string;
return string;
};
// NOTE: This is exported for testing.
cryptohat._zeroPad = zeroPad;
/**
* Special case of {@link array32ToString} when base=16.
*
* @see array32ToString
* @param {Array<number>} array a big-endian representation of the number; each
* element in the array is a 32-bit digit; the elements in the array will be
* trashed
* @param {number} base the base/radix used to represent the number
* @param {Array<string>} digits buffer used to store an intermediate
* representation of the number; the elements in the array will be trashed
* @return {string} the textual representation of the number
* @private
*/
var array32ToHexString = function(array, base, digits) {
// NOTE: The digits array will generally be large enough to contain
// everything except for possibly the first few digits in the first
// array element.
var string = "";
for (var i = 0; i < array.length; ++i) {
// NOTE: Each 32-bit character expands to 8 hexadecimal digits.
string += zeroPad(array[i].toString(16), 8);
}
var extraCharacters = string.length - digits.length;
if (extraCharacters > 0)
string = string.substring(extraCharacters);
return string;
};
// NOTE: This is exported for testing.
cryptohat._array32ToHexString = array32ToHexString;
/**
* Creates a random identifier generator.

@@ -290,10 +369,6 @@ *

// Fast path where we can use JavaScript's toString().
var numberGenerator = module.exports.generator(bits, 0);
var numberGenerator = cryptohat.generator(bits, 0);
return function() {
var identifier = numberGenerator().toString(base);
var missingDigits = digitCount - identifier.length;
if (missingDigits > 0)
identifier = stringRepeat("0", missingDigits) + identifier;
return identifier;
}
return zeroPad(numberGenerator().toString(base), digitCount);
};
}

@@ -309,2 +384,3 @@

numbers[i] = 0;
var stringifer = (base === 16) ? array32ToHexString : array32ToString;
if (bits % 32 === 0) {

@@ -315,3 +391,3 @@ return function() {

return array32ToString(numbers, base, digits);
return stringifer(numbers, base, digits);
};

@@ -325,5 +401,7 @@ } else {

return array32ToString(numbers, base, digits);
return stringifer(numbers, base, digits);
};
}
};
})(this);
{
"name": "cryptohat",
"version": "1.0.0",
"version": "1.0.1",
"description": "Cryptographically strong, hat-compatible, pseudo-random number generator",

@@ -22,5 +22,7 @@ "keywords": ["hat", "crypto", "rng", "random"],

"devDependencies": {
"bower": ">= 0",
"chai": ">= 3.5.0",
"coveralls": ">= 2.11.8",
"hat": ">= 0.0.3",
"http-server": ">= 0",
"ink-docstrap": ">= 1.1.4",

@@ -32,4 +34,2 @@ "istanbul": ">= 0.4.2",

"mocha-lcov-reporter": ">= 1.2.0",
"sinon": ">= 1.17.3",
"sinon-chai": ">= 2.8.0",
"watch": ">= 0.16.0"

@@ -36,0 +36,0 @@ },

@@ -1,2 +0,2 @@

# Hat-Compatible CSPRNG
# `hat`-Compatible CSPRNG

@@ -12,7 +12,7 @@ [![Build Status](https://travis-ci.org/heap/cryptohat.svg?branch=master)](https://travis-ci.org/heap/cryptohat)

to generate the random identifiers. This is especially beneficial when using
older versions of [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine)
older versions of [V8](https://en.wikipedia.org/wiki/V8_(JavaScript_engine))
that exhibit [this bug](https://bugs.chromium.org/p/v8/issues/detail?id=4566).
In our use cases, `cryptohat` takes up to 3x more time to produce a random
identifier than `hat`. `cryptohat` also exposes an alternative API that
string than `hat`. However, `cryptohat` also exposes an alternative API that
produces random *numbers* up to 2x faster than `hat`, while still using a

@@ -24,12 +24,19 @@ CSPRNG.

This package is tested on node.js 0.10 and above. Browser support is planned
for a future version.
This package should work on any reasonably modern browser or node.js version.
Every commit is tested using [continuous integration](https://travis-ci.org/)
on node.js 0.10 and above. Releases are also tested against the most recent
versions of [Chrome](https://www.google.com/chrome/),
[Firefox](https://www.mozilla.org/firefox/),
[Safari](http://www.apple.com/safari/), and
[Internet Explorer](http://windows.microsoft.com/internet-explorer/).
## Installation
Install using [npm](https://www.npmjs.com/).
Install using [npm](https://www.npmjs.com/) or [bower](http://bower.io/).
```bash
npm install cryptohat@0.1.x --save
npm install cryptohat@1.x --save
bower install cryptohat@1.x --save
```

@@ -89,2 +96,3 @@

npm install
node node_modules/.bin/bower install
```

@@ -113,2 +121,20 @@

When modifying code around or inside feature detection blocks (combinations of
`if` and `typeof`), make sure the tests pass at least in Chrome and Firefox, by
opening [test/index.html](./test/index.html) in the browsers.
```bash
open test/index.html # On OSX.
xdg-open test/index.html # On Linux.
```
When testing against a browser in a VM (e.g., for Internet Explorer), spawn a
local Web server inside the source tree and visit it inside the VM
(e.g., `http://10.0.2.2:8080/test/index.html`).
```bash
node node_modules/.bin/http-server
```
If you submit a

@@ -115,0 +141,0 @@ [pull request](https://help.github.com/articles/using-pull-requests/),

@@ -1,14 +0,33 @@

var cryptohat = require("..");
var hat = require("hat");
(function() {
var cryptohat = __test.cryptohat;
var hat = __test.hat;
// Runs the target function for a number of iterations and returns the number
// of nanoseconds passed per iteration.
var benchmark = function (iterations, code) {
var t0 = process.hrtime();
for (var i = 0; i < iterations; ++i) {
code();
var benchmark = null;
if (typeof(process) !== "undefined" && typeof(process.hrtime) === "function") {
// Node.js implementation based on process.hrtime()
benchmark = function(iterations, code) {
var t0 = process.hrtime();
for (var i = 0; i < iterations; ++i) {
code();
}
t1 = process.hrtime();
return ((t1[0] - t0[0]) * 1e9 + t1[1] - t1[0]) / iterations;
}
t1 = process.hrtime();
} else if(typeof(performance) !== "undefined" &&
typeof(performance.now) === "function") {
// Browser implementation based on performance.now()
benchmark = function(iterations, code) {
var t0 = performance.now();
for (var i = 0; i < iterations; ++i) {
code();
}
t1 = performance.now();
return ((t1[0] - t0[0]) * 1e9 + t1[1] - t1[0]) / iterations;
return Math.ceil((t1 - t0) * 1e6);
}
}

@@ -59,3 +78,13 @@

});
it("is at most 2x slower than hat for base-16 128-bits", function() {
var baseline = benchmark(iterations, function() {
return hat(128, 16);
});
var us = benchmark(iterations, cryptohat.generator(128, 16));
console.log([baseline / us, "baseline", baseline, "us", us]);
expect(baseline / us).to.be.at.least(0.2);
});
});
});
})();

@@ -1,3 +0,4 @@

var cryptohat = require("..");
(function() {
var cryptohat = __test.cryptohat;
var generator = cryptohat.generator;

@@ -31,1 +32,3 @@

});
})();

@@ -1,6 +0,22 @@

global.chai = require("chai");
global.sinon = require("sinon");
global.chai.use(require("sinon-chai"));
(function(root) {
global.assert = global.chai.assert;
global.expect = global.chai.expect;
if (typeof(global) !== "undefined")
root = global;
root.__test = {};
if (typeof(require) === "function") {
root.__test.cryptohat = require("..");
root.chai = require("chai");
root.__test.hat = require("hat");
root.__test.lodash = require("lodash");
} else {
root.__test.cryptohat = root.cryptohat;
root.__test.hat = root.hat;
root.__test.lodash = root._;
}
root.assert = root.chai.assert;
root.expect = root.chai.expect;
})(this);

@@ -1,4 +0,6 @@

var _ = require("lodash");
var cryptohat = require("..");
(function() {
var _ = __test.lodash;
var cryptohat = __test.cryptohat;
var testNumberRng = function(generator, bits, count) {

@@ -187,1 +189,3 @@ var numbers = [];

});
})();

@@ -1,21 +0,52 @@

var cryptohat = require("..");
(function() {
var cryptohat = __test.cryptohat;
var array32ToString = cryptohat._array32ToString;
var stringRepeat = cryptohat._stringRepeat;
var array32ToHexString = cryptohat._array32ToHexString;
var zeroPad = cryptohat._zeroPad;
var zeroRepeat = cryptohat._zeroRepeat;
describe("cryptohat._stringRepeat", function() {
describe("cryptohat._zeroRepeat", function() {
it("works for count 0", function() {
expect(stringRepeat("a", 0)).to.equal("");
expect(zeroRepeat(0)).to.equal("");
});
it("works for count 1", function() {
expect(stringRepeat("a", 1)).to.equal("a");
expect(zeroRepeat(1)).to.equal("0");
});
it("works for count 2", function() {
expect(stringRepeat("a", 2)).to.equal("aa");
expect(zeroRepeat(2)).to.equal("00");
});
it("works for count 10", function() {
expect(stringRepeat("a", 10)).to.equal("aaaaaaaaaa");
expect(zeroRepeat(10)).to.equal("0000000000");
});
});
describe("cryptohat._zeroPad", function() {
it("works when length is count", function() {
expect(zeroPad("", 0)).to.equal("");
expect(zeroPad("a", 1)).to.equal("a");
expect(zeroPad("abc", 3)).to.equal("abc");
});
it("works when count exceeds length by 1", function() {
expect(zeroPad("", 1)).to.equal("0");
expect(zeroPad("a", 2)).to.equal("0a");
expect(zeroPad("abc", 4)).to.equal("0abc");
});
it("works when count exceeds length by 2", function() {
expect(zeroPad("", 2)).to.equal("00");
expect(zeroPad("a", 3)).to.equal("00a");
expect(zeroPad("abc", 5)).to.equal("00abc");
});
it("works when count exceeds length by 7", function() {
expect(zeroPad("", 7)).to.equal("0000000");
expect(zeroPad("a", 8)).to.equal("0000000a");
expect(zeroPad("abc", 10)).to.equal("0000000abc");
});
it("works when length exceeds count", function() {
expect(zeroPad("a", 0)).to.equal("a");
expect(zeroPad("abc", 2)).to.equal("abc");
});
});
describe("cryptohat._array32ToString", function() {

@@ -47,2 +78,4 @@ describe("with base == 16", function() {

new Array(24))).to.equal("ffffffffffffffffffffffff");
expect(array32ToString([0xffffffff, 0x0, 0xffffffff], 16,
new Array(24))).to.equal("ffffffff00000000ffffffff");
});

@@ -93,1 +126,33 @@ });

});
describe("cryptohat._array32ToHexString", function() {
it("works on zero", function() {
expect(array32ToHexString([0], 16, new Array(4))).to.equal("0000");
expect(array32ToHexString([0, 0], 16, new Array(4))).to.equal("0000");
});
it("works on one-element arrays", function() {
expect(array32ToHexString([0x1], 16, new Array(4))).to.equal("0001");
expect(array32ToHexString([0xf], 16, new Array(4))).to.equal("000f");
expect(array32ToHexString([0x1234], 16, new Array(8))).to.equal(
"00001234");
expect(array32ToHexString([0x12345678], 16, new Array(8))).to.equal(
"12345678");
expect(array32ToHexString([0xffffffff], 16, new Array(8))).to.equal(
"ffffffff");
});
it("works on multi-element arrays", function() {
expect(array32ToHexString([0xa, 0x12345678], 16, new Array(12))).to.equal(
"000a12345678");
expect(array32ToHexString([0xfedc, 0xba987654], 16, new Array(12))).to.
equal("fedcba987654");
expect(array32ToHexString([0xffffffff, 0xffffffff, 0xffffffff], 16,
new Array(24))).to.equal("ffffffffffffffffffffffff");
expect(array32ToHexString([0xffffffff, 0x0, 0xffffffff], 16,
new Array(24))).to.equal("ffffffff00000000ffffffff");
});
});
})();

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc