dhcrypto/MITM/Diffie_hellman.c
2022-06-13 03:53:40 +00:00

150 lines
3.5 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <gmp.h>
#include <string.h>
typedef struct{
mpz_t prime;
mpz_t base;
mpz_t private_key;
mpz_t public_key;
mpz_t key_for_server; //g^(AB)
mpz_t key_for_client; //g^(AB)
FILE *urand;
}Mim_key;
void generate_random(size_t sz, unsigned char* random_bytes,Mim_key* dhk)
{
unsigned int init_random = 0;
size_t i = 0;
if(0 == sz || NULL == random_bytes)
{
fprintf(stderr, "Wrong params for generate_random\n");
exit(1);
}
init_random ^= ((unsigned int)fgetc(dhk->urand) << 8)|fgetc(dhk->urand);
srand(init_random);
for(i = 0; i < sz; i++)
{
random_bytes[i] = rand();
}
}
void put_hex(unsigned char* value, unsigned int len){
//printf("%d:",len);
printf("exchange key");
for(int i=0;i<len;i++)
printf("%02x ",value[i]);
puts("");
}
unsigned char* str2hex(char *hexStr){
int len=strlen(hexStr)/2;
unsigned char * hexvalue=(unsigned char*)malloc(len*sizeof(char));
memset(hexvalue,0,len);
for(int i=0;i<len;i++){
if(hexStr[i*2]<='9'){
hexvalue[i]=(hexStr[i*2]-'0')*16;
}else
hexvalue[i]=(hexStr[i*2]-87)*16; //aµÄÂëÊÇ97
if(hexStr[i*2+1]<='9'){
hexvalue[i]+=(hexStr[i*2+1]-'0');
}else
hexvalue[i]+=(hexStr[i*2+1]-87);
}
return hexvalue;
}
void generate_key(size_t sz, Mim_key* dhk)
{
unsigned char* random_bytes = NULL;
if(0 == sz || NULL == dhk->private_key)
{
fprintf(stderr, "Wrong params for generate_key\n");
exit(1);
}
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the private key\n");
exit(1);
}
generate_random(sz, random_bytes, dhk);
mpz_import(dhk->private_key, 1, -1, sz, -1, 0, (const void*)random_bytes);
free(random_bytes);
}
void init_prime(size_t sz,Mim_key* dhk)
{
mpz_t tmp;
mpz_t x;
unsigned char* random_bytes = NULL;
if(0 == sz)
{
fprintf(stderr, "Wrong params for init_prime\n");
exit(1);
}
mpz_init(tmp);
mpz_init(x);
random_bytes = (unsigned char *)malloc(sz*sizeof(unsigned char));
if(NULL == random_bytes)
{
fprintf(stderr, "Failed to allocate random bytes array for the prime number\n");
exit(1);
}
while (1)
{
generate_random(sz, random_bytes,dhk);
random_bytes[sz-1] |= (unsigned char)0x40;
random_bytes[0] |= (unsigned char)1;
mpz_import(tmp, 1, -1, sz, -1, 0, (const void*)random_bytes);
while (0 == mpz_probab_prime_p(tmp, 10))
{
mpz_add_ui(tmp, tmp, 2);
}
mpz_mul_ui(dhk->prime, tmp, 2);
mpz_add_ui(dhk->prime, dhk->prime, 1);
if (0 != mpz_probab_prime_p(dhk->prime, 10))
{
break;
}
}
free(random_bytes);
mpz_set_ui(dhk->base, (unsigned long)2);
mpz_clear(tmp);
mpz_clear(x);
}
void init_numbers(Mim_key* dhk)
{
mpz_init(dhk->key_for_client);
mpz_init(dhk->key_for_server);
mpz_init(dhk->prime);
mpz_init(dhk->base);
mpz_init(dhk->private_key);
mpz_init(dhk->public_key);
}
void clear_numbers(Mim_key* dhk)
{
mpz_clear(dhk->key_for_client);
mpz_clear(dhk->key_for_server);
mpz_clear(dhk->prime);
mpz_clear(dhk->base);
mpz_clear(dhk->private_key);
mpz_clear(dhk->public_key);
}