странный результат с использованием EC_POINT_mul из OpenSSL

Я пытаюсь реализовать протокол пересечения частных наборов (PSI), основанный на протоколе Диффи-Хеллмана.

Протокол PSI — это протокол, упомянутый в разделе 2.2 [Kiss et al. 2017] ,,
здесь уже есть реализация Java:

https://github.com/encryptogroup/MobilePSI/blob/master/PSIServer/src/PSIDH.java

Я хочу реализовать это в C ++, поэтому я подумал об использовании OpenSSL

Вот примерно как это работает:
позволять G быть генератором Диффи-Хеллмана;
у Алисы есть секрет DH a и элемент x,
Боб имеет секрет DH b и элемент y;
h это некоторая функция, которая берет любой (цепочка битов) элемент и отображает его в скаляр DH.

  • Алиса отправляет G*a*h(x) (назови это сторона Алисы)
  • Боб отвечает с (G*a*h(x))*b (назови это последняя сторона Алисы)
  • Боб посылает G*b*h(y) (назови это сторона боба)
  • Алиса вычисляет (G*b*h(y))*a

Затем Алиса сравнивает оба окончательных значения, чтобы выяснить, x == y или нет.

(минимальный рабочий пример)

Используя тот факт, что G*a это то, что является «открытым ключом Алисы» в отношении Диффи-Хеллмана.

#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <iostream>

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

// list of possible curve names here:
// https://git.openssl.org/gitweb/?p=openssl.git;a=blob;f=crypto/objects/obj_mac.h;h=b5ea7cdab4f84b90280f0a3aae1478a8d715c7a7;hb=46ebd9e3bb623d3c15ef2203038956f3f7213620#l385
// also here:
// https://github.com/openssl/openssl/blob/67e247fad12308e34817e60c9242113c285fb00c/include/openssl/obj_mac.h#L261
#define CURVE_NAME NID_X9_62_prime256v1

class PSIEntity {
public:
BN_CTX* bn_ctx;
const EC_GROUP* ec_group;
EC_KEY* key;

PSIEntity(BN_CTX* c, const EC_GROUP* g){
bn_ctx = c;

ec_group = g;
key = EC_KEY_new();
EC_KEY_set_group(key, ec_group);
EC_KEY_generate_key(key);
}

EC_POINT* encode_and_mask(const unsigned char* x_data){
BIGNUM* x = BN_bin2bn(x_data, 28, NULL);

const EC_POINT* pubkey = EC_KEY_get0_public_key(key);
EC_POINT* result = EC_POINT_dup(pubkey, ec_group);

EC_POINT_mul(ec_group, result, x, NULL, NULL, bn_ctx);

return result;
}

EC_POINT* mask(EC_POINT* p){
EC_POINT* result = EC_POINT_dup(p, ec_group);
const BIGNUM *priv_key = EC_KEY_get0_private_key(key);
EC_POINT_mul(ec_group, result, priv_key, NULL, NULL, bn_ctx);

return result;
}
};int main(){
EC_GROUP *ec_group = EC_GROUP_new_by_curve_name(CURVE_NAME);
BN_CTX *bn_ctx = BN_CTX_new();

PSIEntity alice(bn_ctx, ec_group);
PSIEntity bob(bn_ctx, ec_group);

// taken from "a_bin" in
// https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography#Defining_Curves
unsigned char x_data[28] =
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE};

EC_POINT* alice_side = alice.encode_and_mask(x_data);
EC_POINT* alice_side_final = bob.mask(alice_side);

EC_POINT* bob_side = bob.encode_and_mask(x_data);
EC_POINT* bob_side_final = alice.mask(bob_side);

int final_points_are_different = EC_POINT_cmp(ec_group,
alice_side_final, bob_side_final,
bn_ctx);
if(final_points_are_different==-1){
std::cout << "comparison of final points failed" << std::endl;
}else if(final_points_are_different==1){
std::cout << "final points are different" << std::endl;
}else if(final_points_are_different==0){
std::cout << "final points are equal" << std::endl;
}

int temp_points_are_different = EC_POINT_cmp(ec_group,
alice_side, bob_side,
bn_ctx);
if(temp_points_are_different==-1){
std::cout << "comparison of temp points failed" << std::endl;
}else if(temp_points_are_different==1){
std::cout << "temp points are different" << std::endl;
}else if(temp_points_are_different==0){
std::cout << "temp points are equal" << std::endl;
}
return 0;
}

Результат:

final points are different
temp points are equal

Я ожидал бы обратного:
конечные точки должны быть равны, потому что это то же самое x с обеих сторон

Относительно «Темп-очки равны», это очень тревожно
это означает, что у нас есть G*a*x == G*b*x ?

Если вы сравните G*a с G*b (открытые ключи) ответ в том, что они разные, так что, похоже, происходит то, что умножение на x с EC_POINT_mul просто «все портит».

Есть идеи, что происходит?

0

Решение

Следующий код должен сделать эту работу. Проблема в передаче неверных параметров EC_POINT_mul(), Увидеть Вот для документации EC_POINT_mul(),

EC_POINT* encode_and_mask(const unsigned char* x_data){
...
EC_POINT_mul(ec_group, result, NULL, result, x, bn_ctx);

return result;
}

EC_POINT* mask(EC_POINT* p){
...
EC_POINT_mul(ec_group, result, NULL, result, priv_key, bn_ctx);

return result;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]