/// <summary> /// Randomly generates a secret key and a corresponding public key. /// </summary> /// <param name="secretKey">Buffer the secret key will be written to.</param> /// <param name="publicKey">Buffer the public key will be written to.</param> /// <exception cref="ArgumentException">thrown if secretKey or publicKey are not 32 bytes long</exception> public static void KeyPair(Span <byte> secretKey, Span <byte> publicKey) { if (secretKey.Length != Curve25519.ScalarLength) { throw new ArgumentException("secretKey length must be 32 bytes"); } if (publicKey.Length != Curve25519.ScalarLength) { throw new ArgumentException("publicKey length must be 32 bytes"); } using var rng = RandomNumberGenerator.Create(); #if NETSTANDARD2_1 rng.GetBytes(secretKey); #else var temp = new byte[KeyLength]; rng.GetBytes(temp); for (int i = 0; i < KeyLength; i++) { secretKey[i] = temp[i]; } Array.Clear(temp, 0, KeyLength); #endif Curve25519.ScalarMultiplicationBase(publicKey, secretKey); }
/// <summary> /// Create a new Curve25519XSalsa20Poly1305 and pre-calculate the shared secret from secret and public key. /// </summary> /// <param name="secretKey">SecretKey</param> /// <param name="publicKey">PublicKey</param> public Curve25519XSalsa20Poly1305(ReadOnlySpan <byte> secretKey, ReadOnlySpan <byte> publicKey) { ReadOnlySpan <byte> zero = stackalloc byte[16]; Span <byte> s = stackalloc byte[32]; Curve25519.ScalarMultiplication(s, secretKey, publicKey); HSalsa20.Transform(key, zero, s, Span <byte> .Empty); s.Clear(); }