zoukankan      html  css  js  c++  java
  • ECC椭圆曲线加密算法—加解密(SageMath实现)

    简介

    ECC椭圆曲线加密,它的安全性基于椭圆曲线上的离散对数问题。

    比特币和目前的二代居民身份证都采用了ECC作为加密算法。

    ECC椭圆曲线函数为:

    [y^{2}=x^{3}+ax+b (mod p) ]

    ECC算法如下:

    椭圆曲线Ep(a,b)(p为模数),基点(生成元)G(x,y),G点的阶数n,私钥k,公钥K(x,y),随机整数r,明文为一点m(x,y),密文为两点c1(x,y)和c2(x,y)
    (其中基点G,明文m,密文c1、c2都是椭圆曲线E上的点)
    选择私钥k(k<n)
    得到公钥K = k*G
    选择随机整数r(r<n)
    加密:
    c1 = m+r*K
    c2 = r*G
    解密:
    m = c1-k*c2(= c1-r*K)
    

    关于椭圆曲线的更多知识,可以参考Kalafinaian师傅的文章:https://www.cnblogs.com/Kalafinaian/p/7392505.html

    SageMath可以直接计算椭圆曲线加法和椭圆曲线乘法。

    椭圆曲线运算(SageMath):

    点u(x,y),整数a,点v(x,y),点w(x,y)
    a_inv = inverse_mod(a,p) #a_inv是a关于模p的乘法逆元a_inv
    v = a*u
    u = v*a_inv
    w = u+v
    

    加解密脚本

    SageMath加密脚本:

    '''
    加密
    椭圆曲线选取时,模数p应是一个大质数
    常用的有几个公开的椭圆曲线,如Secp256k1、Secp256r1等
    '''
    p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
    a = 115792089210356248762697446949407573530086143415290314195533631308867097853948
    b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
    E = EllipticCurve(GF(p),[a,b]) #建立椭圆曲线E
    G = E(101981543389703054444906888236965100227902100585263327233246492901054535785571,105947302391877180514060433855403037184838385483621546199124860815209826713886) #选择一点作为生成元
    n = G.order() #G的阶数
    k = 78772200542717449282831156601030024198219944170436309154595818823706214492400
    K = k*G
    r = 3546765
    m = E(80764032034929976879602863302323059647882062252124869895215418422992624743795,4964654783828069942602279691168356721024126126864424301508238062949726916347) #取E上一点m作为明文
    c1 = m+r*K
    c2 = r*G
    print(c1)
    print(c2)
    

    SageMath解密脚本:

    '''解密'''
    p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
    a = 115792089210356248762697446949407573530086143415290314195533631308867097853948
    b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
    k = 78772200542717449282831156601030024198219944170436309154595818823706214492400
    E = EllipticCurve(GF(p),[a,b]) #建立椭圆曲线E
    c1 = E(55527726590533087179712343802771216661752045890626636388680526348340802301667,99976146729305231192119179111453136971828647307627310904093286590128902629941)
    c2 = E(85460365972589567444123006081329559170090723413178386022601904195400422637884,58249081362527056631776731740177334121295518073095154119886890634279528757192)
    m = c1-k*c2
    print(m)
    

    其他

    使用Crypto.PublicKey.ECC生成ECC密钥:

    from Crypto.PublicKey import ECC
    
    #生成ECC密钥
    key = ECC.generate(curve='NIST P-256') #使用椭圆曲线NIST P-256
    
    #输出密钥(包括私钥k,基点G)
    print(key)
    
    #公钥(point_x,point_y是基点G的坐标)
    print(key.public_key())
    
    #椭圆曲线
    print(key.curve)
    
    #私钥k
    print(key.d)
    
    #导出为pem密钥文件
    print(key.export_key(format='PEM'))
    
    #导入密钥文件
    key = ECC.import_key(f.read())
    

    通过fastecdsa.Curve可以查到公开椭圆曲线的参数

    import fastecdsa.curve as curve
    
    #P-384的a
    curve.P384.a
    
    #P-384的b
    curve.P384.b
    
    #P-384的p
    curve.P384.p
    

    几种公开椭圆曲线参数:

    #NIST P-256(Secp256r1)
    #p = 2^224(2^32 − 1) + 2^192 + 2^96 − 1
    p = 115792089210356248762697446949407573530086143415290314195533631308867097853951
    a = 115792089210356248762697446949407573530086143415290314195533631308867097853948
    b = 41058363725152142129326129780047268409114441015993725554835256314039467401291
    
    #Secp256k1(比特币使用)
    #p = 2^256 − 2^32 − 2^9 − 2^8 − 2^7 − 2^6 − 2^4 − 1 = 2^256 – 2^32 – 977 
    p = 115792089237316195423570985008687907853269984665640564039457584007908834671663
    a = 0
    b = 7
    
    #NIST P-384
    #p = 2^384 – 2^128 – 2^96 + 2^32 – 1
    p = 39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319
    a = -3
    b = 27580193559959705877849011840389048093056905856361568521428707301988689241309860865136260764883745107765439761230575
    
    #NIST P-521
    p = 6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151
    a = -3
    b = 1093849038073734274511112390766805569936207598951683748994586394495953116150735016013708737573759623248592132296706313309438452531591012912142327488478985984
    

    SageMath取椭圆曲线上随机一点:

    E = EllipticCurve(GF(p),[a,b])
    E.random_point() #取椭圆曲线E上随机一点
    

    sagemath计算椭圆曲线上的离散对数问题(数据量不能太大)

    a = 1234577
    b = 3213242
    p = 7654319
    E = EllipticCurve(GF(p),[a,b])
    G = E(5234568, 2287747) #生成元
    #k = 1584718
    K = E(2366653, 1424308) #公钥
    
    #求解私钥,自动选择bsgs或Pohlig Hellman算法
    discrete_log(K,G,operation='+')
    
    #求解私钥,Pollard rho算法
    discrete_log_rho(K,G,operation='+')
    
    #求解私钥,Pollard Lambda算法,能够确定所求值在某一小范围时效率较高
    discrete_log_lambda(K,G,(1500000,2000000),operation='+')
    

    使用openssl查看ECC的pem密钥文件信息

    #查看ECC私钥信息
    openssl ec -in p384-key.pem -text -noout
    
    #查看ECC公钥信息
    openssl ec -pubin -in public.pem -text -noout
  • 相关阅读:
    debug error 错误日志的调试模式
    fork(2)
    Fundamental theorem of arithmetic 为什么1不是质数
    Compile-time Dependency Injection With Go Cloud's Wire 编译时依赖注入 运行时依赖注入
    LevelDB
    MySQL Bugs: #34354: Feature request: EXPLAIN ALTER TABLE https://bugs.mysql.com/bug.php?id=34354
    explain 分析 聚合统计语句的性能
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--005
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--004
    (原创)《Android编程权威指南》学习笔记01-- Android应用初体验--003
  • 原文地址:https://www.cnblogs.com/lnjoy/p/ecc.html
Copyright © 2011-2022 走看看