1 简介
- 作者:Asmuth和Bloom;
- 时间:1983年;
- 理念:基于中国剩余定理(CRT)。
2 具体实现
I 秘密分割算法
-
(1)选择nnn个整数d1,d2,…,dnd_1, d_2, \dots, d_nd1,d2,…,dn, 满足:
d1<d2<⋯<dn;//严格递增(di,dj)=1,i≠j;//两两互素N=Πi=1tdi,M=Πi=n−t+2ndi,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=n−t+2ndi,N>S>M -
(2)分别计算:
S1=Smodd1S2=Smodd2…Sn=Smoddn\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=Smodd2…Sn=Smoddn -
(3)第iii 个参与者计算SiS_iSi作为其分享的秘密。
II 秘密重构算法
-
(1)收集任意ttt个参与者的钥匙;
-
(2)分别计算:
S1=Smodd1S2=Smodd2…Sn=Smoddn\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=Smodd2…Sn=Smoddn -
(3)根据中国剩余定理,求解得到SSS。
3 实例
设秘密S=117S = 117S=117,n=5n = 5n=5, t=3t = 3t=3。
I 秘密分割
-
(1)生成nnn个互质的随机数,要求其中的ttt个最小的随机数相乘的结果大于秘密SSS,t−1t - 1t−1个最大的随机数相乘的结果小于秘密SSS。例如:
d1=4d_1 = 4d1=4,d2=5d_2 = 5d2=5,d3=7d_3 = 7d3=7, d4=9d_4 = 9d4=9, d5=11d_5 = 11d5=11;
其中d1d2d3>S>d4d5d_1d_2d_3 > S > d_4d_5d1d2d3>S>d4d5。
-
(2)分别计算
S1=117mod4=1S2=117mod5=2S3=117mod7=5S4=117mod9=0S5=117mod11=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)将(Si,i)(S_i, i)(Si,i)作为钥匙分发给第iii个参与者。
II 秘密重构
(1)收集任意t=3t = 3t=3个参与者的钥匙,例如第1个人的(1, 4),第2个人的(2, 5),第5个人的(7, 11);
(2)列出方程组
Smod4=1Smod5=2Smod11=7\begin{array}{l} S \bmod 4 = 1 \\ S \bmod 5 = 2 \\ S \bmod 11 = 7 \\ \end{array} Smod4=1Smod5=2Smod11=7
- (3)按照中国剩余定理,计算S=117S = 117S=117。
2.2.4 代码
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include "miracl.h"
#include <Windows.h>
#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]; //Mibig 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]],即计算Mifor (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 ipowmod(x, one, m, x);// x = x^1 mod mprintf("\n");printf("秘密: \n");cotnum(x, stdout);printf("\n");//判断恢复的秘密与原秘密是否相同if (mr_compare(x, secret) != 0){printf("恢复的秘密与所给秘密不同!");}else{ printf("恢复的秘密与所给秘密相同!");}//of ifprintf("\n");
}//of zhongguoint main(){FILE* fp;char fpname[] = "s.txt";//文件名miracl* mip = mirsys(MAX_D, 10);//初始化大数系统,最大位数和进制big secret = mirvar(0);//秘密big one = mirvar(1);//big型数值1big a= mirvar(1);//代表D_DIGBITS位的10进制随机数big n= mirvar(1);//代表N=d1*d2*...*dtbig m = mirvar(1);//代表M=d(n-t+2)*d(n-t+3)*...*dnint 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型变量secretprintf(" 秘密读取\n");cotnum(secret, stdout);//打印secret内容//挑选出五个素数,满足严格递增。只需要产生相邻的素数即可。printf(" 秘密分割");printf("\n产生的di:\n");bigdig(D_DIGBITS,10, a);//产生一个D_DIGBITS位的10进制随机数ai = 0;while (i != N) {add(a,one, a);//a=a+1if (isprime(a)){ //判断大数a是否为素数,为素数返回TRUE,否则返回FALSEabsol(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*...*dtfor (i = 0; i < T; i++){multiply(di[i], n, n);}//of for iprintf("\nN的值为:\n");cotnum(n, stdout);//打印M=d(n-t+2)*d(n-t+3)*...*dnfor (i = N-1; i >(N-T); i--){multiply(di[i], m, m);}//of for iprintf("\nM的值为:\n");cotnum(m, stdout);printf("\n");//进行秘密复原zhongguo(secret);}//of ifreturn 0;
}//of main