Skip to content
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

Allow r: 1, p: 8 in scrypt #61

Closed
homura opened this issue Jun 8, 2023 · 8 comments
Closed

Allow r: 1, p: 8 in scrypt #61

homura opened this issue Jun 8, 2023 · 8 comments

Comments

@homura
Copy link

homura commented Jun 8, 2023

noble-hashes/src/scrypt.ts

Lines 110 to 118 in ba9d92f

const blockSize = 128 * r;
const blockSize32 = blockSize / 4;
if (N <= 1 || (N & (N - 1)) !== 0 || N >= 2 ** (blockSize / 8) || N > 2 ** 32) {
// NOTE: we limit N to be less than 2**32 because of 32 bit variant of Integrify function
// There is no JS engines that allows alocate more than 4GB per single Uint8Array for now, but can change in future.
throw new Error(
'Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32'
);
}

{
    "kdfparams": {
      "dklen": 32,
      "n": 262144,
      "p": 8,
      "r": 1,
      "salt": "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19"
    }
}

Test vector from the Ethereum developer community

the cost 262144 here is over 65535(2 ** (blockSize / 8)

@paulmillr
Copy link
Owner

It's compatible with scrypt spec.

Using p: 8, r: 1 is wrong. No one should be doing that. This is an error in web3 test vectors that was made a while ago.

Instead, p: 1, r: 8 should be done.

@homura
Copy link
Author

homura commented Jun 8, 2023

Got it, you're right. Thanks for your quickly reply

https://datatracker.ietf.org/doc/html/rfc7914#section-2

The parameter r ("blockSize")
specifies the block size. The CPU/Memory cost parameter N
("costParameter") must be larger than 1, a power of 2, and less than
2^(128 * r / 8).

@sreyemnayr
Copy link
Contributor

There have been errata filed for RFC7914 that correct this "incorrect conversion between bits/bytes."

https://www.rfc-editor.org/errata_search.php?rfc=7914

The presented limit on N was incorrectly derived from the original scrypt publication. The correct theoretical upper limit on N is 2^(128 * r) for r < 5, and 2^512 for all other values of r. Thus, the least upper bound is 2^128, which far exceeds all possible values for N in the foreseeable future, making the limit irrelevant for current implementations.

See the conversation here for more context.

I got here via dependency rabbit hole of the Rabby wallet, which depends on @ethereumjs/wallet, which depends on ethereum-cryptography, which depends on @noble/hashes.

Ironically, the issue is intra-organizational Paul vs Paul... the default settings for ethereum/eth-account's keystore write by @pacrob are incompatible with the keystore read ethereum/ethereum-js-cryptography by @paulmillr

@sreyemnayr
Copy link
Contributor

It actually looks like the defaults were fixed in eth-keyfile 0.7, but eth-account pins to >= 0.6, so they still generate files that noble-hashes won't read. That all said, the check is based on bad math, so should probably be a warning at most, rather than raising an error.

@paulmillr
Copy link
Owner

That’s unfortunate, but, is relaxing the check really the best outcome?

I’m not scrypt expert and will need to check if that doesn’t impact security etc.

sure, there are some folks who’ve generated keys using wrong algorithms.

Probably there are other ones, with bugs in algorithms, which make their implementations incompatible with everyone else. Is asking to be compatible with those a good thing? I think answer can be positive - but only when the library is popular. Is eth account popular? Has it ever been?

@sreyemnayr
Copy link
Contributor

sreyemnayr commented Aug 29, 2024 via email

@sreyemnayr
Copy link
Contributor

For a little less "source: trust me, bro", the pypi stats for the eth-account package can be found here.

Over 1m downloads a week is pretty significant. They've just updated their latest release to require a newer version of eth-keyfile (which is actually the culprit of defaults being incompatible with your library) so it will eventually wash itself out over the long term, but the fact still remains that the check is based on incorrectly reported math initially in the RFC. I think updating to change it to a non-lethal warning is an only-positive move.

@paulmillr paulmillr reopened this Aug 30, 2024
@paulmillr paulmillr changed the title The noble/scrypt may incompatible with the WEB3 SECRET STORAGE DEFINITION Allow r: 1, p: 8 in scrypt Aug 30, 2024
@paulmillr
Copy link
Owner

paulmillr commented Aug 30, 2024

Confirmation by scrypt creator that it's ok: golang/go#33703 (comment)

RFC errata that it's ok: https://www.rfc-editor.org/errata_search.php?rfc=7914

sreyemnayr added a commit to sreyemnayr/noble-hashes that referenced this issue Aug 30, 2024
sreyemnayr added a commit to sreyemnayr/noble-hashes that referenced this issue Aug 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants