1 parent
0cf70e272b
commit
54d82ac660
1 file changed
+196
+196
@@ -0,0 +1,196 @@
|
|||||||
|
from math import gcd as mathgcd
|
||||||
|
from itertools import combinations
|
||||||
|
from functools import wraps
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
# home grown gcd
|
||||||
|
def gcd(a, b):
|
||||||
|
return a if b == 0 else gcd(b, a % b)
|
||||||
|
|
||||||
|
|
||||||
|
def cooked(s: set[int]):
|
||||||
|
for a, b in combinations(s, 2):
|
||||||
|
if mathgcd(a, b) == 1:
|
||||||
|
yield a, b
|
||||||
|
|
||||||
|
|
||||||
|
printingTs = False
|
||||||
|
|
||||||
|
|
||||||
|
def printTs(f):
|
||||||
|
@wraps(f)
|
||||||
|
def ff(*a, **kw):
|
||||||
|
if printingTs:
|
||||||
|
if a:
|
||||||
|
print(*a)
|
||||||
|
if kw:
|
||||||
|
print(*kw.items())
|
||||||
|
r = f(*a, *kw)
|
||||||
|
if printingTs:
|
||||||
|
print(r)
|
||||||
|
return r
|
||||||
|
|
||||||
|
return ff
|
||||||
|
|
||||||
|
|
||||||
|
@printTs
|
||||||
|
def smx(x, e, n, r=1): # this is not it cuh
|
||||||
|
return (
|
||||||
|
smx(inv(x, n), -e, n, r)
|
||||||
|
if e < 0
|
||||||
|
else r
|
||||||
|
if e == 0
|
||||||
|
else smx(x * x % n, e >> 1, n, r * x % n if e & 1 else r)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def realsmx(x, e, n):
|
||||||
|
r = x
|
||||||
|
for bro in map(int, bin(e)[3:]):
|
||||||
|
r = (r * r) % n
|
||||||
|
if bro:
|
||||||
|
r = (r * x) % n
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
@printTs
|
||||||
|
def theREALsmx(x, e, n):
|
||||||
|
"locked in"
|
||||||
|
return (
|
||||||
|
theREALsmx(inv(x, n), -e, n)
|
||||||
|
if e < 0
|
||||||
|
else x**e
|
||||||
|
if e <= 1
|
||||||
|
else theREALsmx(x, e >> 1, n) ** 2 % n
|
||||||
|
if not e & 1
|
||||||
|
else (x * theREALsmx(x, e & ~1, n)) % n
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def realest(x=None, y=None, n=None):
|
||||||
|
x = x or random.randint(-10e9, 10e9)
|
||||||
|
y = y or random.randint(-10e9, 10e9)
|
||||||
|
n = n or random.randint(2, 10e9)
|
||||||
|
# print(x, y, n)
|
||||||
|
if y < 0:
|
||||||
|
try:
|
||||||
|
p = pow(x, -1, n)
|
||||||
|
except ValueError:
|
||||||
|
p = None
|
||||||
|
else:
|
||||||
|
assert (p * x) % n == 1, f"{p = }, {(p*x)%n = }"
|
||||||
|
try:
|
||||||
|
i = inv(x, n)
|
||||||
|
except ValueError:
|
||||||
|
i = None
|
||||||
|
else:
|
||||||
|
assert (i * x) % n == 1, f"{i = }, {(i*x)%n = }"
|
||||||
|
|
||||||
|
assert i == p, f"{i = }, {p = }"
|
||||||
|
if gcd(x, n) != 1:
|
||||||
|
return # not doing ts
|
||||||
|
|
||||||
|
p = pow(x, y, n)
|
||||||
|
s = smx(x, y, n)
|
||||||
|
t = theREALsmx(x, y, n)
|
||||||
|
assert p == s == t, f"{p = }, {s = }, {t = }"
|
||||||
|
|
||||||
|
|
||||||
|
def xgcd(a, b) -> tuple[int, tuple[int, int]]:
|
||||||
|
"answer at index 0, wiki ripoff"
|
||||||
|
s, ps, r, pr = 0, 1, b, a
|
||||||
|
# shit = 0
|
||||||
|
while r != 0:
|
||||||
|
# shit += 1
|
||||||
|
# if shit > 1000:
|
||||||
|
# raise RecursionError("SHIT")
|
||||||
|
q = pr // r
|
||||||
|
pr, r = r, (pr - q * r)
|
||||||
|
ps, s = s, (ps - q * s)
|
||||||
|
bt = 0 if b == 0 else (pr - ps * a) % b
|
||||||
|
return (pr, (ps, bt))
|
||||||
|
|
||||||
|
|
||||||
|
def inv(a, n):
|
||||||
|
"also wiki ripoff"
|
||||||
|
t, nt, r, nr = 0, 1, n, a % n
|
||||||
|
# shit = 0
|
||||||
|
while nr != 0:
|
||||||
|
# shit += 1
|
||||||
|
# if shit > 1000:
|
||||||
|
# raise RecursionError("SHIT")
|
||||||
|
q = r // nr
|
||||||
|
r, nr = nr, (r - q * nr)
|
||||||
|
t, nt = nt, (t - q * nt)
|
||||||
|
# print(t, nt, r, nr)
|
||||||
|
if r > 1:
|
||||||
|
raise ValueError("base is not invertible for the given modulus")
|
||||||
|
if t < 0:
|
||||||
|
return t + n
|
||||||
|
return t
|
||||||
|
|
||||||
|
|
||||||
|
def fahhh(x, e, n):
|
||||||
|
"only works for this specific thing"
|
||||||
|
eb = f"{e:b}"
|
||||||
|
print(f"x^H mod n = {x}^{e} mod {n}")
|
||||||
|
print()
|
||||||
|
print(f"H = {e}_10 = {eb}_2")
|
||||||
|
print(
|
||||||
|
",\n".join(reversed([f"h_{i} = {ie}_2" for i, ie in enumerate(reversed(eb))]))
|
||||||
|
)
|
||||||
|
r = x
|
||||||
|
ee = 1
|
||||||
|
print()
|
||||||
|
print(f"x = x^{{{eb[0]}_2}}")
|
||||||
|
print(f"h_{len(eb)-1} = {eb[0]}")
|
||||||
|
print()
|
||||||
|
print(f"r <- {x = }")
|
||||||
|
print()
|
||||||
|
for ie, i in zip(range(len(eb) - 2, -1, -1), eb[1:]):
|
||||||
|
print(f"(x^{ee})^2 = x^{2*ee} = x^{{{2*ee:b}_2}}")
|
||||||
|
print(f"SQ, h_{ie}")
|
||||||
|
print()
|
||||||
|
ee *= 2
|
||||||
|
r *= r
|
||||||
|
print(f"r <- r*r = {r}")
|
||||||
|
print(f"r <- r mod n = {r%n}")
|
||||||
|
r %= n
|
||||||
|
print()
|
||||||
|
if int(i):
|
||||||
|
print(f"x^{ee}*x = x^{ee+1} = x^{{{ee+1:b}_2}}")
|
||||||
|
print(f"MUL, h_{ie} = 1")
|
||||||
|
print()
|
||||||
|
ee += 1
|
||||||
|
r *= x
|
||||||
|
print(f"r <- r * x = {r}")
|
||||||
|
print(f"r <- r mod n = {r%n}")
|
||||||
|
r %= n
|
||||||
|
else:
|
||||||
|
print(f"h_{ie} = 0")
|
||||||
|
print()
|
||||||
|
print(f"x^H mod n = {x}^{e} mod {n} = {r}")
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("#1:", f"{gcd(52698, 61430) = }")
|
||||||
|
E2 = {
|
||||||
|
290345,
|
||||||
|
218585,
|
||||||
|
143231,
|
||||||
|
164172,
|
||||||
|
155768,
|
||||||
|
423151,
|
||||||
|
239707,
|
||||||
|
153544,
|
||||||
|
287390,
|
||||||
|
480837,
|
||||||
|
}
|
||||||
|
print("#2:", *(f"gcd({m}, {n}) = {gcd(m,n)}" for m, n in cooked(E2)), sep="\n")
|
||||||
|
print("#3:")
|
||||||
|
fahhh(856, 25, 7)
|
||||||
|
print(f"{pow(856, 25, 7) = }")
|
||||||
|
print("#4:", f"{inv(65537, 35256) = }")
|
||||||
|
|
||||||
Reference in new issue
Block a user