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