LCOV - code coverage report
Current view: top level - util - wallet_signatures.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 69.8 % 437 305
Test Date: 2026-04-14 15:39:31 Functions: 63.0 % 54 34

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2021-2023 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 wallet_signatures.c
      18              :  * @brief Utility functions for Taler wallet signatures
      19              :  * @author Christian Grothoff
      20              :  * @author Özgür Kesim
      21              :  */
      22              : #include "taler/taler_util.h"
      23              : #include "taler/taler_signatures.h"
      24              : #include <gnunet/gnunet_common.h>
      25              : #include <stdint.h>
      26              : 
      27              : 
      28              : GNUNET_NETWORK_STRUCT_BEGIN
      29              : 
      30              : /**
      31              :  * @brief Format used to generate the signature on a request to deposit
      32              :  * a coin into the account of a merchant.
      33              :  */
      34              : struct TALER_DepositRequestPS
      35              : {
      36              :   /**
      37              :    * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT.
      38              :    * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
      39              :    */
      40              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
      41              : 
      42              :   /**
      43              :    * Hash over the contract for which this deposit is made.
      44              :    */
      45              :   struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
      46              : 
      47              :   /**
      48              :    * Hash over the age commitment that went into the coin. Maybe all zero, if
      49              :    * age commitment isn't applicable to the denomination.
      50              :    */
      51              :   struct TALER_AgeCommitmentHashP h_age_commitment GNUNET_PACKED;
      52              : 
      53              :   /**
      54              :    * Hash over optional policy extension attributes shared with the exchange.
      55              :    */
      56              :   struct TALER_ExtensionPolicyHashP h_policy GNUNET_PACKED;
      57              : 
      58              :   /**
      59              :    * Hash over the wiring information of the merchant.
      60              :    */
      61              :   struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
      62              : 
      63              :   /**
      64              :    * Hash over the denomination public key used to sign the coin.
      65              :    */
      66              :   struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
      67              : 
      68              :   /**
      69              :    * Time when this request was generated.  Used, for example, to
      70              :    * assess when (roughly) the income was achieved for tax purposes.
      71              :    * Note that the Exchange will only check that the timestamp is not "too
      72              :    * far" into the future (i.e. several days).  The fact that the
      73              :    * timestamp falls within the validity period of the coin's
      74              :    * denomination key is irrelevant for the validity of the deposit
      75              :    * request, as obviously the customer and merchant could conspire to
      76              :    * set any timestamp.  Also, the Exchange must accept very old deposit
      77              :    * requests, as the merchant might have been unable to transmit the
      78              :    * deposit request in a timely fashion (so back-dating is not
      79              :    * prevented).
      80              :    */
      81              :   struct GNUNET_TIME_TimestampNBO wallet_timestamp;
      82              : 
      83              :   /**
      84              :    * How much time does the merchant have to issue a refund request?
      85              :    * Zero if refunds are not allowed.  After this time, the coin
      86              :    * cannot be refunded.
      87              :    */
      88              :   struct GNUNET_TIME_TimestampNBO refund_deadline;
      89              : 
      90              :   /**
      91              :    * Amount to be deposited, including deposit fee charged by the
      92              :    * exchange.  This is the total amount that the coin's value at the exchange
      93              :    * will be reduced by.
      94              :    */
      95              :   struct TALER_AmountNBO amount_with_fee;
      96              : 
      97              :   /**
      98              :    * Depositing fee charged by the exchange.  This must match the Exchange's
      99              :    * denomination key's depositing fee.  If the client puts in an
     100              :    * invalid deposit fee (too high or too low) that does not match the
     101              :    * Exchange's denomination key, the deposit operation is invalid and
     102              :    * will be rejected by the exchange.  The @e amount_with_fee minus the
     103              :    * @e deposit_fee is the amount that will be transferred to the
     104              :    * account identified by @e h_wire.
     105              :    */
     106              :   struct TALER_AmountNBO deposit_fee;
     107              : 
     108              :   /**
     109              :    * The Merchant's public key.  Allows the merchant to later refund
     110              :    * the transaction or to inquire about the wire transfer identifier.
     111              :    */
     112              :   struct TALER_MerchantPublicKeyP merchant;
     113              : 
     114              :   /**
     115              :    * Hash over a JSON containing data provided by the
     116              :    * wallet to complete the contract upon payment.
     117              :    */
     118              :   struct GNUNET_HashCode wallet_data_hash;
     119              : 
     120              : };
     121              : 
     122              : GNUNET_NETWORK_STRUCT_END
     123              : 
     124              : void
     125          100 : TALER_wallet_deposit_sign (
     126              :   const struct TALER_Amount *amount,
     127              :   const struct TALER_Amount *deposit_fee,
     128              :   const struct TALER_MerchantWireHashP *h_wire,
     129              :   const struct TALER_PrivateContractHashP *h_contract_terms,
     130              :   const struct GNUNET_HashCode *wallet_data_hash,
     131              :   const struct TALER_AgeCommitmentHashP *h_age_commitment,
     132              :   const struct TALER_ExtensionPolicyHashP *h_policy,
     133              :   const struct TALER_DenominationHashP *h_denom_pub,
     134              :   const struct GNUNET_TIME_Timestamp wallet_timestamp,
     135              :   const struct TALER_MerchantPublicKeyP *merchant_pub,
     136              :   const struct GNUNET_TIME_Timestamp refund_deadline,
     137              :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     138              :   struct TALER_CoinSpendSignatureP *coin_sig)
     139              : {
     140          200 :   struct TALER_DepositRequestPS dr = {
     141          100 :     .purpose.size = htonl (sizeof (dr)),
     142          100 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
     143              :     .h_contract_terms = *h_contract_terms,
     144              :     .h_wire = *h_wire,
     145              :     .h_denom_pub = *h_denom_pub,
     146          100 :     .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
     147          100 :     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
     148              :     .merchant = *merchant_pub
     149              :   };
     150              : 
     151          100 :   if (NULL != wallet_data_hash)
     152            0 :     dr.wallet_data_hash = *wallet_data_hash;
     153          100 :   if (NULL != h_age_commitment)
     154           36 :     dr.h_age_commitment = *h_age_commitment;
     155          100 :   if (NULL != h_policy)
     156            0 :     dr.h_policy = *h_policy;
     157          100 :   TALER_amount_hton (&dr.amount_with_fee,
     158              :                      amount);
     159          100 :   TALER_amount_hton (&dr.deposit_fee,
     160              :                      deposit_fee);
     161          100 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     162              :                             &dr,
     163              :                             &coin_sig->eddsa_signature);
     164          100 : }
     165              : 
     166              : 
     167              : enum GNUNET_GenericReturnValue
     168          204 : TALER_wallet_deposit_verify (
     169              :   const struct TALER_Amount *amount,
     170              :   const struct TALER_Amount *deposit_fee,
     171              :   const struct TALER_MerchantWireHashP *h_wire,
     172              :   const struct TALER_PrivateContractHashP *h_contract_terms,
     173              :   const struct GNUNET_HashCode *wallet_data_hash,
     174              :   const struct TALER_AgeCommitmentHashP *h_age_commitment,
     175              :   const struct TALER_ExtensionPolicyHashP *h_policy,
     176              :   const struct TALER_DenominationHashP *h_denom_pub,
     177              :   struct GNUNET_TIME_Timestamp wallet_timestamp,
     178              :   const struct TALER_MerchantPublicKeyP *merchant_pub,
     179              :   struct GNUNET_TIME_Timestamp refund_deadline,
     180              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     181              :   const struct TALER_CoinSpendSignatureP *coin_sig)
     182              : {
     183          408 :   struct TALER_DepositRequestPS dr = {
     184          204 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
     185          204 :     .purpose.size = htonl (sizeof (dr)),
     186              :     .h_contract_terms = *h_contract_terms,
     187              :     .h_wire = *h_wire,
     188              :     .h_denom_pub = *h_denom_pub,
     189          204 :     .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
     190          204 :     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
     191              :     .merchant = *merchant_pub,
     192              :   };
     193              : 
     194          204 :   if (NULL != wallet_data_hash)
     195          200 :     dr.wallet_data_hash = *wallet_data_hash;
     196          204 :   if (NULL != h_age_commitment)
     197          126 :     dr.h_age_commitment = *h_age_commitment;
     198          204 :   if (NULL != h_policy)
     199          102 :     dr.h_policy = *h_policy;
     200          204 :   TALER_amount_hton (&dr.amount_with_fee,
     201              :                      amount);
     202          204 :   TALER_amount_hton (&dr.deposit_fee,
     203              :                      deposit_fee);
     204          204 :   if (GNUNET_OK !=
     205          204 :       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
     206              :                                   &dr,
     207              :                                   &coin_sig->eddsa_signature,
     208              :                                   &coin_pub->eddsa_pub))
     209              :   {
     210            0 :     GNUNET_break_op (0);
     211            0 :     return GNUNET_SYSERR;
     212              :   }
     213          204 :   return GNUNET_OK;
     214              : }
     215              : 
     216              : 
     217              : GNUNET_NETWORK_STRUCT_BEGIN
     218              : 
     219              : /**
     220              :  * @brief Format used for to allow the wallet to authenticate
     221              :  * link data provided by the exchange.
     222              :  */
     223              : struct TALER_LinkDataPS
     224              : {
     225              : 
     226              :   /**
     227              :    * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK.
     228              :    * Used with an EdDSA signature of a `struct TALER_CoinPublicKeyP`.
     229              :    */
     230              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     231              : 
     232              :   /**
     233              :    * Hash of the denomination public key of the new coin.
     234              :    */
     235              :   struct TALER_DenominationHashP h_denom_pub;
     236              : 
     237              :   /**
     238              :    * Transfer public key (for which the private key was not revealed)
     239              :    */
     240              :   struct TALER_TransferPublicKeyP transfer_pub;
     241              : 
     242              :   /**
     243              :    * Hash of the age commitment, if applicable.  Can be all zero
     244              :    */
     245              :   struct TALER_AgeCommitmentHashP h_age_commitment;
     246              : 
     247              :   /**
     248              :    * Hash of the blinded new coin.
     249              :    */
     250              :   struct TALER_BlindedCoinHashP coin_envelope_hash;
     251              : };
     252              : 
     253              : GNUNET_NETWORK_STRUCT_END
     254              : 
     255              : void
     256            0 : TALER_wallet_link_sign (const struct TALER_DenominationHashP *h_denom_pub,
     257              :                         const struct TALER_TransferPublicKeyP *transfer_pub,
     258              :                         const struct TALER_BlindedCoinHashP *bch,
     259              :                         const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
     260              :                         struct TALER_CoinSpendSignatureP *coin_sig)
     261              : {
     262            0 :   struct TALER_LinkDataPS ldp = {
     263            0 :     .purpose.size = htonl (sizeof (ldp)),
     264            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     265              :     .h_denom_pub = *h_denom_pub,
     266              :     .transfer_pub = *transfer_pub,
     267              :     .coin_envelope_hash = *bch
     268              :   };
     269              : 
     270            0 :   GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
     271              :                             &ldp,
     272              :                             &coin_sig->eddsa_signature);
     273            0 : }
     274              : 
     275              : 
     276              : enum GNUNET_GenericReturnValue
     277            0 : TALER_wallet_link_verify (
     278              :   const struct TALER_DenominationHashP *h_denom_pub,
     279              :   const struct TALER_TransferPublicKeyP *transfer_pub,
     280              :   const struct TALER_BlindedCoinHashP *h_coin_ev,
     281              :   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
     282              :   const struct TALER_CoinSpendSignatureP *coin_sig)
     283              : {
     284            0 :   struct TALER_LinkDataPS ldp = {
     285            0 :     .purpose.size = htonl (sizeof (ldp)),
     286            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     287              :     .h_denom_pub = *h_denom_pub,
     288              :     .transfer_pub = *transfer_pub,
     289              :     .coin_envelope_hash = *h_coin_ev,
     290              :   };
     291              : 
     292              :   return
     293            0 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
     294              :                                 &ldp,
     295              :                                 &coin_sig->eddsa_signature,
     296              :                                 &old_coin_pub->eddsa_pub);
     297              : }
     298              : 
     299              : 
     300              : GNUNET_NETWORK_STRUCT_BEGIN
     301              : 
     302              : /**
     303              :  * Signed data to request that a coin should be refunded as part of
     304              :  * the "emergency" /recoup protocol.  The refund will go back to the bank
     305              :  * account that created the reserve.
     306              :  */
     307              : struct TALER_RecoupRequestPS
     308              : {
     309              :   /**
     310              :    * Purpose is #TALER_SIGNATURE_WALLET_COIN_RECOUP
     311              :    * or #TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH.
     312              :    */
     313              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     314              : 
     315              :   /**
     316              :    * Hash of the (revoked) denomination public key of the coin.
     317              :    */
     318              :   struct TALER_DenominationHashP h_denom_pub;
     319              : 
     320              :   /**
     321              :    * Blinding factor that was used to withdraw the coin.
     322              :    */
     323              :   union GNUNET_CRYPTO_BlindingSecretP coin_blind;
     324              : 
     325              : };
     326              : 
     327              : GNUNET_NETWORK_STRUCT_END
     328              : 
     329              : 
     330              : enum GNUNET_GenericReturnValue
     331            0 : TALER_wallet_recoup_verify (
     332              :   const struct TALER_DenominationHashP *h_denom_pub,
     333              :   const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
     334              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     335              :   const struct TALER_CoinSpendSignatureP *coin_sig)
     336              : {
     337            0 :   struct TALER_RecoupRequestPS pr = {
     338            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
     339            0 :     .purpose.size = htonl (sizeof (pr)),
     340              :     .h_denom_pub = *h_denom_pub,
     341              :     .coin_blind = *coin_bks
     342              :   };
     343              : 
     344            0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
     345              :                                      &pr,
     346              :                                      &coin_sig->eddsa_signature,
     347              :                                      &coin_pub->eddsa_pub);
     348              : }
     349              : 
     350              : 
     351              : void
     352            0 : TALER_wallet_recoup_sign (
     353              :   const struct TALER_DenominationHashP *h_denom_pub,
     354              :   const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
     355              :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     356              :   struct TALER_CoinSpendSignatureP *coin_sig)
     357              : {
     358            0 :   struct TALER_RecoupRequestPS pr = {
     359            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
     360            0 :     .purpose.size = htonl (sizeof (pr)),
     361              :     .h_denom_pub = *h_denom_pub,
     362              :     .coin_blind = *coin_bks
     363              :   };
     364              : 
     365            0 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     366              :                             &pr,
     367              :                             &coin_sig->eddsa_signature);
     368            0 : }
     369              : 
     370              : 
     371              : enum GNUNET_GenericReturnValue
     372            0 : TALER_wallet_recoup_refresh_verify (
     373              :   const struct TALER_DenominationHashP *h_denom_pub,
     374              :   const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
     375              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     376              :   const struct TALER_CoinSpendSignatureP *coin_sig)
     377              : {
     378            0 :   struct TALER_RecoupRequestPS pr = {
     379            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
     380            0 :     .purpose.size = htonl (sizeof (pr)),
     381              :     .h_denom_pub = *h_denom_pub,
     382              :     .coin_blind = *coin_bks
     383              :   };
     384              : 
     385            0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH,
     386              :                                      &pr,
     387              :                                      &coin_sig->eddsa_signature,
     388              :                                      &coin_pub->eddsa_pub);
     389              : }
     390              : 
     391              : 
     392              : void
     393            0 : TALER_wallet_recoup_refresh_sign (
     394              :   const struct TALER_DenominationHashP *h_denom_pub,
     395              :   const union GNUNET_CRYPTO_BlindingSecretP *coin_bks,
     396              :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     397              :   struct TALER_CoinSpendSignatureP *coin_sig)
     398              : {
     399            0 :   struct TALER_RecoupRequestPS pr = {
     400            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
     401            0 :     .purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS)),
     402              :     .h_denom_pub = *h_denom_pub,
     403              :     .coin_blind = *coin_bks
     404              :   };
     405              : 
     406            0 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     407              :                             &pr,
     408              :                             &coin_sig->eddsa_signature);
     409            0 : }
     410              : 
     411              : 
     412              : GNUNET_NETWORK_STRUCT_BEGIN
     413              : 
     414              : /**
     415              :  * @brief Message signed by a coin to indicate that the coin should be
     416              :  * melted.
     417              :  */
     418              : struct TALER_RefreshMeltCoinAffirmationPS
     419              : {
     420              :   /**
     421              :    * Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT.
     422              :    * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
     423              :    */
     424              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     425              : 
     426              :   /**
     427              :    * Which melt commitment is made by the wallet.
     428              :    */
     429              :   struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
     430              : 
     431              :   /**
     432              :    * Hash over the denomination public key used to sign the coin.
     433              :    */
     434              :   struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
     435              : 
     436              :   /**
     437              :    * If age commitment was provided during the withdrawal of the coin, this is
     438              :    * the hash of the age commitment vector.  It must be all zeroes if no age
     439              :    * commitment was provided.
     440              :    */
     441              :   struct TALER_AgeCommitmentHashP h_age_commitment GNUNET_PACKED;
     442              : 
     443              :   /**
     444              :    * How much of the value of the coin should be melted?  This amount
     445              :    * includes the fees, so the final amount contributed to the melt is
     446              :    * this value minus the fee for melting the coin.  We include the
     447              :    * fee in what is being signed so that we can verify a reserve's
     448              :    * remaining total balance without needing to access the respective
     449              :    * denomination key information each time.
     450              :    */
     451              :   struct TALER_AmountNBO amount_with_fee;
     452              : 
     453              :   /**
     454              :    * Melting fee charged by the exchange.  This must match the Exchange's
     455              :    * denomination key's melting fee.  If the client puts in an invalid
     456              :    * melting fee (too high or too low) that does not match the Exchange's
     457              :    * denomination key, the melting operation is invalid and will be
     458              :    * rejected by the exchange.  The @e amount_with_fee minus the @e
     459              :    * melt_fee is the amount that will be credited to the melting
     460              :    * session.
     461              :    */
     462              :   struct TALER_AmountNBO melt_fee;
     463              : };
     464              : 
     465              : GNUNET_NETWORK_STRUCT_END
     466              : 
     467              : void
     468           30 : TALER_wallet_melt_sign (
     469              :   const struct TALER_Amount *amount_with_fee,
     470              :   const struct TALER_Amount *melt_fee,
     471              :   const struct TALER_RefreshCommitmentP *rc,
     472              :   const struct TALER_DenominationHashP *h_denom_pub,
     473              :   const struct TALER_AgeCommitmentHashP *h_age_commitment,
     474              :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     475              :   struct TALER_CoinSpendSignatureP *coin_sig)
     476              : {
     477           30 :   struct TALER_RefreshMeltCoinAffirmationPS melt = {
     478           30 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
     479           30 :     .purpose.size = htonl (sizeof (melt)),
     480              :     .rc = *rc,
     481              :     .h_denom_pub = *h_denom_pub
     482              :   };
     483              : 
     484           30 :   if (NULL != h_age_commitment)
     485           16 :     melt.h_age_commitment = *h_age_commitment;
     486           30 :   TALER_amount_hton (&melt.amount_with_fee,
     487              :                      amount_with_fee);
     488           30 :   TALER_amount_hton (&melt.melt_fee,
     489              :                      melt_fee);
     490           30 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     491              :                             &melt,
     492              :                             &coin_sig->eddsa_signature);
     493           30 : }
     494              : 
     495              : 
     496              : enum GNUNET_GenericReturnValue
     497           30 : TALER_wallet_melt_verify (
     498              :   const struct TALER_Amount *amount_with_fee,
     499              :   const struct TALER_Amount *melt_fee,
     500              :   const struct TALER_RefreshCommitmentP *rc,
     501              :   const struct TALER_DenominationHashP *h_denom_pub,
     502              :   const struct TALER_AgeCommitmentHashP *h_age_commitment,
     503              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     504              :   const struct TALER_CoinSpendSignatureP *coin_sig)
     505              : {
     506           30 :   struct TALER_RefreshMeltCoinAffirmationPS melt = {
     507           30 :     .purpose.size = htonl (sizeof (melt)),
     508           30 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
     509              :     .rc = *rc,
     510              :     .h_denom_pub = *h_denom_pub
     511              :   };
     512              : 
     513           30 :   if (NULL != h_age_commitment)
     514           30 :     melt.h_age_commitment = *h_age_commitment;
     515           30 :   TALER_amount_hton (&melt.amount_with_fee,
     516              :                      amount_with_fee);
     517           30 :   TALER_amount_hton (&melt.melt_fee,
     518              :                      melt_fee);
     519           30 :   return GNUNET_CRYPTO_eddsa_verify (
     520              :     TALER_SIGNATURE_WALLET_COIN_MELT,
     521              :     &melt,
     522              :     &coin_sig->eddsa_signature,
     523              :     &coin_pub->eddsa_pub);
     524              : }
     525              : 
     526              : 
     527              : GNUNET_NETWORK_STRUCT_BEGIN
     528              : 
     529              : /**
     530              :  * @brief Format used for to generate the signature on a refresh nonce,
     531              :  *  a) to prove ownership of the old coin's private key and
     532              :  *  b) to derive the planchet master secrets for the batch of fresh coins
     533              :  */
     534              : struct TALER_RefreshNonceSignaturePS
     535              : {
     536              : 
     537              :   /**
     538              :    * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK
     539              :    */
     540              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     541              : 
     542              :   /**
     543              :    * The nonce to sign
     544              :    */
     545              :   struct TALER_PublicRefreshNonceP nonce GNUNET_PACKED;
     546              : 
     547              :   /**
     548              :    * The running hash of the (hashes of) denomination public keys
     549              :    */
     550              :   struct GNUNET_HashCode h_denoms_h GNUNET_PACKED;
     551              : 
     552              :   /**
     553              :    * The kappa index for this signature, in NBO
     554              :    */
     555              :   uint32_t kappa_index GNUNET_PACKED;
     556              : };
     557              : 
     558              : GNUNET_NETWORK_STRUCT_END
     559              : 
     560              : 
     561              : void
     562            0 : TALER_wallet_refresh_nonce_sign (
     563              :   const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
     564              :   const struct TALER_PublicRefreshNonceP *nonce,
     565              :   size_t num_denoms_h,
     566              :   const struct TALER_DenominationHashP *denoms_h[static num_denoms_h],
     567              :   uint8_t kappa_index,
     568              :   struct TALER_PrivateRefreshNonceSignatureP *sig)
     569            0 : {
     570            0 :   struct TALER_RefreshNonceSignaturePS req = {
     571            0 :     .purpose.size = htonl (sizeof (req)),
     572            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     573              :     .nonce = *nonce,
     574            0 :     .kappa_index = htonl (kappa_index),
     575              :   };
     576            0 :   struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
     577            0 :   GNUNET_assert (ctx);
     578              : 
     579            0 :   for (size_t i = 0; i<num_denoms_h; i++)
     580            0 :     GNUNET_CRYPTO_hash_context_read (ctx,
     581            0 :                                      denoms_h[i],
     582              :                                      sizeof(*denoms_h[i]));
     583              : 
     584            0 :   GNUNET_CRYPTO_hash_context_finish (ctx,
     585              :                                      &req.h_denoms_h);
     586            0 :   GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
     587              :                             &req,
     588              :                             &sig->coin_sig.eddsa_signature);
     589            0 : }
     590              : 
     591              : 
     592              : enum GNUNET_GenericReturnValue
     593            0 : TALER_wallet_refresh_nonce_verify (
     594              :   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
     595              :   const struct TALER_PublicRefreshNonceP *nonce,
     596              :   size_t num_denoms_h,
     597              :   struct TALER_DenominationHashP *const denoms_h[static num_denoms_h],
     598              :   uint8_t kappa_index,
     599              :   const struct TALER_PrivateRefreshNonceSignatureP *sig)
     600            0 : {
     601            0 :   struct TALER_RefreshNonceSignaturePS req = {
     602            0 :     .purpose.size = htonl (sizeof (req)),
     603            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     604              :     .nonce = *nonce,
     605            0 :     .kappa_index = htonl (kappa_index),
     606              :   };
     607            0 :   struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
     608            0 :   GNUNET_assert (ctx);
     609              : 
     610            0 :   for (size_t i = 0; i<num_denoms_h; i++)
     611            0 :     GNUNET_CRYPTO_hash_context_read (ctx,
     612            0 :                                      denoms_h[i],
     613              :                                      sizeof(*denoms_h[i]));
     614              : 
     615            0 :   GNUNET_CRYPTO_hash_context_finish (ctx,
     616              :                                      &req.h_denoms_h);
     617            0 :   return GNUNET_CRYPTO_eddsa_verify (
     618              :     TALER_SIGNATURE_WALLET_COIN_LINK,
     619              :     &req,
     620              :     &sig->coin_sig.eddsa_signature,
     621              :     &old_coin_pub->eddsa_pub);
     622              : }
     623              : 
     624              : 
     625              : GNUNET_NETWORK_STRUCT_BEGIN
     626              : 
     627              : 
     628              : /**
     629              :  * @brief Format used for to generate the signature on a request to withdraw
     630              :  * coins from a reserve.
     631              :  * @note: deprecated.  Will be removed at some point after v24 of the protocol.
     632              :  */
     633              : struct TALER_WithdrawCommitmentPre24PS
     634              : {
     635              : 
     636              :   /**
     637              :    * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW.
     638              :    * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
     639              :    */
     640              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     641              : 
     642              :   /**
     643              :    * Value of the coin being exchanged (matching the denomination key)
     644              :    * plus the transaction fee.  We include this in what is being
     645              :    * signed so that we can verify a reserve's remaining total balance
     646              :    * without needing to access the respective denomination key
     647              :    * information each time.
     648              :    */
     649              :   struct TALER_AmountNBO amount_with_fee;
     650              : 
     651              :   /**
     652              :    * Hash of the denomination public key for the coin that is withdrawn.
     653              :    */
     654              :   struct TALER_DenominationHashP h_denomination_pub GNUNET_PACKED;
     655              : 
     656              :   /**
     657              :    * Hash of the (blinded) message to be signed by the Exchange.
     658              :    */
     659              :   struct TALER_BlindedCoinHashP h_coin_envelope GNUNET_PACKED;
     660              : };
     661              : 
     662              : 
     663              : GNUNET_NETWORK_STRUCT_END
     664              : 
     665              : void
     666            0 : TALER_wallet_withdraw_sign_pre26 (
     667              :   const struct TALER_DenominationHashP *h_denom_pub,
     668              :   const struct TALER_Amount *amount_with_fee,
     669              :   const struct TALER_BlindedCoinHashP *bch,
     670              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     671              :   struct TALER_ReserveSignatureP *reserve_sig)
     672              : {
     673            0 :   struct TALER_WithdrawCommitmentPre24PS req = {
     674            0 :     .purpose.size = htonl (sizeof (req)),
     675            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     676              :     .h_denomination_pub = *h_denom_pub,
     677              :     .h_coin_envelope = *bch
     678              :   };
     679              : 
     680            0 :   TALER_amount_hton (&req.amount_with_fee,
     681              :                      amount_with_fee);
     682            0 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
     683              :                             &req,
     684              :                             &reserve_sig->eddsa_signature);
     685            0 : }
     686              : 
     687              : 
     688              : enum GNUNET_GenericReturnValue
     689            0 : TALER_wallet_withdraw_verify_pre26 (
     690              :   const struct TALER_DenominationHashP *h_denom_pub,
     691              :   const struct TALER_Amount *amount_with_fee,
     692              :   const struct TALER_BlindedCoinHashP *bch,
     693              :   const struct TALER_ReservePublicKeyP *reserve_pub,
     694              :   const struct TALER_ReserveSignatureP *reserve_sig)
     695              : {
     696            0 :   struct TALER_WithdrawCommitmentPre24PS req = {
     697            0 :     .purpose.size = htonl (sizeof (req)),
     698            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     699              :     .h_denomination_pub = *h_denom_pub,
     700              :     .h_coin_envelope = *bch
     701              :   };
     702              : 
     703            0 :   TALER_amount_hton (&req.amount_with_fee,
     704              :                      amount_with_fee);
     705            0 :   return GNUNET_CRYPTO_eddsa_verify (
     706              :     TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
     707              :     &req,
     708              :     &reserve_sig->eddsa_signature,
     709              :     &reserve_pub->eddsa_pub);
     710              : }
     711              : 
     712              : 
     713              : GNUNET_NETWORK_STRUCT_BEGIN
     714              : 
     715              : /**
     716              :  * @brief Format used for to generate the signature on a request to withdraw
     717              :  * coins from a reserve.
     718              :  *
     719              :  */
     720              : struct TALER_WithdrawRequestPS
     721              : {
     722              :   /**
     723              :    * Purpose is #TALER_SIGNATURE_WALLET_WITHDRAW
     724              :    */
     725              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     726              : 
     727              :   /**
     728              :    * Total value of all coins being exchanged (matching the denomination keys),
     729              :    * without the fee.
     730              :    * Note that the reserve must have a value of at least amount+fee.
     731              :    */
     732              :   struct TALER_AmountNBO amount;
     733              : 
     734              :   /**
     735              :    * Total fee for the withdrawal.
     736              :    * Note that the reserve must have a value of at least amount+fee.
     737              :    */
     738              :   struct TALER_AmountNBO fee;
     739              : 
     740              :   /**
     741              :    * Running SHA512 hash of all TALER_BlindedCoinHashP's
     742              :    * of the of n coins, or n*kappa candidate coins in case of age restriction.
     743              :    * In the later case, the coins' hashes are arranged [0..num_coins)...[0..num_coins),
     744              :    * i.e. the coins are grouped per kappa-index.
     745              :    * Note that each coin's TALER_BlindedCoinHashP also captures
     746              :    * the hash of the public key of the corresponding denomination.
     747              :    */
     748              :   struct TALER_HashBlindedPlanchetsP h_planchets GNUNET_PACKED;
     749              : 
     750              :   /**
     751              :    * If any of the denominations is of cipher type Clause-Schnorr,
     752              :    * the client had to call /blinding-prepare prior to the withdraw
     753              :    * to retrieve public R-values for the CS signature scheme.
     754              :    * The input seed for that request must be provided here.
     755              :    * Otherwise, if no CS denomination is used, the struct must be all zeros.
     756              :    */
     757              :   struct TALER_BlindingMasterSeedP blinding_seed;
     758              : 
     759              :   /**
     760              :    * Maximum age group that the coins are going to be restricted to.
     761              :    * MUST be 0 if no age restriction applies.
     762              :    */
     763              :   uint32_t max_age_group;
     764              : 
     765              :   /**
     766              :    * The mask that defines the age groups.
     767              :    * MUST be the same for all denominations.
     768              :    * MUST be 0 if no age restriction applies.
     769              :    */
     770              :   struct TALER_AgeMask mask;
     771              : 
     772              : };
     773              : 
     774              : 
     775              : GNUNET_NETWORK_STRUCT_END
     776              : 
     777              : void
     778          265 : TALER_wallet_blinded_planchets_hash (
     779              :   size_t num_planchets,
     780              :   const struct TALER_BlindedPlanchet blinded_planchets[static num_planchets],
     781              :   const struct TALER_DenominationHashP h_denom_pubs[static num_planchets],
     782              :   struct TALER_HashBlindedPlanchetsP *h_planchets)
     783          265 : {
     784              :   struct TALER_BlindedCoinHashP bch;
     785              :   struct GNUNET_HashContext *coins_hctx;
     786              : 
     787          265 :   GNUNET_assert (num_planchets > 0);
     788          265 :   GNUNET_assert (NULL != h_planchets);
     789              : 
     790          265 :   coins_hctx = GNUNET_CRYPTO_hash_context_start ();
     791          265 :   GNUNET_assert (NULL != coins_hctx);
     792              : 
     793         1084 :   for (size_t i = 0; i < num_planchets; i++)
     794              :   {
     795          819 :     TALER_coin_ev_hash (
     796          819 :       &blinded_planchets[i],
     797          819 :       &h_denom_pubs[i],
     798              :       &bch);
     799          819 :     GNUNET_CRYPTO_hash_context_read (
     800              :       coins_hctx,
     801              :       &bch,
     802              :       sizeof(bch));
     803              :   }
     804              : 
     805          265 :   GNUNET_CRYPTO_hash_context_finish (
     806              :     coins_hctx,
     807              :     &h_planchets->hash);
     808          265 : }
     809              : 
     810              : 
     811              : void
     812          160 : TALER_wallet_blinded_planchet_details_hash (
     813              :   size_t num_planchets,
     814              :   const struct TALER_PlanchetDetail planchet_details[static num_planchets],
     815              :   struct TALER_HashBlindedPlanchetsP *h_planchets)
     816          160 : {
     817              :   struct TALER_BlindedCoinHashP bch;
     818              :   struct GNUNET_HashContext *coins_hctx;
     819              : 
     820          160 :   GNUNET_assert (num_planchets > 0);
     821          160 :   GNUNET_assert (NULL != h_planchets);
     822              : 
     823          160 :   coins_hctx = GNUNET_CRYPTO_hash_context_start ();
     824          160 :   GNUNET_assert (NULL != coins_hctx);
     825              : 
     826          800 :   for (size_t i = 0; i < num_planchets; i++)
     827              :   {
     828          640 :     TALER_coin_ev_hash (
     829          640 :       &planchet_details[i].blinded_planchet,
     830          640 :       &planchet_details[i].denom_pub_hash,
     831              :       &bch);
     832          640 :     GNUNET_CRYPTO_hash_context_read (
     833              :       coins_hctx,
     834              :       &bch,
     835              :       sizeof(bch));
     836              :   }
     837              : 
     838          160 :   GNUNET_CRYPTO_hash_context_finish (
     839              :     coins_hctx,
     840              :     &h_planchets->hash);
     841          160 : }
     842              : 
     843              : 
     844              : struct TALER_HashReservePublicKeyP
     845            0 : TALER_wallet_hash_reserve_pub (
     846              :   const struct TALER_ReservePublicKeyP *reserve_pub)
     847              : {
     848              :   struct TALER_HashReservePublicKeyP hr;
     849              : 
     850            0 :   GNUNET_CRYPTO_hash (reserve_pub,
     851              :                       sizeof(*reserve_pub),
     852              :                       &hr.hash);
     853            0 :   return hr;
     854              : }
     855              : 
     856              : 
     857              : void
     858           75 : TALER_wallet_withdraw_sign (
     859              :   const struct TALER_Amount *amount,
     860              :   const struct TALER_Amount *fee,
     861              :   const struct TALER_HashBlindedPlanchetsP *h_planchets,
     862              :   const struct TALER_BlindingMasterSeedP *blinding_seed,
     863              :   const struct TALER_AgeMask *mask,
     864              :   uint8_t max_age,
     865              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     866              :   struct TALER_ReserveSignatureP *reserve_sig)
     867              : {
     868           75 :   struct TALER_WithdrawRequestPS req = {
     869           75 :     .purpose.size = htonl (sizeof(req)),
     870           75 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     871              :   };
     872              : 
     873           75 :   GNUNET_assert (NULL != h_planchets);
     874           75 :   req.h_planchets = *h_planchets;
     875           75 :   if (NULL != mask)
     876              :   {
     877            5 :     req.mask = *mask;
     878            5 :     req.max_age_group =
     879            5 :       TALER_get_age_group (mask,
     880              :                            max_age);
     881              :   }
     882           75 :   TALER_amount_hton (&req.amount,
     883              :                      amount);
     884           75 :   TALER_amount_hton (&req.fee,
     885              :                      fee);
     886           75 :   if (NULL != blinding_seed)
     887           35 :     req.blinding_seed = *blinding_seed;
     888              : 
     889           75 :   GNUNET_CRYPTO_eddsa_sign (
     890              :     &reserve_priv->eddsa_priv,
     891              :     &req,
     892              :     &reserve_sig->eddsa_signature);
     893              : 
     894           75 : }
     895              : 
     896              : 
     897              : enum GNUNET_GenericReturnValue
     898           82 : TALER_wallet_withdraw_verify (
     899              :   const struct TALER_Amount *amount,
     900              :   const struct TALER_Amount *fee,
     901              :   const struct TALER_HashBlindedPlanchetsP *h_planchets,
     902              :   const struct TALER_BlindingMasterSeedP *blinding_seed,
     903              :   const struct TALER_AgeMask *mask,
     904              :   uint8_t max_age,
     905              :   const struct TALER_ReservePublicKeyP *reserve_pub,
     906              :   const struct TALER_ReserveSignatureP *reserve_sig)
     907              : {
     908           82 :   struct TALER_WithdrawRequestPS req = {
     909           82 :     .purpose.size = htonl (sizeof(req)),
     910           82 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     911              :   };
     912              : 
     913           82 :   GNUNET_assert (NULL != h_planchets);
     914           82 :   req.h_planchets = *h_planchets;
     915           82 :   if (NULL != mask)
     916              :   {
     917            5 :     req.mask = *mask;
     918            5 :     req.max_age_group =
     919            5 :       TALER_get_age_group (mask,
     920              :                            max_age);
     921              :   }
     922           82 :   TALER_amount_hton (&req.amount,
     923              :                      amount);
     924           82 :   TALER_amount_hton (&req.fee,
     925              :                      fee);
     926           82 :   if (NULL != blinding_seed)
     927           38 :     req.blinding_seed = *blinding_seed;
     928              : 
     929           82 :   return GNUNET_CRYPTO_eddsa_verify (
     930              :     TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
     931              :     &req,
     932              :     &reserve_sig->eddsa_signature,
     933              :     &reserve_pub->eddsa_pub);
     934              : }
     935              : 
     936              : 
     937              : GNUNET_NETWORK_STRUCT_BEGIN
     938              : 
     939              : 
     940              : /**
     941              :  * @brief Format used for to generate the signature on a request to withdraw
     942              :  * coins from a reserve.
     943              :  */
     944              : struct TALER_AccountSetupRequestSignaturePS
     945              : {
     946              : 
     947              :   /**
     948              :    * Purpose must be #TALER_SIGNATURE_WALLET_ACCOUNT_SETUP.
     949              :    * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
     950              :    */
     951              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
     952              : 
     953              :   /**
     954              :    * Balance threshold the wallet is about to cross.
     955              :    */
     956              :   struct TALER_AmountNBO threshold;
     957              : 
     958              : };
     959              : 
     960              : 
     961              : GNUNET_NETWORK_STRUCT_END
     962              : 
     963              : 
     964              : void
     965            7 : TALER_wallet_account_setup_sign (
     966              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     967              :   const struct TALER_Amount *balance_threshold,
     968              :   struct TALER_ReserveSignatureP *reserve_sig)
     969              : {
     970            7 :   struct TALER_AccountSetupRequestSignaturePS asap = {
     971            7 :     .purpose.size = htonl (sizeof (asap)),
     972            7 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
     973              :   };
     974              : 
     975            7 :   TALER_amount_hton (&asap.threshold,
     976              :                      balance_threshold);
     977            7 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
     978              :                             &asap,
     979              :                             &reserve_sig->eddsa_signature);
     980            7 : }
     981              : 
     982              : 
     983              : enum GNUNET_GenericReturnValue
     984            7 : TALER_wallet_account_setup_verify (
     985              :   const struct TALER_ReservePublicKeyP *reserve_pub,
     986              :   const struct TALER_Amount *balance_threshold,
     987              :   const struct TALER_ReserveSignatureP *reserve_sig)
     988              : {
     989            7 :   struct TALER_AccountSetupRequestSignaturePS asap = {
     990            7 :     .purpose.size = htonl (sizeof (asap)),
     991            7 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
     992              :   };
     993              : 
     994            7 :   TALER_amount_hton (&asap.threshold,
     995              :                      balance_threshold);
     996            7 :   return GNUNET_CRYPTO_eddsa_verify (
     997              :     TALER_SIGNATURE_WALLET_ACCOUNT_SETUP,
     998              :     &asap,
     999              :     &reserve_sig->eddsa_signature,
    1000              :     &reserve_pub->eddsa_pub);
    1001              : }
    1002              : 
    1003              : 
    1004              : GNUNET_NETWORK_STRUCT_BEGIN
    1005              : 
    1006              : 
    1007              : /**
    1008              :  * Response by which a wallet requests a reserve history.
    1009              :  */
    1010              : struct TALER_ReserveHistoryRequestPS
    1011              : {
    1012              : 
    1013              :   /**
    1014              :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_HISTORY
    1015              :    */
    1016              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1017              : 
    1018              :   /**
    1019              :    * Which entries to exclude. Only return above this offset.
    1020              :    */
    1021              :   uint64_t start_off;
    1022              : 
    1023              : };
    1024              : 
    1025              : GNUNET_NETWORK_STRUCT_END
    1026              : 
    1027              : 
    1028              : enum GNUNET_GenericReturnValue
    1029            8 : TALER_wallet_reserve_history_verify (
    1030              :   uint64_t start_off,
    1031              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1032              :   const struct TALER_ReserveSignatureP *reserve_sig)
    1033              : {
    1034           16 :   struct TALER_ReserveHistoryRequestPS rhr = {
    1035            8 :     .purpose.size = htonl (sizeof (rhr)),
    1036            8 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
    1037            8 :     .start_off = GNUNET_htonll (start_off)
    1038              :   };
    1039              : 
    1040            8 :   return GNUNET_CRYPTO_eddsa_verify (
    1041              :     TALER_SIGNATURE_WALLET_RESERVE_HISTORY,
    1042              :     &rhr,
    1043              :     &reserve_sig->eddsa_signature,
    1044              :     &reserve_pub->eddsa_pub);
    1045              : }
    1046              : 
    1047              : 
    1048              : void
    1049            8 : TALER_wallet_reserve_history_sign (
    1050              :   uint64_t start_off,
    1051              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1052              :   struct TALER_ReserveSignatureP *reserve_sig)
    1053              : {
    1054           16 :   struct TALER_ReserveHistoryRequestPS rhr = {
    1055            8 :     .purpose.size = htonl (sizeof (rhr)),
    1056            8 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
    1057            8 :     .start_off = GNUNET_htonll (start_off)
    1058              :   };
    1059              : 
    1060            8 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
    1061              :                             &rhr,
    1062              :                             &reserve_sig->eddsa_signature);
    1063            8 : }
    1064              : 
    1065              : 
    1066              : GNUNET_NETWORK_STRUCT_BEGIN
    1067              : 
    1068              : /**
    1069              :  * Response by which a wallet requests a coin history.
    1070              :  */
    1071              : struct TALER_CoinHistoryRequestPS
    1072              : {
    1073              : 
    1074              :   /**
    1075              :    * Purpose is #TALER_SIGNATURE_WALLET_COIN_HISTORY
    1076              :    */
    1077              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1078              : 
    1079              :   /**
    1080              :    * Which entries to exclude. Only return above this offset.
    1081              :    */
    1082              :   uint64_t start_off;
    1083              : 
    1084              : };
    1085              : 
    1086              : GNUNET_NETWORK_STRUCT_END
    1087              : 
    1088              : enum GNUNET_GenericReturnValue
    1089            4 : TALER_wallet_coin_history_verify (
    1090              :   uint64_t start_off,
    1091              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1092              :   const struct TALER_CoinSpendSignatureP *coin_sig)
    1093              : {
    1094            8 :   struct TALER_CoinHistoryRequestPS rsr = {
    1095            4 :     .purpose.size = htonl (sizeof (rsr)),
    1096            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
    1097            4 :     .start_off = GNUNET_htonll (start_off)
    1098              :   };
    1099              : 
    1100            4 :   return GNUNET_CRYPTO_eddsa_verify (
    1101              :     TALER_SIGNATURE_WALLET_COIN_HISTORY,
    1102              :     &rsr,
    1103              :     &coin_sig->eddsa_signature,
    1104              :     &coin_pub->eddsa_pub);
    1105              : }
    1106              : 
    1107              : 
    1108              : void
    1109            4 : TALER_wallet_coin_history_sign (
    1110              :   uint64_t start_off,
    1111              :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    1112              :   struct TALER_CoinSpendSignatureP *coin_sig)
    1113              : {
    1114            8 :   struct TALER_CoinHistoryRequestPS rsr = {
    1115            4 :     .purpose.size = htonl (sizeof (rsr)),
    1116            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
    1117            4 :     .start_off = GNUNET_htonll (start_off)
    1118              :   };
    1119              : 
    1120            4 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
    1121              :                             &rsr,
    1122              :                             &coin_sig->eddsa_signature);
    1123            4 : }
    1124              : 
    1125              : 
    1126              : GNUNET_NETWORK_STRUCT_BEGIN
    1127              : 
    1128              : /**
    1129              :  * Message signed to create a purse (without reserve).
    1130              :  */
    1131              : struct TALER_PurseCreatePS
    1132              : {
    1133              : 
    1134              :   /**
    1135              :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_CREATE
    1136              :    */
    1137              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1138              : 
    1139              :   /**
    1140              :    * Time when the purse will expire if still unmerged or unpaid.
    1141              :    */
    1142              :   struct GNUNET_TIME_TimestampNBO purse_expiration;
    1143              : 
    1144              :   /**
    1145              :    * Total amount (with fees) to be put into the purse.
    1146              :    */
    1147              :   struct TALER_AmountNBO purse_amount;
    1148              : 
    1149              :   /**
    1150              :    * Contract this purse pays for.
    1151              :    */
    1152              :   struct TALER_PrivateContractHashP h_contract_terms;
    1153              : 
    1154              :   /**
    1155              :    * Public key identifying the merge capability.
    1156              :    */
    1157              :   struct TALER_PurseMergePublicKeyP merge_pub;
    1158              : 
    1159              :   /**
    1160              :    * Minimum age required for payments into this purse.
    1161              :    */
    1162              :   uint32_t min_age GNUNET_PACKED;
    1163              : 
    1164              : };
    1165              : 
    1166              : 
    1167              : GNUNET_NETWORK_STRUCT_END
    1168              : 
    1169              : 
    1170              : void
    1171           25 : TALER_wallet_purse_create_sign (
    1172              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1173              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1174              :   const struct TALER_PurseMergePublicKeyP *merge_pub,
    1175              :   uint32_t min_age,
    1176              :   const struct TALER_Amount *amount,
    1177              :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1178              :   struct TALER_PurseContractSignatureP *purse_sig)
    1179              : {
    1180           50 :   struct TALER_PurseCreatePS pm = {
    1181           25 :     .purpose.size = htonl (sizeof (pm)),
    1182           25 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
    1183           25 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1184              :     .h_contract_terms = *h_contract_terms,
    1185              :     .merge_pub = *merge_pub,
    1186           25 :     .min_age = htonl (min_age)
    1187              :   };
    1188              : 
    1189           25 :   TALER_amount_hton (&pm.purse_amount,
    1190              :                      amount);
    1191           25 :   GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
    1192              :                             &pm,
    1193              :                             &purse_sig->eddsa_signature);
    1194           25 : }
    1195              : 
    1196              : 
    1197              : enum GNUNET_GenericReturnValue
    1198           25 : TALER_wallet_purse_create_verify (
    1199              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1200              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1201              :   const struct TALER_PurseMergePublicKeyP *merge_pub,
    1202              :   uint32_t min_age,
    1203              :   const struct TALER_Amount *amount,
    1204              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1205              :   const struct TALER_PurseContractSignatureP *purse_sig)
    1206              : {
    1207           50 :   struct TALER_PurseCreatePS pm = {
    1208           25 :     .purpose.size = htonl (sizeof (pm)),
    1209           25 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
    1210           25 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1211              :     .h_contract_terms = *h_contract_terms,
    1212              :     .merge_pub = *merge_pub,
    1213           25 :     .min_age = htonl (min_age)
    1214              :   };
    1215              : 
    1216           25 :   TALER_amount_hton (&pm.purse_amount,
    1217              :                      amount);
    1218           25 :   return GNUNET_CRYPTO_eddsa_verify (
    1219              :     TALER_SIGNATURE_WALLET_PURSE_CREATE,
    1220              :     &pm,
    1221              :     &purse_sig->eddsa_signature,
    1222              :     &purse_pub->eddsa_pub);
    1223              : }
    1224              : 
    1225              : 
    1226              : GNUNET_NETWORK_STRUCT_BEGIN
    1227              : 
    1228              : /**
    1229              :  * Message signed to delete a purse.
    1230              :  */
    1231              : struct TALER_PurseDeletePS
    1232              : {
    1233              : 
    1234              :   /**
    1235              :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DELETE
    1236              :    */
    1237              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1238              : 
    1239              : };
    1240              : 
    1241              : 
    1242              : GNUNET_NETWORK_STRUCT_END
    1243              : 
    1244              : 
    1245              : void
    1246            2 : TALER_wallet_purse_delete_sign (
    1247              :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1248              :   struct TALER_PurseContractSignatureP *purse_sig)
    1249              : {
    1250            2 :   struct TALER_PurseDeletePS pm = {
    1251            2 :     .purpose.size = htonl (sizeof (pm)),
    1252            2 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
    1253              :   };
    1254              : 
    1255            2 :   GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
    1256              :                             &pm,
    1257              :                             &purse_sig->eddsa_signature);
    1258            2 : }
    1259              : 
    1260              : 
    1261              : enum GNUNET_GenericReturnValue
    1262            2 : TALER_wallet_purse_delete_verify (
    1263              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1264              :   const struct TALER_PurseContractSignatureP *purse_sig)
    1265              : {
    1266            2 :   struct TALER_PurseDeletePS pm = {
    1267            2 :     .purpose.size = htonl (sizeof (pm)),
    1268            2 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
    1269              :   };
    1270              : 
    1271            2 :   return GNUNET_CRYPTO_eddsa_verify (
    1272              :     TALER_SIGNATURE_WALLET_PURSE_DELETE,
    1273              :     &pm,
    1274              :     &purse_sig->eddsa_signature,
    1275              :     &purse_pub->eddsa_pub);
    1276              : }
    1277              : 
    1278              : 
    1279              : void
    1280            0 : TALER_wallet_purse_status_sign (
    1281              :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1282              :   struct TALER_PurseContractSignatureP *purse_sig)
    1283              : {
    1284            0 :   struct GNUNET_CRYPTO_SignaturePurpose purpose = {
    1285            0 :     .size = htonl (sizeof (purpose)),
    1286            0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
    1287              :   };
    1288              : 
    1289            0 :   GNUNET_assert (GNUNET_OK ==
    1290              :                  GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
    1291              :                                             &purpose,
    1292              :                                             &purse_sig->eddsa_signature));
    1293            0 : }
    1294              : 
    1295              : 
    1296              : enum GNUNET_GenericReturnValue
    1297            0 : TALER_wallet_purse_status_verify (
    1298              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1299              :   const struct TALER_PurseContractSignatureP *purse_sig)
    1300              : {
    1301            0 :   struct GNUNET_CRYPTO_SignaturePurpose purpose = {
    1302            0 :     .size = htonl (sizeof (purpose)),
    1303            0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
    1304              :   };
    1305              : 
    1306            0 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_STATUS,
    1307              :                                       &purpose,
    1308              :                                       &purse_sig->eddsa_signature,
    1309              :                                       &purse_pub->eddsa_pub);
    1310              : }
    1311              : 
    1312              : 
    1313              : GNUNET_NETWORK_STRUCT_BEGIN
    1314              : 
    1315              : /**
    1316              :  * Message signed to deposit a coin into a purse.
    1317              :  */
    1318              : struct TALER_PurseDepositPS
    1319              : {
    1320              : 
    1321              :   /**
    1322              :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DEPOSIT
    1323              :    */
    1324              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1325              : 
    1326              :   /**
    1327              :    * Amount (with deposit fee) to be deposited into the purse.
    1328              :    */
    1329              :   struct TALER_AmountNBO coin_amount;
    1330              : 
    1331              :   /**
    1332              :    * Hash over the denomination public key used to sign the coin.
    1333              :    */
    1334              :   struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
    1335              : 
    1336              :   /**
    1337              :    * Hash over the age commitment that went into the coin. Maybe all zero, if
    1338              :    * age commitment isn't applicable to the denomination.
    1339              :    */
    1340              :   struct TALER_AgeCommitmentHashP h_age_commitment GNUNET_PACKED;
    1341              : 
    1342              :   /**
    1343              :    * Purse to deposit funds into.
    1344              :    */
    1345              :   struct TALER_PurseContractPublicKeyP purse_pub;
    1346              : 
    1347              :   /**
    1348              :    * Hash of the base URL of the exchange hosting the
    1349              :    * @e purse_pub.
    1350              :    */
    1351              :   struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
    1352              : };
    1353              : 
    1354              : GNUNET_NETWORK_STRUCT_END
    1355              : 
    1356              : void
    1357           18 : TALER_wallet_purse_deposit_sign (
    1358              :   const char *exchange_base_url,
    1359              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1360              :   const struct TALER_Amount *amount,
    1361              :   const struct TALER_DenominationHashP *h_denom_pub,
    1362              :   const struct TALER_AgeCommitmentHashP *h_age_commitment,
    1363              :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    1364              :   struct TALER_CoinSpendSignatureP *coin_sig)
    1365              : {
    1366           18 :   struct TALER_PurseDepositPS pm = {
    1367           18 :     .purpose.size = htonl (sizeof (pm)),
    1368           18 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
    1369              :     .purse_pub = *purse_pub,
    1370              :     .h_denom_pub = *h_denom_pub,
    1371              :     .h_age_commitment = *h_age_commitment
    1372              :   };
    1373              : 
    1374           18 :   GNUNET_CRYPTO_hash (exchange_base_url,
    1375           18 :                       strlen (exchange_base_url) + 1,
    1376              :                       &pm.h_exchange_base_url);
    1377           18 :   TALER_amount_hton (&pm.coin_amount,
    1378              :                      amount);
    1379           18 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
    1380              :                             &pm,
    1381              :                             &coin_sig->eddsa_signature);
    1382           18 : }
    1383              : 
    1384              : 
    1385              : enum GNUNET_GenericReturnValue
    1386           21 : TALER_wallet_purse_deposit_verify (
    1387              :   const char *exchange_base_url,
    1388              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1389              :   const struct TALER_Amount *amount,
    1390              :   const struct TALER_DenominationHashP *h_denom_pub,
    1391              :   const struct TALER_AgeCommitmentHashP *h_age_commitment,
    1392              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1393              :   const struct TALER_CoinSpendSignatureP *coin_sig)
    1394              : {
    1395           21 :   struct TALER_PurseDepositPS pm = {
    1396           21 :     .purpose.size = htonl (sizeof (pm)),
    1397           21 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
    1398              :     .purse_pub = *purse_pub,
    1399              :     .h_denom_pub = *h_denom_pub,
    1400              :     .h_age_commitment = *h_age_commitment
    1401              :   };
    1402              : 
    1403           21 :   GNUNET_CRYPTO_hash (exchange_base_url,
    1404           21 :                       strlen (exchange_base_url) + 1,
    1405              :                       &pm.h_exchange_base_url);
    1406           21 :   TALER_amount_hton (&pm.coin_amount,
    1407              :                      amount);
    1408           21 :   return GNUNET_CRYPTO_eddsa_verify (
    1409              :     TALER_SIGNATURE_WALLET_PURSE_DEPOSIT,
    1410              :     &pm,
    1411              :     &coin_sig->eddsa_signature,
    1412              :     &coin_pub->eddsa_pub);
    1413              : }
    1414              : 
    1415              : 
    1416              : GNUNET_NETWORK_STRUCT_BEGIN
    1417              : 
    1418              : /**
    1419              :  * Message signed to merge a purse into a reserve.
    1420              :  */
    1421              : struct TALER_PurseMergePS
    1422              : {
    1423              : 
    1424              :   /**
    1425              :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_MERGE
    1426              :    */
    1427              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1428              : 
    1429              :   /**
    1430              :    * Time when the purse is merged into the reserve.
    1431              :    */
    1432              :   struct GNUNET_TIME_TimestampNBO merge_timestamp;
    1433              : 
    1434              :   /**
    1435              :    * Which purse is being merged?
    1436              :    */
    1437              :   struct TALER_PurseContractPublicKeyP purse_pub;
    1438              : 
    1439              :   /**
    1440              :    * Which reserve should the purse be merged with.
    1441              :    * Hash of the reserve's payto:// URI.
    1442              :    */
    1443              :   struct TALER_NormalizedPaytoHashP h_payto;
    1444              : 
    1445              : };
    1446              : 
    1447              : GNUNET_NETWORK_STRUCT_END
    1448              : 
    1449              : void
    1450           20 : TALER_wallet_purse_merge_sign (
    1451              :   const struct TALER_NormalizedPayto reserve_uri,
    1452              :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1453              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1454              :   const struct TALER_PurseMergePrivateKeyP *merge_priv,
    1455              :   struct TALER_PurseMergeSignatureP *merge_sig)
    1456              : {
    1457           40 :   struct TALER_PurseMergePS pm = {
    1458           20 :     .purpose.size = htonl (sizeof (pm)),
    1459           20 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
    1460           20 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1461              :     .purse_pub = *purse_pub
    1462              :   };
    1463              : 
    1464           20 :   GNUNET_assert (0 ==
    1465              :                  strncasecmp (reserve_uri.normalized_payto,
    1466              :                               "payto://taler-reserve",
    1467              :                               strlen ("payto://taler-reserve")));
    1468           20 :   TALER_normalized_payto_hash (reserve_uri,
    1469              :                                &pm.h_payto);
    1470           20 :   GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv,
    1471              :                             &pm,
    1472              :                             &merge_sig->eddsa_signature);
    1473           20 : }
    1474              : 
    1475              : 
    1476              : enum GNUNET_GenericReturnValue
    1477           22 : TALER_wallet_purse_merge_verify (
    1478              :   const struct TALER_NormalizedPayto reserve_uri,
    1479              :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1480              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1481              :   const struct TALER_PurseMergePublicKeyP *merge_pub,
    1482              :   const struct TALER_PurseMergeSignatureP *merge_sig)
    1483              : {
    1484           44 :   struct TALER_PurseMergePS pm = {
    1485           22 :     .purpose.size = htonl (sizeof (pm)),
    1486           22 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
    1487           22 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1488              :     .purse_pub = *purse_pub
    1489              :   };
    1490              : 
    1491           22 :   if (0 !=
    1492           22 :       strncasecmp (reserve_uri.normalized_payto,
    1493              :                    "payto://taler-reserve",
    1494              :                    strlen ("payto://taler-reserve")))
    1495              :   {
    1496            0 :     GNUNET_break (0);
    1497            0 :     return GNUNET_NO;
    1498              :   }
    1499           22 :   TALER_normalized_payto_hash (reserve_uri,
    1500              :                                &pm.h_payto);
    1501           22 :   return GNUNET_CRYPTO_eddsa_verify (
    1502              :     TALER_SIGNATURE_WALLET_PURSE_MERGE,
    1503              :     &pm,
    1504              :     &merge_sig->eddsa_signature,
    1505              :     &merge_pub->eddsa_pub);
    1506              : }
    1507              : 
    1508              : 
    1509              : GNUNET_NETWORK_STRUCT_BEGIN
    1510              : 
    1511              : /**
    1512              :  * Message signed by account to merge a purse into a reserve.
    1513              :  */
    1514              : struct TALER_AccountMergePS
    1515              : {
    1516              : 
    1517              :   /**
    1518              :    * Purpose is #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE
    1519              :    */
    1520              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1521              : 
    1522              :   /**
    1523              :    * Time when the purse will expire if still unmerged or unpaid.
    1524              :    */
    1525              :   struct GNUNET_TIME_TimestampNBO purse_expiration;
    1526              : 
    1527              :   /**
    1528              :    * Total amount (with fees) to be put into the purse.
    1529              :    */
    1530              :   struct TALER_AmountNBO purse_amount;
    1531              : 
    1532              :   /**
    1533              :    * Purse creation fee to be paid by the reserve for
    1534              :    * this operation.
    1535              :    */
    1536              :   struct TALER_AmountNBO purse_fee;
    1537              : 
    1538              :   /**
    1539              :    * Contract this purse pays for.
    1540              :    */
    1541              :   struct TALER_PrivateContractHashP h_contract_terms;
    1542              : 
    1543              :   /**
    1544              :    * Purse to merge.
    1545              :    */
    1546              :   struct TALER_PurseContractPublicKeyP purse_pub;
    1547              : 
    1548              :   /**
    1549              :    * Time when the purse is merged into the reserve.
    1550              :    */
    1551              :   struct GNUNET_TIME_TimestampNBO merge_timestamp;
    1552              : 
    1553              :   /**
    1554              :    * Minimum age required for payments into this purse,
    1555              :    * in NBO.
    1556              :    */
    1557              :   uint32_t min_age GNUNET_PACKED;
    1558              : 
    1559              :   /**
    1560              :    * Flags for the operation, in NBO. See
    1561              :    * `enum TALER_WalletAccountMergeFlags`.
    1562              :    */
    1563              :   uint32_t flags GNUNET_PACKED;
    1564              : };
    1565              : 
    1566              : GNUNET_NETWORK_STRUCT_END
    1567              : 
    1568              : 
    1569              : void
    1570           20 : TALER_wallet_account_merge_sign (
    1571              :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1572              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1573              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1574              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1575              :   const struct TALER_Amount *amount,
    1576              :   const struct TALER_Amount *purse_fee,
    1577              :   uint32_t min_age,
    1578              :   enum TALER_WalletAccountMergeFlags flags,
    1579              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1580              :   struct TALER_ReserveSignatureP *reserve_sig)
    1581              : {
    1582           60 :   struct TALER_AccountMergePS pm = {
    1583           20 :     .purpose.size = htonl (sizeof (pm)),
    1584           20 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
    1585           20 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1586              :     .purse_pub = *purse_pub,
    1587           20 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1588              :     .h_contract_terms = *h_contract_terms,
    1589           20 :     .min_age = htonl (min_age),
    1590           20 :     .flags = htonl ((uint32_t) flags)
    1591              :   };
    1592              : 
    1593           20 :   TALER_amount_hton (&pm.purse_amount,
    1594              :                      amount);
    1595           20 :   TALER_amount_hton (&pm.purse_fee,
    1596              :                      purse_fee);
    1597           20 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
    1598              :                             &pm,
    1599              :                             &reserve_sig->eddsa_signature);
    1600           20 : }
    1601              : 
    1602              : 
    1603              : enum GNUNET_GenericReturnValue
    1604           28 : TALER_wallet_account_merge_verify (
    1605              :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1606              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1607              :   struct GNUNET_TIME_Timestamp purse_expiration,
    1608              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1609              :   const struct TALER_Amount *amount,
    1610              :   const struct TALER_Amount *purse_fee,
    1611              :   uint32_t min_age,
    1612              :   enum TALER_WalletAccountMergeFlags flags,
    1613              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1614              :   const struct TALER_ReserveSignatureP *reserve_sig)
    1615              : {
    1616           84 :   struct TALER_AccountMergePS pm = {
    1617           28 :     .purpose.size = htonl (sizeof (pm)),
    1618           28 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
    1619           28 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1620              :     .purse_pub = *purse_pub,
    1621           28 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1622              :     .h_contract_terms = *h_contract_terms,
    1623           28 :     .min_age = htonl (min_age),
    1624           28 :     .flags = htonl ((uint32_t) flags)
    1625              :   };
    1626              : 
    1627           28 :   TALER_amount_hton (&pm.purse_amount,
    1628              :                      amount);
    1629           28 :   TALER_amount_hton (&pm.purse_fee,
    1630              :                      purse_fee);
    1631           28 :   return GNUNET_CRYPTO_eddsa_verify (
    1632              :     TALER_SIGNATURE_WALLET_ACCOUNT_MERGE,
    1633              :     &pm,
    1634              :     &reserve_sig->eddsa_signature,
    1635              :     &reserve_pub->eddsa_pub);
    1636              : }
    1637              : 
    1638              : 
    1639              : GNUNET_NETWORK_STRUCT_BEGIN
    1640              : 
    1641              : /**
    1642              :  * Message signed by reserve key.
    1643              :  */
    1644              : struct TALER_ReserveOpenPS
    1645              : {
    1646              : 
    1647              :   /**
    1648              :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN
    1649              :    */
    1650              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1651              : 
    1652              :   /**
    1653              :    * Amount to be paid from the reserve balance to open
    1654              :    * the reserve.
    1655              :    */
    1656              :   struct TALER_AmountNBO reserve_payment;
    1657              : 
    1658              :   /**
    1659              :    * When was the request created.
    1660              :    */
    1661              :   struct GNUNET_TIME_TimestampNBO request_timestamp;
    1662              : 
    1663              :   /**
    1664              :    * For how long should the reserve be kept open.
    1665              :    * (Determines amount to be paid.)
    1666              :    */
    1667              :   struct GNUNET_TIME_TimestampNBO reserve_expiration;
    1668              : 
    1669              :   /**
    1670              :    * How many open purses should be included with the
    1671              :    * open reserve?
    1672              :    * (Determines amount to be paid.)
    1673              :    */
    1674              :   uint32_t purse_limit GNUNET_PACKED;
    1675              : 
    1676              : };
    1677              : 
    1678              : GNUNET_NETWORK_STRUCT_END
    1679              : 
    1680              : 
    1681              : void
    1682            6 : TALER_wallet_reserve_open_sign (
    1683              :   const struct TALER_Amount *reserve_payment,
    1684              :   struct GNUNET_TIME_Timestamp request_timestamp,
    1685              :   struct GNUNET_TIME_Timestamp reserve_expiration,
    1686              :   uint32_t purse_limit,
    1687              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1688              :   struct TALER_ReserveSignatureP *reserve_sig)
    1689              : {
    1690           12 :   struct TALER_ReserveOpenPS rop = {
    1691            6 :     .purpose.size = htonl (sizeof (rop)),
    1692            6 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
    1693            6 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
    1694            6 :     .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
    1695            6 :     .purse_limit = htonl (purse_limit)
    1696              :   };
    1697              : 
    1698            6 :   TALER_amount_hton (&rop.reserve_payment,
    1699              :                      reserve_payment);
    1700            6 :   GNUNET_assert (GNUNET_OK ==
    1701              :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
    1702              :                                             &rop.purpose,
    1703              :                                             &reserve_sig->eddsa_signature));
    1704            6 : }
    1705              : 
    1706              : 
    1707              : enum GNUNET_GenericReturnValue
    1708            6 : TALER_wallet_reserve_open_verify (
    1709              :   const struct TALER_Amount *reserve_payment,
    1710              :   struct GNUNET_TIME_Timestamp request_timestamp,
    1711              :   struct GNUNET_TIME_Timestamp reserve_expiration,
    1712              :   uint32_t purse_limit,
    1713              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1714              :   const struct TALER_ReserveSignatureP *reserve_sig)
    1715              : {
    1716           12 :   struct TALER_ReserveOpenPS rop = {
    1717            6 :     .purpose.size = htonl (sizeof (rop)),
    1718            6 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
    1719            6 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
    1720            6 :     .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
    1721            6 :     .purse_limit = htonl (purse_limit)
    1722              :   };
    1723              : 
    1724            6 :   TALER_amount_hton (&rop.reserve_payment,
    1725              :                      reserve_payment);
    1726            6 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_OPEN,
    1727              :                                       &rop.purpose,
    1728              :                                       &reserve_sig->eddsa_signature,
    1729              :                                       &reserve_pub->eddsa_pub);
    1730              : }
    1731              : 
    1732              : 
    1733              : GNUNET_NETWORK_STRUCT_BEGIN
    1734              : 
    1735              : /**
    1736              :  * Message signed by
    1737              :  */
    1738              : struct TALER_ReserveOpenDepositPS
    1739              : {
    1740              : 
    1741              :   /**
    1742              :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
    1743              :    */
    1744              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1745              : 
    1746              :   /**
    1747              :    * Which reserve's opening signature should be paid for?
    1748              :    */
    1749              :   struct TALER_ReserveSignatureP reserve_sig;
    1750              : 
    1751              :   /**
    1752              :    * Specifies how much of the coin's value should be spent on opening this
    1753              :    * reserve.
    1754              :    */
    1755              :   struct TALER_AmountNBO coin_contribution;
    1756              : };
    1757              : 
    1758              : GNUNET_NETWORK_STRUCT_END
    1759              : 
    1760              : 
    1761              : // FIXME-#11318: add h_age_commitment, h_denom_pub to have proof!
    1762              : void
    1763            2 : TALER_wallet_reserve_open_deposit_sign (
    1764              :   const struct TALER_Amount *coin_contribution,
    1765              :   const struct TALER_ReserveSignatureP *reserve_sig,
    1766              :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    1767              :   struct TALER_CoinSpendSignatureP *coin_sig)
    1768              : {
    1769            2 :   struct TALER_ReserveOpenDepositPS rod = {
    1770            2 :     .purpose.size = htonl (sizeof (rod)),
    1771            2 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
    1772              :     .reserve_sig = *reserve_sig
    1773              :   };
    1774              : 
    1775            2 :   TALER_amount_hton (&rod.coin_contribution,
    1776              :                      coin_contribution);
    1777            2 :   GNUNET_assert (GNUNET_OK ==
    1778              :                  GNUNET_CRYPTO_eddsa_sign_ (&coin_priv->eddsa_priv,
    1779              :                                             &rod.purpose,
    1780              :                                             &coin_sig->eddsa_signature));
    1781            2 : }
    1782              : 
    1783              : 
    1784              : enum GNUNET_GenericReturnValue
    1785            0 : TALER_wallet_reserve_open_deposit_verify (
    1786              :   const struct TALER_Amount *coin_contribution,
    1787              :   const struct TALER_ReserveSignatureP *reserve_sig,
    1788              :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1789              :   const struct TALER_CoinSpendSignatureP *coin_sig)
    1790              : {
    1791            0 :   struct TALER_ReserveOpenDepositPS rod = {
    1792            0 :     .purpose.size = htonl (sizeof (rod)),
    1793            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
    1794              :     .reserve_sig = *reserve_sig
    1795              :   };
    1796              : 
    1797            0 :   TALER_amount_hton (&rod.coin_contribution,
    1798              :                      coin_contribution);
    1799            0 :   return GNUNET_CRYPTO_eddsa_verify_ (
    1800              :     TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT,
    1801              :     &rod.purpose,
    1802              :     &coin_sig->eddsa_signature,
    1803              :     &coin_pub->eddsa_pub);
    1804              : }
    1805              : 
    1806              : 
    1807              : GNUNET_NETWORK_STRUCT_BEGIN
    1808              : 
    1809              : /**
    1810              :  * Message signed by reserve key.
    1811              :  */
    1812              : struct TALER_ReserveClosePS
    1813              : {
    1814              : 
    1815              :   /**
    1816              :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_CLOSE
    1817              :    */
    1818              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1819              : 
    1820              :   /**
    1821              :    * When was the request created.
    1822              :    */
    1823              :   struct GNUNET_TIME_TimestampNBO request_timestamp;
    1824              : 
    1825              :   /**
    1826              :    * Hash of the payto://-URI of the target account
    1827              :    * for the closure, or all zeros for the reserve
    1828              :    * origin account.
    1829              :    */
    1830              :   struct TALER_FullPaytoHashP target_account_h_payto;
    1831              : 
    1832              : };
    1833              : 
    1834              : GNUNET_NETWORK_STRUCT_END
    1835              : 
    1836              : 
    1837              : void
    1838            4 : TALER_wallet_reserve_close_sign (
    1839              :   struct GNUNET_TIME_Timestamp request_timestamp,
    1840              :   const struct TALER_FullPaytoHashP *h_payto,
    1841              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1842              :   struct TALER_ReserveSignatureP *reserve_sig)
    1843              : {
    1844            4 :   struct TALER_ReserveClosePS rcp = {
    1845            4 :     .purpose.size = htonl (sizeof (rcp)),
    1846            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
    1847            4 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1848              :   };
    1849              : 
    1850            4 :   if (NULL != h_payto)
    1851            4 :     rcp.target_account_h_payto = *h_payto;
    1852            4 :   GNUNET_assert (GNUNET_OK ==
    1853              :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
    1854              :                                             &rcp.purpose,
    1855              :                                             &reserve_sig->eddsa_signature));
    1856            4 : }
    1857              : 
    1858              : 
    1859              : enum GNUNET_GenericReturnValue
    1860            4 : TALER_wallet_reserve_close_verify (
    1861              :   struct GNUNET_TIME_Timestamp request_timestamp,
    1862              :   const struct TALER_FullPaytoHashP *h_payto,
    1863              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1864              :   const struct TALER_ReserveSignatureP *reserve_sig)
    1865              : {
    1866            4 :   struct TALER_ReserveClosePS rcp = {
    1867            4 :     .purpose.size = htonl (sizeof (rcp)),
    1868            4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
    1869            4 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1870              :   };
    1871              : 
    1872            4 :   if (NULL != h_payto)
    1873            4 :     rcp.target_account_h_payto = *h_payto;
    1874            4 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE,
    1875              :                                       &rcp.purpose,
    1876              :                                       &reserve_sig->eddsa_signature,
    1877              :                                       &reserve_pub->eddsa_pub);
    1878              : }
    1879              : 
    1880              : 
    1881              : GNUNET_NETWORK_STRUCT_BEGIN
    1882              : 
    1883              : /**
    1884              :  * Message signed by reserve private key.
    1885              :  */
    1886              : struct TALER_ReserveAttestRequestPS
    1887              : {
    1888              : 
    1889              :   /**
    1890              :    * Purpose is #TALER_SIGNATURE_WALLET_ATTEST_REQUEST
    1891              :    */
    1892              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1893              : 
    1894              :   /**
    1895              :    * When was the request created.
    1896              :    */
    1897              :   struct GNUNET_TIME_TimestampNBO request_timestamp;
    1898              : 
    1899              :   /**
    1900              :    * Hash over the JSON array of requested attributes.
    1901              :    */
    1902              :   struct GNUNET_HashCode h_details;
    1903              : 
    1904              : };
    1905              : 
    1906              : GNUNET_NETWORK_STRUCT_END
    1907              : 
    1908              : 
    1909              : void
    1910            1 : TALER_wallet_reserve_attest_request_sign (
    1911              :   struct GNUNET_TIME_Timestamp request_timestamp,
    1912              :   const json_t *details,
    1913              :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1914              :   struct TALER_ReserveSignatureP *reserve_sig)
    1915              : {
    1916            1 :   struct TALER_ReserveAttestRequestPS rcp = {
    1917            1 :     .purpose.size = htonl (sizeof (rcp)),
    1918            1 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
    1919            1 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1920              :   };
    1921              : 
    1922            1 :   TALER_json_hash (details,
    1923              :                    &rcp.h_details);
    1924            1 :   GNUNET_assert (GNUNET_OK ==
    1925              :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
    1926              :                                             &rcp.purpose,
    1927              :                                             &reserve_sig->eddsa_signature));
    1928            1 : }
    1929              : 
    1930              : 
    1931              : enum GNUNET_GenericReturnValue
    1932            1 : TALER_wallet_reserve_attest_request_verify (
    1933              :   struct GNUNET_TIME_Timestamp request_timestamp,
    1934              :   const json_t *details,
    1935              :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1936              :   const struct TALER_ReserveSignatureP *reserve_sig)
    1937              : {
    1938            1 :   struct TALER_ReserveAttestRequestPS rcp = {
    1939            1 :     .purpose.size = htonl (sizeof (rcp)),
    1940            1 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
    1941            1 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1942              :   };
    1943              : 
    1944            1 :   TALER_json_hash (details,
    1945              :                    &rcp.h_details);
    1946            1 :   return GNUNET_CRYPTO_eddsa_verify_ (
    1947              :     TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS,
    1948              :     &rcp.purpose,
    1949              :     &reserve_sig->eddsa_signature,
    1950              :     &reserve_pub->eddsa_pub);
    1951              : }
    1952              : 
    1953              : 
    1954              : GNUNET_NETWORK_STRUCT_BEGIN
    1955              : 
    1956              : /**
    1957              :  * Message signed by purse to associate an encrypted contract.
    1958              :  */
    1959              : struct TALER_PurseContractPS
    1960              : {
    1961              : 
    1962              :   /**
    1963              :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_ECONTRACT
    1964              :    */
    1965              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    1966              : 
    1967              :   /**
    1968              :    * Hash over the encrypted contract.
    1969              :    */
    1970              :   struct GNUNET_HashCode h_econtract;
    1971              : 
    1972              :   /**
    1973              :    * Public key to decrypt the contract.
    1974              :    */
    1975              :   struct TALER_ContractDiffiePublicP contract_pub;
    1976              : };
    1977              : 
    1978              : GNUNET_NETWORK_STRUCT_END
    1979              : 
    1980              : void
    1981           25 : TALER_wallet_econtract_upload_sign (
    1982              :   const void *econtract,
    1983              :   size_t econtract_size,
    1984              :   const struct TALER_ContractDiffiePublicP *contract_pub,
    1985              :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1986              :   struct TALER_PurseContractSignatureP *purse_sig)
    1987              : {
    1988           25 :   struct TALER_PurseContractPS pc = {
    1989           25 :     .purpose.size = htonl (sizeof (pc)),
    1990           25 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
    1991              :     .contract_pub = *contract_pub
    1992              :   };
    1993              : 
    1994           25 :   GNUNET_CRYPTO_hash (econtract,
    1995              :                       econtract_size,
    1996              :                       &pc.h_econtract);
    1997           25 :   GNUNET_assert (GNUNET_OK ==
    1998              :                  GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
    1999              :                                             &pc.purpose,
    2000              :                                             &purse_sig->eddsa_signature));
    2001           25 : }
    2002              : 
    2003              : 
    2004              : enum GNUNET_GenericReturnValue
    2005           31 : TALER_wallet_econtract_upload_verify2 (
    2006              :   const struct GNUNET_HashCode *h_econtract,
    2007              :   const struct TALER_ContractDiffiePublicP *contract_pub,
    2008              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    2009              :   const struct TALER_PurseContractSignatureP *purse_sig)
    2010              : {
    2011           31 :   struct TALER_PurseContractPS pc = {
    2012           31 :     .purpose.size = htonl (sizeof (pc)),
    2013           31 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
    2014              :     .contract_pub = *contract_pub,
    2015              :     .h_econtract = *h_econtract
    2016              :   };
    2017              : 
    2018           31 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT,
    2019              :                                       &pc.purpose,
    2020              :                                       &purse_sig->eddsa_signature,
    2021              :                                       &purse_pub->eddsa_pub);
    2022              : }
    2023              : 
    2024              : 
    2025              : enum GNUNET_GenericReturnValue
    2026           31 : TALER_wallet_econtract_upload_verify (
    2027              :   const void *econtract,
    2028              :   size_t econtract_size,
    2029              :   const struct TALER_ContractDiffiePublicP *contract_pub,
    2030              :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    2031              :   const struct TALER_PurseContractSignatureP *purse_sig)
    2032              : {
    2033              :   struct GNUNET_HashCode h_econtract;
    2034              : 
    2035           31 :   GNUNET_CRYPTO_hash (econtract,
    2036              :                       econtract_size,
    2037              :                       &h_econtract);
    2038           31 :   return TALER_wallet_econtract_upload_verify2 (&h_econtract,
    2039              :                                                 contract_pub,
    2040              :                                                 purse_pub,
    2041              :                                                 purse_sig);
    2042              : }
    2043              : 
    2044              : 
    2045              : GNUNET_NETWORK_STRUCT_BEGIN
    2046              : 
    2047              : /**
    2048              :  * Message signed by wallet to confirm usage of a token for a transaction.
    2049              :  */
    2050              : struct TALER_TokenUseRequestPS
    2051              : {
    2052              : 
    2053              :   /**
    2054              :    * Purpose is #TALER_SIGNATURE_WALLET_TOKEN_USE
    2055              :    */
    2056              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    2057              : 
    2058              :   /**
    2059              :    * Hash over the contract for which this token is used.
    2060              :    */
    2061              :   struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
    2062              : 
    2063              :   /**
    2064              :    * Hash over a JSON containing data provided by the
    2065              :    * wallet to complete the contract upon payment.
    2066              :    */
    2067              :   struct GNUNET_HashCode wallet_data_hash;
    2068              : 
    2069              : };
    2070              : 
    2071              : GNUNET_NETWORK_STRUCT_END
    2072              : 
    2073              : 
    2074              : void
    2075            0 : TALER_wallet_token_use_sign (
    2076              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    2077              :   const struct GNUNET_HashCode *wallet_data_hash,
    2078              :   const struct TALER_TokenUsePrivateKeyP *token_use_priv,
    2079              :   struct TALER_TokenUseSignatureP *token_sig)
    2080              : {
    2081            0 :   struct TALER_TokenUseRequestPS tur = {
    2082            0 :     .purpose.size = htonl (sizeof (tur)),
    2083            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE),
    2084              :     .h_contract_terms = *h_contract_terms,
    2085              :     .wallet_data_hash = *wallet_data_hash
    2086              :   };
    2087              : 
    2088            0 :   GNUNET_CRYPTO_eddsa_sign (&token_use_priv->private_key,
    2089              :                             &tur,
    2090              :                             &token_sig->signature);
    2091            0 : }
    2092              : 
    2093              : 
    2094              : enum GNUNET_GenericReturnValue
    2095            0 : TALER_wallet_token_use_verify (
    2096              :   const struct TALER_PrivateContractHashP *h_contract_terms,
    2097              :   const struct GNUNET_HashCode *wallet_data_hash,
    2098              :   const struct TALER_TokenUsePublicKeyP *token_use_pub,
    2099              :   const struct TALER_TokenUseSignatureP *token_sig)
    2100              : {
    2101            0 :   struct TALER_TokenUseRequestPS tur = {
    2102            0 :     .purpose.size = htonl (sizeof (tur)),
    2103            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE),
    2104              :     .h_contract_terms = *h_contract_terms,
    2105              :     .wallet_data_hash = *wallet_data_hash
    2106              :   };
    2107              : 
    2108            0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_TOKEN_USE,
    2109              :                                      &tur,
    2110              :                                      &token_sig->signature,
    2111              :                                      &token_use_pub->public_key);
    2112              : }
    2113              : 
    2114              : 
    2115              : GNUNET_NETWORK_STRUCT_BEGIN
    2116              : 
    2117              : /**
    2118              :  * Message signed by reserve key.
    2119              :  */
    2120              : struct TALER_OrderUnclaimPS
    2121              : {
    2122              : 
    2123              :   /**
    2124              :    * Purpose is #TALER_SIGNATURE_WALLET_ORDER_UNCLAIM
    2125              :    */
    2126              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    2127              : 
    2128              :   /**
    2129              :    * Hash of the contract being unclaimed.
    2130              :    */
    2131              :   struct GNUNET_HashCode h_contract;
    2132              : 
    2133              : };
    2134              : 
    2135              : GNUNET_NETWORK_STRUCT_END
    2136              : 
    2137              : 
    2138              : void
    2139            0 : TALER_wallet_order_unclaim_sign (
    2140              :   const struct GNUNET_HashCode *h_contract,
    2141              :   const struct GNUNET_CRYPTO_EddsaPrivateKey *nonce_priv,
    2142              :   struct GNUNET_CRYPTO_EddsaSignature *nsig)
    2143              : {
    2144            0 :   struct TALER_OrderUnclaimPS rcp = {
    2145            0 :     .purpose.size = htonl (sizeof (rcp)),
    2146            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM),
    2147              :     .h_contract = *h_contract
    2148              :   };
    2149              : 
    2150            0 :   GNUNET_assert (GNUNET_OK ==
    2151              :                  GNUNET_CRYPTO_eddsa_sign_ (nonce_priv,
    2152              :                                             &rcp.purpose,
    2153              :                                             nsig));
    2154            0 : }
    2155              : 
    2156              : 
    2157              : enum GNUNET_GenericReturnValue
    2158            0 : TALER_wallet_order_unclaim_verify (
    2159              :   const struct GNUNET_HashCode *h_contract,
    2160              :   const struct GNUNET_CRYPTO_EddsaPublicKey *nonce,
    2161              :   const struct GNUNET_CRYPTO_EddsaSignature *nsig)
    2162              : {
    2163            0 :   struct TALER_OrderUnclaimPS rcp = {
    2164            0 :     .purpose.size = htonl (sizeof (rcp)),
    2165            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
    2166              :     .h_contract = *h_contract
    2167              :   };
    2168              : 
    2169            0 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM,
    2170              :                                       &rcp.purpose,
    2171              :                                       nsig,
    2172              :                                       nonce);
    2173              : }
    2174              : 
    2175              : 
    2176              : GNUNET_NETWORK_STRUCT_BEGIN
    2177              : 
    2178              : /**
    2179              :  * Message signed by reserve map authorization key.
    2180              :  */
    2181              : struct TALER_ReserveMapAuthorizationPS
    2182              : {
    2183              : 
    2184              :   /**
    2185              :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION
    2186              :    */
    2187              :   struct GNUNET_CRYPTO_SignaturePurpose purpose;
    2188              : 
    2189              :   /**
    2190              :    * Account key to associate with the authorization key subject.
    2191              :    */
    2192              :   union TALER_AccountPublicKeyP account_pub;
    2193              : 
    2194              : };
    2195              : 
    2196              : GNUNET_NETWORK_STRUCT_END
    2197              : 
    2198              : 
    2199              : void
    2200            0 : TALER_wallet_reserve_map_authorization_sign (
    2201              :   const union TALER_AccountPublicKeyP *account_pub,
    2202              :   const struct TALER_ReserveMapAuthorizationPrivateKeyP *auth_priv,
    2203              :   struct TALER_ReserveMapAuthorizationSignatureP *auth_sig)
    2204              : {
    2205            0 :   struct TALER_ReserveMapAuthorizationPS rcp = {
    2206            0 :     .purpose.size = htonl (sizeof (rcp)),
    2207            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION),
    2208              :     .account_pub = *account_pub
    2209              :   };
    2210              : 
    2211            0 :   GNUNET_assert (GNUNET_OK ==
    2212              :                  GNUNET_CRYPTO_eddsa_sign_ (
    2213              :                    &auth_priv->eddsa_priv,
    2214              :                    &rcp.purpose,
    2215              :                    &auth_sig->eddsa_signature));
    2216            0 : }
    2217              : 
    2218              : 
    2219              : enum GNUNET_GenericReturnValue
    2220            0 : TALER_wallet_reserve_map_authorization_verify (
    2221              :   const union TALER_AccountPublicKeyP *account_pub,
    2222              :   const struct TALER_ReserveMapAuthorizationPublicKeyP *auth_pub,
    2223              :   const struct TALER_ReserveMapAuthorizationSignatureP *auth_sig)
    2224              : {
    2225            0 :   struct TALER_ReserveMapAuthorizationPS rcp = {
    2226            0 :     .purpose.size = htonl (sizeof (rcp)),
    2227            0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION),
    2228              :     .account_pub = *account_pub
    2229              :   };
    2230              : 
    2231            0 :   return GNUNET_CRYPTO_eddsa_verify_ (
    2232              :     TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION,
    2233              :     &rcp.purpose,
    2234              :     &auth_sig->eddsa_signature,
    2235              :     &auth_pub->eddsa_pub);
    2236              : }
    2237              : 
    2238              : 
    2239              : /* end of wallet_signatures.c */
        

Generated by: LCOV version 2.0-1