// // Lattice-based B&F IBE 128-bit API Functions // Ducas et al. Method // Implementation by M.Scott // For code to set up TA and issue secret keys, contact me - michael.scott@tii.ae #include #include #include #include "tls_pqibe.h" using namespace std; using namespace core; #define PRIME 0x8020001 #define ONE 0x7C1FFE1 #define R2MODP 0xFA047E #define LIM 128 // should be 256? But could be 64 if we went unsigned #define LGN 10 #define ND 0x801FFFF #define DEGREE (1<>32; } static int32_t nres(uint32_t x) { return redc((uint64_t)x*R2MODP); } static int32_t modmul(uint32_t a,uint32_t b) { return redc((uint64_t)a*b); } /* NTT code */ /* Cooley-Tukey NTT */ static void ntt(int32_t *b) { int m,i,j,k,t=DEGREE/2; int32_t S,U,V,q=PRIME; for (j=0;j=LIM) { n--; k=0; for (i=0;i1) { lim=LIM>>n; n--; k=0; for (i=0;i>31)&q; } } // polynomial functions /* reduces inputs < 2q */ static void poly_soft_reduce(int32_t *poly) { int i; int32_t e; for (i=0;i>31)&PRIME)); //** } } /* fully reduces modulo q */ static void poly_hard_reduce(int32_t *poly) { int i; int32_t e; for (i=0;i>31)&PRIME); } } // multiply two polynomials in frequency domain static void poly_mul(int32_t *p1,int32_t *p2,int32_t *p3) { int i; for (i=0;i>=1; p[i]+=1; } else { p[i]>>=1; } } } static void poly_lengthen(int32_t *p) { int i; for (i=0;i(PRIME/2)) id[i]-=PRIME; } } // get n-th bit from byte array static int getbit(byte b[],int n) { int wd=n/8; int bt=n%8; return (b[wd]>>bt)&1; } // centered binomial distribution static void CBD(byte bts[],int32_t *f) { int a,b; for (int i=0;i>=1; m++; m&=7; } } static void shrink(int32_t *key,byte *ikey) { int i,k,m; byte next=0; for (m=k=i=0;i>bts; while (left<8) { i++; w=t[ptr+i]; r|=w<=ab) { bts-=ab; ptr++; } return (byte)r&0xff; } // extract ab bits into word from dense byte stream static int32_t nextword(const int ab,byte t[],int &ptr, int &bts) { int32_t r=t[ptr]>>bts; int32_t mask=(1<=8) { bts-=8; ptr++; } w=r&mask; return w; } // pack ciphertext static int pack_ct(byte ct[],int32_t *u,int32_t *v) { int ptr,bts,i,n=0; ptr=bts=0; for (i=0;i(PRIME/4) && v[i]<((3*PRIME)/4)) v[i]=PRIME/2; else v[i]=0;; } shrink(v,ikey); } // encapsulate 32-byte key inside ciphertext ct void PQIBE_CCA_ENCRYPT(char *ID,octet *R32,octet *KEY,octet *CT) { int i; byte ikey[DEGREE/8],ss[32]; sha3 sh; SHA3_init(&sh,SHAKE256); for (i=0;ilen;i++) SHA3_process(&sh,R32->val[i]); SHA3_shake(&sh,(char *)ikey,128); hdk(ikey,ss); cpa_encrypt(ID,ikey,(byte *)CT->val); for (i=0;i<32;i++) CT->val[i+ULEN+VLEN]=(char)ss[i]; CT->len=ULEN+VLEN+32; SHA3_init(&sh,SHA3_HASH256); for (i=0;ilen;i++) SHA3_process(&sh,(unsigned char)CT->val[i]); for (i=0;ival); KEY->len=32; } // decapsulate 32-byte key inside ciphertext ct void PQIBE_CCA_DECRYPT(char *ID,const int16_t *csk,octet *CT,octet *KEY) { int i; byte ikey[DEGREE/8]; sha3 sh; cpa_decrypt(csk,(byte *)CT->val,ikey); byte mask=cpa_check_encrypt(ID,ikey,(byte *)CT->val); // make sure to generate the same ciphertext for (i=0;ilen;i++) SHA3_process(&sh,(unsigned char)CT->val[i]); for (i=0;ival); KEY->len=32; } /* int main() { int i,m,k; byte ikey[DEGREE/8],ikey2[DEGREE/8]; sha3 SHA3; byte ct[4000]; byte key[32]; byte key2[32]; byte r32[32]; //for (i=0;i<128;i++) // printf("%d,",rand()%256); //printf("\n"); for (m=0;m<100;m++) { for (i=0;i<32;i++) // create byte array with DEGREE bits for polynomial r32[i]=rand()%256; // for (i=0;i