/// <summary> /// Implements the PBKDF1 key derivation function, as defined in §5.1, RFC 2898 (PKCS#5). /// </summary> /// <param name="Password">Password</param> /// <param name="Iterations">Number of iterations</param> /// <param name="KeyLength">Length of generated keys.</param> /// <param name="HashFunction">Hash function.</param> public Pbkdf1(string Password, int Iterations, int KeyLength, HashFunction HashFunction) : base(Password) { if (Iterations <= 0) { throw new ArgumentException("Must be postitive.", nameof(Iterations)); } if (KeyLength <= 0) { throw new ArgumentException("Must be postitive.", nameof(Iterations)); } this.iterations = Iterations; this.salt = PfxEncoder.GetRandomBytes(8); byte[] Bin = Hashes.ComputeHash(HashFunction, Primitives.CONCAT(Encoding.UTF8.GetBytes(Password), this.salt)); while (--Iterations >= 0) { Bin = Hashes.ComputeHash(HashFunction, Bin); } if (KeyLength > Bin.Length) { throw new ArgumentException("Derived key too long.", nameof(KeyLength)); } this.key = new byte[KeyLength]; Array.Copy(Bin, 0, this.key, 0, KeyLength); }
public void Sha256_NSec() { for (var i = 0; i < Trials; i++) { Hashes.ComputeHash(_buffer, HashType.Sha256, HashSource.NSec); } }
public void Sha256_SodiumCore() { for (var i = 0; i < Trials; i++) { Hashes.ComputeHash(_buffer, HashType.Sha256, HashSource.SodiumCore); } }
public void Sha256_SystemNetFips() { for (var i = 0; i < Trials; i++) { Hashes.ComputeHash(_buffer, HashType.Sha256, HashSource.SystemNetFips); } }
private BigInteger CalcE(byte[] Data, HashFunction HashFunction) { byte[] Hash = Hashes.ComputeHash(HashFunction, Data); int c = Hash.Length; if (c != this.orderBytes) { Array.Resize <byte>(ref Hash, this.orderBytes); } Hash[this.orderBytes - 1] &= this.msbMask; return(new BigInteger(Hash)); }
/// <summary> /// Gets a shared key using the Elliptic Curve Diffie-Hellman (ECDH) algorithm. /// </summary> /// <param name="RemotePublicKey">Public key of the remote party.</param> /// <param name="HashFunction">A Hash function is applied to the derived key to generate the shared secret. /// The derived key, as a byte array of equal size as the order of the prime field, ordered by most significant byte first, /// is passed on to the hash function before being returned as the shared key.</param> /// <returns>Shared secret.</returns> public byte[] GetSharedKey(PointOnCurve RemotePublicKey, HashFunction HashFunction) { PointOnCurve P = this.ScalarMultiplication(this.d, RemotePublicKey); byte[] B = P.X.ToByteArray(); if (B.Length != this.orderBytes) { Array.Resize <byte>(ref B, this.orderBytes); } Array.Reverse(B); // Most significant byte first. return(Hashes.ComputeHash(HashFunction, B)); }
/// <summary> /// Verifies a signature of <paramref name="Data"/> made by the ECDSA algorithm. /// </summary> /// <param name="Data">Payload to sign.</param> /// <param name="PublicKey">Public Key of the entity that generated the signature.</param> /// <param name="Signature">Signature</param> /// <returns>If the signature is valid.</returns> public override bool Verify(byte[] Data, byte[] PublicKey, byte[] Signature) { return(ECDSA.Verify(Data, PublicKey, Bin => Hashes.ComputeHash(this.HashFunction, Bin), this.orderBytes, this.msbOrderMask, this, Signature)); }
/// <summary> /// Creates a signature of <paramref name="Data"/> using the ECDSA algorithm. /// </summary> /// <param name="Data">Payload to sign.</param> /// <returns>Signature.</returns> public override byte[] Sign(byte[] Data) { return(ECDSA.Sign(Data, this.PrivateKey, Bin => Hashes.ComputeHash(this.HashFunction, Bin), this.orderBytes, this.msbOrderMask, this)); }
/// <summary> /// Generates a seed, in accordance with RFC 7292, §B.2 /// </summary> /// <param name="H">Hash function</param> /// <param name="r">Iteration count</param> /// <param name="P">Formatted password.</param> /// <param name="S">Salt.</param> /// <param name="n">Number of pseudo-random bits to generate.</param> /// <param name="ID">Purpose of key: /// /// If ID=1, then the pseudorandom bits being produced are to be used /// as key material for performing encryption or decryption. /// /// 2. If ID=2, then the pseudorandom bits being produced are to be used /// as an IV (Initial Value) for encryption or decryption. /// /// 3. If ID=3, then the pseudorandom bits being produced are to be used /// as an integrity key for MACing. /// </param> internal static byte[] PRF(HashFunction H, int r, byte[] P, byte[] S, int n, byte ID) { int u, v; if ((n & 7) != 0) { throw new ArgumentException("Must be a factor of 8.", nameof(n)); } switch (H) { case HashFunction.MD5: u = 128; v = 512; break; case HashFunction.SHA1: u = 160; v = 512; break; case HashFunction.SHA256: u = 256; v = 512; break; case HashFunction.SHA384: u = 384; v = 1024; break; case HashFunction.SHA512: u = 512; v = 1024; break; default: throw new ArgumentException("Hash function not supported.", nameof(H)); } int v8 = v / 8; int u8 = u / 8; byte[] D = new byte[v8]; int i, j, c; for (i = 0; i < v8; i++) { D[i] = ID; } S = Extend(S, v); P = Extend(P, v); byte[] I = Primitives.CONCAT(S, P); int i8 = I.Length; c = (n + u - 1) / u; byte[][] As = new byte[c][]; for (i = 0; i < c; i++) { As[i] = Primitives.CONCAT(D, I); for (j = 0; j < r; j++) { As[i] = Hashes.ComputeHash(H, As[i]); } byte[] B = Extend(As[i], v); for (j = 0; j < i8; j += v8) { AddTo(I, j, B, true); } } byte[] A = Primitives.CONCAT(As); if (A.Length != n) { Array.Resize <byte>(ref A, n); } return(A); }