Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nip46: abandon nip04 entirely and just use nip44 #1248

Merged
merged 1 commit into from
Dec 5, 2024
Merged

nip46: abandon nip04 entirely and just use nip44 #1248

merged 1 commit into from
Dec 5, 2024

Conversation

fiatjaf
Copy link
Member

@fiatjaf fiatjaf commented May 19, 2024

this is a placeholder PR that should only be merged once the full transition has happened.

nip44 support decrypt encrypt
gossip ✔️ ✔️
amethyst ✔️ ✔️
highlighter ✔️
snort ✔️ ✔️
coracle ✔️ ✔️
flotilla ✔️ ✔️
welshman ✔️ ✔️
ndk ✔️ ✔️
nostrify ✔️ ✔️
nostr-tools ✔️
go-nostr ✔️
rust-nostr ✔️ ✔️
nak ✔️
nostr-login ✔️
window.nostr.js ✔️
ditto ✔️
amber ✔️ ✔️
nsec.app

can you edit this comment and include your library/app/etc?

@alexgleason
Copy link
Member

Used my rare privilege to edit other people's posts to add amber to the list

@vitorpamplona
Copy link
Collaborator

I like this support table. It should be a staple in every PR.

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented May 20, 2024

FYI, the new text uses an example for signing kind 14, which should never be signed. :)

Maybe change it to kind 1059 or 13?

@arcbtc
Copy link
Contributor

arcbtc commented Jun 29, 2024

Why abandon? For bunch of use cases nip04 is great. Just have both and recommend for dms using 44

@mikedilger
Copy link
Contributor

I think we should keep NIP-04 to document how that works because we cannot make all the nostr clients stop doing it, and there are many nostr clients now. Marking it as deprecated is good enough.

@mikedilger
Copy link
Contributor

BTW gossip ticks both columns now.

@believethehype
Copy link
Contributor

Rust Nostr also ticks both columns

@greenart7c3
Copy link
Contributor

Amber ticks both columns

@melvincarvalho
Copy link

NIP-04 is used in lots of places other than listed. No finite list can capture Nostr ecosystem at this point. NIP-04 is indeed great, as @arcbtc points out, not least because it's much simpler. It plays well with the simplicity maxis.

@alltheseas
Copy link
Contributor

alltheseas commented Aug 7, 2024

Through nostrability we previously learned that it is not realistic to expect a NIP to be deprecated. Not because the upgraded NIP is not superior, but rather because of the independent and non-synchronized nature of nostr dev work.

The consequence of the above observation is that if @fiatjaf and NIP dev team advise NIP-XX is deprecated, many will switch, AND some will not.

If the devs that switch/upgrade to the superior NIP do not account for backwards compatibility to the older NIP, this could cause a negative experience for nostr users.

Multiply this times however many NIP upgrades take place (imagine the upgraded nostr binary NIP in lieu of JSON is next for discussion), and you will have a lot of "on nostr _______ doesn't work", or "I never knew you interacted with me" reports from users.

When considering these major changes, consider @pablof7z's view of how nostr wins is creating an awesome experience, not possible on the corpo-gulag monopolies such as twitter. Negative interoperability diminishes the chances of this victory.

The question for yall galaxy brain devs to consider is does this NIP upgrade benefit seriously outweigh the negative interoperability introduced to the network, striving towards the Pabloverse vision of nostr winning.

@melvincarvalho
Copy link

If the devs that switch/upgrade to the superior NIP

NIP44 isn't actually superior. It doesn't fix the privacy issues it aims to and is much more complex. NIP04 has its own strengths, especially for simple agent-to-agent communication, which will always be needed. Simplicity wins, which is why nostr succeeded over SSB.

If some central committee decides NIP44 is better, we'll just end up reinventing NIP04, similar to how nostr was invented to simplify SSB. Developers not in the central committee will see this as a rug pull, like what Google did with Angular, making nostr development seem unstable. Developers can't build on quicksand; they'll just spend their time on other things.

We have a lot to improve in nostr. Breaking what's already working shouldn't be a priority. It sends a bad message.

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Aug 7, 2024

NIP44 isn't actually superior.

That's not true. NIP-44 encryption protects against many forms of attack that NIP-04 simply can't. NIP-04 is simple exactly because it ignores most of the cryptographic protections that were added onto NIP-44. Simplicity is the only thing NIP04 has going for it. Superiority is not there.

Also, for reference, there were TONS of discussions on how bad NIP-04 is:

@erskingardner
Copy link
Contributor

I agree that NIP-04 is not great and NIP-44 is definitely better... but I don't like the idea of breaking user space.

This is a fairly naive idea that I've literally spent 10 seconds thinking about but why don't we just have a tag that signals which encryption scheme a given even uses? That would make it easy for libraries/apps/clients to detect which scheme to use for a given event and makes sure that we're always backwards compatible.

@fiatjaf
Copy link
Member Author

fiatjaf commented Aug 9, 2024

That's the same as telling everybody you have to support both forever because you never know if you'll receive a NIP-04 or a NIP-44.

@erskingardner
Copy link
Contributor

That's the same as telling everybody you have to support both forever because you never know if you'll receive a NIP-04 or a NIP-44.

I mean, that is basically true anyway though right? Even if we deprecate NIP-04 some clients won't update and we'll still have NIP-04 events around.

@fiatjaf
Copy link
Member Author

fiatjaf commented Aug 9, 2024

I mean, that is basically true anyway though right? Even if we deprecate NIP-04 some clients won't update and we'll still have NIP-04 events around.

The idea here is that we will remove, delete, drop, erase NIP-04. If that doesn't happen then I'll consider this a failure and then drop NIP-44 instead from my stuff.

What do you mean by "having events around"? These events are ephemeral.

@alltheseas
Copy link
Contributor

alltheseas commented Aug 9, 2024

If there is no way to technically identify lack of compatibility between apps A and B, and surface that to the non-technical app end user, then maybe the simplest way to inform or warn of the poor UX is to say:
-for nip-04 apps, app is only compatible with damus, app Y, app Z etc
-for nip-44 apps, app is only compatible with apps listed in table at the top of this thread

And place the onus on the end user to find out which app(s) their counterparty is using. I think @staab has a similar approach in Coracle DMs.

@karnagebitcoin @robagreda is there a superior design solution in the case of incompatible DM (and potentially other feature) standards?

@staab
Copy link
Member

staab commented Aug 9, 2024

This migration has three steps:

  1. Signers add support for both nip 04 and nip 44
  2. Clients stop sending nip04-encrypted events
  3. Signers drop support for nip04

Knowing whether we can safely take step 3 is the hard part. Signers could monitor requests and update a database somewhere, or the devs could talk to each other, but I've drafted a general-purpose solution to problems like this here: https://github.com/nostr-protocol/nips/pull/1048/files, which would allow clients to signal that they've moved to the new way of doing things.

@staab
Copy link
Member

staab commented Aug 9, 2024

Also, I'm confused, are we talking about the nip46 encryption algorithm only, or DMs? Coracle supports new-style DMs, but I can't confidently move my nip 46 implementation to nip44 until I know it's supported by all the signers people might use.

@fiatjaf
Copy link
Member Author

fiatjaf commented Aug 9, 2024

This issue is just about nip46 encryption, but @alltheseas is talking about DMs for some reason.

@staab
Copy link
Member

staab commented Aug 16, 2024

I added support for using nip46 encryption to welshman this morning, and tested it in Coracle against nsec.app, but it looks like 44 isn't yet supported there. I'm ready to upgrade, but signers have to go first.

@vitorpamplona
Copy link
Collaborator

vitorpamplona commented Aug 28, 2024

I just merged Amethyst's NIP-46 impl and we will be doing nip44 encryptions out of the gate.

@ekzyis
Copy link

ekzyis commented Oct 9, 2024

According to nostr-dev-kit/ndk@722345b, ndk also supports both now.

@pablof7z
Copy link
Member

how about we just change the kind number and use nip44 on this new kind number? far less coordination required.

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 25, 2024

how about we just change the kind number and use nip44 on this new kind number? far less coordination required.

It doesn't help, a client using nip44 will still not be understood by a bunker using nip04.

@vitorpamplona
Copy link
Collaborator

Can we all agree that the plan below is not hard to code? This is so small that, to me, projects that are not doing this should be considered abandoned and should not be used by anyone anymore.

  1. Everybody decrypts both nip 04 and nip 44:

Use the utility function below to pick which decryption to use

fun isNIP04(ciphertext: String): Boolean {
    val l = ciphertext.length
    if (l < 28) return false
    return ciphertext[l - 28] == '?' && 
           ciphertext[l - 27] == 'i' && 
           ciphertext[l - 26] == 'v' && 
           ciphertext[l - 25] == '='
}
  1. Everybody starts encrypting with NIP44 in their own timeline.

Just rename the function to call nip-44 instead of nip-04 methods.

  1. Later, everybody drops support for 1.

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 25, 2024

What is the state of Coracle, Highlighter and nsec.app?

@staab
Copy link
Member

staab commented Oct 25, 2024

Coracle is ready to use nip44 once signers start supporting it

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 26, 2024

Looks like we have basically 100% buy-in at this point, just missing @nostrband.

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 26, 2024

I just modified nak bunker to always use NIP44 encryption and found that it didn't work on Highlighter or nostr-login (it also didn't work on nak itself acting as a client, but at least I fixed that). I also tested Coracle and window.nostr.js and they worked. I don't know how to use NIP-46 on Amethyst, is it possible to login to Amethyst with NIP-46? I couldn't find a way. Also Snort seems to have removed NIP-46 support entirely.

@vitorpamplona
Copy link
Collaborator

No, the support for nip46 is just for quartz, our nostr lib.

NIP-46 on amethyst goes through Amber. We had an early nip46 signer, but I removed it since Amber is the right way to do this.

We can't use remote nip46 because Amethyst decrypts 400s events a second when loading.

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 27, 2024

The next versions of go-nostr, nak, nostr-tools and window.nostr.js will only encrypt with nip44, but will continue to decrypt nip04/nip44.

@pablof7z
Copy link
Member

Next version of ndk will only encrypt and decrypt using nip44 by default.

@alexgleason
Copy link
Member

alexgleason commented Oct 27, 2024

For bunkers that say they support this, eg Amber, if my app sends a NIP-44 encrypted message will you detect that and automatically send me back a NIP-44 encrypted response?

I don't really want to support automatic detection in my app. I want to go all-in on nip44 and just throw an error if the bunker sends me a nip04 encrypted message.

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 27, 2024

@alexgleason nak bunker wouldn't do that because it's annoying. Instead it just tries to decrypt both formats, then responds with a hardcoded one. For now it's nip04, later it will be just nip44.

I thought the plan was that everybody would do this, no need to detect anything, just try to decrypt both, respond with a single.

@greenart7c3
Copy link
Contributor

Amber detect if it's a nip04 or nip44 and sends the same kind in the response

@alexgleason
Copy link
Member

@fiatjaf Maybe you can add a flag to nak bunker like --encryption nip44 --encryption nip04

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 27, 2024

No, please, that would be too hard.

@alexgleason
Copy link
Member

I think the 2D graph in the original post doesn't adequately express what needs to happen, because it's not as simple as "supporting encrypt/decrypt". Here is a writeup of the whole situation.

The Plan

This is a clarification of what the current plan is. This plan has challenges. It may not be the best plan, but it's what we are all currently doing.

  • 1. All bunkers must auto-decrypt, but they will continue to send back nip04 encrypted messages. (Smart bunkers like Amber can also set the encryption for the session based on the encryption of the connect call)
  • 2. Once bunkers auto-decrypt, all apps must start sending nip44 requests. Apps must auto-decrypt responses from the bunker.
  • 3. Once apps send nip44 requests, bunkers must start only sending nip44 responses, and stop sending nip04 responses.
  • 4. Auto decryption is removed from both apps and bunkers. Only nip44 is used for the entire flow.

Bunkers

On the path to nip44-only, bunkers need to first decrypt automatically, and then start only sending nip44 messages once there is enough client support.

Bunker auto-decrypt auto-encrypt nip44-only encrypt nip44-only decrypt
nsecBunker ?
nak ✔️
amber ✔️ ✔️
nsec.app

Definitions

  • auto-decrypt - The bunker automatically detects the encryption of requests from apps. It decrypts both nip04 and nip044 encrypted messages automatically.

  • auto-encrypt (optional) - The bunker checks the encryption used by the app in the connect call, and then automatically uses the same encryption for responses for that session. Mutually exclusive with "nip44-only encrypt".

  • nip44-only encrypt - The bunker only sends nip44-encrypted responses. It does not send nip04-encrypted responses under any circumstances. Mutually exclusive with "auto-encrypt".

  • nip44-only decrypt - The bunker throws an error when requests are nip04 encrypted. It only decrypts nip44 requests. Mutually exclusive with "auto-decrypt".

Apps

Apps need to auto-decrypt responses from bunkers, but will continue to send nip04 requests until bunkers fully support auto-decryption.

App auto-decrypt nip04-only encrypt nip44-only encrypt nip44-only decrypt
gossip ✔️ ✔️
amethyst ✔️ ✔️
highlighter ✔️ ✔️
snort ✔️ ✔️
coracle ✔️ ✔️
ndk ✔️ ✔️
nostrify ✔️ ✔️
nostr-tools ✔️ ✔️
go-nostr ✔️ ✔️
rust-nostr ✔️ ✔️
nostr-login ✔️ ✔️
window.nostr.js ✔️ ✔️
ditto ✔️ ✔️

Definitions

  • auto-decrypt - The app automatically detects the encryption of responses from bunkers. It decrypts both nip04 and nip44 encrypted messages automatically.

  • nip04-only encrypt - The app only ever sends nip04 encrypted requests to the bunker. There is no way for apps to detect the encryption supported by the bunker, so it cannot make this choice automatically. Mutually exclusive with "nip44-only encrypt".

  • nip44-only encrypt - The app only ever sends nip44 encrypted requests to the bunker. Mutually exclusive with "nip04-only encrypt".

  • nip44-only decrypt - The app throws an error when bunker responses are nip04 encrypted. Only nip44 responses are accepted, and nip04 support is removed entirely.

State of the Landscape

Virtually all nip46 apps have implemented "auto-decrypt", but they are blocked from switching to "nip44-only encrypt" until all bunkers support auto-decrypt.

Although auto-decryption is possible on both sides, apps cannot auto-encrypt because there is no way to detect the feature from bunkers. There are 4 possible ways to remedy this:

  1. Do try to auto-encrypt. Send a nip44 request first, and if the bunker returns an error, fallback to nip04. However there is no standard error message, so this method would be fragile and hacky. There is no solution to that that doesn't involve the bunker being updated, and if the bunker were to be updated it should just be updated to support auto-decrypt. This solution is not recommended.

  2. Extend the spec to negotiate the encryption in bunker:// URIs. Adding a param like &encryption=nip44 would enable the bunker to signal to the app that it should use nip44 encryption. This way we could move progress forward in apps without 100% buy-in from bunkers.

  3. Just wait for all bunkers to auto-decrypt before moving apps forward. This is what we're currently doing.

  4. Simply ignore the fact that some bunkers don't support auto-decrypt and move apps forward anyway, breaking compatibility with those bunkers.

As you can see, even though there is much work being done on a single column of this plan, we are a bit stuck from actually moving forward. It's a chicken and egg problem. But even if we are brave and accept option 4 (as I am prepared to do today), we will then hit the next wall, which is that bunkers will continue to send back nip04 responses, so apps cannot remove it entirely. Therefore I've written this entire blog post as a justification for why @fiatjaf should add an --encryption flag to nak bunker. Just kidding. But maybe we should just switch it to nip44 in the text today, "break everything", the whole world explodes etc but we change it overnight instead of waiting 6 years and building all these "flexible" clients that will probably never remove that flexibility while still not even being able to do the thing they're supposed to do. And I think @fiatjaf should push that change directly to master and everyone will scream at him for being a dictator for 5 minutes then we'll have immediate nip44 support and I will delete this post.

@nostrband
Copy link
Collaborator

Looks like we have basically 100% buy-in at this point, just missing @nostrband.

I missed this thread. Will auto-decrypt in nsec.app and nostr-login asap.

@fiatjaf
Copy link
Member Author

fiatjaf commented Oct 28, 2024

I think @alexgleason's post is important and mostly correct, I disagree with some small details but I don't want to write an essay right now so I will just say nothing.

@nostrband
Copy link
Collaborator

Nsec.app auto-decrypts now.

@arthurfranca
Copy link
Contributor

@fiatjaf please consider #1598

@staab
Copy link
Member

staab commented Nov 22, 2024

Welshman/coracle/flotilla will now encrypt using nip 44 by default, starting with the next release. Bunkers that don't support nip 44 decrypt I'll just consider broken at that point. Now seems like a good time to do this since bunkers are mostly broken right now anyway.

@fiatjaf
Copy link
Member Author

fiatjaf commented Nov 22, 2024

If anyone is still encrypting with nip04 this is the time to start encrypting with just nip44.

Once there is no one else encrypting with nip04 we can drop support for decrypting nip04 everywhere.

@arthurfranca
Copy link
Contributor

@fiatjaf please consider #1598

oops I thought this PR was updating many NIPs from nip04 to nip44 like private nip51 lists and everything else that uses encryption on events

didn't see it was just for nip46

@mikedilger
Copy link
Contributor

Yes the title of this PR is very confusing. It looks like "nip46:" is just a random suggested NIP number, and the purpose of the new nip is to deprecate NIP-04 decryption everywhere. But this is actually only about deprecating NIP-04 encryption within NIP-46. I would change the title to make it more clear (the confusion happened many times already)

@dukeh3
Copy link

dukeh3 commented Dec 5, 2024

Can we please do this is some form of structured way? Currently NIP46 says that you should use NIP04, and nothing else.

If you want to change that then NIP46 should, at least be updated, and if possible this should be handled in a backward compatible way. Now there are (ofc) reasons why NIP44 might be preferred, and if NIP04 is dangerous (and a case can be made here), Then NIP46 should be updated that says that you should NOT use NIP04.

My recommendation is that we find a way to clear this up.

@fiatjaf
Copy link
Member Author

fiatjaf commented Dec 5, 2024

Good point, I think we can merge this now. Any objections?

@staab
Copy link
Member

staab commented Dec 5, 2024

Decrypt looks like it's universally supported (nsec.app also supports decrypt, except for create_account). I say it's time.

@staab
Copy link
Member

staab commented Dec 5, 2024

if possible this should be handled in a backward compatible way

See the prior discussion, implementations added support for detection of algorithm so either nip 04 or 44 will work on the receiving side. Merging this signals that people can start sending nip 44 messages with a reasonable amount of confidence that they'll be accepted.

@fiatjaf fiatjaf merged commit 6d16019 into master Dec 5, 2024
@fiatjaf fiatjaf deleted the 4644 branch December 5, 2024 23:14
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.