OpenSSL Libarary: ECDSA: Как преобразовать несжатый ключ publi c в сжатый` - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть сжатый ключ publi c и я хочу преобразовать его в несжатый ключ publi c. Вот как я получаю ключи:

EC_KEY *key_pair_obj = nullptr;

BIGNUM *priv_key;

EC_POINT *pub_key;

EC_GROUP *secp256k1_group;

char *priv_key_char;
char *pub_key_char;
char *pub_key_char_comp;

int ret_error;

// Generate secp256k1 key pair
key_pair_obj = EC_KEY_new_by_curve_name(NID_secp256k1);
ret_error    = EC_KEY_generate_key(key_pair_obj);

// Get private key
priv_key      = (BIGNUM *)EC_KEY_get0_private_key(key_pair_obj);
priv_key_char = BN_bn2hex(priv_key);

// Get public key
pub_key            = (EC_POINT *)EC_KEY_get0_public_key(key_pair_obj);
secp256k1_group    = EC_GROUP_new_by_curve_name(NID_secp256k1);
pub_key_char       = EC_POINT_point2hex(secp256k1_group, pub_key, POINT_CONVERSION_UNCOMPRESSED, nullptr);

EC_GROUP_free(secp256k1_group);

printf("Private key        : %s\n\n", priv_key_char);
printf("Public key uncomp. : %s\n", pub_key_char_comp);

Я знаю, что могу использовать:

pub_key_char_comp  = EC_POINT_point2hex(secp256k1_group, pub_key, POINT_CONVERSION_COMPRESSED, nullptr);

... но я бы хотел преобразовать это позже. Как я могу это сделать?

1 Ответ

0 голосов
/ 13 апреля 2020

Текст вашего вопроса обратный от вашего названия и примера. Предполагая последнее:

Учитывая шестнадцатеричное представление несжатой формы точки c публикации (или любой другой точки) на кривой простого поля , такой как secp256k1, которая имеет вид Форма, подобная

 u = "04xxxxxxxxyyyyyyyy" // with lengths depending on curve's field

, для создания шестнадцатеричного представления сжатой формы сделайте что-то вроде:

 int k = strlen(u)/4; // hexit-pairs (value bytes) of each coordinate
 // or use known constant for curve e.g. 32 for secp256k1 
 char * c = malloc (k*2+2+1); // error handling needed but depends on program
 memcpy (c+2, u+2, k*2); // copy x
 memcpy (c, u[k*4+1] & 1? "03": "02", 2); // set first byte per low bit of y
 c[k*2+2] = '\0'; // string terminator 

Или, если вам не нужно сохранять несжатую форму, вы можете проще -используйте его OpenSSL_mallo c 'ed (хотя часть его тратится впустую):

 u[1] = '2' | u[k*4+1] & 1; 
 // leave u[0] and u[2..k*2+1] alone
 u[k*2+2] = '\0'; 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...