diff --git a/11.md b/11.md index a529d4145..cdab3cc1f 100644 --- a/11.md +++ b/11.md @@ -154,6 +154,46 @@ msg = secret_0 || C_0 || ... || secret_n || C_n || amount_0 || B_0 || ... || amo Here, `||` denotes string concatenation. The `C` of each input and `B_` of each output are **hex strings** and `amount` is a UTF-encoded string. +### SigAllSigningPackage + +To facilitate multi-party signing for [`SIG_ALL`](#signature-flag-sig_all) transactions, wallets can exchange a `SigAllSigningPackage` containing the minimal data required to reconstruct the transaction message and produce signatures. It is a wallet-to-wallet transport format. Mints do not process these packages. + +Each signer **MUST** derive the message to sign from the package contents itself, as described in [Message aggregation for `SIG_ALL`](#message-aggregation-for-sig_all). The package deliberately carries no precomputed digest: a signer that trusts one blindly would sign a message it has not verified against the transaction it is approving. This also keeps the format independent of the message aggregation scheme in use. + +The `SigAllSigningPackage` has the following structure: + +```json +{ + "version": "sigallA", + "type": "swap" | "melt", + "quote": , // Optional, for melt only + "inputs": [ + { + "secret": , + "C": + } + ], + "outputs": , + "witness": { + "signatures": + } // Optional, decoded P2PKWitness object +} +``` + +> [!NOTE] +> +> `witness` is the **JSON-decoded** [`P2PKWitness`](#witness-format) object, not the serialized JSON string carried in `Proof.witness`. A wallet assembling the final transaction MUST serialize it before placing it in `Proof.witness`, and MUST NOT put an already-serialized string here, or the witness ends up double-encoded. By contrast, `inputs[].secret` is carried **verbatim** as it appears in `Proof.secret` and MUST NOT be transformed in transit. + +The package is serialized to a string by JSON-encoding the object with specific key ordering (see `SigAllSigningPackage` definition), converting to base64url, and prefixing with `sigallA`. The keys must be sorted as: `version`, `type`, `quote` (if present), `inputs`, `outputs`, `witness` (if present). + +Below is a sample base64url encoded `SigAllSigningPackage`. + +``` +sigallAeyJ2ZXJzaW9uIjoic2lnYWxsQSIsInR5cGUiOiJzd2FwIiwiaW5wdXRzIjpbeyJzZWNyZXQiOiJbXCJQMlBLXCIse1wibm9uY2VcIjpcImM3ZjI4MGViNTVjMWU4NTY0ZTAzZGIwNjk3M2U5NGJjOWI2NjZkOWUxY2E0MmFkMjc4NDA4ZmU2MjU5NTAzMDNcIixcImRhdGFcIjpcIjAzMGQ4YWNlZGZlMDcyYzlmYTQ0OWExZWZlMDgxNzE1NzQwM2ZiZWM0NjBkOGU3OWY5NTc5NjYwNTZlNWRkNzZjMVwiLFwidGFnc1wiOltbXCJzaWdmbGFnXCIsXCJTSUdfQUxMXCJdXX1dIiwiQyI6IjAyYzk3ZWUzZDFkYjQxY2YwYTNkZGI2MDE3MjRiZTg3MTFhMDMyOTUwODExYmYzMjZmODIxOWM1MGM0ODA4ZDNjZCJ9XSwib3V0cHV0cyI6W3siYW1vdW50IjoyLCJpZCI6IjAwYmZhNzMzMDJkMTJmZmQiLCJCXyI6IjAzOGVjODUzZDY1YWUxYjc5YjVjZGJjMjc3NDE1MGIyY2IyODhkNmQyNmUxMjk1OGExNmZiMzNjMzJkOWE4NmMzOSJ9XSwid2l0bmVzcyI6eyJzaWduYXR1cmVzIjpbImNlMDE3Y2EyNWIxYjk3ZGYyZjcyZTRiNDlmNjlhYzI2YTI0MGNlMTRiMzY5MGE4ZmU2MTlkNDFjY2M0MmQzYzEyODJlMDczZjg1YWNkMzZkYzUwMDExNjM4OTA2ZjM1YjU2NjE1ZjI0ZTRkMDNlOGVmZmU4MjU3ZjZhODA4NTM4Il19fQ +``` + +See the [test vectors][tests] for a full example. + ## Locktime Tag The `locktime` tag signals which set of locking rules the mint should apply. There are three possible states the `locktime` tag can represent: @@ -288,3 +328,4 @@ The [NUT-06][06] `MintMethodSetting` indicates support for this feature: [10]: 10.md [11]: 11.md [12]: 12.md +[tests]: tests/11-test.md diff --git a/tests/11-test.md b/tests/11-test.md index 96468410b..c2d91e425 100644 --- a/tests/11-test.md +++ b/tests/11-test.md @@ -409,3 +409,63 @@ The following is a valid multi-sig `SIG_ALL` `MeltRequest`. ] } ``` + +### SigAllSigningPackage Test Vectors + +The following is an example of a `SigAllSigningPackage`, derived from a `swap` transaction. + +Input transaction data: + +```json +{ + "inputs": [ + { + "amount": 2, + "id": "00bfa73302d12ffd", + "secret": "[\"P2PK\",{\"nonce\":\"c7f280eb55c1e8564e03db06973e94bc9b666d9e1ca42ad278408fe625950303\",\"data\":\"030d8acedfe072c9fa449a1efe0817157403fbec460d8e79f957966056e5dd76c1\",\"tags\":[[\"sigflag\",\"SIG_ALL\"]]}]", + "C": "02c97ee3d1db41cf0a3ddb601724be8711a032950811bf326f8219c50c4808d3cd", + "witness": "{\"signatures\":[\"ce017ca25b1b97df2f72e4b49f69ac26a240ce14b3690a8fe619d41ccc42d3c1282e073f85acd36dc50011638906f35b56615f24e4d03e8effe8257f6a808538\"]}" + } + ], + "outputs": [ + { + "amount": 2, + "id": "00bfa73302d12ffd", + "B_": "038ec853d65ae1b79b5cdbc2774150b2cb288d6d26e12958a16fb33c32d9a86c39" + } + ] +} +``` + +Derived `SigAllSigningPackage` JSON. Note the representation change: `Proof.witness` above is a serialized JSON string, while the package's `witness` is the decoded object. The `secret` is carried over unchanged. + +```json +{ + "version": "sigallA", + "type": "swap", + "inputs": [ + { + "secret": "[\"P2PK\",{\"nonce\":\"c7f280eb55c1e8564e03db06973e94bc9b666d9e1ca42ad278408fe625950303\",\"data\":\"030d8acedfe072c9fa449a1efe0817157403fbec460d8e79f957966056e5dd76c1\",\"tags\":[[\"sigflag\",\"SIG_ALL\"]]}]", + "C": "02c97ee3d1db41cf0a3ddb601724be8711a032950811bf326f8219c50c4808d3cd" + } + ], + "outputs": [ + { + "amount": 2, + "id": "00bfa73302d12ffd", + "B_": "038ec853d65ae1b79b5cdbc2774150b2cb288d6d26e12958a16fb33c32d9a86c39" + } + ], + "witness": { + "signatures": [ + "ce017ca25b1b97df2f72e4b49f69ac26a240ce14b3690a8fe619d41ccc42d3c1282e073f85acd36dc50011638906f35b56615f24e4d03e8effe8257f6a808538" + ] + } +} +``` + +Serialized string: + +``` +sigallAeyJ2ZXJzaW9uIjoic2lnYWxsQSIsInR5cGUiOiJzd2FwIiwiaW5wdXRzIjpbeyJzZWNyZXQiOiJbXCJQMlBLXCIse1wibm9uY2VcIjpcImM3ZjI4MGViNTVjMWU4NTY0ZTAzZGIwNjk3M2U5NGJjOWI2NjZkOWUxY2E0MmFkMjc4NDA4ZmU2MjU5NTAzMDNcIixcImRhdGFcIjpcIjAzMGQ4YWNlZGZlMDcyYzlmYTQ0OWExZWZlMDgxNzE1NzQwM2ZiZWM0NjBkOGU3OWY5NTc5NjYwNTZlNWRkNzZjMVwiLFwidGFnc1wiOltbXCJzaWdmbGFnXCIsXCJTSUdfQUxMXCJdXX1dIiwiQyI6IjAyYzk3ZWUzZDFkYjQxY2YwYTNkZGI2MDE3MjRiZTg3MTFhMDMyOTUwODExYmYzMjZmODIxOWM1MGM0ODA4ZDNjZCJ9XSwib3V0cHV0cyI6W3siYW1vdW50IjoyLCJpZCI6IjAwYmZhNzMzMDJkMTJmZmQiLCJCXyI6IjAzOGVjODUzZDY1YWUxYjc5YjVjZGJjMjc3NDE1MGIyY2IyODhkNmQyNmUxMjk1OGExNmZiMzNjMzJkOWE4NmMzOSJ9XSwid2l0bmVzcyI6eyJzaWduYXR1cmVzIjpbImNlMDE3Y2EyNWIxYjk3ZGYyZjcyZTRiNDlmNjlhYzI2YTI0MGNlMTRiMzY5MGE4ZmU2MTlkNDFjY2M0MmQzYzEyODJlMDczZjg1YWNkMzZkYzUwMDExNjM4OTA2ZjM1YjU2NjE1ZjI0ZTRkMDNlOGVmZmU4MjU3ZjZhODA4NTM4Il19fQ +```