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