Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jack4818
GitHub Repository: jack4818/Castryck-Decru-SageMath
Path: blob/main/Magma-Reference/SIKEp434.m
323 views
1
/*
2
This code was downloaded from https://homes.esat.kuleuven.be/~wcastryc/ on 3 August 2022
3
*/
4
5
load "richelot_aux.m";
6
load "uvtable.m";
7
8
a := 216;
9
b := 137;
10
11
p := 2^a*3^b - 1;
12
Fp2<I> := GF(p, 2);
13
assert I^2 eq -1;
14
R<x> := PolynomialRing(Fp2);
15
16
E_start := EllipticCurve(x^3 + 6*x^2 + x);
17
18
// NAIVE GENERATION OF AUTOMORPHISM 2i
19
E1728, phi := IsogenyFromKernel(E_start, x);
20
for iota in Automorphisms(E1728) do
21
P := Random(E1728);
22
if iota(iota(P)) eq -P then
23
two_i := phi*iota*DualIsogeny(phi);
24
break;
25
end if;
26
end for;
27
28
infty := E_start ! 0;
29
30
repeat
31
P2 := 3^b*Random(E_start);
32
until 2^(a-1)*P2 ne infty;
33
repeat
34
Q2 := 3^b*Random(E_start);
35
until WeilPairing(P2, Q2, 2^a)^(2^(a-1)) ne 1;
36
37
repeat
38
P3 := 2^a*Random(E_start);
39
until 3^(b-1)*P3 ne infty;
40
repeat
41
Q3 := 2^a*Random(E_start);
42
until WeilPairing(P3, Q3, 3^b)^(3^(b-1)) ne 1;
43
44
// generate challenge key
45
46
Bobskey := Random(3^b);
47
48
EB, chain := Pushing3Chain(E_start, P3 + Bobskey*Q3, b);
49
PB := P2; for c in chain do PB := c(PB); end for;
50
QB := Q2; for c in chain do QB := c(QB); end for;
51
52
skB := []; // DIGITS IN EXPANSION OF BOB'S SECRET KEY
53
// kappas := []; // CHAIN OF ISOGENIES // is eigenlijk niet nodig, merkwaardig genoeg!
54
55
print "If all goes well then the following digits should be found", Intseq(Bobskey, 3);
56
57
tim := Cputime();
58
59
skB := []; // TERNARY DIGITS IN EXPANSION OF BOB'S SECRET KEY
60
61
// gathering the alpha_i, u, v from table
62
63
expdata := [[0, 0, 0] : i in [1..b-3]];
64
for i in [1..b-3] do
65
if IsOdd(b-i) then
66
index := (b - i + 1) div 2;
67
exp := uvtable[index][2];
68
if exp le a then
69
u := uvtable[index][3];
70
v := uvtable[index][4];
71
expdata[i] := [exp, u, v];
72
end if;
73
end if;
74
end for;
75
76
// gather digits until beta_1
77
78
bet1 := 0;
79
repeat
80
bet1 +:= 1;
81
until expdata[bet1][1] ne 0;
82
83
ai := expdata[bet1][1];
84
u := expdata[bet1][2];
85
v := expdata[bet1][3];
86
87
print "Determination of first", bet1, "ternary digits. We are working with 2^"*IntegerToString(ai)*"-torsion.";
88
89
bi := b - bet1;
90
alp := a - ai;
91
92
for j in CartesianPower([0,1,2], bet1) do
93
print "Testing digits", &*[IntegerToString(j[k])*" " : k in [1..bet1]];
94
tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*j[k] : k in [1..bet1]])*3^bi*Q3;
95
tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);
96
C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, bet1);
97
P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;
98
Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;
99
if j eq <2 : k in [1..bet1]> or Does22ChainSplit(C, EB, 2^alp*P_c, 2^alp*Q_c, 2^alp*PB, 2^alp*QB, ai) then
100
print "Glue-and-split! These are most likely the secret digits.";
101
skB cat:= [j[k] : k in [1..bet1]];
102
break;
103
end if;
104
end for;
105
106
// now compute longest prolongation of Bob's isogeny that may be needed
107
108
length := 1;
109
max_length := 0;
110
for i in [bet1+1..b-3] do
111
if expdata[i][1] ne 0 then
112
max_length := Max(length, max_length);
113
length := 0;
114
else
115
length +:= 1;
116
end if;
117
end for;
118
119
repeat
120
K := 2^a*3^(b - max_length)*Random(EB);
121
until Order(K) eq 3^max_length;
122
123
repeat
124
alternativeK := 2^a*3^(b - max_length)*Random(EB);
125
until WeilPairing(K, alternativeK, 3^max_length)^(3^(max_length - 1)) ne 1;
126
127
_, EBprolong := Pushing3Chain(EB, K, max_length);
128
129
// gather next digit and change prolongation if needed
130
131
i := bet1 + 1;
132
bi := b - i;
133
134
print "Determination of the "*IntegerToString(i)*"th ternary digit. We are working with 2^"*IntegerToString(ai)*"-torsion.";
135
prolong := 1;
136
print "Prolonging with 1 steps.";
137
endPB := EBprolong[1](PB);
138
endQB := EBprolong[1](QB);
139
endEB := Codomain(EBprolong[1]);
140
141
positives := [];
142
143
for j in [0..2] do
144
print "Testing digit", j;
145
tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*skB[k] : k in [1..i-1]] + 3^(i-1)*j)*3^bi*Q3;
146
tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);
147
C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, i);
148
P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;
149
Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;
150
if Does22ChainSplit(C, endEB, 2^alp*P_c, 2^alp*Q_c, 2^alp*endPB, 2^alp*endQB, ai) then
151
print "Glue-and-split!";
152
positives cat:=[j];
153
if #positives gt 1 then
154
break;
155
end if;
156
end if;
157
end for;
158
159
if #positives eq 1 then
160
print "Most likely good prolongation and the secret digit is", positives[1];
161
skB cat:= [positives[1]];
162
next_i := i + 1;
163
else
164
print "All glue-and-splits, must be bad prolongation: changing it and redoing this digit.";
165
_, EBprolong := Pushing3Chain(EB, alternativeK, max_length);
166
next_i := i;
167
prolong := 0;
168
end if;
169
170
// now gather all remaining digits, except for last three
171
172
for i in [next_i..b-3] do
173
bi := b - i;
174
if expdata[i][1] ne 0 then
175
ai := expdata[i][1];
176
alp := a - ai;
177
u := expdata[i][2];
178
v := expdata[i][3];
179
prolong := 0;
180
else
181
prolong +:= 1;
182
end if;
183
print "Determination of the "*IntegerToString(i)*"th ternary digit. We are working with 2^"*IntegerToString(ai)*"-torsion.";
184
185
endPB := PB;
186
endQB := QB;
187
endEB := EB;
188
for j in [1..prolong] do
189
endPB := EBprolong[j](endPB);
190
endQB := EBprolong[j](endQB);
191
if j eq prolong then
192
endEB := Codomain(EBprolong[j]);
193
end if;
194
end for;
195
196
for j in [0..2] do
197
print "Testing digit", j;
198
tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*skB[k] : k in [1..i-1]] + 3^(i-1)*j)*3^bi*Q3;
199
tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);
200
C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, i);
201
P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;
202
Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;
203
if j eq 2 or Does22ChainSplit(C, endEB, 2^alp*P_c, 2^alp*Q_c, 2^alp*endPB, 2^alp*endQB, ai) then
204
print "Glue-and-split! This is most likely the secret digit.";
205
skB cat:= [j];
206
break;
207
end if;
208
end for;
209
210
end for;
211
212
213
key := &+[skB[i]*3^(i-1) : i in [1..b-3]];
214
215
// bridge last safety gap
216
217
tim2 := Cputime();
218
219
found := false;
220
for i in [0..3^3] do
221
bobskey := key + i*3^(b-3);
222
bobscurve := Pushing3Chain(E_start, P3 + bobskey*Q3, b);
223
if jInvariant(bobscurve) eq jInvariant(EB) then
224
found := true;
225
break;
226
end if;
227
end for;
228
229
print "Bridging last gap took", Cputime(tim2);
230
231
if found then
232
print "Bob's secret key revealed as", bobskey;
233
else
234
print "Something went wrong.";
235
end if;
236
237
print "Altogether this took", Cputime(tim), "seconds.";
238
239