Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jack4818
GitHub Repository: jack4818/Castryck-Decru-SageMath
Path: blob/main/helpers.py
323 views
1
from sage.all import parallel, GF
2
3
def possibly_parallel(num_cores):
4
if num_cores == 1:
5
def _wrap(fun):
6
def _fun(args):
7
for a in args:
8
yield ((a,), None), fun(a)
9
return _fun
10
return _wrap
11
return parallel(num_cores)
12
13
def supersingular_gens(E):
14
"""
15
Compute generators of E, assuming E is supersingular
16
with smooth order (p+1)^2 with factors 2 and 3 only.
17
This is faster than the PARI method.
18
"""
19
# Find a random point of order (p+1) (probability 1/3)
20
p = E.base_ring().characteristic()
21
while True:
22
P = E.random_point()
23
if ((p+1)//2) * P != 0 and ((p+1)//3) * P != 0:
24
break
25
26
while True:
27
Q = E.random_point()
28
if ((p+1)//2) * Q != 0 and ((p+1)//3) * Q != 0:
29
# but is it linearly independent? (probability 1/3)
30
w = P.weil_pairing(Q, p+1)
31
if w**((p+1)/2) != 1 and w**((p+1)//3) != 1:
32
return P, Q
33
34
def fast_log3(x, base):
35
"""
36
Fast discrete log when elements are known to have order
37
dividing 3^k
38
"""
39
one = x.parent().one()
40
powers = [base]
41
b = base
42
log_order = None
43
for i in range(10_000):
44
b = b**3
45
if b.is_one():
46
log_order = i+1
47
break
48
powers.append(b)
49
if not b.is_one():
50
raise Exception("impossible")
51
digits = []
52
#assert x**(3**log_order) == 1
53
#assert base**(3**(log_order-1)) != 1
54
for i in range(log_order):
55
for d in range(3):
56
if (x * powers[i]**d)**(3**(log_order-i-1)) == 1:
57
digits.append((-d) % 3)
58
if d:
59
x /= powers[i]**(3-d)
60
break
61
if x == 1:
62
break
63
#assert x == 1
64
dlog = sum(d*3**i for i, d in enumerate(digits))
65
return dlog
66
67
def test_fast_log3():
68
K = GF(70 * 3**69 + 1)
69
g = K.multiplicative_generator()
70
g = g**70
71
for _ in range(1000):
72
r = K.random_element()**70
73
dl = fast_log3(r, g)
74
assert r == g**dl
75
76
77