Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2021-2023 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER is distributed in the hope that it will be useful, but WITHOUT ANY
10 : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 : A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 :
13 : You should have received a copy of the GNU General Public License along with
14 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file wallet_signatures.c
18 : * @brief Utility functions for Taler wallet signatures
19 : * @author Christian Grothoff
20 : * @author Özgür Kesim
21 : */
22 : #include "taler/taler_util.h"
23 : #include "taler/taler_signatures.h"
24 : #include <gnunet/gnunet_common.h>
25 : #include <stdint.h>
26 :
27 :
28 : GNUNET_NETWORK_STRUCT_BEGIN
29 :
30 : /**
31 : * @brief Format used to generate the signature on a request to deposit
32 : * a coin into the account of a merchant.
33 : */
34 : struct TALER_DepositRequestPS
35 : {
36 : /**
37 : * Purpose must be #TALER_SIGNATURE_WALLET_COIN_DEPOSIT.
38 : * Used for an EdDSA signature with the `struct TALER_CoinSpendPublicKeyP`.
39 : */
40 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
41 :
42 : /**
43 : * Hash over the contract for which this deposit is made.
44 : */
45 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
46 :
47 : /**
48 : * Hash over the age commitment that went into the coin. Maybe all zero, if
49 : * age commitment isn't applicable to the denomination.
50 : */
51 : struct TALER_AgeCommitmentHashP h_age_commitment GNUNET_PACKED;
52 :
53 : /**
54 : * Hash over optional policy extension attributes shared with the exchange.
55 : */
56 : struct TALER_ExtensionPolicyHashP h_policy GNUNET_PACKED;
57 :
58 : /**
59 : * Hash over the wiring information of the merchant.
60 : */
61 : struct TALER_MerchantWireHashP h_wire GNUNET_PACKED;
62 :
63 : /**
64 : * Hash over the denomination public key used to sign the coin.
65 : */
66 : struct TALER_DenominationHashP h_denom_pub GNUNET_PACKED;
67 :
68 : /**
69 : * Time when this request was generated. Used, for example, to
70 : * assess when (roughly) the income was achieved for tax purposes.
71 : * Note that the Exchange will only check that the timestamp is not "too
72 : * far" into the future (i.e. several days). The fact that the
73 : * timestamp falls within the validity period of the coin's
74 : * denomination key is irrelevant for the validity of the deposit
75 : * request, as obviously the customer and merchant could conspire to
76 : * set any timestamp. Also, the Exchange must accept very old deposit
77 : * requests, as the merchant might have been unable to transmit the
78 : * deposit request in a timely fashion (so back-dating is not
79 : * prevented).
80 : */
81 : struct GNUNET_TIME_TimestampNBO wallet_timestamp;
82 :
83 : /**
84 : * How much time does the merchant have to issue a refund request?
85 : * Zero if refunds are not allowed. After this time, the coin
86 : * cannot be refunded.
87 : */
88 : struct GNUNET_TIME_TimestampNBO refund_deadline;
89 :
90 : /**
91 : * Amount to be deposited, including deposit fee charged by the
92 : * exchange. This is the total amount that the coin's value at the exchange
93 : * will be reduced by.
94 : */
95 : struct TALER_AmountNBO amount_with_fee;
96 :
97 : /**
98 : * Depositing fee charged by the exchange. This must match the Exchange's
99 : * denomination key's depositing fee. If the client puts in an
100 : * invalid deposit fee (too high or too low) that does not match the
101 : * Exchange's denomination key, the deposit operation is invalid and
102 : * will be rejected by the exchange. The @e amount_with_fee minus the
103 : * @e deposit_fee is the amount that will be transferred to the
104 : * account identified by @e h_wire.
105 : */
106 : struct TALER_AmountNBO deposit_fee;
107 :
108 : /**
109 : * The Merchant's public key. Allows the merchant to later refund
110 : * the transaction or to inquire about the wire transfer identifier.
111 : */
112 : struct TALER_MerchantPublicKeyP merchant;
113 :
114 : /**
115 : * Hash over a JSON containing data provided by the
116 : * wallet to complete the contract upon payment.
117 : */
118 : struct GNUNET_HashCode wallet_data_hash;
119 :
120 : };
121 :
122 : GNUNET_NETWORK_STRUCT_END
123 :
124 : void
125 100 : 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 200 : struct TALER_DepositRequestPS dr = {
141 100 : .purpose.size = htonl (sizeof (dr)),
142 100 : .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 100 : .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
147 100 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
148 : .merchant = *merchant_pub
149 : };
150 :
151 100 : if (NULL != wallet_data_hash)
152 0 : dr.wallet_data_hash = *wallet_data_hash;
153 100 : if (NULL != h_age_commitment)
154 36 : dr.h_age_commitment = *h_age_commitment;
155 100 : if (NULL != h_policy)
156 0 : dr.h_policy = *h_policy;
157 100 : TALER_amount_hton (&dr.amount_with_fee,
158 : amount);
159 100 : TALER_amount_hton (&dr.deposit_fee,
160 : deposit_fee);
161 100 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
162 : &dr,
163 : &coin_sig->eddsa_signature);
164 100 : }
165 :
166 :
167 : enum GNUNET_GenericReturnValue
168 204 : 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 408 : struct TALER_DepositRequestPS dr = {
184 204 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_DEPOSIT),
185 204 : .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 204 : .wallet_timestamp = GNUNET_TIME_timestamp_hton (wallet_timestamp),
190 204 : .refund_deadline = GNUNET_TIME_timestamp_hton (refund_deadline),
191 : .merchant = *merchant_pub,
192 : };
193 :
194 204 : if (NULL != wallet_data_hash)
195 200 : dr.wallet_data_hash = *wallet_data_hash;
196 204 : if (NULL != h_age_commitment)
197 126 : dr.h_age_commitment = *h_age_commitment;
198 204 : if (NULL != h_policy)
199 102 : dr.h_policy = *h_policy;
200 204 : TALER_amount_hton (&dr.amount_with_fee,
201 : amount);
202 204 : TALER_amount_hton (&dr.deposit_fee,
203 : deposit_fee);
204 204 : if (GNUNET_OK !=
205 204 : GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_COIN_DEPOSIT,
206 : &dr,
207 : &coin_sig->eddsa_signature,
208 : &coin_pub->eddsa_pub))
209 : {
210 0 : GNUNET_break_op (0);
211 0 : return GNUNET_SYSERR;
212 : }
213 204 : 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 0 : 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 0 : struct TALER_LinkDataPS ldp = {
263 0 : .purpose.size = htonl (sizeof (ldp)),
264 0 : .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 0 : GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
271 : &ldp,
272 : &coin_sig->eddsa_signature);
273 0 : }
274 :
275 :
276 : enum GNUNET_GenericReturnValue
277 0 : 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 0 : struct TALER_LinkDataPS ldp = {
285 0 : .purpose.size = htonl (sizeof (ldp)),
286 0 : .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 0 : 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 0 : 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 0 : struct TALER_RecoupRequestPS pr = {
338 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
339 0 : .purpose.size = htonl (sizeof (pr)),
340 : .h_denom_pub = *h_denom_pub,
341 : .coin_blind = *coin_bks
342 : };
343 :
344 0 : 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 0 : 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 0 : struct TALER_RecoupRequestPS pr = {
359 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP),
360 0 : .purpose.size = htonl (sizeof (pr)),
361 : .h_denom_pub = *h_denom_pub,
362 : .coin_blind = *coin_bks
363 : };
364 :
365 0 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
366 : &pr,
367 : &coin_sig->eddsa_signature);
368 0 : }
369 :
370 :
371 : enum GNUNET_GenericReturnValue
372 0 : 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 0 : struct TALER_RecoupRequestPS pr = {
379 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
380 0 : .purpose.size = htonl (sizeof (pr)),
381 : .h_denom_pub = *h_denom_pub,
382 : .coin_blind = *coin_bks
383 : };
384 :
385 0 : 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 0 : 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 0 : struct TALER_RecoupRequestPS pr = {
400 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_RECOUP_REFRESH),
401 0 : .purpose.size = htonl (sizeof (struct TALER_RecoupRequestPS)),
402 : .h_denom_pub = *h_denom_pub,
403 : .coin_blind = *coin_bks
404 : };
405 :
406 0 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
407 : &pr,
408 : &coin_sig->eddsa_signature);
409 0 : }
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 30 : 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 30 : struct TALER_RefreshMeltCoinAffirmationPS melt = {
478 30 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
479 30 : .purpose.size = htonl (sizeof (melt)),
480 : .rc = *rc,
481 : .h_denom_pub = *h_denom_pub
482 : };
483 :
484 30 : if (NULL != h_age_commitment)
485 16 : melt.h_age_commitment = *h_age_commitment;
486 30 : TALER_amount_hton (&melt.amount_with_fee,
487 : amount_with_fee);
488 30 : TALER_amount_hton (&melt.melt_fee,
489 : melt_fee);
490 30 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
491 : &melt,
492 : &coin_sig->eddsa_signature);
493 30 : }
494 :
495 :
496 : enum GNUNET_GenericReturnValue
497 30 : 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 30 : struct TALER_RefreshMeltCoinAffirmationPS melt = {
507 30 : .purpose.size = htonl (sizeof (melt)),
508 30 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_MELT),
509 : .rc = *rc,
510 : .h_denom_pub = *h_denom_pub
511 : };
512 :
513 30 : if (NULL != h_age_commitment)
514 30 : melt.h_age_commitment = *h_age_commitment;
515 30 : TALER_amount_hton (&melt.amount_with_fee,
516 : amount_with_fee);
517 30 : TALER_amount_hton (&melt.melt_fee,
518 : melt_fee);
519 30 : 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 0 : 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 0 : {
570 0 : struct TALER_RefreshNonceSignaturePS req = {
571 0 : .purpose.size = htonl (sizeof (req)),
572 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
573 : .nonce = *nonce,
574 0 : .kappa_index = htonl (kappa_index),
575 : };
576 0 : struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
577 0 : GNUNET_assert (ctx);
578 :
579 0 : for (size_t i = 0; i<num_denoms_h; i++)
580 0 : GNUNET_CRYPTO_hash_context_read (ctx,
581 0 : denoms_h[i],
582 : sizeof(*denoms_h[i]));
583 :
584 0 : GNUNET_CRYPTO_hash_context_finish (ctx,
585 : &req.h_denoms_h);
586 0 : GNUNET_CRYPTO_eddsa_sign (&old_coin_priv->eddsa_priv,
587 : &req,
588 : &sig->coin_sig.eddsa_signature);
589 0 : }
590 :
591 :
592 : enum GNUNET_GenericReturnValue
593 0 : 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 0 : {
601 0 : struct TALER_RefreshNonceSignaturePS req = {
602 0 : .purpose.size = htonl (sizeof (req)),
603 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_LINK),
604 : .nonce = *nonce,
605 0 : .kappa_index = htonl (kappa_index),
606 : };
607 0 : struct GNUNET_HashContext *ctx = GNUNET_CRYPTO_hash_context_start ();
608 0 : GNUNET_assert (ctx);
609 :
610 0 : for (size_t i = 0; i<num_denoms_h; i++)
611 0 : GNUNET_CRYPTO_hash_context_read (ctx,
612 0 : denoms_h[i],
613 : sizeof(*denoms_h[i]));
614 :
615 0 : GNUNET_CRYPTO_hash_context_finish (ctx,
616 : &req.h_denoms_h);
617 0 : 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 0 : 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 0 : struct TALER_WithdrawCommitmentPre24PS req = {
674 0 : .purpose.size = htonl (sizeof (req)),
675 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
676 : .h_denomination_pub = *h_denom_pub,
677 : .h_coin_envelope = *bch
678 : };
679 :
680 0 : TALER_amount_hton (&req.amount_with_fee,
681 : amount_with_fee);
682 0 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
683 : &req,
684 : &reserve_sig->eddsa_signature);
685 0 : }
686 :
687 :
688 : enum GNUNET_GenericReturnValue
689 0 : 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 0 : struct TALER_WithdrawCommitmentPre24PS req = {
697 0 : .purpose.size = htonl (sizeof (req)),
698 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
699 : .h_denomination_pub = *h_denom_pub,
700 : .h_coin_envelope = *bch
701 : };
702 :
703 0 : TALER_amount_hton (&req.amount_with_fee,
704 : amount_with_fee);
705 0 : 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 265 : 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 265 : {
784 : struct TALER_BlindedCoinHashP bch;
785 : struct GNUNET_HashContext *coins_hctx;
786 :
787 265 : GNUNET_assert (num_planchets > 0);
788 265 : GNUNET_assert (NULL != h_planchets);
789 :
790 265 : coins_hctx = GNUNET_CRYPTO_hash_context_start ();
791 265 : GNUNET_assert (NULL != coins_hctx);
792 :
793 1084 : for (size_t i = 0; i < num_planchets; i++)
794 : {
795 819 : TALER_coin_ev_hash (
796 819 : &blinded_planchets[i],
797 819 : &h_denom_pubs[i],
798 : &bch);
799 819 : GNUNET_CRYPTO_hash_context_read (
800 : coins_hctx,
801 : &bch,
802 : sizeof(bch));
803 : }
804 :
805 265 : GNUNET_CRYPTO_hash_context_finish (
806 : coins_hctx,
807 : &h_planchets->hash);
808 265 : }
809 :
810 :
811 : void
812 160 : 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 160 : {
817 : struct TALER_BlindedCoinHashP bch;
818 : struct GNUNET_HashContext *coins_hctx;
819 :
820 160 : GNUNET_assert (num_planchets > 0);
821 160 : GNUNET_assert (NULL != h_planchets);
822 :
823 160 : coins_hctx = GNUNET_CRYPTO_hash_context_start ();
824 160 : GNUNET_assert (NULL != coins_hctx);
825 :
826 800 : for (size_t i = 0; i < num_planchets; i++)
827 : {
828 640 : TALER_coin_ev_hash (
829 640 : &planchet_details[i].blinded_planchet,
830 640 : &planchet_details[i].denom_pub_hash,
831 : &bch);
832 640 : GNUNET_CRYPTO_hash_context_read (
833 : coins_hctx,
834 : &bch,
835 : sizeof(bch));
836 : }
837 :
838 160 : GNUNET_CRYPTO_hash_context_finish (
839 : coins_hctx,
840 : &h_planchets->hash);
841 160 : }
842 :
843 :
844 : struct TALER_HashReservePublicKeyP
845 0 : TALER_wallet_hash_reserve_pub (
846 : const struct TALER_ReservePublicKeyP *reserve_pub)
847 : {
848 : struct TALER_HashReservePublicKeyP hr;
849 :
850 0 : GNUNET_CRYPTO_hash (reserve_pub,
851 : sizeof(*reserve_pub),
852 : &hr.hash);
853 0 : return hr;
854 : }
855 :
856 :
857 : void
858 75 : 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 75 : struct TALER_WithdrawRequestPS req = {
869 75 : .purpose.size = htonl (sizeof(req)),
870 75 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
871 : };
872 :
873 75 : GNUNET_assert (NULL != h_planchets);
874 75 : req.h_planchets = *h_planchets;
875 75 : if (NULL != mask)
876 : {
877 5 : req.mask = *mask;
878 5 : req.max_age_group =
879 5 : TALER_get_age_group (mask,
880 : max_age);
881 : }
882 75 : TALER_amount_hton (&req.amount,
883 : amount);
884 75 : TALER_amount_hton (&req.fee,
885 : fee);
886 75 : if (NULL != blinding_seed)
887 35 : req.blinding_seed = *blinding_seed;
888 :
889 75 : GNUNET_CRYPTO_eddsa_sign (
890 : &reserve_priv->eddsa_priv,
891 : &req,
892 : &reserve_sig->eddsa_signature);
893 :
894 75 : }
895 :
896 :
897 : enum GNUNET_GenericReturnValue
898 82 : 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 82 : struct TALER_WithdrawRequestPS req = {
909 82 : .purpose.size = htonl (sizeof(req)),
910 82 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_WITHDRAW),
911 : };
912 :
913 82 : GNUNET_assert (NULL != h_planchets);
914 82 : req.h_planchets = *h_planchets;
915 82 : if (NULL != mask)
916 : {
917 5 : req.mask = *mask;
918 5 : req.max_age_group =
919 5 : TALER_get_age_group (mask,
920 : max_age);
921 : }
922 82 : TALER_amount_hton (&req.amount,
923 : amount);
924 82 : TALER_amount_hton (&req.fee,
925 : fee);
926 82 : if (NULL != blinding_seed)
927 38 : req.blinding_seed = *blinding_seed;
928 :
929 82 : 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 7 : 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 7 : struct TALER_AccountSetupRequestSignaturePS asap = {
971 7 : .purpose.size = htonl (sizeof (asap)),
972 7 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
973 : };
974 :
975 7 : TALER_amount_hton (&asap.threshold,
976 : balance_threshold);
977 7 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
978 : &asap,
979 : &reserve_sig->eddsa_signature);
980 7 : }
981 :
982 :
983 : enum GNUNET_GenericReturnValue
984 7 : 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 7 : struct TALER_AccountSetupRequestSignaturePS asap = {
990 7 : .purpose.size = htonl (sizeof (asap)),
991 7 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_SETUP)
992 : };
993 :
994 7 : TALER_amount_hton (&asap.threshold,
995 : balance_threshold);
996 7 : 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 8 : 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 16 : struct TALER_ReserveHistoryRequestPS rhr = {
1035 8 : .purpose.size = htonl (sizeof (rhr)),
1036 8 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
1037 8 : .start_off = GNUNET_htonll (start_off)
1038 : };
1039 :
1040 8 : 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 8 : 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 16 : struct TALER_ReserveHistoryRequestPS rhr = {
1055 8 : .purpose.size = htonl (sizeof (rhr)),
1056 8 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_HISTORY),
1057 8 : .start_off = GNUNET_htonll (start_off)
1058 : };
1059 :
1060 8 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
1061 : &rhr,
1062 : &reserve_sig->eddsa_signature);
1063 8 : }
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 4 : 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 8 : struct TALER_CoinHistoryRequestPS rsr = {
1095 4 : .purpose.size = htonl (sizeof (rsr)),
1096 4 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
1097 4 : .start_off = GNUNET_htonll (start_off)
1098 : };
1099 :
1100 4 : 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 4 : 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 8 : struct TALER_CoinHistoryRequestPS rsr = {
1115 4 : .purpose.size = htonl (sizeof (rsr)),
1116 4 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_COIN_HISTORY),
1117 4 : .start_off = GNUNET_htonll (start_off)
1118 : };
1119 :
1120 4 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
1121 : &rsr,
1122 : &coin_sig->eddsa_signature);
1123 4 : }
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 25 : 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 50 : struct TALER_PurseCreatePS pm = {
1181 25 : .purpose.size = htonl (sizeof (pm)),
1182 25 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
1183 25 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1184 : .h_contract_terms = *h_contract_terms,
1185 : .merge_pub = *merge_pub,
1186 25 : .min_age = htonl (min_age)
1187 : };
1188 :
1189 25 : TALER_amount_hton (&pm.purse_amount,
1190 : amount);
1191 25 : GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
1192 : &pm,
1193 : &purse_sig->eddsa_signature);
1194 25 : }
1195 :
1196 :
1197 : enum GNUNET_GenericReturnValue
1198 25 : 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 50 : struct TALER_PurseCreatePS pm = {
1208 25 : .purpose.size = htonl (sizeof (pm)),
1209 25 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_CREATE),
1210 25 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1211 : .h_contract_terms = *h_contract_terms,
1212 : .merge_pub = *merge_pub,
1213 25 : .min_age = htonl (min_age)
1214 : };
1215 :
1216 25 : TALER_amount_hton (&pm.purse_amount,
1217 : amount);
1218 25 : 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 2 : TALER_wallet_purse_delete_sign (
1247 : const struct TALER_PurseContractPrivateKeyP *purse_priv,
1248 : struct TALER_PurseContractSignatureP *purse_sig)
1249 : {
1250 2 : struct TALER_PurseDeletePS pm = {
1251 2 : .purpose.size = htonl (sizeof (pm)),
1252 2 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
1253 : };
1254 :
1255 2 : GNUNET_CRYPTO_eddsa_sign (&purse_priv->eddsa_priv,
1256 : &pm,
1257 : &purse_sig->eddsa_signature);
1258 2 : }
1259 :
1260 :
1261 : enum GNUNET_GenericReturnValue
1262 2 : TALER_wallet_purse_delete_verify (
1263 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1264 : const struct TALER_PurseContractSignatureP *purse_sig)
1265 : {
1266 2 : struct TALER_PurseDeletePS pm = {
1267 2 : .purpose.size = htonl (sizeof (pm)),
1268 2 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DELETE)
1269 : };
1270 :
1271 2 : 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 0 : TALER_wallet_purse_status_sign (
1281 : const struct TALER_PurseContractPrivateKeyP *purse_priv,
1282 : struct TALER_PurseContractSignatureP *purse_sig)
1283 : {
1284 0 : struct GNUNET_CRYPTO_SignaturePurpose purpose = {
1285 0 : .size = htonl (sizeof (purpose)),
1286 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
1287 : };
1288 :
1289 0 : GNUNET_assert (GNUNET_OK ==
1290 : GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
1291 : &purpose,
1292 : &purse_sig->eddsa_signature));
1293 0 : }
1294 :
1295 :
1296 : enum GNUNET_GenericReturnValue
1297 0 : TALER_wallet_purse_status_verify (
1298 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1299 : const struct TALER_PurseContractSignatureP *purse_sig)
1300 : {
1301 0 : struct GNUNET_CRYPTO_SignaturePurpose purpose = {
1302 0 : .size = htonl (sizeof (purpose)),
1303 0 : .purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_STATUS)
1304 : };
1305 :
1306 0 : 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 18 : 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 18 : struct TALER_PurseDepositPS pm = {
1367 18 : .purpose.size = htonl (sizeof (pm)),
1368 18 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
1369 : .purse_pub = *purse_pub,
1370 : .h_denom_pub = *h_denom_pub,
1371 : .h_age_commitment = *h_age_commitment
1372 : };
1373 :
1374 18 : GNUNET_CRYPTO_hash (exchange_base_url,
1375 18 : strlen (exchange_base_url) + 1,
1376 : &pm.h_exchange_base_url);
1377 18 : TALER_amount_hton (&pm.coin_amount,
1378 : amount);
1379 18 : GNUNET_CRYPTO_eddsa_sign (&coin_priv->eddsa_priv,
1380 : &pm,
1381 : &coin_sig->eddsa_signature);
1382 18 : }
1383 :
1384 :
1385 : enum GNUNET_GenericReturnValue
1386 21 : TALER_wallet_purse_deposit_verify (
1387 : const char *exchange_base_url,
1388 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1389 : const struct TALER_Amount *amount,
1390 : const struct TALER_DenominationHashP *h_denom_pub,
1391 : const struct TALER_AgeCommitmentHashP *h_age_commitment,
1392 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1393 : const struct TALER_CoinSpendSignatureP *coin_sig)
1394 : {
1395 21 : struct TALER_PurseDepositPS pm = {
1396 21 : .purpose.size = htonl (sizeof (pm)),
1397 21 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_DEPOSIT),
1398 : .purse_pub = *purse_pub,
1399 : .h_denom_pub = *h_denom_pub,
1400 : .h_age_commitment = *h_age_commitment
1401 : };
1402 :
1403 21 : GNUNET_CRYPTO_hash (exchange_base_url,
1404 21 : strlen (exchange_base_url) + 1,
1405 : &pm.h_exchange_base_url);
1406 21 : TALER_amount_hton (&pm.coin_amount,
1407 : amount);
1408 21 : return GNUNET_CRYPTO_eddsa_verify (
1409 : TALER_SIGNATURE_WALLET_PURSE_DEPOSIT,
1410 : &pm,
1411 : &coin_sig->eddsa_signature,
1412 : &coin_pub->eddsa_pub);
1413 : }
1414 :
1415 :
1416 : GNUNET_NETWORK_STRUCT_BEGIN
1417 :
1418 : /**
1419 : * Message signed to merge a purse into a reserve.
1420 : */
1421 : struct TALER_PurseMergePS
1422 : {
1423 :
1424 : /**
1425 : * Purpose is #TALER_SIGNATURE_WALLET_PURSE_MERGE
1426 : */
1427 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1428 :
1429 : /**
1430 : * Time when the purse is merged into the reserve.
1431 : */
1432 : struct GNUNET_TIME_TimestampNBO merge_timestamp;
1433 :
1434 : /**
1435 : * Which purse is being merged?
1436 : */
1437 : struct TALER_PurseContractPublicKeyP purse_pub;
1438 :
1439 : /**
1440 : * Which reserve should the purse be merged with.
1441 : * Hash of the reserve's payto:// URI.
1442 : */
1443 : struct TALER_NormalizedPaytoHashP h_payto;
1444 :
1445 : };
1446 :
1447 : GNUNET_NETWORK_STRUCT_END
1448 :
1449 : void
1450 20 : TALER_wallet_purse_merge_sign (
1451 : const struct TALER_NormalizedPayto reserve_uri,
1452 : struct GNUNET_TIME_Timestamp merge_timestamp,
1453 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1454 : const struct TALER_PurseMergePrivateKeyP *merge_priv,
1455 : struct TALER_PurseMergeSignatureP *merge_sig)
1456 : {
1457 40 : struct TALER_PurseMergePS pm = {
1458 20 : .purpose.size = htonl (sizeof (pm)),
1459 20 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
1460 20 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1461 : .purse_pub = *purse_pub
1462 : };
1463 :
1464 20 : GNUNET_assert (0 ==
1465 : strncasecmp (reserve_uri.normalized_payto,
1466 : "payto://taler-reserve",
1467 : strlen ("payto://taler-reserve")));
1468 20 : TALER_normalized_payto_hash (reserve_uri,
1469 : &pm.h_payto);
1470 20 : GNUNET_CRYPTO_eddsa_sign (&merge_priv->eddsa_priv,
1471 : &pm,
1472 : &merge_sig->eddsa_signature);
1473 20 : }
1474 :
1475 :
1476 : enum GNUNET_GenericReturnValue
1477 22 : TALER_wallet_purse_merge_verify (
1478 : const struct TALER_NormalizedPayto reserve_uri,
1479 : struct GNUNET_TIME_Timestamp merge_timestamp,
1480 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1481 : const struct TALER_PurseMergePublicKeyP *merge_pub,
1482 : const struct TALER_PurseMergeSignatureP *merge_sig)
1483 : {
1484 44 : struct TALER_PurseMergePS pm = {
1485 22 : .purpose.size = htonl (sizeof (pm)),
1486 22 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_MERGE),
1487 22 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1488 : .purse_pub = *purse_pub
1489 : };
1490 :
1491 22 : if (0 !=
1492 22 : strncasecmp (reserve_uri.normalized_payto,
1493 : "payto://taler-reserve",
1494 : strlen ("payto://taler-reserve")))
1495 : {
1496 0 : GNUNET_break (0);
1497 0 : return GNUNET_NO;
1498 : }
1499 22 : TALER_normalized_payto_hash (reserve_uri,
1500 : &pm.h_payto);
1501 22 : return GNUNET_CRYPTO_eddsa_verify (
1502 : TALER_SIGNATURE_WALLET_PURSE_MERGE,
1503 : &pm,
1504 : &merge_sig->eddsa_signature,
1505 : &merge_pub->eddsa_pub);
1506 : }
1507 :
1508 :
1509 : GNUNET_NETWORK_STRUCT_BEGIN
1510 :
1511 : /**
1512 : * Message signed by account to merge a purse into a reserve.
1513 : */
1514 : struct TALER_AccountMergePS
1515 : {
1516 :
1517 : /**
1518 : * Purpose is #TALER_SIGNATURE_WALLET_ACCOUNT_MERGE
1519 : */
1520 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1521 :
1522 : /**
1523 : * Time when the purse will expire if still unmerged or unpaid.
1524 : */
1525 : struct GNUNET_TIME_TimestampNBO purse_expiration;
1526 :
1527 : /**
1528 : * Total amount (with fees) to be put into the purse.
1529 : */
1530 : struct TALER_AmountNBO purse_amount;
1531 :
1532 : /**
1533 : * Purse creation fee to be paid by the reserve for
1534 : * this operation.
1535 : */
1536 : struct TALER_AmountNBO purse_fee;
1537 :
1538 : /**
1539 : * Contract this purse pays for.
1540 : */
1541 : struct TALER_PrivateContractHashP h_contract_terms;
1542 :
1543 : /**
1544 : * Purse to merge.
1545 : */
1546 : struct TALER_PurseContractPublicKeyP purse_pub;
1547 :
1548 : /**
1549 : * Time when the purse is merged into the reserve.
1550 : */
1551 : struct GNUNET_TIME_TimestampNBO merge_timestamp;
1552 :
1553 : /**
1554 : * Minimum age required for payments into this purse,
1555 : * in NBO.
1556 : */
1557 : uint32_t min_age GNUNET_PACKED;
1558 :
1559 : /**
1560 : * Flags for the operation, in NBO. See
1561 : * `enum TALER_WalletAccountMergeFlags`.
1562 : */
1563 : uint32_t flags GNUNET_PACKED;
1564 : };
1565 :
1566 : GNUNET_NETWORK_STRUCT_END
1567 :
1568 :
1569 : void
1570 20 : TALER_wallet_account_merge_sign (
1571 : struct GNUNET_TIME_Timestamp merge_timestamp,
1572 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1573 : struct GNUNET_TIME_Timestamp purse_expiration,
1574 : const struct TALER_PrivateContractHashP *h_contract_terms,
1575 : const struct TALER_Amount *amount,
1576 : const struct TALER_Amount *purse_fee,
1577 : uint32_t min_age,
1578 : enum TALER_WalletAccountMergeFlags flags,
1579 : const struct TALER_ReservePrivateKeyP *reserve_priv,
1580 : struct TALER_ReserveSignatureP *reserve_sig)
1581 : {
1582 60 : struct TALER_AccountMergePS pm = {
1583 20 : .purpose.size = htonl (sizeof (pm)),
1584 20 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
1585 20 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1586 : .purse_pub = *purse_pub,
1587 20 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1588 : .h_contract_terms = *h_contract_terms,
1589 20 : .min_age = htonl (min_age),
1590 20 : .flags = htonl ((uint32_t) flags)
1591 : };
1592 :
1593 20 : TALER_amount_hton (&pm.purse_amount,
1594 : amount);
1595 20 : TALER_amount_hton (&pm.purse_fee,
1596 : purse_fee);
1597 20 : GNUNET_CRYPTO_eddsa_sign (&reserve_priv->eddsa_priv,
1598 : &pm,
1599 : &reserve_sig->eddsa_signature);
1600 20 : }
1601 :
1602 :
1603 : enum GNUNET_GenericReturnValue
1604 28 : TALER_wallet_account_merge_verify (
1605 : struct GNUNET_TIME_Timestamp merge_timestamp,
1606 : const struct TALER_PurseContractPublicKeyP *purse_pub,
1607 : struct GNUNET_TIME_Timestamp purse_expiration,
1608 : const struct TALER_PrivateContractHashP *h_contract_terms,
1609 : const struct TALER_Amount *amount,
1610 : const struct TALER_Amount *purse_fee,
1611 : uint32_t min_age,
1612 : enum TALER_WalletAccountMergeFlags flags,
1613 : const struct TALER_ReservePublicKeyP *reserve_pub,
1614 : const struct TALER_ReserveSignatureP *reserve_sig)
1615 : {
1616 84 : struct TALER_AccountMergePS pm = {
1617 28 : .purpose.size = htonl (sizeof (pm)),
1618 28 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ACCOUNT_MERGE),
1619 28 : .merge_timestamp = GNUNET_TIME_timestamp_hton (merge_timestamp),
1620 : .purse_pub = *purse_pub,
1621 28 : .purse_expiration = GNUNET_TIME_timestamp_hton (purse_expiration),
1622 : .h_contract_terms = *h_contract_terms,
1623 28 : .min_age = htonl (min_age),
1624 28 : .flags = htonl ((uint32_t) flags)
1625 : };
1626 :
1627 28 : TALER_amount_hton (&pm.purse_amount,
1628 : amount);
1629 28 : TALER_amount_hton (&pm.purse_fee,
1630 : purse_fee);
1631 28 : return GNUNET_CRYPTO_eddsa_verify (
1632 : TALER_SIGNATURE_WALLET_ACCOUNT_MERGE,
1633 : &pm,
1634 : &reserve_sig->eddsa_signature,
1635 : &reserve_pub->eddsa_pub);
1636 : }
1637 :
1638 :
1639 : GNUNET_NETWORK_STRUCT_BEGIN
1640 :
1641 : /**
1642 : * Message signed by reserve key.
1643 : */
1644 : struct TALER_ReserveOpenPS
1645 : {
1646 :
1647 : /**
1648 : * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN
1649 : */
1650 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1651 :
1652 : /**
1653 : * Amount to be paid from the reserve balance to open
1654 : * the reserve.
1655 : */
1656 : struct TALER_AmountNBO reserve_payment;
1657 :
1658 : /**
1659 : * When was the request created.
1660 : */
1661 : struct GNUNET_TIME_TimestampNBO request_timestamp;
1662 :
1663 : /**
1664 : * For how long should the reserve be kept open.
1665 : * (Determines amount to be paid.)
1666 : */
1667 : struct GNUNET_TIME_TimestampNBO reserve_expiration;
1668 :
1669 : /**
1670 : * How many open purses should be included with the
1671 : * open reserve?
1672 : * (Determines amount to be paid.)
1673 : */
1674 : uint32_t purse_limit GNUNET_PACKED;
1675 :
1676 : };
1677 :
1678 : GNUNET_NETWORK_STRUCT_END
1679 :
1680 :
1681 : void
1682 6 : TALER_wallet_reserve_open_sign (
1683 : const struct TALER_Amount *reserve_payment,
1684 : struct GNUNET_TIME_Timestamp request_timestamp,
1685 : struct GNUNET_TIME_Timestamp reserve_expiration,
1686 : uint32_t purse_limit,
1687 : const struct TALER_ReservePrivateKeyP *reserve_priv,
1688 : struct TALER_ReserveSignatureP *reserve_sig)
1689 : {
1690 12 : struct TALER_ReserveOpenPS rop = {
1691 6 : .purpose.size = htonl (sizeof (rop)),
1692 6 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
1693 6 : .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
1694 6 : .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
1695 6 : .purse_limit = htonl (purse_limit)
1696 : };
1697 :
1698 6 : TALER_amount_hton (&rop.reserve_payment,
1699 : reserve_payment);
1700 6 : GNUNET_assert (GNUNET_OK ==
1701 : GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
1702 : &rop.purpose,
1703 : &reserve_sig->eddsa_signature));
1704 6 : }
1705 :
1706 :
1707 : enum GNUNET_GenericReturnValue
1708 6 : TALER_wallet_reserve_open_verify (
1709 : const struct TALER_Amount *reserve_payment,
1710 : struct GNUNET_TIME_Timestamp request_timestamp,
1711 : struct GNUNET_TIME_Timestamp reserve_expiration,
1712 : uint32_t purse_limit,
1713 : const struct TALER_ReservePublicKeyP *reserve_pub,
1714 : const struct TALER_ReserveSignatureP *reserve_sig)
1715 : {
1716 12 : struct TALER_ReserveOpenPS rop = {
1717 6 : .purpose.size = htonl (sizeof (rop)),
1718 6 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN),
1719 6 : .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp),
1720 6 : .reserve_expiration = GNUNET_TIME_timestamp_hton (reserve_expiration),
1721 6 : .purse_limit = htonl (purse_limit)
1722 : };
1723 :
1724 6 : TALER_amount_hton (&rop.reserve_payment,
1725 : reserve_payment);
1726 6 : return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_OPEN,
1727 : &rop.purpose,
1728 : &reserve_sig->eddsa_signature,
1729 : &reserve_pub->eddsa_pub);
1730 : }
1731 :
1732 :
1733 : GNUNET_NETWORK_STRUCT_BEGIN
1734 :
1735 : /**
1736 : * Message signed by
1737 : */
1738 : struct TALER_ReserveOpenDepositPS
1739 : {
1740 :
1741 : /**
1742 : * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT
1743 : */
1744 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1745 :
1746 : /**
1747 : * Which reserve's opening signature should be paid for?
1748 : */
1749 : struct TALER_ReserveSignatureP reserve_sig;
1750 :
1751 : /**
1752 : * Specifies how much of the coin's value should be spent on opening this
1753 : * reserve.
1754 : */
1755 : struct TALER_AmountNBO coin_contribution;
1756 : };
1757 :
1758 : GNUNET_NETWORK_STRUCT_END
1759 :
1760 :
1761 : // FIXME-#11318: add h_age_commitment, h_denom_pub to have proof!
1762 : void
1763 2 : TALER_wallet_reserve_open_deposit_sign (
1764 : const struct TALER_Amount *coin_contribution,
1765 : const struct TALER_ReserveSignatureP *reserve_sig,
1766 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
1767 : struct TALER_CoinSpendSignatureP *coin_sig)
1768 : {
1769 2 : struct TALER_ReserveOpenDepositPS rod = {
1770 2 : .purpose.size = htonl (sizeof (rod)),
1771 2 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
1772 : .reserve_sig = *reserve_sig
1773 : };
1774 :
1775 2 : TALER_amount_hton (&rod.coin_contribution,
1776 : coin_contribution);
1777 2 : GNUNET_assert (GNUNET_OK ==
1778 : GNUNET_CRYPTO_eddsa_sign_ (&coin_priv->eddsa_priv,
1779 : &rod.purpose,
1780 : &coin_sig->eddsa_signature));
1781 2 : }
1782 :
1783 :
1784 : enum GNUNET_GenericReturnValue
1785 0 : TALER_wallet_reserve_open_deposit_verify (
1786 : const struct TALER_Amount *coin_contribution,
1787 : const struct TALER_ReserveSignatureP *reserve_sig,
1788 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
1789 : const struct TALER_CoinSpendSignatureP *coin_sig)
1790 : {
1791 0 : struct TALER_ReserveOpenDepositPS rod = {
1792 0 : .purpose.size = htonl (sizeof (rod)),
1793 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT),
1794 : .reserve_sig = *reserve_sig
1795 : };
1796 :
1797 0 : TALER_amount_hton (&rod.coin_contribution,
1798 : coin_contribution);
1799 0 : return GNUNET_CRYPTO_eddsa_verify_ (
1800 : TALER_SIGNATURE_WALLET_RESERVE_OPEN_DEPOSIT,
1801 : &rod.purpose,
1802 : &coin_sig->eddsa_signature,
1803 : &coin_pub->eddsa_pub);
1804 : }
1805 :
1806 :
1807 : GNUNET_NETWORK_STRUCT_BEGIN
1808 :
1809 : /**
1810 : * Message signed by reserve key.
1811 : */
1812 : struct TALER_ReserveClosePS
1813 : {
1814 :
1815 : /**
1816 : * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_CLOSE
1817 : */
1818 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1819 :
1820 : /**
1821 : * When was the request created.
1822 : */
1823 : struct GNUNET_TIME_TimestampNBO request_timestamp;
1824 :
1825 : /**
1826 : * Hash of the payto://-URI of the target account
1827 : * for the closure, or all zeros for the reserve
1828 : * origin account.
1829 : */
1830 : struct TALER_FullPaytoHashP target_account_h_payto;
1831 :
1832 : };
1833 :
1834 : GNUNET_NETWORK_STRUCT_END
1835 :
1836 :
1837 : void
1838 4 : TALER_wallet_reserve_close_sign (
1839 : struct GNUNET_TIME_Timestamp request_timestamp,
1840 : const struct TALER_FullPaytoHashP *h_payto,
1841 : const struct TALER_ReservePrivateKeyP *reserve_priv,
1842 : struct TALER_ReserveSignatureP *reserve_sig)
1843 : {
1844 4 : struct TALER_ReserveClosePS rcp = {
1845 4 : .purpose.size = htonl (sizeof (rcp)),
1846 4 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
1847 4 : .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
1848 : };
1849 :
1850 4 : if (NULL != h_payto)
1851 4 : rcp.target_account_h_payto = *h_payto;
1852 4 : GNUNET_assert (GNUNET_OK ==
1853 : GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
1854 : &rcp.purpose,
1855 : &reserve_sig->eddsa_signature));
1856 4 : }
1857 :
1858 :
1859 : enum GNUNET_GenericReturnValue
1860 4 : TALER_wallet_reserve_close_verify (
1861 : struct GNUNET_TIME_Timestamp request_timestamp,
1862 : const struct TALER_FullPaytoHashP *h_payto,
1863 : const struct TALER_ReservePublicKeyP *reserve_pub,
1864 : const struct TALER_ReserveSignatureP *reserve_sig)
1865 : {
1866 4 : struct TALER_ReserveClosePS rcp = {
1867 4 : .purpose.size = htonl (sizeof (rcp)),
1868 4 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
1869 4 : .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
1870 : };
1871 :
1872 4 : if (NULL != h_payto)
1873 4 : rcp.target_account_h_payto = *h_payto;
1874 4 : return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_RESERVE_CLOSE,
1875 : &rcp.purpose,
1876 : &reserve_sig->eddsa_signature,
1877 : &reserve_pub->eddsa_pub);
1878 : }
1879 :
1880 :
1881 : GNUNET_NETWORK_STRUCT_BEGIN
1882 :
1883 : /**
1884 : * Message signed by reserve private key.
1885 : */
1886 : struct TALER_ReserveAttestRequestPS
1887 : {
1888 :
1889 : /**
1890 : * Purpose is #TALER_SIGNATURE_WALLET_ATTEST_REQUEST
1891 : */
1892 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1893 :
1894 : /**
1895 : * When was the request created.
1896 : */
1897 : struct GNUNET_TIME_TimestampNBO request_timestamp;
1898 :
1899 : /**
1900 : * Hash over the JSON array of requested attributes.
1901 : */
1902 : struct GNUNET_HashCode h_details;
1903 :
1904 : };
1905 :
1906 : GNUNET_NETWORK_STRUCT_END
1907 :
1908 :
1909 : void
1910 1 : TALER_wallet_reserve_attest_request_sign (
1911 : struct GNUNET_TIME_Timestamp request_timestamp,
1912 : const json_t *details,
1913 : const struct TALER_ReservePrivateKeyP *reserve_priv,
1914 : struct TALER_ReserveSignatureP *reserve_sig)
1915 : {
1916 1 : struct TALER_ReserveAttestRequestPS rcp = {
1917 1 : .purpose.size = htonl (sizeof (rcp)),
1918 1 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
1919 1 : .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
1920 : };
1921 :
1922 1 : TALER_json_hash (details,
1923 : &rcp.h_details);
1924 1 : GNUNET_assert (GNUNET_OK ==
1925 : GNUNET_CRYPTO_eddsa_sign_ (&reserve_priv->eddsa_priv,
1926 : &rcp.purpose,
1927 : &reserve_sig->eddsa_signature));
1928 1 : }
1929 :
1930 :
1931 : enum GNUNET_GenericReturnValue
1932 1 : TALER_wallet_reserve_attest_request_verify (
1933 : struct GNUNET_TIME_Timestamp request_timestamp,
1934 : const json_t *details,
1935 : const struct TALER_ReservePublicKeyP *reserve_pub,
1936 : const struct TALER_ReserveSignatureP *reserve_sig)
1937 : {
1938 1 : struct TALER_ReserveAttestRequestPS rcp = {
1939 1 : .purpose.size = htonl (sizeof (rcp)),
1940 1 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS),
1941 1 : .request_timestamp = GNUNET_TIME_timestamp_hton (request_timestamp)
1942 : };
1943 :
1944 1 : TALER_json_hash (details,
1945 : &rcp.h_details);
1946 1 : return GNUNET_CRYPTO_eddsa_verify_ (
1947 : TALER_SIGNATURE_WALLET_RESERVE_ATTEST_DETAILS,
1948 : &rcp.purpose,
1949 : &reserve_sig->eddsa_signature,
1950 : &reserve_pub->eddsa_pub);
1951 : }
1952 :
1953 :
1954 : GNUNET_NETWORK_STRUCT_BEGIN
1955 :
1956 : /**
1957 : * Message signed by purse to associate an encrypted contract.
1958 : */
1959 : struct TALER_PurseContractPS
1960 : {
1961 :
1962 : /**
1963 : * Purpose is #TALER_SIGNATURE_WALLET_PURSE_ECONTRACT
1964 : */
1965 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
1966 :
1967 : /**
1968 : * Hash over the encrypted contract.
1969 : */
1970 : struct GNUNET_HashCode h_econtract;
1971 :
1972 : /**
1973 : * Public key to decrypt the contract.
1974 : */
1975 : struct TALER_ContractDiffiePublicP contract_pub;
1976 : };
1977 :
1978 : GNUNET_NETWORK_STRUCT_END
1979 :
1980 : void
1981 25 : TALER_wallet_econtract_upload_sign (
1982 : const void *econtract,
1983 : size_t econtract_size,
1984 : const struct TALER_ContractDiffiePublicP *contract_pub,
1985 : const struct TALER_PurseContractPrivateKeyP *purse_priv,
1986 : struct TALER_PurseContractSignatureP *purse_sig)
1987 : {
1988 25 : struct TALER_PurseContractPS pc = {
1989 25 : .purpose.size = htonl (sizeof (pc)),
1990 25 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
1991 : .contract_pub = *contract_pub
1992 : };
1993 :
1994 25 : GNUNET_CRYPTO_hash (econtract,
1995 : econtract_size,
1996 : &pc.h_econtract);
1997 25 : GNUNET_assert (GNUNET_OK ==
1998 : GNUNET_CRYPTO_eddsa_sign_ (&purse_priv->eddsa_priv,
1999 : &pc.purpose,
2000 : &purse_sig->eddsa_signature));
2001 25 : }
2002 :
2003 :
2004 : enum GNUNET_GenericReturnValue
2005 31 : TALER_wallet_econtract_upload_verify2 (
2006 : const struct GNUNET_HashCode *h_econtract,
2007 : const struct TALER_ContractDiffiePublicP *contract_pub,
2008 : const struct TALER_PurseContractPublicKeyP *purse_pub,
2009 : const struct TALER_PurseContractSignatureP *purse_sig)
2010 : {
2011 31 : struct TALER_PurseContractPS pc = {
2012 31 : .purpose.size = htonl (sizeof (pc)),
2013 31 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT),
2014 : .contract_pub = *contract_pub,
2015 : .h_econtract = *h_econtract
2016 : };
2017 :
2018 31 : return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_PURSE_ECONTRACT,
2019 : &pc.purpose,
2020 : &purse_sig->eddsa_signature,
2021 : &purse_pub->eddsa_pub);
2022 : }
2023 :
2024 :
2025 : enum GNUNET_GenericReturnValue
2026 31 : TALER_wallet_econtract_upload_verify (
2027 : const void *econtract,
2028 : size_t econtract_size,
2029 : const struct TALER_ContractDiffiePublicP *contract_pub,
2030 : const struct TALER_PurseContractPublicKeyP *purse_pub,
2031 : const struct TALER_PurseContractSignatureP *purse_sig)
2032 : {
2033 : struct GNUNET_HashCode h_econtract;
2034 :
2035 31 : GNUNET_CRYPTO_hash (econtract,
2036 : econtract_size,
2037 : &h_econtract);
2038 31 : return TALER_wallet_econtract_upload_verify2 (&h_econtract,
2039 : contract_pub,
2040 : purse_pub,
2041 : purse_sig);
2042 : }
2043 :
2044 :
2045 : GNUNET_NETWORK_STRUCT_BEGIN
2046 :
2047 : /**
2048 : * Message signed by wallet to confirm usage of a token for a transaction.
2049 : */
2050 : struct TALER_TokenUseRequestPS
2051 : {
2052 :
2053 : /**
2054 : * Purpose is #TALER_SIGNATURE_WALLET_TOKEN_USE
2055 : */
2056 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
2057 :
2058 : /**
2059 : * Hash over the contract for which this token is used.
2060 : */
2061 : struct TALER_PrivateContractHashP h_contract_terms GNUNET_PACKED;
2062 :
2063 : /**
2064 : * Hash over a JSON containing data provided by the
2065 : * wallet to complete the contract upon payment.
2066 : */
2067 : struct GNUNET_HashCode wallet_data_hash;
2068 :
2069 : };
2070 :
2071 : GNUNET_NETWORK_STRUCT_END
2072 :
2073 :
2074 : void
2075 0 : TALER_wallet_token_use_sign (
2076 : const struct TALER_PrivateContractHashP *h_contract_terms,
2077 : const struct GNUNET_HashCode *wallet_data_hash,
2078 : const struct TALER_TokenUsePrivateKeyP *token_use_priv,
2079 : struct TALER_TokenUseSignatureP *token_sig)
2080 : {
2081 0 : struct TALER_TokenUseRequestPS tur = {
2082 0 : .purpose.size = htonl (sizeof (tur)),
2083 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE),
2084 : .h_contract_terms = *h_contract_terms,
2085 : .wallet_data_hash = *wallet_data_hash
2086 : };
2087 :
2088 0 : GNUNET_CRYPTO_eddsa_sign (&token_use_priv->private_key,
2089 : &tur,
2090 : &token_sig->signature);
2091 0 : }
2092 :
2093 :
2094 : enum GNUNET_GenericReturnValue
2095 0 : TALER_wallet_token_use_verify (
2096 : const struct TALER_PrivateContractHashP *h_contract_terms,
2097 : const struct GNUNET_HashCode *wallet_data_hash,
2098 : const struct TALER_TokenUsePublicKeyP *token_use_pub,
2099 : const struct TALER_TokenUseSignatureP *token_sig)
2100 : {
2101 0 : struct TALER_TokenUseRequestPS tur = {
2102 0 : .purpose.size = htonl (sizeof (tur)),
2103 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_TOKEN_USE),
2104 : .h_contract_terms = *h_contract_terms,
2105 : .wallet_data_hash = *wallet_data_hash
2106 : };
2107 :
2108 0 : return GNUNET_CRYPTO_eddsa_verify (TALER_SIGNATURE_WALLET_TOKEN_USE,
2109 : &tur,
2110 : &token_sig->signature,
2111 : &token_use_pub->public_key);
2112 : }
2113 :
2114 :
2115 : GNUNET_NETWORK_STRUCT_BEGIN
2116 :
2117 : /**
2118 : * Message signed by reserve key.
2119 : */
2120 : struct TALER_OrderUnclaimPS
2121 : {
2122 :
2123 : /**
2124 : * Purpose is #TALER_SIGNATURE_WALLET_ORDER_UNCLAIM
2125 : */
2126 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
2127 :
2128 : /**
2129 : * Hash of the contract being unclaimed.
2130 : */
2131 : struct GNUNET_HashCode h_contract;
2132 :
2133 : };
2134 :
2135 : GNUNET_NETWORK_STRUCT_END
2136 :
2137 :
2138 : void
2139 0 : TALER_wallet_order_unclaim_sign (
2140 : const struct GNUNET_HashCode *h_contract,
2141 : const struct GNUNET_CRYPTO_EddsaPrivateKey *nonce_priv,
2142 : struct GNUNET_CRYPTO_EddsaSignature *nsig)
2143 : {
2144 0 : struct TALER_OrderUnclaimPS rcp = {
2145 0 : .purpose.size = htonl (sizeof (rcp)),
2146 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM),
2147 : .h_contract = *h_contract
2148 : };
2149 :
2150 0 : GNUNET_assert (GNUNET_OK ==
2151 : GNUNET_CRYPTO_eddsa_sign_ (nonce_priv,
2152 : &rcp.purpose,
2153 : nsig));
2154 0 : }
2155 :
2156 :
2157 : enum GNUNET_GenericReturnValue
2158 0 : TALER_wallet_order_unclaim_verify (
2159 : const struct GNUNET_HashCode *h_contract,
2160 : const struct GNUNET_CRYPTO_EddsaPublicKey *nonce,
2161 : const struct GNUNET_CRYPTO_EddsaSignature *nsig)
2162 : {
2163 0 : struct TALER_OrderUnclaimPS rcp = {
2164 0 : .purpose.size = htonl (sizeof (rcp)),
2165 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_CLOSE),
2166 : .h_contract = *h_contract
2167 : };
2168 :
2169 0 : return GNUNET_CRYPTO_eddsa_verify_ (TALER_SIGNATURE_WALLET_ORDER_UNCLAIM,
2170 : &rcp.purpose,
2171 : nsig,
2172 : nonce);
2173 : }
2174 :
2175 :
2176 : GNUNET_NETWORK_STRUCT_BEGIN
2177 :
2178 : /**
2179 : * Message signed by reserve map authorization key.
2180 : */
2181 : struct TALER_ReserveMapAuthorizationPS
2182 : {
2183 :
2184 : /**
2185 : * Purpose is #TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION
2186 : */
2187 : struct GNUNET_CRYPTO_SignaturePurpose purpose;
2188 :
2189 : /**
2190 : * Account key to associate with the authorization key subject.
2191 : */
2192 : union TALER_AccountPublicKeyP account_pub;
2193 :
2194 : };
2195 :
2196 : GNUNET_NETWORK_STRUCT_END
2197 :
2198 :
2199 : void
2200 0 : TALER_wallet_reserve_map_authorization_sign (
2201 : const union TALER_AccountPublicKeyP *account_pub,
2202 : const struct TALER_ReserveMapAuthorizationPrivateKeyP *auth_priv,
2203 : struct TALER_ReserveMapAuthorizationSignatureP *auth_sig)
2204 : {
2205 0 : struct TALER_ReserveMapAuthorizationPS rcp = {
2206 0 : .purpose.size = htonl (sizeof (rcp)),
2207 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION),
2208 : .account_pub = *account_pub
2209 : };
2210 :
2211 0 : GNUNET_assert (GNUNET_OK ==
2212 : GNUNET_CRYPTO_eddsa_sign_ (
2213 : &auth_priv->eddsa_priv,
2214 : &rcp.purpose,
2215 : &auth_sig->eddsa_signature));
2216 0 : }
2217 :
2218 :
2219 : enum GNUNET_GenericReturnValue
2220 0 : TALER_wallet_reserve_map_authorization_verify (
2221 : const union TALER_AccountPublicKeyP *account_pub,
2222 : const struct TALER_ReserveMapAuthorizationPublicKeyP *auth_pub,
2223 : const struct TALER_ReserveMapAuthorizationSignatureP *auth_sig)
2224 : {
2225 0 : struct TALER_ReserveMapAuthorizationPS rcp = {
2226 0 : .purpose.size = htonl (sizeof (rcp)),
2227 0 : .purpose.purpose = htonl (TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION),
2228 : .account_pub = *account_pub
2229 : };
2230 :
2231 0 : return GNUNET_CRYPTO_eddsa_verify_ (
2232 : TALER_SIGNATURE_WALLET_RESERVE_MAP_AUTHORIZATION,
2233 : &rcp.purpose,
2234 : &auth_sig->eddsa_signature,
2235 : &auth_pub->eddsa_pub);
2236 : }
2237 :
2238 :
2239 : /* end of wallet_signatures.c */
|