wallet_signatures.c (65015B)
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 GNUNET_NETWORK_STRUCT_END 1759 1760 1761 // FIXME-#11318: add h_age_commitment, h_denom_pub to have proof! 1762 void 1763 TALER_wallet_reserve_open_deposit_sign ( 1764 const struct TALER_Amount *coin_contribution, 1765 const struct TALER_ReserveSignatureP *reserve_sig, 1766 const struct TALER_CoinSpendPrivateKeyP *coin_priv, 1767 struct TALER_CoinSpendSignatureP *coin_sig) 1768 { 1769 struct TALER_ReserveOpenDepositPS rod = { 1770 .purpose.size = htonl (sizeof (rod)), 1771 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT), 1772 .reserve_sig = *reserve_sig 1773 }; 1774 1775 TALER_amount_hton (&rod.coin_contribution, 1776 coin_contribution); 1777 GNUNET_assert (GNUNET_OK == 1778 GNUNET_CRYPTO_eddsa_sign_ (&coin_priv->eddsa_priv, 1779 &rod.purpose, 1780 &coin_sig->eddsa_signature)); 1781 } 1782 1783 1784 enum GNUNET_GenericReturnValue 1785 TALER_wallet_reserve_open_deposit_verify ( 1786 const struct TALER_Amount *coin_contribution, 1787 const struct TALER_ReserveSignatureP *reserve_sig, 1788 const struct TALER_CoinSpendPublicKeyP *coin_pub, 1789 const struct TALER_CoinSpendSignatureP *coin_sig) 1790 { 1791 struct TALER_ReserveOpenDepositPS rod = { 1792 .purpose.size = htonl (sizeof (rod)), 1793 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT), 1794 .reserve_sig = *reserve_sig 1795 }; 1796 1797 TALER_amount_hton (&rod.coin_contribution, 1798 coin_contribution); 1799 return GNUNET_CRYPTO_eddsa_verify_ ( 1800 TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT, 1801 &rod.purpose, 1802 &coin_sig->eddsa_signature, 1803 &coin_pub->eddsa_pub); 1804 } 1805 1806 1807 GNUNET_NETWORK_STRUCT_BEGIN 1808 1809 /** 1810 * Message signed by reserve key. 1811 */ 1812 struct TALER_ReserveClosePS 1813 { 1814 1815 /** 1816 * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_CLOSE 1817 */ 1818 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1819 1820 /** 1821 * When was the request created. 1822 */ 1823 struct GNUNET_TIME_TimestampNBO request_timestamp; 1824 1825 /** 1826 * Hash of the payto://-URI of the target account 1827 * for the closure, or all zeros for the reserve 1828 * origin account. 1829 */ 1830 struct TALER_FullPaytoHashP target_account_h_payto; 1831 1832 }; 1833 1834 GNUNET_NETWORK_STRUCT_END 1835 1836 1837 void 1838 TALER_wallet_reserve_close_sign ( 1839 struct GNUNET_TIME_Timestamp request_timestamp, 1840 const struct TALER_FullPaytoHashP *h_payto, 1841 const struct TALER_ReservePrivateKeyP *reserve_priv, 1842 struct TALER_ReserveSignatureP *reserve_sig) 1843 { 1844 struct TALER_ReserveClosePS rcp = { 1845 .purpose.size = htonl (sizeof (rcp)), 1846 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE), 1847 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp) 1848 }; 1849 1850 if (NULL != h_payto) 1851 rcp.target_account_h_payto = *h_payto; 1852 GNUNET_assert (GNUNET_OK == 1853 GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv, 1854 &rcp.purpose, 1855 &reserve_sig->eddsa_signature)); 1856 } 1857 1858 1859 enum GNUNET_GenericReturnValue 1860 TALER_wallet_reserve_close_verify ( 1861 struct GNUNET_TIME_Timestamp request_timestamp, 1862 const struct TALER_FullPaytoHashP *h_payto, 1863 const struct TALER_ReservePublicKeyP *reserve_pub, 1864 const struct TALER_ReserveSignatureP *reserve_sig) 1865 { 1866 struct TALER_ReserveClosePS rcp = { 1867 .purpose.size = htonl (sizeof (rcp)), 1868 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE), 1869 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp) 1870 }; 1871 1872 if (NULL != h_payto) 1873 rcp.target_account_h_payto = *h_payto; 1874 return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE, 1875 &rcp.purpose, 1876 &reserve_sig->eddsa_signature, 1877 &reserve_pub->eddsa_pub); 1878 } 1879 1880 1881 GNUNET_NETWORK_STRUCT_BEGIN 1882 1883 /** 1884 * Message signed by reserve private key. 1885 */ 1886 struct TALER_ReserveAttestRequestPS 1887 { 1888 1889 /** 1890 * Purpose is #TALER_SIGNATURE_WALLET_ATTEST_REQUEST 1891 */ 1892 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1893 1894 /** 1895 * When was the request created. 1896 */ 1897 struct GNUNET_TIME_TimestampNBO request_timestamp; 1898 1899 /** 1900 * Hash over the JSON array of requested attributes. 1901 */ 1902 struct GNUNET_HashCode h_details; 1903 1904 }; 1905 1906 GNUNET_NETWORK_STRUCT_END 1907 1908 1909 void 1910 TALER_wallet_reserve_attest_request_sign ( 1911 struct GNUNET_TIME_Timestamp request_timestamp, 1912 const json_t *details, 1913 const struct TALER_ReservePrivateKeyP *reserve_priv, 1914 struct TALER_ReserveSignatureP *reserve_sig) 1915 { 1916 struct TALER_ReserveAttestRequestPS rcp = { 1917 .purpose.size = htonl (sizeof (rcp)), 1918 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS), 1919 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp) 1920 }; 1921 1922 TALER_json_hash (details, 1923 &rcp.h_details); 1924 GNUNET_assert (GNUNET_OK == 1925 GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv, 1926 &rcp.purpose, 1927 &reserve_sig->eddsa_signature)); 1928 } 1929 1930 1931 enum GNUNET_GenericReturnValue 1932 TALER_wallet_reserve_attest_request_verify ( 1933 struct GNUNET_TIME_Timestamp request_timestamp, 1934 const json_t *details, 1935 const struct TALER_ReservePublicKeyP *reserve_pub, 1936 const struct TALER_ReserveSignatureP *reserve_sig) 1937 { 1938 struct TALER_ReserveAttestRequestPS rcp = { 1939 .purpose.size = htonl (sizeof (rcp)), 1940 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS), 1941 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp) 1942 }; 1943 1944 TALER_json_hash (details, 1945 &rcp.h_details); 1946 return GNUNET_CRYPTO_eddsa_verify_ ( 1947 TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS, 1948 &rcp.purpose, 1949 &reserve_sig->eddsa_signature, 1950 &reserve_pub->eddsa_pub); 1951 } 1952 1953 1954 GNUNET_NETWORK_STRUCT_BEGIN 1955 1956 /** 1957 * Message signed by purse to associate an encrypted contract. 1958 */ 1959 struct TALER_PurseContractPS 1960 { 1961 1962 /** 1963 * Purpose is #TALER_SIGNATURE_WALLET_PURSE_ECONTRACT 1964 */ 1965 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1966 1967 /** 1968 * Hash over the encrypted contract. 1969 */ 1970 struct GNUNET_HashCode h_econtract; 1971 1972 /** 1973 * Public key to decrypt the contract. 1974 */ 1975 struct TALER_ContractDiffiePublicP contract_pub; 1976 }; 1977 1978 GNUNET_NETWORK_STRUCT_END 1979 1980 void 1981 TALER_wallet_econtract_upload_sign ( 1982 const void *econtract, 1983 size_t econtract_size, 1984 const struct TALER_ContractDiffiePublicP *contract_pub, 1985 const struct TALER_PurseContractPrivateKeyP *purse_priv, 1986 struct TALER_PurseContractSignatureP *purse_sig) 1987 { 1988 struct TALER_PurseContractPS pc = { 1989 .purpose.size = htonl (sizeof (pc)), 1990 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT), 1991 .contract_pub = *contract_pub 1992 }; 1993 1994 GNUNET_CRYPTO_hash (econtract, 1995 econtract_size, 1996 &pc.h_econtract); 1997 GNUNET_assert (GNUNET_OK == 1998 GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv, 1999 &pc.purpose, 2000 &purse_sig->eddsa_signature)); 2001 } 2002 2003 2004 enum GNUNET_GenericReturnValue 2005 TALER_wallet_econtract_upload_verify2 ( 2006 const struct GNUNET_HashCode *h_econtract, 2007 const struct TALER_ContractDiffiePublicP *contract_pub, 2008 const struct TALER_PurseContractPublicKeyP *purse_pub, 2009 const struct TALER_PurseContractSignatureP *purse_sig) 2010 { 2011 struct TALER_PurseContractPS pc = { 2012 .purpose.size = htonl (sizeof (pc)), 2013 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT), 2014 .contract_pub = *contract_pub, 2015 .h_econtract = *h_econtract 2016 }; 2017 2018 return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT, 2019 &pc.purpose, 2020 &purse_sig->eddsa_signature, 2021 &purse_pub->eddsa_pub); 2022 } 2023 2024 2025 enum GNUNET_GenericReturnValue 2026 TALER_wallet_econtract_upload_verify ( 2027 const void *econtract, 2028 size_t econtract_size, 2029 const struct TALER_ContractDiffiePublicP *contract_pub, 2030 const struct TALER_PurseContractPublicKeyP *purse_pub, 2031 const struct TALER_PurseContractSignatureP *purse_sig) 2032 { 2033 struct GNUNET_HashCode h_econtract; 2034 2035 GNUNET_CRYPTO_hash (econtract, 2036 econtract_size, 2037 &h_econtract); 2038 return TALER_wallet_econtract_upload_verify2 (&h_econtract, 2039 contract_pub, 2040 purse_pub, 2041 purse_sig); 2042 } 2043 2044 2045 GNUNET_NETWORK_STRUCT_BEGIN 2046 2047 /** 2048 * Message signed by wallet to confirm usage of a token for a transaction. 2049 */ 2050 struct TALER_TokenUseRequestPS 2051 { 2052 2053 /** 2054 * Purpose is #TALER_SIGNATURE_WALLET_TOKEN_USE 2055 */ 2056 struct GNUNET_CRYPTO_SignaturePurpose purpose; 2057 2058 /** 2059 * Hash over the contract for which this token is used. 2060 */ 2061 struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; 2062 2063 /** 2064 * Hash over a JSON containing data provided by the 2065 * wallet to complete the contract upon payment. 2066 */ 2067 struct GNUNET_HashCode wallet_data_hash; 2068 2069 }; 2070 2071 GNUNET_NETWORK_STRUCT_END 2072 2073 2074 void 2075 TALER_wallet_token_use_sign ( 2076 const struct TALER_PrivateContractHashP *h_contract_terms, 2077 const struct GNUNET_HashCode *wallet_data_hash, 2078 const struct TALER_TokenUsePrivateKeyP *token_use_priv, 2079 struct TALER_TokenUseSignatureP *token_sig) 2080 { 2081 struct TALER_TokenUseRequestPS tur = { 2082 .purpose.size = htonl (sizeof (tur)), 2083 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE), 2084 .h_contract_terms = *h_contract_terms, 2085 .wallet_data_hash = *wallet_data_hash 2086 }; 2087 2088 GNUNET_CRYPTO_eddsa_sign (&token_use_priv->private_key, 2089 &tur, 2090 &token_sig->signature); 2091 } 2092 2093 2094 enum GNUNET_GenericReturnValue 2095 TALER_wallet_token_use_verify ( 2096 const struct TALER_PrivateContractHashP *h_contract_terms, 2097 const struct GNUNET_HashCode *wallet_data_hash, 2098 const struct TALER_TokenUsePublicKeyP *token_use_pub, 2099 const struct TALER_TokenUseSignatureP *token_sig) 2100 { 2101 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 return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_TOKEN_USE, 2109 &tur, 2110 &token_sig->signature, 2111 &token_use_pub->public_key); 2112 } 2113 2114 2115 GNUNET_NETWORK_STRUCT_BEGIN 2116 2117 /** 2118 * Message signed by reserve key. 2119 */ 2120 struct TALER_OrderUnclaimPS 2121 { 2122 2123 /** 2124 * Purpose is #TALER_SIGNATURE_WALLET_ORDER_UNCLAIM 2125 */ 2126 struct GNUNET_CRYPTO_SignaturePurpose purpose; 2127 2128 /** 2129 * Hash of the contract being unclaimed. 2130 */ 2131 struct GNUNET_HashCode h_contract; 2132 2133 }; 2134 2135 GNUNET_NETWORK_STRUCT_END 2136 2137 2138 void 2139 TALER_wallet_order_unclaim_sign ( 2140 const struct GNUNET_HashCode *h_contract, 2141 const struct GNUNET_CRYPTO_EddsaPrivateKey *nonce_priv, 2142 struct GNUNET_CRYPTO_EddsaSignature *nsig) 2143 { 2144 struct TALER_OrderUnclaimPS rcp = { 2145 .purpose.size = htonl (sizeof (rcp)), 2146 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM), 2147 .h_contract = *h_contract 2148 }; 2149 2150 GNUNET_assert (GNUNET_OK == 2151 GNUNET_CRYPTO_eddsa_sign_ (nonce_priv, 2152 &rcp.purpose, 2153 nsig)); 2154 } 2155 2156 2157 enum GNUNET_GenericReturnValue 2158 TALER_wallet_order_unclaim_verify ( 2159 const struct GNUNET_HashCode *h_contract, 2160 const struct GNUNET_CRYPTO_EddsaPublicKey *nonce, 2161 const struct GNUNET_CRYPTO_EddsaSignature *nsig) 2162 { 2163 struct TALER_OrderUnclaimPS rcp = { 2164 .purpose.size = htonl (sizeof (rcp)), 2165 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE), 2166 .h_contract = *h_contract 2167 }; 2168 2169 return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM, 2170 &rcp.purpose, 2171 nsig, 2172 nonce); 2173 } 2174 2175 2176 GNUNET_NETWORK_STRUCT_BEGIN 2177 2178 /** 2179 * Message signed by reserve map authorization key. 2180 */ 2181 struct TALER_ReserveMapAuthorizationPS 2182 { 2183 2184 /** 2185 * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION 2186 */ 2187 struct GNUNET_CRYPTO_SignaturePurpose purpose; 2188 2189 /** 2190 * Account key to associate with the authorization key subject. 2191 */ 2192 union TALER_AccountPublicKeyP account_pub; 2193 2194 }; 2195 2196 GNUNET_NETWORK_STRUCT_END 2197 2198 2199 void 2200 TALER_wallet_reserve_map_authorization_sign ( 2201 const union TALER_AccountPublicKeyP *account_pub, 2202 const struct TALER_ReserveMapAuthorizationPrivateKeyP *auth_priv, 2203 struct TALER_ReserveMapAuthorizationSignatureP *auth_sig) 2204 { 2205 struct TALER_ReserveMapAuthorizationPS rcp = { 2206 .purpose.size = htonl (sizeof (rcp)), 2207 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION), 2208 .account_pub = *account_pub 2209 }; 2210 2211 GNUNET_assert (GNUNET_OK == 2212 GNUNET_CRYPTO_eddsa_sign_ ( 2213 &auth_priv->eddsa_priv, 2214 &rcp.purpose, 2215 &auth_sig->eddsa_signature)); 2216 } 2217 2218 2219 enum GNUNET_GenericReturnValue 2220 TALER_wallet_reserve_map_authorization_verify ( 2221 const union TALER_AccountPublicKeyP *account_pub, 2222 const struct TALER_ReserveMapAuthorizationPublicKeyP *auth_pub, 2223 const struct TALER_ReserveMapAuthorizationSignatureP *auth_sig) 2224 { 2225 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 return GNUNET_CRYPTO_eddsa_verify_ ( 2232 TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION, 2233 &rcp.purpose, 2234 &auth_sig->eddsa_signature, 2235 &auth_pub->eddsa_pub); 2236 } 2237 2238 2239 /* end of wallet_signatures.c */