1 2 3 4 5 6 7 8 9 title: 双线性配对补充及陇剑杯rsa.io复现 date: 2025-9 -11 12:00:00tags: - crypto - 复现 - 区块链 categories: crypto banner_img: /img/xulun.jpg banner_img_height: 150px
双线性配对补充+陇剑杯-rsa.io复现 双线性配对
双线性配对在最初的学习密码学的时候已经接触过,不过当时不是很能理解一些东西,现在重新写一下顺便进行总结。
双线性映射
线性映射
这里做简单的解释:线性映射
给定域$F$ 上的线性空间$V$和$U$。如果有映射$f:V->U$满足: 对于任意向量$v_1,v_2∈V,标量c_1,c_2∈F$都有
$f(c_1v_1+c_2v_2)=c_1f(x_1)+c_2f(x_2)$
则称作$f$是V到U的一个线性映射$(linear .~mp)$ 也叫做线性变换
上述满足的条件也可以叫做加性与齐加性
$f(u+v)=f(u+v)$ $f(cu)=c[f(u)]$
双线性映射:
双线性性意味着
对于给定域$k$的向量空间 ,$X,Y,Z$ 或者交换环的模$X,Y,Z$,有
$f:X\times Y\longrightarrow Z$ 这样的映射
$f$是双线性映射,指$f$关于x,y都是线性的。也就是说,若固定$y∈Y,x∈X$
则映射$f(x,y)$ 是$X$到Z的线性映射。固定X同理
weil配对
陇剑杯-rsa.iso 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 from Crypto.Util.number import *from secret import flag f = open ("output.txt" , "w" )def get_Prime (bits ): from random import choices bytes = [long_to_bytes(x) for x in range (1 , 256 )] while True : num = b'' .join(choices(bytes , k=bits//8 )) if is_prime(bytes_to_long(num)): return bytes_to_long(num)def gen_para (): while True : a = randint(50 , 70 ) r = getPrime(10 ) if is_prime(2 **a * r * lcm(range (1 , 256 )) - 1 ): return a, r a, r = gen_para() f.write(f'{a = } \n' ) f.write(f'{r = } \n' ) p = 2 **a * r * lcm(range (1 , 256 )) - 1 F.<i> = GF(p^2 , modulus=[1 , 0 , 1 ]) E = EllipticCurve(F, [0 , 1 ]) E.set_order((p+1 )**2 ) P, Q = E.gens()[0 ], E.gens()[1 ] f.write(f'P = {(P.x(), P.y())} \n' ) f.write(f'Q = {(Q.x(), Q.y())} \n' ) pp = get_Prime(1024 ) qq = get_Prime(1024 ) n = pp * qq e = 65537 gift = []while pp: x = pp & 0xff assert x != 0 pp = pp >> 8 k = randint(1 , 2 **a * x) R = P + k * Q K = (p + 1 ) // (2 **a * x) * R phi = E.isogeny(K, algorithm="factored" ) tmp1 = phi(P) tmp2 = phi(Q) gift.append([(tmp1.x(), tmp1.y()), (tmp2.x(), tmp2.y())]) f.write(f'gift = {gift} \n' ) m = bytes_to_long(flag) c = pow (m, e, n) f.write(f'n = {n} \n' ) f.write(f'c = {c} \n' )
$phi = E.isogeny(K, algorithm=”factored”)$
进行了一个同源映射,进行了群同态(由K生成核),因为核子群的阶和域f的特征p互素,那么我们可以知道
ker(k)=der(phi),同源映射的度等于这个核子群的阶。
同态映射的度,是指的这个映射的核群=k.order()(k的阶)=der(phi)。那么
我们可以利用weil配对der(phi)=d
$e_m(phi(P),phi(Q))=e_m(P,Q)^d$之后再利用discrete_log求解除p
不过呢。我们还需要计算一下同态映射后的椭圆曲线E2具体计算见WP。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 from sage.all import *from Crypto.Util.number import * aa = 58 r = 677 p = 1626863075383233617973114208257225766167963541697680166689538585027790888344497393319393220115606426479054738139191706757627903999 F.<i> = GF(p^2 , modulus=[1 , 0 , 1 ]) E = EllipticCurve(F, [0 , 1 ]) P = E(1480902412624330128467265433604967924879175621324778721822553791992483165650313334065712892856426887628203798402227946111937619985 *i + 248280033442212078026584729381629912663660842264732233544133931088920517333558326483592439680557530508869168630141184328058575487 , 1063473267082463348943776983826670708619445017230835195844111648761226238767209731540252058515506618539450166188109440566086315438 *i + 1477214491399359292603355035977428268773417965220883548847591474468057528862252443133638716703507083176807648546588008345161697639 ) Q = E(254336484714918197927485057298709531964473530684332223357900471713016451491419116513817849296332713866136292050578743336482952063 *i + 336569779925581133673425296270934299380299004021997431211455336955947557460506916625576473941830956381008213287862958120734974088 , 672798403906655690530129932893570217632405529086858027624968144934702132760440998323563013877307454993136939248872471610804174868 *i + 978599551527900215169394972113017743837581044055673443208277943573091308364000557275120262619669438354499782419523067775829261358 ) gift = [] n = 1702964505167542294309894624134040051985456000751301895681450703711209123273929347840767189769333598802007931175534183099577982055982094813045245735950771056151798358709294596212693586845327740981840974734260947504192849082082247982531638166723519817368621543647358361718962016975501235560072299206879455551179363257011645248897834786135688841937320538329157671950684987955303502005404340327657787221436015711630895743615195023754086594138352253842575921303048726058807135221950653758612234421493377641405846466416194921001135032171697695572842723082164349170706748881797912294462023414297556608213847345725952421549 c = 1029114088686337892631302678503751809542083988891442035793586975372895407547705418982466289898928319560409880414514578474791488427127025559202986548834389826420682378231639934214095320267479088288097862850583409973649066883523716495624685075221287755197089845642475957655326217081767651038275947961474613737339181490066613632071544485135542705782597487288176673605371342372887413483451432315489970957375439078944009120957142560963596958126921713605049998752504003069481700268168699099735284558580028754084228031725395039694427728930164273683375216610222208763440193601962605329874384315938196365292841272339652972630 N =p+1 a = P.weil_pairing(Q, p+1 ) pp=0 xs=[]for idx, item in enumerate (gift): (x1, y1), (x2, y2) = item S1 = y1*y1 - x1*x1*x1 S2 = y2*y2 - x2*x2*x2 dx = x1 - x2 A1 = (S1 - S2) / dx B1 = S1 - A1*x1 E1 = EllipticCurve(F,[A1, B1]) phiP=E1(x1,y1) phiQ=E1(x2,y2) a1=phiP.weil_pairing(phiQ,N) d=discrete_log(a1,a,N) x=int (d)//(2 **aa) print (x) xs.append(x)for i,b in enumerate (xs): pp|=(b<<(8 *i))if n % pp != 0 : raise RuntimeError("pp 不能整除 n,可能解析出错。" )print (f'pp={pp} ' ) qq = n // pp phi_n = (pp - 1 ) * (qq - 1 ) dd = inverse(0x10001 , phi_n) m = pow (c, dd, n) flag = long_to_bytes(m)print ("flag =" , flag)