python 椭圆曲线加法_椭圆曲线上点的运算
https://aaron67.cc/2020/09/26/ec-point-operation/
对定义在有限域上的椭圆曲线
E
=
(
p
,
a
,
b
,
G
,
n
,
h
)
E = (p, a, b, G, n, h)
E
=
(
p
,
a
,
b
,
G
,
n
,
h
)
y
2
≡
x
3
+
a
x
+
b
(
m
o
d
p
)
y^2 \equiv x^3 + ax + b \pmod{p}
y
2
≡
x
3
+
a
x
+
b
(
m
o
d
p
)
本文将通过代码计算下面两个问题:
已知曲线上的点
P
=
(
x
P
,
y
P
)
P = (x_P, y_P)
P
=
(
x
P
,
y
P
)
和
Q
=
(
x
Q
,
y
Q
)
Q = (x_Q, y_Q)
Q
=
(
x
Q
,
y
Q
)
,求点
R
=
P
+
Q
R = P + Q
R
=
P
+
Q
已知整数
k
k
k
,求点
K
=
k
⋅
G
K = k \cdot G
K
=
k
⋅
G
比特币使用的椭圆曲线由
Secp256k1
标准定义,我们可以事先声明好这些参数,并实现一些基础方法。
import collections
EllipticCurve = collections.namedtuple('EllipticCurve', 'name p a b g n h')
curve = EllipticCurve(
name='Secp256k1',
p=0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f,
a=0,
b=7,
g=(0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798, 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8),
n=0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141,
h=1,
)
def on_curve(point):
"""Returns True if the given point lies on the elliptic curve."""
if point is None:
# None represents the point at infinity.
return True
x, y = point
return (y * y - x * x * x - curve.a * x - curve.b) % curve.p == 0
def negative(point):
"""Returns -point."""
assert on_curve(point)
if point is None:
# -0 = 0
return None
x, y = point
result = (x, -y % curve.p)
assert on_curve(result)
return result
点的(代数)加法
当
P
=
−
Q
(
x
Q
,
−
y
Q
m
o
d
p
)
P = -Q\ (x_Q, -y_Q \bmod{p})
P
=
−
Q
(
x
Q
,
−
y
Q
m
o
d
p
)
时,根据定义,
P
+
Q
=
0
P + Q = 0
P
+
Q
=
0
,结果为理想点(无穷远点)。
当
P
≠
−
Q
P \neq -Q
P
=
−
Q
时,有
x
=
(
m
2
−
x
P
−
x
Q
)
m
o
d
p
x = (m^2 - x_P - x_Q) \bmod{p}
x
=
(
m
2
−
x
P
−
x
Q
)
m
o
d
p
y
=
(
y
P
+
m
(
x
R
−
x
P
)
)
m
o
d
p
=
(
y
Q
+
m
(
x
R
−
x
Q
)
)
m
o
d
p
y = (y_P + m(x_R - x_P)) \bmod{p} = (y_Q + m(x_R - x_Q)) \bmod{p}
y
=
(
y
P
+
m
(
x
R
−
x
P
)
)
m
o
d
p
=
(
y
Q
+
m
(
x
R
−
x
Q
)
)
m
o
d
p
对于
m
m
m
,当
P
≠
Q
P \neq Q
P
=
Q
时,
m
=
(
y
P
−
y
Q
)
(
x
P
−
x
Q
)
−
1
m
o
d
p
m = (y_P - y_Q)(x_P - x_Q)^{-1} \bmod{p}
m
=
(
y
P
−
y
Q
)
(
x
P
−
x
Q
)
−
1
m
o
d
p
当
P
=
Q
P = Q
P
=
Q
时,
m
=
(
3
x
P
2
+
a
)
(
2
y
P
)
−
1
m
o
d
p
m = (3 x_P^2 + a)(2 y_P)^{-1} \bmod{p}
m
=
(
3
x
P
2
+
a
)
(
2
y
P
)
−
1
m
o
d
p
综上,
R
=
(
x
m
o
d
p
,
−
y
m
o
d
p
)
R = (x \bmod{p}, -y \bmod{p})
R
=
(
x
m
o
d
p
,
−
y
m
o
d
p
)
。
注意,在计算
m
m
m
时,用到了模
p
p
p
的除法(模逆元),相关概念及代码请参考之前的
文章
。
def add(p, q):
"""Returns the result of p + q according to the group law."""
assert on_curve(p)
assert on_curve(q)
if p is None:
# 0 + q = q
return q
if q is None:
# p + 0 = p
return p
#
# p == -q
#
if p == negative(q):
return None
#
# p != -q
#
x1, y1 = p
x2, y2 = q
if p == q:
m = (3 * x1 * x1 + curve.a) * modular_multiplicative_inverse(2 * y1, curve.p)
else:
m = (y1 - y2) * modular_multiplicative_inverse(x1 - x2, curve.p)
x = m * m - x1 - x2
y = y1 + m * (x - x1)
result = (x % curve.p, -y % curve.p)
assert on_curve(result)
return result
标量积(数乘运算)
标量积(scalar multiplication)的定义可以从加法扩展,其中
k
k
k
为正整数。
k
⋅
P
=
P
+
P
+
.
.
.
+
P
⏟
_
k
个
k \cdot P = \underbrace{P + P + ... + P}\_{k\ 个}
k
⋅
P
=
P
+
P
+
.
.
.
+
P
_
k
个
通过调用已实现的加法并循环累加结果,可以直接求得点
141
P
141P
1
4
1
P
的坐标,但这样要做 140 次加法运算。
因为椭圆曲线上点的加法,满足交换律和结合律,所以我们可以用“倍乘法”改进。将 141 用二进制表示
14
1
10
=
1000110
1
2
141_{10} = 10001101_{2}
1
4
1
1
0
=
1
0
0
0
1
1
0
1
2
也就是说
141
P
=
2
7
P
+
2
3
P
+
2
2
P
+
2
0
P
141P = 2^7P + 2^3P + 2^2P + 2^0P
1
4
1
P
=
2
7
P
+
2
3
P
+
2
2
P
+
2
0
P
改进后的计算过程为
计算
2
P
=
P
+
P
2P = P + P
2
P
=
P
+
P
,即
2
1
P
2^1P
2
1
P
计算
4
P
=
2
P
+
2
P
4P = 2P + 2P
4
P
=
2
P
+
2
P
,即
2
2
P
2^2P
2
2
P
计算
8
P
=
4
P
+
4
P
8P = 4P + 4P
8
P
=
4
P
+
4
P
,即
2
3
P
2^3P
2
3
P
……
计算
2
7
P
2^7P
2
7
P
计算
2
7
P
+
2
3
P
+
2
2
P
+
2
0
P
2^7P + 2^3P + 2^2P + 2^0P
2
7
P
+
2
3
P
+
2
2
P
+
2
0
P
得到
141
P
141P
1
4
1
P
只需要做 10 次加法运算。显而易见,随着
k
k
k
的增大,“倍乘法”能显著提升
k
⋅
P
k \cdot P
k
⋅
P
的计算效率。
def scalar_multiply(k, point):
"""Returns k * point computed using the double and add algorithm."""
assert on_curve(point)
if k % curve.n == 0 or point is None:
return None
if k < 0:
# k * point = -k * (-point)
return scalar_multiply(-k, negative(point))
# Double and add
result = None
while k:
if k & 1:
result = add(result, point)
point = add(point, point)
k >>= 1
assert on_curve(result)
return result
验证
我们使用之前
文章
中的例子,来验证一下代码的正确性。
if __name__ == '__main__':
a = 0xf97c89aaacf0cd2e47ddbacc97dae1f88bec49106ac37716c451dcdd008a4b62
print('a =', hex(a))
ag = scalar_multiply(a, curve.g)
print('x =', hex(ag[0]))
print('y =', hex(ag[1]))
运行结果为
a = 0xf97c89aaacf0cd2e47ddbacc97dae1f88bec49106ac37716c451dcdd008a4b62
x = 0xe46dcd7991e5a4bd642739249b0158312e1aee56a60fd1bf622172ffe65bd789
y = 0x97693d32c540ac253de7a3dc73f7e4ba7b38d2dc1ecc8e07920b496fb107d6b2
完整代码
参考
Elliptic Curve Cryptography: a gentle introduction
原文
译文
Elliptic Curve Cryptography: finite fields and discrete logarithms
原文
译文
python 椭圆曲线加法_椭圆曲线上点的运算相关推荐
- python 椭圆曲线加法_椭圆曲线密码学简介(一):实数域的椭圆曲线及其群运算规则...
经过前面几篇文章的介绍,相信对公钥密码学有所了解的各位应该已经听说过ECC,ECDH和ECDSA,ECC是椭圆密码学的简称,后面两个是基于椭圆密码学的具体算法. 目前我们可以在当前web和IT世界当中 ...
- python椭圆曲线加密算法_椭圆曲线加密中的加法乘法浅析
本文不深入椭圆曲线加密算法的全部知识,只针对椭圆曲线加密中需要用到的加法和乘法计算规则进行浅析. 实际练习中碰到一个比较简单密码学的问题,但是涉及到了椭圆曲线加密算法,题目描述如下: 已知椭圆曲线加密 ...
- python 椭圆曲线加密_椭圆曲线加解密算法Python3完整实现
信息安全课程的实验,根据课件及网上资料,参考实现 代码中注释比较完善,算法的实现整体流程如下: - 实现基本流程:考虑K=kG ,其中K.G为椭圆曲线Ep(a,b)上的点,n为G的阶(nG=O∞ ), ...
- python爬虫案例_推荐上百个github上Python爬虫案例
现在学生都对爬虫感兴趣,这里发现一些好的github开源的代码,分享给各位 1.awesome-spider 该网站提供了近上百个爬虫案例代码,这是ID为facert的一个知乎工程师开源的,star6 ...
- python 完全面向对象_史上最全的Python面向对象知识点疏理
原标题:史上最全的Python面向对象知识点疏理 面向对象技术简介 类: 用来描述具有相同的属性和方法的对象的集合.它定义了该集合中每个对象所共有的属性和方法.对象是类的实例.class 类变量:类变 ...
- python xgboost实战_史上最详细的XGBoost实战
0. 环境介绍 Python 版 本: 3.6.2 操作系统 : Windows 集成开发环境: PyCharm 1. 安装Python环境 安装Python 首先,我们需要安装Python环境.本人 ...
- 用python画篮球场_走上python自学的辛酸路
大学毕业一个不出名的211林业大学,面试总会被尴尬的问起你们的机械电子是针对林业么?毕业前收到格力.宇通等传统制造业的offer,但我就在毕业前班级晚会大醉后彻底想起了自己真的需要什么,还依稀记得那晚 ...
- python期末知识点_史上最全的Python知识点整理之基本语法
一.程序的格式框架 1.缩进 缩进是指每行语句前的空白区域,用来表示Python程序间的包含和层次关系. 一般语句不需要缩进,顶行书写且不留空白. 当表示分支.循环.函数.类等含义,在if,while ...
- python返回菜单_返回上一菜单
编辑:似乎人们不明白这一点... 我有三个不同的函数可以调用一个公共函数.如何根据用户角色从普通功能回到右上一个功能? 我有这样的登录功能:def login(): users = open('use ...
最新文章
- 机器学习平台跃迁,AI中台才是大势所趋
- Spring Boot 2.x基础教程:使用国产数据库连接池Druid
- 有限元基础: Jacobian 矩阵和高斯积分
- elasticSearch入门到java操作api一套搞定
- OllyDbg笔记-暴力破解简单判断程序(TraceMe.exe与简单Qt程序)
- android绘制论文,基于Android平台的三维地形绘制研究与实现
- xshell5产品秘钥
- VB.net 2010下关联与程序图标设置
- 指令系统相兼容的计算机称为系列机,第4章指令系统.ppt
- python如何从字符串中提取数字_如何在Python中从字符串中提取数字?
- Hello Juejin
- 前端网络基础-传输层UDP协议
- 微服务系统架构设计系列 - RateLimiter - 1. 限流器简介与一般算法
- windows获取公网IP,记录公网ip脚本和命令
- Java兔子生兔子问题
- 标签打印软件如何设置不规则标签纸
- openCV读入图片,openGL实现纹理贴图
- c语言调用json编程,c语言开发JSON - wangxuwei的个人空间 - OSCHINA - 中文开源技术交流社区...
- CSS 网页字体最佳实践
- 电脑32位和64位操作系统的区别
热门文章
- Linux驱动开发---杂项设备
- 怎样用sc命令运行服务器,windows中的sc控制服务命令
- Bumping制程简介
- acdream 1201 SuSu's Power dp
- commons-math3-3.6.1-org.apache.commons.math3.analysis.function-包下的类(三)-中英对照文档及源码赏析
- 用python搭建微商城_怎么搭建微商城?用什么系统好?
- Oracle 11g中文繁体特殊乱码问题解决
- JavaWEB(applicationjavabean封装)
- 【seaborn】jointplot 改变图片长宽比,非方形
- 干货!最全的AI速查表|神经网络,机器学习,深度学习