MastersThesis/TIIGER_TLS/PQ_TIIGER_TLS/lib/ibe/tls_bfibe.cpp
2024-04-15 11:53:30 +02:00

269 lines
6.4 KiB
C++

//
// Pairing-based B&F IBE 128-bit API Functions
// Uses MIRACL
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#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;j<L;j++)
fd[j]=OKM.val[j];
BIG_dfromBytesLen(dx,fd,L);
BIG_dmod(w,dx,q);
FP_nres(&u1,w);
for (j=0;j<L;j++)
fd[j]=OKM.val[L+j];
BIG_dfromBytesLen(dx,fd,L);
BIG_dmod(w,dx,q);
FP_nres(&u2,w);
FP2_from_FPs(&u,&u1,&u2);
ECP2_map2point(Qid,&u);
ECP2_cfp(Qid);
ECP2_affine(Qid);
}
/* create random r in Zq from U and V, and rP */
static void h3(octet *U,octet *V,BIG r,ECP *rP)
{
int i;
BIG q;
csprng RNG;
BIG_rcopy(q, CURVE_Order);
char raw[128];
octet RAW = {128, sizeof(raw), raw};
sha3 sh;
SHA3_init(&sh,SHAKE256);
for (i=0;i<U->len;i++) {
SHA3_process(&sh,U->val[i]&0xff);
}
if (V!=NULL)
{
for (i=0;i<V->len;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;i<I->len;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;i<R32->len;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<LOOPS;i++)
{
for (int j=0;j<32;j++) {
r32[j]=((i+j)%256);
}
BFIBE_CCA_ENCRYPT(id,&R32,&M,&CT);
printf("EM= ");
OCT_output(&M);
BFIBE_CCA_DECRYPT(&SK,&CT,&M);
printf("DM= ");
OCT_output(&M);
}
return 0;
}
*/