From b7152f5d61707bc4fadd668c6af91cbdec26d43f Mon Sep 17 00:00:00 2001 From: callebtc <93376500+callebtc@users.noreply.github.com> Date: Wed, 4 Dec 2024 17:43:18 +0300 Subject: [PATCH] edit pass --- 04.md | 5 ++++- 20.md | 64 ++++++++++++++++++++++++++++++++--------------------------- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/04.md b/04.md index e3f7a28..c0c6d59 100644 --- a/04.md +++ b/04.md @@ -2,6 +2,8 @@ `mandatory` +`used in: NUT-20` + --- Minting tokens is a two-step process: requesting a mint quote and minting new tokens. Here, we describe both steps. @@ -49,7 +51,8 @@ Where `quote` is the quote ID and `request` is the payment request to fulfill. ` - `"PAID"` means that the request has been paid. - `"ISSUED"` means that the quote has already been issued. -Note: `quote` is a **unique and random** id generated by the mint to internally look up the payment state. `quote` **MUST** remain a secret between user and mint and **MUST NOT** be derivable from the payment request. A third party who knows the `quote` ID can front-run and steal the tokens that this operation mints. +> [!CAUTION] +> `quote` is a **unique and random** id generated by the mint to internally look up the payment state. `quote` **MUST** remain a secret between user and mint and **MUST NOT** be derivable from the payment request. A third party who knows the `quote` ID can front-run and steal the tokens that this operation mints. ## Example diff --git a/20.md b/20.md index c499c76..1170489 100644 --- a/20.md +++ b/20.md @@ -2,12 +2,18 @@ `optional` -This NUT defines a protocol extension that enables signature-based authentication for mint quote redemption. When requesting a mint quote, clients can provide a public key. The mint will then require a valid signature from the corresponding secret key before processing the mint. -Caution: If the mint does not support this NUT, anyone with the mint quote id will be able to mint even without providing a signature. +`depends on: NUT-04` -# Mint quote +--- -To request a mint quote, the wallet of `Alice` makes a `POST /v1/mint/quote/{method}` request where `method` is the payment method requested (here `bolt11`). +This NUT defines signature-based authentication for mint quote redemption. When requesting a mint quote, clients provide a public key. The mint will then require a valid signature from the corresponding secret key to process the mint operation. + +> [!CAUTION] +> [NUT-04][04] mint quotes without a public key can be minted by anyone who knows the mint quote id without providing a signature. + +## Mint quote + +To request a mint quote, the wallet of `Alice` makes a `POST /v1/mint/quote/{method}` request where `method` is the payment method requested. We present an example with the `method` being `bolt11` here. ```http POST https://mint.host:3338/v1/mint/quote/bolt11 @@ -24,9 +30,11 @@ The wallet of `Alice` includes the following `PostMintQuoteBolt11Request` data i } ``` -with the requested `amount` and the `unit`. An optional `description` can be passed if the mint signals support for it in `MintMethodSetting`. `pubkey` is the public key that will be required for signature verification during the minting process. The mint will only mint ecash after receiving a valid signature from the corresponding private key in the `PostMintRequest`. +with the requested `amount`,`unit`, and `description` according to [NUT-04][04]. -> **Privacy:** To prevent linking multiple mint quotes together, wallets **SHOULD** generate a unique public key for each mint quote request +`pubkey` is the public key that will be required for signature verification during the minting operation. The mint will only mint ecash after receiving a valid signature from the corresponding private key in the subsequent `PostMintRequest`. + +> [!IMPORTANT] > **Privacy:** To prevent the mint from being able to link multiple mint quotes, wallets **SHOULD** generate a unique public key for each mint quote request. The mint `Bob` then responds with a `PostMintQuoteBolt11Response`: @@ -40,12 +48,7 @@ The mint `Bob` then responds with a `PostMintQuoteBolt11Response`: } ``` -Where `quote` is the quote ID and `request` is the payment request to fulfill. `expiry` is the Unix timestamp until which the mint quote is valid. -`state` is an enum string field with possible values `"UNPAID"`, `"PAID"`, `"ISSUED"`: - -- `"UNPAID"` means that the quote's request has not been paid yet. -- `"PAID"` means that the request has been paid. -- `"ISSUED"` means that the quote has already been issued. +The response is the same as in [NUT-04][04] except for `pubkey` which has been provided by the wallet in the previous request. ## Example @@ -67,23 +70,28 @@ Response of `Bob`: } ``` -#### Message aggregation +## Signing the mint request + +### Message aggregation -To provide a signature for a mint request, the owner of one of the signing public keys must concatenate the `PostMintQuoteBolt11Response.quote` and the `B_` fields of all `BlindedMessages` (outputs, see [NUT-00][00]) to a single message string in the order they appear in the `PostMintRequest`. This string concatenated is then hashed and signed (see [Signature scheme](#signature-scheme)). +To provide a signature for a mint request, the owner of the signing public keys must concatenate the quote ID `quote` in `PostMintQuoteBolt11Response` and the `B_` fields of all `BlindedMessages` in the `PostMintBolt11Request` (i.e., the outputs, see [NUT-00][00]) to a single message string in the order they appear in the `PostMintRequest`. This concatenated string is then hashed and signed (see [Signature scheme](#signature-scheme)). -If a request has `n` outputs the message to sign becomes: +> [!NOTE] +> Concatenating the quote ID and the outputs into a single message prevents maliciously replacing the outputs. + +If a request has `n` outputs, the message to sign becomes: ``` -msg = quote_id || B_0 || ... || B_n +msg_to_sign = quote || B_0 || ... || B_(n-1) ``` -Where || denotes concatenation, `quote_id` is a UTF-8 string, and each `B_` is a hex string, with all components encoded to UTF-8 bytes +Where `||` denotes concatenation, `quote` is the UTF-8 quote id in `PostMintQuoteBolt11Response`, and each `B_n` is a UTF-8 encoded hex string of the outputs in the `PostMintBolt11Request`. -#### Signature scheme +### Signature scheme -To mint a quote where a public key was provided, the minter needs to include signatures in the `PostMintBolt11Request`. We use a [BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) signature on the SHA-256 hash of the message to sign as defined above. +To mint a quote where a public key was provided, the wallet includes a signature on `msg_to_sign` in the `PostMintBolt11Request`. We use a [BIP340](https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki) Schnorr signature on the SHA-256 hash of the message to sign as defined above. -# Minting tokens +## Minting tokens After requesting a mint quote and paying the request, the wallet proceeds with minting new tokens by calling the `POST /v1/mint/{method}` endpoint where `method` is the payment method requested (here `bolt11`). @@ -101,16 +109,11 @@ The wallet `Alice` includes the following `PostMintBolt11Request` data in its re } ``` -with the `quote` being the quote ID from the previous step and `outputs` being `BlindedMessages` (see [NUT-00][00]) that the wallet requests signatures on whose sum is `amount` as requested in the quote. `signature` is the signature on the mint quote id as defined above. -The mint `Bob` then responds with a `PostMintBolt11Response`: +with the `quote` being the quote ID from the previous step and `outputs` being `BlindedMessages` as in [NUT-04][04]. -```json -{ - "signatures": -} -``` +`signature` is the signature on the `msg_to_sign` which is the concatenated quote id and the outputs as defined above. -where `signatures` is an array of blind signatures on the outputs. +The mint responds with a `PostMintBolt11Response` as in [NUT-04][04] if all validations are successful. ## Example @@ -156,7 +159,9 @@ Response of `Bob`: } ``` -If the invoice was not paid yet, `Bob` responds with an error. In that case, `Alice` **MAY** repeat the same request until the Lightning invoice is settled, as in NUT04. If `Alice` does not include a signature on the `PostMintBolt11Request` but did include a `pubkey` in the `PostMintBolt11QuoteRequest` then `Bob` **MUST** respond with an error, `Alice` **SHOULD** repeat the request with a signature in order to mint the ecash. +## Errors + +If the wallet user `Alice` does not include a signature on the `PostMintBolt11Request` but did include a `pubkey` in the `PostMintBolt11QuoteRequest` then `Bob` **MUST** respond with an error. `Alice` **CAN** repeat the request with a valid signature. ## Settings @@ -171,4 +176,5 @@ The settings for this NUT indicate the support for requiring a signature before ``` [00]: 00.md +[04]: 04.md [06]: 06.md