Path: blob/main/Magma-Reference/SIKEp434.m
323 views
/*1This code was downloaded from https://homes.esat.kuleuven.be/~wcastryc/ on 3 August 20222*/34load "richelot_aux.m";5load "uvtable.m";67a := 216;8b := 137;910p := 2^a*3^b - 1;11Fp2<I> := GF(p, 2);12assert I^2 eq -1;13R<x> := PolynomialRing(Fp2);1415E_start := EllipticCurve(x^3 + 6*x^2 + x);1617// NAIVE GENERATION OF AUTOMORPHISM 2i18E1728, phi := IsogenyFromKernel(E_start, x);19for iota in Automorphisms(E1728) do20P := Random(E1728);21if iota(iota(P)) eq -P then22two_i := phi*iota*DualIsogeny(phi);23break;24end if;25end for;2627infty := E_start ! 0;2829repeat30P2 := 3^b*Random(E_start);31until 2^(a-1)*P2 ne infty;32repeat33Q2 := 3^b*Random(E_start);34until WeilPairing(P2, Q2, 2^a)^(2^(a-1)) ne 1;3536repeat37P3 := 2^a*Random(E_start);38until 3^(b-1)*P3 ne infty;39repeat40Q3 := 2^a*Random(E_start);41until WeilPairing(P3, Q3, 3^b)^(3^(b-1)) ne 1;4243// generate challenge key4445Bobskey := Random(3^b);4647EB, chain := Pushing3Chain(E_start, P3 + Bobskey*Q3, b);48PB := P2; for c in chain do PB := c(PB); end for;49QB := Q2; for c in chain do QB := c(QB); end for;5051skB := []; // DIGITS IN EXPANSION OF BOB'S SECRET KEY52// kappas := []; // CHAIN OF ISOGENIES // is eigenlijk niet nodig, merkwaardig genoeg!5354print "If all goes well then the following digits should be found", Intseq(Bobskey, 3);5556tim := Cputime();5758skB := []; // TERNARY DIGITS IN EXPANSION OF BOB'S SECRET KEY5960// gathering the alpha_i, u, v from table6162expdata := [[0, 0, 0] : i in [1..b-3]];63for i in [1..b-3] do64if IsOdd(b-i) then65index := (b - i + 1) div 2;66exp := uvtable[index][2];67if exp le a then68u := uvtable[index][3];69v := uvtable[index][4];70expdata[i] := [exp, u, v];71end if;72end if;73end for;7475// gather digits until beta_17677bet1 := 0;78repeat79bet1 +:= 1;80until expdata[bet1][1] ne 0;8182ai := expdata[bet1][1];83u := expdata[bet1][2];84v := expdata[bet1][3];8586print "Determination of first", bet1, "ternary digits. We are working with 2^"*IntegerToString(ai)*"-torsion.";8788bi := b - bet1;89alp := a - ai;9091for j in CartesianPower([0,1,2], bet1) do92print "Testing digits", &*[IntegerToString(j[k])*" " : k in [1..bet1]];93tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*j[k] : k in [1..bet1]])*3^bi*Q3;94tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);95C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, bet1);96P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;97Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;98if 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) then99print "Glue-and-split! These are most likely the secret digits.";100skB cat:= [j[k] : k in [1..bet1]];101break;102end if;103end for;104105// now compute longest prolongation of Bob's isogeny that may be needed106107length := 1;108max_length := 0;109for i in [bet1+1..b-3] do110if expdata[i][1] ne 0 then111max_length := Max(length, max_length);112length := 0;113else114length +:= 1;115end if;116end for;117118repeat119K := 2^a*3^(b - max_length)*Random(EB);120until Order(K) eq 3^max_length;121122repeat123alternativeK := 2^a*3^(b - max_length)*Random(EB);124until WeilPairing(K, alternativeK, 3^max_length)^(3^(max_length - 1)) ne 1;125126_, EBprolong := Pushing3Chain(EB, K, max_length);127128// gather next digit and change prolongation if needed129130i := bet1 + 1;131bi := b - i;132133print "Determination of the "*IntegerToString(i)*"th ternary digit. We are working with 2^"*IntegerToString(ai)*"-torsion.";134prolong := 1;135print "Prolonging with 1 steps.";136endPB := EBprolong[1](PB);137endQB := EBprolong[1](QB);138endEB := Codomain(EBprolong[1]);139140positives := [];141142for j in [0..2] do143print "Testing digit", j;144tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*skB[k] : k in [1..i-1]] + 3^(i-1)*j)*3^bi*Q3;145tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);146C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, i);147P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;148Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;149if Does22ChainSplit(C, endEB, 2^alp*P_c, 2^alp*Q_c, 2^alp*endPB, 2^alp*endQB, ai) then150print "Glue-and-split!";151positives cat:=[j];152if #positives gt 1 then153break;154end if;155end if;156end for;157158if #positives eq 1 then159print "Most likely good prolongation and the secret digit is", positives[1];160skB cat:= [positives[1]];161next_i := i + 1;162else163print "All glue-and-splits, must be bad prolongation: changing it and redoing this digit.";164_, EBprolong := Pushing3Chain(EB, alternativeK, max_length);165next_i := i;166prolong := 0;167end if;168169// now gather all remaining digits, except for last three170171for i in [next_i..b-3] do172bi := b - i;173if expdata[i][1] ne 0 then174ai := expdata[i][1];175alp := a - ai;176u := expdata[i][2];177v := expdata[i][3];178prolong := 0;179else180prolong +:= 1;181end if;182print "Determination of the "*IntegerToString(i)*"th ternary digit. We are working with 2^"*IntegerToString(ai)*"-torsion.";183184endPB := PB;185endQB := QB;186endEB := EB;187for j in [1..prolong] do188endPB := EBprolong[j](endPB);189endQB := EBprolong[j](endQB);190if j eq prolong then191endEB := Codomain(EBprolong[j]);192end if;193end for;194195for j in [0..2] do196print "Testing digit", j;197tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*skB[k] : k in [1..i-1]] + 3^(i-1)*j)*3^bi*Q3;198tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);199C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, i);200P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;201Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;202if j eq 2 or Does22ChainSplit(C, endEB, 2^alp*P_c, 2^alp*Q_c, 2^alp*endPB, 2^alp*endQB, ai) then203print "Glue-and-split! This is most likely the secret digit.";204skB cat:= [j];205break;206end if;207end for;208209end for;210211212key := &+[skB[i]*3^(i-1) : i in [1..b-3]];213214// bridge last safety gap215216tim2 := Cputime();217218found := false;219for i in [0..3^3] do220bobskey := key + i*3^(b-3);221bobscurve := Pushing3Chain(E_start, P3 + bobskey*Q3, b);222if jInvariant(bobscurve) eq jInvariant(EB) then223found := true;224break;225end if;226end for;227228print "Bridging last gap took", Cputime(tim2);229230if found then231print "Bob's secret key revealed as", bobskey;232else233print "Something went wrong.";234end if;235236print "Altogether this took", Cputime(tim), "seconds.";237238239