make elliptic curves available to solver.py
This commit is contained in:
78
data/seq_moebius.txt
Normal file
78
data/seq_moebius.txt
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
1
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
-1
|
||||||
|
-1
|
||||||
|
0
|
||||||
|
-1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
-1
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
0
|
0
|
||||||
|
1
|
||||||
4
|
4
|
||||||
6
|
6
|
||||||
8
|
8
|
||||||
|
|||||||
46
lib.py
46
lib.py
@@ -7,6 +7,8 @@ import math
|
|||||||
def is_prime(num):
|
def is_prime(num):
|
||||||
if isinstance(num, str):
|
if isinstance(num, str):
|
||||||
num = int(num)
|
num = int(num)
|
||||||
|
if num in [2, 3, 5]:
|
||||||
|
return True
|
||||||
if num & 1 and num % 5 > 0:
|
if num & 1 and num % 5 > 0:
|
||||||
for i in range(2, math.floor(math.sqrt(num)) + 1):
|
for i in range(2, math.floor(math.sqrt(num)) + 1):
|
||||||
if i & 1 and (num % i) == 0:
|
if i & 1 and (num % i) == 0:
|
||||||
@@ -24,3 +26,47 @@ def rev(num): # or int(str(num)[::-1])
|
|||||||
revs = (revs * 10) + remainder
|
revs = (revs * 10) + remainder
|
||||||
num = num // 10
|
num = num // 10
|
||||||
return revs
|
return revs
|
||||||
|
|
||||||
|
|
||||||
|
def power(x, y, p):
|
||||||
|
res = 1
|
||||||
|
x %= p
|
||||||
|
while (y > 0):
|
||||||
|
if (y & 1):
|
||||||
|
res = (res * x) % p
|
||||||
|
y = y >> 1
|
||||||
|
x = (x * x) % p
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def sqrtNormal(n, p):
|
||||||
|
n %= p
|
||||||
|
for x in range(2, p):
|
||||||
|
if ((x * x) % p == n):
|
||||||
|
return x
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
# Assumption: p is of the form 3*i + 4 where i >= 1
|
||||||
|
def sqrtFast(n, p):
|
||||||
|
if (p % 4 != 3):
|
||||||
|
# raise ValueError('Invalid Input')
|
||||||
|
return sqrtNormal(n, p)
|
||||||
|
# Try "+(n ^ ((p + 1)/4))"
|
||||||
|
n = n % p
|
||||||
|
x = power(n, (p + 1) // 4, p)
|
||||||
|
if ((x * x) % p == n):
|
||||||
|
return x
|
||||||
|
# Try "-(n ^ ((p + 1)/4))"
|
||||||
|
x = p - x
|
||||||
|
if ((x * x) % p == n):
|
||||||
|
return x
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def elliptic_curve(x, a, b, r):
|
||||||
|
y2 = (x ** 3 + a * x + b) % r
|
||||||
|
y = sqrtFast(y2, r) if y2 > 0 else 0
|
||||||
|
if y is None:
|
||||||
|
return None, None
|
||||||
|
return y, -y % r
|
||||||
|
|||||||
@@ -1,79 +1,74 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
if True:
|
||||||
|
sys.path.append('..')
|
||||||
|
import lib as LIB
|
||||||
try:
|
try:
|
||||||
from PIL import Image, ImageDraw
|
from PIL import Image, ImageDraw
|
||||||
IMG_OUT = True
|
IMG_OUT = True
|
||||||
except ModuleNotFoundError:
|
except ModuleNotFoundError:
|
||||||
IMG_OUT = False
|
IMG_OUT = False
|
||||||
|
|
||||||
|
ALL_OF_THEM = []
|
||||||
def power(x, y, p):
|
OFFSET = 0
|
||||||
res = 1
|
SEPERATORS = []
|
||||||
x %= p
|
PRIMES_RED = False
|
||||||
while (y > 0):
|
|
||||||
if (y & 1):
|
|
||||||
res = (res * x) % p
|
|
||||||
y = y >> 1
|
|
||||||
x = (x * x) % p
|
|
||||||
return res
|
|
||||||
|
|
||||||
|
|
||||||
# Assumption: p is of the form 3*i + 4 where i >= 1
|
def write_image(dots, name, h, sz=0, width=None):
|
||||||
def sqrtFast(n, p):
|
if width is None:
|
||||||
if (p % 4 != 3):
|
width = h
|
||||||
raise ValueError('Invalid Input')
|
image = Image.new('RGB', (width, h))
|
||||||
# Try "+(n ^ ((p + 1)/4))"
|
draw = ImageDraw.Draw(image)
|
||||||
n = n % p
|
draw.rectangle((0, 0, width, h), fill='white')
|
||||||
x = power(n, (p + 1) // 4, p)
|
for x, p1, p2, pr in dots:
|
||||||
if ((x * x) % p == n):
|
z1 = h - 1 - p1
|
||||||
return x
|
z2 = h - 1 - p2
|
||||||
# Try "-(n ^ ((p + 1)/4))"
|
color = 'red' if PRIMES_RED and pr else 'black'
|
||||||
x = p - x
|
draw.rectangle((x - sz, z1 - sz, x + sz, z1 + sz), fill=color)
|
||||||
if ((x * x) % p == n):
|
draw.rectangle((x - sz, z2 - sz, x + sz, z2 + sz), fill=color)
|
||||||
return x
|
for x in SEPERATORS:
|
||||||
return None
|
draw.rectangle((x, 0, x + 1, h), fill='gray')
|
||||||
|
image.save(name, 'PNG')
|
||||||
|
|
||||||
|
|
||||||
def sqrtNormal(n, p):
|
def draw_curve(a, b, r):
|
||||||
n %= p
|
global ALL_OF_THEM, OFFSET, SEPERATORS
|
||||||
for x in range(2, p):
|
# print(f'generate curve: a={a}, b={b}, r={r}')
|
||||||
if ((x * x) % p == n):
|
img_dots = []
|
||||||
return x
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def elliptic_curve(a, b, r):
|
|
||||||
print(f'generate curve: a={a}, b={b}, r={r}')
|
|
||||||
if IMG_OUT:
|
|
||||||
image1 = Image.new('RGB', (r, r))
|
|
||||||
draw1 = ImageDraw.Draw(image1)
|
|
||||||
draw1.rectangle((0, 0, r, r), fill='white')
|
|
||||||
image2 = Image.new('RGB', (r, r))
|
|
||||||
draw2 = ImageDraw.Draw(image2)
|
|
||||||
draw2.rectangle((0, 0, r, r), fill='white')
|
|
||||||
|
|
||||||
sqrtFn = sqrtNormal if (r % 4 != 3) else sqrtFast
|
|
||||||
txt = ''
|
txt = ''
|
||||||
for x in range(r):
|
for x in range(r):
|
||||||
y2 = (x ** 3 + a * x + b) % r
|
p1, p2 = LIB.elliptic_curve(x, a, b, r)
|
||||||
u2 = sqrtFn(y2, r) if y2 > 0 else 0
|
if p1 is not None:
|
||||||
if u2 is not None:
|
# print(x, p1, p2)
|
||||||
z1 = r - 1 - u2
|
txt += f'{x} {p1} {p2}\n'
|
||||||
z2 = r - 1 - (-u2 % r)
|
# img_dots.append((x + OFFSET, p1, p2, LIB.is_prime(x)))
|
||||||
print(x, y2, -y2 % r)
|
if LIB.is_prime(x):
|
||||||
txt += f'{x} {y2} {-y2 % r}\n'
|
img_dots.append((x + OFFSET, p1, p2, True))
|
||||||
if IMG_OUT:
|
|
||||||
draw1.rectangle((x, z1, x, z1), fill='black')
|
|
||||||
draw1.rectangle((x, z2, x, z2), fill='black')
|
|
||||||
draw2.rectangle((x - 2, z1 - 2, x + 2, z1 + 2), fill='black')
|
|
||||||
draw2.rectangle((x - 2, z2 - 2, x + 2, z2 + 2), fill='black')
|
|
||||||
|
|
||||||
with open(f'ec-a{a}-b{b}-r{r}.txt', 'w') as f:
|
# with open(f'ec-a{a}-b{b}-r{r}.txt', 'w') as f:
|
||||||
f.write(txt)
|
# f.write(txt)
|
||||||
if IMG_OUT:
|
|
||||||
print('writing image output')
|
ALL_OF_THEM.append(((a, b, r), img_dots))
|
||||||
image1.save(f'ec-a{a}-b{b}-r{r}-pp.png', 'PNG')
|
OFFSET += len(img_dots) + 10
|
||||||
image2.save(f'ec-a{a}-b{b}-r{r}-lg.png', 'PNG')
|
SEPERATORS.append(OFFSET - 6)
|
||||||
print()
|
# if IMG_OUT:
|
||||||
|
# print(f'writing image output (a={a}, b={b}, r={r})')
|
||||||
|
# write_image(img_dots, f'ec-a{a}-b{b}-r{r}-pp.png', r)
|
||||||
|
# write_image(img_dots, f'ec-a{a}-b{b}-r{r}-lg.png', r, sz=2)
|
||||||
|
# print()
|
||||||
|
|
||||||
|
|
||||||
elliptic_curve(a=149, b=263, r=3299)
|
r = 3299
|
||||||
|
t = [2, 3, 5, 7, 13, 23, 43, 79, 149, 263, 463, 829, 1481, 2593]
|
||||||
|
# t = [2, 3]
|
||||||
|
for x in t:
|
||||||
|
ALL_OF_THEM = []
|
||||||
|
SEPERATORS = []
|
||||||
|
OFFSET = 0
|
||||||
|
for y in t:
|
||||||
|
draw_curve(a=x, b=y, r=r)
|
||||||
|
|
||||||
|
print(f'writing image output ({x}@{t[0]}-{t[-1]} r={r}) {OFFSET}x{r}')
|
||||||
|
just_all = [z for x, y in ALL_OF_THEM for z in y]
|
||||||
|
write_image(just_all, f'ec-{x}-r{r}.png', r, sz=3, width=OFFSET)
|
||||||
|
|||||||
15
solver.py
15
solver.py
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
from RuneSolver import VigenereSolver, SequenceSolver
|
from RuneSolver import VigenereSolver, SequenceSolver
|
||||||
from RuneText import Rune, RuneText
|
from RuneText import Rune, RuneText
|
||||||
|
from lib import elliptic_curve
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ PRIMES_3301 = load_sequence_file('data/seq_primes_3301.txt')
|
|||||||
NOT_PRIMES = load_sequence_file('data/seq_not_primes.txt')
|
NOT_PRIMES = load_sequence_file('data/seq_not_primes.txt')
|
||||||
FIBONACCI = load_sequence_file('data/seq_fibonacci.txt')
|
FIBONACCI = load_sequence_file('data/seq_fibonacci.txt')
|
||||||
LUCAS = load_sequence_file('data/seq_lucas_numbers.txt')
|
LUCAS = load_sequence_file('data/seq_lucas_numbers.txt')
|
||||||
|
MOEBIUS = load_sequence_file('data/seq_moebius.txt')
|
||||||
|
|
||||||
|
|
||||||
def print_all_solved():
|
def print_all_solved():
|
||||||
@@ -77,17 +79,23 @@ def try_totient_on_unsolved():
|
|||||||
slvr = SequenceSolver()
|
slvr = SequenceSolver()
|
||||||
slvr.output.QUIET = True
|
slvr.output.QUIET = True
|
||||||
slvr.output.BREAK_MODE = '' # disable line breaks
|
slvr.output.BREAK_MODE = '' # disable line breaks
|
||||||
# for uuu in ['54-55']:
|
# for uuu in ['15-22']:
|
||||||
for uuu in ['0-2', '3-7', '8-14', '15-22', '23-26', '27-32', '33-39', '40-53', '54-55']:
|
for uuu in ['0-2', '3-7', '8-14', '15-22', '23-26', '27-32', '33-39', '40-53', '54-55']:
|
||||||
print()
|
print()
|
||||||
print(uuu)
|
print(uuu)
|
||||||
with open(f'pages/p{uuu}.txt', 'r') as f:
|
with open(f'pages/p{uuu}.txt', 'r') as f:
|
||||||
slvr.input.load(RuneText(f.read()[:110]))
|
slvr.input.load(RuneText(f.read()[:15]))
|
||||||
# alldata = slvr.input.runes_no_whitespace() + [Rune(i=29)]
|
# alldata = slvr.input.runes_no_whitespace() + [Rune(i=29)]
|
||||||
|
|
||||||
def b60(x):
|
def b60(x):
|
||||||
v = x % 60
|
v = x % 60
|
||||||
return v if v < 29 else 60 - v
|
return v if v < 29 else 60 - v
|
||||||
|
|
||||||
|
def ec(r, i):
|
||||||
|
p1, p2 = elliptic_curve(i, 149, 263, 3299)
|
||||||
|
if p1 is None:
|
||||||
|
return r.index
|
||||||
|
return r.index + p1 % 29
|
||||||
# for p in PRIMES[:500]:
|
# for p in PRIMES[:500]:
|
||||||
# print(p)
|
# print(p)
|
||||||
# for z in range(29):
|
# for z in range(29):
|
||||||
@@ -103,7 +111,8 @@ def try_totient_on_unsolved():
|
|||||||
# slvr.FN = lambda i, r: Rune(i=b60(r.prime) + z % 29)
|
# slvr.FN = lambda i, r: Rune(i=b60(r.prime) + z % 29)
|
||||||
# slvr.FN = lambda i, r: Rune(i=((r.prime + alldata[i + 1].prime) + z) % 60 // 2)
|
# slvr.FN = lambda i, r: Rune(i=((r.prime + alldata[i + 1].prime) + z) % 60 // 2)
|
||||||
# slvr.FN = lambda i, r: Rune(i=(3301 * r.index + z) % 29)
|
# slvr.FN = lambda i, r: Rune(i=(3301 * r.index + z) % 29)
|
||||||
slvr.FN = lambda i, r: Rune(i=(67 * r.index + z) % 29)
|
slvr.FN = lambda i, r: Rune(i=(ec(r, i) + z) % 29)
|
||||||
|
# slvr.FN = lambda i, r: Rune(i=(r.prime - PRIMES[FIBONACCI[i]] + z) % 29)
|
||||||
# slvr.FN = lambda i, r: Rune(i=(r.prime ** i + z) % 29)
|
# slvr.FN = lambda i, r: Rune(i=(r.prime ** i + z) % 29)
|
||||||
slvr.run()
|
slvr.run()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user