# [HGAME 2022 week4]ECC

# 题目

#sage
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
'''

只要求 m 就行了

c1=m + r * K=m+r * G * k

c2=r * G

m=c1-c2*k=m+r * G * k-r * G * k

# exp

#sage
from Crypto.Util.number import *
p = 74997021559434065975272431626618720725838473091721936616560359000648651891507
a = 61739043730332859978236469007948666997510544212362386629062032094925353519657
b = 87821782818477817609882526316479721490919815013668096771992360002467657827319
k = 93653874272176107584459982058527081604083871182797816204772644509623271061231
E = EllipticCurve(GF(p),[a,b])
c1 = E(14455613666211899576018835165132438102011988264607146511938249744871964946084 , 25506582570581289714612640493258299813803157561796247330693768146763035791942)
c2 = E(37554871162619456709183509122673929636457622251880199235054734523782483869931 , 71392055540616736539267960989304287083629288530398474590782366384873814477806)
cipher_left = 68208062402162616009217039034331142786282678107650228761709584478779998734710
cipher_right = 27453988545002384546706933590432585006240439443312571008791835203660152890619
m=c1-c2*k
cl=cipher_left//m[0]
cr=cipher_right//m[1]
print(long_to_bytes(int(cl)))
print(long_to_bytes(int(cr)))

# [SECCONCTF quals 2013]Cryptanalysis

# 题目

给了一张图

<img src="https://nss-1307121815.cos.ap-chengdu.myqcloud.com/7295019da9184805988c3d128585fe32?q-sign-algorithm=sha1&q-ak=AKIDUnqdARRAernSrzrTothETSAcmgJfkY6O&q-sign-time=1657521005%3B1657524665&q-key-time=1657521005%3B1657524665&q-header-list=&q-url-param-list=response-content-disposition&q-signature=60d5c2af3c1d22160756531bc8695236211d0094&response-content-disposition=attachment%3Bfilename%3D20140127213558.png" alt="1657521089076" style="zoom:50%;" />

最最最基本的 ECC

# exp

#Sage
a = 1234577
b = 3213242
p = 7654319
#EllipticCurve([a1, a2, a3, a4, a6]) -- y^2+(a1)xy+(a3)y=x^3+(a2)x^2+(a4)x+(a6)
E = EllipticCurve(GF(p), [0, 0, 0, a, b])
base = E([5234568,2287747 ])
pub = E([2366653, 1424308])
c1 = E([5081741, 6744615])
c2 = E([610619,6218 ])
X = base
n=base.order()
#Bruteforce secret k
for i in range(1, n):
    if X == pub:
        k = i
        print("[+] secret k = ", i)
        break
    else:
        X = X + base
m = c2 - (c1 * k)
print("[+] x = ", m[0])
print("[+] y = ", m[1])
print("[+] x+y = ", m[0] + m[1])

# [HITCTF 2021]Baby ECC

# 题目

#Elliptic Curve: y^2 = x^3 + 7 mod N which is secp256k1
N = 2**256-2**32-2**9-2**8-2**7-2**6-2**4-1
E = EllipticCurve(GF(N), [0, 7])
xG = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
yG = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
G = (xG,yG)
n = [secret0,secret1,secret2]
#flag = "HITCTF2021{"+''.join([hex(i) for i in n])
for i in n:
    assert i<1048575
    print(i*G)
cipher0 = E(76950424233905085841024245566087362444302867365333079406072251240614685819574 , 85411751544372518735487392020328074286181156955764536032224435533596344295845)
cipher1 = E(42965775717446397624794967106656352716523975639425128723916600655527177888618 , 32441185377964242317381212165164045554672930373070033784896067179784273837186)
cipher2 = E(26540437977825986616280918476305280126789402372613847626897144336866973077426 , 1098483412130402123611878473773066229139054475941277138170271010492372383833)
assert n[0]*G == cipher0
assert n[1]*G == cipher1
assert n[2]*G == cipher2
#Find n and recover the flag. Good luck!

# exp

N = 2**256-2**32-2**9-2**8-2**7-2**6-2**4-1
E = EllipticCurve(GF(N), [0, 7])
xG = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
yG = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
G = E(xG,yG)
cipher0 = E(76950424233905085841024245566087362444302867365333079406072251240614685819574 , 85411751544372518735487392020328074286181156955764536032224435533596344295845)
cipher1 = E(42965775717446397624794967106656352716523975639425128723916600655527177888618 , 32441185377964242317381212165164045554672930373070033784896067179784273837186)
cipher2 = E(26540437977825986616280918476305280126789402372613847626897144336866973077426 , 1098483412130402123611878473773066229139054475941277138170271010492372383833)
n=[]
n.append(discrete_log(cipher0,G,operation='+'))
n.append(discrete_log(cipher1,G,operation='+'))
n.append(discrete_log(cipher2,G,operation='+'))
flag = "HITCTF2021{"+''.join([hex(i) for i in n])

# [ctfshow 击剑杯] 依稀稀

# 题目

from Crypto.Util.number import *
import random
class Point:
    global p, a, b
    def __init__(self, x, y):
        self.x = x % p
        self.y = y % p
    
    def __str__(self):
        return f'({self.x}, {self.y})'
    def __add__(self, B):
        x1, y1, x2, y2 = self.x, self.y, B.x, B.y
        if (x1 == 0 and y1 == 0):
            return B
        if (x2 == 0 and y2 == 0):
            return self
        if (x1 == x2 and (y1 + y2) % p == 0):
            return Point(0, 0)
        
        if (x1 != x2 or y1 != y2):
            lam = (y2 - y1) * inverse(x2-x1, p) % p
        else:
            lam = (3*x1**2+a) * inverse(2*y1, p) % p
        
        x = (lam**2 - x1 - x2) % p
        y = (lam * (x1 - x) - y1) % p
        return Point(x, y)
    
    def __rmul__(self, k):
        B = Point(0, 0)
        k = f'{k:b}'
        
        for k_i in k:
            B = B + B
            if (k_i == '1'):
                B = B + self
            
        return B
    
    def __eq__(self, B):
        return self.x == B.x and self.y == B.y
p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
order = 115792089210356248762697446949407573529996955224135760342422259061068512044369
a = -3
b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
WELCOME = """
Welcome to my YiXiXi!
As I have mentioned before, to predict the value of Q, the possibility is only about O(yixixi)!
If you know how to capture the probability of O(yixixi), you can capture the flag!
"""
def main():
    print(WELCOME)
    x, y = map(int, input("Enter the coordinate of point P: ")[1:-1].split(', '))
    P = Point(x, y)
    k = random.randint(1,order)
    Q = k * P
    print("As we all have known, Q = kP")
    print("Now with the probability of O(yixixi), please tell me ---")
    x, y = map(int, input("Enter the coordinate of point Q: ")[1:-1].split(', '))
    Q_ = Point(x, y)
    if Q_ == Point(0, 0) or Q_ == P:
        print("Not that easy")
    elif Q_ == Q:
        print("Amazing! You have captured the probability of O(yixixi) successfully!")
        with open('flag.txt') as f:
            flag = f.read()
        print(f"Here is your flag: {flag}")
    else:
        print("Uh-oh! You have not captured the probability of O(yixixi)...")
        print("Maybe next time...")
if __name__ == '__main__':
    main()

这道题有一个漏洞就是没有验证输入的点是否在曲线上

题目需要输入 G,随机生成 k,预测 P=kG 的坐标

并且 P=G 和 P=O 都是不行的

也就是构造 G=O 和 2G=O 都不行

于是就能想到构造 3G=O(想不到)

去猜测 P=2G 的坐标

也就是 2G=-G

可以得到(3,4)他的二倍点是(3,-4)满足

# exp

from pwn import *
re=remote("pwn.challenge.ctf.show",28147)
re.recvuntil(b'Enter the coordinate of point P: ')
re.sendline(b'(3, 4)')
re.recvuntil(b'Enter the coordinate of point Q: ')
re.sendline(b'(3, -4)')
re.interactive()

#

更新于 阅读次数