1
- import { bigIntToBytes , maxInt } from "../utils/bigint" ;
1
+ import {
2
+ bigIntToBytes ,
3
+ maxInt ,
4
+ serverStyleHexFromBigInt ,
5
+ setBigIntegerFromBytes ,
6
+ } from "../utils/bigint" ;
2
7
import { hexToBigInt } from "../utils/hex" ;
3
8
import { minExponentSize , SrpGroup } from "./srpGroup" ;
4
9
import { createHash , randomBytes } from "node:crypto" ;
@@ -42,8 +47,8 @@ export class SrpClient {
42
47
if ( ! this . group ) {
43
48
throw new Error ( "group is not set" ) ;
44
49
}
45
- hash . update ( new Uint8Array ( this . group . getN ( ) . toByteArray ( ) ) ) ;
46
- hash . update ( new Uint8Array ( this . group . getGenerator ( ) . toByteArray ( ) ) ) ;
50
+ hash . update ( bigIntToBytes ( this . group . getN ( ) ) ) ;
51
+ hash . update ( bigIntToBytes ( this . group . getGenerator ( ) ) ) ;
47
52
return hexToBigInt ( hash . digest ( "hex" ) ) ;
48
53
}
49
54
@@ -59,7 +64,7 @@ export class SrpClient {
59
64
}
60
65
61
66
private makeA ( ) : BigInteger {
62
- if ( this . ephemeralPrivate === zero ) {
67
+ if ( this . ephemeralPrivate . compareTo ( zero ) === 0 ) {
63
68
this . generateMySecret ( ) ;
64
69
}
65
70
if ( ! this . group ) {
@@ -123,17 +128,21 @@ export class SrpClient {
123
128
throw new Error ( "both A and B must be known to calculate u" ) ;
124
129
}
125
130
131
+ const trimmedHexPublicA = serverStyleHexFromBigInt ( this . ephemeralPublicA ) ;
132
+ const trimmedHexPublicB = serverStyleHexFromBigInt ( this . ephemeralPublicB ) ;
133
+
126
134
const hash = createHash ( "sha256" ) ;
127
135
hash . update (
128
- new TextEncoder ( ) . encode (
129
- this . ephemeralPublicA . toString ( ) + this . ephemeralPublicB . toString ( )
130
- )
136
+ new TextEncoder ( ) . encode ( trimmedHexPublicA + trimmedHexPublicB )
131
137
) ;
132
138
133
- this . u = new BigInteger ( hash . digest ( ) . toString ( "hex" ) , 16 ) ;
139
+ const hashed = hash . digest ( ) ;
140
+
141
+ this . u = setBigIntegerFromBytes ( new Uint8Array ( hashed ) ) ;
134
142
if ( this . u . compareTo ( zero ) === 0 ) {
135
143
throw new Error ( "u == 0, which is a bad thing" ) ;
136
144
}
145
+
137
146
return this . u ;
138
147
}
139
148
@@ -191,8 +200,8 @@ need that.
191
200
throw new Error ( "cannot make Key with my ephemeral secret" ) ;
192
201
}
193
202
194
- let b = new BigInteger ( "0" ) ;
195
- let e = new BigInteger ( "0" ) ;
203
+ let b : BigInteger ;
204
+ let e : BigInteger ;
196
205
197
206
if (
198
207
this . ephemeralPublicB . compareTo ( zero ) === 0 ||
@@ -201,19 +210,20 @@ need that.
201
210
) {
202
211
throw new Error ( "not enough is known to create Key" ) ;
203
212
}
213
+
204
214
e = this . u . multiply ( this . x ) ;
205
215
e = e . add ( this . ephemeralPrivate ) ;
206
216
207
217
if ( ! this . group ) {
208
218
throw new Error ( "group is not set" ) ;
209
219
}
210
220
211
- b = this . group . getGenerator ( ) . modPow ( this . x , this . group . getN ( ) ) ;
221
+ b = this . group . getGenerator ( ) . modPow ( this . x , this . group . getN ( ) . abs ( ) ) ;
212
222
b = b . multiply ( this . k ) ;
223
+
213
224
b = this . ephemeralPublicB . subtract ( b ) ;
214
225
b = b . mod ( this . group . getN ( ) ) ;
215
-
216
- this . premasterKey = b . modPow ( e , this . group . getN ( ) ) ;
226
+ this . premasterKey = b . modPow ( e , this . group . getN ( ) . abs ( ) ) ;
217
227
218
228
const hash = createHash ( "sha256" ) ;
219
229
hash . update ( new TextEncoder ( ) . encode ( this . premasterKey . toString ( 16 ) ) ) ;
@@ -238,7 +248,6 @@ slice (without padding to size of N)
238
248
throw new Error ( "group is not set" ) ;
239
249
}
240
250
const nLen = bigIntToBytes ( this . group . getN ( ) ) . length ;
241
- console . log ( `Server padding length: ${ nLen } ` ) ;
242
251
243
252
if ( this . m !== null ) {
244
253
return this . m ;
@@ -257,8 +266,7 @@ slice (without padding to size of N)
257
266
. update ( bigIntToBytes ( this . group . getGenerator ( ) ) )
258
267
. digest ( ) ;
259
268
const gHash = new Uint8Array ( gHashBuffer ) ;
260
- console . log ( `nHash: ${ nHashBuffer . toString ( "hex" ) } ` ) ;
261
- console . log ( `gHash: ${ gHashBuffer . toString ( "hex" ) } ` ) ;
269
+
262
270
let groupXOR = new Uint8Array ( SHA256_SIZE ) ;
263
271
const length = safeXORBytes ( groupXOR , nHash , gHash ) ;
264
272
if ( length !== SHA256_SIZE ) {
@@ -268,43 +276,11 @@ slice (without padding to size of N)
268
276
}
269
277
const groupHashBuffer = createHash ( "sha256" ) . update ( groupXOR ) . digest ( ) ;
270
278
const groupHash = new Uint8Array ( groupHashBuffer ) ;
271
- console . log ( `groupHash: ${ groupHashBuffer . toString ( "hex" ) } ` ) ;
272
279
273
280
const uHashBuffer = createHash ( "sha256" )
274
281
. update ( new TextEncoder ( ) . encode ( uname ) )
275
282
. digest ( ) ;
276
283
const uHash = new Uint8Array ( uHashBuffer ) ;
277
- console . log ( `uHash: ${ uHashBuffer . toString ( "hex" ) } ` ) ;
278
-
279
- let m1 = createHash ( "sha256" ) ;
280
- m1 . update ( groupHash ) ;
281
- console . log ( "After groupHash:" , m1 . digest ( "hex" ) ) ;
282
-
283
- let m2 = createHash ( "sha256" ) ;
284
- m2 . update ( groupHash ) ;
285
- m2 . update ( uHash ) ;
286
- console . log ( "After uHash:" , m2 . digest ( "hex" ) ) ;
287
-
288
- let m3 = createHash ( "sha256" ) ;
289
- m3 . update ( groupHash ) ;
290
- m3 . update ( uHash ) ;
291
- m3 . update ( salt ) ;
292
- console . log ( "After salt:" , m3 . digest ( "hex" ) ) ;
293
-
294
- let m4 = createHash ( "sha256" ) ;
295
- m4 . update ( groupHash ) ;
296
- m4 . update ( uHash ) ;
297
- m4 . update ( salt ) ;
298
- m4 . update ( bigIntToBytes ( this . ephemeralPublicA ) ) ;
299
- console . log ( "After ephemeralPublicA:" , m4 . digest ( "hex" ) ) ;
300
-
301
- let m5 = createHash ( "sha256" ) ;
302
- m5 . update ( groupHash ) ;
303
- m5 . update ( uHash ) ;
304
- m5 . update ( salt ) ;
305
- m5 . update ( bigIntToBytes ( this . ephemeralPublicA ) ) ;
306
- m5 . update ( bigIntToBytes ( this . ephemeralPublicB ) ) ;
307
- console . log ( "After ephemeralPublicB:" , m5 . digest ( "hex" ) ) ;
308
284
309
285
let m6 = createHash ( "sha256" ) ;
310
286
m6 . update ( groupHash ) ;
@@ -313,7 +289,6 @@ slice (without padding to size of N)
313
289
m6 . update ( bigIntToBytes ( this . ephemeralPublicA ) ) ;
314
290
m6 . update ( bigIntToBytes ( this . ephemeralPublicB ) ) ;
315
291
m6 . update ( this . key ) ;
316
- console . log ( "After key:" , m6 . digest ( "hex" ) ) ;
317
292
318
293
this . m = new Uint8Array ( m6 . digest ( ) ) ;
319
294
return this . m ;
0 commit comments