比特币ecdsa算法python
⑴ 比特币的原理吗
首先你要知道公钥和私钥的概念
2.比特币主要用了ECDSA,也就是椭圆曲线签名算法,这个算法有两个特性,注意这两点对下面至关重要
3.比特币其实没有钱包,只有交易账单,整个比特币就是交易账单
4.比特币的账户,就是一段公钥
⑵ 比特币钱包地址是如何得到的不是比特币地址而是钱包地址!
首先,你应该在大脑中想象出一个“钱包”的概念。你的bitcoin都放在你的“钱包”中一个钱包可以包含很多很多......很多个地址。地址的形式就是形如。
利用比特币钱包中生成的比特币地址你可以接收来自他人的比特币,你也可以将你帐户上的比特币转到他人的比特币地址上面。比特币地址就像银行卡号一样,具有支付、转账、提现功能,但在转账时,你只有知道别人的比特币地址才能进行比特币转账。
如果我们把比特币钱包简单比作成银行卡账户的话,那么比特币钱包地址就可以看成是银行卡账号。不同的是,比特币地址是可以不存储在网络上的,更是可以独立于你的钱包而存在的。
(2)比特币ecdsa算法python扩展阅读:
比特币地址是一串由 26位到34位字母和数字字符串组成的。 看上去像一堆乱码一样,说白了这个就像你的银行卡卡号一样。 通过区块链查可以查每个比特币地址的所有转账记录,公开透明。
比特币钱包地址生成:通过随机选出256位二进制数字,形成私钥,然后通过加密函数来生成地址。这个生成方向是单向的。也就是你知道了地址是无法通过解密方法来计算出私钥的。就目前的人类计算机运算能力无法破解,你可以很放心地把地址公布到网上。
参考链接:比特币|网络
⑶ python怎么安装ecdsa
貌似缺少依握渣好赖包。 先安装个python-pip 然后用pip install beautifulsoup 自段铅动搞梁做定依赖。
⑷ 3、数字签名(ECDSA)
比特币中使用的数字签名算法是椭圆曲线数字签名算法(Elliptic Curve Digital Signature Algorithm)或ECDSA。 ECDSA是用于基于椭圆曲线私钥/公钥对的数字签名的算法,如椭圆曲线章节[elliptic_curve]所述。 ECDSA用于脚本函数OP_CHECKSIG,OP_CHECKSIGVERIFY,OP_CHECKMULTISIG和OP_CHECKMULTISIGVERIFY。每当你锁定脚本中看到这些时,解锁脚本都必须包含一个ECDSA签名。
数字签名在比特币中有三种慎拿高用途:
● 第一,签名证明私钥的所有者,即资金所有者,已经授权支出这些资金。
● 第二,授权证明是不可否认的(不可否认性)。
● 第三,签名证明交易(或交易的具体部分)在签字之后没有也不能被任何人修改。
创建数字签名
在比特币的ECDSA算法的实现中,被签名的“消息”是交易,或更确切地说是交易中特定数据子集的哈希值(参见签名哈希类型(SIGHASH))。
签名密钥是用户的私钥,结果是签名:
((Sig = F{sig}(F{hash}(m), dA)))
这里的:
● dA 是签名私钥
● m 是交易(或其部分)
● F hash 是散列函数
● F sig 是签名算法
● Sig 是结果签名
ECDSA数学运算的更多细节可以在ECDSA Math章节中找到。
函数F sig 产生由两个值组成的签名Sig,通常称宽尺为R和S:
Sig = (R, S)
签名序列化(DER)
解锁脚本序列化之后:
1301
包含敏嫌以下9个元素:
● 0x30表示DER序列的开始
● 0x45 - 序列的长度(69字节)
● 0x02 - 一个整数值
● 0x21 - 整数的长度(33字节)
● R-
● 0x02 - 接下来是一个整数
● 0x20 - 整数的长度(32字节)
● S-
● 后缀(0x01)指示使用的哈希的类型(SIGHASH_ALL)
⑸ 理解椭圆曲线加密算法
椭圆曲线加密算法,即:Elliptic Curve Cryptography,简称ECC,是基于椭圆曲线数学理论实现的一种非对称加密算法。相比RSA,ECC优势是可以使用更短的密钥,来实现与RSA相当或更高的安全。据研究,160位ECC加密安全性相当于1024位RSA加密,210位ECC加密安全性相当于2048位RSA加密。
一般椭圆曲线方程式表示为:(其中a,b,c,d为系数)
> y2=ax3+ bx2+cx+d
典型的椭圆曲线如:y2=x3−4x2+16
先摆一个栗子:
小米很难算到的那个数,就是公钥密码算法中的私钥(一个公钥密码算法安全的必要条件(非充分)是“由公钥不能反推出私钥”),公钥密码算法最根本的原理是利用信息的不对称性:即掌握私钥的人在整个通信过程中掌握最多的信息。
椭圆曲线加密算法是一个基于加法阶数难求问题的密码方案。 对于椭圆曲线来讲,椭圆曲线的基点就是例子里面的5,而私钥就是基点的加法阶数(例子里面的11),公钥是基点(5)进行对应阶数的加法(11次)得到的结果(55)。
简单描述就是:G * k = K (G,K公开,k保密)
上述例子相对简单,椭圆曲线加密算法里的加法建立在 “有限域上的二元三次曲线上的点”上 ,组成一个“有限加法循环群”。具体的说,这个加法的几何定义如下图,两个点的加法结果是指这两点的连线和曲线的交点关于x轴的镜像。
如果我们从某一点出发(所谓的单位元,比如正整数域的1,代表一个空间里的最基本单元),不停做自增操作(所谓群操作,比如++),枚举出整个空间的集合元素。如图:
因此给定椭圆曲线的某一点G,从G出发,不停做切线,找对称点,依次得到-2G,2G,-4G,4G,-8G,8G... 。即:当给定G点时,已知x,求xG点并不困难。反之,已知xG点,求x则非常困难。即Q = NG,N就是我们的私钥,Q就是我们的公钥。
现在我们知道了公钥(Q)和私钥(N)的生成的原理,我们在看看椭圆曲线数字签名算法(ECDSA)的过程,椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟。ECDSA于1999年成为ANSI标准,并于2000年成为IEEE和NIST标准。
私钥主要用于 签名,解密 ;公钥主要用于 验签,加密 ,可以通过私钥可以计算出公钥,反之则不行。
公钥加密:公钥加密的内容可以用私钥来解密——只有私钥持有者才能解密。
私钥签名:私钥签名的内容可以用公钥验证。公钥能验证的签名均可视为私钥持有人所签署。
通常需要六个参数来描叙一个特定的椭圆曲线:T = (p, a, b, G, n, h).
p: 代表有限域Fp的那个质数 a,b:椭圆方程的参数 G: 椭圆曲线上的一个基点G = (xG, yG) n:G在Fp中规定的序号,一个质数。 h:余因数(cofactor),控制选取点的密度。h = #E(Fp) / n。
这里以secp256k1曲线(比特币签名所使用的曲线)为例介绍一下公私钥对的产生的过成。
secp256k1的参数为:
本质上ECDSA的私钥就是一个随机数满足在曲线G的n阶里及k∈(0,n),根据Q=kG可以计算出公钥,生成的私钥一般为32字节大小,公钥通常为64个字节大小。如:
ECDSA签名算法的输入是数据的哈希值,而不是数据的本身,我们假设用户的密钥对:(d, Q);(d为私钥,Q为公钥) 待签名的信息:M; e = Hash(M);签名:Signature(e) = ( r, s)。
签名接口:
验证接口:
一个例子:
⑹ ECDSA的最简理解
y^2 = (x^3 + a * x + b) mod p
上述的曲线是在整数,一定bit数量(假设是160bit)内可以表达的,p是 160bits内可以表示的大整数。
为什么是这种曲线定义呢,我个人觉得有3个原因:
在椭圆曲线上随意取两个点 A,B,连接A,B两个点的直线与曲线的新的交点称为C,C关于X对称的-C点表示为 A+B。
乘法可以用加法表示,但是算法复杂堵是 log(n)。
其实为什么选择上述的椭圆曲线实际上是由这个加法规则选出来的,总是要求解这个新的交点更加简单。
R=k*P 的性质,已知R与P的值,无法推出k的值, 而知道k值于P值是很容易计算R值(log(n))。这是ECDSA签名算法的理论基础。
如何利用这个门限函数来做一个签名算法呢?
一个顺理成章的想法是: 给验证人一个 R和P,那只有签名人才能提供K,那K是不是老掘乱可以作为一个签名指纹呢?
ok,咱先生成一个公私钥对, Qa = dA * G , Qa 就是公钥, dA 是一个随机数,就当是一个私钥吧,当然这个椭圆曲线的 a , b , p , G 值都是要公开的。这个 G 就是椭圆曲线上随机挑选的一个节点,我们叫原点,也是要公开的。
每次对一个数据做签名,都随机生成一个随机数 K 吧, P = K * G 。咱们把 P的x轴坐标R作为签名的一部分。另一部分签名数据叫 S 。侍档
显然这个 S 既要和 dA 相关,也要和被签名的信息 z 相关。我们就假定:
S = Sig(dA, G, z, R, K) , 那这个函数就是签名函数。
而验证函数应该只有 S,R ,而不会有 K,dA
P = h(S, G, z, R) , h 就是签名函数。
密码学专家想到了一个实现:
S = k^-1 (z + dA * R) mod p
k^-1 表示的是关于p的模逆元。( k^-1 * k mod p = 1)。
可以推倒初验证函数:
==> k = S^-1 (z + dA * R) mod p
==> k*G = S^-1 (z + dA * R) *G
==> P = S^-1*z*G + S^-1*dA*R*G
==> P = S^-1*z*G + S^-1*R*Qa
对于验证者来说,需要计算: S^-1*z*G + S^-1*R*Qa 的x坐标是否就是 R 。
go的椭圆曲线 a 为固定的-3, 而 b 可以自由的选择,而p224, p256曲线的其实指的是 曲线的bit位数是224和256。
算法实现着为了更加快速散歼地执行曲线上的加法和乘法,对笛卡尔坐标做了投射成(x,y,z)的雅各布坐标,投射关系:
可以加速在雅各布坐标系上的运算,在需要最终结果的时候再投射回笛卡尔坐标系。
一个曲线的表示:
公私钥对的表示:
可以看出曲线,公钥,私钥拥有的信息越来越全。
公钥是 曲线信息+ dA*G的信息。
私钥是 公钥信息 + dA信息。
美国国安局发布的曲线其实是 secp256k1 , 对于其参数其实没有很好的解释,大家猜测是国安局找到了这是一条弱化的椭圆曲线,因此BTC在设计之初也没有采用这个曲线,而是用了 Koblitz Curve , b 是7, a 是0,btcsuit的package中,对 KoblitzCurve 是golang的 curvparam 的一层封装(主要是为了加速),但是有更多的参数, 是因为a和b等参数都是预先设定的,增加更多的参数来加速计算。至于公私方法和golang基本一样。
Ed25519 从某种意义上来说也属于椭圆曲线密码学,不同的是它采用扭曲爱德华兹曲线作为椭圆曲线,同时采用的签名机制也不同于 ECDSA 算法。EdDSA 的重要实现 ED25519 是 Daniel J. Bernstein 等人设计的 EdDSA 算法,采用的曲线参数完全公开,并说明了参数选取的意义,保证曲线中并未内置后门。
曲线:
y^2 = (x^3 + x^2 + {一个很大的随机数}x ) mod p
他生成公私钥的流程有一些区别,seed作为私钥,seed计算出的hash值去和G相乘得到公钥,为了防止多次计算,把这部分公钥扩展到私钥的后面作为一个完整的私钥。计算签名的时候,普通ecdsa会生成一个随机数K,而ec25519为了避免伪随机数被猜测到,因此是私钥和msg的hash值作为这个随机数。
⑺ 我了解到生成比特币地址的十个步骤, 求问:第一步生成私钥是随机生成呢,还是根据你的比特币数量信息
矿工你好
⑻ 比特币基础知识 你绝对想不到
椭圆曲线数字签名算法
椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线对数字签名算法(DSA)的模拟,该算法是构成比特币系统的基石。
私钥
非公开,拥有者需安全保管。通常是由随机算法生成的,说白了,就是一个巨大的随机整数,32字节,256位。
大小介于1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之间的数,都可以认为是一个合法的私钥。
于是,除了随机方法外,采用特定算法由固定的输入,得到32字节输出的算法就可以成为得到私钥的方法。于是,便有了迷你私钥(Mini Privkey),原理很简单,例如,采用SHA256的一种实现:
private key = SHA256()1
迷你私钥存在安全问题,因为输入集合太小,易被构造常见组合的彩虹表暴力破解,所以通常仿轮纳还是使用系统随机生成的比较好,无安全隐患。
公钥
公钥与私钥是相对应的,一把私钥可以推出唯一的公钥,但公钥却无法推导出私钥。公钥有两种形式:压缩与非压缩。
早期比特币均使用非压缩公钥,现大部分客户端已默认使用压缩公钥。
这个貌似是比特币系统一个长得像feature的bug,早期人少活多代码写得不够精细,openssl库的文档又不足够好,导致Satoshi以为必须使用非压缩的完整公钥,后来大家发现其实公钥的左右两个32字节是有关联的,左侧(X)可以推出右侧(Y)的平方值,有左侧(X)就可以了。
现在系统里两种方式共存,应该会一直共存下去。两种公钥的首个字节为标识位,压缩为33字节,非压缩为65字节。以0x04开头为非压缩,0x02/0x03开头为压缩公钥,0x02/0x03的选取由右侧Y开方后的奇偶决定。
压缩形式可以减小Tx/Block的体积,每个Tx Input减少32字节。
签名
使用私钥对数据进行签署(Sign)会得到签名(Signature)。通常会将数据先生成Hash值,然后对此Hash值进行签名。签名(signature)有两部分组成: R + S。由签名(signature)与Hash值,便可以推出一个公钥,验证此公钥,便可知道此签名是否由公钥对应的私钥签名。
通常,每个签名会有三个长度:73、72、71,符合校验的概率为25%、50%、25%。所以每次签署后,需要找出符合校验的签名长度,再提供给验证方。
地址
地址是为了人们交换方便而弄出来的一个方案,因为公钥太长了(130字符串或66字符串)。地址长度为25字节,转为base58编码后,为34或35个字符。base58是类似base64的编码,但去掉了易引起视觉混淆的字符,又在地址末尾添加了4个字节校验位,保障在人们交换个别字符错误时,也能够因地址校验失败而制止了误操作。
由于存在公钥有两种形式,那么一个公钥便对应两个地址。这两个地址都可由同一私钥签署交易。
公钥生成地址的算法:
Version = 1 byte of 0 (zero); on the test network, this is 1 byte of 111
Key hash = Version concatenated with RIPEMD-160(SHA-256(public key))
Checksum = 1st 4 bytes of SHA-256(SHA-256(Key hash))
Bitcoin Address = Base58Encode(Key hash concatenated with Checksum)1234
下图是非压缩公钥生成地址的过程:
对于压缩公钥生成地址时,则只取公钥的X部分即可。
推导关系
三者推导关系:私钥
公钥
两个地址。过程均不可逆。拥有私钥便拥有一切,但通常为了方便,会把对应的公钥、地址也存储起来。
交易
比特币的交易(Transation,缩写Tx),并不是通常意义的桐散交易,例如一手交钱一手交货,而是转账。交易由N个输入和M个输出两部分组成。交易的每个输入便是前向交易的某个输出,那么追踪到源头,必然出现一个没有输入的交易,此类交易称为CoinBase Tx。CoinBase类备没交易是奖励挖矿者而产生的交易,该交易总是位于Block块的第一笔。
拥有一个输入与输出的Tx数据:
Input:
Previous tx:
Index: 0
scriptSig:
241501
Output:
Value: 5000000000
scriptPubKey: OP_DUP OP_HASH160
OP_EQUALVERIFY OP_CHECKSIG12345678910
一旦某个Tx的第N个输出成为另一个Tx的输入,那么该笔比特币即为已花费。每个交易有唯一Hash字符串来标识,通过对交易数据做两次SHA256哈希运算而来:
Tx Hash ID = SHA256(SHA256(Tx Data))1
矿工费
矿工费(Transaction Fee)是鼓励矿工将Tx打包进Block的激励报酬。计算一笔交易的矿工费:
Transaction Fee = SUM(Inputs amount) - SUM(Outputs amount)1
每笔Tx的矿工费必然大于等于零,否则该笔Tx即为非法,不会被网络接收。
数据块
数据块(Block)是存储Block Meta与Tx的地方。Block的第一笔Tx总是CoinBase Tx,因此Block中的交易数量总是大于等于1,随后是这段时间内网络广播出来的Tx。
找到合适的Block是一件非常困难的事情,需要通过大量的数学计算才能发现,该计算过程称为“挖矿”。首个发现者,会得到一些比特币作为奖励。
数据链
多个Block连接起来成为数据链(Block Chain)。
为了引入容错与竞争机制,比特币系统允许Block Chain出现分叉,但每个节点总是倾向于选择最高的、难度最大的链,并称之为Best Chain,节点只认可Best Chain上的数据。
首个Block称为Genesis Block,并设定高度为零,后续每新增一个Block,高度则递增一。目前是不允许花费Genesis Block中的比特币的。
每个Block中的Tx在此Block中均唯一
一个Tx通常只会在一个Block里,也可能会出现在多个Block中,但只会在Best Chain中的某一个Block出现一次
货币存储
比特币是密码货币、纯数字化货币,没有看得见摸得着的硬币或纸币。一个人持有比特币意味着:
其拥有一些地址的私钥
这些地址是数笔交易的输出,且未花费
所有货币记录均以交易形式存储在整个blockchain数据块中,无交易无货币。货币不会凭空产生,也不会凭空消失。遗失了某个地址的私钥,意味着该地址上的Tx无法签署,无法成为下一个Tx的输入,便认为该笔比特币永久消失了。
货币发行
既然所有交易的输入源头都是来自CoinBase,产生CoinBase时即意味着货币发行。比特币采用衰减发行,每四年产量减半,第一个四年每个block的coinbase奖励50BTC,随后是25btc, 12.5btc, 并最终于2140年为零,此时总量达到极限为2100万个btc。
减半周期,严格来说,并不是准确的四年,而是每生成210000个block。之所以俗称四年减半,是因为比特币系统会根据全网算力的大小自动调整难度系统,使得大约每两周产生2016个block,那么四年约21万块block。
该函数GetBlockValue()用于计算挖得Block的奖励值:
int64 static GetBlockValue(int nHeight, int64 nFees)
{
int64 nSubsidy = 50 * COIN;
// Subsidy is cut in half every 210000 blocks, which will occur approximately every 4 years
nSubsidy = (nHeight / 210000);
return nSubsidy + nFees;
}123456789
当达到2100万btc以后,不再有来自CoinBase的奖励了,矿工的收入来源仅剩下交易的矿工费。此时,每个block的收入绝对值btc很低,但此时比特币应当会非常繁荣,币值也会相当的高,使得矿工们依然有利可图。
杜绝多重支付
传统货币存在多重支付(Double Spending)问题,典型的比如非数字时代的支票诈骗、数字时代的信用卡诈骗等。在比特币系统里,每笔交易的确认均需要得到全网广播,并收录进Block后才能得到真正确认。每笔钱的花销,均需要检测上次输入交易的状态。数据是带时间戳的、公开的,BlockChain由巨大的算力保障其安全性。所以比特币系统将货币的多重支付的风险极大降低,几近于零。通过等待多个Block确认,更是从概率上降低至零。一般得到6个确认后,可认为非常安全。但对于能影响你人生的重大支付,建议等待20~30个确认。
匿名性
任何人均可以轻易生成大量的私钥、公钥、地址。地址本身是匿名的,通过多个地址交易可进一步提高匿名性。但该匿名性并不像媒体宣传的那样,是某种程度上的匿名。因为比特币的交易数据是公开的,所以任何一笔资金的流向均是可以追踪的。
不了解比特币的人为它的匿名性产生一些担忧,比如担心更利于从事非法业务;了解比特币的人却因为它的伪匿名性而苦恼。传统货币在消费中也是匿名的,且是法律保障的,大部分国家都不允许个人涂画纸币。
地址本身是匿名的,但你可以通过地址对应的私钥签名消息来向公众证明你拥有某个比特币地址。
其他名词
哈希
哈希(Hash)是一种函数,将一个数映射到另一个集合当中。不同的哈希函数映射的空间不同,反映到计算机上就是生成的值长度不一样。同一个哈希函数,相同的输入必然是相同的输出,但同一个输出却可能有不同的输入,这种情况称为哈希碰撞。
常见的哈希函数有CRC32, MD5, SHA1, SHA-256, SHA-512, RIPEMD-160等,哈希函数在计算中有着非常广泛的用途。比特币里主要采用的是SHA-256和RIPEMD-160。
脑钱包纸钱包
前面提到过的脑钱包与纸钱包,这其实不算是钱包的分类,只是生成、存储密钥的方式而已。脑钱包属于迷你私钥的产物。脑钱包就是记在脑袋里的密钥,纸钱包就是打印到纸上的密钥,仅此而已。
有同学提到过,以一个计算机文件作为输入,例如一个数MB大小的照片,通过某种Hash运算后得到私钥的方法。这个方案的安全性还是不错的,同时可以防止盗私钥木马根据特征扫描私钥。文本形式存储私钥是有特征的,而一个照片文件却难以察觉,即使放在云盘等第三方存储空间中都是安全的。
⑼ ECDSA(椭圆曲线数字签名算法)
ECDSA(Elliptic Curve Digital Signature Algorithm)
在现实工作和生活中,我们使用签名的方式表达对一份文件的认可,其他人可以识别出你的签名并且无法伪造你的签名。数字签名就是对显示签名的一种电子实现,它不仅可以完全达到现实签名的特点,甚至能够做的更好。
常用的数字签名算法有RSA(Rivest-Shamir-Adleman Scheme)、DSS(Digital Signature Standard)等。 比特币使用ECDSA来生成账户的公私钥以及对交易和区块进行验证。
1.Alice(密码学中常用A到Z开头的人名代替甲乙丙丁等,字母越靠后出现频率越低)生成一对密钥,一个是sk(signing key),是非公开的;另一个是vk(verification key),是公开的。
这一对密钥同时生成,并且在数学上是相互关联的,同时,根据vk无法推测出关于sk的任何信息。
2.数字签名算法接收两个输出:信息M和sk,生成一个数字签名Sm
3.验证函数接收信息M、Sm以及vk作为输入,,返回结果是yes或者no。这一步的目的是为了验证你看到的针对信息M的数字签名确实是由Alice的sk来签发的,用于确认信息与签名是否相符。
与手写签名不同,手写签名基本都是相似的,但是数字签名却受输入影响很大。对输入轻微的改变都会产生一个完全不同的数字签名。一般不会对信息直接进行数字签名,而是对信息的哈希值进行签名。由加密哈希函数的无碰撞性可知,这样和对原信息进行签名一样安全。
在数学上,任何满足以下方程的点所形成的曲线称为随机椭圆曲线: 并且 ,a和b可以为任意值。下面展示几个随机椭圆函数的示例:
在了解如何通过基于secp256k1椭圆曲线的ECDSA算法生成公私钥之前,我们需要了解在随机椭圆曲线里,点的加法是如何实现的。
首先定义椭圆曲线上点的加法。设椭圆曲线上有两点,A和B点,那么作过这两点的直线与该曲线相交于第三点(C点),然后关于X轴对称得到D点,则D为这两个点的和,记作D=A+BD=A+BD=A+B。很明显,D点也在该曲线上。所以椭圆曲线上两点之和也是曲线上的点。
特例:
1.如果两点重合,则做该点的切线,与曲线相交点的对称点为和,即A+A=C
如图:
有了加法以后,乘法实现是不过是进行多次加法运算。有了一个基准点P以后,我们可以对其进行乘法运算,最后可以得到曲线上的另外一个点。
设PPP是椭圆曲线上的一个点,那么正整数kkk乘以点PPP的结果由下面的式子定义,注意式子中的加法是上面提到的椭圆曲线上点的加法:
点的运算满足结合律:
很显然,通过累加 的方式计算 是一种很笨的办法,其时间复杂度是线性的。上面我们提到过,椭圆曲线上点的加法是满足结合律的,即 ,扩展一下,就有
于是就有这么一种骚操作,比如计算 ,我们可以先计算 ;然后计算 ;再计算 ;最后计算 。这里我们把15次加法减少到了4次。
当然,k的值不可能总是2的幂。实际上上面的操作可以推广到k为任意正整数的情况。比如计算23P,首先计算 ,然后
因为 ,所以 。总共只需要7次加法。
分析一下,对于任意正整数k,我们都可以利用这个方法将计算k∗P所需的加法计算次数降低到
也就是说,从时间复杂度的角度来看,这个算法是一个 的算法。
这个方法被称为快速幂算法,原本常用于快速计算某个数的k次幂,这里将其推广到椭圆曲线点乘的快速计算中。
为什么要在介绍了椭圆曲线上点的乘法后突然冒出一个快速幂算法?快速幂算法对于椭圆曲线加密有什么意义?因为数学家/密码学家发现,利用快速幂算法计算 的时间复杂度是对数级的,但是要在知道 和 的前提下,倒推出 的值,没有比挨个尝试 的值快太多的算法。于是椭圆曲线加密依赖的数学难题就这么诞生了。
如果我们改一种记法,把椭圆曲线上点的加法记作乘法,原来的乘法就变成了幂运算,那么上述难题的形式跟离散对数问题应该是一致的。即:
所以这个难题叫椭圆曲线上的离散对数问题。
尽管两者形式一致,但是他们并不等价。实际上这个问题比大整数质因子分解(RSA)和离散对数(DH)难题都要难得多,目前还没有出现亚指数级时间复杂度的算法(大整数质因子分解和离散对数问题都有),以致于同样的安全强度下,椭圆曲线加密的密钥比RSA和DH的短不少,这是椭圆曲线加密的一大优势。
假设随机取一个 ~ 位之间的值x,计算 ,最后的结果一定会落在曲线上的一点。假设该点为 ,在公开 以及具体曲线的方程的情况下,能否反推出最初的随机值 ?
证:寻找 的过程只能通过暴力计算, 的可能值为 ~ 中的一个,平均来说需要计算 次能够找到一次 值。那么问题来了,运行一次 的计算需要多长的时间呢?
假设我们使用的是超级计算机,主频为 (一秒钟可以进行一万亿次运算),从宇宙诞生的那一刻开始计算,到现在也就进行了 次。找到 值的概率为 。这个概率和下一秒地球被巨型陨石撞击而毁灭的概率接近,既然我们读到了这里,那么说明这件事没有发生。
在上面的案例中, 是 ~ 位的一个随机数,可以作为私钥。 是随机椭圆曲线上的一个点,也就是由私钥生成的公钥,因此优点可以1得证。
但是密码学中,并不能使用上面介绍的实数域上的椭圆曲线。因为
所以我们需要引入有限域上的椭圆曲线。
要证明优点2,还需要将随机椭圆曲线做一些改动:为了保证最后计算出来的点的坐标值相加是512位,secp256k1引入了一个对质数取模的机制。具体来说,随机椭圆曲线从
变为了 其中 ,是小于 的最大质数。
此时的随机椭圆曲线函数图如下:
具体来说,就是向别人证明我知道 ,但不暴露 的任何信息。(有些类似于零知识证明)
证:前面介绍过结合律: 添加一个hash函数,简单修改可以得出: 使 ,那么可知 为 。此时方程为: 为了简单起见,我们记 和 。此时方程化简为: 上面这个方程是什么意思呢?
可以这样假设:在已知 的情况下,如果能够提供一个 和 满足上面的方程,就可以证明一个人拥有 。这个假设有一个前提,如果一个人不知道x,那么他就无法提供 和 满足上面的等式。
详细探讨这个前提:如果一个人不知道x,又想计算出 和 ,能够办到吗?结论是不能,首先我们无法从 计算出 (在有限时间内)。
还有一个问题:在已知 和 的情况下,能否计算出关于 的任何信息?
根据公式: 只要解出 就可以了。
要想计算出x,就需要知道r,但是在r没有公开的情况下,有什么办法可以计算r吗?我们知道R=r*P;但是根据这个公式无法倒推出r(刚才介绍的那个数学难题),所以x也是安全的。
至此,可以证明算法的第二个优点。