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);
*
* @param pub public key for deriviation
* @param label label for deriviation
+ * @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,
- const char *label)
+ const char *label,
+ const char *context)
{
gcry_mpi_t h;
struct GNUNET_HashCode hc;
GNUNET_CRYPTO_kdf (&hc, sizeof (hc),
"key-derivation", strlen ("key-derivation"),
pub, sizeof (*pub),
- label, sizeof (label),
+ label, strlen (label),
+ context, strlen (context),
NULL, 0);
mpi_scan (&h, (unsigned char *) &hc, sizeof (hc));
return h;
*
* @param priv original private key
* @param label label to use for key deriviation
+ * @param context additional context to use for HKDF of 'h';
+ * typically the name of the subsystem/application
* @return derived private key
*/
struct GNUNET_CRYPTO_EccPrivateKey *
GNUNET_CRYPTO_ecc_key_derive (const struct GNUNET_CRYPTO_EccPrivateKey *priv,
- const char *label)
+ const char *label,
+ const char *context)
{
struct GNUNET_CRYPTO_EccPublicKey pub;
struct GNUNET_CRYPTO_EccPrivateKey *ret;
gcry_ctx_t ctx;
GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, NULL, CURVE));
- n = gcry_mpi_ec_get_mpi ("n", ctx, 0 /* no copy */);
+ n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
GNUNET_CRYPTO_ecc_key_get_public (priv, &pub);
- h = derive_h (&pub, label);
+ h = derive_h (&pub, label, context);
mpi_scan (&x, priv->d, sizeof (priv->d));
d = gcry_mpi_new (256);
gcry_mpi_mulm (d, h, x, n);
gcry_mpi_release (h);
gcry_mpi_release (x);
+ gcry_mpi_release (n);
+ gcry_ctx_release (ctx);
ret = GNUNET_new (struct GNUNET_CRYPTO_EccPrivateKey);
mpi_print (ret->d, sizeof (ret->d), d);
gcry_mpi_release (d);
*
* @param pub original public key
* @param label label to use for key deriviation
+ * @param context additional context to use for HKDF of 'h';
+ * typically the name of the subsystem/application
* @param result where to write the derived public key
*/
void
GNUNET_CRYPTO_ecc_public_key_derive (const struct GNUNET_CRYPTO_EccPublicKey *pub,
const char *label,
+ const char *context,
struct GNUNET_CRYPTO_EccPublicKey *result)
{
gcry_ctx_t ctx;
gcry_mpi_release (q_y);
/* calulcate h_mod_n = h % n */
- h = derive_h (pub, label);
- n = gcry_mpi_ec_get_mpi ("n", ctx, 0 /* no copy */);
+ h = derive_h (pub, label, context);
+ n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
h_mod_n = gcry_mpi_new (256);
gcry_mpi_mod (h_mod_n, h, n);
/* calculate v = h_mod_n * q */
gcry_mpi_ec_mul (v, h_mod_n, q, ctx);
gcry_mpi_release (h_mod_n);
gcry_mpi_release (h);
+ 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);