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())
Verifies an Scrypt hash.
Decodes and verifies an Scrypt header using a supplied password, following the documented specs.
Functions
@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, ...>>
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, ...>>
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/
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
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