JSFiddle - React, Tailwind, and code Playground
JavaScript
let unsafeToSquare = Math.floor(Math.sqrt(Number.MAX_SAFE_INTEGER))
function addMod(a, b, m) {
// Returns (a + b) % m
let sum = a + b
let result = sum % m
if (sum < Number.MAX_SAFE_INTEGER)
return result
let signature = ((a % 8) + (b % 8)) % 8
let sumMod = sum % 8
for (let i = -2; i <= 2; ++i) {
if ((sumMod + i) % 8 === signature) {
let ret = result + i
if (ret > m)
ret = (result - m) + i // prevent overflow
return ret
}
}
}
function mulMod(a, b, m) {
if (m === 0)
return 0
let prod = a * b
if (prod < Number.MAX_SAFE_INTEGER)
return prod % m
let y = 0
let result = a
while (b > 1) {
if (b % 2 === 0) {
result = addMod(result, result, m)
b /= 2
} else {
y = addMod(result, y, m)
result = addMod(result, result, m)
b = (b - 1) / 2
}
}
return addMod(result, y, m)
}
function squareMod(b, m) {
// Computes (b * b % m)
return mulMod(b, b, m)
}
function expModLargeB(b, exponent, m) {
let y = 1
while (exponent > 1) {
if (exponent % 2 === 0) {
b = squareMod(b, m)
exponent /= 2
} else {
y = mulMod(y, b, m)
b = squareMod(b, m)
exponent = (exponent - 1) / 2
}
}
return mulMod(b, y, m)
}
function expMod(b, exponent, m) {
if (exponent === 0)
return 1
if (b >= unsafeToSquare || m >= unsafeToSquare) {
return expModLargeB(b, exponent, m)
}
let y = 1
while (exponent > 1) {
if (exponent % 2 === 0) {
b *= b
b %= m
exponent /= 2
} else {
y *= b
b *= b
y %= m
b %= m
exponent = (exponent - 1) / 2
}
}
return (b * y) % m
}
function _isPrimeTrialDivision(p) {
let sqrtP = Math.ceil(Math.sqrt(p))
for (let i = 23; i <= sqrtP + 1; i += 2) {
if (p % i === 0)
return false
}
return true
}
function _isProbablePrimeMillerRabin(p, base=2) {
let pm1 = p - 1
let pm1div = pm1
let d, r = 0
while...