【区块链】椭圆曲线数字签名算法(ECDSA)

news2024/11/18 17:43:43

本文主要参考:

一文读懂ECDSA算法如何保护数据
椭圆曲线数字签名算法

1. ECDSA算法简介

  ECDSAElliptic Curve Digital Signature Algorithm 的简称,主要用于对数据(比如一个文件)创建数字签名,以便于你在不破坏它的安全性的前提下对它的真实性进行验证。
  你不应该将 ECDSA 与用来对数据进行加密的 AES(高级加密标准)相混淆。ECDSA 不会对数据进行加密、或阻止别人看到或访问你的数据,它可以防止的是确保数据没有被篡改。
  ECDSA 原理非常简单,有一个数学方程,在图上画了一条曲线,然后你在这条曲线上面随机选取了一个点作为你的 原点 G。接着你产生了一个 随机数 k,作为你的 私钥,最后你用上面的 随机数 k原点 G 通过一些复杂的魔法数学方程得到该条曲线上面的第二个点,这是你的 公钥 P

  当你想要对一个文件进行签名的时候,签名本身由两部分组成,称为 r 和 s 。通过 私钥k(随机数) 和文件的 哈希 组成一个魔法数学方程,这将给出你的签名的 s 部分。取 公钥 P 的 x 轴即为签名的 r 部分。为了验证签名的正确性,你需要 公钥 P 和签名 s、r组成一个魔法数学方程,该方程计算会得到一个坐标点,如果该坐标点的 x 轴刚好为签名中的 r,那么即可认为改签名是有效的。

2.椭圆曲线密钥生成

  像 y 2 = x 3 + a x + b y^2 = x^3 +ax+b y2=x3+ax+b 这样的式子通常画出来是个椭圆曲线,如下图所示:

  画一条直线与椭圆曲线产生三个交点(P、Q、-R),我们称 P + Q = R,R 即为 -R 关于x轴的对称点(请注意这里的 + 实际指的是第三个交点的 x 轴对称点)。
  若以椭圆曲线的某一切点 G 做一直线,则直线与椭圆曲线的另一交点即为 -2G,其关于x轴对称点即为 2G 点,若 2G 点与 G 点连接即可得到 3G 点,以此类推,即可得到 kG 点。
  引入 G 点的好处是可以实现快速寻找,我们以 G 点做切线即可得到 2G 点,以 2G点为切线即可得到 4G 点,以此类推,这样的寻找过程,大大的减少了寻找次数。

  椭圆曲线还有一个特性就是,我们以 G 为起点经过 k 次寻找后,得到 kG 点这一顺序计算过程是比较简单的,但如果我们已知 G 点要得到 kG 点是经过多少次寻找得到的是比较困难的,我们只能对 k 一个一个尝试,当 k 比较大时,k 的寻找过程是及其困难的,因此,这一过程是ECDSA算法背后安全性的基础,而这一原则也被称为 单向陷门函数

比特币的椭圆曲线一般是采用以下函数:
y 2 = x 3 + 7 , a = 0 , b = 7 y^2 = x^3+7,a=0,b=7 y2=x3+7a=0,b=7
开始的节点 Generator(G) 坐标为:
G x = 0 x 79 B E 667 E F 9 D C B B A C 55 A 06295 C E 870 B 07029 B F C D B 2 D C E 28 D 959 F 2815 B 16 F 81798 Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gx=0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
G y = 0 x 483 A D A 7726 A 3 C 4655 D A 4 F B F C 0 E 1108 A 8 F D 17 B 448 A 68554199 C 47 D 08 F F B 10 D 4 B 8 Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 Gy=0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8
私钥 k 一般是选择比较大的随机数,通过开始节点 G 与私钥 k,我们即可得到公钥节点 P

3.椭圆曲线数字签名实现

  假设Alice要给Bob发送消息 M,Alice 根据 起始点 G 与选择的 随机数(私钥) k 可得到 公钥 P,然后用 私钥 k 与 要发送的消息M的哈希值 HASH(M) 相乘得到 s,然后将要发送的信息 M 与 s 一同发送给 Bob。Bob得到信息后,通过Alice的 公钥 PHash(M) 相乘得到 Y,然后将 s 与 G 相乘得到X,如果X=Y则改签名即为有效,具体过程如下图所示:
在这里插入图片描述
X=Y合理性证明:
X = H a s h ( M ) ∗ P = H a s h ( M ) ∗ k ∗ G = s ∗ G = Y X=Hash(M) * P=Hash(M)*k*G=s*G=Y X=Hash(M)P=Hash(M)kG=sG=Y
  虽然以上过程实现了数字签名,但是以上的签名过程是存在一定漏洞的,因为 Bob 得到的数据有 Alice 的公钥 P、s、以及起始坐标 G,根据 G 与 P 是推断不出私钥 k 的,但是 k 可由 s 计算得到 k = s / H a s h ( M ) k = s/Hash(M) k=s/Hash(M),因此,科学家为其又想了新的办法。

签名过程:

  • 随机产生一个随机数 e ,通过计算得到 e G = Q eG = Q eG=Q
  • 随机产生一个随机数 k 作为私钥,计算得到 k G = P kG = P kG=P P P P 即为公钥,然后记录下 P P P x x x 坐标记为 r r r
  • 利用 SHA1 计算要传递信息 M M M 的哈希值 z z z
  • 利用方程 s = ( z + e ∗ r ) / k s = (z+e*r)/k s=(z+er)/k 计算得到 s s s
  • 要传递的数据即为 原始数据MM的Hash值zrs

验证过程:

  计算 z ∗ G s + r ∗ Q s = P \frac{z*G}{s}+\frac{r*Q}{s} = P szG+srQ=P ,若左右相等,则即为有效签名。

签名验证过程:
在这里插入图片描述

验证以上公式有效性:
z ∗ G s + r ∗ Q s = z ∗ G + r ∗ Q s = z ∗ G + r ∗ e ∗ G s = ( z + r ∗ e ) ∗ G s = ( z + r ∗ e ) ∗ G ∗ k ( z + r ∗ e ) = k G = P \begin{aligned} \frac{z*G}{s}+\frac{r*Q}{s}&=\frac{z*G+r*Q}{s}\\&=\frac{z*G+r*e*G}{s}\\&=\frac{(z+r*e)*G}{s}\\&=\frac{(z+r*e)*G*k} {(z+r*e)}\\&=kG\\&=P\end{aligned} szG+srQ=szG+rQ=szG+reG=s(z+re)G=(z+re)(z+re)Gk=kG=P
由于两侧求得的都为坐标,比较 x 轴即可。

  以上签名过程中被外界所指的参数有 公钥P公钥Q起始点Grs,我们可以看到在上面可由 s 求出密钥 k 的漏洞在现在的签名中不存在了,因为 s = ( z + e ∗ r ) / k s = (z+e*r)/k s=(z+er)/k,其中有两个未知参数 e 与 k,所以此签名过程比上面的更加完备了。

  由于计算过程中所得数据要在规定的字节范围内,所以在实际代码中要进行取模运算。

4. 代码实现

  以下是使用 go 语言实现的ECDSA算法的签名与认证:
签名:

func (ecc *MyECC) Sign(msg []byte, secKey *big.Int) (*Signature, error) {
	// 随机产生随机数k作为私钥
	k,error := newRand()
	if error != nil {
		return nil, error
	}
	
	// 对要传递的消息msg进行hash运算得到z
	z_bytes := crypto.Keccak256(msg)
	z := new(big.Int).SetBytes(z_bytes)
	z.Mod(z, N)
	
	//计算得到私钥k的公钥P,并求出其x坐标作为r
	P := Multi(G,k)
	r := new(big.Int).Mod(P.X,N)
	
	// 计算要传递的参数s
	s := new(big.Int).Mul(r, secKey)
	s.Add(s, z)  
	s.Mul(s, Inv(k, N))  
	s.Mod(s, N)  

	// 传递s与r
	s_r := &Signature{s, r}

	return s_r, nil
}

验证:

func (ecc *MyECC) VerifySignature(msg []byte, signature *Signature, pubkey *Point) bool {
	// 获得s与r
	s, r := signature.s, signature.r
	
	// 获得传递信息msg的hash值z
	z_bytes := crypto.Keccak256(msg)
	z := new(big.Int).SetBytes(z_bytes)
	z.Mod(z, N)
	
	// 使用费马小定理求得1/s
	s_inv := Inv(s, N)
	
	// 取u = z/s
	u := new(big.Int).Mul(z,s_inv)
	u.Mod(u, N)
	
	// 取v = r/s
	v := new(big.Int).Mul(r,s_inv)
	v.Mod(v, N)
	
	// 计算u*G与v*Q
	uG := Multi(G,u)
	vQ := Multi(pubkey,v)

	// 计算u*G+v*Q得到R,并取出其x轴
	R := Add(uG,vP)
	Rx := new(big.Int).Mod(R.X,N)
	
	// 比较判断是否相同
	if Rx.Cmp(r)==0{
		return true
	}else{
		return false
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1629699.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Maven的仓库、周期和插件

优质博文:IT-BLOG-CN 一、简介 随着各公司的Java项目入库方式由老的Ant改为Maven后,相信大家对Maven已经有了个基本的熟悉。但是在实际的使用、入库过程中,笔者发现挺多人对Maven的一些基本知识还缺乏了解,因此在此处跟大家简单地…

SpringCloud系列(19)--将服务消费者Consumer注册进Consul

前言:在上一章节中我们把服务提供者Provider注册进了Consul,而本章节则是关于如何将服务消费者Consumer注册进Consul 1、再次创建一个服务提供者模块,命名为consumerconsul-order80 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选…

使用CubeMx配置GD32F303系列单片机进行DMA ADC

原理图查看 查原理图可以看到GD32F103C8T6的官方开发板GD32303C-START-V1.0的PA1没有接任何东西 使用PA1作为ADC端口 CubeMX配置ADC和时钟 配置ADC通道 启用循环模式 配置此通道ADC分频 配置ADC DMA为循环模式 配置时钟 生成项目 Keil里面的配置 选择对应的GD32型号 编译…

2024全新瀚海跑道:矢量图片迅速养号游戏玩法,每天一小时,日转现200

最初我注意到这种玩法,是因为最近在浏览各大平台的视频时,我发现了一种特殊类型的账号,其养号成功率高达90%。这些账号发布的视频内容和数据非常夸张,而且制作起来非常简单,任何人都可以轻松上手。这些账号主要发布矢量…

堆与优先队列——练习题

1. 数据流中的第 K 大元素 代码实现: 思路:创建一个大小为 k 的小顶堆,堆顶元素就是第 K 大元素 typedef struct {int *__data, *data;int size;int n; } KthLargest;#define swap(a, b) { \__typeof(a) __c (a); \(a) (b); \(b) __c; \ }…

C++ 笔试练习笔记【1】:字符串中找出连续最长的数字串 OR59

文章目录 OR59 字符串中找出连续最长的数字串题目思路分析实现代码 注:本次练习题目出自牛客网 OR59 字符串中找出连续最长的数字串 题目思路分析 首先想到的是用双指针模拟,进行检索比较输出 以示例1为例: 1.首先i遍历str直到遍历到数字&a…

字符串类型漏洞之updatexml函数盲注

UPDATEXML 是 MySQL 数据库中的一个函数,它用于对 XML 文档数据进行修改和查询。然而,当它被不当地使用或与恶意输入结合时,它可能成为 SQL 注入攻击的一部分,从而暴露敏感信息或导致其他安全漏洞。 在 SQL 注入攻击中&#xff0…

CentOS 9 (stream) 安装 nginx

1.我们直接使用安装命令 dnf install nginx 2.安装完成后启动nginx服务 # 启动 systemctl start nginx # 设置开机自启动 systemctl enable nginx# 重启 systemctl restart nginx# 查看状态 systemctl status nginx# 停止服务 systemctl stop nginx 3.查看版本确认安装成功…

Pytorch实现线性回归模型

在机器学习和深度学习的世界中,线性回归模型是一种基础且广泛使用的算法,简单易于理解,但功能强大,可以作为更复杂模型的基础。使用PyTorch实现线性回归模型不仅可以帮助初学者理解模型的基本概念,还可以为进一步探索更…

深信服超融合虚拟机备份报错显示准备备分镜像失败

问题:最近一段时间深信服超融合虚拟机在执行备份策略时总是报错,备份空间又还很富余。 解决办法: 1 删除备份失败虚拟机的所有备份 2 解绑该虚拟机的备份策略 可靠服务>>备份与CDP>> 找到备份策略>>点【编辑】>>…

刷机维修进阶教程---开机定屏 红字感叹号报错 写字库保资料 救砖 刷官方包保资料的步骤方法解析

在维修各种机型 中经常会遇到开机定屏 进不去系统,正常使用无故定屏进不去系统或者更新降级开机红色感叹号的一些故障机。但顾客需要报资料救砖的要求,遇到这种情况。我们首先要确定故障机型的缘由。是摔 还是更新降级 还是无故使用重启定屏等等。根据原因来对症解决。 通过…

springboot3整合redis

redis在我们的日常开发中是必不可少的&#xff0c;本次来介绍使用spring boot整合redis实现一些基本的操作&#xff1b; 1、新建一个spring boot项目&#xff0c;并导入相应的依赖&#xff1b; <dependency><groupId>org.springframework.boot</groupId><…

基于YOLOV8+Pyqt5无人机航拍太阳能电池板检测系统

1.YOLOv8的基本原理 YOLOv8是一种前沿的目标检测技术&#xff0c;它基于先前YOLO版本在目标检测任务上的成功&#xff0c;进一步提升了性能和灵活性&#xff0c;在精度和速度方面都具有尖端性能。在之前YOLO 版本的基础上&#xff0c;YOLOv8 引入了新的功能和优化&#xff0c;…

PDF 正确指定页码挂载书签后,书签页码对不上

这个问题与我的另一篇中方法一样 如何让一个大几千页的打开巨慢的 PDF 秒开-CSDN博客 https://blog.csdn.net/u013669912/article/details/138166922 另做一篇原因是一篇文章附带一个与该文章主题不相关的问题时&#xff0c;不利于被遇到该问题的人快速搜索发现以解决其遇到的…

C++笔试强训day9

目录 1.添加逗号 2.跳台阶 3.扑克牌顺子 day9的题目都比较简单&#xff0c;就不赘述了 1.添加逗号 链接 我的思路很清晰也很简单易懂&#xff1a; 把输入数据存入字符串string s&#xff0c;定义一个string ret&#xff0c;然后逆置string s&#xff0c;将s中的数一个一个…

C#窗体控件ColorDialog

介绍 可以获取颜色&#xff0c;然后对其他控件的颜色属性进行设置。 构造方式 直接把ColorDialog控件拖动到Form窗口。 常用属性 AllowFullOpen 可以控制是否使用自定义颜色&#xff0c;true表示可使用&#xff0c;否&#xff0c;表示不可使用。 AnyColor 如果为tr…

C#给PDF加文字水印

安装iTextSharp包。 using iTextSharp.text.pdf; using iTextSharp.text; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks;namespace Pdf1 {internal class Program{public static v…

Python爬虫-BeautifulSoup解析

1.简介 BeautifulSoup 是一个用于解析 HTML 和 XML 文档的 Python 库。它提供了一种灵活且方便的方式来导航、搜索和修改树结构或标记文档。这个库非常适合网页抓取和数据提取任务&#xff0c;因为它允许你以非常直观的方式查询和操作文档内容。 2.安装 Beautiful Soup 终端输…

MyBatis面试题总结,详细(2024最新)

面试必须要看看 1、MyBatis 中的一级缓存和二级缓存是什么&#xff1f;它们的区别是什么&#xff1f; MyBatis 中的一级缓存是指 SqlSession 对象内部的缓存&#xff0c;它是默认开启的。一级缓存的生命周期是与 SqlSession 对象绑定的&#xff0c;当 SqlSession 关闭时&#…

PotatoPie 4.0 实验教程(25) —— FPGA实现摄像头图像直方图均衡变换

图像的直方图均衡是什么&#xff1f; 图像的直方图均衡是一种用于增强图像对比度的图像处理技术。在直方图均衡中&#xff0c;图像的像素值被重新分配&#xff0c;以使得图像的直方图变得更均匀&#xff0c;即各个像素值的分布更加平衡。这意味着直方图中每个像素值的频率大致…