Cipolla's algorithm: Difference between revisions

m
→‎{{header|Sage}}: Fixed a few stray bugs and updated algorithm for cases where p is not prime.
(→‎{{header|FreeBASIC}}: added GMP version)
m (→‎{{header|Sage}}: Fixed a few stray bugs and updated algorithm for cases where p is not prime.)
Line 827:
return ((x1*x2 + y1*y2*u) % p), ((x1*y2 + x2*y1) % p)
 
def cipollaAlgorithm(a, p, t = 10):
ifa not= is_primepow(a, 1, p):
out = []
print "❌ " + str(p) + " is not a prime."
 
return False
if eulerCriterion(a, p) == -1:
print "❌ " + str(a) + " is not a quadratic residue modulo " + str(p)
return False
if pow(p, 1, 4) == 3:
return [pow(a, int((p-1)/4), p), -pow(a, int((p-1)/4), p)]
 
aif =not powis_prime(a, 1, p):
conglst = [] #congruence list
out = []
crtlst = []
factors = []
 
for k in list(factor(p)):
outfactors.append(xint(k[0]))
 
for f in factors:
conglst.append(cipollaAlgorithm(a, f))
 
for i in Permutations([0, 1] * len(factors), len(factors)).list():
for j in range(len(factors)):
crtlst.append(int(conglst[ j ][ i[j] ]))
 
out.append(crt(crtlst, factors))
tcrtlst = randrange(2, p)[]
 
return Falsesorted(out)
 
if pow(p, 1, 4) == 3:
returntemp [pow(a,= int((p-1)/4), p), -pow(a, int((p-1)/4), p)]
return [temp, p - temp]
 
fort i= in rangerandrange(t2, p):
u = pow(t**2 - a, 1, p)
while (eulerCriterion(u, p) == 1):
t = randrange(2, p)
u = pow(t**2 - a, 1, p)
while (eulerCriterion(u, p) == 1):
t = randrange(2, p)
u = pow(t**2 - a, 1, p)
 
x0, y0 = t, 1
x, y = t, 1
for i in range(int((p + 1) / 2) - 1):
x, y = cipollaMult(x, y, x0, y0, u, p)
 
out.extend([x, if pow(-x, not1, in out:p)])
out.append(x)
 
return sorted(out)