主页 > imtoken安卓官网 > 以太坊系列三:以太坊的加密模块--以太坊源码学习

以太坊系列三:以太坊的加密模块--以太坊源码学习

imtoken安卓官网 2023-02-13 05:36:27

以太坊的加密模块

模块分为两部分,一是实现sha3,二是实现secp256k1(这也是比特币使用的签名算法)。 需要注意的是,secp256k1有两种实现方式,一种是依赖libsecp256k1,需要cgo,另一种是依赖github.com/btcsuite/btcd,这是一个用go语言实现的比特币客户端. 混帐

sha3模块

这个模块其实可以认为是一个计算sha3-256的函数,用法也很简单,就是在crypto中调用Keccak256以太坊算法,输出的是一个32字节的hash结果github

hash := crypto.Keccak256Hash([]byte("hello"))
//hash值:4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45

secp256k1 模块

以太坊算法_以太坊为什么叫以太坊_以太坊和以太经典未来哪个好

这个模块比较复杂。 如果要精炼源码,需要对密码学有更深入的了解,但其实使用起来还是比较简单的。

主要是签名、验证、公钥和以太坊地址转换算法

1.签名

secp256k1私钥地址长度为32字节256位,公钥地址长度为65字节,以太坊地址长度为20字节,ui

//签名
var testPrivHex = "289c2857d4598e37fb9647507e47a309d6133539bf21a8b9cb6df88fd5232032"

以太坊为什么叫以太坊_以太坊和以太经典未来哪个好_以太坊算法

//1.获取私钥 key, _ := crypto.HexToECDSA(testPrivHex) //2.对message进行hash msg := crypto.Keccak256([]byte("foo")) //3.对hash进行签名,注意签名对象只能是hash,而且长度真是32个字节的hash sig, err := crypto.Sign(msg, key)

以太坊算法_以太坊和以太经典未来哪个好_以太坊为什么叫以太坊

//sig:d155e94305af7e07dd8c32873e5c03cb95c9e05960ef85be9c07f671da58c73718c19adc397a211aa9e87e519e2038c5a3b658618db335f74f800b8e0cfeef4401 //签名结果长度和公钥长度相同

2.验证

要验证签名是否正确,需要公钥、哈希(对消息进行哈希处理的结果)和签名。 这里真正的验证是第三步以太坊算法,也就是公钥是否与个人相同,不像普通的RSA签名验证一样。 当然我们可以封装成func VerifySignature(pubKey,msg,sig []byte) errorcode 和RSA签名验证一样的形式

//1.从签名中提取公钥
recoveredPub, err := crypto.Ecrecover(msg, sig)

以太坊算法_以太坊为什么叫以太坊_以太坊和以太经典未来哪个好

//2.将公钥转换为长度为65的字节序列 recoveredPubBytes:=crypto.FromECDSAPub(recoveredPub) //3.校验这个公钥是否和个人公钥一致 if recoveredPubBytes!=myPubKey { ...... }

以太坊算法_以太坊为什么叫以太坊_以太坊和以太经典未来哪个好

3.公钥和地址的转换

在以太坊中,公钥并不直接作为账户地址,而是进行了简单的转换。 具体来说,它是散列(公钥)的最后 20 位数字。 这里的hash算法是sha3-256,用一行代码就可以表示对象

crypto.Keccak256(pubKey)[12:]

详细代码在crypto.go,获取

func PubkeyToAddress(p ecdsa.PublicKey) common.Address {
    pubBytes := FromECDSAPub(&p) //将pubkey转换为字节序列
    return common.BytesToAddress(Keccak256(pubBytes[1:])[12:]) //对字节序列进行hash并去后二十个字节,BytesToAddress实际上就是[32]byte
}