Blinding the locking keys in NUT-11 #290
Labels
No labels
breaking change
bug
documentation
enhancement
needs discussion
needs implementation
new nut
ready
wallet-only
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo-admin/nuts#290
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The problem
The current state of NUT-11 provides that we input the public key itself into the well known secret structure:
This means that, during redemption, we provide the unblinded secret that exposes the public key to the Mint. If this public key represents a Nostr identity or in general is not ephemeral (e.g. is re-used multiple times), the Mint is able to tell who is claiming the payment.
Blinding the key
Let
Pbe the public key033281c37677ea273eb7183b783067f5244933ef78d8c3f15b1a77cb246099c26e.Instead of locking to
P, we could lock toP' = P + r \cdot G, whereris a random scalar.Then the sender can include
rtogether with the payment, for example it could be included in theProofobject:The receiver can calculate the correct signing key by combining their secret key
pandr:k = p + r.So as you can see this requires no alterations to the verification logic of the Mint. It's all client side.
Result
With this hack, the Mint is no longer able to see the real public keys the ecash is being locked to.
Update - 2025-10-20
We've discussed the scheme further and improved on it, inspired by silent payments. The new scheme works as follows:
Pis still the receiver's public key, andpis the respective private key, known only to the receiver.}\leftarrow \mathbb{Z}_q, whereqis the order of the secp256k1 curve, and sendsE = e \cdot Gasp2pk_eadditional field in theProofobject.Z = e \cdot P = p \cdot E.Zis derived, the blinding factors follow with a KDF function:r_i = SHA256(domain_separator || x-only(Z) || keyset_id || i)Where
i \in [0, 9]such that each key gets its own blinding factorThe result is a new P2BK scheme which is truly silent in the sense that, even with the Mint eavesdropping on public channels, they wouldn't be able to unblind the keys in the secret.