Skip to content

Commit b2f8ba7

Browse files
committed
crypto: reconsile oneshot sign/verify sync and async implementations
1 parent 43f599b commit b2f8ba7

File tree

8 files changed

+151
-258
lines changed

8 files changed

+151
-258
lines changed
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const crypto = require('crypto');
5+
const fs = require('fs');
6+
const path = require('path');
7+
const fixtures_keydir = path.resolve(__dirname, '../../test/fixtures/keys/');
8+
const keys = {
9+
publicKey: crypto.createPublicKey(
10+
fs.readFileSync(`${fixtures_keydir}/ed25519_public.pem`)),
11+
privateKey: crypto.createPrivateKey(
12+
fs.readFileSync(`${fixtures_keydir}/ed25519_private.pem`)),
13+
};
14+
15+
const data = crypto.randomBytes(256);
16+
const args = [null, data];
17+
18+
const bench = common.createBenchmark(main, {
19+
sync: [0, 1],
20+
n: [1e4],
21+
});
22+
23+
function measureSync(n) {
24+
bench.start();
25+
for (let i = 0; i < n; ++i) {
26+
crypto.verify(...args, keys.publicKey,
27+
crypto.sign(...args, keys.privateKey));
28+
}
29+
bench.end(n);
30+
}
31+
32+
function measureAsync(n) {
33+
let remaining = n;
34+
function done() {
35+
if (--remaining === 0)
36+
bench.end(n);
37+
}
38+
bench.start();
39+
for (let i = 0; i < n; ++i) {
40+
crypto.sign(...args, keys.privateKey, (err, signature) => {
41+
crypto.verify(...args, keys.publicKey, signature, done);
42+
});
43+
}
44+
}
45+
46+
function main({ n, sync }) {
47+
if (sync)
48+
measureSync(n);
49+
else
50+
measureAsync(n);
51+
}

lib/internal/crypto/dsa.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,15 @@ function dsaSignVerify(key, data, algorithm, signature) {
251251
kCryptoJobAsync,
252252
signature === undefined ? kSignJobModeSign : kSignJobModeVerify,
253253
key[kKeyObject][kHandle],
254+
undefined,
255+
undefined,
256+
undefined,
254257
data,
255258
normalizeHashName(key.algorithm.hash.name),
256259
undefined, // Salt-length is not used in DSA
257260
undefined, // Padding is not used in DSA
258-
signature,
259-
kSigEncDER));
261+
kSigEncDER,
262+
signature));
260263
}
261264

262265
module.exports = {

lib/internal/crypto/ec.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,15 @@ function ecdsaSignVerify(key, data, { name, hash }, signature) {
467467
kCryptoJobAsync,
468468
mode,
469469
key[kKeyObject][kHandle],
470+
undefined,
471+
undefined,
472+
undefined,
470473
data,
471474
hashname,
472475
undefined, // Salt length, not used with ECDSA
473476
undefined, // PSS Padding, not used with ECDSA
474-
signature,
475-
kSigEncP1363));
477+
kSigEncP1363,
478+
signature));
476479
}
477480

478481
module.exports = {

lib/internal/crypto/rsa.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,14 @@ function rsaSignVerify(key, data, { saltLength }, signature) {
356356
kCryptoJobAsync,
357357
signature === undefined ? kSignJobModeSign : kSignJobModeVerify,
358358
key[kKeyObject][kHandle],
359+
undefined,
360+
undefined,
361+
undefined,
359362
data,
360363
normalizeHashName(key.algorithm.hash.name),
361364
saltLength,
362365
padding,
366+
undefined,
363367
signature));
364368
}
365369

lib/internal/crypto/sig.js

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ const {
2424
Sign: _Sign,
2525
SignJob,
2626
Verify: _Verify,
27-
signOneShot: _signOneShot,
28-
verifyOneShot: _verifyOneShot,
2927
kCryptoJobAsync,
28+
kCryptoJobSync,
3029
kSigEncDER,
3130
kSigEncP1363,
3231
kSignJobModeSign,
@@ -40,10 +39,6 @@ const {
4039
} = require('internal/crypto/util');
4140

4241
const {
43-
createPrivateKey,
44-
createPublicKey,
45-
isCryptoKey,
46-
isKeyObject,
4742
preparePrivateKey,
4843
preparePublicOrPrivateKey,
4944
} = require('internal/crypto/keys');
@@ -162,38 +157,34 @@ function signOneShot(algorithm, data, key, callback) {
162157
// Options specific to (EC)DSA
163158
const dsaSigEnc = getDSASignatureEncoding(key);
164159

165-
if (!callback) {
166-
const {
167-
data: keyData,
168-
format: keyFormat,
169-
type: keyType,
170-
passphrase: keyPassphrase
171-
} = preparePrivateKey(key);
172-
173-
return _signOneShot(keyData, keyFormat, keyType, keyPassphrase, data,
174-
algorithm, rsaPadding, pssSaltLength, dsaSigEnc);
175-
}
176-
177-
let keyData;
178-
if (isKeyObject(key) || isCryptoKey(key)) {
179-
({ data: keyData } = preparePrivateKey(key));
180-
} else if (key != null && (isKeyObject(key.key) || isCryptoKey(key.key))) {
181-
({ data: keyData } = preparePrivateKey(key.key));
182-
} else {
183-
keyData = createPrivateKey(key)[kHandle];
184-
}
160+
const {
161+
data: keyData,
162+
format: keyFormat,
163+
type: keyType,
164+
passphrase: keyPassphrase
165+
} = preparePrivateKey(key);
185166

186167
const job = new SignJob(
187-
kCryptoJobAsync,
168+
callback ? kCryptoJobAsync : kCryptoJobSync,
188169
kSignJobModeSign,
189170
keyData,
171+
keyFormat,
172+
keyType,
173+
keyPassphrase,
190174
data,
191175
algorithm,
192176
pssSaltLength,
193177
rsaPadding,
194-
undefined,
195178
dsaSigEnc);
196179

180+
if (!callback) {
181+
const { 0: err, 1: signature } = job.run();
182+
if (err !== undefined)
183+
throw err;
184+
185+
return Buffer.from(signature);
186+
}
187+
197188
job.ondone = (error, signature) => {
198189
if (error) return FunctionPrototypeCall(callback, job, error);
199190
FunctionPrototypeCall(callback, job, null, Buffer.from(signature));
@@ -272,38 +263,34 @@ function verifyOneShot(algorithm, data, key, signature, callback) {
272263
);
273264
}
274265

275-
if (!callback) {
276-
const {
277-
data: keyData,
278-
format: keyFormat,
279-
type: keyType,
280-
passphrase: keyPassphrase
281-
} = preparePublicOrPrivateKey(key);
282-
283-
return _verifyOneShot(keyData, keyFormat, keyType, keyPassphrase,
284-
signature, data, algorithm, rsaPadding,
285-
pssSaltLength, dsaSigEnc);
286-
}
287-
288-
let keyData;
289-
if (isKeyObject(key) || isCryptoKey(key)) {
290-
({ data: keyData } = preparePublicOrPrivateKey(key));
291-
} else if (key != null && (isKeyObject(key.key) || isCryptoKey(key.key))) {
292-
({ data: keyData } = preparePublicOrPrivateKey(key.key));
293-
} else {
294-
keyData = createPublicKey(key)[kHandle];
295-
}
266+
const {
267+
data: keyData,
268+
format: keyFormat,
269+
type: keyType,
270+
passphrase: keyPassphrase
271+
} = preparePublicOrPrivateKey(key);
296272

297273
const job = new SignJob(
298-
kCryptoJobAsync,
274+
callback ? kCryptoJobAsync : kCryptoJobSync,
299275
kSignJobModeVerify,
300276
keyData,
277+
keyFormat,
278+
keyType,
279+
keyPassphrase,
301280
data,
302281
algorithm,
303282
pssSaltLength,
304283
rsaPadding,
305-
signature,
306-
dsaSigEnc);
284+
dsaSigEnc,
285+
signature);
286+
287+
if (!callback) {
288+
const { 0: err, 1: result } = job.run();
289+
if (err !== undefined)
290+
throw err;
291+
292+
return result;
293+
}
307294

308295
job.ondone = (error, result) => {
309296
if (error) return FunctionPrototypeCall(callback, job, error);

0 commit comments

Comments
 (0)