【安全多方计算】百万富翁问题

文章目录

  • 【安全多方计算】百万富翁问题
    • 【问题描述】
    • 【问题分析】
    • 【代码实现】
      • 【前导模块】
        • 1.判断素数
        • 2.求最大公约数
        • 3.求乘法逆元
        • 4.生成公钥和私钥
      • 【总体实现】
      • 【测试结果】

【问题描述】

​ 百万富翁问题是姚期智先生在1982年提出的第一个安全双方计算问题,两个百万富翁街头邂逅,他们都想炫一下富,比比谁更有钱,但是出于隐私,都不想让对方知道自己到底拥有多少财富,所以要在不借助第三方的情况下,知道他们之间谁更有钱。

【问题分析】

①这里假设Alice和Bob就是这两个百万富翁,Alice拥有财富i百万,Bob拥有财富j百万,假设他们两的财富都没有超过N百万,即1 ≤ i , j ≤ N,如下图所示:

②Alice随机选择一个大随机数x,用Bob的公钥加密后得到x的密文c,如下图所示:

③Alice将c-i发送给Bob(减去i是为了破坏密文c),如下图所示:

④Bob首先计算N个数:yu=DSKB(c-i+u), 其中u=1,2…N(这里加上u是为了能在yu的数列里面还原出被破坏的密文),然后随机选择一个大素数p,再计算N个数:zu=yu mod p, 其中u=1,2…N,如下图所示:

⑤接着Bob对于所有的0≤a≠b≤N,是否都满足|za-zb|≥2(如果小于2的话,就可能导致第⑥步里面的数串,zj+1+1,zj+2+1,…,zN+1和zj+1相等),若不满足,则重新选择大素数p并重新验证。如下图所示:

⑥如果满足,Bob将以下的N个数串和p:(z1,z2,…,zj,zj+1+1,zj+2+1,…,zN+1,p)一起发给Alice(这里从zj+1开始每一项+1是为了在第⑦步Alice验证的时候能得出正确的结论,而且也保护了Bob的隐私,不能泄露j的值),如下图所示:

⑦假设Alice收到这N+1个数的第i个数满足Zi=x(mod p),则结论是i≤j,否则i>j(对应第④步中的zu=yu mod p)。如下图所示:

【代码实现】

这部分的算法思想参考了csdn上Bertramoon的博客,只不过这里换成java实现。

【前导模块】

1.判断素数

public static boolean is_prime(int x) throws Exception {//判断素数if (x <= 1) {throw new Exception("0和1既不是素数也不是合数,x应为大于1的正整数");}for(int i = 2; i < (int) (Math.sqrt(x) + 1); i++) {if(x % i == 0) {return false;}}return true;}

2.求最大公约数

public static int gcd(int a,int b) {//求最大公约数if (b == 0) {return a;} else {return gcd(b, a % b);}

3.求乘法逆元

​ 首先,数学上的乘法逆元就是指直观的倒数,即 a 的逆元是 1/a,也即与 a 相乘得 1 的数。ax=1,则x是a的乘法逆元。

​ 这里我们讨论关于取模运算的乘法逆元,即对于整数 a,与 a 互质的数 b 作为模数,当整数 x 满足 ax mod b≡1 时,称 x 为 a 关于模 b 的逆元,代码表示就是a*x % b == 1

这部分的实现代码如下:

    public static int[] get_inverse(int a, int b){//        a*x = 1 mod b
//        b*y = 1 mod a
//        已知a、b,返回x, yif (b == 0) {int [] l = {1, 0};return l;} else {int [] r = get_inverse(b, a % b);int x1, x2, y1, y2;x2 = r[0];y2 = r[1];x1 = y2;y1 = x2 - ((int)a / b) * y2;int [] r2 = {x1, y1};return r2;}}

4.生成公钥和私钥

  1. 随机生成两个大素数p 、 q ( p ! = q ) ;

  2. n = p ∗ q , s = ( p − 1 ) ∗ ( q − 1 ) ;

  3. 随机取一个大整数e ,使得2 ≤ e ≤ s − 1且 g c d ( e , s ) = 1;

  4. 用扩展欧几里得算法求e 的乘法逆元 d ( e ∗ d = 1 m o d s , d > 0 ) ;

  5. 公钥为( n , e ),私钥为( n , d );

public static int [][] create_key() throws Exception {//        创建公钥和私钥int p, q, n, s;while (true) {p = new Random().nextInt(90) + 10;if (is_prime(p)) {break;}}while (true) {q = new Random().nextInt(90) + 10;if (is_prime(q) && q != p) {break;}}n = p * q;s = (p - 1)*(q - 1);int d,e;System.out.println("n="+String.valueOf(n)+",s="+String.valueOf(s));while (true) {e = new Random().nextInt(s - 3) + 2;if (gcd(e, s) == 1){d = get_inverse(e,s)[0];if (d>0){break;}}}int [][] r = {{n,e},{n,d}};return r;}

【总体实现】

import java.math.BigInteger;
import java.util.Random;
import java.util.Scanner;public class millionaire{public static void main(String[] args) throws Exception {//        Alice的财富为i,Bob的财富为j,取值为0~10
//        Alice选择一个随机大整数x
//        Alice和Bob约定使用RSA算法
//        Bob用RSA算法生成公钥和私钥,将公钥发给Alice
//        Alice使用Bob的公钥加密x得C=E(x),并发送C-i给Bob
//        Bob使用私钥计算Y(u) = D(C-i+u) (1<=u<=10)
//        Bob随机取一个小于x的大整数p,将Y(u) mod p得到Z(u),验证对所有Z(u)都满足0<Z(u)<p-1。若不满足则更换p重新计算
//        再将Z(u)从第j-1位开始向右均+1得到K(u),然后将K(u)和p发给Alice
//        Alice将K[i-1]与(x mod p)进行比较,如果相等,则说明i<j,即Alice不如Bob富有;若不相等,则说明i>=j,说明Alice比BOb富有或者和Bob一样富有Scanner input = new Scanner(System.in);System.out.print("Alice:");int i = input.nextInt();System.out.print("Bob:");int j = input.nextInt();int x;while (true) {x = new Random().nextInt(90) + 10;if (is_prime(x)){break;}}System.out.println("随机整数x="+String.valueOf(x));int [] pbk, pvk;int [][] r = create_key();pbk = r[0];pvk = r[1];System.out.println("公钥(n,e)=("+String.valueOf(pbk[0])+","+String.valueOf(pbk[1])+")\n"+"私钥(n,d)=("+String.valueOf(pvk[0])+","+String.valueOf(pvk[1])+")");int C = encrypt(x, pbk);System.out.println("Alice发送C-i="+String.valueOf(C - i)+"给Bob");int [] Y = new int[10];for(int u = 1; u<11;u++){Y[u - 1] = decrypt(C-i+u,pvk);}System.out.println("Y="+toS(Y).toString());int p = new Random().nextInt(x - 11) + 10;int [] Z = new int[10];while (true) {for(int u = 0; u<10;u++){Z[u] = Y[u] % p;}if(max(Z) < p -1 &&min(Z)>0){break;}p = new Random().nextInt(x - 11) + 10;}System.out.println("p="+String.valueOf(p)+"\nZ="+toS(Z).toString());for(int u=0;u<10;u++){if(u>=j+1){Z[u] = Z[u] + 1;}}System.out.println("k="+toS(Z).toString());if(Z[i-1] == x % p){if (i<j){System.out.println("Bob更富有");}else {System.out.println("验证错误,i应该大于j,Alice可能更富有,也可能和Bob一样富有");}}else {if (i >= j){System.out.println("Alice可能更富有,也可能和Bob一样富有");}else {System.out.println("验证错误,j应该大于i,Bob更富有才对");}}}public static StringBuffer toS(int []d){StringBuffer stringBuffer = new StringBuffer();stringBuffer.append("[ ");for (int i=0;i<d.length;i++){stringBuffer.append(d[i]);stringBuffer.append(" ");}stringBuffer.append(" ]");return stringBuffer;}public static int gcd(int n, int m){int z = 0;while (m%n != 0){z = m%n;m = n;n = z;}return n;}public static int max(int []d){int m = d[0];for (int i = 1; i<d.length;i++){if(m<d[i]){m = d[i];}}return m;}public static int min(int []d){int m = d[0];for (int i = 1; i<d.length;i++){if(m>d[i]){m = d[i];}}return m;}public static boolean is_prime(int x) throws Exception {if (x <= 1) {throw new Exception("0和1既不是素数也不是合数,x应为大于1的正整数");}for(int i = 2; i < (int) (Math.sqrt(x) + 1); i++) {if(x % i == 0) {return false;}}return true;}public static int[] get_inverse(int a, int b){//        a*x = 1 mod b
//        b*y = 1 mod a
//        已知a、b,返回x, yif (b == 0) {int [] l = {1, 0};return l;} else {int [] r = get_inverse(b, a % b);int x1, x2, y1, y2;x2 = r[0];y2 = r[1];x1 = y2;y1 = x2 - ((int)a / b) * y2;int [] r2 = {x1, y1};return r2;}}public static int [][] create_key() throws Exception {//        创建公钥和私钥int p, q, n, s;while (true) {p = new Random().nextInt(90) + 10;if (is_prime(p)) {break;}}while (true) {q = new Random().nextInt(90) + 10;if (is_prime(q) && q != p) {break;}}n = p * q;s = (p - 1)*(q - 1);int d,e;System.out.println("n="+String.valueOf(n)+",s="+String.valueOf(s));while (true) {e = new Random().nextInt(s - 3) + 2;if (gcd(e, s) == 1){d = get_inverse(e,s)[0];if (d>0){break;}}}int [][] r = {{n,e},{n,d}};return r;}public static int encrypt(int content, int [] pbkey){BigInteger c = new BigInteger(String.valueOf(content));BigInteger p0 = new BigInteger(String.valueOf(pbkey[0]));int r = (c.pow(pbkey[1]).mod(p0)).intValue();return r;
//        return (int)Math.pow(content, pbkey[1]) % pbkey[0];}public static int decrypt(int encrypt_content, int [] pvkey){BigInteger c = new BigInteger(String.valueOf(encrypt_content));BigInteger p0 = new BigInteger(String.valueOf(pvkey[0]));int r = (c.pow(pvkey[1]).mod(p0)).intValue();return r;
//        return (int)Math.pow(encrypt_content, pvkey[1]) % pvkey[0];}}

【测试结果】

ps:本人也是这方面知识的初学者,如果有什么认识不到位或者错误的地方恳请批评指正。

【安全多方计算】百万富翁问题相关推荐

  1. 安全多方计算——百万富翁问题

    安全多方计算(SMC)是解决一组互不信任的参与方之间保护隐私的协同计算问题,SMC要确保输入的独立性,计算的正确性,同时不泄露各输入值给参与计算的其他成员.主要是针对无可信第三方的情况下,如何安全地计 ...

  2. 百万富翁问题--安全多方计算

    百万富翁问题-安全多方计算 是由图灵奖获得者姚期智提出的. 有A.B两个富翁,A资产i亿元,B资产j亿元,i.j均在0-10范围内,在互不让对方知道自己资产的情况下,比较A和B的资产谁多谁少. 那么如 ...

  3. 安全多方计算之二:一文搞懂百万富翁问题

    百万富翁问题 1. 解决方案 2. 协议描述 3. 协议说明 4. 协议举例 两个百万富翁Alice和Bob想知道他们两个谁更富有,但他们都不想让对方及其他第三方知道自己财富的任何信息,这是由中国计算 ...

  4. 区块链BaaS云服务(14)华大BGI区块链“安全多方计算“

    数据流通安全一直是大数据时代难以解决的难题:在保护本地数据隐私安全的情况下,促进不同地区.不同机构间的数据共享与协同计算. 1. 定义 1.1 安全多方计算(SMC) 由图灵奖得主姚期智院士在 198 ...

  5. mpc 安全多方计算协议_BNC公链 | 不看到数据却能进行计算?一文了解安全多方计算...

    今天,数据可以用来分析复杂问题,提供解决方案,甚至解决无法回答的问题.但是,当涉及到利用数据为公众服务时,数据共享和数据保护之间往往存在着许多矛盾.而安全多方计算(MPC)如何在不泄露隐私数据的情况下 ...

  6. mpc 安全多方计算协议_HashKey:说透安全多方计算 MPC 技术方案、挑战与未来

    链闻 ChainNews 安全多方计算对网络信息安全与数据市场的发展具有重要价值. 撰文:钱柏均,就职于 HashKey Capital Research审校:邹传伟,万向区块链.PlatON首席经济 ...

  7. 安全多方计算与证券业数据生态

    区块链技术的出现,使得各方事务在去中心化的方式下协调执行,数据在不可篡改.公开验证的方式下共享,这种特性天然适合用以解决证券行业信息共享的问题.但是,在传统区块链系统中,事务涉及数据会为全体成员所公开 ...

  8. 什么是多方计算multi-party computation (MPC)

    文章目录 什么是多方计算multi-party computation (MPC) MPC和TEE比较 外包计算 安全模型 MPC问题分类 其他参考 什么是多方计算multi-party comput ...

  9. 安全多方计算 # 个人笔记

    一个优美令人如痴如醉的领域. Data is the oil of the 21st century 欢迎读者拍砖和提供本文修改建议.本文长期维护. 第二次编辑于2021/10/20,新增了部分阅读材 ...

最新文章

  1. python递归使用
  2. catia的vh轴怎么显示_Origin入门教程(三):Origin中曲线怎么平移?
  3. oracle主机名的脚本,一个开启Oracle服务和更改主机名的脚本-Oracle
  4. 单片机机器周期怎么计算公式_单片机定时器周期计算公式
  5. 自己总结的sql基本操作
  6. 浪潮成立Inspur DevOps Lab:以应用开发和平台服务打造开发者生态
  7. 微pe工具箱 系统安装教程_wepe启动盘制作教程|微pe工具箱怎么制作u盘启动盘
  8. 广东女子职业技术学院计算机应用技术,广东女子学院虚拟校园系统的构建与技术实现...
  9. linux 儒略日时间计算,儒略日计算公式的解读
  10. 乡下人生活录——程序员给自己买份保险吧
  11. 城市公交线路查询系统mysql_公交车路线查询系统后台数据库设计
  12. 软工网络15团队作业4——Alpha阶段敏捷冲刺之Scrum 冲刺博客(Day4)
  13. 038-拯救大兵瑞恩之 TiDB 如何在 TiKV 损坏的情况下恢复
  14. Latex去除正文中的章节编号但同时在目标中保留索引
  15. 理解深度学习中的学习率
  16. uniapp原生sdk插件极光短信·极光短信插件可快速对接收发短信·官方伙伴优雅草发布
  17. 光学变焦----景深=景深远界-景深近界
  18. 基于NLM的插值算法
  19. 【C++控制台实战】飞机大战控制台游戏源码
  20. DeepLearing—CV系列(十八)——图像分割之U-Net的Pytorch实现

热门文章

  1. unigui1.90.0.1555版本简易安装方式(delphi11)
  2. 真实评测:华为mate30epro和mate30的区别-哪个好
  3. HTML 字体标签 图片标签 列表标签 链接标签 div span 语义化标签 表格标签
  4. 街头智慧:罗杰斯的投资与人生
  5. splitter MP3 file
  6. java中支持mp3格式_可以播放mp3格式文件的机器,都遵守了什么协议,才能让mp3格式的文件可以:“一处保存,到处播放?...
  7. 电机控制电流环设计笔记
  8. XenApp / XenDesktop 7.6 初体验四 配置Win 8 模板和Personal vDisk
  9. 空间点数据分析与ArcGIS
  10. MySQL对Goup By的处理