Skip to content

Commit 4aba8ac

Browse files
committed
Switch from bigint to bignum.
This makes node-srp easier to use (simplified dependencies). It is about 30% slower (getV with bigint took 1.78ms, bignum took 2.35ms, on my 2012 MBP laptop). Run test/speed.js to measure this. Original patch from Danny Coates, extracted from PR mozilla#9.
1 parent b4a5676 commit 4aba8ac

8 files changed

+114
-94
lines changed

index.js

-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
module.exports = require('./lib/srp');
22

33
module.exports.params = require('./lib/params');
4-

lib/params.js

+22-22
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,30 @@
1111
* The 1024-bit and 1536-bit groups MUST be supported.
1212
*/
1313

14-
const bigint = require('bigint');
14+
const bignum = require('bignum');
1515

1616
module.exports = {
1717

1818
1024: {
19-
N: bigint('EEAF0AB9 ADB38DD6 9C33F80A FA8FC5E8 60726187 75FF3C0B 9EA2314C'
19+
N: bignum(('EEAF0AB9 ADB38DD6 9C33F80A FA8FC5E8 60726187 75FF3C0B 9EA2314C'
2020
+'9C256576 D674DF74 96EA81D3 383B4813 D692C6E0 E0D5D8E2 50B98BE4'
2121
+'8E495C1D 6089DAD1 5DC7D7B4 6154D6B6 CE8EF4AD 69B15D49 82559B29'
2222
+'7BCF1885 C529F566 660E57EC 68EDBC3C 05726CC0 2FD4CBF4 976EAA9A'
23-
+'FD5138FE 8376435B 9FC61D2F C0EB06E3', 16),
24-
g: bigint(2)},
23+
+'FD5138FE 8376435B 9FC61D2F C0EB06E3').split(/\s/).join(''), 16),
24+
g: bignum(2)},
2525

2626
1536: {
27-
N: bigint('9DEF3CAF B939277A B1F12A86 17A47BBB DBA51DF4 99AC4C80 BEEEA961'
27+
N: bignum(('9DEF3CAF B939277A B1F12A86 17A47BBB DBA51DF4 99AC4C80 BEEEA961'
2828
+'4B19CC4D 5F4F5F55 6E27CBDE 51C6A94B E4607A29 1558903B A0D0F843'
2929
+'80B655BB 9A22E8DC DF028A7C EC67F0D0 8134B1C8 B9798914 9B609E0B'
3030
+'E3BAB63D 47548381 DBC5B1FC 764E3F4B 53DD9DA1 158BFD3E 2B9C8CF5'
3131
+'6EDF0195 39349627 DB2FD53D 24B7C486 65772E43 7D6C7F8C E442734A'
3232
+'F7CCB7AE 837C264A E3A9BEB8 7F8A2FE9 B8B5292E 5A021FFF 5E91479E'
33-
+'8CE7A28C 2442C6F3 15180F93 499A234D CF76E3FE D135F9BB', 16),
34-
g: bigint(2)},
33+
+'8CE7A28C 2442C6F3 15180F93 499A234D CF76E3FE D135F9BB').split(/\s/).join(''), 16),
34+
g: bignum(2)},
3535

3636
2048: {
37-
N: bigint('AC6BDB41 324A9A9B F166DE5E 1389582F AF72B665 1987EE07 FC319294'
37+
N: bignum(('AC6BDB41 324A9A9B F166DE5E 1389582F AF72B665 1987EE07 FC319294'
3838
+'3DB56050 A37329CB B4A099ED 8193E075 7767A13D D52312AB 4B03310D'
3939
+'CD7F48A9 DA04FD50 E8083969 EDB767B0 CF609517 9A163AB3 661A05FB'
4040
+'D5FAAAE8 2918A996 2F0B93B8 55F97993 EC975EEA A80D740A DBF4FF74'
@@ -43,11 +43,11 @@ module.exports = {
4343
+'5EA77A27 75D2ECFA 032CFBDB F52FB378 61602790 04E57AE6 AF874E73'
4444
+'03CE5329 9CCC041C 7BC308D8 2A5698F3 A8D0C382 71AE35F8 E9DBFBB6'
4545
+'94B5C803 D89F7AE4 35DE236D 525F5475 9B65E372 FCD68EF2 0FA7111F'
46-
+'9E4AFF73', 16),
47-
g: bigint(2)},
46+
+'9E4AFF73').split(/\s/).join(''), 16),
47+
g: bignum(2)},
4848

4949
3072: {
50-
N: bigint('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
50+
N: bignum(('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
5151
+'8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B'
5252
+'302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9'
5353
+'A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6'
@@ -60,11 +60,11 @@ module.exports = {
6060
+'B3970F85 A6E1E4C7 ABF5AE8C DB0933D7 1E8C94E0 4A25619D CEE3D226'
6161
+'1AD2EE6B F12FFA06 D98A0864 D8760273 3EC86A64 521F2B18 177B200C'
6262
+'BBE11757 7A615D6C 770988C0 BAD946E2 08E24FA0 74E5AB31 43DB5BFC'
63-
+'E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF', 16),
64-
g: bigint(5)},
63+
+'E0FD108E 4B82D120 A93AD2CA FFFFFFFF FFFFFFFF').split(/\s/).join(''), 16),
64+
g: bignum(5)},
6565

6666
4096: {
67-
N: bigint('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
67+
N: bignum(('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
6868
+'8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B'
6969
+'302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9'
7070
+'A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6'
@@ -82,11 +82,11 @@ module.exports = {
8282
+'04DE8EF9 2E8EFC14 1FBECAA6 287C5947 4E6BC05D 99B2964F A090C3A2'
8383
+'233BA186 515BE7ED 1F612970 CEE2D7AF B81BDD76 2170481C D0069127'
8484
+'D5B05AA9 93B4EA98 8D8FDDC1 86FFB7DC 90A6C08F 4DF435C9 34063199'
85-
+'FFFFFFFF FFFFFFFF', 16),
86-
g: bigint(5)},
85+
+'FFFFFFFF FFFFFFFF').split(/\s/).join(''), 16),
86+
g: bignum(5)},
8787

8888
6244: {
89-
N: bigint('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
89+
N: bignum(('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
9090
+'8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B'
9191
+'302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9'
9292
+'A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6'
@@ -113,11 +113,11 @@ module.exports = {
113113
+'CC8F6D7E BF48E1D8 14CC5ED2 0F8037E0 A79715EE F29BE328 06A1D58B'
114114
+'B7C5DA76 F550AA3D 8A1FBFF0 EB19CCB1 A313D55C DA56C9EC 2EF29632'
115115
+'387FE8D7 6E3C0468 043E8F66 3F4860EE 12BF2D5B 0B7474D6 E694F91E'
116-
+'6DCC4024 FFFFFFFF FFFFFFFF', 16),
117-
g: bigint(5)},
116+
+'6DCC4024 FFFFFFFF FFFFFFFF').split(/\s/).join(''), 16),
117+
g: bignum(5)},
118118

119119
8192: {
120-
N: bigint('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
120+
N: bignum(('FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 29024E08'
121121
+'8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD EF9519B3 CD3A431B'
122122
+'302B0A6D F25F1437 4FE1356D 6D51C245 E485B576 625E7EC6 F44C42E9'
123123
+'A637ED6B 0BFF5CB6 F406B7ED EE386BFB 5A899FA5 AE9F2411 7C4B1FE6'
@@ -153,6 +153,6 @@ module.exports = {
153153
+'0846851D F9AB4819 5DED7EA1 B1D510BD 7EE74D73 FAF36BC3 1ECFA268'
154154
+'359046F4 EB879F92 4009438B 481C6CD7 889A002E D5EE382B C9190DA6'
155155
+'FC026E47 9558E447 5677E9AA 9E3050E2 765694DF C81F56E8 80B96E71'
156-
+'60C980DD 98EDD3DF FFFFFFFF FFFFFFFF', 16),
157-
g: bigint(19)}
156+
+'60C980DD 98EDD3DF FFFFFFFF FFFFFFFF').split(/\s/).join(''), 16),
157+
g: bignum(19)}
158158
};

lib/srp.js

+36-36
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
const crypto = require('crypto'),
2-
bigint = require('bigint'),
2+
bignum = require('bignum'),
33
assert = require('assert'),
44
ALG = 'sha256';
55

6-
const zero = bigint(0);
6+
const zero = bignum(0);
77

88
/*
99
* If a conversion is explicitly specified with the operator PAD(),
@@ -12,8 +12,8 @@ const zero = bigint(0);
1212
* length equals the implicitly-converted length of N.
1313
*
1414
* params:
15-
* n (bigint) Number to pad
16-
* N (bigint) N
15+
* n (bignum) Number to pad
16+
* N (bignum) N
1717
*
1818
* returns: buffer
1919
*/
@@ -55,7 +55,7 @@ var getx = exports.getx = function getx(s, I, P, alg) {
5555
.update(s)
5656
.update(hashIP)
5757
.digest('hex');
58-
return bigint(hashX, 16);
58+
return bignum(hashX, 16);
5959
};
6060

6161
/*
@@ -72,11 +72,11 @@ var getx = exports.getx = function getx(s, I, P, alg) {
7272
* s (buffer) salt
7373
* I (buffer) user identity
7474
* P (buffer) user password
75-
* N (bigint) group parameter N
76-
* g (bigint) generator
75+
* N (bignum) group parameter N
76+
* g (bignum) generator
7777
* alg (string) default = ALG
7878
*
79-
* returns: bigint
79+
* returns: bignum
8080
*/
8181
var getv = exports.getv = function getv(s, I, P, N, g, alg) {
8282
alg = alg || ALG;
@@ -87,15 +87,15 @@ var getv = exports.getv = function getv(s, I, P, N, g, alg) {
8787
* calculate the SRP-6 multiplier
8888
*
8989
* params:
90-
* N (bigint) group parameter N
91-
* g (bigint) generator
90+
* N (bignum) group parameter N
91+
* g (bignum) generator
9292
* alg (string) default = ALG
9393
*
94-
* returns: bigint
94+
* returns: bignum
9595
*/
9696
var getk = exports.getk = function getk(N, g, alg) {
9797
alg = alg || ALG;
98-
return bigint(
98+
return bignum(
9999
crypto
100100
.createHash(alg)
101101
.update(N.toBuffer())
@@ -110,7 +110,7 @@ var getk = exports.getk = function getk(N, g, alg) {
110110
* bytes (int) length of key (default=32)
111111
* callback (func) function to call with err,key
112112
*
113-
* returns: bigint
113+
* returns: bignum
114114
*/
115115
var genKey = exports.genKey = function genKey(bytes, callback) {
116116
// bytes is optional
@@ -123,7 +123,7 @@ var genKey = exports.genKey = function genKey(bytes, callback) {
123123
}
124124
crypto.randomBytes(bytes, function(err, buf) {
125125
if (err) return callback (err);
126-
return callback(null, bigint.fromBuffer(buf));
126+
return callback(null, bignum.fromBuffer(buf));
127127
});
128128
};
129129

@@ -136,8 +136,8 @@ var genKey = exports.genKey = function genKey(bytes, callback) {
136136
* Note: as the tests imply, the entire expression is mod N.
137137
*
138138
* params:
139-
* v (bigint) verifier
140-
* g (bigint) generator
139+
* v (bignum) verifier
140+
* g (bignum) generator
141141
*/
142142
var getB = exports.getB = function getB(v, g, b, N, alg) {
143143
alg = alg || ALG;
@@ -164,13 +164,13 @@ var getA = exports.getA = function getA(g, a, N) {
164164
* Random scrambling parameter u
165165
*
166166
* params:
167-
* A (bigint) client ephemeral public key
168-
* B (bigint) server ephemeral public key
169-
* N (bigint) group parameter N
167+
* A (bignum) client ephemeral public key
168+
* B (bignum) server ephemeral public key
169+
* N (bignum) group parameter N
170170
*/
171171
var getu = exports.getu = function getu(A, B, N, alg) {
172172
alg = alg || ALG;
173-
return bigint(
173+
return bignum(
174174
crypto
175175
.createHash(alg)
176176
.update(pad(A, N))
@@ -185,12 +185,12 @@ var getu = exports.getu = function getu(A, B, N, alg) {
185185
* s (buffer) salt (read from server)
186186
* I (buffer) user identity (read from user)
187187
* P (buffer) user password (read from user)
188-
* N (bigint) group parameter N (known in advance)
189-
* g (bigint) generator for N (known in advance)
190-
* a (bigint) ephemeral private key (generated for session)
191-
* B (bigint) server ephemeral public key (read from server)
188+
* N (bignum) group parameter N (known in advance)
189+
* g (bignum) generator for N (known in advance)
190+
* a (bignum) ephemeral private key (generated for session)
191+
* B (bignum) server ephemeral public key (read from server)
192192
*
193-
* returns: bigint
193+
* returns: bignum
194194
*/
195195
var client_getS = exports.client_getS = function client_getS(s, I, P, N, g, a, B, alg) {
196196
if (zero.ge(B) || N.le(B))
@@ -206,14 +206,14 @@ var client_getS = exports.client_getS = function client_getS(s, I, P, N, g, a, B
206206
* The TLS premastersecret as calculated by the server
207207
*
208208
* params:
209-
* s (bigint) salt (stored on server)
210-
* v (bigint) verifier (stored on server)
211-
* N (bigint) group parameter N (known in advance)
212-
* g (bigint) generator for N (known in advance)
213-
* A (bigint) ephemeral client public key (read from client)
214-
* b (bigint) server ephemeral private key (generated for session)
215-
*
216-
* returns: bigint
209+
* s (bignum) salt (stored on server)
210+
* v (bignum) verifier (stored on server)
211+
* N (bignum) group parameter N (known in advance)
212+
* g (bignum) generator for N (known in advance)
213+
* A (bignum) ephemeral client public key (read from client)
214+
* b (bignum) server ephemeral private key (generated for session)
215+
*
216+
* returns: bignum
217217
*/
218218
var server_getS = exports.server_getS = function server_getS(s, v, N, g, A, b, alg) {
219219
if (zero.ge(A) || N.le(A))
@@ -228,14 +228,14 @@ var server_getS = exports.server_getS = function server_getS(s, v, N, g, A, b, a
228228
* Compute the shared session key K from S
229229
*
230230
* params:
231-
* S (bigint) Session key
231+
* S (bignum) Session key
232232
*
233-
* returns: bigint
233+
* returns: bignum
234234
*/
235235
var getK = exports.getK = function getK(S, N, alg) {
236236
alg = alg || ALG;
237237
var S_pad = new Buffer(pad(S, N));
238-
return bigint(
238+
return bignum(
239239
crypto
240240
.createHash(alg)
241241
.update(S_pad)

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"main": "index.js",
77

88
"scripts": {
9-
"test": "vows test/*.js --spec"
9+
"test": "vows test/test*.js --spec"
1010
},
1111

1212
"repository": {
@@ -19,7 +19,7 @@
1919
"readmeFilename": "README.md",
2020

2121
"dependencies": {
22-
"bigint": "0.4.2"
22+
"bignum": "0.6.1"
2323
},
2424

2525
"devDependencies": {

test/speed.js

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
const params = require('../lib/params'),
2+
srp = require('../lib/srp'),
3+
s = new Buffer("salty"),
4+
I = new Buffer("alice"),
5+
P = new Buffer("password123"),
6+
N = params[4096].N,
7+
g = params[4096].g,
8+
ALG_NAME = 'sha256';
9+
// use "npm install benchmark microtime" to run this
10+
var benchmark = require("benchmark");
11+
12+
var b = new benchmark("getV", function() {
13+
var v = srp.getv(s, I, P, N, g, ALG_NAME);
14+
});
15+
16+
var res = b.run();
17+
18+
console.log("getV (mean)", res.times.period, "seconds");
19+
20+
// getV: 1.78ms with bigint, 2.35ms with bignum
21+
// (on my mid-2012 Retina MacBookPro, quad-core 2.6GHz Core i7)

0 commit comments

Comments
 (0)