PqEncryption class

Post-quantum hybrid encryption for Nostr direct messages.

Every encrypted message on Nostr today can be recorded now and decrypted later, once a quantum computer breaks secp256k1 — NIP-44 derives its conversation key from a secp256k1 ECDH secret. That is "harvest now, decrypt later", and it is the only half of the quantum problem that can be fixed in advance: a message protected today stays confidential permanently. Forgery, by contrast, cannot be pre-empted — it is fixed only by migrating signatures before the break.

The construction is hybrid: the ML-KEM-1024 shared secret is combined with the ordinary NIP-44 conversation key through HKDF, so the result is never weaker than what Nostr uses today. A break in a comparatively young lattice scheme must not be able to make messaging worse than it is now.

The payload rides inside unchanged NIP-44 and NIP-59 gift wrap, so relays need no changes and clients that have not implemented it are unaffected.

Wire-compatible with @nostr-wot/pq, which is what the Nostr WoT browser extension ships. The Rust test suite pins a complete envelope produced by that implementation.

What this does not do

It protects confidentiality only. Events are still signed with secp256k1, so a quantum adversary can still forge events in your name.

Properties

hashCode int
The hash code for this object.
no setterinherited
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

Methods

noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toString() String
A string representation of this object.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited

Static Methods

decrypt({required String payload, required Uint8List recipientKemSecretKey, required String recipientPrivateKey, required String senderPubkey, required String recipientPubkey}) Future<String>
Decrypts a base64 envelope produced by encrypt.
deriveKeyPair(Uint8List seed, {int account = 0}) PqKeyPair
Derives the ML-KEM-1024 keypair for account from a BIP-39 seed.
encrypt({required String plaintext, required Uint8List recipientKemKey, required String senderPrivateKey, required String senderPubkey, required String recipientPubkey}) Future<String>
Encrypts plaintext to recipientKemKey, returning a base64 envelope.
isPqEnvelope(String payload) bool
Whether payload looks like a post-quantum envelope.

Constants

kemPublicKeyBytes → const int
Length of an ML-KEM-1024 encapsulation key, per FIPS 203.
seedBytes → const int
A BIP-39 seed is always 64 bytes, whatever the mnemonic length.