I am trying to implement ECDH in libgcrypt. I have found examples online for how to compute a shared secret and I know how to do symmetric encryption I just can’t figure out how to generate the keypairs.
I want the keys to be stored as unsigned char *’s . This is how I am currently trying to do it but it always segfaults on the line gcry_mpi_ec_mul(mpi_public_key, mpi_private_key, NULL, ctx);
Here is my code: `
void generate_curve25519_keypair(unsigned char *public_key, unsigned char *private_key) {
gcry_error_t error;
gcry_mpi_t mpi_private_key;
gcry_mpi_point_t mpi_public_key;
gcry_ctx_t ctx;
// Generate a random private key
gcry_randomize(private_key, CURVE25519_KEY_SIZE, GCRY_STRONG_RANDOM);
// Clamp the private key for Curve25519
private_key[0] &= 248;
private_key[31] &= 127;
private_key[31] |= 64;
// Initialize the context for Curve25519
error = gcry_mpi_ec_new(&ctx, NULL, "Curve25519");
if (error) {
fprintf(stderr, "Failed to create context: %sn", gpg_strerror(error));
return;
}
// Convert the private key to an MPI
error = gcry_mpi_scan(&mpi_private_key, GCRYMPI_FMT_USG, private_key, CURVE25519_KEY_SIZE, NULL);
if (error) {
fprintf(stderr, "Failed to convert private key to MPI: %sn", gpg_strerror(error));
gcry_ctx_release(ctx);
return;
}
// Allocate memory for the resulting public key point
mpi_public_key = gcry_mpi_point_new(0);
// Multiply the base point with the private key MPI to get the public key point
gcry_mpi_ec_mul(mpi_public_key, mpi_private_key, NULL, ctx); // Use NULL for the default base point G
if (error) {
fprintf(stderr, "Failed to multiply with base point: %sn", gpg_strerror(error));
gcry_mpi_release(mpi_private_key);
gcry_mpi_point_release(mpi_public_key);
gcry_ctx_release(ctx);
return;
}
// Extract the x-coordinate of the public key point and convert it to a byte array
gcry_mpi_t mpi_x = gcry_mpi_new(0);
gcry_mpi_point_get(mpi_x, NULL, NULL, mpi_public_key);
error = gcry_mpi_print(GCRYMPI_FMT_USG, public_key, CURVE25519_KEY_SIZE, NULL, mpi_x);
if (error) {
fprintf(stderr, "Failed to export public key: %sn", gpg_strerror(error));
gcry_mpi_release(mpi_x);
gcry_mpi_release(mpi_private_key);
gcry_mpi_point_release(mpi_public_key);
gcry_ctx_release(ctx);
return;
}
// Release resources
gcry_mpi_release(mpi_x);
gcry_mpi_release(mpi_private_key);
gcry_mpi_point_release(mpi_public_key);
gcry_ctx_release(ctx);
}
New contributor
Daniel is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.