使用来自OpenSSL的EC_POINT_mul的奇怪结果
weird result using EC_POINT_mul from OpenSSL
我正在尝试实现一个基于Diffie-Hellman协议的私有集交集(PSI)协议。
PSI协议是[Kiss等人2017]第2.2节中提到的协议,,这里已经有一个Java实现:
https://github.com/encryptogroup/MobilePSI/blob/master/PSIServer/src/PSIDH.java
我想用C++实现它,所以我想到了使用OpenSSL
我想做什么
以下是它的大致工作原理:设CCD_ 1为diffie-hellman的生成元;alice具有DH秘密CCD_ 2和元素CCD_,bob具有DH秘密CCD_ 4和元素CCD_;h
是一些函数,它接受任何(位串)元素并将其映射到DH标量。
- alice发送
G*a*h(x)
(称之为alice侧) - bob回复
(G*a*h(x))*b
(称之为最后一方爱丽丝) - bob发送
G*b*h(y)
(称之为bob侧) - alice计算
G
0
Alice然后比较两个最终值以了解是否为x == y
。
代码
(最小工作示例)
利用G*a
是关于Diffie-Hellman的"Alice公钥"这一事实。
#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
的乘积只是"把事情搞砸了"。
知道发生了什么吗?
下面的代码应该可以完成这项工作。问题是将错误的参数传递给EC_POINT_mul()
。有关a
0的文档,请参见此处。
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;
}
相关文章:
- Qt5 部署"procedure entry point could not be located"
- boost beast Websocket Multi Request Server/Client 并不是真正的 mul
- 我想获取点的属性,它报告错误 C3867:"point::output_x":非标准语法;使用"&"创建指向成员的指针
- 如何从内存中分配GDI+ POINT类地址?
- 如何在OpenCV中存储部分轮廓点喜欢新矢量中的左侧,该类型为<vector<vector<Point>>
- 在每个向量<向量中查找最小/最大 x,y<Point>>
- "Entry Point Not Found" Azure 中的错误 LightGBM R 包
- 如何修复'The procedure entry point SDL_RWclose could not be located in the dynamic link library'
- 如何创建geometry_msgs :: point
- 为什么我会得到"floating point exception"
- Paraview:Live Point Cloud可视化插件
- Libavcodec "the procedure entry point for av_frame_alloc could not be located" Visual Studio 2017 C+
- 无法运行Qt C++发布版本。 'The procedure entry point could not be located'
- Parameters of OpenCV Mat::Mul
- 没有用于初始化'point'的匹配构造函数
- CGAL 如何将 std::vector<Point> 点保存到 .xyz 文件中?
- 我如何理解"Point of Instantiation"的含义
- "[Error] pointer value used where a floating point value was expected" 如何解决此错误?
- CreatePolygonRgn and const POINT *
- Qt QGraphicsScene origin point