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

Generated by: LCOV version 2.0-1