Crate bip324

Source
Expand description

BIP-324 encrypted transport protocol for bitcoin p2p communication.

This crate implements the BIP-324 version 2 encrypted transport protocol, which provides encryption and authentication for bitcoin p2p connections. Like TLS, it begins with a handshake establishing shared secrets, then encrypts all subsequent communication.

§Quick Start

For a complete encrypted connection, use the high-level APIs in the io or [futures] modules:

§Synchronous API (requires std feature)

use bip324::io::{Protocol, Payload};
use bip324::serde::{serialize, deserialize, NetworkMessage};
use std::net::TcpStream;
use std::io::BufReader;

let stream = TcpStream::connect("127.0.0.1:8333")?;

// Wrap reader in BufReader for efficiency (protocol makes many small reads)
let reader = BufReader::new(stream.try_clone()?);
let writer = stream;

let mut protocol = Protocol::new(
    bip324::Network::Bitcoin,
    bip324::Role::Initiator,
    None, None, // no garbage or decoys
    reader,
    writer,
)?;

let ping_msg = NetworkMessage::Ping(0xdeadbeef);
let serialized = serialize(ping_msg);
protocol.write(&Payload::genuine(serialized))?;

let response = protocol.read()?;
let response_msg: NetworkMessage = deserialize(&response.contents())?;

§Asynchronous API (requires tokio feature)

use bip324::futures::Protocol;
use bip324::io::Payload;
use bip324::serde::{serialize, deserialize, NetworkMessage};
use tokio::net::TcpStream;
use tokio::io::BufReader;

let stream = TcpStream::connect("127.0.0.1:8333").await?;
let (reader, writer) = stream.into_split();

// Wrap reader in BufReader for efficiency (protocol makes many small reads)
let buffered_reader = BufReader::new(reader);

let mut protocol = Protocol::new(
    bip324::Network::Bitcoin,
    bip324::Role::Initiator,
    None, None, // no garbage or decoys
    buffered_reader,
    writer,
).await?;

let ping_msg = NetworkMessage::Ping(12345); // nonce
let serialized = serialize(ping_msg);
protocol.write(&Payload::genuine(serialized)).await?;

let response = protocol.read().await?;
let response_msg: NetworkMessage = deserialize(&response.contents())?;

§Message Serialization

BIP-324 introduces specific changes to how bitcoin P2P messages are serialized for V2 transport. The serde module provides these serialization functions.

use bip324::serde::{serialize, deserialize, NetworkMessage};

let ping_msg = NetworkMessage::Ping(0xdeadbeef);
let serialized = serialize(ping_msg);

let received_bytes = vec![0x12, 0xef, 0xbe, 0xad, 0xde, 0, 0, 0, 0];
let message: NetworkMessage = deserialize(&received_bytes)?;

§Performance Considerations

The BIP-324 protocol makes multiple small reads, particularly during the handshake (reading 64-byte keys, 16-byte terminators) and for each message (3-byte length prefix). For optimal performance, wrap your reader in a BufReader:

use std::io::BufReader;
use std::net::TcpStream;

let stream = TcpStream::connect("127.0.0.1:8333")?;
let buffered_reader = BufReader::new(stream.try_clone()?);

§Advanced Usage

For more control, such as no-std environments, you can use the lower level components.

  • Handshake - Type-safe handshake state machine.
  • CipherSession - Managed encryption/decryption after handshake.

§Protocol Details

After the initial handshake, all data is encrypted in packets.

FieldSizeDescription
Length3 bytesEncrypted length of contents
Header1 byteProtocol flags including decoy indicator
ContentsVariableThe serialized message
Tag16 bytesAuthentication tag

The protocol supports both genuine packets containing application data and decoy packets with random data for traffic analysis resistance.

Modules§

io
High-level synchronous interfaces for establishing BIP-324 encrypted connections over Read/Write IO transports. For asynchronous support, see the futures module.
serde
Serialize and deserialize V2 messages over the wire.

Structs§

CipherSession
Manages cipher state for a BIP-324 encrypted connection.
Handshake
Handshake state-machine to establish the secret material in the communication channel.
InboundCipher
Decrypts packets received from the remote peer.
Initialized
Initial state of the handshake state machine which holds local secret materials.
OutboundCipher
Encrypts packets to send to the remote peer.
ReceivedGarbage
Fifth state after receiving the remote’s garbage and garbage terminator.
ReceivedKey
Third state after receiving the remote’s public key and generating the shared secret materials for the session.
SentKey
Second state after sending the local public key.
SentVersion
Fourth state after sending the decoy and version packets.
SessionKeyMaterial
All keys derived from the ECDH.

Enums§

Error
Errors encountered throughout the lifetime of a V2 connection.
GarbageResult
Success variants for reading remote garbage.
Network
The cryptocurrency network to act on.
PacketType
A decoy packet contains bogus information, but can be used to hide the shape of the data being communicated over an encrypted channel.
Role
Role in the handshake.
SecretGenerationError
Secret generation specific errors.
VersionResult
Success variants for receiving remote version.

Constants§

DECOY_BYTE
Value for header byte with the decoy flag flipped to true.
NUM_HEADER_BYTES
Number of bytes for the header holding protocol flags.
NUM_LENGTH_BYTES
Number of bytes for the encrypted length prefix of a packet.