橢圓曲線加密解密算法python3實現(xiàn)

信息安全課程的實驗锚沸,根據(jù)課件及網(wǎng)上資料第晰,參考實現(xiàn)

代碼中注釋比較完善,算法的實現(xiàn)整體流程如下:

- 實現(xiàn)基本流程:

考慮K=kG 裸卫,其中K仿贬、G為橢圓曲線Ep(a,b)上的點,nG的階(nG=O∞ )墓贿,k為小于n的整數(shù)茧泪。
則給定kG,根據(jù)加法法則聋袋,計算K很容易但反過來队伟,給定KG,求k就非常困難幽勒。
因為實際使用中的ECC原則上把p取得相當(dāng)大嗜侮,n也相當(dāng)大,要把n個解點逐一算出來列成上表是不可能的啥容。
這就是橢圓曲線加密算法的數(shù)學(xué)依據(jù)

G稱為基點(base point

kk<n)為私有密鑰(privte key

K為公開密鑰(public key)


- 代碼實現(xiàn)(Python3.6)

# -*- coding:utf-8 *-
# author: DYBOY
# time: 2019-3-22 10:12:59
# description: ECC橢圓曲線加密算法實現(xiàn)
"""
    考慮K=kG 锈颗,其中K、G為橢圓曲線Ep(a,b)上的點咪惠,n為G的階(nG=O∞ )击吱,k為小于n的整數(shù)。
    則給定k和G遥昧,根據(jù)加法法則覆醇,計算K很容易但反過來朵纷,給定K和G,求k就非常困難永脓。
    因為實際使用中的ECC原則上把p取得相當(dāng)大柴罐,n也相當(dāng)大,要把n個解點逐一算出來列成上表是不可能的憨奸。
    這就是橢圓曲線加密算法的數(shù)學(xué)依據(jù)

    點G稱為基點(base point)

    k(k<n)為私有密鑰(privte key)

    K為公開密鑰(public key)
"""


def get_inverse(mu, p):
    """
    獲取y的負(fù)元
    """
    for i in range(1, p):
        if (i*mu)%p == 1:
            return i
    return -1


def get_gcd(zi, mu):
    """
    獲取最大公約數(shù)
    """
    if mu:
        return get_gcd(mu, zi%mu)
    else:
        return zi


def get_np(x1, y1, x2, y2, a, p):
    """
    獲取n*p,每次+p凿试,直到求解階數(shù)np=-p
    """
    flag = 1  # 定義符號位(+/-)

    # 如果 p=q  k=(3x2+a)/2y1mod p
    if x1 == x2 and y1 == y2:
        zi = 3 * (x1 ** 2) + a  # 計算分子      【求導(dǎo)】
        mu = 2 * y1    # 計算分母

    # 若P≠Q(mào)排宰,則k=(y2-y1)/(x2-x1) mod p
    else:
        zi = y2 - y1
        mu = x2 - x1
        if zi* mu < 0:
            flag = 0        # 符號0為-(負(fù)數(shù))
            zi = abs(zi)
            mu = abs(mu)

    # 將分子和分母化為最簡
    gcd_value = get_gcd(zi, mu)     # 最大公約數(shù)
    zi = zi // gcd_value            # 整除
    mu = mu // gcd_value
    # 求分母的逆元  逆元: ?a ∈G ,ョb∈G 使得 ab = ba = e
    # P(x,y)的負(fù)元是 (x,-y mod p)= (x,p-y) 那婉,有P+(-P)= O∞
    inverse_value = get_inverse(mu, p)
    k = (zi * inverse_value)

    if flag == 0:                   # 斜率負(fù)數(shù) flag==0
        k = -k
    k = k % p
    # 計算x3,y3 P+Q
    """
        x3≡k2-x1-x2(mod p)
        y3≡k(x1-x3)-y1(mod p)
    """
    x3 = (k ** 2 - x1 - x2) % p
    y3 = (k * (x1 - x3) - y1) % p
    return x3,y3


def get_rank(x0, y0, a, b, p):
    """
    獲取橢圓曲線的階
    """
    x1 = x0             #-p的x坐標(biāo)
    y1 = (-1*y0)%p      #-p的y坐標(biāo)
    tempX = x0
    tempY = y0
    n = 1
    while True:
        n += 1
        # 求p+q的和板甘,得到n*p,直到求出階
        p_x,p_y = get_np(tempX, tempY, x0, y0, a, p)
        # 如果 == -p,那么階數(shù)+1详炬,返回
        if p_x == x1 and p_y == y1:
            return n+1
        tempX = p_x
        tempY = p_y


def get_param(x0, a, b, p):
    """
    計算p與-p
    """
    y0 = -1
    for i in range(p):
        # 滿足取模約束條件盐类,橢圓曲線Ep(a,b),p為質(zhì)數(shù)呛谜,x,y∈[0,p-1]
        if i**2%p == (x0**3 + a*x0 + b)%p:
            y0 = i
            break

    # 如果y0沒有在跳,返回false
    if y0 == -1:
        return False

    # 計算-y(負(fù)數(shù)取模)
    x1 = x0
    y1 = (-1*y0) % p
    return x0,y0,x1,y1


def get_graph(a, b, p):
    """
    輸出橢圓曲線散點圖
    """
    x_y = []
    # 初始化二維數(shù)組
    for i in range(p):
        x_y.append(['-' for i in range(p)])

    for i in range(p):
        val =get_param(i, a, b, p)  # 橢圓曲線上的點
        if(val != False):
            x0,y0,x1,y1 = val
            x_y[x0][y0] = 1
            x_y[x1][y1] = 1

    print("橢圓曲線的散列圖為:")
    for i in range(p):              # i= 0-> p-1
        temp = p-1-i        # 倒序

        # 格式化輸出1/2位數(shù),y坐標(biāo)軸
        if temp >= 10:
            print(temp, end=" ")
        else:
            print(temp, end="  ")

        # 輸出具體坐標(biāo)的值隐岛,一行
        for j in range(p):
            print(x_y[j][temp], end="  ")
        print("")   #換行

    # 輸出 x 坐標(biāo)軸
    print("  ", end="")
    for i in range(p):
        if i >=10:
            print(i, end=" ")
        else:
            print(i, end="  ")
    print('\n')


def get_ng(G_x, G_y, key, a, p):
    """
    計算nG
    """
    temp_x = G_x
    temp_y = G_y
    while key != 1:
        temp_x,temp_y = get_np(temp_x,temp_y, G_x, G_y, a, p)
        key -= 1
    return temp_x,temp_y


def ecc_main():
    while True:
        a = int(input("請輸入橢圓曲線參數(shù)a(a>0)的值:"))
        b = int(input("請輸入橢圓曲線參數(shù)b(b>0)的值:"))
        p = int(input("請輸入橢圓曲線參數(shù)p(p為素數(shù))的值:"))   #用作模運(yùn)算

        # 條件滿足判斷
        if (4*(a**3)+27*(b**2))%p == 0:
            print("您輸入的參數(shù)有誤猫妙,請重新輸入!>郯肌割坠!\n")
        else:
            break

    # 輸出橢圓曲線散點圖
    get_graph(a, b, p)

    # 選點作為G點
    print("user1:在如上坐標(biāo)系中選一個值為G的坐標(biāo)")
    G_x = int(input("user1:請輸入選取的x坐標(biāo)值:"))
    G_y = int(input("user1:請輸入選取的y坐標(biāo)值:"))

    # 獲取橢圓曲線的階
    n = get_rank(G_x, G_y, a, b, p)

    # user1生成私鑰,小key
    key = int(input("user1:請輸入私鑰小key(<{}):".format(n)))

    # user1生成公鑰妒牙,大KEY
    KEY_x,kEY_y = get_ng(G_x, G_y, key, a, p)

    # user2階段
    # user2拿到user1的公鑰KEY彼哼,Ep(a,b)階n,加密需要加密的明文數(shù)據(jù)
    # 加密準(zhǔn)備
    k = int(input("user2:請輸入一個整數(shù)k(<{})用于求kG和kQ:".format(n)))
    k_G_x,k_G_y = get_ng(G_x, G_y, k, a, p)                         # kG
    k_Q_x,k_Q_y = get_ng(KEY_x, kEY_y, k, a, p)                     # kQ

    # 加密
    plain_text = input("user2:請輸入需要加密的字符串:")
    plain_text = plain_text.strip()
    #plain_text = int(input("user1:請輸入需要加密的密文:"))
    c = []
    print("密文為:",end="")
    for char in plain_text:
        intchar = ord(char)
        cipher_text = intchar*k_Q_x
        c.append([k_G_x, k_G_y, cipher_text])
        print("({},{}),{}".format(k_G_x, k_G_y, cipher_text),end="-")


    # user1階段
    # 拿到user2加密的數(shù)據(jù)進(jìn)行解密
    # 知道 k_G_x,k_G_y湘今,key情況下敢朱,求解k_Q_x,k_Q_y是容易的,然后plain_text = cipher_text/k_Q_x
    print("\nuser1解密得到明文:",end="")
    for charArr in c:
        decrypto_text_x,decrypto_text_y = get_ng(charArr[0], charArr[1], key, a, p)
        print(chr(charArr[2]//decrypto_text_x),end="")

        #inverse_value = get_inverse(decrypto_text_x, p)
        #text = charArr[2]*inverse_value%p
        #print(text,end=" ")


if __name__ == "__main__":
    print("*************ECC橢圓曲線加密*************")
    ecc_main()


- 運(yùn)行效果:


- 參考文章:

原文地址:https://blog.dyboy.cn/websecurity/121.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末象浑,一起剝皮案震驚了整個濱河市蔫饰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌愉豺,老刑警劉巖篓吁,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蚪拦,居然都是意外死亡杖剪,警方通過查閱死者的電腦和手機(jī)冻押,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盛嘿,“玉大人洛巢,你說我怎么就攤上這事〈握祝” “怎么了稿茉?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長芥炭。 經(jīng)常有香客問我漓库,道長,這世上最難降的妖魔是什么园蝠? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任渺蒿,我火速辦了婚禮,結(jié)果婚禮上彪薛,老公的妹妹穿的比我還像新娘茂装。我一直安慰自己,他們只是感情好善延,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布少态。 她就那樣靜靜地躺著,像睡著了一般挚冤。 火紅的嫁衣襯著肌膚如雪况增。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天训挡,我揣著相機(jī)與錄音澳骤,去河邊找鬼。 笑死澜薄,一個胖子當(dāng)著我的面吹牛为肮,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播肤京,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼颊艳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了忘分?” 一聲冷哼從身側(cè)響起棋枕,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妒峦,沒想到半個月后重斑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡肯骇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年窥浪,在試婚紗的時候發(fā)現(xiàn)自己被綠了祖很。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡漾脂,死狀恐怖假颇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情骨稿,我是刑警寧澤笨鸡,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站坦冠,受9級特大地震影響镜豹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蓝牲,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望泰讽。 院中可真熱鬧例衍,春花似錦、人聲如沸已卸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽累澡。三九已至梦抢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愧哟,已是汗流浹背奥吩。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留蕊梧,地道東北人霞赫。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像肥矢,于是被迫代替她去往敵國和親端衰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容