From e80df8028b19c7d909b07214dd835526192755cd Mon Sep 17 00:00:00 2001 From: Konradsop Date: Wed, 1 Apr 2026 23:04:15 +0200 Subject: [PATCH] docs: add XML documentation for AES, AEAD modes and Dilithium This commit adds XML documentation to the core symmetric suite and the Dilithium signer. Critical security warnings regarding Nonce reuse were added to GCM and ChaCha20Poly1305. --- crypto/src/crypto/IBlockCipher.cs | 7 +- crypto/src/crypto/engines/AesEngine.cs | 70 +++++++------- crypto/src/crypto/modes/CbcBlockCipher.cs | 53 ++++------- crypto/src/crypto/modes/ChaCha20Poly1305.cs | 79 +++++++++++++++- crypto/src/crypto/modes/GCMBlockCipher.cs | 72 +++++++++++++++ crypto/src/crypto/modes/IAeadBlockCipher.cs | 1 + crypto/src/crypto/modes/IAeadCipher.cs | 92 +++++++++---------- .../crystals/dilithium/DilithiumSigner.cs | 27 ++++++ 8 files changed, 276 insertions(+), 125 deletions(-) diff --git a/crypto/src/crypto/IBlockCipher.cs b/crypto/src/crypto/IBlockCipher.cs index 36f10d3e8f..d1c58d8984 100644 --- a/crypto/src/crypto/IBlockCipher.cs +++ b/crypto/src/crypto/IBlockCipher.cs @@ -2,7 +2,9 @@ namespace Org.BouncyCastle.Crypto { - /// Base interface for a symmetric key block cipher. + /// + /// Base interface for a symmetric key block cipher. + /// public interface IBlockCipher { /// The name of the algorithm this cipher implements. @@ -13,6 +15,9 @@ public interface IBlockCipher /// The key or other data required by the cipher. void Init(bool forEncryption, ICipherParameters parameters); + /// + /// Return the block size for this cipher (in bytes). + /// /// The block size for this cipher, in bytes. int GetBlockSize(); diff --git a/crypto/src/crypto/engines/AesEngine.cs b/crypto/src/crypto/engines/AesEngine.cs index 0eb2dc1ecd..ebf79a5c57 100644 --- a/crypto/src/crypto/engines/AesEngine.cs +++ b/crypto/src/crypto/engines/AesEngine.cs @@ -6,30 +6,25 @@ namespace Org.BouncyCastle.Crypto.Engines { - /** - * an implementation of the AES (Rijndael), from FIPS-197. - *

- * For further details see: http://csrc.nist.gov/encryption/aes/. - * - * This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at - * http://fp.gladman.plus.com/cryptography_technology/rijndael/ - * - * There are three levels of tradeoff of speed vs memory - * Because java has no preprocessor, they are written as three separate classes from which to choose - * - * The fastest uses 8Kbytes of static tables to precompute round calculations, 4 256 word tables for encryption - * and 4 for decryption. - * - * The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, - * adding 12 rotate operations per round to compute the values contained in the other tables from - * the contents of the first. - * - * The slowest version uses no static tables at all and computes the values in each round. - *

- *

- * This file contains the middle performance version with 2Kbytes of static tables for round precomputation. - *

- */ + /// An implementation of the AES (Rijndael), from FIPS-197. + /// + /// For further details see: http://csrc.nist.gov/encryption/aes/. + /// + /// This implementation is based on optimizations from Dr. Brian Gladman's paper and C code at + /// http://fp.gladman.plus.com/cryptography_technology/rijndael/ + /// + /// + /// There are three levels of tradeoff of speed vs memory: + /// + /// + /// The fastest uses 8Kbytes of static tables to precompute round calculations. + /// The middle performance version uses only one 256 word table for each, for a total of 2Kbytes, adding 12 rotate operations per round. + /// The slowest version uses no static tables at all and computes the values in each round. + /// + /// + /// This file contains the middle performance version with 2Kbytes of static tables for round precomputation. + /// + /// public sealed class AesEngine : IBlockCipher { @@ -437,21 +432,15 @@ private uint[][] GenerateWorkingKey(KeyParameter keyParameter, bool forEncryptio private const int BLOCK_SIZE = 16; - /** - * default constructor - 128 bit block size. - */ + /// Default constructor - 128 bit block size. public AesEngine() { } - /** - * initialise an AES cipher. - * - * @param forEncryption whether or not we are for encryption. - * @param parameters the parameters required to set up the cipher. - * @exception ArgumentException if the parameters argument is - * inappropriate. - */ + /// Initialise an AES cipher. + /// Whether or not we are using it for encryption. + /// The parameters required to set up the cipher. + /// If the parameters argument is inappropriate. public void Init(bool forEncryption, ICipherParameters parameters) { if (!(parameters is KeyParameter keyParameter)) @@ -464,16 +453,27 @@ public void Init(bool forEncryption, ICipherParameters parameters) this.s = Arrays.Clone(forEncryption ? S : Si); } + /// The name of the algorithm this engine implements. public string AlgorithmName { get { return "AES"; } } + /// Return the block size for this cipher (in bytes). + /// 16 (fixed block size for AES). public int GetBlockSize() { return BLOCK_SIZE; } + /// Process a single block of data. + /// The input buffer containing the data to be processed. + /// The offset into the input buffer. + /// The output buffer to store the result. + /// The offset into the output buffer. + /// The number of bytes processed and produced. + /// If the input buffer is too small, or the output buffer is too small. + /// If the cipher isn't initialised. public int ProcessBlock(byte[] input, int inOff, byte[] output, int outOff) { if (WorkingKey == null) diff --git a/crypto/src/crypto/modes/CbcBlockCipher.cs b/crypto/src/crypto/modes/CbcBlockCipher.cs index 0423af2426..f55af0d9d6 100644 --- a/crypto/src/crypto/modes/CbcBlockCipher.cs +++ b/crypto/src/crypto/modes/CbcBlockCipher.cs @@ -5,9 +5,7 @@ namespace Org.BouncyCastle.Crypto.Modes { - /** - * implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher. - */ + /// Implements Cipher-Block-Chaining (CBC) mode on top of a simple cipher. public sealed class CbcBlockCipher : IBlockCipherMode { @@ -16,11 +14,8 @@ public sealed class CbcBlockCipher private IBlockCipher cipher; private bool encrypting; - /** - * Basic constructor. - * - * @param cipher the block cipher to be used as the basis of chaining. - */ + /// Basic constructor. + /// The block cipher to be used as the basis of chaining. public CbcBlockCipher( IBlockCipher cipher) { @@ -32,23 +27,15 @@ public CbcBlockCipher( this.cbcNextV = new byte[blockSize]; } - /** - * return the underlying block cipher that we are wrapping. - * - * @return the underlying block cipher that we are wrapping. - */ + /// Return the underlying block cipher that we are wrapping. + /// The underlying block cipher that we are wrapping. public IBlockCipher UnderlyingCipher => cipher; - /** - * Initialise the cipher and, possibly, the initialisation vector (IV). - * If an IV isn't passed as part of the parameter, the IV will be all zeros. - * - * @param forEncryption if true the cipher is initialised for - * encryption, if false for decryption. - * @param param the key and other data required by the cipher. - * @exception ArgumentException if the parameters argument is - * inappropriate. - */ + /// Initialise the cipher and, possibly, the initialisation vector (IV). + /// If an IV isn't passed as part of the parameter, the IV will be all zeros. + /// If true the cipher is initialised for encryption, if false for decryption. + /// The key and other data required by the cipher. + /// If the parameters argument is inappropriate. public void Init(bool forEncryption, ICipherParameters parameters) { bool oldEncrypting = this.encrypting; @@ -82,26 +69,21 @@ public void Init(bool forEncryption, ICipherParameters parameters) } } - /** - * return the algorithm name and mode. - * - * @return the name of the underlying algorithm followed by "/CBC". - */ + /// Return the algorithm name and mode. + /// The name of the underlying algorithm followed by "/CBC". public string AlgorithmName { get { return cipher.AlgorithmName + "/CBC"; } } + /// Indicates whether this cipher can handle partial blocks. public bool IsPartialBlockOkay { get { return false; } } - /** - * return the block size of the underlying cipher. - * - * @return the block size of the underlying cipher. - */ + /// Return the block size of the underlying cipher. + /// The block size in bytes. public int GetBlockSize() { return cipher.GetBlockSize(); @@ -129,10 +111,7 @@ public int ProcessBlock(ReadOnlySpan input, Span output) } #endif - /** - * reset the chaining vector back to the IV and reset the underlying - * cipher. - */ + /// Reset the chaining vector back to the IV and reset the underlying cipher. public void Reset() { Array.Copy(IV, 0, cbcV, 0, IV.Length); diff --git a/crypto/src/crypto/modes/ChaCha20Poly1305.cs b/crypto/src/crypto/modes/ChaCha20Poly1305.cs index ddfddbeec3..ffbc762043 100644 --- a/crypto/src/crypto/modes/ChaCha20Poly1305.cs +++ b/crypto/src/crypto/modes/ChaCha20Poly1305.cs @@ -1,4 +1,4 @@ -using System; +using System; using Org.BouncyCastle.Crypto.Engines; using Org.BouncyCastle.Crypto.Macs; @@ -8,6 +8,21 @@ namespace Org.BouncyCastle.Crypto.Modes { + /// + /// Implementation of the ChaCha20-Poly1305 AEAD construction as defined in RFC 7539 / RFC 8439. + /// + /// + /// + /// ChaCha20-Poly1305 is an Authenticated Encryption with Associated Data (AEAD) algorithm + /// combining the ChaCha20 stream cipher with the Poly1305 message authentication code. + /// + /// + /// CRITICAL SECURITY WARNING: For encryption, a unique nonce (IV) MUST be used for every + /// invocation with the same key. Reusing a nonce with the same key catastrophically compromises + /// the security of the cipher, allowing an attacker to recover the authentication key (Poly1305) + /// and plaintext. + /// + /// public class ChaCha20Poly1305 : IAeadCipher { @@ -48,11 +63,20 @@ private enum State private State mState = State.Uninitialized; private int mBufPos; + /// + /// Default constructor using the standard MAC. + /// public ChaCha20Poly1305() : this(new Poly1305()) { } + /// + /// Constructor allowing a custom Poly1305 implementation. + /// + /// The Poly1305 MAC implementation to use. + /// If poly1305 is null. + /// If poly1305 is not a 128-bit MAC. public ChaCha20Poly1305(IMac poly1305) { if (null == poly1305) @@ -64,11 +88,18 @@ public ChaCha20Poly1305(IMac poly1305) this.mPoly1305 = poly1305; } + /// The name of the algorithm ("ChaCha20Poly1305"). public virtual string AlgorithmName { get { return "ChaCha20Poly1305"; } } + /// + /// Initialise the ChaCha20Poly1305 cipher. + /// + /// True if initializing for encryption, false for decryption. + /// The parameters required (typically or ). + /// If parameters are invalid or nonce is reused for encryption. public virtual void Init(bool forEncryption, ICipherParameters parameters) { KeyParameter initKeyParam; @@ -157,6 +188,9 @@ public virtual void Init(bool forEncryption, ICipherParameters parameters) Reset(true, false); } + /// Return the size of the output buffer required for an input of bytes. + /// Input length. + /// Required output buffer size. public virtual int GetOutputSize(int len) { int total = System.Math.Max(0, len); @@ -177,6 +211,9 @@ public virtual int GetOutputSize(int len) } } + /// Return the size of the output buffer required for a ProcessBytes call with bytes. + /// Input length. + /// Update output size. public virtual int GetUpdateOutputSize(int len) { int total = System.Math.Max(0, len); @@ -202,6 +239,8 @@ public virtual int GetUpdateOutputSize(int len) return total - total % BufSize; } + /// Process a single byte of Additional Authenticated Data (AAD). + /// The byte to be processed. public virtual void ProcessAadByte(byte input) { CheckAad(); @@ -210,6 +249,10 @@ public virtual void ProcessAadByte(byte input) mPoly1305.Update(input); } + /// Process a sequence of bytes of Additional Authenticated Data (AAD). + /// The input buffer containing AAD. + /// The offset into the input buffer. + /// The length of the data to process. public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) { if (null == inBytes) @@ -230,6 +273,8 @@ public virtual void ProcessAadBytes(byte[] inBytes, int inOff, int len) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a span of bytes of Additional Authenticated Data (AAD). + /// The input span containing AAD. public virtual void ProcessAadBytes(ReadOnlySpan input) { CheckAad(); @@ -242,6 +287,11 @@ public virtual void ProcessAadBytes(ReadOnlySpan input) } #endif + /// Process a single byte of data. + /// The input byte. + /// The output buffer. + /// The offset into the output buffer. + /// Number of bytes written to the output buffer. public virtual int ProcessByte(byte input, byte[] outBytes, int outOff) { CheckData(); @@ -289,6 +339,10 @@ public virtual int ProcessByte(byte input, byte[] outBytes, int outOff) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a single byte of data using Spans. + /// The input byte. + /// The output span. + /// Number of bytes written to the output span. public virtual int ProcessByte(byte input, Span output) { CheckData(); @@ -328,6 +382,13 @@ public virtual int ProcessByte(byte input, Span output) } #endif + /// Process a sequence of bytes from the input buffer. + /// The input buffer. + /// The offset into the input buffer. + /// The length of data to process. + /// The output buffer. + /// The offset into the output buffer. + /// The number of bytes written to the output buffer. public virtual int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff) { if (null == inBytes) @@ -463,6 +524,10 @@ public virtual int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBy } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a span of bytes from the input. + /// The input span. + /// The output span. + /// The number of bytes written to the output span. public virtual int ProcessBytes(ReadOnlySpan input, Span output) { CheckData(); @@ -573,6 +638,11 @@ public virtual int ProcessBytes(ReadOnlySpan input, Span output) } #endif + /// Finish the operation, generating or verifying the MAC. + /// The output buffer for remaining processed data and/or MAC. + /// The offset into the output buffer. + /// Number of bytes written to the output buffer. + /// If the MAC check fails. public virtual int DoFinal(byte[] outBytes, int outOff) { if (null == outBytes) @@ -641,6 +711,10 @@ public virtual int DoFinal(byte[] outBytes, int outOff) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Finish the operation using Spans, generating or verifying the MAC. + /// The output span for remaining data and/or MAC. + /// Number of bytes written to the output span. + /// If the MAC check fails. public virtual int DoFinal(Span output) { CheckData(); @@ -700,11 +774,14 @@ public virtual int DoFinal(Span output) } #endif + /// Return the Message Authentication Code (MAC) generated or verified by the cipher. + /// A byte array containing the MACBlock. public virtual byte[] GetMac() { return Arrays.Clone(mMac); } + /// Reset the cipher to its initial state (ready for a new message with the same key but DIFFERENT nonce). public virtual void Reset() { Reset(true, true); diff --git a/crypto/src/crypto/modes/GCMBlockCipher.cs b/crypto/src/crypto/modes/GCMBlockCipher.cs index 63a5c1627f..28d8a04ba3 100644 --- a/crypto/src/crypto/modes/GCMBlockCipher.cs +++ b/crypto/src/crypto/modes/GCMBlockCipher.cs @@ -22,6 +22,17 @@ namespace Org.BouncyCastle.Crypto.Modes /// /// Implements the Galois/Counter mode (GCM) detailed in NIST Special Publication 800-38D. /// + /// + /// + /// GCM provides both confidentiality and data origin authentication (AEAD). + /// It requires a block cipher with a 128-bit block size, typically . + /// + /// + /// CRITICAL SECURITY WARNING: For encryption, a unique nonce (IV) MUST be used for every + /// invocation with the same key. Reusing a nonce with the same key catastrophically compromises + /// the security of the cipher, allowing an attacker to recover the authentication key or plaintext. + /// + /// public sealed class GcmBlockCipher : IAeadBlockCipher { @@ -76,6 +87,10 @@ internal static IGcmMultiplier CreateGcmMultiplier() private ulong atLength; private ulong atLengthPre; + /// + /// Base constructor. + /// + /// The underlying block cipher to use (must have a 128-bit block size). public GcmBlockCipher( IBlockCipher c) : this(c, null) @@ -99,10 +114,14 @@ public GcmBlockCipher( this.multiplier = m; } + /// The name of the algorithm this cipher implements (e.g., "AES/GCM"). public string AlgorithmName => cipher.AlgorithmName + "/GCM"; + /// Return the underlying block cipher being wrapped. public IBlockCipher UnderlyingCipher => cipher; + /// Return the block size for GCM (fixed at 16 bytes). + /// 16. public int GetBlockSize() { return BlockSize; @@ -112,6 +131,12 @@ public int GetBlockSize() /// MAC sizes from 32 bits to 128 bits (must be a multiple of 8) are supported. The default is 128 bits. /// Sizes less than 96 are not recommended, but are supported for specialized applications. /// + /// + /// Initialise the GCM cipher. + /// + /// True if initializing for encryption, false for decryption. + /// The parameters required (typically or ). + /// If parameters are invalid or nonce is reused for encryption. public void Init(bool forEncryption, ICipherParameters parameters) { this.forEncryption = forEncryption; @@ -259,11 +284,16 @@ public void Init(bool forEncryption, ICipherParameters parameters) } } + /// Return the Message Authentication Code (MAC) generated or verified by the cipher. + /// A byte array containing the MACBlock. public byte[] GetMac() { return macBlock == null ? new byte[macSize] : (byte[])macBlock.Clone(); } + /// Return the size of the output buffer required for an input of bytes. + /// Input length. + /// Required output buffer size. public int GetOutputSize(int len) { int totalData = len + bufOff; @@ -274,6 +304,9 @@ public int GetOutputSize(int len) return totalData < macSize ? 0 : totalData - macSize; } + /// Return the size of the output buffer required for a ProcessBytes call with bytes. + /// Input length. + /// Update output size. public int GetUpdateOutputSize(int len) { int totalData = len + bufOff; @@ -287,6 +320,8 @@ public int GetUpdateOutputSize(int len) return totalData - totalData % BlockSize; } + /// Process a single byte of Additional Authenticated Data (AAD). + /// The byte to be processed. public void ProcessAadByte(byte input) { CheckStatus(); @@ -301,6 +336,10 @@ public void ProcessAadByte(byte input) } } + /// Process a sequence of bytes of Additional Authenticated Data (AAD). + /// The input buffer containing AAD. + /// The offset into the input buffer. + /// The length of the data to process. public void ProcessAadBytes(byte[] inBytes, int inOff, int len) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -341,6 +380,8 @@ public void ProcessAadBytes(byte[] inBytes, int inOff, int len) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a span of bytes of Additional Authenticated Data (AAD). + /// The input span containing AAD. public void ProcessAadBytes(ReadOnlySpan input) { CheckStatus(); @@ -395,6 +436,12 @@ private void InitCipher() } } + /// Process a single byte of data. + /// The input byte. + /// The output buffer. + /// The offset into the output buffer. + /// Number of bytes written to the output buffer. + /// If output buffer is too short. public int ProcessByte(byte input, byte[] output, int outOff) { CheckStatus(); @@ -441,6 +488,10 @@ public int ProcessByte(byte input, byte[] output, int outOff) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a single byte of data using Spans. + /// The input byte. + /// The output span. + /// Number of bytes written to the output span. public int ProcessByte(byte input, Span output) { CheckStatus(); @@ -479,6 +530,13 @@ public int ProcessByte(byte input, Span output) } #endif + /// Process a sequence of bytes from the input buffer. + /// The input buffer. + /// The offset into the input buffer. + /// The length of data to process. + /// The output buffer. + /// The offset into the output buffer. + /// The number of bytes written to the output buffer. public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int outOff) { CheckStatus(); @@ -631,6 +689,10 @@ public int ProcessBytes(byte[] input, int inOff, int len, byte[] output, int out } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a span of bytes from the input. + /// The input span. + /// The output span. + /// The number of bytes written to the output span. public int ProcessBytes(ReadOnlySpan input, Span output) { CheckStatus(); @@ -806,6 +868,11 @@ public int ProcessBytes(ReadOnlySpan input, Span output) } #endif + /// Finish the operation, generating or verifying the Message Authentication Code (MAC). + /// The output buffer for remaining processed data and/or MAC. + /// The offset into the output buffer. + /// Number of bytes written to the output buffer. + /// If the MAC check fails. public int DoFinal(byte[] output, int outOff) { #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER @@ -926,6 +993,10 @@ public int DoFinal(byte[] output, int outOff) } #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Finish the operation using Spans, generating or verifying the MAC. + /// The output span for remaining data and/or MAC. + /// Number of bytes written to the output span. + /// If the MAC check fails. public int DoFinal(Span output) { CheckStatus(); @@ -1042,6 +1113,7 @@ public int DoFinal(Span output) } #endif + /// Reset the cipher to its initial state (ready for a new message with the same key but DIFFERENT nonce). public void Reset() { Reset(true); diff --git a/crypto/src/crypto/modes/IAeadBlockCipher.cs b/crypto/src/crypto/modes/IAeadBlockCipher.cs index a4dc0857c8..4cee457bf7 100644 --- a/crypto/src/crypto/modes/IAeadBlockCipher.cs +++ b/crypto/src/crypto/modes/IAeadBlockCipher.cs @@ -6,6 +6,7 @@ namespace Org.BouncyCastle.Crypto.Modes public interface IAeadBlockCipher : IAeadCipher { + /// Return the block size for this cipher (in bytes). /// The block size for this cipher, in bytes. int GetBlockSize(); diff --git a/crypto/src/crypto/modes/IAeadCipher.cs b/crypto/src/crypto/modes/IAeadCipher.cs index 5e92c78f37..597d3a7b5b 100644 --- a/crypto/src/crypto/modes/IAeadCipher.cs +++ b/crypto/src/crypto/modes/IAeadCipher.cs @@ -1,4 +1,4 @@ -using System; +using System; using Org.BouncyCastle.Crypto.Parameters; @@ -48,78 +48,68 @@ public interface IAeadCipher void ProcessAadBytes(ReadOnlySpan input); #endif - /** - * Encrypt/decrypt a single byte. - * - * @param input the byte to be processed. - * @param outBytes the output buffer the processed byte goes into. - * @param outOff the offset into the output byte array the processed data starts at. - * @return the number of bytes written to out. - * @exception DataLengthException if the output buffer is too small. - */ + /// Process a single byte of data. + /// The byte to be processed. + /// The output buffer. + /// The offset into the output buffer. + /// The number of bytes written to the output buffer. + /// If the output buffer is too small. int ProcessByte(byte input, byte[] outBytes, int outOff); #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a single byte of data using Spans. + /// The byte to be processed. + /// The output span. + /// The number of bytes written to the output span. int ProcessByte(byte input, Span output); #endif - /** - * Process a block of bytes from in putting the result into out. - * - * @param inBytes the input byte array. - * @param inOff the offset into the in array where the data to be processed starts. - * @param len the number of bytes to be processed. - * @param outBytes the output buffer the processed bytes go into. - * @param outOff the offset into the output byte array the processed data starts at. - * @return the number of bytes written to out. - * @exception DataLengthException if the output buffer is too small. - */ + /// Process a sequence of bytes from the input buffer. + /// The input buffer. + /// The offset into the input buffer. + /// The length of data to process. + /// The output buffer. + /// The offset into the output buffer. + /// The number of bytes written to the output buffer. + /// If the output buffer is too small. int ProcessBytes(byte[] inBytes, int inOff, int len, byte[] outBytes, int outOff); #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Process a span of bytes from the input. + /// The input span. + /// The output span. + /// The number of bytes written to the output span. int ProcessBytes(ReadOnlySpan input, Span output); #endif - /** - * Finish the operation either appending or verifying the MAC at the end of the data. - * - * @param outBytes space for any resulting output data. - * @param outOff offset into out to start copying the data at. - * @return number of bytes written into out. - * @throws InvalidOperationException if the cipher is in an inappropriate state. - * @throws InvalidCipherTextException if the MAC fails to match. - */ + /// Finish the operation, generating or verifying the MAC. + /// The output buffer for remaining data and/or MAC. + /// The offset into the output buffer. + /// Number of bytes written to the output buffer. + /// If the cipher is in an inappropriate state. + /// If the MAC check fails. int DoFinal(byte[] outBytes, int outOff); #if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Finish the operation using Spans, generating or verifying the MAC. + /// The output span for remaining data and/or MAC. + /// Number of bytes written to the output span. + /// If the MAC check fails. int DoFinal(Span output); #endif - /** - * Return the value of the MAC associated with the last stream processed. - * - * @return MAC for plaintext data. - */ + /// Return the Message Authentication Code (MAC) generated or verified by the cipher. + /// A byte array containing the MAC Block. byte[] GetMac(); - /** - * Return the size of the output buffer required for a ProcessBytes - * an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to ProcessBytes - * with len bytes of input. - */ + /// Return the size of the output buffer required for a ProcessBytes call with bytes. + /// Input length. + /// The space required for ProcessBytes with len bytes of input. int GetUpdateOutputSize(int len); - /** - * Return the size of the output buffer required for a ProcessBytes plus a - * DoFinal with an input of len bytes. - * - * @param len the length of the input. - * @return the space required to accommodate a call to ProcessBytes and DoFinal - * with len bytes of input. - */ + /// Return the size of the output buffer required for a ProcessBytes plus a DoFinal call with bytes. + /// Input length. + /// The space required for ProcessBytes and DoFinal with len bytes of input. int GetOutputSize(int len); /// diff --git a/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs b/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs index d939dec6f8..938d3881f4 100644 --- a/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs +++ b/crypto/src/pqc/crypto/crystals/dilithium/DilithiumSigner.cs @@ -6,6 +6,14 @@ namespace Org.BouncyCastle.Pqc.Crypto.Crystals.Dilithium { + /// + /// Signer implementation for the CRYSTALS-Dilithium post-quantum signature algorithm. + /// + /// + /// Dilithium is part of the CRYSTALS (Cryptographic Suite for Algebraic Lattices) family. + /// This implementation corresponds to the submission to the NIST PQC project. + /// Note: Users are encouraged to migrate to ML-DSA (FIPS 204) as the standardized version. + /// [Obsolete("Use ML-DSA instead")] public class DilithiumSigner : IMessageSigner @@ -15,10 +23,18 @@ public class DilithiumSigner private SecureRandom random; + /// + /// Default constructor. + /// public DilithiumSigner() { } + /// + /// Initialise the Dilithium signer. + /// + /// True if initializing for signing, false for verification. + /// The parameters for the signer (typically or ). public void Init(bool forSigning, ICipherParameters param) { if (forSigning) @@ -41,6 +57,11 @@ public void Init(bool forSigning, ICipherParameters param) } } + /// + /// Generate a signature for the given message. + /// + /// The message bytes to sign. + /// The generated signature byte array. public byte[] GenerateSignature(byte[] message) { DilithiumEngine engine = privKey.Parameters.GetEngine(random); @@ -50,6 +71,12 @@ public byte[] GenerateSignature(byte[] message) return sig; } + /// + /// Verify a signature for the given message. + /// + /// The original message bytes. + /// The signature bytes to verify. + /// True if the signature is valid, false otherwise. public bool VerifySignature(byte[] message, byte[] signature) { var engine = pubKey.Parameters.GetEngine(random);