namespace System.Security.Cryptography
{
///
/// HashMetadata represents the information stored in the encoded Argon2 format
///
public class HashMetadata
{
///
/// The type of Argon2 hashing algorithm to use
/// Argon2d - The memory access is dependent upon the hash value (vulnerable to side-channel attacks)
/// Argon2i - The memory access is independent upon the hash value (safe from side-channel atacks)
///
public Argon2Type ArgonType { get; set; }
///
/// How much memory to use while hashing in kibibytes (KiB)
///
public uint MemoryCost { get; set; }
///
/// How many iterations of the Argon2 hash to perform
///
public uint TimeCost { get; set; }
///
/// How many threads to use while hashing
///
public uint Parallelism { get; set; }
///
/// The raw bytes of the salt
///
public byte[] Salt { get; set; }
///
/// The raw bytes of the hash
///
public byte[] Hash { get; set; }
///
/// A base-64 encoded string of the salt, minus the padding (=) characters
///
public string GetBase64Salt() => Convert.ToBase64String(Salt).Replace("=", "");
///
/// A base-64 encoded string of the hash, minus the padding (=) characters
///
public string GetBase64Hash() => Convert.ToBase64String(Hash).Replace("=", "");
///
/// Converts HashMetadata back into the original Argon2 formatted string.
///
public override string ToString() =>
$"$argon2{(ArgonType == Argon2Type.Argon2i ? "i" : "d")}$v=19$m={MemoryCost},t={TimeCost},p={Parallelism}${GetBase64Salt()}${GetBase64Hash()}";
}
}