From 3d108294a1f4a5e1a842f30921e56054a69fecce Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Thu, 20 Nov 2014 09:23:59 +0100 Subject: initial import of sphinx documentation --- api-mint.rst | 640 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 640 insertions(+) create mode 100644 api-mint.rst (limited to 'api-mint.rst') diff --git a/api-mint.rst b/api-mint.rst new file mode 100644 index 00000000..18e2bff6 --- /dev/null +++ b/api-mint.rst @@ -0,0 +1,640 @@ +======================== +The Mint JSON API +======================== + +------- +General +------- + + This section describes how certain types of values are + represented throughout the API. + + * **Timestamps**: + Timestamps are represented in JSON as a string literal `"\\/Date(x)\\/"`, where `x` is the decimal representation + of the number of milliseconds past the Unix Epoch (January 1, 1970). The escaped slash (`\\/`) is interpreted in JSON simply + as a normal slash, but distinguishes the timestamp from a normal string literal. + * **Public key**: Public keys are represented using the Ed25519 standard + compact format (256 bits), converted to Base32Hex (RFC 4648) for + transmission. + * **Signatures**: Signatures are transmitted as a JSON object with the following fields: + + * `purpose`: a unique number to state the context in which the signature is to be used in + * `size`: the number of bytes that were hashed (using SHA-512) to create the signature; note that signatures are always done over a packed, binary representation of the data and not the JSON representations. + * `r`: R value of the signature (256 bit, in Base32Hex). + * `s`: S value of the signature (256 bit, in Base32Hex). + + The specific signature scheme in use (blind signature, EdDSA) + depends on the context and can be derived from the purpose. + + * **Denominations**: Currency denominations are expressed as a JSON object with the following fields: + + * `currency`: name of the currency using ISO 4217 currency code + * `value`: unsigned 32 bit value in the currency, note that "1" here would correspond to 1 EUR or 1 USD (depending on `currency`), not 1 cent. + * `fraction`: unsigned 32 bit fractional value (to be added to `value`) representing an additional currency fraction, in units of 1 in one million (1/1000000) of the base currency value. For example, a fraction of 50000000 (50 million) would correspond to 50 cents. + + * **Large numbers**: Large numbers (typically 256 bits), such as blinding factors and private keys, are transmitted in Base32Hex encoding. + +------------------- +Obtaining Mint Keys +------------------- +.. http:get:: /keys + + Get a list of all denomination keys offered by the bank, + as well as the bank's current online signing key. + + **Response on Success** + + On success, the mint responds with HTTP status code `200 OK`. + The body of the response contains a JSON object with the following fields: + + * `denoms`: A JSON list of denomination descriptions. Described below in detail. + * `denoms_date`: The date when the denomination keys were last updated. + * `denoms_sig`: A signature over the list of denomination keys and the date. + * `signing_key`: The mint's current signing key. Described below in detail. + + A denomination description is a JSON object with the following fields: + + * `value`: Value of the denomination. An integer, to be interpreted + relative to the currency provided by the mint. + * `stamp_start`: timestamp indicating when the denomination key becomes valid. + * `stamp_expire_withdraw`: timestamp indicating when the denomination key can't + be used anymore to withdraw new coins. + * `stamp_expire_deposit`: timestamp indicating when coins of this + denomination become invalid. + * `key`: Public key for the denomination. + * `kappa`: Security parameter for refreshing. + * `sig`: Signature over the expiration dates, value and the key, created + with the mint's master key. + + The `signing_key` field contains a JSON object with the following fields: + + * `key`: The actual mint's signing public key. + * `stamp_expire`: Expiration date for the signing key. + * `sig`: Signature over the `key` and `stamp_expire` by the mint master key. + + .. note:: + + Both the individual denominations *and* the denomination list is signed, + allowing customers to prove that they received an inconsistent list. + + +------------------ +Withdrawal +------------------ + +When transfering money to the mint via SEPA, the mint records +a *purse*, which stores the remaining money from the transaction and the +customer's withdrawal key for the purse. + + +.. http:get:: /withdraw/status + + Request information about a purse, including the blinding key that is necessary to + withdraw a coin. + + :query withdraw_pub: Withdrawal key identifying the purse. + + **Success Response** + + The mint responds with a JSON object containing the following fields: + + * `balance`: Money left in this purse. A list of denominations (in case multiple currencies happen to be in the same purse). + * `blind_session_pub`: Blinding key to be used for withdrawing from this purse. + The field may be absent if the balance is smaller than the smallest denomination offered by the mint. + * `expiration`: Expiration date of the purse. + * `sig`: Signature of the mint. + + For the same `balance`, the blinding key `blinding_pub` must be the same. Otherwise the mint is faulty. + + **Error Responses** + + :status 402 Payment Required: The balance of the purse is not sufficient + to withdraw any coin denomination offered by the mint. + + :status 400 Bad Request: The `withdraw_pub` parameter is missing or malformed. + + :status 404 Not Found: The withdrawal key does not belong to a purse known to the mint. + + +.. http:get:: /withdraw/sign + + Withdraw a coin with a given denomination key. + + :query denom: denomination key + :query blank: blinded coin blank + :blind_session_pub: blind session public key + :withdraw_pub: withdraw / purse public key + :query sig: signature, created with the withdrawal key + + **Success Response**: + + :status 200 OK: The request was succesful. + + The response body of a succesful request contains a JSON object with the following fields: + + * `bcsig`: The blindly signed coin. + + **Error Responses**: + + :status 400 Bad Request: A request parameter is missing or malformed. + + :status 402 Payment Required: The balance of the purse is not sufficient to withdraw a coin of the + indicated denomination. + + :status 401 Unauthorized: The signature is invalid. + + :status 404 Not Found: The blinding key is not known to the mint. + + :status 409 Conflict: A sign request for the same `big_r` has already been sent, + but with a different `denom` or `blank`. + + +------------------ +Refreshing +------------------ + +Refreshing creates `n` new coins from `m` old coins, where the sum +of denominations of the new coins must be smaller than the sum of +the old coins' denominations plus a refreshing fee imposed by the mint. + +The new coins are linkable from all old coins. + +In order group multipe coins, the customer generates a refreshing session key. + +.. http:post:: /refresh/melt + + "Melt" coins, marking it for refreshing. Invalidates the coins. + + The request body must contain a JSON object with the following fields: + * `melt_coins`: List of coins to refresh. + * `new_denoms`: List of new denominations to order. + * `session_pub`: Session public key + + The `melt_coins` field is a list of JSON objects with the following fields: + * `coin_pub`: Coin public key + * `coin_sig`: Signature by the coin over the session public key + * `denom_pub`: Denomination public key + * `denom_sig`: Signature over the coin public key by the denomination key + + + **Success Response**: + + :status 200 OK: The request was succesful. In that case, the responst body is a json + object with `kappa` blind session keys for each new coin. + + **Error Responses**: + + :status 400 Bad Request: A request parameter is missing or malformed. + + :status 401 Gone: The coin `coin` has already been refreshed. + + :status 403 Forbidden: Either `csig` or `ssig` is invalid. + +.. http:post:: /refresh/commit + + Commit values for the cut-and-choose in the refreshing protocol. + The request body must be a JSON object with the following fields: + * `session_pub`: Session to commit values for + * `session_sig`: Signature over the whole commitment + * `coin_evs`: For each new coin, `kappa` coin blanks. + * `transfer_pubs`: List of transfer public keys + * `new_encs`: For each new coin, a list of encryptions (one for each cnc instance) + * `secret_encs`: For each cut-and-choose instance, the linking encryption for each old coin + + **Success Response**: + + :status 202 Accepted: The mint accepted the commitment, but still needs more commitments. + + The response body contains a JSON object with the following fields: + + **Error Response**: + + :status 400 Bad Request: A request parameter is missing or malformed. + + :status 403 Forbidden: The signature `sig` is invalid. + + :status 404 Not Found: The mint does not know the blind key `blindkey` given + in the request. + +.. http:post:: /refresh/reveal + + Reveal previously commited values to the bank. Request body contains a JSON object with + the following fields: + * `session_pub`: The session public key + * `transfer_privs`: Revealed transfer private keys + + **Success Response**: + + :status 200 OK: All commitments were revealed successfully. + + The mint responds with a JSON object containing the following + fields: + + * `bcsig_list`: List of the mint's blind signatures on the ordered new coins. + + :status 202 Accepted: The revealed value was accepted, but the mint + requires more reveals. + + **Error Responses**: + + If the reveal is incomplete, the JSON object contains: + + * `reveal_missing`: List of blinding keys with missing reveals from the customer. + + :status 400 Bad Request: Request parameters incomplete or malformed. + :status 403 Forbidden: The signature `ssig` is invalid. + :status 404 Not Found: The blinding key is not known to the mint. + :status 409 Conflict: The revealed value was inconsistent with the commitment. + :status 410 Gone: A conflict occured, the money is gone. + +.. http:get:: /refresh/link + + Link an old key to the refreshed coin. + + :query coin: coin public key + :query csig: signature by the coin + + **Success Response**: + + :status 200 OK: All commitments were revealed successfully. + + The mint responds with a JSON object containing the following fields: + * `link_secret_enc`: ... + * `enc_list`: List of encrypted values for the result coins. + * `tpk_list`: List of transfer public keys for the new coins. + * `bscoin_list`: List of blind signatures on the new coins. + + **Error Responses**: + + :status 400 Bad Request: Request parameters incomplete or malformed. + :status 403 Forbidden: The signature `csig` is invalid. + :status 404 Not Found: The coin public key is not known to the bank, or was not involved + in a refresh. + + + +-------------------- +Locking and Deposit +-------------------- + +Locking and Deposit operations are requested by a merchant during a transaction. +For locking operation, the merchant has to obtain a lock permission for a coin +from the customer. Similarly, for deposit operation the merchant has to obtain +deposit permission for the coin from the customer. + +.. http:GET:: /lock + + Lock the given coin which is identified by the coin's public key. + + :query C: coin's public key + :query K: denomination key with which the coin is signed + :query ubsig: mint's unblinded signature of the coin + :query t: timestamp indicating the lock expire time + :query m: transaction id for the transaction between merchant and customer + :query f: the maximum amount for which the coin has to be locked + :query M: the public key of the merchant + :query csig: the signature made by the customer with the coin's private key over + the parameters `t`, `m`, `f`, `M` and the string `"LOCK"` + + The locking operation may succeed if the coin is not already locked or a + previous lock for the coin has already expired. + + **Success response** + + :status 200: the operation succeeded + + The mint responds with a JSON object containing the following fields: + + * `status`: The string constant `LOCK_OK` + * `C`: the coin's public key + * `t`: timestamp indicating the lock expire time + * `m`: transaction id for the transaction between merchant and customer + * `f`: the maximum amount for which the coin has to be locked + * `M`: the public key of the merchant + * `sig`: the signature made by the mint with the corresponding coin's + denomination key over the parameters `status`, `C`, `t`, `m`, `f`, + `M` + + The merchant can then save this JSON object as a proof that the mint has + agreed to transfer a maximum amount equalling to the locked amount upon a + successful deposit request (see /deposit). + + **Failure response** + + :status 403: the locking operation has failed because the coin is already + locked or already refreshed and the same request should not be + repeated as it will always fail. + + In this case the response contains a proof that the given coin is already + locked ordeposited. + + If the coin is already locked, then the response contains the existing lock + object rendered as a JSON object with the following fields: + + * `status`: the string constant `LOCKED` + * `C`: the coin's public key + * `t`: the expiration time of the existing lock + * `m`: the transaction ID which locked the coin + * `f`: the amount locked for the coin + * `M`: the public key of the merchant who locked the coin + * `csig`: the signature made by the customer with the coin's private key + over the parameters `t`, `m`, `f` and `M` + + If the coin has already been refreshed then the mint responds with a JSON + object with the following fields: + + * `status`: the string constant `REFRESHED` + * ... TBD + + :status 404: the coin is not minted by this mint, or it has been expired + :status 501: the request or one of the query parameters are not valid and the + response body will contain an error string explaining why they are + invalid + :status 503: the mint is currently unavailable; the request can be retried after + the delay indicated in the Retry-After response header + + In these failures, the response contains an error string describing the reason + why the request has failed. + +.. _deposit: +.. http:POST:: /deposit + + Deposit the given coin and ask the mint to transfer the given amount to the + merchants bank account. The request should contain a JSON object with the + following fields + + * `C`: coin's public key + * `K`: denomination key with which the coin is signed + * `ubsig`: mint's unblinded signature of the coin + * `type`: the string constant `"DIRECT_DEPOSIT"` or `"INCREMENTAL_DEPOSIT"` + respectively for direct deposit or incremental deposit type of interaction + chosen by the customer and the merchant. + * `m`: transaction id for the transaction between merchant and customer + * `f`: the maximum amount for which the coin has to be locked + * `M`: the public key of the merchant + * `H_a`: the hash of the contract made between merchant and customer + * `H_wire`: the hash of the merchant's payment information `wire` + * `csig`: the signature made by the customer with the coin's private key over + the parameters `type`, `m`, `f`, `M`, `H_a` and, `H_wire` + * `wire`: this should be a JSON object whose format should comply to one of the + supported wire transfer formats. See :ref:`wireformats` + + The deposit operation succeeds if the coin is valid for making a deposit and + is not already deposited or refreshed. + + **Success response** + + :status 200: the operation succeeded + + The mint responds with a JSON object containing the following fields: + + * `status`: the string constant `DEPOSIT_OK` + * `t`: the current timestamp + * `deposit_tx`: the transaction identifier of the transfer transaction made by the + mint to deposit money into the merchant's account + * `sig`: signature of the mint made over the parameters `status`, `t` and + `deposit_tx` + + :status 202: the operation is accepted but will take a while to complete; + check back later for its reponse + + This happens when the mint cannot immediately execute the SEPA transaction. + The response contains the following fields as part of a JSON object: + + * `status`: the string contant `DEPOSIT_QUEUED` + * `t`: the current timestamp + * `retry`: timestamp indicating when the result of the request will be made + available + * `sig`: the signature of the mint made over the parameters `status`, `t`, and + `retry` + + **Failure response** + + :status 403: the deposit operation has failed because the coin has previously + been deposited or it has been already refreshed; the request + should not be repeated again + + In case of failure due to the coin being already deposity, the response + contains a JSON object with the following fields: + + * `status`: the string constant `DEPOSITED` + * `C`: the coin's public key + * `m`: ID of the past transaction which corresponding to this deposit + * `f`: the amount that has been deposited from this coin + * `M`: the public key of the merchant to whom the deposit was earlier made + * `H`: the hash of the contract made between the merchant identified by `M` + and the customer + * `csig`: the signature made by the owner of the coin with the coin's private + key over the parameters `m`, `f`, `M`, `H` and the string `"DEPOSIT"` + * `t`: the timestamp when the deposit was made + * `deposit_tx`: the transaction identifier of the SEPA transaction made by the + mint to deposit money into the merchant's account + + In case if the coin has been already refreshed, the response contains a JSON + object with the following fields: + + * `status`: the string constant `REFRESHED` + * ... TBD + + :status 404: the coin is not minted by this mint, or it has been expired + :status 501: the request or one of the query parameters are not valid and the + response body will contain an error string explaining why they are + invalid + :status 503: the mint is currently unavailable; the request can be retried after + the delay indicated in the Retry-After response header + + In these failures the response contains an error string describing the reason + why the request has failed. + +=========================== +Binary Blob Specification +=========================== +This section specifies the binary representation of messages used in Neuro's protocols. +The message formats are given in a C-style pseudocode notation. In contrast to real C structs, +padding is always specified explicitly, and numeric values are little endian. + +.. sourcecode:: c + + struct PublicKey { + uint8_t v[32]; + }; + + struct PrivateKey { + uint8_t d[32]; + }; + + struct Timestamp { + uint64_t val_us; + }; + + struct Signature { + uint8_t rs[64]; + }; + +In our notation, the type of a field can depend on the value of another field. +For the following message, the length of the `payload` array must match the value +of the `size` field. + +.. sourcecode:: c + + struct SignedData { + uint32_t size; + uint32_t purpose; + uint8_t payload[size]; + }; + + struct Denomination { + uint32_t value; + uint32_t fraction; + uint8_t currency_code[4]; + }; + + +In the subsequent messages, we use the following notation + +.. sourcecode:: c + + signed (purpose = SOME_CONSTANT) { + FIELDS + } msg; + +for signed data (contained in `FIELDS`) with the given purpose. The `size` field of the +corresponding `struct SignedData` is determined by the size of `FIELDS`. + +.. sourcecode:: c + + struct CoinIssue { + // signed by the master key + signed (purpose = COIN_ISSUE) { + struct PublicKey key; + struct Timestamp stamp_expire_withdraw; + struct Timestamp stamp_expire_deposit; + struct Timestamp stamp_start; + uint32_t kappa; + uint32_t padding; + struct Denomination denom; + }; + }; + + struct CoinIssueList { + // signed by the master key + signed (purpose = COIN_ISSUE_LIST) { + uint32_t n; + struct Timestamp stamp_issue; + struct CoinIssue coins[n]; + struct PublicKey mint_signing_key; + }; + }; + + struct PurseInformation { + // signed with the mint signing key + signed (purpose = PURSE_INFO) { + struct PublicKey big_r; + struct Timestamp stamp_expire_purse; + struct Denomination balance; + struct Timestamp purse_expiration; + }; + }; + + struct BlindBlankCoin { + TODO todo; + }; + + struct BlindSignedCoin { + TODO todo; + }; + + struct SignedCoin { + TODO todo; + }; + + struct WithdrawRequest { + // signed with the withdrawal key + signed (purpose = WITHDRAW_REQUEST) { + struct PublicKey denom_key; + struct PublicKey big_r; + struct BlindBlankCoin blank; + }; + }; + + struct MeltRequest { + // signed with the coin key + signed (purpose = MELT_COIN) { + // signed with the session key + signed (purpose = MELT_SESSION) { + SignedCoin coin; + PublicKey session; + }; + }; + }; + + struct OrderRequest { + // signed with the session key + signed (purpose = REFRESH_REQUEST) { + struct PublicKey denom_key; + struct PublicKey session; + }; + }; + + +In the following message, `n` is the number of coins +melted by the customer, and `KAPPA` is a security parameter determined +by the new coin's denomination. + +.. sourcecode:: c + + struct OrderResponse { + signed (purpose = ORDER_RESPONSE) { + Denomination rest_balance; + struct { + PublicKey big_r; + PublicKey old_coin; + } challenges[KAPPA * n]; + }; + }; + + struct BlindFactor { + TODO todo; + }; + +The `encrypted` block denotes an encrypted message. + +.. sourcecode:: c + + struct RefreshEnc { + encrypted { + struct BlindFactor bf; + struct PrivateKey tsk; + struct PrivateKey csk; + }; + }; + + struct CommitRequest { + signed (purpose = REFRESH_COMMIT) { + struct PublicKey tpk; + struct BlindBlankCoin blank; + struct RefreshEnc enc; + }; + }; + + struct RevealRequest { + // FIXME: does this need to be signed? + struct PublicKey big_r; + struct BlindFactor bf; + struct PrivateKey csk; + }; + + struct LinkRequest { + signed (purpose = REFRESH_LINK) { + struct PublicKey coin; + }; + }; + + struct LinkResponse { + uint16_t n; + struct BlindSignedCoin coins[n]; + struct PublicKey tpks[n]; + struct RefreshEnc encs[n]; + }; + + -- cgit v1.2.3