Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
|
|
@ -0,0 +1,65 @@
|
|||
proc pow*[T: SomeInteger](x, n, p: T): T =
|
||||
var t = x mod p
|
||||
var e = n
|
||||
result = 1
|
||||
while e > 0:
|
||||
if (e and 1) == 1:
|
||||
result = result * t mod p
|
||||
t = t * t mod p
|
||||
e = e shr 1
|
||||
|
||||
proc legendre*[T: SomeInteger](a, p: T): T = pow(a, (p-1) shr 1, p)
|
||||
|
||||
proc tonelliShanks*[T: SomeInteger](n, p: T): T =
|
||||
# Check that n is indeed a square.
|
||||
if legendre(n, p) != 1:
|
||||
raise newException(ValueError, "Not a square")
|
||||
|
||||
# Factor out power of 2 from p-1.
|
||||
var q = p - 1
|
||||
var s = 0
|
||||
while (q and 1) == 0:
|
||||
s += 1
|
||||
q = q shr 1
|
||||
|
||||
if s == 1:
|
||||
return pow(n, (p+1) shr 2, p)
|
||||
|
||||
# Select a non-square z such as (z | p) = -1.
|
||||
var z = 2
|
||||
while legendre(z, p) != p - 1:
|
||||
z += 1
|
||||
|
||||
var
|
||||
c = pow(z, q, p)
|
||||
t = pow(n, q, p)
|
||||
m = s
|
||||
result = pow(n, (q+1) shr 1, p)
|
||||
while t != 1:
|
||||
var
|
||||
i = 1
|
||||
z = t * t mod p
|
||||
while z != 1 and i < m-1:
|
||||
i += 1
|
||||
z = z * z mod p
|
||||
|
||||
var b = pow(c, 1 shl (m-i-1), p)
|
||||
c = b * b mod p
|
||||
t = t * c mod p
|
||||
m = i
|
||||
result = result * b mod p
|
||||
|
||||
when isMainModule:
|
||||
proc run(n, p: SomeInteger) =
|
||||
try:
|
||||
let r = tonelliShanks(n, p)
|
||||
echo r, " ", p-r
|
||||
except ValueError:
|
||||
echo getCurrentExceptionMsg()
|
||||
|
||||
run(10, 13)
|
||||
run(56, 101)
|
||||
run(1030, 10009)
|
||||
run(1032, 10009)
|
||||
run(44402, 100049)
|
||||
run(665820697, 1000000009)
|
||||
Loading…
Add table
Add a link
Reference in a new issue