Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions crypto/src/crypto/agreement/X25519Agreement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,39 @@

namespace Org.BouncyCastle.Crypto.Agreement
{
/// <summary>
/// X25519 (RFC 7748) Diffie-Hellman raw agreement. Init takes the local
/// <see cref="X25519PrivateKeyParameters"/>; <see cref="CalculateAgreement(ICipherParameters, byte[], int)"/>
/// writes the 32-byte shared secret derived against the peer's
/// <see cref="X25519PublicKeyParameters"/>.
/// </summary>
public sealed class X25519Agreement
: IRawAgreement
{
private X25519PrivateKeyParameters m_privateKey;

/// <summary>Capture the local private key used for subsequent agreements.</summary>
/// <exception cref="InvalidCastException">If <paramref name="parameters"/> is not an
/// <see cref="X25519PrivateKeyParameters"/>.</exception>
public void Init(ICipherParameters parameters)
{
m_privateKey = (X25519PrivateKeyParameters)parameters;
}

/// <summary>Length in bytes of the shared secret produced by the agreement (32).</summary>
public int AgreementSize
{
get { return X25519PrivateKeyParameters.SecretSize; }
}

/// <summary>
/// Perform the agreement against <paramref name="publicKey"/> and write the shared secret into
/// <paramref name="buf"/> starting at <paramref name="off"/>.
/// </summary>
/// <exception cref="InvalidCastException">If <paramref name="publicKey"/> is not an
/// <see cref="X25519PublicKeyParameters"/>.</exception>
/// <exception cref="InvalidOperationException">If the agreement produces an all-zero secret
/// (degenerate peer key).</exception>
public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
Expand All @@ -29,6 +47,7 @@ public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off)
}

#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <summary>Span-based overload of <see cref="CalculateAgreement(ICipherParameters, byte[], int)"/>.</summary>
public void CalculateAgreement(ICipherParameters publicKey, Span<byte> buf)
{
m_privateKey.GenerateSecret((X25519PublicKeyParameters)publicKey, buf);
Expand Down
19 changes: 19 additions & 0 deletions crypto/src/crypto/agreement/X448Agreement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,39 @@

namespace Org.BouncyCastle.Crypto.Agreement
{
/// <summary>
/// X448 (RFC 7748) Diffie-Hellman raw agreement. Init takes the local
/// <see cref="X448PrivateKeyParameters"/>; <see cref="CalculateAgreement(ICipherParameters, byte[], int)"/>
/// writes the 56-byte shared secret derived against the peer's
/// <see cref="X448PublicKeyParameters"/>.
/// </summary>
public sealed class X448Agreement
: IRawAgreement
{
private X448PrivateKeyParameters m_privateKey;

/// <summary>Capture the local private key used for subsequent agreements.</summary>
/// <exception cref="InvalidCastException">If <paramref name="parameters"/> is not an
/// <see cref="X448PrivateKeyParameters"/>.</exception>
public void Init(ICipherParameters parameters)
{
m_privateKey = (X448PrivateKeyParameters)parameters;
}

/// <summary>Length in bytes of the shared secret produced by the agreement (56).</summary>
public int AgreementSize
{
get { return X448PrivateKeyParameters.SecretSize; }
}

/// <summary>
/// Perform the agreement against <paramref name="publicKey"/> and write the shared secret into
/// <paramref name="buf"/> starting at <paramref name="off"/>.
/// </summary>
/// <exception cref="InvalidCastException">If <paramref name="publicKey"/> is not an
/// <see cref="X448PublicKeyParameters"/>.</exception>
/// <exception cref="InvalidOperationException">If the agreement produces an all-zero secret
/// (degenerate peer key).</exception>
public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
Expand All @@ -29,6 +47,7 @@ public void CalculateAgreement(ICipherParameters publicKey, byte[] buf, int off)
}

#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <summary>Span-based overload of <see cref="CalculateAgreement(ICipherParameters, byte[], int)"/>.</summary>
public void CalculateAgreement(ICipherParameters publicKey, Span<byte> buf)
{
m_privateKey.GenerateSecret((X448PublicKeyParameters)publicKey, buf);
Expand Down
29 changes: 29 additions & 0 deletions crypto/src/crypto/signers/Ed25519Signer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

namespace Org.BouncyCastle.Crypto.Signers
{
/// <summary>
/// Pure Ed25519 (RFC 8032) signature primitive. Buffers the message via the streaming
/// <see cref="ISigner"/> surface and dispatches it to the curve routines on finalisation; no
/// context is permitted.
/// </summary>
public class Ed25519Signer
: ISigner
{
Expand All @@ -15,15 +20,23 @@ public class Ed25519Signer
private Ed25519PrivateKeyParameters privateKey;
private Ed25519PublicKeyParameters publicKey;

/// <summary>Construct an uninitialised pure-Ed25519 signer; call <see cref="Init"/> before use.</summary>
public Ed25519Signer()
{
}

/// <inheritdoc/>
public virtual string AlgorithmName
{
get { return "Ed25519"; }
}

/// <summary>
/// Initialise for signing (private key) or verification (public key).
/// </summary>
/// <exception cref="InvalidCastException">If <paramref name="parameters"/> is not an
/// <see cref="Ed25519PrivateKeyParameters"/> (signing) or
/// <see cref="Ed25519PublicKeyParameters"/> (verification).</exception>
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
Expand All @@ -42,25 +55,32 @@ public virtual void Init(bool forSigning, ICipherParameters parameters)
Reset();
}

/// <inheritdoc/>
public virtual void Update(byte b)
{
buffer.WriteByte(b);
}

/// <inheritdoc/>
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
buffer.Write(buf, off, len);
}

#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <inheritdoc/>
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
buffer.Write(input);
}
#endif

/// <summary>Length in bytes of an Ed25519 signature (64).</summary>
public virtual int GetMaxSignatureSize() => Ed25519.SignatureSize;

/// <summary>Finalise the buffered message and produce the signature. Buffer is reset on return.</summary>
/// <exception cref="InvalidOperationException">If the signer was initialised for verification,
/// not signing.</exception>
public virtual byte[] GenerateSignature()
{
if (!forSigning || null == privateKey)
Expand All @@ -69,6 +89,14 @@ public virtual byte[] GenerateSignature()
return buffer.GenerateSignature(privateKey);
}

/// <summary>
/// Finalise the buffered message and verify <paramref name="signature"/>. Buffer is reset on
/// return.
/// </summary>
/// <returns><c>true</c> if the signature is valid for the accumulated message and bound public
/// key; otherwise <c>false</c>.</returns>
/// <exception cref="InvalidOperationException">If the signer was initialised for signing, not
/// verification.</exception>
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || null == publicKey)
Expand All @@ -77,6 +105,7 @@ public virtual bool VerifySignature(byte[] signature)
return buffer.VerifySignature(publicKey, signature);
}

/// <summary>Clear and rewind the buffered message.</summary>
public virtual void Reset()
{
buffer.Reset();
Expand Down
30 changes: 30 additions & 0 deletions crypto/src/crypto/signers/Ed25519ctxSigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

namespace Org.BouncyCastle.Crypto.Signers
{
/// <summary>
/// Ed25519ctx (RFC 8032 §5.1) signature primitive: pure Ed25519 with a domain-separation context
/// of up to 255 bytes captured at construction.
/// </summary>
public class Ed25519ctxSigner
: ISigner
{
Expand All @@ -16,6 +20,11 @@ public class Ed25519ctxSigner
private Ed25519PrivateKeyParameters privateKey;
private Ed25519PublicKeyParameters publicKey;

/// <summary>
/// Construct an Ed25519ctx signer bound to the supplied <paramref name="context"/>. The context
/// bytes are cloned so the caller may mutate the array afterwards.
/// </summary>
/// <exception cref="ArgumentNullException">If <paramref name="context"/> is <c>null</c>.</exception>
public Ed25519ctxSigner(byte[] context)
{
if (null == context)
Expand All @@ -24,11 +33,16 @@ public Ed25519ctxSigner(byte[] context)
this.context = (byte[])context.Clone();
}

/// <inheritdoc/>
public virtual string AlgorithmName
{
get { return "Ed25519ctx"; }
}

/// <summary>Initialise for signing (private key) or verification (public key).</summary>
/// <exception cref="InvalidCastException">If <paramref name="parameters"/> is not an
/// <see cref="Ed25519PrivateKeyParameters"/> (signing) or
/// <see cref="Ed25519PublicKeyParameters"/> (verification).</exception>
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
Expand All @@ -47,25 +61,32 @@ public virtual void Init(bool forSigning, ICipherParameters parameters)
Reset();
}

/// <inheritdoc/>
public virtual void Update(byte b)
{
buffer.WriteByte(b);
}

/// <inheritdoc/>
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
buffer.Write(buf, off, len);
}

#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <inheritdoc/>
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
buffer.Write(input);
}
#endif

/// <summary>Length in bytes of an Ed25519ctx signature (64).</summary>
public virtual int GetMaxSignatureSize() => Ed25519.SignatureSize;

/// <summary>Finalise the buffered message and produce the signature. Buffer is reset on return.</summary>
/// <exception cref="InvalidOperationException">If the signer was initialised for verification,
/// not signing.</exception>
public virtual byte[] GenerateSignature()
{
if (!forSigning || null == privateKey)
Expand All @@ -74,6 +95,14 @@ public virtual byte[] GenerateSignature()
return buffer.GenerateSignature(privateKey, context);
}

/// <summary>
/// Finalise the buffered message and verify <paramref name="signature"/>. Buffer is reset on
/// return.
/// </summary>
/// <returns><c>true</c> if the signature is valid for the accumulated message, bound public
/// key and captured context; otherwise <c>false</c>.</returns>
/// <exception cref="InvalidOperationException">If the signer was initialised for signing, not
/// verification.</exception>
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || null == publicKey)
Expand All @@ -82,6 +111,7 @@ public virtual bool VerifySignature(byte[] signature)
return buffer.VerifySignature(publicKey, context, signature);
}

/// <summary>Clear and rewind the buffered message; the captured context survives.</summary>
public virtual void Reset()
{
buffer.Reset();
Expand Down
27 changes: 27 additions & 0 deletions crypto/src/crypto/signers/Ed25519phSigner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

namespace Org.BouncyCastle.Crypto.Signers
{
/// <summary>
/// Ed25519ph (RFC 8032 §5.1) signature primitive: pre-hashes the message with SHA-512 before
/// running pure Ed25519, parameterised by a fixed context captured at construction.
/// </summary>
public class Ed25519phSigner
: ISigner
{
Expand All @@ -15,6 +19,11 @@ public class Ed25519phSigner
private Ed25519PrivateKeyParameters privateKey;
private Ed25519PublicKeyParameters publicKey;

/// <summary>
/// Construct an Ed25519ph signer bound to the supplied <paramref name="context"/>. The context
/// bytes are cloned so the caller may mutate the array afterwards.
/// </summary>
/// <exception cref="ArgumentNullException">If <paramref name="context"/> is <c>null</c>.</exception>
public Ed25519phSigner(byte[] context)
{
if (null == context)
Expand All @@ -23,11 +32,16 @@ public Ed25519phSigner(byte[] context)
this.context = (byte[])context.Clone();
}

/// <inheritdoc/>
public virtual string AlgorithmName
{
get { return "Ed25519ph"; }
}

/// <summary>Initialise for signing (private key) or verification (public key).</summary>
/// <exception cref="InvalidCastException">If <paramref name="parameters"/> is not an
/// <see cref="Ed25519PrivateKeyParameters"/> (signing) or
/// <see cref="Ed25519PublicKeyParameters"/> (verification).</exception>
public virtual void Init(bool forSigning, ICipherParameters parameters)
{
this.forSigning = forSigning;
Expand All @@ -46,25 +60,32 @@ public virtual void Init(bool forSigning, ICipherParameters parameters)
Reset();
}

/// <inheritdoc/>
public virtual void Update(byte b)
{
prehash.Update(b);
}

/// <inheritdoc/>
public virtual void BlockUpdate(byte[] buf, int off, int len)
{
prehash.BlockUpdate(buf, off, len);
}

#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
/// <inheritdoc/>
public virtual void BlockUpdate(ReadOnlySpan<byte> input)
{
prehash.BlockUpdate(input);
}
#endif

/// <summary>Length in bytes of an Ed25519ph signature (64).</summary>
public virtual int GetMaxSignatureSize() => Ed25519.SignatureSize;

/// <summary>Finalise the pre-hash and produce the signature.</summary>
/// <exception cref="InvalidOperationException">If the signer was initialised for verification,
/// not signing, or the pre-hash finalisation produces an unexpected length.</exception>
public virtual byte[] GenerateSignature()
{
if (!forSigning || null == privateKey)
Expand All @@ -79,6 +100,11 @@ public virtual byte[] GenerateSignature()
return signature;
}

/// <summary>Finalise the pre-hash and verify <paramref name="signature"/>.</summary>
/// <returns><c>true</c> if the signature is valid for the accumulated message, bound public
/// key and captured context; otherwise <c>false</c>.</returns>
/// <exception cref="InvalidOperationException">If the signer was initialised for signing, not
/// verification, or the pre-hash finalisation produces an unexpected length.</exception>
public virtual bool VerifySignature(byte[] signature)
{
if (forSigning || null == publicKey)
Expand All @@ -96,6 +122,7 @@ public virtual bool VerifySignature(byte[] signature)
return publicKey.Verify(Ed25519.Algorithm.Ed25519ph, context, msg, 0, Ed25519.PrehashSize, signature, 0);
}

/// <summary>Reset the pre-hash digest; the captured context survives.</summary>
public void Reset()
{
prehash.Reset();
Expand Down
Loading