2017-02-02 2 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' содержит указатель на динамически распределенные данные - вы неправильно сериализуете его. Предложите использовать одну из функций вывода mpz на 'key' –

+0

Вы имеете в виду такие функции, как mpz_out_str? – despinac

ответ

0

Вы должны преобразовать mpz_t с до стандартных типов C, используя один из conversion functions перед отправкой их, а затем преобразовать их обратно с помощью assignment function когда вы получаете их.

Вы должны для максимальной переносимости также преобразовать типы C от байта хоста к сетевому порядку байта перед их отправкой, а затем преобразовать их из сетевого байтового порядка в хост-порядок байта, когда вы их получите. Для этого вы используете conversion functions in netinet/in.h.

+0

Я пробовал то, что вы предлагали, однако функция назначения, которую я использовал на сервере, не восстанавливает первоначальное значение, которое произвел клиент. Я думаю, это может произойти, потому что исходное значение mpz_t слишком велико, поэтому сохраняется только его часть. На странице функций преобразования указано, что это может произойти. Есть ли способ избежать этого? – despinac

+0

Вы можете преобразовать его в строку с 'mpz_get_str()' и отправить ее так, а затем преобразовать ее с помощью 'mpz_set_str()'. –

Смежные вопросы