Skip to content

Commit b66dfc8

Browse files
committed
Apply suggestions from code review
1 parent d7e7ab8 commit b66dfc8

2 files changed

Lines changed: 9 additions & 20 deletions

File tree

00.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,6 @@ A `Proof` is also called an _input_ and is generated by `Alice` from a `BlindSig
9595

9696
`amount` is the amount of the `Proof`, `secret` is the secret message and is a utf-8 encoded string (the use of a 64 character hex string generated from 32 random bytes is recommended to prevent fingerprinting), `C` is the unblinded signature on `secret` (hex string), `id` is the [keyset id][02] of the mint public keys that signed the token (hex string).
9797

98-
> [!NOTE]
99-
> A proof may optionally be extended by other NUTs. These include:
100-
>
101-
> - [NUT-28][28]: Pay-to-Blinded-Key - adds `"p2pk_e": hex_str` to store an ephemeral pubkey
102-
10398
## 0.2 - Protocol
10499

105100
### Errors
@@ -282,11 +277,6 @@ If a short keyset ID resolves to more than one known full keyset ID, the identif
282277

283278
The mint is unaware of the `s_id`. All API endpoints exposed by the mint use the full keyset ID.
284279

285-
> [!NOTE]
286-
> The token format may optionally be extended by other NUTs. These include:
287-
>
288-
> - [NUT-28][28]: Pay-to-Blinded-Key - adds `"pe": bytes` to individual proofs
289-
290280
##### Example
291281

292282
Below is a TokenV4 JSON before CBOR and `base64_urlsafe` serialization.
@@ -357,4 +347,3 @@ utf8("craw") || utf8(<token_version>) || <serialised_token>
357347
[10]: 10.md
358348
[11]: 11.md
359349
[12]: 12.md
360-
[28]: 28.md

28.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,17 @@
1010

1111
This NUT describes Pay-to-Blinded-Key (P2BK), which extends the [NUT-11][11] (P2PK) spending conditions. By implication, it also extends [NUT-14][14] (HTLC).
1212

13-
P2BK preserves privacy by blinding each NUT-11 receiver pubkey `P` with an ECDH-derived scalar `rᵢ`. Both sides can deterministically derive the same `rᵢ` from their own keys, but a third party cannot.
14-
15-
This brings _"silent payments"_ to Cashu: Proofs can be locked to a well known public key, posted in public without compromising privacy, and spent by the recipient without needing any side-channel communication.
13+
P2BK preserves privacy by blinding each NUT-11 receiver pubkey `P` with an ECDH-derived scalar `rᵢ`. Both sides can deterministically derive the same `rᵢ` from their own keys, but a third party cannot. This improves user privacy by preventing the mint from linking multiple P2PK spends by the same party.
1614

1715
## ECDH Shared Secret (Zx)
1816

19-
ECDH allows two parties to create an x-coordinate shared secret (`Zx`) by combining their private key with the public key of the other party: `Zx = x(epG) = x(eP) = x(pE)`.
17+
Elliptic-curve Diffie–Hellman (ECDH) allows two parties to create an x-coordinate shared secret (`Zx`) by combining their private key with the public key of the other party: `Zx = x(epG) = x(eP) = x(pE)`.
2018

2119
For P2BK, the sender creates an ephemeral keypair (private key: `e`, public key: `E`). This protects the privacy of their own long-lived public key. They then calculate the shared secret by combining the ephemeral private key (`e`) and the receiver's long-lived public key (`P`).
2220

23-
The receiver calculates the same shared secret using their private key (`p`) and the ephemeral public key (`E`), which is supplied by the sender in the [proof metadata](#proof-object-extension).
21+
The receiver calculates the same shared secret `Zx` using their private key (`p`) and the ephemeral public key (`E`), which is supplied by the sender in the [proof metadata](#proof-object-extension).
2422

25-
This shared secret is then used to derive the blinded public keys.
23+
The shared secret `Zx` is then used to derive the blinded public keys.
2624

2725
## Deriving Blinded Public Keys
2826

@@ -61,7 +59,9 @@ Finally, the public key (`P`) for slot `i` is blinded (`P'`) as follows:
6159
P' = P + rᵢG
6260
```
6361

64-
Here is a code example in TypeScript:
62+
### Example
63+
64+
Below is an example implementation in TypeScript.
6565

6666
```ts
6767
function deriveP2BKBlindingTweakFromECDH(
@@ -105,7 +105,7 @@ Each proof adds a single new metadata field:
105105
"id": hex_str,
106106
"secret": str, // still ["P2PK", {...}]
107107
"C": hex_str,
108-
"p2pk_e": hex_str // 33-byte SEC1 compressed ephemeral public key E
108+
"p2pk_e": hex_str // NEW: 33-byte SEC1 compressed ephemeral public key E
109109
}
110110
```
111111

@@ -118,7 +118,7 @@ Each proof adds a single new metadata field:
118118

119119
With P2BK, the NUT-11 public locking keys are permanently blinded. The mint sees only the blinded public keys, and expects signatures from the corresponding private key.
120120

121-
The receiver must therefore derive the correct blinded private key. Because BIP-340 lifts public keys to even-Y parity, there are two possible derivation paths:
121+
The receiver must therefore derive the correct blinded private key (`k`). Because BIP-340 lifts public keys to even-Y parity, there are two possible derivation paths:
122122

123123
- Standard derivation: `k = (p + rᵢ) mod n`
124124
- Negated derivation: `k = (-p + rᵢ) mod n`

0 commit comments

Comments
 (0)