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