-
Notifications
You must be signed in to change notification settings - Fork 685
Added optional signString() method #1842
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
base: master
Are you sure you want to change the base?
Conversation
Can you add the methods in nip 46 and 55 too? |
I've added a signature for the method to NIP-46. I've made it more generic than NIP-55 seems to be a primer for specific implementation of the methods defined in NIP-07. |
@fiatjaf - I think defining the broader return object But as per @greenart7c3 comment above, some apps, including Alby are just returning e.g. Alby :: Would you prefer the object return as drafted, or stick with the unoffically adopted single string return? |
We've had all sorts of discussions in the past about this, I don't see what has changed. In fact NIP-60 has shown that we don't need this at all to use Cashu with Nostr, have you taken a look at that? Also, any signer is free to implement this as well as they are free to implement other signing algorithms, but none of it is related to Nostr at all so the specification shouldn't live in this repository. |
I understand your position - what's changed is that it's 2025, and Nostr users expect to keep their SK private and use a signer for operations where their Nostr identity is involved. We are (thankfully) moving away from "enter your nsec" type applications. I agree that adding a plethora of signing algorithms would be undesirable... issue #292 highlighted this floodgate. There is already established demand for it (Alby, 0xchat, Keychat, Cashu P2PK), and even though it's an optional, it's important because applications need to know the interface they are working with. Cheers Ps - I have indeed looked at NIP-60. The P2PK unlocking of tokens manually locked to an npub is not related to nutzaps. But that's a side issue... it was simply a concrete example use case for signing. |
aa19d24
to
39bf3cd
Compare
Have tweaked it into line with existing signer implementation (Alby) to maximize backwards compatibility with existing apps. |
… to avoid backwards incompatibility in the wild
On reflection, I've reversed the attempt to align the proposed method with the existing Alby method signature. Nostr events are always presented to the user in raw form for signing, and I believe it is safer and more consistent to do the same in this new method, so the user can be sure they are not signing something unintended or malicious. The Alby Extension signSchnorr() method takes a hash input, not the original message string, and only returns the signature, so to increase flexibility and remove potential backwards incompatibility, I've renamed the proposed method to The new I believe this presents the most flexible and future-proofed method for signing non-event structured messages. |
For completeness, here's a pseudo-code stub for the method itself:
|
@fiatjaf - here's another reason why you should add this PR: You cannot control what you do not specify. The core of the Nostr protocol is the Schnorr signed Event. That makes Schnorr an integral part of what makes Nostr so brilliant and special. And there is clearly demand for Schnorr signing of messages outside of the event structure. If you do not protect that by specifying a Schnorr message signing method, you risk undermining NIP-07. Why? Because a Schnorr signer like the existing Alby With this PR, you ensure signers use Schnorr in a structured, controlled way. As you'll see, I've submitted PRs for nos2x and AKA Profiles that protects the core Nature abhors a vacuum. Please reconsider filling this one. |
I merged Rob's PR with signString() into AKA Profiles Signing Extension. I haven't been active in the Nostr space for awhile, but the old guidelines were a certain number of implementations before making a change to a NIP. So +1. I actually agree with @fiatjaf that because its not strictly Nostr related it should not be in the NIP. (He is bombarded with requests, and has to hold the line somewhere). That said, more than happy to continue to add features to my signing extension, and put links in my readme to pull requests that describe new functionality. |
NACK.
This is wrong - signEvent signs event id, not it's content, from nip01:
So I can create an event, calculate it's id, sign id with signString and publish the event, bypassing the permissions. |
@nostrband - The signString() method, as specified, computes the hash of the string and signs it. This would NOT result in a valid event, as it would be a hash of a hash. |
Ok sorry for not reading this deep enough. This signString method should then be called signStringSha256? Won't there be requests for sha512 tomorrow? Maybe hashing algo should also be provided and method called signStringHash? |
Alby’s really leading the way here with a solid implementation. I think NIP-07 is in a good spot to be standardized. There’s growing interest even outside the Nostr space, so maybe it’s time to think about this as a proper web standard. Would be great if browser vendors could eventually support it natively too. On the Trezor front, maybe we just add a quick Security Considerations section. Could also patch the current extension or spin up a second one to handle that flow. This opens up all sorts of use cases—it might help to jot a few down to show the range. But yeah, feels like this needs to happen to get more folks aligned with the great work Alby’s already doing. |
FWIW: I have implemented a full bitcoin testnet and nostr wallet using alby's amazing signSchnorr function here: It allows getting coins from a faucet, proof-of-publication for nostr identities, sending coins to other npubs, and OP_RETURNs. Testing on testnet4 but would just be one param for main net leading to native on-chain payments, zaps and utxo management. signSchnorr is critical, and needs to be done. The alby way works. I would be very hesitant to change anything. |
In drafting this PR, I've been pretty conscious to avoid stepping outside core Nostr ecosystem. The concerns of scope-creep are real, and I also agree that Nostr should not support any and all random signers/algos as part of core protocol. I make an exception for If, in time, Nostr
I'm thrilled that Alby has led the way, and the demand for this type of method is real. However, I believe the current Alby This is also why I'm keen to formally establish a "safer" method within the NIPs. Migrating from That said, there is no reason Alby or other signers could not informally support OTHER signing/hashing methods as well. I just think the NIP needs to protect its core algo (Schnorr signed SHA256 hash of UTF8 string). |
Are there any signer had implemented it? And Are there any client has used it? Can you show me some use case. I want to test it if i had implemented it. |
Yes, it is I currently implemented by AKA Profiles signer: it is pending review in nos2x: it is used in Cashu Redeem: |
Cashu Witness also uses it: |
This is really not a Nostr-related proposal at all. It would make more sense as |
The Cashu-P2PK use case is a valid one, but NIP-60 has already solved it by keeping a different key for the Cashu wallet and sharing it around with every Nostr/NIP-60 client. That same key could be used in P2PK. |
Would supercede #1026 NIP60/61 helps, but does not solve the case where a users Nostr pubkey has been used as the p2pk lock. With this addition, Nostr becomes the identity layer for countless apps… Example: |
To cover the Cashu P2PK case without exposing users to a risk of signing data they don't agree with, the method could be limited to only signing NUT-10 well-known secret structures that look like this:
This should still cover all Cashu-related use cases for now and in the future. |
Delegation (NIP-26, deprecated) requires signing of the hash of the delegation string, and while adding nip-46 support to gossip I ran into the problem that NIP-46 doesn't offer any method to do that. I'm not saying it should, just to be aware that this is/was another use case for signString(). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blind signing is not a good idea.
How is it blind? The raw json is visible to user. That said, am more in support of the NUT-10 specific signSecret for the identified Cashu use cases. |
Anything that is not shown in a format that the user can easily understand the implications of without technical knowledge may as well be blind signing. |
No difference to a Nostr event. And a signer could “pretty it up“. That makes this version much “safer” than the leading signString implementation, which shows the user a SHA-256 string to sign. But again, am now favoring the #1890 PR, which signs NUT-10 format secrets only. This has a specific use case for Cashu integration. |
Allows Nostr users to sign/authenticate messages for external apps without compromising their private key (nsec).
It opens up a more generic and flexible challenge-response style external authentication method, using the same Schnorr signature mechanism that Nostr uses to sign events natively.
External apps need only understand Schnorr signatures - they do not need to understand Nostr's event structure. This widens interoperability.
A concrete example of where this would be useful is P2PK locking of Cashu ecash tokens to a Nostr pubkey (npub). Decoding the token requires a Scnorr signature on a structured message string. This method would allow a signer to handle It cleanly.
Would close: #292