“我有几个小秘密,成双成对告诉你”——异地可靠合同签署协议

上一篇文章介绍了“1/2不经意传输协议”。这个协议能达到的效果是,一个人可以发送两条信息给位于另一地的某个接收方,并且可以确信接收方只能获取其中一条信息,而接收方也可以确信,发送方不知道他获取的是哪一条信息。

这个协议解决的需求有点奇怪,它有什么实用价值吗?还真有,这个协议的发明者基于“1/2不经意传输协议”,开发了一个“远程合同签署协议”。但其中还有一个中间协议:交换部分秘密协议(Partial Secrect Exchange)。

这个中间协议,顾名思义,就是要解决异地安全可靠的交换一个秘密(后面会看到,实际上可靠交换的只是部分秘密,而非全部),这个协议是非常有用的,所以先解释一下这个协议。

生活中经常有这种场景,你需要与别人交换一个秘密。这个秘密可以是任何你认为有价值的信息,某人的工资、年龄,一张老照片,一段文字等等。正好你持有某个秘密,是某人想知道的。某人也持有某个秘密,是你想知道的,所以你们想交换秘密。

那么就会产生一个谁先给出秘密的问题。特别是当两个人不在同一地点,这个“谁先给”的问题就尤其棘手,因为谁都不能承受我的秘密给出去了,对方却没有把他的秘密给我的结局。这种场景里影视剧里看得太多了。

(上图:如何安全交换情报,一直是特工人员必须谨慎对付的问题,取自电视剧“潜伏”剧照)

现实中,有个常用的解决方法就是分部分交换秘密。比如,如果是钱货交易的话,那可以分批次给钱,对方分批次给货。这样,如果交易过程中一旦发现对方有欺诈行为,那么交易马上终止,及时止损。

对数字化的秘密信息来说,分部分交易就更合适了。理论上,对数字化的秘密,最小可以拆成1比特的长度进行交换,我给你一比特,你给我一比特交换,这下够安全了吧?一方如果欺诈,他也最多比对方多得到1比特的有用信息,这是几乎可以忽略不计的一个优势(或者对另一方的损失)。

这个思路很好,但是这样不能防范另一种形式的欺诈。有很多数字化的文件需要完整的文件才能打开查看。那么当你与对方按1比特的速率互相交换秘密的时候,你若无法在交换过程中对文件内容检查,而只能在对方声称完成信息交换后才能检查,若此时打开对方的文件,发现不是需要的信息,那你就要跳脚了。

所以,这里需要引入一个“可识别秘密”的概念,即有办法将这个秘密与其他无关或者你不在意的信息区分出来。简单来说,你知道,别人不知道,但是别人可以检查验证的信息,就是“可识别秘密”。比如“我妈妈的身份证号码”,就是一个“可识别秘密”。我知道我妈妈的身份证号码,他人不知道,并且别人可以拿着这个号码去身份验证系统上去检查。

数学上的一种可识别秘密是这样的:你自己生成两个大质数,然后两个数字乘积告诉对方。那么你手上的两个质数就是可识别秘密。因为对方知道这个乘积,但是以目前数学知识,分解大质数是很困难的。但是如果你把这个质数发给对方,对方很容易验证这两个质数乘积是否等于那个大数字。所以这也是一种“可识别秘密”。

那么,就有人设计了这样一种交换可识别秘密协议,前提是交换偶数个可识别协议,数字越大越安全。那我们先看看这个协议的过程,其中会用到上一期介绍的“1/2不经意传输”。然后分析一下为什么说它是安全的,安全到什么程度。

假设甲乙双方各持有相同数量的偶数个“可识别秘密”,并且每个秘密的长度是相同的,需要互相交换。我就以身份证号码为例,假设双方要交换10个身份证号码,身份证号码是可识别秘密,并且长度相同。

第一步是“不经意传输阶段”,甲乙双方各自将自己的10个号码任意配对,组合成5对。对这5对身份证号,以“1/2不经意传输”的方式,交替发送给对方(后面会看到,其实交替发送也是不必要的,可以全部一起发送)。那么根据之前的介绍,完成这一步骤时,双方已经互相交换了5个身份证号,但是双方都不能确切知道对方拿到的是哪个身份证号。

只能知道,对方在每一对身份证中,已经拿到了一个。并且交换过程中,你随时可以检查对方发过来的身份证号,上网查一下,身份证号是否正确。如果你发现对方给的不是你要的身份证号,或者不可识别,那么交换终止。此时,对方最多比你多持有一个身份证号。

第二步是“按比特交换阶段”。对这5对共10个号码,同时依次按比特位交换。即对这个10个号码,按位取1bit,一共10个bit,发送给对方,直到最后一个bit位发送完成。过程中,因为接收方已经持有了每一对号码中的一个,因此,当对方发来10个号码时,可以检查其中5个bit是否与你已经持有的那个号码吻合。如果不吻合,则证明对方在欺诈,马上终止协议。此时,对方最多比你在5个号码上,多得到1个bit位。

以上就是就是这个秘密交换协议的全过程。那分析一下,它有哪些特性。对交换秘密,最不希望的就是我把我的秘密给出去了,却没有拿到对方的秘密。从以上过程我们可以看出,第一阶段,对方最多比我多得1个号码,看上去还是可以接受的。并且在后文有关这个协议的应用中可以看到,该阶段无需交替发送,对方比我多得5个号码也是可以接受的。

第二阶段,对方最多比我多得5个bit位,这个差距就更小了。要指出一点的是,以上身份证号码并不是一个非常好的例子,因为身份号码的每一位之间有关联,很多位置上的数字是可以很容易猜测或计算的。所以,在实际应用中,这里的“可识别信息”应该都是长的随机数,那才是最安全的。至于如何让随机数成为可识别秘密,后面也会提到。

你可能会问,为啥不直接开始按比特传输呢?效果也差不多嘛,不也是最多对方多得一个秘密吗?这是好问题。答案在于,以上这个协议的目的,并不在于安全地交换所有秘密,而是在于,安全地交换至少一对秘密。这“一对秘密”是作为一个完整的信息实体,确保接收者得到的。也就是说,如果其中一方欺诈,他无法做到在自己获得至少一对秘密的情况下,让对方一对秘密也得不到。以下简单分析一下理由。

在第一阶段,双方对每一对秘密进行的是“1/2不经意传输”,那么每一方最多只能得到每一对秘密中的一个,而不会是全部。我们知道“1/2不经意传输”本身是有防止欺诈机制的,并且交换的信息都是可以识别的。每一方都可以检查收到的身份证号是否是约定的身份证号。若不是,则结束协议。不管怎样,任何一方都无法拿到完整一对秘密。

第二阶段,假设一方想欺诈,他想设法对让对方一对秘密也得不到,但是他会发现没法简单做到。因为欺诈方无法知道在上一轮传输后,对方具体收到了哪些秘密,所以他不知道可以在哪一个bit位上进行欺骗。他在某一对秘密上欺骗的成功概率是二分之一,但是他要在全部5对秘密上猜对的概率就只有1/32了。如果觉得这还不够安全,那么可以增加秘密的对数。秘密的对数越多,对方欺诈的成功率就越低。

这就是这个交换秘密协议的要点,它的效果是:双方交换n对秘密,如果双方诚信,则可以交换全部n对秘密。

如果一方欺诈,那么可以确保这样一种情况:如果欺诈方得到了对方的一对或若干对秘密,那么诚信方至少可以得到对方一对秘密,并且n越大协议越可靠。可以证明,如果欺诈方可以通过某种计算,花费一定时间算出诚信方的秘密,那么诚信方最多花4倍的时间,也可以算出欺诈方的至少一对秘密。所以,双方算力基本相等的情况,我们相信这个协议是安全的,这就是整个协议最终要达到的效果。

那这个协议有什么用呢?看上去好像不是很有用嘛?因为该协议交换的只能是偶数个可识别秘密,而只能保证至少一对秘密被交换。但如果我们能把一般的交换秘密问题转化为交换偶数个可识别秘密的问题,那就可以了。

所以我们来看一个以上协议的应用:“远程合同签署协议”。通常的合同签署,需要双方在一起,当场签字,互相交换签过字的合同。但是远程的话,就有一个签字先后问题。谁也不想先签字,因为怕自己签了对方不签,或者给别人去签,做其他坏事等等。

那考虑一下用密码学来解决以上问题。首先,密码学里,数字签名技术已经是很成熟了。数字签名的原理还是用之前提到过的非对称加密体系。如果一段文本是用我的某个私钥加密的,那么任何人都可以用我的公钥对其解密。如果解密出来的信息是:“我要执行某个合同……”,那么人们可以确信我是对这个合同签名了,因为这个原始的加密的信息只能是持有私钥的人才能产生,是无可抵赖的。所以某种意义上,数字签名比手写签名更可靠。

那么远程合同签署协议,就变成交换各自数字签名过的合同文本的过程。这个签名过的文本确实是一个可识别秘密,但是我们需要把它转化为偶数个可识别秘密,并且数量越多越好。怎么转化呢?其实也很简单。

因为身份证信息是可识别秘密,因此,我可以先声明并签署这样一段信息:


声明:

如果对方能够拿到以下10对身份证号中的至少一对号码:

  1. 我爸爸,我妈妈
  2. 我哥哥,我堂弟
  3. 我表妹1,我表妹2
  4. 我初中同桌,我高中同桌

我就执行以下合同:

……


当然这样太费身份证号了。所以,我们数学一点的方法是:


声明:

如果对方能够给出以下10对合数中,至少一对合数的质因子:

  1. 7990443202579378949,3764830991206009457

….

我就执行以下合同:

……


将以上文字用自己的私钥签名,发送给对方,最好还发在网上,广而告之。对方也做同样的事情,把类似信息发给你,同时广而告之。收到后,双方用对方的公钥解密,并检查一下对方的这段信息,确保没有猫腻。

然后把手上的10对大合数作为可识别秘密,执行上述交换秘密协议。如果双方诚信,那么双方应该在协议结束时,得到所有20个数字的某个因子,那么合同生效。

如果对方欺诈,根据之前的分析,我们知道,如果对方得到了我的某一对合数的因子,那我也应该可以在不长的时间内,同样计算出对方某一对合数的因子,从而确保双方同时签署了这个合同。

从这个过程中,也可以看出,交换秘密协议还是很有用的,因为理论上只要把任何一个交换秘密问题转化成交换若干对可识别秘密,就可以使用上述协议。而“可识别秘密”很容易构造的。

最后还要指出一点是,上文中用大数字的因子作为可识别秘密还是有一些小的缺陷,使得可以被用来欺诈,大家可以自己思考一下,怎么用来欺诈。另外,有人用以上这个秘密交换协议,实现了另一种远程猜硬币协议。远程猜硬币就是在网络上玩猜硬币,一个丢一个猜。怎么才能做到没有欺诈和抵赖呢?曾有人用量子物理特性设计了一个“量子猜硬币协议”,有点“大炮打蚊子了”。请你考虑下,如何使用以上交换秘密协议,实现一个防抵赖和欺诈的“远程猜硬币协议”。