aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ecc.c
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-04 12:43:47 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-01-04 12:43:47 +0000
commit588c1bd23e49f3264bdfdb3b02c7cf6e78b66534 (patch)
tree2fe3b1f9e930a75675eb7e75aaab5100cb13ab54 /src/util/crypto_ecc.c
parent1af781131216a54772885e8514d5a9c9ef2f6cd0 (diff)
downloadgnunet-588c1bd23e49f3264bdfdb3b02c7cf6e78b66534.tar.gz
gnunet-588c1bd23e49f3264bdfdb3b02c7cf6e78b66534.zip
- Add ecdsa ecdh functions
- Update identity token to encrypted protocol
Diffstat (limited to 'src/util/crypto_ecc.c')
-rw-r--r--src/util/crypto_ecc.c91
1 files changed, 90 insertions, 1 deletions
diff --git a/src/util/crypto_ecc.c b/src/util/crypto_ecc.c
index bcc04fea5..c4e101369 100644
--- a/src/util/crypto_ecc.c
+++ b/src/util/crypto_ecc.c
@@ -1298,6 +1298,77 @@ GNUNET_CRYPTO_eddsa_ecdh (const struct GNUNET_CRYPTO_EddsaPrivateKey *priv,
1298 return GNUNET_OK; 1298 return GNUNET_OK;
1299} 1299}
1300 1300
1301/**
1302 * @ingroup crypto
1303 * Derive key material from a ECDH public key and a private ECDSA key.
1304 * Dual to #GNUNET_CRRYPTO_ecdh_eddsa.
1305 *
1306 * @param priv private key from ECDSA to use for the ECDH (x)
1307 * @param pub public key to use for the ECDH (yG)
1308 * @param key_material where to write the key material H(h(x)yG)
1309 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
1310 */
1311int
1312GNUNET_CRYPTO_ecdsa_ecdh (const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv,
1313 const struct GNUNET_CRYPTO_EcdhePublicKey *pub,
1314 struct GNUNET_HashCode *key_material)
1315{
1316 gcry_mpi_point_t result;
1317 gcry_mpi_point_t q;
1318 gcry_mpi_t d;
1319 gcry_ctx_t ctx;
1320 gcry_sexp_t pub_sexpr;
1321 gcry_mpi_t result_x;
1322 unsigned char xbuf[256 / 8];
1323 size_t rsize;
1324
1325 /* first, extract the q = dP value from the public key */
1326 if (0 != gcry_sexp_build (&pub_sexpr, NULL,
1327 "(public-key(ecc(curve " CURVE ")(q %b)))",
1328 (int)sizeof (pub->q_y), pub->q_y))
1329 return GNUNET_SYSERR;
1330 GNUNET_assert (0 == gcry_mpi_ec_new (&ctx, pub_sexpr, NULL));
1331 gcry_sexp_release (pub_sexpr);
1332 q = gcry_mpi_ec_get_point ("q", ctx, 0);
1333
1334 /* second, extract the d value from our private key */
1335 GNUNET_CRYPTO_mpi_scan_unsigned (&d, priv->d, sizeof (priv->d));
1336
1337 /* then call the 'multiply' function, to compute the product */
1338 result = gcry_mpi_point_new (0);
1339 gcry_mpi_ec_mul (result, d, q, ctx);
1340 gcry_mpi_point_release (q);
1341 gcry_mpi_release (d);
1342
1343 /* finally, convert point to string for hashing */
1344 result_x = gcry_mpi_new (256);
1345 if (gcry_mpi_ec_get_affine (result_x, NULL, result, ctx))
1346 {
1347 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "get_affine failed", 0);
1348 gcry_mpi_point_release (result);
1349 gcry_ctx_release (ctx);
1350 return GNUNET_SYSERR;
1351 }
1352 gcry_mpi_point_release (result);
1353 gcry_ctx_release (ctx);
1354
1355 rsize = sizeof (xbuf);
1356 GNUNET_assert (! gcry_mpi_get_flag (result_x, GCRYMPI_FLAG_OPAQUE));
1357 /* result_x can be negative here, so we do not use 'GNUNET_CRYPTO_mpi_print_unsigned'
1358 as that does not include the sign bit; x should be a 255-bit
1359 value, so with the sign it should fit snugly into the 256-bit
1360 xbuf */
1361 GNUNET_assert (0 ==
1362 gcry_mpi_print (GCRYMPI_FMT_STD, xbuf, rsize, &rsize,
1363 result_x));
1364 GNUNET_CRYPTO_hash (xbuf,
1365 rsize,
1366 key_material);
1367 gcry_mpi_release (result_x);
1368 return GNUNET_OK;
1369}
1370
1371
1301 1372
1302/** 1373/**
1303 * @ingroup crypto 1374 * @ingroup crypto
@@ -1369,6 +1440,24 @@ GNUNET_CRYPTO_ecdh_eddsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1369 return GNUNET_OK; 1440 return GNUNET_OK;
1370} 1441}
1371 1442
1372 1443/**
1444 * @ingroup crypto
1445 * Derive key material from a ECDSA public key and a private ECDH key.
1446 * Dual to #GNUNET_CRRYPTO_eddsa_ecdh.
1447 *
1448 * @param priv private key to use for the ECDH (y)
1449 * @param pub public key from ECDSA to use for the ECDH (X=h(x)G)
1450 * @param key_material where to write the key material H(yX)=H(h(x)yG)
1451 * @return #GNUNET_SYSERR on error, #GNUNET_OK on success
1452 */
1453int
1454GNUNET_CRYPTO_ecdh_ecdsa (const struct GNUNET_CRYPTO_EcdhePrivateKey *priv,
1455 const struct GNUNET_CRYPTO_EcdsaPublicKey *pub,
1456 struct GNUNET_HashCode *key_material)
1457{
1458 return GNUNET_CRYPTO_ecdh_eddsa (priv,
1459 (const struct GNUNET_CRYPTO_EddsaPublicKey *)pub,
1460 key_material);
1461}
1373 1462
1374/* end of crypto_ecc.c */ 1463/* end of crypto_ecc.c */