美文网首页
区块链椭圆加密及使用

区块链椭圆加密及使用

作者: 王乐城愚人云端 | 来源:发表于2019-02-26 13:48 被阅读0次

    相关文章:

    1. [区块链] 密码学——椭圆曲线密码算法(ECC)
    2. 椭圆曲线算法:入门
    3. ECC椭圆曲线详解(有具体实例)
    4. 谁能最简单的详解椭圆曲线算法,secp256k1 是如何生成公钥和私钥的?

    加密算法

    对称加密

    概念:即加密,解密的密钥相同。

    优点:是加解密效率高(速度快,空间占用小),加密强度高。

    缺点:是参与多方都需要持有密钥,一旦有人泄露则安全性被破坏;另外如何在不安全通道下分发密钥也是个问题。

    代表算法:包括DES、3DES、AES、IDEA等。

    非对称加密

    概念:加密密钥和解密密钥是不同的,分别称为公钥和私钥。公钥一般是公开的,人人可获取的,私钥一般是个人自己持有,不能被他人获取。

    优点:是公私钥分开,不安全通道也可以使用。
    缺点:是加解密速度慢,一般比对称加解密算法慢2到3个数量级;同时加密强度相比对称加密要差。
    非对称加密算法的安全性往往需要基于数学问题来保障,目前主要有基于大数质因子分解、离散对数、椭圆曲线等几种思路。

    代表算法:RSA、ElGamal、椭圆曲线(Elliptic Curve Crytosystems,ECC)系列算法。

    混合机密机制

    既先用计算复杂度高的非对称机密协商一个临时的加密密钥(会话密钥,一般相对内容来说要短得多),然后双方再通过对称加密对传递的大量数据进行加解密处理。
    典型的场景是现在大家常用的HTTPS机制。

    即:先用较短的非对称加密确认权限,再用对称加密对传递的大量数据进行加解密。

    区块链椭圆曲线加密(Elliptic Curve Crytosystems,ECC)简介

    导入

    假设这个世界上所有的人都会乘法,却没有人会除法。
    有一天张三挑出了两个数字,123,456。
    由于张三会乘法,于是乎张三计算出了:

    123 * 456 = 56088
    

    于是张三告诉你:

    123 * ??? =56088
    

    你是个天资卓绝的人,但是没办法,上天不允许你会除法,因此你没法知道张三说的???是什么。
    当然了,别人也不知道,因为张三没有告诉其他人???是啥。
    有一天,你打算告诉张三一个秘密,67。但是你又不想别人知道。于是聪明绝顶的你随手选了一个数字222。

    计算出:

    123 * 222 = 27306
    
    56088 * 222 + 67 = 12451603
    

    然后你对张三说:

    123 * ??? = 27306
    
    56088 * ??? + x = 12451603
    

    当然,你聪明绝顶,张三聪明秃顶,于是张三一寻思:

    123 * ??? * 456 = 56088 * ???
    

    这上下一减,

    x = 12451603 - 27306 * 456 = 67
    

    哎妈呀,这x就这么被传递过来了。如果我们把上面的过程写成数学公式的话,

    G * k = K   (G,K公开,k保密)
    c1 = G * Mc2 = K * M + x (M随机选取,x为要加密的数字,M和x都保密)
    x = c2 - c1 * k  
      = K * M + x - G * M * k  = G * M * k + x - G * M * k (消除左右两侧的G * M * k) 
      = x
    

    总结:

    所以我们想要实现加密容易,校验容易,但解密很难,
    其实就是要找到一组运算加,减,乘很简单,除却很难,这个事情并不容易。
    因为加,减,乘就可以实现加密和校验,但除我们希望他很难,难到几乎无法得到解。
    而这个符合这个条件的运算之一,就是:椭圆曲线方程,其加减乘除是指上的加减乘除,域的概念是从我们的有理数,实数的运算中抽象出来的,严格的定义请参考近世代数方面的数。简单的说,域中的元素同有理数一样,有自己得加法、乘法、除法、单位元(1),零元(0),并满足交换率、分配率。

    椭圆曲线方程

    包括ECC、ECDH或者ECDSA。ECC是Elliptic Curve Cryptography的缩写,就是椭圆加密算法,ECDH和ECDSA是ECC的不同实现。

    椭圆加密算法的应用范围很广,主要的三个技术 TLS、PGP以及SSH都在使用它,更别提比特币以及其他加密数字货币了。

    椭圆曲线方程:(可以暂时简单的理解为描述了特定点的集合的公式

    y² = x³ + ax + b

    椭圆曲线几何学上的加法

    任意取椭圆曲线上两点P、Q(若P、Q两点重合,则作P点的切线),作直线交于椭圆曲线的另一点R',过R'做y轴的平行线交于R,定义P+Q=R。这样,加法的和也在椭圆曲线上,并同样具备加法的交换律、结合律。

    image

    椭圆曲线上的加密/解密

    公开密钥算法总是要基于一个数学上的难题。比如RSA 依据的是:给定两个素数p、q 很容易相乘得到n,而对n进行因式分解却相对困难。那椭圆曲线上有什么难题呢?

    考虑如下等式:
    K=kG [其中 K,G为Ep(a,b)上的点,k为小于n(n是点G的阶)的整数]
    不难发现,给定k和G,根据加法法则,计算K很容易;但给定K和G,求k就相对困难了。
      这就是椭圆曲线加密算法采用的难题。

    我们把点G称为基点(base point),

    k(k<n,n为基点g的阶)称为私有密钥(privte key),

    k称为公开密钥(public="" key)。<="" p="">

    现在我们描述一个利用椭圆曲线进行加密通信的过程:

    1、用户A选定一条椭圆曲线Ep(a,b),并取椭圆曲线上一点,作为基点G。
    2、用户A选择一个私有密钥k,并生成公开密钥K=kG。
    3、用户A将Ep(a,b)和点K,G传给用户B。
    4、用户B接到信息后 ,将待传输的明文编码到Ep(a,b)上一点M(编码方法很多,这里不作讨论),并产生一个随机整数r(r<n)。
    5、用户B计算点C1=M+rK;C2=rG。
    6、用户B将C1、C2传给用户A。
      7、用户A接到信息后,计算C1-kC2,结果就是点M。

    因为C1-kC2=M+rK-k(rG)=M+rK-r(kG)=M再对点M进行解码就可以得到明文。

    在这个加密通信中,如果有一个偷窥者H ,他只能看到Ep(a,b)、K、G、C1、C2 而通过K、G 求k 或通过C2、G求r 都是相对困难的。因此,H无法得到A、B间传送的明文信息。

    总结:

    设私钥、公钥分别为k、K,即K = kG,其中G为G点。

    公钥加密:
    选择随机数r,将消息M生成密文C,该密文是一个点对,即:
    C = {rG, M+rK},其中K为公钥

    私钥解密:
    M + rK - k(rG) = M + r(kG) - k(rG) = M
    其中k、K分别为私钥、公钥。

    椭圆曲线签名与验证签名

    椭圆曲线签名算法,即ECDSA。
    设私钥、公钥分别为k、K,即K = kG,其中G为G点。

    私钥签名:
    1、选择随机数r,计算点rG(x, y)。
    2、根据随机数r、消息M的哈希h、私钥k,计算s = (h + kx)/r。
    3、将消息M、和签名{rG, s}发给接收方。

    公钥验证签名:
    1、接收方收到消息M、以及签名{rG=(x,y), s}。
    2、根据消息求哈希h。
    3、使用发送方公钥K计算:hG/s + xK/s,并与rG比较,如相等即验签成功。

    原理如下:
    hG/s + xK/s = hG/s + x(kG)/s = (h+xk)G/s = r(h+xk)G / (h+kx) = rG

    比特币私钥、公钥、钱包地址的来历和关系

    比特币系统选用的secp256k1

    比特币钱包地址示例:1QCXRuoxWo5Bya9NxHaVBArBQYhatHJrU7

    那这个钱包地址是如何生成的?

    从比特币私钥得到我们日常转账所用的比特币钱包地址总共需要9个步骤,中间用到了SHA256加密、RIPEMD160加密和BASE58编码。

    1. 生成随机私钥

    私钥是一个随机数,随机选取一个32字节的数,这个数的范围大小是介于1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之间的一个数,为了方便后面的计算,我们随机生成一个合法的私钥:

    8F72F6B29E6E225A36B68DFE333C7CE5E55D83249D3D2CD6332671FA445C4DD3
    

    2. 椭圆曲线算公钥

    生成了私钥之后,我们使用椭圆曲线加密算法(ECDSA-secp256k1)计算私钥所对应的非压缩公钥,生成的公钥共65字节, 其中一个字节是0x04,其中32个字节是X坐标,另外32个字节是Y坐标:

    公钥P.X:06CCAE7536386DA2C5ADD428B099C7658814CA837F94FADE365D0EC6B1519385
    
    公钥P.Y:FF83EC5F2C0C8F016A32134589F7B9E97ACBFEFD2EF12A91FA622B38A1449EEB
    

    3.计算公钥的SHA-256哈希值

    将上述公钥地址拼合,得到标准地址:

    0406CCAE7536386DA2C5ADD428B099C7658814CA837F94FADE365D0EC6B1519385FF83EC5F2C0C8F016A32134589F7B9E97ACBFEFD2EF12A91FA622B38A1449EEB
    

    对齐进行SHA-256哈希计算,得到结果:

    2572e5f4a8e77ddf5bb35b9e61c61f66455a4a24bcfd6cb190a8e8ff48fc097d
    

    4.计算 RIPEMD-160哈希值

    取上一步结果,进行RIPEMD-160计算,得到结果:

    0b14f003d63ab31aef5fedde2b504699547dd1f6
    

    5.加入地址版本号(比特币主网版本号“0x00”)

    取上一步结果,在前面加上16进制的00,即:

    000b14f003d63ab31aef5fedde2b504699547dd1f6
    

    6.计算 SHA-256 哈希值

    取上一步结果,进行SHA-256计算,可得:

    ddc2270f93cc84cc6869dd373f3c340bbf5cb9a8f5559297cc9e5d947aab2536
    

    然后,对以上结果再次计算 SHA-256 哈希值,得到:

    869ac57b83ccf75ca9da8895823562fffb611e3c297d9c2d4612aeeb32850078
    

    7.取上一步结果的前4个字节(8位十六进制)

    869ac57b
    

    8.把这4个字节加在步骤5的结果后面

    作为校验位,将这4个字节加载第五步的结果后面,这就是比特币地址的16进制形态了:

    869ac57b000b14f003d63ab31aef5fedde2b504699547dd1f6
    

    9.用Base58编码变换一下地址

    对上一步的结果进行Base58编码,得到:

    1QCXRuoxWo5Bya9NxHaVBArBQYhatHJrU7
    

    这就是我们经常看到的传统意义上的比特币钱包地址了。

    Delos区块链使用的椭圆加密

    delos区块链上使用了两种不同的椭圆加密实现,都是go语言编写

    • ed25519 gitlab.zhonganonline.com/ann/ann-module/lib/ed25519

    • secp256k1 github.com/btcsuite/btcd/btcec

    delos链生成私钥

    privkey crypto.PrivKeyEd25519
    

    delos/api项目中调用的是以太坊的delos/eth/crypto的ECDSA椭圆加密方法生成私钥和地址

    生成account私钥和地址

    result.Privkey = ethcmn.Bytes2Hex(crypto.FromECDSA(privkey))
    result.Address = ethcmn.Bytes2Hex(crypto.FromECDSAPubCompressed(&privkey.PublicKey))
    

    Breadwallet-android使用的椭圆加密

    Breadwallet-android使用的是secp256k1,都是c语言编写

    在app/src/main/secp/secp256k1下

    生成私钥

    app\src\main\jni\breadwallet-core\Java\root\com\breadwallet\core\BRCoreKey.java
    
    private static native long createJniCoreKey ();
    

    调用的是 jni c库

    /*
     * Class:     com_breadwallet_core_BRCoreKey
     * Method:    createJniCoreKey
     * Signature: ()J
     */
    JNIEXPORT jlong JNICALL
    Java_com_breadwallet_core_BRCoreKey_createJniCoreKey
            (JNIEnv *env, jclass thisClass) {
        BRKey *key = (BRKey *) calloc (1, sizeof(BRKey));
        return (jlong) key;
    }
    

    生成公钥

    可用助记词或序列

    src\main\jni\breadwallet-core\Java\root\com\breadwallet\core\BRCoreMasterPubKey.java
    
    private static native long createJniCoreMasterPubKeyFromPhrase (byte[] phrase);
    
    private static native long createJniCoreMasterPubKeyFromSerialization(byte[] pubKey);
    

    调用的是 jni c库

    /*
     * Class:     com_breadwallet_core_BRCoreMasterPubKey
     * Method:    createJniCoreMasterPubKeyFromPubKey
     * Signature: ([B)J
     */
    JNIEXPORT jlong JNICALL
    Java_com_breadwallet_core_BRCoreMasterPubKey_createJniCoreMasterPubKeyFromSerialization
            (JNIEnv *env, jclass thisClass,
             jbyteArray serialization) {
        jsize serializationLength = (*env)->GetArrayLength (env, serialization);
        jbyte *serializationBytes = (*env)->GetByteArrayElements (env, serialization, 0);
        assert (serializationLength == sizeof(BRMasterPubKey));
    
        BRMasterPubKey *key = (BRMasterPubKey *) calloc (1, sizeof (BRMasterPubKey));
        memcpy(key, serializationBytes, sizeof(BRMasterPubKey));
    
        return (jlong) key;
    }
    

    相关文章

      网友评论

          本文标题:区块链椭圆加密及使用

          本文链接:https://www.haomeiwen.com/subject/xvsayqtx.html