/* Waters ABE "Ciphertext-Policy Attribute-Based Encryption: An Expressive, Efficient, and Provably Secure Realisation" Section 3 Implemented on Type-3 pairing Compile with modules as specified below For MR_PAIRING_CP curve cl /O2 /GX cpabe.cpp cp_pair.cpp zzn2.cpp big.cpp zzn.cpp ecn.cpp miracl.lib For MR_PAIRING_MNT curve cl /O2 /GX cpabe.cpp mnt_pair.cpp zzn6a.cpp ecn3.cpp zzn3.cpp zzn2.cpp big.cpp zzn.cpp ecn.cpp miracl.lib For MR_PAIRING_BN curve cl /O2 /GX cpabe.cpp bn_pair.cpp zzn12a.cpp ecn2.cpp zzn4.cpp zzn2.cpp big.cpp zzn.cpp ecn.cpp miracl.lib For MR_PAIRING_KSS curve cl /O2 /GX cpabe.cpp kss_pair.cpp zzn18.cpp zzn6.cpp ecn3.cpp zzn3.cpp big.cpp zzn.cpp ecn.cpp miracl.lib For MR_PAIRING_BLS curve cl /O2 /GX cpabe.cpp bls_pair.cpp zzn24.cpp zzn8.cpp zzn4.cpp zzn2.cpp ecn4.cpp big.cpp zzn.cpp ecn.cpp miracl.lib See http://eprint.iacr.org/2008/290 */ #include #include //********* choose just one of these pairs ********** //#define MR_PAIRING_CP // AES-80 security //#define AES_SECURITY 80 //#define MR_PAIRING_MNT // AES-80 security //#define AES_SECURITY 80 #define MR_PAIRING_BN // AES-128 or AES-192 security #define AES_SECURITY 128 //#define AES_SECURITY 192 //#define MR_PAIRING_KSS // AES-192 security //#define AES_SECURITY 192 //#define MR_PAIRING_BLS // AES-256 security //#define AES_SECURITY 256 //********************************************* #include "pairing_3.h" // Access structure - crude boolean description of combination of attributes that a recipient must have // to be able to reconstruct the secret value /* Note that Access structure consists of threshold gates - output is TRUE if t out of n inputs are TRUE */ /* Access tree: Number (n), threshold (t), followed by n Child nodes */ /* Negative number denotes leaf node */ /* // This is example from Liu and Cao http://eprint.iacr.org/2010/374 // Negative number denotes leaf node int Access[]={ // node - index 2,2,1,2, // node 0 - 0 Here (n,t) = (2,2) so AND gate and the two children are nodes 1 and 2 2,1,3,4, // node 1 - 4 Here (n,t) = (2,1) so OR gate and the two children are nodes 3 and 4 4,3,-'E',-'F',-'G',-'H', // node 2 - 8 2,2,-'B',5, // node 3 - 14 Here (n,t) = (2,2) the first child is a leaf node, the second is node 5 3,2,-'C',-'D',-'E', // node 4 - 18 Here (n,t) = (3,2) and all 3 children are leaf nodes. 2,1,-'A',-'C', // node 5 - 23 0}; // Note total of 8 attributes A-H #define U 8 // These are the attributes of a particular recipient int auth[]={'D','E','F','G',0}; // attributes of recipient */ int Access[]={ // node - index 3,3,1,2,6, // node 0 - 0 Here (n,t) = (3,3) so AND gate and the children are nodes 1 and 2 and 6 2,1,3,4, // node 1 - 4 Here (n,t) = (2,1) so OR gate and the two children are nodes 3 and 4 4,3,-'E',-'F',-'G',-'H', // node 2 - 8 2,2,-'B',5, // node 3 - 14 Here (n,t) = (2,2) the first child is a leaf node, the second is node 5 3,2,-'C',-'D',-'E', // node 4 - 18 Here (n,t) = (3,2) and all 3 children are leaf nodes. 2,1,-'A',-'C', // node 5 - 23 2,1,-'I',7, // add in n<11 condition 2,2,-'J',8, 2,1,-'K',-'L', 0}; // Note total of 12 attributes A-L #define U 12 // These are the attributes of a particular recipient int auth[]={'D','E','F','G','J','K',0}; // attributes of valid recipient - try removing one! /* int Access[]={ // node - index 20,20,-'A',-'B',-'C',-'D',-'E',-'F',-'G',-'H',-'I',-'J',-'K',-'L',-'M',-'N',-'O',-'P',-'Q',-'R',-'S',-'T',0 }; #define U 20 int auth[]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T',0}; */ // get node index for i-th node int find_index(int Access[],int i) { int n,j,k; j=k=0; while (kn=Access[ipos]; nd->t=Access[ipos+1]; nd->child=new node [nd->n]; for (i=0;in;i++) { k=Access[ipos+2+i]; if (k<0) nd->child[i].n=k; else { j=find_index(Access,k); fill_node(&nd->child[i],Access,j); } } } void delete_node(node *nd) { int i,n=nd->n; nd->n=0; nd->t=0; if (n<=0) return; for (i=0;ichild[i]); delete [] nd->child; nd->child=NULL; } void copy_node(node *f, node *t) { int i; t->n=f->n; if (t->n<=0) return; t->t=f->t; t->child=new node [t->n]; for (i=0;in;i++) copy_node(&f->child[i],&t->child[i]); } // node constructor node::node(int *Access) { fill_node(this,Access,0); } // node destructor node::~node() { delete_node(this); } node& node::operator=(node& b) { delete_node(this); copy_node(&b,this); return *this; } // Find number of leaf attributes - the number of rows in Access matrix int find_m(int Access[]) { int i,m; i=m=0; while (Access[i]!=0) { i++; if (Access[i]<0) m++; } return m; } // find number of columns in Access matrix = 1 + Sum of (thresholds-1) ?? int find_d(int Access[]) { int j,d,n; j=0; d=1; while (Access[j]>0) { n=Access[j]; if (n==0) break; d+=Access[j+1]-1; j+=(n+2); } return d; } // traverse Access tree and pretty-print it void print_node(node *nd) { int c,n=nd->n; if (n<0) { cout << "(" << (char)(-n) << ")"; return; } cout << "("; for (int i=0;ichild[i].n; if (c<0) cout << (char)(-c) << ","; else print_node(&nd->child[i]); } cout << nd->t << "),"; } ostream& operator<<(ostream& s, node& x) { print_node(&x); return s; } // // make LSSS matrix of size rowsXcols from Access description // attr[i] contains attribute of each row. // algorithm due to Liu and Cao http://eprint.iacr.org/2010/374 // (but much simplified) // void make_LSSS(int Access[],int rows,int cols,Big **LSSS,int *attr) { int i,j,z,m,d,n,t; Big k; node Fz,root(Access); node *L=new node[rows]; for (i=0;i=z;i--) L[i+n-1]=L[i]; for (i=0;i=z;i--) { for (j=0;j=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;korder/2) { if (w[j]<0) w[j]+=order; else if (w[j]>0) w[j]-=order; } } delete [] row; return ok; } // given set of attributes and LSSS matrix, returns reconstruction constant numerators w, and rows // Note that original LSSS matrix is destroyed. Returns denominator of w. BOOL reduce_LSSS(Big &order,int &m,int &d,Big **LSSS,int *attr,int *auth,int *rows,Big *w) { int i,j,k,n,nattr=0; Big s,det; while (auth[nattr]!=0) nattr++; // find rows in LSSS which are associated with attributes in auth k=0; for (i=0;iIOBASE=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