View Source Scrypt (ScryptElixir v0.1.1)

This module provides the base functionality to work with the Scrypt KDF.

Summary

Functions

Creates an Scrypt hash from the given parameters, allowing a custom salt and key length.

Generates an Scrypt header from the given parameters, using 32 bytes hash and a 64 bytes key length. If a salt is not given, one is generated with :crypto.strong_rand_bytes(n :: non_neg_integer())

Decodes and verifies an Scrypt header using a supplied password, following the documented specs.

Functions

Link to this function

hash(password, salt, log_n, r, p, key_length)

View Source
@spec hash(String.t(), String.t(), integer(), integer(), integer(), integer()) ::
  String.t() | none()

Creates an Scrypt hash from the given parameters, allowing a custom salt and key length.

Examples

iex> Scrypt.hash("hunter2", "oftheearth", 14, 8, 1, 64)
<<66, 229, 151, 70, 35, 13, 211, 30, 1, 153, 91, 172, 42, 194, 249, 50, 229, 34,
  92, 157, 115, 218, 91, 163, 223, 167, 219, 42, 90, 20, 93, 163, 101, 225, 98,
  198, 152, 96, 97, 86, 50, 220, 91, 22, 5, 160, 199, 150, 150, 253, ...>>
Link to this function

kdf(password, log_n, r, p)

View Source
@spec kdf(String.t(), integer(), integer(), integer()) :: String.t()

Generates an Scrypt header from the given parameters, using 32 bytes hash and a 64 bytes key length. If a salt is not given, one is generated with :crypto.strong_rand_bytes(n :: non_neg_integer())

Examples

iex> Scrypt.kdf("hunter2", 14, 8, 1)
<<115, 99, 114, 121, 112, 116, 0, 14, 0, 0, 0, 8, 0, 0, 0, 1, 166, 59, 141, 39,
  16, 29, 92, 191, 50, 7, 102, 174, 27, 240, 229, 27, 121, 234, 97, 111, 98,
  182, 29, 158, 117, 43, 9, 141, 172, 189, 106, 88, 213, 152, ...>>

iex> Scrypt.kdf("hunter2", :crypto.strong_rand_bytes(32), 14, 8, 1)
<<115, 99, 114, 121, 112, 116, 0, 14, 0, 0, 0, 8, 0, 0, 0, 1, 120, 127, 46, 232,
  104, 21, 51, 3, 154, 50, 72, 127, 172, 43, 131, 37, 182, 149, 168, 88, 27,
  146, 85, 169, 52, 134, 20, 143, 37, 97, 197, 66, 148, 182, ...>>
Link to this function

kdf(password, salt, log_n, r, p)

View Source
@spec kdf(String.t(), salt :: <<_::256>>, integer(), integer(), integer()) ::
  String.t()
Link to this function

secure_compare(left, right)

View Source

Copied from: https://github.com/elixir-plug/plug/blob/v1.5.0-rc.2/lib/plug/crypto.ex#L102

Compares the two binaries in constant-time to avoid timing attacks. See: http://codahale.com/a-lesson-in-timing-attacks/

Link to this function

verify?(base_hash, password, salt, log_n, r, p)

View Source
@spec verify?(String.t(), String.t(), String.t(), integer(), integer(), integer()) ::
  boolean()

Verifies an Scrypt hash.

Examples

iex(1)> hash = Scrypt.hash("hunter2", "oftheearth", 14, 8, 1, 64)
<<66, 229, 151, 70, 35, 13, 211, 30, 1, 153, 91, 172, 42, 194, 249, 50, 229, 34,
  92, 157, 115, 218, 91, 163, 223, 167, 219, 42, 90, 20, 93, 163, 101, 225, 98,
  198, 152, 96, 97, 86, 50, 220, 91, 22, 5, 160, 199, 150, 150, 253, ...>>
iex(2)> Scrypt.verify?(hash, "hunter2", "oftheearth", 14, 8, 1)
true
Link to this function

verify_kdf?(arg, password)

View Source
@spec verify_kdf?(header :: <<_::768>>, String.t()) :: boolean()

Decodes and verifies an Scrypt header using a supplied password, following the documented specs.

+----------+--------+----------------------------------------------------------+
|   offset | length |                        assignment                        |
+----------+--------+----------------------------------------------------------+
|   0      | 6      | "scrypt"                                                 |
|   6      | 1      | scrypt data file version number (== 0)                   |
|   7      | 1      | log2(N) (must be between 1 and 63 inclusive)             |
|   8      | 4      | r (big-endian integer; must satisfy r * p < 2^30)        |
|   12     | 4      | p (big-endian integer; must satisfy r * p < 2^30)        |
|   16     | 32     | salt                                                     |
|   48     | 16     | first 16 bytes of SHA256(bytes 0 .. 47)                  |
|   64     | 32     | HMAC-SHA256(bytes 0 .. 63)                               |
|   96     | X      | data xor AES256-CTR key stream generated with nonce == 0 |
|   96+X   | 32     | HMAC-SHA256(bytes 0 .. 96 + (X - 1))                     |
+----------+--------+----------------------------------------------------------+

Examples

iex(1)> header = Scrypt.kdf("hunter2", 14, 8, 1)
<<115, 99, 114, 121, 112, 116, 0, 14, 0, 0, 0, 8, 0, 0, 0, 1, 66, 223, 14, 146,
  240, 251, 4, 70, 177, 59, 232, 159, 183, 134, 188, 127, 72, 170, 70, 224, 134,
  201, 74, 15, 188, 227, 34, 222, 250, 192, 153, 226, 42, 189, ...>>
iex(2)> Scrypt.verify_kdf?(header, "hunter2")
true