六、电子签名设计举例
这里我们设计一种最为简单,极易被破解的电子签名算法。它虽然不安全,却能够很好地说明用公钥和私钥产生电子签名的基本原理。这段文字的目的在于让读者理解电子签名在数学层面上的实现过程。对数字天生反感的人可以跳过这一节。
比如说我现在有一对数字,7和3。我把7藏起来作为私钥,而把3作为公钥告知天下。
我随便写了一个数字,比如9,现在我要向天下人证明,这个9是我写的。
电子签名的基本思路是:把我所写的数字与我的私钥进行运算,得到的结果即为签名;任何人想要验证我的签名,只需把我得签名和我的公钥进行运算,所得到的应该就是数字本身。在这个运算过程中,内容、私钥、公钥、签名通过算法变成了紧紧相扣的统一体,任何一个部分稍加更改,整个运算就不再成立。公钥和私钥就是以这种方式来达到验证文件真伪的目的。
加密的过程是:把9加上我的私钥7,然后把结果去除以10,最后得到的余数就是被加密的数字。写成算式是:
(9 + 7) ÷ 10 = 1 余 6
现在我郑重地向世界宣布:这个数字9是我写的,我还为它做了防伪签名,这个签名是6。你们谁要是不相信,可以用我的公钥3去验证。
世上还真有好事之徒,他们看到我的宣告之后,立即进行了验证,验证的算法和我加密的算法一模一样,只不过他们是用签名6来验证数字9:
(6 + 3) ÷ 10 = 0 余 9
看,我把9用私钥7去签名,得到签名6,而人们把我的签名6用公钥3去验证,得到了我写的数字9,验证通过。
给一个一位数的数字签名很容易,假如是一串数字,比如说12345,该怎么签名?
我们可以先用一个算法把12345变成一位数的数字,比如说先做1 + 2 + 3 + 4 + 5 = 15,15依然大于10,于是重复此步骤做1 + 5 = 6。 6小于10,最后我把所得结果6用私钥加密成为签名:
(6 + 7)÷ 10 = 1 余3
在发送信息的时候,我需要把内容和签名一起发出去,例如用下面的格式:
12345(3)
信息中除了内容之外,还包含了括号中的签名。人们收到这则信息后,依然可以拿我的公钥3来验明正身信息的真假,步骤如下:
1 + 2 + 3 + 4 + 5 = 15
1 + 5 = 6
(3 + 3)÷ 10 = 1 余6
把信息本身的数字相加相加再相加,最后得出了6,用我的公钥3去验证签名3,最后也得出了6,所以人们得出结论:此消息的确为我所发。
为了帮助大家理解,让我们把上面的过程符号化。假设有信息X(长短任意),公钥A,私钥B,那么签名的过程就是:
现在假定有人写了一个文件23456,并想伪造签名,那么第一步他应该这么做:把23456相加相加再,直至得到一个小于10的数字2。接下来,因为他没有私钥7,所以无法把2 与私钥进行运算得出签名。但是他可以随意猜想签名是个什么数字,然后用公钥来验证。比方说,他假定签名是4,然后就可以用公钥3去验证,如果通过,那么证明他猜对了,伪造文件成功!如果验证通不过,就换一个假定继续试,直到试通了为止。
假如签名真像我们所举的例子这样只有一位数,那么它的确很容易被黑客用上述方法猜到。但是,如果我们把签名变为一个较大的数,比如说,一个256位的数字,那么黑客想要用上述方法猜出签名的可能性就非常低了。即使他使用当今世界上最强大的电脑,也恐怕得算上几亿年才能得到结果。假如哪个黑客真的有这样的恒心,那就让他去以此慢慢地消磨自己的时光吧。
七、矿工挖矿
老张为了向老王买烧饼,产生了一个交易文件,此文件被发到网上。那么是谁来核实文件的真伪,并最终把记录写进区块链中呢?答曰:是一群矿工。
矿工(Miner)是比特币网络里一群比较特殊的人,他们专门负责核对每笔比特币交易并把通过核对的交易记录在案。这个过程被称作挖矿(Mining)。
谁能成为矿工来担当这么重要的工作呢,有没有资格考试来挑选称职的人?有没有上岗培训?成为矿工的人是不是每年都要接受KPI考核?
答案是地球上的任何人,只要他/她愿意,都可以成为矿工,这其中当然包括我和你。因为只有这样,比特币才能摆脱掉中间的金融机构,成为一种全自由的货币。
那么普通人为什么要当矿工呢,他们会通过挖矿得到什么实实在在的好处吗?
是的,你每成功核实并记录一笔交易后,会有一定数量的比特币送给你作为酬报。这是所有矿工们至今仍在奋力挖矿的一个基本动力。由于比特币自诞生之日起对美元兑换率便开始不断走高,因而时至今日,那些早年便开始挖矿的矿工们应该早就赚得盆满钵满了。
矿工们的工作是什么呢?第一,他们要从网上收集诸如由老张所产生的那个交易文件。第二,拿到文件后,他们要用文件中的公钥去验证附在后面的签名。第三,他们要验证文件中所提到的区块记录仍然有效。第四,他们要验证交易文件中所写的金额是正确的。最后,他们要把这笔交易写到新的区块链中去。
验证签名,除了需要验证老张是公钥Z的主人之外,还得确保交易文件本身没有被更改过。
试想,老张产生了交易文件,并把它交给了老王。老王一看,文件里写着要付我六元钱。忽然,他脑子里闪过一个念头:既然文件是由我送到互联网上去,那么我何不就此做个手脚,把文件中的6改为8,那么我不就能神不知鬼不觉地多赚两元钱了吗?
或者,在老王把文件送到互联网上但尚未到达矿工手里之时,或许会有黑客入侵,把文件中老王的公钥W改成了自己的公钥H,那么钱会不会就被转到黑客的账号里去了呢?
如果您看过第六节里举的例子,就会知道,被篡改的文件在通过验证签名这一关时会轻易失效。
因为老张所作的电子签名其实是包含着原始文件中每一个字符的信息。哪怕就是改动原文的一个标点符号,解密也会失效。
老张的交易文件如下:
吾,公钥Z持有者,特授权将区块100第一笔交易所得金额之陆元整转入账号W,余下四元整转入账号Z (签名)
在签名时,首先老张会把“吾,公钥Z持有者……转入账号Z “这句话做数学运算,得出一个数字,假如说是1234。然后,他再用自己的私钥去加密1234,比如说他得到了WXYZ 。这个WXYZ便是他的电子签名。
在验证此文件时,矿工们需要用同样的算法把“吾,公钥Z持有者……转入账号Z “这句话做数学运算,得到1234,然后用公钥去解密签名WXYZ,假如这时我们也得到了1234,验证就通过了。
矿工们的任务就是把从网上收集而来的多个类似这样的交易文件编辑起来,形成一个新的区块,并将其加入区块链的链接中。加入之后,他/她还必须将新形成的区块链发放给网上所有其他矿工,只有当大多数矿工都开始使用新版本的区块链时,老张和老王之间的交易才算是正式确立。从此之后,老王便可以用从老张那里得到的6元钱去做新的消费了。
八、找钱及凑钱
在前面的例子里,老张向老王买烧饼需要6元钱,而他所使用的是从煤老板老钱那里得到的10元钱。余下的4元钱怎么办,是像我们平时买东西那样,让老张先付给老王10元钱,再由老王找给老张4元钱吗?
答案是不用那么麻烦,让我们仔细看看老张所产生的交易文件的后半段:
吾,公钥Z持有者,特授权……余下四元整转入账号Z (签名)
是的,老张的这个交易文件中其实含有两笔交易:一笔是把6元钱付给老王,另一笔是把余下的4元钱转给自己。因而,比特币的找钱是由买东西的人自我实现的。通过这次交易,区块链中产生了两个新的记录,一个记录归在老王名下(6元),另一个仍由老张所有(4元),这两个记录都可以被各自的主人继续消费。而原来归在老张名下的10元钱的记录由于已经被消费了,因而就不能再被使用。
假如老张看到老王6元钱的烧饼个儿太小,想用16元钱买另外一种豪华烧饼怎么办?有两种办法可以解决这个问题。其一,老张可以看看自己是否有过一笔收益大于或等于10元的交易,如果有,他就可以用那笔交易的收益去支付烧饼钱。其二,他还可以把两笔或多笔交易的钱凑在一起做一次性支付。例如,他可以把从煤老板老钱那里得到的10元钱和从油老板老财那里得到的6元钱组合起来购买老王的豪华烧饼,在交易书里他是这么写的:
吾,公钥Z持有者,特授权将区块99第五笔交易所得金额之陆元整转入账号W,区块100第一笔交易所得金额之拾元整转入账号W(签名)
比特币的基本原则是,一笔交易的金额只能被使用一次。假如你动用了任何一笔交易所得的金额,就必须当场把它全部用掉。至于拿多少钱去付账,多少钱作为找钱送回给自己,那完全是你自己的事情。
(待续)