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