-
Notifications
You must be signed in to change notification settings - Fork 20.2k
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
scrypt usage not compliant with RFC 7914? #19977
Comments
It seems that Go's implementation of scrypt, used by geth, doesn't adhere to the RFC: https://github.com/golang/crypto/blob/master/scrypt/scrypt.go#L200 That is, it doesn't enforce I suspect the answer to my question ("Can someone shed light...?") boils down to: "geth's test data reflects what Go's scrypt allows for." On the other hand, the Rust implementation of scrypt used by parity does seem to restrict https://docs.rs/rust-crypto/0.2.36/src/crypto/scrypt.rs.html#193-196 I don't know Rust, so I can't speak to whether those lines are an exact match for |
I conducted the experiment with parity vs. geth: With a wallet based on geth's test data, but regen'd so as to include the address (otherwise an exact match):
With that wallet in the keystore and web3.js connected to geth, this works in a Node.js REPL:
But it does not work when web3.js is connected to a parity client that has loaded the same wallet. When using
I think the right thing would be for geth to start checking the kdf params for correctness re: the scrypt RFC before calling golang's scrypt implementation; and that geth's test wallets should be refactored so that they're all valid with respect to the RFC. |
Geth uses As for invalidating the tests, we don't plan on overriding Go's crypto constraints. I'm not saying that those should not be updated, but please open an issue against upstream Go. That is the place to fix standardization issues, not downstream packages. If they accept the proposal, we'll gladly pull in the changes. |
I opened an issue upstream a few minutes after I opened this one. See #33703. I also opened an upstream issue, of sorts, with ethereum/wiki, see #674. As I mentioned in the latter issue, portability seems to be a concern. A wallet with As you note, in practice, because geth only generates wallets with valid params it's probably not a huge issue for geth users. I also understand your decision to wait on an upstream change. But this was a rather confusing puzzle to piece together, and it already has implications for JS libs such as web3.js and ethereumjs-wallet. |
The RFC's author says that's an error in the spec golang/go#33703 (comment) and the code is actually correct. They'll probably fix up the spec whenever. |
@tniessen Thank you for the corrections and the confirmation! |
See: https://tools.ietf.org/html/rfc7914. In particular, Section 2: scrypt Parameters:
go-ethereum test data: https://github.com/ethereum/go-ethereum/blob/master/accounts/keystore/testdata/v3_test_vector.json#L13-L15.
Parameters
{N: 262144, r: 1, p: 8}
are not valid for an RFC-compliant implementation of scrypt.Can someone on the geth team shed light on why geth's usage of scrypt is not compliant with the RFC? Was/is it a deliberate decision or an accident?
Context re: why I'm filing this issue: nodejs/node#28799 (comment).
geth's test data has long been adapted for use in test suite's of tools for other runtimes. For example, see: https://github.com/ethereum/web3.js/blob/1.x/test/eth.accounts.encrypt-decrypt.js#L32-L34. The PR that landed that test script/data was made in mid 2017. Likewise, implementations of scrypt (for those other runtimes; example: scryptsy) that are used to build Ethereum tooling don't adhere to the RFC.
In the case of Node.js, per the GitHub comment linked above, the built-in RFC-compliant
scrypt
can't handle the N, r, p combination in the test data.The text was updated successfully, but these errors were encountered: