help-gnunet
[Top][All Lists]
Advanced

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

Re: Help with hashing and signatures


From: TheJackiMonster
Subject: Re: Help with hashing and signatures
Date: Tue, 04 Aug 2020 16:21:27 +0200
User-agent: Evolution 3.36.4

Hello,

I am currently working on signing messages with ECDSA using GNUnets EGO
keys as well, so maybe I can help you.

On Tue, 2020-08-04 at 15:13 +0200, Alessio Vanni wrote:
> 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.

Does the `sd` variable contain the the same data in the verify function
as in the sign function? You wrote you would hash again but the
documentation mentions also: 

"The size field in ps->purpose must correctly indicate the number of
bytes of the data structure, including its header."

and

"purpose of the signature, must match 'ps->purpose.purpose' (except in
host byte order)"

So maybe these points are the root of your problem.

> 
> 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.
> 

Also a question: Why do you sign the hash values instead of the actual
data to calculate the hash? Do you have memory limitations?

Happy hacking
Jacki

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

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