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.
Field | Size | Description |
---|---|---|
Length | 3 bytes | Encrypted length of contents |
Header | 1 byte | Protocol flags including decoy indicator |
Contents | Variable | The serialized message |
Tag | 16 bytes | Authentication 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§
- Cipher
Session - Manages cipher state for a BIP-324 encrypted connection.
- Handshake
- Handshake state-machine to establish the secret material in the communication channel.
- Inbound
Cipher - Decrypts packets received from the remote peer.
- Initialized
- Initial state of the handshake state machine which holds local secret materials.
- Outbound
Cipher - Encrypts packets to send to the remote peer.
- Received
Garbage - Fifth state after receiving the remote’s garbage and garbage terminator.
- Received
Key - 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.
- Sent
Version - Fourth state after sending the decoy and version packets.
- Session
KeyMaterial - All keys derived from the ECDH.
Enums§
- Error
- Errors encountered throughout the lifetime of a V2 connection.
- Garbage
Result - Success variants for reading remote garbage.
- Network
- The cryptocurrency network to act on.
- Packet
Type - 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.
- Secret
Generation Error - Secret generation specific errors.
- Version
Result - 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.