LCOV - code coverage report
Current view: top level - src - bip324.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 3 5 60.0 %
Date: 2023-10-05 12:38:51 Functions: 4 6 66.7 %
Branches: 2 6 33.3 %

           Branch data     Line data    Source code
       1                 :            : // Copyright (c) 2023 The Bitcoin Core developers
       2                 :            : // Distributed under the MIT software license, see the accompanying
       3                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :            : 
       5                 :            : #ifndef BITCOIN_BIP324_H
       6                 :            : #define BITCOIN_BIP324_H
       7                 :            : 
       8                 :            : #include <array>
       9                 :            : #include <cstddef>
      10                 :            : #include <optional>
      11                 :            : 
      12                 :            : #include <crypto/chacha20.h>
      13                 :            : #include <crypto/chacha20poly1305.h>
      14                 :            : #include <key.h>
      15                 :            : #include <pubkey.h>
      16                 :            : #include <span.h>
      17                 :            : 
      18                 :            : /** The BIP324 packet cipher, encapsulating its key derivation, stream cipher, and AEAD. */
      19                 :            : class BIP324Cipher
      20                 :            : {
      21                 :            : public:
      22                 :            :     static constexpr unsigned SESSION_ID_LEN{32};
      23                 :            :     static constexpr unsigned GARBAGE_TERMINATOR_LEN{16};
      24                 :            :     static constexpr unsigned REKEY_INTERVAL{224};
      25                 :            :     static constexpr unsigned LENGTH_LEN{3};
      26                 :            :     static constexpr unsigned HEADER_LEN{1};
      27                 :            :     static constexpr unsigned EXPANSION = LENGTH_LEN + HEADER_LEN + FSChaCha20Poly1305::EXPANSION;
      28                 :            :     static constexpr std::byte IGNORE_BIT{0x80};
      29                 :            : 
      30                 :            : private:
      31                 :            :     std::optional<FSChaCha20> m_send_l_cipher;
      32                 :            :     std::optional<FSChaCha20> m_recv_l_cipher;
      33                 :            :     std::optional<FSChaCha20Poly1305> m_send_p_cipher;
      34                 :            :     std::optional<FSChaCha20Poly1305> m_recv_p_cipher;
      35                 :            : 
      36                 :            :     CKey m_key;
      37                 :            :     EllSwiftPubKey m_our_pubkey;
      38                 :            : 
      39                 :            :     std::array<std::byte, SESSION_ID_LEN> m_session_id;
      40                 :            :     std::array<std::byte, GARBAGE_TERMINATOR_LEN> m_send_garbage_terminator;
      41                 :            :     std::array<std::byte, GARBAGE_TERMINATOR_LEN> m_recv_garbage_terminator;
      42                 :            : 
      43                 :            : public:
      44                 :            :     /** No default constructor; keys must be provided to create a BIP324Cipher. */
      45                 :            :     BIP324Cipher() = delete;
      46                 :            : 
      47                 :            :     /** Initialize a BIP324 cipher with specified key and encoding entropy (testing only). */
      48                 :            :     BIP324Cipher(const CKey& key, Span<const std::byte> ent32) noexcept;
      49                 :            : 
      50                 :            :     /** Initialize a BIP324 cipher with specified key (testing only). */
      51                 :            :     BIP324Cipher(const CKey& key, const EllSwiftPubKey& pubkey) noexcept;
      52                 :            : 
      53                 :            :     /** Retrieve our public key. */
      54                 :      10108 :     const EllSwiftPubKey& GetOurPubKey() const noexcept { return m_our_pubkey; }
      55                 :            : 
      56                 :            :     /** Initialize when the other side's public key is received. Can only be called once.
      57                 :            :      *
      58                 :            :      * initiator is set to true if we are the initiator establishing the v2 P2P connection.
      59                 :            :      * self_decrypt is only for testing, and swaps encryption/decryption keys, so that encryption
      60                 :            :      * and decryption can be tested without knowing the other side's private key.
      61                 :            :      */
      62                 :            :     void Initialize(const EllSwiftPubKey& their_pubkey, bool initiator, bool self_decrypt = false) noexcept;
      63                 :            : 
      64                 :            :     /** Determine whether this cipher is fully initialized. */
      65                 :          0 :     explicit operator bool() const noexcept { return m_send_l_cipher.has_value(); }
      66                 :            : 
      67                 :            :     /** Encrypt a packet. Only after Initialize().
      68                 :            :      *
      69                 :            :      * It must hold that output.size() == contents.size() + EXPANSION.
      70                 :            :      */
      71                 :            :     void Encrypt(Span<const std::byte> contents, Span<const std::byte> aad, bool ignore, Span<std::byte> output) noexcept;
      72                 :            : 
      73                 :            :     /** Decrypt the length of a packet. Only after Initialize().
      74                 :            :      *
      75                 :            :      * It must hold that input.size() == LENGTH_LEN.
      76                 :            :      */
      77                 :            :     unsigned DecryptLength(Span<const std::byte> input) noexcept;
      78                 :            : 
      79                 :            :     /** Decrypt a packet. Only after Initialize().
      80                 :            :      *
      81                 :            :      * It must hold that input.size() + LENGTH_LEN == contents.size() + EXPANSION.
      82                 :            :      * Contents.size() must equal the length returned by DecryptLength.
      83                 :            :      */
      84                 :            :     bool Decrypt(Span<const std::byte> input, Span<const std::byte> aad, bool& ignore, Span<std::byte> contents) noexcept;
      85                 :            : 
      86                 :            :     /** Get the Session ID. Only after Initialize(). */
      87         [ #  # ]:          0 :     Span<const std::byte> GetSessionID() const noexcept { return m_session_id; }
      88                 :            : 
      89                 :            :     /** Get the Garbage Terminator to send. Only after Initialize(). */
      90         [ +  - ]:        670 :     Span<const std::byte> GetSendGarbageTerminator() const noexcept { return m_send_garbage_terminator; }
      91                 :            : 
      92                 :            :     /** Get the expected Garbage Terminator to receive. Only after Initialize(). */
      93         [ +  - ]:    1015680 :     Span<const std::byte> GetReceiveGarbageTerminator() const noexcept { return m_recv_garbage_terminator; }
      94                 :            : };
      95                 :            : 
      96                 :            : #endif // BITCOIN_BIP324_H

Generated by: LCOV version 1.14