(ps:需提前安装pbc库 )
0、生成公共参数(椭圆曲线)
char *param = "type a\n"
"q 8780710799663312522437781984754049815806883199414208211028653399266475630880222957078625179422662221423155858769582317459277713367317481324925129998224791\n"
"h 12016012264891146079388821366740534204802954401251311822919615131047207289359704531102844802183906537786776\n"
"r 730750818665451621361119245571504901405976559617\n"
"exp2 159\n"
"exp1 107\n"
"sign1 1\n"
"sign0 1";
int t = 3, n = 5;
int num = 16;
void initPP(PublicParameter *PP,char* param){
pairing_init_set_buf(PP->pairing, param, strlen(param));
element_init_G1(PP->P,PP->pairing);
element_random(PP->P);
return;
}
1、生成秘密共享
生成的secretshare会存在result里
void genshare(element_t secret,int n,int t,element_t *result,pairing_t pairing)
{
element_t *a;//多项式系数a0....a(t-1)
a = (element_t*)malloc(sizeof(element_t) * (t));
element_t *share;//分享的密钥
share = (element_t*)malloc(sizeof(element_t) * (n));
//element_printf("secret in = %B\n",secret);
element_init_Zr(a[0],pairing);//a0 = secret
element_set(a[0],secret);
//element_printf("a[0] = %B\n",a[0]);
for(int i=1;i<t;i++)
{
element_init_Zr(a[i],pairing);
// element_set1(a[i]);
element_random(a[i]);
//element_printf("a[%d] = %B\n",i,a[i]);
}
for(int i=0;i<n;i++)//share初始化
{
element_init_Zr(share[i],pairing);
element_set(share[i],a[0]);
//element_printf("share[%d] = %B\n",i,share[i]);
}
for(int i=1;i<=n;i++)//计算share0...4 sharei对应x=i+1
{
element_t tmp;//存储x ... x^(t-1)
element_t x;
element_init_Zr(tmp,pairing);
element_init_Zr(x,pairing);
element_set_si(x,i);
for(int j =1;j<t;j++)
{
element_t tmp1;//存储a[j]*x^j
element_t xpowj;
element_t jz;
element_init_Zr(tmp1,pairing);
element_init_Zr(xpowj,pairing);
element_init_Zr(jz,pairing);
element_set_si(jz,j);
element_pow_zn(xpowj,x,jz);
element_mul(tmp1,a[j],xpowj);
element_add(share[i-1],share[i-1],tmp1);
element_set0(tmp1);
}
}
for(int i=0;i<n;i++)//赋值
{
element_init_Zr(result[i],pairing);
element_set(result[i],share[i]);
element_printf("%B\n",result[i]);
}
free(a);
free(share);
}
2、随机选择服务器做门限
需要注意这里的result和上面不同,这里的result是服务器列表
void random_select(int* result)
{
// 初始化数组
for (int i = 0; i < n; i++) {
result[i] = i;
}
// 随机交换数组中的元素
srand(time(NULL));
for (int i = n - 1; i > 0; i--) {
int j = rand() % (i + 1);
int temp = result[i];
result[i] = result[j];
result[j] = temp;
}
// 返回前 t 个元素
for (int i = 0; i < t; i++) {
printf("%d ", result[i]);
}
printf("\n");
}
3、抽象拉格朗日差值法
void get_lagrange_coefficient(int a,int *shareid,element_t *lagrange_co,pairing_t pairing)
{
//printf("lagrang\n");
int thisid = a+1;
int idgroup[t];
for(int i=0;i<t;i++)
{
idgroup[i]=shareid[i];
//printf("%d\n",idgroup[i]);
idgroup[i]++;
}
element_t l;
element_t ll,lr;
element_t lrn;
element_init_Zr(l,pairing);
element_init_Zr(lrn,pairing);
element_init_Zr(ll,pairing);
element_init_Zr(lr,pairing);
signed long int lleft=1;
for(int i=0;i<t;i++)
{
if(idgroup[i]==thisid)
{
continue;
}
lleft = lleft * (0-idgroup[i]);
}
signed long int lright=1;
for(int i=0;i<t;i++)
{
if(idgroup[i]==thisid)
{
continue;
}
lright = lright * (idgroup[i]-thisid);
}
element_set_si(ll,lleft);
element_set_si(lr,lright);
element_invert(lrn,lr);
element_mul(l,ll,lrn);
element_init_Zr(lagrange_co,pairing);
element_set(lagrange_co,l);
element_printf("lagl %B\n",ll);
element_printf("lagr %B\n",lr);
element_printf("lagrn %B\n",lrn);
}
4、恢复秘密
void recover_secret(element_t* s,element_t *result,pairing_t pairing)
{
// int shareid[3] = {3,2,1};
int shareid[t];
printf("选择的%d个用于计算w的服务器为:\n",t);
random_select(&shareid);
// for(int i=0;i<t;i++)
// {
// IS[shareid[i]].chosen=1;
// }
// for(int i=0;i<n;i++)
// {
// printf("%d\n",IS[i].chosen);
// }
element_t *l;
l = (element_t*)malloc(sizeof(element_t) * (t));
for(int i=0;i<t;i++)
{
element_init_Zr(l[i],pairing);
get_lagrange_coefficient(shareid[i],shareid,&l[i],pairing);
//element_printf("lagrange_co%d=%B\n",i,l[i]);
}
element_t *wl;
wl = (element_t*)malloc(sizeof(element_t) * (t));
for(int i=0;i<t;i++)
{
element_init_Zr(wl[i],pairing);
element_mul(wl[i],result[shareid[i]],l[i]);
element_printf("%B\n",wl[i]);
}
// element_add(wl[1],wl[0],wl[1]);
// element_add(wl[2],wl[1],wl[2]);
// element_printf("wl %B\n",wl[2]);
element_t *w_compute;//w_c[0]存w1w2,w_c[1]存w1w2w3....w_c[t-2]存最终结果
w_compute = (element_t*)malloc(sizeof(element_t) * (t-1));
element_init_Zr(w_compute[0],pairing);
element_add(w_compute[0],wl[0],wl[1]);
// element_printf("%B\n",w_compute[0]);
for(int i=1;i<t-1;i++)
{
element_init_Zr(w_compute[i],pairing);
element_add(w_compute[i],w_compute[i-1],wl[i+1]);
// element_printf("%B\n",w_compute[i]);
}
element_init_Zr(s,pairing);
element_set(s,w_compute[t-2]);
element_printf("\nrecover secret = %B\n",s);
// printf("here1\n");
free(l);
free(wl);
free(w_compute);
}
5、主函数
int main() {
printf("Hello, World!\n");
initPP(&PP, param);
element_t secret;
element_t *result;
element_t s;
result = (element_t*) malloc(sizeof(element_t)*n);
element_init_Zr(secret,PP.pairing);
element_set_si(secret,10086);
element_printf("%B\n",secret);
genshare(secret,n,t,result,PP.pairing);
recover_secret(&s,result,PP.pairing);
return 0;
}
6、运行结果