-
Notifications
You must be signed in to change notification settings - Fork 461
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
x1.4 Faster LruCache #5251
x1.4 Faster LruCache #5251
Conversation
Do we need |
|
Good question, I think the only way to know is profile the node as a whole and try to see the differences. |
~x1.4 improvement BenchmarkDotNet=v0.13.4, OS=Windows 11 (10.0.22623.1250)
|
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.
General comments/remarks.
{ | ||
if (Bytes is null) return 0; | ||
|
||
long v0 = Unsafe.ReadUnaligned<long>(ref MemoryMarshal.GetArrayDataReference(Bytes)); |
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.
Have you noticed collisions at all? This is Keccak
on its own so it should have low collision rate. Also as GetHashCode has int
as a return parameter, we'll still use 32bits so that
if (Bytes is null) return 0;
return Unsafe.ReadUnaligned<int>(ref MemoryMarshal.GetArrayDataReference(Bytes));
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.
Good question, if Keccak has equal distribution its first 4 bytes should also have equal distribution and mixing all of them might be an overkill?
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.
It is a world where people brute force Keccak hashes to get vanity addresses[1][2] with as many zeros as possible with 32bits of consecutive zeros or 0 nibbles of zeros taking a fairly small amount of time [1]; with gpu brute forcing becoming so powerful that you can inverse brute force from the 8+ character vanity address to the private keys if you used a deterministic random start [3].
The distribution of the returns from GetHashcode
from user input can lead to a hashcode collision attack in Dictionary causing a DoS CVE[4] as handling collisions are an O(n²) (e.g. CVE-2011-3414)
So for example if someone sent more than 1000+ txns that their Keccak hash all started with 8 zeros; through brute forcing txn construction, as the hashcode only takes the first 4 bytes its entirely possible to turn that into a DoS of the execution client. Whereas using all 256 bits makes that an impossibility with current hardware.
[1] https://github.com/1inch/profanity2
[2] https://github.com/johguse/ERADICATE2
[3] https://blog.1inch.io/a-vulnerability-disclosed-in-profanity-an-ethereum-vanity-address-tool-68ed7455fc8c
[4] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3414
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.
tl;dr is safer to fold in all the bits since some of the Keccak hashes are directly determined by EOA; and 8 zero leading hashes (32bits) are brute forcible
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.
Interesting finding about the vanity addresses. Looks good then!
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 may have dabbled in vanity addresses 😅
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.
Also that was my CVE report for .NET 🤣
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.
It is a world where people brute force Keccak hashes to get vanity addresses[1][2] with as many zeros as possible with 32bits of consecutive zeros or 0 nibbles of zeros taking a fairly small amount of time [1]; with gpu brute forcing becoming so powerful that you can inverse brute force from the 8+ character vanity address to the private keys if you used a deterministic random start [3].
The distribution of the returns from
GetHashcode
from user input can lead to a hashcode collision attack in Dictionary causing a DoS CVE[4] as handling collisions are an O(n²) (e.g. CVE-2011-3414)So for example if someone sent more than 1000+ txns that their Keccak hash all started with 8 zeros; through brute forcing txn construction, as the hashcode only takes the first 4 bytes its entirely possible to turn that into a DoS of the execution client. Whereas using all 256 bits makes that an impossibility with current hardware.
[1] https://github.com/1inch/profanity2 [2] https://github.com/johguse/ERADICATE2 [3] https://blog.1inch.io/a-vulnerability-disclosed-in-profanity-an-ethereum-vanity-address-tool-68ed7455fc8c [4] https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3414
Great explanation! By the way, FYI, the profanity vanity vulnerability caused a large hack of a famous market maker recently.
Changes
Keccak
vsKeccakKey
struct
Keccak
bytes forGetHashCode
to reduce dictionary collisionsUnsafe.Same
+.Length
comparisons for some span compares for early exit when same referenceTypes of changes
What types of changes does your code introduce?
Testing
Requires testing
If yes, did you write tests?
Notes on testing
Performance tests (before/after)