Skip to content

Commit 2240349

Browse files
committed
Add bitLen to Entropy class
Allows string creation of default bit len
1 parent a018deb commit 2240349

File tree

4 files changed

+326
-87
lines changed

4 files changed

+326
-87
lines changed

dist/lib/entropy.js

Lines changed: 70 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ Object.defineProperty(exports, "__esModule", {
55
});
66
exports.charset2 = exports.charset4 = exports.charset8 = exports.charset16 = exports.charset32 = exports.charset64 = undefined;
77

8-
var _log = require('babel-runtime/core-js/math/log2');
9-
10-
var _log2 = _interopRequireDefault(_log);
11-
128
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
139

1410
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
@@ -17,6 +13,10 @@ var _createClass2 = require('babel-runtime/helpers/createClass');
1713

1814
var _createClass3 = _interopRequireDefault(_createClass2);
1915

16+
var _log = require('babel-runtime/core-js/math/log2');
17+
18+
var _log2 = _interopRequireDefault(_log);
19+
2020
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
2121

2222
var Crypto = require('crypto');
@@ -103,22 +103,63 @@ var randomBytes = function randomBytes(count) {
103103
return buffer;
104104
};
105105

106+
var entropyBits = function entropyBits(total, risk) {
107+
if (total === 0) {
108+
return 0;
109+
}
110+
var log2 = _log2.default;
111+
112+
var N = void 0;
113+
if (total < 1000) {
114+
N = log2(total) + log2(total - 1);
115+
} else {
116+
N = 2 * log2(total);
117+
}
118+
return N + log2(risk) - 1;
119+
};
120+
121+
var createCharset = function createCharset(arg) {
122+
if (arg instanceof CharSet) {
123+
return arg;
124+
} else if (typeof arg === 'string' || arg instanceof String) {
125+
return new CharSet(arg);
126+
}
127+
return charset32;
128+
};
129+
106130
var _class = function () {
107-
function _class(arg) {
131+
function _class() {
132+
var arg = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { bits: 128, charset: CharSet.charset32 };
108133
(0, _classCallCheck3.default)(this, _class);
109134

110135
var charset = void 0;
111-
if (arg === undefined) {
112-
charset = charset32;
113-
} else if (arg instanceof CharSet) {
114-
charset = arg;
115-
} else if (typeof arg === 'string' || arg instanceof String) {
116-
charset = new CharSet(arg);
136+
var bitLen = 0;
137+
138+
if (arg instanceof CharSet || arg instanceof String || typeof arg === 'string') {
139+
charset = createCharset(arg);
140+
} else if (arg instanceof Object) {
141+
if (typeof arg.bits === 'number') {
142+
bitLen = arg.bits;
143+
} else if (typeof arg.total === 'number' && typeof arg.risk === 'number') {
144+
bitLen = entropyBits(arg.total, arg.risk);
145+
} else {
146+
throw new Error('Entropy params must include either bits or both total and risk');
147+
}
148+
charset = createCharset(arg.charset);
117149
} else {
118-
throw new Error('Invalid arg: must be either valid CharSet or valid chars');
150+
throw new Error('Constructor arg must either be a valid CharSet, valid characters, or valid Entropy params');
151+
}
152+
153+
if (charset === undefined) {
154+
throw new Error('Invalid constructor CharSet declaration');
155+
} else if (bits < 0) {
156+
throw new Error('Invalid constructor declaration of bits less than zero');
119157
}
158+
120159
var hideProps = {
121-
charset: charset
160+
charset: charset,
161+
bitLen: bitLen,
162+
bytesNeeded: charset.bytesNeeded(bitLen)
122163
};
123164
propMap.set(this, hideProps);
124165
}
@@ -160,9 +201,18 @@ var _class = function () {
160201
}
161202
}, {
162203
key: 'string',
163-
value: function string(bitLen) {
204+
value: function string() {
205+
var bitLen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;
164206
var charset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : propMap.get(this).charset;
165207

208+
if (bitLen === undefined) {
209+
var _propMap$get = propMap.get(this),
210+
classCharset = _propMap$get.charset,
211+
classBitLen = _propMap$get.bitLen,
212+
_bytesNeeded = _propMap$get.bytesNeeded;
213+
214+
return this.stringWithBytes(classBitLen, cryptoBytes(_bytesNeeded), classCharset);
215+
}
166216
var bytesNeeded = charset.bytesNeeded(bitLen);
167217
return this.stringWithBytes(bitLen, cryptoBytes(bytesNeeded), charset);
168218
}
@@ -193,6 +243,11 @@ var _class = function () {
193243
value: function chars() {
194244
return propMap.get(this).charset.chars();
195245
}
246+
}, {
247+
key: 'bits',
248+
value: function bits() {
249+
return propMap.get(this).bitLen;
250+
}
196251
}, {
197252
key: 'use',
198253
value: function use(charset) {
@@ -212,20 +267,7 @@ var _class = function () {
212267
}], [{
213268
key: 'bits',
214269
value: function bits(total, risk) {
215-
if (total === 0) {
216-
return 0;
217-
}
218-
219-
var log2 = _log2.default;
220-
221-
222-
var N = void 0;
223-
if (total < 1000) {
224-
N = log2(total) + log2(total - 1);
225-
} else {
226-
N = 2 * log2(total);
227-
}
228-
return N + log2(risk) - 1;
270+
return entropyBits(total, risk);
229271
}
230272
}]);
231273
return _class;

lib/entropy.js

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -75,38 +75,63 @@ const randomBytes = (count) => {
7575
return buffer
7676
}
7777

78+
const entropyBits = (total, risk) => {
79+
if (total === 0) { return 0 }
80+
const { log2 } = Math
81+
let N
82+
if (total < 1000) {
83+
N = log2(total) + log2(total - 1)
84+
} else {
85+
N = 2 * log2(total)
86+
}
87+
return (N + log2(risk)) - 1
88+
}
89+
90+
const createCharset = (arg) => {
91+
if (arg instanceof CharSet) {
92+
return arg
93+
} else if ((typeof arg === 'string' || arg instanceof String)) {
94+
return new CharSet(arg)
95+
}
96+
return charset32
97+
}
98+
7899
export default class {
79-
constructor(arg) {
100+
constructor(arg = { bits: 128, charset: charset32 }) {
80101
let charset
81-
if (arg === undefined) {
82-
charset = charset32
83-
} else if (arg instanceof CharSet) {
84-
charset = arg
85-
} else if ((typeof arg === 'string' || arg instanceof String)) {
86-
charset = new CharSet(arg)
102+
let bitLen = 0
103+
104+
if (arg instanceof CharSet || arg instanceof String || typeof arg === 'string') {
105+
charset = createCharset(arg)
106+
} else if (arg instanceof Object) {
107+
const { round } = Math
108+
if (typeof arg.bits === 'number') {
109+
bitLen = round(arg.bits)
110+
} else if (typeof arg.total === 'number' && typeof arg.risk === 'number') {
111+
bitLen = round(entropyBits(arg.total, arg.risk))
112+
} else {
113+
throw new Error('Entropy params must include either bits or both total and risk')
114+
}
115+
charset = createCharset(arg.charset)
87116
} else {
88-
throw new Error('Invalid arg: must be either valid CharSet or valid chars')
89-
}
90-
const hideProps = {
91-
charset
117+
throw new Error('Constructor arg must either be a valid CharSet, valid characters, or valid Entropy params')
92118
}
93-
propMap.set(this, hideProps)
94-
}
95-
96-
static bits(total, risk) {
97-
if (total === 0) { return 0 }
98119

99-
const { log2 } = Math
100-
101-
let N
102-
if (total < 1000) {
103-
N = log2(total) + log2(total - 1)
104-
} else {
105-
N = 2 * log2(total)
120+
if (charset === undefined) {
121+
throw new Error('Invalid constructor CharSet declaration')
122+
} else if (bitLen < 0) {
123+
throw new Error('Invalid constructor declaration of bits less than zero')
106124
}
107-
return (N + log2(risk)) - 1
125+
126+
propMap.set(this, {
127+
charset,
128+
bitLen,
129+
bytesNeeded: charset.bytesNeeded(bitLen)
130+
})
108131
}
109132

133+
static bits(total, risk) { return entropyBits(total, risk) }
134+
110135
smallID(charset = propMap.get(this).charset) {
111136
return this.string(29, charset)
112137
}
@@ -127,28 +152,39 @@ export default class {
127152
return this.string(256, charset)
128153
}
129154

130-
string(bitLen, charset = propMap.get(this).charset) {
155+
string(bitLen = propMap.get(this).bitLen, charset = propMap.get(this).charset) {
131156
const bytesNeeded = charset.bytesNeeded(bitLen)
132157
return this.stringWithBytes(bitLen, cryptoBytes(bytesNeeded), charset)
133158
}
134159

135-
stringRandom(bitLen, charset = propMap.get(this).charset) {
160+
stringPRNG(bitLen = propMap.get(this).bitLen, charset = propMap.get(this).charset) {
136161
const bytesNeeded = charset.bytesNeeded(bitLen)
137162
return this.stringWithBytes(bitLen, randomBytes(bytesNeeded), charset)
138163
}
139164

165+
/**
166+
* @deprecated Since version 3.1. Will be deleted in version 4.0. Use stringPRNG instead.
167+
*/
168+
stringRandom(bitLen = propMap.get(this).bitLen, charset = propMap.get(this).charset) {
169+
return this.stringPRNG(bitLen, charset)
170+
}
171+
140172
stringWithBytes(bitLen, bytes, charset = propMap.get(this).charset) {
141173
return stringWithBytes(bitLen, bytes, charset)
142174
}
143175

144-
bytesNeeded(bitLen, charset = propMap.get(this).charset) {
176+
bytesNeeded(bitLen = propMap.get(this).bitLen, charset = propMap.get(this).charset) {
145177
return charset.bytesNeeded(bitLen)
146178
}
147179

148180
chars() {
149181
return propMap.get(this).charset.chars()
150182
}
151183

184+
bits() {
185+
return propMap.get(this).bitLen
186+
}
187+
152188
use(charset) {
153189
if (!(charset instanceof CharSet)) { throw new Error('Invalid CharSet') }
154190
propMap.get(this).charset = charset

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "entropy-string",
3-
"version": "3.0.2",
3+
"version": "3.1.0",
44
"description": "Efficiently generate cryptographically strong random strings of specified entropy from various character sets.",
55
"main": "entropy-string.js",
66
"directories": {

0 commit comments

Comments
 (0)