
- •Простые числа и простейшие теоретико-числовые функции
- •Вероятностный тест простоты (тест Миллера-Рабина)
- •Пример реализации «Решета Эратосфена» и теста Миллера-Рабина
- •Теоретико-числовые функции Наибольший общий делитель
- •Наименьшее общее кратное
- •Вычисление мультипликативного обратного
- •Извлечение квадратного корня из а по модулю m
- •Извлечение квадратного корня из а по модулю p*q
Вычисление мультипликативного обратного
Решая уравнение вида а·х =1(mod M) может возникнуть вопрос о существовании числа х мультипликативного обратного числу а по модулю N.
Такое число х должно удовлетворять сравнению a · x≡x ·a≡1(mod M) и обозначается как a-1.
Если M положительное простое число, то для любого простого числа a≥0 существует мультипликативное обратное число a-1 . Т. е. число a-1 мультипликативного обратного к числу а существует только тогда, когда числа а и M взаимно просты, а значит НОД(а, М) = 1.
Нахождение мультипликативного обратного числа может проводиться по расширенному алгоритму Евклида, реализованного в виде следующей функции:
Вычисление мультипликативного обратного
Синтаксис: void inv_l (CLINT a, CLINT M, CLINT g ,CLINT a_1);
Вход: a, M (операнды)
Выход: g (наибольший общий делитель чисел а и M)
a_1 (обратный элемент к a mod M, если он существует)
Листинг программы, реализующей вычисление мультипликативного обратного
#include <FLINT.h>
#include <stdio.h>
#include <conio.h>
#include <math.h>
#define ClintToStr xclint2str_l // Переопределение функции xclint2str_l
int main(int argc, char* argv[])
{
CLINT a,b,c,ed;
CLINT g , a_1 ;
char *s1 =new char;s1="7"; // Строка 10-х цифр
str2clint_l (a,s1,10);//Инициализация строкой
char *s2 =new char;s2="13"; // Строка 10-х цифр
str2clint_l (b,s2,10);//Инициализация строкой
char *s3 =new char;s3="1"; // Строка 10-х цифр
str2clint_l (ed,s3,10);//Инициализация 1
printf("a=%s\n",ClintToStr(a,10,1));
printf("b=%s\n",ClintToStr(b,10,1));
// Наибольший общий делитель (НОД)
gcd_l ( a, b, c);
printf("HOD(a,b)=%s\n",ClintToStr(c,10,1));
// Вычисление мультипликативного обратного
inv_l (a, b, g , a_1);
if( cmp_l( g, ed)==0) printf("x_1= %s\n",ClintToStr(a_1,10,1));
getch(); return 0;
}
Извлечение квадратного корня из а по модулю m
Извлечением квадратного корня из числа а по модулю M является процедура нахождения такого x, для которого справедливо сравнение
x 2 ≡ a (mod M)
Квадратный корень, в общем, определен неоднозначно, то есть может существовать несколько квадратных корней из одного элемента, а может не существовать ни одного решения.
Если НОД(а,M) =1 и существует одно решение b такое, что b ≡ a mod M, то число а называется квадратичным вычетом по модулю M.
Если сравнение неразрешимо, то число а называется квадратичным невычетом по модулю M.
Если число M простое, то найти квадратные корни по модулю M довольно просто.
Трудность вычисления квадратных корней по модулю составного числа M определяется тем, известно ли разложение числа M на простые множители. Если разложение неизвестно, то вычисление квадратных корней для большого числа M является математически сложной задачей, лежащей в основе безопасности ряда современных криптосистем.
Определение того, является ли число квадратичным вычетом, и вычисление квадратных корней - это две разные задачи, для решения каждой из которых существуют свои методы.
В FLINT/C описана следующая функция, позволяющая совместно с функцией проверки числа на простоту, выполнить извлечение квадратного корня из а по модулю M .
Извлечение квадратного корня из а по модулю M
Синтаксис: int proot_l (CLINT a, CLINT M, CLINT x);
Вход: a (операнд, a ≠ M)
M (операнд, M > 2 – простое, M ≠ a)
Выход: x (квадратный корень из а по модулю р)
Возврат: 0, если а - квадратичный вычет по модулю р,
-1 в противном случае