LCOV - code coverage report
Current view: top level - util - wallet_signatures.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 334 415 80.5 %
Date: 2025-06-05 21:03:14 Functions: 36 50 72.0 %

          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 "platform.h"
      23             : #include "taler_util.h"
      24             : #include "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_EccSignaturePurpose 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_AgeCommitmentHash 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_AgeCommitmentHash *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         315 : 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_AgeCommitmentHash *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         630 :   struct TALER_DepositRequestPS dr = {
     185         315 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
     186         315 :     .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         315 :     .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
     191         315 :     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
     192             :     .merchant = *merchant_pub,
     193             :   };
     194             : 
     195         315 :   if (NULL != wallet_data_hash)
     196         212 :     dr.wallet_data_hash = *wallet_data_hash;
     197         315 :   if (NULL != h_age_commitment)
     198         231 :     dr.h_age_commitment = *h_age_commitment;
     199         315 :   if (NULL != h_policy)
     200         207 :     dr.h_policy = *h_policy;
     201         315 :   TALER_amount_hton (&dr.amount_with_fee,
     202             :                      amount);
     203         315 :   TALER_amount_hton (&dr.deposit_fee,
     204             :                      deposit_fee);
     205         315 :   if (GNUNET_OK !=
     206         315 :       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
     207             :                                   &dr,
     208             :                                   &coin_sig->eddsa_signature,
     209             :                                   &coin_pub->eddsa_pub))
     210             :   {
     211           5 :     GNUNET_break_op (0);
     212           5 :     return GNUNET_SYSERR;
     213             :   }
     214         310 :   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_EccSignaturePurpose 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_AgeCommitmentHash 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_EccSignaturePurpose 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_EccSignaturePurpose 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_AgeCommitmentHash 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_AgeCommitmentHash *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             :     .h_age_commitment = {{{0}}},
     484             :   };
     485             : 
     486          30 :   if (NULL != h_age_commitment)
     487          16 :     melt.h_age_commitment = *h_age_commitment;
     488             : 
     489             : 
     490          30 :   TALER_amount_hton (&melt.amount_with_fee,
     491             :                      amount_with_fee);
     492          30 :   TALER_amount_hton (&melt.melt_fee,
     493             :                      melt_fee);
     494          30 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     495             :                             &melt,
     496             :                             &coin_sig->eddsa_signature);
     497          30 : }
     498             : 
     499             : 
     500             : enum GNUNET_GenericReturnValue
     501         174 : TALER_wallet_melt_verify (
     502             :   const struct TALER_Amount *amount_with_fee,
     503             :   const struct TALER_Amount *melt_fee,
     504             :   const struct TALER_RefreshCommitmentP *rc,
     505             :   const struct TALER_DenominationHashP *h_denom_pub,
     506             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
     507             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     508             :   const struct TALER_CoinSpendSignatureP *coin_sig)
     509             : {
     510         174 :   struct TALER_RefreshMeltCoinAffirmationPS melt = {
     511         174 :     .purpose.size = htonl (sizeof (melt)),
     512         174 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
     513             :     .rc = *rc,
     514             :     .h_denom_pub = *h_denom_pub,
     515             :     .h_age_commitment = {{{0}}},
     516             :   };
     517             : 
     518         174 :   if (NULL != h_age_commitment)
     519          38 :     melt.h_age_commitment = *h_age_commitment;
     520             : 
     521         174 :   TALER_amount_hton (&melt.amount_with_fee,
     522             :                      amount_with_fee);
     523         174 :   TALER_amount_hton (&melt.melt_fee,
     524             :                      melt_fee);
     525         174 :   return GNUNET_CRYPTO_eddsa_verify (
     526             :     TALER_SIGNATURE_WALLET_COIN_MELT,
     527             :     &melt,
     528             :     &coin_sig->eddsa_signature,
     529             :     &coin_pub->eddsa_pub);
     530             : }
     531             : 
     532             : 
     533             : GNUNET_NETWORK_STRUCT_BEGIN
     534             : 
     535             : /**
     536             :  * @brief Format used for to generate the signature on a refresh nonce,
     537             :  *  a) to prove ownership of the old coin's private key and
     538             :  *  b) to derive the planchet master secrets for the batch of fresh coins
     539             :  */
     540             : struct TALER_RefreshNonceSignaturePS
     541             : {
     542             : 
     543             :   /**
     544             :    * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK
     545             :    */
     546             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     547             : 
     548             :   /**
     549             :    * The nonce to sign
     550             :    */
     551             :   struct TALER_PublicRefreshNonceP nonce GNUNET_PACKED;
     552             : 
     553             :   /**
     554             :    * The running hash of the (hashes of) denomination public keys
     555             :    */
     556             :   struct GNUNET_HashCode h_denoms_h GNUNET_PACKED;
     557             : 
     558             :   /**
     559             :    * The kappa index for this signature, in NBO
     560             :    */
     561             :   uint32_t kappa_index GNUNET_PACKED;
     562             : };
     563             : 
     564             : GNUNET_NETWORK_STRUCT_END
     565             : 
     566             : 
     567             : void
     568         132 : TALER_wallet_refresh_nonce_sign (
     569             :   const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
     570             :   const struct TALER_PublicRefreshNonceP *nonce,
     571             :   size_t num_denoms_h,
     572             :   const struct TALER_DenominationHashP *denoms_h[static num_denoms_h],
     573             :   uint8_t kappa_index,
     574             :   struct TALER_PrivateRefreshNonceSignatureP *sig)
     575         132 : {
     576         132 :   struct TALER_RefreshNonceSignaturePS req = {
     577         132 :     .purpose.size = htonl (sizeof (req)),
     578         132 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     579             :     .nonce = *nonce,
     580         132 :     .kappa_index = htonl (kappa_index),
     581             :   };
     582         132 :   struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
     583         132 :   GNUNET_assert (ctx);
     584             : 
     585         660 :   for (size_t i = 0; i<num_denoms_h; i++)
     586         528 :     GNUNET_CRYPTO_hash_context_read (ctx,
     587         528 :                                      denoms_h[i],
     588             :                                      sizeof(*denoms_h[i]));
     589             : 
     590         132 :   GNUNET_CRYPTO_hash_context_finish (ctx,
     591             :                                      &req.h_denoms_h);
     592         132 :   GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
     593             :                             &req,
     594             :                             &sig->coin_sig.eddsa_signature);
     595         132 : }
     596             : 
     597             : 
     598             : enum GNUNET_GenericReturnValue
     599          44 : TALER_wallet_refresh_nonce_verify (
     600             :   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
     601             :   const struct TALER_PublicRefreshNonceP *nonce,
     602             :   size_t num_denoms_h,
     603             :   struct TALER_DenominationHashP *const denoms_h[static num_denoms_h],
     604             :   uint8_t kappa_index,
     605             :   const struct TALER_PrivateRefreshNonceSignatureP *sig)
     606          44 : {
     607          44 :   struct TALER_RefreshNonceSignaturePS req = {
     608          44 :     .purpose.size = htonl (sizeof (req)),
     609          44 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     610             :     .nonce = *nonce,
     611          44 :     .kappa_index = htonl (kappa_index),
     612             :   };
     613          44 :   struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
     614          44 :   GNUNET_assert (ctx);
     615             : 
     616         332 :   for (size_t i = 0; i<num_denoms_h; i++)
     617         288 :     GNUNET_CRYPTO_hash_context_read (ctx,
     618         288 :                                      denoms_h[i],
     619             :                                      sizeof(*denoms_h[i]));
     620             : 
     621          44 :   GNUNET_CRYPTO_hash_context_finish (ctx,
     622             :                                      &req.h_denoms_h);
     623          44 :   return GNUNET_CRYPTO_eddsa_verify (
     624             :     TALER_SIGNATURE_WALLET_COIN_LINK,
     625             :     &req,
     626             :     &sig->coin_sig.eddsa_signature,
     627             :     &old_coin_pub->eddsa_pub);
     628             : }
     629             : 
     630             : 
     631             : GNUNET_NETWORK_STRUCT_BEGIN
     632             : 
     633             : 
     634             : /**
     635             :  * @brief Format used for to generate the signature on a request to withdraw
     636             :  * coins from a reserve.
     637             :  * @note: deprecated.  Will be removed at some point after v24 of the protocol.
     638             :  */
     639             : struct TALER_WithdrawCommitmentPre24PS
     640             : {
     641             : 
     642             :   /**
     643             :    * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW.
     644             :    * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
     645             :    */
     646             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     647             : 
     648             :   /**
     649             :    * Value of the coin being exchanged (matching the denomination key)
     650             :    * plus the transaction fee.  We include this in what is being
     651             :    * signed so that we can verify a reserve's remaining total balance
     652             :    * without needing to access the respective denomination key
     653             :    * information each time.
     654             :    */
     655             :   struct TALER_AmountNBO amount_with_fee;
     656             : 
     657             :   /**
     658             :    * Hash of the denomination public key for the coin that is withdrawn.
     659             :    */
     660             :   struct TALER_DenominationHashP h_denomination_pub GNUNET_PACKED;
     661             : 
     662             :   /**
     663             :    * Hash of the (blinded) message to be signed by the Exchange.
     664             :    */
     665             :   struct TALER_BlindedCoinHashP h_coin_envelope GNUNET_PACKED;
     666             : };
     667             : 
     668             : 
     669             : GNUNET_NETWORK_STRUCT_END
     670             : 
     671             : void
     672           0 : TALER_wallet_withdraw_sign_pre26 (
     673             :   const struct TALER_DenominationHashP *h_denom_pub,
     674             :   const struct TALER_Amount *amount_with_fee,
     675             :   const struct TALER_BlindedCoinHashP *bch,
     676             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     677             :   struct TALER_ReserveSignatureP *reserve_sig)
     678             : {
     679           0 :   struct TALER_WithdrawCommitmentPre24PS req = {
     680           0 :     .purpose.size = htonl (sizeof (req)),
     681           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     682             :     .h_denomination_pub = *h_denom_pub,
     683             :     .h_coin_envelope = *bch
     684             :   };
     685             : 
     686           0 :   TALER_amount_hton (&req.amount_with_fee,
     687             :                      amount_with_fee);
     688           0 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
     689             :                             &req,
     690             :                             &reserve_sig->eddsa_signature);
     691           0 : }
     692             : 
     693             : 
     694             : enum GNUNET_GenericReturnValue
     695           0 : TALER_wallet_withdraw_verify_pre26 (
     696             :   const struct TALER_DenominationHashP *h_denom_pub,
     697             :   const struct TALER_Amount *amount_with_fee,
     698             :   const struct TALER_BlindedCoinHashP *bch,
     699             :   const struct TALER_ReservePublicKeyP *reserve_pub,
     700             :   const struct TALER_ReserveSignatureP *reserve_sig)
     701             : {
     702           0 :   struct TALER_WithdrawCommitmentPre24PS req = {
     703           0 :     .purpose.size = htonl (sizeof (req)),
     704           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     705             :     .h_denomination_pub = *h_denom_pub,
     706             :     .h_coin_envelope = *bch
     707             :   };
     708             : 
     709           0 :   TALER_amount_hton (&req.amount_with_fee,
     710             :                      amount_with_fee);
     711           0 :   return GNUNET_CRYPTO_eddsa_verify (
     712             :     TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
     713             :     &req,
     714             :     &reserve_sig->eddsa_signature,
     715             :     &reserve_pub->eddsa_pub);
     716             : }
     717             : 
     718             : 
     719             : GNUNET_NETWORK_STRUCT_BEGIN
     720             : 
     721             : /**
     722             :  * @brief Format used for to generate the signature on a request to withdraw
     723             :  * coins from a reserve.
     724             :  *
     725             :  */
     726             : struct TALER_WithdrawRequestPS
     727             : {
     728             :   /**
     729             :    * Purpose is #TALER_SIGNATURE_WALLET_WITHDRAW
     730             :    */
     731             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     732             : 
     733             :   /**
     734             :    * Total value of all coins being exchanged (matching the denomination keys),
     735             :    * without the fee.
     736             :    * Note that the reserve must have a value of at least amount+fee.
     737             :    */
     738             :   struct TALER_AmountNBO amount;
     739             : 
     740             :   /**
     741             :    * Total fee for the withdrawal.
     742             :    * Note that the reserve must have a value of at least amount+fee.
     743             :    */
     744             :   struct TALER_AmountNBO fee;
     745             : 
     746             :   /**
     747             :    * Running SHA512 hash of all TALER_BlindedCoinHashP's
     748             :    * of the of n coins, or n*kappa candidate coins in case of age restriction.
     749             :    * In the later case, the coins' hashes are arranged [0..num_coins)...[0..num_coins),
     750             :    * i.e. the coins are grouped per kappa-index.
     751             :    * Note that each coin's TALER_BlindedCoinHashP also captures
     752             :    * the hash of the public key of the corresponding denomination.
     753             :    */
     754             :   struct TALER_HashBlindedPlanchetsP h_planchets GNUNET_PACKED;
     755             : 
     756             :   /**
     757             :    * If any of the denominations is of cipher type Clause-Schnorr,
     758             :    * the client had to call /blinding-prepare prior to the withdraw
     759             :    * to retrieve public R-values for the CS signature scheme.
     760             :    * The input seed for that request must be provided here.
     761             :    * Otherwise, if no CS denomination is used, the struct must be all zeros.
     762             :    */
     763             :   struct TALER_BlindingMasterSeedP blinding_seed;
     764             : 
     765             :   /**
     766             :    * Maximum age group that the coins are going to be restricted to.
     767             :    * MUST be 0 if no age restriction applies.
     768             :    */
     769             :   uint32_t max_age_group;
     770             : 
     771             :   /**
     772             :    * The mask that defines the age groups.
     773             :    * MUST be the same for all denominations.
     774             :    * MUST be 0 if no age restriction applies.
     775             :    */
     776             :   struct TALER_AgeMask mask;
     777             : 
     778             : };
     779             : 
     780             : 
     781             : GNUNET_NETWORK_STRUCT_END
     782             : 
     783             : void
     784         317 : TALER_wallet_blinded_planchets_hash (
     785             :   size_t num_planchets,
     786             :   const struct TALER_BlindedPlanchet blinded_planchets[static num_planchets],
     787             :   const struct TALER_DenominationHashP h_denom_pubs[static num_planchets],
     788             :   struct TALER_HashBlindedPlanchetsP *h_planchets)
     789         317 : {
     790             :   struct TALER_BlindedCoinHashP bch;
     791             :   struct GNUNET_HashContext *coins_hctx;
     792             : 
     793         317 :   GNUNET_assert (num_planchets > 0);
     794         317 :   GNUNET_assert (NULL != h_planchets);
     795             : 
     796         317 :   coins_hctx = GNUNET_CRYPTO_hash_context_start ();
     797         317 :   GNUNET_assert (NULL != coins_hctx);
     798             : 
     799        1716 :   for (size_t i = 0; i < num_planchets; i++)
     800             :   {
     801        1399 :     TALER_coin_ev_hash (
     802        1399 :       &blinded_planchets[i],
     803        1399 :       &h_denom_pubs[i],
     804             :       &bch);
     805        1399 :     GNUNET_CRYPTO_hash_context_read (
     806             :       coins_hctx,
     807             :       &bch,
     808             :       sizeof(bch));
     809             :   }
     810             : 
     811         317 :   GNUNET_CRYPTO_hash_context_finish (
     812             :     coins_hctx,
     813             :     &h_planchets->hash);
     814         317 : }
     815             : 
     816             : 
     817             : void
     818         176 : TALER_wallet_blinded_planchet_details_hash (
     819             :   size_t num_planchets,
     820             :   const struct TALER_PlanchetDetail planchet_details[static num_planchets],
     821             :   struct TALER_HashBlindedPlanchetsP *h_planchets)
     822         176 : {
     823             :   struct TALER_BlindedCoinHashP bch;
     824             :   struct GNUNET_HashContext *coins_hctx;
     825             : 
     826         176 :   GNUNET_assert (num_planchets > 0);
     827         176 :   GNUNET_assert (NULL != h_planchets);
     828             : 
     829         176 :   coins_hctx = GNUNET_CRYPTO_hash_context_start ();
     830         176 :   GNUNET_assert (NULL != coins_hctx);
     831             : 
     832         992 :   for (size_t i = 0; i < num_planchets; i++)
     833             :   {
     834         816 :     TALER_coin_ev_hash (
     835         816 :       &planchet_details[i].blinded_planchet,
     836         816 :       &planchet_details[i].denom_pub_hash,
     837             :       &bch);
     838         816 :     GNUNET_CRYPTO_hash_context_read (
     839             :       coins_hctx,
     840             :       &bch,
     841             :       sizeof(bch));
     842             :   }
     843             : 
     844         176 :   GNUNET_CRYPTO_hash_context_finish (
     845             :     coins_hctx,
     846             :     &h_planchets->hash);
     847         176 : }
     848             : 
     849             : 
     850             : struct TALER_HashReservePublicKeyP
     851           0 : TALER_wallet_hash_reserve_pub (
     852             :   const struct TALER_ReservePublicKeyP *reserve_pub)
     853             : {
     854             :   struct TALER_HashReservePublicKeyP hr;
     855             : 
     856           0 :   GNUNET_CRYPTO_hash (reserve_pub,
     857             :                       sizeof(*reserve_pub),
     858             :                       &hr.hash);
     859           0 :   return hr;
     860             : }
     861             : 
     862             : 
     863             : void
     864          75 : TALER_wallet_withdraw_sign (
     865             :   const struct TALER_Amount *amount,
     866             :   const struct TALER_Amount *fee,
     867             :   const struct TALER_HashBlindedPlanchetsP *h_planchets,
     868             :   const struct TALER_BlindingMasterSeedP *blinding_seed,
     869             :   const struct TALER_AgeMask *mask,
     870             :   uint8_t max_age,
     871             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     872             :   struct TALER_ReserveSignatureP *reserve_sig)
     873             : {
     874          75 :   struct TALER_WithdrawRequestPS req = {
     875          75 :     .purpose.size = htonl (sizeof(req)),
     876          75 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     877             :   };
     878             : 
     879          75 :   GNUNET_assert (NULL != h_planchets);
     880          75 :   req.h_planchets = *h_planchets;
     881          75 :   if (NULL != mask)
     882             :   {
     883           5 :     req.mask = *mask;
     884           5 :     req.max_age_group =
     885           5 :       TALER_get_age_group (mask,
     886             :                            max_age);
     887             :   }
     888          75 :   TALER_amount_hton (&req.amount,
     889             :                      amount);
     890          75 :   TALER_amount_hton (&req.fee,
     891             :                      fee);
     892          75 :   if (NULL != blinding_seed)
     893          35 :     req.blinding_seed = *blinding_seed;
     894             : 
     895          75 :   GNUNET_CRYPTO_eddsa_sign (
     896             :     &reserve_priv->eddsa_priv,
     897             :     &req,
     898             :     &reserve_sig->eddsa_signature);
     899             : 
     900          75 : }
     901             : 
     902             : 
     903             : enum GNUNET_GenericReturnValue
     904         152 : TALER_wallet_withdraw_verify (
     905             :   const struct TALER_Amount *amount,
     906             :   const struct TALER_Amount *fee,
     907             :   const struct TALER_HashBlindedPlanchetsP *h_planchets,
     908             :   const struct TALER_BlindingMasterSeedP *blinding_seed,
     909             :   const struct TALER_AgeMask *mask,
     910             :   uint8_t max_age,
     911             :   const struct TALER_ReservePublicKeyP *reserve_pub,
     912             :   const struct TALER_ReserveSignatureP *reserve_sig)
     913             : {
     914         152 :   struct TALER_WithdrawRequestPS req = {
     915         152 :     .purpose.size = htonl (sizeof(req)),
     916         152 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     917             :   };
     918             : 
     919         152 :   GNUNET_assert (NULL != h_planchets);
     920         152 :   req.h_planchets = *h_planchets;
     921         152 :   if (NULL != mask)
     922             :   {
     923           5 :     req.mask = *mask;
     924           5 :     req.max_age_group =
     925           5 :       TALER_get_age_group (mask,
     926             :                            max_age);
     927             :   }
     928         152 :   TALER_amount_hton (&req.amount,
     929             :                      amount);
     930         152 :   TALER_amount_hton (&req.fee,
     931             :                      fee);
     932         152 :   if (NULL != blinding_seed)
     933          38 :     req.blinding_seed = *blinding_seed;
     934             : 
     935         152 :   return GNUNET_CRYPTO_eddsa_verify (
     936             :     TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
     937             :     &req,
     938             :     &reserve_sig->eddsa_signature,
     939             :     &reserve_pub->eddsa_pub);
     940             : }
     941             : 
     942             : 
     943             : GNUNET_NETWORK_STRUCT_BEGIN
     944             : 
     945             : 
     946             : /**
     947             :  * @brief Format used for to generate the signature on a request to withdraw
     948             :  * coins from a reserve.
     949             :  */
     950             : struct TALER_AccountSetupRequestSignaturePS
     951             : {
     952             : 
     953             :   /**
     954             :    * Purpose must be #TALER_SIGNATURE_WALLET_ACCOUNT_SETUP.
     955             :    * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
     956             :    */
     957             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     958             : 
     959             :   /**
     960             :    * Balance threshold the wallet is about to cross.
     961             :    */
     962             :   struct TALER_AmountNBO threshold;
     963             : 
     964             : };
     965             : 
     966             : 
     967             : GNUNET_NETWORK_STRUCT_END
     968             : 
     969             : 
     970             : void
     971           7 : TALER_wallet_account_setup_sign (
     972             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     973             :   const struct TALER_Amount *balance_threshold,
     974             :   struct TALER_ReserveSignatureP *reserve_sig)
     975             : {
     976           7 :   struct TALER_AccountSetupRequestSignaturePS asap = {
     977           7 :     .purpose.size = htonl (sizeof (asap)),
     978           7 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
     979             :   };
     980             : 
     981           7 :   TALER_amount_hton (&asap.threshold,
     982             :                      balance_threshold);
     983           7 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
     984             :                             &asap,
     985             :                             &reserve_sig->eddsa_signature);
     986           7 : }
     987             : 
     988             : 
     989             : enum GNUNET_GenericReturnValue
     990           7 : TALER_wallet_account_setup_verify (
     991             :   const struct TALER_ReservePublicKeyP *reserve_pub,
     992             :   const struct TALER_Amount *balance_threshold,
     993             :   const struct TALER_ReserveSignatureP *reserve_sig)
     994             : {
     995           7 :   struct TALER_AccountSetupRequestSignaturePS asap = {
     996           7 :     .purpose.size = htonl (sizeof (asap)),
     997           7 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
     998             :   };
     999             : 
    1000           7 :   TALER_amount_hton (&asap.threshold,
    1001             :                      balance_threshold);
    1002           7 :   return GNUNET_CRYPTO_eddsa_verify (
    1003             :     TALER_SIGNATURE_WALLET_ACCOUNT_SETUP,
    1004             :     &asap,
    1005             :     &reserve_sig->eddsa_signature,
    1006             :     &reserve_pub->eddsa_pub);
    1007             : }
    1008             : 
    1009             : 
    1010             : GNUNET_NETWORK_STRUCT_BEGIN
    1011             : 
    1012             : 
    1013             : /**
    1014             :  * Response by which a wallet requests a reserve history.
    1015             :  */
    1016             : struct TALER_ReserveHistoryRequestPS
    1017             : {
    1018             : 
    1019             :   /**
    1020             :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_HISTORY
    1021             :    */
    1022             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1023             : 
    1024             :   /**
    1025             :    * Which entries to exclude. Only return above this offset.
    1026             :    */
    1027             :   uint64_t start_off;
    1028             : 
    1029             : };
    1030             : 
    1031             : GNUNET_NETWORK_STRUCT_END
    1032             : 
    1033             : 
    1034             : enum GNUNET_GenericReturnValue
    1035           8 : TALER_wallet_reserve_history_verify (
    1036             :   uint64_t start_off,
    1037             :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1038             :   const struct TALER_ReserveSignatureP *reserve_sig)
    1039             : {
    1040          16 :   struct TALER_ReserveHistoryRequestPS rhr = {
    1041           8 :     .purpose.size = htonl (sizeof (rhr)),
    1042           8 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
    1043           8 :     .start_off = GNUNET_htonll (start_off)
    1044             :   };
    1045             : 
    1046           8 :   return GNUNET_CRYPTO_eddsa_verify (
    1047             :     TALER_SIGNATURE_WALLET_RESERVE_HISTORY,
    1048             :     &rhr,
    1049             :     &reserve_sig->eddsa_signature,
    1050             :     &reserve_pub->eddsa_pub);
    1051             : }
    1052             : 
    1053             : 
    1054             : void
    1055           8 : TALER_wallet_reserve_history_sign (
    1056             :   uint64_t start_off,
    1057             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1058             :   struct TALER_ReserveSignatureP *reserve_sig)
    1059             : {
    1060          16 :   struct TALER_ReserveHistoryRequestPS rhr = {
    1061           8 :     .purpose.size = htonl (sizeof (rhr)),
    1062           8 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
    1063           8 :     .start_off = GNUNET_htonll (start_off)
    1064             :   };
    1065             : 
    1066           8 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
    1067             :                             &rhr,
    1068             :                             &reserve_sig->eddsa_signature);
    1069           8 : }
    1070             : 
    1071             : 
    1072             : GNUNET_NETWORK_STRUCT_BEGIN
    1073             : 
    1074             : /**
    1075             :  * Response by which a wallet requests a coin history.
    1076             :  */
    1077             : struct TALER_CoinHistoryRequestPS
    1078             : {
    1079             : 
    1080             :   /**
    1081             :    * Purpose is #TALER_SIGNATURE_WALLET_COIN_HISTORY
    1082             :    */
    1083             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1084             : 
    1085             :   /**
    1086             :    * Which entries to exclude. Only return above this offset.
    1087             :    */
    1088             :   uint64_t start_off;
    1089             : 
    1090             : };
    1091             : 
    1092             : GNUNET_NETWORK_STRUCT_END
    1093             : 
    1094             : enum GNUNET_GenericReturnValue
    1095           4 : TALER_wallet_coin_history_verify (
    1096             :   uint64_t start_off,
    1097             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1098             :   const struct TALER_CoinSpendSignatureP *coin_sig)
    1099             : {
    1100           8 :   struct TALER_CoinHistoryRequestPS rsr = {
    1101           4 :     .purpose.size = htonl (sizeof (rsr)),
    1102           4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
    1103           4 :     .start_off = GNUNET_htonll (start_off)
    1104             :   };
    1105             : 
    1106           4 :   return GNUNET_CRYPTO_eddsa_verify (
    1107             :     TALER_SIGNATURE_WALLET_COIN_HISTORY,
    1108             :     &rsr,
    1109             :     &coin_sig->eddsa_signature,
    1110             :     &coin_pub->eddsa_pub);
    1111             : }
    1112             : 
    1113             : 
    1114             : void
    1115           4 : TALER_wallet_coin_history_sign (
    1116             :   uint64_t start_off,
    1117             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    1118             :   struct TALER_CoinSpendSignatureP *coin_sig)
    1119             : {
    1120           8 :   struct TALER_CoinHistoryRequestPS rsr = {
    1121           4 :     .purpose.size = htonl (sizeof (rsr)),
    1122           4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
    1123           4 :     .start_off = GNUNET_htonll (start_off)
    1124             :   };
    1125             : 
    1126           4 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
    1127             :                             &rsr,
    1128             :                             &coin_sig->eddsa_signature);
    1129           4 : }
    1130             : 
    1131             : 
    1132             : GNUNET_NETWORK_STRUCT_BEGIN
    1133             : 
    1134             : /**
    1135             :  * Message signed to create a purse (without reserve).
    1136             :  */
    1137             : struct TALER_PurseCreatePS
    1138             : {
    1139             : 
    1140             :   /**
    1141             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_CREATE
    1142             :    */
    1143             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1144             : 
    1145             :   /**
    1146             :    * Time when the purse will expire if still unmerged or unpaid.
    1147             :    */
    1148             :   struct GNUNET_TIME_TimestampNBO purse_expiration;
    1149             : 
    1150             :   /**
    1151             :    * Total amount (with fees) to be put into the purse.
    1152             :    */
    1153             :   struct TALER_AmountNBO purse_amount;
    1154             : 
    1155             :   /**
    1156             :    * Contract this purse pays for.
    1157             :    */
    1158             :   struct TALER_PrivateContractHashP h_contract_terms;
    1159             : 
    1160             :   /**
    1161             :    * Public key identifying the merge capability.
    1162             :    */
    1163             :   struct TALER_PurseMergePublicKeyP merge_pub;
    1164             : 
    1165             :   /**
    1166             :    * Minimum age required for payments into this purse.
    1167             :    */
    1168             :   uint32_t min_age GNUNET_PACKED;
    1169             : 
    1170             : };
    1171             : 
    1172             : 
    1173             : GNUNET_NETWORK_STRUCT_END
    1174             : 
    1175             : 
    1176             : void
    1177          25 : TALER_wallet_purse_create_sign (
    1178             :   struct GNUNET_TIME_Timestamp purse_expiration,
    1179             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1180             :   const struct TALER_PurseMergePublicKeyP *merge_pub,
    1181             :   uint32_t min_age,
    1182             :   const struct TALER_Amount *amount,
    1183             :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1184             :   struct TALER_PurseContractSignatureP *purse_sig)
    1185             : {
    1186          50 :   struct TALER_PurseCreatePS pm = {
    1187          25 :     .purpose.size = htonl (sizeof (pm)),
    1188          25 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
    1189          25 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1190             :     .h_contract_terms = *h_contract_terms,
    1191             :     .merge_pub = *merge_pub,
    1192          25 :     .min_age = htonl (min_age)
    1193             :   };
    1194             : 
    1195          25 :   TALER_amount_hton (&pm.purse_amount,
    1196             :                      amount);
    1197          25 :   GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
    1198             :                             &pm,
    1199             :                             &purse_sig->eddsa_signature);
    1200          25 : }
    1201             : 
    1202             : 
    1203             : enum GNUNET_GenericReturnValue
    1204          25 : TALER_wallet_purse_create_verify (
    1205             :   struct GNUNET_TIME_Timestamp purse_expiration,
    1206             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1207             :   const struct TALER_PurseMergePublicKeyP *merge_pub,
    1208             :   uint32_t min_age,
    1209             :   const struct TALER_Amount *amount,
    1210             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1211             :   const struct TALER_PurseContractSignatureP *purse_sig)
    1212             : {
    1213          50 :   struct TALER_PurseCreatePS pm = {
    1214          25 :     .purpose.size = htonl (sizeof (pm)),
    1215          25 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
    1216          25 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1217             :     .h_contract_terms = *h_contract_terms,
    1218             :     .merge_pub = *merge_pub,
    1219          25 :     .min_age = htonl (min_age)
    1220             :   };
    1221             : 
    1222          25 :   TALER_amount_hton (&pm.purse_amount,
    1223             :                      amount);
    1224          25 :   return GNUNET_CRYPTO_eddsa_verify (
    1225             :     TALER_SIGNATURE_WALLET_PURSE_CREATE,
    1226             :     &pm,
    1227             :     &purse_sig->eddsa_signature,
    1228             :     &purse_pub->eddsa_pub);
    1229             : }
    1230             : 
    1231             : 
    1232             : GNUNET_NETWORK_STRUCT_BEGIN
    1233             : 
    1234             : /**
    1235             :  * Message signed to delete a purse.
    1236             :  */
    1237             : struct TALER_PurseDeletePS
    1238             : {
    1239             : 
    1240             :   /**
    1241             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DELETE
    1242             :    */
    1243             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1244             : 
    1245             : };
    1246             : 
    1247             : 
    1248             : GNUNET_NETWORK_STRUCT_END
    1249             : 
    1250             : 
    1251             : void
    1252           2 : TALER_wallet_purse_delete_sign (
    1253             :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1254             :   struct TALER_PurseContractSignatureP *purse_sig)
    1255             : {
    1256           2 :   struct TALER_PurseDeletePS pm = {
    1257           2 :     .purpose.size = htonl (sizeof (pm)),
    1258           2 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
    1259             :   };
    1260             : 
    1261           2 :   GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
    1262             :                             &pm,
    1263             :                             &purse_sig->eddsa_signature);
    1264           2 : }
    1265             : 
    1266             : 
    1267             : enum GNUNET_GenericReturnValue
    1268           2 : TALER_wallet_purse_delete_verify (
    1269             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1270             :   const struct TALER_PurseContractSignatureP *purse_sig)
    1271             : {
    1272           2 :   struct TALER_PurseDeletePS pm = {
    1273           2 :     .purpose.size = htonl (sizeof (pm)),
    1274           2 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
    1275             :   };
    1276             : 
    1277           2 :   return GNUNET_CRYPTO_eddsa_verify (
    1278             :     TALER_SIGNATURE_WALLET_PURSE_DELETE,
    1279             :     &pm,
    1280             :     &purse_sig->eddsa_signature,
    1281             :     &purse_pub->eddsa_pub);
    1282             : }
    1283             : 
    1284             : 
    1285             : void
    1286           0 : TALER_wallet_purse_status_sign (
    1287             :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1288             :   struct TALER_PurseContractSignatureP *purse_sig)
    1289             : {
    1290           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
    1291           0 :     .size = htonl (sizeof (purpose)),
    1292           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
    1293             :   };
    1294             : 
    1295           0 :   GNUNET_assert (GNUNET_OK ==
    1296             :                  GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
    1297             :                                             &purpose,
    1298             :                                             &purse_sig->eddsa_signature));
    1299           0 : }
    1300             : 
    1301             : 
    1302             : enum GNUNET_GenericReturnValue
    1303           0 : TALER_wallet_purse_status_verify (
    1304             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1305             :   const struct TALER_PurseContractSignatureP *purse_sig)
    1306             : {
    1307           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
    1308           0 :     .size = htonl (sizeof (purpose)),
    1309           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
    1310             :   };
    1311             : 
    1312           0 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_STATUS,
    1313             :                                       &purpose,
    1314             :                                       &purse_sig->eddsa_signature,
    1315             :                                       &purse_pub->eddsa_pub);
    1316             : }
    1317             : 
    1318             : 
    1319             : GNUNET_NETWORK_STRUCT_BEGIN
    1320             : 
    1321             : /**
    1322             :  * Message signed to deposit a coin into a purse.
    1323             :  */
    1324             : struct TALER_PurseDepositPS
    1325             : {
    1326             : 
    1327             :   /**
    1328             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DEPOSIT
    1329             :    */
    1330             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1331             : 
    1332             :   /**
    1333             :    * Amount (with deposit fee) to be deposited into the purse.
    1334             :    */
    1335             :   struct TALER_AmountNBO coin_amount;
    1336             : 
    1337             :   /**
    1338             :    * Hash over the denomination public key used to sign the coin.
    1339             :    */
    1340             :   struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
    1341             : 
    1342             :   /**
    1343             :    * Hash over the age commitment that went into the coin. Maybe all zero, if
    1344             :    * age commitment isn't applicable to the denomination.
    1345             :    */
    1346             :   struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
    1347             : 
    1348             :   /**
    1349             :    * Purse to deposit funds into.
    1350             :    */
    1351             :   struct TALER_PurseContractPublicKeyP purse_pub;
    1352             : 
    1353             :   /**
    1354             :    * Hash of the base URL of the exchange hosting the
    1355             :    * @e purse_pub.
    1356             :    */
    1357             :   struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
    1358             : };
    1359             : 
    1360             : GNUNET_NETWORK_STRUCT_END
    1361             : 
    1362             : void
    1363          18 : TALER_wallet_purse_deposit_sign (
    1364             :   const char *exchange_base_url,
    1365             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1366             :   const struct TALER_Amount *amount,
    1367             :   const struct TALER_DenominationHashP *h_denom_pub,
    1368             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
    1369             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    1370             :   struct TALER_CoinSpendSignatureP *coin_sig)
    1371             : {
    1372          18 :   struct TALER_PurseDepositPS pm = {
    1373          18 :     .purpose.size = htonl (sizeof (pm)),
    1374          18 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
    1375             :     .purse_pub = *purse_pub,
    1376             :     .h_denom_pub = *h_denom_pub,
    1377             :     .h_age_commitment = *h_age_commitment
    1378             :   };
    1379             : 
    1380          18 :   GNUNET_CRYPTO_hash (exchange_base_url,
    1381          18 :                       strlen (exchange_base_url) + 1,
    1382             :                       &pm.h_exchange_base_url);
    1383          18 :   TALER_amount_hton (&pm.coin_amount,
    1384             :                      amount);
    1385          18 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
    1386             :                             &pm,
    1387             :                             &coin_sig->eddsa_signature);
    1388          18 : }
    1389             : 
    1390             : 
    1391             : enum GNUNET_GenericReturnValue
    1392          21 : TALER_wallet_purse_deposit_verify (
    1393             :   const char *exchange_base_url,
    1394             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1395             :   const struct TALER_Amount *amount,
    1396             :   const struct TALER_DenominationHashP *h_denom_pub,
    1397             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
    1398             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1399             :   const struct TALER_CoinSpendSignatureP *coin_sig)
    1400             : {
    1401          21 :   struct TALER_PurseDepositPS pm = {
    1402          21 :     .purpose.size = htonl (sizeof (pm)),
    1403          21 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
    1404             :     .purse_pub = *purse_pub,
    1405             :     .h_denom_pub = *h_denom_pub,
    1406             :     .h_age_commitment = *h_age_commitment
    1407             :   };
    1408             : 
    1409          21 :   GNUNET_CRYPTO_hash (exchange_base_url,
    1410          21 :                       strlen (exchange_base_url) + 1,
    1411             :                       &pm.h_exchange_base_url);
    1412          21 :   TALER_amount_hton (&pm.coin_amount,
    1413             :                      amount);
    1414          21 :   return GNUNET_CRYPTO_eddsa_verify (
    1415             :     TALER_SIGNATURE_WALLET_PURSE_DEPOSIT,
    1416             :     &pm,
    1417             :     &coin_sig->eddsa_signature,
    1418             :     &coin_pub->eddsa_pub);
    1419             : }
    1420             : 
    1421             : 
    1422             : GNUNET_NETWORK_STRUCT_BEGIN
    1423             : 
    1424             : /**
    1425             :  * Message signed to merge a purse into a reserve.
    1426             :  */
    1427             : struct TALER_PurseMergePS
    1428             : {
    1429             : 
    1430             :   /**
    1431             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_MERGE
    1432             :    */
    1433             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1434             : 
    1435             :   /**
    1436             :    * Time when the purse is merged into the reserve.
    1437             :    */
    1438             :   struct GNUNET_TIME_TimestampNBO merge_timestamp;
    1439             : 
    1440             :   /**
    1441             :    * Which purse is being merged?
    1442             :    */
    1443             :   struct TALER_PurseContractPublicKeyP purse_pub;
    1444             : 
    1445             :   /**
    1446             :    * Which reserve should the purse be merged with.
    1447             :    * Hash of the reserve's payto:// URI.
    1448             :    */
    1449             :   struct TALER_NormalizedPaytoHashP h_payto;
    1450             : 
    1451             : };
    1452             : 
    1453             : GNUNET_NETWORK_STRUCT_END
    1454             : 
    1455             : void
    1456          20 : TALER_wallet_purse_merge_sign (
    1457             :   const struct TALER_NormalizedPayto reserve_uri,
    1458             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1459             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1460             :   const struct TALER_PurseMergePrivateKeyP *merge_priv,
    1461             :   struct TALER_PurseMergeSignatureP *merge_sig)
    1462             : {
    1463          40 :   struct TALER_PurseMergePS pm = {
    1464          20 :     .purpose.size = htonl (sizeof (pm)),
    1465          20 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
    1466          20 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1467             :     .purse_pub = *purse_pub
    1468             :   };
    1469             : 
    1470          20 :   GNUNET_assert (0 ==
    1471             :                  strncasecmp (reserve_uri.normalized_payto,
    1472             :                               "payto://taler-reserve",
    1473             :                               strlen ("payto://taler-reserve")));
    1474          20 :   TALER_normalized_payto_hash (reserve_uri,
    1475             :                                &pm.h_payto);
    1476          20 :   GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv,
    1477             :                             &pm,
    1478             :                             &merge_sig->eddsa_signature);
    1479          20 : }
    1480             : 
    1481             : 
    1482             : enum GNUNET_GenericReturnValue
    1483          22 : TALER_wallet_purse_merge_verify (
    1484             :   const struct TALER_NormalizedPayto reserve_uri,
    1485             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1486             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1487             :   const struct TALER_PurseMergePublicKeyP *merge_pub,
    1488             :   const struct TALER_PurseMergeSignatureP *merge_sig)
    1489             : {
    1490          44 :   struct TALER_PurseMergePS pm = {
    1491          22 :     .purpose.size = htonl (sizeof (pm)),
    1492          22 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
    1493          22 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1494             :     .purse_pub = *purse_pub
    1495             :   };
    1496             : 
    1497          22 :   if (0 !=
    1498          22 :       strncasecmp (reserve_uri.normalized_payto,
    1499             :                    "payto://taler-reserve",
    1500             :                    strlen ("payto://taler-reserve")))
    1501             :   {
    1502           0 :     GNUNET_break (0);
    1503           0 :     return GNUNET_NO;
    1504             :   }
    1505          22 :   TALER_normalized_payto_hash (reserve_uri,
    1506             :                                &pm.h_payto);
    1507          22 :   return GNUNET_CRYPTO_eddsa_verify (
    1508             :     TALER_SIGNATURE_WALLET_PURSE_MERGE,
    1509             :     &pm,
    1510             :     &merge_sig->eddsa_signature,
    1511             :     &merge_pub->eddsa_pub);
    1512             : }
    1513             : 
    1514             : 
    1515             : GNUNET_NETWORK_STRUCT_BEGIN
    1516             : 
    1517             : /**
    1518             :  * Message signed by account to merge a purse into a reserve.
    1519             :  */
    1520             : struct TALER_AccountMergePS
    1521             : {
    1522             : 
    1523             :   /**
    1524             :    * Purpose is #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE
    1525             :    */
    1526             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1527             : 
    1528             :   /**
    1529             :    * Time when the purse will expire if still unmerged or unpaid.
    1530             :    */
    1531             :   struct GNUNET_TIME_TimestampNBO purse_expiration;
    1532             : 
    1533             :   /**
    1534             :    * Total amount (with fees) to be put into the purse.
    1535             :    */
    1536             :   struct TALER_AmountNBO purse_amount;
    1537             : 
    1538             :   /**
    1539             :    * Purse creation fee to be paid by the reserve for
    1540             :    * this operation.
    1541             :    */
    1542             :   struct TALER_AmountNBO purse_fee;
    1543             : 
    1544             :   /**
    1545             :    * Contract this purse pays for.
    1546             :    */
    1547             :   struct TALER_PrivateContractHashP h_contract_terms;
    1548             : 
    1549             :   /**
    1550             :    * Purse to merge.
    1551             :    */
    1552             :   struct TALER_PurseContractPublicKeyP purse_pub;
    1553             : 
    1554             :   /**
    1555             :    * Time when the purse is merged into the reserve.
    1556             :    */
    1557             :   struct GNUNET_TIME_TimestampNBO merge_timestamp;
    1558             : 
    1559             :   /**
    1560             :    * Minimum age required for payments into this purse,
    1561             :    * in NBO.
    1562             :    */
    1563             :   uint32_t min_age GNUNET_PACKED;
    1564             : 
    1565             :   /**
    1566             :    * Flags for the operation, in NBO. See
    1567             :    * `enum TALER_WalletAccountMergeFlags`.
    1568             :    */
    1569             :   uint32_t flags GNUNET_PACKED;
    1570             : };
    1571             : 
    1572             : GNUNET_NETWORK_STRUCT_END
    1573             : 
    1574             : 
    1575             : void
    1576          20 : TALER_wallet_account_merge_sign (
    1577             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1578             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1579             :   struct GNUNET_TIME_Timestamp purse_expiration,
    1580             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1581             :   const struct TALER_Amount *amount,
    1582             :   const struct TALER_Amount *purse_fee,
    1583             :   uint32_t min_age,
    1584             :   enum TALER_WalletAccountMergeFlags flags,
    1585             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1586             :   struct TALER_ReserveSignatureP *reserve_sig)
    1587             : {
    1588          60 :   struct TALER_AccountMergePS pm = {
    1589          20 :     .purpose.size = htonl (sizeof (pm)),
    1590          20 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
    1591          20 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1592             :     .purse_pub = *purse_pub,
    1593          20 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1594             :     .h_contract_terms = *h_contract_terms,
    1595          20 :     .min_age = htonl (min_age),
    1596          20 :     .flags = htonl ((uint32_t) flags)
    1597             :   };
    1598             : 
    1599          20 :   TALER_amount_hton (&pm.purse_amount,
    1600             :                      amount);
    1601          20 :   TALER_amount_hton (&pm.purse_fee,
    1602             :                      purse_fee);
    1603          20 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
    1604             :                             &pm,
    1605             :                             &reserve_sig->eddsa_signature);
    1606          20 : }
    1607             : 
    1608             : 
    1609             : enum GNUNET_GenericReturnValue
    1610          28 : TALER_wallet_account_merge_verify (
    1611             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1612             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1613             :   struct GNUNET_TIME_Timestamp purse_expiration,
    1614             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1615             :   const struct TALER_Amount *amount,
    1616             :   const struct TALER_Amount *purse_fee,
    1617             :   uint32_t min_age,
    1618             :   enum TALER_WalletAccountMergeFlags flags,
    1619             :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1620             :   const struct TALER_ReserveSignatureP *reserve_sig)
    1621             : {
    1622          84 :   struct TALER_AccountMergePS pm = {
    1623          28 :     .purpose.size = htonl (sizeof (pm)),
    1624          28 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
    1625          28 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1626             :     .purse_pub = *purse_pub,
    1627          28 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1628             :     .h_contract_terms = *h_contract_terms,
    1629          28 :     .min_age = htonl (min_age),
    1630          28 :     .flags = htonl ((uint32_t) flags)
    1631             :   };
    1632             : 
    1633          28 :   TALER_amount_hton (&pm.purse_amount,
    1634             :                      amount);
    1635          28 :   TALER_amount_hton (&pm.purse_fee,
    1636             :                      purse_fee);
    1637          28 :   return GNUNET_CRYPTO_eddsa_verify (
    1638             :     TALER_SIGNATURE_WALLET_ACCOUNT_MERGE,
    1639             :     &pm,
    1640             :     &reserve_sig->eddsa_signature,
    1641             :     &reserve_pub->eddsa_pub);
    1642             : }
    1643             : 
    1644             : 
    1645             : GNUNET_NETWORK_STRUCT_BEGIN
    1646             : 
    1647             : /**
    1648             :  * Message signed by reserve key.
    1649             :  */
    1650             : struct TALER_ReserveOpenPS
    1651             : {
    1652             : 
    1653             :   /**
    1654             :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN
    1655             :    */
    1656             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1657             : 
    1658             :   /**
    1659             :    * Amount to be paid from the reserve balance to open
    1660             :    * the reserve.
    1661             :    */
    1662             :   struct TALER_AmountNBO reserve_payment;
    1663             : 
    1664             :   /**
    1665             :    * When was the request created.
    1666             :    */
    1667             :   struct GNUNET_TIME_TimestampNBO request_timestamp;
    1668             : 
    1669             :   /**
    1670             :    * For how long should the reserve be kept open.
    1671             :    * (Determines amount to be paid.)
    1672             :    */
    1673             :   struct GNUNET_TIME_TimestampNBO reserve_expiration;
    1674             : 
    1675             :   /**
    1676             :    * How many open purses should be included with the
    1677             :    * open reserve?
    1678             :    * (Determines amount to be paid.)
    1679             :    */
    1680             :   uint32_t purse_limit GNUNET_PACKED;
    1681             : 
    1682             : };
    1683             : 
    1684             : GNUNET_NETWORK_STRUCT_END
    1685             : 
    1686             : 
    1687             : void
    1688           6 : TALER_wallet_reserve_open_sign (
    1689             :   const struct TALER_Amount *reserve_payment,
    1690             :   struct GNUNET_TIME_Timestamp request_timestamp,
    1691             :   struct GNUNET_TIME_Timestamp reserve_expiration,
    1692             :   uint32_t purse_limit,
    1693             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1694             :   struct TALER_ReserveSignatureP *reserve_sig)
    1695             : {
    1696          12 :   struct TALER_ReserveOpenPS rop = {
    1697           6 :     .purpose.size = htonl (sizeof (rop)),
    1698           6 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
    1699           6 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
    1700           6 :     .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
    1701           6 :     .purse_limit = htonl (purse_limit)
    1702             :   };
    1703             : 
    1704           6 :   TALER_amount_hton (&rop.reserve_payment,
    1705             :                      reserve_payment);
    1706           6 :   GNUNET_assert (GNUNET_OK ==
    1707             :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
    1708             :                                             &rop.purpose,
    1709             :                                             &reserve_sig->eddsa_signature));
    1710           6 : }
    1711             : 
    1712             : 
    1713             : enum GNUNET_GenericReturnValue
    1714           6 : TALER_wallet_reserve_open_verify (
    1715             :   const struct TALER_Amount *reserve_payment,
    1716             :   struct GNUNET_TIME_Timestamp request_timestamp,
    1717             :   struct GNUNET_TIME_Timestamp reserve_expiration,
    1718             :   uint32_t purse_limit,
    1719             :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1720             :   const struct TALER_ReserveSignatureP *reserve_sig)
    1721             : {
    1722          12 :   struct TALER_ReserveOpenPS rop = {
    1723           6 :     .purpose.size = htonl (sizeof (rop)),
    1724           6 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
    1725           6 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
    1726           6 :     .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
    1727           6 :     .purse_limit = htonl (purse_limit)
    1728             :   };
    1729             : 
    1730           6 :   TALER_amount_hton (&rop.reserve_payment,
    1731             :                      reserve_payment);
    1732           6 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_OPEN,
    1733             :                                       &rop.purpose,
    1734             :                                       &reserve_sig->eddsa_signature,
    1735             :                                       &reserve_pub->eddsa_pub);
    1736             : }
    1737             : 
    1738             : 
    1739             : GNUNET_NETWORK_STRUCT_BEGIN
    1740             : 
    1741             : /**
    1742             :  * Message signed by
    1743             :  */
    1744             : struct TALER_ReserveOpenDepositPS
    1745             : {
    1746             : 
    1747             :   /**
    1748             :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
    1749             :    */
    1750             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1751             : 
    1752             :   /**
    1753             :    * Which reserve's opening signature should be paid for?
    1754             :    */
    1755             :   struct TALER_ReserveSignatureP reserve_sig;
    1756             : 
    1757             :   /**
    1758             :    * Specifies how much of the coin's value should be spent on opening this
    1759             :    * reserve.
    1760             :    */
    1761             :   struct TALER_AmountNBO coin_contribution;
    1762             : };
    1763             : 
    1764             : GNUNET_NETWORK_STRUCT_END
    1765             : 
    1766             : 
    1767             : // FIXME-#7267: add h_age_commitment, h_denom_pub to have proof!
    1768             : void
    1769           2 : TALER_wallet_reserve_open_deposit_sign (
    1770             :   const struct TALER_Amount *coin_contribution,
    1771             :   const struct TALER_ReserveSignatureP *reserve_sig,
    1772             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
    1773             :   struct TALER_CoinSpendSignatureP *coin_sig)
    1774             : {
    1775           2 :   struct TALER_ReserveOpenDepositPS rod = {
    1776           2 :     .purpose.size = htonl (sizeof (rod)),
    1777           2 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
    1778             :     .reserve_sig = *reserve_sig
    1779             :   };
    1780             : 
    1781           2 :   TALER_amount_hton (&rod.coin_contribution,
    1782             :                      coin_contribution);
    1783           2 :   GNUNET_assert (GNUNET_OK ==
    1784             :                  GNUNET_CRYPTO_eddsa_sign_ (&coin_priv->eddsa_priv,
    1785             :                                             &rod.purpose,
    1786             :                                             &coin_sig->eddsa_signature));
    1787           2 : }
    1788             : 
    1789             : 
    1790             : enum GNUNET_GenericReturnValue
    1791           0 : TALER_wallet_reserve_open_deposit_verify (
    1792             :   const struct TALER_Amount *coin_contribution,
    1793             :   const struct TALER_ReserveSignatureP *reserve_sig,
    1794             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
    1795             :   const struct TALER_CoinSpendSignatureP *coin_sig)
    1796             : {
    1797           0 :   struct TALER_ReserveOpenDepositPS rod = {
    1798           0 :     .purpose.size = htonl (sizeof (rod)),
    1799           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
    1800             :     .reserve_sig = *reserve_sig
    1801             :   };
    1802             : 
    1803           0 :   TALER_amount_hton (&rod.coin_contribution,
    1804             :                      coin_contribution);
    1805           0 :   return GNUNET_CRYPTO_eddsa_verify_ (
    1806             :     TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT,
    1807             :     &rod.purpose,
    1808             :     &coin_sig->eddsa_signature,
    1809             :     &coin_pub->eddsa_pub);
    1810             : }
    1811             : 
    1812             : 
    1813             : GNUNET_NETWORK_STRUCT_BEGIN
    1814             : 
    1815             : /**
    1816             :  * Message signed by reserve key.
    1817             :  */
    1818             : struct TALER_ReserveClosePS
    1819             : {
    1820             : 
    1821             :   /**
    1822             :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_CLOSE
    1823             :    */
    1824             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1825             : 
    1826             :   /**
    1827             :    * When was the request created.
    1828             :    */
    1829             :   struct GNUNET_TIME_TimestampNBO request_timestamp;
    1830             : 
    1831             :   /**
    1832             :    * Hash of the payto://-URI of the target account
    1833             :    * for the closure, or all zeros for the reserve
    1834             :    * origin account.
    1835             :    */
    1836             :   struct TALER_FullPaytoHashP target_account_h_payto;
    1837             : 
    1838             : };
    1839             : 
    1840             : GNUNET_NETWORK_STRUCT_END
    1841             : 
    1842             : 
    1843             : void
    1844           4 : TALER_wallet_reserve_close_sign (
    1845             :   struct GNUNET_TIME_Timestamp request_timestamp,
    1846             :   const struct TALER_FullPaytoHashP *h_payto,
    1847             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1848             :   struct TALER_ReserveSignatureP *reserve_sig)
    1849             : {
    1850           4 :   struct TALER_ReserveClosePS rcp = {
    1851           4 :     .purpose.size = htonl (sizeof (rcp)),
    1852           4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
    1853           4 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1854             :   };
    1855             : 
    1856           4 :   if (NULL != h_payto)
    1857           4 :     rcp.target_account_h_payto = *h_payto;
    1858           4 :   GNUNET_assert (GNUNET_OK ==
    1859             :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
    1860             :                                             &rcp.purpose,
    1861             :                                             &reserve_sig->eddsa_signature));
    1862           4 : }
    1863             : 
    1864             : 
    1865             : enum GNUNET_GenericReturnValue
    1866           4 : TALER_wallet_reserve_close_verify (
    1867             :   struct GNUNET_TIME_Timestamp request_timestamp,
    1868             :   const struct TALER_FullPaytoHashP *h_payto,
    1869             :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1870             :   const struct TALER_ReserveSignatureP *reserve_sig)
    1871             : {
    1872           4 :   struct TALER_ReserveClosePS rcp = {
    1873           4 :     .purpose.size = htonl (sizeof (rcp)),
    1874           4 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
    1875           4 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1876             :   };
    1877             : 
    1878           4 :   if (NULL != h_payto)
    1879           4 :     rcp.target_account_h_payto = *h_payto;
    1880           4 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE,
    1881             :                                       &rcp.purpose,
    1882             :                                       &reserve_sig->eddsa_signature,
    1883             :                                       &reserve_pub->eddsa_pub);
    1884             : }
    1885             : 
    1886             : 
    1887             : GNUNET_NETWORK_STRUCT_BEGIN
    1888             : 
    1889             : /**
    1890             :  * Message signed by reserve private key.
    1891             :  */
    1892             : struct TALER_ReserveAttestRequestPS
    1893             : {
    1894             : 
    1895             :   /**
    1896             :    * Purpose is #TALER_SIGNATURE_WALLET_ATTEST_REQUEST
    1897             :    */
    1898             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1899             : 
    1900             :   /**
    1901             :    * When was the request created.
    1902             :    */
    1903             :   struct GNUNET_TIME_TimestampNBO request_timestamp;
    1904             : 
    1905             :   /**
    1906             :    * Hash over the JSON array of requested attributes.
    1907             :    */
    1908             :   struct GNUNET_HashCode h_details;
    1909             : 
    1910             : };
    1911             : 
    1912             : GNUNET_NETWORK_STRUCT_END
    1913             : 
    1914             : 
    1915             : void
    1916           1 : TALER_wallet_reserve_attest_request_sign (
    1917             :   struct GNUNET_TIME_Timestamp request_timestamp,
    1918             :   const json_t *details,
    1919             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1920             :   struct TALER_ReserveSignatureP *reserve_sig)
    1921             : {
    1922           1 :   struct TALER_ReserveAttestRequestPS rcp = {
    1923           1 :     .purpose.size = htonl (sizeof (rcp)),
    1924           1 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
    1925           1 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1926             :   };
    1927             : 
    1928           1 :   TALER_json_hash (details,
    1929             :                    &rcp.h_details);
    1930           1 :   GNUNET_assert (GNUNET_OK ==
    1931             :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
    1932             :                                             &rcp.purpose,
    1933             :                                             &reserve_sig->eddsa_signature));
    1934           1 : }
    1935             : 
    1936             : 
    1937             : enum GNUNET_GenericReturnValue
    1938           1 : TALER_wallet_reserve_attest_request_verify (
    1939             :   struct GNUNET_TIME_Timestamp request_timestamp,
    1940             :   const json_t *details,
    1941             :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1942             :   const struct TALER_ReserveSignatureP *reserve_sig)
    1943             : {
    1944           1 :   struct TALER_ReserveAttestRequestPS rcp = {
    1945           1 :     .purpose.size = htonl (sizeof (rcp)),
    1946           1 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
    1947           1 :     .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
    1948             :   };
    1949             : 
    1950           1 :   TALER_json_hash (details,
    1951             :                    &rcp.h_details);
    1952           1 :   return GNUNET_CRYPTO_eddsa_verify_ (
    1953             :     TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS,
    1954             :     &rcp.purpose,
    1955             :     &reserve_sig->eddsa_signature,
    1956             :     &reserve_pub->eddsa_pub);
    1957             : }
    1958             : 
    1959             : 
    1960             : GNUNET_NETWORK_STRUCT_BEGIN
    1961             : 
    1962             : /**
    1963             :  * Message signed by purse to associate an encrypted contract.
    1964             :  */
    1965             : struct TALER_PurseContractPS
    1966             : {
    1967             : 
    1968             :   /**
    1969             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_ECONTRACT
    1970             :    */
    1971             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1972             : 
    1973             :   /**
    1974             :    * Hash over the encrypted contract.
    1975             :    */
    1976             :   struct GNUNET_HashCode h_econtract;
    1977             : 
    1978             :   /**
    1979             :    * Public key to decrypt the contract.
    1980             :    */
    1981             :   struct TALER_ContractDiffiePublicP contract_pub;
    1982             : };
    1983             : 
    1984             : GNUNET_NETWORK_STRUCT_END
    1985             : 
    1986             : void
    1987          25 : TALER_wallet_econtract_upload_sign (
    1988             :   const void *econtract,
    1989             :   size_t econtract_size,
    1990             :   const struct TALER_ContractDiffiePublicP *contract_pub,
    1991             :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1992             :   struct TALER_PurseContractSignatureP *purse_sig)
    1993             : {
    1994          25 :   struct TALER_PurseContractPS pc = {
    1995          25 :     .purpose.size = htonl (sizeof (pc)),
    1996          25 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
    1997             :     .contract_pub = *contract_pub
    1998             :   };
    1999             : 
    2000          25 :   GNUNET_CRYPTO_hash (econtract,
    2001             :                       econtract_size,
    2002             :                       &pc.h_econtract);
    2003          25 :   GNUNET_assert (GNUNET_OK ==
    2004             :                  GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
    2005             :                                             &pc.purpose,
    2006             :                                             &purse_sig->eddsa_signature));
    2007          25 : }
    2008             : 
    2009             : 
    2010             : enum GNUNET_GenericReturnValue
    2011          31 : TALER_wallet_econtract_upload_verify2 (
    2012             :   const struct GNUNET_HashCode *h_econtract,
    2013             :   const struct TALER_ContractDiffiePublicP *contract_pub,
    2014             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    2015             :   const struct TALER_PurseContractSignatureP *purse_sig)
    2016             : {
    2017          31 :   struct TALER_PurseContractPS pc = {
    2018          31 :     .purpose.size = htonl (sizeof (pc)),
    2019          31 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
    2020             :     .contract_pub = *contract_pub,
    2021             :     .h_econtract = *h_econtract
    2022             :   };
    2023             : 
    2024          31 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT,
    2025             :                                       &pc.purpose,
    2026             :                                       &purse_sig->eddsa_signature,
    2027             :                                       &purse_pub->eddsa_pub);
    2028             : }
    2029             : 
    2030             : 
    2031             : enum GNUNET_GenericReturnValue
    2032          31 : TALER_wallet_econtract_upload_verify (
    2033             :   const void *econtract,
    2034             :   size_t econtract_size,
    2035             :   const struct TALER_ContractDiffiePublicP *contract_pub,
    2036             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    2037             :   const struct TALER_PurseContractSignatureP *purse_sig)
    2038             : {
    2039             :   struct GNUNET_HashCode h_econtract;
    2040             : 
    2041          31 :   GNUNET_CRYPTO_hash (econtract,
    2042             :                       econtract_size,
    2043             :                       &h_econtract);
    2044          31 :   return TALER_wallet_econtract_upload_verify2 (&h_econtract,
    2045             :                                                 contract_pub,
    2046             :                                                 purse_pub,
    2047             :                                                 purse_sig);
    2048             : }
    2049             : 
    2050             : 
    2051             : GNUNET_NETWORK_STRUCT_BEGIN
    2052             : 
    2053             : /**
    2054             :  * Message signed by wallet to confirm usage of a token for a transaction.
    2055             :  */
    2056             : struct TALER_TokenUseRequestPS
    2057             : {
    2058             : 
    2059             :   /**
    2060             :    * Purpose is #TALER_SIGNATURE_WALLET_TOKEN_USE
    2061             :    */
    2062             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    2063             : 
    2064             :   /**
    2065             :    * Hash over the contract for which this token is used.
    2066             :    */
    2067             :   struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
    2068             : 
    2069             :   /**
    2070             :    * Hash over a JSON containing data provided by the
    2071             :    * wallet to complete the contract upon payment.
    2072             :    */
    2073             :   struct GNUNET_HashCode wallet_data_hash;
    2074             : 
    2075             : };
    2076             : 
    2077             : GNUNET_NETWORK_STRUCT_END
    2078             : 
    2079             : 
    2080             : void
    2081           0 : TALER_wallet_token_use_sign (
    2082             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    2083             :   const struct GNUNET_HashCode *wallet_data_hash,
    2084             :   const struct TALER_TokenUsePrivateKeyP *token_use_priv,
    2085             :   struct TALER_TokenUseSignatureP *token_sig)
    2086             : {
    2087           0 :   struct TALER_TokenUseRequestPS tur = {
    2088           0 :     .purpose.size = htonl (sizeof (tur)),
    2089           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE),
    2090             :     .h_contract_terms = *h_contract_terms,
    2091             :     .wallet_data_hash = *wallet_data_hash
    2092             :   };
    2093             : 
    2094           0 :   GNUNET_CRYPTO_eddsa_sign (&token_use_priv->private_key,
    2095             :                             &tur,
    2096             :                             &token_sig->signature);
    2097           0 : }
    2098             : 
    2099             : 
    2100             : enum GNUNET_GenericReturnValue
    2101           0 : TALER_wallet_token_use_verify (
    2102             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    2103             :   const struct GNUNET_HashCode *wallet_data_hash,
    2104             :   const struct TALER_TokenUsePublicKeyP *token_use_pub,
    2105             :   const struct TALER_TokenUseSignatureP *token_sig)
    2106             : {
    2107           0 :   struct TALER_TokenUseRequestPS tur = {
    2108           0 :     .purpose.size = htonl (sizeof (tur)),
    2109           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE),
    2110             :     .h_contract_terms = *h_contract_terms,
    2111             :     .wallet_data_hash = *wallet_data_hash
    2112             :   };
    2113             : 
    2114           0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_TOKEN_USE,
    2115             :                                      &tur,
    2116             :                                      &token_sig->signature,
    2117             :                                      &token_use_pub->public_key);
    2118             : }
    2119             : 
    2120             : 
    2121             : /* end of wallet_signatures.c */

Generated by: LCOV version 1.16