From ea79c0d81cffac76670d0a46ff095320eb40e51f Mon Sep 17 00:00:00 2001 From: Konradsop Date: Tue, 5 May 2026 22:07:10 +0200 Subject: [PATCH] docs: add XML documentation for modern-curve parameters Document the public/private/key-generation parameter classes for the RFC 8032 EdDSA and RFC 7748 X-DH curves: Ed25519, Ed448, X25519, X448. Adds class-level summaries citing the relevant RFC and per-method , , , and tags for the public API (constructors, encoders, key derivation, sign/verify, agreement). No behavioural changes. --- .../Ed25519KeyGenerationParameters.cs | 7 +++ .../parameters/Ed25519PrivateKeyParameters.cs | 40 ++++++++++++++ .../parameters/Ed25519PublicKeyParameters.cs | 54 +++++++++++++++++++ .../Ed448KeyGenerationParameters.cs | 7 +++ .../parameters/Ed448PrivateKeyParameters.cs | 36 +++++++++++++ .../parameters/Ed448PublicKeyParameters.cs | 41 ++++++++++++++ .../X25519KeyGenerationParameters.cs | 7 +++ .../parameters/X25519PrivateKeyParameters.cs | 34 ++++++++++++ .../parameters/X25519PublicKeyParameters.cs | 22 ++++++++ .../parameters/X448KeyGenerationParameters.cs | 7 +++ .../parameters/X448PrivateKeyParameters.cs | 34 ++++++++++++ .../parameters/X448PublicKeyParameters.cs | 22 ++++++++ 12 files changed, 311 insertions(+) diff --git a/crypto/src/crypto/parameters/Ed25519KeyGenerationParameters.cs b/crypto/src/crypto/parameters/Ed25519KeyGenerationParameters.cs index daf3856c3b..243491621d 100644 --- a/crypto/src/crypto/parameters/Ed25519KeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/Ed25519KeyGenerationParameters.cs @@ -4,9 +4,16 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Key generation parameters for Ed25519 (RFC 8032). Carries the used for + /// seed generation; the strength is fixed at 256 bits. + /// public class Ed25519KeyGenerationParameters : KeyGenerationParameters { + /// + /// Construct using as the entropy source for the 32-byte seed. + /// public Ed25519KeyGenerationParameters(SecureRandom random) : base(random, 256) { diff --git a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs index 1774daccb1..e19cc04435 100644 --- a/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/Ed25519PrivateKeyParameters.cs @@ -8,27 +8,40 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Ed25519 private key (RFC 8032). Holds the 32-byte secret seed; the corresponding public key is + /// derived lazily on first use and cached. + /// public sealed class Ed25519PrivateKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an Ed25519 private-key seed (32). public static readonly int KeySize = Ed25519.SecretKeySize; + + /// Length in bytes of an Ed25519 signature (64). public static readonly int SignatureSize = Ed25519.SignatureSize; private readonly byte[] data = new byte[KeySize]; private Ed25519PublicKeyParameters cachedPublicKey; + /// Generate a fresh random Ed25519 private key using . public Ed25519PrivateKeyParameters(SecureRandom random) : base(true) { Ed25519.GeneratePrivateKey(random, data); } + /// Construct from a 32-byte seed buffer. + /// If length differs from + /// . public Ed25519PrivateKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// Construct from at ; reads + /// bytes. public Ed25519PrivateKeyParameters(byte[] buf, int off) : base(true) { @@ -36,6 +49,9 @@ public Ed25519PrivateKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Construct from a span carrying the 32-byte seed. + /// If length differs from + /// . public Ed25519PrivateKeyParameters(ReadOnlySpan buf) : base(true) { @@ -46,6 +62,9 @@ public Ed25519PrivateKeyParameters(ReadOnlySpan buf) } #endif + /// Read the 32-byte seed from . + /// If the stream ends before + /// bytes have been read. public Ed25519PrivateKeyParameters(Stream input) : base(true) { @@ -53,18 +72,21 @@ public Ed25519PrivateKeyParameters(Stream input) throw new EndOfStreamException("EOF encountered in middle of Ed25519 private key"); } + /// Write the 32-byte seed into at . public void Encode(byte[] buf, int off) { Array.Copy(data, 0, buf, off, KeySize); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 32-byte seed into the supplied span. public void Encode(Span buf) { data.CopyTo(buf); } #endif + /// Return a fresh copy of the 32-byte seed. public byte[] GetEncoded() { return Arrays.Clone(data); @@ -76,9 +98,23 @@ public byte[] GetEncoded() internal ReadOnlyMemory DataMemory => data; #endif + /// + /// Derive (and cache) the public key corresponding to this private key. + /// public Ed25519PublicKeyParameters GeneratePublicKey() => Objects.EnsureSingletonInitialized(ref cachedPublicKey, data, CreatePublicKey); + /// + /// Compute an Ed25519 signature. Selects between pure Ed25519, Ed25519ctx and Ed25519ph based on + /// . The pure variant rejects a non-null context; the context + /// and prehash variants require a context up to 255 bytes long, and Ed25519ph additionally + /// requires to equal . + /// + /// If is required but + /// null. + /// If exceeds 255 bytes, + /// is supplied for pure Ed25519, is wrong for Ed25519ph, or + /// is unrecognised. public void Sign(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, byte[] sig, int sigOff) { @@ -127,6 +163,10 @@ public void Sign(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// + /// Span-based overload of + /// . + /// public void Sign(Ed25519.Algorithm algorithm, byte[] ctx, ReadOnlySpan msg, Span sig) { Ed25519PublicKeyParameters publicKey = GeneratePublicKey(); diff --git a/crypto/src/crypto/parameters/Ed25519PublicKeyParameters.cs b/crypto/src/crypto/parameters/Ed25519PublicKeyParameters.cs index fe4e7d4e6a..389fcc221a 100644 --- a/crypto/src/crypto/parameters/Ed25519PublicKeyParameters.cs +++ b/crypto/src/crypto/parameters/Ed25519PublicKeyParameters.cs @@ -6,18 +6,35 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Ed25519 public key (RFC 8032). Wraps a decoded curve point obtained from a 32-byte encoded + /// representation; the point is validated at construction so that subsequent verifications work + /// against a known-good key. + /// public sealed class Ed25519PublicKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an Ed25519 public key encoding (32). public static readonly int KeySize = Ed25519.PublicKeySize; private readonly Ed25519.PublicPoint m_publicPoint; + /// + /// Construct from a 32-byte buffer holding the encoded public point. + /// + /// If length differs from + /// , or the encoding does not decode to a valid curve point. public Ed25519PublicKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// + /// Construct from starting at ; reads + /// bytes. + /// + /// If the encoded bytes do not decode to a valid curve + /// point. public Ed25519PublicKeyParameters(byte[] buf, int off) : base(false) { @@ -25,6 +42,11 @@ public Ed25519PublicKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// + /// Construct from a span holding the encoded public point. + /// + /// If length differs from + /// , or the encoding does not decode to a valid curve point. public Ed25519PublicKeyParameters(ReadOnlySpan buf) : base(false) { @@ -35,6 +57,13 @@ public Ed25519PublicKeyParameters(ReadOnlySpan buf) } #endif + /// + /// Read encoded bytes from and decode them. + /// + /// If the stream ends before + /// bytes have been read. + /// If the encoded bytes do not decode to a valid curve + /// point. public Ed25519PublicKeyParameters(Stream input) : base(false) { @@ -54,24 +83,33 @@ public Ed25519PublicKeyParameters(Stream input) #endif } + /// + /// Construct from an already-decoded curve point. No further validation is performed. + /// + /// If is null. public Ed25519PublicKeyParameters(Ed25519.PublicPoint publicPoint) : base(false) { m_publicPoint = publicPoint ?? throw new ArgumentNullException(nameof(publicPoint)); } + /// + /// Write the 32-byte encoded public point into at . + /// public void Encode(byte[] buf, int off) { Ed25519.EncodePublicPoint(m_publicPoint, buf, off); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 32-byte encoded public point into the supplied span. public void Encode(Span buf) { Ed25519.EncodePublicPoint(m_publicPoint, buf); } #endif + /// Return a fresh copy of the 32-byte encoded public point. public byte[] GetEncoded() { byte[] data = new byte[KeySize]; @@ -79,6 +117,18 @@ public byte[] GetEncoded() return data; } + /// + /// Verify an Ed25519 signature. Selects between pure Ed25519, Ed25519ctx and Ed25519ph based on + /// . The pure variant rejects a non-null context; the context + /// and prehash variants require a context up to 255 bytes long, and Ed25519ph additionally + /// requires to equal . + /// + /// true if the signature is valid for this key; otherwise false. + /// If is required but + /// null. + /// If exceeds 255 bytes, + /// is supplied for pure Ed25519, is wrong for Ed25519ph, or + /// is unrecognised. public bool Verify(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, byte[] sig, int sigOff) { @@ -119,6 +169,10 @@ public bool Verify(Ed25519.Algorithm algorithm, byte[] ctx, byte[] msg, int msgO } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// + /// Span-based overload of + /// . + /// public bool Verify(Ed25519.Algorithm algorithm, byte[] ctx, ReadOnlySpan msg, ReadOnlySpan sig) { switch (algorithm) diff --git a/crypto/src/crypto/parameters/Ed448KeyGenerationParameters.cs b/crypto/src/crypto/parameters/Ed448KeyGenerationParameters.cs index 830d15a044..c522b2d685 100644 --- a/crypto/src/crypto/parameters/Ed448KeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/Ed448KeyGenerationParameters.cs @@ -4,9 +4,16 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Key generation parameters for Ed448 (RFC 8032). Carries the used for + /// seed generation; the strength is fixed at 448 bits. + /// public class Ed448KeyGenerationParameters : KeyGenerationParameters { + /// + /// Construct using as the entropy source for the 57-byte seed. + /// public Ed448KeyGenerationParameters(SecureRandom random) : base(random, 448) { diff --git a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs index f2c234cd07..149922e428 100644 --- a/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/Ed448PrivateKeyParameters.cs @@ -8,27 +8,40 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Ed448 private key (RFC 8032). Holds the 57-byte secret seed; the corresponding public key is + /// derived lazily on first use and cached. + /// public sealed class Ed448PrivateKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an Ed448 private-key seed (57). public static readonly int KeySize = Ed448.SecretKeySize; + + /// Length in bytes of an Ed448 signature (114). public static readonly int SignatureSize = Ed448.SignatureSize; private readonly byte[] data = new byte[KeySize]; private Ed448PublicKeyParameters cachedPublicKey; + /// Generate a fresh random Ed448 private key using . public Ed448PrivateKeyParameters(SecureRandom random) : base(true) { Ed448.GeneratePrivateKey(random, data); } + /// Construct from a 57-byte seed buffer. + /// If length differs from + /// . public Ed448PrivateKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// Construct from at ; reads + /// bytes. public Ed448PrivateKeyParameters(byte[] buf, int off) : base(true) { @@ -36,6 +49,9 @@ public Ed448PrivateKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Construct from a span carrying the 57-byte seed. + /// If length differs from + /// . public Ed448PrivateKeyParameters(ReadOnlySpan buf) : base(true) { @@ -46,6 +62,9 @@ public Ed448PrivateKeyParameters(ReadOnlySpan buf) } #endif + /// Read the 57-byte seed from . + /// If the stream ends before + /// bytes have been read. public Ed448PrivateKeyParameters(Stream input) : base(true) { @@ -53,18 +72,21 @@ public Ed448PrivateKeyParameters(Stream input) throw new EndOfStreamException("EOF encountered in middle of Ed448 private key"); } + /// Write the 57-byte seed into at . public void Encode(byte[] buf, int off) { Array.Copy(data, 0, buf, off, KeySize); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 57-byte seed into the supplied span. public void Encode(Span buf) { data.CopyTo(buf); } #endif + /// Return a fresh copy of the 57-byte seed. public byte[] GetEncoded() { return Arrays.Clone(data); @@ -76,9 +98,19 @@ public byte[] GetEncoded() internal ReadOnlyMemory DataMemory => data; #endif + /// Derive (and cache) the public key corresponding to this private key. public Ed448PublicKeyParameters GeneratePublicKey() => Objects.EnsureSingletonInitialized(ref cachedPublicKey, data, CreatePublicKey); + /// + /// Compute an Ed448 signature. Both Ed448 and Ed448ph require a non-null context up to + /// 255 bytes; Ed448ph additionally requires to equal + /// . + /// + /// If is null. + /// If exceeds 255 bytes, + /// is wrong for Ed448ph, or is + /// unrecognised. public void Sign(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, byte[] sig, int sigOff) { @@ -119,6 +151,10 @@ public void Sign(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// + /// Span-based overload of + /// . + /// public void Sign(Ed448.Algorithm algorithm, byte[] ctx, ReadOnlySpan msg, Span sig) { Ed448PublicKeyParameters publicKey = GeneratePublicKey(); diff --git a/crypto/src/crypto/parameters/Ed448PublicKeyParameters.cs b/crypto/src/crypto/parameters/Ed448PublicKeyParameters.cs index ab8f84c5b9..48b8aeb152 100644 --- a/crypto/src/crypto/parameters/Ed448PublicKeyParameters.cs +++ b/crypto/src/crypto/parameters/Ed448PublicKeyParameters.cs @@ -6,18 +6,30 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Ed448 public key (RFC 8032). Wraps a decoded curve point obtained from a 57-byte encoded + /// representation; the point is validated at construction. + /// public sealed class Ed448PublicKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an Ed448 public key encoding (57). public static readonly int KeySize = Ed448.PublicKeySize; private readonly Ed448.PublicPoint m_publicPoint; + /// Construct from a 57-byte buffer holding the encoded public point. + /// If length differs from + /// , or the encoding does not decode to a valid curve point. public Ed448PublicKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// Construct from at ; reads + /// bytes. + /// If the encoded bytes do not decode to a valid curve + /// point. public Ed448PublicKeyParameters(byte[] buf, int off) : base(false) { @@ -25,6 +37,9 @@ public Ed448PublicKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Construct from a span holding the encoded public point. + /// If length differs from + /// , or the encoding does not decode to a valid curve point. public Ed448PublicKeyParameters(ReadOnlySpan buf) : base(false) { @@ -35,6 +50,11 @@ public Ed448PublicKeyParameters(ReadOnlySpan buf) } #endif + /// Read encoded bytes from and decode them. + /// If the stream ends before + /// bytes have been read. + /// If the encoded bytes do not decode to a valid curve + /// point. public Ed448PublicKeyParameters(Stream input) : base(false) { @@ -54,24 +74,31 @@ public Ed448PublicKeyParameters(Stream input) #endif } + /// Construct from an already-decoded curve point. No further validation is performed. + /// If is null. public Ed448PublicKeyParameters(Ed448.PublicPoint publicPoint) : base(false) { m_publicPoint = publicPoint ?? throw new ArgumentNullException(nameof(publicPoint)); } + /// + /// Write the 57-byte encoded public point into at . + /// public void Encode(byte[] buf, int off) { Ed448.EncodePublicPoint(m_publicPoint, buf, off); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 57-byte encoded public point into the supplied span. public void Encode(Span buf) { Ed448.EncodePublicPoint(m_publicPoint, buf); } #endif + /// Return a fresh copy of the 57-byte encoded public point. public byte[] GetEncoded() { byte[] data = new byte[KeySize]; @@ -79,6 +106,16 @@ public byte[] GetEncoded() return data; } + /// + /// Verify an Ed448 signature. Both Ed448 and Ed448ph require a non-null context up to + /// 255 bytes; Ed448ph additionally requires to equal + /// . + /// + /// true if the signature is valid for this key; otherwise false. + /// If is null. + /// If exceeds 255 bytes, + /// is wrong for Ed448ph, or is + /// unrecognised. public bool Verify(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff, int msgLen, byte[] sig, int sigOff) { @@ -112,6 +149,10 @@ public bool Verify(Ed448.Algorithm algorithm, byte[] ctx, byte[] msg, int msgOff } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// + /// Span-based overload of + /// . + /// public bool Verify(Ed448.Algorithm algorithm, byte[] ctx, ReadOnlySpan msg, ReadOnlySpan sig) { switch (algorithm) diff --git a/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs b/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs index d0bcffa94d..e02c0290d0 100644 --- a/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/X25519KeyGenerationParameters.cs @@ -4,9 +4,16 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Key generation parameters for X25519 (RFC 7748). Carries the used for + /// scalar generation; the strength is fixed at 255 bits. + /// public class X25519KeyGenerationParameters : KeyGenerationParameters { + /// + /// Construct using as the entropy source for the 32-byte scalar. + /// public X25519KeyGenerationParameters(SecureRandom random) : base(random, 255) { diff --git a/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs b/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs index ca989a8d3e..263189cd37 100644 --- a/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/X25519PrivateKeyParameters.cs @@ -8,25 +8,38 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// X25519 private key (RFC 7748). Holds the 32-byte clamped scalar used in Curve25519 + /// Diffie-Hellman. + /// public sealed class X25519PrivateKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an X25519 private-key scalar (32). public static readonly int KeySize = X25519.ScalarSize; + + /// Length in bytes of the shared secret produced by an X25519 agreement (32). public static readonly int SecretSize = X25519.PointSize; private readonly byte[] data = new byte[KeySize]; + /// Generate a fresh random X25519 private key using . public X25519PrivateKeyParameters(SecureRandom random) : base(true) { X25519.GeneratePrivateKey(random, data); } + /// Construct from a 32-byte scalar buffer. + /// If length differs from + /// . public X25519PrivateKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// Construct from at ; reads + /// bytes. public X25519PrivateKeyParameters(byte[] buf, int off) : base(true) { @@ -34,6 +47,9 @@ public X25519PrivateKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Construct from a span carrying the 32-byte scalar. + /// If length differs from + /// . public X25519PrivateKeyParameters(ReadOnlySpan buf) : base(true) { @@ -44,6 +60,9 @@ public X25519PrivateKeyParameters(ReadOnlySpan buf) } #endif + /// Read the 32-byte scalar from . + /// If the stream ends before + /// bytes have been read. public X25519PrivateKeyParameters(Stream input) : base(true) { @@ -51,18 +70,21 @@ public X25519PrivateKeyParameters(Stream input) throw new EndOfStreamException("EOF encountered in middle of X25519 private key"); } + /// Write the 32-byte scalar into at . public void Encode(byte[] buf, int off) { Array.Copy(data, 0, buf, off, KeySize); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 32-byte scalar into the supplied span. public void Encode(Span buf) { data.CopyTo(buf); } #endif + /// Return a fresh copy of the 32-byte scalar. public byte[] GetEncoded() { return Arrays.Clone(data); @@ -74,6 +96,7 @@ public byte[] GetEncoded() internal ReadOnlyMemory DataMemory => data; #endif + /// Compute the public key (u-coordinate) corresponding to this scalar. public X25519PublicKeyParameters GeneratePublicKey() { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -87,6 +110,13 @@ public X25519PublicKeyParameters GeneratePublicKey() #endif } + /// + /// Perform an X25519 Diffie-Hellman agreement against and write the + /// resulting -byte shared secret into starting at + /// . + /// + /// If the agreement produces an all-zero secret + /// (degenerate peer key). public void GenerateSecret(X25519PublicKeyParameters publicKey, byte[] buf, int off) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -100,6 +130,10 @@ public void GenerateSecret(X25519PublicKeyParameters publicKey, byte[] buf, int } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// + /// Span-based overload of . + /// + /// If the agreement produces an all-zero secret. public void GenerateSecret(X25519PublicKeyParameters publicKey, Span buf) { Span encoded = stackalloc byte[X25519.PointSize]; diff --git a/crypto/src/crypto/parameters/X25519PublicKeyParameters.cs b/crypto/src/crypto/parameters/X25519PublicKeyParameters.cs index c68be30602..aabcbdd863 100644 --- a/crypto/src/crypto/parameters/X25519PublicKeyParameters.cs +++ b/crypto/src/crypto/parameters/X25519PublicKeyParameters.cs @@ -7,18 +7,29 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// X25519 public key (RFC 7748). Holds the 32-byte u-coordinate of the peer's curve point. The + /// encoding is stored verbatim; validation of the point is performed during scalar multiplication + /// in the agreement primitive. + /// public sealed class X25519PublicKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an X25519 public key encoding (32). public static readonly int KeySize = X25519.PointSize; private readonly byte[] data = new byte[KeySize]; + /// Construct from a 32-byte buffer holding the encoded u-coordinate. + /// If length differs from + /// . public X25519PublicKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// Construct from at ; reads + /// bytes. public X25519PublicKeyParameters(byte[] buf, int off) : base(false) { @@ -26,6 +37,9 @@ public X25519PublicKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Construct from a span holding the encoded u-coordinate. + /// If length differs from + /// . public X25519PublicKeyParameters(ReadOnlySpan buf) : base(false) { @@ -36,6 +50,9 @@ public X25519PublicKeyParameters(ReadOnlySpan buf) } #endif + /// Read the 32-byte encoded u-coordinate from . + /// If the stream ends before + /// bytes have been read. public X25519PublicKeyParameters(Stream input) : base(false) { @@ -43,18 +60,23 @@ public X25519PublicKeyParameters(Stream input) throw new EndOfStreamException("EOF encountered in middle of X25519 public key"); } + /// + /// Write the 32-byte encoded u-coordinate into at . + /// public void Encode(byte[] buf, int off) { Array.Copy(data, 0, buf, off, KeySize); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 32-byte encoded u-coordinate into the supplied span. public void Encode(Span buf) { data.CopyTo(buf); } #endif + /// Return a fresh copy of the 32-byte encoded u-coordinate. public byte[] GetEncoded() { return Arrays.Clone(data); diff --git a/crypto/src/crypto/parameters/X448KeyGenerationParameters.cs b/crypto/src/crypto/parameters/X448KeyGenerationParameters.cs index a7cb55844d..e55ec0e6f5 100644 --- a/crypto/src/crypto/parameters/X448KeyGenerationParameters.cs +++ b/crypto/src/crypto/parameters/X448KeyGenerationParameters.cs @@ -4,9 +4,16 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// Key generation parameters for X448 (RFC 7748). Carries the used for + /// scalar generation; the strength is fixed at 448 bits. + /// public class X448KeyGenerationParameters : KeyGenerationParameters { + /// + /// Construct using as the entropy source for the 56-byte scalar. + /// public X448KeyGenerationParameters(SecureRandom random) : base(random, 448) { diff --git a/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs b/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs index 7128858753..7b671d0799 100644 --- a/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs +++ b/crypto/src/crypto/parameters/X448PrivateKeyParameters.cs @@ -8,25 +8,38 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// X448 private key (RFC 7748). Holds the 56-byte clamped scalar used in Curve448 + /// Diffie-Hellman. + /// public sealed class X448PrivateKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an X448 private-key scalar (56). public static readonly int KeySize = X448.ScalarSize; + + /// Length in bytes of the shared secret produced by an X448 agreement (56). public static readonly int SecretSize = X448.PointSize; private readonly byte[] data = new byte[KeySize]; + /// Generate a fresh random X448 private key using . public X448PrivateKeyParameters(SecureRandom random) : base(true) { X448.GeneratePrivateKey(random, data); } + /// Construct from a 56-byte scalar buffer. + /// If length differs from + /// . public X448PrivateKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// Construct from at ; reads + /// bytes. public X448PrivateKeyParameters(byte[] buf, int off) : base(true) { @@ -34,6 +47,9 @@ public X448PrivateKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Construct from a span carrying the 56-byte scalar. + /// If length differs from + /// . public X448PrivateKeyParameters(ReadOnlySpan buf) : base(true) { @@ -44,6 +60,9 @@ public X448PrivateKeyParameters(ReadOnlySpan buf) } #endif + /// Read the 56-byte scalar from . + /// If the stream ends before + /// bytes have been read. public X448PrivateKeyParameters(Stream input) : base(true) { @@ -51,18 +70,21 @@ public X448PrivateKeyParameters(Stream input) throw new EndOfStreamException("EOF encountered in middle of X448 private key"); } + /// Write the 56-byte scalar into at . public void Encode(byte[] buf, int off) { Array.Copy(data, 0, buf, off, KeySize); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 56-byte scalar into the supplied span. public void Encode(Span buf) { data.CopyTo(buf); } #endif + /// Return a fresh copy of the 56-byte scalar. public byte[] GetEncoded() { return Arrays.Clone(data); @@ -74,6 +96,7 @@ public byte[] GetEncoded() internal ReadOnlyMemory DataMemory => data; #endif + /// Compute the public key (u-coordinate) corresponding to this scalar. public X448PublicKeyParameters GeneratePublicKey() { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -87,6 +110,13 @@ public X448PublicKeyParameters GeneratePublicKey() #endif } + /// + /// Perform an X448 Diffie-Hellman agreement against and write the + /// resulting -byte shared secret into starting at + /// . + /// + /// If the agreement produces an all-zero secret + /// (degenerate peer key). public void GenerateSecret(X448PublicKeyParameters publicKey, byte[] buf, int off) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -100,6 +130,10 @@ public void GenerateSecret(X448PublicKeyParameters publicKey, byte[] buf, int of } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// + /// Span-based overload of . + /// + /// If the agreement produces an all-zero secret. public void GenerateSecret(X448PublicKeyParameters publicKey, Span buf) { Span encoded = stackalloc byte[X448.PointSize]; diff --git a/crypto/src/crypto/parameters/X448PublicKeyParameters.cs b/crypto/src/crypto/parameters/X448PublicKeyParameters.cs index e66056f9c6..1f57f6827c 100644 --- a/crypto/src/crypto/parameters/X448PublicKeyParameters.cs +++ b/crypto/src/crypto/parameters/X448PublicKeyParameters.cs @@ -7,18 +7,29 @@ namespace Org.BouncyCastle.Crypto.Parameters { + /// + /// X448 public key (RFC 7748). Holds the 56-byte u-coordinate of the peer's curve point. The + /// encoding is stored verbatim; validation of the point is performed during scalar multiplication + /// in the agreement primitive. + /// public sealed class X448PublicKeyParameters : AsymmetricKeyParameter { + /// Length in bytes of an X448 public key encoding (56). public static readonly int KeySize = X448.PointSize; private readonly byte[] data = new byte[KeySize]; + /// Construct from a 56-byte buffer holding the encoded u-coordinate. + /// If length differs from + /// . public X448PublicKeyParameters(byte[] buf) : this(Validate(buf), 0) { } + /// Construct from at ; reads + /// bytes. public X448PublicKeyParameters(byte[] buf, int off) : base(false) { @@ -26,6 +37,9 @@ public X448PublicKeyParameters(byte[] buf, int off) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Construct from a span holding the encoded u-coordinate. + /// If length differs from + /// . public X448PublicKeyParameters(ReadOnlySpan buf) : base(false) { @@ -36,6 +50,9 @@ public X448PublicKeyParameters(ReadOnlySpan buf) } #endif + /// Read the 56-byte encoded u-coordinate from . + /// If the stream ends before + /// bytes have been read. public X448PublicKeyParameters(Stream input) : base(false) { @@ -43,18 +60,23 @@ public X448PublicKeyParameters(Stream input) throw new EndOfStreamException("EOF encountered in middle of X448 public key"); } + /// + /// Write the 56-byte encoded u-coordinate into at . + /// public void Encode(byte[] buf, int off) { Array.Copy(data, 0, buf, off, KeySize); } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Write the 56-byte encoded u-coordinate into the supplied span. public void Encode(Span buf) { data.CopyTo(buf); } #endif + /// Return a fresh copy of the 56-byte encoded u-coordinate. public byte[] GetEncoded() { return Arrays.Clone(data);