Data update
This commit is contained in:
parent
4d5544505c
commit
4924dd0264
3073 changed files with 55820 additions and 4408 deletions
98
Task/Tonelli-Shanks-algorithm/R/tonelli-shanks-algorithm.r
Normal file
98
Task/Tonelli-Shanks-algorithm/R/tonelli-shanks-algorithm.r
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
library(gmp) # For handling large integers and modular arithmetic
|
||||
|
||||
# Legendre symbol: a^((p-1)/2) mod p
|
||||
legendre <- function(a, p) {
|
||||
a <- as.bigz(a)
|
||||
p <- as.bigz(p)
|
||||
e <- div.bigz(sub.bigz(p, 1), 2)
|
||||
result <- powm(a, e, p)
|
||||
return(result)
|
||||
}
|
||||
|
||||
# Tonelli-Shanks algorithm to find square root of n mod p
|
||||
tonelli <- function(n, p) {
|
||||
n <- as.bigz(n)
|
||||
p <- as.bigz(p)
|
||||
|
||||
# Check that n is a quadratic residue
|
||||
leg <- legendre(n, p)
|
||||
if (!identical(as.character(leg), "1")) {
|
||||
stop("not a square (mod p)")
|
||||
}
|
||||
|
||||
q <- sub.bigz(p, 1)
|
||||
s <- 0
|
||||
while (mod.bigz(q, 2) == 0) {
|
||||
q <- div.bigz(q, 2)
|
||||
s <- s + 1
|
||||
}
|
||||
|
||||
if (s == 1) {
|
||||
e <- div.bigz(add.bigz(p, 1), 4)
|
||||
return(powm(n, e, p))
|
||||
}
|
||||
|
||||
z <- as.bigz(2)
|
||||
p_minus_1 <- sub.bigz(p, 1)
|
||||
while (z < p) {
|
||||
if (identical(as.character(legendre(z, p)), as.character(p_minus_1))) {
|
||||
break
|
||||
}
|
||||
z <- add.bigz(z, 1)
|
||||
}
|
||||
|
||||
c <- powm(z, q, p)
|
||||
r <- powm(n, div.bigz(add.bigz(q, 1), 2), p)
|
||||
t <- powm(n, q, p)
|
||||
m <- s
|
||||
|
||||
one <- as.bigz(1)
|
||||
two <- as.bigz(2)
|
||||
|
||||
while (!identical(mod.bigz(sub.bigz(t, one), p), as.bigz(0))) {
|
||||
t2 <- mod.bigz(mul.bigz(t, t), p)
|
||||
i <- 1
|
||||
while (i < m) {
|
||||
if (identical(mod.bigz(sub.bigz(t2, one), p), as.bigz(0))) {
|
||||
break
|
||||
}
|
||||
t2 <- mod.bigz(mul.bigz(t2, t2), p)
|
||||
i <- i + 1
|
||||
}
|
||||
|
||||
b_exp <- pow.bigz(two, m - i - 1)
|
||||
b <- powm(c, b_exp, p)
|
||||
r <- mod.bigz(mul.bigz(r, b), p)
|
||||
c <- mod.bigz(mul.bigz(b, b), p)
|
||||
t <- mod.bigz(mul.bigz(t, c), p)
|
||||
m <- i
|
||||
}
|
||||
|
||||
return(r)
|
||||
}
|
||||
|
||||
# Test cases
|
||||
ttest <- list(
|
||||
c("10", "13"),
|
||||
c("56", "101"),
|
||||
c("1030", "10009"),
|
||||
c("44402", "100049"),
|
||||
c("665820697", "1000000009"),
|
||||
c("881398088036", "1000000000039"),
|
||||
c("41660815127637347468140745042827704103445750172002", "100000000000000000000000000000000000000000000000577")
|
||||
)
|
||||
|
||||
for (case in ttest) {
|
||||
n <- as.bigz(case[1])
|
||||
p <- as.bigz(case[2])
|
||||
r <- tonelli(n, p)
|
||||
check <- mod.bigz(sub.bigz(mul.bigz(r, r), n), p)
|
||||
|
||||
# Verify the result
|
||||
if (!identical(as.character(check), "0")) {
|
||||
stop("Verification failed")
|
||||
}
|
||||
|
||||
cat("n =", as.character(n), "p =", as.character(p), "\n")
|
||||
cat("\troots :", as.character(r), as.character(sub.bigz(p, r)), "\n")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue