Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions 12.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ The complete DLEQ proof reads
(These steps occur when Bob returns C')

Bob:
r = random nonce
r = HMAC-SHA256(key=a, data="Cashu_DLEQ_R_v1" || A || B' || C' || 0x00) mod n
R1 = r*G
R2 = r*B'
e = hash(R1,R2,A,C')
s = r + e*a
s = (r + e*a) mod n
return e, s

Alice:
Expand Down Expand Up @@ -51,6 +51,20 @@ def hash_e(*publickeys: PublicKey) -> bytes:
> [!NOTE]
> For examples of valid DLEQ proofs, see the [test vectors][tests].

### Nonce derivation

`r` **SHOULD** be derived deterministically from the private key and proof context:

```
r = HMAC-SHA256(key=a, data="Cashu_DLEQ_R_v1" || A || B' || C' || ctr) mod n
```

`a` is the 32-byte secp256k1 private key scalar, encoded as big-endian bytes. `A`, `B'`, and `C'` are uncompressed SEC1 (65 bytes each). `ctr` is a single byte starting at `0x00` and incremented if `r == 0` (max 256 attempts).

This removes a dependency on RNG quality. Reusing `r` across two proofs with different challenges leaks the private key immediately via `a = (s₁ - s₂) · (e₁ - e₂)⁻¹ mod n`.

Mints that use random nonces instead **MUST** source them from a cryptographically secure RNG.

### Mint to user: DLEQ in `BlindSignature`

The mint produces these DLEQ proofs when returning `BlindSignature`'s in the responses for minting ([NUT-04][04]) and swapping ([NUT-03][03]) tokens. The `BlindSignature` object is extended in the following way to include the DLEQ proof:
Expand Down
18 changes: 18 additions & 0 deletions tests/12-tests.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,24 @@ C_: "02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2"
hash(R1, R2, K, C_): "a4dc034b74338c28c6bc3ea49731f2a24440fc7c4affc08b31a93fc9fbe6401e"
```

## Deterministic nonce derivation

The following vectors verify the deterministic `r` derivation. All values are fixed; an implementation **MUST** reproduce `e` and `s` exactly.

```shell
a: 0000000000000000000000000000000000000000000000000000000000000002
A: 02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5
B_: 02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2
C_: 0244eccfc7a348274458bb38044c7f3c389b3c2086c7ec18b5812d2877ab937787
```

```shell
e: 2a16ffee280aff3c429045607f9b8e0bf8b35910c44c1b20b9dfaf01b263d7b3
s: 9df27731238334718d120d4f74611a7c668233f988e687ac3fb188f0a34a2dab
```

Verification (`e == hash(R1, R2, A, C_)`) **MUST** pass.

## DLEQ verification on `BlindSignature`

The following is a `BlindSignature` with a **valid** DLEQ proof.
Expand Down
Loading