LCOV - code coverage report
Current view: top level - util - wallet_signatures.c (source / functions) Hit Total Coverage
Test: GNU Taler exchange coverage report Lines: 0 249 0.0 %
Date: 2022-08-25 06:15:09 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :   This file is part of TALER
       3             :   Copyright (C) 2021, 2022 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             :  */
      21             : #include "platform.h"
      22             : #include "taler_util.h"
      23             : #include "taler_signatures.h"
      24             : 
      25             : 
      26             : /**
      27             :  * @brief Format used to generate the signature on a request to deposit
      28             :  * a coin into the account of a merchant.
      29             :  */
      30             : struct TALER_DepositRequestPS
      31             : {
      32             :   /**
      33             :    * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT.
      34             :    * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
      35             :    */
      36             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
      37             : 
      38             :   /**
      39             :    * Hash over the contract for which this deposit is made.
      40             :    */
      41             :   struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
      42             : 
      43             :   /**
      44             :    * Hash over the age commitment that went into the coin. Maybe all zero, if
      45             :    * age commitment isn't applicable to the denomination.
      46             :    */
      47             :   struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
      48             : 
      49             :   /**
      50             :    * Hash over extension attributes shared with the exchange.
      51             :    */
      52             :   struct TALER_ExtensionContractHashP h_extensions GNUNET_PACKED;
      53             : 
      54             :   /**
      55             :    * Hash over the wiring information of the merchant.
      56             :    */
      57             :   struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
      58             : 
      59             :   /**
      60             :    * Hash over the denomination public key used to sign the coin.
      61             :    */
      62             :   struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
      63             : 
      64             :   /**
      65             :    * Time when this request was generated.  Used, for example, to
      66             :    * assess when (roughly) the income was achieved for tax purposes.
      67             :    * Note that the Exchange will only check that the timestamp is not "too
      68             :    * far" into the future (i.e. several days).  The fact that the
      69             :    * timestamp falls within the validity period of the coin's
      70             :    * denomination key is irrelevant for the validity of the deposit
      71             :    * request, as obviously the customer and merchant could conspire to
      72             :    * set any timestamp.  Also, the Exchange must accept very old deposit
      73             :    * requests, as the merchant might have been unable to transmit the
      74             :    * deposit request in a timely fashion (so back-dating is not
      75             :    * prevented).
      76             :    */
      77             :   struct GNUNET_TIME_TimestampNBO wallet_timestamp;
      78             : 
      79             :   /**
      80             :    * How much time does the merchant have to issue a refund request?
      81             :    * Zero if refunds are not allowed.  After this time, the coin
      82             :    * cannot be refunded.
      83             :    */
      84             :   struct GNUNET_TIME_TimestampNBO refund_deadline;
      85             : 
      86             :   /**
      87             :    * Amount to be deposited, including deposit fee charged by the
      88             :    * exchange.  This is the total amount that the coin's value at the exchange
      89             :    * will be reduced by.
      90             :    */
      91             :   struct TALER_AmountNBO amount_with_fee;
      92             : 
      93             :   /**
      94             :    * Depositing fee charged by the exchange.  This must match the Exchange's
      95             :    * denomination key's depositing fee.  If the client puts in an
      96             :    * invalid deposit fee (too high or too low) that does not match the
      97             :    * Exchange's denomination key, the deposit operation is invalid and
      98             :    * will be rejected by the exchange.  The @e amount_with_fee minus the
      99             :    * @e deposit_fee is the amount that will be transferred to the
     100             :    * account identified by @e h_wire.
     101             :    */
     102             :   struct TALER_AmountNBO deposit_fee;
     103             : 
     104             :   /**
     105             :    * The Merchant's public key.  Allows the merchant to later refund
     106             :    * the transaction or to inquire about the wire transfer identifier.
     107             :    */
     108             :   struct TALER_MerchantPublicKeyP merchant;
     109             : 
     110             : };
     111             : 
     112             : 
     113             : void
     114           0 : TALER_wallet_deposit_sign (
     115             :   const struct TALER_Amount *amount,
     116             :   const struct TALER_Amount *deposit_fee,
     117             :   const struct TALER_MerchantWireHashP *h_wire,
     118             :   const struct TALER_PrivateContractHashP *h_contract_terms,
     119             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
     120             :   const struct TALER_ExtensionContractHashP *h_extensions,
     121             :   const struct TALER_DenominationHashP *h_denom_pub,
     122             :   const struct GNUNET_TIME_Timestamp wallet_timestamp,
     123             :   const struct TALER_MerchantPublicKeyP *merchant_pub,
     124             :   const struct GNUNET_TIME_Timestamp refund_deadline,
     125             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     126             :   struct TALER_CoinSpendSignatureP *coin_sig)
     127             : {
     128           0 :   struct TALER_DepositRequestPS dr = {
     129           0 :     .purpose.size = htonl (sizeof (dr)),
     130           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
     131             :     .h_contract_terms = *h_contract_terms,
     132             :     .h_wire = *h_wire,
     133             :     .h_denom_pub = *h_denom_pub,
     134           0 :     .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
     135           0 :     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
     136             :     .merchant = *merchant_pub
     137             :   };
     138             : 
     139           0 :   if (NULL != h_age_commitment)
     140           0 :     dr.h_age_commitment = *h_age_commitment;
     141           0 :   if (NULL != h_extensions)
     142           0 :     dr.h_extensions = *h_extensions;
     143           0 :   TALER_amount_hton (&dr.amount_with_fee,
     144             :                      amount);
     145           0 :   TALER_amount_hton (&dr.deposit_fee,
     146             :                      deposit_fee);
     147           0 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     148             :                             &dr,
     149             :                             &coin_sig->eddsa_signature);
     150           0 : }
     151             : 
     152             : 
     153             : enum GNUNET_GenericReturnValue
     154           0 : TALER_wallet_deposit_verify (
     155             :   const struct TALER_Amount *amount,
     156             :   const struct TALER_Amount *deposit_fee,
     157             :   const struct TALER_MerchantWireHashP *h_wire,
     158             :   const struct TALER_PrivateContractHashP *h_contract_terms,
     159             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
     160             :   const struct TALER_ExtensionContractHashP *h_extensions,
     161             :   const struct TALER_DenominationHashP *h_denom_pub,
     162             :   struct GNUNET_TIME_Timestamp wallet_timestamp,
     163             :   const struct TALER_MerchantPublicKeyP *merchant_pub,
     164             :   struct GNUNET_TIME_Timestamp refund_deadline,
     165             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     166             :   const struct TALER_CoinSpendSignatureP *coin_sig)
     167             : {
     168           0 :   struct TALER_DepositRequestPS dr = {
     169           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
     170           0 :     .purpose.size = htonl (sizeof (dr)),
     171             :     .h_contract_terms = *h_contract_terms,
     172             :     .h_wire = *h_wire,
     173             :     .h_denom_pub = *h_denom_pub,
     174           0 :     .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
     175           0 :     .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
     176             :     .merchant = *merchant_pub,
     177             :     .h_age_commitment = {{{0}}},
     178             :     .h_extensions = {{{0}}}
     179             :   };
     180             : 
     181           0 :   if (NULL != h_age_commitment)
     182           0 :     dr.h_age_commitment = *h_age_commitment;
     183           0 :   if (NULL != h_extensions)
     184           0 :     dr.h_extensions = *h_extensions;
     185           0 :   TALER_amount_hton (&dr.amount_with_fee,
     186             :                      amount);
     187           0 :   TALER_amount_hton (&dr.deposit_fee,
     188             :                      deposit_fee);
     189           0 :   if (GNUNET_OK !=
     190           0 :       GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
     191             :                                   &dr,
     192             :                                   &coin_sig->eddsa_signature,
     193             :                                   &coin_pub->eddsa_pub))
     194             :   {
     195           0 :     GNUNET_break_op (0);
     196           0 :     return GNUNET_SYSERR;
     197             :   }
     198           0 :   return GNUNET_OK;
     199             : }
     200             : 
     201             : 
     202             : /**
     203             :  * @brief Format used for to allow the wallet to authenticate
     204             :  * link data provided by the exchange.
     205             :  */
     206             : struct TALER_LinkDataPS
     207             : {
     208             : 
     209             :   /**
     210             :    * Purpose must be #TALER_SIGNATURE_WALLET_COIN_LINK.
     211             :    * Used with an EdDSA signature of a `struct TALER_CoinPublicKeyP`.
     212             :    */
     213             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     214             : 
     215             :   /**
     216             :    * Hash of the denomination public key of the new coin.
     217             :    */
     218             :   struct TALER_DenominationHashP h_denom_pub;
     219             : 
     220             :   /**
     221             :    * Transfer public key (for which the private key was not revealed)
     222             :    */
     223             :   struct TALER_TransferPublicKeyP transfer_pub;
     224             : 
     225             :   /**
     226             :    * Hash of the age commitment, if applicable.  Can be all zero
     227             :    */
     228             :   struct TALER_AgeCommitmentHash h_age_commitment;
     229             : 
     230             :   /**
     231             :    * Hash of the blinded new coin.
     232             :    */
     233             :   struct TALER_BlindedCoinHashP coin_envelope_hash;
     234             : };
     235             : 
     236             : 
     237             : void
     238           0 : TALER_wallet_link_sign (const struct TALER_DenominationHashP *h_denom_pub,
     239             :                         const struct TALER_TransferPublicKeyP *transfer_pub,
     240             :                         const struct TALER_BlindedCoinHashP *bch,
     241             :                         const struct TALER_CoinSpendPrivateKeyP *old_coin_priv,
     242             :                         struct TALER_CoinSpendSignatureP *coin_sig)
     243             : {
     244           0 :   struct TALER_LinkDataPS ldp = {
     245           0 :     .purpose.size = htonl (sizeof (ldp)),
     246           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     247             :     .h_denom_pub = *h_denom_pub,
     248             :     .transfer_pub = *transfer_pub,
     249             :     .coin_envelope_hash = *bch
     250             :   };
     251             : 
     252           0 :   GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
     253             :                             &ldp,
     254             :                             &coin_sig->eddsa_signature);
     255           0 : }
     256             : 
     257             : 
     258             : enum GNUNET_GenericReturnValue
     259           0 : TALER_wallet_link_verify (
     260             :   const struct TALER_DenominationHashP *h_denom_pub,
     261             :   const struct TALER_TransferPublicKeyP *transfer_pub,
     262             :   const struct TALER_BlindedCoinHashP *h_coin_ev,
     263             :   const struct TALER_CoinSpendPublicKeyP *old_coin_pub,
     264             :   const struct TALER_CoinSpendSignatureP *coin_sig)
     265             : {
     266           0 :   struct TALER_LinkDataPS ldp = {
     267           0 :     .purpose.size = htonl (sizeof (ldp)),
     268           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
     269             :     .h_denom_pub = *h_denom_pub,
     270             :     .transfer_pub = *transfer_pub,
     271             :     .coin_envelope_hash = *h_coin_ev,
     272             :   };
     273             : 
     274             :   return
     275           0 :     GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_LINK,
     276             :                                 &ldp,
     277             :                                 &coin_sig->eddsa_signature,
     278             :                                 &old_coin_pub->eddsa_pub);
     279             : }
     280             : 
     281             : 
     282             : /**
     283             :  * Signed data to request that a coin should be refunded as part of
     284             :  * the "emergency" /recoup protocol.  The refund will go back to the bank
     285             :  * account that created the reserve.
     286             :  */
     287             : struct TALER_RecoupRequestPS
     288             : {
     289             :   /**
     290             :    * Purpose is #TALER_SIGNATURE_WALLET_COIN_RECOUP
     291             :    * or #TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH.
     292             :    */
     293             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     294             : 
     295             :   /**
     296             :    * Hash of the (revoked) denomination public key of the coin.
     297             :    */
     298             :   struct TALER_DenominationHashP h_denom_pub;
     299             : 
     300             :   /**
     301             :    * Blinding factor that was used to withdraw the coin.
     302             :    */
     303             :   union TALER_DenominationBlindingKeyP coin_blind;
     304             : 
     305             : };
     306             : 
     307             : 
     308             : enum GNUNET_GenericReturnValue
     309           0 : TALER_wallet_recoup_verify (
     310             :   const struct TALER_DenominationHashP *h_denom_pub,
     311             :   const union TALER_DenominationBlindingKeyP *coin_bks,
     312             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     313             :   const struct TALER_CoinSpendSignatureP *coin_sig)
     314             : {
     315           0 :   struct TALER_RecoupRequestPS pr = {
     316           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
     317           0 :     .purpose.size = htonl (sizeof (pr)),
     318             :     .h_denom_pub = *h_denom_pub,
     319             :     .coin_blind = *coin_bks
     320             :   };
     321             : 
     322           0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP,
     323             :                                      &pr,
     324             :                                      &coin_sig->eddsa_signature,
     325             :                                      &coin_pub->eddsa_pub);
     326             : }
     327             : 
     328             : 
     329             : void
     330           0 : TALER_wallet_recoup_sign (
     331             :   const struct TALER_DenominationHashP *h_denom_pub,
     332             :   const union TALER_DenominationBlindingKeyP *coin_bks,
     333             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     334             :   struct TALER_CoinSpendSignatureP *coin_sig)
     335             : {
     336           0 :   struct TALER_RecoupRequestPS pr = {
     337           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
     338           0 :     .purpose.size = htonl (sizeof (pr)),
     339             :     .h_denom_pub = *h_denom_pub,
     340             :     .coin_blind = *coin_bks
     341             :   };
     342             : 
     343           0 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     344             :                             &pr,
     345             :                             &coin_sig->eddsa_signature);
     346           0 : }
     347             : 
     348             : 
     349             : enum GNUNET_GenericReturnValue
     350           0 : TALER_wallet_recoup_refresh_verify (
     351             :   const struct TALER_DenominationHashP *h_denom_pub,
     352             :   const union TALER_DenominationBlindingKeyP *coin_bks,
     353             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     354             :   const struct TALER_CoinSpendSignatureP *coin_sig)
     355             : {
     356           0 :   struct TALER_RecoupRequestPS pr = {
     357           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
     358           0 :     .purpose.size = htonl (sizeof (pr)),
     359             :     .h_denom_pub = *h_denom_pub,
     360             :     .coin_blind = *coin_bks
     361             :   };
     362             : 
     363           0 :   return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH,
     364             :                                      &pr,
     365             :                                      &coin_sig->eddsa_signature,
     366             :                                      &coin_pub->eddsa_pub);
     367             : }
     368             : 
     369             : 
     370             : void
     371           0 : TALER_wallet_recoup_refresh_sign (
     372             :   const struct TALER_DenominationHashP *h_denom_pub,
     373             :   const union TALER_DenominationBlindingKeyP *coin_bks,
     374             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     375             :   struct TALER_CoinSpendSignatureP *coin_sig)
     376             : {
     377           0 :   struct TALER_RecoupRequestPS pr = {
     378           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
     379           0 :     .purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS)),
     380             :     .h_denom_pub = *h_denom_pub,
     381             :     .coin_blind = *coin_bks
     382             :   };
     383             : 
     384           0 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     385             :                             &pr,
     386             :                             &coin_sig->eddsa_signature);
     387           0 : }
     388             : 
     389             : 
     390             : /**
     391             :  * @brief Message signed by a coin to indicate that the coin should be
     392             :  * melted.
     393             :  */
     394             : struct TALER_RefreshMeltCoinAffirmationPS
     395             : {
     396             :   /**
     397             :    * Purpose is #TALER_SIGNATURE_WALLET_COIN_MELT.
     398             :    * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
     399             :    */
     400             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     401             : 
     402             :   /**
     403             :    * Which melt commitment is made by the wallet.
     404             :    */
     405             :   struct TALER_RefreshCommitmentP rc GNUNET_PACKED;
     406             : 
     407             :   /**
     408             :    * Hash over the denomination public key used to sign the coin.
     409             :    */
     410             :   struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
     411             : 
     412             :   /**
     413             :    * If age commitment was provided during the withdrawal of the coin, this is
     414             :    * the hash of the age commitment vector.  It must be all zeroes if no age
     415             :    * commitment was provided.
     416             :    */
     417             :   struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
     418             : 
     419             :   /**
     420             :    * How much of the value of the coin should be melted?  This amount
     421             :    * includes the fees, so the final amount contributed to the melt is
     422             :    * this value minus the fee for melting the coin.  We include the
     423             :    * fee in what is being signed so that we can verify a reserve's
     424             :    * remaining total balance without needing to access the respective
     425             :    * denomination key information each time.
     426             :    */
     427             :   struct TALER_AmountNBO amount_with_fee;
     428             : 
     429             :   /**
     430             :    * Melting fee charged by the exchange.  This must match the Exchange's
     431             :    * denomination key's melting fee.  If the client puts in an invalid
     432             :    * melting fee (too high or too low) that does not match the Exchange's
     433             :    * denomination key, the melting operation is invalid and will be
     434             :    * rejected by the exchange.  The @e amount_with_fee minus the @e
     435             :    * melt_fee is the amount that will be credited to the melting
     436             :    * session.
     437             :    */
     438             :   struct TALER_AmountNBO melt_fee;
     439             : };
     440             : 
     441             : 
     442             : void
     443           0 : TALER_wallet_melt_sign (
     444             :   const struct TALER_Amount *amount_with_fee,
     445             :   const struct TALER_Amount *melt_fee,
     446             :   const struct TALER_RefreshCommitmentP *rc,
     447             :   const struct TALER_DenominationHashP *h_denom_pub,
     448             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
     449             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     450             :   struct TALER_CoinSpendSignatureP *coin_sig)
     451             : {
     452           0 :   struct TALER_RefreshMeltCoinAffirmationPS melt = {
     453           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
     454           0 :     .purpose.size = htonl (sizeof (melt)),
     455             :     .rc = *rc,
     456             :     .h_denom_pub = *h_denom_pub,
     457             :     .h_age_commitment = {{{0}}},
     458             :   };
     459             : 
     460           0 :   if (NULL != h_age_commitment)
     461           0 :     melt.h_age_commitment = *h_age_commitment;
     462             : 
     463             : 
     464           0 :   TALER_amount_hton (&melt.amount_with_fee,
     465             :                      amount_with_fee);
     466           0 :   TALER_amount_hton (&melt.melt_fee,
     467             :                      melt_fee);
     468           0 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     469             :                             &melt,
     470             :                             &coin_sig->eddsa_signature);
     471           0 : }
     472             : 
     473             : 
     474             : enum GNUNET_GenericReturnValue
     475           0 : TALER_wallet_melt_verify (
     476             :   const struct TALER_Amount *amount_with_fee,
     477             :   const struct TALER_Amount *melt_fee,
     478             :   const struct TALER_RefreshCommitmentP *rc,
     479             :   const struct TALER_DenominationHashP *h_denom_pub,
     480             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
     481             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     482             :   const struct TALER_CoinSpendSignatureP *coin_sig)
     483             : {
     484           0 :   struct TALER_RefreshMeltCoinAffirmationPS melt = {
     485           0 :     .purpose.size = htonl (sizeof (melt)),
     486           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
     487             :     .rc = *rc,
     488             :     .h_denom_pub = *h_denom_pub,
     489             :     .h_age_commitment = {{{0}}},
     490             :   };
     491             : 
     492           0 :   if (NULL != h_age_commitment)
     493           0 :     melt.h_age_commitment = *h_age_commitment;
     494             : 
     495           0 :   TALER_amount_hton (&melt.amount_with_fee,
     496             :                      amount_with_fee);
     497           0 :   TALER_amount_hton (&melt.melt_fee,
     498             :                      melt_fee);
     499           0 :   return GNUNET_CRYPTO_eddsa_verify (
     500             :     TALER_SIGNATURE_WALLET_COIN_MELT,
     501             :     &melt,
     502             :     &coin_sig->eddsa_signature,
     503             :     &coin_pub->eddsa_pub);
     504             : }
     505             : 
     506             : 
     507             : /**
     508             :  * @brief Format used for to generate the signature on a request to withdraw
     509             :  * coins from a reserve.
     510             :  */
     511             : struct TALER_WithdrawRequestPS
     512             : {
     513             : 
     514             :   /**
     515             :    * Purpose must be #TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW.
     516             :    * Used with an EdDSA signature of a `struct TALER_ReservePublicKeyP`.
     517             :    */
     518             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     519             : 
     520             :   /**
     521             :    * Value of the coin being exchanged (matching the denomination key)
     522             :    * plus the transaction fee.  We include this in what is being
     523             :    * signed so that we can verify a reserve's remaining total balance
     524             :    * without needing to access the respective denomination key
     525             :    * information each time.
     526             :    */
     527             :   struct TALER_AmountNBO amount_with_fee;
     528             : 
     529             :   /**
     530             :    * Hash of the denomination public key for the coin that is withdrawn.
     531             :    */
     532             :   struct TALER_DenominationHashP h_denomination_pub GNUNET_PACKED;
     533             : 
     534             :   /**
     535             :    * Hash of the (blinded) message to be signed by the Exchange.
     536             :    */
     537             :   struct TALER_BlindedCoinHashP h_coin_envelope GNUNET_PACKED;
     538             : };
     539             : 
     540             : 
     541             : void
     542           0 : TALER_wallet_withdraw_sign (
     543             :   const struct TALER_DenominationHashP *h_denom_pub,
     544             :   const struct TALER_Amount *amount_with_fee,
     545             :   const struct TALER_BlindedCoinHashP *bch,
     546             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     547             :   struct TALER_ReserveSignatureP *reserve_sig)
     548             : {
     549           0 :   struct TALER_WithdrawRequestPS req = {
     550           0 :     .purpose.size = htonl (sizeof (req)),
     551           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     552             :     .h_denomination_pub = *h_denom_pub,
     553             :     .h_coin_envelope = *bch
     554             :   };
     555             : 
     556           0 :   TALER_amount_hton (&req.amount_with_fee,
     557             :                      amount_with_fee);
     558           0 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
     559             :                             &req,
     560             :                             &reserve_sig->eddsa_signature);
     561           0 : }
     562             : 
     563             : 
     564             : enum GNUNET_GenericReturnValue
     565           0 : TALER_wallet_withdraw_verify (
     566             :   const struct TALER_DenominationHashP *h_denom_pub,
     567             :   const struct TALER_Amount *amount_with_fee,
     568             :   const struct TALER_BlindedCoinHashP *bch,
     569             :   const struct TALER_ReservePublicKeyP *reserve_pub,
     570             :   const struct TALER_ReserveSignatureP *reserve_sig)
     571             : {
     572           0 :   struct TALER_WithdrawRequestPS wsrd = {
     573           0 :     .purpose.size = htonl (sizeof (wsrd)),
     574           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
     575             :     .h_denomination_pub = *h_denom_pub,
     576             :     .h_coin_envelope = *bch
     577             :   };
     578             : 
     579           0 :   TALER_amount_hton (&wsrd.amount_with_fee,
     580             :                      amount_with_fee);
     581           0 :   return GNUNET_CRYPTO_eddsa_verify (
     582             :     TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW,
     583             :     &wsrd,
     584             :     &reserve_sig->eddsa_signature,
     585             :     &reserve_pub->eddsa_pub);
     586             : }
     587             : 
     588             : 
     589             : void
     590           0 : TALER_wallet_account_setup_sign (
     591             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     592             :   struct TALER_ReserveSignatureP *reserve_sig)
     593             : {
     594           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
     595           0 :     .size = htonl (sizeof (purpose)),
     596           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
     597             :   };
     598             : 
     599           0 :   GNUNET_assert (GNUNET_OK ==
     600             :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
     601             :                                             &purpose,
     602             :                                             &reserve_sig->eddsa_signature));
     603           0 : }
     604             : 
     605             : 
     606             : enum GNUNET_GenericReturnValue
     607           0 : TALER_wallet_account_setup_verify (
     608             :   const struct TALER_ReservePublicKeyP *reserve_pub,
     609             :   const struct TALER_ReserveSignatureP *reserve_sig)
     610             : {
     611           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
     612           0 :     .size = htonl (sizeof (purpose)),
     613           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
     614             :   };
     615             : 
     616           0 :   return GNUNET_CRYPTO_eddsa_verify_ (
     617             :     TALER_SIGNATURE_WALLET_ACCOUNT_SETUP,
     618             :     &purpose,
     619             :     &reserve_sig->eddsa_signature,
     620             :     &reserve_pub->eddsa_pub);
     621             : }
     622             : 
     623             : 
     624             : /**
     625             :  * Response by which a wallet requests a full
     626             :  * reserve history and indicates it is willing
     627             :  * to pay for it.
     628             :  */
     629             : struct TALER_ReserveHistoryRequestPS
     630             : {
     631             : 
     632             :   /**
     633             :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_HISTORY
     634             :    */
     635             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     636             : 
     637             :   /**
     638             :    * When did the wallet make the request.
     639             :    */
     640             :   struct GNUNET_TIME_TimestampNBO request_timestamp;
     641             : 
     642             :   /**
     643             :    * How much does the exchange charge for the history?
     644             :    */
     645             :   struct TALER_AmountNBO history_fee;
     646             : 
     647             : };
     648             : 
     649             : 
     650             : enum GNUNET_GenericReturnValue
     651           0 : TALER_wallet_reserve_history_verify (
     652             :   const struct GNUNET_TIME_Timestamp ts,
     653             :   const struct TALER_Amount *history_fee,
     654             :   const struct TALER_ReservePublicKeyP *reserve_pub,
     655             :   const struct TALER_ReserveSignatureP *reserve_sig)
     656             : {
     657           0 :   struct TALER_ReserveHistoryRequestPS rhr = {
     658           0 :     .purpose.size = htonl (sizeof (rhr)),
     659           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
     660           0 :     .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
     661             :   };
     662             : 
     663           0 :   TALER_amount_hton (&rhr.history_fee,
     664             :                      history_fee);
     665           0 :   return GNUNET_CRYPTO_eddsa_verify (
     666             :     TALER_SIGNATURE_WALLET_RESERVE_HISTORY,
     667             :     &rhr,
     668             :     &reserve_sig->eddsa_signature,
     669             :     &reserve_pub->eddsa_pub);
     670             : }
     671             : 
     672             : 
     673             : void
     674           0 : TALER_wallet_reserve_history_sign (
     675             :   const struct GNUNET_TIME_Timestamp ts,
     676             :   const struct TALER_Amount *history_fee,
     677             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     678             :   struct TALER_ReserveSignatureP *reserve_sig)
     679             : {
     680           0 :   struct TALER_ReserveHistoryRequestPS rhr = {
     681           0 :     .purpose.size = htonl (sizeof (rhr)),
     682           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
     683           0 :     .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
     684             :   };
     685             : 
     686           0 :   TALER_amount_hton (&rhr.history_fee,
     687             :                      history_fee);
     688           0 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
     689             :                             &rhr,
     690             :                             &reserve_sig->eddsa_signature);
     691           0 : }
     692             : 
     693             : 
     694             : /**
     695             :  * Response by which a wallet requests an account status.
     696             :  */
     697             : struct TALER_ReserveStatusRequestPS
     698             : {
     699             : 
     700             :   /**
     701             :    * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_STATUS
     702             :    */
     703             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     704             : 
     705             :   /**
     706             :    * When did the wallet make the request.
     707             :    */
     708             :   struct GNUNET_TIME_TimestampNBO request_timestamp;
     709             : 
     710             : };
     711             : 
     712             : 
     713             : enum GNUNET_GenericReturnValue
     714           0 : TALER_wallet_reserve_status_verify (
     715             :   const struct GNUNET_TIME_Timestamp ts,
     716             :   const struct TALER_ReservePublicKeyP *reserve_pub,
     717             :   const struct TALER_ReserveSignatureP *reserve_sig)
     718             : {
     719           0 :   struct TALER_ReserveStatusRequestPS rsr = {
     720           0 :     .purpose.size = htonl (sizeof (rsr)),
     721           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_STATUS),
     722           0 :     .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
     723             :   };
     724             : 
     725           0 :   return GNUNET_CRYPTO_eddsa_verify (
     726             :     TALER_SIGNATURE_WALLET_RESERVE_STATUS,
     727             :     &rsr,
     728             :     &reserve_sig->eddsa_signature,
     729             :     &reserve_pub->eddsa_pub);
     730             : }
     731             : 
     732             : 
     733             : void
     734           0 : TALER_wallet_reserve_status_sign (
     735             :   const struct GNUNET_TIME_Timestamp ts,
     736             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
     737             :   struct TALER_ReserveSignatureP *reserve_sig)
     738             : {
     739           0 :   struct TALER_ReserveStatusRequestPS rsr = {
     740           0 :     .purpose.size = htonl (sizeof (rsr)),
     741           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_STATUS),
     742           0 :     .request_timestamp = GNUNET_TIME_timestamp_hton (ts)
     743             :   };
     744             : 
     745           0 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
     746             :                             &rsr,
     747             :                             &reserve_sig->eddsa_signature);
     748           0 : }
     749             : 
     750             : 
     751             : /**
     752             :  * Message signed to create a purse (without reserve).
     753             :  */
     754             : struct TALER_PurseCreatePS
     755             : {
     756             : 
     757             :   /**
     758             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_CREATE
     759             :    */
     760             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     761             : 
     762             :   /**
     763             :    * Time when the purse will expire if still unmerged or unpaid.
     764             :    */
     765             :   struct GNUNET_TIME_TimestampNBO purse_expiration;
     766             : 
     767             :   /**
     768             :    * Total amount (with fees) to be put into the purse.
     769             :    */
     770             :   struct TALER_AmountNBO purse_amount;
     771             : 
     772             :   /**
     773             :    * Contract this purse pays for.
     774             :    */
     775             :   struct TALER_PrivateContractHashP h_contract_terms;
     776             : 
     777             :   /**
     778             :    * Public key identifying the merge capability.
     779             :    */
     780             :   struct TALER_PurseMergePublicKeyP merge_pub;
     781             : 
     782             :   /**
     783             :    * Minimum age required for payments into this purse.
     784             :    */
     785             :   uint32_t min_age GNUNET_PACKED;
     786             : 
     787             : };
     788             : 
     789             : 
     790             : void
     791           0 : TALER_wallet_purse_create_sign (
     792             :   struct GNUNET_TIME_Timestamp purse_expiration,
     793             :   struct TALER_PrivateContractHashP *h_contract_terms,
     794             :   const struct TALER_PurseMergePublicKeyP *merge_pub,
     795             :   uint32_t min_age,
     796             :   const struct TALER_Amount *amount,
     797             :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
     798             :   struct TALER_PurseContractSignatureP *purse_sig)
     799             : {
     800           0 :   struct TALER_PurseCreatePS pm = {
     801           0 :     .purpose.size = htonl (sizeof (pm)),
     802           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
     803           0 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
     804             :     .h_contract_terms = *h_contract_terms,
     805             :     .merge_pub = *merge_pub,
     806           0 :     .min_age = htonl (min_age)
     807             :   };
     808             : 
     809           0 :   TALER_amount_hton (&pm.purse_amount,
     810             :                      amount);
     811           0 :   GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
     812             :                             &pm,
     813             :                             &purse_sig->eddsa_signature);
     814           0 : }
     815             : 
     816             : 
     817             : enum GNUNET_GenericReturnValue
     818           0 : TALER_wallet_purse_create_verify (
     819             :   struct GNUNET_TIME_Timestamp purse_expiration,
     820             :   struct TALER_PrivateContractHashP *h_contract_terms,
     821             :   const struct TALER_PurseMergePublicKeyP *merge_pub,
     822             :   uint32_t min_age,
     823             :   const struct TALER_Amount *amount,
     824             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
     825             :   const struct TALER_PurseContractSignatureP *purse_sig)
     826             : {
     827           0 :   struct TALER_PurseCreatePS pm = {
     828           0 :     .purpose.size = htonl (sizeof (pm)),
     829           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
     830           0 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
     831             :     .h_contract_terms = *h_contract_terms,
     832             :     .merge_pub = *merge_pub,
     833           0 :     .min_age = htonl (min_age)
     834             :   };
     835             : 
     836           0 :   TALER_amount_hton (&pm.purse_amount,
     837             :                      amount);
     838           0 :   return GNUNET_CRYPTO_eddsa_verify (
     839             :     TALER_SIGNATURE_WALLET_PURSE_CREATE,
     840             :     &pm,
     841             :     &purse_sig->eddsa_signature,
     842             :     &purse_pub->eddsa_pub);
     843             : }
     844             : 
     845             : 
     846             : void
     847           0 : TALER_wallet_purse_status_sign (
     848             :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
     849             :   struct TALER_PurseContractSignatureP *purse_sig)
     850             : {
     851           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
     852           0 :     .size = htonl (sizeof (purpose)),
     853           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
     854             :   };
     855             : 
     856           0 :   GNUNET_assert (GNUNET_OK ==
     857             :                  GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
     858             :                                             &purpose,
     859             :                                             &purse_sig->eddsa_signature));
     860           0 : }
     861             : 
     862             : 
     863             : enum GNUNET_GenericReturnValue
     864           0 : TALER_wallet_purse_status_verify (
     865             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
     866             :   const struct TALER_PurseContractSignatureP *purse_sig)
     867             : {
     868           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
     869           0 :     .size = htonl (sizeof (purpose)),
     870           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
     871             :   };
     872             : 
     873           0 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_STATUS,
     874             :                                       &purpose,
     875             :                                       &purse_sig->eddsa_signature,
     876             :                                       &purse_pub->eddsa_pub);
     877             : }
     878             : 
     879             : 
     880             : /**
     881             :  * Message signed to deposit a coin into a purse.
     882             :  */
     883             : struct TALER_PurseDepositPS
     884             : {
     885             : 
     886             :   /**
     887             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_DEPOSIT
     888             :    */
     889             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     890             : 
     891             :   /**
     892             :    * Amount (with deposit fee) to be deposited into the purse.
     893             :    */
     894             :   struct TALER_AmountNBO coin_amount;
     895             : 
     896             :   /**
     897             :    * Hash over the denomination public key used to sign the coin.
     898             :    */
     899             :   struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
     900             : 
     901             :   /**
     902             :    * Hash over the age commitment that went into the coin. Maybe all zero, if
     903             :    * age commitment isn't applicable to the denomination.
     904             :    */
     905             :   struct TALER_AgeCommitmentHash h_age_commitment GNUNET_PACKED;
     906             : 
     907             :   /**
     908             :    * Purse to deposit funds into.
     909             :    */
     910             :   struct TALER_PurseContractPublicKeyP purse_pub;
     911             : 
     912             :   /**
     913             :    * Hash of the base URL of the exchange hosting the
     914             :    * @e purse_pub.
     915             :    */
     916             :   struct GNUNET_HashCode h_exchange_base_url GNUNET_PACKED;
     917             : };
     918             : 
     919             : 
     920             : void
     921           0 : TALER_wallet_purse_deposit_sign (
     922             :   const char *exchange_base_url,
     923             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
     924             :   const struct TALER_Amount *amount,
     925             :   const struct TALER_DenominationHashP *h_denom_pub,
     926             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
     927             :   const struct TALER_CoinSpendPrivateKeyP *coin_priv,
     928             :   struct TALER_CoinSpendSignatureP *coin_sig)
     929             : {
     930           0 :   struct TALER_PurseDepositPS pm = {
     931           0 :     .purpose.size = htonl (sizeof (pm)),
     932           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
     933             :     .purse_pub = *purse_pub,
     934             :     .h_denom_pub = *h_denom_pub,
     935             :     .h_age_commitment = *h_age_commitment
     936             :   };
     937             : 
     938           0 :   GNUNET_CRYPTO_hash (exchange_base_url,
     939           0 :                       strlen (exchange_base_url) + 1,
     940             :                       &pm.h_exchange_base_url);
     941           0 :   TALER_amount_hton (&pm.coin_amount,
     942             :                      amount);
     943           0 :   GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
     944             :                             &pm,
     945             :                             &coin_sig->eddsa_signature);
     946           0 : }
     947             : 
     948             : 
     949             : enum GNUNET_GenericReturnValue
     950           0 : TALER_wallet_purse_deposit_verify (
     951             :   const char *exchange_base_url,
     952             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
     953             :   const struct TALER_Amount *amount,
     954             :   const struct TALER_DenominationHashP *h_denom_pub,
     955             :   const struct TALER_AgeCommitmentHash *h_age_commitment,
     956             :   const struct TALER_CoinSpendPublicKeyP *coin_pub,
     957             :   const struct TALER_CoinSpendSignatureP *coin_sig)
     958             : {
     959           0 :   struct TALER_PurseDepositPS pm = {
     960           0 :     .purpose.size = htonl (sizeof (pm)),
     961           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
     962             :     .purse_pub = *purse_pub,
     963             :     .h_denom_pub = *h_denom_pub,
     964             :     .h_age_commitment = *h_age_commitment
     965             :   };
     966             : 
     967           0 :   GNUNET_CRYPTO_hash (exchange_base_url,
     968           0 :                       strlen (exchange_base_url) + 1,
     969             :                       &pm.h_exchange_base_url);
     970           0 :   TALER_amount_hton (&pm.coin_amount,
     971             :                      amount);
     972           0 :   return GNUNET_CRYPTO_eddsa_verify (
     973             :     TALER_SIGNATURE_WALLET_PURSE_DEPOSIT,
     974             :     &pm,
     975             :     &coin_sig->eddsa_signature,
     976             :     &coin_pub->eddsa_pub);
     977             : }
     978             : 
     979             : 
     980             : /**
     981             :  * Message signed to merge a purse into a reserve.
     982             :  */
     983             : struct TALER_PurseMergePS
     984             : {
     985             : 
     986             :   /**
     987             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_MERGE
     988             :    */
     989             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
     990             : 
     991             :   /**
     992             :    * Time when the purse is merged into the reserve.
     993             :    */
     994             :   struct GNUNET_TIME_TimestampNBO merge_timestamp;
     995             : 
     996             :   /**
     997             :    * Which purse is being merged?
     998             :    */
     999             :   struct TALER_PurseContractPublicKeyP purse_pub;
    1000             : 
    1001             :   /**
    1002             :    * Which reserve should the purse be merged with.
    1003             :    * Hash of the reserve's payto:// URI.
    1004             :    */
    1005             :   struct TALER_PaytoHashP h_payto;
    1006             : 
    1007             : };
    1008             : 
    1009             : 
    1010             : void
    1011           0 : TALER_wallet_purse_merge_sign (
    1012             :   const char *reserve_uri,
    1013             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1014             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1015             :   const struct TALER_PurseMergePrivateKeyP *merge_priv,
    1016             :   struct TALER_PurseMergeSignatureP *merge_sig)
    1017             : {
    1018           0 :   struct TALER_PurseMergePS pm = {
    1019           0 :     .purpose.size = htonl (sizeof (pm)),
    1020           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
    1021           0 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1022             :     .purse_pub = *purse_pub
    1023             :   };
    1024             : 
    1025           0 :   GNUNET_assert (0 ==
    1026             :                  strncasecmp (reserve_uri,
    1027             :                               "payto://taler-reserve",
    1028             :                               strlen ("payto://taler-reserve")));
    1029           0 :   TALER_payto_hash (reserve_uri,
    1030             :                     &pm.h_payto);
    1031           0 :   GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv,
    1032             :                             &pm,
    1033             :                             &merge_sig->eddsa_signature);
    1034           0 : }
    1035             : 
    1036             : 
    1037             : enum GNUNET_GenericReturnValue
    1038           0 : TALER_wallet_purse_merge_verify (
    1039             :   const char *reserve_uri,
    1040             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1041             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1042             :   const struct TALER_PurseMergePublicKeyP *merge_pub,
    1043             :   const struct TALER_PurseMergeSignatureP *merge_sig)
    1044             : {
    1045           0 :   struct TALER_PurseMergePS pm = {
    1046           0 :     .purpose.size = htonl (sizeof (pm)),
    1047           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
    1048           0 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1049             :     .purse_pub = *purse_pub
    1050             :   };
    1051             : 
    1052           0 :   if (0 !=
    1053           0 :       strncasecmp (reserve_uri,
    1054             :                    "payto://taler-reserve",
    1055             :                    strlen ("payto://taler-reserve")))
    1056             :   {
    1057           0 :     GNUNET_break (0);
    1058           0 :     return GNUNET_NO;
    1059             :   }
    1060           0 :   TALER_payto_hash (reserve_uri,
    1061             :                     &pm.h_payto);
    1062           0 :   return GNUNET_CRYPTO_eddsa_verify (
    1063             :     TALER_SIGNATURE_WALLET_PURSE_MERGE,
    1064             :     &pm,
    1065             :     &merge_sig->eddsa_signature,
    1066             :     &merge_pub->eddsa_pub);
    1067             : }
    1068             : 
    1069             : 
    1070             : /**
    1071             :  * Message signed by account to merge a purse into a reserve.
    1072             :  */
    1073             : struct TALER_AccountMergePS
    1074             : {
    1075             : 
    1076             :   /**
    1077             :    * Purpose is #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE
    1078             :    */
    1079             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1080             : 
    1081             :   /**
    1082             :    * Time when the purse will expire if still unmerged or unpaid.
    1083             :    */
    1084             :   struct GNUNET_TIME_TimestampNBO purse_expiration;
    1085             : 
    1086             :   /**
    1087             :    * Total amount (with fees) to be put into the purse.
    1088             :    */
    1089             :   struct TALER_AmountNBO purse_amount;
    1090             : 
    1091             :   /**
    1092             :    * Purse creation fee to be paid by the reserve for
    1093             :    * this operation.
    1094             :    */
    1095             :   struct TALER_AmountNBO purse_fee;
    1096             : 
    1097             :   /**
    1098             :    * Contract this purse pays for.
    1099             :    */
    1100             :   struct TALER_PrivateContractHashP h_contract_terms;
    1101             : 
    1102             :   /**
    1103             :    * Purse to merge.
    1104             :    */
    1105             :   struct TALER_PurseContractPublicKeyP purse_pub;
    1106             : 
    1107             :   /**
    1108             :    * Time when the purse is merged into the reserve.
    1109             :    */
    1110             :   struct GNUNET_TIME_TimestampNBO merge_timestamp;
    1111             : 
    1112             :   /**
    1113             :    * Minimum age required for payments into this purse,
    1114             :    * in NBO.
    1115             :    */
    1116             :   uint32_t min_age GNUNET_PACKED;
    1117             : 
    1118             :   /**
    1119             :    * Flags for the operation, in NBO. See
    1120             :    * `enum TALER_WalletAccountMergeFlags`.
    1121             :    */
    1122             :   uint32_t flags GNUNET_PACKED;
    1123             : };
    1124             : 
    1125             : 
    1126             : void
    1127           0 : TALER_wallet_account_merge_sign (
    1128             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1129             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1130             :   struct GNUNET_TIME_Timestamp purse_expiration,
    1131             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1132             :   const struct TALER_Amount *amount,
    1133             :   const struct TALER_Amount *purse_fee,
    1134             :   uint32_t min_age,
    1135             :   enum TALER_WalletAccountMergeFlags flags,
    1136             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1137             :   struct TALER_ReserveSignatureP *reserve_sig)
    1138             : {
    1139           0 :   struct TALER_AccountMergePS pm = {
    1140           0 :     .purpose.size = htonl (sizeof (pm)),
    1141           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
    1142           0 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1143             :     .purse_pub = *purse_pub,
    1144           0 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1145             :     .h_contract_terms = *h_contract_terms,
    1146           0 :     .min_age = htonl (min_age),
    1147           0 :     .flags = htonl ((uint32_t) flags)
    1148             :   };
    1149             : 
    1150           0 :   TALER_amount_hton (&pm.purse_amount,
    1151             :                      amount);
    1152           0 :   TALER_amount_hton (&pm.purse_fee,
    1153             :                      purse_fee);
    1154           0 :   GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
    1155             :                             &pm,
    1156             :                             &reserve_sig->eddsa_signature);
    1157           0 : }
    1158             : 
    1159             : 
    1160             : enum GNUNET_GenericReturnValue
    1161           0 : TALER_wallet_account_merge_verify (
    1162             :   struct GNUNET_TIME_Timestamp merge_timestamp,
    1163             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1164             :   struct GNUNET_TIME_Timestamp purse_expiration,
    1165             :   const struct TALER_PrivateContractHashP *h_contract_terms,
    1166             :   const struct TALER_Amount *amount,
    1167             :   const struct TALER_Amount *purse_fee,
    1168             :   uint32_t min_age,
    1169             :   enum TALER_WalletAccountMergeFlags flags,
    1170             :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1171             :   const struct TALER_ReserveSignatureP *reserve_sig)
    1172             : {
    1173           0 :   struct TALER_AccountMergePS pm = {
    1174           0 :     .purpose.size = htonl (sizeof (pm)),
    1175           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
    1176           0 :     .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
    1177             :     .purse_pub = *purse_pub,
    1178           0 :     .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
    1179             :     .h_contract_terms = *h_contract_terms,
    1180           0 :     .min_age = htonl (min_age),
    1181           0 :     .flags = htonl ((uint32_t) flags)
    1182             :   };
    1183             : 
    1184           0 :   TALER_amount_hton (&pm.purse_amount,
    1185             :                      amount);
    1186           0 :   TALER_amount_hton (&pm.purse_fee,
    1187             :                      purse_fee);
    1188           0 :   return GNUNET_CRYPTO_eddsa_verify (
    1189             :     TALER_SIGNATURE_WALLET_ACCOUNT_MERGE,
    1190             :     &pm,
    1191             :     &reserve_sig->eddsa_signature,
    1192             :     &reserve_pub->eddsa_pub);
    1193             : }
    1194             : 
    1195             : 
    1196             : void
    1197           0 : TALER_wallet_account_close_sign (
    1198             :   const struct TALER_ReservePrivateKeyP *reserve_priv,
    1199             :   struct TALER_ReserveSignatureP *reserve_sig)
    1200             : {
    1201           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
    1202           0 :     .size = htonl (sizeof (purpose)),
    1203           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE)
    1204             :   };
    1205             : 
    1206           0 :   GNUNET_assert (GNUNET_OK ==
    1207             :                  GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
    1208             :                                             &purpose,
    1209             :                                             &reserve_sig->eddsa_signature));
    1210           0 : }
    1211             : 
    1212             : 
    1213             : enum GNUNET_GenericReturnValue
    1214           0 : TALER_wallet_account_close_verify (
    1215             :   const struct TALER_ReservePublicKeyP *reserve_pub,
    1216             :   const struct TALER_ReserveSignatureP *reserve_sig)
    1217             : {
    1218           0 :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose = {
    1219           0 :     .size = htonl (sizeof (purpose)),
    1220           0 :     .purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE)
    1221             :   };
    1222             : 
    1223           0 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE,
    1224             :                                       &purpose,
    1225             :                                       &reserve_sig->eddsa_signature,
    1226             :                                       &reserve_pub->eddsa_pub);
    1227             : }
    1228             : 
    1229             : 
    1230             : /**
    1231             :  * Message signed by purse to associate an encrypted contract.
    1232             :  */
    1233             : struct TALER_PurseContractPS
    1234             : {
    1235             : 
    1236             :   /**
    1237             :    * Purpose is #TALER_SIGNATURE_WALLET_PURSE_ECONTRACT
    1238             :    */
    1239             :   struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
    1240             : 
    1241             :   /**
    1242             :    * Hash over the encrypted contract.
    1243             :    */
    1244             :   struct GNUNET_HashCode h_econtract;
    1245             : 
    1246             :   /**
    1247             :    * Public key to decrypt the contract.
    1248             :    */
    1249             :   struct TALER_ContractDiffiePublicP contract_pub;
    1250             : };
    1251             : 
    1252             : 
    1253             : void
    1254           0 : TALER_wallet_econtract_upload_sign (
    1255             :   const void *econtract,
    1256             :   size_t econtract_size,
    1257             :   const struct TALER_ContractDiffiePublicP *contract_pub,
    1258             :   const struct TALER_PurseContractPrivateKeyP *purse_priv,
    1259             :   struct TALER_PurseContractSignatureP *purse_sig)
    1260             : {
    1261           0 :   struct TALER_PurseContractPS pc = {
    1262           0 :     .purpose.size = htonl (sizeof (pc)),
    1263           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
    1264             :     .contract_pub = *contract_pub
    1265             :   };
    1266             : 
    1267           0 :   GNUNET_CRYPTO_hash (econtract,
    1268             :                       econtract_size,
    1269             :                       &pc.h_econtract);
    1270           0 :   GNUNET_assert (GNUNET_OK ==
    1271             :                  GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
    1272             :                                             &pc.purpose,
    1273             :                                             &purse_sig->eddsa_signature));
    1274           0 : }
    1275             : 
    1276             : 
    1277             : enum GNUNET_GenericReturnValue
    1278           0 : TALER_wallet_econtract_upload_verify2 (
    1279             :   const struct GNUNET_HashCode *h_econtract,
    1280             :   const struct TALER_ContractDiffiePublicP *contract_pub,
    1281             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1282             :   const struct TALER_PurseContractSignatureP *purse_sig)
    1283             : {
    1284           0 :   struct TALER_PurseContractPS pc = {
    1285           0 :     .purpose.size = htonl (sizeof (pc)),
    1286           0 :     .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
    1287             :     .contract_pub = *contract_pub,
    1288             :     .h_econtract = *h_econtract
    1289             :   };
    1290             : 
    1291           0 :   return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT,
    1292             :                                       &pc.purpose,
    1293             :                                       &purse_sig->eddsa_signature,
    1294             :                                       &purse_pub->eddsa_pub);
    1295             : }
    1296             : 
    1297             : 
    1298             : enum GNUNET_GenericReturnValue
    1299           0 : TALER_wallet_econtract_upload_verify (
    1300             :   const void *econtract,
    1301             :   size_t econtract_size,
    1302             :   const struct TALER_ContractDiffiePublicP *contract_pub,
    1303             :   const struct TALER_PurseContractPublicKeyP *purse_pub,
    1304             :   const struct TALER_PurseContractSignatureP *purse_sig)
    1305             : {
    1306             :   struct GNUNET_HashCode h_econtract;
    1307             : 
    1308           0 :   GNUNET_CRYPTO_hash (econtract,
    1309             :                       econtract_size,
    1310             :                       &h_econtract);
    1311           0 :   return TALER_wallet_econtract_upload_verify2 (&h_econtract,
    1312             :                                                 contract_pub,
    1313             :                                                 purse_pub,
    1314             :                                                 purse_sig);
    1315             : }
    1316             : 
    1317             : 
    1318             : /* end of wallet_signatures.c */

Generated by: LCOV version 1.14