-
Notifications
You must be signed in to change notification settings - Fork 30.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
crypto: improve random-bytes performance by ~60% #44661
Conversation
Review requested:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
@@ -34,13 +34,11 @@ hooks = async_hooks.createHook({ | |||
|
|||
|
|||
process.on('uncaughtException', common.mustCall(() => { | |||
assert.strictEqual(call_id, async_hooks.executionAsyncId()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My guess here is that in certain cases now the async context may or may not be the same. @nodejs/async_hooks folks, I just want to confirm with y'all that this looks correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing these asserts makes this test quite useless. It no longer tests what was tested before.
After this change the random byte comes from the cache therefore no RANDOMBYTESREQUEST
is done at all.
To keep the behavior of the test as before it's needed to request more random bytes as the cache has.
It would be good to add a test that ensures that, when the cache is used, the results of multiple random-bytes calls return different results each time without any overlap to ensure that the cache is advancing the way that it should. |
IIRC I was the one to implement caching for My main concern here is that, unlike I assume that the main performance bottleneck is crossing the JS/C++ border, and V8 fast API calls would be a good approach to reducing that performance bottleneck without having to cache secret data in the JS heap. |
Yeah, caching random bytes unconditionally could lead to problems. The cache could be set up to use the openssl secure heap if that is enabled for the process (https://nodejs.org/dist/latest-v18.x/docs/api/cli.html#--secure-heapn) which would at least separate it from the rest of the js heap space. But if we're going to add this, it would be good to make use of the cache optional (and likely off by default) |
Another motivation for caching
It could, but secure heap is almost always disabled, and even unsupported on many operating systems IIRC. |
I can only think of two solutions to address the heap-related issues:
|
By the way; can we add |
@anonrig this can be a good approach to try. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to sound too negative but I strongly feel this is optimizing the wrong thing.
It's extremely important to maintain the security properties of the cryptographic random number generator. The more speed hacks you pile on, the harder it becomes to understand and the easier it becomes for bugs to slip in.
I'm also skeptical it needs to be super fast because even a dedicated keygen server probably doesn't use more than a few hundred bytes of entropy per second.
Is there any documentation for v8 Fast API? I couldn't find docs or usage of fast api. |
There unfortunately is very little documentation beyond https://github.com/nodejs/node/blob/main/deps/v8/include/v8-fast-api-calls.h. |
By using the same method of
randomInt
, I added to reduce the random byte generation for key size less than 8 * 1024 bytesSome of the tests are failing due to the async nature of caching. I appreciate any help for resolving those.