Skip to content

Build with PsstPsst

Encryption keys & device sync

Interoperate with PsstPsst using NIP-4E: separate identity and encryption keys, key announcements, and authenticated encryption-key transfer between devices.

Protocol source ↗
On this page

draft optional

This document specifies PsstPsst’s profile of the draft NIP-4E proposal. It separates the Nostr identity key from the key used for NIP-44 encryption and synchronizes the encryption key between devices. Its use in message envelopes is specified in Private messages.

Event Purpose
kind 10044 Announce the current encryption public key
kind 4454 Request the encryption private key on another device
kind 4455 Transfer the encryption private key to that device

Encryption-key announcement

The identity publishes its current encryption public key in a replaceable kind 10044 event signed by the identity key:

{
  "id": "<event-id>",
  "kind": 10044,
  "pubkey": "<identity-pubkey>",
  "created_at": "<unix-timestamp>",
  "tags": [["n", "<encryption-pubkey>"]],
  "content": "",
  "sig": "<identity-signature>"
}

The first n value MUST be a 32-byte lowercase hexadecimal secp256k1 public key. A sender compares the latest valid kind 10044 with encryption-key evidence from the recipient’s latest authenticated incoming seal and encrypts to whichever signed event is newer. Exact timestamp ties use event ordering, with the lexicographically smaller event ID considered newer. Republishing kind 10044 with another n value rotates the publicly advertised encryption key without changing the account identity.

Encryption-key synchronization

Kinds 4454 and 4455 transfer the current encryption private key between devices using the same identity.

Request

The requesting device selects a client key pair and publishes:

{
  "id": "<event-id>",
  "pubkey": "<identity-pubkey>",
  "created_at": "<unix-timestamp>",
  "kind": 4454,
  "tags": [
    ["P", "<requester-client-pubkey>"],
    ["pubkey", "<requester-client-pubkey>"],
    ["relay", "<response-relay>"],
    ["n", "<requested-encryption-pubkey>"]
  ],
  "content": "",
  "sig": "<identity-signature>"
}

P is the NIP-4E client public key. pubkey is an optional compatibility alias; when both are present they MUST be equal. Each relay value is a relay on which the requester accepts the response. When n is present, the responder transfers that encryption key; otherwise it transfers its current key.

The requester publishes kind 4454 to its advertised relays. Requests are authored by the shared identity.

Response

After authorizing the request, another device selects a sender client key pair and publishes:

{
  "id": "<event-id>",
  "pubkey": "<identity-pubkey>",
  "created_at": "<unix-timestamp>",
  "kind": 4455,
  "tags": [
    ["P", "<sender-client-pubkey>"],
    ["p", "<identity-pubkey>"],
    ["p", "<requester-client-pubkey>"]
  ],
  "content": "<nip44-encrypted-private-key>",
  "sig": "<identity-signature>"
}

The content plaintext is the 32-byte encryption private key encoded as 64 lowercase hexadecimal characters. It is encrypted with NIP-44 using the sender client private key and requester client public key. The responder publishes the response to one or more relays shared with the requester and SHOULD include valid relay hints from the request when present.

A kind 4455 response is authored by the shared identity and p-tagged with the requester client public key. The requester obtains the sender client public key from P, decrypts the content, derives the transferred public key, and accepts the key only when that public key equals the current kind 10044 n value. Undecryptable and non-matching responses are ignored.

The identity p tag routes the response to the account inbox. Receivers MUST require the requester client p tag and MAY accept a response without the identity p tag.

Authorization code

The comparison code is the first eight hexadecimal characters of the requester client public key, rendered uppercase as XXXX XXXX. A responder SHOULD require out-of-band authorization before disclosing the encryption private key.