2017-02-02 57 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將其轉換回()'。 –