// // Pairing-based B&F IBE 128-bit API Functions // Uses MIRACL // #include #include #include #include #include "randapi.h" #include "tls_bfibe.h" #if CHUNK == 32 using namespace B384_29; #else using namespace B384_58; #endif using namespace BLS12381; #define ROUNDUP(a,b) ((a)-1)/(b)+1 /* Encode octet to curve point on G2 */ static void h1(char *identity,ECP2 *Qid) { int j,k,m,L; char okm[128],fd[64],dst[64],id[100]; octet ID = {0,sizeof(id),id}; octet DST = {0, sizeof(dst), dst}; OCT_jstring(&DST,(char *)"BLS12381G1_XMD:SHA-256_SVDW_NU_BFIBE"); // Domain Separation Tag OCT_jstring(&ID,identity); BIG q,r,w; FP u1,u2; FP2 u; DBIG dx; octet OKM = {0,sizeof(okm),okm}; BIG_rcopy(q,Modulus); k=BIG_nbits(q); BIG_rcopy(r, CURVE_Order); m=BIG_nbits(r); L=ROUNDUP(k+ROUNDUP(m,2),8); XOF_Expand(SHAKE128,&OKM,2*L,&DST,&ID); for (j=0;jlen;i++) { SHA3_process(&sh,U->val[i]&0xff); } if (V!=NULL) { for (i=0;ilen;i++) { SHA3_process(&sh,V->val[i]&0xff); } } SHA3_shake(&sh,raw,128); CREATE_CSPRNG(&RNG, &RAW); BIG_randtrunc(r, q, 2 * CURVE_SECURITY_BLS12381, &RNG); ECP_generator(rP); PAIR_G1mul(rP,r); } /* hash input octet to 32 bytes */ static void h4(octet *I,octet *O) { sha3 sh; SHA3_init(&sh,SHA3_HASH256); for (int i=0;ilen;i++) { SHA3_process(&sh,I->val[i]&0xff); } SHA3_hash(&sh,O->val); O->len=32; } /* Client secret CST=s*IDHTS where IDHTS is server ID hashed to a curve point, and s is the master secret */ static void bfibe_get_id_secret(BIG s, char *id, octet *SK) { ECP2 Q; h1(id,&Q); // Hash to curve PAIR_G2mul(&Q, s); ECP2_toOctet(SK, &Q, false); // change to TRUE for point compression } /* Extract TA public PK=S*Q where Q is fixed generator in G2 and S is master secret */ static void bfibe_get_ta_public(BIG s, octet *PK) { BIG r; ECP P; BIG_rcopy(r, CURVE_Order); ECP_generator(&P); PAIR_G1mul(&P, s); ECP_toOctet(PK, &P, false); } char *tapk=(char *)"0402d506a111d406dd0ad9d64b6515c4e15fd28ab45595b89817871d9220f0242c7b7ef1800ad8e6a8f047100088702ac8042add1af478ae20672c6670959ae36f19dcdee948f6b40a3498af69d708fbf15e81b536dacac484a697a59f3742063b"; /* IBE Encrypt */ bool BFIBE_CCA_ENCRYPT(char *ID,octet *R32,octet *M,octet *CT) { ECP rP,Ppub; ECP2 Qid; BIG r; FP12 g; char u[2*PFS_BLS12381+1],z[12*PFS_BLS12381],sigma[32],mask[32],v[32],w[32]; octet SIGMA={0,sizeof(sigma),sigma}; octet MASK={0,sizeof(mask),mask}; octet U = {0, sizeof(u), u}; octet V = {0, sizeof(v), v}; octet W = {0, sizeof(w), w}; octet Z = {0, sizeof(z), z}; sha3 sh; SHA3_init(&sh,SHAKE256); for (int i=0;ilen;i++) { SHA3_process(&sh,R32->val[i]&0xff); } SHA3_shake(&sh,SIGMA.val,32); // random sigma SHA3_shake(&sh,M->val,32); // generate encapsulated M->len=32; SIGMA.len=32; h1(ID,&Qid); // HID=H1(ID) h3(&SIGMA,M,r,&rP); // r,rP=H3(sigma,m) h4(&SIGMA,&MASK); // MASK=H4(sigma) OCT_copy(&W,M); OCT_xor(&W,&MASK); OCT_fromHex(&U,tapk); if (!ECP_fromOctet(&Ppub,&U)) return false; PAIR_G1mul(&Ppub,r); ECP_toOctet(&U,&rP,false); PAIR_ate(&g, &Qid, &Ppub); // e(HID,r.Ppub) PAIR_fexp(&g); FP12_toOctet(&Z,&g); h4(&Z,&MASK); OCT_copy(&V,&SIGMA); OCT_xor(&V,&MASK); OCT_empty(CT); OCT_joctet(CT,&U); OCT_joctet(CT,&V); OCT_joctet(CT,&W); return true; } /* IBE Decrypt */ bool BFIBE_CCA_DECRYPT(octet *SK,octet *CT,octet *M) { ECP rPc,rP; ECP2 Did; FP12 g; BIG r; char u[2*PFS_BLS12381+65],z[12*PFS_BLS12381],sigma[32],v[64],w[32]; octet U={0,sizeof(u),u}; octet W={0,sizeof(w),w}; octet V={0,sizeof(v),v}; octet Z = {0, sizeof(z), z}; octet SIGMA={0,sizeof(sigma),sigma}; OCT_copy(&U,CT); OCT_chop(&U,&V,2*PFS_BLS12381+1); OCT_chop(&V,&W,32); if (!ECP_fromOctet(&rP,&U)) return false; if (!ECP2_fromOctet(&Did,SK)) return false; PAIR_ate(&g,&Did,&rP); // e(Did,U) PAIR_fexp(&g); FP12_toOctet(&Z,&g); h4(&Z,&SIGMA); OCT_xor(&SIGMA,&V); h4(&SIGMA,M); OCT_xor(M,&W); h3(&SIGMA,M,r,&rPc); if (!ECP_equals(&rP,&rPc)) return false; return true; } // secret key for "localhost" char *idsk=(char *)"040ec014966d3442e85ed19b46044d9655d8ed91ef05e6678e57a51cfd9202c8dad2c854850b09fc919b6cb000a2f5b05801b767a87194d62d45cb1b1a9cd15b63ea733770361de22f64946631c2c21826d8abf884e4d07159d54c91b79662e2e4050ae782a9fb9394853669540b4cb1f46098ca690bd572b9c47587ca12a2f2c268e1a22ebc0d752f95bcf926a8b6e2cb1452dc7bf03eab18c5b68822b0da20279d1e8997a759637abdffec93f4c985f9256deed1cca5c50e2c37ae6c10c67c13"; /* #define LOOPS 100 int main() { char *id=(char *)"localhost"; char r32[32],sk[256],m[32],ct[2*PFS_BLS12381+65],pk[4*PFS_BLS12381+1]; octet R32={32, sizeof(r32), r32}; octet SK = {0, sizeof(sk), sk}; octet PK = {0, sizeof(pk), pk}; octet M = {0, sizeof(m), m}; octet CT = {0, sizeof(ct), ct}; // BIG s; // ECP rP; // // for (int i=0;i<32;i++) // r32[i]=i+5; // // h3(&R32,NULL, s, &rP); // //OCT_output(&S); // bfibe_get_id_secret(s, id, &SK); // printf("SK= "); OCT_output(&SK); // bfibe_get_ta_public(s, &PK); // printf("PK= "); OCT_output(&PK); OCT_fromHex(&SK,idsk); for (int i=0;i