Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2014-2022 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 util/crypto.c
18 : * @brief Cryptographic utility functions
19 : * @author Sree Harsha Totakura <sreeharsha@totakura.in>
20 : * @author Florian Dold
21 : * @author Benedikt Mueller
22 : * @author Christian Grothoff
23 : * @author Özgür Kesim
24 : */
25 : #include "platform.h"
26 : #include "taler/taler_util.h"
27 : #include <gcrypt.h>
28 :
29 : /**
30 : * Function called by libgcrypt on serious errors.
31 : * Prints an error message and aborts the process.
32 : *
33 : * @param cls NULL
34 : * @param wtf unknown
35 : * @param msg error message
36 : */
37 : static void
38 0 : fatal_error_handler (void *cls,
39 : int wtf,
40 : const char *msg)
41 : {
42 : (void) cls;
43 : (void) wtf;
44 0 : fprintf (stderr,
45 : "Fatal error in libgcrypt: %s\n",
46 : msg);
47 0 : abort ();
48 : }
49 :
50 :
51 : /**
52 : * Initialize libgcrypt.
53 : */
54 : void __attribute__ ((constructor))
55 642 : TALER_gcrypt_init ()
56 : {
57 642 : gcry_set_fatalerror_handler (&fatal_error_handler,
58 : NULL);
59 642 : if (! gcry_check_version (NEED_LIBGCRYPT_VERSION))
60 : {
61 0 : fprintf (stderr,
62 : "libgcrypt version mismatch\n");
63 0 : abort ();
64 : }
65 : /* Disable secure memory (we should never run on a system that
66 : even uses swap space for memory). */
67 642 : gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
68 642 : gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
69 642 : }
70 :
71 :
72 : enum GNUNET_GenericReturnValue
73 250 : TALER_test_coin_valid (const struct TALER_CoinPublicInfo *coin_public_info,
74 : const struct TALER_DenominationPublicKey *denom_pub)
75 : {
76 : struct TALER_CoinPubHashP c_hash;
77 : #if ENABLE_SANITY_CHECKS
78 : struct TALER_DenominationHashP d_hash;
79 :
80 250 : TALER_denom_pub_hash (denom_pub,
81 : &d_hash);
82 250 : GNUNET_assert (0 ==
83 : GNUNET_memcmp (&d_hash,
84 : &coin_public_info->denom_pub_hash));
85 : #endif
86 :
87 250 : TALER_coin_pub_hash (&coin_public_info->coin_pub,
88 250 : coin_public_info->no_age_commitment
89 : ? NULL
90 : : &coin_public_info->h_age_commitment,
91 : &c_hash);
92 :
93 250 : if (GNUNET_OK !=
94 250 : TALER_denom_pub_verify (denom_pub,
95 : &coin_public_info->denom_sig,
96 : &c_hash))
97 : {
98 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
99 : "coin signature is invalid\n");
100 0 : return GNUNET_NO;
101 : }
102 250 : return GNUNET_YES;
103 : }
104 :
105 :
106 : void
107 1 : TALER_link_derive_transfer_secret (
108 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
109 : const struct TALER_TransferPrivateKeyP *trans_priv,
110 : struct TALER_TransferSecretP *ts)
111 : {
112 : struct TALER_CoinSpendPublicKeyP coin_pub;
113 :
114 1 : GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
115 : &coin_pub.eddsa_pub);
116 1 : GNUNET_assert (GNUNET_OK ==
117 : GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
118 : &coin_pub.eddsa_pub,
119 : &ts->key));
120 1 : }
121 :
122 :
123 : void
124 641 : TALER_link_reveal_transfer_secret (
125 : const struct TALER_TransferPrivateKeyP *trans_priv,
126 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
127 : struct TALER_TransferSecretP *transfer_secret)
128 : {
129 641 : GNUNET_assert (GNUNET_OK ==
130 : GNUNET_CRYPTO_ecdh_eddsa (&trans_priv->ecdhe_priv,
131 : &coin_pub->eddsa_pub,
132 : &transfer_secret->key));
133 641 : }
134 :
135 :
136 : void
137 1 : TALER_link_recover_transfer_secret (
138 : const struct TALER_TransferPublicKeyP *trans_pub,
139 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
140 : struct TALER_TransferSecretP *transfer_secret)
141 : {
142 1 : GNUNET_assert (GNUNET_OK ==
143 : GNUNET_CRYPTO_eddsa_ecdh (&coin_priv->eddsa_priv,
144 : &trans_pub->ecdhe_pub,
145 : &transfer_secret->key));
146 1 : }
147 :
148 :
149 : void
150 112 : TALER_withdraw_expand_secrets (
151 : size_t num_coins,
152 : const struct TALER_WithdrawMasterSeedP *seed,
153 : struct TALER_PlanchetMasterSecretP secrets[static num_coins])
154 112 : {
155 : _Static_assert (sizeof(seed->seed_data) == sizeof(secrets->key_data));
156 112 : GNUNET_assert (0 < num_coins);
157 :
158 112 : if (1 == num_coins)
159 : {
160 93 : GNUNET_memcpy (&secrets[0].key_data,
161 : &seed->seed_data,
162 : sizeof(secrets[0].key_data));
163 : }
164 : else
165 : {
166 19 : uint32_t be_salt = htonl (num_coins);
167 :
168 19 : GNUNET_assert (GNUNET_OK ==
169 : GNUNET_CRYPTO_hkdf_gnunet (
170 : secrets,
171 : sizeof (*secrets) * num_coins,
172 : &be_salt,
173 : sizeof (be_salt),
174 : seed,
175 : sizeof (*seed),
176 : GNUNET_CRYPTO_kdf_arg_string ("taler-withdraw-secrets")));
177 : }
178 112 : }
179 :
180 :
181 : void
182 5 : TALER_withdraw_expand_kappa_seed (
183 : const struct TALER_WithdrawMasterSeedP *seed,
184 : struct TALER_KappaWithdrawMasterSeedP *seeds)
185 : {
186 5 : uint32_t be_salt = htonl (TALER_CNC_KAPPA);
187 :
188 5 : GNUNET_assert (GNUNET_OK ==
189 : GNUNET_CRYPTO_hkdf_gnunet (
190 : seeds,
191 : sizeof (*seeds),
192 : &be_salt,
193 : sizeof (be_salt),
194 : seed,
195 : sizeof (*seed),
196 : GNUNET_CRYPTO_kdf_arg_string ("taler-kappa-seeds")));
197 5 : }
198 :
199 :
200 : void
201 9 : TALER_planchet_master_setup_random (
202 : struct TALER_PlanchetMasterSecretP *ps)
203 : {
204 9 : GNUNET_CRYPTO_random_block (ps,
205 : sizeof (*ps));
206 9 : }
207 :
208 :
209 : void
210 87 : TALER_withdraw_master_seed_setup_random (
211 : struct TALER_WithdrawMasterSeedP *seed)
212 : {
213 87 : GNUNET_CRYPTO_random_block (seed,
214 : sizeof (*seed));
215 87 : }
216 :
217 :
218 : void
219 22 : TALER_refresh_master_setup_random (
220 : struct TALER_PublicRefreshMasterSeedP *rms)
221 : {
222 22 : GNUNET_CRYPTO_random_block (rms,
223 : sizeof (*rms));
224 22 : }
225 :
226 :
227 : void
228 642 : TALER_transfer_secret_to_planchet_secret (
229 : const struct TALER_TransferSecretP *secret_seed,
230 : uint32_t coin_num_salt,
231 : struct TALER_PlanchetMasterSecretP *ps)
232 : {
233 642 : uint32_t be_salt = htonl (coin_num_salt);
234 :
235 642 : GNUNET_assert (GNUNET_OK ==
236 : GNUNET_CRYPTO_hkdf_gnunet (
237 : ps,
238 : sizeof (*ps),
239 : &be_salt,
240 : sizeof (be_salt),
241 : secret_seed,
242 : sizeof (*secret_seed),
243 : GNUNET_CRYPTO_kdf_arg_string ("taler-coin-derivation")));
244 642 : }
245 :
246 :
247 : void
248 92 : TALER_cs_withdraw_seed_to_blinding_seed (
249 : const struct TALER_WithdrawMasterSeedP *seed,
250 : struct TALER_BlindingMasterSeedP *blinding_seed)
251 : {
252 92 : GNUNET_assert (GNUNET_YES ==
253 : GNUNET_CRYPTO_hkdf_gnunet (
254 : blinding_seed,
255 : sizeof (*blinding_seed),
256 : "withdraw-blinding",
257 : strlen ("withdraw-blinding"),
258 : seed,
259 : sizeof(*seed)));
260 92 : }
261 :
262 :
263 : void
264 15 : TALER_cs_refresh_seed_to_blinding_seed (
265 : const struct TALER_PublicRefreshMasterSeedP *seed,
266 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
267 : struct TALER_BlindingMasterSeedP *blinding_seed)
268 : {
269 15 : GNUNET_assert (GNUNET_YES ==
270 : GNUNET_CRYPTO_hkdf_gnunet (
271 : blinding_seed,
272 : sizeof (*blinding_seed),
273 : "refresh-blinding",
274 : strlen ("refresh-blinding"),
275 : coin_priv,
276 : sizeof (*coin_priv),
277 : GNUNET_CRYPTO_kdf_arg_auto (seed)));
278 15 : }
279 :
280 :
281 : void
282 516 : TALER_cs_nonce_derive_indexed (
283 : const struct TALER_BlindingMasterSeedP *seed,
284 : bool for_melt,
285 : uint32_t index,
286 : struct GNUNET_CRYPTO_CsSessionNonce *nonce)
287 : {
288 516 : uint32_t be_salt = htonl (index);
289 516 : const char *operation = for_melt ? "refresh-n" : "withdraw-n";
290 :
291 516 : GNUNET_assert (GNUNET_YES ==
292 : GNUNET_CRYPTO_hkdf_gnunet (
293 : nonce,
294 : sizeof (*nonce),
295 : &be_salt,
296 : sizeof (be_salt),
297 : operation,
298 : strlen (operation),
299 : GNUNET_CRYPTO_kdf_arg_auto (seed)));
300 516 : }
301 :
302 :
303 : void
304 99 : TALER_cs_derive_nonces_from_seed (
305 : const struct TALER_BlindingMasterSeedP *seed,
306 : bool for_melt,
307 : size_t num,
308 : const uint32_t indices[static num],
309 : struct GNUNET_CRYPTO_CsSessionNonce nonces[static num])
310 99 : {
311 99 : GNUNET_assert (TALER_MAX_COINS >= num);
312 :
313 294 : for (size_t i = 0; i < num; i++)
314 195 : TALER_cs_nonce_derive_indexed (
315 : seed,
316 : for_melt,
317 195 : indices[i],
318 195 : &nonces[i]);
319 99 : }
320 :
321 :
322 : void
323 64 : TALER_cs_derive_only_cs_blind_nonces_from_seed (
324 : const struct TALER_BlindingMasterSeedP *seed,
325 : bool for_melt,
326 : size_t num,
327 : const uint32_t indices[static num],
328 : union GNUNET_CRYPTO_BlindSessionNonce nonces[static num])
329 64 : {
330 64 : GNUNET_assert (TALER_MAX_COINS >= num);
331 :
332 297 : for (size_t i = 0; i < num; i++)
333 233 : TALER_cs_nonce_derive_indexed (
334 : seed,
335 : for_melt,
336 233 : indices[i],
337 233 : &nonces[i].cs_nonce);
338 64 : }
339 :
340 :
341 : void
342 22 : TALER_cs_derive_blind_nonces_from_seed (
343 : const struct TALER_BlindingMasterSeedP *seed,
344 : bool for_melt,
345 : size_t num,
346 : const bool is_cs[static num],
347 : union GNUNET_CRYPTO_BlindSessionNonce nonces[static num])
348 22 : {
349 110 : for (size_t i = 0; i < num; i++)
350 : {
351 88 : if (is_cs[i])
352 88 : TALER_cs_nonce_derive_indexed (
353 : seed,
354 : for_melt,
355 : i,
356 88 : &nonces[i].cs_nonce);
357 : }
358 22 : }
359 :
360 :
361 : void
362 514 : TALER_rsa_pub_hash (const struct GNUNET_CRYPTO_RsaPublicKey *rsa,
363 : struct TALER_RsaPubHashP *h_rsa)
364 : {
365 514 : GNUNET_CRYPTO_rsa_public_key_hash (rsa,
366 : &h_rsa->hash);
367 :
368 514 : }
369 :
370 :
371 : void
372 420 : TALER_cs_pub_hash (const struct GNUNET_CRYPTO_CsPublicKey *cs,
373 : struct TALER_CsPubHashP *h_cs)
374 : {
375 420 : GNUNET_CRYPTO_hash (cs,
376 : sizeof(*cs),
377 : &h_cs->hash);
378 420 : }
379 :
380 :
381 : enum GNUNET_GenericReturnValue
382 1351 : TALER_planchet_prepare (
383 : const struct TALER_DenominationPublicKey *dk,
384 : const struct TALER_ExchangeBlindingValues *blinding_values,
385 : const union GNUNET_CRYPTO_BlindingSecretP *bks,
386 : const union GNUNET_CRYPTO_BlindSessionNonce *nonce,
387 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
388 : const struct TALER_AgeCommitmentHashP *ach,
389 : struct TALER_CoinPubHashP *c_hash,
390 : struct TALER_PlanchetDetail *pd)
391 : {
392 : struct TALER_CoinSpendPublicKeyP coin_pub;
393 :
394 1351 : GNUNET_assert (blinding_values->blinding_inputs->cipher ==
395 : dk->bsign_pub_key->cipher);
396 1351 : GNUNET_CRYPTO_eddsa_key_get_public (&coin_priv->eddsa_priv,
397 : &coin_pub.eddsa_pub);
398 1351 : if (GNUNET_OK !=
399 1351 : TALER_denom_blind (dk,
400 : bks,
401 : nonce,
402 : ach,
403 : &coin_pub,
404 : blinding_values,
405 : c_hash,
406 : &pd->blinded_planchet))
407 : {
408 0 : GNUNET_break (0);
409 0 : return GNUNET_SYSERR;
410 : }
411 1351 : TALER_denom_pub_hash (dk,
412 : &pd->denom_pub_hash);
413 1351 : return GNUNET_OK;
414 : }
415 :
416 :
417 : void
418 114 : TALER_planchet_detail_free (struct TALER_PlanchetDetail *pd)
419 : {
420 114 : TALER_blinded_planchet_free (&pd->blinded_planchet);
421 114 : }
422 :
423 :
424 : enum GNUNET_GenericReturnValue
425 190 : TALER_planchet_to_coin (
426 : const struct TALER_DenominationPublicKey *dk,
427 : const struct TALER_BlindedDenominationSignature *blind_sig,
428 : const union GNUNET_CRYPTO_BlindingSecretP *bks,
429 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
430 : const struct TALER_AgeCommitmentHashP *ach,
431 : const struct TALER_CoinPubHashP *c_hash,
432 : const struct TALER_ExchangeBlindingValues *alg_values,
433 : struct TALER_FreshCoin *coin)
434 : {
435 190 : if (dk->bsign_pub_key->cipher !=
436 190 : blind_sig->blinded_sig->cipher)
437 : {
438 0 : GNUNET_break_op (0);
439 0 : return GNUNET_SYSERR;
440 : }
441 190 : if (dk->bsign_pub_key->cipher !=
442 190 : alg_values->blinding_inputs->cipher)
443 : {
444 0 : GNUNET_break_op (0);
445 0 : return GNUNET_SYSERR;
446 : }
447 190 : if (GNUNET_OK !=
448 190 : TALER_denom_sig_unblind (&coin->sig,
449 : blind_sig,
450 : bks,
451 : c_hash,
452 : alg_values,
453 : dk))
454 : {
455 0 : GNUNET_break_op (0);
456 0 : return GNUNET_SYSERR;
457 : }
458 190 : if (GNUNET_OK !=
459 190 : TALER_denom_pub_verify (dk,
460 190 : &coin->sig,
461 : c_hash))
462 : {
463 0 : GNUNET_break_op (0);
464 0 : TALER_denom_sig_free (&coin->sig);
465 0 : return GNUNET_SYSERR;
466 : }
467 :
468 190 : coin->coin_priv = *coin_priv;
469 190 : coin->h_age_commitment = ach;
470 190 : return GNUNET_OK;
471 : }
472 :
473 :
474 : // FIXME-Oec: k_tpbs is dead in the code below!
475 : void
476 88 : TALER_refresh_get_commitment (
477 : struct TALER_RefreshCommitmentP *rc,
478 : const struct TALER_PublicRefreshMasterSeedP *refresh_seed,
479 : const struct TALER_BlindingMasterSeedP *blinding_seed,
480 : const struct TALER_KappaTransferPublicKeys *k_tpbs,
481 : const struct TALER_KappaHashBlindedPlanchetsP *k_bps_h,
482 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
483 : const struct TALER_Amount *amount_with_fee)
484 : {
485 : struct GNUNET_HashContext *hash_context;
486 :
487 88 : hash_context = GNUNET_CRYPTO_hash_context_start ();
488 :
489 : /* First, the refresh master seed (from which the nonces, then signatures
490 : and finally private keys of the fresh coins are derived from) */
491 88 : GNUNET_assert (NULL != refresh_seed);
492 88 : GNUNET_CRYPTO_hash_context_read (hash_context,
493 : refresh_seed,
494 : sizeof (*refresh_seed));
495 :
496 : /* Then, in case of CS denominations, the blinding_seed from which all
497 : nonces are derived from, and therefore public R-values */
498 : {
499 88 : struct TALER_BlindingMasterSeedP blanko = {0};
500 88 : const struct TALER_BlindingMasterSeedP *pbms = &blanko;
501 :
502 88 : if (NULL != blinding_seed)
503 59 : pbms = blinding_seed;
504 88 : GNUNET_CRYPTO_hash_context_read (hash_context,
505 : pbms,
506 : sizeof(*pbms));
507 : }
508 :
509 : /* Next, add public key of coin and amount being refreshed */
510 : {
511 : struct TALER_AmountNBO melt_amountn;
512 :
513 88 : GNUNET_CRYPTO_hash_context_read (hash_context,
514 : coin_pub,
515 : sizeof (struct TALER_CoinSpendPublicKeyP));
516 88 : TALER_amount_hton (&melt_amountn,
517 : amount_with_fee);
518 88 : GNUNET_CRYPTO_hash_context_read (hash_context,
519 : &melt_amountn,
520 : sizeof (struct TALER_AmountNBO));
521 : }
522 :
523 : /* Finally, add all the hashes of the blinded coins
524 : * (containing information about denominations), depths first */
525 352 : for (unsigned int k = 0; k<TALER_CNC_KAPPA; k++)
526 264 : GNUNET_CRYPTO_hash_context_read (hash_context,
527 264 : &k_bps_h->tuple[k],
528 : sizeof(k_bps_h->tuple[k]));
529 :
530 : /* Conclude */
531 88 : GNUNET_CRYPTO_hash_context_finish (hash_context,
532 : &rc->session_hash);
533 88 : }
534 :
535 :
536 : void
537 44 : TALER_refresh_expand_seed_to_kappa_batch_seeds (
538 : const struct TALER_PublicRefreshMasterSeedP *refresh_master_seed,
539 : const struct TALER_CoinSpendPrivateKeyP *coin_priv,
540 : struct TALER_KappaPrivateRefreshBatchSeedsP *kappa_batch_seeds)
541 : {
542 44 : GNUNET_assert (GNUNET_OK ==
543 : GNUNET_CRYPTO_hkdf_gnunet (
544 : kappa_batch_seeds,
545 : sizeof (*kappa_batch_seeds),
546 : "refresh-batch-seeds",
547 : strlen ("refresh-batch-seeds"),
548 : refresh_master_seed,
549 : sizeof (*refresh_master_seed),
550 : GNUNET_CRYPTO_kdf_arg_auto (coin_priv)));
551 44 : }
552 :
553 :
554 : void
555 160 : TALER_refresh_expand_batch_seed_to_transfer_private_keys (
556 : const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
557 : size_t num_transfer_pks,
558 : struct TALER_TransferPrivateKeyP transfer_pks[num_transfer_pks])
559 160 : {
560 160 : GNUNET_assert (GNUNET_OK ==
561 : GNUNET_CRYPTO_hkdf_gnunet (
562 : transfer_pks,
563 : sizeof (*transfer_pks) * num_transfer_pks,
564 : "refresh-transfer-private-keys",
565 : strlen ("refresh-transfer-private-keys"),
566 : batch_seed,
567 : sizeof (*batch_seed)));
568 160 : }
569 :
570 :
571 : void
572 0 : TALER_refresh_expand_batch_seed_to_transfer_secrets (
573 : const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
574 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
575 : size_t num_transfer_secrets,
576 : struct TALER_TransferSecretP transfer_secrets[num_transfer_secrets])
577 0 : {
578 0 : struct TALER_TransferPrivateKeyP transfer_pks[num_transfer_secrets];
579 :
580 0 : TALER_refresh_expand_batch_seed_to_transfer_private_keys (
581 : batch_seed,
582 : num_transfer_secrets,
583 : transfer_pks);
584 :
585 0 : for (size_t i = 0; i < num_transfer_secrets; i++)
586 : {
587 0 : TALER_link_reveal_transfer_secret (
588 0 : &transfer_pks[i],
589 : coin_pub,
590 0 : &transfer_secrets[i]);
591 : }
592 0 : }
593 :
594 :
595 : void
596 0 : TALER_refresh_expand_batch_seed_to_planchet_master_secrets (
597 : const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
598 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
599 : size_t num_planchet_secrets,
600 : struct TALER_PlanchetMasterSecretP planchet_secrets[num_planchet_secrets])
601 0 : {
602 0 : struct TALER_TransferPrivateKeyP transfer_pks[num_planchet_secrets];
603 0 : struct TALER_TransferSecretP transfer_secrets[num_planchet_secrets];
604 :
605 0 : TALER_refresh_expand_batch_seed_to_transfer_private_keys (
606 : batch_seed,
607 : num_planchet_secrets,
608 : transfer_pks);
609 :
610 0 : for (size_t i = 0; i < num_planchet_secrets; i++)
611 : {
612 0 : TALER_link_reveal_transfer_secret (
613 0 : &transfer_pks[i],
614 : coin_pub,
615 : &transfer_secrets[i]);
616 :
617 0 : TALER_transfer_secret_to_planchet_secret (
618 0 : &transfer_secrets[i],
619 : i,
620 0 : &planchet_secrets[i]);
621 : }
622 0 : }
623 :
624 :
625 : void
626 160 : TALER_refresh_expand_batch_seed_to_transfer_data (
627 : const struct TALER_PrivateRefreshBatchSeedP *batch_seed,
628 : const struct TALER_CoinSpendPublicKeyP *coin_pub,
629 : size_t num,
630 : struct TALER_PlanchetMasterSecretP planchet_secrets[num],
631 : struct TALER_TransferPublicKeyP transfer_pubs[num])
632 160 : {
633 160 : struct TALER_TransferPrivateKeyP transfer_pks[num];
634 160 : struct TALER_TransferSecretP transfer_secrets[num];
635 :
636 160 : TALER_refresh_expand_batch_seed_to_transfer_private_keys (
637 : batch_seed,
638 : num,
639 : transfer_pks);
640 :
641 800 : for (size_t i = 0; i < num; i++)
642 : {
643 640 : TALER_link_reveal_transfer_secret (
644 640 : &transfer_pks[i],
645 : coin_pub,
646 : &transfer_secrets[i]);
647 :
648 640 : TALER_transfer_secret_to_planchet_secret (
649 640 : &transfer_secrets[i],
650 : i,
651 640 : &planchet_secrets[i]);
652 :
653 640 : GNUNET_CRYPTO_ecdhe_key_get_public (
654 640 : &transfer_pks[i].ecdhe_priv,
655 640 : &transfer_pubs[i].ecdhe_pub);
656 : }
657 160 : }
658 :
659 :
660 : void
661 0 : TALER_refresh_expand_kappa_nonces_v27 (
662 : const struct TALER_PublicRefreshMasterSeedP *refresh_seed,
663 : struct TALER_KappaPublicRefreshNoncesP *kappa_nonces)
664 : {
665 0 : GNUNET_assert (GNUNET_OK ==
666 : GNUNET_CRYPTO_hkdf_gnunet (
667 : kappa_nonces,
668 : sizeof (*kappa_nonces),
669 : "refresh-kappa-nonces",
670 : strlen ("refresh-kappa-nonces"),
671 : refresh_seed,
672 : sizeof (*refresh_seed)));
673 0 : }
674 :
675 :
676 : void
677 0 : TALER_refresh_signature_to_secrets_v27 (
678 : const struct TALER_PrivateRefreshNonceSignatureP *sig,
679 : size_t num_secrets,
680 : struct TALER_PlanchetMasterSecretP secrets[static num_secrets])
681 0 : {
682 0 : GNUNET_assert (GNUNET_YES ==
683 : GNUNET_CRYPTO_hkdf_gnunet (
684 : secrets,
685 : sizeof (*secrets) * num_secrets,
686 : "refresh-planchet-secret",
687 : strlen ("refresh-planchet-secret"),
688 : sig,
689 : sizeof(*sig)));
690 0 : }
691 :
692 :
693 : void
694 1681 : TALER_coin_pub_hash (const struct TALER_CoinSpendPublicKeyP *coin_pub,
695 : const struct TALER_AgeCommitmentHashP *ach,
696 : struct TALER_CoinPubHashP *coin_h)
697 : {
698 1681 : if (TALER_AgeCommitmentHashP_isNullOrZero (ach))
699 : {
700 : /* No age commitment was set */
701 747 : GNUNET_CRYPTO_hash (&coin_pub->eddsa_pub,
702 : sizeof (coin_pub->eddsa_pub),
703 : &coin_h->hash);
704 : }
705 : else
706 : {
707 : /* Coin comes with age commitment. Take the hash of the age commitment
708 : * into account */
709 : struct GNUNET_HashContext *hash_context;
710 :
711 934 : hash_context = GNUNET_CRYPTO_hash_context_start ();
712 :
713 934 : GNUNET_CRYPTO_hash_context_read (
714 : hash_context,
715 934 : &coin_pub->eddsa_pub,
716 : sizeof(coin_pub->eddsa_pub));
717 :
718 934 : GNUNET_CRYPTO_hash_context_read (
719 : hash_context,
720 : ach,
721 : sizeof(struct TALER_AgeCommitmentHashP));
722 :
723 934 : GNUNET_CRYPTO_hash_context_finish (
724 : hash_context,
725 : &coin_h->hash);
726 : }
727 1681 : }
728 :
729 :
730 : void
731 1671 : TALER_coin_ev_hash (const struct TALER_BlindedPlanchet *blinded_planchet,
732 : const struct TALER_DenominationHashP *denom_hash,
733 : struct TALER_BlindedCoinHashP *bch)
734 : {
735 : struct GNUNET_HashContext *hash_context;
736 :
737 1671 : hash_context = GNUNET_CRYPTO_hash_context_start ();
738 1671 : GNUNET_CRYPTO_hash_context_read (hash_context,
739 : denom_hash,
740 : sizeof(*denom_hash));
741 1671 : TALER_blinded_planchet_hash_ (blinded_planchet,
742 : hash_context);
743 1671 : GNUNET_CRYPTO_hash_context_finish (hash_context,
744 : &bch->hash);
745 1671 : }
746 :
747 :
748 : GNUNET_NETWORK_STRUCT_BEGIN
749 : /**
750 : * Structure we hash to compute the group key for
751 : * a denomination group.
752 : */
753 : struct DenominationGroupP
754 : {
755 : /**
756 : * Value of coins in this denomination group.
757 : */
758 : struct TALER_AmountNBO value;
759 :
760 : /**
761 : * Fee structure for all coins in the group.
762 : */
763 : struct TALER_DenomFeeSetNBOP fees;
764 :
765 : /**
766 : * Age mask for the denomiation, in NBO.
767 : */
768 : uint32_t age_mask GNUNET_PACKED;
769 :
770 : /**
771 : * Cipher used for the denomination, in NBO.
772 : */
773 : uint32_t cipher GNUNET_PACKED;
774 : };
775 : GNUNET_NETWORK_STRUCT_END
776 :
777 :
778 : void
779 1776 : TALER_denomination_group_get_key (
780 : const struct TALER_DenominationGroup *dg,
781 : struct GNUNET_HashCode *key)
782 : {
783 1776 : struct DenominationGroupP dgp = {
784 1776 : .age_mask = htonl (dg->age_mask.bits),
785 1776 : .cipher = htonl (dg->cipher)
786 : };
787 :
788 1776 : TALER_amount_hton (&dgp.value,
789 : &dg->value);
790 1776 : TALER_denom_fee_set_hton (&dgp.fees,
791 : &dg->fees);
792 1776 : GNUNET_CRYPTO_hash (&dgp,
793 : sizeof (dgp),
794 : key);
795 1776 : }
796 :
797 :
798 : void
799 23 : TALER_kyc_measure_authorization_hash (
800 : const struct TALER_AccountAccessTokenP *access_token,
801 : uint64_t row,
802 : uint32_t offset,
803 : struct TALER_KycMeasureAuthorizationHashP *mah)
804 : {
805 23 : uint64_t be64 = GNUNET_htonll (row);
806 23 : uint32_t be32 = htonl ((uint32_t) offset);
807 :
808 23 : GNUNET_assert (
809 : GNUNET_YES ==
810 : GNUNET_CRYPTO_hkdf_gnunet (
811 : mah,
812 : sizeof (*mah),
813 : &be64,
814 : sizeof (be64),
815 : access_token,
816 : sizeof (*access_token),
817 : GNUNET_CRYPTO_kdf_arg_auto (&be32)));
818 23 : }
819 :
820 :
821 : void
822 0 : TALER_merchant_instance_auth_hash_with_salt (
823 : struct TALER_MerchantAuthenticationHashP *auth_hash,
824 : struct TALER_MerchantAuthenticationSaltP *salt,
825 : const char *passphrase)
826 : {
827 0 : GNUNET_assert (GNUNET_YES ==
828 : GNUNET_CRYPTO_hkdf_gnunet (
829 : auth_hash,
830 : sizeof (*auth_hash),
831 : salt,
832 : sizeof (*salt),
833 : passphrase,
834 : strlen (passphrase),
835 : GNUNET_CRYPTO_kdf_arg_string ("merchant-instance-auth")));
836 0 : }
837 :
838 :
839 : /* end of crypto.c */
|