初识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}

posted @ 2024-07-18 17:11  附体欢欢  阅读(6)  评论(0编辑  收藏  举报