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