Update plibc header
[oweals/gnunet.git] / src / util / crypto_ecc.c
index 5ad0b81cb03c55200d682068eff26bd1c7c1a360..34edec3deca1702f023fcfb8d15e5f3233fd66a3 100644 (file)
  */
 #include "platform.h"
 #include <gcrypt.h>
-#include "gnunet_common.h"
 #include "gnunet_util_lib.h"
 
-#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS 
+#define EXTRA_CHECKS ALLOW_EXTRA_CHECKS
 
 /**
  * Name of the curve we are using.  Note that we have hard-coded
  * structs that use 256 bits, so using a bigger curve will require
  * changes that break stuff badly.  The name of the curve given here
  * must be agreed by all peers and be supported by libgcrypt.
+ *
+ * NOTE: this will change to Curve25519 before GNUnet 0.10.0.
  */
 #define CURVE "NIST P-256"
 
@@ -49,7 +50,7 @@
  * a failure of the command 'cmd' with the message given
  * by gcry_strerror(rc).
  */
-#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
+#define LOG_GCRY(level, cmd, rc) do { LOG(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0)
 
 
 /**
@@ -72,13 +73,13 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
   unsigned int idx;
 
   list = gcry_sexp_find_token (sexp, topname, 0);
-  if (! list)  
-    return 1;  
+  if (! list)
+    return 1;
   l2 = gcry_sexp_cadr (list);
   gcry_sexp_release (list);
   list = l2;
-  if (! list)  
-    return 2;  
+  if (! list)
+    return 2;
 
   idx = 0;
   for (s = elems; *s; s++, idx++)
@@ -113,11 +114,11 @@ key_from_sexp (gcry_mpi_t * array, gcry_sexp_t sexp, const char *topname,
 
 
 /**
- * If target != size, move target bytes to the end of the size-sized
- * buffer and zero out the first target-size bytes.
+ * If target != size, move @a target bytes to the end of the size-sized
+ * buffer and zero out the first @a target - @a size bytes.
  *
  * @param buf original buffer
- * @param size number of bytes in the buffer
+ * @param size number of bytes in @a buf
  * @param target target size of the buffer
  */
 static void
@@ -135,10 +136,10 @@ adjust (unsigned char *buf,
 
 /**
  * Output the given MPI value to the given buffer.
- * 
+ *
  * @param buf where to output to
- * @param size number of bytes in buf
- * @param val value to write to buf
+ * @param size number of bytes in @a buf
+ * @param val value to write to @a buf
  */
 static void
 mpi_print (unsigned char *buf,
@@ -170,7 +171,7 @@ mpi_scan (gcry_mpi_t *result,
   int rc;
 
   if (0 != (rc = gcry_mpi_scan (result,
-                               GCRYMPI_FMT_USG, 
+                               GCRYMPI_FMT_USG,
                                data, size, &size)))
   {
     LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
@@ -202,7 +203,7 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
   gcry_mpi_release (d);
   if (0 != rc)
   {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc); 
+    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
     GNUNET_assert (0);
   }
 #if EXTRA_CHECKS
@@ -223,15 +224,46 @@ decode_private_key (const struct GNUNET_CRYPTO_EccPrivateKey *priv)
  * @param q point on curve
  * @param pub public key struct to initialize
  * @param ctx context to use for ECC operations
- */ 
+ */
+static void
+point_to_public_sign_key (gcry_mpi_point_t q,
+                         gcry_ctx_t ctx,
+                         struct GNUNET_CRYPTO_EccPublicSignKey *pub)
+{
+  gcry_mpi_t q_x;
+  gcry_mpi_t q_y;
+
+  q_x = gcry_mpi_new (256);
+  q_y = gcry_mpi_new (256);
+  if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
+  {
+    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
+    return;
+  }
+
+  mpi_print (pub->q_x, sizeof (pub->q_x), q_x);
+  mpi_print (pub->q_y, sizeof (pub->q_y), q_y);
+  gcry_mpi_release (q_x);
+  gcry_mpi_release (q_y);
+}
+
+
+/**
+ * Initialize public key struct from the respective point
+ * on the curve.
+ *
+ * @param q point on curve
+ * @param pub public key struct to initialize
+ * @param ctx context to use for ECC operations
+ */
 static void
-point_to_public_key (gcry_mpi_point_t q,
-                    gcry_ctx_t ctx,
-                    struct GNUNET_CRYPTO_EccPublicKey *pub)
+point_to_public_encrypt_key (gcry_mpi_point_t q,
+                            gcry_ctx_t ctx,
+                            struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
 {
   gcry_mpi_t q_x;
   gcry_mpi_t q_y;
-  
+
   q_x = gcry_mpi_new (256);
   q_y = gcry_mpi_new (256);
   if (gcry_mpi_ec_get_affine (q_x, q_y, q, ctx))
@@ -254,8 +286,8 @@ point_to_public_key (gcry_mpi_point_t q,
  * @param pub where to write the public key
  */
 void
-GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
-                                  struct GNUNET_CRYPTO_EccPublicKey *pub)
+GNUNET_CRYPTO_ecc_key_get_public_for_signature (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
+                                               struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 {
   gcry_sexp_t sexp;
   gcry_ctx_t ctx;
@@ -266,7 +298,32 @@ GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv
   GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
   gcry_sexp_release (sexp);
   q = gcry_mpi_ec_get_point ("q", ctx, 0);
-  point_to_public_key (q, ctx, pub);
+  point_to_public_sign_key (q, ctx, pub);
+  gcry_ctx_release (ctx);
+  gcry_mpi_point_release (q);
+}
+
+
+/**
+ * Extract the public key for the given private key.
+ *
+ * @param priv the private key
+ * @param pub where to write the public key
+ */
+void
+GNUNET_CRYPTO_ecc_key_get_public_for_encryption (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
+                                                struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
+{
+  gcry_sexp_t sexp;
+  gcry_ctx_t ctx;
+  gcry_mpi_point_t q;
+
+  sexp = decode_private_key (priv);
+  GNUNET_assert (NULL != sexp);
+  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, sexp, NULL));
+  gcry_sexp_release (sexp);
+  q = gcry_mpi_ec_get_point ("q", ctx, 0);
+  point_to_public_encrypt_key (q, ctx, pub);
   gcry_ctx_release (ctx);
   gcry_mpi_point_release (q);
 }
@@ -276,22 +333,22 @@ GNUNET_CRYPTO_ecc_key_get_public (const struct GNUNET_CRYPTO_EccPrivateKey *priv
  * Convert a public key to a string.
  *
  * @param pub key to convert
- * @return string representing  'pub'
+ * @return string representing @a pub
  */
 char *
-GNUNET_CRYPTO_ecc_public_key_to_string (const struct GNUNET_CRYPTO_EccPublicKey *pub)
+GNUNET_CRYPTO_ecc_public_sign_key_to_string (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 {
   char *pubkeybuf;
-  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicKey)) * 8;
+  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)) * 8;
   char *end;
 
   if (keylen % 5 > 0)
     keylen += 5 - keylen % 5;
   keylen /= 5;
   pubkeybuf = GNUNET_malloc (keylen + 1);
-  end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub, 
-                                      sizeof (struct GNUNET_CRYPTO_EccPublicKey), 
-                                      pubkeybuf, 
+  end = GNUNET_STRINGS_data_to_string ((unsigned char *) pub,
+                                      sizeof (struct GNUNET_CRYPTO_EccPublicSignKey),
+                                      pubkeybuf,
                                       keylen);
   if (NULL == end)
   {
@@ -307,16 +364,16 @@ GNUNET_CRYPTO_ecc_public_key_to_string (const struct GNUNET_CRYPTO_EccPublicKey
  * Convert a string representing a public key to a public key.
  *
  * @param enc encoded public key
- * @param enclen number of bytes in enc (without 0-terminator)
+ * @param enclen number of bytes in @a enc (without 0-terminator)
  * @param pub where to store the public key
- * @return GNUNET_OK on success
+ * @return #GNUNET_OK on success
  */
 int
-GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc, 
+GNUNET_CRYPTO_ecc_public_sign_key_from_string (const char *enc,
                                          size_t enclen,
-                                         struct GNUNET_CRYPTO_EccPublicKey *pub)
+                                         struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 {
-  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicKey)) * 8;
+  size_t keylen = (sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)) * 8;
 
   if (keylen % 5 > 0)
     keylen += 5 - keylen % 5;
@@ -326,7 +383,7 @@ GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc,
 
   if (GNUNET_OK != GNUNET_STRINGS_string_to_data (enc, enclen,
                                                  pub,
-                                                 sizeof (struct GNUNET_CRYPTO_EccPublicKey)))
+                                                 sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)))
     return GNUNET_SYSERR;
   return GNUNET_OK;
 }
@@ -340,7 +397,7 @@ GNUNET_CRYPTO_ecc_public_key_from_string (const char *enc,
  * @return NULL on error
  */
 static gcry_sexp_t
-decode_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub)
+decode_public_sign_key (const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 {
   gcry_sexp_t pub_sexp;
   gcry_mpi_t q_x;
@@ -351,7 +408,7 @@ decode_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub)
   mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
   mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
   q = gcry_mpi_point_new (256);
-  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE); 
+  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
   gcry_mpi_release (q_x);
   gcry_mpi_release (q_y);
 
@@ -367,6 +424,19 @@ decode_public_key (const struct GNUNET_CRYPTO_EccPublicKey *pub)
 }
 
 
+/**
+ * @ingroup crypto
+ * Clear memory that was used to store a private key.
+ *
+ * @param pk location of the key
+ */
+void
+GNUNET_CRYPTO_ecc_key_clear (struct GNUNET_CRYPTO_EccPrivateKey *pk)
+{
+  memset (pk, 0, sizeof (struct GNUNET_CRYPTO_EccPrivateKey));
+}
+
+
 /**
  * Create a new private key. Caller must free return value.
  *
@@ -433,8 +503,8 @@ GNUNET_CRYPTO_ecc_key_get_anonymous ()
 
   if (once)
     return &anonymous;
-  mpi_print (anonymous.d, 
-            sizeof (anonymous.d), 
+  mpi_print (anonymous.d,
+            sizeof (anonymous.d),
             GCRYMPI_CONST_ONE);
   once = 1;
   return &anonymous;
@@ -620,6 +690,7 @@ GNUNET_CRYPTO_ecc_key_create_from_file (const char *filename)
  * Create a new private key by reading our peer's key from
  * the file specified in the configuration.
  *
+ * @param cfg the configuration to use
  * @return new private key, NULL on error (for example,
  *   permission denied)
  */
@@ -629,7 +700,7 @@ GNUNET_CRYPTO_ecc_key_create_from_configuration (const struct GNUNET_CONFIGURATI
   struct GNUNET_CRYPTO_EccPrivateKey *priv;
   char *fn;
 
-  if (GNUNET_OK != 
+  if (GNUNET_OK !=
       GNUNET_CONFIGURATION_get_value_filename (cfg, "PEER", "PRIVATE_KEY", &fn))
     return NULL;
   priv = GNUNET_CRYPTO_ecc_key_create_from_file (fn);
@@ -666,15 +737,14 @@ GNUNET_CRYPTO_ecc_setup_key (const char *cfg_name)
  *
  * @param cfg configuration to use
  * @param dst pointer to where to write the peer identity
- * @return GNUNET_OK on success, GNUNET_SYSERR if the identity
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if the identity
  *         could not be retrieved
  */
 int
-GNUNET_CRYPTO_get_host_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
+GNUNET_CRYPTO_get_peer_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
                                  struct GNUNET_PeerIdentity *dst)
 {
   struct GNUNET_CRYPTO_EccPrivateKey *priv;
-  struct GNUNET_CRYPTO_EccPublicKey pub;
 
   if (NULL == (priv = GNUNET_CRYPTO_ecc_key_create_from_configuration (cfg)))
   {
@@ -682,9 +752,8 @@ GNUNET_CRYPTO_get_host_identity (const struct GNUNET_CONFIGURATION_Handle *cfg,
                 _("Could not load peer's private key\n"));
     return GNUNET_SYSERR;
   }
-  GNUNET_CRYPTO_ecc_key_get_public (priv, &pub);
+  GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &dst->public_key);
   GNUNET_free (priv);
-  GNUNET_CRYPTO_hash (&pub, sizeof (pub), &dst->hashPubKey);
   return GNUNET_OK;
 }
 
@@ -723,7 +792,7 @@ data_to_pkcs1 (const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose)
  * @param priv private key to use for the signing
  * @param purpose what to sign (size, purpose)
  * @param sig where to write the signature
- * @return GNUNET_SYSERR on error, GNUNET_OK on success
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
  */
 int
 GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
@@ -774,14 +843,14 @@ GNUNET_CRYPTO_ecc_sign (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
  * @param validate block to validate (size, purpose, data)
  * @param sig signature that is being validated
  * @param pub public key of the signer
- * @returns GNUNET_OK if ok, GNUNET_SYSERR if invalid
+ * @returns #GNUNET_OK if ok, #GNUNET_SYSERR if invalid
  */
 int
 GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
                           const struct GNUNET_CRYPTO_EccSignaturePurpose
                           *validate,
                           const struct GNUNET_CRYPTO_EccSignature *sig,
-                          const struct GNUNET_CRYPTO_EccPublicKey *pub)
+                          const struct GNUNET_CRYPTO_EccPublicSignKey *pub)
 {
   gcry_sexp_t data;
   gcry_sexp_t sig_sexpr;
@@ -796,7 +865,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
   /* build s-expression for signature */
   mpi_scan (&r, sig->r, sizeof (sig->r));
   mpi_scan (&s, sig->s, sizeof (sig->s));
-  if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL, 
+  if (0 != (rc = gcry_sexp_build (&sig_sexpr, NULL,
                                  "(sig-val(ecdsa(r %m)(s %m)))",
                                   r, s)))
   {
@@ -808,7 +877,7 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
   gcry_mpi_release (r);
   gcry_mpi_release (s);
   data = data_to_pkcs1 (validate);
-  if (! (pub_sexpr = decode_public_key (pub)))
+  if (! (pub_sexpr = decode_public_sign_key (pub)))
   {
     gcry_sexp_release (data);
     gcry_sexp_release (sig_sexpr);
@@ -829,35 +898,65 @@ GNUNET_CRYPTO_ecc_verify (uint32_t purpose,
 }
 
 
+/**
+ * Convert the given public key from the network format to the
+ * S-expression that can be used by libgcrypt.
+ *
+ * @param pub public key to decode
+ * @return NULL on error
+ */
+static gcry_sexp_t
+decode_public_encrypt_key (const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub)
+{
+  gcry_sexp_t pub_sexp;
+  gcry_mpi_t q_x;
+  gcry_mpi_t q_y;
+  gcry_mpi_point_t q;
+  gcry_ctx_t ctx;
+
+  mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
+  mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
+  q = gcry_mpi_point_new (256);
+  gcry_mpi_point_set (q, q_x, q_y, GCRYMPI_CONST_ONE);
+  gcry_mpi_release (q_x);
+  gcry_mpi_release (q_y);
+
+  /* initialize 'ctx' with 'q' */
+  GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
+  gcry_mpi_ec_set_point ("q", q, ctx);
+  gcry_mpi_point_release (q);
+
+  /* convert 'ctx' to 'sexp' */
+  GNUNET_assert (0 == gcry_pubkey_get_sexp (&pub_sexp, GCRY_PK_GET_PUBKEY, ctx));
+  gcry_ctx_release (ctx);
+  return pub_sexp;
+}
+
+
 /**
  * Derive key material from a public and a private ECC key.
  *
  * @param priv private key to use for the ECDH (x)
  * @param pub public key to use for the ECDH (yG)
  * @param key_material where to write the key material (xyG)
- * @return GNUNET_SYSERR on error, GNUNET_OK on success
+ * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
  */
 int
 GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
-                        const struct GNUNET_CRYPTO_EccPublicKey *pub,
+                        const struct GNUNET_CRYPTO_EccPublicEncryptKey *pub,
                         struct GNUNET_HashCode *key_material)
-{ 
-  size_t slen;
-  unsigned char sdata_buf[2048]; /* big enough to print
-                                   dh-shared-secret as
-                                   S-expression */
+{
   gcry_mpi_point_t result;
   gcry_mpi_point_t q;
   gcry_mpi_t d;
   gcry_ctx_t ctx;
   gcry_sexp_t pub_sexpr;
-  gcry_sexp_t ecdh_sexp;
   gcry_mpi_t result_x;
   gcry_mpi_t result_y;
-  int rc;
+  unsigned char xbuf[256 / 8];
 
   /* first, extract the q = dP value from the public key */
-  if (! (pub_sexpr = decode_public_key (pub)))
+  if (! (pub_sexpr = decode_public_encrypt_key (pub)))
     return GNUNET_SYSERR;
   GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
   gcry_sexp_release (pub_sexpr);
@@ -884,32 +983,17 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
   }
   gcry_mpi_point_release (result);
   gcry_ctx_release (ctx);
-  if (0 != (rc = gcry_sexp_build (&ecdh_sexp, NULL, 
-                                 "(dh-shared-secret (x %m)(y %m))",
-                                 result_x,
-                                 result_y)))
-  {
-    LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
-    gcry_mpi_release (result_x);
-    gcry_mpi_release (result_y);
-    return GNUNET_SYSERR;
-  }
+
+  mpi_print (xbuf, sizeof (xbuf), result_x);
+  GNUNET_CRYPTO_hash (xbuf, sizeof (xbuf), key_material);
   gcry_mpi_release (result_x);
   gcry_mpi_release (result_y);
-  slen = gcry_sexp_sprint (ecdh_sexp,
-                          GCRYSEXP_FMT_DEFAULT, 
-                          sdata_buf, sizeof (sdata_buf));
-  GNUNET_assert (0 != slen);
-  gcry_sexp_release (ecdh_sexp);
-  /* finally, get a string of the resulting S-expression and hash it
-     to generate the key material */
-  GNUNET_CRYPTO_hash (sdata_buf, slen, key_material);
   return GNUNET_OK;
 }
 
 
 /**
- * Derive the 'h' value for key derivation, where 
+ * Derive the 'h' value for key derivation, where
  * 'h = H(l,P)'.
  *
  * @param pub public key for deriviation
@@ -917,9 +1001,9 @@ GNUNET_CRYPTO_ecc_ecdh (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
  * @param context additional context to use for HKDF of 'h';
  *        typically the name of the subsystem/application
  * @return h value
- */ 
-static gcry_mpi_t 
-derive_h (const struct GNUNET_CRYPTO_EccPublicKey *pub,
+ */
+static gcry_mpi_t
+derive_h (const struct GNUNET_CRYPTO_EccPublicSignKey *pub,
          const char *label,
          const char *context)
 {
@@ -954,7 +1038,7 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
                              const char *label,
                              const char *context)
 {
-  struct GNUNET_CRYPTO_EccPublicKey pub;
+  struct GNUNET_CRYPTO_EccPublicSignKey pub;
   struct GNUNET_CRYPTO_EccPrivateKey *ret;
   gcry_mpi_t h;
   gcry_mpi_t x;
@@ -964,7 +1048,7 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
 
   GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
   n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
-  GNUNET_CRYPTO_ecc_key_get_public (priv, &pub);
+  GNUNET_CRYPTO_ecc_key_get_public_for_signature (priv, &pub);
   h = derive_h (&pub, label, context);
   mpi_scan (&x, priv->d, sizeof (priv->d));
   d = gcry_mpi_new (256);
@@ -991,10 +1075,10 @@ GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
  * @param result where to write the derived public key
  */
 void
-GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicKey *pub,
+GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicSignKey *pub,
                                     const char *label,
                                     const char *context,
-                                    struct GNUNET_CRYPTO_EccPublicKey *result)
+                                    struct GNUNET_CRYPTO_EccPublicSignKey *result)
 {
   gcry_ctx_t ctx;
   gcry_mpi_t h;
@@ -1006,7 +1090,7 @@ GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicKey *pu
   gcry_mpi_point_t v;
 
   GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
-  
+
   /* obtain point 'q' from original public key */
   mpi_scan (&q_x, pub->q_x, sizeof (pub->q_x));
   mpi_scan (&q_y, pub->q_y, sizeof (pub->q_y));
@@ -1029,7 +1113,7 @@ GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicKey *pu
   gcry_mpi_release (n);
   gcry_mpi_point_release (q);
   /* convert point 'v' to public key that we return */
-  point_to_public_key (v, ctx, result);
+  point_to_public_sign_key (v, ctx, result);
   gcry_mpi_point_release (v);
   gcry_ctx_release (ctx);
 }