IpdbCT * Ipdb::Enc(GT M, Big *X, int len, Big s3, Big s4, bool message, string Msg, string fname) { Big s1,s2; Big D; #ifdef VERBOSE printf("Enc (start):\n"); #endif IpdbCT *Ct; Ct=new IpdbCT(len); pfc->random(s1); pfc->random(s2); Ct->A=pfc->mult(g1,s2); Ct->B=pfc->mult(g1_1,s1); for(int i=0;i<len;i++){ Ct->C1[i]=pfc->mult(W1[i],s1)+pfc->mult(F1[i],s2)+pfc->mult(U1,modmult(X[i],s3,order)); Ct->C2[i]=pfc->mult(W2[i],s1)+pfc->mult(F2[i],s2)+pfc->mult(U2,modmult(X[i],s3,order)); Ct->C3[i]=pfc->mult(T1[i],s1)+pfc->mult(H1[i],s2)+pfc->mult(V1,modmult(X[i],s4,order)); Ct->C4[i]=pfc->mult(T2[i],s1)+pfc->mult(H2[i],s2)+pfc->mult(V2,modmult(X[i],s4,order)); } if(message) EncMsg(M,Msg,fname); //Encrypt Msg creating an AES key from M Ct->C=M*pfc->power(alpha,s2); // ciphertext #ifdef VERBOSE printf("Enc (end) :\n"); #endif return Ct; }
void Ipdb::GenPar(PFC *pp, miracl *mp, G1 gg1, G2 gg2, Big om) { pfc=pp; mip=mp; order=pfc->order(); #ifdef VERBOSE printf("GenParam (start):\n"); #endif pfc->random(delta1); pfc->random(delta2); pfc->random(g1); pfc->random(g2); pfc->random(g2_2); pfc->random(theta1); pfc->random(theta2); pfc->random(omega); omega=om; g1=gg1; g2=gg2; for(int i=0;i<len;i++){ pfc->random(w1[i]); pfc->random(t1[i]); pfc->random(f1[i]); pfc->random(h1[i]); w2[i]=moddiv(omega+modmult(delta2,w1[i],order),delta1,order); t2[i]=moddiv(omega+modmult(theta2,t1[i],order),theta1,order); pfc->random(f2[i]); pfc->random(h2[i]); W1[i]=pfc->mult(g1,w1[i]); W2[i]=pfc->mult(g1,w2[i]); pfc->precomp_for_mult(W1[i]); // precompute on everything! pfc->precomp_for_mult(W2[i]); T1[i]=pfc->mult(g1,t1[i]); T2[i]=pfc->mult(g1,t2[i]); pfc->precomp_for_mult(T1[i]); pfc->precomp_for_mult(T2[i]); F1[i]=pfc->mult(g1,f1[i]); F2[i]=pfc->mult(g1,f2[i]); pfc->precomp_for_mult(F1[i]); pfc->precomp_for_mult(F2[i]); H1[i]=pfc->mult(g1,h1[i]); H2[i]=pfc->mult(g1,h2[i]); pfc->precomp_for_mult(H1[i]); pfc->precomp_for_mult(H2[i]); } U1=pfc->mult(g1,delta1); U2=pfc->mult(g1,delta2); V1=pfc->mult(g1,theta1); V2=pfc->mult(g1,theta2); g1_1=pfc->mult(g1,omega); alpha=pfc->pairing(g2_2,g1); pfc->precomp_for_power(alpha); pfc->precomp_for_mult(U1); pfc->precomp_for_mult(U2); pfc->precomp_for_mult(V1); pfc->precomp_for_mult(V2); pfc->precomp_for_mult(g1); pfc->precomp_for_mult(g2); pfc->precomp_for_mult(g1_1); #ifdef VERBOSE printf("GenParam (end) :\n"); #endif }
void Ipdb::GenPar(PFC *pp, miracl *mp) { pfc=pp; mip=mp; order=pfc->order(); printf("GenParam (start) with ell=%d\n",ell); pfc->random(g1); pfc->random(g2_2); pfc->random(g2); pfc->random(delta1); pfc->random(delta2); pfc->random(theta1); pfc->random(theta2); pfc->random(omega); for(int i=0;i<ell;i++){ pfc->random(w1[i]); pfc->random(t1[i]); pfc->random(f1[i]); pfc->random(h1[i]); pfc->random(f2[i]); pfc->random(h2[i]); w2[i]=moddiv(omega+modmult(delta2,w1[i],order),delta1,order); t2[i]=moddiv(omega+modmult(theta2,t1[i],order),theta1,order); W1[i]=pfc->mult(g1,w1[i]); W2[i]=pfc->mult(g1,w2[i]); pfc->precomp_for_mult(W1[i]); // precompute on everything! pfc->precomp_for_mult(W2[i]); T1[i]=pfc->mult(g1,t1[i]); T2[i]=pfc->mult(g1,t2[i]); pfc->precomp_for_mult(T1[i]); pfc->precomp_for_mult(T2[i]); F1[i]=pfc->mult(g1,f1[i]); F2[i]=pfc->mult(g1,f2[i]); pfc->precomp_for_mult(F1[i]); pfc->precomp_for_mult(F2[i]); H1[i]=pfc->mult(g1,h1[i]); H2[i]=pfc->mult(g1,h2[i]); pfc->precomp_for_mult(H1[i]); pfc->precomp_for_mult(H2[i]); } U1=pfc->mult(g1,delta1); U2=pfc->mult(g1,delta2); V1=pfc->mult(g1,theta1); V2=pfc->mult(g1,theta2); g1_1=pfc->mult(g1,omega); alpha=pfc->pairing(g2_2,g1); pfc->precomp_for_power(alpha); pfc->precomp_for_mult(U1); pfc->precomp_for_mult(U2); pfc->precomp_for_mult(V1); pfc->precomp_for_mult(V2); pfc->precomp_for_mult(g2); pfc->precomp_for_mult(g1); pfc->precomp_for_mult(g1_1); printf("GenParam (end) :\n"); }
unsigned long long modpow(unsigned long long a,unsigned long long b,unsigned long long N) { if(a>=N)a%=N; unsigned long long res=1ll; while(b) { if(b&1)res=modmult(a,res,N); b>>=1; a=modmult(a,a,N); } return res; }
int main(void) { modmult(P1, P2, bigmod, a); debug(a); modmult(a, P3, bigmod, mod); debug(mod); sub(P1, One, a); debug(a); sub(P2, One, b); debug(b); modmult(a, b, bigmod, c); debug(c); sub(P3, One, a); debug(a); modmult(a, c, bigmod, b); debug(b); modpow(Two, b, mod, a); debug(a); return 0; }
void zzn2_sqr(_MIPD_ zzn2 *x,zzn2 *w) { #ifdef MR_COUNT_OPS fpa+=3; fpc+=2; #endif modadd(x->a->w,x->b->w,mr_mip->w1->w); modsub(x->a->w,x->b->w,mr_mip->w2->w); modmult(x->a->w,x->b->w,w->b->w); modmult(mr_mip->w1->w,mr_mip->w2->w,w->a->w); modadd(w->b->w,w->b->w,w->b->w); w->a->len=2; w->b->len=2; }
static int ComputeDLogModSubGroupOrder(int indexBase, int indexExp, BigInteger *Exponent, BigInteger *subGroupOrder) { // Set tmpBase to 1 in Montgomery notation. memcpy(tmpBase.limbs, MontgomeryMultR1, NumberLength * sizeof(limb)); // Set Exponent to zero. Exponent->limbs[0].x = 0; Exponent->nbrLimbs = 1; Exponent->sign = SIGN_POSITIVE; for (;;) { if (TestBigNbrEqual(Exponent, subGroupOrder)) { // All exponents have been tried and logarithm has not been found, so go out. indicateCannotComputeLog(indexBase, indexExp); return 0; } if (!memcmp(tmpBase.limbs, powerPHMontg, NumberLength * sizeof(limb))) { // Logarithm for this subgroup has been found. Go out. return 1; } // Set tmpBase to next power. modmult(tmpBase.limbs, primRootPwr, tmpBase.limbs); // Set next exponent. addbigint(Exponent, 1); } }
void inner_product(Big *x,Big *v,Big& order) { Big prod=0; for (int i=0;i<3-1;i++) prod+=modmult(x[i],v[i],order); v[3-1]=moddiv(order-prod,x[3-1],order); }
//evaluates add_i polynomial for layer 59+d of the F0 circuit void FLT_add_lvl2(mpz_t rop, const mpz_t* r, int mi, int mip1, int ni, int nip1, const mpz_t prime) { mpz_t tmp, ans; mpz_init(tmp); mpz_init(ans); //even ps go to nip1-1 for in1 and p/2 for both in2 one_sub(ans, r[0]); /* uint64 ans1 = 1+PRIME-r[0]; uint64 temp; */ //now make sure p>>1 matches in2 check_equal(ans, &r[1], &r[mi+mip1], 0, mip1, prime); //make sure in1 matches nip1-1 chi(tmp, nip1-1, r+mi, mip1, prime); modmult(rop, tmp, ans, prime); /* ans1 = myModMult(ans1, chi(nip1-1, r+mi, mip1)); return ans1; */ mpz_clear(tmp); mpz_clear(ans); }
function modpow(a,exp,N) { if (exp == 0) return 1; // Right to left binary exponentiation var t = 1; var f = a; while (exp > 1) { if ((exp & 1) == 1) { // if exponent is odd t = modmult(t,f,N); } exp = Math.floor(exp/2); f = modmult(f,f,N); }; t = modmult(t,f,N); return t; }
IpeCt * Ipe::MEncrypt(IpeMsk *msk, Big *X, Big s3, Big s4, GT M){ IpeCt *ct; IpeBCt ***bct = new IpeBCt**[len]; Big s1,s2; G1 g_1, g1_1; pfc->random(s1); pfc->random(s2); for(int i=0;i<len;i++){ bct[i] = new IpeBCt*[2]; bct[i][0]=BasicEncrypt(msk->bmsk[i][0],msk->Delta1,X[i],s1,s2,s3,msk->g); bct[i][1]=BasicEncrypt(msk->bmsk[i][1],msk->Delta2,X[i],s1,s2,s4,msk->g); } g_1 = pfc->mult(msk->g,s2); g1_1 = pfc->mult(msk->g,modmult(msk->omega,s1,order)); GT tmpgt = pfc->pairing(msk->g2,msk->g); GT C0 = pfc->power(tmpgt,s2); GT C = M*C0; ct = new IpeCt(g_1,g1_1,bct,C); return ct; }
/* Y attribute vector */ IpdbKey * Ipdb::KeyGen(Big *Y) { IpdbKey *Key; Key= new IpdbKey(ell); Big lambda1,lambda2,t; Big *r =new Big[ell]; Big *phi=new Big[ell]; printf("KeyGen (start) with ell=%d\n",ell); char ctt[100]; mip->IOBASE=16; ctt<<Y[0]; printf("KAttribute 0 --> %s\n",ctt); ctt<<Y[1]; printf("KAttribute 1 --> %s\n",ctt); ctt<<Y[2]; printf("KAttribute 2 --> %s\n",ctt); pfc->random(lambda1); pfc->random(lambda2); for(int i=0;i<ell;i++){pfc->random(r[i]); pfc->random(phi[i]); } for(int i=0;i<ell;i++){ t=modmult(lambda1,Y[i],order); Key->K1[i]=pfc->mult(g2,modmult(t,w2[i],order)-modmult(delta2,r[i],order)); Key->K2[i]=pfc->mult(g2,modmult(delta1,r[i],order)-modmult(t,w1[i],order)); pfc->precomp_for_pairing(Key->K1[i]); pfc->precomp_for_pairing(Key->K2[i]); } for(int i=0;i<ell;i++){ t=modmult(lambda2,Y[i],order); Key->K3[i]=pfc->mult(g2,modmult(t,t2[i],order)-modmult(theta2,phi[i],order)); Key->K4[i]=pfc->mult(g2,modmult(theta1,phi[i],order)-modmult(t,t1[i],order)); pfc->precomp_for_pairing(Key->K3[i]); pfc->precomp_for_pairing(Key->K4[i]); } Key->KA=g2_2; for(int i=0;i<ell;i++){ Key->KA=Key->KA+pfc->mult(Key->K1[i],-f1[i])+pfc->mult(Key->K2[i],-f2[i])+pfc->mult(Key->K3[i],-h1[i])+pfc->mult(Key->K4[i],-h2[i]); Key->KB=Key->KB+pfc->mult(g2,-(r[i]+phi[i])%order); } pfc->precomp_for_pairing(Key->KA); pfc->precomp_for_pairing(Key->KB); return Key; }
template<int bit> void FLT_mul(mpz_t rop, const mpz_t* r, int mi, int mip1, int ni, int nip1, const mpz_t prime) { mpz_t ans1, ans2, tmp, tmp2; mpz_init(tmp); mpz_init(tmp2); mpz_init(ans1); mpz_init(ans2); mpz_set_ui(ans1, 1); // First make sure all but least and most significant bits of in1 and in2 match p check_equal(ans1, r, &r[mi], &r[mi+mip1], 0, mi - 1, prime); mpz_set(ans2, ans1); if (bit) { //first handle even p contribution //first term in product makes sure p is even one_sub(tmp, r[0]); mpz_mul(ans1, ans1, tmp); //finally check that least significant bit of in1 is 0 and lsb of in2 is 1 one_sub(tmp, r[mi]); mpz_mul(tmp2, tmp, r[mi+mip1]); mpz_mul(ans1, ans1, tmp2); //subtract contribution of last even gate mpz_set_ui(tmp, 0); check_wiring(tmp, r, ni-1, nip1-1, nip1-1, mi, mip1, prime); mpz_sub(ans1, ans1, tmp); } else { mpz_set_ui(ans1, 0); } //now handle odd p contribution mpz_mul(ans2, ans2, r[0]); //uint64 ans2 = r[0]; //finally check that least significant bit of in1 and in2 are 1 mpz_mul(tmp, r[mi], r[mi+mip1]); mpz_mul(ans2, ans2, tmp); mpz_add(tmp, ans1, ans2); // Make sure that highest order bit of p is 0. one_sub(tmp2, r[mi-1]); modmult(rop, tmp, tmp2, prime); mpz_clear(tmp); mpz_clear(tmp2); mpz_clear(ans1); mpz_clear(ans2); }
ZR PairingGroup::mul(ZR g, ZR h) { ZR o = pfcObject->order(); ZR r = modmult(g, h, o); if(r < 0) { return (r + o) % o; } return r; }
// Lagrange interpolation Big lagrange(int i,int *S,int d,Big order) { int j,k; Big z=1; for (k=0;k<d;k++) { j=S[k]; if (j!=i) z=modmult(z,moddiv(order-j,(Big)(i-j),order),order); } return z; }
void zzn2_mul(_MIPD_ zzn2 *x,zzn2 *y,zzn2 *w) { #ifdef MR_COUNT_OPS fpa+=5; fpc+=3; #endif modmult(x->a->w,y->a->w,mr_mip->w1->w); modmult(x->b->w,y->b->w,mr_mip->w2->w); modadd(x->a->w,x->b->w,mr_mip->w5->w); modadd(y->a->w,y->b->w,w->b->w); modmult(w->b->w,mr_mip->w5->w,w->b->w); modsub(w->b->w,mr_mip->w1->w,w->b->w); modsub(w->b->w,mr_mip->w2->w,w->b->w); modsub(mr_mip->w1->w,mr_mip->w2->w,w->a->w); w->a->len=2; w->b->len=2; }
int main(int argc, char *argv[]) { int iy,i; char *line = new char[512];//buffer needs char instead of const char ofstream fout; ifstream fin; time_t seed; Big tempB,a,b,p,q,x,y,s1,s2; ECn g; miracl *mip=&precision; time(&seed); irand((long)seed); /* change parameter for different values */ //cout << "Adding EC-ElGamal ciphertexts...." << endl; a=-3; mip->IOBASE=16; b=ecb; p=ecp; q=ecq;// order ecurve(a,b,p,MR_BEST); // means use PROJECTIVE if possible, else AFFINE coordinates x=ecx; y=ecy; g=ECn(x,y); //Read cipher and multiply i = 0; mip->IOBASE=64; fin.open(PFILE); s1 = 0; s2 = 0; while(fin.getline(line,512)){ x = line; fin.getline(line,512); y = line; //"add" (could not fine add mod) s1 += x; s2 += y; i++; } fin.close(); // a stupid way to mod q x = 1; s2 = modmult(s2,x,q); fout.open(TFILE); fout<<s1<<endl<<s2<<endl; fout.close(); //free buffer delete [] line; return 0; }
static void modpow(Bignum r1, Bignum r2, Bignum modulus, Bignum result) { Bignum temp = newbn(modulus[0]+1); Bignum tmp2 = newbn(modulus[0]+1); int i; int bit, bits, digit, smallbit; enter((">modpow\n")); debug(r1); debug(r2); debug(modulus); for (i=1; i<=result[0]; i++) result[i] = (i==1); /* result := 1 */ for (i=1; i<=temp[0]; i++) temp[i] = (i > r1[0] ? 0 : r1[i]); /* temp := r1 */ bits = 1+msb(r2); for (bit = 0; bit < bits; bit++) { digit = 1 + bit / 16; smallbit = bit % 16; debug(temp); if (digit <= r2[0] && (r2[digit] & (1<<smallbit))) { dmsg(("bit %d\n", bit)); modmult(temp, result, modulus, tmp2); add(tmp2, Zero, result); debug(result); } modmult(temp, temp, modulus, tmp2); add(tmp2, Zero, temp); } freebn(temp); freebn(tmp2); debug(result); leave(("<modpow\n")); }
function SPRP(N,a) { var d = N-1; s = 1; // Assumes N is odd! while ( ((d=d/2) & 1) == 0) s++; // Using d>>1 changed the sign of d! // Now N-1 = d*2^s with d odd var b = modpow(a,d,N); if (b == 1) return true; if (b+1 == N) return true; while (s-- > 1) { b = modmult(b,b,N); if (b+1 == N) return true; } return false; }
IpeBCt * Ipe::BasicEncrypt(IpeBMsk *bmsk, Big *D, Big x, Big s1, Big s2, Big t, G1 g){ IpeBCt *ct; G1 ct1,ct2; Big c1,c2; c1 = modmult(bmsk->w1,s1,order)+modmult(bmsk->f1,s2,order)+modmult(D[0],modmult(x,t,order),order); c2 = modmult(bmsk->w2,s1,order)+modmult(bmsk->f2,s2,order)+modmult(D[1],modmult(x,t,order),order); ct1=pfc->mult(g,c1); ct2=pfc->mult(g,c2); ct = new IpeBCt(ct1,ct2); return ct; }
void Widget::on_pushButton_3_clicked() { Big pm[2],m,t; pm[0]=pow(c%p,d%(p-1),p); /* get result mod p */ pm[1]=pow(c%q,d%(q-1),q); /* get result mod q */ t=modmult(inv,pm[1]-pm[0],q); // use CRT in simple way, as only 2 primes m=t*p+pm[0]; // m=chinese.eval(pm); /* combine them using CRT */ mip->IOBASE=256; ui->textEdit_7->setText(bs(m,m.len())); }
IpeBMsk * Ipe::BasicSetup(Big o, Big d1, Big d2){ IpeBMsk *bmsk; Big w1,w2,f1,f2; pfc->random(w1); pfc->random(f1); pfc->random(f2); w2=moddiv(o+modmult(d2,w1,order),d1,order); bmsk = new IpeBMsk(w1,w2,f1,f2); return bmsk; }
/* M is the message X is the attribute vector */ IpdbCT * Ipdb::Enc(GT M, Big *X) { Big s1,s2,s3,s4; printf("Enc (start) with ell=%d\n",ell); char ctt[100]; mip->IOBASE=16; ctt<<X[0]; printf("CAttribute 0 --> %s\n",ctt); ctt<<X[1]; printf("CAttribute 1 --> %s\n",ctt); ctt<<X[2]; printf("CAttribute 2 --> %s\n",ctt); IpdbCT *Ct; Ct=new IpdbCT(ell); pfc->random(s1); pfc->random(s2); pfc->random(s3); pfc->random(s4); Ct->A=pfc->mult(g1,s2); Ct->B=pfc->mult(g1_1,s1); for(int i=0;i<ell;i++){ Ct->C1[i]=pfc->mult(W1[i],s1)+pfc->mult(F1[i],s2)+pfc->mult(U1,modmult(X[i],s3,order)); Ct->C2[i]=pfc->mult(W2[i],s1)+pfc->mult(F2[i],s2)+pfc->mult(U2,modmult(X[i],s3,order)); } for(int i=0;i<ell;i++){ Ct->C3[i]=pfc->mult(T1[i],s1)+pfc->mult(H1[i],s2)+pfc->mult(V1,modmult(X[i],s4,order)); Ct->C4[i]=pfc->mult(T2[i],s1)+pfc->mult(H2[i],s2)+pfc->mult(V2,modmult(X[i],s4,order)); } //D=pfc->hash_to_aes_key(pfc->power(alpha,s2)); //Ct->C=lxor(M,D); // ciphertext GT Lambda=pfc->power(alpha,s2); LambdaStored=Lambda; Ct->C=M*Lambda; printf("Enc (end) :\n"); return Ct; }
/* Y attribute vector */ IpdbKey * Ipdb::KeyGen(Big *Y,Big lambda1,Big lambda2) { IpdbKey *Key; Key= new IpdbKey(len); Big t; Big *r =new Big[len]; Big *phi=new Big[len]; for(int i=0;i<len;i++){pfc->random(r[i]); pfc->random(phi[i]); } for(int i=0;i<len;i++){ t=modmult(lambda1,Y[i],order); Key->K1[i]=pfc->mult(g2,modmult(t,w2[i],order)-modmult(delta2,r[i],order)); Key->K2[i]=pfc->mult(g2,modmult(delta1,r[i],order)-modmult(t,w1[i],order)); pfc->precomp_for_pairing(Key->K1[i]); pfc->precomp_for_pairing(Key->K2[i]); } for(int i=0;i<len;i++){ t=modmult(lambda2,Y[i],order); Key->K3[i]=pfc->mult(g2,modmult(t,t2[i],order)-modmult(theta2,phi[i],order)); Key->K4[i]=pfc->mult(g2,modmult(theta1,phi[i],order)-modmult(t,t1[i],order)); pfc->precomp_for_pairing(Key->K3[i]); pfc->precomp_for_pairing(Key->K4[i]); } Key->KA=g2_2; for(int i=0;i<len;i++){ Key->KA=Key->KA+pfc->mult(Key->K1[i],-f1[i])+pfc->mult(Key->K2[i],-f2[i])+pfc->mult(Key->K3[i],-h1[i])+pfc->mult(Key->K4[i],-h2[i]); Key->KB=Key->KB+pfc->mult(g2,-(r[i]+phi[i])%order); } pfc->precomp_for_pairing(Key->KA); pfc->precomp_for_pairing(Key->KB); return Key; }
function modmult(a,b,N) { if (a > N) a = a%N; if (b > N) b = b%N; if (a*b <= 9007199254740991) { return ((a*b)%N); } else { if (b > a) return modmult(b,a,N); // Right to left binary multiplication var t = 0; var f = a; while (b > 1) { if ((b & 1) == 1) t = modadd(t,f,N); b = Math.floor(b/2); f = modadd(f,f,N); }; t = modadd(t,f,N); return t; } }
IpeBKey * Ipe::BasicKeyGen(IpeBMsk *bmsk, Big *D, Big y, Big lambda, Big r, G2 g2){ IpeBKey *k; G2 k1,k2; Big bk1,bk2; bk1 = modmult(modmult(lambda,y,order),bmsk->w2,order)-modmult(D[1],r,order); bk2 = modmult(D[0],r,order)-modmult(modmult(lambda,y,order),bmsk->w1,order); k1 = pfc->mult(g2,bk1); k2 = pfc->mult(g2,bk2); k = new IpeBKey(k1,k2); return k; }
bool Miller(unsigned long long N) { if(N<2)return false; else if(N<4) return true; else if((N&1)==0)return false; unsigned long long D=N-1,S=0; while((D&1)==0) { D>>=1; S++; } for(int a=0;a<5;a++) { unsigned long long ad=modpow(rand()%(N-4)+2,D,N); if(ad==1||ad==N-1) continue; for(unsigned long long r=0;r<S-1;r++) if((ad=modmult(ad,ad,N))==N-1) goto BPP; return false; BPP:; } return true; }
IpeCt * Ipe::PEncrypt(IpeMsk *msk, Big *X){ IpeCt *ct; IpeBCt ***bct = new IpeBCt**[len]; Big s1,s2,s3,s4; G1 g_1, g1_1; pfc->random(s1); pfc->random(s2); pfc->random(s3); pfc->random(s4); for(int i=0;i<len;i++){ bct[i] = new IpeBCt*[2]; bct[i][0]=BasicEncrypt(msk->bmsk[i][0],msk->Delta1,X[i],s1,s2,s3,msk->g); bct[i][1]=BasicEncrypt(msk->bmsk[i][1],msk->Delta2,X[i],s1,s2,s4,msk->g); } g_1 = pfc->mult(msk->g,s2); g1_1 = pfc->mult(msk->g,modmult(msk->omega,s1,order)); ct = new IpeCt(g_1,g1_1,bct); return ct; }
int main() { PFC pfc(AES_SECURITY); // initialise pairing-friendly curve miracl *mip=get_mip(); // get handle on mip (Miracl Instance Pointer) time_t seed; int i,j,k,l,n,m,d,nS; Big **LSSS; int *attr; Big det,order=pfc.order(); // get pairing-friendly group order Big alpha,a,M,CT,s,t; G2 g2,g2a,*h,CD; G1 g1,g1a,K,L,MSK; GT eg2g1a,mask; time(&seed); // initialise (insecure!) random numbers irand((long)seed); // Setup pfc.random(alpha); pfc.random(a); pfc.random(g1); pfc.random(g2); pfc.precomp_for_mult(g1); // g1 is fixed, so precompute on it pfc.precomp_for_mult(g2); // g2 is fixed, so precompute on it eg2g1a=pfc.power(pfc.pairing(g2,g1),alpha); pfc.precomp_for_power(eg2g1a); g1a=pfc.mult(g1,a); g2a=pfc.mult(g2,a); pfc.precomp_for_mult(g2a); // g2a is fixed, so precompute on it h=new G2[U]; for (i=0;i<U;i++) { pfc.random(h[i]); pfc.precomp_for_mult(h[i]); // precompute on h[.] } MSK=pfc.mult(g1,alpha); // Encrypt m=find_m(Access); d=find_d(Access); LSSS=new Big *[m]; for (i=0;i<m;i++) LSSS[i]=new Big[d+1]; // get memory for each row attr=new int [m]; make_LSSS(Access,m,d,LSSS,attr); // create LSSS matrix from Access structure cout << "LSSS matrix " << m << "x" << d << endl; for (i=0;i<m;i++) { for (j=0;j<d;j++) cout << LSSS[i][j] << " "; cout << " " << (char)attr[i] << endl; } cout << endl; mip->IOBASE=256; M=(char *)"test message"; cout << "Message to be encrypted= " << M << endl; mip->IOBASE=16; Big *v=new Big [d]; Big *lambda=new Big [m]; Big *r=new Big [m]; for (i=0;i<d;i++) pfc.random(v[i]); s=v[0]; for (i=0;i<m;i++) pfc.random(r[i]); G2 *C=new G2 [m]; G1 *D=new G1 [m]; for (i=0;i<m;i++) { lambda[i]=0; for (j=0;j<d;j++) lambda[i]+=modmult(LSSS[i][j],v[j],order); lambda[i]%=order; } CT=lxor(M,pfc.hash_to_aes_key(pfc.power(eg2g1a,s))); CD=pfc.mult(g2,s); for (i=0;i<m;i++) { C[i]=pfc.mult(g2a,lambda[i])+pfc.mult(h[attr[i]-'A'],-r[i]); D[i]=pfc.mult(g1,r[i]); } // keygen cout << "Generating keys" << endl; pfc.random(t); K=MSK+pfc.mult(g1a,t); L=pfc.mult(g1,t); G2 *KX=new G2[U]; nS=0; while (auth[nS]!=0) { j=auth[nS++]-'A'; KX[j]=pfc.mult(h[j],t); pfc.precomp_for_pairing(KX[j]); } // decrypt - and apply some optimisations e.g. e(A,B)*e(A,C) = e(A,B+C) cout << "Decrypting" << endl; int *rows=new int [m]; Big *w=new Big [m]; if (!reduce_LSSS(order,m,d,LSSS,attr,auth,rows,w)) { cout << "Unable to decrypt - insufficient attributes" << endl; exit(0); } cout << "reduced matrix= " << m << "x" << d << endl; // Note that w[i] are usually very small, so this is fast G2 TC; for (i=0;i<m;i++) { cout << "w[i]= " << w[i] << endl; TC=TC+pfc.mult(C[rows[i]],w[i]); D[rows[i]]=pfc.mult(D[rows[i]],-w[i]); } TC=-TC; // combine rows which share same attribute for (i=0;i<m;i++) { k=rows[i]; for (j=i+1;j<m;j++) { if (attr[j]==attr[i]) { D[k]=D[k]+D[rows[j]]; // combine them for (n=j;n<m;n++) { rows[n]=rows[n+1]; attr[n]=attr[n+1]; } m--; // delete row } } } G2 **t2=new G2* [m+2]; G1 **t1=new G1* [m+2]; t2[0]=&CD; t1[0]=&K; // e(CD,K) t2[1]=&TC; t1[1]=&L; // e(TC,L) for (i=0;i<m;i++) { t2[i+2]=&KX[attr[i]-'A']; t1[i+2]=&D[rows[i]]; } mask=pfc.multi_pairing(m+2,t2,t1); // most pairings benefit from precomputation M=lxor(CT,pfc.hash_to_aes_key(mask)); mip->IOBASE=256; cout << "Decrypted message= " << M << endl; return 0; }
BOOL gauss(Big &order,int n,Big *matrix[],Big *w) { int i,ii,j,jj,k,m; int *row; BOOL ok,pivot; Big s,p; ok=TRUE; w[0]=1; row=new int[n]; for (i=1;i<n;i++) w[i]=0; for (i=0;i<n;i++) {matrix[i][n]=w[i];row[i]=i;} for (i=0;i<n;i++) { /* Gaussian elimination */ m=i; ii=row[i]; pivot=TRUE; if (matrix[ii][i]==0) { // look for non-zero pivot.. pivot=FALSE; for (j=i+1;j<n;j++) { jj=row[j]; if (matrix[jj][i]!=0) { m=j; pivot=TRUE; k=row[i]; row[i]=row[m]; row[m]=k; // swap row indices break; } } } if (!pivot) { // no non-zero pivot found ok=FALSE; break; } ii=row[i]; p=inverse(matrix[ii][i],order); for (j=i+1;j<n;j++) { jj=row[j]; s=modmult(matrix[jj][i],p,order); for (k=n;k>=i;k--) matrix[jj][k]-=modmult(s,matrix[ii][k],order); } } if (ok) for (j=n-1;j>=0;j--) { /* Backward substitution */ s=0; for (k=j+1;k<n;k++) s+=modmult(w[k],matrix[row[j]][k],order); if (matrix[row[j]][j]==0) { ok=FALSE; break; } w[j]=moddiv(matrix[row[j]][n]-s,matrix[row[j]][j],order); // try and make them small if (abs(w[j])>order/2) { if (w[j]<0) w[j]+=order; else if (w[j]>0) w[j]-=order; } } delete [] row; return ok; }