C 服务器和客户端错误地交换 mpz_t 值

C server and client exchange mpz_t values incorrectly

我试图让用 C 编写的服务器和客户端交换 mpz_t 值。这些程序使用 GMP 库和椭圆曲线库的一些函数。问题在于客户端生成的值与服务器接收到的值不同。你知道为什么会这样吗?

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;}

您需要在收到 mpz_t 时使用 conversion functions before sending them, and then convert them back using an assignment function 之一将其转换为标准 C 类型。

为了获得最大的可移植性,您还应该在发送 C 类型之前将它们从主机字节顺序转换为网络字节顺序,然后在接收它们时将它们从网络字节顺序转换回主机字节顺序。您使用 conversion functions in netinet/in.h 来执行此操作。