/* This file is part of GNUnet. Copyright (C) 2020 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/gnunet-crypto-tgv.c * @brief Generate test vectors for cryptographic operations. * @author Florian Dold */ #include "platform.h" #include "gnunet_util_lib.h" #include "gnunet_signatures.h" #include "gnunet_testing_lib.h" #include GNUNET_NETWORK_STRUCT_BEGIN /** * Sample signature struct. * * Purpose is #GNUNET_SIGNATURE_PURPOSE_TEST */ struct TestSignatureDataPS { struct GNUNET_CRYPTO_EccSignaturePurpose purpose; uint32_t testval; }; GNUNET_NETWORK_STRUCT_END /** * Print data base32-crockford with a preceding label. * * @param label label to print * @param data data to print * @param size size of data */ static void display_data (char *label, void *data, size_t size) { char *enc = GNUNET_STRINGS_data_to_string_alloc (data, size); printf ("%s %s\n", label, enc); GNUNET_free (enc); } /** * Main function that will be run. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param cfg configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg) { { struct GNUNET_HashCode hc; char *str = "Hello, GNUnet"; GNUNET_CRYPTO_hash (str, strlen (str), &hc); printf ("hash code:\n"); display_data (" input", str, strlen (str)); display_data (" output", &hc, sizeof (struct GNUNET_HashCode)); } { struct GNUNET_CRYPTO_EcdhePrivateKey priv1; struct GNUNET_CRYPTO_EcdhePublicKey pub1; struct GNUNET_CRYPTO_EcdhePrivateKey priv2; struct GNUNET_HashCode skm; GNUNET_CRYPTO_ecdhe_key_create (&priv1); GNUNET_CRYPTO_ecdhe_key_create (&priv2); GNUNET_CRYPTO_ecdhe_key_get_public (&priv1, &pub1); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_ecc_ecdh (&priv2, &pub1, &skm)); printf ("ecdhe key:\n"); display_data (" priv1", &priv1, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); display_data (" pub1", &pub1, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); display_data (" priv2", &priv2, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); display_data (" skm", &skm, sizeof (struct GNUNET_HashCode)); } { struct GNUNET_CRYPTO_EddsaPrivateKey priv; struct GNUNET_CRYPTO_EddsaPublicKey pub; GNUNET_CRYPTO_eddsa_key_create (&priv); GNUNET_CRYPTO_eddsa_key_get_public (&priv, &pub); printf ("eddsa key:\n"); display_data (" priv", &priv, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); } { struct GNUNET_CRYPTO_EddsaPrivateKey priv; struct GNUNET_CRYPTO_EddsaPublicKey pub; struct GNUNET_CRYPTO_EddsaSignature sig; struct TestSignatureDataPS data = { 0 }; GNUNET_CRYPTO_eddsa_key_create (&priv); GNUNET_CRYPTO_eddsa_key_get_public (&priv, &pub); data.purpose.size = htonl (sizeof (data)); data.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST); GNUNET_CRYPTO_eddsa_sign (&priv, &data, &sig); GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST, &data, &sig, &pub)); printf ("eddsa sig:\n"); display_data (" priv", &priv, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); display_data (" pub", &pub, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); display_data (" data", &data, sizeof (struct TestSignatureDataPS)); display_data (" sig", &sig, sizeof (struct GNUNET_CRYPTO_EddsaSignature)); } { size_t out_len = 64; char out[out_len]; char *ikm = "I'm the secret input key material"; char *salt = "I'm very salty"; char *ctx = "I'm a context chunk, also known as 'info' in the RFC"; GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_kdf (&out, out_len, salt, strlen (salt), ikm, strlen (ikm), ctx, strlen (ctx), NULL)); printf ("kdf:\n"); display_data (" salt", salt, strlen (salt)); display_data (" ikm", ikm, strlen (ikm)); display_data (" ctx", ctx, strlen (ctx)); printf (" out_len %u\n", (unsigned int) out_len); display_data (" out", out, out_len); } { struct GNUNET_CRYPTO_EcdhePrivateKey priv_ecdhe; struct GNUNET_CRYPTO_EcdhePublicKey pub_ecdhe; struct GNUNET_CRYPTO_EddsaPrivateKey priv_eddsa; struct GNUNET_CRYPTO_EddsaPublicKey pub_eddsa; struct GNUNET_HashCode key_material; GNUNET_CRYPTO_ecdhe_key_create (&priv_ecdhe); GNUNET_CRYPTO_ecdhe_key_get_public (&priv_ecdhe, &pub_ecdhe); GNUNET_CRYPTO_eddsa_key_create (&priv_eddsa); GNUNET_CRYPTO_eddsa_key_get_public (&priv_eddsa, &pub_eddsa); GNUNET_CRYPTO_ecdh_eddsa (&priv_ecdhe, &pub_eddsa, &key_material); printf ("eddsa_ecdh:\n"); display_data (" priv_ecdhe", &priv_ecdhe, sizeof (struct GNUNET_CRYPTO_EcdhePrivateKey)); display_data (" pub_ecdhe", &pub_ecdhe, sizeof (struct GNUNET_CRYPTO_EcdhePublicKey)); display_data (" priv_eddsa", &priv_eddsa, sizeof (struct GNUNET_CRYPTO_EddsaPrivateKey)); display_data (" pub_eddsa", &pub_eddsa, sizeof (struct GNUNET_CRYPTO_EddsaPublicKey)); display_data (" key_material", &key_material, sizeof (struct GNUNET_HashCode)); } { struct GNUNET_CRYPTO_RsaPrivateKey *skey; struct GNUNET_CRYPTO_RsaPublicKey *pkey; struct GNUNET_HashCode message_hash; struct GNUNET_CRYPTO_RsaBlindingKeySecret bks; struct GNUNET_CRYPTO_RsaSignature *blinded_sig; struct GNUNET_CRYPTO_RsaSignature *sig; void *blinded_data; size_t blinded_len; void *public_enc_data; size_t public_enc_len; void *blinded_sig_enc_data; size_t blinded_sig_enc_length; void *sig_enc_data; size_t sig_enc_length; skey = GNUNET_CRYPTO_rsa_private_key_create (2048); pkey = GNUNET_CRYPTO_rsa_private_key_get_public (skey); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &message_hash, sizeof (struct GNUNET_HashCode)); GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, &bks, sizeof (struct GNUNET_CRYPTO_RsaBlindingKeySecret)); GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_blind (&message_hash, &bks, pkey, &blinded_data, &blinded_len)); blinded_sig = GNUNET_CRYPTO_rsa_sign_blinded (skey, blinded_data, blinded_len); sig = GNUNET_CRYPTO_rsa_unblind (blinded_sig, &bks, pkey); GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_rsa_verify (&message_hash, sig, pkey)); public_enc_len = GNUNET_CRYPTO_rsa_public_key_encode (pkey, &public_enc_data); blinded_sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (blinded_sig, & blinded_sig_enc_data); sig_enc_length = GNUNET_CRYPTO_rsa_signature_encode (sig, &sig_enc_data); printf ("blind signing:\n"); display_data (" message_hash", &message_hash, sizeof (struct GNUNET_HashCode)); display_data (" rsa_public_key", public_enc_data, public_enc_len); display_data (" blinding_key_secret", &bks, sizeof (struct GNUNET_CRYPTO_RsaBlindingKeySecret)); display_data (" blinded_message", blinded_data, blinded_len); display_data (" blinded_sig", blinded_sig_enc_data, blinded_sig_enc_length); display_data (" sig", sig_enc_data, sig_enc_length); GNUNET_CRYPTO_rsa_private_key_free (skey); GNUNET_CRYPTO_rsa_public_key_free (pkey); GNUNET_CRYPTO_rsa_signature_free (sig); GNUNET_CRYPTO_rsa_signature_free (blinded_sig); } } /** * The main function of the test vector generation tool. * * @param argc number of arguments from the command line * @param argv command line arguments * @return 0 ok, 1 on error */ int main (int argc, char *const *argv) { const struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_OPTION_END }; GNUNET_assert (GNUNET_OK == GNUNET_log_setup ("gnunet-crypto-tvg", "INFO", NULL)); if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "gnunet-crypto-tvg", "Generate test vectors for cryptographic operations", options, &run, NULL)) return 1; return 0; } /* end of gnunet-crypto-tvg.c */