使用c语言实现DH秘钥分配算法
DH算法原理
密钥分配
-
- 选择一个大素数p, 选择一个整数g(g < p);
- 通信方A选择一个随机数a,并发送 mod p 给 通信方B;
- 通信方B选择一个随机数b,并发送 mod p 给 通信方A;
- 通信方A计算k1 = ( mod p)a mod p;
- 通信方B计算k2 = ( mod p)b mod p;
- 由此,k1 = k2。
DH.h
cpp
#pragma once
#include <tommath.h>
#include <time.h>
#include <iostream>
#include <Windows.h>
using namespace std;
#define SUBKEY_LENGTH 78 // >512 bit
void Create_number(mp_int *number, int mode);
int Miller_rabin(mp_int *number);
void Create_prime_number(mp_int *number);
void initial();
void mp_print(mp_int *number);
void Write_num_2_File(char *file_name, mp_int *num);
DH.cpp
cpp
#include "DH.h"
mp_int two;
mp_int five;
mp_int zero;
mp_int one;
void Create_number(mp_int *number, int mode)
{
int i;
srand((unsigned)time(NULL));
char temp_number[SUBKEY_LENGTH + 1];
temp_number[0] = rand() % 9 + 1 + 48;
if (0 == mode)
{
int temp;
for (i = 1; i <= SUBKEY_LENGTH - 2; i++)
temp_number[i] = rand() % 10 + 48;
temp = rand() % 10;
if (0 == temp % 2)
temp++;
if (5 == temp)
temp = 7;
temp_number[SUBKEY_LENGTH - 1] = temp + 48;
temp_number[SUBKEY_LENGTH] = '\0';
}
else if (1 == mode)
{
int digit = rand() % (SUBKEY_LENGTH - 2) + 2;
for (i = 1; i <= digit - 1; i++)
temp_number[i] = rand() % 10 + 48;
temp_number[digit] = '\0';
}
mp_read_radix(number, temp_number, 10);
}
int Miller_rabin(mp_int *number)
{
int result;
mp_int base;
mp_init_size(&base, SUBKEY_LENGTH);
Create_number(&base, 1);
mp_prime_miller_rabin(number, &base, &result);
mp_clear(&base);
return result;
}
void Create_prime_number(mp_int *number)
{
mp_int r;
mp_init(&r);
int time = 100;
int result;
int i;
Create_number(number, 0);
while (1)
{
mp_prime_is_divisible(number, &result);
if (0 != result)
{
do
{
mp_add(number, &two, number);
mp_mod(number, &five, &r);
} while (MP_EQ == mp_cmp_mag(&zero, &r));
continue;
}
for (i = 0; i < time; i++)
{
if (!Miller_rabin(number))
break;
}
if (i == time)
return;
else
{
do
{
mp_add(number, &two, number);
mp_mod(number, &five, &r);
} while (MP_EQ == mp_cmp_mag(&zero, &r));
}
}
}
void initial()
{
mp_init_set_int(&two, 2);
mp_init_set_int(&five, 5);
mp_init_set_int(&zero, 0);
mp_init_set_int(&one, 1);
}
void mp_print(mp_int *number)
{
char str[SUBKEY_LENGTH * 2 + 1];
mp_toradix(number, str, 10);
cout << str << endl;
}
void Write_num_2_File(char *file_name, mp_int *num)
{
remove(file_name);
FILE *fp = fopen(file_name, "w+");
if (NULL == fp)
{
cout << "open file error!" << endl;
return;
}
char str[SUBKEY_LENGTH * 2];
mp_toradix(num, str, 10);
fprintf(fp, "%s", str);
fclose(fp);
}
main.h
cpp
#pragma once
#include "DH.h"
main.cpp
cpp
#include "main.h"
int main()
{
initial();
mp_int p, g, a, b, ka, kb;
mp_init_size(&p, SUBKEY_LENGTH);
mp_init_size(&g, SUBKEY_LENGTH);
mp_init_size(&a, SUBKEY_LENGTH);
mp_init_size(&b, SUBKEY_LENGTH);
mp_init_size(&ka, SUBKEY_LENGTH);
mp_init_size(&kb, SUBKEY_LENGTH);
Create_prime_number(&p);
Create_number(&g, 1);
Sleep(1000);
Create_number(&a, 1);
Sleep(1000);
Create_number(&b, 1);
mp_exptmod(&g, &a, &p, &ka);
mp_exptmod(&g, &b, &p, &kb);
cout << "p: ";
mp_print(&p);
cout << "g: ";
mp_print(&g);
cout << "a: ";
mp_print(&a);
cout << "b: ";
mp_print(&b);
cout << "ka: ";
mp_print(&ka);
cout << "kb: ";
mp_print(&kb);
Write_num_2_File("d:\\DH_p.txt", &p);
Write_num_2_File("d:\\DH_g.txt", &g);
Write_num_2_File("d:\\DH_a.txt", &a);
Write_num_2_File("d:\\DH_b.txt", &b);
Write_num_2_File("d:\\DH_ka.txt", &ka);
Write_num_2_File("d:\\DH_kb.txt", &kb);
mp_clear_multi(&p, &g, &a, &b, &ka, &kb, NULL);
return 0;
}