/// <summary> /// Get a Public Key for my Private Key /// </summary> /// <param name="secretKey"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentException"></exception> public static byte[] GetPublicKey(byte[] secretKey) { if (secretKey == null) { throw new ArgumentNullException(nameof(secretKey)); } if (secretKey.Length != PrivateKeySizeInBytes) { throw new ArgumentException($"{nameof(secretKey)} must be {PrivateKeySizeInBytes}"); } var publicKey = new byte[PrivateKeySizeInBytes]; Array.Copy(sourceArray: secretKey, destinationArray: publicKey, length: PrivateKeySizeInBytes); ClampOperation.Clamp(s: publicKey); var a = GroupElementsOperations.ScalarMultiplicationBase(a: publicKey); // To MontgomeryX var tempX = FieldElementOperations.Add(f: ref a.Z, g: ref a.Y); //Get X var tempZ = FieldElementOperations.Sub(f: ref a.Z, g: ref a.Y); tempZ = FieldElementOperations.Invert(z: ref tempZ); //Get Z // Obtains the Public Key var publicKeyFieldElement = FieldElementOperations.Multiplication(f: ref tempX, g: ref tempZ); //X*Z FieldElementOperations.ToBytes(s: publicKey, h: ref publicKeyFieldElement); return(publicKey); }
/// <summary> /// Creates a random private key /// </summary> /// <returns>32 random bytes that are clamped to a suitable private key</returns> public static byte[] GetRandomPrivateKey() { var privateKey = new byte[PrivateKeySizeInBytes]; RandomNumberGenerator.Create().GetBytes(privateKey); ClampOperation.Clamp(s: privateKey, offset: 0); return(privateKey); }