exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

exchange_signatures.c (59970B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2021-2025 Taler Systems SA
      4 
      5   TALER is free software; you can redistribute it and/or modify it under the
      6   terms of the GNU General Public License as published by the Free Software
      7   Foundation; either version 3, or (at your option) any later version.
      8 
      9   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
     10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file exchange_signatures.c
     18  * @brief Utility functions for Taler security module signatures
     19  * @author Christian Grothoff
     20  */
     21 #include "taler/taler_util.h"
     22 #include "taler/taler_signatures.h"
     23 
     24 
     25 GNUNET_NETWORK_STRUCT_BEGIN
     26 
     27 /**
     28  * @brief Format used to generate the signature on a confirmation
     29  * from the exchange that a deposit request succeeded.
     30  */
     31 struct TALER_DepositConfirmationPS
     32 {
     33   /**
     34    * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT.  Signed
     35    * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
     36    */
     37   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     38 
     39   /**
     40    * Hash over the contract for which this deposit is made.
     41    */
     42   struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
     43 
     44   /**
     45    * Hash over the wiring information of the merchant.
     46    */
     47   struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
     48 
     49   /**
     50    * Hash over the optional policy extension of the deposit, 0 if there
     51    * was no policy.
     52    */
     53   struct TALER_ExtensionPolicyHashP h_policy GNUNET_PACKED;
     54 
     55   /**
     56    * Time when this confirmation was generated / when the exchange received
     57    * the deposit request.
     58    */
     59   struct GNUNET_TIME_TimestampNBO exchange_timestamp;
     60 
     61   /**
     62    * By when does the exchange expect to pay the merchant
     63    * (as per the merchant's request).
     64    */
     65   struct GNUNET_TIME_TimestampNBO wire_deadline;
     66 
     67   /**
     68    * How much time does the @e merchant have to issue a refund
     69    * request?  Zero if refunds are not allowed.  After this time, the
     70    * coin cannot be refunded.  Note that the wire transfer will not be
     71    * performed by the exchange until the refund deadline.  This value
     72    * is taken from the original deposit request.
     73    */
     74   struct GNUNET_TIME_TimestampNBO refund_deadline;
     75 
     76   /**
     77    * Amount to be deposited, excluding fee.  Calculated from the
     78    * amount with fee and the fee from the deposit request.
     79    */
     80   struct TALER_AmountNBO total_without_fee;
     81 
     82   /**
     83    * Hash over all of the coin signatures.
     84    */
     85   struct GNUNET_HashCode h_coin_sigs;
     86 
     87   /**
     88    * The Merchant's public key.  Allows the merchant to later refund
     89    * the transaction or to inquire about the wire transfer identifier.
     90    */
     91   struct TALER_MerchantPublicKeyP merchant_pub;
     92 
     93 };
     94 
     95 GNUNET_NETWORK_STRUCT_END
     96 
     97 
     98 enum TALER_ErrorCode
     99 TALER_exchange_online_deposit_confirmation_sign (
    100   TALER_ExchangeSignCallback scb,
    101   const struct TALER_PrivateContractHashP *h_contract_terms,
    102   const struct TALER_MerchantWireHashP *h_wire,
    103   const struct TALER_ExtensionPolicyHashP *h_policy,
    104   struct GNUNET_TIME_Timestamp exchange_timestamp,
    105   struct GNUNET_TIME_Timestamp wire_deadline,
    106   struct GNUNET_TIME_Timestamp refund_deadline,
    107   const struct TALER_Amount *total_without_fee,
    108   unsigned int num_coins,
    109   const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins],
    110   const struct TALER_MerchantPublicKeyP *merchant_pub,
    111   struct TALER_ExchangePublicKeyP *pub,
    112   struct TALER_ExchangeSignatureP *sig)
    113 {
    114   struct TALER_DepositConfirmationPS dcs = {
    115     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
    116     .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
    117     .h_contract_terms = *h_contract_terms,
    118     .h_wire = *h_wire,
    119     .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
    120     .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
    121     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
    122     .merchant_pub = *merchant_pub,
    123     .h_policy = {{{0}}}
    124   };
    125   struct GNUNET_HashContext *hc;
    126 
    127   hc = GNUNET_CRYPTO_hash_context_start ();
    128   for (unsigned int i = 0; i<num_coins; i++)
    129     GNUNET_CRYPTO_hash_context_read (hc,
    130                                      coin_sigs[i],
    131                                      sizeof (*coin_sigs[i]));
    132   GNUNET_CRYPTO_hash_context_finish (hc,
    133                                      &dcs.h_coin_sigs);
    134   if (NULL != h_policy)
    135     dcs.h_policy = *h_policy;
    136   TALER_amount_hton (&dcs.total_without_fee,
    137                      total_without_fee);
    138   return scb (&dcs.purpose,
    139               pub,
    140               sig);
    141 }
    142 
    143 
    144 enum GNUNET_GenericReturnValue
    145 TALER_exchange_online_deposit_confirmation_verify (
    146   const struct TALER_PrivateContractHashP *h_contract_terms,
    147   const struct TALER_MerchantWireHashP *h_wire,
    148   const struct TALER_ExtensionPolicyHashP *h_policy,
    149   struct GNUNET_TIME_Timestamp exchange_timestamp,
    150   struct GNUNET_TIME_Timestamp wire_deadline,
    151   struct GNUNET_TIME_Timestamp refund_deadline,
    152   const struct TALER_Amount *total_without_fee,
    153   unsigned int num_coins,
    154   const struct TALER_CoinSpendSignatureP *coin_sigs[static num_coins],
    155   const struct TALER_MerchantPublicKeyP *merchant_pub,
    156   const struct TALER_ExchangePublicKeyP *exchange_pub,
    157   const struct TALER_ExchangeSignatureP *exchange_sig)
    158 {
    159   struct TALER_DepositConfirmationPS dcs = {
    160     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT),
    161     .purpose.size = htonl (sizeof (struct TALER_DepositConfirmationPS)),
    162     .h_contract_terms = *h_contract_terms,
    163     .h_wire = *h_wire,
    164     .exchange_timestamp = GNUNET_TIME_timestamp_hton (exchange_timestamp),
    165     .wire_deadline = GNUNET_TIME_timestamp_hton (wire_deadline),
    166     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
    167     .merchant_pub = *merchant_pub
    168   };
    169   struct GNUNET_HashContext *hc;
    170 
    171   hc = GNUNET_CRYPTO_hash_context_start ();
    172   for (unsigned int i = 0; i<num_coins; i++)
    173     GNUNET_CRYPTO_hash_context_read (hc,
    174                                      coin_sigs[i],
    175                                      sizeof (*coin_sigs[i]));
    176   GNUNET_CRYPTO_hash_context_finish (hc,
    177                                      &dcs.h_coin_sigs);
    178   if (NULL != h_policy)
    179     dcs.h_policy = *h_policy;
    180   TALER_amount_hton (&dcs.total_without_fee,
    181                      total_without_fee);
    182   if (GNUNET_OK !=
    183       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_DEPOSIT,
    184                                   &dcs,
    185                                   &exchange_sig->eddsa_signature,
    186                                   &exchange_pub->eddsa_pub))
    187   {
    188     GNUNET_break_op (0);
    189     return GNUNET_SYSERR;
    190   }
    191   return GNUNET_OK;
    192 }
    193 
    194 
    195 GNUNET_NETWORK_STRUCT_BEGIN
    196 
    197 /**
    198  * @brief Format used to generate the signature on a request to refund
    199  * a coin into the account of the customer.
    200  */
    201 struct TALER_RefundConfirmationPS
    202 {
    203   /**
    204    * Purpose must be #TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND.
    205    */
    206   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    207 
    208   /**
    209    * Hash over the proposal data to identify the contract
    210    * which is being refunded.
    211    */
    212   struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
    213 
    214   /**
    215    * The coin's public key.  This is the value that must have been
    216    * signed (blindly) by the Exchange.
    217    */
    218   struct TALER_CoinSpendPublicKeyP coin_pub;
    219 
    220   /**
    221    * The Merchant's public key.  Allows the merchant to later refund
    222    * the transaction or to inquire about the wire transfer identifier.
    223    */
    224   struct TALER_MerchantPublicKeyP merchant;
    225 
    226   /**
    227    * Merchant-generated transaction ID for the refund.
    228    */
    229   uint64_t rtransaction_id GNUNET_PACKED;
    230 
    231   /**
    232    * Amount to be refunded, including refund fee charged by the
    233    * exchange to the customer.
    234    */
    235   struct TALER_AmountNBO refund_amount;
    236 };
    237 
    238 GNUNET_NETWORK_STRUCT_END
    239 
    240 
    241 enum TALER_ErrorCode
    242 TALER_exchange_online_refund_confirmation_sign (
    243   TALER_ExchangeSignCallback scb,
    244   const struct TALER_PrivateContractHashP *h_contract_terms,
    245   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    246   const struct TALER_MerchantPublicKeyP *merchant,
    247   uint64_t rtransaction_id,
    248   const struct TALER_Amount *refund_amount,
    249   struct TALER_ExchangePublicKeyP *pub,
    250   struct TALER_ExchangeSignatureP *sig)
    251 {
    252   struct TALER_RefundConfirmationPS rc = {
    253     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
    254     .purpose.size = htonl (sizeof (rc)),
    255     .h_contract_terms = *h_contract_terms,
    256     .coin_pub = *coin_pub,
    257     .merchant = *merchant,
    258     .rtransaction_id = GNUNET_htonll (rtransaction_id)
    259   };
    260 
    261   TALER_amount_hton (&rc.refund_amount,
    262                      refund_amount);
    263   return scb (&rc.purpose,
    264               pub,
    265               sig);
    266 }
    267 
    268 
    269 enum GNUNET_GenericReturnValue
    270 TALER_exchange_online_refund_confirmation_verify (
    271   const struct TALER_PrivateContractHashP *h_contract_terms,
    272   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    273   const struct TALER_MerchantPublicKeyP *merchant,
    274   uint64_t rtransaction_id,
    275   const struct TALER_Amount *refund_amount,
    276   const struct TALER_ExchangePublicKeyP *pub,
    277   const struct TALER_ExchangeSignatureP *sig)
    278 {
    279   struct TALER_RefundConfirmationPS rc = {
    280     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND),
    281     .purpose.size = htonl (sizeof (rc)),
    282     .h_contract_terms = *h_contract_terms,
    283     .coin_pub = *coin_pub,
    284     .merchant = *merchant,
    285     .rtransaction_id = GNUNET_htonll (rtransaction_id)
    286   };
    287 
    288   TALER_amount_hton (&rc.refund_amount,
    289                      refund_amount);
    290   if (GNUNET_OK !=
    291       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_REFUND,
    292                                   &rc,
    293                                   &sig->eddsa_signature,
    294                                   &pub->eddsa_pub))
    295   {
    296     GNUNET_break_op (0);
    297     return GNUNET_SYSERR;
    298   }
    299   return GNUNET_OK;
    300 }
    301 
    302 
    303 GNUNET_NETWORK_STRUCT_BEGIN
    304 
    305 /**
    306  * @brief Format of the block signed by the Exchange in response to a successful
    307  * "/refresh/melt" request.  Hereby the exchange affirms that all of the
    308  * coins were successfully melted.  This also commits the exchange to a
    309  * particular index to not be revealed during the refresh.
    310  */
    311 struct TALER_RefreshMeltConfirmationPS
    312 {
    313   /**
    314    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT.   Signed
    315    * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
    316    */
    317   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    318 
    319   /**
    320    * Commitment made in the /refresh/melt.
    321    */
    322   struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
    323 
    324   /**
    325    * Index that the client will not have to reveal, in NBO.
    326    * Must be smaller than #TALER_CNC_KAPPA.
    327    */
    328   uint32_t noreveal_index GNUNET_PACKED;
    329 
    330 };
    331 
    332 GNUNET_NETWORK_STRUCT_END
    333 
    334 
    335 enum TALER_ErrorCode
    336 TALER_exchange_online_melt_confirmation_sign (
    337   TALER_ExchangeSignCallback scb,
    338   const struct TALER_RefreshCommitmentP *rc,
    339   uint32_t noreveal_index,
    340   struct TALER_ExchangePublicKeyP *pub,
    341   struct TALER_ExchangeSignatureP *sig)
    342 {
    343   struct TALER_RefreshMeltConfirmationPS confirm = {
    344     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
    345     .purpose.size = htonl (sizeof (confirm)),
    346     .rc = *rc,
    347     .noreveal_index = htonl (noreveal_index)
    348   };
    349 
    350   return scb (&confirm.purpose,
    351               pub,
    352               sig);
    353 }
    354 
    355 
    356 enum GNUNET_GenericReturnValue
    357 TALER_exchange_online_melt_confirmation_verify (
    358   const struct TALER_RefreshCommitmentP *rc,
    359   uint32_t noreveal_index,
    360   const struct TALER_ExchangePublicKeyP *exchange_pub,
    361   const struct TALER_ExchangeSignatureP *exchange_sig)
    362 {
    363   struct TALER_RefreshMeltConfirmationPS confirm = {
    364     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT),
    365     .purpose.size = htonl (sizeof (confirm)),
    366     .rc = *rc,
    367     .noreveal_index = htonl (noreveal_index)
    368   };
    369 
    370   return
    371     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_MELT,
    372                                 &confirm,
    373                                 &exchange_sig->eddsa_signature,
    374                                 &exchange_pub->eddsa_pub);
    375 }
    376 
    377 
    378 GNUNET_NETWORK_STRUCT_BEGIN
    379 
    380 /**
    381  * @brief Format of the block signed by the Exchange in response to a
    382  * successful "/withdraw" request.
    383  * If age restriction is set, the exchange hereby also
    384  * affirms that the commitment along with the maximum age group and
    385  * the amount were accepted.  This also commits the exchange to a particular
    386  * index to not be revealed during the reveal.
    387  */
    388 struct TALER_WithdrawConfirmationPS
    389 {
    390   /**
    391    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW.   Signed by a
    392    * `struct TALER_ExchangePublicKeyP` using EdDSA.
    393    */
    394   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    395 
    396   /**
    397    * Commitment made in the /withdraw call.
    398    */
    399   struct TALER_HashBlindedPlanchetsP h_planchets GNUNET_PACKED;
    400 
    401   /**
    402    * If age restriction does not apply to this withdrawal,
    403    * (i.e. max_age was not set during the request)
    404    * MUST be 0xFFFFFFFF.
    405    * Otherwise (i.e. age restriction applies):
    406    * index that the client will not have to reveal, in NBO,
    407    * MUST be smaller than #TALER_CNC_KAPPA.
    408    */
    409   uint32_t noreveal_index GNUNET_PACKED;
    410 
    411 };
    412 
    413 GNUNET_NETWORK_STRUCT_END
    414 
    415 enum TALER_ErrorCode
    416 TALER_exchange_online_withdraw_age_confirmation_sign (
    417   TALER_ExchangeSignCallback scb,
    418   const struct TALER_HashBlindedPlanchetsP *h_planchets,
    419   uint32_t noreveal_index,
    420   struct TALER_ExchangePublicKeyP *pub,
    421   struct TALER_ExchangeSignatureP *sig)
    422 {
    423 
    424   struct TALER_WithdrawConfirmationPS confirm = {
    425     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
    426     .purpose.size = htonl (sizeof (confirm)),
    427     .h_planchets = *h_planchets,
    428     .noreveal_index = htonl (noreveal_index)
    429   };
    430 
    431   return scb (&confirm.purpose,
    432               pub,
    433               sig);
    434 }
    435 
    436 
    437 enum TALER_ErrorCode
    438 TALER_exchange_online_withdraw_confirmation_sign (
    439   TALER_ExchangeSignCallback scb,
    440   const struct TALER_HashBlindedPlanchetsP *h_planchets,
    441   struct TALER_ExchangePublicKeyP *pub,
    442   struct TALER_ExchangeSignatureP *sig)
    443 {
    444 
    445   struct TALER_WithdrawConfirmationPS confirm = {
    446     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
    447     .purpose.size = htonl (sizeof (confirm)),
    448     .h_planchets = *h_planchets,
    449     .noreveal_index = htonl (0xFFFFFFFF)
    450   };
    451 
    452   return scb (&confirm.purpose,
    453               pub,
    454               sig);
    455 }
    456 
    457 
    458 enum GNUNET_GenericReturnValue
    459 TALER_exchange_online_withdraw_age_confirmation_verify (
    460   const struct TALER_HashBlindedPlanchetsP *h_planchets,
    461   uint32_t noreveal_index,
    462   const struct TALER_ExchangePublicKeyP *exchange_pub,
    463   const struct TALER_ExchangeSignatureP *exchange_sig)
    464 {
    465   struct TALER_WithdrawConfirmationPS confirm = {
    466     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
    467     .purpose.size = htonl (sizeof (confirm)),
    468     .h_planchets = *h_planchets,
    469     .noreveal_index = htonl (noreveal_index)
    470   };
    471 
    472   if (GNUNET_OK !=
    473       GNUNET_CRYPTO_eddsa_verify (
    474         TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW,
    475         &confirm,
    476         &exchange_sig->eddsa_signature,
    477         &exchange_pub->eddsa_pub))
    478   {
    479     GNUNET_break_op (0);
    480     return GNUNET_SYSERR;
    481   }
    482   return GNUNET_OK;
    483 }
    484 
    485 
    486 enum GNUNET_GenericReturnValue
    487 TALER_exchange_online_withdraw_confirmation_verify (
    488   const struct TALER_HashBlindedPlanchetsP *h_planchets,
    489   const struct TALER_ExchangePublicKeyP *exchange_pub,
    490   const struct TALER_ExchangeSignatureP *exchange_sig)
    491 {
    492   struct TALER_WithdrawConfirmationPS confirm = {
    493     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW),
    494     .purpose.size = htonl (sizeof (confirm)),
    495     .h_planchets = *h_planchets,
    496     .noreveal_index = htonl (0xFFFFFFFF)
    497   };
    498 
    499   if (GNUNET_OK !=
    500       GNUNET_CRYPTO_eddsa_verify (
    501         TALER_SIGNATURE_EXCHANGE_CONFIRM_WITHDRAW,
    502         &confirm,
    503         &exchange_sig->eddsa_signature,
    504         &exchange_pub->eddsa_pub))
    505   {
    506     GNUNET_break_op (0);
    507     return GNUNET_SYSERR;
    508   }
    509   return GNUNET_OK;
    510 }
    511 
    512 
    513 GNUNET_NETWORK_STRUCT_BEGIN
    514 
    515 /**
    516  * @brief Signature made by the exchange over the full set of keys, used
    517  * to detect cheating exchanges that give out different sets to
    518  * different users.
    519  */
    520 struct TALER_ExchangeKeySetPS
    521 {
    522 
    523   /**
    524    * Purpose is #TALER_SIGNATURE_EXCHANGE_KEY_SET.   Signed
    525    * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
    526    */
    527   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    528 
    529   /**
    530    * Time of the key set issue.
    531    */
    532   struct GNUNET_TIME_TimestampNBO list_issue_date;
    533 
    534   /**
    535    * Hash over the various denomination signing keys returned.
    536    */
    537   struct GNUNET_HashCode hc GNUNET_PACKED;
    538 };
    539 
    540 GNUNET_NETWORK_STRUCT_END
    541 
    542 
    543 enum TALER_ErrorCode
    544 TALER_exchange_online_key_set_sign (
    545   TALER_ExchangeSignCallback2 scb,
    546   void *cls,
    547   struct GNUNET_TIME_Timestamp timestamp,
    548   const struct GNUNET_HashCode *hc,
    549   struct TALER_ExchangePublicKeyP *pub,
    550   struct TALER_ExchangeSignatureP *sig)
    551 {
    552   struct TALER_ExchangeKeySetPS ks = {
    553     .purpose.size = htonl (sizeof (ks)),
    554     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
    555     .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
    556     .hc = *hc
    557   };
    558 
    559   return scb (cls,
    560               &ks.purpose,
    561               pub,
    562               sig);
    563 }
    564 
    565 
    566 enum GNUNET_GenericReturnValue
    567 TALER_exchange_online_key_set_verify (
    568   struct GNUNET_TIME_Timestamp timestamp,
    569   const struct GNUNET_HashCode *hc,
    570   const struct TALER_ExchangePublicKeyP *pub,
    571   const struct TALER_ExchangeSignatureP *sig)
    572 {
    573   struct TALER_ExchangeKeySetPS ks = {
    574     .purpose.size = htonl (sizeof (ks)),
    575     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_KEY_SET),
    576     .list_issue_date = GNUNET_TIME_timestamp_hton (timestamp),
    577     .hc = *hc
    578   };
    579 
    580   return
    581     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_KEY_SET,
    582                                 &ks,
    583                                 &sig->eddsa_signature,
    584                                 &pub->eddsa_pub);
    585 }
    586 
    587 
    588 GNUNET_NETWORK_STRUCT_BEGIN
    589 
    590 /**
    591  * @brief Format internally used for packing the detailed information
    592  * to generate the signature for /track/transfer signatures.
    593  */
    594 struct TALER_WireDepositDetailP
    595 {
    596 
    597   /**
    598    * Hash of the contract
    599    */
    600   struct TALER_PrivateContractHashP h_contract_terms;
    601 
    602   /**
    603    * Time when the wire transfer was performed by the exchange.
    604    */
    605   struct GNUNET_TIME_TimestampNBO execution_time;
    606 
    607   /**
    608    * Coin's public key.
    609    */
    610   struct TALER_CoinSpendPublicKeyP coin_pub;
    611 
    612   /**
    613    * Total value of the coin.
    614    */
    615   struct TALER_AmountNBO deposit_value;
    616 
    617   /**
    618    * Fees charged by the exchange for the deposit.
    619    */
    620   struct TALER_AmountNBO deposit_fee;
    621 
    622 };
    623 
    624 GNUNET_NETWORK_STRUCT_END
    625 
    626 
    627 void
    628 TALER_exchange_online_wire_deposit_append (
    629   struct GNUNET_HashContext *hash_context,
    630   const struct TALER_PrivateContractHashP *h_contract_terms,
    631   struct GNUNET_TIME_Timestamp execution_time,
    632   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    633   const struct TALER_Amount *deposit_value,
    634   const struct TALER_Amount *deposit_fee)
    635 {
    636   struct TALER_WireDepositDetailP dd = {
    637     .h_contract_terms = *h_contract_terms,
    638     .execution_time = GNUNET_TIME_timestamp_hton (execution_time),
    639     .coin_pub = *coin_pub
    640   };
    641   TALER_amount_hton (&dd.deposit_value,
    642                      deposit_value);
    643   TALER_amount_hton (&dd.deposit_fee,
    644                      deposit_fee);
    645   GNUNET_CRYPTO_hash_context_read (hash_context,
    646                                    &dd,
    647                                    sizeof (dd));
    648 }
    649 
    650 
    651 GNUNET_NETWORK_STRUCT_BEGIN
    652 
    653 /**
    654  * @brief Format used to generate the signature for /wire/deposit
    655  * replies.
    656  */
    657 struct TALER_WireDepositDataPS
    658 {
    659   /**
    660    * Purpose header for the signature over the contract with
    661    * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT.
    662    */
    663   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    664 
    665   /**
    666    * Total amount that was transferred.
    667    */
    668   struct TALER_AmountNBO total;
    669 
    670   /**
    671    * Wire fee that was charged.
    672    */
    673   struct TALER_AmountNBO wire_fee;
    674 
    675   /**
    676    * Public key of the merchant (for all aggregated transactions).
    677    */
    678   struct TALER_MerchantPublicKeyP merchant_pub;
    679 
    680   /**
    681    * Hash of bank account of the merchant.
    682    */
    683   struct TALER_FullPaytoHashP h_payto;
    684 
    685   /**
    686    * Hash of the individual deposits that were aggregated,
    687    * each in the format of a `struct TALER_WireDepositDetailP`.
    688    */
    689   struct GNUNET_HashCode h_details;
    690 
    691 };
    692 
    693 GNUNET_NETWORK_STRUCT_END
    694 
    695 
    696 enum TALER_ErrorCode
    697 TALER_exchange_online_wire_deposit_sign (
    698   TALER_ExchangeSignCallback scb,
    699   const struct TALER_Amount *total,
    700   const struct TALER_Amount *wire_fee,
    701   const struct TALER_MerchantPublicKeyP *merchant_pub,
    702   const struct TALER_FullPayto payto,
    703   const struct GNUNET_HashCode *h_details,
    704   struct TALER_ExchangePublicKeyP *pub,
    705   struct TALER_ExchangeSignatureP *sig)
    706 {
    707   struct TALER_WireDepositDataPS wdp = {
    708     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
    709     .purpose.size = htonl (sizeof (wdp)),
    710     .merchant_pub = *merchant_pub,
    711     .h_details = *h_details
    712   };
    713 
    714   TALER_amount_hton (&wdp.total,
    715                      total);
    716   TALER_amount_hton (&wdp.wire_fee,
    717                      wire_fee);
    718   TALER_full_payto_hash (payto,
    719                          &wdp.h_payto);
    720   return scb (&wdp.purpose,
    721               pub,
    722               sig);
    723 }
    724 
    725 
    726 enum GNUNET_GenericReturnValue
    727 TALER_exchange_online_wire_deposit_verify (
    728   const struct TALER_Amount *total,
    729   const struct TALER_Amount *wire_fee,
    730   const struct TALER_MerchantPublicKeyP *merchant_pub,
    731   const struct TALER_FullPaytoHashP *h_payto,
    732   const struct GNUNET_HashCode *h_details,
    733   const struct TALER_ExchangePublicKeyP *pub,
    734   const struct TALER_ExchangeSignatureP *sig)
    735 {
    736   struct TALER_WireDepositDataPS wdp = {
    737     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT),
    738     .purpose.size = htonl (sizeof (wdp)),
    739     .merchant_pub = *merchant_pub,
    740     .h_details = *h_details,
    741     .h_payto = *h_payto
    742   };
    743 
    744   TALER_amount_hton (&wdp.total,
    745                      total);
    746   TALER_amount_hton (&wdp.wire_fee,
    747                      wire_fee);
    748   return GNUNET_CRYPTO_eddsa_verify (
    749     TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE_DEPOSIT,
    750     &wdp,
    751     &sig->eddsa_signature,
    752     &pub->eddsa_pub);
    753 }
    754 
    755 
    756 GNUNET_NETWORK_STRUCT_BEGIN
    757 
    758 /**
    759  * Details affirmed by the exchange about a wire transfer the exchange
    760  * claims to have done with respect to a deposit operation.
    761  */
    762 struct TALER_ConfirmWirePS
    763 {
    764   /**
    765    * Purpose header for the signature over the contract with
    766    * purpose #TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE.
    767    */
    768   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    769 
    770   /**
    771    * Hash over the wiring information of the merchant.
    772    */
    773   struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
    774 
    775   /**
    776    * Hash over the contract for which this deposit is made.
    777    */
    778   struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
    779 
    780   /**
    781    * Raw value (binary encoding) of the wire transfer subject.
    782    */
    783   struct TALER_WireTransferIdentifierRawP wtid;
    784 
    785   /**
    786    * The coin's public key.  This is the value that must have been
    787    * signed (blindly) by the Exchange.
    788    */
    789   struct TALER_CoinSpendPublicKeyP coin_pub;
    790 
    791   /**
    792    * When did the exchange execute this transfer? Note that the
    793    * timestamp may not be exactly the same on the wire, i.e.
    794    * because the wire has a different timezone or resolution.
    795    */
    796   struct GNUNET_TIME_TimestampNBO execution_time;
    797 
    798   /**
    799    * The contribution of @e coin_pub to the total transfer volume.
    800    * This is the value of the deposit minus the fee.
    801    */
    802   struct TALER_AmountNBO coin_contribution;
    803 
    804 };
    805 
    806 GNUNET_NETWORK_STRUCT_END
    807 
    808 
    809 enum TALER_ErrorCode
    810 TALER_exchange_online_confirm_wire_sign (
    811   TALER_ExchangeSignCallback scb,
    812   const struct TALER_MerchantWireHashP *h_wire,
    813   const struct TALER_PrivateContractHashP *h_contract_terms,
    814   const struct TALER_WireTransferIdentifierRawP *wtid,
    815   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    816   struct GNUNET_TIME_Timestamp execution_time,
    817   const struct TALER_Amount *coin_contribution,
    818   struct TALER_ExchangePublicKeyP *pub,
    819   struct TALER_ExchangeSignatureP *sig)
    820 
    821 {
    822   struct TALER_ConfirmWirePS cw = {
    823     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
    824     .purpose.size = htonl (sizeof (cw)),
    825     .h_wire = *h_wire,
    826     .h_contract_terms = *h_contract_terms,
    827     .wtid = *wtid,
    828     .coin_pub = *coin_pub,
    829     .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
    830   };
    831 
    832   TALER_amount_hton (&cw.coin_contribution,
    833                      coin_contribution);
    834   return scb (&cw.purpose,
    835               pub,
    836               sig);
    837 }
    838 
    839 
    840 enum GNUNET_GenericReturnValue
    841 TALER_exchange_online_confirm_wire_verify (
    842   const struct TALER_MerchantWireHashP *h_wire,
    843   const struct TALER_PrivateContractHashP *h_contract_terms,
    844   const struct TALER_WireTransferIdentifierRawP *wtid,
    845   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    846   struct GNUNET_TIME_Timestamp execution_time,
    847   const struct TALER_Amount *coin_contribution,
    848   const struct TALER_ExchangePublicKeyP *pub,
    849   const struct TALER_ExchangeSignatureP *sig)
    850 {
    851   struct TALER_ConfirmWirePS cw = {
    852     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE),
    853     .purpose.size = htonl (sizeof (cw)),
    854     .h_wire = *h_wire,
    855     .h_contract_terms = *h_contract_terms,
    856     .wtid = *wtid,
    857     .coin_pub = *coin_pub,
    858     .execution_time = GNUNET_TIME_timestamp_hton (execution_time)
    859   };
    860 
    861   TALER_amount_hton (&cw.coin_contribution,
    862                      coin_contribution);
    863   return
    864     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_WIRE,
    865                                 &cw,
    866                                 &sig->eddsa_signature,
    867                                 &pub->eddsa_pub);
    868 }
    869 
    870 
    871 GNUNET_NETWORK_STRUCT_BEGIN
    872 
    873 /**
    874  * Response by which the exchange affirms that it will
    875  * refund a coin as part of the emergency /recoup
    876  * protocol.  The recoup will go back to the bank
    877  * account that created the reserve.
    878  */
    879 struct TALER_RecoupConfirmationPS
    880 {
    881 
    882   /**
    883    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP
    884    */
    885   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    886 
    887   /**
    888    * When did the exchange receive the recoup request?
    889    * Indirectly determines when the wire transfer is (likely)
    890    * to happen.
    891    */
    892   struct GNUNET_TIME_TimestampNBO timestamp;
    893 
    894   /**
    895    * How much of the coin's value will the exchange transfer?
    896    * (Needed in case the coin was partially spent.)
    897    */
    898   struct TALER_AmountNBO recoup_amount;
    899 
    900   /**
    901    * Public key of the coin.
    902    */
    903   struct TALER_CoinSpendPublicKeyP coin_pub;
    904 
    905   /**
    906    * Public key of the reserve that will receive the recoup.
    907    */
    908   struct TALER_ReservePublicKeyP reserve_pub;
    909 };
    910 
    911 GNUNET_NETWORK_STRUCT_END
    912 
    913 
    914 enum TALER_ErrorCode
    915 TALER_exchange_online_confirm_recoup_sign (
    916   TALER_ExchangeSignCallback scb,
    917   struct GNUNET_TIME_Timestamp timestamp,
    918   const struct TALER_Amount *recoup_amount,
    919   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    920   const struct TALER_ReservePublicKeyP *reserve_pub,
    921   struct TALER_ExchangePublicKeyP *pub,
    922   struct TALER_ExchangeSignatureP *sig)
    923 {
    924   struct TALER_RecoupConfirmationPS pc = {
    925     .purpose.size = htonl (sizeof (pc)),
    926     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
    927     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    928     .coin_pub = *coin_pub,
    929     .reserve_pub = *reserve_pub
    930   };
    931 
    932   TALER_amount_hton (&pc.recoup_amount,
    933                      recoup_amount);
    934   return scb (&pc.purpose,
    935               pub,
    936               sig);
    937 }
    938 
    939 
    940 enum GNUNET_GenericReturnValue
    941 TALER_exchange_online_confirm_recoup_verify (
    942   struct GNUNET_TIME_Timestamp timestamp,
    943   const struct TALER_Amount *recoup_amount,
    944   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    945   const struct TALER_ReservePublicKeyP *reserve_pub,
    946   const struct TALER_ExchangePublicKeyP *pub,
    947   const struct TALER_ExchangeSignatureP *sig)
    948 {
    949   struct TALER_RecoupConfirmationPS pc = {
    950     .purpose.size = htonl (sizeof (pc)),
    951     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP),
    952     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
    953     .coin_pub = *coin_pub,
    954     .reserve_pub = *reserve_pub
    955   };
    956 
    957   TALER_amount_hton (&pc.recoup_amount,
    958                      recoup_amount);
    959   return
    960     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP,
    961                                 &pc,
    962                                 &sig->eddsa_signature,
    963                                 &pub->eddsa_pub);
    964 }
    965 
    966 
    967 GNUNET_NETWORK_STRUCT_BEGIN
    968 
    969 /**
    970  * Response by which the exchange affirms that it will refund a refreshed coin
    971  * as part of the emergency /recoup protocol.  The recoup will go back to the
    972  * old coin's balance.
    973  */
    974 struct TALER_RecoupRefreshConfirmationPS
    975 {
    976 
    977   /**
    978    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH
    979    */
    980   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    981 
    982   /**
    983    * When did the exchange receive the recoup request?
    984    * Indirectly determines when the wire transfer is (likely)
    985    * to happen.
    986    */
    987   struct GNUNET_TIME_TimestampNBO timestamp;
    988 
    989   /**
    990    * How much of the coin's value will the exchange transfer?
    991    * (Needed in case the coin was partially spent.)
    992    */
    993   struct TALER_AmountNBO recoup_amount;
    994 
    995   /**
    996    * Public key of the refreshed coin.
    997    */
    998   struct TALER_CoinSpendPublicKeyP coin_pub;
    999 
   1000   /**
   1001    * Public key of the old coin that will receive the recoup.
   1002    */
   1003   struct TALER_CoinSpendPublicKeyP old_coin_pub;
   1004 };
   1005 
   1006 GNUNET_NETWORK_STRUCT_END
   1007 
   1008 
   1009 enum TALER_ErrorCode
   1010 TALER_exchange_online_confirm_recoup_refresh_sign (
   1011   TALER_ExchangeSignCallback scb,
   1012   struct GNUNET_TIME_Timestamp timestamp,
   1013   const struct TALER_Amount *recoup_amount,
   1014   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   1015   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
   1016   struct TALER_ExchangePublicKeyP *pub,
   1017   struct TALER_ExchangeSignatureP *sig)
   1018 {
   1019   struct TALER_RecoupRefreshConfirmationPS pc = {
   1020     .purpose.purpose = htonl (
   1021       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
   1022     .purpose.size = htonl (sizeof (pc)),
   1023     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1024     .coin_pub = *coin_pub,
   1025     .old_coin_pub = *old_coin_pub
   1026   };
   1027 
   1028   TALER_amount_hton (&pc.recoup_amount,
   1029                      recoup_amount);
   1030   return scb (&pc.purpose,
   1031               pub,
   1032               sig);
   1033 }
   1034 
   1035 
   1036 enum GNUNET_GenericReturnValue
   1037 TALER_exchange_online_confirm_recoup_refresh_verify (
   1038   struct GNUNET_TIME_Timestamp timestamp,
   1039   const struct TALER_Amount *recoup_amount,
   1040   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   1041   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
   1042   const struct TALER_ExchangePublicKeyP *pub,
   1043   const struct TALER_ExchangeSignatureP *sig)
   1044 {
   1045   struct TALER_RecoupRefreshConfirmationPS pc = {
   1046     .purpose.purpose = htonl (
   1047       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH),
   1048     .purpose.size = htonl (sizeof (pc)),
   1049     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1050     .coin_pub = *coin_pub,
   1051     .old_coin_pub = *old_coin_pub
   1052   };
   1053 
   1054   TALER_amount_hton (&pc.recoup_amount,
   1055                      recoup_amount);
   1056 
   1057   return
   1058     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH,
   1059                                 &pc,
   1060                                 &sig->eddsa_signature,
   1061                                 &pub->eddsa_pub);
   1062 }
   1063 
   1064 
   1065 void
   1066 TALER_recoup_batch_hash (
   1067   size_t num_recoups,
   1068   const struct TALER_RecoupedCoin recoups[static num_recoups],
   1069   struct GNUNET_HashCode *h_recoups)
   1070 {
   1071   struct GNUNET_HashContext *hc;
   1072 
   1073   hc = GNUNET_CRYPTO_hash_context_start ();
   1074   for (size_t i = 0; i < num_recoups; i++)
   1075   {
   1076     struct TALER_AmountNBO amount_nbo;
   1077 
   1078     GNUNET_CRYPTO_hash_context_read (hc,
   1079                                      &recoups[i].coin_pub,
   1080                                      sizeof (recoups[i].coin_pub));
   1081     TALER_amount_hton (&amount_nbo,
   1082                        &recoups[i].amount);
   1083     GNUNET_CRYPTO_hash_context_read (hc,
   1084                                      &amount_nbo,
   1085                                      sizeof (amount_nbo));
   1086   }
   1087   GNUNET_CRYPTO_hash_context_finish (hc,
   1088                                      h_recoups);
   1089 }
   1090 
   1091 
   1092 GNUNET_NETWORK_STRUCT_BEGIN
   1093 
   1094 /**
   1095  * Response by which the exchange affirms that it credited a reserve
   1096  * for all coins recouped in one /recoup-withdraw request.
   1097  */
   1098 struct TALER_RecoupWithdrawBatchConfirmationPS
   1099 {
   1100 
   1101   /**
   1102    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH
   1103    */
   1104   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1105 
   1106   /**
   1107    * When did the exchange accept the recoup request?
   1108    */
   1109   struct GNUNET_TIME_TimestampNBO timestamp;
   1110 
   1111   /**
   1112    * Public key of the reserve that was credited.
   1113    */
   1114   struct TALER_ReservePublicKeyP reserve_pub;
   1115 
   1116   /**
   1117    * Commitment of the withdraw operation the coins originated from.
   1118    */
   1119   struct TALER_HashBlindedPlanchetsP planchets_h;
   1120 
   1121   /**
   1122    * Total amount credited to the reserve.
   1123    */
   1124   struct TALER_AmountNBO total_amount;
   1125 
   1126   /**
   1127    * Hash over the recouped coins and their amounts,
   1128    * see #TALER_recoup_batch_hash().
   1129    */
   1130   struct GNUNET_HashCode h_recoups;
   1131 };
   1132 
   1133 GNUNET_NETWORK_STRUCT_END
   1134 
   1135 
   1136 enum TALER_ErrorCode
   1137 TALER_exchange_online_confirm_recoup_withdraw_batch_sign (
   1138   TALER_ExchangeSignCallback scb,
   1139   struct GNUNET_TIME_Timestamp timestamp,
   1140   const struct TALER_ReservePublicKeyP *reserve_pub,
   1141   const struct TALER_HashBlindedPlanchetsP *planchets_h,
   1142   const struct TALER_Amount *total_amount,
   1143   const struct GNUNET_HashCode *h_recoups,
   1144   struct TALER_ExchangePublicKeyP *pub,
   1145   struct TALER_ExchangeSignatureP *sig)
   1146 {
   1147   struct TALER_RecoupWithdrawBatchConfirmationPS pc = {
   1148     .purpose.size = htonl (sizeof (pc)),
   1149     .purpose.purpose = htonl (
   1150       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH),
   1151     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1152     .reserve_pub = *reserve_pub,
   1153     .planchets_h = *planchets_h,
   1154     .h_recoups = *h_recoups
   1155   };
   1156 
   1157   TALER_amount_hton (&pc.total_amount,
   1158                      total_amount);
   1159   return scb (&pc.purpose,
   1160               pub,
   1161               sig);
   1162 }
   1163 
   1164 
   1165 enum GNUNET_GenericReturnValue
   1166 TALER_exchange_online_confirm_recoup_withdraw_batch_verify (
   1167   struct GNUNET_TIME_Timestamp timestamp,
   1168   const struct TALER_ReservePublicKeyP *reserve_pub,
   1169   const struct TALER_HashBlindedPlanchetsP *planchets_h,
   1170   const struct TALER_Amount *total_amount,
   1171   const struct GNUNET_HashCode *h_recoups,
   1172   const struct TALER_ExchangePublicKeyP *pub,
   1173   const struct TALER_ExchangeSignatureP *sig)
   1174 {
   1175   struct TALER_RecoupWithdrawBatchConfirmationPS pc = {
   1176     .purpose.size = htonl (sizeof (pc)),
   1177     .purpose.purpose = htonl (
   1178       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH),
   1179     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1180     .reserve_pub = *reserve_pub,
   1181     .planchets_h = *planchets_h,
   1182     .h_recoups = *h_recoups
   1183   };
   1184 
   1185   TALER_amount_hton (&pc.total_amount,
   1186                      total_amount);
   1187   return
   1188     GNUNET_CRYPTO_eddsa_verify (
   1189     TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_WITHDRAW_BATCH,
   1190     &pc,
   1191     &sig->eddsa_signature,
   1192     &pub->eddsa_pub);
   1193 }
   1194 
   1195 
   1196 GNUNET_NETWORK_STRUCT_BEGIN
   1197 
   1198 /**
   1199  * Response by which the exchange affirms that it credited an old coin
   1200  * for all coins recouped in one /recoup-refresh request.
   1201  */
   1202 struct TALER_RecoupRefreshBatchConfirmationPS
   1203 {
   1204 
   1205   /**
   1206    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH
   1207    */
   1208   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1209 
   1210   /**
   1211    * When did the exchange accept the recoup request?
   1212    */
   1213   struct GNUNET_TIME_TimestampNBO timestamp;
   1214 
   1215   /**
   1216    * Public key of the old coin that was credited.
   1217    */
   1218   struct TALER_CoinSpendPublicKeyP old_coin_pub;
   1219 
   1220   /**
   1221    * Commitment of the refresh operation the coins originated from.
   1222    */
   1223   struct TALER_RefreshCommitmentP rc;
   1224 
   1225   /**
   1226    * Total amount credited to the old coin.
   1227    */
   1228   struct TALER_AmountNBO total_amount;
   1229 
   1230   /**
   1231    * Hash over the recouped coins and their amounts,
   1232    * see #TALER_recoup_batch_hash().
   1233    */
   1234   struct GNUNET_HashCode h_recoups;
   1235 };
   1236 
   1237 GNUNET_NETWORK_STRUCT_END
   1238 
   1239 
   1240 enum TALER_ErrorCode
   1241 TALER_exchange_online_confirm_recoup_refresh_batch_sign (
   1242   TALER_ExchangeSignCallback scb,
   1243   struct GNUNET_TIME_Timestamp timestamp,
   1244   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
   1245   const struct TALER_RefreshCommitmentP *rc,
   1246   const struct TALER_Amount *total_amount,
   1247   const struct GNUNET_HashCode *h_recoups,
   1248   struct TALER_ExchangePublicKeyP *pub,
   1249   struct TALER_ExchangeSignatureP *sig)
   1250 {
   1251   struct TALER_RecoupRefreshBatchConfirmationPS pc = {
   1252     .purpose.size = htonl (sizeof (pc)),
   1253     .purpose.purpose = htonl (
   1254       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH),
   1255     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1256     .old_coin_pub = *old_coin_pub,
   1257     .rc = *rc,
   1258     .h_recoups = *h_recoups
   1259   };
   1260 
   1261   TALER_amount_hton (&pc.total_amount,
   1262                      total_amount);
   1263   return scb (&pc.purpose,
   1264               pub,
   1265               sig);
   1266 }
   1267 
   1268 
   1269 enum GNUNET_GenericReturnValue
   1270 TALER_exchange_online_confirm_recoup_refresh_batch_verify (
   1271   struct GNUNET_TIME_Timestamp timestamp,
   1272   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
   1273   const struct TALER_RefreshCommitmentP *rc,
   1274   const struct TALER_Amount *total_amount,
   1275   const struct GNUNET_HashCode *h_recoups,
   1276   const struct TALER_ExchangePublicKeyP *pub,
   1277   const struct TALER_ExchangeSignatureP *sig)
   1278 {
   1279   struct TALER_RecoupRefreshBatchConfirmationPS pc = {
   1280     .purpose.size = htonl (sizeof (pc)),
   1281     .purpose.purpose = htonl (
   1282       TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH),
   1283     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1284     .old_coin_pub = *old_coin_pub,
   1285     .rc = *rc,
   1286     .h_recoups = *h_recoups
   1287   };
   1288 
   1289   TALER_amount_hton (&pc.total_amount,
   1290                      total_amount);
   1291   return
   1292     GNUNET_CRYPTO_eddsa_verify (
   1293     TALER_SIGNATURE_EXCHANGE_CONFIRM_RECOUP_REFRESH_BATCH,
   1294     &pc,
   1295     &sig->eddsa_signature,
   1296     &pub->eddsa_pub);
   1297 }
   1298 
   1299 
   1300 GNUNET_NETWORK_STRUCT_BEGIN
   1301 
   1302 /**
   1303  * Response by which the exchange affirms that it does not
   1304  * currently know a denomination by the given hash.
   1305  */
   1306 struct TALER_DenominationUnknownAffirmationPS
   1307 {
   1308 
   1309   /**
   1310    * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN
   1311    */
   1312   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1313 
   1314   /**
   1315    * When did the exchange sign this message.
   1316    */
   1317   struct GNUNET_TIME_TimestampNBO timestamp;
   1318 
   1319   /**
   1320    * Hash of the public denomination key we do not know.
   1321    */
   1322   struct TALER_DenominationHashP h_denom_pub;
   1323 };
   1324 
   1325 GNUNET_NETWORK_STRUCT_END
   1326 
   1327 
   1328 enum TALER_ErrorCode
   1329 TALER_exchange_online_denomination_unknown_sign (
   1330   TALER_ExchangeSignCallback scb,
   1331   struct GNUNET_TIME_Timestamp timestamp,
   1332   const struct TALER_DenominationHashP *h_denom_pub,
   1333   struct TALER_ExchangePublicKeyP *pub,
   1334   struct TALER_ExchangeSignatureP *sig)
   1335 {
   1336   struct TALER_DenominationUnknownAffirmationPS dua = {
   1337     .purpose.size = htonl (sizeof (dua)),
   1338     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
   1339     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1340     .h_denom_pub = *h_denom_pub,
   1341   };
   1342 
   1343   return scb (&dua.purpose,
   1344               pub,
   1345               sig);
   1346 }
   1347 
   1348 
   1349 enum GNUNET_GenericReturnValue
   1350 TALER_exchange_online_denomination_unknown_verify (
   1351   struct GNUNET_TIME_Timestamp timestamp,
   1352   const struct TALER_DenominationHashP *h_denom_pub,
   1353   const struct TALER_ExchangePublicKeyP *pub,
   1354   const struct TALER_ExchangeSignatureP *sig)
   1355 {
   1356   struct TALER_DenominationUnknownAffirmationPS dua = {
   1357     .purpose.size = htonl (sizeof (dua)),
   1358     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN),
   1359     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1360     .h_denom_pub = *h_denom_pub,
   1361   };
   1362 
   1363   return
   1364     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_UNKNOWN,
   1365                                 &dua,
   1366                                 &sig->eddsa_signature,
   1367                                 &pub->eddsa_pub);
   1368 }
   1369 
   1370 
   1371 GNUNET_NETWORK_STRUCT_BEGIN
   1372 
   1373 /**
   1374  * Response by which the exchange affirms that it does not
   1375  * currently consider the given denomination to be valid
   1376  * for the requested operation.
   1377  */
   1378 struct TALER_DenominationExpiredAffirmationPS
   1379 {
   1380 
   1381   /**
   1382    * Purpose is #TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED
   1383    */
   1384   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1385 
   1386   /**
   1387    * When did the exchange sign this message.
   1388    */
   1389   struct GNUNET_TIME_TimestampNBO timestamp;
   1390 
   1391   /**
   1392    * Name of the operation that is not allowed at this time.  Might NOT be 0-terminated, but is padded with 0s.
   1393    */
   1394   char operation[8];
   1395 
   1396   /**
   1397    * Hash of the public denomination key we do not know.
   1398    */
   1399   struct TALER_DenominationHashP h_denom_pub;
   1400 
   1401 };
   1402 
   1403 GNUNET_NETWORK_STRUCT_END
   1404 
   1405 
   1406 enum TALER_ErrorCode
   1407 TALER_exchange_online_denomination_expired_sign (
   1408   TALER_ExchangeSignCallback scb,
   1409   struct GNUNET_TIME_Timestamp timestamp,
   1410   const struct TALER_DenominationHashP *h_denom_pub,
   1411   const char *op,
   1412   struct TALER_ExchangePublicKeyP *pub,
   1413   struct TALER_ExchangeSignatureP *sig)
   1414 {
   1415   struct TALER_DenominationExpiredAffirmationPS dua = {
   1416     .purpose.size = htonl (sizeof (dua)),
   1417     .purpose.purpose = htonl (
   1418       TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
   1419     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1420     .h_denom_pub = *h_denom_pub,
   1421   };
   1422 
   1423   /* strncpy would create a compiler warning */
   1424   GNUNET_memcpy (dua.operation,
   1425                  op,
   1426                  GNUNET_MIN (sizeof (dua.operation),
   1427                              strlen (op)));
   1428   return scb (&dua.purpose,
   1429               pub,
   1430               sig);
   1431 }
   1432 
   1433 
   1434 enum GNUNET_GenericReturnValue
   1435 TALER_exchange_online_denomination_expired_verify (
   1436   struct GNUNET_TIME_Timestamp timestamp,
   1437   const struct TALER_DenominationHashP *h_denom_pub,
   1438   const char *op,
   1439   const struct TALER_ExchangePublicKeyP *pub,
   1440   const struct TALER_ExchangeSignatureP *sig)
   1441 {
   1442   struct TALER_DenominationExpiredAffirmationPS dua = {
   1443     .purpose.size = htonl (sizeof (dua)),
   1444     .purpose.purpose = htonl (
   1445       TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED),
   1446     .timestamp = GNUNET_TIME_timestamp_hton (timestamp),
   1447     .h_denom_pub = *h_denom_pub,
   1448   };
   1449 
   1450   /* strncpy would create a compiler warning */
   1451   GNUNET_memcpy (dua.operation,
   1452                  op,
   1453                  GNUNET_MIN (sizeof (dua.operation),
   1454                              strlen (op)));
   1455   return
   1456     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_AFFIRM_DENOM_EXPIRED,
   1457                                 &dua,
   1458                                 &sig->eddsa_signature,
   1459                                 &pub->eddsa_pub);
   1460 }
   1461 
   1462 
   1463 GNUNET_NETWORK_STRUCT_BEGIN
   1464 
   1465 /**
   1466  * Response by which the exchange affirms that it has
   1467  * closed a reserve and send back the funds.
   1468  */
   1469 struct TALER_ReserveCloseConfirmationPS
   1470 {
   1471 
   1472   /**
   1473    * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED
   1474    */
   1475   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1476 
   1477   /**
   1478    * When did the exchange initiate the wire transfer.
   1479    */
   1480   struct GNUNET_TIME_TimestampNBO timestamp;
   1481 
   1482   /**
   1483    * How much did the exchange send?
   1484    */
   1485   struct TALER_AmountNBO closing_amount;
   1486 
   1487   /**
   1488    * How much did the exchange charge for closing the reserve?
   1489    */
   1490   struct TALER_AmountNBO closing_fee;
   1491 
   1492   /**
   1493    * Public key of the reserve that was closed.
   1494    */
   1495   struct TALER_ReservePublicKeyP reserve_pub;
   1496 
   1497   /**
   1498    * Hash of the receiver's bank account.
   1499    */
   1500   struct TALER_FullPaytoHashP h_payto;
   1501 
   1502   /**
   1503    * Wire transfer subject.
   1504    */
   1505   struct TALER_WireTransferIdentifierRawP wtid;
   1506 };
   1507 
   1508 GNUNET_NETWORK_STRUCT_END
   1509 
   1510 
   1511 enum TALER_ErrorCode
   1512 TALER_exchange_online_reserve_closed_sign (
   1513   TALER_ExchangeSignCallback scb,
   1514   struct GNUNET_TIME_Timestamp timestamp,
   1515   const struct TALER_Amount *closing_amount,
   1516   const struct TALER_Amount *closing_fee,
   1517   const struct TALER_FullPayto payto,
   1518   const struct TALER_WireTransferIdentifierRawP *wtid,
   1519   const struct TALER_ReservePublicKeyP *reserve_pub,
   1520   struct TALER_ExchangePublicKeyP *pub,
   1521   struct TALER_ExchangeSignatureP *sig)
   1522 {
   1523   struct TALER_ReserveCloseConfirmationPS rcc = {
   1524     .purpose.size = htonl (sizeof (rcc)),
   1525     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
   1526     .wtid = *wtid,
   1527     .reserve_pub = *reserve_pub,
   1528     .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
   1529   };
   1530 
   1531   TALER_amount_hton (&rcc.closing_amount,
   1532                      closing_amount);
   1533   TALER_amount_hton (&rcc.closing_fee,
   1534                      closing_fee);
   1535   TALER_full_payto_hash (payto,
   1536                          &rcc.h_payto);
   1537   return scb (&rcc.purpose,
   1538               pub,
   1539               sig);
   1540 }
   1541 
   1542 
   1543 enum GNUNET_GenericReturnValue
   1544 TALER_exchange_online_reserve_closed_verify (
   1545   struct GNUNET_TIME_Timestamp timestamp,
   1546   const struct TALER_Amount *closing_amount,
   1547   const struct TALER_Amount *closing_fee,
   1548   const struct TALER_FullPayto payto,
   1549   const struct TALER_WireTransferIdentifierRawP *wtid,
   1550   const struct TALER_ReservePublicKeyP *reserve_pub,
   1551   const struct TALER_ExchangePublicKeyP *pub,
   1552   const struct TALER_ExchangeSignatureP *sig)
   1553 {
   1554   struct TALER_ReserveCloseConfirmationPS rcc = {
   1555     .purpose.size = htonl (sizeof (rcc)),
   1556     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED),
   1557     .wtid = *wtid,
   1558     .reserve_pub = *reserve_pub,
   1559     .timestamp = GNUNET_TIME_timestamp_hton (timestamp)
   1560   };
   1561 
   1562   TALER_amount_hton (&rcc.closing_amount,
   1563                      closing_amount);
   1564   TALER_amount_hton (&rcc.closing_fee,
   1565                      closing_fee);
   1566   TALER_full_payto_hash (payto,
   1567                          &rcc.h_payto);
   1568   return GNUNET_CRYPTO_eddsa_verify (
   1569     TALER_SIGNATURE_EXCHANGE_RESERVE_CLOSED,
   1570     &rcc,
   1571     &sig->eddsa_signature,
   1572     &pub->eddsa_pub);
   1573 }
   1574 
   1575 
   1576 GNUNET_NETWORK_STRUCT_BEGIN
   1577 
   1578 /**
   1579  * Response by which the exchange affirms that it has
   1580  * received funds deposited into a purse.
   1581  */
   1582 struct TALER_PurseCreateDepositConfirmationPS
   1583 {
   1584 
   1585   /**
   1586    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION
   1587    */
   1588   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1589 
   1590   /**
   1591    * When did the exchange receive the deposits.
   1592    */
   1593   struct GNUNET_TIME_TimestampNBO exchange_time;
   1594 
   1595   /**
   1596    * When will the purse expire?
   1597    */
   1598   struct GNUNET_TIME_TimestampNBO purse_expiration;
   1599 
   1600   /**
   1601    * How much should the purse ultimately contain.
   1602    */
   1603   struct TALER_AmountNBO amount_without_fee;
   1604 
   1605   /**
   1606    * How much was deposited so far.
   1607    */
   1608   struct TALER_AmountNBO total_deposited;
   1609 
   1610   /**
   1611    * Public key of the purse.
   1612    */
   1613   struct TALER_PurseContractPublicKeyP purse_pub;
   1614 
   1615   /**
   1616    * Hash of the contract of the purse.
   1617    */
   1618   struct TALER_PrivateContractHashP h_contract_terms;
   1619 
   1620 };
   1621 
   1622 GNUNET_NETWORK_STRUCT_END
   1623 
   1624 
   1625 enum TALER_ErrorCode
   1626 TALER_exchange_online_purse_created_sign (
   1627   TALER_ExchangeSignCallback scb,
   1628   struct GNUNET_TIME_Timestamp exchange_time,
   1629   struct GNUNET_TIME_Timestamp purse_expiration,
   1630   const struct TALER_Amount *amount_without_fee,
   1631   const struct TALER_Amount *total_deposited,
   1632   const struct TALER_PurseContractPublicKeyP *purse_pub,
   1633   const struct TALER_PrivateContractHashP *h_contract_terms,
   1634   struct TALER_ExchangePublicKeyP *pub,
   1635   struct TALER_ExchangeSignatureP *sig)
   1636 {
   1637   struct TALER_PurseCreateDepositConfirmationPS dc = {
   1638     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
   1639     .purpose.size = htonl (sizeof (dc)),
   1640     .h_contract_terms = *h_contract_terms,
   1641     .purse_pub = *purse_pub,
   1642     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
   1643     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
   1644   };
   1645 
   1646   TALER_amount_hton (&dc.amount_without_fee,
   1647                      amount_without_fee);
   1648   TALER_amount_hton (&dc.total_deposited,
   1649                      total_deposited);
   1650   return scb (&dc.purpose,
   1651               pub,
   1652               sig);
   1653 }
   1654 
   1655 
   1656 enum GNUNET_GenericReturnValue
   1657 TALER_exchange_online_purse_created_verify (
   1658   struct GNUNET_TIME_Timestamp exchange_time,
   1659   struct GNUNET_TIME_Timestamp purse_expiration,
   1660   const struct TALER_Amount *amount_without_fee,
   1661   const struct TALER_Amount *total_deposited,
   1662   const struct TALER_PurseContractPublicKeyP *purse_pub,
   1663   const struct TALER_PrivateContractHashP *h_contract_terms,
   1664   const struct TALER_ExchangePublicKeyP *pub,
   1665   const struct TALER_ExchangeSignatureP *sig)
   1666 {
   1667   struct TALER_PurseCreateDepositConfirmationPS dc = {
   1668     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION),
   1669     .purpose.size = htonl (sizeof (dc)),
   1670     .h_contract_terms = *h_contract_terms,
   1671     .purse_pub = *purse_pub,
   1672     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
   1673     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
   1674   };
   1675 
   1676   TALER_amount_hton (&dc.amount_without_fee,
   1677                      amount_without_fee);
   1678   TALER_amount_hton (&dc.total_deposited,
   1679                      total_deposited);
   1680   return GNUNET_CRYPTO_eddsa_verify (
   1681     TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_CREATION,
   1682     &dc,
   1683     &sig->eddsa_signature,
   1684     &pub->eddsa_pub);
   1685 }
   1686 
   1687 
   1688 GNUNET_NETWORK_STRUCT_BEGIN
   1689 
   1690 /**
   1691  * Response by which the exchange affirms that it has
   1692  * received funds deposited into a purse.
   1693  */
   1694 struct TALER_CoinPurseRefundConfirmationPS
   1695 {
   1696 
   1697   /**
   1698    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND
   1699    */
   1700   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1701 
   1702   /**
   1703    * Public key of the purse.
   1704    */
   1705   struct TALER_PurseContractPublicKeyP purse_pub;
   1706 
   1707   /**
   1708    * Public key of the coin.
   1709    */
   1710   struct TALER_CoinSpendPublicKeyP coin_pub;
   1711 
   1712   /**
   1713    * How much will be refunded to the purse.
   1714    */
   1715   struct TALER_AmountNBO refunded_amount;
   1716 
   1717   /**
   1718    * How much was the refund fee.
   1719    */
   1720   struct TALER_AmountNBO refund_fee;
   1721 
   1722 };
   1723 
   1724 GNUNET_NETWORK_STRUCT_END
   1725 
   1726 
   1727 enum TALER_ErrorCode
   1728 TALER_exchange_online_purse_refund_sign (
   1729   TALER_ExchangeSignCallback scb,
   1730   const struct TALER_Amount *amount_without_fee,
   1731   const struct TALER_Amount *refund_fee,
   1732   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   1733   const struct TALER_PurseContractPublicKeyP *purse_pub,
   1734   struct TALER_ExchangePublicKeyP *pub,
   1735   struct TALER_ExchangeSignatureP *sig)
   1736 {
   1737   struct TALER_CoinPurseRefundConfirmationPS dc = {
   1738     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
   1739     .purpose.size = htonl (sizeof (dc)),
   1740     .coin_pub = *coin_pub,
   1741     .purse_pub = *purse_pub,
   1742   };
   1743 
   1744   TALER_amount_hton (&dc.refunded_amount,
   1745                      amount_without_fee);
   1746   TALER_amount_hton (&dc.refund_fee,
   1747                      refund_fee);
   1748   return scb (&dc.purpose,
   1749               pub,
   1750               sig);
   1751 }
   1752 
   1753 
   1754 enum GNUNET_GenericReturnValue
   1755 TALER_exchange_online_purse_refund_verify (
   1756   const struct TALER_Amount *amount_without_fee,
   1757   const struct TALER_Amount *refund_fee,
   1758   const struct TALER_CoinSpendPublicKeyP *coin_pub,
   1759   const struct TALER_PurseContractPublicKeyP *purse_pub,
   1760   const struct TALER_ExchangePublicKeyP *pub,
   1761   const struct TALER_ExchangeSignatureP *sig)
   1762 {
   1763   struct TALER_CoinPurseRefundConfirmationPS dc = {
   1764     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND),
   1765     .purpose.size = htonl (sizeof (dc)),
   1766     .coin_pub = *coin_pub,
   1767     .purse_pub = *purse_pub,
   1768   };
   1769 
   1770   TALER_amount_hton (&dc.refunded_amount,
   1771                      amount_without_fee);
   1772   TALER_amount_hton (&dc.refund_fee,
   1773                      refund_fee);
   1774   return GNUNET_CRYPTO_eddsa_verify (
   1775     TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_REFUND,
   1776     &dc,
   1777     &sig->eddsa_signature,
   1778     &pub->eddsa_pub);
   1779 }
   1780 
   1781 
   1782 GNUNET_NETWORK_STRUCT_BEGIN
   1783 
   1784 /**
   1785  * Response by which the exchange affirms that it has
   1786  * merged a purse into a reserve.
   1787  */
   1788 struct TALER_PurseMergedConfirmationPS
   1789 {
   1790 
   1791   /**
   1792    * Purpose is #TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED
   1793    */
   1794   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1795 
   1796   /**
   1797    * When did the exchange receive the deposits.
   1798    */
   1799   struct GNUNET_TIME_TimestampNBO exchange_time;
   1800 
   1801   /**
   1802    * When will the purse expire?
   1803    */
   1804   struct GNUNET_TIME_TimestampNBO purse_expiration;
   1805 
   1806   /**
   1807    * How much should the purse ultimately contain.
   1808    */
   1809   struct TALER_AmountNBO amount_without_fee;
   1810 
   1811   /**
   1812    * Public key of the purse.
   1813    */
   1814   struct TALER_PurseContractPublicKeyP purse_pub;
   1815 
   1816   /**
   1817    * Public key of the reserve.
   1818    */
   1819   struct TALER_ReservePublicKeyP reserve_pub;
   1820 
   1821   /**
   1822    * Hash of the contract of the purse.
   1823    */
   1824   struct TALER_PrivateContractHashP h_contract_terms;
   1825 
   1826   /**
   1827    * Hash of the provider URL hosting the reserve.
   1828    */
   1829   struct GNUNET_HashCode h_provider_url;
   1830 
   1831 };
   1832 
   1833 GNUNET_NETWORK_STRUCT_END
   1834 
   1835 
   1836 enum TALER_ErrorCode
   1837 TALER_exchange_online_purse_merged_sign (
   1838   TALER_ExchangeSignCallback scb,
   1839   struct GNUNET_TIME_Timestamp exchange_time,
   1840   struct GNUNET_TIME_Timestamp purse_expiration,
   1841   const struct TALER_Amount *amount_without_fee,
   1842   const struct TALER_PurseContractPublicKeyP *purse_pub,
   1843   const struct TALER_PrivateContractHashP *h_contract_terms,
   1844   const struct TALER_ReservePublicKeyP *reserve_pub,
   1845   const char *exchange_url,
   1846   struct TALER_ExchangePublicKeyP *pub,
   1847   struct TALER_ExchangeSignatureP *sig)
   1848 {
   1849   struct TALER_PurseMergedConfirmationPS dc = {
   1850     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
   1851     .purpose.size = htonl (sizeof (dc)),
   1852     .h_contract_terms = *h_contract_terms,
   1853     .purse_pub = *purse_pub,
   1854     .reserve_pub = *reserve_pub,
   1855     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
   1856     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
   1857   };
   1858 
   1859   TALER_amount_hton (&dc.amount_without_fee,
   1860                      amount_without_fee);
   1861   GNUNET_CRYPTO_hash (exchange_url,
   1862                       strlen (exchange_url) + 1,
   1863                       &dc.h_provider_url);
   1864   return scb (&dc.purpose,
   1865               pub,
   1866               sig);
   1867 }
   1868 
   1869 
   1870 enum GNUNET_GenericReturnValue
   1871 TALER_exchange_online_purse_merged_verify (
   1872   struct GNUNET_TIME_Timestamp exchange_time,
   1873   struct GNUNET_TIME_Timestamp purse_expiration,
   1874   const struct TALER_Amount *amount_without_fee,
   1875   const struct TALER_PurseContractPublicKeyP *purse_pub,
   1876   const struct TALER_PrivateContractHashP *h_contract_terms,
   1877   const struct TALER_ReservePublicKeyP *reserve_pub,
   1878   const char *exchange_url,
   1879   const struct TALER_ExchangePublicKeyP *pub,
   1880   const struct TALER_ExchangeSignatureP *sig)
   1881 {
   1882   struct TALER_PurseMergedConfirmationPS dc = {
   1883     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED),
   1884     .purpose.size = htonl (sizeof (dc)),
   1885     .h_contract_terms = *h_contract_terms,
   1886     .purse_pub = *purse_pub,
   1887     .reserve_pub = *reserve_pub,
   1888     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
   1889     .exchange_time = GNUNET_TIME_timestamp_hton (exchange_time)
   1890   };
   1891 
   1892   TALER_amount_hton (&dc.amount_without_fee,
   1893                      amount_without_fee);
   1894   GNUNET_CRYPTO_hash (exchange_url,
   1895                       strlen (exchange_url) + 1,
   1896                       &dc.h_provider_url);
   1897   return
   1898     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_CONFIRM_PURSE_MERGED,
   1899                                 &dc,
   1900                                 &sig->eddsa_signature,
   1901                                 &pub->eddsa_pub);
   1902 }
   1903 
   1904 
   1905 GNUNET_NETWORK_STRUCT_BEGIN
   1906 
   1907 /**
   1908  * @brief Format used to generate the signature on a purse status
   1909  * from the exchange.
   1910  */
   1911 struct TALER_PurseStatusPS
   1912 {
   1913   /**
   1914    * Purpose must be #TALER_SIGNATURE_EXCHANGE_PURSE_STATUS.  Signed
   1915    * by a `struct TALER_ExchangePublicKeyP` using EdDSA.
   1916    */
   1917   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   1918 
   1919   /**
   1920    * Time when the purse was merged, possibly 'never'.
   1921    */
   1922   struct GNUNET_TIME_TimestampNBO merge_timestamp;
   1923 
   1924   /**
   1925    * Time when the purse was deposited last, possibly 'never'.
   1926    */
   1927   struct GNUNET_TIME_TimestampNBO deposit_timestamp;
   1928 
   1929   /**
   1930    * Amount deposited in total in the purse without fees.
   1931    * May be possibly less than the target amount.
   1932    */
   1933   struct TALER_AmountNBO balance;
   1934 
   1935 };
   1936 
   1937 GNUNET_NETWORK_STRUCT_END
   1938 
   1939 
   1940 enum TALER_ErrorCode
   1941 TALER_exchange_online_purse_status_sign (
   1942   TALER_ExchangeSignCallback scb,
   1943   struct GNUNET_TIME_Timestamp merge_timestamp,
   1944   struct GNUNET_TIME_Timestamp deposit_timestamp,
   1945   const struct TALER_Amount *balance,
   1946   struct TALER_ExchangePublicKeyP *pub,
   1947   struct TALER_ExchangeSignatureP *sig)
   1948 {
   1949   struct TALER_PurseStatusPS dcs = {
   1950     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
   1951     .purpose.size = htonl (sizeof (dcs)),
   1952     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
   1953     .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
   1954   };
   1955 
   1956   TALER_amount_hton (&dcs.balance,
   1957                      balance);
   1958   return scb (&dcs.purpose,
   1959               pub,
   1960               sig);
   1961 }
   1962 
   1963 
   1964 enum GNUNET_GenericReturnValue
   1965 TALER_exchange_online_purse_status_verify (
   1966   struct GNUNET_TIME_Timestamp merge_timestamp,
   1967   struct GNUNET_TIME_Timestamp deposit_timestamp,
   1968   const struct TALER_Amount *balance,
   1969   const struct TALER_ExchangePublicKeyP *exchange_pub,
   1970   const struct TALER_ExchangeSignatureP *exchange_sig)
   1971 {
   1972   struct TALER_PurseStatusPS dcs = {
   1973     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS),
   1974     .purpose.size = htonl (sizeof (dcs)),
   1975     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
   1976     .deposit_timestamp = GNUNET_TIME_timestamp_hton (deposit_timestamp)
   1977   };
   1978 
   1979   TALER_amount_hton (&dcs.balance,
   1980                      balance);
   1981   if (GNUNET_OK !=
   1982       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_EXCHANGE_PURSE_STATUS,
   1983                                   &dcs,
   1984                                   &exchange_sig->eddsa_signature,
   1985                                   &exchange_pub->eddsa_pub))
   1986   {
   1987     GNUNET_break_op (0);
   1988     return GNUNET_SYSERR;
   1989   }
   1990   return GNUNET_OK;
   1991 }
   1992 
   1993 
   1994 GNUNET_NETWORK_STRUCT_BEGIN
   1995 
   1996 /**
   1997  * Message signed by the exchange to affirm that the
   1998  * owner of a reserve has certain attributes.
   1999  */
   2000 struct TALER_ExchangeAttestPS
   2001 {
   2002 
   2003   /**
   2004    * Purpose is #TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS
   2005    */
   2006   struct GNUNET_CRYPTO_SignaturePurpose purpose;
   2007 
   2008   /**
   2009    * Time when the attestation was made.
   2010    */
   2011   struct GNUNET_TIME_TimestampNBO attest_timestamp;
   2012 
   2013   /**
   2014    * Time when the attestation expires.
   2015    */
   2016   struct GNUNET_TIME_TimestampNBO expiration_time;
   2017 
   2018   /**
   2019    * Public key of the reserve for which the attributes
   2020    * are attested.
   2021    */
   2022   struct TALER_ReservePublicKeyP reserve_pub;
   2023 
   2024   /**
   2025    * Hash over the attributes.
   2026    */
   2027   struct GNUNET_HashCode h_attributes;
   2028 
   2029 };
   2030 
   2031 GNUNET_NETWORK_STRUCT_END
   2032 
   2033 
   2034 enum TALER_ErrorCode
   2035 TALER_exchange_online_reserve_attest_details_sign (
   2036   TALER_ExchangeSignCallback scb,
   2037   struct GNUNET_TIME_Timestamp attest_timestamp,
   2038   struct GNUNET_TIME_Timestamp expiration_time,
   2039   const struct TALER_ReservePublicKeyP *reserve_pub,
   2040   const json_t *attributes,
   2041   struct TALER_ExchangePublicKeyP *pub,
   2042   struct TALER_ExchangeSignatureP *sig)
   2043 {
   2044   struct TALER_ExchangeAttestPS rap = {
   2045     .purpose.size = htonl (sizeof (rap)),
   2046     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
   2047     .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
   2048     .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
   2049     .reserve_pub = *reserve_pub
   2050   };
   2051 
   2052   TALER_json_hash (attributes,
   2053                    &rap.h_attributes);
   2054   return scb (&rap.purpose,
   2055               pub,
   2056               sig);
   2057 }
   2058 
   2059 
   2060 enum GNUNET_GenericReturnValue
   2061 TALER_exchange_online_reserve_attest_details_verify (
   2062   struct GNUNET_TIME_Timestamp attest_timestamp,
   2063   struct GNUNET_TIME_Timestamp expiration_time,
   2064   const struct TALER_ReservePublicKeyP *reserve_pub,
   2065   const json_t *attributes,
   2066   struct TALER_ExchangePublicKeyP *pub,
   2067   struct TALER_ExchangeSignatureP *sig)
   2068 {
   2069   struct TALER_ExchangeAttestPS rap = {
   2070     .purpose.size = htonl (sizeof (rap)),
   2071     .purpose.purpose = htonl (TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS),
   2072     .attest_timestamp = GNUNET_TIME_timestamp_hton (attest_timestamp),
   2073     .expiration_time = GNUNET_TIME_timestamp_hton (expiration_time),
   2074     .reserve_pub = *reserve_pub
   2075   };
   2076 
   2077   TALER_json_hash (attributes,
   2078                    &rap.h_attributes);
   2079   if (GNUNET_OK !=
   2080       GNUNET_CRYPTO_eddsa_verify (
   2081         TALER_SIGNATURE_EXCHANGE_RESERVE_ATTEST_DETAILS,
   2082         &rap,
   2083         &sig->eddsa_signature,
   2084         &pub->eddsa_pub))
   2085   {
   2086     GNUNET_break_op (0);
   2087     return GNUNET_SYSERR;
   2088   }
   2089   return GNUNET_OK;
   2090 }
   2091 
   2092 
   2093 /* end of exchange_signatures.c */