初识ECC
考点
\[本题考查了ECC最基础的特性,目的在于初步了解椭圆曲线以及各个参量所代表的意思
\]
思路解析
\[如题所示
\]
# sage
from Crypto.Util.number import getPrime
from libnum import s2n
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 = 12824761259043751634610094689861000765081341921946160155432001001819005935812
# k = 101132820309810002341803718592118308198937008894344022672869610847374761942333
# E = Elliptic Curve defined by y^2 = x^3 + 61739043730332859978236469007948666997510544212362386629062032094925353519657*x + 12824761259043751634610094689861000765081341921946160155432001001819005935812 over Finite Field of size 74997021559434065975272431626618720725838473091721936616560359000648651891507
# c1 = (57009380193886532378569303439033601453149979626036481908451460670186649267627 : 10962542324870273580782193983044663445206691522485860260557069375514546469634 : 1)
# c2 = (50289692889761113054173182964536751303670791652979898309016511669508762730275 : 43000219003438320713960240141557876963837430645137262740177869482318079614572 : 1)
# cipher_left = 72767842527949029771259815012050151626838796359653432952398922272453844670919
# cipher_right = 62963060607109417183969335469433197002171931571987651799164124884199227965291
\[\\题目看着与椭圆曲线相关,实际上我们不难发现只是在进行点运算
\\对于标准的椭圆曲线式 y^2 ≡ x^3 + a∗x + b(modP)
\\其中a为x一次项的系数,b为常数项,p为模数
\\m,G分别为在椭圆曲线上随机取得点
\\且k = getPrime(256),r = getPrime(256)
\\K为G的k倍点
\\我们已知c1,c2的点值,且c1,c2有
\\c1 = m + r * K
\\c2 = r * G
\\在了解之后,我们看flag的值,flag满足
\\cipher-left = s2n(flag[:len(flag)//2]) * m[0]
\\cipher-right = s2n(flag[len(flag)//2:]) * m[1]
\\即密文的左半部分为flag的前半部分转换成数字再与m点的x位相乘
\\即密文的右半部分为flag的后半部分转换成数字再与m点的y位相乘
\\不难发现,既然给了cipher-left,cipher-right的值
\\我们尝试求出m点的值便可以求出flag
\\那我们进行一个简单的推导
\\c2 = r * G
\\r = c2 * G^{-1}
\\m = c1 - r * K = c1 - c2 * G^{-1} * k * G
\\所以 m = c1 - k * c2
\\其实本题只是以椭圆曲线为背景,实际解密很简单,当然,欢迎进入椭圆曲线的学习
\\得到结论,解密脚本如下
\]
from Crypto.Util.number import long_to_bytes
p = 74997021559434065975272431626618720725838473091721936616560359000648651891507
a = 61739043730332859978236469007948666997510544212362386629062032094925353519657
b = 12824761259043751634610094689861000765081341921946160155432001001819005935812
k = 101132820309810002341803718592118308198937008894344022672869610847374761942333
E = EllipticCurve(GF(p), [a, b])
c1 = E([57009380193886532378569303439033601453149979626036481908451460670186649267627,
10962542324870273580782193983044663445206691522485860260557069375514546469634])
c2 = E([50289692889761113054173182964536751303670791652979898309016511669508762730275,
43000219003438320713960240141557876963837430645137262740177869482318079614572])
cipher_left = 72767842527949029771259815012050151626838796359653432952398922272453844670919
cipher_right = 62963060607109417183969335469433197002171931571987651799164124884199227965291
m = c1 - k * c2
left = cipher_left // m[0]
right = cipher_right // m[1]
a = long_to_bytes(int(left)) + long_to_bytes(int(right))
print(long_to_bytes(int(a)))
运行得到flag{7yVXcvlBv8trNNCU5nKA}