literalt cvc_propt::lxor(const bvt &bv) { if(bv.empty()) return const_literal(false); if(bv.size()==1) return bv[0]; if(bv.size()==2) return lxor(bv[0], bv[1]); literalt literal=const_literal(false); forall_literals(it, bv) literal=lxor(*it, literal); return literal; }
literalt z3_propt::lxor(const bvt &bv) { if(bv.size()==0) return const_literal(false); if(bv.size()==1) return bv[0]; if(bv.size()==2) return lxor(bv[0], bv[1]); literalt literal=const_literal(false); for(unsigned i=0; i<bv.size(); i++) literal=lxor(bv[i], literal); return literal; }
literalt aig_prop_baset::lxor(const bvt &bv) { literalt literal=const_literal(false); forall_literals(it, bv) literal=lxor(*it, literal); return literal; }
literalt z3_propt::lxor(literalt a, literalt b) { if(a==const_literal(false)) return b; if(b==const_literal(false)) return a; if(a==const_literal(true)) return lnot(b); if(b==const_literal(true)) return lnot(a); literalt o=new_variable(); lxor(a, b, o); return o; }
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; }
PlaintextMessage EncryptedMessage::decrypt(const G2& P, const G2& Ppub, G1 D, PFC *pfc) { G2 uCalc; G2 U = (*autData).getU(); Big ud_hash = (*pfc).hash_to_aes_key((*pfc).pairing(U,D)); Big ses_key; Big r; int nbOfRecipients = (*autData).getNbOfRecipients(); Big W; Big V = (*autData).getV(); Big rho, rho_hash; vector <Big> ws = (*autData).getEncryptedRecipientKeys(); char P_text[Clen]; bool integrity = false; time_t begin_time = clock(); int i = 0; while(U != uCalc && i < nbOfRecipients){ // rho = V XOR Hash(e(D,U)) W=ws.at(i); rho = lxor(W, ud_hash); // M = W XOR Hash(rho) (*pfc).start_hash(); (*pfc).add_to_hash(rho); rho_hash = (*pfc).finish_hash_to_group(); ses_key = lxor(V, rho_hash); // r = Hash(rho,M) (*pfc).start_hash(); (*pfc).add_to_hash(rho); (*pfc).add_to_hash(ses_key); r = (*pfc).finish_hash_to_group(); uCalc = (*pfc).mult(P,r); i++; } cout << "ses_key is " << endl << ses_key << endl; /************************************************* * AES GCM part of the decryption step * **************************************************/ to_binary(ses_key, HASH_LEN, sessionKey, TRUE); char k1[HASH_LEN/2]; char iv[HASH_LEN/2]; char Tdec[TAG_LEN]; memset(P_text, 0, Clen+1); getIV(iv); getK1(k1); int Alen = (*autData).getLength(); char A[Alen]; (*autData).encodeTo(A); gcm g; gcm_init(&g, HASH_LEN/2, k1, HASH_LEN/2, iv); gcm_add_header(&g, A, Alen); gcm_add_cipher(&g, GCM_DECRYPTING, P_text, Clen, C); gcm_finish(&g, Tdec); integrity = true; for (int j = 0; j < TAG_LEN; j++) { if(Tdec[j] != T[j]) { integrity = false; } } if(integrity == false) { cout << "Received tag T does not correspond to decrypted T. There are some integrity issues here." << endl; } else { cout << "Successful integrity check!" << endl; } message = (string)P_text; return PlaintextMessage(message); }
literalt z3_propt::lequal(literalt a, literalt b) { return lnot(lxor(a, b)); }
void z3_propt::lequal(literalt a, literalt b, literalt o) { lxor(a, b, lnot(o)); }
int main() { PFC pfc(AES_SECURITY); // initialise pairing-friendly curve Big q=pfc.order(); Big z,b,SSV,r,H,t; G1 P,Z,KB,R; GT g; time_t seed; time(&seed); irand((long)seed); // setup pfc.random(P); g=pfc.pairing(P,P); pfc.precomp_for_power(g); pfc.random(z); pfc.precomp_for_mult(P); Z=pfc.mult(P,z); // extract private key for Robert b=pfc.hash_to_group((char *)"Robert"); KB=pfc.mult(P,inverse(b+z,q)); // verify private key pfc.precomp_for_pairing(KB); // Bob can precompute on his own private key if (pfc.pairing(KB,pfc.mult(P,b)+Z)!=g) { cout << "Bad private key" << endl; exit(0); } char *bytes; int len=pfc.spill(KB,bytes); // demo - spill precomputation to byte array // Send session key to Bob cout << "All set to go.." << endl; pfc.rankey(SSV); // random AES key pfc.start_hash(); pfc.add_to_hash(SSV); pfc.add_to_hash(b); r=pfc.finish_hash_to_group(); R=pfc.mult(pfc.mult(P,b)+Z,r); t=pfc.hash_to_aes_key(pfc.power(g,r)); H=lxor(SSV,t); cout << "Encryption key= " << SSV << endl; // Receiver pfc.restore(bytes,KB); // restore precomputation for KB from byte array t=pfc.hash_to_aes_key(pfc.pairing(KB,R)); SSV=lxor(H,t); pfc.start_hash(); pfc.add_to_hash(SSV); pfc.add_to_hash(b); r=pfc.finish_hash_to_group(); if (pfc.mult(pfc.mult(P,b)+Z,r)==R) cout << "Decryption key= " << SSV << endl; else cout << "The key is BAD - do not use!" << endl; return 0; }
int main() { PFC pfc(AES_SECURITY); // initialise pairing-friendly curve miracl* mip=get_mip(); Big s,r,sigma,c,M,V,W; G2 P,Ppub,U; G1 Alice,D,rA; time_t seed; time(&seed); irand((long)seed); // common values pfc.random(P); pfc.precomp_for_mult(P); // Note that P is a constant - so precompute! pfc.random(s); Ppub=pfc.mult(P,s); // will exploit precomputation on P pfc.precomp_for_pairing(Ppub); // W is a system-wide constant //extract pfc.hash_and_map(Alice,(char *)"Alice"); // Alices public key D=pfc.mult(Alice,s); // Alice's private key //encrypt to (U,V,W) mip->IOBASE=256; M=(char *)"message"; // to be encrypted to Alice cout << "Message to be encrypted= " << M << endl; mip->IOBASE=16; pfc.rankey(sigma); pfc.start_hash(); pfc.add_to_hash(sigma); pfc.add_to_hash(M); r=pfc.finish_hash_to_group(); U=pfc.mult(P,r); // will exploit precomputation on P rA=pfc.mult(Alice,r); V=pfc.hash_to_aes_key(pfc.pairing(Ppub,rA)); // Use public key - will exploit precomputation on Ppub V=lxor(sigma,V); W=lxor(M,sigma); //decrypt from (U,V,W) sigma=lxor(V,pfc.hash_to_aes_key(pfc.pairing(U,D))); // Use private key M=lxor(W,sigma); pfc.start_hash(); pfc.add_to_hash(sigma); pfc.add_to_hash(M); r=pfc.finish_hash_to_group(); if (U!=pfc.mult(P,r)) { cout << "CIphertext rejected" << endl; return 0; } mip->IOBASE=256; cout << "Decrypted message= " << M << endl; return 0; }
int main() { PFC pfc(AES_SECURITY); // initialise pairing-friendly curve miracl* mip=get_mip(); Big order=pfc.order(); Big s,u,a,b,x,c,h,M; G1 P,Ppub,Pa,Pb,R,S,U; G2 Q,Qsa,Qsb,T; GT g,N,V; time_t seed; time(&seed); irand((long)seed); //setup pfc.random(s); pfc.random(P); pfc.random(Q); g=pfc.pairing(Q,P); pfc.precomp_for_power(g); Ppub=pfc.mult(P,s); //Keygen a=pfc.hash_to_group((char *)"Alice"); Qsa=pfc.mult(Q,inverse(modmult(s,a,order),order)); b=pfc.hash_to_group((char *)"Bob"); Qsb=pfc.mult(Q,inverse(modmult(s,b,order),order)); Pa=pfc.mult(Ppub,a); Pb=pfc.mult(Ppub,b); //Signcrypt mip->IOBASE=256; M=(char *)"test message"; // to be signcrypted from Alice to Bob cout << "Signed Message= " << M << endl; mip->IOBASE=16; pfc.precomp_for_mult(Pa); pfc.precomp_for_mult(Qsa); pfc.random(x); N=pfc.power(g,inverse(x,order)); R=pfc.mult(Pa,x); S=pfc.mult(Pb,inverse(x,order)); c=lxor(M,pfc.hash_to_aes_key(N)); pfc.start_hash(); pfc.add_to_hash(R); pfc.add_to_hash(S); pfc.add_to_hash(c); h=pfc.finish_hash_to_group(); T=pfc.mult(Qsa,inverse(x+h,order)); // Unsigncrypt pfc.precomp_for_pairing(Qsb); // Bob can precompute on his private key pfc.start_hash(); pfc.add_to_hash(R); pfc.add_to_hash(S); pfc.add_to_hash(c); h=pfc.finish_hash_to_group(); U=pfc.mult(Pa,h); V=pfc.pairing(T,R+U); N=pfc.pairing(Qsb,S); M=lxor(c,pfc.hash_to_aes_key(N)); mip->IOBASE=256; if (V==g) { cout << "Message is OK" << endl; cout << "Verified Message= " << M << endl; } else cout << "Message is bad " << M << endl; return 0; }
int main() { PFC pfc(AES_SECURITY); // initialise pairing-friendly curve float ext_time, set_time, enc_time, dec_time; clock_t begin_time; Big q=pfc.order(); Big z,b,SSV,r,H,t; G1 P,Z,R; G2 Q,KB; GT g,w; time_t seed; time(&seed); irand((long)seed); // setup begin_time = clock(); pfc.random(P); pfc.random(Q); g=pfc.pairing(Q,P); pfc.precomp_for_power(g); pfc.random(z); pfc.precomp_for_mult(P); Z=pfc.mult(P,z); pfc.precomp_for_mult(Q); set_time = getExecutionTime(begin_time); // extract private key for Robert begin_time = clock(); b=pfc.hash_to_group((char *)"Robert"); KB=pfc.mult(Q,inverse(b+z,q)); ext_time = getExecutionTime(begin_time); begin_time = clock(); // verify private key pfc.precomp_for_pairing(KB); // Bob can precompute on his own private key if (pfc.pairing(KB,pfc.mult(P,b)+Z)!=g) { cout << "Bad private key" << endl; exit(0); } // Send session key to Bob cout << "All set to go.." << endl; pfc.rankey(SSV); // random AES key pfc.start_hash(); pfc.add_to_hash(SSV); pfc.add_to_hash(b); r=pfc.finish_hash_to_group(); R=pfc.mult(pfc.mult(P,b)+Z,r); t=pfc.hash_to_aes_key(pfc.power(g,r)); H=lxor(SSV,t); cout << "Encryption key= " << SSV << endl; enc_time = getExecutionTime(begin_time); // Receiver begin_time = clock(); t=pfc.hash_to_aes_key(pfc.pairing(KB,R)); SSV=lxor(H,t); pfc.start_hash(); pfc.add_to_hash(SSV); pfc.add_to_hash(b); r=pfc.finish_hash_to_group(); if (pfc.mult(pfc.mult(P,b)+Z,r)==R) cout << "Decryption key= " << SSV << endl; else cout << "The key is BAD - do not use!" << endl; dec_time = getExecutionTime(begin_time); cout << "Setup time: " << set_time << endl; cout << "Extract time: " << ext_time << endl; cout << "Encryption time: " << enc_time << endl; cout << "Decryption time: " << dec_time << endl; cout << " + --------" << endl; cout << "Total time: " << set_time + ext_time + enc_time + dec_time << endl; return 0; }
literalt smt1_propt::lequal(literalt a, literalt b) { return !lxor(a, b); }
int main() { PFC pfc(AES_SECURITY); // initialise pairing-friendly curve miracl *mip=get_mip(); // get handle on mip (Miracl Instance Pointer) Big order=pfc.order(); // get pairing-friendly group order time_t seed; // crude randomisation time(&seed); irand((long)seed); // setup - for 20 attributes 1-20 int i,j,k,n,ik,S[NBOB]; Big s,y,qi,M,ED,t[NATTR]; Big poly[Nd]; G1 P,T[NATTR],E[Nd],AE[NALICE]; G2 Q,AD[NALICE],BD[NBOB]; GT Y,DB; pfc.random(P); pfc.random(Q); pfc.precomp_for_mult(Q); // Q is fixed, so precompute on it pfc.random(y); Y=pfc.power(pfc.pairing(Q,P),y); for (i=0;i<NATTR;i++) { pfc.random(t[i]); // Note t[i] will be 2*AES_SECURITY bits long T[i]=pfc.mult(P,t[i]); // which may be less than the group order. pfc.precomp_for_mult(T[i],TRUE); // T[i] are system params, so precompute on them // Note second parameter indicates that all multipliers // must be <=2*AES_SECURITY bits, which may be shorter // than the full group size. } // key generation for Alice // A d-1 degree polynomial is randomly chosen such that q(0)=y poly[0]=y; for (i=1;i<Nd;i++) pfc.random(poly[i]); // Private key consists of components D_i where D_i=g^(q(i)/t_i) for (j=0;j<NALICE;j++) { i=Alice[j]; qi=y; ik=i; for (k=1;k<Nd;k++) { // evaluate polynomial a0+a1*x+a2*x^2... for x=i; => result is q(i) qi+=modmult(poly[k],(Big)ik,order); ik*=i; qi%=order; } // D_i=g^(q(i)/t_i) AD[j]=pfc.mult(Q,moddiv(qi,t[i],order)); // exploits precomputation } // key generation for Bob poly[0]=y; for (i=1;i<Nd;i++) pfc.random(poly[i]); for (j=0;j<NBOB;j++) { i=Bob[j]; qi=y; ik=i; for (k=1;k<Nd;k++) { // evaluate polynomial a0+a1*x+a2*x^2... for x=i; qi+=modmult(poly[k],(Big)ik,order); ik*=i; qi%=order; } BD[j]=pfc.mult(Q,moddiv(qi,t[i],order)); pfc.precomp_for_pairing(BD[j]); // Bob precomputes on his private key } // Encryption to Alice mip->IOBASE=256; M=(char *)"test message"; cout << "Message to be encrypted= " << M << endl; mip->IOBASE=16; pfc.random(s); ED=lxor(M,pfc.hash_to_aes_key(pfc.power(Y,s))); for (j=0;j<NALICE;j++) { i=Alice[j]; // calculate T_i^s AE[j]=pfc.mult(T[i],s); // exploit precomputation } // Decryption by Bob // set up to exploit multi-pairing G1 *g1[5]; G2 *g2[5]; k=0; for (j=0;j<NBOB;j++) { // check for common attributes i=Bob[j]; n=has_attribute(NALICE,Alice,i); if (n<0) continue; // Alice doesn't have it S[k]=i; E[k]=AE[n]; g2[k]=&BD[j]; k++; } if (k<Nd) { cout << "Bob does not have enough attributes in common with Alice to decrypt successfully" << endl; exit(0); } // faster to multiply in G1 than to exponentiate in GT for (j=0;j<Nd;j++) { i=S[j]; E[j]=pfc.mult(E[j],lagrange(i,S,Nd,order)); g1[j]=&E[j]; } DB=pfc.multi_pairing(Nd,g2,g1); M=lxor(ED,pfc.hash_to_aes_key(DB)); mip->IOBASE=256; cout << "Decrypted message= " << M << endl; return 0; }
literalt aig_prop_baset::lequal(literalt a, literalt b) { return !lxor(a, b); }
literalt boolector_propt::lequal(literalt a, literalt b) { return lnot(lxor(a, b)); }
literalt dplib_propt::lequal(literalt a, literalt b) { return !lxor(a, b); }