Path: blob/main/Magma-Reference/SIKE_challenge.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 := 110;8b := 67;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;2627xQ2 := 86445170414599058485968715662346922796016566052081315743781191908 + I*40452781127453632342062231901634407992350274206219311799642330230;28yQ2 := 65598021239445364766945421641383356785387864046503211101901536990 + I*4185188043442820950612067662642469583838730096408235972690714750;29Q2 := E_start ! [xQ2, yQ2];3031xP2 := 37927755131506746411537091732732279589710442710570639382902295344 + I*37017495259074475516858568039563512752905548684528955375066616976;32yP2 := 47930070613074499206421889519713097155043539387599009924307417901 + I*7176302698603683442486948733484190513242470057553561741081582098;33P2 := E_start ! [xP2, yP2];3435// CONSISTENCY WITH R (NOT NEEDED BUT OK)36// xR2 := 46724562430016373759602265681716628459894400021233033976074511127 + I*62869247191516167619032311426583862201277153531817575978673280654;37// (P2 - Q2)[1] eq xR2;3839xQ3 := 47793138785202808493310870472269548499693686682045542672866243781;40yQ3 := I*59233392251697228025115695338640088714243311845504632846426147327;41Q3 := E_start ! [xQ3, yQ3];4243xP3 := 92537981321677359984282752681526321709848257167914581295182029482;44yP3 := 64890706732687703644418730466418873818100958793359354306462487533;45P3 := E_start ! [xP3, yP3];4647// CONSISTENCY WITH R (NOT NEEDED BUT OK)48// xRB := 100985822528123790926639173045977043567721100360555352880158477546 + I*53651151307208479216007649001480928514654306829312202244997088803;49// (PB - QB)[1] eq xRB;5051// ALICE'S PUBLIC KEY:5253xPA := 78851325149093883127710876413676714831509071567295995722742563459 + I*21481241277029422048465721240261620296276964367410557936597294375;54xQA := 109443172641179151776707590487317622581952970379528972130069645642 + I*3867221956981918915643365445875236474767408154492041549977730573;55xRA := 24146826348939386714009375843953121070061474437444339669850030464 + I*9794094030587590044286487045494277248551007280921263840310791516;5657A := (1 - xPA*xQA - xPA*xRA - xQA*xRA)^2/(4*xPA*xQA*xRA) - xPA - xQA - xRA;5859yPA := Sqrt(xPA^3 + A*xPA^2 + xPA);60yQA := Sqrt(xQA^3 + A*xQA^2 + xQA);6162if xRA + xQA + xPA + A ne (yQA + yPA)^2 / (xQA - xPA)^2 then yQA := -yQA; end if; // SMALL ERROR IN SIDH-spec.pdf, CORRECTED HERE6364// let's check:6566EA := EllipticCurve(x^3 + A*x^2 + x);67PA := EA ! [xPA, yPA];68QA := EA ! [xQA, yQA];6970// BOB'S PUBLIC KEY:7172xPB := 52037618715847826453371077000320105687598036562145407135988121710 + I*62945436285055860346151337655131657491042243534644871894809196747;73xQB := 94057161062674597281795314311864564004565620907834550169224722966 + I*91420731496759657779126063859508682663377955903334296321639551249;74xRB := 43790287819500432145214110821932450371863522319238208485657321972 + I*98694640376206066779482191725776091085259044935342665789389325446;7576B := (1 - xPB*xQB - xPB*xRB - xQB*xRB)^2/(4*xPB*xQB*xRB) - xPB - xQB - xRB;7778yPB := Sqrt(xPB^3 + B*xPB^2 + xPB);79yQB := Sqrt(xQB^3 + B*xQB^2 + xQB);8081if xRB + xQB + xPB + B ne (yQB + yPB)^2 / (xQB - xPB)^2 then yQB := -yQB; end if; // SMALL ERROR IN SIDH-spec.pdf, CORRECTED HERE8283// let's check:8485EB := EllipticCurve(x^3 + B*x^2 + x);86PB := EB ! [xPB, yPB];87QB := EB ! [xQB, yQB];8889// ===================================90// ===== ATTACK ====================91// ===================================9293tim := Cputime();9495skB := []; // TERNARY DIGITS IN EXPANSION OF BOB'S SECRET KEY9697// gathering the alpha_i, u, v from table9899expdata := [[0, 0, 0] : i in [1..b-3]];100for i in [1..b-3] do101if IsOdd(b-i) then102index := (b - i + 1) div 2;103exp := uvtable[index][2];104if exp le a then105u := uvtable[index][3];106v := uvtable[index][4];107expdata[i] := [exp, u, v];108end if;109end if;110end for;111112// gather digits until beta_1113114bet1 := 0;115repeat116bet1 +:= 1;117until expdata[bet1][1] ne 0;118119ai := expdata[bet1][1];120u := expdata[bet1][2];121v := expdata[bet1][3];122123print "Determination of first", bet1, "ternary digits. We are working with 2^"*IntegerToString(ai)*"-torsion.";124125bi := b - bet1;126alp := a - ai;127128for j in CartesianPower([0,1,2], bet1) do129print "Testing digits", &*[IntegerToString(j[k])*" " : k in [1..bet1]];130tauhatkernel := 3^bi*P3 + (j[1] + 3*j[2])*3^bi*Q3;131tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);132C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, bet1);133P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;134Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;135if 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) then136print "Glue-and-split! These are most likely the secret digits.";137skB cat:= [j[k] : k in [1..bet1]];138break;139end if;140end for;141142// now compute longest prolongation of Bob's isogeny that may be needed143144length := 1;145max_length := 0;146for i in [bet1+1..b-3] do147if expdata[i][1] ne 0 then148max_length := Max(length, max_length);149length := 0;150else151length +:= 1;152end if;153end for;154155repeat156K := 2^a*3^(b - max_length)*Random(EB);157until Order(K) eq 3^max_length;158159repeat160alternativeK := 2^a*3^(b - max_length)*Random(EB);161until WeilPairing(K, alternativeK, 3^max_length)^(3^(max_length - 1)) ne 1;162163_, EBprolong := Pushing3Chain(EB, K, max_length);164165// gather next digit and change prolongation if needed166167i := bet1 + 1;168bi := b - i;169170print "Determination of the "*IntegerToString(i)*"th ternary digit. We are working with 2^"*IntegerToString(ai)*"-torsion.";171prolong := 1;172print "Prolonging with 1 steps.";173endPB := EBprolong[1](PB);174endQB := EBprolong[1](QB);175endEB := Codomain(EBprolong[1]);176177positives := [];178179for j in [0..2] do180print "Testing digit", j;181tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*skB[k] : k in [1..i-1]] + 3^(i-1)*j)*3^bi*Q3;182tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);183C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, i);184P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;185Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;186if Does22ChainSplit(C, endEB, 2^alp*P_c, 2^alp*Q_c, 2^alp*endPB, 2^alp*endQB, ai) then187print "Glue-and-split!";188positives cat:=[j];189if #positives gt 1 then190break;191end if;192end if;193end for;194195if #positives eq 1 then196print "Most likely good prolongation and the secret digit is", positives[1];197skB cat:= [positives[1]];198next_i := i + 1;199else200print "All glue-and-splits, must be bad prolongation: changing it and redoing this digit.";201_, EBprolong := Pushing3Chain(EB, alternativeK, max_length);202next_i := i;203prolong := 0;204end if;205206// now gather all remaining digits, except for last three (we close that gap by trial and error)207208for i in [next_i..b-3] do209bi := b - i;210if expdata[i][1] ne 0 then211ai := expdata[i][1];212alp := a - ai;213u := expdata[i][2];214v := expdata[i][3];215prolong := 0;216else217prolong +:= 1;218end if;219print "Determination of the "*IntegerToString(i)*"th ternary digit. We are working with 2^"*IntegerToString(ai)*"-torsion.";220print "Prolonging with", prolong, "steps.";221endPB := PB;222endQB := QB;223endEB := EB;224for j in [1..prolong] do225endPB := EBprolong[j](endPB);226endQB := EBprolong[j](endQB);227if j eq prolong then228endEB := Codomain(EBprolong[j]);229end if;230end for;231232for j in [0..2] do233print "Testing digit", j;234tauhatkernel := 3^bi*P3 + (&+[3^(k-1)*skB[k] : k in [1..i-1]] + 3^(i-1)*j)*3^bi*Q3;235tauhatkernel_distort := u*tauhatkernel + v*two_i(tauhatkernel);236C, tau_tilde := Pushing3Chain(E_start, tauhatkernel_distort, i);237P_c := u*P2 + v*two_i(P2); for taut in tau_tilde do P_c := taut(P_c); end for;238Q_c := u*Q2 + v*two_i(Q2); for taut in tau_tilde do Q_c := taut(Q_c); end for;239if j eq 2 or Does22ChainSplit(C, endEB, 2^alp*P_c, 2^alp*Q_c, 2^alp*endPB, 2^alp*endQB, ai) then240print "Glue-and-split! This is most likely the secret digit.";241skB cat:= [j];242break;243end if;244end for;245246end for;247248249key := &+[skB[i]*3^(i-1) : i in [1..b-3]];250251// bridge last safety gap252253tim2 := Cputime();254255found := false;256for i in [0..3^5] do257bobskey := key + i*3^(b-3);258bobscurve := Pushing3Chain(E_start, P3 + bobskey*Q3, b);259if jInvariant(bobscurve) eq jInvariant(EB) then260found := true;261break;262end if;263end for;264265print "Bridging last gap took", Cputime(tim2);266267if found then268print "Bob's secret key revealed as", bobskey;269else270print "Something went wrong.";271end if;272273print "Altogether this took", Cputime(tim), "seconds.";274275276