Compute EC_KEY starting from X or Y coordinate only

Luca Di Mauro luca.dimauro at cnit.it
Thu Oct 24 21:00:08 UTC 2019


Hi,
the link you posted below are very useful!

However, after many trials and errors, I created a little program to  
derive a public key from an x-only coordinate but, in the last step,  
it fails, namely in the function  
'EC_POINT_set_compressed_coordinates_GFp' called in the function  
'loadKey_xOnly'.
Here the whole code:


#include <iostream>
#include <string>
#include <cstring>

#include <openssl/ec.h>
#include <openssl/ecdsa.h>
#include <openssl/obj_mac.h>
#include <openssl/err.h>

char *ossl_err_as_string (void)
{ BIO *bio = BIO_new (BIO_s_mem ());
   ERR_print_errors (bio);
   char *buf = NULL;
   size_t len = BIO_get_mem_data (bio, &buf);
   char *ret = (char *) calloc (1, 1 + len);
   if (ret)
     memcpy (ret, buf, len);
   BIO_free (bio);
   return ret;
}


void printAndExit (std::string s) {
	std::cerr << "ERROR!\n" << s << std::endl << ossl_err_as_string () <<  
std::endl;
	exit(EXIT_FAILURE);
}


EC_KEY* loadKey_xOnly (std::string& xOnly) {
	EC_GROUP* group		= EC_GROUP_new_by_curve_name (NID_secp256k1);
	if (group == NULL)
		printAndExit ("group null");

	EC_GROUP_set_point_conversion_form (group, POINT_CONVERSION_COMPRESSED);
	EC_POINT* pubPoint	= EC_POINT_new (group);
	if (pubPoint == NULL)
		printAndExit ("pibpoint == null");

	BN_CTX* bnCtx	= BN_CTX_new ();
	BIGNUM* x		= BN_new ();
	if (x == NULL)
		printAndExit ("X == NULL");

	if (BN_hex2bn (&x, (const char*) xOnly.c_str()) == 0)
		printAndExit ("hex2bn == 0");

	std::cout << "x_BN:\t" << BN_bn2hex (x) << std::endl;
	std::cout << "x_BA:\t" << xOnly << std::endl;

	if (EC_POINT_set_compressed_coordinates_GFp (group, pubPoint, x, 0,  
bnCtx) == 0)
		printAndExit ("set_compr_coord == 0");
}



int main () {
	std::string xOnlyStr	=  
"c16b4ce0532f5dc9d09114fe121d3956ae84f9eb677a0d4bdac1d3af7a91950c";
	EC_KEY* key				= loadKey_xOnly (xOnlyStr);

	return 0;
}

The string 'xOnlyStr' contains a real x-only coordinate of a verification key.

Could you help me?

Thank you,

Luca Di Mauro

Luca Di Mauro <luca.dimauro at cnit.it> ha scritto:

> Thank you very much for the reply!
> Yes, I have also the additional information about on which of two  
> solutions I should take.
>
> I'll check the guides you linked below.
>
> Luca Di Mauro
>
> Nicola Tuveri <nic.tuv at gmail.com> ha scritto:
>
>> Hi,
>>
>> with traditional EC from the x coordinate alone you can't really do that,
>> because there are always 2 possible solutions for y (in R the curve is
>> symmetrical on the x axis).
>>
>> The standards define a "compressed point" format in which you can send the
>> coordinate x and an additional bit to select which of the 2 y solutions to
>> pick.
>>
>> You can read more about it in EC_GROUP_set_point_conversion_form at
>> https://www.openssl.org/docs/man1.1.1/man3/EC_GROUP_copy.html
>>
>> and in EC_POINT_set_compressed_coordinates at
>> https://www.openssl.org/docs/man1.1.1/man3/EC_POINT_new.html
>>
>> Hope this helps,
>>
>> Nicola Tuveri
>>
>>
>> On Fri, Oct 18, 2019, 11:31 Luca Di Mauro <luca.dimauro at cnit.it> wrote:
>>
>>>
>>> Hello all,
>>>
>>> I don't know if it is the correct mailing list to ask this, so I'm
>>> sorry if it is the wrong palce.
>>>
>>> I'm using openssl v1.1, and I'm trying to compute both the X and Y
>>> coordinates of an elliptic curve point starting from a single
>>> coordinate (X or Y).
>>>
>>> How can i perform that in C/C++ language using libssl? I searched on
>>> google for a couple of days but i haven't found a solution.
>>>
>>> Luca Di Mauro
>>>
>>>
>>>





More information about the openssl-users mailing list