The scrypt key derivation function
The scrypt key derivation function was originally developed for use in the Tarsnap online backup system and is designed to be far more secure against hardware brute-force attacks than alternative functions such as PBKDF2 or bcrypt.
We estimate that on modern (2009) hardware, if 5 seconds are spent computing a
derived key, the cost of a hardware brute-force attack against
roughly 4000 times greater than the cost of a similar attack against bcrypt (to
find the same password), and 20000 times greater than a similar attack against
PBKDF2. If the
scrypt encryption utility is used with default parameters,
the cost of cracking the password on a file encrypted by
scrypt enc is
approximately 100 billion times more than the cost of cracking the same
password on a file encrypted by
openssl enc; this means that a five-character
scrypt is stronger than a ten-character password using
Details of the
scrypt key derivation function are given in:
- The Internet Engineering Task Force (IETF) RFC 7914: The scrypt Password-Based Key Derivation Function.
- The original conference paper: Colin Percival, Stronger Key Derivation via Sequential Memory-Hard Functions, presented at BSDCan'09, May 2009. Conference presentation slides.
Some additional articles may be of interest:
Filippo Valsorda presented a very well-written explanation about how the scrypt parameters impact the memory usage and CPU time of the algorithm.
J. Alwen, B. Chen, K. Pietrzak, L. Reyzin, S. Tessaro, Scrypt is Maximally Memory-Hard, Cryptology ePrint Archive: Report 2016/989.
The scrypt encryption utility
A simple password-based encryption utility is available as a demonstration of
scrypt key derivation function. It can be invoked as
scrypt enc infile [outfile] to encrypt data (if
outfile is not specified, the encrypted data
is written to the standard output), or as
scrypt dec infile [outfile] to
decrypt data (if outfile is not specified, the decrypted data is written to the
scrypt also supports three command-line options:
-t maxtimewill instruct
scryptto spend at most maxtime seconds computing the derived encryption key from the password; for encryption, this value will determine how secure the encrypted data is, while for decryption this value is used as an upper limit (if
scryptdetects that it would take too long to decrypt the data, it will exit with an error message).
scryptto use at most the specified fraction of the available RAM for computing the derived encryption key. For encryption, increasing this value might increase the security of the encrypted data, depending on the
maxtimevalue; for decryption, this value is used as an upper limit and may
causescrypt to exit with an error.
scryptto use at most the specified number of bytes of RAM when computing the derived encryption key.
If the encrypted data is corrupt,
scrypt dec will exit with a non-zero
scrypt dec may produce output before it determines that
the encrypted data was corrupt, so for applications which require data to be
authenticated, you must store the output of
scrypt dec in a temporary
location and check
scrypt's exit code before using the decrypted data.
scrypt utility has been tested on FreeBSD, NetBSD, OpenBSD, Linux
(Slackware, CentOS, Gentoo, Ubuntu), Solaris, OS X, Cygwin, and GNU Hurd.
This cleartext signature of the SHA256 output can be verified with:
gpg --decrypt scrypt-sigs-1.2.1.asc
You may then compare the displayed hash to the SHA256 hash of
scrypt is available in the OpenBSD and FreeBSD ports trees and
in NetBSD pkgsrc as
Using scrypt as a KDF
To use scrypt as a key derivation function (KDF), take a look at
lib/crypto/crypto_scrypt.h header, which provides:
/** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, * p, buflen) and write the result into buf. The parameters r, p, and buflen * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N * must be a power of 2 greater than 1. * * Return 0 on success; or -1 on error. */ int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, uint32_t, uint32_t, uint8_t *, size_t);
The same function is provided in the optional
libscrypt-kdf library; there
is a sample of using it in
tests/libscrypt-kdf. If you installed the
library, you can compile that file and run the binary:
$ cd tests/libscrypt-kdf/ $ c99 sample-libscrypt-kdf.c -lscrypt-kdf $ ./a.out crypto_scrypt(): success
To build scrypt, extract the tarball and run
make. See the
BUILDING file for more details (e.g., dealing with OpenSSL on OSX).
A small test suite can be run with:
Memory-testing normal operations with valgrind (takes approximately 4 times as long as no valgrind tests) can be enabled with:
make test USE_VALGRIND=1
Memory-testing all tests with valgrind (requires over 1 GB memory, and takes
approximately 4 times as long as
USE_VALGRIND=1) can be enabled with:
make test USE_VALGRIND=2
The scrypt key derivation function and the scrypt encryption utility are discussed on the email@example.com mailing list.