Solidity–如何实现椭圆算法签名(ECDSA)

椭圆算法签名

椭圆曲线算法签名(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(bytes32  messageHash, 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;
});

代码详分:

  1. 首先,通过 ethers.utils.solidityKeccak256 函数生成了一个消息哈希,该哈希是使用 Solidity 中的 keccak256 哈希函数生成的。

  1. 然后,生成了一个前缀字符串 "\x19Ethereum Signed Message:\n32",该字符串是用于标识该消息哈希是通过 Ethereum 数字签名算法签名的。

  1. 使用 ethers.utils.keccak256 函数对前缀字符串和消息哈希进行组合,生成一个最终的消息。

  1. 使用 ethers.utils.SigningKey 生成一个签名密钥,并使用该签名密钥签名最终的消息,生成签名(即 signature)。

  1. 最后,使用 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) {
    return  ecrecover(messageHash, v, r, s);
}**

代码详分:

这段代码执行了两个 Solidity 函数:hashMessageverifyEcrecover

  1. hashMessage 函数接收一个字节数组作为参数,并返回一个经过哈希处理后的字节数组的哈希值。该函数使用 keccak256 哈希函数对消息进行哈希处理,并使用 abi.encodePacked 函数将前缀 "\x19Ethereum Signed Message:\n32" 和消息一起打包。

  1. verifyEcrecover 函数接收四个参数:消息哈希,V 值,R 值和 S 值。该函数使用 ecrecover 函数从数字签名中恢复地址,并返回恢复的地址。

总的来说,该代码的目的是使用 Ethereum 椭圆曲线数字签名算法(ECDSA)验证数字签名的有效性

为什么要加 ” x19Ethereum Signed Message:n3”

这段字符串是在 Ethereum 中使用的椭圆算法签名的前缀,其目的是为了防止签名消息的修改。

在 Ethereum 中,使用的椭圆算法(ECDSA)是不安全的,因为签名消息可以被篡改。为了防止消息被修改,引入了这个前缀。前缀的作用是在签名之前,将原始消息加上前缀,这样在验证签名时,需要将原始消息加上前缀再验证,从而防止消息被篡改。

因此,椭圆算法签名验证中加上 "x19Ethereum Signed Message:n3" 这个前缀的目的是为了防止签名消息的修改,保证签名的安全性

扩展:

Hash

Hash 是一种数字摘要算法,用于将任意长度的数据映射为固定长度的数字。这个映射的结果称为散列值或哈希值。

Hash 算法的特点:

  1. 唯一性:对于不同的输入数据,hash 算法生成的散列值是不同的。

  1. 抗修改性:一个小的变更会导致散列值的大幅改变。

  1. 不可逆性:通过散列值不能推出原始数据

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇

)">
下一篇>>