Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Клуб программистов > Свободное общение
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.11.2011, 12:19   #1
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение Описание алгоритма шифрования Эль-гамаль

Возникла необходимость реализовать алгоритм шифрования Эль-гамаль. Разумеется начал искать теоретические сведения по этому алгоритму, как он работает и т.д. Заглянул на любимую многими WikiPedi'ю, посмотрел там алгоритм, пример шифрования\дешифрования и если говорить откровенно, то ни черта его не понял. Цитирую:
Цитата:
Пример

Шифрование:
Допустим что нужно зашифровать сообщение M=5.
Произведем генерацию ключей :
пусть p=11, g=2. Выберем x=8 - случайное целое число x такое,что 1 < x < p.
Вычислим y= (g^x)mod p=(2^8)mod 11=3.
Итак , открытым является тройка (p,g,y)=(11,2,3),а закрытым ключом является число x=8.
Выбираем случайное целое число k такое, что 1 < k < (p − 1). Пусть k=9.
Вычисляем число a=(g^k)mod p=(2^9)mod 11=512 mod 11=6.
Вычисляем число b=(y^k)*M*mod p=(3^9)*5*mod 11=19683*5*mod 11=9.
Полученная пара (a,b)=(6,9) является шифротекстом.
Расшифрование:
Необходимо получить сообщение M=5 по известному шифротексту (a,b)=(6,9) и закрытому ключу x=8.
Вычисляем M по формуле : M=b((a^x)^-1)mod p=9((6^8)^-1)\mod 11=5
Получили исходное сообщение M=5.
Выделенная жирным шрифтом строка вызвала у меня глубокое непонимание: 9*((6^8)^-1)=9/(6^8)=9/1679616=0(для целочисленного типа); теперь берем остаток от деления 0 на 11 и получаем 0(здесь никакого велосипеда при расчетах нет), но никак не 5!
Ладно, начал искать другие источники по алгоритму Эль-гамаль: последняя чудесная формула как только не перевиралась в разных источниках, считаешь вручную то, что написано в книге и получается совсем не тот результат(как говориться на форумах: "аффтар сжет")! На одном форуме, когда человек просил пояснить ему данный алгоритм, написали: "mod - это не остаток от деления, это результат решения уравнения...".
Перерыл еще с десяток источников, без всякой надежды открыл книгу Рябко, Фионов - Криптографические методы защиты информации, посмотрел что автору пишут там, как объясняют пример и вручную пересчитал все то, что они написали и о чудо - результаты моих вычислений для предоставленных данных совпадают с результатами в книге! Начал пробовать по предоставленным формулам зашифровать другие данные с другими коэффициентами и все отлично шифруется-дешифруется - моей радости не было предела - единственная найденная мной книга с человеческим описанием алгоритма Эль-гамаль!
Чтобы никто больше не мучился с реализацией и пониманием алгоритма шифрования Эль-гамаль, цитирую пример из книги Рябко, Фионов:
Цитата:
Для всей группы абонентов выбираются некоторое большое простое число p и число g, такие, что различные степени g суть различные числа по модулю p(вот здесь, видимо, в книге некоторые опечатки. В принципе, определение чисел p и q верно дано и на Википедии<см.вышеприведенный линк>) Числа p и q передаются абонентам в открытом виде(они могут использоваться всеми абонентами сети).
Затем каждый абонент группы выбирает свое секретное число ci, 1<ci<p-1, и вычисляет соответствующее ему открытое число di,
di=(g^ci)mod p
Покажем теперь, как A передает сообщение m абоненту B. Будем предполагать, как и при описании шифра Шамира, что сообщение представлено в виде числа m<p(вот это условие крайне важно).
Шаг 1. A формирует случайное число k, 1<=k<=p-2, вычисляет числа
r=(g^k)mod p
e=m*(dB^k) mod p
и передает пару чисел (r,e) абоненту B.
Шаг 2. B, получив (r,e), вычисляет
m'=e*(r^(p-1-cB)) mod p
То, что написано курсивом в данной цитате является моими небольшими комментариями. Числа dB, cB являются числами di и ci, т.е. i=B.
Если не забуду, то когда реализую это все с помощью класса C#, постараюсь выложить свой код для простоты понимания.
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Старый 28.11.2011, 13:38   #2
alexBlack
Участник клуба
 
Регистрация: 12.10.2007
Сообщений: 1,204
По умолчанию

Цитата:
Сообщение от Mixim Посмотреть сообщение
...
Выделенная жирным шрифтом строка вызвала у меня глубокое непонимание: 9*((6^8)^-1)=9/(6^8)=9/1679616=0(для целочисленного типа);
В модулярной арифметике делить нужно тоже по модулю. Для этого ищется обратное число (см. например, вики "Сравнение по модулю/Сравнения первой степени")
(1679616^-1) mod 11 = 3 => 3*9 mod 11 = 5
Правда, такая операция выполнима не всегда, но, наверное, конкретно в этом алгоритме значения подобраны так, что деление можно выполнить.

поскольку к C# вопрос тема отношения не имеет, перенесу в свободное общение.

Последний раз редактировалось alexBlack; 28.11.2011 в 16:04.
alexBlack вне форума Ответить с цитированием
Старый 28.11.2011, 15:16   #3
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение

В процессе сегодняшней работы получилась следующая часть кода:
Код:
        public class ElGamal
        {
            #region КОНСТАНТЫ, необходимые в классе ElGamal
                protected const String PIsNotPrime = "Переданное значение числа P является недопустимым, возможно, оно не является простым";
                protected const String GValueIsNotFound = "Невозможно вычислить параметр G, удовлетворяющий условиям 1<G<(P-1) и (G^Q)modP!=1";
                protected const String CIsNotCorrect = "Переданное значение числа C является недопустимым. Его значение должно удовлетворять неравенству 1<C<(P-1)";
            #endregion

            #region ПЕРЕМЕННЫЕ, необходимые в классе ElGamal
                protected System.Numerics.BigInteger p = System.Numerics.BigInteger.Zero;
                protected System.Numerics.BigInteger g = System.Numerics.BigInteger.Zero;
                protected System.Numerics.BigInteger c = System.Numerics.BigInteger.Zero;
            #endregion

            #region Конструктор класса ElGamal[с параметрами]
                public ElGamal(System.Numerics.BigInteger P, System.Numerics.BigInteger C)
                {
                    this.P = P;
                    this.C = C;
                }
            #endregion

            #region Организация доступа к полю p с помощью свойства
                public System.Numerics.BigInteger P
                {
                    get
                    {
                        return this.p;
                    }
                    set
                    {
                        if (IsPrimeNumber(value))
                        {
                            this.p = value;
                            this.g = this.Calculate_g(this.P);  //попытаться вычислить коэффициент g
                        }
                        else
                        {
                            throw new ArgumentException(ElGamal.PIsNotPrime);
                        }

                    }
                }
            #endregion

            #region Организация доступа к полю g с помощью свойства[доступ только для чтения]
                public System.Numerics.BigInteger G
                {
                    get
                    {
                        return this.p;
                    }
                }
            #endregion

            #region Организация доступа к полю c благодаря свойству
                public System.Numerics.BigInteger C
                {
                    get
                    {
                        return this.c;
                    }
                    set
                    {
                        if ((System.Numerics.BigInteger.One < value) && (value > this.P - 1))
                        {
                            this.c = value;
                        }
                        else
                        {
                            throw new ArgumentException(CIsNotCorrect);
                        }
                    }
                }
            #endregion

            #region Метод для проверки числа на простоту
                protected Boolean IsPrimeNumber(System.Numerics.BigInteger Number)
                {
                    UInt16 quantityOfDivisors = 0;
                    Boolean returnedValue = true;
                        
                    for (System.Numerics.BigInteger i = 1; i <= Number; i++)
                    {
                        if (Number % i == System.Numerics.BigInteger.Zero)
                        {
                            quantityOfDivisors++;
                            if (quantityOfDivisors > 2)
                            {
                                returnedValue = false;
                                break;
                            }
                        }
                    }

                    return returnedValue;
                }
            #endregion
Продолжение кода в следующем посте
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Старый 28.11.2011, 15:20   #4
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение

продолжение кода
Код:
            /*#region Метод для проверки чисел на взаимную простоту
                protected Boolean IsValueRelativelyPrime(System.Numerics.BigInteger Value1, System.Numerics.BigInteger Value2)
                {
                    System.Numerics.BigInteger minimalValue = System.Numerics.BigInteger.Zero;
                    UInt16 quantityOfDivisors = 0;
                    Boolean returnedValue = true;

                    if (Value1 < Value2)
                    {
                        minimalValue = Value1;
                    }
                    else
                    {
                        minimalValue = Value2;
                    }

                    for (System.Numerics.BigInteger i = 1; i <= minimalValue; i++)
                    {
                        if ((Value1 % i == System.Numerics.BigInteger.Zero) && (Value2 % i == System.Numerics.BigInteger.Zero))
                        {
                            quantityOfDivisors++;
                            if (quantityOfDivisors > 1)
                            {
                                returnedValue = false;
                                break;
                            }
                        }
                    }

                    return returnedValue;
                }
            #endregion

            /*#region Метод для генерации числа, взаимно простого с Value(т.е. числа k)
                protected System.Numerics.BigInteger GenerateRelativelyPrime(System.Numerics.BigInteger Value)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;

                    return returnedValue;
                }
            #endregion*/

            #region Метод для подсчета коэффициента g
                protected System.Numerics.BigInteger Calculate_g(System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;
                            //p=2q-1
                            //тогда в качестве g можно взять любое число для которого справедливы неравенства 1<g<(p-1) и (g^q)mod p!=1
                    System.Numerics.BigInteger q = (P - 1) / 2;
                    Boolean isGFound = false;   //равняется true когда найдено число g

                    for (System.Numerics.BigInteger g = 2; g < P; g++)
                    {
                        if (System.Numerics.BigInteger.ModPow(g,q,p)!=System.Numerics.BigInteger.One)
                        {
                            isGFound = true;
                            returnedValue = g;
                            break;
                        }
                    }

                    //если не удалось найти параметр g
                    if (!isGFound)
                    {
                        throw new ArgumentException(ElGamal.GValueIsNotFound);
                    }

                    return returnedValue;
                }
            #endregion

            #region Метод для вычисления открытого числа d
                protected System.Numerics.BigInteger Calculate_D(System.Numerics.BigInteger G, System.Numerics.BigInteger C, System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue=System.Numerics.BigInteger.Zero;

                    returnedValue=System.Numerics.BigInteger.ModPow(G, C, P);

                    return returnedValue;
                }
            #endregion

            #region Метод для вычисления случайного числа 1<=k<=(p-2)
                protected System.Numerics.BigInteger Calculate_K(System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.One;
                    System.Numerics.BigInteger forGenerateK = P - 2;
                    Random random = new Random();

                    do
                    {
                        if (forGenerateK > Int32.MaxValue)
                        {
                            returnedValue = returnedValue * random.Next(Int32.MaxValue);
                        }
                        else
                        {
                            returnedValue = returnedValue * random.Next(Convert.ToInt32(forGenerateK));     //если !(forGenerateK > Int32.MaxValue), то преобразование Convert.ToInt32(forGenerateK) пройдет успешно(не будет переполнения)
                        }
                        forGenerateK = forGenerateK / Int32.MaxValue;   //получаем целую часть от деления forGenerateK на Int32.MaxValue
                    }
                    while (forGenerateK > System.Numerics.BigInteger.Zero);

                    return returnedValue;
                }
            #endregion
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Старый 28.11.2011, 15:20   #5
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
По умолчанию

продолжение кода
Код:
#region Метод для вычисления числа r
                protected System.Numerics.BigInteger Calculate_R(System.Numerics.BigInteger G, System.Numerics.BigInteger K, System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;

                    returnedValue = System.Numerics.BigInteger.ModPow(G, K, P);

                    return returnedValue;
                }
            #endregion

            #region Метод для вычисления числа e
                protected System.Numerics.BigInteger Calculate_E(System.Numerics.BigInteger M, System.Numerics.BigInteger D, System.Numerics.BigInteger K, System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;

                    returnedValue = M * System.Numerics.BigInteger.ModPow(D, K, P);

                    return returnedValue;
                }
            #endregion

            #region Метод для вычисления m'(её числового значения)
                protected System.Numerics.BigInteger Calculate_M(System.Numerics.BigInteger E, System.Numerics.BigInteger R, System.Numerics.BigInteger P, System.Numerics.BigInteger C)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;
                    System.Numerics.BigInteger exponent = P-System.Numerics.BigInteger.One - C;


                    returnedValue = E * System.Numerics.BigInteger.ModPow(R, exponent, P);

                    return returnedValue;
                }
            #endregion








            #region Метод для шифрования строки методом Эль Гамаль
                public String Encrypt(String EncryptingString)
                {
                    String returnedValue = String.Empty;

                    return returnedValue;
                }
            #endregion
            #region Метод для дешифрования строки методом Эль Гамаль
                public String Decrypt(String DecryptingString)
                {                    
                    String returnedValue = String.Empty;
                 
                    return returnedValue;
                }
            #endregion

        }
    #endregion
Класс BigInteger расположен в модуле System.Numerics, который необходимо подключать к проекту
Завтра постараюсь продолжить данный код
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.

Последний раз редактировалось Mixim; 28.11.2011 в 15:26.
Mixim вне форума Ответить с цитированием
Старый 30.11.2011, 03:07   #6
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение

Вроде бы окончил реализацию метода Эль-гамаль. В ранее указанном коде были допущены некоторые ошибки(обнаружено с помощью отладчика). Не стал удалять из кода некоторые строки, которые использовались для отладки - просто их закомментировал. В итоге класс для шифрования текста методом Эль-гамаля имеет следующий вид(из-за ограниченного количества символов в посте класс будет последовательно размещен в нескольких сообщениях):
Код:
        public class ElGamal
        {
            #region КОНСТАНТЫ, необходимые в классе ElGamal
                protected const String PIsNotPrime = "Переданное значение числа P является недопустимым, возможно, оно не является простым";
                protected const String GValueIsNotFound = "Невозможно вычислить параметр G, удовлетворяющий условиям 1<G<(P-1) и (G^Q)modP!=1";
                protected const String CIsNotCorrect = "Переданное значение числа C является недопустимым. Его значение должно удовлетворять неравенству 1<C<(P-1)";
                protected const String ExponentIsNotAvailable = "Параметр Exponent является недопустимым. Его значение должно удовлетворять неравенству Exponent>0";
                protected const String PIsNotMoreThenM = "Текущие значения параметра P и кодируемого символа M неудовлетворяют условию P>M";
                protected const String ProblemsWithDecryptionAlgorithm = "Проблемы с алгоритмом дешифрования";

                protected const Char MoveToNewLine = '\n';  //необходимо для перехода на новую строчку при шифровании
            #endregion

            #region ПЕРЕМЕННЫЕ, необходимые в классе ElGamal
                protected System.Numerics.BigInteger p = System.Numerics.BigInteger.Zero;
                protected System.Numerics.BigInteger g = System.Numerics.BigInteger.Zero;
                protected System.Numerics.BigInteger c = System.Numerics.BigInteger.Zero;   //выбранное пользователем секретное число, обозначаемое в литературе CB
                protected System.Numerics.BigInteger k = System.Numerics.BigInteger.Zero;   //случайное число, удовлетворяющее условию 1<=k<=(p-2)
            #endregion

            #region Конструктор класса ElGamal[с параметрами]
                public ElGamal(System.Numerics.BigInteger P, System.Numerics.BigInteger C)
                {
                    this.P = P;
                    this.C = C;
                }
            #endregion

            #region Организация доступа к полю p с помощью свойства
                public System.Numerics.BigInteger P
                {
                    get
                    {
                        return this.p;
                    }
                    set
                    {
                        if (IsPrimeNumber(value))
                        {
                            this.p = value;
                            this.g = this.Calculate_G(this.P);  //попытаться вычислить коэффициент g
                            this.k = this.Calculate_K(this.P);
                        }
                        else
                        {
                            throw new ArgumentException(ElGamal.PIsNotPrime);
                        }

                    }
                }
            #endregion

            #region Организация доступа к полю g с помощью свойства[доступ только для чтения]
                public System.Numerics.BigInteger G
                {
                    get
                    {
                        return this.g;
                    }
                }
            #endregion

            #region Организация доступа к полю c благодаря свойству
                public System.Numerics.BigInteger C
                {
                    get
                    {
                        return this.c;
                    }
                    set
                    {
                        if ((System.Numerics.BigInteger.One < value) && (value < this.P - 1))
                        {
                            this.c = value;
                        }
                        else
                        {
                            throw new ArgumentException(CIsNotCorrect);
                        }
                    }
                }
            #endregion

            #region Организация доступа к полю k с помощью свойства[доступ только для чтения]
                public System.Numerics.BigInteger K
                {
                    get
                    {
                        return this.k;
                    }
                }
            #endregion
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.

Последний раз редактировалось Mixim; 30.11.2011 в 03:13.
Mixim вне форума Ответить с цитированием
Старый 30.11.2011, 03:09   #7
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение

ПРОДОЛЖЕНИЕ:
Код:
            #region Метод для проверки числа на простоту
                protected Boolean IsPrimeNumber(System.Numerics.BigInteger Number)
                {
                    UInt16 quantityOfDivisors = 0;
                    Boolean returnedValue = true;
                        
                    for (System.Numerics.BigInteger i = 1; i <= Number; i++)
                    {
                        if (Number % i == System.Numerics.BigInteger.Zero)
                        {
                            quantityOfDivisors++;
                            if (quantityOfDivisors > 2)
                            {
                                returnedValue = false;
                                break;
                            }
                        }
                    }

                    return returnedValue;
                }
            #endregion

            #region Метод для возведения числа типа System.Numerics.BigInteger в степень System.Numerics.BigInteger
                protected System.Numerics.BigInteger Pow(System.Numerics.BigInteger Value, System.Numerics.BigInteger Exponent)
                {
                    if(Exponent<System.Numerics.BigInteger.Zero)
                    {
                        throw new ArgumentException(ElGamal.ExponentIsNotAvailable);
                    }
                    else
                    {
                        System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.One;

                        for (System.Numerics.BigInteger currentExponent = System.Numerics.BigInteger.One; currentExponent <= Exponent; currentExponent++)
                        {
                            returnedValue = returnedValue * Value;
                        }

                        return returnedValue;
                    }
                }
            #endregion

            #region Метод для подсчета коэффициента G
                public/*protected*/ System.Numerics.BigInteger Calculate_G(System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;
                            //p=2q-1
                            //тогда в качестве g можно взять любое число для которого справедливы неравенства 1<g<(p-1) и (g^q)mod p!=1
                    System.Numerics.BigInteger q = (P - 1) / 2;
                    Boolean isGFound = false;   //равняется true когда найдено число g

                    for (System.Numerics.BigInteger g = 2; g < P; g++)
                    {
                        if (System.Numerics.BigInteger.ModPow(g,q,p)!=System.Numerics.BigInteger.One)
                        {
                            isGFound = true;
                            returnedValue = g;
                            break;
                        }
                    }

                    //если не удалось найти параметр g
                    if (!isGFound)
                    {
                        throw new ArgumentException(ElGamal.GValueIsNotFound);
                    }

                    return returnedValue;
                    //return 20;
                }
            #endregion

            #region Метод для вычисления открытого числа d
                public/*protected*/ System.Numerics.BigInteger Calculate_D(System.Numerics.BigInteger G, System.Numerics.BigInteger C, System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue=System.Numerics.BigInteger.Zero;

                    returnedValue=System.Numerics.BigInteger.ModPow(G, C, P);

                    return returnedValue;
                }
            #endregion
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Старый 30.11.2011, 03:10   #8
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение

ПРОДОЛЖЕНИЕ 2:
Код:
            #region Метод для вычисления случайного числа 1<=k<=(p-2)
                public/*protected*/ System.Numerics.BigInteger Calculate_K(System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.One;
                    System.Numerics.BigInteger forGenerateK = P - 2;
                    Random random = new Random();

                    do
                    {
                        if (forGenerateK > Int32.MaxValue)
                        {
                            returnedValue = returnedValue * random.Next(Int32.MaxValue);
                        }
                        else
                        {
                            returnedValue = returnedValue * random.Next(Convert.ToInt32(forGenerateK.ToString()));     //если !(forGenerateK > Int32.MaxValue), то преобразование Convert.ToInt32(forGenerateK) пройдет успешно(не будет переполнения)
                        }
                        forGenerateK = forGenerateK / Int32.MaxValue;   //получаем целую часть от деления forGenerateK на Int32.MaxValue
                    }
                    while (forGenerateK > System.Numerics.BigInteger.Zero);

                    return returnedValue;
                }
            #endregion

            #region Метод для вычисления числа r
                public/*protected*/ System.Numerics.BigInteger Calculate_R(System.Numerics.BigInteger G, System.Numerics.BigInteger K, System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;

                    returnedValue = System.Numerics.BigInteger.ModPow(G, K, P);

                    return returnedValue;
                }
            #endregion

            #region Метод для вычисления числа e
                public/*protected*/ System.Numerics.BigInteger Calculate_E(System.Numerics.BigInteger M, System.Numerics.BigInteger D, System.Numerics.BigInteger K, System.Numerics.BigInteger P)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;

                    returnedValue = M * this.Pow(D, K) % P;

                    return returnedValue;
                }
            #endregion

            #region Метод для вычисления m'(её числового значения)
                public/*protected*/ System.Numerics.BigInteger Calculate_M(System.Numerics.BigInteger E, System.Numerics.BigInteger R, System.Numerics.BigInteger P, System.Numerics.BigInteger C)
                {
                    System.Numerics.BigInteger returnedValue = System.Numerics.BigInteger.Zero;
                    System.Numerics.BigInteger exponent = P-System.Numerics.BigInteger.One - C;


                    returnedValue = E * this.Pow(R, exponent)% P;

                    return returnedValue;
                }
            #endregion

            #region Метод для проверки условия m<p  [Unicode текущего шифруемого символа меньше числа p]
                protected Boolean isPMoreThenM(System.Numerics.BigInteger P, System.Numerics.BigInteger M)
                {
                    Boolean returnedValue = false;

                    if (M < P)
                    {
                        returnedValue = true;
                    }
                    else
                    {
                        returnedValue = false;
                    }

                    return returnedValue;
                }
            #endregion
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Старый 30.11.2011, 03:11   #9
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение

ПРОДОЛЖЕНИЕ 3:
Код:
            #region Метод для шифрования строки методом Эль-Гамаль
                public String Encrypt(String EncryptingString)
                {                                      
                    String returnedValue = String.Empty;

                    foreach (Char ch in EncryptingString)
                    {
                        if (this.isPMoreThenM(this.P, ch))
                        {
                            returnedValue += this.Calculate_R(this.G, this.K, this.P).ToString();   //записываем в строку число r
                            returnedValue += ElGamal.MoveToNewLine; //переходим на новую строку
                            returnedValue += this.Calculate_E(ch, this.Calculate_D(this.G, this.C, this.P), K, this.P).ToString();  //записываем в строку число e
                            returnedValue += ElGamal.MoveToNewLine; //переходим на новую строку
                        }
                        else
                        {
                            throw new ArgumentException(ElGamal.PIsNotMoreThenM);
                        }
                    }

                    return returnedValue;
                }
            #endregion

            #region Метод для дешифрования строки методом Эль-Гамаль
                public String Decrypt(String DecryptingString)
                {                    
                    String returnedValue = String.Empty;
                        System.Numerics.BigInteger R = System.Numerics.BigInteger.Zero;
                            Boolean isRReaded = false;
                        System.Numerics.BigInteger E = System.Numerics.BigInteger.Zero;
                            Boolean isEReaded = false;
                        String forReadString = String.Empty;
                            Int32 forReadChar=0;

                    foreach (Char ch in DecryptingString)
                    {
                        if (Int32.TryParse(ch.ToString(), out forReadChar))
                        {
                            forReadString += ch;
                        }
                        else
                        {
                            if (!isRReaded)
                            {
                                R = System.Numerics.BigInteger.Parse(forReadString);
                                    forReadString = String.Empty;
                                isRReaded = true;
                            }
                            else
                            {
                                if (!isEReaded)
                                {
                                    E = System.Numerics.BigInteger.Parse(forReadString);

                                    //returnedValue += this.Calculate_M(E, R, this.P, this.C).ToString();
                                    returnedValue += Convert.ToChar(Convert.ToInt32(this.Calculate_M(E, R, this.P, this.C).ToString()));

                                        forReadString = String.Empty;
                                        isEReaded = true;

                                    isRReaded = false;
                                    isRReaded = false;
                                }
                                else
                                {
                                    throw new Exception(ElGamal.ProblemsWithDecryptionAlgorithm);
                                }
                            }
                        }
                    }

                    if (isRReaded)
                    {
                        returnedValue += this.Calculate_M(E, R, this.P, this.C).ToString();
                    }

                    return returnedValue;
                }
            #endregion

        }
    #endregion
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Старый 30.11.2011, 03:15   #10
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Счастье

В коде использовался класс BigInteger, описание которого можно найти на MSDN ЗДЕСЬ
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
криптосистема Эль-Гамаля Nanochka Помощь студентам 16 21.04.2012 10:53
криптография (эль-гамаль) serega28 Общие вопросы Delphi 0 22.06.2011 11:54
Блок-схема алгоритма шифрования/расшифрования MontyJo Помощь студентам 6 28.06.2010 21:20