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

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zeke链上学堂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值