summaryrefslogtreecommitdiff
path: root/cipher/pubkey.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2013-09-07 10:06:46 +0200
committerWerner Koch <wk@gnupg.org>2013-09-18 13:14:31 +0200
commit63cd3474425cb5a7ec4d1a56be15b248ecda4680 (patch)
tree0cac978b7b066736b04c1205149834bfea406063 /cipher/pubkey.c
parent89fe2173649a72019d75e059e6c6938efd10421f (diff)
downloadlibgcrypt-63cd3474425cb5a7ec4d1a56be15b248ecda4680.tar.gz
ecc: Add Ed25519 key generation and prepare for optimizations.
* src/mpi.h (enum ecc_dialects): New. * src/ec-context.h (mpi_ec_ctx_s): Add field DIALECT. * cipher/ecc-common.h (elliptic_curve_t): Ditto. * cipher/ecc-curves.c (ecc_domain_parms_t): Ditto. (domain_parms): Add dialect values. (_gcry_ecc_fill_in_curve): Set dialect. (_gcry_ecc_get_curve): Ditto. (_gcry_mpi_ec_new): Ditto. (_gcry_ecc_get_param): Use ECC_DIALECT_STANDARD for now. * cipher/ecc-misc.c (_gcry_ecc_curve_copy): Copy dialect. (_gcry_ecc_dialect2str): New. * mpi/ec.c (ec_p_init): Add arg DIALECT. (_gcry_mpi_ec_p_internal_new): Ditto. (_gcry_mpi_ec_p_new): Ditto. * mpi/mpiutil.c (gcry_mpi_set_opaque): Set the secure flag. (_gcry_mpi_set_opaque_copy): New. * cipher/ecc-misc.c (_gcry_ecc_os2ec): Take care of an opaque MPI. * cipher/ecc.c (eddsa_generate_key): New. (generate_key): Rename to nist_generate_key and factor some code out to ... (ecc_generate_ext): here. Divert to eddsa_generate_key if desired. (eddsa_decodepoint): Take care of an opaque MPI. (ecc_check_secret_key): Ditto. (ecc_sign): Ditto. * cipher/pubkey.c (sexp_elements_extract_ecc): Store public and secret key as opaque MPIs. (gcry_pk_genkey): Add the curve_name also to the private key part of the result. * tests/benchmark.c (ecc_bench): Support Ed25519. (main): Add option --debug. * tests/curves.c (sample_key_2): Make sure that P and N are positive. * tests/keygen.c (show): New. (check_ecc_keys): Support Ed25519. -- There are two main purposes of this patch: Add a key generation feature for Ed25519 and add the "dialect" thingy which will eventually be used to add curve specific optimization. Note that the entire way of how we interface between the public key modules and pubkey.c is overly complex and probably also the cause for a lot of performance overhead. Given that we don't have the loadable module system anymore, we should entirely get rid of the MPI-array based internal interface and move parts of the s-expression handling direct into the pubkey modules. This needs to be fixed or we are turning Libgcrypt into another software incarnation of Heathrow Airport. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'cipher/pubkey.c')
-rw-r--r--cipher/pubkey.c50
1 files changed, 39 insertions, 11 deletions
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 949c5382..8fa7ebff 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -1903,7 +1903,16 @@ sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
elements[idx] = NULL;
else
{
- elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
+ switch (idx)
+ {
+ case 5: /* The public and */
+ case 6: /* the secret key must to be passed opaque. */
+ elements[idx] = _gcry_sexp_nth_opaque_mpi (list, 1);
+ break;
+ default:
+ elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_STD);
+ break;
+ }
gcry_sexp_release (list);
if (!elements[idx])
{
@@ -3706,6 +3715,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
size_t nelem=0, nelem_cp = 0, needed=0;
gcry_mpi_t mpis[30];
int percent_s_idx = -1;
+ int percent_s_idx2 = -1;
/* Estimate size of format string. */
nelem = strlen (pub_elems) + strlen (sec_elems);
@@ -3714,11 +3724,13 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
for (i = 0; factors[i]; i++)
nelem++;
}
+ if (extrainfo)
+ nelem += 2;
nelem_cp = nelem;
needed += nelem * 10;
- /* (+5 is for EXTRAINFO ("%S")). */
- needed += 2 * strlen (algo_name) + 300 + 5;
+ /* (+10 for two times EXTRAINFO ("%S")). */
+ needed += 2 * strlen (algo_name) + 300 + 10;
if (nelem > DIM (mpis))
BUG ();
@@ -3744,7 +3756,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
{
/* Very ugly hack to insert the used curve parameter into the
list of public key parameters. */
- percent_s_idx = nelem;
+ percent_s_idx = nelem++;
p = stpcpy (p, "%S");
}
p = stpcpy (p, "))");
@@ -3757,15 +3769,24 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
p = stpcpy (p, "%m)");
mpis[nelem++] = skey[i];
}
+ if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
+ {
+ percent_s_idx2 = nelem++;
+ p = stpcpy (p, "%S");
+ }
p = stpcpy (p, "))");
/* Hack to make release_mpi_array() work. */
skey[i] = NULL;
- if (extrainfo && percent_s_idx == -1)
+ if (extrainfo)
{
/* If we have extrainfo we should not have any factors. */
- p = stpcpy (p, "%S");
+ if (percent_s_idx == -1)
+ {
+ percent_s_idx = nelem++;
+ p = stpcpy (p, "%S");
+ }
}
else if (factors && factors[0])
{
@@ -3787,8 +3808,12 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
int elem_n = strlen (pub_elems) + strlen (sec_elems);
void **arg_list;
- /* Allocate one extra for EXTRAINFO ("%S"). */
- arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
+ if (percent_s_idx != -1)
+ elem_n++;
+ if (percent_s_idx2 != -1)
+ elem_n++;
+
+ arg_list = gcry_calloc (nelem_cp, sizeof *arg_list);
if (!arg_list)
{
rc = gpg_err_code_from_syserror ();
@@ -3798,10 +3823,13 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
{
if (i == percent_s_idx)
arg_list[j++] = &extrainfo;
- arg_list[j++] = mpis + i;
+ else if (i == percent_s_idx2)
+ arg_list[j++] = &extrainfo;
+ else
+ arg_list[j++] = mpis + i;
}
- if (extrainfo && percent_s_idx == -1)
- arg_list[j] = &extrainfo;
+ if (extrainfo)
+ ;
else if (factors && factors[0])
{
for (; i < nelem_cp; i++)