姚氏经典百万富翁问题
1.张三和李四各有i,j财富
2.李四选取一个大整数x并加密得到K,并用K减去财富j得到c,把c发送给张三
3.张三把计算 c+1、c+2...c+o并解密,随后用这10个数模除一个适当的整数p得到
d....dio(要保证d, = x mod p)
4.张三对前i 企.d不动,从第i+1个后每个加1,发送给李四
5.李四计算x mod p 与d,比较,如果相等说明d;,属于前i个数,可以知道i>=j,如果不相
等说明dj,属于i后面的数,则i>j.
完整源代码可以关注公众号回复百万富翁问题代码即可
# SimpleRSA.py # 简单的RSA生成公私钥的算法 # -*- coding: utf-8 -*- import random from collections import namedtuple # 返回范围内的一个素数列表(start, stop) def get_primes(start, stop): if start >= stop: return [] primes = [2] for n in range(3, stop + 1, 2): for p in primes: if n % p == 0: break else: primes.append(n) while primes and primes[0] < start: del primes[0] return primes # 判断是否为相对质数 def are_relatively_prime(a, b): """ 如果“a”和“b”是两个相对质数,则返回“True”。 如果两个数没有公因数,它们就是质数。 """ for n in range(2, min(a, b) + 1): if a % n == b % n == 0: return False return True # 获取私钥和公钥 def make_key_pair(length): if length < 4: raise ValueError('cannot generate a key of length less than 4 (got {!r})'.format(length)) n_min = 1 << (length - 1) n_max = (1 << length) - 1 start = 1 << (length // 2 - 1) stop = 1 << (length // 2 + 1) primes = get_primes(start, stop) while primes: p = random.choice(primes) primes.remove(p) q_candidates = [q for q in primes if n_min <= p * q <= n_max] if q_candidates: q = random.choice(q_candidates) break else: raise AssertionError("cannot find 'p' and 'q' for a key of length={!r}".format(length)) stop = (p - 1) * (q - 1) for e in range(3, stop, 2): if are_relatively_prime(e, stop): break else: raise AssertionError("cannot find 'e' with p={!r} and q={!r}".format(p, q)) for d in range(3, stop, 2): if d * e % stop == 1: break else: raise AssertionError("cannot find 'd' with p={!r}, q={!r} and e={!r}".format(p, q, e)) pkey = PublicKey(p * q, e) skey = PrivateKey(p * q, d) return pkey, skey # 加密 class PublicKey(namedtuple('PublicKey', 'n e')): __slots__ = () def encrypt(self, x): return pow(x, self.e, self.n) # 解密 class PrivateKey(namedtuple('PrivateKey', 'n d')): __slots__ = () def decrypt(self, x): return pow(x, self.d, self.n)
# Billion.py # 百万富翁问题 主程序 # -*- coding: utf-8 -*- from SimpleRSA import * import random public_key, private_key = make_key_pair(12) # safe for n<100 A = random.randint(1, 9) B = random.randint(1, 9) def safeCmpAleB(a, b): print("\n假设张三有 i={} 亿,李四有 j={} 亿".format(a, b)) print("\n张三生成一对RSA公私钥:") print("公钥(n,e): {}".format(public_key)) print("私钥(n,d): {}\n".format(private_key)) x = random.randint(1000, 2000) print("Step 1:李四随机选取一个大整数:{} ".format(x)) K = public_key.encrypt(x) print("\t\t李四利用张三公开的公钥对大整数进行加密得到密文K: ".format(K)) print("\t\t然后李四将 c=K-j({}-{}={}) 发送给张三\n".format(K, b, K - b)) c = K - b p = 29 d = [] for i in range(c + 1, c + 11): d.append((private_key.decrypt(i) % p)) print("Step 2:张三用自己的私钥对 c+1至c+10 进行加密:") print("\t\t{}".format(d)) for i in range(a, 10): d[i] = d[i] + 1 print("\t\t对c+i+1至c+10执行+1操作,得到:") print("\t\t{}".format(d)) print("Step 3:计算 x mod p 是否等于 d[j]. \n\t\t如果是, i>=j,即张三比李四富裕\n\t\t否则,i<j,即李四比张三富裕\n") print("\t\t计算:d[j] = {}, x mod p = {}".format(d[b - 1], x % p)) if x % p == d[b - 1]: return print("\t\t此次结果:i>=j,张三比李四富裕") else: return print("\t\t此次结果:i<j,李四比张三富裕") if __name__ == '__main__': safeCmpAleB(A, B)
举个例子:
假设张三有 i=5 亿,李四有 j=7 亿
张三生成一对RSA公私钥:
公钥(n,e): PublicKey(n=3589, e=5)
私钥(n,d): PrivateKey(n=3589, d=2765)
Step 1:李四随机选取一个大整数:1688
李四利用张三公开的公钥对大整数进行加密得到密文K:
然后李四将 c=K-j(1007-7=1000) 发送给张三
Step 2:张三用自己的私钥对 c+1至c+10 进行加密:
[23, 26, 0, 18, 14, 14, 6, 17, 26, 26]
对c+i+1至c+10执行+1操作,得到:
[23, 26, 0, 18, 14, 15, 7, 18, 27, 27]
Step 3:计算 x mod p 是否等于 d[j].
如果是, i>=j,即张三比李四富裕
否则,i<j,即李四比张三富裕
计算:d[j] = 7, x mod p = 6
此次结果:i<j,李四比张三富裕
用一个前辈的化学解释:先在一不透光试管中加入未知量的水
A女士量取她年龄那么多毫升的1mol/L的HCl 加入试管
B女士量取她年龄那么多毫升的1mol/L的NaOH 加入试管
然后用Ph试纸就可判断谁的年龄大了
量取之后可以用水稀释至相同体积(比如40mL)这样就不怕泄露了
标签:姚氏,return,张三,李四,百万富翁,多方,key,primes From: https://www.cnblogs.com/hndreamer/p/16917544.html