I'm trying to make a server and a client, written in C, exchange mpz_t values. The programs use the GMP library, and some functions of an elliptic curves library. The problem is that the value the client generates is different than the one the server receives. Do you have any idea why is that happening?
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;}
You need to convert the mpz_t
s to standard C types using one of the conversion functions before sending them, and then convert them back using an assignment function when you receive them.
You should for maximum portability also convert the C types from host byte order to network byte order before sending them, and then convert them back from network byte order to host byte order when you receive them. You use the conversion functions in netinet/in.h to do this.