2017-02-02 30 views
0

我试图做一个服务器和客户端,用C写的,交换mpz_t值。这些程序使用GMP库以及椭圆曲线库的一些功能。问题是客户端生成的值与服务器接收的值不同。你知道为什么会这样吗?C服务器和客户端交换mpz_t值不正确

int server(){ 
gmp_randstate_t status; 
mpz_t curv[2]; 
mpz_t p; 
mpz_t base_point[2]; 
mpz_t priv_numb; 
mpz_t rec; 
mpz_t key; 
int sockfd1, sockfd2; 
int clilen; 
struct sockaddr_un srv_addr, cl_addr; 
char *file="parameters.txt"; 


gmp_randinit_mt(status); 
mpz_init(curv[0]); mpz_init(curv[1]); 
mpz_init(p); 
mpz_init(base_point[0]); mpz_init(base_point[1]); 
mpz_init(priv_numb); 
mpz_init(rec); 
mpz_init(key); 

mpz_t seed; 
long sd; 
mpz_init(seed); 

srand((unsigned) getpid()); 
sd=rand(); 
mpz_set_ui(seed, sd); 

gmp_randseed(status, seed); 

mpz_urandomb(priv_numb, status, 8); 
gmp_printf("priv_numb %Zd\n", priv_numb); 

FILE *keyfd=fopen(file, "r"); 
gmp_fscanf(keyfd, "%Zd %Zd %Zd %Zd %Zd", curv[0], curv[1], p, base_point[0],base_point[1]); 

fclose(keyfd); 

gmp_printf("curv[0]: %Zd curv[1]: %Zd base[0]: %Zd\n base[1]: %Zd\n p: %Zd\n", curv[0], curv[1], base_point[0], base_point[1], p); 
myzmulmod(key, priv_numb, base_point, p);// key = private*base_point mod p 

gmp_printf("key: %Zd\n", key); 

sockfd1 = socket(AF_LOCAL, SOCK_STREAM, 0); 
if(!sockfd1) 
    printf("Error opening socket\n"); 
bzero(&srv_addr, sizeof(srv_addr)); 

srv_addr.sun_family = AF_LOCAL; 
strcpy(srv_addr.sun_path, UNIXSTR_PATH); 
unlink(srv_addr.sun_path); 
if(bind(sockfd1, (struct sockaddr*) &srv_addr, sizeof(srv_addr))<0) { 
    perror("Error on binding\n"); 
    exit(1); 
} 

listen(sockfd1,1); 
clilen = sizeof(cl_addr); 
sockfd2 = accept(sockfd1, (struct sockaddr *)&cl_addr, &clilen); 


if(recv(sockfd2, &rec, sizeof(mpz_t),0) <0) 
    printf("Could not receive key!!!\n"); 
else { 
    gmp_printf("Received: %Zd \n", rec); 
    printf("%d\n", sizeof(rec)); 
} 

if(close(sockfd1)<0) 
    perror("Error closing sockfd1"); 
if(close(sockfd2)<0) 
    perror("Error closing sockfd2"); 

gmp_randclear(stat); 
mpz_clear(curv[0]); mpz_clear(curv[1]); 
mpz_clear(p); 
mpz_clear(base_point[0]); mpz_clear(base_point[1]); 
mpz_clear(priv_numb); 
mpz_clear(key); 
return 0;} 



int client(){ 
gmp_randstate_t status; 
mpz_t curv[2]; 
mpz_t p; 
mpz_t base_point[2]; 
mpz_t priv_numb; 
mpz_t rec; mpz_t key; 
int sockfd1; 
int clilen; 
struct sockaddr_un srv_addr; 
char *file="parameters.txt"; 

gmp_randinit_mt(status); 
mpz_init(curv[0]); mpz_init(curv[1]); 
mpz_init(p); 
mpz_init(base_point[0]); mpz_init(base_point[1]); 
mpz_init(priv_numb); 
mpz_init(rec); 
mpz_init(key); 


FILE *keyfd=fopen(file, "r"); 
gmp_fscanf(keyfd, "%Zd %Zd %Zd %Zd %Zd", curv[0], curv[1], p, base_point[0],base_point[1]); 

fclose(keyfd); 

gmp_printf("curv[0]: %Zd curv[1]: %Zd base[0]: %Zd\n base[1]: %Zd\n p: %Zd\n", curv[0], curv[1], base_point[0], base_point[1], p); 

mpz_t seed; 
long sd; 
mpz_init(seed); 

srand((unsigned) getpid()); 
sd=rand(); 
mpz_set_ui(seed, sd); 
gmp_randseed(status, seed); 

mpz_urandomb(priv_numb, status, 8); 

gmp_printf("priv_numb %Zd\n", priv_numb); 
myzmulmod(key, priv_numb, base_point, p); 

sockfd1 = socket(AF_LOCAL, SOCK_STREAM, 0); 
if(!sockfd1) 
    printf("Error opening socket\n"); 
srv_addr.sun_family = AF_LOCAL; 
strcpy(srv_addr.sun_path, UNIXSTR_PATH); 


if(connect(sockfd1, (struct sockaddr *)&srv_addr, sizeof(srv_addr)) < 0) 
    printf("Connection error!!! \n"); 

if(send(sockfd1, &key, sizeof(key), 0)<0) 
    printf("Could not send public key!! \n"); 
else 
    { 
    printf("I sent %d bytes:", sizeof(key)); 
    gmp_printf(" %Zd\n", key); 
    } 

if(close(sockfd1)<0) 
    perror("Error closing socket!"); 

gmp_randclear(status); 
mpz_clear(curv[0]); mpz_clear(curv[1]); 
mpz_clear(p); 
mpz_clear(base_point[0]); mpz_clear(base_point[1]); 
mpz_clear(priv_numb); 
mpz_clear(key); 

return 0;} 
+1

'mpz_t'包含指向动态分配的数据 - 你是不是正确的序列化它。建议使用'key'上的mpz输出函数之一' –

+0

您的意思是像mpz_out_str? – despinac

回答

0

您需要将mpz_t秒值进行转换,以使用conversion functions的一个发送之前标准的C类型,然后将其转换回,当您收到他们使用assignment function

你应该为最大的可移植性也从主机字节顺序发送之前为网络字节顺序,然后将它们转换回从网络字节顺序,当您收到他们为主机字节顺序转换的C类型。您使用conversion functions in netinet/in.h来执行此操作。

+0

我尝试了你的建议,但是我在服务器中使用的赋值函数并没有恢复客户端产生的原始值。我认为这可能会发生,因为原始mpz_t值太大,所以只保留其中的一部分。在转换函数页面中提到了这可能会发生。有没有办法避免这种情况? – despinac

+0

你可以将其与'mpz_get_str()'转换成字符串,并将其发送这样的,然后用'mpz_set_str将其转换回()'。 –