隐私计算 2.3 基于中国剩余定理的秘密共享方案

1 简介

  • 作者:Asmuth和Bloom;
  • 时间:1983年;
  • 理念:基于中国剩余定理(CRT)。

2 具体实现

I 秘密分割算法

  • (1)选择 n n n个整数 d 1 , d 2 , … , d n d_1, d_2, \dots, d_n d1,d2,,dn, 满足:
    d 1 < d 2 < ⋯ < d n ; / / 严 格 递 增 ( d i , d j ) = 1 , i ≠ j ; / / 两 两 互 素 N = Π i = 1 t d i , M = Π i = n − t + 2 n d i , N > S > M \begin{array}{l} d_1 < d_2 < \dots < d_n; //严格递增 \\ (d_i, d_j) = 1, i \neq j; //两两互素\\ N = \Pi_{i = 1}^{t} d_i, M = \Pi_{i = n - t + 2}^{n} d_i, N > S > M \\ \end{array} d1<d2<<dn;//(di,dj)=1,i=j;//N=Πi=1tdi,M=Πi=nt+2ndi,N>S>M

  • (2)分别计算:
    S 1 = S   m o d   d 1 S 2 = S   m o d   d 2 … S n = S   m o d   d n \begin{array}{l} S_{1}= S \bmod d_1 \\ S_{2}= S \bmod d_2 \\ \dots \\ S_{n}= S \bmod d_n \\ \end{array} S1=Smodd1S2=Smodd2Sn=Smoddn

  • (3)第 i i i 个参与者计算 S i S_i Si作为其分享的秘密。

II 秘密重构算法

  • (1)收集任意 t t t个参与者的钥匙;

  • (2)分别计算:
    S 1 = S   m o d   d 1 S 2 = S   m o d   d 2 … S n = S   m o d   d n \begin{array}{l} S_{1}= S \bmod d_1 \\ S_{2}= S \bmod d_2 \\ \dots \\ S_{n}= S \bmod d_n \\ \end{array} S1=Smodd1S2=Smodd2Sn=Smoddn

  • (3)根据中国剩余定理,求解得到 S S S

3 实例

设秘密 S = 117 S = 117 S=117 n = 5 n = 5 n=5, t = 3 t = 3 t=3
I 秘密分割

  • (1)生成 n n n个互质的随机数,要求其中的 t t t个最小的随机数相乘的结果大于秘密 S S S t − 1 t - 1 t1个最大的随机数相乘的结果小于秘密 S S S。例如:

    d 1 = 4 d_1 = 4 d1=4 d 2 = 5 d_2 = 5 d2=5 d 3 = 7 d_3 = 7 d3=7, d 4 = 9 d_4 = 9 d4=9, d 5 = 11 d_5 = 11 d5=11

    其中 d 1 d 2 d 3 > S > d 4 d 5 d_1d_2d_3 > S > d_4d_5 d1d2d3>S>d4d5

  • (2)分别计算

S 1 = 117   m o d   4 = 1 S 2 = 117   m o d   5 = 2 S 3 = 117   m o d   7 = 5 S 4 = 117   m o d   9 = 0 S 5 = 117   m o d   11 = 7 \begin{array}{l} S_{1}= 117 \bmod 4 = 1 \\ S_{2}= 117 \bmod 5 = 2 \\ S_{3}= 117 \bmod 7 = 5 \\ S_{4}= 117 \bmod 9 = 0 \\ S_{5}= 117 \bmod 11 = 7 \\ \end{array} S1=117mod4=1S2=117mod5=2S3=117mod7=5S4=117mod9=0S5=117mod11=7

(3)将 ( S i , i ) (S_i, i) (Si,i)作为钥匙分发给第 i i i个参与者。

II 秘密重构

(1)收集任意 t = 3 t = 3 t=3个参与者的钥匙,例如第1个人的(1, 4),第2个人的(2, 5),第5个人的(7, 11);

(2)列出方程组
S   m o d   4 = 1 S   m o d   5 = 2 S   m o d   11 = 7 \begin{array}{l} S \bmod 4 = 1 \\ S \bmod 5 = 2 \\ S \bmod 11 = 7 \\ \end{array} Smod4=1Smod5=2Smod11=7

  • (3)按照中国剩余定理,计算 S = 117 S = 117 S=117

2.2.4 代码

#include 
#include 
#include 
#include "miracl.h"
#include 
#define SECRET_BITS 500		//秘密的位数 
#define N 5					//子秘密的个数n
#define T 3					//恢复秘密所需要的最少子秘密个数t
#define D_DIGBITS (((SECRET_BITS/T)+(SECRET_BITS/(T-1)))/2)	//di的位数,di的长度在B/t与B/(t-1)之间,使N(最小的前t个数的乘积)>k>M(最大的前t-1个数的乘积)
#define MAX_D ((N)*(D_DIGBITS)+(N))							// 定义大数系统的最大位数(稍微比N倍的d大就可以) 
big ki[N], di[N];
void zhongguo(big secret){
	int i, num[N];
	big x = mirvar(0);
	big one = mirvar(1);
	big m = mirvar(1);	//m是di连乘的乘积
	big Mit[N];			//Mi
	big Mit_1[N];		//Mi的逆
	big g1[N];			//中间变量,计算Mi*Mi的逆*ai(a1即Ki)

	printf("\n                                                     秘密恢复");
	printf("\n请选择%d个子秘密,输入序号1 - %d\n", T, N);
	for (i = 0; i < T; i++){
		scanf_s("%d", &num[i]);
		num[i]--;//使序号从1 - t ,转化为 0 - t-1,符合数组下标的实际情况
	}//of for i

	//初始化
	for (i = 0; i < N; i++){
		Mit[i] = mirvar(0);
		Mit_1[i] = mirvar(0);
		g1[i] = mirvar(0);
	}//of for i

	//m=di[num[i]]连乘
	for (i = 0; i < T; i++){
		multiply(m, di[num[i]], m);//di[num[i]]表示的就是中国剩余定理中的mi
	}//of for i
	
	//Mit[t]=m/di[num[i]],即计算Mi
	for (i = 0; i < T; i++){
		fdiv(m, di[num[i]], Mit[i]);//除法
	}//of for i

	//Mit_1为Mit的逆
	for (i = 0; i < T; i++){
		xgcd(Mit[i], di[num[i]], Mit_1[i], Mit_1[i], Mit_1[i]);//求逆运算,Mit_1为Mit在模di[num[i]]下的逆
	}//of for i

	//g1 = Mi t* Mit_1 * ki[ num[i] ]
	for (i = 0; i < T; i++){
		multiply(Mit[i], Mit_1[i], g1[i]);
		multiply(g1[i], ki[num[i]], g1[i]);
	}//of for i

	//x=g1[1]+g1[2]+...+g1[t]
	for (i = 0; i < T; i++){
		add(x, g1[i], x);
	}//of for i
	powmod(x, one, m, x);// x = x^1 mod m

	printf("\n");
	printf("秘密: \n");
	cotnum(x, stdout);
	printf("\n");

	//判断恢复的秘密与原秘密是否相同
	if (mr_compare(x, secret) != 0){
		printf("恢复的秘密与所给秘密不同!");
	}else{ 
		printf("恢复的秘密与所给秘密相同!");
	}//of if
	printf("\n");
}//of zhongguo

int main(){
	FILE* fp;
	char fpname[] = "s.txt";//文件名
	miracl* mip = mirsys(MAX_D, 10);//初始化大数系统,最大位数和进制
	big secret = mirvar(0);//秘密
	big one = mirvar(1);//big型数值1
	big a= mirvar(1);//代表D_DIGBITS位的10进制随机数
	big n= mirvar(1);//代表N=d1*d2*...*dt
	big m = mirvar(1);//代表M=d(n-t+2)*d(n-t+3)*...*dn
	int i;

	for (i = 0; i < N; i++){
		ki[i] = mirvar(0);//对每一个ki[]进行初始化
		di[i] = mirvar(0);//对每一个di[]进行初始化
	}//of for i

	//从文件中读秘密
	if ((fp = fopen(fpname, "r")) == NULL){
		printf("Fail to open the file\n");
		return -1;
	}else{
		cinnum(secret, fp);//从fp文件中把大数赋值给big型变量secret
		printf("                                                     秘密读取\n");
		cotnum(secret, stdout);//打印secret内容
		//挑选出五个素数,满足严格递增。只需要产生相邻的素数即可。
		printf("                                                     秘密分割");
		printf("\n产生的di:\n");
		bigdig(D_DIGBITS,10, a);//产生一个D_DIGBITS位的10进制随机数a
		i = 0;
		while (i != N) {
			add(a,one, a);//a=a+1
			if (isprime(a)){ //判断大数a是否为素数,为素数返回TRUE,否则返回FALSE
				absol(a, di[i]);//di=|a| 
				cotnum(di[i], stdout);
				printf("\n");
				i++;
			}//of if
		}//of while
		//求出子秘密
		printf("\n产生的子秘密为:\n");
		for (i = 0; i < N; i++) {
			ki[i] = mirvar(1);
			powmod(secret,one, di[i], ki[i]);//模幂运算,ki[i]=secret^1(mod di[i])
			printf("\n第%d个子秘密k%d为:\n", i + 1,i+1);
			cotnum(ki[i], stdout);
		}//of for i
		//打印N=d1*d2*...*dt
		for (i = 0; i < T; i++){
			multiply(di[i], n, n);
		}//of for i
		printf("\nN的值为:\n");
		cotnum(n, stdout);
		//打印M=d(n-t+2)*d(n-t+3)*...*dn
		for (i = N-1; i >(N-T); i--){
			multiply(di[i], m, m);
		}//of for i
		printf("\nM的值为:\n");
		cotnum(m, stdout);
		printf("\n");
		//进行秘密复原
		zhongguo(secret);
	}//of if

	return 0;
}//of main

你可能感兴趣的:(隐私计算,算法,安全,网络)