This fixes the main problem with encryption today, which is that you cannot allow an application to encrypt/decrypt only some kinds.
This opens up users to risks where applications can exfiltrate private information like DMs, even if you just wanted to allow access to modify your encrypted lists.
It also has some other improvements, such as allowing larger encrypted payloads.
Read more:
quoting
naddr1qq…ldywIf you just want to read the specification, it's at https://spec.nostr.land/nip44v3.
The problem with current encryption
The current specification, NIP-44 v2, was created during simpler times: Nostr was smaller, remote signers were rare, and pasting
nsecs was the standard.Since then, things have changed. Large events are much more common, using remote signers is the norm, and encryption is everywhere.
When you want to allow a Nostr app to encrypt/decrypt data, by default, most signers prompt you to approve or reject it.
Depending on your signer, you might get a prompt that: 1. Shows the raw data.
Good, but you can't know if the[["p", ...], ...]list is the private mute list you wanted to edit, or actually the member list for your group chat. 2. Shows no information at all, just that decryption was requested. Not helpful. 3. Tells you a rough type, such as JSON, or plaintext.
This is much better but has the same problem as 1: Two different contexts can share the same format without being related.Encrypted data is now integral to most Nostr apps. Applications need access to decrypt to look for new DMs, load your private lists, store application settings, and much more.
The sheer number of decryption requests can cause permission fatigue, leading users to allow all decryption requests without confirmation.
This can be exploited by malicious applications to exfiltrate sensitive conversations, ecash/LN wallet keys, and more:
There has been a discussion about how to allow restricting decryption/encryption, and the conclusion was: The only robust solution is a new AEAD scheme.
It has been 21 months without any progress.
There are also other issues with the current encryption scheme:
Large data
Have you ever tried to use a remote signer with a follow list that is larger than 2000 users? No?
Well, you can't, even if you want to.
Events like this are over the size limit of NIP-44 v2, making it impossible to manage such lists with a remote signer. You instead need to use your
nsecdirectly, or use a browser extension.Binary encoding
There are many use cases where encrypting binary data can be useful. However, NIP-44 v2 only supports UTF-8 encoded text, and support for binary data is inconsistent.
Some of these use cases include: - Gift wrapped DMs currently incur an unnecessary additional 33% overhead in size, since the seal event's payload is not binary but Base64. - Private user and note lists are 2x larger than they have to be. The content has to be encoded with JSON and hex encoding, requiring 64 bytes per item, instead of a binary encoding that can use 32 bytes.
This overhead adds up, and wastes mobile data and relay resources.
What is NIP-44 v3?
NIP-44 v3 is a new encryption scheme that solves these issues, without introducing any new cryptographic primitives or constructions in Nostr.
Some of the features: - Context binding allows associating specific information about what is being encrypted, and makes it possible to have granular access control. - Binary encoding is supported for the plaintext. - The 64KB message limit is gone, and message sizes can be as large as what your code and relays can process. - It is designed to allow implementation on signers with restricted resources, such as secure elements, while preserving access control over the context. - Clients can support NIP-44 v2 and v3 at the same time, allowing a smooth transition to more secure encryption.
Context binding
NIP-44 v3 supports context binding, which means each message has an associated context.
The signer can use the context from the message to identify what it is, and accept/deny accordingly: a private message, your mute list, or your LN wallet's data.
Much nicer, isn't it?
This also prevents the usage of an encrypted piece of data, such as a private message, in another context like a long-form draft.
The specific implementation in NIP-44 v3 has two fields: -
kind, for the kind of the event. -scope, which is an additional scope that is defined by the specific kind. This can be thedtag, for example.Getting started
The NIP-44 v3 specification is available at https://spec.nostr.land/nip44v3, and includes the main specification, a less-formal implementation guide, and test vectors.
An implementation of NIP-44 v3 in Go is available as
pkg.nostr.land/go/ncrypt. This also supports NIP-44 v2, NIP-04, and provides a way to detect the encryption version used.The specification is still a draft, but it is unlikely to change except for the formatting, and the addition of new test vectors.
Why not submit it as a NIP now?
I plan to submit NIP-44 v3 to the main NIPs repository at a future date.
However, the NIPs repository's "process" (or lack thereof) significantly slows down the adoption of any new specifications.
For this reason, this specification is released as a standalone repository.
This allows the development of secure encryption to start now, instead of after months of waiting for a single approval from the "official" maintainers.
Some technical details
The cryptography in NIP-44 v3 does not differ significantly from NIP-44 v2.
HKDF is used to derive per-message subkeys, which protects the shared secrets and ensures the keys are unbiased. The main difference includes using
info/saltcorrectly compared to v2, and separateHKDF-Expandcalls for each key.The ChaCha20 nonce is set to all-zeroes, as any given encryption key is only used to encrypt one message due to the subkey derivation.
The encoding has additional fields for the kind and scope, and the MAC now incorporates those as well.
NIP-44 v3 incorporates a slightly modified version of the padding in NIP-44 v2, that increases the uncertainty of the padding size for short messages, like DMs, without much overhead.
The padding used by NIP-44 v3 does not enforce a specific algorithm, but it is strongly recommended that all implementations use the reference algorithm.
End
Thanks for reading! If you have any feedback, please reply or tag me.
If you want to support my work, consider zapping.
