Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Catalog · How the catalog works
Anything · Lazarus or Delphi
Random projectRandom project

scrypt-for-delphi

Scrypt implementation for Delphi

View on GitHub

Member rating

No ratings yet.

Sign in to rate this project.

README

Scrypt for Delphi

Scrypt is a key derivation function. It is designed to take a password (and some salt), and generate a desired number of pseudo-random bytes.

overview

The generated bytes are usually then used as a symmetric encryption key. SCrypt is similar to PBKDF2, except that it is memory-hard, making it difficult to parallelize in hardware. It was first described by Colin Percival in 2012 for the Tarsnap online backup service.

Sample Usage

To generate 16 bytes (e.g. AES-128 key) from a password, and using default cost factors:

pascal
secretKey := TScrypt.GetBytes('correct horse battery staple', 'seasalt', 16); //returns 16 bytes (128 bits)

To specify custom Scrypt parameters:

pascal
secretKey := TScrypt.GetBytes('correct horse battery staple', 'seasalt', {N=2^}14}, {r=}8, {p=}1, 32); //returns 32 bytes (256 bits)

Password Hashing

The TScrypt class also supports being used for password hashing (i.e. storage and verification of passwords).

  • To hash a password:
    pascal
    hash := TScrypt.HashPassword('correct battery horse staple'); //using default cost factors
  • To hash a password specifying your own cost factors:
    pascal
    hash := TScrypt.HashPassword('correct battery horse staple', 14, 8, 1); //N=2^14, r=8, p=1
  • To verify a password:
    pascal
    isPasswordValid := TScrypt.CheckPassword('correct battery horse stapler', expectedHash, {out}passwordRehashNeeded);

By convention TScrypt outputs a password hash as string in the form:

pascal
$s1$NNrrpp$salt$hash
$s1$131003$aXzuBr2qvisBj/bl7vr2pe$ksOS0sSZD38pZ8Nr/Zucq6fZrSLrQJTwXMmpSRvK4fGmyHg/ivJnd/dTDMICZO3uVvCxL/tQqjlLCK6bfz31Ju

The parts of the string are:

Value Meaning Notes
s1 Hash algorithm "s1" = current version of Scrypt
N Hex encoded log2(N) Default is 14 (i.e. 2^14) iterations
rr Hex encoded Block Size 1-255
pp Hex encoded Parallelization Factor 1-255
salt base64 encoded salt 0-16 bytes decoded
hash base64 encoded hash 64-bytes

Because the three scrypt parameters are stored in the returned string, scrypt password hashes are backwards and forwards compatible with changing the factors. It also makes Scrypt extraordinarily convenient, in that a random salt is automatically generated and stored for you (you don't have to worry about storing it in a database or retrieving it).

Scrypt Operation

Scrypt uses three parameters to tune CPU and memory usage:

  • CostFactor: determines how many blocks will have to be allocated in memory (the memory hard factor).
    pascal
    # of blocks = *"cost"* = N = 2^costFactor
    Memory required =cost*blockSize = 2^costFactor * blockSize
  • BlockSizeFactor: determines the size of a block (r)
    pascal
    BlockSize = blockSizeFactor * 128 bytes
  • ParallelizationFactor: determines how many independant calculations have to be performed (p)

The default parameters given in the original whitepaper are:

  • CostFactor (cf): 14 (N = 214 = 16,384)
  • Block Size Factor (r): 1 (blockSize = 1*128 bytes)
  • Parallelization Factor (p): 1

Note: Most scrypt documentation uses Cost (N), which is a large value and a power of two. We adopt the BCrypt convention of expressing a Cost Factor, which is the log_2(Cost).

Algorithm

Scrypt uses the standard PBDKF2 function to generate the desired number of bytes. The password fed to PBKDF2 is the user password. The virtue of Scrypt is its expensive generation of the salt to be fed into PBKDF2:

operation

Created by Ian Boyd, 4/9/2015, and released into the public domain