Safe Haskell | None |
---|
Scrypt is a sequential memory-hard key derivation function. This module
provides low-level bindings to the scrypt
key derivation function as
well as a higher-level password-storage API. It is based on a fast C
implementation of scrypt, written by Colin Percival. For further
information see http://www.tarsnap.com/scrypt.html.
- data ScryptParams
- scryptParams :: Integer -> Integer -> Integer -> Maybe ScryptParams
- defaultParams :: ScryptParams
- newtype EncryptedPass = EncryptedPass {}
- encryptPass :: ScryptParams -> Pass -> IO EncryptedPass
- encryptPass' :: Pass -> IO EncryptedPass
- verifyPass :: ScryptParams -> Pass -> EncryptedPass -> (Bool, Maybe EncryptedPass)
- verifyPass' :: Pass -> EncryptedPass -> Bool
- newtype Pass = Pass {
- unPass :: ByteString
- newtype Salt = Salt {
- unSalt :: ByteString
- newtype PassHash = PassHash {
- unHash :: ByteString
- scrypt :: ScryptParams -> Salt -> Pass -> PassHash
- scrypt' :: Salt -> Pass -> PassHash
Parameters to the scrypt
function
Scrypt takes three tuning parameters: N
, r
and p
. They affect running
time and memory usage:
Memory usage is approximately 128*r*N
bytes. Note that the
scryptParams
function takes log_2(N)
as a parameter. As an example,
the defaultParams
log_2(N) = 14, r = 8 and p = 1
lead to scrypt
using 128 * 8 * 2^14 = 16M
bytes of memory.
Running time is proportional to all of N
, r
and p
. Since it's
influence on memory usage is small, p
can be used to independently tune
the running time.
data ScryptParams Source
Encapsulates the three tuning parameters to the scrypt
function: N
,
r
and p
(see above).
:: Integer |
|
-> Integer | The parameter |
-> Integer | The parameter |
-> Maybe ScryptParams | Returns |
Constructor function for the ScryptParams
data type
defaultParams :: ScryptParamsSource
Default parameters as recommended in the scrypt paper:
N = 2^14, r = 8, p = 1
Equivalent to
.
fromJust
(scryptParams
14 8 1)
Password Storage
To allow storing encrypted passwords conveniently in a single database
column, the password storage API provides the data type EncryptedPass
. It
combines a Pass
as well as the Salt
and ScryptParams
used to compute
it into a single ByteString
, separated by pipe ("|") characters. The
Salt
and PassHash
are base64-encoded. Storing the ScryptParams
with
the password allows to gradually strengthen password encryption in case of
changing security requirements.
A usage example is given below, showing encryption, verification and
changing ScryptParams
:
>>> encrypted <- encryptPass defaultParams (Pass "secret") >>> print encrypted EncryptedPass {unEncryptedPass = "14|8|1|Wn5x[SNIP]nM=|Zl+p[SNIP]g=="} >>> print $ verifyPass defaultParams (Pass "secret") encrypted (True,Nothing) >>> print $ verifyPass defaultParams (Pass "wrong") encrypted (False,Nothing) >>> let newParams = fromJust $ scryptParams 16 8 1 >>> print $ verifyPass newParams (Pass "secret") encrypted (True,Just (EncryptedPass {unEncryptedPass = "16|8|1|Wn5x[SNIP]nM=|ZmWw[SNIP]Q=="}))
newtype EncryptedPass Source
encryptPass :: ScryptParams -> Pass -> IO EncryptedPassSource
Encrypt the password with the given parameters and a random 32-byte salt.
The salt is read from /dev/urandom
on Unix systems or CryptoAPI
on
Windows.
encryptPass' :: Pass -> IO EncryptedPassSource
Equivalent to encryptPass defaultParams
.
:: ScryptParams | Parameters to use for updating the |
-> Pass | The candidate |
-> EncryptedPass | The |
-> (Bool, Maybe EncryptedPass) | Returns a pair of
|
Verify a Pass
against an EncryptedPass
. The function also takes
ScryptParams
meeting your current security requirements. In case the
EncryptedPass
was generated with different parameters, the function
returns an updated EncryptedPass
, generated with the given
ScryptParams
. The Salt
is kept from the given EncryptedPass
.
verifyPass' :: Pass -> EncryptedPass -> BoolSource
Check the Pass
against the EncryptedPass
, using the ScryptParams
encapsulated in the EncryptedPass
.
Low-level bindings to the scrypt
key derivation function
Bindings to a fast C implementation of scrypt
. For password storage,
consider using the more convenient higher-level API above.