Skip to content

Litep2p clean#574

Open
illuzen wants to merge 15 commits into
mainfrom
illuzen/pq-litep2p-clean
Open

Litep2p clean#574
illuzen wants to merge 15 commits into
mainfrom
illuzen/pq-litep2p-clean

Conversation

@illuzen
Copy link
Copy Markdown
Contributor

@illuzen illuzen commented May 30, 2026

  • vendors the litep2p code
  • switches the networking stack over to litep2p exclusively
  • adds post-quantum support to litep2p
  • turns off libp2p

The litep2p code was first copied from the official source, then modified to add dilithium and kyber support, then elliptic curve support was removed.

The idea behind litep2p and our adoption of it is to reduce the attack surface in the networking stack.

The node connects to testnet and syncs without issues because the wire protocol is identical to the libp2p stack, but we should probably run a few more tests to be sure.


Note

High Risk
Replaces the entire Substrate networking stack and changes peer authentication/encryption (Dilithium, pqXX Noise, PQ TLS); interoperability and security regressions need thorough testnet and adversarial validation.

Overview
This PR replaces libp2p with a vendored litep2p stack as the only P2P backend: workspace and lockfile drop libp2p / patched identity-noise crates, add a new client/litep2p crate (patched via [patch.crates-io]), and wire sc-network through Litep2pNetworkBackend while removing the old libp2p swarm/transport modules.

Node identity and handshakes move to post-quantum crypto: Dilithium ML-DSA-87 for local keys and PeerId, pqXX Noise with ML-KEM 768 (clatter), and QUIC/TLS via rustls-post-quantum / aws-lc-rs with libp2p-style certificate extensions. CLI defaults and generate-node-key / inspect-node-key now use litep2p types; --network-backend defaults to Litep2p (libp2p option removed).

Smaller lockfile/pallet dependency trims are secondary to the networking swap.

Reviewed by Cursor Bugbot for commit bc0f44a. Bugbot is set up for automated code reviews on this repo. Configure here.

illuzen added 15 commits May 30, 2026 22:59
Removed:
- qp-wormhole-verifier, sp-keyring from runtime
- codec from sp-consensus-qpow
- qp-poseidon, sp-io from qp-dilithium-crypto
- qp-poseidon from qp-wormhole
- log from pallet-multisig, pallet-zk-tree
- sp-weights from pallet-scheduler
- sp-metadata-ir from pallet-wormhole
- num-traits, sp-arithmetic from pallet-qpow
- qp-poseidon from pallet-mining-rewards
- qp-high-security from pallet-reversible-transfers
- qp-poseidon, qp-rusty-crystals-dilithium from node
- sc-service from sc-consensus-qpow

Note: codec and scale-info are required by frame macros even if not
directly imported - cargo-machete reports false positives for pallets.
@illuzen illuzen requested a review from n13 May 30, 2026 14:35
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit bc0f44a. Configure here.


kp.zeroize();

Ok(Keypair { seed, public })
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stored public key unchecked

Medium Severity

When a Dilithium node key is loaded from the combined seed-plus-public-key format, the trailing public key bytes are accepted without checking they match the key regenerated from the seed. sign derives the secret from the seed while public() returns the stored bytes, so a corrupted file can advertise one PeerId while signatures and Noise identity proofs use another key, breaking handshakes and peer identity.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bc0f44a. Configure here.

address.iter().last().and_then(|p| match p {
Protocol::P2p(hash) => PeerId::from_multihash(hash).ok(),
_ => None,
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2p only at multiaddr end

Low Severity

PeerId::try_from_multiaddr in litep2p only treats a /p2p/ component as the peer ID when it is the last protocol in the multiaddr. Substrate’s sc-network-types peer ID parsing accepts a /p2p/ anywhere in the address. The same multiaddr can resolve to a peer ID in one layer and None in litep2p, breaking address validation and public-address handling.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bc0f44a. Configure here.

Self::try_from_bytes(&mut kp.to_bytes())
.expect("Substrate Dilithium keypair to use the same format")
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate Dilithium key module

Low Severity

The PR adds a full Dilithium Keypair/PublicKey/SecretKey implementation in sc-network-types that mirrors the same logic vendored in client/litep2p/src/crypto/dilithium.rs, including try_from_bytes, signing, and conversions. Two copies of security-sensitive key handling increase the risk of divergent fixes (as with public-key validation) and extra maintenance burden.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bc0f44a. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant