понедельник, 9 января 2012 г.

Алгоритм шифрования Эль-Гамаля (Elgamal) на C++

Собственно рабочая версия

int power(int a, int b, int n){// a^b mod n
    int tmp=a;
    int sum=tmp;
    for(int i=1;i<b;i++){
        for(int j=1;j<a;j++){
            sum+=tmp;
            if(sum>=n){
                sum-=n;
            }
        }
        tmp=sum;
    }
    return tmp;
}
 
int mul(int a, int b, int n){// a*b mod n
    int sum=0;
     
    for(int i=0;i<b;i++){
        sum+=a;
         
        if(sum>=n){
            sum-=n;
        }
    }
 
    return sum;
}

/*****************************************************
    p - простое число
    0 < g < p-1
    0 < x < p-1
    m - шифруемое сообщение m < p
*****************************************************/
void crypt(int p,int g,int x, string inFileName,string outFileName){
    ifstream inf(inFileName.c_str());
    ofstream outf(outFileName.c_str());
 
    int y=power(g,x,p);
     
    wcout<<"Открытый ключ (p,g,y)="<<"("<<p<<","<<g<<","<<y<<")"<<endl;
    wcout<<"Закрытый ключ x="<<x<<endl;
     
    wcout<<"\nШифруемый текст:"<<endl;
 
    while(inf.good()){
        int m=inf.get();
        if(m>0){
            wcout<<(char)m;
             
            int k=rand()%(p-2)+1; // 1 < k < (p-1)
            int a= power(g,k,p);
            int b= mul(power(y,k,p),m,p);
            outf<<a<<" "<<b<<" ";
        }
    }
 
    wcout<<endl;
 
    inf.close();
    outf.close();
}
 
void decrypt(int p,int x,string inFileName,string outFileName){
    ifstream inf(inFileName.c_str());
    ofstream outf(outFileName.c_str());
     
    wcout<<"\nДешифрованый текст:"<<endl;
 
    while(inf.good()){
        int a=0;
        int b=0;
        inf>>a;
        inf>>b;
         
        if(a!=0&&b!=0){
            //wcout<<a<<" "<<b<<endl;
         
            int deM=mul(b,power(a,p-1-x,p),p);// m=b*(a^x)^(-1)mod p =b*a^(p-1-x)mod p - трудно было  найти нормальную формулу, в ней вся загвоздка
            char m=static_cast<char>(deM);
            outf<<m;
            wcout<<m;
        }
    }
     
    wcout<<endl;
 
    inf.close();
    outf.close();
}

int main(){
    srand(time(NULL));
   
    crypt(593,123,8, "in.txt","out_crypt.txt");
    decrypt(593,8,"out_crypt.txt","out_decrypt.txt");

    
    return 0;
}

Описание алгоритма на википедии без волшебной формулы

20 комментариев:

  1. Вся загвоздка в отсутствии генератора g

    ОтветитьУдалить
    Ответы
    1. за генерацию этих чисел должен отвечать вызывающий код

      Удалить
  2. а можешь на почту архив с прогой скинуть, пожалуйста
    baglin-ml@mail.ru

    ОтветитьУдалить
    Ответы
    1. код рабочий, нужно только подключить заголовочные файлы и пространство имен std.

      Удалить
    2. сделал все, подключил все библиотеки и пространство имен, а у меня ругается на
      ifstream inf(inFileName.c_str());
      ofstream outf(outFileName.c_str());

      Удалить
    3. http://www.cplusplus.com/reference/fstream/ifstream/ifstream/

      // ifstream constructor.
      #include // std::cout
      #include // std::ifstream

      int main () {

      std::ifstream ifs ("test.txt", std::ifstream::in);

      char c = ifs.get();

      while (ifs.good()) {
      std::cout << c;
      c = ifs.get();
      }

      ifs.close();

      return 0;
      }

      Удалить
  3. Как выполнить данный код в Visual C++. Заголовки подключил, проект запустился, но в упор не читает файлы, непонятно в чем проблема.

    ОтветитьУдалить
    Ответы
    1. Нужны следующие заголовочные файлы стандартной библиотеки std
      iostream
      cstdlib
      ctime

      а также объявить пространство имен
      use namespace std;

      Файл in.txt нужно положить в ту же папку где и исполняемый файл, там же должны появиться файлы out_crypt.txt out_decrypt.txt

      Удалить
    2. также еще нужна библиотека string

      а входные файлы должны содержать только символы ASCII

      Удалить
    3. Здравствуйте, все подключил, ничего не работает, в конце выбивает пустой эран, в файлах ничего нет?

      Удалить
  4. А можно кинуть готовый проект пожалуйста, что-то у меня вылетает много ошибок

    ОтветитьУдалить
  5. не выводит шифрованный и дешифрованный текст. Файлы out_crypt.txt out_decrypt.txt не появляются

    ОтветитьУдалить
  6. Файлы out_crypt.txt out_decrypt.txt появились,но они пустые. Что делать?

    ОтветитьУдалить
  7. чтобы программа работала также надо подключить #include

    ОтветитьУдалить
  8. #include
    #include
    #include
    #include

    using namespace std;

    int power(int a, int b, int n) // a^b mod n
    {
    int tmp = a;
    int sum = tmp;
    for (int i = 1; i < b; i++)
    {
    for (int j = 1; j < a; j++)
    {
    sum += tmp;
    if (sum >= n)
    {
    sum -= n;
    }
    }
    tmp = sum;
    }
    return tmp;
    }

    int mul(int a, int b, int n) // a*b mod n
    {
    int sum = 0;

    for (int i = 0; i < b; i++)
    {
    sum += a;

    if (sum >= n)
    {
    sum -= n;
    }
    }

    return sum;
    }

    /*****************************************************
    p - простое число
    0 < g < p-1
    0 < x < p-1
    m - шифруемое сообщение m < p
    *****************************************************/

    void crypt(int p, int g, int x, string inFileName, string outFileName)
    {
    ifstream inf(inFileName.c_str());
    ofstream outf(outFileName.c_str());

    int y = power(g, x, p);

    cout << "Открытый ключ (p,g,y)=" << "(" << p << "," << g << "," << y << ")" << endl;
    cout << "Закрытый ключ x=" << x << endl;

    cout << "\nШифруемый текст:" << endl;

    while (inf.good())
    {
    int m = inf.get();
    if (m > 0) {
    cout << (char)m;

    int k = rand() % (p - 2) + 1; // 1 < k < (p-1)
    int a = power(g, k, p);
    int b = mul(power(y, k, p), m, p);
    outf << a << " " << b << " ";
    }
    }

    cout << endl;

    inf.close();
    outf.close();
    }

    void decrypt(int p, int x, string inFileName, string outFileName)
    {
    ifstream inf(inFileName.c_str());
    ofstream outf(outFileName.c_str());

    cout << "\nДешифрованый текст:" << endl;

    while (inf.good())
    {
    int a = 0;
    int b = 0;
    inf >> a;
    inf >> b;

    if (a != 0 && b != 0)
    {
    int deM = mul(b, power(a, p - 1 - x, p), p);// m=b*(a^x)^(-1)mod p =b*a^(p-1-x)mod p - трудно было найти нормальную формулу, в ней вся загвоздка
    char m = static_cast(deM);
    outf << m;
    cout << m;
    }
    }

    cout << endl;

    inf.close();
    outf.close();
    }

    int main()
    {
    setlocale(LC_ALL, "Russian");
    srand(time(NULL));

    crypt(593, 123, 8, "in.txt", "out_crypt.txt");
    decrypt(593, 8, "out_crypt.txt", "out_decrypt.txt");

    return 0;
    }

    ОтветитьУдалить
  9. TOTO MINT TOTO MINT TOTO MINT TOTO
    TOTO MINT TOTO MINT TOTO MINT TOTO MINT TOTO MINT TOTO TOTO revlon hair dryer brush titanium MINT burnt titanium TOTO smith titanium TOTO MINT TOTO titanium max MINT TOTO titanium wedding ring TOTO TOTO TOTO MINT TOTO TOTO TOTO TOTO MINT TOTO TOTO MINT TOTO TOTO TOTO

    ОтветитьУдалить