From 7278ae87e0d5de5fa31e076581a69d62f3d1fe65 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Fri, 20 Oct 2023 23:13:09 +0200 Subject: more work on new blind signature API and implementation --- src/include/gnunet_crypto_lib.h | 56 +++++++++++++++++++++--- src/lib/util/Makefile.am | 8 +++- src/lib/util/crypto_blind_sign.c | 69 +++++++++++++++++++++++++---- src/lib/util/crypto_cs.c | 11 +++-- src/lib/util/test_crypto_blind.c | 93 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 216 insertions(+), 21 deletions(-) create mode 100644 src/lib/util/test_crypto_blind.c diff --git a/src/include/gnunet_crypto_lib.h b/src/include/gnunet_crypto_lib.h index 11bd680e7..31472f7a1 100644 --- a/src/include/gnunet_crypto_lib.h +++ b/src/include/gnunet_crypto_lib.h @@ -3556,6 +3556,27 @@ GNUNET_CRYPTO_blinded_sig_decref ( struct GNUNET_CRYPTO_BlindedSignature *blind_sig); +/** + * Decrement reference counter of a @a bm, and free it if it reaches zero. + * + * @param[in] bm blinded message to free + */ +void +GNUNET_CRYPTO_blinded_message_decref ( + struct GNUNET_CRYPTO_BlindedMessage *bm); + + +/** + * Increment reference counter of the given @a bm. + * + * @param[in,out] bm blinded message to increment reference counter for + * @return alias of @a bm with RC incremented + */ +struct GNUNET_CRYPTO_BlindedMessage * +GNUNET_CRYPTO_blinded_message_incref ( + struct GNUNET_CRYPTO_BlindedMessage *bm); + + /** * Increment reference counter of the given @a bsign_pub. * @@ -3630,7 +3651,7 @@ GNUNET_CRYPTO_ub_sig_cmp (const struct GNUNET_CRYPTO_UnblindedSignature *sig1, * @return 0 if the keys are equal, otherwise -1 or 1 */ int -GNUNET_blind_sig_cmp ( +GNUNET_CRYPTO_blind_sig_cmp ( const struct GNUNET_CRYPTO_BlindedSignature *sig1, const struct GNUNET_CRYPTO_BlindedSignature *sig2); @@ -3655,27 +3676,48 @@ GNUNET_CRYPTO_blinded_message_cmp ( * argument with the number of bits for 'n' (e.g. 2048) must * be passed. * - * @param[out] denom_priv where to write the private key with RC 1 - * @param[out] denom_pub where to write the public key with RC 1 + * @param[out] bsign_priv where to write the private key with RC 1 + * @param[out] bsign_pub where to write the public key with RC 1 * @param cipher which type of cipher to use * @param ... RSA key size (eg. 2048/3072/4096) - * @return #GNUNET_OK on success, #GNUNET_NO if parameters were invalid + * @return #GNUNET_OK on success, #GNUNET_NO if parameterst were invalid */ enum GNUNET_GenericReturnValue GNUNET_CRYPTO_blind_sign_keys_create ( - struct GNUNET_CRYPTO_BlindSignPrivateKey **denom_priv, - struct GNUNET_CRYPTO_BlindSignPublicKey **denom_pub, + struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, + struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, ...); +/** + * Initialize public-private key pair for blind signatures. + * + * For #GNUNET_CRYPTO_BSA_RSA, an additional "unsigned int" + * argument with the number of bits for 'n' (e.g. 2048) must + * be passed. + * + * @param[out] bsign_priv where to write the private key with RC 1 + * @param[out] bsign_pub where to write the public key with RC 1 + * @param cipher which type of cipher to use + * @param ap RSA key size (eg. 2048/3072/4096) + * @return #GNUNET_OK on success, #GNUNET_NO if parameterst were invalid + */ +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_blind_sign_keys_create_va ( + struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, + struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, + va_list ap); + + /** * @brief Type of blinding secrets. Must be exactly 32 bytes (DB). */ union GNUNET_CRYPTO_BlindingSecretP { /** - * Clause Schnorr nonce. + * Clause Schnorr nonce. */ struct GNUNET_CRYPTO_CsBlindingNonce nonce; diff --git a/src/lib/util/Makefile.am b/src/lib/util/Makefile.am index 097dec82a..7ab6301f5 100644 --- a/src/lib/util/Makefile.am +++ b/src/lib/util/Makefile.am @@ -198,7 +198,7 @@ check_PROGRAMS = \ test_container_multihashmap32 \ test_container_multipeermap \ test_container_heap \ - test_crypto_symmetric \ + test_crypto_blind \ test_crypto_crc \ test_crypto_cs \ test_crypto_ecdsa \ @@ -215,6 +215,7 @@ check_PROGRAMS = \ test_crypto_paillier \ test_crypto_random \ test_crypto_rsa \ + test_crypto_symmetric \ test_disk \ test_getopt \ test_hexcoder \ @@ -347,6 +348,11 @@ test_container_heap_SOURCES = \ test_container_heap_LDADD = \ libgnunetutil.la +test_crypto_blind_SOURCES = \ + test_crypto_blind.c +test_crypto_blind_LDADD = \ + libgnunetutil.la + test_crypto_symmetric_SOURCES = \ test_crypto_symmetric.c test_crypto_symmetric_LDADD = \ diff --git a/src/lib/util/crypto_blind_sign.c b/src/lib/util/crypto_blind_sign.c index 6121ef9a0..bf6fbc119 100644 --- a/src/lib/util/crypto_blind_sign.c +++ b/src/lib/util/crypto_blind_sign.c @@ -135,6 +135,38 @@ GNUNET_CRYPTO_blinded_sig_decref ( } +void +GNUNET_CRYPTO_blinded_message_decref ( + struct GNUNET_CRYPTO_BlindedMessage *bm) +{ + GNUNET_assert (bm->rc > 0); + bm->rc--; + if (0 != bm->rc) + return; + switch (bm->cipher) + { + case GNUNET_CRYPTO_BSA_INVALID: + GNUNET_break (0); + break; + case GNUNET_CRYPTO_BSA_RSA: + GNUNET_free (bm->details.rsa_blinded_message.blinded_msg); + break; + case GNUNET_CRYPTO_BSA_CS: + break; + } + GNUNET_free (bm); +} + + +struct GNUNET_CRYPTO_BlindedMessage * +GNUNET_CRYPTO_blinded_message_incref ( + struct GNUNET_CRYPTO_BlindedMessage *bm) +{ + bm->rc++; + return bm; +} + + struct GNUNET_CRYPTO_BlindSignPublicKey * GNUNET_CRYPTO_bsign_pub_incref (struct GNUNET_CRYPTO_BlindSignPublicKey *bsign_pub) { @@ -217,7 +249,7 @@ GNUNET_CRYPTO_ub_sig_cmp ( int -GNUNET_blind_sig_cmp ( +GNUNET_CRYPTO_blind_sig_cmp ( const struct GNUNET_CRYPTO_BlindedSignature *sig1, const struct GNUNET_CRYPTO_BlindedSignature *sig2) { @@ -271,20 +303,43 @@ GNUNET_CRYPTO_blinded_message_cmp ( enum GNUNET_GenericReturnValue GNUNET_CRYPTO_blind_sign_keys_create ( - struct GNUNET_CRYPTO_BlindSignPrivateKey **denom_priv, - struct GNUNET_CRYPTO_BlindSignPublicKey **denom_pub, + struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, + struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, ...) { + enum GNUNET_GenericReturnValue ret; + va_list ap; + + va_start (ap, + cipher); + ret = GNUNET_CRYPTO_blind_sign_keys_create_va (bsign_priv, + bsign_pub, + cipher, + ap); + va_end (ap); + return ret; +} + + +enum GNUNET_GenericReturnValue +GNUNET_CRYPTO_blind_sign_keys_create_va ( + struct GNUNET_CRYPTO_BlindSignPrivateKey **bsign_priv, + struct GNUNET_CRYPTO_BlindSignPublicKey **bsign_pub, + enum GNUNET_CRYPTO_BlindSignatureAlgorithm cipher, + va_list ap) + { struct GNUNET_CRYPTO_BlindSignPrivateKey *priv; struct GNUNET_CRYPTO_BlindSignPublicKey *pub; priv = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPrivateKey); priv->rc = 1; priv->cipher = cipher; + *bsign_priv = priv; pub = GNUNET_new (struct GNUNET_CRYPTO_BlindSignPublicKey); pub->rc = 1; pub->cipher = cipher; + *bsign_pub = pub; switch (cipher) { case GNUNET_CRYPTO_BSA_INVALID: @@ -292,14 +347,10 @@ GNUNET_CRYPTO_blind_sign_keys_create ( break; case GNUNET_CRYPTO_BSA_RSA: { - va_list ap; unsigned int bits; - va_start (ap, - cipher); bits = va_arg (ap, unsigned int); - va_end (ap); if (bits < 512) { GNUNET_break (0); @@ -331,8 +382,8 @@ GNUNET_CRYPTO_blind_sign_keys_create ( } GNUNET_free (priv); GNUNET_free (pub); - *denom_priv = NULL; - *denom_pub = NULL; + *bsign_priv = NULL; + *bsign_pub = NULL; return GNUNET_SYSERR; } diff --git a/src/lib/util/crypto_cs.c b/src/lib/util/crypto_cs.c index cf1c43c25..2ff7c70ce 100644 --- a/src/lib/util/crypto_cs.c +++ b/src/lib/util/crypto_cs.c @@ -53,8 +53,9 @@ GNUNET_CRYPTO_cs_private_key_get_public ( const struct GNUNET_CRYPTO_CsPrivateKey *priv, struct GNUNET_CRYPTO_CsPublicKey *pub) { - GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp (pub->point.y, - priv->scalar.d)); + GNUNET_assert (0 == + crypto_scalarmult_ed25519_base_noclamp (pub->point.y, + priv->scalar.d)); } @@ -209,7 +210,8 @@ calc_r_dash (const struct GNUNET_CRYPTO_CsBlindingSecret *bs, { // R'i = Ri + alpha i*G + beta i*pub struct GNUNET_CRYPTO_Cs25519Point alpha_mul_base; - GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp ( + GNUNET_assert (0 == + crypto_scalarmult_ed25519_base_noclamp ( alpha_mul_base.y, bs->alpha.d)); struct GNUNET_CRYPTO_Cs25519Point beta_mul_pub; @@ -323,7 +325,8 @@ GNUNET_CRYPTO_cs_verify (const struct GNUNET_CRYPTO_CsSignature *sig, // s'G ?= R' + c' pub struct GNUNET_CRYPTO_Cs25519Point sig_scal_mul_base; - GNUNET_assert (0 == crypto_scalarmult_ed25519_base_noclamp ( + GNUNET_assert (0 == + crypto_scalarmult_ed25519_base_noclamp ( sig_scal_mul_base.y, sig->s_scalar.scalar.d)); struct GNUNET_CRYPTO_Cs25519Point c_dash_mul_pub; diff --git a/src/lib/util/test_crypto_blind.c b/src/lib/util/test_crypto_blind.c new file mode 100644 index 000000000..726516bc2 --- /dev/null +++ b/src/lib/util/test_crypto_blind.c @@ -0,0 +1,93 @@ +/* + This file is part of GNUnet + Copyright (C) 2014, 2015, 2023 GNUnet e.V. + + GNUnet is free software: you can redistribute it and/or modify it + under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + + SPDX-License-Identifier: AGPL3.0-or-later + */ + +/** + * @file util/test_crypto_blind.c + * @brief testcase for utility functions for blind signatures + * @author Christian Grothoff + */ +#include "platform.h" +#include +#include "gnunet_util_lib.h" + + +int +main (int argc, + char *argv[]) +{ + struct GNUNET_CRYPTO_BlindSignPrivateKey *priv; + struct GNUNET_CRYPTO_BlindSignPublicKey *pub; + struct GNUNET_CRYPTO_BlindingInputValues biv; + struct GNUNET_CRYPTO_BlindedMessage *bm; + struct GNUNET_CRYPTO_BlindedSignature *bsig; + struct GNUNET_CRYPTO_UnblindedSignature *sig; + union GNUNET_CRYPTO_BlindingSecretP bsec; + struct GNUNET_CRYPTO_CsSessionNonce nonce; + struct GNUNET_CRYPTO_CsRSecret cspriv[2]; + + GNUNET_log_setup ("test-crypto-blind", + "WARNING", + NULL); + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, + &bsec, + sizeof (bsec)); + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, + &nonce, + sizeof (nonce)); + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_blind_sign_keys_create (&priv, + &pub, + GNUNET_CRYPTO_BSA_CS)); + biv.cipher = GNUNET_CRYPTO_BSA_CS; + GNUNET_CRYPTO_cs_r_derive (&nonce, + "salt", + &priv->details.cs_private_key, + cspriv); + GNUNET_CRYPTO_cs_r_get_public (&cspriv[0], + &biv.details.cs_values.r_pub[0]); + GNUNET_CRYPTO_cs_r_get_public (&cspriv[1], + &biv.details.cs_values.r_pub[1]); + bm = GNUNET_CRYPTO_message_blind_to_sign (pub, + &bsec, + "hello", + 5, + &biv); + bm->details.cs_blinded_message.nonce = nonce; // FIXME: ugly! + bsig = GNUNET_CRYPTO_blind_sign (priv, + "salt", + bm); + sig = GNUNET_CRYPTO_blind_sig_unblind (bsig, + &bsec, + "hello", + 5, + &biv, + pub); + GNUNET_assert (GNUNET_OK == + GNUNET_CRYPTO_blind_sig_verify (pub, + sig, + "hello", + 5)); + GNUNET_CRYPTO_blinded_sig_decref (bsig); + GNUNET_CRYPTO_unblinded_sig_decref (sig); + GNUNET_CRYPTO_blinded_message_decref (bm); + GNUNET_CRYPTO_blind_sign_priv_decref (priv); + GNUNET_CRYPTO_blind_sign_pub_decref (pub); + return 0; +} -- cgit v1.2.3