椭圆算法签名
椭圆曲线算法签名(ECDSA)是一种数字签名算法,其基于椭圆曲线密码学(ECC)。它是一种非对称密码算法,即发送方和接收方都有不同的密钥。在数字签名中,发送方使用它的私钥对数据进行签名,以证明数据的完整性和发送方身份。接收方可以使用发送方的公钥验证签名,以确认数据没有被篡改。
ECDSA在许多方面都优于其他数字签名算法,例如RSA,因为它更加安全且计算效率更高。然而,它也有一些缺点,例如密钥长度必须比RSA大得多,以达到相同的安全级别。因此,选择使用ECDSA或其他签名算法取决于特定的使用情况和安全要求
场景
我目前举个项目中的例子
项目介绍:
L1如何保证链下提交的数据是真实有效性,并且防止被途中篡改?
解决办法:
使用椭圆算法签名,链上验证提交的数据是否真实并且是否是节点提交的.
主要的机制:
用于证明数字信息或文件真实性的数学方案。有效的数字签名使收件人有理由相信该信息是由已知的发件人(认证)创建的,发件人不能否认已发送的信息(不可否认),并且信息在传输过程中未被更改(完整性)
如何工作
数字签名是一种数学签名,由两部分组成。第一部分是使用私钥(签名密钥)从消息(交易)中 创建签名的算法。第二部分是允许任何人仅使用消息和公钥来验证签名的算法
第一步创建数字签名:
在以太坊实现的ECDSA中,被签名的“消息”是交易,或者更确切地说,来自交易的RLP编码数据的Keccak256哈希。签名密钥是EOA的私钥。结果是签名:
\(\(Sig = F_{sig}(F_{keccak256}(m), k)\)\)
其中:
_k_是签名私钥
_m_是RLP编码的交易
F**keccak256 是Keccak256哈希函数
F**sig 是签名算法
Sig 是由此产生的签名
函数 F**sig
产生一个由两个值组成的签名+Sig+,通常称为+R+和+S+:Sig = (R, S)
第二步验证签名:
要验证签名,必须有签名(R+和+S),序列化交易和公钥(与用于创建签名的私钥对应)。实质上,对签名的验证意味着“只有生成此公钥的私钥的所有者才能在此交易上产生此签名
签名验证算法采用消息(交易的散列或其部分),签名者的公钥和签名(+R+和+S+值),如果签名对此消息和公钥有效,则返回TRUE。
三种用途
签名证明私钥的所有者,暗示着以太坊账户的所有者,已经授权支付ether或执行合约
授权的证明是_undeniable_(不可否认)
签名证明交易数据在交易签名后没有也不能被任何人修改
实现
签名(前端)
let prefix = "\\x19Ethereum Signed Message:\\n32";let messageHash = ethers.utils.solidityKeccak256(["string", "address", "uint32", "address", "uint32", "bool"],["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266","0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",100000,"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",1,false]); let msg = ethers.utils.keccak256(ethers.utils.solidityPack(["string", "bytes32"],[prefix, messageHash]));let signingKey = new ethers.utils.SigningKey("0x");let signature = await signingKey.signDigest(msg);let { v, r, s } = signature; //verifyEcrecover(bytes32messageHash, uint8 v, bytes32 r, bytes32 s)let MeshData = await lock.verifyEcrecover(messageHash, v, r, s); }// We recommend this pattern to be able to use async/await everywhere// and properly handle errors.main().catch((error) => {console.error(error);process.exitCode = 1;});
代码详分:
首先,通过 ethers.utils.solidityKeccak256 函数生成了一个消息哈希,该哈希是使用 Solidity 中的 keccak256 哈希函数生成的。
然后,生成了一个前缀字符串 “\\x19Ethereum Signed Message:\\n32”,该字符串是用于标识该消息哈希是通过 Ethereum 数字签名算法签名的。
使用 ethers.utils.keccak256 函数对前缀字符串和消息哈希进行组合,生成一个最终的消息。
使用 ethers.utils.SigningKey 生成一个签名密钥,并使用该签名密钥签名最终的消息,生成签名(即 signature)。
最后,使用 lock.verifyEcrecover 函数验证签名是否有效,如果有效,则返回一个可信的数据(即 MeshData)。
总的来说,该代码的目的是生成并验证一个数字签名,以保证消息的完整性和不可更改性
验签(合约)
**function hashMessage(bytes memory message) public view returns (bytes32 messageHash) {messageHash = keccak256(abi.encodePacked("\\x19Ethereum Signed Message:\\n32", message));return messageHash;}function verifyEcrecover(bytes32 messageHash, uint8 v, bytes32 r, bytes32 s) public view returns (address recoveredAddress) {returnecrecover(messageHash, v, r, s);}**
代码详分:
这段代码执行了两个 Solidity 函数:hashMessage 和 verifyEcrecover。
hashMessage 函数接收一个字节数组作为参数,并返回一个经过哈希处理后的字节数组的哈希值。该函数使用 keccak256 哈希函数对消息进行哈希处理,并使用 abi.encodePacked 函数将前缀 “\\x19Ethereum Signed Message:\\n32” 和消息一起打包。
verifyEcrecover 函数接收四个参数:消息哈希,V 值,R 值和 S 值。该函数使用 ecrecover 函数从数字签名中恢复地址,并返回恢复的地址。
总的来说,该代码的目的是使用 Ethereum 椭圆曲线数字签名算法(ECDSA)验证数字签名的有效性
为什么要加 ” \x19Ethereum Signed Message:\n3”
这段字符串是在 Ethereum 中使用的椭圆算法签名的前缀,其目的是为了防止签名消息的修改。
在 Ethereum 中,使用的椭圆算法(ECDSA)是不安全的,因为签名消息可以被篡改。为了防止消息被修改,引入了这个前缀。前缀的作用是在签名之前,将原始消息加上前缀,这样在验证签名时,需要将原始消息加上前缀再验证,从而防止消息被篡改。
因此,椭圆算法签名验证中加上 “\x19Ethereum Signed Message:\n3” 这个前缀的目的是为了防止签名消息的修改,保证签名的安全性
扩展:
Hash
Hash 是一种数字摘要算法,用于将任意长度的数据映射为固定长度的数字。这个映射的结果称为散列值或哈希值。
Hash 算法的特点:
唯一性:对于不同的输入数据,hash 算法生成的散列值是不同的。
抗修改性:一个小的变更会导致散列值的大幅改变。
不可逆性:通过散列值不能推出原始数据
Hash种类
哈希算法有很多种,其中包括:
MD5 (Message-Digest Algorithm 5)
SHA-1 (Secure Hash Algorithm 1)
SHA-224
SHA-256
SHA-384
SHA-512
SHA-3
BLAKE2
HMAC (Hash-based Message Authentication Code)
RIPEMD (RACE Integrity Primitives Evaluation Message Digest)
Tiger
这些算法的安全性和效率各不相同,有的已经被攻破,不再被推荐使用,因此选择哈希算法时,需要考虑多方面的因素,包括安全性、效率、支持性等。
用途
为了隐藏起某些信息,且保证这些信息不被篡改,需要用到哈希算法。keccak256算法则可以将任意长度的输入压缩成64位16进制的数,且哈希碰撞的概率近乎为0
如果有遇到不懂得或者有疑问欢迎联系本人进行交流
WC:luo425116243