<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.0" />

X448PrivateKeyParameters

using Org.BouncyCastle.Math.EC.Rfc7748; using Org.BouncyCastle.Security; using Org.BouncyCastle.Utilities; using Org.BouncyCastle.Utilities.IO; using System; using System.IO; namespace Org.BouncyCastle.Crypto.Parameters { public sealed class X448PrivateKeyParameters : AsymmetricKeyParameter { public static readonly int KeySize = 56; public static readonly int SecretSize = 56; private readonly byte[] data = new byte[KeySize]; internal ReadOnlySpan<byte> DataSpan => data; internal ReadOnlyMemory<byte> DataMemory => data; public X448PrivateKeyParameters(SecureRandom random) : base(true) { X448.GeneratePrivateKey(random, data); } public X448PrivateKeyParameters(byte[] buf) : this(Validate(buf), 0) { } public X448PrivateKeyParameters(byte[] buf, int off) : base(true) { Array.Copy(buf, off, data, 0, KeySize); } public X448PrivateKeyParameters(ReadOnlySpan<byte> buf) : base(true) { if (buf.Length != KeySize) throw new ArgumentException("must have length " + KeySize.ToString(), "buf"); buf.CopyTo(data); } public X448PrivateKeyParameters(Stream input) : base(true) { if (KeySize != Streams.ReadFully(input, data)) throw new EndOfStreamException("EOF encountered in middle of X448 private key"); } public void Encode(byte[] buf, int off) { Array.Copy(data, 0, buf, off, KeySize); } public void Encode(Span<byte> buf) { data.CopyTo(buf); } public byte[] GetEncoded() { return Arrays.Clone(data); } public unsafe X448PublicKeyParameters GeneratePublicKey() { Span<byte> span = new Span<byte>(stackalloc byte[56], 56); X448.GeneratePublicKey(data, span); return new X448PublicKeyParameters(span); } public void GenerateSecret(X448PublicKeyParameters publicKey, byte[] buf, int off) { GenerateSecret(publicKey, buf.AsSpan(off)); } public unsafe void GenerateSecret(X448PublicKeyParameters publicKey, Span<byte> buf) { Span<byte> span = new Span<byte>(stackalloc byte[56], 56); publicKey.Encode(span); if (!X448.CalculateAgreement(data, span, buf)) throw new InvalidOperationException("X448 agreement failed"); } private static byte[] Validate(byte[] buf) { if (buf.Length != KeySize) throw new ArgumentException("must have length " + KeySize.ToString(), "buf"); return buf; } } }