/// <summary> /// Determines whether the specified modulus is valid. /// </summary> /// <param name="N">The modulus to validate.</param> /// <returns>True if the specified modulus is valid, otherwise /// false.</returns> public static bool IsValidModulus(Mpi N) { foreach (string s in moduli) { BigInteger a = BigInteger.Parse(s, NumberStyles.HexNumber); if (BigInteger.Compare(a, N.Value) == 0) { return(true); } } // Fixme: Perform proper validation? return(false); }
/// <summary> /// Determines whether the specified generator is valid. /// </summary> /// <param name="g">The generator to validate.</param> /// <returns>True if the specified generator is valid, otherwise /// false.</returns> public static bool IsValidGenerator(Mpi g) { return(BigInteger.Compare(new BigInteger(2), g.Value) == 0); }
/// <summary> /// Computes the client evidence from the given parameters. /// </summary> /// <param name="safePrimeModulus">The safe prime modulus sent by the /// server.</param> /// <param name="generator">The generator sent by the server.</param> /// <param name="username">The username to authenticate with.</param> /// <param name="salt">The client's password salt.</param> /// <param name="clientPublicKey">The client's ephemeral public key.</param> /// <param name="serverPublicKey">The server's ephemeral public key.</param> /// <param name="sharedKey">The shared context key.</param> /// <param name="authId">The authorization identity.</param> /// <param name="options">The raw options string as received from the /// server.</param> /// <param name="hashAlgorithm">The message digest algorithm to use for /// calculating the client proof.</param> /// <returns>The client proof as an array of bytes.</returns> public static byte[] ComputeClientProof(Mpi safePrimeModulus, Mpi generator, string username, byte[] salt, Mpi clientPublicKey, Mpi serverPublicKey, Mpi sharedKey, string authId, string options, HashAlgorithm hashAlgorithm) { byte[] N = safePrimeModulus.ToBytes(), g = generator.ToBytes(), U = Encoding.UTF8.GetBytes(username), s = salt, A = clientPublicKey.ToBytes(), B = serverPublicKey.ToBytes(), K = sharedKey.ToBytes(), I = Encoding.UTF8.GetBytes(authId), L = Encoding.UTF8.GetBytes(options); HashAlgorithm H = hashAlgorithm; // The proof is calculated as follows: // // H( bytes(H( bytes(N) )) ^ bytes( H( bytes(g) )) // | bytes(H( bytes(U) )) // | bytes(s) // | bytes(A) // | bytes(B) // | bytes(K) // | bytes(H( bytes(I) )) // | bytes(H( bytes(L) )) // ) byte[] seq = new ByteBuilder() .Append(Xor(H.ComputeHash(N), H.ComputeHash(g))) .Append(H.ComputeHash(U)) .Append(s) .Append(A) .Append(B) .Append(K) .Append(H.ComputeHash(I)) .Append(H.ComputeHash(L)) .ToArray(); return(H.ComputeHash(seq)); }