3

I'm having a problem of calculating the same scrypt digest between RbNaCl and Go's implementation.

Here's how I'm generating key with rbnacl:

opslimit = 2**20
memlimit = 2**24
digest_size = 32

digest = RbNaCl::PasswordHash.scrypt(
        password,
        salt,
        opslimit,
        memlimit,
        digest_size
)

opslimit and memlimit parameter values have been found from documentation.

Here's my attempt to replicate same results with Go:

N := 32768
r := 8
p := 1
keyLength := 32

secretKeyBytes, _ := scrypt.Key(password, salt, N, r, p, keyLength)

Values for N, r, p and keyLength gotten from documentation.

password and salt have same values.

I'm not a cryptographer, but as far as I understand there should be same cost factor values to get the same digest? The problem here is that since both implementations take different count of parameters it's hard for me to find the correct combination too. Any ideas how to make cost factors match between these two implementations so that I could calculate same scrypt hashes between two programming languages?

Jarmo Pertman
  • 1,905
  • 1
  • 12
  • 19

1 Answers1

5

Managed to calculate N, p and r from opslimit and memlimit by looking into libsodium's function pickparams, which was called by crypto_pwhash_scryptsalsa208sha256, which in turn was called by Ruby's scrypt implementation at RbNaCl.

Here's the relevant code to convert opslimit and memlimit to appropriate N, p and r to be used by other scrypt implementations, which offer lower level API for scrypt if anyone else needs it in the future: https://gist.github.com/jarmo/22f871076ff70e39b54e69c6305c020f

Just change opslimit and memlimit variable values in main and compile it with gcc and run it to get values for N, r and p.

All in all the problem was that Go exposes lower level API than RbNaCl even though they are doing the same thing.

Jarmo Pertman
  • 1,905
  • 1
  • 12
  • 19