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