Scrypt Class
Definition
- Namespace
- Bodu.Security.Cryptography
- Assembly
- Bodu.Security.Cryptography.dll
- Package
- Bodu.Security.Cryptography 1.2.0
- Source
- Scrypt.cs
Computes the scrypt sequential memory-hard password-hashing and key-derivation function defined by RFC 7914. This class cannot be inherited.
public sealed class Scrypt
- Inheritance
-
Scrypt
- Inherited Members
- Extension Methods
Remarks
scrypt derives a key from a password and salt while deliberately requiring a large amount of memory, raising the cost of large-scale custom-hardware attacks. An instance binds a set of cost ScryptParameters once, then derives keys or PHC password hashes. The static one-shot methods are provided for convenience.
By default a derivation runs its Parallelization units one after another on the
calling thread. MaxDegreeOfParallelism lets them run at once instead, each with a V of its
own, so the time falls and the memory rises with the threads; the derived key never depends on them.
The working memory - V, 128 · N · r bytes - is held in native memory and reused across derivations, in
the same reserve as Argon2's matrix, so a derivation neither allocates it on the collected heap nor waits for it to
be zeroed. Up to one buffer per processor stays reserved - cleared - for up to thirty seconds after the last
derivation; the Bodu.Security.Cryptography.Argon2.DisableMatrixReuse AppContext switch
releases each buffer as soon as its derivation ends instead. Every buffer holding a password-derived value is
cleared before it is released; values the JIT keeps in registers or its own stack slots are beyond the library's
reach.
This implementation is not independently audited and offers best-effort, not guaranteed, side-channel resistance.
Constructors
Scrypt(ScryptParameters)
Initializes a new instance of the Scrypt class with the specified cost parameters.
public Scrypt(ScryptParameters parameters)
Parameters
parametersScryptParametersThe cost parameters governing the derivation.
Remarks
Every derivation runs on the calling thread; see MaxDegreeOfParallelism.
Exceptions
- ArgumentNullException
parametersis null.- ArgumentOutOfRangeException
A cost parameter in
parametersfalls outside the range permitted by RFC 7914.
Scrypt(ScryptParameters, int)
Initializes a new instance of the Scrypt class with the specified cost parameters and bound on the threads each derivation may use.
public Scrypt(ScryptParameters parameters, int maxDegreeOfParallelism)
Parameters
parametersScryptParametersThe cost parameters governing the derivation.
maxDegreeOfParallelismintThe greatest number of threads one derivation may use, the calling thread included;
-1for up to one per processor.
Remarks
Each unit that runs at once holds its own V of 128 · N · r bytes, so a derivation on several
threads needs that much memory for each of them; see MaxDegreeOfParallelism.
Exceptions
- ArgumentNullException
parametersis null.- ArgumentOutOfRangeException
A cost parameter in
parametersfalls outside the range permitted by RFC 7914, ormaxDegreeOfParallelismis zero or less than-1.
Scrypt(int, int, int)
Initializes a new instance of the Scrypt class with the specified cost parameters.
public Scrypt(int costN, int blockSizeR, int parallelization)
Parameters
costNintThe CPU/memory cost parameter
N- a power of two greater than one.blockSizeRintThe block-size parameter
r.parallelizationintThe parallelization parameter
p.
Remarks
Every derivation runs on the calling thread; see MaxDegreeOfParallelism.
Exceptions
- ArgumentOutOfRangeException
A cost parameter falls outside the range permitted by RFC 7914.
Scrypt(int, int, int, int)
Initializes a new instance of the Scrypt class with the specified cost parameters and bound on the threads each derivation may use.
public Scrypt(int costN, int blockSizeR, int parallelization, int maxDegreeOfParallelism)
Parameters
costNintThe CPU/memory cost parameter
N- a power of two greater than one.blockSizeRintThe block-size parameter
r.parallelizationintThe parallelization parameter
p.maxDegreeOfParallelismintThe greatest number of threads one derivation may use, the calling thread included;
-1for up to one per processor.
Remarks
Each unit that runs at once holds its own V of 128 · N · r bytes, so a derivation on several
threads needs that much memory for each of them; see MaxDegreeOfParallelism.
Exceptions
- ArgumentOutOfRangeException
A cost parameter falls outside the range permitted by RFC 7914, or
maxDegreeOfParallelismis zero or less than-1.
Properties
MaxDegreeOfParallelism
Gets the greatest number of threads one derivation by this instance may use, the calling thread included.
public int MaxDegreeOfParallelism { get; }
Property Value
- int
1, the default, runs a derivation's Parallelization units one after another on the calling thread. A larger value, or-1for up to one thread per processor, lets them run at once, on no more threads than there are units. The derived key never depends on this value.
Remarks
Unlike Argon2's lanes, which share one memory matrix, each scrypt unit that runs at once holds its own V
of 128 · N · r bytes, so a derivation on t threads needs t times the memory of one on the
calling thread. That is why the default is 1: a service that verifies many passwords at once already
keeps every core busy, and would only multiply its memory.
A derivation keeps its working memory within the 2 GiB ceiling on a single V however high the bound,
running on fewer threads when its units are large, so an encoded hash from an untrusted source cannot multiply
the memory a verification takes. It stays on the calling thread when its units are small - under 1 MiB of
V each - where handing them to other threads costs more than it saves.
Parameters
Gets the cost parameters bound to this instance.
public ScryptParameters Parameters { get; }
Property Value
- ScryptParameters
The ScryptParameters supplied at construction.
Methods
DeriveKey(SecretBytes, Salt, int, int, int, int)
Derives a key in a single call from a pinned, disposable password holder and a typed salt.
public static byte[] DeriveKey(SecretBytes password, Salt salt, int costN, int blockSizeR, int parallelization, int length)
Parameters
passwordSecretBytesThe password material to derive from. Must not be null.
saltSaltThe salt, typically produced by Random(int).
costNintThe CPU/memory cost parameter
N.blockSizeRintThe block-size parameter
r.parallelizationintThe parallelization parameter
p.lengthintThe derived-key length, in bytes.
Returns
- byte[]
The derived key.
Remarks
Convenience overload over the span form for callers using the SecretBytes and Salt value types, which keep password material pinned and zeroed on disposal and keep salts distinct from keys and nonces in calling code.
Exceptions
- ArgumentNullException
passwordis null.- ObjectDisposedException
passwordhas been disposed.
DeriveKey(ReadOnlySpan<byte>, ReadOnlySpan<byte>, int, int, int, int)
Derives a key from a password and salt using the supplied parameters in a single call.
public static byte[] DeriveKey(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int costN, int blockSizeR, int parallelization, int length)
Parameters
passwordReadOnlySpan<byte>The password to derive from.
saltReadOnlySpan<byte>The salt.
costNintThe CPU/memory cost parameter
N.blockSizeRintThe block-size parameter
r.parallelizationintThe parallelization parameter
p.lengthintThe derived-key length, in bytes.
Returns
- byte[]
The derived key.
DeriveKey(ReadOnlySpan<byte>, ReadOnlySpan<byte>, int, int, int, Span<byte>)
Derives a key into the supplied destination buffer using the supplied parameters in a single call.
public static void DeriveKey(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int costN, int blockSizeR, int parallelization, Span<byte> destination)
Parameters
passwordReadOnlySpan<byte>The password to derive from.
saltReadOnlySpan<byte>The salt.
costNintThe CPU/memory cost parameter
N.blockSizeRintThe block-size parameter
r.parallelizationintThe parallelization parameter
p.destinationSpan<byte>The buffer to receive the derived key.
DeriveKey(ReadOnlySpan<byte>, ReadOnlySpan<byte>, Span<byte>)
Derives a key into the supplied destination buffer.
public void DeriveKey(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, Span<byte> destination)
Parameters
passwordReadOnlySpan<byte>The password to derive from.
saltReadOnlySpan<byte>The salt.
destinationSpan<byte>The buffer to receive the derived key; its length is the derived-key length.
Exceptions
- ArgumentException
destinationis empty.
GetBytes(ReadOnlySpan<byte>, ReadOnlySpan<byte>, int)
Derives a key of the requested length from the supplied password and salt.
public byte[] GetBytes(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int length)
Parameters
passwordReadOnlySpan<byte>The password to derive from.
saltReadOnlySpan<byte>The salt.
lengthintThe derived-key length, in bytes.
Returns
- byte[]
The derived key.
Exceptions
- ArgumentOutOfRangeException
lengthis less than 1.
Hash(ReadOnlySpan<byte>, int)
Derives a hash from the password and a freshly generated random 16-byte salt and returns it as a PHC encoded-hash string.
public string Hash(ReadOnlySpan<byte> password, int length)
Parameters
passwordReadOnlySpan<byte>The password to hash.
lengthintThe hash length, in bytes.
Returns
- string
The PHC encoded-hash string, including the generated salt.
Hash(ReadOnlySpan<byte>, ReadOnlySpan<byte>, int)
Derives a hash from the password and the supplied salt and returns it as a PHC encoded-hash string.
public string Hash(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int length)
Parameters
passwordReadOnlySpan<byte>The password to hash.
saltReadOnlySpan<byte>The salt to embed in the encoded string.
lengthintThe hash length, in bytes.
Returns
- string
The PHC encoded-hash string.
Exceptions
- ArgumentOutOfRangeException
lengthis less than 1.
Hash(ReadOnlySpan<byte>, ReadOnlySpan<byte>, int, int, int, int)
Derives a hash and returns it as a PHC encoded-hash string using the supplied parameters in a single call.
public static string Hash(ReadOnlySpan<byte> password, ReadOnlySpan<byte> salt, int costN, int blockSizeR, int parallelization, int length)
Parameters
passwordReadOnlySpan<byte>The password to hash.
saltReadOnlySpan<byte>The salt to embed in the encoded string.
costNintThe CPU/memory cost parameter
N.blockSizeRintThe block-size parameter
r.parallelizationintThe parallelization parameter
p.lengthintThe hash length, in bytes.
Returns
- string
The PHC encoded-hash string.
Verify(string, ReadOnlySpan<byte>)
Verifies a password against a scrypt PHC encoded-hash string.
public static bool Verify(string encoded, ReadOnlySpan<byte> password)
Parameters
encodedstringThe PHC encoded-hash string produced by Hash(ReadOnlySpan<byte>, ReadOnlySpan<byte>, int).
passwordReadOnlySpan<byte>The password to verify.
Returns
Remarks
The derivation runs on the calling thread.
Exceptions
- ArgumentNullException
encodedis null.- ArgumentOutOfRangeException
The cost parameters in
encodedfall outside the range permitted by RFC 7914 or the memory ceiling.- FormatException
encodedis not a well-formed scrypt PHC string.
Verify(string, ReadOnlySpan<byte>, int)
Verifies a password against a scrypt PHC encoded-hash string, with a bound on the threads the derivation may use.
public static bool Verify(string encoded, ReadOnlySpan<byte> password, int maxDegreeOfParallelism)
Parameters
encodedstringThe PHC encoded-hash string produced by Hash(ReadOnlySpan<byte>, ReadOnlySpan<byte>, int).
passwordReadOnlySpan<byte>The password to verify.
maxDegreeOfParallelismintThe greatest number of threads the derivation may use, the calling thread included;
-1for up to one per processor.
Returns
Remarks
The bound lets a hash with several units (p greater than 1) verify faster at the cost of memory; the
result never depends on it. The working memory stays within the 2 GiB ceiling on a single V whatever the
encoded hash asks for; see MaxDegreeOfParallelism.
Exceptions
- ArgumentNullException
encodedis null.- ArgumentOutOfRangeException
maxDegreeOfParallelismis zero or less than-1, or the cost parameters inencodedfall outside the range permitted by RFC 7914 or the memory ceiling.- FormatException
encodedis not a well-formed scrypt PHC string.
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |