@@ -41,64 +41,48 @@ var Ecdsa = function() {};
41
41
/**
42
42
* Verifies the given signature using the given ECDSA public key.
43
43
* @param {!CryptoKey } pk The ECDSA public key
44
- * @param {! string } hashAlg The hash algorithm
44
+ * @param {string } hashAlg The hash algorithm
45
45
* @param {!ArrayBuffer } msg The message to be verified
46
46
* @param {!ArrayBuffer } sig The signature to be verified
47
47
*
48
48
* @return {!Promise }
49
49
*/
50
50
Ecdsa . verify = function ( pk , hashAlg , msg , sig ) {
51
51
return crypto . subtle . verify (
52
- {
53
- name : 'ECDSA' ,
54
- hash : { name : hashAlg }
55
- } ,
56
- pk ,
57
- sig ,
58
- msg
59
- ) ;
52
+ { name : 'ECDSA' , hash : { name : hashAlg } } , pk , sig , msg ) ;
60
53
} ;
61
54
62
55
/**
63
56
* Signs a message using the given ECDSA private key and hash algorithm.
64
57
* @param {!CryptoKey } sk The ECDSA private key
65
58
* @param {!ArrayBuffer } msg The message to be signed
66
- * @param {! string } hashAlg The hash algorithm
59
+ * @param {string } hashAlg The hash algorithm
67
60
*
68
61
* @return {!Promise }
69
62
*/
70
63
Ecdsa . sign = function ( sk , msg , hashAlg ) {
71
64
return crypto . subtle . sign (
72
- {
65
+ {
73
66
name : 'ECDSA' ,
74
67
hash : { name : hashAlg } ,
75
- } ,
76
- sk ,
77
- msg
78
- ) ;
68
+ } ,
69
+ sk , msg ) ;
79
70
} ;
80
71
81
72
82
73
/**
83
74
* Imports a ECDSA public key.
84
75
* @param {!JSONObject } keyData The key data in JWK format
85
- * @param {! string } hashAlg The hash algorithm
76
+ * @param {string } hashAlg The hash algorithm
86
77
* @param {!Array<string> } usages The usages of the key
87
78
*
88
79
* @return {!Promise }
89
80
*/
90
81
Ecdsa . importPublicKey = function ( keyData , hashAlg , usages ) {
91
82
return crypto . subtle . importKey (
92
- 'jwk' ,
93
- keyData ,
94
- {
95
- name : 'ECDSA' ,
96
- namedCurve : keyData [ 'crv' ] ,
97
- hash : { name : hashAlg }
98
- } ,
99
- true ,
100
- usages
101
- ) ;
83
+ 'jwk' , keyData ,
84
+ { name : 'ECDSA' , namedCurve : keyData [ 'crv' ] , hash : { name : hashAlg } } , true ,
85
+ usages ) ;
102
86
} ;
103
87
104
88
/**
@@ -113,20 +97,18 @@ Ecdsa.exportKey = function(key) {
113
97
114
98
/**
115
99
* Generates an ECDSA key pair using the given hash algorithm and curve name.
116
- * @param {! string } hashAlg The hash algorithm
117
- * @param {! string } curveName The curve name
100
+ * @param {string } hashAlg The hash algorithm
101
+ * @param {string } curveName The curve name
118
102
*
119
103
* @return {!Promise }
120
104
*/
121
105
Ecdsa . generateKey = function ( hashAlg , curveName ) {
122
106
return crypto . subtle . generateKey (
123
- {
107
+ {
124
108
name : 'ECDSA' ,
125
109
namedCurve : curveName ,
126
- } ,
127
- true ,
128
- [ 'sign' , 'verify' ]
129
- ) ;
110
+ } ,
111
+ true , [ 'sign' , 'verify' ] ) ;
130
112
} ;
131
113
132
114
@@ -139,20 +121,25 @@ Ecdsa.generateKey = function(hashAlg, curveName) {
139
121
Ecdsa . testVerify = function ( ) {
140
122
tc = this ;
141
123
var promise = new Promise ( ( resolve , reject ) => {
142
- Ecdsa . importPublicKey ( tc . keyData , tc . hashAlg , [ 'verify' ] ) . then ( function ( pk ) {
143
- Ecdsa . verify ( pk , tc . hashAlg , tc . msg , tc . sig ) . then ( function ( isValid ) {
144
- if ( ( tc . result == 'valid' && ! isValid ) ||
145
- ( tc . result == 'invalid' && isValid ) ) {
146
- reject ( 'Failed in test case ' + tc . id ) ;
147
- }
148
- resolve ( ) ;
149
- } ) . catch ( function ( err ) {
150
- // don't expect any exception in signature verification
151
- reject ( 'Unexpected exception on test case ' + tc . id + ": " + err ) ;
152
- } ) ;
153
- } ) . catch ( function ( err ) {
154
- reject ( 'Failed to import key in test case ' + tc . id + ': ' + err ) ;
155
- } ) ;
124
+ Ecdsa . importPublicKey ( tc . keyData , tc . hashAlg , [ 'verify' ] )
125
+ . then ( function ( pk ) {
126
+ Ecdsa . verify ( pk , tc . hashAlg , tc . msg , tc . sig )
127
+ . then ( function ( isValid ) {
128
+ if ( ( tc . result == 'valid' && ! isValid ) ||
129
+ ( tc . result == 'invalid' && isValid ) ) {
130
+ reject ( 'Failed in test case ' + tc . id ) ;
131
+ }
132
+ resolve ( ) ;
133
+ } )
134
+ . catch ( function ( err ) {
135
+ // don't expect any exception in signature verification
136
+ reject (
137
+ 'Unexpected exception on test case ' + tc . id + ': ' + err ) ;
138
+ } ) ;
139
+ } )
140
+ . catch ( function ( err ) {
141
+ reject ( 'Failed to import key in test case ' + tc . id + ': ' + err ) ;
142
+ } ) ;
156
143
} ) ;
157
144
return promise ;
158
145
} ;
@@ -162,10 +149,10 @@ Ecdsa.testVerify = function() {
162
149
* Parameters of a ECDSA signature verification test.
163
150
* @param {!number } id Test case's id
164
151
* @param {!JSONObject } keyData The key data in JWK format
165
- * @param {! string } hashAlg The hash algorithm
152
+ * @param {string } hashAlg The hash algorithm
166
153
* @param {!ArrayBuffer } msg The message that was signed
167
154
* @param {!ArrayBuffer } sig The signature to be verified
168
- * @param {! string } result The expected result of the test case
155
+ * @param {string } result The expected result of the test case
169
156
*/
170
157
var EcdsaVerifyTestCase = function ( id , keyData , hashAlg , msg , sig , result ) {
171
158
this . id = id ;
@@ -191,8 +178,8 @@ function testEcdsaVectors() {
191
178
var keyData = tg [ 'jwk' ] ;
192
179
var curveName = keyData [ 'crv' ] ;
193
180
var hashAlg = tg [ 'sha' ] ;
194
- if ( SUPPORTED [ 'ecdsa-curve' ] . indexOf ( curveName ) == - 1
195
- || SUPPORTED [ 'hash' ] . indexOf ( hashAlg ) == - 1 ) {
181
+ if ( SUPPORTED [ 'ecdsa-curve' ] . indexOf ( curveName ) == - 1 ||
182
+ SUPPORTED [ 'hash' ] . indexOf ( hashAlg ) == - 1 ) {
196
183
continue ;
197
184
}
198
185
for ( var j = 0 ; j < tg [ 'tests' ] . length ; j ++ ) {
@@ -201,8 +188,8 @@ function testEcdsaVectors() {
201
188
var result = tc [ 'result' ] ;
202
189
var msg = TestUtil . hexToArrayBuffer ( tc [ 'msg' ] ) ;
203
190
var sig = TestUtil . hexToArrayBuffer ( tc [ 'sig' ] ) ;
204
- var test = new EcdsaVerifyTestCase (
205
- tcId , keyData , hashAlg , msg , sig , result ) ;
191
+ var test =
192
+ new EcdsaVerifyTestCase ( tcId , keyData , hashAlg , msg , sig , result ) ;
206
193
testCase . addNewTest ( 'Test ' + tcId , Ecdsa . testVerify , test ) ;
207
194
}
208
195
}
@@ -219,9 +206,9 @@ function testEcdsaVectors() {
219
206
Ecdsa . extractSig = function ( sig ) {
220
207
var bytes = new Uint8Array ( sig ) ;
221
208
var byteLen = bytes . length ;
222
- var rBytes = bytes . subarray ( 0 , byteLen / 2 ) ;
209
+ var rBytes = bytes . subarray ( 0 , byteLen / 2 ) ;
223
210
var r = new BigInteger ( rBytes ) ;
224
- var sBytes = bytes . subarray ( byteLen / 2 , byteLen ) ;
211
+ var sBytes = bytes . subarray ( byteLen / 2 , byteLen ) ;
225
212
var s = new BigInteger ( sBytes ) ;
226
213
return [ r , s ] ;
227
214
} ;
@@ -250,7 +237,7 @@ Ecdsa.extractNonce = function(h, r, s, d, curveSpec) {
250
237
* @param {!wycheproof.BigInteger } s The 's' value of the signature
251
238
* @param {!wycheproof.BigInteger } d The private component of the ECDSA key
252
239
* @param {!wycheproof.BigInteger } k The nonce that needs to be checked
253
- * @param {! string } curveName The curve name
240
+ * @param {string } curveName The curve name
254
241
*/
255
242
Ecdsa . checkNonceCorrectness = function ( msg , r , s , d , k , curveName ) {
256
243
var e2eCurveMap = {
@@ -259,14 +246,13 @@ Ecdsa.checkNonceCorrectness = function(msg, r, s, d, k, curveName) {
259
246
'P-521' : 'P_521' ,
260
247
} ;
261
248
var e2eCurveName = e2eCurveMap [ curveName ] ;
262
- var key = new e2e . ecc . Ecdsa ( e2eCurveName ,
263
- { privKey : d . toByteArray ( ) } ) ;
249
+ var key = new e2e . ecc . Ecdsa ( e2eCurveName , { privKey : d . toByteArray ( ) } ) ;
264
250
var msgBytes = new Uint8Array ( msg ) ;
265
251
var calSig = key . signForTestingOnly ( msgBytes , k ) ;
266
252
var calR = new BigInteger ( calSig [ 'r' ] ) ;
267
253
var calS = new BigInteger ( calSig [ 's' ] ) ;
268
- assertTrue ( 'Nonce calculation was incorrect' ,
269
- r . isEqual ( calR ) && s . isEqual ( calS ) ) ;
254
+ assertTrue (
255
+ 'Nonce calculation was incorrect' , r . isEqual ( calR ) && s . isEqual ( calS ) ) ;
270
256
} ;
271
257
272
258
/**
@@ -285,61 +271,72 @@ Ecdsa.checkNonceCorrectness = function(msg, r, s, d, k, curveName) {
285
271
*/
286
272
Ecdsa . testBias = function ( ) {
287
273
var tc = this ;
288
- var nDone = 0 ;
289
274
var countLsb = 0 ;
290
275
var countMsb = 0 ;
291
- var promise = new Promise ( function ( resolve , reject ) {
292
- for ( var i = 0 ; i < tc . nTests ; i ++ ) {
293
- Ecdsa . generateKey ( tc . hashAlg , tc . curveName ) . then ( function ( key ) {
294
- Ecdsa . exportKey ( key . privateKey ) . then ( function ( keyData ) {
295
- Ecdsa . sign ( key . privateKey , tc . msg , tc . hashAlg ) . then ( function ( sig ) {
296
- HashUtil . digest ( tc . hashAlg , tc . msg ) . then ( function ( digest ) {
297
- var curveSpec = EcUtil . getCurveSpec ( tc . curveName ) ;
298
- var h = new BigInteger ( new Uint8Array ( digest ) ) ;
299
- // private key value
300
- var d = BigInteger . fromHex ( TestUtil . base64UrlToHex ( keyData [ 'd' ] ) ) ;
301
- var r , s ;
302
- [ r , s ] = Ecdsa . extractSig ( sig ) ;
303
- var k = Ecdsa . extractNonce ( h , r , s , d , curveSpec ) ;
304
- // Uncomment this line to check correctness of nonce calculation
305
- // Ecdsa.checkNonceCorrectness(tc.msg, r, s, d, k, tc.curveName);
306
- var halfN = curveSpec . n . shiftRight ( 1 ) ;
307
- if ( k . isBitSet ( 0 ) ) countLsb += 1 ;
308
- if ( k . compare ( halfN ) == 1 ) countMsb += 1 ;
309
276
310
- nDone += 1 ;
311
- if ( nDone == tc . nTests ) {
312
- if ( countLsb < tc . minCount || countLsb > tc . nTests - tc . minCount ) {
313
- reject ( "Bias detected in the LSB of k" +
314
- ", hash: " + tc . hashAlg + ", curve: " + tc . curveName +
315
- ", countLSB: " + countLsb + ", countMSB: " + countMsb ) ;
277
+ return Ecdsa . generateKey ( tc . hashAlg , tc . curveName )
278
+ . then ( function ( key ) {
279
+ return Ecdsa . exportKey ( key . privateKey )
280
+ . then ( function ( keyData ) {
281
+ var promises = [ ] ;
282
+
283
+ for ( var i = 0 ; i < tc . nTests ; i ++ ) {
284
+ promises . push (
285
+ Ecdsa . sign ( key . privateKey , tc . msg , tc . hashAlg )
286
+ . then ( function ( sig ) {
287
+ return HashUtil . digest ( tc . hashAlg , tc . msg )
288
+ . then ( function ( digest ) {
289
+ var curveSpec =
290
+ EcUtil . getCurveSpec ( tc . curveName ) ;
291
+ var h = new BigInteger ( new Uint8Array ( digest ) ) ;
292
+ // private key value
293
+ var d = BigInteger . fromHex (
294
+ TestUtil . base64UrlToHex ( keyData [ 'd' ] ) ) ;
295
+ var r , s ;
296
+ [ r , s ] = Ecdsa . extractSig ( sig ) ;
297
+ var k =
298
+ Ecdsa . extractNonce ( h , r , s , d , curveSpec ) ;
299
+ // Uncomment this line to check correctness of
300
+ // nonce calculation
301
+ // Ecdsa.checkNonceCorrectness(tc.msg, r, s, d,
302
+ // k, tc.curveName);
303
+ var halfN = curveSpec . n . shiftRight ( 1 ) ;
304
+ if ( k . isBitSet ( 0 ) ) countLsb += 1 ;
305
+ if ( k . compare ( halfN ) == 1 ) countMsb += 1 ;
306
+ } ) ;
307
+ } ) ) ;
308
+ }
309
+
310
+ return Promise . all ( promises ) . then ( function ( ) {
311
+ if ( countLsb < tc . minCount ||
312
+ countLsb > tc . nTests - tc . minCount ) {
313
+ reject (
314
+ 'Bias detected in the LSB of k' +
315
+ ', hash: ' + tc . hashAlg + ', curve: ' + tc . curveName +
316
+ ', countLSB: ' + countLsb + ', countMSB: ' + countMsb ) ;
316
317
}
317
- if ( countMsb < tc . minCount || countMsb > tc . nTests - tc . minCount ) {
318
- reject ( "Bias detected in the MSB of k" +
319
- ", hash: " + tc . hashAlg + ", curve: " + tc . curveName +
320
- ", countLSB: " + countLsb + ", countMSB: " + countMsb ) ;
318
+ if ( countMsb < tc . minCount ||
319
+ countMsb > tc . nTests - tc . minCount ) {
320
+ reject (
321
+ 'Bias detected in the MSB of k' +
322
+ ', hash: ' + tc . hashAlg + ', curve: ' + tc . curveName +
323
+ ', countLSB: ' + countLsb + ', countMSB: ' + countMsb ) ;
321
324
}
322
- resolve ( ) ;
323
- }
325
+ } ) ;
326
+ } )
327
+ . catch ( function ( err ) {
328
+ throw new Error ( 'Failed to export private key: ' + err ) ;
324
329
} ) ;
325
- } ) . catch ( function ( err ) {
326
- reject ( 'Failed to sign: ' + err ) ;
327
- } ) ;
328
- } ) . catch ( function ( err ) {
329
- reject ( 'Failed to export private key: ' + err ) ;
330
- } ) ;
331
- } ) . catch ( function ( err ) {
332
- reject ( 'Failed to generate key: ' + err ) ;
330
+ } )
331
+ . catch ( function ( err ) {
332
+ throw new Error ( 'Failed to generate key: ' + err ) ;
333
333
} ) ;
334
- }
335
- } ) ;
336
- return promise ;
337
334
} ;
338
335
339
336
/**
340
337
* Parameters of a ECDSA bias test.
341
- * @param {! string } hashAlg The hash algorithm
342
- * @param {! string } curveName The curve name
338
+ * @param {string } hashAlg The hash algorithm
339
+ * @param {string } curveName The curve name
343
340
* @param {!ArrayBuffer } msg The message that was signed
344
341
* @param {!number } nTests The number of key to be generated
345
342
* @param {!number } minCount
@@ -362,17 +359,19 @@ var EcdsaBiasTestCase = function(hashAlg, curveName, msg, nTests, minCount) {
362
359
*/
363
360
function testEcdsaBiasAll ( ) {
364
361
var testCase = new goog . testing . TestCase ( ) ;
365
- testCase . promiseTimeout = 120 * 1000 ;
366
- var msg = TestUtil . hexToArrayBuffer ( '48656c6c6f' ) ; // msg = 'Hello'
362
+ testCase . promiseTimeout = 120 * 1000 ;
363
+ var msg = TestUtil . hexToArrayBuffer ( '48656c6c6f' ) ; // msg = 'Hello'
367
364
var nTests = 1024 ;
368
365
var minCount = 410 ;
369
- var biasTest256 = new EcdsaBiasTestCase ( 'SHA-256' , 'P-256' , msg , nTests , minCount ) ;
366
+ var biasTest256 =
367
+ new EcdsaBiasTestCase ( 'SHA-256' , 'P-256' , msg , nTests , minCount ) ;
370
368
testCase . addNewTest ( 'bias256' , Ecdsa . testBias , biasTest256 ) ;
371
- var biasTest384 = new EcdsaBiasTestCase ( 'SHA-384' , 'P-384' , msg , nTests , minCount ) ;
369
+ var biasTest384 =
370
+ new EcdsaBiasTestCase ( 'SHA-384' , 'P-384' , msg , nTests , minCount ) ;
372
371
testCase . addNewTest ( 'bias384' , Ecdsa . testBias , biasTest384 ) ;
373
- var biasTest521 = new EcdsaBiasTestCase ( 'SHA-512' , 'P-521' , msg , nTests , minCount ) ;
372
+ var biasTest521 =
373
+ new EcdsaBiasTestCase ( 'SHA-512' , 'P-521' , msg , nTests , minCount ) ;
374
374
testCase . addNewTest ( 'bias521' , Ecdsa . testBias , biasTest521 ) ;
375
- return testCase . runTestsReturningPromise ( )
376
- . then ( wycheproof . TestUtil . checkTestCaseResult ) ;
375
+ return testCase . runTestsReturningPromise ( ) . then (
376
+ wycheproof . TestUtil . checkTestCaseResult ) ;
377
377
}
378
-
0 commit comments