help-gnunet
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Help with hashing and signatures


From: Alessio Vanni
Subject: Help with hashing and signatures
Date: Tue, 04 Aug 2020 15:13:45 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux)

Hello,

I have a function used to sign some data and embed it in a larger
structure, defined like so:

     int
     sign_data(container, public_key, private_key) { ... }

(the type of the arguments are not included because they are not
important; the keys are the GNUnet structs used by egos.)

The function hashes the data inside the container using GNUnet's hashing
contexts and then signs the hash with the ECDSA signing functions.  The
problem is that when I do the reverse, i.e. verifying the signature, I'm
always getting a bad signature error.

The verify function is defined as:

     int
     verify_signature(container) { ... }

in which `container' contains the signature and the public key of the
signing entity.

Both functions hash the data using the following snippet (`msg' is the
formal name of `container' in the actual function.)

     #define MAXBYTES 8192
     struct SignatureData *sd = GNUNET_new(struct SignatureData);

     size_t segments = (msg->data_size / MAXBYTES) + 1;
     struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start();

     if (1 == segments) {
          GNUNET_CRYPTO_hash_context_read(hc, msg->data, msg->data_size);
     } else {
          size_t cursor = 0;
          for (size_t i=0; i<segments; ++i) {
               size_t mult = i * MAXBYTES;
               size_t sz = (msg->data_size - mult > MAXBYTES) ?
                    MAXBYTES :
                    msg->data_size - mult;

               GNUNET_CRYPTO_hash_context_read(hc, msg->data+cursor, sz);
               cursor += sz;
          }
     }

     GNUNET_CRYPTO_hash_context_finish(hc, &sd->hash);

     sd->purpose.size = htonl(sizeof(struct SignatureData));
     sd->purpose.purpose = htonl(SIGN_PURPOSE);

where `struct SignatureData' is defined as such:

     struct SignatureData {
          struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
          struct GNUNET_HashCode hash;
     };

After hashing the data, the signing function does this:

     struct GNUNET_CRYPTO_EcdsaSignature sig;
     GNUNET_CRYPTO_ecdsa_sign(private_key, sd, &sig);
     char *sstr = GNUNET_STRINGS_data_to_string_alloc(&sig, sizeof(sig));

`sstr' is then embedded in the container as explained earlier.

The verifying function first extracts the public key and the signature
from the container, like so:

     struct GNUNET_CRYPTO_EcdsaPublicKey pk;
     char *pkstr = extract_key(msg);
     size_t pklen = strlen(pkstr);
     GNUNET_CRYPTO_ecdsa_public_key_from_string(pkstr, pklen, &pk);

     struct GNUNET_CRYPTO_EcdsaSignature sig;
     char *sigstr = extract_sig(msg);
     size_t siglen = strlen(sigstr);
     GNUNET_STRINGS_string_to_data(sigstr, siglen, &sig, sizeof(sig));

After that it hashes the data with the same code as above and then
executes these statements:

     if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(SIGN_PURPOSE,
                                                 sd,
                                                 &sig,
                                                 &pk)) {
          ERRLOG(_("Message not verified!\n"));
          GNUNET_free(sd);
          return GNUNET_NO;
     }

The error happens here, as I'm always getting the error message and a
return value of GNUNET_NO.

I don't really know what I'm doing wrong here and the documentation
unfortunately isn't helpful at all, as the comments before the
`GNUNET_CRYPTO_ecdsa_verify' function isn't even about that function
(they list arguments that the function doesn't use.)  I'd really
appreciate some guidance here.

Thank you,
A.V.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]