Skip to content

crypto: add optional callback to crypto.sign and crypto.verify - #37500

Closed
panva wants to merge 11 commits into
nodejs:masterfrom
panva:crypto-sig-callbacks
Closed

crypto: add optional callback to crypto.sign and crypto.verify#37500
panva wants to merge 11 commits into
nodejs:masterfrom
panva:crypto-sig-callbacks

Conversation

@panva

@panvapanva commented Feb 24, 2021

Copy link
Copy Markdown
Member

As discussed in #37218 this begins adding callbacks for one-shot crypto module operations to allow for execution using libuv's threadpool, rather than introducing a new module.

Starting off with

  • crypto.sign(algorithm, data, key[, callback])
  • crypto.verify(algorithm, data, key, signature[, callback])

@nodejs-github-botnodejs-github-bot added the crypto Issues and PRs related to the crypto subsystem. label Feb 24, 2021
@panvapanva added the wip Issues and PRs that are still a work in progress. label Feb 24, 2021
@panvapanva mentioned this pull request Feb 24, 2021
8 tasks
@tniessen

Copy link
Copy Markdown
Member

Is there room for benchmarks? I can imagine two aspects:

  1. How much slower is async signing compared to sync signing? (Both sequentially)
  2. How much faster is async signing compared to sync signing? (Async in parallel)

So we'd expect drastic performance improvements in the second case, I assume?

@panva

panva commented Feb 26, 2021

Copy link
Copy Markdown
MemberAuthor

I can benchmark locally for sure, but would need help setting up the benchmark in CI.

@panva

panva commented Feb 26, 2021

Copy link
Copy Markdown
MemberAuthor

So we'd expect drastic performance improvements in the second case, I assume?

Would you expect a drastic performance improvement in the second case? What I assume is slightly lower performance but having the main thread unblocked...

It is what i'm seeing locally.

Details
constcrypto=require('crypto')constkp=crypto.generateKeyPairSync('rsa',{modulusLength: 2048*2})constdata=crypto.randomBytes(256)functionmeasureLag(iteration){console.time(`measureLag${iteration}`)setTimeout(()=>{console.timeEnd(`measureLag${iteration}`)measureLag(iteration+1)// Recurse})}measureLag(1)functionsign(iteration){console.time(`sign${iteration}`)crypto.sign('sha256',data,kp.privateKey,()=>{console.timeEnd(`sign${iteration}`)setTimeout(sign.bind(undefined,iteration+1))})}sign(1)
measureLag2: 1.948ms
measureLag3: 1.485ms
measureLag4: 0.09ms
measureLag5: 1.313ms
measureLag6: 1.318ms
sign2: 4.473ms
measureLag7: 0.174ms
measureLag8: 1.512ms
measureLag9: 1.237ms
measureLag10: 1.346ms
sign3: 3.778ms
measureLag11: 0.971ms
measureLag12: 1.43ms
measureLag13: 1.394ms
measureLag14: 1.092ms
measureLag15: 1.165ms
sign4: 4.07ms
measureLag16: 0.137ms
measureLag17: 1.355ms
measureLag18: 1.286ms
measureLag19: 0.07ms

Compared to sync

constcrypto=require('crypto')constkp=crypto.generateKeyPairSync('rsa',{modulusLength: 2048*2})constdata=crypto.randomBytes(256)functionmeasureLag(iteration){console.time(`measureLag${iteration}`)setTimeout(()=>{console.timeEnd(`measureLag${iteration}`)measureLag(iteration+1)// Recurse})}measureLag(1)functionsign(iteration){console.time(`sign${iteration}`)crypto.sign('sha256',data,kp.privateKey)console.timeEnd(`sign${iteration}`)setTimeout(sign.bind(undefined,iteration+1))}sign(1)
measureLag2: 5.191ms
sign3: 4.1ms
measureLag3: 4.339ms
sign4: 3.481ms
measureLag4: 4.656ms
sign5: 3.729ms
measureLag5: 5.178ms
sign6: 3.581ms
measureLag6: 5ms
sign7: 3.87ms
measureLag7: 5.056ms
sign8: 3.837ms
measureLag8: 5.303ms
sign9: 3.896ms
measureLag9: 5.309ms
sign10: 3.703ms
measureLag10: 5.043ms
sign11: 3.991ms
measureLag11: 5.473ms
sign12: 3.932ms
measureLag12: 5.453ms
sign13: 4.012ms
measureLag13: 5.523ms
sign14: 4.119ms
measureLag14: 5.637ms
sign15: 4.088ms
measureLag15: 5.592ms
sign16: 4.07ms
measureLag16: 5.476ms
sign17: 4.16ms
measureLag17: 5.615ms
sign18: 4.016ms
measureLag18: 5.403ms
sign19: 3.961ms
measureLag19: 5.187ms

Comment threadtest/parallel/test-crypto-async-sign-verify.js Outdated
@mcollina

Copy link
Copy Markdown
Member

Would you expect a drastic performance improvement in the second case? What I assume is slightly lower performance but having the main thread unblocked...

It also depends on how many CPUs are available on the machine.

@panvapanva added the semver-minor PRs that contain new features and should be released in the next minor version. label Feb 26, 2021
Comment threadlib/internal/crypto/dsa.js Outdated
Comment threadlib/internal/crypto/ec.js Outdated
Comment threadlib/internal/crypto/rsa.js Outdated
@jasnell

This comment has been minimized.

@jasnell

Copy link
Copy Markdown
Member

Specifically on the performance bit... it's all relative to what you're testing. Moving the sign/verify operations onto the thread pool will not alter the performance of those operations in any significant way, in fact, if anything it will make those slightly slower. What it does, however, is allow the main event loop to continue turning so it can do other things, so you should see an increase in overall throughput even if the individual operations themselves are not actually faster. That said, you also have to consider all of the other things that may be using the libuv threadpool. File system operations and DNS resolution in particular. If your system is heavy on async file system and crypto, then the individual sign operations may be fairly significantly impacted. Bottom line is that moving to async is not, in itself, a performance silver bullet :-)

@jasnell

This comment has been minimized.

@panva

panva commented Mar 8, 2021

Copy link
Copy Markdown
MemberAuthor

@panva ... here's the updated patch for dsaEncoding with the necessary adjustments... If I can get a moment later this afternoon I'll push to your branch if you don't beat me to it...

Thank you, i'll re-push your patch.

@panva
panvaforce-pushed the crypto-sig-callbacks branch from df713fa to b7dead3CompareMarch 8, 2021 19:06
@jasnell

This comment has been minimized.

@panva
panva marked this pull request as ready for review March 8, 2021 19:26
@panvapanva removed the wip Issues and PRs that are still a work in progress. label Mar 8, 2021
@panva
panva requested review from jasnell and mcollinaMarch 8, 2021 19:27

@jasnelljasnell left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM for all the parts that I didn't contribute to. Will need another sign off to cover those

@panvapanva added the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Mar 8, 2021
@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot

This comment has been minimized.

@nodejs-github-bot

This comment has been minimized.

@panva
panvaforce-pushed the crypto-sig-callbacks branch from 8176164 to 78440b9CompareMarch 10, 2021 19:23
@panva

Copy link
Copy Markdown
MemberAuthor

rebased to hopefully get a clean CI.

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

@nodejsnodejs deleted a comment from nodejs-github-botMar 10, 2021
@jasnell

Copy link
Copy Markdown
Member

Landed in 25985d6

@jasnelljasnell closed this Mar 10, 2021
jasnell pushed a commit that referenced this pull request Mar 10, 2021
PR-URL: #37500
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@panva
panva deleted the crypto-sig-callbacks branch March 10, 2021 23:13
danielleadams pushed a commit that referenced this pull request Mar 16, 2021
PR-URL: #37500
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@danielleadamsdanielleadams mentioned this pull request Mar 16, 2021
danielleadams added a commit that referenced this pull request Mar 16, 2021
PR-URL: #37766
Notable changes:
* crypto:
* add optional callback to crypto.sign and crypto.verify (Filip Skokan) #37500
* support JWK objects in create\*Key (Filip Skokan) #37254
* deps:
* update archs files for OpenSSL-1.1.1+quic (James M Snell) #37601
* switch openssl to quictls/openssl (James M Snell) #37601
* doc:
* update maintaining-openssl guide (James M Snell) #37601
* fs:
* improve fsPromises writeFile performance (Nitzan Uziely) #37610
* add promisified readFile benchmark (Nitzan Uziely) #37608
* improve fsPromises readFile performance (Nitzan Uziely) #37608
* lib:
* implement AbortSignal.abort() (James M Snell) #37693
* node-api:
* define version 8 (Gabriel Schulhof) #37652
* test:
* update dom/abort tests (James M Snell) #37693
* fixup test to account for quic openssl version (James M Snell) #37601
* worker:
* add setEnvironmentData/getEnvironmentData (James M Snell) #37486
danielleadams pushed a commit that referenced this pull request Mar 16, 2021
PR-URL: #37500
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
danielleadams added a commit that referenced this pull request Mar 16, 2021
PR-URL: #37766
Notable changes:
* crypto:
* add optional callback to crypto.sign and crypto.verify (Filip Skokan) #37500
* support JWK objects in create\*Key (Filip Skokan) #37254
* deps:
* switch openssl to quictls/openssl (James M Snell) #37601
* fs:
* improve fsPromises writeFile performance (Nitzan Uziely) #37610
* improve fsPromises readFile performance (Nitzan Uziely) #37608
* lib:
* implement AbortSignal.abort() (James M Snell) #37693
* node-api:
* define version 8 (Gabriel Schulhof) #37652
* worker:
* add setEnvironmentData/getEnvironmentData (James M Snell) #37486
danielleadams added a commit that referenced this pull request Mar 17, 2021
PR-URL: #37766
Notable changes:
* crypto:
* add optional callback to crypto.sign and crypto.verify (Filip Skokan) #37500
* support JWK objects in create\*Key (Filip Skokan) #37254
* deps:
* switch openssl to quictls/openssl (James M Snell) #37601
* fs:
* improve fsPromises writeFile performance (Nitzan Uziely) #37610
* improve fsPromises readFile performance (Nitzan Uziely) #37608
* lib:
* implement AbortSignal.abort() (James M Snell) #37693
* node-api:
* define version 8 (Gabriel Schulhof) #37652
* worker:
* add setEnvironmentData/getEnvironmentData (James M Snell) #37486
danielleadams added a commit that referenced this pull request Mar 17, 2021
PR-URL: #37766
Notable changes:
* crypto:
* add optional callback to crypto.sign and crypto.verify (Filip Skokan) #37500
* support JWK objects in create\*Key (Filip Skokan) #37254
* deps:
* update to cjs-module-lexer@1.1.0 (Guy Bedford) #37712
* switch openssl to quictls/openssl (James M Snell) #37601
* fs:
* improve fsPromises writeFile performance (Nitzan Uziely) #37610
* improve fsPromises readFile performance (Nitzan Uziely) #37608
* lib:
* implement AbortSignal.abort() (James M Snell) #37693
* node-api:
* define version 8 (Gabriel Schulhof) #37652
* worker:
* add setEnvironmentData/getEnvironmentData (James M Snell) #37486
danielleadams added a commit that referenced this pull request Mar 17, 2021
PR-URL: #37766
Notable changes:
* crypto:
* add optional callback to crypto.sign and crypto.verify (Filip Skokan) #37500
* support JWK objects in create\*Key (Filip Skokan) #37254
* deps:
* update to cjs-module-lexer@1.1.0 (Guy Bedford) #37712
* switch openssl to quictls/openssl (James M Snell) #37601
* fs:
* improve fsPromises writeFile performance (Nitzan Uziely) #37610
* improve fsPromises readFile performance (Nitzan Uziely) #37608
* lib:
* implement AbortSignal.abort() (James M Snell) #37693
* node-api:
* define version 8 (Gabriel Schulhof) #37652
* worker:
* add setEnvironmentData/getEnvironmentData (James M Snell) #37486
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author readyPRs that have at least one approval, no pending requests for changes, and a CI started.cryptoIssues and PRs related to the crypto subsystem.semver-minorPRs that contain new features and should be released in the next minor version.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@panva@tniessen@mcollina@jasnell@nodejs-github-bot@targos