首页 > 其他分享 >姚氏百万富翁问题——多方安全计算

姚氏百万富翁问题——多方安全计算

时间:2022-11-23 10:45:03浏览次数:36  
标签:姚氏 return 张三 李四 百万富翁 多方 key primes

姚氏经典百万富翁问题
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

相关文章