advanced 30 min

Handshake & message relaying

The protocol handshake and how messages (proposals, validations, transactions) are relayed and squelched — plus a look at proposed protocol extensions.

Prerequisites

Complete these before starting this module:

What you'll learn

  • Understand the HTTP-upgrade protocol handshake.
  • Explain message relaying and the squelch mechanism.
  • See how reduce-relay limits redundant traffic.
Complete this module by mentor review and a quiz. Jump to assessment

Introduction

≈30 min · Advanced · builds on Peer discovery & connection lifecycle

Now let's watch messages actually move. In this module you'll learn the HTTP-upgrade handshake that starts a peer session, how proposals, validations and transactions are relayed across the mesh, and how squelching and reduce-relay cut the redundant traffic that would otherwise drown a large network. You'll also get a glimpse of where the protocol is heading next.


Handshake Objectives

In brief: what the protocol handshake has to establish before two peers exchange data.

The handshake accomplishes several essential goals:

Authentication: Each node proves its identity using cryptographic signatures. This prevents impersonation attacks where a malicious node pretends to be a trusted validator.

Protocol Negotiation: Nodes agree on the protocol version and features they will use for communication. This enables the network to evolve while maintaining backward compatibility.

Trust Establishment: Both parties verify that the other is a legitimate participant running compatible software. This ensures network integrity.

Capability Exchange: Nodes share information about their supported features, enabling peers to optimize their communication strategies.


HTTP Upgrade and Handshake

In brief: a peer session starts as an HTTP Upgrade request, then switches to the peer protocol.

(README)

  • Outbound peer initiates a TLS connection, then sends an HTTP/1.1 request with URI "/" and uses the HTTP/1.1 Upgrade mechanism with custom headers.
  • Both sides verify the provided signature against the session's unique fingerprint.
  • If signature check fails, the link is dropped.

Key idea. Relaying uses squelching and reduce-relay so a node does not forward the same proposal or validation from every peer. That is what keeps a large network's traffic manageable.

PeerImp::run and doAccept

In brief: the code that accepts a connection and starts relaying messages.

PeerImp::run (PeerImp.cpp):

  • Ensures execution on the correct strand for thread safety.
  • Parses handshake headers ("Closed-Ledger", "Previous-Ledger").
  • Stores parsed ledger hashes in peer state.
  • If inbound, calls doAccept(). If outbound, calls doProtocolStart().

PeerImp::doAccept (PeerImp.cpp):

  • Asserts read buffer is empty.
  • Logs the accept event.
  • Generates shared value for session.
  • Logs protocol and public key.
  • Checks for cluster membership and assigns name if present.
  • Calls overlay_.activate(shared_from_this()) to register the peer as active.
  • Prepares and sends handshake response.
  • On successful write, calls doProtocolStart().

Conclusion

The handshake protocol establishes secure, authenticated connections between XRP Ledger nodes. Through TLS encryption, cryptographic signatures, and careful protocol negotiation, it ensures that only legitimate nodes can participate in the network while maintaining compatibility across different software versions. Understanding this process is essential for diagnosing connection issues and implementing protocol enhancements.


XLS-??d Quantum-Resistant Signatures

Title: Quantum-Resistant Signatures
Revision: 1 (2025-07-08)
Type: Draft
Author:
    Atharva Lele, Trinity College Dublin
    Denis Angell, XRPL Labs

Abstract

This proposal introduces quantum-resistant digital signatures to the XRP Ledger (XRPL) using the Dilithium post-quantum cryptographic algorithm. The amendment provides accounts with the ability to use quantum-resistant signatures for enhanced security against future quantum computing threats while maintaining backward compatibility with existing signature schemes.

Motivation and Rationale

As quantum computing advances, current cryptographic signatures (secp256k1, ed25519) may become vulnerable to quantum attacks. This proposal adds support for Dilithium, a NIST-standardized post-quantum signature algorithm, ensuring long-term security for XRPL accounts.

Amendment

This feature enables accounts to use quantum-resistant signatures with an optional enforcement mechanism.

The amendment adds:

  • Support for Dilithium signature algorithm (KeyType::dilithium = 2)
  • New account flag lsfForceQuantum to enforce quantum-resistant signatures
  • Updated key generation, encoding, and verification systems

Development Branch

Implementation Repository

The quantum-resistant signatures implementation is currently under active development in the following branch:

Repository: Transia-RnD/rippled
Branch: dilithium-full

Development Status

This branch contains the working implementation of the quantum-resistant signature system, including:

  • Core Dilithium Integration: Implementation of the Dilithium post-quantum signature algorithm
  • Key Management Updates: Modified key generation, storage, and retrieval systems
  • Signature Verification: Updated transaction signing and verification processes
  • Account Flag Implementation: lsfForceQuantum flag enforcement mechanisms
  • Backward Compatibility: Maintained support for existing signature schemes

Testing and Validation

The dilithium-full branch includes:

  • Unit tests for Dilithium key operations
  • Integration tests for quantum-resistant transaction processing
  • Performance benchmarks comparing signature verification times
  • Compatibility tests ensuring existing functionality remains intact

Contributing

Developers interested in contributing to the quantum-resistant signatures implementation should:

  1. Fork the repository and checkout the dilithium-full branch
  2. Review the existing implementation and test coverage
  3. Submit pull requests against the dilithium-full branch
  4. Ensure all tests pass and maintain backward compatibility

Implementation Details

Key Specifications

Aspect secp256k1 ed25519 Dilithium
Public Key Size 33 bytes 33 bytes 1312 bytes
Secret Key Size 32 bytes 32 bytes 2528 bytes
Signature Size ~70 bytes 64 bytes ~2420 bytes
Security Level 128-bit 128-bit 128-bit (quantum-resistant)

Key Generation

// Generate quantum-resistant keys
auto keyPair = generateKeyPair(KeyType::dilithium, seed);
auto secretKey = randomSecretKey(KeyType::dilithium);

Public Key Detection

std::optional<KeyType> publicKeyType(Slice const& slice) {
    if (slice.size() == 33) {
        if (slice[0] == 0xED) return KeyType::ed25519;
        if (slice[0] == 0x02 || slice[0] == 0x03) return KeyType::secp256k1;
    }
    else if (slice.size() == CRYPTO_PUBLICKEYBYTES) {
        return KeyType::dilithium;  // 1312 bytes
    }
    return std::nullopt;
}

Account Flag: Force Quantum Signatures

lsfForceQuantum Flag

Field Value Description
lsfForceQuantum 0x02000000 When set, account requires quantum-resistant signatures
asfForceQuantum 11 AccountSet flag to enable/disable quantum requirement

Usage

{
  "TransactionType": "AccountSet",
  "Account": "rAccount...",
  "SetFlag": 11  // Enable quantum-only signatures
}

Enforcement

if (account.isFlag(lsfForceQuantum) && publicKey.size() != DILITHIUM_PK_SIZE)
    return telBAD_PUBLIC_KEY;

Signature Operations

Signature Generation

case KeyType::dilithium: {
    uint8_t sig[CRYPTO_BYTES];
    size_t len;
    crypto_sign_signature(sig, &len, message.data(), message.size(), secretKey.data());
    return Buffer{sig, len};
}

Signature Verification

if (keyType == KeyType::dilithium) {
    return crypto_sign_verify(
        sig.data(), sig.size(), 
        message.data(), message.size(), 
        publicKey.data()) == 0;
}

Migration Strategy

Gradual Adoption

  1. Optional Phase: Quantum signatures available but not required
  2. Account Choice: Individual accounts can enable lsfForceQuantum
  3. Network Transition: Networks can mandate quantum signatures over time

Backward Compatibility

  • Existing accounts continue using current signature types
  • No breaking changes to existing functionality
  • Smooth upgrade path for enhanced security

Error Codes

Error Code Description
telBAD_PUBLIC_KEY Non-quantum signature used with lsfForceQuantum account

Future Requirements

Validator Infrastructure Updates

As quantum-resistant signatures become standard, several validator-related components will require updates:

Validator Code Updates

  • rippled: Core validator software must support quantum-resistant key generation and signature verification
  • Consensus Algorithm: Ensure quantum-resistant signatures are properly validated during consensus
  • Peer Communication: Update peer-to-peer communication to handle larger quantum signatures

UNL (Unique Node List) Generation

  • UNL Tools: Update UNL generation tools to support quantum-resistant validator keys
  • Key Format: Modify UNL file format to accommodate larger Dilithium public keys (1312 bytes)
  • Validation: Ensure UNL validation processes can verify quantum-resistant signatures

validator-keys Repository

  • Key Generation: Update validator-keys tool to generate Dilithium key pairs
  • Key Management: Modify key storage and management for larger quantum keys
  • Migration Tools: Provide utilities for existing validators to transition to quantum-resistant keys
  • Documentation: Update validator setup guides for quantum key generation

Network Transition Considerations

  • Phased Rollout: Gradual migration of validators to quantum-resistant keys
  • Backward Compatibility: Maintain support for existing validator keys during transition
  • Performance Impact: Account for increased signature verification time and bandwidth usage

Dependencies

  • Dilithium Library: pq-crystals/dilithium reference implementation

Example Usage

Generate Quantum-Resistant Keys

// From seed
auto seed = generateSeed("masterpassphrase");
auto keyPair = generateKeyPair(KeyType::dilithium, seed);

// Random generation
auto secretKey = randomSecretKey(KeyType::dilithium);
auto publicKey = derivePublicKey(KeyType::dilithium, secretKey);

Enable Quantum-Only Account

{
  "TransactionType": "AccountSet",
  "Account": "rQuantumAccount...",
  "SetFlag": 11
}

Sign Transaction with Quantum Key

auto signature = sign(publicKey, secretKey, transactionData);
bool isValid = verify(publicKey, transactionData, signature);

Message Relaying


Introduction

Efficient message propagation is essential for a decentralized ledger. Transactions must reach validators quickly, proposals must spread to enable consensus, and validations must propagate to finalize ledgers. The overlay network's message relaying system ensures information flows efficiently while preventing network overload through intelligent squelching.

This lesson explores how messages propagate through the network and how Rippled optimizes this process to handle high-throughput scenarios.


OverlayImpl::relay

OverlayImpl::relay(protocol::TMProposeSet& m, uint256 const& uid, PublicKey const& validator) (OverlayImpl.cpp):

  • Calls app_.getHashRouter().shouldRelay(uid) to determine if the proposal should be relayed.
  • If not, returns an empty set.
  • If yes:
  • Creates a shared pointer to a Message object containing the proposal.
  • Iterates over all active peers.
  • For each peer not in the skip set, sends the proposal message.
  • Returns the set of peer IDs that were skipped.

Slot::update and Squelch Mechanism

Squelching in action: a validator's messages arrive through many peers, the slot selects a couple of reliable messengers, and TMSquelch mutes the redundant senders until the timer expires.

Slot::update (Slot.h):

  • Tracks peer activity for a validator, incrementing message counts and considering peers for selection.
  • When enough peers reach the message threshold, randomly selects a subset to be "Selected" and squelches the rest (temporarily mutes them).
  • Squelched peers are unsquelched after expiration.
  • Handles all state transitions, logging, and squelch/unsquelch notifications via the SquelchHandler interface.

OverlayImpl::unsquelch (OverlayImpl.cpp):

  • Looks up the peer by short ID.
  • If found, constructs a TMSquelch message with squelch=false for the validator.
  • Sends the message to the peer, instructing it to stop squelching messages from the validator.

Summary

This module showed messages actually moving across the mesh. A peer session begins as an HTTP Upgrade request, then proposals, validations, and transactions are relayed between peers, and squelching and reduce-relay suppress redundant duplicates so a large network's traffic stays manageable. You also glimpsed a proposed protocol extension for quantum-resistant signatures.

To remember:

  • A peer session starts life as an HTTP Upgrade request (PeerImp::run / doAccept)
  • Relaying is deduplicated: a node forwards a message once, not once per peer
  • Squelching tells redundant senders to stop; reduce-relay trims proposal/validation duplication
  • Suppression is per-source, not censorship: content still arrives via other peers
  • The quantum-resistant signature material (Dilithium) is a forward-looking proposal, not shipped protocol
  • Code: src/xrpld/overlay/detail
  • Watch out: when debugging "missing" messages, check squelch state before suspecting the network

Next up. Peers talk to peers; everyone else knocks on a different door. New phase: the RPC architecture, from port to handler and back.

Assignments

0 of 2 complete

Unlocks

Finishing this module opens up:

XRPL Academy © 2026