文章目录
- 题一([HGAME 2022 week4]ECC)
- 题目描述:
- 题目分析(概念题):
- 题二([watevrCTF 2019]ECC-RSA)
- 题目描述:
- 题目分析(多项式求根):
- 题三(ECC)
- 题目描述:
- 题目分析(求点公式):
- ♠ \spadesuit ♠知识导入:
- 题四([第五空间 2021]ecc)
- 题目描述:
- 题目分析(私钥求解):
- ♠ \spadesuit ♠小记一下(求私钥k):
- discrete_log()
- 普适性Pohlig_Hellman算法
- Smart’s attack
- 持续更新中~
题一([HGAME 2022 week4]ECC)
题目描述:
from Crypto.Util.number import getPrime
from libnum import s2n
from secret import flag
p = getPrime(256)
a = getPrime(256)
b = getPrime(256)
E = EllipticCurve(GF(p),[a,b])
m = E.random_point()
G = E.random_point()
k = getPrime(256)
K = k * G
r = getPrime(256)
c1 = m + r * K
c2 = r * G
cipher_left = s2n(flag[:len(flag)//2]) * m[0]
cipher_right = s2n(flag[len(flag)//2:]) * m[1]
print(f"p = {p}")
print(f"a = {a}")
print(f"b = {b}")
print(f"k = {k}")
print(f"E = {E}")
print(f"c1 = {c1}")
print(f"c2 = {c2}")
print(f"cipher_left = {cipher_left}")
print(f"cipher_right = {cipher_right}")
'''
p = 74997021559434065975272431626618720725838473091721936616560359000648651891507
a = 61739043730332859978236469007948666997510544212362386629062032094925353519657
b = 87821782818477817609882526316479721490919815013668096771992360002467657827319
k = 93653874272176107584459982058527081604083871182797816204772644509623271061231
E = Elliptic Curve defined by y^2 = x^3 + 61739043730332859978236469007948666997510544212362386629062032094925353519657*x + 12824761259043751634610094689861000765081341921946160155432001001819005935812 over Finite Field of size 74997021559434065975272431626618720725838473091721936616560359000648651891507
c1 = (14455613666211899576018835165132438102011988264607146511938249744871964946084 : 25506582570581289714612640493258299813803157561796247330693768146763035791942 : 1)
c2 = (37554871162619456709183509122673929636457622251880199235054734523782483869931 : 71392055540616736539267960989304287083629288530398474590782366384873814477806 : 1)
cipher_left = 68208062402162616009217039034331142786282678107650228761709584478779998734710
cipher_right = 27453988545002384546706933590432585006240439443312571008791835203660152890619
'''
题目分析(概念题):
是道概念题了,直接解
from Crypto.Util.number import *
p = 74997021559434065975272431626618720725838473091721936616560359000648651891507
a = 61739043730332859978236469007948666997510544212362386629062032094925353519657
b = 12824761259043751634610094689861000765081341921946160155432001001819005935812
k = 93653874272176107584459982058527081604083871182797816204772644509623271061231
E = EllipticCurve(GF(p),[a,b])
c1 = E([14455613666211899576018835165132438102011988264607146511938249744871964946084,25506582570581289714612640493258299813803157561796247330693768146763035791942])
c2 = E([37554871162619456709183509122673929636457622251880199235054734523782483869931, 71392055540616736539267960989304287083629288530398474590782366384873814477806])
cipher_left = 68208062402162616009217039034331142786282678107650228761709584478779998734710
cipher_right = 27453988545002384546706933590432585006240439443312571008791835203660152890619
m = c1 - k * c2
left = cipher_left//m[0]
right = cipher_right//m[1] # 不能转int或Integer型,不然结果为0,不知道为什么,很奇怪
print(long_to_bytes(int(left))+long_to_bytes(int(right)))
# b'hgame{Ecc$is!sO@HaRd}'
题二([watevrCTF 2019]ECC-RSA)
题目描述:
from fastecdsa.curve import P521 as Curve
from fastecdsa.point import Point
from Crypto.Util.number import bytes_to_long, isPrime
from os import urandom
from random import getrandbits
def gen_rsa_primes(G):
urand = bytes_to_long(urandom(521//8))
while True:
s = getrandbits(521) ^ urand
Q = s*G
if isPrime(Q.x) and isPrime(Q.y):
print("ECC Private key:", hex(s))
print("RSA primes:", hex(Q.x), hex(Q.y))
print("Modulo:", hex(Q.x * Q.y))
return (Q.x, Q.y)
flag = int.from_bytes(input(), byteorder="big") # 将字节序列转化为整数
ecc_p = Curve.p
a = Curve.a
b = Curve.b
Gx = Curve.gx
Gy = Curve.gy
G = Point(Gx, Gy, curve=Curve)
e = 0x10001
p, q = gen_rsa_primes(G)
n = p*q
file_out = open("downloads/ecc-rsa.txt", "w")
file_out.write("ECC Curve Prime: " + hex(ecc_p) + "\n")
file_out.write("Curve a: " + hex(a) + "\n")
file_out.write("Curve b: " + hex(b) + "\n")
file_out.write("Gx: " + hex(Gx) + "\n")
file_out.write("Gy: " + hex(Gy) + "\n")
file_out.write("e: " + hex(e) + "\n")
file_out.write("p * q: " + hex(n) + "\n")
c = pow(flag, e, n)
file_out.write("ciphertext: " + hex(c) + "\n")
'''
ECC Curve Prime: 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
Curve a: -0x3
Curve b: 0x51953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
Gx: 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
Gy: 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650
e: 0x10001
p * q: 0x118aaa1add80bdd0a1788b375e6b04426c50bb3f9cae0b173b382e3723fc858ce7932fb499cd92f5f675d4a2b05d2c575fc685f6cf08a490d6c6a8a6741e8be4572adfcba233da791ccc0aee033677b72788d57004a776909f6d699a0164af514728431b5aed704b289719f09d591f5c1f9d2ed36a58448a9d57567bd232702e9b28f
ciphertext: 0x3862c872480bdd067c0c68cfee4527a063166620c97cca4c99baff6eb0cf5d42421b8f8d8300df5f8c7663adb5d21b47c8cb4ca5aab892006d7d44a1c5b5f5242d88c6e325064adf9b969c7dfc52a034495fe67b5424e1678ca4332d59225855b7a9cb42db2b1db95a90ab6834395397e305078c5baff78c4b7252d7966365afed9e
'''
题目分析(多项式求根):
p , q 是椭圆曲线上的点,满足方程: q 2 ≡ p 3 + a ∗ p + b ( m o d P ) 两边同乘 p 2 , 得到: n 2 ≡ p 5 + a ∗ p 3 + b ∗ p 2 ( m o d P ) 多项式求根即可解出 p , 随后得到 q ,之后整除 r s a 解密即可得到 f l a g p,q是椭圆曲线上的点,满足方程:\\q^{2} \equiv p^{3} + a * p + b \pmod P\\两边同乘p^{2},得到:\\n^{2} \equiv p^{5} + a * p^{3} + b * p^{2} \pmod P \\多项式求根即可解出p,随后得到q,之后整除rsa解密即可得到flag p,q是椭圆曲线上的点,满足方程:q2≡p3+a∗p+b(modP)两边同乘p2,得到:n2≡p5+a∗p3+b∗p2(modP)多项式求根即可解出p,随后得到q,之后整除rsa解密即可得到flag
from Crypto.Util.number import *
from gmpy2 import *
P = 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
a = -0x3
b = 0x51953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00
Gx = 0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66
Gy = 0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650
e = 0x10001
n = 0x118aaa1add80bdd0a1788b375e6b04426c50bb3f9cae0b173b382e3723fc858ce7932fb499cd92f5f675d4a2b05d2c575fc685f6cf08a490d6c6a8a6741e8be4572adfcba233da791ccc0aee033677b72788d57004a776909f6d699a0164af514728431b5aed704b289719f09d591f5c1f9d2ed36a58448a9d57567bd232702e9b28f
c = 0x3862c872480bdd067c0c68cfee4527a063166620c97cca4c99baff6eb0cf5d42421b8f8d8300df5f8c7663adb5d21b47c8cb4ca5aab892006d7d44a1c5b5f5242d88c6e325064adf9b969c7dfc52a034495fe67b5424e1678ca4332d59225855b7a9cb42db2b1db95a90ab6834395397e305078c5baff78c4b7252d7966365afed9e
R.<x> = Zmod(P)[]
f = x ^ 5 + a * x ^ 3 + b * x ^ 2 - n ^ 2
res = f.roots()
for i,j in res:
if n % int(i) == 0:
p = int(i)
q = n // int(i) # 数据类型要转(转Integer也行),否则得到错误的结果。很神奇,不会报错,倒是结果会错。
d = inverse_mod(e,(p-1)*(q-1))
print(long_to_bytes(int(pow(c,d,n))))
# b'watevr{factoring_polynomials_over_finite_fields_is_too_ez}'
题三(ECC)
题目描述:
from Crypto.Util.number import *
from gmpy2 import *
from random import *
from secrets import flag
assert len(flag)==42
p=getPrime(600)
a=bytes_to_long(flag)
b=randrange(2,p-1)
E=EllipticCurve(GF(p),[a,b]) #定义在a,b上模p的椭圆曲线
G=E.random_element()
x1,y1,_=G
G=2*G
x2,y2,_=G
print(f"p = {p}")
print(f"b = {b}")
print(f"x1 = {x1}")
print(f"x2 = {x2}")
'''
p = 3660057339895840489386133099442699911046732928957592389841707990239494988668972633881890332850396642253648817739844121432749159024098337289268574006090698602263783482687565322890623
b = 1515231655397326550194746635613443276271228200149130229724363232017068662367771757907474495021697632810542820366098372870766155947779533427141016826904160784021630942035315049381147
x1 = 2157670468952062330453195482606118809236127827872293893648601570707609637499023981195730090033076249237356704253400517059411180554022652893726903447990650895219926989469443306189740
x2 = 1991876990606943816638852425122739062927245775025232944491452039354255349384430261036766896859410449488871048192397922549895939187691682643754284061389348874990018070631239671589727
'''
题目分析(求点公式):
其实这题单纯就是根据ECC求点公式来求flag,并没有涉及到复杂的加密问题
♠ \spadesuit ♠知识导入:
y 2 ≡ x 3 + a ∗ x + b ( m o d P ) y^{2} \equiv x^{3} + a * x + b \pmod P y2≡x3+a∗x+b(modP)
P ( x 1 , y 1 ) , Q ( x 2 , y 2 ) 的和 R ( x 3 , y 3 ) 有如下关系: x 3 ≡ k 2 − x 1 − x 2 ( m o d p ) y 3 ≡ k ( x 1 − x 3 ) − y 1 ( m o d p ) 若 P = Q 则 k = 3 x 1 2 + a 2 y 1 ( m o d p ) ; 若 P ≠ Q 则 k = y 2 − y 1 x 2 − x 1 ( m o d p ) . \begin{aligned} &P(x_1,y_1),Q(x_2,y_2)\text{ 的和 }R(x_3,y_3)\text{ 有如下关系:} \\ &x_3\equiv k^2-x_1-x_2\pmod{p} \\ &y_3\equiv k(x_1-x_3)-y_1\pmod{p} \\ &\text{若 }P=Q\text{ 则 }k=\frac{3x_1^2+a}{2y_1}\pmod{p}\text{;} \\ &\text{若 }P\neq Q\text{ 则 }k=\frac{y_2-y_1}{x_2-x_1}\pmod{p}. \end{aligned} P(x1,y1),Q(x2,y2) 的和 R(x3,y3) 有如下关系:x3≡k2−x1−x2(modp)y3≡k(x1−x3)−y1(modp)若 P=Q 则 k=2y13x12+a(modp);若 P=Q 则 k=x2−x1y2−y1(modp).
首先 x 1 , y 1 在椭圆曲线上,所以: y 1 2 ≡ x 1 3 + a ∗ x 1 + b ( m o d p ) ① 题中 P , Q 是相同的两点 ( 即都为 G ) , 所以 : x 2 = k 2 − 2 ∗ x 1 k 2 = x 2 − 2 ∗ x 1 又: k = 3 x 1 2 + a 2 y 1 ( m o d p ) k 2 = ( 3 x 1 2 + a 2 y 1 ) 2 ( m o d p ) y 1 2 = ( 3 x 1 2 + a 2 k ) 2 ( m o d p ) ,带入①式,得到: ( 3 ∗ x 1 2 + a ) 2 ≡ 4 ∗ k 2 ∗ ( x 1 3 + a ∗ x 1 + b ) ( m o d p ) 多项式解方程即可得到 f l a g 首先x_1,y_1在椭圆曲线上,所以:\\ y_1^{2} \equiv x_1^{3} + a * x_1 + b \pmod p ①\\ 题中P,Q是相同的两点(即都为G),所以:\\x_2 = k^2 - 2 * x_1 \\ k^2 = x_2 - 2 * x_1\\又:\\ k=\frac{3x_1^2+a}{2y_1}\pmod{p}\\k^2=(\frac{3x_1^2+a}{2y_1})^2\pmod{p}\\ y_1^2=(\frac{3x_1^2+a}{2k})^2\pmod{p},带入①式,得到:\\ (3 * x_1^2 + a)^2 \equiv 4 * k^2 * (x_1^{3} + a * x_1 + b) \pmod p\\ 多项式解方程即可得到flag 首先x1,y1在椭圆曲线上,所以:y12≡x13+a∗x1+b(modp)①题中P,Q是相同的两点(即都为G),所以:x2=k2−2∗x1k2=x2−2∗x1又:k=2y13x12+a(modp)k2=(2y13x12+a)2(modp)y12=(2k3x12+a)2(modp),带入①式,得到:(3∗x12+a)2≡4∗k2∗(x13+a∗x1+b)(modp)多项式解方程即可得到flag
from Crypto.Util.number import *
from gmpy2 import *
p = 3660057339895840489386133099442699911046732928957592389841707990239494988668972633881890332850396642253648817739844121432749159024098337289268574006090698602263783482687565322890623
b = 1515231655397326550194746635613443276271228200149130229724363232017068662367771757907474495021697632810542820366098372870766155947779533427141016826904160784021630942035315049381147
x1 = 2157670468952062330453195482606118809236127827872293893648601570707609637499023981195730090033076249237356704253400517059411180554022652893726903447990650895219926989469443306189740
x2 = 1991876990606943816638852425122739062927245775025232944491452039354255349384430261036766896859410449488871048192397922549895939187691682643754284061389348874990018070631239671589727
k_2 = (x2 + 2 * x1)
PR.<a> = PolynomialRing(Zmod(p))
f = 4 * k_2 * (x1 ^ 3 + a * x1 + b) - (3 * x1 ^ 2 + a) ^ 2
a = f.roots()
# print(a)
a = 56006392793430010663016642098239513811260175999551893260401436587175373756825079518464264729364083325
print(long_to_bytes(a))
# flag{fa76cfb1-0052-4416-914d-91517bcebd52}
题四([第五空间 2021]ecc)
题目描述:
print 'Try to solve the 3 ECC'
from secret import flag
from Crypto.Util.number import *
assert(flag[:5]=='flag{')
flag = flag[5:-1]
num1 = bytes_to_long(flag[:7])
num2 = bytes_to_long(flag[7:14])
num3 = bytes_to_long(flag[14:])
def ECC1(num):
p = 146808027458411567
A = 46056180
B = 2316783294673
E = EllipticCurve(GF(p),[A,B])
P = E.random_point()
Q = num*P
print E
print 'P:',P
print 'Q:',Q
def ECC2(num):
p = 1256438680873352167711863680253958927079458741172412327087203
#import random
#A = random.randrange(389718923781273978681723687163812)
#B = random.randrange(816378675675716537126387613131232121431231)
A = 377999945830334462584412960368612
B = 604811648267717218711247799143415167229480
E = EllipticCurve(GF(p),[A,B])
P = E.random_point()
Q = num*P
print E
print 'P:',P
print 'Q:',Q
factors, exponents = zip(*factor(E.order()))
primes = [factors[i] ^ exponents[i] for i in range(len(factors))][:-1]
print primes
dlogs = []
for fac in primes:
t = int(int(P.order()) / int(fac))
dlog = discrete_log(t*Q,t*P,operation="+")
dlogs += [dlog]
print("factor: "+str(fac)+", Discrete Log: "+str(dlog)) #calculates discrete logarithm for each prime order
print num
print crt(dlogs,primes)
def ECC3(num):
p = 0xd3ceec4c84af8fa5f3e9af91e00cabacaaaecec3da619400e29a25abececfdc9bd678e2708a58acb1bd15370acc39c596807dab6229dca11fd3a217510258d1b
A = 0x95fc77eb3119991a0022168c83eee7178e6c3eeaf75e0fdf1853b8ef4cb97a9058c271ee193b8b27938a07052f918c35eccb027b0b168b4e2566b247b91dc07
B = 0x926b0e42376d112ca971569a8d3b3eda12172dfb4929aea13da7f10fb81f3b96bf1e28b4a396a1fcf38d80b463582e45d06a548e0dc0d567fc668bd119c346b2
E = EllipticCurve(GF(p),[A,B])
P = E.random_point()
Q = num*P
print E
print 'P:',P
print 'Q:',Q
ECC1(num1)
print '=============='
ECC2(num2)
print '=============='
ECC3(num3)
'''
Try to solve the 3 ECC
Elliptic Curve defined by y^2 = x^3 + 46056180*x + 2316783294673 over Finite Field of size 146808027458411567
P: (119851377153561800 : 50725039619018388 : 1)
Q: (22306318711744209 : 111808951703508717 : 1)
==============
Elliptic Curve defined by y^2 = x^3 + 377999945830334462584412960368612*x + 604811648267717218711247799143415167229480 over Finite Field of size 1256438680873352167711863680253958927079458741172412327087203
P: (550637390822762334900354060650869238926454800955557622817950 : 700751312208881169841494663466728684704743091638451132521079 : 1)
Q: (1152079922659509908913443110457333432642379532625238229329830 : 819973744403969324837069647827669815566569448190043645544592 : 1)
==============
Elliptic Curve defined by y^2 = x^3 + 490963434153515882934487973185142842357175523008183292296815140698999054658777820556076794490414610737654365807063916602037816955706321036900113929329671*x + 7668542654793784988436499086739239442915170287346121645884096222948338279165302213440060079141960679678526016348025029558335977042712382611197995002316466 over Finite Field of size 11093300438765357787693823122068501933326829181518693650897090781749379503427651954028543076247583697669597230934286751428880673539155279232304301123931419
P: (10121571443191913072732572831490534620810835306892634555532657696255506898960536955568544782337611042739846570602400973952350443413585203452769205144937861 : 8425218582467077730409837945083571362745388328043930511865174847436798990397124804357982565055918658197831123970115905304092351218676660067914209199149610 : 1)
Q: (964864009142237137341389653756165935542611153576641370639729304570649749004810980672415306977194223081235401355646820597987366171212332294914445469010927 : 5162185780511783278449342529269970453734248460302908455520831950343371147566682530583160574217543701164101226640565768860451999819324219344705421407572537 : 1)
'''
题目分析(私钥求解):
分三部分解
第一部分 数也比较小,可以直接用
d
i
s
c
r
e
t
e
_
l
o
g
(
)
得出
第二部分 用
p
o
h
l
i
g
_
h
e
l
l
m
a
n
算法出(题目中也给了)
第三部分 可以发现椭圆曲线阶数与
p
相等,用
s
m
a
r
t
’
s
a
t
t
a
c
k
出
分三部分解\\第一部分\ 数也比较小,可以直接用discrete\_log()得出\\第二部分\ 用pohlig\_hellman算法出(题目中也给了)\\第三部分\ 可以发现椭圆曲线阶数与p相等,用smart’s attack出
分三部分解第一部分 数也比较小,可以直接用discrete_log()得出第二部分 用pohlig_hellman算法出(题目中也给了)第三部分 可以发现椭圆曲线阶数与p相等,用smart’sattack出
一:
# 1
from Crypto.Util.number import *
p = 146808027458411567
a = 46056180
b = 2316783294673
E = EllipticCurve(GF(p),(a,b))
P = E(119851377153561800,50725039619018388)
Q = E(22306318711744209,111808951703508717)
num1 = discrete_log(Q,P,operation = '+')
二:
# 2
p = 1256438680873352167711863680253958927079458741172412327087203
a = 377999945830334462584412960368612
b = 604811648267717218711247799143415167229480
E = EllipticCurve(GF(p),[a,b])
P = E(550637390822762334900354060650869238926454800955557622817950,700751312208881169841494663466728684704743091638451132521079)
Q = E(1152079922659509908913443110457333432642379532625238229329830,819973744403969324837069647827669815566569448190043645544592)
# Q = k * P
n = E.order()
def Pohlig_Hellman(n,P,Q):
factors, exponents = zip(*factor(n))
primes = [factors[i] ^ exponents[i] for i in range(len(factors))][:-1]
print(primes)
dlogs = []
for fac in primes:
t = int(int(P.order()) // int(fac))
dlog = discrete_log(t*Q,t*P,operation="+")
dlogs += [dlog]
print("factor: "+str(fac)+", Discrete Log: "+str(dlog)) #calculates discrete logarithm for each prime order
num2 = crt(dlogs,primes)
return num2
num2 = Pohlig_Hellman(n,P,Q)
三:
# 3
p = 0xd3ceec4c84af8fa5f3e9af91e00cabacaaaecec3da619400e29a25abececfdc9bd678e2708a58acb1bd15370acc39c596807dab6229dca11fd3a217510258d1b
A = 0x95fc77eb3119991a0022168c83eee7178e6c3eeaf75e0fdf1853b8ef4cb97a9058c271ee193b8b27938a07052f918c35eccb027b0b168b4e2566b247b91dc07
B = 0x926b0e42376d112ca971569a8d3b3eda12172dfb4929aea13da7f10fb81f3b96bf1e28b4a396a1fcf38d80b463582e45d06a548e0dc0d567fc668bd119c346b2
E = EllipticCurve(GF(p),[A,B])
P = E(10121571443191913072732572831490534620810835306892634555532657696255506898960536955568544782337611042739846570602400973952350443413585203452769205144937861,8425218582467077730409837945083571362745388328043930511865174847436798990397124804357982565055918658197831123970115905304092351218676660067914209199149610)
Q = E(964864009142237137341389653756165935542611153576641370639729304570649749004810980672415306977194223081235401355646820597987366171212332294914445469010927,5162185780511783278449342529269970453734248460302908455520831950343371147566682530583160574217543701164101226640565768860451999819324219344705421407572537)
def SmartAttack(P,Q,p):
E = P.curve()
Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])
P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True)
for P_Qp in P_Qps:
if GF(p)(P_Qp.xy()[1]) == P.xy()[1]:
break
Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
for Q_Qp in Q_Qps:
if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]:
break
p_times_P = p*P_Qp
p_times_Q = p*Q_Qp
x_P,y_P = p_times_P.xy()
x_Q,y_Q = p_times_Q.xy()
phi_P = -(x_P/y_P)
phi_Q = -(x_Q/y_Q)
k = phi_Q/phi_P
return ZZ(k)
num3 = SmartAttack(P, Q, p)
Final:
print(long_to_bytes(num1) + long_to_bytes(num2) + long_to_bytes(num3))
# NSSCTF{025ab3d9-2521-4a81-9957-8c3381622434}
♠ \spadesuit ♠小记一下(求私钥k):
discrete_log()
discrete_log(Q,P,operation = '+') # Q = k * P
普适性Pohlig_Hellman算法
根据经验,发现了,好像因子大于10 ** 9 就比较难出结果,故下面略过了大于 10 ** 9 的数
def Pohlig_Hellman(n,P,Q): # n为阶,Q = k * P
factors = list(factor(n))
m = 1
moduli = []
remainders = []
print(f"[+] Running Pohlig Hellman")
print(factors)
for i, j in factors:
if i > 10**9: # 把过大的数过滤掉,防止计算不出
print('不考虑的数:',i)
break
mod = i**j
g2 = P*(n//mod)
q2 = Q*(n//mod)
r = discrete_log(q2, g2, operation='+')
remainders.append(r)
moduli.append(mod)
m *= mod
r = crt(remainders, moduli)
return r
Smart’s attack
适用情况:E.order()=p
def SmartAttack(P,Q,p):
E = P.curve()
Eqp = EllipticCurve(Qp(p, 2), [ ZZ(t) + randint(0,p)*p for t in E.a_invariants() ])
P_Qps = Eqp.lift_x(ZZ(P.xy()[0]), all=True)
for P_Qp in P_Qps:
if GF(p)(P_Qp.xy()[1]) == P.xy()[1]:
break
Q_Qps = Eqp.lift_x(ZZ(Q.xy()[0]), all=True)
for Q_Qp in Q_Qps:
if GF(p)(Q_Qp.xy()[1]) == Q.xy()[1]:
break
p_times_P = p*P_Qp
p_times_Q = p*Q_Qp
x_P,y_P = p_times_P.xy()
x_Q,y_Q = p_times_Q.xy()
phi_P = -(x_P/y_P)
phi_Q = -(x_Q/y_Q)
k = phi_Q/phi_P
return ZZ(k)