Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
using
using
using
System;
System.Collections.Generic;
System.ComponentModel;
System.Windows.Forms;
namespace AKSPrimalityTest
{
class AKSTest
{
bool prime, rTooBig;
long[] n;
MainForm mainForm;
TextBox atb, ltb;
public bool Prime
{
get
{
return prime;
}
}
public bool RTooBig
{
get
{
return rTooBig;
}
}
long Log10(long[] n)
{
long b = lngint.BASE;
long l = (long)Math.Log10(b);
long h = (long)Math.Log10(n[n.Length - 1]);
return l * (n.Length - 2) + h;
}
long Order(long[] n, ref long[] r, ref long log10)
{
log10 = Log10(n);
long l2 = log10 * log10;
long[] one = { 1, 1 };
long[] g = null, p = null;
r = new long[2];
r[0] = 1;
r[1] = 2;
while (true)
{
g = lngint.gcd(n, r);
if (lngint.compare(g, one) == 0)
{
for (long k = l2 + 1; k <= l2 + 64; k++)
{
p = lngint.powermod(n, k, r);
if (lngint.compare(p, one) == 0)
return k;
}
}
r = lngint.add(r, one);
}
}
long Phi(List<long> primes, long m)
{
int index = primes.BinarySearch(m);
if (index >= 0)
return primes[index] - 1;
long d = m;
long phi = 1;
for (int i = 0; i < primes.Count; i++)
{
long p = primes[i];
if (d % p == 0)
{
long e = 1;
d /= p;
while (d % p == 0)
{
d /= p;
e++;
}
phi *= (m - m / p);
}
}
return phi;
}
void Sieve(long B0, ref List<long> primes)
{
// Sieve of Eratosthenes
// find all prime numbers
// less than or equal B0
bool[] sieve = new bool[B0 + 1];
long c = 3, i, inc;
sieve[2] = true;
for (i = 3; i <= B0; i++)
if (i % 2 == 1)
sieve[i] = true;
do
{
i = c * c;
inc = c + c;
while (i <= B0)
{
sieve[i] = false;
i += inc;
}
c += 2;
while (!sieve[c])
c++;
} while (c * c <= B0);
primes = new List<long>();
for (i = 2; i <= B0; i++)
if (sieve[i])
primes.Add(i);
}
public struct Coeff
{
public long[] val;
}
void polydivmod(long m, long n, long[] N, Coeff[] u, Coeff[] v,
ref Coeff[] q, ref Coeff[] r, ref long p, ref long s)
{
long j, jk, k, nk;
long[] a = null, b = null;
long[] vn = v[n].val;
r = new Coeff[m + 1];
for (j = 0; j <= m; j++)
r[j].val = slngint.copy(u[j].val);
if (m < n)
{
p = 0;
s = m;
q = new Coeff[1];
q[0].val = new long[2];
q[0].val[0] = 1;
q[0].val[1] = 0;
}
else
{
p = m - n;
s = n - 1;
q = new Coeff[p + 1];
for (k = p; k >= 0; k--)
{
nk = n + k;
a = slngint.powermod(vn, k, N);
return S;
long p = 0,
long[] kk =
long[] c2 =
Coeff[] G =
Coeff[] Q =
Coeff[] R =
s = 0;
slngint.copy(k);
{ 1, 2 };
new Coeff[g.Length];
null;
null;
{
MillerRabin mr = new MillerRabin();
if (mr.Composite(n, 8))
{
prime = false;
return;
}
long log10
long[] r =
long[] o =
long[] a =
long ord =
= 0;
null;
{ 1, 1 };
{ 1, 2 };
Order(n, ref r, ref log10);
if (lngint.compare(r, n) > 0)
{
prime = false;
return;
}
while (lngint.compare(a, r) < 0)
{
long[] g = lngint.gcd(a, n);
if (lngint.compare(g, o) > 0 && lngint.compare(g, n) < 0)
{
prime = false;
return;
}
a = lngint.add(a, o);
}
if (r.Length == 2)
{
if (worker.CancellationPending)
e.Cancel = true;
else
{
rTooBig = false;
long A = a[1];
long R = r[1];
long B0 = 10000000;
List<long> primes = null;
Sieve(B0, ref primes);
long phi = Phi(primes, R);
long upper = (long)(Math.Sqrt(phi) * log10);
long[] z = { 1, 0 };
Coeff[] X = new Coeff[R + 1];
Coeff[] Y = new Coeff[2];
for (int i = 1; i < R; i++)
X[i].val = slngint.copy(z);
X[R].val = slngint.copy(o);
X[0].val = slngint.copy(o);
X[0].val[0] = -1;
mainForm.SetText5(upper.ToString());
for (A = 1; A <= upper; A++)
{
if (worker.CancellationPending)
e.Cancel = true;
else
{
mainForm.SetText4(A.ToString());
a[0] = 1;
a[1] = A;
long[] g = lngint.gcd(a, n);
if (g[0] == 1 && g[1] == 1)
{
Y[1].val = slngint.copy(o);
Y[0].val = slngint.copy(a);
Coeff[] P = polypowmod(Y, X, n, n);
if (!(P[0].val[0] == 1 && P[0].val[1] == A))
{
prime = false;
return;
}
}
}
}
prime = true;
return;
}
}
else
{
rTooBig = true;
return;
}
}
public AKSTest(long[] n, MainForm mainForm, TextBox atb, TextBox ltb)
{
this.n = slngint.copy(n);
this.mainForm = mainForm;
this.atb = atb;
this.ltb = ltb;
prime = false;
}
}
}
================================================================================
=============================================
================================================================================
=============================================
#include <iostream>
using namespace std;
#include <math.h>
#ifdef _M_IX86
#define
__asm
__asm
__asm
__asm
umulrem(z, x, y, m)
mov
eax, x
mul
y
div
m
mov
z, edx
\
\
\
\
#define
__asm
__asm
__asm
__asm
__asm
__asm
umuladdrem(z, x, y, a, m)
mov
eax, x \
mul
y
\
add
eax, a \
adc
edx, 0 \
div
m
\
mov
z, edx
#else
#ifdef _MSC_VER
typedef unsigned __int64
#else
typedef unsigned long long
#endif
Tu64;
Tu64;
#define umulrem(z, x, y, m)
\
{
\
z = (unsigned int)(x * (Tu64)y % m);
}
#define umuladdrem(z, x, y, a, m)
\
{
\
z = (unsigned int)((x * (Tu64)y + a) % m);
}
#endif
static bool IsPrime(unsigned int n)
{
if (n < 2) return false;
if (n < 4) return true;
if (n % 2 == 0) return false;
const unsigned int iMax = (int)sqrt(n) + 1;
unsigned int i;
for (i = 3; i <= iMax; i += 2)
if (n % i == 0)
return false;
return true;
}
static unsigned int LargestPrimeFactor(unsigned int n)
{
if (n < 2) return 1;
unsigned int r = n, p;
if (r % 2 == 0)
{
p = 2;
do { r /= 2; } while (r % 2 == 0);
}
unsigned int i;
for (i = 3; i <= r; i += 2)
{
if (r % i == 0)
{
p = i;
do { r /= i; } while (r % i == 0);
}
}
return p;
}
static unsigned int Powm(unsigned int n, unsigned int e, unsigned int m)
{
unsigned int r = 1;
unsigned int t = n % m;
unsigned int i;
for (i = e; i != 0; i /= 2)
{
if (i % 2 != 0)
{
umulrem(r, r, t, m);
}
umulrem(t, t, t, m);
}
return r;
}
static unsigned int Inv(unsigned int n, unsigned int m)
{
unsigned int a = n, b = m;
int u = 1, v = 0;
do
{
const unsigned int q = a / b;
const unsigned int t1 = a - q*b;
a = b;
b = t1;
const int t2 = u - (int)q*v;
u = v;
v = t2;
} while (b != 0);
if (a != 1) u = 0;
if (u < 0) u += m;
return u;
}
class CPolyMod
{
protected:
// (mod x^r - 1, n)
const unsigned int m_r;
const unsigned int m_n;
unsigned int m_deg;
unsigned int * mp_a;
private:
CPolyMod():m_r(0), m_n(0) { mp_a = NULL; };
public:
// default value is x
CPolyMod(unsigned int r, unsigned int n)
: m_r(r), m_n(n)
{
m_deg = 1;
mp_a = new unsigned int [2];
mp_a[0] = 0; mp_a[1] = 1;
}
CPolyMod(const CPolyMod & p)
: m_r(p.m_r), m_n(p.m_n)
{
m_deg = p.m_deg;
mp_a = new unsigned int [p.m_deg + 1];
unsigned int i;
for (i = 0; i <= p.m_deg; ++i)
mp_a[i] = p.mp_a[i];
}
virtual ~CPolyMod()
{
if (mp_a != NULL)
delete [] mp_a;
}
private:
void _polySquare()
{
const unsigned int deg = m_deg;
const unsigned int n = m_n;
const unsigned int * const p_a = mp_a;
const unsigned int degr = deg + deg;
unsigned int * const p_ar = new unsigned int [degr + 1];
unsigned int k;
for (k = 0; k <= degr; ++k)
p_ar[k] = 0;
unsigned int j;
for (j = 1; j <= deg; ++j)
{
const unsigned int x = p_a[j];
if (x != 0)
{
unsigned int i;
}
CPolyMod & operator -= (unsigned int i)
{
const unsigned int t = m_n - i % m_n;
mp_a[0] += t;
if (mp_a[0] >= m_n) mp_a[0] -= m_n;
return *this;
}
CPolyMod Pow(unsigned int e) const
{
unsigned int er = 1;
unsigned int j;
for (j = e; j != 1; j /= 2)
{
er = 2 * er + (j % 2);
}
CPolyMod t(*this);
unsigned int i;
for (i = er; i != 1; i /= 2)
{
t._polySquare();
t._Mod();
if (i % 2 != 0)
{
t._polyMul(*this);
t._Mod();
}
}
t._Norm();
return t;
}
};
int main(int argc, char * argv[])
{
// AKS
// n=11701, r=11699, q=5849, s=2923
// n=1000000007, r=57287, q=28643, s=14311
//
// Bernstein
// n=349, r=347, q=173, s=140
// n=1000000007, r=3623, q=1811, s=1785
unsigned int n0;
cout << "n ? ";
cin >> n0;
unsigned int n;
for (n = n0; true; n += 2)
{
bool b = false;
unsigned int q, r, s;
for (r = 3; r < n; r += 2)
{
if (IsPrime(r))
{
const unsigned int m = n % r;
if (m == 0) break;
q = LargestPrimeFactor(r - 1);
if (Powm(m, (r - 1) / q, r) <= 1) continue;
/*
// AKS
if (q >= 4 * sqrt(r) * n.Log()/log(2))
{
s = (unsigned int)(2 * sqrt(r) * n.Log()
/log(2));
b = true;
break;
}
*/
// Bernstein
const double cMin = 2 * floor(sqrt(r)) * log(n);
double c = 0;
for (s = 1; s <= q; s++)
{
c += log(q + s - 1) - log(s);
if (c >= cMin)
{
b = true;
break;
}
}
if (b) break;
}
}
if (b)
{
cout << "n=" << n << ", r=" << r << ", q=" << q << ", s=
" << s << "\r" << flush;;
bool b = true;
CPolyMod rPoly(r, n);
// x
try
{
rPoly = rPoly.Pow(n);
// x^n
}
catch (...)
{
b = false;
}
if (b)
{
unsigned int a;
for (a = 1; a <= s; ++a)
{
cout << "n=" << n << ", r=" << r << ", q
=" << q << ", s=" << s << " " << a << "\r" << flush;;
CPolyMod lPoly(r, n);
lPoly -= a;
// x
// x - a
try
{
lPoly = lPoly.Pow(n);
a)^n
// (x -
}
catch (...)
{
b = false;
break;
}
lPoly += a;
// (x - a)^n + a
if (lPoly != rPoly)
{
b = false;
break;
}
}
}
if (b)
cout << "n=" << n << ", r=" << r << ", q=" << q
<< ", s=" << s << ", power of a prime." << endl;
else
cout << "n=" << n << ", r=" << r << ", q=" << q
<< ", s=" << s << ", composite." << endl;
}
}
return 0;
}
================================================================================
=================================================
================================================================================
=================================================
use strict;
# use bignum;
print <<USAGE and exit 0 unless @ARGV;
$0 [-v] n
Use the AKS primality test to check whether n is prime
-v adds verbose log spew
USAGE
sub
sub
sub
sub
sub
sub
sub
sub
sub
sub
is_power($$);
ceil_log2($);
first_r($$);
check_gcds($$);
check_polynomials($$$);
gcd($$);
totient($);
polypow($$\@);
polymult($$\@\@);
polyeq(\@\@);
my $verbose = $ARGV[0] eq
shift @ARGV if $verbose;
-v ;
unless 1 == @ARGV;
if $verbose;
my $t = $b ** $i;
if ($t == $n) {
print $n = $b^$i; $n is COMPOSITE\n ;
return 1;
}
($t > $n ? $b_high : $b_low) = $b;
}
#
#
#
#
#
#
#
#
1) >
n
#
# we ll square b_high; b ^ i > n => (b ^ 2) ^ (i 1) = b ^ (2 i
2) > n
# since i >= 2
#
# OPEN ISSUE: is there a better way to raise this higher bound? Does thi
s help much?
$b_high *= $b_high;
}
# nope, not a power
return 0;
}
sub ceil_log2($) {
my $n = shift;
my $i = 0;
my $t = 1;
until ($t >= $n) {
$i++;
$t *= 2;
}
return $i;
}
sub first_r($$) {
my $n = shift;
my $log2_n = shift; # actually ceil(log2(n))
my $s = $log2_n ** 2;
print Looking for the first r where o_r($n) > $s \n ;
# for each r we want to find the smallest k such that
# n^k == 1 mod r
my $r;
for ($r = 2; ; $r++) {
# print \tTrying $r \n ;
# find the multiplicative order of n mod r
my $k = 1;
my $t = $n % $r;
until (1 == $t or $k > $s) {
$t = ($t * $n) % $r;
$k++;
}
if ($k > $s) {
# print \to_$r($n) is at least $k\n ;
last;
} else {
# print \to_$r($n) = $k\n ;
}
}
return $r;
}
sub check_gcds($$) {
my ($n, $r) = @_;
print Checking GCD($n, a) for a = 2 to $r \n ;
for (my $a = 2; $a <= $r; $a++) {
my $g = gcd($n, $a);
next if ($g == $n); # this is OK
if (1 != $g) {
print gcd($n, $a) = $g; $n is COMPOSITE\n ;
return 0;
}
}
print All GCDs are 1 or $n\n ;
return 1;
}
sub gcd($$) {
my ($x, $y) = @_;
($x, $y) = ($y, $x) unless $x > $y;
while ($y) {
($x, $y) = ($y, $x % $y);
}
return $x;
}
sub check_polynomials($$$) {
my $n = shift;
my $r = shift;
\n ;
1, $n)\n ;
next if $r % $p;
print \t$p is a factor\n if $verbose;
# decrease the totient
$t /= $p;
$t *= $p 1;
# decrease r
$r /= $p; # we know there s at least one factor of p
$r /= $p until $r % $p; # there might be more
}
print
Totient is $t\n ;
return $t;
}
sub polypow($$\@) {
my $n = shift; # this is both the mod and the exponent
my $r = shift;
my @base = @{ +shift };
my $exp = $n;
my @result = (1); # 1
# print \t( , join(
1, $n)\n
if $verbose;
, @result), )\n
if $verbose;
}
sub polymult($$\@\@) {
my $n = shift;
my $r = shift;
my @first = @{ +shift };
my @second = @{ +shift };
# print
ose;
\t\t( , join(
, @first),
) * ( , join(
my @result = ();
# first
my $s =
for (my
for
1, $n)\
}
#
#
#
#
#
#
#
#
, @result), )\n
if $verbose;
}
sub polyeq(\@\@) {
my @lhs = @{ +shift };
my @rhs = @{ +shift };
# print
( , join(
, @lhs),
) = ( , join(
, @rhs),
)?\n if $verbose;
================================================================================
========================================================
================================================================================
====================================
import math
import sys
#used literature http://teal.gmu.edu/courses/ECE746/project/F06_Project_resource
s/Salembier_Southerington_AKS.pdf
#http://dha.spb.ru/PDF/AKS.pdf
#https://en.wikipedia.org/wiki/AKS_primality_test
def Main():
if len(sys.argv) != 3:
print ('Invalid number of input arguments')
else:
try:
fil = sys.argv[1]
f = open(fil, 'r')
except:
print ('File not found')
else:
fil
f =
n =
q =
= sys.argv[1]
open(fil, 'r')
int(f.read()) #?????????? ???????? ?????
int(4 * pow(math.log2(n),2) + 1)
check_input(n)
PerfectPower(n)
Individual_r(n,q)
def check_input(n):
if n < 1 :
Output('\nFalse, input is incorrect')
elif n == 1 :
Output('\nFalse, Composite number')
def Output(text) :
fil1 = sys.argv[2]
f = open(fil1, 'w')
f.writelines(text)
f.close()
exit(0)
def PerfectPower(n):
b = 2
if b > math.log2(n):
Output('\nPrime')
#??????? ????? n
else:
q += 1
return Individual_r(q)
def GCD(n,r):
if r >= n:
r = n - 1
for gcd in range(r,0,-1) :
z = n
if z % gcd == 0 :
if gcd != 1:
Output('\nFalse, Composite number')
else:
for gcd in range(r,0,-1) :
z = n
if z % gcd == 0 :
if gcd != 1:
Output('\nFalse, Composite number')
def FermaTest(n,r):
for k in range(2 , int(2 * math.sqrt(r) * math.log2(n))) : #????? ?????
if (pow(k , (n - 1)) - 1) % n != 0 :
Output('\nFalse, Composite number')
continue
else :
Output('\nPrime')
Main()
================================================================================
====================================================
================================================================================
====================================================