< Summary - Combined Code Coverage

Information
Class: NLightning.Infrastructure.Crypto.Ciphers.ChaCha20Poly1305
Assembly: NLightning.Infrastructure
File(s): /home/runner/work/nlightning/nlightning/src/NLightning.Infrastructure/Crypto/Ciphers/ChaCha20Poly1305.cs
Tag: 30_15166811759
Line coverage
94%
Covered lines: 18
Uncovered lines: 1
Coverable lines: 19
Total lines: 84
Line coverage: 94.7%
Branch coverage
75%
Covered branches: 3
Total branches: 4
Branch coverage: 75%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
Encrypt(...)50%2.01285.71%
Decrypt(...)100%22100%
Dispose()100%11100%

File(s)

/home/runner/work/nlightning/nlightning/src/NLightning.Infrastructure/Crypto/Ciphers/ChaCha20Poly1305.cs

#LineLine coverage
 1// Based on Noise.NET by Nemanja Mijailovic https://github.com/Metalnem/noise
 2
 3using System.Buffers.Binary;
 4using System.Diagnostics;
 5using System.Security.Cryptography;
 6
 7namespace NLightning.Infrastructure.Crypto.Ciphers;
 8
 9using Domain.Crypto.Constants;
 10using Factories;
 11using Interfaces;
 12
 13/// <summary>
 14/// AEAD_CHACHA20_POLY1305 from <see href="https://tools.ietf.org/html/rfc7539">RFC 7539</see>.
 15/// The 96-bit nonce is formed by encoding 32 bits of zeros followed by little-endian encoding of n.
 16/// </summary>
 17public sealed class ChaCha20Poly1305 : IDisposable
 18{
 19    private readonly ICryptoProvider _cryptoProvider;
 20
 19221    public ChaCha20Poly1305()
 22    {
 19223        _cryptoProvider = CryptoFactory.GetCryptoProvider();
 19224    }
 25
 26    /// <summary>
 27    /// Encrypts plaintext using the cipher key of 32 bytes and an 8-byte unsigned integer publicNonce which must be
 28    /// unique for the key. Writes the result into ciphertext parameter and returns the number of bytes written.
 29    /// Encryption must be done with an "AEAD" encryption mode with the authenticationData and results in a ciphertext
 30    /// that is the same size as the plaintext plus 16 bytes for authentication data.
 31    /// </summary>
 32    public int Encrypt(ReadOnlySpan<byte> key, ulong publicNonce, ReadOnlySpan<byte> authenticationData,
 33                       ReadOnlySpan<byte> plaintext, Span<byte> ciphertext)
 34    {
 35        Debug.Assert(key.Length == CryptoConstants.PRIVKEY_LEN);
 36        Debug.Assert(ciphertext.Length >= plaintext.Length + CryptoConstants.CHACHA20_POLY1305_TAG_LEN);
 37
 814438        Span<byte> nonce = stackalloc byte[CryptoConstants.CHACHA20_POLY1305_NONCE_LEN];
 814439        BinaryPrimitives.WriteUInt64LittleEndian(nonce[4..], publicNonce);
 40
 814441        var result = _cryptoProvider.AeadChaCha20Poly1305IetfEncrypt(key, nonce, null, authenticationData, plaintext,
 814442                                                                     ciphertext, out var length);
 43
 814444        if (result != 0)
 45        {
 046            throw new CryptographicException("Encryption failed.");
 47        }
 48
 49        Debug.Assert(length == plaintext.Length + CryptoConstants.CHACHA20_POLY1305_TAG_LEN);
 814450        return (int)length;
 51    }
 52
 53    /// <summary>
 54    /// Decrypts ciphertext using a cipher key of 32 bytes, an 8-byte unsigned integer publicNonce, and
 55    /// authenticationData. Reads the result into plaintext parameter and returns the number of bytes read, unless
 56    /// authentication fails, in which case an error is signaled to the caller.
 57    /// </summary>
 58    public int Decrypt(ReadOnlySpan<byte> key, ulong publicNonce, ReadOnlySpan<byte> authenticationData,
 59                       ReadOnlySpan<byte> ciphertext, Span<byte> plaintext)
 60    {
 61        Debug.Assert(key.Length == CryptoConstants.PRIVKEY_LEN);
 62        Debug.Assert(ciphertext.Length >= CryptoConstants.CHACHA20_POLY1305_TAG_LEN);
 63        Debug.Assert(plaintext.Length >= ciphertext.Length - CryptoConstants.CHACHA20_POLY1305_TAG_LEN);
 64
 813665        Span<byte> nonce = stackalloc byte[CryptoConstants.CHACHA20_POLY1305_NONCE_LEN];
 813666        BinaryPrimitives.WriteUInt64LittleEndian(nonce[4..], publicNonce);
 67
 813668        var result = _cryptoProvider.AeadChaCha20Poly1305IetfDecrypt(key, nonce, null, authenticationData,
 813669                                                                     ciphertext, plaintext, out var length);
 70
 812871        if (result != 0)
 72        {
 873            throw new CryptographicException("Decryption failed.");
 74        }
 75
 76        Debug.Assert(length == ciphertext.Length - CryptoConstants.CHACHA20_POLY1305_TAG_LEN);
 812077        return (int)length;
 78    }
 79
 80    public void Dispose()
 81    {
 14482        _cryptoProvider.Dispose();
 14483    }
 84}