wallet_signatures.c (67462B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2021-2026 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 }; 1372 1373 if (NULL != h_age_commitment) 1374 pm.h_age_commitment = *h_age_commitment; 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 }; 1402 1403 if (NULL != h_age_commitment) 1404 pm.h_age_commitment = *h_age_commitment; 1405 GNUNET_CRYPTO_hash (exchange_base_url, 1406 strlen (exchange_base_url) + 1, 1407 &pm.h_exchange_base_url); 1408 TALER_amount_hton (&pm.coin_amount, 1409 amount); 1410 return GNUNET_CRYPTO_eddsa_verify ( 1411 TALER_SIGNATURE_WALLET_PURSE_DEPOSIT, 1412 &pm, 1413 &coin_sig->eddsa_signature, 1414 &coin_pub->eddsa_pub); 1415 } 1416 1417 1418 GNUNET_NETWORK_STRUCT_BEGIN 1419 1420 /** 1421 * Message signed to merge a purse into a reserve. 1422 */ 1423 struct TALER_PurseMergePS 1424 { 1425 1426 /** 1427 * Purpose is #TALER_SIGNATURE_WALLET_PURSE_MERGE 1428 */ 1429 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1430 1431 /** 1432 * Time when the purse is merged into the reserve. 1433 */ 1434 struct GNUNET_TIME_TimestampNBO merge_timestamp; 1435 1436 /** 1437 * Which purse is being merged? 1438 */ 1439 struct TALER_PurseContractPublicKeyP purse_pub; 1440 1441 /** 1442 * Which reserve should the purse be merged with. 1443 * Hash of the reserve's payto:// URI. 1444 */ 1445 struct TALER_NormalizedPaytoHashP h_payto; 1446 1447 }; 1448 1449 GNUNET_NETWORK_STRUCT_END 1450 1451 void 1452 TALER_wallet_purse_merge_sign ( 1453 const struct TALER_NormalizedPayto reserve_uri, 1454 struct GNUNET_TIME_Timestamp merge_timestamp, 1455 const struct TALER_PurseContractPublicKeyP *purse_pub, 1456 const struct TALER_PurseMergePrivateKeyP *merge_priv, 1457 struct TALER_PurseMergeSignatureP *merge_sig) 1458 { 1459 struct TALER_PurseMergePS pm = { 1460 .purpose.size = htonl (sizeof (pm)), 1461 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE), 1462 .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), 1463 .purse_pub = *purse_pub 1464 }; 1465 1466 GNUNET_assert (0 == 1467 strncasecmp (reserve_uri.normalized_payto, 1468 "payto://taler-reserve", 1469 strlen ("payto://taler-reserve"))); 1470 TALER_normalized_payto_hash (reserve_uri, 1471 &pm.h_payto); 1472 GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv, 1473 &pm, 1474 &merge_sig->eddsa_signature); 1475 } 1476 1477 1478 enum GNUNET_GenericReturnValue 1479 TALER_wallet_purse_merge_verify ( 1480 const struct TALER_NormalizedPayto reserve_uri, 1481 struct GNUNET_TIME_Timestamp merge_timestamp, 1482 const struct TALER_PurseContractPublicKeyP *purse_pub, 1483 const struct TALER_PurseMergePublicKeyP *merge_pub, 1484 const struct TALER_PurseMergeSignatureP *merge_sig) 1485 { 1486 struct TALER_PurseMergePS pm = { 1487 .purpose.size = htonl (sizeof (pm)), 1488 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE), 1489 .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), 1490 .purse_pub = *purse_pub 1491 }; 1492 1493 if (0 != 1494 strncasecmp (reserve_uri.normalized_payto, 1495 "payto://taler-reserve", 1496 strlen ("payto://taler-reserve"))) 1497 { 1498 GNUNET_break (0); 1499 return GNUNET_NO; 1500 } 1501 TALER_normalized_payto_hash (reserve_uri, 1502 &pm.h_payto); 1503 return GNUNET_CRYPTO_eddsa_verify ( 1504 TALER_SIGNATURE_WALLET_PURSE_MERGE, 1505 &pm, 1506 &merge_sig->eddsa_signature, 1507 &merge_pub->eddsa_pub); 1508 } 1509 1510 1511 GNUNET_NETWORK_STRUCT_BEGIN 1512 1513 /** 1514 * Message signed by account to merge a purse into a reserve. 1515 */ 1516 struct TALER_AccountMergePS 1517 { 1518 1519 /** 1520 * Purpose is #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE 1521 */ 1522 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1523 1524 /** 1525 * Time when the purse will expire if still unmerged or unpaid. 1526 */ 1527 struct GNUNET_TIME_TimestampNBO purse_expiration; 1528 1529 /** 1530 * Total amount (with fees) to be put into the purse. 1531 */ 1532 struct TALER_AmountNBO purse_amount; 1533 1534 /** 1535 * Purse creation fee to be paid by the reserve for 1536 * this operation. 1537 */ 1538 struct TALER_AmountNBO purse_fee; 1539 1540 /** 1541 * Contract this purse pays for. 1542 */ 1543 struct TALER_PrivateContractHashP h_contract_terms; 1544 1545 /** 1546 * Purse to merge. 1547 */ 1548 struct TALER_PurseContractPublicKeyP purse_pub; 1549 1550 /** 1551 * Time when the purse is merged into the reserve. 1552 */ 1553 struct GNUNET_TIME_TimestampNBO merge_timestamp; 1554 1555 /** 1556 * Minimum age required for payments into this purse, 1557 * in NBO. 1558 */ 1559 uint32_t min_age GNUNET_PACKED; 1560 1561 /** 1562 * Flags for the operation, in NBO. See 1563 * `enum TALER_WalletAccountMergeFlags`. 1564 */ 1565 uint32_t flags GNUNET_PACKED; 1566 }; 1567 1568 GNUNET_NETWORK_STRUCT_END 1569 1570 1571 void 1572 TALER_wallet_account_merge_sign ( 1573 struct GNUNET_TIME_Timestamp merge_timestamp, 1574 const struct TALER_PurseContractPublicKeyP *purse_pub, 1575 struct GNUNET_TIME_Timestamp purse_expiration, 1576 const struct TALER_PrivateContractHashP *h_contract_terms, 1577 const struct TALER_Amount *amount, 1578 const struct TALER_Amount *purse_fee, 1579 uint32_t min_age, 1580 enum TALER_WalletAccountMergeFlags flags, 1581 const struct TALER_ReservePrivateKeyP *reserve_priv, 1582 struct TALER_ReserveSignatureP *reserve_sig) 1583 { 1584 struct TALER_AccountMergePS pm = { 1585 .purpose.size = htonl (sizeof (pm)), 1586 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE), 1587 .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), 1588 .purse_pub = *purse_pub, 1589 .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), 1590 .h_contract_terms = *h_contract_terms, 1591 .min_age = htonl (min_age), 1592 .flags = htonl ((uint32_t) flags) 1593 }; 1594 1595 TALER_amount_hton (&pm.purse_amount, 1596 amount); 1597 TALER_amount_hton (&pm.purse_fee, 1598 purse_fee); 1599 GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv, 1600 &pm, 1601 &reserve_sig->eddsa_signature); 1602 } 1603 1604 1605 enum GNUNET_GenericReturnValue 1606 TALER_wallet_account_merge_verify ( 1607 struct GNUNET_TIME_Timestamp merge_timestamp, 1608 const struct TALER_PurseContractPublicKeyP *purse_pub, 1609 struct GNUNET_TIME_Timestamp purse_expiration, 1610 const struct TALER_PrivateContractHashP *h_contract_terms, 1611 const struct TALER_Amount *amount, 1612 const struct TALER_Amount *purse_fee, 1613 uint32_t min_age, 1614 enum TALER_WalletAccountMergeFlags flags, 1615 const struct TALER_ReservePublicKeyP *reserve_pub, 1616 const struct TALER_ReserveSignatureP *reserve_sig) 1617 { 1618 struct TALER_AccountMergePS pm = { 1619 .purpose.size = htonl (sizeof (pm)), 1620 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE), 1621 .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp), 1622 .purse_pub = *purse_pub, 1623 .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration), 1624 .h_contract_terms = *h_contract_terms, 1625 .min_age = htonl (min_age), 1626 .flags = htonl ((uint32_t) flags) 1627 }; 1628 1629 TALER_amount_hton (&pm.purse_amount, 1630 amount); 1631 TALER_amount_hton (&pm.purse_fee, 1632 purse_fee); 1633 return GNUNET_CRYPTO_eddsa_verify ( 1634 TALER_SIGNATURE_WALLET_ACCOUNT_MERGE, 1635 &pm, 1636 &reserve_sig->eddsa_signature, 1637 &reserve_pub->eddsa_pub); 1638 } 1639 1640 1641 GNUNET_NETWORK_STRUCT_BEGIN 1642 1643 /** 1644 * Message signed by reserve key. 1645 */ 1646 struct TALER_ReserveOpenPS 1647 { 1648 1649 /** 1650 * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN 1651 */ 1652 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1653 1654 /** 1655 * Amount to be paid from the reserve balance to open 1656 * the reserve. 1657 */ 1658 struct TALER_AmountNBO reserve_payment; 1659 1660 /** 1661 * When was the request created. 1662 */ 1663 struct GNUNET_TIME_TimestampNBO request_timestamp; 1664 1665 /** 1666 * For how long should the reserve be kept open. 1667 * (Determines amount to be paid.) 1668 */ 1669 struct GNUNET_TIME_TimestampNBO reserve_expiration; 1670 1671 /** 1672 * How many open purses should be included with the 1673 * open reserve? 1674 * (Determines amount to be paid.) 1675 */ 1676 uint32_t purse_limit GNUNET_PACKED; 1677 1678 }; 1679 1680 GNUNET_NETWORK_STRUCT_END 1681 1682 1683 void 1684 TALER_wallet_reserve_open_sign ( 1685 const struct TALER_Amount *reserve_payment, 1686 struct GNUNET_TIME_Timestamp request_timestamp, 1687 struct GNUNET_TIME_Timestamp reserve_expiration, 1688 uint32_t purse_limit, 1689 const struct TALER_ReservePrivateKeyP *reserve_priv, 1690 struct TALER_ReserveSignatureP *reserve_sig) 1691 { 1692 struct TALER_ReserveOpenPS rop = { 1693 .purpose.size = htonl (sizeof (rop)), 1694 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN), 1695 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp), 1696 .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration), 1697 .purse_limit = htonl (purse_limit) 1698 }; 1699 1700 TALER_amount_hton (&rop.reserve_payment, 1701 reserve_payment); 1702 GNUNET_assert (GNUNET_OK == 1703 GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv, 1704 &rop.purpose, 1705 &reserve_sig->eddsa_signature)); 1706 } 1707 1708 1709 enum GNUNET_GenericReturnValue 1710 TALER_wallet_reserve_open_verify ( 1711 const struct TALER_Amount *reserve_payment, 1712 struct GNUNET_TIME_Timestamp request_timestamp, 1713 struct GNUNET_TIME_Timestamp reserve_expiration, 1714 uint32_t purse_limit, 1715 const struct TALER_ReservePublicKeyP *reserve_pub, 1716 const struct TALER_ReserveSignatureP *reserve_sig) 1717 { 1718 struct TALER_ReserveOpenPS rop = { 1719 .purpose.size = htonl (sizeof (rop)), 1720 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN), 1721 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp), 1722 .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration), 1723 .purse_limit = htonl (purse_limit) 1724 }; 1725 1726 TALER_amount_hton (&rop.reserve_payment, 1727 reserve_payment); 1728 return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_OPEN, 1729 &rop.purpose, 1730 &reserve_sig->eddsa_signature, 1731 &reserve_pub->eddsa_pub); 1732 } 1733 1734 1735 GNUNET_NETWORK_STRUCT_BEGIN 1736 1737 /** 1738 * Message signed by 1739 */ 1740 struct TALER_ReserveOpenDepositPS 1741 { 1742 1743 /** 1744 * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT 1745 */ 1746 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1747 1748 /** 1749 * Which reserve's opening signature should be paid for? 1750 */ 1751 struct TALER_ReserveSignatureP reserve_sig; 1752 1753 /** 1754 * Specifies how much of the coin's value should be spent on opening this 1755 * reserve. 1756 */ 1757 struct TALER_AmountNBO coin_contribution; 1758 1759 /** 1760 * Hash over the coin's age commitment, all zero if the coin had 1761 * no age restriction. 1762 */ 1763 struct TALER_AgeCommitmentHashP h_age_commitment; 1764 1765 /** 1766 * Hash over the coin's denomination public key. 1767 */ 1768 struct TALER_DenominationHashP h_denom_pub; 1769 }; 1770 1771 GNUNET_NETWORK_STRUCT_END 1772 1773 1774 void 1775 TALER_wallet_reserve_open_deposit_sign ( 1776 const struct TALER_Amount *coin_contribution, 1777 const struct TALER_DenominationHashP *h_denom_pub, 1778 const struct TALER_AgeCommitmentHashP *h_age_commitment, 1779 const struct TALER_ReserveSignatureP *reserve_sig, 1780 const struct TALER_CoinSpendPrivateKeyP *coin_priv, 1781 struct TALER_CoinSpendSignatureP *coin_sig) 1782 { 1783 struct TALER_ReserveOpenDepositPS rod = { 1784 .purpose.size = htonl (sizeof (rod)), 1785 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT), 1786 .reserve_sig = *reserve_sig, 1787 .h_denom_pub = *h_denom_pub 1788 }; 1789 1790 if (NULL != h_age_commitment) 1791 rod.h_age_commitment = *h_age_commitment; 1792 TALER_amount_hton (&rod.coin_contribution, 1793 coin_contribution); 1794 GNUNET_assert (GNUNET_OK == 1795 GNUNET_CRYPTO_eddsa_sign_ (&coin_priv->eddsa_priv, 1796 &rod.purpose, 1797 &coin_sig->eddsa_signature)); 1798 } 1799 1800 1801 enum GNUNET_GenericReturnValue 1802 TALER_wallet_reserve_open_deposit_verify ( 1803 const struct TALER_Amount *coin_contribution, 1804 const struct TALER_DenominationHashP *h_denom_pub, 1805 const struct TALER_AgeCommitmentHashP *h_age_commitment, 1806 const struct TALER_ReserveSignatureP *reserve_sig, 1807 const struct TALER_CoinSpendPublicKeyP *coin_pub, 1808 const struct TALER_CoinSpendSignatureP *coin_sig) 1809 { 1810 struct TALER_ReserveOpenDepositPS rod = { 1811 .purpose.size = htonl (sizeof (rod)), 1812 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT), 1813 .reserve_sig = *reserve_sig, 1814 .h_denom_pub = *h_denom_pub 1815 }; 1816 1817 if (NULL != h_age_commitment) 1818 rod.h_age_commitment = *h_age_commitment; 1819 TALER_amount_hton (&rod.coin_contribution, 1820 coin_contribution); 1821 return GNUNET_CRYPTO_eddsa_verify_ ( 1822 TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT, 1823 &rod.purpose, 1824 &coin_sig->eddsa_signature, 1825 &coin_pub->eddsa_pub); 1826 } 1827 1828 1829 GNUNET_NETWORK_STRUCT_BEGIN 1830 1831 /** 1832 * Message signed by reserve key. 1833 */ 1834 struct TALER_ReserveClosePS 1835 { 1836 1837 /** 1838 * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_CLOSE 1839 */ 1840 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1841 1842 /** 1843 * When was the request created. 1844 */ 1845 struct GNUNET_TIME_TimestampNBO request_timestamp; 1846 1847 /** 1848 * Hash of the payto://-URI of the target account 1849 * for the closure, or all zeros for the reserve 1850 * origin account. 1851 */ 1852 struct TALER_FullPaytoHashP target_account_h_payto; 1853 1854 }; 1855 1856 GNUNET_NETWORK_STRUCT_END 1857 1858 1859 void 1860 TALER_wallet_reserve_close_sign ( 1861 struct GNUNET_TIME_Timestamp request_timestamp, 1862 const struct TALER_FullPaytoHashP *h_payto, 1863 const struct TALER_ReservePrivateKeyP *reserve_priv, 1864 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 GNUNET_assert (GNUNET_OK == 1875 GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv, 1876 &rcp.purpose, 1877 &reserve_sig->eddsa_signature)); 1878 } 1879 1880 1881 enum GNUNET_GenericReturnValue 1882 TALER_wallet_reserve_close_verify ( 1883 struct GNUNET_TIME_Timestamp request_timestamp, 1884 const struct TALER_FullPaytoHashP *h_payto, 1885 const struct TALER_ReservePublicKeyP *reserve_pub, 1886 const struct TALER_ReserveSignatureP *reserve_sig) 1887 { 1888 struct TALER_ReserveClosePS rcp = { 1889 .purpose.size = htonl (sizeof (rcp)), 1890 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE), 1891 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp) 1892 }; 1893 1894 if (NULL != h_payto) 1895 rcp.target_account_h_payto = *h_payto; 1896 return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE, 1897 &rcp.purpose, 1898 &reserve_sig->eddsa_signature, 1899 &reserve_pub->eddsa_pub); 1900 } 1901 1902 1903 GNUNET_NETWORK_STRUCT_BEGIN 1904 1905 /** 1906 * Message signed by reserve private key. 1907 */ 1908 struct TALER_ReserveAttestRequestPS 1909 { 1910 1911 /** 1912 * Purpose is #TALER_SIGNATURE_WALLET_ATTEST_REQUEST 1913 */ 1914 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1915 1916 /** 1917 * When was the request created. 1918 */ 1919 struct GNUNET_TIME_TimestampNBO request_timestamp; 1920 1921 /** 1922 * Hash over the JSON array of requested attributes. 1923 */ 1924 struct GNUNET_HashCode h_details; 1925 1926 }; 1927 1928 GNUNET_NETWORK_STRUCT_END 1929 1930 1931 void 1932 TALER_wallet_reserve_attest_request_sign ( 1933 struct GNUNET_TIME_Timestamp request_timestamp, 1934 const json_t *details, 1935 const struct TALER_ReservePrivateKeyP *reserve_priv, 1936 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 GNUNET_assert (GNUNET_OK == 1947 GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv, 1948 &rcp.purpose, 1949 &reserve_sig->eddsa_signature)); 1950 } 1951 1952 1953 enum GNUNET_GenericReturnValue 1954 TALER_wallet_reserve_attest_request_verify ( 1955 struct GNUNET_TIME_Timestamp request_timestamp, 1956 const json_t *details, 1957 const struct TALER_ReservePublicKeyP *reserve_pub, 1958 const struct TALER_ReserveSignatureP *reserve_sig) 1959 { 1960 struct TALER_ReserveAttestRequestPS rcp = { 1961 .purpose.size = htonl (sizeof (rcp)), 1962 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS), 1963 .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp) 1964 }; 1965 1966 TALER_json_hash (details, 1967 &rcp.h_details); 1968 return GNUNET_CRYPTO_eddsa_verify_ ( 1969 TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS, 1970 &rcp.purpose, 1971 &reserve_sig->eddsa_signature, 1972 &reserve_pub->eddsa_pub); 1973 } 1974 1975 1976 GNUNET_NETWORK_STRUCT_BEGIN 1977 1978 /** 1979 * Message signed by purse to associate an encrypted contract. 1980 */ 1981 struct TALER_PurseContractPS 1982 { 1983 1984 /** 1985 * Purpose is #TALER_SIGNATURE_WALLET_PURSE_ECONTRACT 1986 */ 1987 struct GNUNET_CRYPTO_SignaturePurpose purpose; 1988 1989 /** 1990 * Hash over the encrypted contract. 1991 */ 1992 struct GNUNET_HashCode h_econtract; 1993 1994 /** 1995 * Public key to decrypt the contract. 1996 */ 1997 struct TALER_ContractDiffiePublicP contract_pub; 1998 }; 1999 2000 GNUNET_NETWORK_STRUCT_END 2001 2002 void 2003 TALER_wallet_econtract_upload_sign ( 2004 const void *econtract, 2005 size_t econtract_size, 2006 const struct TALER_ContractDiffiePublicP *contract_pub, 2007 const struct TALER_PurseContractPrivateKeyP *purse_priv, 2008 struct TALER_PurseContractSignatureP *purse_sig) 2009 { 2010 struct TALER_PurseContractPS pc = { 2011 .purpose.size = htonl (sizeof (pc)), 2012 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT), 2013 .contract_pub = *contract_pub 2014 }; 2015 2016 GNUNET_CRYPTO_hash (econtract, 2017 econtract_size, 2018 &pc.h_econtract); 2019 GNUNET_assert (GNUNET_OK == 2020 GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv, 2021 &pc.purpose, 2022 &purse_sig->eddsa_signature)); 2023 } 2024 2025 2026 enum GNUNET_GenericReturnValue 2027 TALER_wallet_econtract_upload_verify2 ( 2028 const struct GNUNET_HashCode *h_econtract, 2029 const struct TALER_ContractDiffiePublicP *contract_pub, 2030 const struct TALER_PurseContractPublicKeyP *purse_pub, 2031 const struct TALER_PurseContractSignatureP *purse_sig) 2032 { 2033 struct TALER_PurseContractPS pc = { 2034 .purpose.size = htonl (sizeof (pc)), 2035 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT), 2036 .contract_pub = *contract_pub, 2037 .h_econtract = *h_econtract 2038 }; 2039 2040 return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT, 2041 &pc.purpose, 2042 &purse_sig->eddsa_signature, 2043 &purse_pub->eddsa_pub); 2044 } 2045 2046 2047 enum GNUNET_GenericReturnValue 2048 TALER_wallet_econtract_upload_verify ( 2049 const void *econtract, 2050 size_t econtract_size, 2051 const struct TALER_ContractDiffiePublicP *contract_pub, 2052 const struct TALER_PurseContractPublicKeyP *purse_pub, 2053 const struct TALER_PurseContractSignatureP *purse_sig) 2054 { 2055 struct GNUNET_HashCode h_econtract; 2056 2057 GNUNET_CRYPTO_hash (econtract, 2058 econtract_size, 2059 &h_econtract); 2060 return TALER_wallet_econtract_upload_verify2 (&h_econtract, 2061 contract_pub, 2062 purse_pub, 2063 purse_sig); 2064 } 2065 2066 2067 GNUNET_NETWORK_STRUCT_BEGIN 2068 2069 /** 2070 * Message signed by wallet to confirm usage of a token for a transaction. 2071 */ 2072 struct TALER_TokenUseRequestPS 2073 { 2074 2075 /** 2076 * Purpose is #TALER_SIGNATURE_WALLET_TOKEN_USE 2077 */ 2078 struct GNUNET_CRYPTO_SignaturePurpose purpose; 2079 2080 /** 2081 * Hash over the contract for which this token is used. 2082 */ 2083 struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED; 2084 2085 /** 2086 * Hash over a JSON containing data provided by the 2087 * wallet to complete the contract upon payment. 2088 */ 2089 struct GNUNET_HashCode wallet_data_hash; 2090 2091 }; 2092 2093 GNUNET_NETWORK_STRUCT_END 2094 2095 2096 void 2097 TALER_wallet_token_use_sign ( 2098 const struct TALER_PrivateContractHashP *h_contract_terms, 2099 const struct GNUNET_HashCode *wallet_data_hash, 2100 const struct TALER_TokenUsePrivateKeyP *token_use_priv, 2101 struct TALER_TokenUseSignatureP *token_sig) 2102 { 2103 struct TALER_TokenUseRequestPS tur = { 2104 .purpose.size = htonl (sizeof (tur)), 2105 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE), 2106 .h_contract_terms = *h_contract_terms, 2107 .wallet_data_hash = *wallet_data_hash 2108 }; 2109 2110 GNUNET_CRYPTO_eddsa_sign (&token_use_priv->private_key, 2111 &tur, 2112 &token_sig->signature); 2113 } 2114 2115 2116 enum GNUNET_GenericReturnValue 2117 TALER_wallet_token_use_verify ( 2118 const struct TALER_PrivateContractHashP *h_contract_terms, 2119 const struct GNUNET_HashCode *wallet_data_hash, 2120 const struct TALER_TokenUsePublicKeyP *token_use_pub, 2121 const struct TALER_TokenUseSignatureP *token_sig) 2122 { 2123 struct TALER_TokenUseRequestPS tur = { 2124 .purpose.size = htonl (sizeof (tur)), 2125 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE), 2126 .h_contract_terms = *h_contract_terms, 2127 .wallet_data_hash = *wallet_data_hash 2128 }; 2129 2130 return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_TOKEN_USE, 2131 &tur, 2132 &token_sig->signature, 2133 &token_use_pub->public_key); 2134 } 2135 2136 2137 GNUNET_NETWORK_STRUCT_BEGIN 2138 2139 /** 2140 * Message signed by reserve key. 2141 */ 2142 struct TALER_OrderUnclaimPS 2143 { 2144 2145 /** 2146 * Purpose is #TALER_SIGNATURE_WALLET_ORDER_UNCLAIM 2147 */ 2148 struct GNUNET_CRYPTO_SignaturePurpose purpose; 2149 2150 /** 2151 * Hash of the contract being unclaimed. 2152 */ 2153 struct GNUNET_HashCode h_contract; 2154 2155 }; 2156 2157 GNUNET_NETWORK_STRUCT_END 2158 2159 2160 void 2161 TALER_wallet_order_unclaim_sign ( 2162 const struct GNUNET_HashCode *h_contract, 2163 const struct GNUNET_CRYPTO_EddsaPrivateKey *nonce_priv, 2164 struct GNUNET_CRYPTO_EddsaSignature *nsig) 2165 { 2166 struct TALER_OrderUnclaimPS rcp = { 2167 .purpose.size = htonl (sizeof (rcp)), 2168 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM), 2169 .h_contract = *h_contract 2170 }; 2171 2172 GNUNET_assert (GNUNET_OK == 2173 GNUNET_CRYPTO_eddsa_sign_ (nonce_priv, 2174 &rcp.purpose, 2175 nsig)); 2176 } 2177 2178 2179 enum GNUNET_GenericReturnValue 2180 TALER_wallet_order_unclaim_verify ( 2181 const struct GNUNET_HashCode *h_contract, 2182 const struct GNUNET_CRYPTO_EddsaPublicKey *nonce, 2183 const struct GNUNET_CRYPTO_EddsaSignature *nsig) 2184 { 2185 struct TALER_OrderUnclaimPS rcp = { 2186 .purpose.size = htonl (sizeof (rcp)), 2187 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM), 2188 .h_contract = *h_contract 2189 }; 2190 2191 return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM, 2192 &rcp.purpose, 2193 nsig, 2194 nonce); 2195 } 2196 2197 2198 GNUNET_NETWORK_STRUCT_BEGIN 2199 2200 /** 2201 * Message signed by prepared transfer authorization key. 2202 */ 2203 struct TALER_PreparedTransferRegisterPS 2204 { 2205 /** 2206 * Purpose is #TALER_SIGNATURE_WALLET_PREPARED_TRANSFER_REGISTER 2207 */ 2208 struct GNUNET_CRYPTO_SignaturePurpose purpose; 2209 struct TALER_FullPaytoHashP credit_account; 2210 struct TALER_AmountNBO credit_amount; 2211 /** 2212 * 1: reserve, 2: kyc 2213 */ 2214 uint32_t type; 2215 /** 2216 * 1: one-time, 2: recurrent 2217 */ 2218 uint16_t recurrent; 2219 /** 2220 * 1: EdDSA 2221 */ 2222 uint16_t alg; 2223 union TALER_AccountPublicKeyP account_pub; 2224 }; 2225 2226 2227 GNUNET_NETWORK_STRUCT_END 2228 2229 2230 void 2231 TALER_wallet_prepared_transfer_registration_sign ( 2232 const struct TALER_FullPayto credit_account, 2233 const struct TALER_Amount *credit_amount, 2234 // enum TALER_BANK_RegistrationType type, TODO solve the include cycle 2235 bool is_reserve, 2236 bool recurrent, 2237 const union TALER_AccountPublicKeyP *account_pub, 2238 const struct TALER_PreparedTransferAuthorizationPrivateKeyP *auth_priv, 2239 struct TALER_PreparedTransferAuthorizationSignatureP *auth_sig) 2240 { 2241 struct TALER_PreparedTransferRegisterPS rcp = { 2242 .purpose.size = htonl (sizeof (rcp)), 2243 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PREPARED_TRANSFER_REGISTER) 2244 , 2245 .alg = htons (1), 2246 .account_pub = *account_pub 2247 }; 2248 2249 TALER_full_payto_hash (credit_account, 2250 &rcp.credit_account); 2251 TALER_amount_hton (&rcp.credit_amount, 2252 credit_amount); 2253 2254 if (is_reserve) 2255 { 2256 rcp.type = htonl (1); 2257 } 2258 else 2259 { 2260 rcp.type = htonl (2); 2261 } 2262 2263 if (recurrent) 2264 { 2265 rcp.recurrent = htons (2); 2266 } 2267 else 2268 { 2269 rcp.recurrent = htons (1); 2270 } 2271 2272 GNUNET_assert (GNUNET_OK == 2273 GNUNET_CRYPTO_eddsa_sign_ ( 2274 &auth_priv->eddsa_priv, 2275 &rcp.purpose, 2276 &auth_sig->eddsa_signature)); 2277 } 2278 2279 2280 enum GNUNET_GenericReturnValue 2281 TALER_wallet_prepared_transfer_registration_verify ( 2282 const struct TALER_FullPayto credit_account, 2283 const struct TALER_Amount *credit_amount, 2284 // enum TALER_BANK_RegistrationType type, TODO solve the include cycle 2285 bool is_reserve, 2286 bool recurrent, 2287 const union TALER_AccountPublicKeyP *account_pub, 2288 const struct TALER_PreparedTransferAuthorizationPublicKeyP *auth_pub, 2289 const struct TALER_PreparedTransferAuthorizationSignatureP *auth_sig) 2290 { 2291 struct TALER_PreparedTransferRegisterPS rcp = { 2292 .purpose.size = htonl (sizeof (rcp)), 2293 .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PREPARED_TRANSFER_REGISTER) 2294 , 2295 .alg = htonl (1), 2296 .account_pub = *account_pub 2297 }; 2298 2299 TALER_full_payto_hash (credit_account, 2300 &rcp.credit_account); 2301 TALER_amount_hton (&rcp.credit_amount, 2302 credit_amount); 2303 2304 if (is_reserve) 2305 { 2306 rcp.type = htonl (1); 2307 } 2308 else 2309 { 2310 rcp.type = htonl (2); 2311 } 2312 2313 if (recurrent) 2314 { 2315 rcp.recurrent = htonl (1); 2316 } 2317 else 2318 { 2319 rcp.recurrent = htonl (2); 2320 } 2321 2322 return GNUNET_CRYPTO_eddsa_verify_ ( 2323 TALER_SIGNATURE_WALLET_PREPARED_TRANSFER_REGISTER, 2324 &rcp.purpose, 2325 &auth_sig->eddsa_signature, 2326 &auth_pub->eddsa_pub); 2327 } 2328 2329 2330 GNUNET_NETWORK_STRUCT_BEGIN 2331 2332 /** 2333 * Message signed by prepared transfer authorization key. 2334 */ 2335 struct TALER_PreparedTransferUnregisterPS 2336 { 2337 /** 2338 * Purpose is #TALER_SIGNATURE_WALLET_PREPARED_TRANSFER_UNREGISTER 2339 */ 2340 struct GNUNET_CRYPTO_SignaturePurpose purpose; 2341 struct GNUNET_TIME_TimestampNBO timestamp; 2342 }; 2343 2344 GNUNET_NETWORK_STRUCT_END 2345 2346 /* end of wallet_signatures.c */