Contents

POST /reveal-withdraw#

Reveal previously committed values to the exchange, except for the values corresponding to the noreveal_index returned by the /withdraw step.

The base URL for /reveal-withdraw-request may differ from the main base URL of the exchange. Clients SHOULD respect the reveal_base_url returned for the coin during melt operations. The exchange MUST return a 307 or 308 redirection to the correct base URL if the client failed to respect the reveal_base_url or if the allocation has changed.

The request body is a RevealWithdrawRequest.

This endpoint was introduced in this form in protocol v32.

200 OK:

The coin’s’ secret material matched the commitment and the original request was well-formed. The response body is a RevealResponse.

400 Bad request:

The request from the client is malformed. Error codes used are: - TALER_EC_GENERIC_PARAMETER_MALFORMED - TALER_EC_EXCHANGE_WITHDRAW_REVEAL_INVALID_HASH

404 Not found:

The provided commitment $RCH is unknown. Error code: TALER_EC_EXCHANGE_WITHDRAW_COMMITMENT_UNKNOWN

413 Request entity too large:

The uploaded body is to long, it exceeds the size limit. Returned with an error code of TALER_EC_GENERIC_UPLOAD_EXCEEDS_LIMIT.

500 Internal Server Error:

Returned if the server had an internal issue processing the request. Error codes include: - TALER_EC_GENERIC_DB_FETCH_FAILED - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE

503 Service unavailable:

The server could not process the request because it is currently unavailable. Error codes include: - TALER_EC_EXCHANGE_GENERIC_KEYS_MISSING

Details:

Request body for a reveal-withdraw request contains a JSON object with the following fields:

interface RevealWithdrawRequest {

  // This is the running hash of all blinded planchets
  // from the previous call to /withdraw.
  planchets_h: string;

  // Array of (kappa - 1) disclosed batch secrets,
  // from which for each of the n coins in a batch
  // their coin master secret is derived,
  // from which in turn their private key,
  // blinding, nonce (for Clause-Schnorr) and
  // age-restriction is calculated.
  disclosed_batch_seeds: AgeRestrictedPlanchetSeed[];

}
// The master seed material from which for n coins in a batch,
// each the coins' private key coin_priv,  blinding beta
// and nonce nonce (for Clause-Schnorr) itself are
// derived as usually in wallet-core.  Given a coin's master key material,
// the age commitment for the coin MUST be derived from this private key as
// follows:
//
// Let m ∈  {1,...,M} be the maximum age group as defined in the reserve
// that the wallet can commit to.
//
// For age group $AG ∈  {1,...m}, set
//     seed = HDKF(coin_secret, "age-commitment", $AG)
//   p[$AG] = Edx25519_generate_private(seed)
// and calculate the corresponding Edx25519PublicKey as
//   q[$AG] = Edx25519_public_from_private(p[$AG])
//
// For age groups $AG ∈  {m+1,...,M}, set
//   f[$AG] = HDKF(coin_secret, "age-factor", $AG)
// and calculate the corresponding Edx25519PublicKey as
//   q[$AG] = Edx25519_derive_public(PublishedAgeRestrictionBaseKey, f[$AG])
//
type AgeRestrictedPlanchetSeed = string;
// The value for PublishedAgeRestrictionBaseKey is a randomly chosen
// Edx25519PublicKey for which the private key is not known to the clients.  It is
// used during the age-withdraw protocol so that clients can prove that they
// derived all public keys to age groups higher than their allowed maximum
// from this particular value.
const PublishedAgeRestrictionBaseKey =
    new Edx25519PublicKey("CH0VKFDZ2GWRWHQBBGEK9MWV5YDQVJ0RXEE0KYT3NMB69F0R96TG");