2017-02-02 10 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出力関数の1つを使うことを提案してください。 –

+0

mpz_out_strのような関数ですか? – despinac

答えて

0

あなたはそれらを送信する前conversion functionsのいずれかを使用して、標準のC型にmpz_t秒を変換した後、あなたがそれらを受け取るときassignment functionを使用して、それらをバックに変換する必要があります。

移植性を最大限に高めるには、Cタイプをホストバイトオーダーからネットワークバイトオーダーに変換してから、ネットワークバイトオーダーからホストバイトオーダーに変換する必要があります。これを行うにはconversion functions in netinet/in.hを使用します。

+0

私があなたが提案したことを試しましたが、私がサーバで使った代入関数は、クライアントが生成した元の値を復元しません。私は元のmpz_t値が大きすぎるので、これが起こるかもしれないと思うので、その一部だけが保存されます。このことが起こる可能性があることは、変換機能ページに記載されています。私がそれを避ける方法はありますか? – despinac

+0

'mpz_get_str()'でそれを文字列に変換して送信し、 'mpz_set_str()'でそれを戻すことができます。 –

関連する問題