denom.c (13557B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2021, 2022, 2023 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file denom.c 18 * @brief denomination utility functions 19 * @author Christian Grothoff 20 */ 21 #include "taler/taler_util.h" 22 23 24 enum GNUNET_GenericReturnValue 25 TALER_denom_priv_create (struct TALER_DenominationPrivateKey *denom_priv, 26 struct TALER_DenominationPublicKey *denom_pub, 27 enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, 28 ...) 29 { 30 enum GNUNET_GenericReturnValue ret; 31 va_list ap; 32 33 memset (denom_pub, 34 0, 35 sizeof (*denom_pub)); 36 memset (denom_priv, 37 0, 38 sizeof (*denom_priv)); 39 va_start (ap, 40 cipher); 41 ret = GNUNET_CRYPTO_blind_sign_keys_create_va ( 42 &denom_priv->bsign_priv_key, 43 &denom_pub->bsign_pub_key, 44 cipher, 45 ap); 46 va_end (ap); 47 return ret; 48 } 49 50 51 enum GNUNET_GenericReturnValue 52 TALER_denom_sign_blinded (struct TALER_BlindedDenominationSignature *denom_sig, 53 const struct TALER_DenominationPrivateKey *denom_priv, 54 bool for_melt, 55 const struct TALER_BlindedPlanchet *blinded_planchet) 56 { 57 denom_sig->blinded_sig 58 = GNUNET_CRYPTO_blind_sign (denom_priv->bsign_priv_key, 59 for_melt ? "rm" : "rw", 60 blinded_planchet->blinded_message); 61 if (NULL == denom_sig->blinded_sig) 62 { 63 GNUNET_break (0); 64 return GNUNET_SYSERR; 65 } 66 return GNUNET_OK; 67 } 68 69 70 enum GNUNET_GenericReturnValue 71 TALER_denom_sig_unblind ( 72 struct TALER_DenominationSignature *denom_sig, 73 const struct TALER_BlindedDenominationSignature *bdenom_sig, 74 const union GNUNET_CRYPTO_BlindingSecretP *bks, 75 const struct TALER_CoinPubHashP *c_hash, 76 const struct TALER_ExchangeBlindingValues *alg_values, 77 const struct TALER_DenominationPublicKey *denom_pub) 78 { 79 denom_sig->unblinded_sig 80 = GNUNET_CRYPTO_blind_sig_unblind (bdenom_sig->blinded_sig, 81 bks, 82 c_hash, 83 sizeof (*c_hash), 84 alg_values->blinding_inputs, 85 denom_pub->bsign_pub_key); 86 if (NULL == denom_sig->unblinded_sig) 87 { 88 GNUNET_break_op (0); 89 return GNUNET_SYSERR; 90 } 91 return GNUNET_OK; 92 } 93 94 95 void 96 TALER_denom_pub_hash (const struct TALER_DenominationPublicKey *denom_pub, 97 struct TALER_DenominationHashP *denom_hash) 98 { 99 struct GNUNET_CRYPTO_BlindSignPublicKey *bsp 100 = denom_pub->bsign_pub_key; 101 uint32_t opt[2] = { 102 htonl (denom_pub->age_mask.bits), 103 htonl ((uint32_t) bsp->cipher) 104 }; 105 struct GNUNET_HashContext *hc; 106 107 hc = GNUNET_CRYPTO_hash_context_start (); 108 GNUNET_CRYPTO_hash_context_read (hc, 109 opt, 110 sizeof (opt)); 111 switch (bsp->cipher) 112 { 113 case GNUNET_CRYPTO_BSA_RSA: 114 { 115 void *buf; 116 size_t blen; 117 118 blen = GNUNET_CRYPTO_rsa_public_key_encode ( 119 bsp->details.rsa_public_key, 120 &buf); 121 GNUNET_CRYPTO_hash_context_read (hc, 122 buf, 123 blen); 124 GNUNET_free (buf); 125 } 126 break; 127 case GNUNET_CRYPTO_BSA_CS: 128 GNUNET_CRYPTO_hash_context_read (hc, 129 &bsp->details.cs_public_key, 130 sizeof(bsp->details.cs_public_key)); 131 break; 132 default: 133 GNUNET_assert (0); 134 } 135 GNUNET_CRYPTO_hash_context_finish (hc, 136 &denom_hash->hash); 137 } 138 139 140 const struct TALER_ExchangeBlindingValues * 141 TALER_denom_ewv_rsa_singleton () 142 { 143 static struct GNUNET_CRYPTO_BlindingInputValues bi = { 144 .cipher = GNUNET_CRYPTO_BSA_RSA 145 }; 146 static struct TALER_ExchangeBlindingValues alg_values = { 147 .blinding_inputs = &bi 148 }; 149 return &alg_values; 150 } 151 152 153 enum GNUNET_GenericReturnValue 154 TALER_denom_blind ( 155 const struct TALER_DenominationPublicKey *dk, 156 const union GNUNET_CRYPTO_BlindingSecretP *coin_bks, 157 const union GNUNET_CRYPTO_BlindSessionNonce *nonce, 158 const struct TALER_AgeCommitmentHashP *ach, 159 const struct TALER_CoinSpendPublicKeyP *coin_pub, 160 const struct TALER_ExchangeBlindingValues *alg_values, 161 struct TALER_CoinPubHashP *c_hash, 162 struct TALER_BlindedPlanchet *blinded_planchet) 163 { 164 TALER_coin_pub_hash (coin_pub, 165 ach, 166 c_hash); 167 blinded_planchet->blinded_message 168 = GNUNET_CRYPTO_message_blind_to_sign (dk->bsign_pub_key, 169 coin_bks, 170 nonce, 171 c_hash, 172 sizeof (*c_hash), 173 alg_values->blinding_inputs); 174 if (NULL == blinded_planchet->blinded_message) 175 { 176 GNUNET_break_op (0); 177 return GNUNET_SYSERR; 178 } 179 return GNUNET_OK; 180 } 181 182 183 enum GNUNET_GenericReturnValue 184 TALER_denom_pub_verify (const struct TALER_DenominationPublicKey *denom_pub, 185 const struct TALER_DenominationSignature *denom_sig, 186 const struct TALER_CoinPubHashP *c_hash) 187 { 188 return GNUNET_CRYPTO_blind_sig_verify (denom_pub->bsign_pub_key, 189 denom_sig->unblinded_sig, 190 c_hash, 191 sizeof (*c_hash)); 192 } 193 194 195 void 196 TALER_denom_pub_free (struct TALER_DenominationPublicKey *denom_pub) 197 { 198 if (NULL != denom_pub->bsign_pub_key) 199 { 200 GNUNET_CRYPTO_blind_sign_pub_decref (denom_pub->bsign_pub_key); 201 denom_pub->bsign_pub_key = NULL; 202 } 203 } 204 205 206 void 207 TALER_denom_priv_free (struct TALER_DenominationPrivateKey *denom_priv) 208 { 209 if (NULL != denom_priv->bsign_priv_key) 210 { 211 GNUNET_CRYPTO_blind_sign_priv_decref (denom_priv->bsign_priv_key); 212 denom_priv->bsign_priv_key = NULL; 213 } 214 } 215 216 217 void 218 TALER_denom_sig_free (struct TALER_DenominationSignature *denom_sig) 219 { 220 if (NULL != denom_sig->unblinded_sig) 221 { 222 GNUNET_CRYPTO_unblinded_sig_decref (denom_sig->unblinded_sig); 223 denom_sig->unblinded_sig = NULL; 224 } 225 } 226 227 228 void 229 TALER_blinded_denom_sig_free ( 230 struct TALER_BlindedDenominationSignature *denom_sig) 231 { 232 if (NULL != denom_sig->blinded_sig) 233 { 234 GNUNET_CRYPTO_blinded_sig_decref (denom_sig->blinded_sig); 235 denom_sig->blinded_sig = NULL; 236 } 237 } 238 239 240 void 241 TALER_denom_ewv_free (struct TALER_ExchangeBlindingValues *ewv) 242 { 243 if (ewv == TALER_denom_ewv_rsa_singleton ()) 244 return; 245 if (ewv->blinding_inputs == 246 TALER_denom_ewv_rsa_singleton ()->blinding_inputs) 247 { 248 ewv->blinding_inputs = NULL; 249 return; 250 } 251 if (NULL != ewv->blinding_inputs) 252 { 253 GNUNET_CRYPTO_blinding_input_values_decref (ewv->blinding_inputs); 254 ewv->blinding_inputs = NULL; 255 } 256 } 257 258 259 void 260 TALER_denom_ewv_copy (struct TALER_ExchangeBlindingValues *bi_dst, 261 const struct TALER_ExchangeBlindingValues *bi_src) 262 { 263 if (bi_src == TALER_denom_ewv_rsa_singleton ()) 264 { 265 *bi_dst = *bi_src; 266 return; 267 } 268 bi_dst->blinding_inputs 269 = GNUNET_CRYPTO_blinding_input_values_incref (bi_src->blinding_inputs); 270 } 271 272 273 void 274 TALER_denom_pub_copy (struct TALER_DenominationPublicKey *denom_dst, 275 const struct TALER_DenominationPublicKey *denom_src) 276 { 277 denom_dst->age_mask = denom_src->age_mask; 278 denom_dst->bsign_pub_key 279 = GNUNET_CRYPTO_bsign_pub_incref (denom_src->bsign_pub_key); 280 } 281 282 283 void 284 TALER_denom_sig_copy (struct TALER_DenominationSignature *denom_dst, 285 const struct TALER_DenominationSignature *denom_src) 286 { 287 denom_dst->unblinded_sig 288 = GNUNET_CRYPTO_ub_sig_incref (denom_src->unblinded_sig); 289 } 290 291 292 void 293 TALER_blinded_denom_sig_copy ( 294 struct TALER_BlindedDenominationSignature *denom_dst, 295 const struct TALER_BlindedDenominationSignature *denom_src) 296 { 297 denom_dst->blinded_sig 298 = GNUNET_CRYPTO_blind_sig_incref (denom_src->blinded_sig); 299 } 300 301 302 int 303 TALER_denom_pub_cmp (const struct TALER_DenominationPublicKey *denom1, 304 const struct TALER_DenominationPublicKey *denom2) 305 { 306 if (denom1->bsign_pub_key->cipher != 307 denom2->bsign_pub_key->cipher) 308 return (denom1->bsign_pub_key->cipher > 309 denom2->bsign_pub_key->cipher) ? 1 : -1; 310 if (denom1->age_mask.bits != denom2->age_mask.bits) 311 return (denom1->age_mask.bits > denom2->age_mask.bits) ? 1 : -1; 312 return GNUNET_CRYPTO_bsign_pub_cmp (denom1->bsign_pub_key, 313 denom2->bsign_pub_key); 314 } 315 316 317 int 318 TALER_denom_sig_cmp (const struct TALER_DenominationSignature *sig1, 319 const struct TALER_DenominationSignature *sig2) 320 { 321 return GNUNET_CRYPTO_ub_sig_cmp (sig1->unblinded_sig, 322 sig2->unblinded_sig); 323 } 324 325 326 int 327 TALER_blinded_planchet_cmp ( 328 const struct TALER_BlindedPlanchet *bp1, 329 const struct TALER_BlindedPlanchet *bp2) 330 { 331 return GNUNET_CRYPTO_blinded_message_cmp (bp1->blinded_message, 332 bp2->blinded_message); 333 } 334 335 336 int 337 TALER_blinded_denom_sig_cmp ( 338 const struct TALER_BlindedDenominationSignature *sig1, 339 const struct TALER_BlindedDenominationSignature *sig2) 340 { 341 return GNUNET_CRYPTO_blind_sig_cmp (sig1->blinded_sig, 342 sig2->blinded_sig); 343 } 344 345 346 void 347 TALER_blinded_planchet_hash_ (const struct TALER_BlindedPlanchet *bp, 348 struct GNUNET_HashContext *hash_context) 349 { 350 const struct GNUNET_CRYPTO_BlindedMessage *bm = bp->blinded_message; 351 uint32_t cipher = htonl (bm->cipher); 352 353 GNUNET_CRYPTO_hash_context_read (hash_context, 354 &cipher, 355 sizeof (cipher)); 356 switch (bm->cipher) 357 { 358 case GNUNET_CRYPTO_BSA_INVALID: 359 GNUNET_break (0); 360 return; 361 case GNUNET_CRYPTO_BSA_RSA: 362 GNUNET_CRYPTO_hash_context_read ( 363 hash_context, 364 bm->details.rsa_blinded_message.blinded_msg, 365 bm->details.rsa_blinded_message.blinded_msg_size); 366 return; 367 case GNUNET_CRYPTO_BSA_CS: 368 GNUNET_CRYPTO_hash_context_read ( 369 hash_context, 370 &bm->details.cs_blinded_message, 371 sizeof (bm->details.cs_blinded_message)); 372 return; 373 } 374 GNUNET_assert (0); 375 } 376 377 378 void 379 TALER_planchet_blinding_secret_create ( 380 const struct TALER_PlanchetMasterSecretP *ps, 381 const struct TALER_ExchangeBlindingValues *alg_values, 382 union GNUNET_CRYPTO_BlindingSecretP *bks) 383 { 384 const struct GNUNET_CRYPTO_BlindingInputValues *bi = 385 alg_values->blinding_inputs; 386 387 switch (bi->cipher) 388 { 389 case GNUNET_CRYPTO_BSA_INVALID: 390 GNUNET_break (0); 391 return; 392 case GNUNET_CRYPTO_BSA_RSA: 393 GNUNET_assert (GNUNET_YES == 394 GNUNET_CRYPTO_hkdf_gnunet ( 395 &bks->rsa_bks, 396 sizeof (bks->rsa_bks), 397 "bks", 398 strlen ("bks"), 399 ps, 400 sizeof(*ps))); 401 return; 402 case GNUNET_CRYPTO_BSA_CS: 403 GNUNET_assert (GNUNET_YES == 404 GNUNET_CRYPTO_hkdf_gnunet ( 405 &bks->nonce, 406 sizeof (bks->nonce), 407 "bseed", 408 strlen ("bseed"), 409 ps, 410 sizeof(*ps), 411 GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values))); 412 return; 413 } 414 GNUNET_assert (0); 415 } 416 417 418 void 419 TALER_planchet_setup_coin_priv ( 420 const struct TALER_PlanchetMasterSecretP *ps, 421 const struct TALER_ExchangeBlindingValues *alg_values, 422 struct TALER_CoinSpendPrivateKeyP *coin_priv) 423 { 424 const struct GNUNET_CRYPTO_BlindingInputValues *bi 425 = alg_values->blinding_inputs; 426 427 switch (bi->cipher) 428 { 429 case GNUNET_CRYPTO_BSA_INVALID: 430 GNUNET_break (0); 431 memset (coin_priv, 432 0, 433 sizeof (*coin_priv)); 434 return; 435 case GNUNET_CRYPTO_BSA_RSA: 436 GNUNET_assert (GNUNET_YES == 437 GNUNET_CRYPTO_hkdf_gnunet ( 438 coin_priv, 439 sizeof (*coin_priv), 440 "coin", 441 strlen ("coin"), 442 ps, 443 sizeof(*ps))); 444 return; 445 case GNUNET_CRYPTO_BSA_CS: 446 GNUNET_assert (GNUNET_YES == 447 GNUNET_CRYPTO_hkdf_gnunet ( 448 coin_priv, 449 sizeof (*coin_priv), 450 "coin", 451 strlen ("coin"), 452 ps, 453 sizeof(*ps), 454 GNUNET_CRYPTO_kdf_arg_auto (&bi->details.cs_values))); 455 return; 456 } 457 GNUNET_assert (0); 458 } 459 460 461 void 462 TALER_blinded_planchet_free (struct TALER_BlindedPlanchet *blinded_planchet) 463 { 464 if (NULL != blinded_planchet->blinded_message) 465 { 466 GNUNET_CRYPTO_blinded_message_decref (blinded_planchet->blinded_message); 467 blinded_planchet->blinded_message = NULL; 468 } 469 } 470 471 472 /* end of denom.c */