I guess that's the end of my attempts to do the exact opposite π nostr:note154fktkfdycyyrntcw9qv8ry29mcjmmgxqwegvl6dkduehu49kresg60hss
Mining block 820132 took 98 minutes. In the next 3 minutes, 3 blocks followed. https://stacker.news/items/342425
Pretty basic construction of Nostr silent DM's that break the DM graph privacy nightmare.
Others probably have suggested the same thing because it's too damn simple and obvious of a solution. Still gonna put it up here, maybe someone has comments. Might become a NIP proposal if there is interest.
I've coded it up and it works quite nicely.
https://void.cat/d/6gXGCYLJXqEeu4emNkM5TA.webp
Apart from the shared secret issue, one thing not addressed here is sender authentication.
Assuming the encryption key is `S' = w * Q2`, since the sender signs with the ephemeral key `w`, unless the recipient can somehow verify that `w` belongs to the intended counterparty, the recipient has no way of authenticating the sender.
Anyone who correctly guesses one of the participants of the silent inbox (e.g. a relay operator would be able to trivially figure this out in many cases) can send a DM to that participant with an ephemeral private key of their own, pretending to be the other participant.
What you could do is hash the shared secret curve point `S` (preferably using a tagged hash function) into a shared private key `r`, then use the corresponding public key `R = r * G` for the `p` tag. This would not leak the actual shared secret.
Maybe something's missing in the pictures. Note that I'm not talking about decrypting *silent inbox* DMs. Here's an example of it going wrong as I understand it:
First, Alice (keypair p1, Q1) sends Bob (keypair p2, Q2) a *regular* NIP-04 DM (no silent inbox).
NIP-04 uses shared secret `S = p1 * Q2 = p2 * Q1` to encrypt the message. In NIP-04, this is given in the example code as:
`let sharedPoint = secp.getSharedSecret(ourPrivateKey, '02' + theirPublicKey)`
Eve also picks up this DM. She sees that Alice sent Bob a DM of a certain length at a certain point in time. She can't decrypt it yet, but stores it in her collection for later.
Next, they Bob decides to try using a silent inbox. This time, Bob sends a message to Alice.
Silent inbox uses shared secret `S = p1 * Q2 = p2 * Q1` (from the picture titled "Shared Secrets").
Bob constructs the event using an ephemeral key `w`, encrypting to `Q1` (I presume using `w * Q1` as the NIP-04 encryption key, but this is not relevant to the attack). She puts `S` in the `p` tag of the event and signs it (from the picture titled "Send and receive flow").
Eve also picks up this DM. She doesn't yet know its sender or recipient, but she reads the `p` tag and starts trying to decrypt the DMs she's got in her collection one by one, using the contents of the `p` tag as the shared secret.
One of the DMs does decrypt to a valid message, namely the first, regular, DM from Alice to Bob. Eve can now decrypt every past and future regular (not silent inbox) DM between Alice and Bob. Furthermore, while Eve can not decrypt silent inbox messages due to the use of different encryption keys here, she learns that the silent inbox in question belongs to Alice and Bob and can see the length and timing of each message going to it.
NIP-92: Rendezvous Beacons (draft; https://github.com/nostr-protocol/nips/pull/333 ) enables anonymous establishment of communication between two parties, addressing the issue of receiving messages from unknown contacts.
A shared secret is derived using ECDH like in NIP-04, but this shared secret is only used through *tagged hashes*, with a different tag (not to be confused with nostr tags) for each purpose.
From the shared secret, a *rendezvous keypair* is established, where the sender knows the private key and the recipient knows the public key. This is done by tweaking the sender's key (an ephemeral key in the case of NIP-92) using a tweak value derived from the shared secret.
Pretty basic construction of Nostr silent DM's that break the DM graph privacy nightmare.
Others probably have suggested the same thing because it's too damn simple and obvious of a solution. Still gonna put it up here, maybe someone has comments. Might become a NIP proposal if there is interest.
I've coded it up and it works quite nicely.
https://void.cat/d/6gXGCYLJXqEeu4emNkM5TA.webp
I'd be uneasy about a supposed "shared secret" being put in a public `p` tag.
Indeed, AIUI, using a silent inbox as presented here completely breaks the security of any past and future regular NIP-04 DMs between the same parties, because the same "shared secret" used for encryption in regular NIP-04 DMs is being used publicly in the silent inbox. An attacker doing trial and error decryption of NIP-04 DMs would be able to decrypt all regular DMs between the two, as well as deanonymize the silent inbox.
Seems like Binance has currently queued up at least 5 blocks worth of panic consolidation transactions in the mempool at 201 sat/vB for a total of at least 10 BTC in transaction fees. https://mempool.space/address/bc1qm34lsc65zpw79lxes69zkqmk6ee3ewf0j77s3h
Every time we come up with a way to implement some Twitter feature on Nostr we discover that it was implemented in exactly the same way as on Twitter.
Today I found out that, much like NIP-18 reposts, a "retweet" is a normal tweet with the full text of the thing being retweeted copied below after "RT @username".

For reference: https://twitter.com/fiatjaf/status/1655170785944674304
Twitter didn't have retweets originally, they introduced a retweet feature in 2009. The "RT @twitterhandle" form started as a convention among users a year or two earlier. Twitter may have implemented their APIs in a backwards-compatible way by presenting their later implementation of retweet as such to older clients, though I'm pretty sure their internal representation of a retweet would be different.
Whoever is consolidating multisig utxos right now is getting absolutely rekt
https://mempool.space/tx/91b8def136d9b261dd23082dad6424f1d3e324107ab096eda5648b3cd269e0bc
Some of the inputs don't even cover the cost of including them!
Since nostr uses Schnorr signatures, it already supports n-of-n multisig. Though in this case I guess you're thinking of something where not all users need to sign?
Maybe not (see: Deniable authentication)
I don't like the concept of duplicating the original event and putting its json in the content. There's a lot of duplication and it's not trivial for a relay to deduplicate as the original event can be serialized in countless different ways.
Rather have the relay optionally send the original event alongside the (first) repost event.
Not gonna compromise my on-chain privacy for the sake of keeping some pocket money secure. Sorry not sorry.
Relays shouldn't have to be trusted.
It's not really true that you need a full node to verify OTS timestamps, you can use an SPV-like trust model where you just have the Bitcoin block headers and check their POW. The headers are just 80 bytes per block.
NIP-03: OpenTimestamps Attestations for Events
With confidential amounts you'd have better anonymity guarantees. With public denominations, each denomination effectively has its own anonymity set, which might especially affect user anonymity when different denominations are combined, and the issuer knows a per-denomination lower bound on a user's funds and upper bound on amounts being transferred between users.
I'm still trying to wrap my head around the cryptography needed for confidential amounts. I think each token has to be bigger by some constant factor, but each user only needs to store a single token. And someone might have a single token worth 4.2 BTC and remain in the same anonymity set as someone with a balance of 69 sat.
UX-wise there should be no difference, but it could be made insanely private, with the issuer not even knowing whether a particular user is sending, receiving or just renewing a token.
When the client adds `"nip05valid":true` to the public profile ποΈ

The new generation of ecash wallets is looking pretty good π
How it started:
https://void.cat/d/Bx1tTwXi1TsvpGVUDaVESM.webp
How it's going:
Cashu tokens are still power-of-2 denominations, right?
Wen confidential amounts?
Please do not accept invalid events in your client. Do not accept non-integer "created_at" values, do not accept non-string-array on "tags", do not accept bech32-encoded keys as tag values. Every time you do that, Nostr dies a little.
For more information on how this kills Nostr, read https://fiatjaf.com/27598e6f.html
Idea: Relay that only serves events that are slightly corrupted in different ways, if your client accepts any of them, it's broken
#[0]