-
Notifications
You must be signed in to change notification settings - Fork 7
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
feat: use native crypto functions #61
Conversation
wemeetagain
commented
Jul 12, 2024
•
edited
Loading
edited
- see Improve key decryption times for validator client keystores lodestar#6946
- Use nodejs crypto (if in node environment) for kdf (pbkdf2, scrypt)
- Use webcrypto (if in webcrypto environment) for hashing+encryption+kdf (pbkdf2 only)
30e7cb5
to
7455701
Compare
This does not change much for me when importing keys in Lodestar Unstable branch
Using this branch ChainSafe/lodestar@unstable...nflaig/web-crypto-pbkdf2
|
My guess is the decryption part takes most of the time, not key derivation Line 37 in 20f0b33
We might be able to use https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/decrypt there |
I have updated the branch to use webcrypto everywhere but the results are still the same
Need to further investigate, might wanna benchmark each function individually and compare that way. Also tried keystore decryption without thread pool, and with thread pool and increased concurrency, both made the results much worse. Looking at standard thread pool configuration we use, CPU utilization is maxed out already, likely the only way to improve the situation is to use more efficient implementations which does not seem to be the case with webcrypto compared to previous performance. |
strange, the unit tests run ~10x faster |
I know why, it is using scrypt, not pbkdf2. I guess this depens on how the keystores are created? |
Looking at decrypt timings
the majority of time is spend here bls-keystore/src/functional.ts Line 83 in 44d22af
|
Individual tests are running 10x faster. Specifically the round trip test (uses pbkdf2) and the pbkdf2 test vectors |
Looks like all my keystores use scrypt {"crypto": {"kdf": {"function": "scrypt", "params": {"dklen": 32, "n": 262144, "r": 8, "p": 1, "salt": "9b030cd77d229630253ffbb61708fb55e5206a3586de016b929f03315993d71b"}, "message": ""}, "checksum": {"function": "sha256", "params": {}, "message": "6455354b6666a28e4fa3b88e74d8b53e57d32a7dacbe0c299c8f7dfbb154c7c9"}, "cipher": {"function": "aes-128-ctr", "params": {"iv": "4c68e0d27df40979c5c466b801102ae5"}, "message": "fc6f971cf0d6863937e989c02be40b191b03b9c05dd36f35a9d85da1f73aedc5"}}, "description": "", "pubkey": "b8123417e2afcb2877fef62b74d8dc9b4405fa724953c9c61fd47b3efc346915902fbfd9f9c356328a1d37660c771e70", "path": "m/12381/3600/1047/0/0", "uuid": "0e120faa-39af-40a1-aad9-964bf45acacc", "version": 4} Which is the default for staking deposit cli, see ethereum/staking-deposit-cli#140 |
Benchmarks for pbkdf2 This branch (before my changes)
This branch (after my changes)
Master branch (using ethereum-cryptography)
Looks like key derivation takes most of the time, using webcrypto for pbkdf2 might be sufficient. PS: I was not able to get the benchmark tool to work without a few hacks, due to issues with loading files. Not sure if it's worth to get it to work with this repository. |
@nflaig can you give another review/benchmark? |
Benchmarks before update to node crypto
Importing pbkdf2 keys in Lodestar (uses ethereum-cryptography)
Importing pbkdf2 keys in Lodestar (uses webcrypto)
Importing scrypt keys in Lodestar (uses ethereum-cryptogprahy)
Benchmarks after update to node crypto
Importing pbkdf2 keys in Lodestar (uses node:crypto), it almost instantly imported the 2k keys. I am not quite sure why the benchmarks are the same but I observed some strange behavior when using webcrypto inside worker threads, it almost looks like it needs to warm up, it starts really slow, taking ~1-2 seconds for kdf but after few runs it goes down to a few ms.
Importing scrypt keys in Lodestar (uses node:crypto), it's a nice speed up here as well, I don't think we can speed up scrypt much more than that
The speed up for pbkdf2 is ~10x based on data which is also the format used by Kurtosis which uses https://github.com/protolambda/eth2-val-tools to generate the keys. Although there is strange behavior if running Lodestar inside docker (see below) Running the command
It seems to take a while to start decryption, might be related to workers inside docker? I don't see this when running locally (as shown in logs above)
And looking at timings of each decrypt (inside worker), it looks pretty strange, some take a few ms, others more than second
Our current unstable branch image seems to be faster..
Could give this a try without using worker threads, maybe we check key count and only spawn threads at a certain amount, although for scrypt this is likely not a good idea. So far the observation are
I have pushed code to take benchmarks here: master...nflaig/benchmark (wip) |
Did more testing in Kurtosis, with and without workers threads, at least on my machine not using workers make this pretty much instant. The reason why this is so fast in Kurtosis is because they use pbkdf2 but in addition set c=2 in kdf params which is insecure but much faster and good for testing. Disabling the worker pool, it takes ~1 sec to decrypt 64 keys
It take sub ms time to decrypt those keystores, so spawning workers would anyhow be overkill in this environment. My idea is to add a CLI flag which allows to disable worker thread for decryption. |
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 - might wanna get another review, also do we want to use webcrypto everywhere or just for key derivation?