2017-02-02 9 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

은 당신이 그들을 보내기 전에 conversion functions 중 하나를 사용하여 표준 C 유형에 mpz_t의 변환하고 당신이 그들을받을 때 assignment function를 사용하여 다시 변환해야합니다.

최대 이식성을 위해 호스트 유형을 호스트 바이트 순서에서 네트워크 바이트 순서로 변환 한 다음 네트워크 바이트 순서에서 호스트 바이트 순서로 다시 변환해야합니다. 이 작업을 수행하려면 conversion functions in netinet/in.h을 사용하십시오.

+0

나는 당신이 제안한 것을 시도했지만 서버에서 사용한 할당 기능은 클라이언트가 생성 한 원래 값을 복원하지 못합니다. 원래 mpz_t 값이 너무 커서 일부만 유지되므로이 문제가 발생할 수 있다고 생각합니다. 이 문제가 발생할 수있는 변환 기능 페이지에 언급되어 있습니다. 내가 그것을 피할 수있는 방법이 있을까요? – despinac

+0

'mpz_get_str()'을 사용하여 그것을 문자열로 변환하고 그것을 보내고'mpz_set_str()'으로 다시 변환 할 수 있습니다. –