CTF-CRYPTO-ECC(1)
CTF—CRYPTO-ECC(1)
橢圓加密
1.簡介
橢圓曲線密碼學(xué)(Elliptic curve cryptography),簡稱 ECC,和RSA、ElGamel 算法等類似,是一種公開秘鑰加密的算法,也就是非對稱加密。ECC 被公認為在給定秘鑰長度下最安全的加密算法。ECC 依賴于解決大橢圓曲線離散對數(shù)問題的困難性。它的優(yōu)勢主要在于相對于其它方法,它可以在使用較短密鑰長度的同時保持相同的密碼強度。
2.ECC加解密
2.1密鑰生成
用戶A先選擇一條橢圓曲線
\]
選擇其上的一個生成元G,假設(shè)其階為n,之后再選擇一個正整數(shù)
\]
將其作為密鑰,計算:
\]
所以,公鑰為
\]
私鑰為:
\]
2.2加密
用戶 B 在向用戶 A 發(fā)送消息 m,這里假設(shè)消息 m 已經(jīng)被編碼為橢圓曲線上的點,其加密步驟如下
1.查詢用戶A的公鑰:
\]
2.在(1,q-1)的區(qū)間內(nèi)選擇隨機數(shù)k
根據(jù)A的公鑰計算
\]
計算
\]
如果為0,則從第二步重新開始
計算
\]
于是,發(fā)送給A的消息是
\]
2.3解密
利用私鑰計算
\]
計算消息
\]
3.Pohlig-Hellman與ECC
設(shè)求解的式子為:
\]
其中,P為我們選取的一個基點,l是我們選定的隨機數(shù),就是要求解的私鑰
首先取P的階n。可使得n*P不存在最小的正整數(shù)
設(shè)
\]
對于i屬于[1,r]
\]
如果得到了這些 li 的值我們就能使用中國剩余定理進行求解得到 l 了,現(xiàn)在的問題就是求解這些
\]
\]
所以
\]
\]
\]
即
\]
所以
\]
\]
依次將zi全部算出來,然后用crt算出l
例題
[第五空間 2021]
task.py
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)
這題第一個部分就是簡單的離散對數(shù)法就可以解決,第二部分需要用到Pohlig-Hellman,順便提一下,dlog = discrete_log(t * Q, t * P,operation = "+")這句代碼中,dlog = discrete_log()可以自動換域,所以可以使用CRT
關(guān)于這個離散對數(shù)的問題,可以詳見
https://xz.aliyun.com/t/13919?time__1311=GqmxnD2D9A0QKGNDQieBK4YvxAKPrw7YLbD
EXP
from Crypto.Util.number import *
from sage.all import *
# Part1
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 = '+')
# Part2
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)
# Part3
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)
print(b'NSSCTF{' + long_to_bytes(num1) + long_to_bytes(num2) + long_to_bytes(num3) + b'}')
總結(jié)
以上是生活随笔為你收集整理的CTF-CRYPTO-ECC(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 判断数组中某个元素的个数
- 下一篇: 如何使用Java与Mysql进行数据交互