q not derived from d in gcry_pk_sign

Christian Grothoff grothoff at in.tum.de
Fri Mar 22 17:26:09 CET 2013

On 03/22/2013 03:43 PM, Werner Koch wrote:
> On Fri, 22 Mar 2013 10:19, grothoff at in.tum.de said:
>> 'q' value is not found (as it is neither in the curve nor explicitly in
>> the S-expression); however, q can of course be calculated as q = dg
>> from the private key and the curve.
> Right.  That raises another question.  In contrast to gcry_cipher_ and
> gcry_md_, the gcry_pk_ functions don't follow an open-process-close
> paradigm and thus have no associated context.  For the fast ECC
> operations we have seen that a context is sometimes useful to speed up
> operations.  To some degree this would also be true for the other
> algorithms.  For example, I never implemented Montgomery multiplication
> because a real performance gain could only be achieved if we would be
> able to cache temporary values.  The original idea was to employ a real
> cache for this, however that requires quite some code to get it right
> and thread safe.  If we could use a caller provided context instead,
> this would shift the responsibility of caching to the caller, who better
> knows whether it makes sense.

You might even require the caller to take care of the locking (i.e. you 
must only use each context in one thread at a time).

> Given that we have an ABI break anyway, I consider to add a context
> argument to all gcry_pk_ functions which may eventually be used to
> implement such features.  For now we would just pass NULL for the
> context but we may then start to experiment without breaking the ABI or
> API.

I like the idea, but I'm not sure about why you'd risk breaking the API;
in my experience that causes Debian to not update your package for about
a decade, and that would be unfortunate.  Introducing a
gcry_pk_sign2 function with context and having the old one create a
context on-the-fly (and destroy it immediately again) should suffice
without causing too much bloat.  The existing ABI changes for 1.6 seemed
minor (i.e. didn't touch GNUnet at all, and we use libgcrypt a lot);
that would not be true for adding the NULL context; also, moving to a
macro breaks just as badly, so I'd keep gcry_pk_sign as a real, 
backwards-compatible, exported function.

>   gcry_error_t gcry_pk_sign_ext (gcry_sexp_t *result,
>                                  gcry_sexp_t data, gcry_sexp_t skey,
>                                  gcry_ctx_t ctx);
>   #define gcry_pk_sign(a,b,c) gcry_pk_sign_ext ((a),(b),(c), NULL)
> (Or should we use gcry_pubkey_foo instead of gcry_pk_sign_ext ?)

I'd personally not use a generic context but one specific to the
primitive and then it would be gcry_ec_sign (gcry_ec_ctx_t, ...),
even if the interface would not be as generic.  If we later need
the super-generic interface with a context, we can always add a
union gcry_pk_ctx with a generic pk_sign function.  I'm just
not sure that'll ever be needed; and if it is, I'd still want the
low-level EC primitives to not use the generic pk_ctx as then the
compiler wouldn't bark at passing an RSA ctx to a low-level
EC operation.

>> The nicest fix I can think of right now would be a change to how
>> sexp_elements_extract_ecc' works (i.e. reporting "got all" even
>> if q was not found and forcing the caller to manually check&
> Given that ECC is not yet in widespread use it would be okay to go with
> this little interface change.

What I proposed for sexp_elements_extract_ecc wasn't really an interface 
change, as the function that would change is completely internal.  The 
only visible change to the outside is that ECC calls
with d and without q would work instead of fail, whereas previously
they'd fail.  So that's pretty much just a bugfix, as no application
should *rely* on that failure.

My 2 cents


More information about the Gcrypt-devel mailing list