Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > [C++] Шифрование методом Эль-Гамаля


Автор: alver 5.4.2007, 22:05
Попросили меня зделать такую программку, шифрование методом Эль-Гамаля. Я тока где то два часа врубал этот метод, тока потом начал его описывать как код. Кое что получается, но почему то иногда выдаётся неправильный результат. Я подозреваю дело в типах, просто не хватает знаков, т.к. числа очень большие, помогите кто что знает по этому поводу. Вот то, что я успел написать: 
Код

#include "iostream"
#include "stdio.h"
#include "conio.h"
using namespace std;
unsigned long int N;
void extended_euclid(unsigned long int a, unsigned long int b, unsigned long int *x, unsigned long int *y, unsigned long int *d)
/* calculates a * *x + b * *y = gcd(a, b) = *d */
{
  unsigned long int q, r, x1, x2, y1, y2;
  if (b == 0) {
    *d = a, *x = 1, *y = 0;
    return;
  }
  x2 = 1, x1 = 0, y2 = 0, y1 = 1;
  while (b > 0) {
    q = a / b, r = a - q * b;
    *x = x2 - q * x1, *y = y2 - q * y1;
    a = b, b = r;
    x2 = x1, x1 = *x, y2 = y1, y1 = *y;
  }
  *d = a, *x = x2, *y = y2;
}

unsigned long int invmod(unsigned long int a, unsigned long int n)
/* computes the inverse of a modulo n */
{
  unsigned long int d, x, y;
  extended_euclid(a, n, &x, &y, &d);
  if (d == 1)
    if (x>0)
      return x;
    else
      return x+n;
  return 0;
}

unsigned long int powmod(unsigned long int g, unsigned long int x, unsigned long int p)
{
  unsigned long int b=1;
  unsigned long int i;
  for(i=0;i<x;i++)
  b=g*g;
  b=b%p;
  return b;
}

unsigned long int powmod(unsigned long int y, unsigned long int k, unsigned long int p, unsigned long int m)
{
    unsigned long int b=0;
    unsigned long int i;
    for(i=0;i<k;i++)
    b=y*y;
    b=b*m;
    b=b%p;
    return b;
}
unsigned long int Get() 
{
    unsigned long int val;
    while (1) {
        cin >> val;
        if (cin.peek () == '\n') break;
        else {
            cout<<"\t\t\tReenter symvol";
            cin.clear();
            while (cin.get() != '\n'){};
            }    
        }
    return val;
}

int Getint() 
{
    int val;
    while (1) {
        cin >> val;
        if (cin.peek () == '\n') break;
        else {
            cout<<"\t\t\tReenter symvol";
            cin.clear();
            while (cin.get() != '\n'){};
            }    
        }
    return val;
}
void Rus(char *y)
{
    int i;
    char *x = new char[strlen(y)];
    for (i = 0; ; i++) 
    {
        if (y[i] == 0)
        {
            x[i] = 0;                // конец символа
            break;
        }
        x[i] = y[i];
    }
    for (i = 0; ; i++) 
    {
        if (x[i] == 0) 
            break;
        if (x[i]>-65 && x[i]<-16)
        x[i] += -64;            // смещение таблиц win от dos
        if (x[i]>-17 && x[i]<0)
        x[i] += -16;            // смещение таблиц win от dos
        cout << x[i];
    }
}
unsigned long int vvod(int p)
{
    unsigned long int T=0;
    switch(p)
    {
    case 1:do{Rus("Введите любое большое(пятизначное) число P"); T=Get();N=T;}while(T<22222);break;
    case 2:do{Rus("Введите любое большое(пятизначное) число G, но меньше P");T=Get();}while(T>N&&T>22222-1);break;
    case 3:do{Rus("Введите секретный ключ - случайное целое число X <P");T=Get();}while(T>N);break;
    case 4:do{Rus("Выберите целое число K, так чтобы 1< K< P-1");T=Get();}while(T<1&&T>N-1);break;
    case 5:do{Rus("Введите число которое хотите зашифровать, должно быть меньше 55555, т.к. ограничение на тип");T=Get();}while(T>55555);break; 
    }
    return T;
}

int main() 
{
unsigned long int P,G,X,Y,K,M,A,B,ok;
int vibor;
do
{
    system("cls");
    Rus("1.Ввод данных для шифрования\n");
    Rus("2.Просмотр зашифрованных данных\n");
    Rus("3.Проверка правильности шифрования\n");
    Rus("4.Выход\n");
    vibor=Getint();
    switch(vibor)
    {
    case 1:system("cls");P=vvod(1);G=vvod(2);X=vvod(3);Y=powmod(G,X,P);K=vvod(4);M=vvod(5);break;
    case 2:system("cls");A=powmod(G,K,P);B=powmod(Y,K,P,M);cout<<"a="<<A<<endl;cout<<"b="<<B<<endl;getch();break;
    case 3:system("cls");ok=(B*invmod(powmod(A,X,P),P))%P;cout<<ok;getch();break;
    case 4:break;
    }
}
while(vibor!=4);
cin.get();
}

Вот краткое описание метода:
Получатель сообщения выбирает два больших числа P и G, причем P > G.
Получатель выбирает секретный ключ - случайное целое число X < P.
Вычисляется открытый ключ Y= G x mod P.
Получатель выбирает целое число K, 1< K< P-1.
Шифрование сообщения (M): a= GK mod P, b=Y K M mod P, где пара чисел (a,b) является шифротекстом.
Помогите спецы, задача по мне не очень то простая.!

Автор: permea 6.4.2007, 05:55
если числа большие, то почему не 64 битные целые?(непереносимо, но gcc и VC++ поддрживают 64-битные целые, хотя названия, емнип, разные
+ если целые _очень_ большие, есть спецбиблиотеки для работы с ними.

Автор: Alexandr87 6.4.2007, 06:55
разрядность больших чисел, используемых в криптографии с открытым ключом очень велика, используются числа с разрядность 512-5120 бит. Соответсвенно, использовать встроенные типы здесь не получится. Есть специальные библиотеки, которые реализуют способ представления таких данных и логические операции с ними, есть и OpenSource библиотеки - вы найдете их без труда.

Автор: korbian 6.4.2007, 07:57
Операции над числами такой разрядности "отжирают" много ресурсов, поэтому советую сразу думать над оптимизацией. Потому ищи информацию о математике над длиными (так их называют) числами. 
Очень советую книгу: А.В.Домашев, М.М. Грунтович, В.О.Попов, Д.И.Правиков,А.Ю.Щербаков "Программирование алгоритмов защиты информации"

Автор: alver 6.4.2007, 11:34
Чего то я не нашёл такие библиотеки, может конечно плохо искал, но никто не направит на нужный сайт??
Так же кинга то может хорошая, но в электронном варианте её нигде нет, а купить это долго, мне до понедельника надо.

Автор: Alexandr87 6.4.2007, 20:57
http://gmplib.org/

Из книг "Прикладная криптография" - но разбираться и реализовывать - дело долгое.

Автор: volatile 30.11.2011, 00:10
Цитата(Elisey44 @  29.11.2011,  14:48 Найти цитируемый пост)
не голову ломать над написанием Эль Гамаля, а купить 

Наглая реклама. 
И много вы на продаже Эль-Гамаля (фиг знает как написанного), думаете заработать? smile
да еще и 
Цитата

Технологии/языки:
C# Windows Forms

 smile 

http://www.cryptopp.com/docs/ref/elgamal_8h_source.html

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)