├── README.md ├── Testbed.py ├── abenc_bsw07.py ├── abenc_waters09.py ├── abenc_lsw08.py ├── abenc_yct14.py ├── abenc_unmcpabe_yahk14.py ├── dabe_aw11.py ├── abenc_maabe_rw15.py ├── abenc_tbpre_lww14.py ├── abenc_maabe_yj14.py └── abenc_dacmacs_yj14.py /README.md: -------------------------------------------------------------------------------- 1 | # Attribute-Based-Encryption 2 | 3 | >>>python3 Testbed.py
4 | Enter the name of Algorithm
5 | NAME
6 | 7 | O/P
8 | Time taken by Setup function is ###
9 | Time taken by Keygen function is ###
10 | Time taken by Encrypt function is ###
11 | Time taken by Decrypt function is ###
12 | Total time taken by NAME.py function is ### 13 | 14 | -------------------------------------------------------------------------------- /Testbed.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import subprocess 3 | import time 4 | import io 5 | #s2_out = subprocess.check_output([sys.executable, "test2.py"]) 6 | d={} 7 | d[0]=[] 8 | d[1]=[] 9 | d[2]=[] 10 | d[3]=[] 11 | print("Enter the name of Algorithm") 12 | s=input()+'.py' 13 | #print(s) 14 | #s = io.StringIO(s) 15 | start_time=time.time() 16 | for i in range(10): 17 | exec(open(s).read()) 18 | d[0].append(a[0]) 19 | d[1].append(a[1]) 20 | d[2].append(a[2]) 21 | d[3].append(a[3]) 22 | end_time=time.time() 23 | print("Time taken by Setup function is ",sum(d[0])/10) 24 | print("Time taken by Keygen function is ",sum(d[1])/10) 25 | print("Time taken by Encrypt function is ",sum(d[2])/10) 26 | print("Time taken by Decrypt function is ",sum(d[3])/10) 27 | print("Total time taken by ",s," function is ", (end_time-start_time)/10) 28 | #for j in d.keys(): 29 | # print(sum(d[j])/10) 30 | -------------------------------------------------------------------------------- /abenc_bsw07.py: -------------------------------------------------------------------------------- 1 | ''' 2 | John Bethencourt, Brent Waters (Pairing-based) 3 | 4 | | From: "Ciphertext-Policy Attribute-Based Encryption". 5 | | Published in: 2007 6 | | Available from: 7 | | Notes: 8 | | Security Assumption: 9 | | 10 | | type: ciphertext-policy attribute-based encryption (public key) 11 | | setting: Pairing 12 | 13 | :Authors: J Ayo Akinyele 14 | :Date: 04/2011 15 | ''' 16 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair 17 | from charm.toolbox.secretutil import SecretUtil 18 | from charm.toolbox.ABEnc import ABEnc, Input, Output 19 | import time 20 | 21 | # type annotations 22 | pk_t = { 'g':G1, 'g2':G2, 'h':G1, 'f':G1, 'e_gg_alpha':GT } 23 | mk_t = {'beta':ZR, 'g2_alpha':G2 } 24 | sk_t = { 'D':G2, 'Dj':G2, 'Djp':G1, 'S':str } 25 | ct_t = { 'C_tilde':GT, 'C':G1, 'Cy':G1, 'Cyp':G2 } 26 | 27 | debug = False 28 | class CPabe_BSW07(ABEnc): 29 | """ 30 | >>> from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair 31 | >>> group = PairingGroup('SS512') 32 | >>> cpabe = CPabe_BSW07(group) 33 | >>> msg = group.random(GT) 34 | >>> attributes = ['ONE', 'TWO', 'THREE'] 35 | >>> access_policy = '((four or three) and (three or one))' 36 | >>> (master_public_key, master_key) = cpabe.setup() 37 | >>> secret_key = cpabe.keygen(master_public_key, master_key, attributes) 38 | >>> cipher_text = cpabe.encrypt(master_public_key, msg, access_policy) 39 | >>> decrypted_msg = cpabe.decrypt(master_public_key, secret_key, cipher_text) 40 | >>> msg == decrypted_msg 41 | True 42 | """ 43 | 44 | def __init__(self, groupObj): 45 | ABEnc.__init__(self) 46 | global util, group 47 | util = SecretUtil(groupObj, verbose=False) 48 | group = groupObj 49 | 50 | @Output(pk_t, mk_t) 51 | def setup(self): 52 | g, gp = group.random(G1), group.random(G2) 53 | alpha, beta = group.random(ZR), group.random(ZR) 54 | # initialize pre-processing for generators 55 | g.initPP(); gp.initPP() 56 | 57 | h = g ** beta; f = g ** ~beta 58 | e_gg_alpha = pair(g, gp ** alpha) 59 | 60 | pk = { 'g':g, 'g2':gp, 'h':h, 'f':f, 'e_gg_alpha':e_gg_alpha } 61 | mk = {'beta':beta, 'g2_alpha':gp ** alpha } 62 | return (pk, mk) 63 | 64 | @Input(pk_t, mk_t, [str]) 65 | @Output(sk_t) 66 | def keygen(self, pk, mk, S): 67 | r = group.random() 68 | g_r = (pk['g2'] ** r) 69 | D = (mk['g2_alpha'] * g_r) ** (1 / mk['beta']) 70 | D_j, D_j_pr = {}, {} 71 | for j in S: 72 | r_j = group.random() 73 | D_j[j] = g_r * (group.hash(j, G2) ** r_j) 74 | D_j_pr[j] = pk['g'] ** r_j 75 | return { 'D':D, 'Dj':D_j, 'Djp':D_j_pr, 'S':S } 76 | 77 | @Input(pk_t, GT, str) 78 | @Output(ct_t) 79 | def encrypt(self, pk, M, policy_str): 80 | policy = util.createPolicy(policy_str) 81 | a_list = util.getAttributeList(policy) 82 | s = group.random(ZR) 83 | shares = util.calculateSharesDict(s, policy) 84 | 85 | C = pk['h'] ** s 86 | C_y, C_y_pr = {}, {} 87 | for i in shares.keys(): 88 | j = util.strip_index(i) 89 | C_y[i] = pk['g'] ** shares[i] 90 | C_y_pr[i] = group.hash(j, G2) ** shares[i] 91 | 92 | return { 'C_tilde':(pk['e_gg_alpha'] ** s) * M, 93 | 'C':C, 'Cy':C_y, 'Cyp':C_y_pr, 'policy':policy_str, 'attributes':a_list } 94 | 95 | @Input(pk_t, sk_t, ct_t) 96 | @Output(GT) 97 | def decrypt(self, pk, sk, ct): 98 | policy = util.createPolicy(ct['policy']) 99 | pruned_list = util.prune(policy, sk['S']) 100 | if pruned_list == False: 101 | return False 102 | z = util.getCoefficients(policy) 103 | A = 1 104 | for i in pruned_list: 105 | j = i.getAttributeAndIndex(); k = i.getAttribute() 106 | A *= ( pair(ct['Cy'][j], sk['Dj'][k]) / pair(sk['Djp'][k], ct['Cyp'][j]) ) ** z[j] 107 | 108 | return ct['C_tilde'] / (pair(ct['C'], sk['D']) / A) 109 | 110 | 111 | def main(arg): 112 | l=[] 113 | groupObj = PairingGroup('SS512') 114 | 115 | cpabe = CPabe_BSW07(groupObj) 116 | attrs = ['ONE', 'TWO', 'THREE'] 117 | access_policy = '((four or three) and (three or one))' 118 | #if debug: 119 | # print("Attributes =>", attrs); print("Policy =>", access_policy) 120 | 121 | start1= time.time() 122 | (pk, mk) = cpabe.setup() 123 | l.append(time.time()-start1) 124 | 125 | start2 = time.time() 126 | sk = cpabe.keygen(pk, mk, attrs) 127 | l.append(time.time() - start2) 128 | #print("sk :=>", sk) 129 | 130 | rand_msg = groupObj.random(GT) 131 | #if debug: print("msg =>", rand_msg) 132 | start3 = time.time() 133 | ct = cpabe.encrypt(pk, rand_msg, access_policy) 134 | l.append(time.time() - start3) 135 | #if debug: print("\n\nCiphertext...\n") 136 | groupObj.debug(ct) 137 | 138 | start4 = time.time() 139 | rec_msg = cpabe.decrypt(pk, sk, ct) 140 | l.append(time.time() - start4) 141 | #if debug: print("\n\nDecrypt...\n") 142 | #if debug: print("Rec msg =>", rec_msg) 143 | 144 | assert rand_msg == rec_msg, "FAILED Decryption: message is incorrect" 145 | #if debug: print("Successful Decryption!!!") 146 | 147 | return l 148 | 149 | 150 | if __name__ == "__main__": 151 | debug = False 152 | a = main(0) 153 | -------------------------------------------------------------------------------- /abenc_waters09.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Brent Waters (Pairing-based) 3 | 4 | | From: "Ciphertext-Policy Attribute-Based Encryption: An Expressive, Efficient, and Provably Secure Realization", Appendix C. 5 | | Published in: 2008 6 | | Available from: http://eprint.iacr.org/2008/290.pdf 7 | | Notes: Security Assumption: parallel q-DBDHE. The sole disadvantage of this scheme is the high number of pairings 8 | | that must be computed during the decryption process (2 + N) for N attributes mathing in the key. 9 | 10 | * type: ciphertext-policy attribute-based encryption (public key) 11 | * setting: Pairing 12 | 13 | :Authors: J Ayo Akinyele 14 | :Date: 11/2010 15 | ''' 16 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair 17 | from charm.toolbox.secretutil import SecretUtil 18 | from charm.toolbox.ABEnc import ABEnc 19 | import time 20 | 21 | debug = False 22 | class CPabe09(ABEnc): 23 | """ 24 | >>> from charm.toolbox.pairinggroup import PairingGroup,GT 25 | >>> group = PairingGroup('SS512') 26 | >>> cpabe = CPabe09(group) 27 | >>> msg = group.random(GT) 28 | >>> (master_secret_key, master_public_key) = cpabe.setup() 29 | >>> policy = '((ONE or THREE) and (TWO or FOUR))' 30 | >>> attr_list = ['THREE', 'ONE', 'TWO'] 31 | >>> secret_key = cpabe.keygen(master_public_key, master_secret_key, attr_list) 32 | >>> cipher_text = cpabe.encrypt(master_public_key, msg, policy) 33 | >>> decrypted_msg = cpabe.decrypt(master_public_key, secret_key, cipher_text) 34 | >>> decrypted_msg == msg 35 | True 36 | """ 37 | 38 | def __init__(self, groupObj): 39 | ABEnc.__init__(self) 40 | global util, group 41 | util = SecretUtil(groupObj, debug) 42 | group = groupObj 43 | 44 | def setup(self): 45 | g1, g2 = group.random(G1), group.random(G2) 46 | alpha, a = group.random(), group.random() 47 | e_gg_alpha = pair(g1,g2) ** alpha 48 | msk = {'g1^alpha':g1 ** alpha, 'g2^alpha':g2 ** alpha} 49 | pk = {'g1':g1, 'g2':g2, 'e(gg)^alpha':e_gg_alpha, 'g1^a':g1 ** a, 'g2^a':g2 ** a} 50 | return (msk, pk) 51 | 52 | 53 | def keygen(self, pk, msk, attributes): 54 | t = group.random() 55 | K = msk['g2^alpha'] * (pk['g2^a'] ** t) 56 | L = pk['g2'] ** t 57 | k_x = [group.hash(s, G1) ** t for s in attributes] 58 | 59 | K_x = {} 60 | for i in range(0, len(k_x)): 61 | K_x[ attributes[i] ] = k_x[i] 62 | 63 | key = { 'K':K, 'L':L, 'K_x':K_x, 'attributes':attributes } 64 | return key 65 | 66 | 67 | def encrypt(self, pk, M, policy_str): 68 | # Extract the attributes as a list 69 | policy = util.createPolicy(policy_str) 70 | p_list = util.getAttributeList(policy) 71 | s = group.random() 72 | C_tilde = (pk['e(gg)^alpha'] ** s) * M 73 | C_0 = pk['g1'] ** s 74 | C, D = {}, {} 75 | secret = s 76 | shares = util.calculateSharesList(secret, policy) 77 | 78 | # ciphertext 79 | for i in range(len(p_list)): 80 | r = group.random() 81 | if shares[i][0] == p_list[i]: 82 | attr = shares[i][0].getAttribute() 83 | C[ p_list[i] ] = ((pk['g1^a'] ** shares[i][1]) * (group.hash(attr, G1) ** -r)) 84 | D[ p_list[i] ] = (pk['g2'] ** r) 85 | 86 | if debug: print("SessionKey: %s" % C_tilde) 87 | return { 'C0':C_0, 'C':C, 'D':D , 'C_tilde':C_tilde, 'policy':policy_str, 'attribute':p_list } 88 | 89 | 90 | def decrypt(self, pk, sk, ct): 91 | policy = util.createPolicy(ct['policy']) 92 | pruned = util.prune(policy, sk['attributes']) 93 | if pruned == False: 94 | return False 95 | coeffs = util.getCoefficients(policy) 96 | numerator = pair(ct['C0'], sk['K']) 97 | 98 | # create list for attributes in order... 99 | k_x, w_i = {}, {} 100 | for i in pruned: 101 | j = i.getAttributeAndIndex() 102 | k = i.getAttribute() 103 | k_x[ j ] = sk['K_x'][k] 104 | w_i[ j ] = coeffs[j] 105 | #print('Attribute %s: coeff=%s, k_x=%s' % (j, w_i[j], k_x[j])) 106 | 107 | C, D = ct['C'], ct['D'] 108 | denominator = 1 109 | for i in pruned: 110 | j = i.getAttributeAndIndex() 111 | denominator *= ( pair(C[j] ** w_i[j], sk['L']) * pair(k_x[j] ** w_i[j], D[j]) ) 112 | return ct['C_tilde'] / (numerator / denominator) 113 | 114 | 115 | def main(arg): 116 | #Get the eliptic curve with the bilinear mapping feature needed. 117 | l=[] 118 | groupObj = PairingGroup('SS512') 119 | 120 | cpabe = CPabe09(groupObj) 121 | 122 | start1 = time.time() 123 | (msk, pk) = cpabe.setup() 124 | l.append(time.time() - start1) 125 | 126 | 127 | pol = '((ONE or THREE) and (TWO or FOUR))' 128 | attr_list = ['THREE', 'ONE', 'TWO'] 129 | 130 | if debug: print('Acces Policy: %s' % pol) 131 | if debug: print('User credential list: %s' % attr_list) 132 | m = groupObj.random(GT) 133 | 134 | start2 = time.time() 135 | cpkey = cpabe.keygen(pk, msk, attr_list) 136 | l.append(time.time() - start2) 137 | 138 | #if debug: print("\nSecret key: %s" % attr_list) 139 | #if debug:groupObj.debug(cpkey) 140 | 141 | start3 = time.time() 142 | cipher = cpabe.encrypt(pk, m, pol) 143 | l.append(time.time() - start3) 144 | 145 | # if debug: print("\nCiphertext...") 146 | #if debug:groupObj.debug(cipher) 147 | 148 | start4 = time.time() 149 | orig_m = cpabe.decrypt(pk, cpkey, cipher) 150 | l.append(time.time() - start4) 151 | 152 | assert m == orig_m, 'FAILED Decryption!!!' 153 | # if debug: print('Successful Decryption!') 154 | del groupObj 155 | return l 156 | 157 | 158 | if __name__ == '__main__': 159 | debug = False 160 | a = main(0) -------------------------------------------------------------------------------- /abenc_lsw08.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Allison Lewko, Amit Sahai and Brent Waters (Pairing-based) 3 | 4 | | From: "Revocation Systems with Very Small Private Keys", Large Universe Construction 5 | | Published in: IEEE S&P 2010 6 | | Available from: http://eprint.iacr.org/2008/309.pdf 7 | | Notes: 8 | 9 | * type: key-policy attribute-based encryption (public key) 10 | * setting: Pairing 11 | 12 | :Authors: J Ayo Akinyele 13 | :Date: 12/2010 14 | ''' 15 | 16 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair 17 | from charm.toolbox.secretutil import SecretUtil 18 | from charm.toolbox.ABEnc import ABEnc 19 | import time 20 | debug = False 21 | class KPabe(ABEnc): 22 | """ 23 | >>> from charm.toolbox.pairinggroup import PairingGroup,GT 24 | >>> group = PairingGroup('MNT224') 25 | >>> kpabe = KPabe(group) 26 | >>> (master_public_key, master_key) = kpabe.setup() 27 | >>> policy = '(ONE or THREE) and (THREE or TWO)' 28 | >>> attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ] 29 | >>> secret_key = kpabe.keygen(master_public_key, master_key, policy) 30 | >>> msg=group.random(GT) 31 | >>> cipher_text = kpabe.encrypt(master_public_key, msg, attributes) 32 | >>> decrypted_msg = kpabe.decrypt(cipher_text, secret_key) 33 | >>> decrypted_msg == msg 34 | True 35 | """ 36 | 37 | def __init__(self, groupObj, verbose=False): 38 | ABEnc.__init__(self) 39 | global group, util 40 | group = groupObj 41 | util = SecretUtil(group, verbose) 42 | 43 | 44 | def setup(self): 45 | # pick random exponents 46 | alpha1, alpha2, b = group.random(ZR), group.random(ZR), group.random(ZR) 47 | 48 | alpha = alpha1 * alpha2 49 | g_G1, g_G2 = group.random(G1), group.random(G2) # PK 1,2 50 | h_G1, h_G2 = group.random(G1), group.random(G2) # PK 3 51 | g1b = g_G1 ** b 52 | e_gg_alpha = pair(g_G1,g_G2) ** alpha 53 | 54 | #public parameters # 'g_G2^b':(g_G2 ** b), 'g_G2^b2':g_G2 ** (b * b), 55 | pk = { 'g_G1':g_G1, 'g_G2':g_G2, 'g_G1_b':g1b, 56 | 'g_G1_b2':g1b ** b, 'h_G1_b':h_G1 ** b, 'e(gg)_alpha':e_gg_alpha } 57 | #secret parameters 58 | mk = { 'alpha1':alpha1, 'alpha2':alpha2, 'b':b, 'h_G1':h_G1, 'h_G2':h_G2 } 59 | return (pk, mk) 60 | 61 | 62 | 63 | def keygen(self, pk, mk, policy_str): 64 | policy = util.createPolicy(policy_str) 65 | attr_list = util.getAttributeList(policy) 66 | 67 | s = mk['alpha1']; secret = s 68 | shares = util.calculateSharesDict(secret, policy) 69 | 70 | D = { 'policy': policy_str } 71 | for x in attr_list: 72 | y = util.strip_index(x) 73 | d = []; r = group.random(ZR) 74 | if not self.negatedAttr(x): # meaning positive 75 | d.append((pk['g_G1'] ** (mk['alpha2'] * shares[x])) * (group.hash(y, G1) ** r)) # compute D1 for attribute x 76 | d.append((pk['g_G2'] ** r)) # compute D2 for attribute x 77 | #else: 78 | #d.append((pk['g2_G1'] ** shares[x]) * (pk['g_G1_b2'] ** r)) # compute D3 79 | #d.append((pk['g_G1_b'] ** (r * group.hash(x))) * (pk['h_G1'] ** r)) # compute D4 80 | #d.append(pk['g_G1'] ** -r) # compute D5 81 | D[x] = d 82 | if debug: print("Access Policy for key: %s" % policy) 83 | if debug: print("Attribute list: %s" % attr_list) 84 | return D 85 | 86 | 87 | 88 | def negatedAttr(self, attribute): 89 | if type(attribute) != str: attr = attribute.getAttribute() 90 | else: attr = attribute 91 | if attr[0] == '!': 92 | if debug: print("Checking... => %s" % attr[0]) 93 | return True 94 | return False 95 | 96 | 97 | 98 | def encrypt(self, pk, M, attr_list): 99 | if debug: print('Encryption Algorithm...') 100 | # s will hold secret 101 | t = group.init(ZR, 0) 102 | s = group.random(); sx = [s] 103 | for i in range(len(attr_list)): 104 | sx.append(group.random(ZR)) 105 | sx[0] -= sx[i] 106 | 107 | E3 = {} 108 | #E4, E5 = {}, {} 109 | for i in range(len(attr_list)): 110 | attr = attr_list[i] 111 | E3[attr] = group.hash(attr, G1) ** s 112 | #E4[attr] = pk['g_G1_b'] ** sx[i] 113 | #E5[attr] = (pk['g_G1_b2'] ** (sx[i] * group.hash(attr))) * (pk['h_G1_b'] ** sx[i]) 114 | 115 | E1 = (pk['e(gg)_alpha'] ** s) * M 116 | E2 = pk['g_G2'] ** s 117 | return {'E1':E1, 'E2':E2, 'E3':E3, 'attributes':attr_list } 118 | 119 | 120 | 121 | def decrypt(self, E, D): 122 | policy = util.createPolicy(D['policy']) 123 | attrs = util.prune(policy, E['attributes']) 124 | if attrs == False: 125 | return False 126 | coeff = util.getCoefficients(policy) 127 | 128 | Z = {}; prodT = 1 129 | for i in range(len(attrs)): 130 | x = attrs[i].getAttribute() 131 | y = attrs[i].getAttributeAndIndex() 132 | if not self.negatedAttr(y): 133 | Z[y] = pair(D[y][0], E['E2']) / pair(E['E3'][x], D[y][1]) 134 | prodT *= Z[y] ** coeff[y] 135 | 136 | return E['E1'] / prodT 137 | 138 | 139 | 140 | def main(arg): 141 | 142 | l=[] 143 | groupObj = PairingGroup('MNT224') 144 | kpabe = KPabe(groupObj) 145 | 146 | start1=time.time() 147 | (pk, mk) = kpabe.setup() 148 | l.append(time.time()-start1) 149 | 150 | policy = '(ONE or THREE) and (THREE or TWO)' 151 | attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ] 152 | msg = groupObj.random(GT) 153 | 154 | start2=time.time() 155 | mykey = kpabe.keygen(pk, mk, policy) 156 | l.append(time.time()-start2) 157 | 158 | # if debug: print("Encrypt under these attributes: ", attributes) 159 | 160 | start3=time.time() 161 | ciphertext = kpabe.encrypt(pk, msg, attributes) 162 | l.append(time.time()-start3) 163 | 164 | # if debug: print(ciphertext) 165 | 166 | start4=time.time() 167 | rec_msg = kpabe.decrypt(ciphertext, mykey) 168 | l.append(time.time()-start4) 169 | 170 | assert msg == rec_msg 171 | # if debug: print("Successful Decryption!") 172 | return l 173 | 174 | 175 | if __name__ == "__main__": 176 | debug = True 177 | a=main(0) 178 | 179 | -------------------------------------------------------------------------------- /abenc_yct14.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Xuanxia Yao, Zhi Chen, Ye Tian 3 | 4 | | From: A lightweight attribute-based encryption scheme for the Internet of things 5 | | Published in: Future Generation Computer Systems 6 | | Available From: http://www.sciencedirect.com/science/article/pii/S0167739X14002039 7 | | Notes: 8 | 9 | * type: key-policy attribute-based encryption (public key) 10 | * setting: No Pairing 11 | 12 | :Authors: artjomb 13 | :Date: 10/2014 14 | ''' 15 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair 16 | from charm.toolbox.secretutil import SecretUtil 17 | from charm.toolbox.symcrypto import SymmetricCryptoAbstraction 18 | from charm.toolbox.ABEnc import ABEnc 19 | from charm.schemes.abenc.abenc_lsw08 import KPabe 20 | from charm.core.math.pairing import hashPair as extractor 21 | 22 | from time import clock 23 | 24 | debug = False 25 | class EKPabe(ABEnc): 26 | """ 27 | >>> from charm.toolbox.pairinggroup import PairingGroup,GT 28 | >>> group = PairingGroup('MNT224') 29 | >>> kpabe = EKPabe(group) 30 | >>> attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ] 31 | >>> (master_public_key, master_key) = kpabe.setup(attributes) 32 | >>> policy = '(ONE or THREE) and (THREE or TWO)' 33 | >>> secret_key = kpabe.keygen(master_public_key, master_key, policy) 34 | >>> msg = b"Some Random Message" 35 | >>> cipher_text = kpabe.encrypt(master_public_key, msg, attributes) 36 | >>> decrypted_msg = kpabe.decrypt(cipher_text, secret_key) 37 | >>> decrypted_msg == msg 38 | True 39 | """ 40 | 41 | def __init__(self, groupObj, verbose=False): 42 | ABEnc.__init__(self) 43 | global group, util 44 | group = groupObj 45 | util = SecretUtil(group, verbose) 46 | 47 | def setup(self, attributes): 48 | s = group.random(ZR) 49 | g = group.random(G1) 50 | 51 | self.attributeSecrets = {} 52 | self.attribute = {} 53 | for attr in attributes: 54 | si = group.random(ZR) 55 | self.attributeSecrets[attr] = si 56 | self.attribute[attr] = g**si 57 | return (g**s, s) # (pk, mk) 58 | 59 | 60 | def keygen(self, pk, mk, policy_str): 61 | policy = util.createPolicy(policy_str) 62 | attr_list = util.getAttributeList(policy) 63 | 64 | s = mk 65 | shares = util.calculateSharesDict(s, policy) 66 | 67 | d = {} 68 | D = { 'policy': policy_str, 'Du': d } 69 | for x in attr_list: 70 | y = util.strip_index(x) 71 | d[y] = shares[x]/self.attributeSecrets[y] 72 | if debug: print(str(y) + " d[y] " + str(d[y])) 73 | if debug: print("Access Policy for key: %s" % policy) 74 | if debug: print("Attribute list: %s" % attr_list) 75 | return D 76 | 77 | 78 | def encrypt(self, pk, M, attr_list): 79 | if debug: print('Encryption Algorithm...') 80 | k = group.random(ZR); 81 | Cs = pk ** k 82 | 83 | Ci = {} 84 | for attr in attr_list: 85 | Ci[attr] = self.attribute[attr] ** k 86 | 87 | symcrypt = SymmetricCryptoAbstraction(extractor(Cs)) 88 | C = symcrypt.encrypt(M) 89 | 90 | return { 'C': C, 'Ci': Ci, 'attributes': attr_list } 91 | 92 | 93 | def decrypt(self, C, D): 94 | policy = util.createPolicy(D['policy']) 95 | attrs = util.prune(policy, C['attributes']) 96 | if attrs == False: 97 | return False 98 | coeff = util.getCoefficients(policy) 99 | 100 | Z = {} 101 | prodT = 1 102 | for i in range(len(attrs)): 103 | x = attrs[i].getAttribute() 104 | y = attrs[i].getAttributeAndIndex() 105 | Z[y] = C['Ci'][x] ** D['Du'][x] 106 | prodT *= Z[y] ** coeff[y] 107 | 108 | symcrypt = SymmetricCryptoAbstraction(extractor(prodT)) 109 | 110 | return symcrypt.decrypt(C['C']) 111 | 112 | 113 | def main(): 114 | groupObj = PairingGroup('MNT224') 115 | kpabe = EKPabe(groupObj) 116 | 117 | attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ] 118 | 119 | (pk, mk) = kpabe.setup(attributes) 120 | 121 | # policy = '(ONE or THREE) and (THREE or TWO)' 122 | policy = 'THREE and (ONE or TWO)' 123 | msg = b"Some Random Message" 124 | 125 | mykey = kpabe.keygen(pk, mk, policy) 126 | 127 | if debug: print("Encrypt under these attributes: ", attributes) 128 | ciphertext = kpabe.encrypt(pk, msg, attributes) 129 | if debug: print(ciphertext) 130 | 131 | rec_msg = kpabe.decrypt(ciphertext, mykey) 132 | assert rec_msg 133 | if debug: print("rec_msg=%s" % str(rec_msg)) 134 | 135 | assert msg == rec_msg 136 | if debug: print("Successful Decryption!") 137 | 138 | 139 | def benchmark(arg): 140 | groupObj1 = PairingGroup('MNT224') 141 | groupObj2 = PairingGroup('MNT224') 142 | ekpabe = EKPabe(groupObj1) 143 | kpabe = KPabe(groupObj2) 144 | l=[] 145 | t1_s = 0 146 | t1_k = 0 147 | t1_e = 0 148 | t1_d = 0 149 | t2_s = 0 150 | t2_k = 0 151 | t2_e = 0 152 | t2_d = 0 153 | 154 | attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ] 155 | policy = 'THREE and (ONE or TWO)' 156 | msg1 = b"Some Random Message" 157 | msg2 = groupObj2.random(GT) 158 | 159 | for b in range(4): 160 | start = clock() 161 | (epk, emk) = ekpabe.setup(attributes) 162 | t1_s += clock() - start 163 | 164 | start = clock() 165 | (pk, mk) = kpabe.setup() 166 | t2_s += clock() - start 167 | 168 | start = clock() 169 | emykey = ekpabe.keygen(epk, emk, policy) 170 | t1_k += clock() - start 171 | 172 | start = clock() 173 | mykey = kpabe.keygen(pk, mk, policy) 174 | t2_k += clock() - start 175 | 176 | for i in range(50): 177 | start = clock() 178 | eciphertext = ekpabe.encrypt(epk, msg1, attributes) 179 | t1_e += clock() - start 180 | 181 | start = clock() 182 | ciphertext = kpabe.encrypt(pk, msg2, attributes) 183 | t2_e += clock() - start 184 | 185 | start = clock() 186 | erec_msg = ekpabe.decrypt(eciphertext, emykey) 187 | t1_d += clock() - start 188 | 189 | start = clock() 190 | rec_msg = kpabe.decrypt(ciphertext, mykey) 191 | t2_d += clock() - start 192 | 193 | assert msg1 == erec_msg 194 | assert msg2 == rec_msg 195 | 196 | # print ("yct14 s=%s k=%s e=%s d=%s" % (t1_s, t1_k, t1_e, t1_d)) 197 | # print ("lsw08 s=%s k=%s e=%s d=%s" % (t2_s, t2_k, t2_e, t2_d)) 198 | l.append(t1_s+t2_s) 199 | l.append(t1_k+t2_k) 200 | l.append(t1_e+t2_e) 201 | l.append(t1_d+t2_d) 202 | return l 203 | 204 | 205 | # Result in VM: 206 | # yct14 s=0.1 k=0.02 e=3.44 d=2.91 207 | # lsw08 s=0.42 k=0.41 e=10.32 d=21.25 208 | 209 | if __name__ == "__main__": 210 | # debug = True 211 | # main() 212 | a = benchmark(0) 213 | -------------------------------------------------------------------------------- /abenc_unmcpabe_yahk14.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Yamada, Attrapadung, Hanaoka, Kunihiro 3 | 4 | | From: "A Framework and Compact Constructions for Non-monotonic Attribute-Based Encryption" 5 | | Published in: Public-Key Cryptography--PKC 2014 6 | | Pages: 275--292 7 | | Available from: http://eprint.iacr.org/2014/181 Sec. 7 8 | | Notes: 9 | 10 | * type: attribute-based encryption (public key) 11 | * setting: bilinear pairing group of prime order 12 | * assumption: complex q-type assumption 13 | 14 | :Authors: al, artjomb 15 | :Date: 07/15 16 | ''' 17 | 18 | from charm.toolbox.pairinggroup import * 19 | from charm.toolbox.secretutil import SecretUtil 20 | from charm.toolbox.ABEnc import * 21 | import time 22 | 23 | 24 | debug = False 25 | class CPABE_YAHK14(ABEnc): 26 | """ 27 | >>> from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair 28 | >>> group = PairingGroup('SS512') 29 | >>> cpabe = CPABE_YAHK14(group) 30 | >>> msg = group.random(GT) 31 | >>> attributes = ['2', '3'] # must be integer strings 32 | >>> access_policy = '2 and !1' # must be integer strings 33 | >>> (master_public_key, master_key) = cpabe.setup() 34 | >>> secret_key = cpabe.keygen(master_public_key, master_key, attributes) 35 | >>> cipher_text = cpabe.encrypt(master_public_key, msg, access_policy) 36 | >>> decrypted_msg = cpabe.decrypt(master_public_key, secret_key, cipher_text) 37 | >>> msg == decrypted_msg 38 | True 39 | """ 40 | 41 | def __init__(self, groupObj, verbose = False): 42 | ABEnc.__init__(self) 43 | global util, group 44 | group = groupObj 45 | util = SecretUtil(group, verbose) 46 | 47 | # Defining a function to pick explicit exponents in the group 48 | def exp(self,value): 49 | return group.init(ZR, value) 50 | 51 | 52 | def setup(self): 53 | g = group.random(G1) # this element can also be in G2 and then PairingGroup('MNT224') can be used 54 | g2, u, h, w, v = group.random(G1), group.random(G1), group.random(G1), group.random(G1), group.random(G1) 55 | alpha, beta = group.random( ), group.random( )#from ZR 56 | vDot = u ** beta 57 | egg = pair(g2,g)**alpha 58 | pp = {'g':g, 'g2':g2, 'u':u, 'h':h, 'w':w, 'v':v, 'vDot':vDot,'egg':egg} 59 | mk = {'g2_alpha':g2 ** alpha, 'beta': beta } 60 | return (pp, mk) 61 | 62 | 63 | def keygen(self, pp, mk, S): 64 | # S is a set of attributes written as STRINGS i.e. {'1', '2', '3',...} 65 | r = group.random( ) 66 | 67 | D1 = mk['g2_alpha'] * (pp['w']**r) 68 | D2 = pp['g']**r 69 | 70 | vR = pp['v']**(-r) 71 | 72 | K1, K1Dot, K2, K2Dot = {}, {}, {}, {} 73 | rDotCumulative = r 74 | for i, idx in zip(S, range(len(S))): 75 | ri = group.random( ) 76 | if idx + 1 is len(S): 77 | riDot = rDotCumulative 78 | else: 79 | riDot = group.random( ) 80 | rDotCumulative -= riDot 81 | 82 | omega_i = self.exp(int(i)) 83 | K1[i] = vR * (pp['u']**omega_i * pp['h'])**ri 84 | K1Dot[i] = (pp['u']**(omega_i * mk['beta']) * pp['h']**mk['beta'])**riDot 85 | 86 | K2[i] = pp['g']**ri 87 | K2Dot[i] = pp['g']**(mk['beta']*riDot) 88 | S = [s for s in S] #Have to be an array for util.prune 89 | 90 | return { 'S':S, 'D1': D1, 'D2' : D2, 'K1':K1, 'K1Dot':K1Dot, 'K2':K2, 'K2Dot':K2Dot } 91 | 92 | 93 | def encrypt(self, pp, message, policy_str): 94 | s = group.random() 95 | 96 | policy = util.createPolicy(policy_str) 97 | a_list = util.getAttributeList(policy) 98 | 99 | shares = util.calculateSharesDict(s, policy) #These are correctly set to be exponents in Z_p 100 | 101 | C0 = message * (pp['egg']**s) 102 | C1 = pp['g']**s 103 | 104 | C_1, C_2, C_3 = {}, {}, {} 105 | for i in a_list: 106 | ti = group.random() 107 | if i[0] == '!': 108 | inti = util.strip_index(i[1:]) 109 | C_1[i] = pp['w']**shares[i] * pp['vDot']**ti 110 | else: 111 | inti = util.strip_index(i) 112 | C_1[i] = pp['w']**shares[i] * pp['v']**ti 113 | 114 | inti = self.exp(int(inti)) 115 | C_2[i] = (pp['u']**inti * pp['h'])**(-ti) 116 | C_3[i] = pp['g']**ti 117 | 118 | #print('The exponent is ',inti) 119 | 120 | return { 'Policy':policy_str, 'C0':C0, 'C1':C1, 'C_1':C_1, 'C_2':C_2, 'C_3':C_3 } 121 | 122 | 123 | def decrypt(self, pp, sk, ct): 124 | policy = util.createPolicy(ct['Policy']) 125 | z = util.getCoefficients(policy) 126 | 127 | # workaround to let the charm policy parser successfully parse the non-monotonic attributes 128 | a_list = util.getAttributeList(policy) 129 | nS = sk['S'][:] 130 | for att in a_list: 131 | if att[0] == '!' and att[1:] not in sk['S']: 132 | nS.append(att) 133 | 134 | pruned_list = util.prune(policy, nS) 135 | 136 | if (pruned_list == False): 137 | return group.init(GT,1) 138 | 139 | B = pair(ct['C1'], sk['D1']) 140 | for i in range(len(pruned_list)): 141 | x = pruned_list[i].getAttribute( ) #without the underscore 142 | y = pruned_list[i].getAttributeAndIndex( ) #with the underscore 143 | 144 | a = pair( ct['C_1'][x], sk['D2']) 145 | if x[0] == '!': 146 | b = group.init(GT, 1) 147 | inti = self.exp(int(x[1:])) 148 | for xj in sk['S']: 149 | if xj[0] == '!': 150 | intj = self.exp(int(xj[1:])) 151 | else: 152 | intj = self.exp(int(xj)) 153 | b *= ( pair( ct['C_2'][x], sk['K2Dot'][str(intj)]) * pair( ct['C_3'][x], sk['K1Dot'][str(intj)]) ) ** (1 / (inti - intj)) 154 | else: 155 | b = pair( ct['C_2'][x], sk['K2'][x]) * pair( ct['C_3'][x], sk['K1'][x]) 156 | d = - z[y] 157 | B *= ( a * b )**d 158 | 159 | return ct['C0'] / B 160 | 161 | 162 | def randomMessage(self): 163 | return group.random(GT) 164 | 165 | 166 | def main(arg): 167 | l=[] 168 | curve = 'SS512' 169 | 170 | groupObj = PairingGroup(curve) 171 | scheme = CPABE_YAHK14(groupObj) 172 | 173 | start1 = time.time() 174 | (pp, mk) = scheme.setup() 175 | l.append(time.time() - start1) 176 | 177 | testCases = [ 178 | ( '2 and !1', [ 179 | ({'1', '2'}, False), 180 | ({'1'}, False), 181 | ({'2'}, True), 182 | ({'3'}, False), 183 | ({'2', '3'}, True) 184 | ] ), 185 | ( '2 and 1', [ 186 | ({'1', '2'}, True), 187 | ({'1'}, False), 188 | ({'2'}, False), 189 | ({'3'}, False) 190 | ] ), 191 | ( '2', [ 192 | ({'1', '2'}, True), 193 | ({'1'}, False), 194 | ({'2'}, True) 195 | ] ), 196 | ( '!2', [ 197 | ({'1', '2'}, False), 198 | ({'1'}, True), 199 | ({'2'}, False) 200 | ] ), 201 | ] 202 | 203 | for policy_str, users in testCases: 204 | for S, success in users: 205 | m = group.random(GT) 206 | sk = scheme.keygen(pp, mk, S) 207 | ct = scheme.encrypt(pp, m, policy_str) 208 | res = scheme.decrypt(pp, sk, ct) 209 | 210 | # if (m == res) == success: 211 | # print("PASS", S, '' if success else 'not', "in '" + policy_str + "'") 212 | # else: 213 | # print("FAIL", S, '' if success else 'not', "in '" + policy_str + "'") 214 | 215 | m = group.random(GT) 216 | 217 | start2 = time.time() 218 | sk = scheme.keygen(pp, mk, {'1', '2'}) 219 | l.append(time.time() - start2) 220 | 221 | start3 = time.time() 222 | ct = scheme.encrypt(pp, m, '!1 and 2') 223 | l.append(time.time() - start3) 224 | 225 | 226 | sk['S'].remove('1') 227 | 228 | start4 = time.time() 229 | res = scheme.decrypt(pp, sk, ct) 230 | l.append(time.time() - start4) 231 | 232 | # if (m == res) == False: 233 | # print("PASS: attack failed") 234 | # else: 235 | # print("FAIL: attack succeeded") 236 | return l 237 | 238 | 239 | if __name__ == '__main__': 240 | debug = False 241 | a = main(0) 242 | -------------------------------------------------------------------------------- /dabe_aw11.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Lewko-Waters Decentralized Attribute-Based Encryption 3 | 4 | | Lewko, Allison, and Brent Waters, "Decentralizing Attribute-Based Encryption.", Appendix D 5 | | Published in: Eurocrypt 2011 6 | | Available from: http://eprint.iacr.org/2010/351.pdf 7 | 8 | * type: encryption (identity-based) 9 | * setting: bilinear groups (asymmetric) 10 | 11 | :Authors: Gary Belvin 12 | :Date: 06/2011 13 | ''' 14 | 15 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair 16 | from charm.toolbox.secretutil import SecretUtil 17 | from charm.toolbox.ABEncMultiAuth import ABEncMultiAuth 18 | import time 19 | 20 | debug = False 21 | class Dabe(ABEncMultiAuth): 22 | """ 23 | Decentralized Attribute-Based Encryption by Lewko and Waters 24 | 25 | >>> group = PairingGroup('SS512') 26 | >>> dabe = Dabe(group) 27 | >>> public_parameters = dabe.setup() 28 | >>> auth_attrs= ['ONE', 'TWO', 'THREE', 'FOUR'] #setup an authority 29 | >>> (master_secret_key, master_public_key) = dabe.authsetup(public_parameters, auth_attrs) 30 | 31 | Setup a user and give him some keys 32 | >>> ID, secret_keys = "bob", {} 33 | >>> usr_attrs = ['THREE', 'ONE', 'TWO'] 34 | >>> for i in usr_attrs: dabe.keygen(public_parameters, master_secret_key, i, ID, secret_keys) 35 | >>> msg = group.random(GT) 36 | >>> policy = '((one or three) and (TWO or FOUR))' 37 | >>> cipher_text = dabe.encrypt(public_parameters, master_public_key, msg, policy) 38 | >>> decrypted_msg = dabe.decrypt(public_parameters, secret_keys, cipher_text) 39 | >>> decrypted_msg == msg 40 | True 41 | """ 42 | def __init__(self, groupObj): 43 | ABEncMultiAuth.__init__(self) 44 | global util, group 45 | util = SecretUtil(groupObj, verbose=False) #Create Secret Sharing Scheme 46 | group = groupObj #:Prime order group 47 | #Another comment 48 | 49 | def setup(self): 50 | '''Global Setup''' 51 | #:In global setup, a bilinear group G of prime order p is chosen 52 | #:The global public parameters, GP and p, and a generator g of G. A random oracle H maps global identities GID to elements of G 53 | 54 | #:group contains 55 | #:the prime order p is contained somewhere within the group object 56 | g = group.random(G1) 57 | #: The oracle that maps global identities GID onto elements of G 58 | #:H = lambda str: g** group.hash(str) 59 | H = lambda x: group.hash(x, G1) 60 | GP = {'g':g, 'H': H} 61 | 62 | return GP 63 | 64 | 65 | def authsetup(self, GP, attributes): 66 | '''Authority Setup for a given set of attributes''' 67 | #For each attribute i belonging to the authority, the authority chooses two random exponents, 68 | #alpha_i, y_i and publishes PK={e(g,g)^alpha_i, g^y_i} for each attribute 69 | #it keeps SK = {alpha_i, y_i} as its secret key 70 | SK = {} #dictionary of {s: {alpha_i, y_i}} 71 | PK = {} #dictionary of {s: {e(g,g)^alpha_i, g^y}} 72 | for i in attributes: 73 | #TODO: Is ZR an appropriate choice for a random element in Zp? 74 | alpha_i, y_i = group.random(), group.random() 75 | e_gg_alpha_i = pair(GP['g'],GP['g']) ** alpha_i 76 | g_y_i = GP['g'] ** y_i 77 | SK[i.upper()] = {'alpha_i': alpha_i, 'y_i': y_i} 78 | PK[i.upper()] = {'e(gg)^alpha_i': e_gg_alpha_i, 'g^y_i': g_y_i} 79 | 80 | # if(debug): 81 | # print("Authority Setup for %s" % attributes) 82 | # print("SK = {alpha_i, y_i}") 83 | # print(SK) 84 | # print("PK = {e(g,g) ^ alpha_i, g ^ y_i}") 85 | # print(PK) 86 | 87 | return (SK, PK) 88 | 89 | 90 | def keygen(self, gp, sk, i, gid, pkey): 91 | '''Create a key for GID on attribute i belonging to authority sk 92 | sk is the private key for the releveant authority 93 | i is the attribute to give bob 94 | pkey is bob's private key dictionary, to which the appropriate private key is added 95 | ''' 96 | #To create a key for GID for attribute i belonging to an authority, the authority computes K_{i,GID} = g^alpha_i * H(GID)^y_ 97 | h = gp['H'](gid) 98 | K = (gp['g'] ** sk[i.upper()]['alpha_i']) * (h ** sk[i.upper()]['y_i']) 99 | 100 | pkey[i.upper()] = {'k': K} 101 | pkey['gid'] = gid 102 | 103 | # if(debug): 104 | # print("Key gen for %s on %s" % (gid, i)) 105 | # print("H(GID): '%s'" % h) 106 | # print("K = g^alpha_i * H(GID) ^ y_i: %s" % K) 107 | return None 108 | 109 | 110 | def encrypt(self, gp, pk, M, policy_str): 111 | '''Encrypt''' 112 | #M is a group element 113 | #pk is a dictionary with all the attributes of all authorities put together. 114 | #This is legal because no attribute can be shared by more than one authority 115 | #{i: {'e(gg)^alpha_i: , 'g^y_i'} 116 | s = group.random() 117 | w = group.init(ZR, 0) 118 | egg_s = pair(gp['g'],gp['g']) ** s 119 | C0 = M * egg_s 120 | C1, C2, C3 = {}, {}, {} 121 | 122 | #Parse the policy string into a tree 123 | policy = util.createPolicy(policy_str) 124 | sshares = util.calculateSharesList(s, policy) #Shares of the secret 125 | wshares = util.calculateSharesList(w, policy) #Shares of 0 126 | 127 | 128 | wshares = dict([(x[0].getAttributeAndIndex(), x[1]) for x in wshares]) 129 | sshares = dict([(x[0].getAttributeAndIndex(), x[1]) for x in sshares]) 130 | for attr, s_share in sshares.items(): 131 | k_attr = util.strip_index(attr) 132 | w_share = wshares[attr] 133 | r_x = group.random() 134 | C1[attr] = (pair(gp['g'],gp['g']) ** s_share) * (pk[k_attr]['e(gg)^alpha_i'] ** r_x) 135 | C2[attr] = gp['g'] ** r_x 136 | C3[attr] = (pk[k_attr]['g^y_i'] ** r_x) * (gp['g'] ** w_share) 137 | 138 | return { 'C0':C0, 'C1':C1, 'C2':C2, 'C3':C3, 'policy':policy_str } 139 | 140 | 141 | def decrypt(self, gp, sk, ct): 142 | '''Decrypt a ciphertext 143 | SK is the user's private key dictionary {attr: { xxx , xxx }} 144 | ''' 145 | usr_attribs = list(sk.keys()) 146 | usr_attribs.remove('gid') 147 | policy = util.createPolicy(ct['policy']) 148 | pruned = util.prune(policy, usr_attribs) 149 | # if pruned == False: 150 | # raise Exception("Don't have the required attributes for decryption!") 151 | coeffs = util.getCoefficients(policy) 152 | 153 | h_gid = gp['H'](sk['gid']) #find H(GID) 154 | egg_s = 1 155 | for i in pruned: 156 | x = i.getAttributeAndIndex() 157 | y = i.getAttribute() 158 | num = ct['C1'][x] * pair(h_gid, ct['C3'][x]) 159 | dem = pair(sk[y]['k'], ct['C2'][x]) 160 | egg_s *= ( (num / dem) ** coeffs[x] ) 161 | 162 | # if(debug): print("e(gg)^s: %s" % egg_s) 163 | 164 | return ct['C0'] / egg_s 165 | 166 | 167 | def main(arg): 168 | groupObj = PairingGroup('SS512') 169 | 170 | l=[] 171 | 172 | dabe = Dabe(groupObj) 173 | 174 | start1 = time.time() 175 | GP = dabe.setup() 176 | l.append(time.time() - start1) 177 | 178 | #Setup an authority 179 | auth_attrs= ['ONE', 'TWO', 'THREE', 'FOUR'] 180 | (SK, PK) = dabe.authsetup(GP, auth_attrs) 181 | # if debug: print("Authority SK") 182 | # if debug: print(SK) 183 | 184 | #Setup a user and give him some keys 185 | gid, K = "bob", {} 186 | usr_attrs = ['THREE', 'ONE', 'TWO'] 187 | 188 | start2 = time.time() 189 | for i in usr_attrs: dabe.keygen(GP, SK, i, gid, K) 190 | l.append(time.time() - start2) 191 | 192 | # if debug: print('User credential list: %s' % usr_attrs) 193 | # if debug: print("\nSecret key:") 194 | # if debug: groupObj.debug(K)''' 195 | 196 | 197 | #Encrypt a random element in GT 198 | m = groupObj.random(GT) 199 | policy = '((one or three) and (TWO or FOUR))' 200 | # if debug: print('Acces Policy: %s' % policy) 201 | 202 | start3 = time.time() 203 | CT = dabe.encrypt(GP, PK, m, policy) 204 | l.append(time.time() - start3) 205 | 206 | # ''' if debug: print("\nCiphertext...") 207 | # if debug: groupObj.debug(CT) 208 | 209 | start4 = time.time() 210 | orig_m = dabe.decrypt(GP, K, CT) 211 | l.append(time.time() - start4) 212 | 213 | assert m == orig_m, 'FAILED Decryption!!!' 214 | #if debug: print('Successful Decryption!') 215 | 216 | return l 217 | 218 | 219 | if __name__ == '__main__': 220 | debug = False 221 | a = main(0) 222 | -------------------------------------------------------------------------------- /abenc_maabe_rw15.py: -------------------------------------------------------------------------------- 1 | """ 2 | Rouselakis - Waters Efficient Statically-Secure Large-Universe Multi-Authority Attribute-Based Encryption 3 | 4 | | From: Efficient Statically-Secure Large-Universe Multi-Authority Attribute-Based Encryption 5 | | Published in: Financial Crypto 2015 6 | | Available from: http://eprint.iacr.org/2015/016.pdf 7 | | Notes: Implementation based on implementation (maabe_rw12.py) 8 | which cah be found here: https://sites.google.com/site/yannisrouselakis/rwabe 9 | 10 | * type: attribute-based encryption (public key) 11 | * setting: bilinear pairing group of prime order 12 | * assumption: complex q-type assumption 13 | 14 | :Authors: Yannis Rouselakis 15 | :Date: 11/12 16 | """ 17 | 18 | from charm.toolbox.pairinggroup import * 19 | from charm.toolbox.secretutil import SecretUtil 20 | from charm.toolbox.ABEncMultiAuth import ABEncMultiAuth 21 | import re 22 | import time 23 | 24 | debug = False 25 | 26 | 27 | def merge_dicts(*dict_args): 28 | """ 29 | Given any number of dicts, shallow copy and merge into a new dict, 30 | precedence goes to key value pairs in latter dicts. 31 | """ 32 | result = {} 33 | for dictionary in dict_args: 34 | result.update(dictionary) 35 | return result 36 | 37 | 38 | 39 | class MaabeRW15(ABEncMultiAuth): 40 | """ 41 | Efficient Statically-Secure Large-Universe Multi-Authority Attribute-Based Encryption 42 | Rouselakis - Waters 43 | 44 | >>> group = PairingGroup('SS512') 45 | >>> maabe = MaabeRW15(group) 46 | >>> public_parameters = maabe.setup() 47 | 48 | Setup the attribute authorities 49 | >>> attributes1 = ['ONE', 'TWO'] 50 | >>> attributes2 = ['THREE', 'FOUR'] 51 | >>> (public_key1, secret_key1) = maabe.authsetup(public_parameters, 'UT') 52 | >>> (public_key2, secret_key2) = maabe.authsetup(public_parameters, 'OU') 53 | >>> public_keys = {'UT': public_key1, 'OU': public_key2} 54 | 55 | Setup a user and give him some keys 56 | >>> gid = "bob" 57 | >>> user_attributes1 = ['STUDENT@UT', 'PHD@UT'] 58 | >>> user_attributes2 = ['STUDENT@OU'] 59 | >>> user_keys1 = maabe.multiple_attributes_keygen(public_parameters, secret_key1, gid, user_attributes1) 60 | >>> user_keys2 = maabe.multiple_attributes_keygen(public_parameters, secret_key2, gid, user_attributes2) 61 | >>> user_keys = {'GID': gid, 'keys': merge_dicts(user_keys1, user_keys2)} 62 | 63 | Create a random message 64 | >>> message = group.random(GT) 65 | 66 | Encrypt the message 67 | >>> access_policy = '(STUDENT@UT or PROFESSOR@OU) and (STUDENT@UT or MASTERS@OU)' 68 | >>> cipher_text = maabe.encrypt(public_parameters, public_keys, message, access_policy) 69 | 70 | Decrypt the message 71 | >>> decrypted_message = maabe.decrypt(public_parameters, user_keys, cipher_text) 72 | >>> decrypted_message == message 73 | True 74 | """ 75 | 76 | def __init__(self, group, verbose=False): 77 | ABEncMultiAuth.__init__(self) 78 | self.group = group 79 | self.util = SecretUtil(group, verbose) 80 | 81 | def setup(self): 82 | g1 = self.group.random(G1) 83 | g2 = self.group.random(G2) 84 | egg = pair(g1, g2) 85 | H = lambda x: self.group.hash(x, G2) 86 | F = lambda x: self.group.hash(x, G2) 87 | gp = {'g1': g1, 'g2': g2, 'egg': egg, 'H': H, 'F': F} 88 | if debug: 89 | print("Setup") 90 | print(gp) 91 | return gp 92 | 93 | 94 | def unpack_attribute(self, attribute): 95 | """ 96 | Unpacks an attribute in attribute name, authority name and index 97 | :param attribute: The attribute to unpack 98 | :return: The attribute name, authority name and the attribute index, if present. 99 | 100 | >>> group = PairingGroup('SS512') 101 | >>> maabe = MaabeRW15(group) 102 | >>> maabe.unpack_attribute('STUDENT@UT') 103 | ('STUDENT', 'UT', None) 104 | >>> maabe.unpack_attribute('STUDENT@UT_2') 105 | ('STUDENT', 'UT', '2') 106 | """ 107 | parts = re.split(r"[@_]", attribute) 108 | assert len(parts) > 1, "No @ char in [attribute@authority] name" 109 | return parts[0], parts[1], None if len(parts) < 3 else parts[2] 110 | 111 | 112 | def authsetup(self, gp, name): 113 | """ 114 | Setup an attribute authority. 115 | :param gp: The global parameters 116 | :param name: The name of the authority 117 | :return: The public and private key of the authority 118 | """ 119 | alpha, y = self.group.random(), self.group.random() 120 | egga = gp['egg'] ** alpha 121 | gy = gp['g1'] ** y 122 | pk = {'name': name, 'egga': egga, 'gy': gy} 123 | sk = {'name': name, 'alpha': alpha, 'y': y} 124 | if debug: 125 | print("Authsetup: %s" % name) 126 | print(pk) 127 | print(sk) 128 | return pk, sk 129 | 130 | 131 | def keygen(self, gp, sk, gid, attribute): 132 | """ 133 | Generate a user secret key for the attribute. 134 | :param gp: The global parameters. 135 | :param sk: The secret key of the attribute authority. 136 | :param gid: The global user identifier. 137 | :param attribute: The attribute. 138 | :return: The secret key for the attribute for the user with identifier gid. 139 | """ 140 | _, auth, _ = self.unpack_attribute(attribute) 141 | assert sk['name'] == auth, "Attribute %s does not belong to authority %s" % (attribute, sk['name']) 142 | 143 | t = self.group.random() 144 | K = gp['g2'] ** sk['alpha'] * gp['H'](gid) ** sk['y'] * gp['F'](attribute) ** t 145 | KP = gp['g1'] ** t 146 | if debug: 147 | print("Keygen") 148 | print("User: %s, Attribute: %s" % (gid, attribute)) 149 | print({'K': K, 'KP': KP}) 150 | return {'K': K, 'KP': KP} 151 | 152 | 153 | def multiple_attributes_keygen(self, gp, sk, gid, attributes): 154 | """ 155 | Generate a dictionary of secret keys for a user for a list of attributes. 156 | :param gp: The global parameters. 157 | :param sk: The secret key of the attribute authority. 158 | :param gid: The global user identifier. 159 | :param attributes: The list of attributes. 160 | :return: A dictionary with attribute names as keys, and secret keys for the attributes as values. 161 | """ 162 | uk = {} 163 | for attribute in attributes: 164 | uk[attribute] = self.keygen(gp, sk, gid, attribute) 165 | return uk 166 | 167 | 168 | def encrypt(self, gp, pks, message, policy_str): 169 | """ 170 | Encrypt a message under an access policy 171 | :param gp: The global parameters. 172 | :param pks: The public keys of the relevant attribute authorities, as dict from authority name to public key. 173 | :param message: The message to encrypt. 174 | :param policy_str: The access policy to use. 175 | :return: The encrypted message. 176 | """ 177 | s = self.group.random() # secret to be shared 178 | w = self.group.init(ZR, 0) # 0 to be shared 179 | 180 | policy = self.util.createPolicy(policy_str) 181 | attribute_list = self.util.getAttributeList(policy) 182 | 183 | secret_shares = self.util.calculateSharesDict(s, policy) # These are correctly set to be exponents in Z_p 184 | zero_shares = self.util.calculateSharesDict(w, policy) 185 | 186 | C0 = message * (gp['egg'] ** s) 187 | C1, C2, C3, C4 = {}, {}, {}, {} 188 | for i in attribute_list: 189 | attribute_name, auth, _ = self.unpack_attribute(i) 190 | attr = "%s@%s" % (attribute_name, auth) 191 | tx = self.group.random() 192 | C1[i] = gp['egg'] ** secret_shares[i] * pks[auth]['egga'] ** tx 193 | C2[i] = gp['g1'] ** (-tx) 194 | C3[i] = pks[auth]['gy'] ** tx * gp['g1'] ** zero_shares[i] 195 | C4[i] = gp['F'](attr) ** tx 196 | if debug: 197 | print("Encrypt") 198 | print(message) 199 | print({'policy': policy_str, 'C0': C0, 'C1': C1, 'C2': C2, 'C3': C3, 'C4': C4}) 200 | return {'policy': policy_str, 'C0': C0, 'C1': C1, 'C2': C2, 'C3': C3, 'C4': C4} 201 | 202 | 203 | def decrypt(self, gp, sk, ct): 204 | """ 205 | Decrypt the ciphertext using the secret keys of the user. 206 | :param gp: The global parameters. 207 | :param sk: The secret keys of the user. 208 | :param ct: The ciphertext to decrypt. 209 | :return: The decrypted message. 210 | :raise Exception: When the access policy can not be satisfied with the user's attributes. 211 | """ 212 | policy = self.util.createPolicy(ct['policy']) 213 | coefficients = self.util.getCoefficients(policy) 214 | pruned_list = self.util.prune(policy, sk['keys'].keys()) 215 | 216 | if not pruned_list: 217 | raise Exception("You don't have the required attributes for decryption!") 218 | 219 | B = self.group.init(GT, 1) 220 | for i in range(len(pruned_list)): 221 | x = pruned_list[i].getAttribute() # without the underscore 222 | y = pruned_list[i].getAttributeAndIndex() # with the underscore 223 | B *= (ct['C1'][y] * pair(ct['C2'][y], sk['keys'][x]['K']) * pair(ct['C3'][y], gp['H'](sk['GID'])) * pair( 224 | sk['keys'][x]['KP'], ct['C4'][y])) ** coefficients[y] 225 | if debug: 226 | print("Decrypt") 227 | print("SK:") 228 | print(sk) 229 | print("Decrypted Message:") 230 | print(ct['C0'] / B) 231 | return ct['C0'] / B 232 | 233 | def main(arg): 234 | l = [] 235 | group = PairingGroup('SS512') 236 | maabe = MaabeRW15(group) 237 | 238 | start1 = time.time() 239 | public_parameters = maabe.setup() 240 | l.append(time.time() - start1) 241 | 242 | attributes1 = ['ONE', 'TWO'] 243 | attributes2 = ['THREE', 'FOUR'] 244 | (public_key1, secret_key1) = maabe.authsetup(public_parameters, 'UT') 245 | (public_key2, secret_key2) = maabe.authsetup(public_parameters, 'OU') 246 | public_keys = {'UT': public_key1, 'OU': public_key2} 247 | 248 | gid = "bob" 249 | user_attributes1 = ['STUDENT@UT', 'PHD@UT'] 250 | user_attributes2 = ['STUDENT@OU'] 251 | start2 = time.time() 252 | user_keys1 = maabe.multiple_attributes_keygen(public_parameters, secret_key1, gid, user_attributes1) 253 | user_keys2 = maabe.multiple_attributes_keygen(public_parameters, secret_key2, gid, user_attributes2) 254 | l.append(time.time() - start2) 255 | user_keys = {'GID': gid, 'keys': merge_dicts(user_keys1, user_keys2)} 256 | 257 | 258 | message = group.random(GT) 259 | 260 | access_policy = '(STUDENT@UT or PROFESSOR@OU) and (STUDENT@UT or MASTERS@OU)' 261 | 262 | start3 = time.time() 263 | cipher_text = maabe.encrypt(public_parameters, public_keys, message, access_policy) 264 | l.append(time.time() - start3) 265 | 266 | start4 = time.time() 267 | decrypted_message = maabe.decrypt(public_parameters, user_keys, cipher_text) 268 | l.append(time.time() - start4) 269 | decrypted_message == message 270 | 271 | return l 272 | 273 | if __name__ == '__main__': 274 | debug = False 275 | 276 | a = main(0) 277 | 278 | ''' 279 | import doctest 280 | 281 | doctest.testmod() 282 | 283 | ''' -------------------------------------------------------------------------------- /abenc_tbpre_lww14.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Qin Liu, Guojun Wang, Jie Wu 3 | 4 | | From: Time-based proxy re-encryption scheme for secure data sharing in a cloud environment 5 | | Published in: Information Sciences (Volume: 258, year: 2014) 6 | | Available From: http://www.sciencedirect.com/science/article/pii/S0020025512006275 7 | | Notes: 8 | 9 | * type: ciphertext-policy attribute-based encryption (public key) 10 | * setting: Pairing 11 | 12 | :Author: artjomb 13 | :Date: 07/2014 14 | ''' 15 | 16 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,GT,pair 17 | from charm.toolbox.secretutil import SecretUtil 18 | 19 | from functools import reduce 20 | import time 21 | 22 | # taken from https://gist.github.com/endolith/114336 23 | def gcd(*numbers): 24 | """Return the greatest common divisor of the given integers""" 25 | from fractions import gcd 26 | return reduce(gcd, numbers) 27 | 28 | 29 | # taken from https://gist.github.com/endolith/114336 30 | def lcm(numbers): 31 | """Return lowest common multiple.""" 32 | def lcm(a, b): 33 | return (a * b) // gcd(a, b) 34 | return reduce(lcm, numbers, 1) 35 | 36 | 37 | class TBPRE(object): 38 | def __init__(self, groupObj): 39 | self.util = SecretUtil(groupObj, verbose=False) #Create Secret Sharing Scheme 40 | self.group = groupObj #:Prime order group 41 | #self.users = {} 42 | #self.authorities = {} 43 | 44 | def setup(self, attributes): 45 | '''Global Setup (executed by CA)''' 46 | P0 = self.group.random(G1) # generator 47 | P1 = self.group.random(G1) # random element 48 | s = self.group.random() 49 | mk0 = self.group.random() 50 | mk1 = self.group.random() 51 | Q0 = P0 ** mk0 52 | SK1 = P1 ** mk0 53 | 54 | Htemp = lambda x, y: self.group.hash(x + y, ZR) 55 | H = { 56 | 'user': lambda x: self.group.hash(str(x), ZR), # first convert G1 to str, then hash 57 | 'attr': lambda x: Htemp(x,"_attribute"), 58 | 'sy': lambda x: Htemp(x,"_year"), 59 | 'sym': lambda x: Htemp(x,"_year_month"), 60 | 'symd': lambda x: Htemp(x,"_year_month_day") 61 | } 62 | 63 | PK = { 'A': {}, 'Q0': Q0, 'P0': P0, 'P1': P1 } 64 | MK = { 'A': {}, 'mk0': mk0, 'mk1': mk1, 'SK1': SK1 } 65 | for attribute in attributes: 66 | ska = self.group.random() 67 | PKa = P0 ** ska 68 | PK['A'][attribute] = PKa 69 | MK['A'][attribute] = ska 70 | 71 | #self.MK = MK # private 72 | #self.s = s # sent to cloud service provider 73 | #self.PK = PK # public 74 | 75 | return (MK, PK, s, H) 76 | 77 | 78 | def registerUser(self, PK, H): 79 | '''Registers a user by id (executed by user)''' 80 | sku = self.group.random() 81 | PKu = PK['P0'] ** sku 82 | mku = H['user'](PKu) 83 | 84 | #self.users[userid] = { 'PKu': PKu, 'mku': mku } 85 | return (sku, { 'PKu': PKu, 'mku': mku }) # (private, public) 86 | 87 | 88 | def hashDate(self, H, time, s): 89 | hash = s 90 | key = 'y' 91 | if "year" in time: 92 | hash = H['sy'](time['year']) ** hash 93 | else: 94 | # print("Error: time has to contain at least 'year'") 95 | return None, None 96 | if "month" in time: 97 | hash = H['sym'](time['month']) ** hash 98 | key = 'ym' 99 | if "day" in time: 100 | hash = H['symd'](time['day']) ** hash 101 | key = 'ymd' 102 | elif "day" in time: 103 | # print("Error: time has to contain 'month' if it contains 'year'") 104 | return None, None 105 | return hash, key 106 | 107 | 108 | def timeSuffices(self, timeRange, needle): 109 | # assumes that the time obj is valid 110 | if timeRange['year'] != needle['year']: 111 | return False 112 | if 'month' not in timeRange: 113 | return True 114 | if 'month' not in needle: 115 | return None # Error 116 | if timeRange['month'] != needle['month']: 117 | return False 118 | if 'day' not in timeRange: 119 | return True 120 | if 'day' not in needle: 121 | return None # Error 122 | return timeRange['day'] == needle['day'] 123 | 124 | 125 | def policyTerm(self, user, policy): 126 | userAttributes = user['A'].keys() 127 | for i, term in zip(range(len(policy)), policy): 128 | notFound = False 129 | for termAttr in term: 130 | if termAttr not in userAttributes: 131 | notFound = True 132 | break 133 | if not notFound: 134 | return i 135 | return False 136 | 137 | 138 | def keygen(self, MK, PK, H, s, user, pubuser, attribute, time): 139 | '''Generate user keys for a specific attribute (executed by CA)''' 140 | 141 | hash, key = self.hashDate(H, time, s) 142 | if hash is None: 143 | return None 144 | 145 | if 'SKu' not in user: 146 | user['SKu'] = PK['P0'] ** (MK['mk1'] * pubuser['mku']) 147 | PKat = PK['A'][attribute] * (PK['P0'] ** hash) 148 | SKua = MK['SK1'] * (PKat ** (MK['mk1'] * pubuser['mku'])) 149 | 150 | if 'A' not in user: 151 | user['A'] = {} 152 | if attribute not in user['A']: 153 | user['A'][attribute] = [] 154 | user['A'][attribute].append((time, SKua)) 155 | 156 | 157 | def encrypt(self, PK, policy, F): 158 | '''Generate the cipher-text from the content(-key) and a policy (executed by the content owner)''' 159 | r = self.group.random() 160 | nA = lcm(map(lambda x: len(x), policy)) 161 | U0 = PK['P0'] ** r 162 | attributes = [] 163 | U = [] 164 | for term in policy: 165 | Ui = 1 166 | for attribute in term: 167 | Ui *= PK['A'][attribute] 168 | U.append(Ui ** r) 169 | V = F * pair(PK['Q0'], PK['P1'] ** (r * nA)) 170 | return { 'A': policy, 'U0': U0, 'U': U, 'V': V, 'nA': nA } 171 | 172 | 173 | def decrypt(self, CT, user, term = None): 174 | '''Decrypts the content(-key) from the cipher-text (executed by user/content consumer)''' 175 | if term is None: 176 | term = self.policyTerm(user, CT['A']) 177 | if term is False: 178 | # print("Error: user attributes don't satisfy the policy") 179 | return None 180 | 181 | sumSK = 1 182 | for attribute in CT['A'][term]: 183 | foundTimeSlot = False 184 | for timeRange, SKua in user['A'][attribute]: 185 | if self.timeSuffices(timeRange, CT['t']): 186 | foundTimeSlot = True 187 | sumSK *= SKua 188 | break 189 | if not foundTimeSlot: 190 | # print("Error: could not find time slot in user attribute keys") 191 | return None 192 | 193 | 194 | n = CT['nA'] // len(CT['A'][term]) 195 | return CT['Vt'] / (pair(CT['U0t'], sumSK ** n) / pair(user['SKu'], CT['Ut']['year'][term] ** n)) # TODO: fix year 196 | 197 | 198 | def reencrypt(self, PK, H, s, CT, currentTime): 199 | '''Re-encrypts the cipher-text using the current time (executed by cloud service provider)''' 200 | if 'year' not in currentTime or 'month' not in currentTime or 'day' not in currentTime: 201 | # print("Error: pass proper current time containing 'year', 'month' and 'day'") 202 | return None 203 | 204 | day = currentTime 205 | month = dict(day) 206 | del month['day'] 207 | year = dict(month) 208 | del year['month'] 209 | 210 | day, daykey = self.hashDate(H, day, s) 211 | month, monthkey = self.hashDate(H, month, s) 212 | year, yearkey = self.hashDate(H, year, s) 213 | 214 | rs = self.group.random() 215 | U0t = CT['U0'] * (PK['P0'] ** rs) 216 | 217 | Ut = { 'year': [], 'month': [], 'day': [] } 218 | for term, Ui in zip(CT['A'], CT['U']): 219 | Uit_year = Ui 220 | Uit_month = Ui 221 | Uit_day = Ui 222 | for attribute in term: 223 | Uit_year *= (PK['A'][attribute] ** rs) * (U0t ** year) 224 | Uit_month *= (PK['A'][attribute] ** rs) * (U0t ** month) 225 | Uit_day *= (PK['A'][attribute] ** rs) * (U0t ** day) 226 | Ut['year'].append(Uit_year) 227 | Ut['month'].append(Uit_month) 228 | Ut['day'].append(Uit_day) 229 | 230 | Vt = CT['V'] * pair(PK['Q0'], PK['P1'] ** (rs * CT['nA'])) 231 | 232 | return { 'A': CT['A'], 'U0t': U0t, 'Ut': Ut, 'Vt': Vt, 'nA': CT['nA'], 't': currentTime } 233 | 234 | 235 | def basicTest(): 236 | l=[] 237 | # print("RUN basicTest") 238 | groupObj = PairingGroup('SS512') 239 | tbpre = TBPRE(groupObj) 240 | attributes = ["ONE", "TWO", "THREE", "FOUR"] 241 | 242 | start1 = time.time() 243 | MK, PK, s, H = tbpre.setup(attributes) 244 | l.append(time.time() - start1) 245 | 246 | users = {} # public 247 | 248 | alice = { 'id': 'alice' } 249 | alice['sku'], users[alice['id']] = tbpre.registerUser(PK, H) 250 | alice2 = { 'id': 'alice2' } 251 | alice2['sku'], users[alice2['id']] = tbpre.registerUser(PK, H) 252 | 253 | year = { 'year': "2014" } 254 | pastYear = { 'year': "2013" } 255 | 256 | start2 = time.time() 257 | for attr in attributes[0:-1]: 258 | tbpre.keygen(MK, PK, H, s, alice, users[alice['id']], attr, year) 259 | tbpre.keygen(MK, PK, H, s, alice2, users[alice2['id']], attr, pastYear) 260 | l.append(time.time() - start2) 261 | 262 | k = groupObj.random(GT) 263 | 264 | policy = [['ONE', 'THREE'], ['TWO', 'FOUR']] # [['ONE' and 'THREE'] or ['TWO' and 'FOUR']] 265 | currentDate = { 'year': "2014", 'month': "2", 'day': "15" } 266 | 267 | start3 = time.time() 268 | CT = tbpre.encrypt(PK, policy, k) 269 | l.append(time.time() - start3) 270 | 271 | CTt = tbpre.reencrypt(PK, H, s, CT, currentDate) 272 | 273 | start4 = time.time() 274 | PT = tbpre.decrypt(CTt, alice) 275 | l.append(time.time() - start4) 276 | 277 | assert k == PT, 'FAILED DECRYPTION! 1' 278 | # print('SUCCESSFUL DECRYPTION 1') 279 | 280 | PT2 = tbpre.decrypt(CTt, alice2) 281 | 282 | assert k != PT2, 'SUCCESSFUL DECRYPTION! 2' 283 | # print('DECRYPTION correctly failed') 284 | 285 | return l 286 | 287 | 288 | def basicTest2(): 289 | '''Month-based attributes are used''' 290 | # print("RUN basicTest2") 291 | groupObj = PairingGroup('SS512') 292 | tbpre = TBPRE(groupObj) 293 | attributes = ["ONE", "TWO", "THREE", "FOUR"] 294 | MK, PK, s, H = tbpre.setup(attributes) 295 | 296 | users = {} # public 297 | 298 | alice = { 'id': 'alice' } 299 | alice['sku'], users[alice['id']] = tbpre.registerUser(PK, H) 300 | 301 | year = { 'year': "2014", 'month': '2' } 302 | 303 | for attr in attributes[0:-1]: 304 | tbpre.keygen(MK, PK, H, s, alice, users[alice['id']], attr, year) 305 | 306 | k = groupObj.random(GT) 307 | 308 | policy = [['ONE', 'THREE'], ['TWO', 'FOUR']] # [['ONE' and 'THREE'] or ['TWO' and 'FOUR']] 309 | currentDate = { 'year': "2014", 'month': "2", 'day': "15" } 310 | 311 | CT = tbpre.encrypt(PK, policy, k) 312 | CTt = tbpre.reencrypt(PK, H, s, CT, currentDate) 313 | PT = tbpre.decrypt(CTt, alice) 314 | 315 | assert k == PT, 'FAILED DECRYPTION!' 316 | # print('SUCCESSFUL DECRYPTION') 317 | 318 | def test(): 319 | # print 1, lcm(1, 2) 320 | print(2, lcm([1, 2])) 321 | 322 | def main(arg): 323 | l = basicTest() 324 | return l 325 | 326 | if __name__ == '__main__': 327 | # basicTest2() 328 | # test() 329 | a = main(0) 330 | -------------------------------------------------------------------------------- /abenc_maabe_yj14.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Kan Yang, Xiaohua Jia 3 | 4 | | From: Expressive, Efficient, and Revocable Data Access Control for Multi-Authority Cloud Storage 5 | | Published in: Parallel and Distributed Systems, IEEE Transactions on (Volume: 25, Issue: 7) 6 | | Available From: http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6620875 7 | | Notes: 8 | 9 | * type: ciphertext-policy attribute-based encryption (public key) 10 | * setting: Pairing 11 | 12 | :Authors: artjomb 13 | :Date: 07/2014 14 | ''' 15 | 16 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,GT,pair 17 | from charm.toolbox.secretutil import SecretUtil 18 | from charm.toolbox.ABEncMultiAuth import ABEncMultiAuth 19 | import time 20 | 21 | class MAABE(object): 22 | def __init__(self, groupObj): 23 | self.util = SecretUtil(groupObj, verbose=False) #Create Secret Sharing Scheme 24 | self.group = groupObj #:Prime order group 25 | 26 | def setup(self): 27 | '''Global Setup (executed by CA)''' 28 | #:In global setup, a bilinear group G of prime order p is chosen 29 | #:The global public parameters, GP and p, and a generator g of G. A random oracle H maps global identities GID to elements of G 30 | 31 | #:group contains 32 | #:the prime order p is contained somewhere within the group object 33 | g = self.group.random(G1) 34 | #: The oracle that maps global identities GID onto elements of G 35 | #:H = lambda str: g** group.hash(str) 36 | H = lambda x: self.group.hash(x, G1) 37 | a = self.group.random() 38 | b = self.group.random() 39 | g_a = g ** a 40 | g_b = g ** b 41 | GPP = {'g': g, 'g_a': g_a, 'g_b': g_b, 'H': H} 42 | GMK = {'a': a, 'b': b} 43 | 44 | return (GPP, GMK) 45 | 46 | 47 | def registerUser(self, GPP): 48 | '''Generate user keys (executed by the user).''' 49 | g = GPP['g'] 50 | ugsk1 = self.group.random() 51 | ugsk2 = self.group.random() 52 | ugpk1 = g ** ugsk1 53 | ugpk2 = g ** ugsk2 54 | 55 | return ((ugpk1, ugsk2), { 'pk': ugpk2, 'sk': ugsk1 }) # (private, public) 56 | 57 | 58 | def setupAuthority(self, GPP, authorityid, attributes, authorities): 59 | '''Generate attribute authority keys (executed by attribute authority)''' 60 | if authorityid not in authorities: 61 | alpha = self.group.random() 62 | beta = self.group.random() 63 | gamma = self.group.random() 64 | SK = {'alpha': alpha, 'beta': beta, 'gamma': gamma} 65 | PK = { 66 | 'e_alpha': pair(GPP['g'], GPP['g']) ** alpha, 67 | 'g_beta': GPP['g'] ** beta, 68 | 'g_beta_inv': GPP['g'] ** ~beta 69 | } 70 | authAttrs = {} 71 | authorities[authorityid] = (SK, PK, authAttrs) 72 | else: 73 | SK, PK, authAttrs = authorities[authorityid] 74 | for attrib in attributes: 75 | if attrib in authAttrs: 76 | continue 77 | versionKey = self.group.random() # random or really 'choose' ? 78 | h = GPP['H'](attrib) 79 | pk = h ** versionKey 80 | authAttrs[attrib] = { 81 | 'VK': versionKey, #secret 82 | 'PK1': pk, #public 83 | 'PK2': pk ** SK['gamma'] #public 84 | } 85 | return (SK, PK, authAttrs) 86 | 87 | 88 | def keygen(self, GPP, authority, attribute, userObj, USK = None): 89 | '''Generate user keys for a specific attribute (executed on attribute authority)''' 90 | if 't' not in userObj: 91 | userObj['t'] = self.group.random() #private to AA 92 | t = userObj['t'] 93 | 94 | ASK, APK, authAttrs = authority 95 | u = userObj 96 | if USK is None: 97 | USK = {} 98 | if 'K' not in USK or 'KS' not in USK or 'AK' not in USK: 99 | USK['K'] = \ 100 | (GPP['g'] ** ASK['alpha']) * \ 101 | (GPP['g_a'] ** u['sk']) * \ 102 | (GPP['g_b'] ** t) 103 | USK['KS'] = GPP['g'] ** t 104 | USK['AK'] = {} 105 | AK = (u['pk'] ** (t * ASK['beta'])) * \ 106 | ((authAttrs[attribute]['PK1'] ** ASK['beta']) ** (u['sk'] + ASK['gamma'])) 107 | USK['AK'][attribute] = AK 108 | return USK 109 | 110 | 111 | def encrypt(self, GPP, policy_str, k, authority): 112 | '''Generate the cipher-text from the content(-key) and a policy (executed by the content owner)''' 113 | #GPP are global parameters 114 | #k is the content key (group element based on AES key) 115 | #policy_str is the policy string 116 | #authority is the authority tuple 117 | 118 | _, APK, authAttrs = authority 119 | 120 | policy = self.util.createPolicy(policy_str) 121 | secret = self.group.random() 122 | shares = self.util.calculateSharesList(secret, policy) 123 | shares = dict([(x[0].getAttributeAndIndex(), x[1]) for x in shares]) 124 | 125 | C1 = k * (APK['e_alpha'] ** secret) 126 | C2 = GPP['g'] ** secret 127 | C3 = GPP['g_b'] ** secret 128 | C = {} 129 | CS = {} 130 | D = {} 131 | DS = {} 132 | 133 | for attr, s_share in shares.items(): 134 | k_attr = self.util.strip_index(attr) 135 | r_i = self.group.random() 136 | attrPK = authAttrs[attr] 137 | C[attr] = (GPP['g_a'] ** s_share) * ~(attrPK['PK1'] ** r_i) 138 | CS[attr] = GPP['g'] ** r_i 139 | D[attr] = APK['g_beta_inv'] ** r_i 140 | DS[attr] = attrPK['PK2'] ** r_i 141 | 142 | return {'C1': C1, 'C2': C2, 'C3': C3, 'C': C, 'CS': CS, 'D': D, 'DS': DS, 'policy': policy_str} 143 | 144 | 145 | def decrypt(self, GPP, CT, user): 146 | '''Decrypts the content(-key) from the cipher-text (executed by user/content consumer)''' 147 | UASK = user['authoritySecretKeys'] 148 | USK = user['keys'] 149 | usr_attribs = list(UASK['AK'].keys()) 150 | policy = self.util.createPolicy(CT['policy']) 151 | pruned = self.util.prune(policy, usr_attribs) 152 | if pruned == False: 153 | return False 154 | coeffs = self.util.getCoefficients(policy) 155 | 156 | first = pair(CT['C2'], UASK['K']) * ~pair(CT['C3'], UASK['KS']) 157 | n_a = 1 158 | 159 | ugpk1, ugsk2 = USK 160 | e_gg_auns = 1 161 | 162 | for attr in pruned: 163 | x = attr.getAttributeAndIndex() 164 | y = attr.getAttribute() 165 | temp = \ 166 | pair(CT['C'][y], ugpk1) * \ 167 | pair(CT['D'][y], UASK['AK'][y]) * \ 168 | pair(CT['CS'][y], ~(UASK['KS'] ** ugsk2)) * \ 169 | ~pair(GPP['g'], CT['DS'][y]) 170 | e_gg_auns *= temp ** (coeffs[x] * n_a) 171 | return CT['C1'] / (first / e_gg_auns) 172 | 173 | 174 | def ukeygen(self, GPP, authority, attribute, userObj): 175 | '''Generate update keys for users and cloud provider (executed by attribute authority?)''' 176 | ASK, _, authAttrs = authority 177 | oldVersionKey = authAttrs[attribute]['VK'] 178 | newVersionKey = oldVersionKey 179 | while oldVersionKey == newVersionKey: 180 | newVersionKey = self.group.random() 181 | authAttrs[attribute]['VK'] = newVersionKey 182 | 183 | u_uid = userObj['sk'] 184 | UKs = GPP['H'](attribute) ** (ASK['beta'] * (newVersionKey - oldVersionKey) * (u_uid + ASK['gamma'])) 185 | UKc = (newVersionKey/oldVersionKey, (oldVersionKey - newVersionKey)/(oldVersionKey * ASK['gamma'])) 186 | 187 | authAttrs[attribute]['PK1'] = authAttrs[attribute]['PK1'] ** UKc[0] 188 | authAttrs[attribute]['PK2'] = authAttrs[attribute]['PK2'] ** UKc[0] 189 | 190 | return { 'UKs': UKs, 'UKc': UKc } 191 | 192 | 193 | def skupdate(self, USK, attribute, UKs): 194 | '''Updates the user attribute secret key for the specified attribute (executed by non-revoked user)''' 195 | USK['AK'][attribute] = USK['AK'][attribute] * UKs 196 | 197 | 198 | def ctupdate(self, GPP, CT, attribute, UKc): 199 | '''Updates the cipher-text using the update key, because of the revoked attribute (executed by cloud provider)''' 200 | CT['C'][attribute] = CT['C'][attribute] * (CT['DS'][attribute] ** UKc[1]) 201 | CT['DS'][attribute] = CT['DS'][attribute] ** UKc[0] 202 | 203 | 204 | def basicTest(): 205 | l=[] 206 | # print("RUN basicTest") 207 | groupObj = PairingGroup('SS512') 208 | maabe = MAABE(groupObj) 209 | 210 | start1 = time.time() 211 | GPP, GMK = maabe.setup() 212 | l.append(time.time() - start1) 213 | 214 | users = {} # public user data 215 | authorities = {} 216 | 217 | authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"] 218 | authority1 = "authority1" 219 | 220 | maabe.setupAuthority(GPP, authority1, authorityAttributes, authorities) 221 | 222 | alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None } 223 | alice['keys'], users[alice['id']] = maabe.registerUser(GPP) 224 | 225 | start2 = time.time() 226 | for attr in authorityAttributes[0:-1]: 227 | maabe.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys']) 228 | l.append(time.time() - start2) 229 | 230 | k = groupObj.random(GT) 231 | 232 | policy_str = '((ONE or THREE) and (TWO or FOUR))' 233 | 234 | start3 = time.time() 235 | CT = maabe.encrypt(GPP, policy_str, k, authorities[authority1]) 236 | l.append(time.time() - start3) 237 | 238 | start4 = time.time() 239 | PT = maabe.decrypt(GPP, CT, alice) 240 | l.append(time.time() - start4) 241 | 242 | # print "k", k 243 | # print "PT", PT 244 | 245 | assert k == PT, 'FAILED DECRYPTION!' 246 | # print('SUCCESSFUL DECRYPTION') 247 | 248 | return l 249 | 250 | 251 | def revokedTest(): 252 | # print("RUN revokedTest") 253 | groupObj = PairingGroup('SS512') 254 | maabe = MAABE(groupObj) 255 | GPP, GMK = maabe.setup() 256 | 257 | users = {} # public user data 258 | authorities = {} 259 | 260 | authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"] 261 | authority1 = "authority1" 262 | 263 | maabe.setupAuthority(GPP, authority1, authorityAttributes, authorities) 264 | 265 | alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None } 266 | alice['keys'], users[alice['id']] = maabe.registerUser(GPP) 267 | 268 | bob = { 'id': 'bob', 'authoritySecretKeys': {}, 'keys': None } 269 | bob['keys'], users[bob['id']] = maabe.registerUser(GPP) 270 | 271 | for attr in authorityAttributes[0:-1]: 272 | maabe.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys']) 273 | maabe.keygen(GPP, authorities[authority1], attr, users[bob['id']], bob['authoritySecretKeys']) 274 | 275 | k = groupObj.random(GT) 276 | 277 | policy_str = '((ONE or THREE) and (TWO or FOUR))' 278 | 279 | CT = maabe.encrypt(GPP, policy_str, k, authorities[authority1]) 280 | 281 | PT1a = maabe.decrypt(GPP, CT, alice) 282 | PT1b = maabe.decrypt(GPP, CT, bob) 283 | 284 | assert k == PT1a, 'FAILED DECRYPTION (1a)!' 285 | assert k == PT1b, 'FAILED DECRYPTION (1b)!' 286 | # print('SUCCESSFUL DECRYPTION 1') 287 | 288 | # revoke bob on "ONE" 289 | attribute = "ONE" 290 | UK = maabe.ukeygen(GPP, authorities[authority1], attribute, users[alice['id']]) 291 | maabe.skupdate(alice['authoritySecretKeys'], attribute, UK['UKs']) 292 | maabe.ctupdate(GPP, CT, attribute, UK['UKc']) 293 | 294 | PT2a = maabe.decrypt(GPP, CT, alice) 295 | PT2b = maabe.decrypt(GPP, CT, bob) 296 | 297 | assert k == PT2a, 'FAILED DECRYPTION (2a)!' 298 | assert k != PT2b, 'SUCCESSFUL DECRYPTION (2b)!' 299 | # print('SUCCESSFUL DECRYPTION 2') 300 | 301 | 302 | def test(): 303 | groupObj = PairingGroup('SS512') 304 | 305 | # k = groupObj.random() 306 | #print "k", k, ~k, k * ~k 307 | # g = groupObj.random(G1) 308 | # print "g", g, pair(g, g) 309 | # gt = groupObj.random(GT) 310 | # print "gt", gt 311 | 312 | def main(arg): 313 | l = basicTest() 314 | revokedTest() 315 | return l 316 | 317 | if __name__ == '__main__': 318 | 319 | a = main(0) 320 | # test() 321 | -------------------------------------------------------------------------------- /abenc_dacmacs_yj14.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Kan Yang, Xiaohua Jia 3 | 4 | | From: DAC-MACS: Effective Data Access Control for Multi-Authority Cloud Storage Systems 5 | | Published in: Security for Cloud Storage Systems - SpringerBriefs in Computer Science 2014 6 | | Available From: http://link.springer.com/chapter/10.1007/978-1-4614-7873-7_4 7 | | Notes: 8 | 9 | * type: ciphertext-policy attribute-based encryption (public key) 10 | * setting: Pairing 11 | 12 | :Authors: artjomb 13 | :Date: 07/2014 14 | ''' 15 | 16 | from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,GT,pair 17 | from charm.toolbox.secretutil import SecretUtil 18 | from charm.toolbox.ABEncMultiAuth import ABEncMultiAuth 19 | import time 20 | 21 | class DACMACS(object): 22 | def __init__(self, groupObj): 23 | self.util = SecretUtil(groupObj, verbose=False) #Create Secret Sharing Scheme 24 | self.group = groupObj #:Prime order group 25 | 26 | def setup(self): 27 | '''Global Setup (executed by CA)''' 28 | #:In global setup, a bilinear group G of prime order p is chosen 29 | #:The global public parameters, GP and p, and a generator g of G. A random oracle H maps global identities GID to elements of G 30 | 31 | #:group contains 32 | #:the prime order p is contained somewhere within the group object 33 | g = self.group.random(G1) 34 | #: The oracle that maps global identities GID onto elements of G 35 | #:H = lambda str: g** group.hash(str) 36 | H = lambda x: self.group.hash(x, G1) 37 | a = self.group.random() 38 | g_a = g ** a 39 | GPP = {'g': g, 'g_a': g_a, 'H': H} 40 | GMK = {'a': a} 41 | 42 | return (GPP, GMK) 43 | 44 | 45 | def registerUser(self, GPP): 46 | '''Generate user keys (executed by the user).''' 47 | g = GPP['g'] 48 | u = self.group.random() 49 | z = self.group.random() 50 | g_u = g ** u 51 | g_z = g ** (1 / z) 52 | 53 | return ((g_u, z), { 'g_z': g_z, 'u': u }) # (private, public) 54 | 55 | 56 | def setupAuthority(self, GPP, authorityid, attributes, authorities): 57 | '''Generate attribute authority keys (executed by attribute authority)''' 58 | if authorityid not in authorities: 59 | alpha = self.group.random() 60 | beta = self.group.random() 61 | gamma = self.group.random() 62 | SK = {'alpha': alpha, 'beta': beta, 'gamma': gamma} 63 | PK = { 64 | 'e_alpha': pair(GPP['g'], GPP['g']) ** alpha, 65 | 'g_beta_inv': GPP['g'] ** (1/beta), 66 | 'g_beta_gamma': GPP['g'] ** (gamma/beta) 67 | } 68 | authAttrs = {} 69 | authorities[authorityid] = (SK, PK, authAttrs) 70 | else: 71 | SK, PK, authAttrs = authorities[authorityid] 72 | for attrib in attributes: 73 | if attrib in authAttrs: 74 | continue 75 | versionKey = self.group.random() # random or really 'choose' ? 76 | h = GPP['H'](attrib) 77 | pk = ((GPP['g'] ** versionKey) * h) ** SK['gamma'] 78 | authAttrs[attrib] = { 79 | 'VK': versionKey, #secret 80 | 'PK': pk, #public 81 | } 82 | return (SK, PK, authAttrs) 83 | 84 | 85 | def keygen(self, GPP, authority, attribute, userObj, USK = None): 86 | '''Generate user keys for a specific attribute (executed on attribute authority)''' 87 | if 't' not in userObj: 88 | userObj['t'] = self.group.random() #private to AA 89 | t = userObj['t'] 90 | 91 | ASK, APK, authAttrs = authority 92 | u = userObj 93 | if USK is None: 94 | USK = {} 95 | if 'K' not in USK or 'L' not in USK or 'R' not in USK or 'AK' not in USK: 96 | USK['K'] = \ 97 | (u['g_z'] ** ASK['alpha']) * \ 98 | (GPP['g_a'] ** u['u']) * \ 99 | (GPP['g_a'] ** (t / ASK['beta'])) 100 | USK['L'] = u['g_z'] ** (ASK['beta'] * t) 101 | USK['R'] = GPP['g_a'] ** t 102 | USK['AK'] = {} 103 | AK = (u['g_z'] ** (ASK['beta'] * ASK['gamma'] * t)) * \ 104 | (authAttrs[attribute]['PK'] ** (ASK['beta'] * u['u'])) 105 | USK['AK'][attribute] = AK 106 | return USK 107 | 108 | 109 | def encrypt(self, GPP, policy_str, k, authority): 110 | '''Generate the cipher-text from the content(-key) and a policy (executed by the content owner)''' 111 | #GPP are global parameters 112 | #k is the content key (group element based on AES key) 113 | #policy_str is the policy string 114 | #authority is the authority tuple 115 | 116 | _, APK, authAttrs = authority 117 | 118 | policy = self.util.createPolicy(policy_str) 119 | secret = self.group.random() 120 | shares = self.util.calculateSharesList(secret, policy) 121 | shares = dict([(x[0].getAttributeAndIndex(), x[1]) for x in shares]) 122 | 123 | C1 = k * (APK['e_alpha'] ** secret) 124 | C2 = GPP['g'] ** secret 125 | C3 = APK['g_beta_inv'] ** secret 126 | C = {} 127 | D = {} 128 | DS = {} 129 | 130 | for attr, s_share in shares.items(): 131 | k_attr = self.util.strip_index(attr) 132 | r_i = self.group.random() 133 | attrPK = authAttrs[attr] 134 | C[attr] = (GPP['g_a'] ** s_share) * ~(attrPK['PK'] ** r_i) 135 | D[attr] = APK['g_beta_inv'] ** r_i 136 | DS[attr] = ~(APK['g_beta_gamma'] ** r_i) 137 | 138 | return {'C1': C1, 'C2': C2, 'C3': C3, 'C': C, 'D': D, 'DS': DS, 'policy': policy_str} 139 | 140 | 141 | def generateTK(self, GPP, CT, UASK, g_u): 142 | '''Generates a token using the user's attribute secret keys to offload the decryption process (executed by cloud provider)''' 143 | usr_attribs = list(UASK['AK'].keys()) 144 | policy = self.util.createPolicy(CT['policy']) 145 | pruned = self.util.prune(policy, usr_attribs) 146 | if pruned == False: 147 | return False 148 | coeffs = self.util.getCoefficients(policy) 149 | 150 | dividend = pair(CT['C2'], UASK['K']) * ~pair(UASK['R'], CT['C3']) 151 | n_a = 1 152 | divisor = 1 153 | 154 | for attr in pruned: 155 | x = attr.getAttributeAndIndex() 156 | y = attr.getAttribute() 157 | temp = \ 158 | pair(CT['C'][y], g_u) * \ 159 | pair(CT['D'][y], UASK['AK'][y]) * \ 160 | pair(CT['DS'][y], UASK['L']) 161 | divisor *= temp ** (coeffs[x] * n_a) 162 | return dividend / divisor 163 | 164 | 165 | def decrypt(self, CT, TK, z): 166 | '''Decrypts the content(-key) from the cipher-text using the token and the user secret key (executed by user/content consumer)''' 167 | return CT['C1'] / (TK ** z) 168 | 169 | 170 | def ukeygen(self, GPP, authority, attribute, userObj): 171 | '''Generate update keys for users and cloud provider (executed by attribute authority?)''' 172 | ASK, _, authAttrs = authority 173 | oldVersionKey = authAttrs[attribute]['VK'] 174 | newVersionKey = oldVersionKey 175 | while oldVersionKey == newVersionKey: 176 | newVersionKey = self.group.random() 177 | authAttrs[attribute]['VK'] = newVersionKey 178 | 179 | u = userObj['u'] 180 | 181 | AUK = ASK['gamma'] * (newVersionKey - oldVersionKey) 182 | KUK = GPP['g'] ** (u * ASK['beta'] * AUK) 183 | CUK = ASK['beta'] * AUK / ASK['gamma'] 184 | 185 | authAttrs[attribute]['PK'] = authAttrs[attribute]['PK'] * (GPP['g'] ** AUK) 186 | 187 | return { 'KUK': KUK, 'CUK': CUK } 188 | 189 | 190 | def skupdate(self, USK, attribute, KUK): 191 | '''Updates the user attribute secret key for the specified attribute (executed by non-revoked user)''' 192 | USK['AK'][attribute] = USK['AK'][attribute] * KUK 193 | 194 | 195 | def ctupdate(self, GPP, CT, attribute, CUK): 196 | '''Updates the cipher-text using the update key, because of the revoked attribute (executed by cloud provider)''' 197 | CT['C'][attribute] = CT['C'][attribute] * (CT['DS'][attribute] ** CUK) 198 | 199 | 200 | def basicTest(): 201 | l=[] 202 | # print("RUN basicTest") 203 | groupObj = PairingGroup('SS512') 204 | dac = DACMACS(groupObj) 205 | 206 | start1 = time.time() 207 | GPP, GMK = dac.setup() 208 | l.append(time.time() - start1) 209 | 210 | users = {} # public user data 211 | authorities = {} 212 | 213 | authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"] 214 | authority1 = "authority1" 215 | 216 | dac.setupAuthority(GPP, authority1, authorityAttributes, authorities) 217 | 218 | alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None } 219 | alice['keys'], users[alice['id']] = dac.registerUser(GPP) 220 | 221 | start2 = time.time() 222 | for attr in authorityAttributes[0:-1]: 223 | dac.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys']) 224 | l.append(time.time() - start2) 225 | 226 | k = groupObj.random(GT) 227 | 228 | policy_str = '((ONE or THREE) and (TWO or FOUR))' 229 | 230 | start3 = time.time() 231 | CT = dac.encrypt(GPP, policy_str, k, authorities[authority1]) 232 | l.append(time.time() - start3) 233 | 234 | 235 | TK = dac.generateTK(GPP, CT, alice['authoritySecretKeys'], alice['keys'][0]) 236 | 237 | start4 = time.time() 238 | PT = dac.decrypt(CT, TK, alice['keys'][1]) 239 | l.append(time.time() - start4) 240 | 241 | # print "k", k 242 | # print "PT", PT 243 | 244 | assert k == PT, 'FAILED DECRYPTION!' 245 | # print('SUCCESSFUL DECRYPTION') 246 | return l 247 | 248 | 249 | def revokedTest(): 250 | # print("RUN revokedTest") 251 | groupObj = PairingGroup('SS512') 252 | dac = DACMACS(groupObj) 253 | GPP, GMK = dac.setup() 254 | 255 | users = {} # public user data 256 | authorities = {} 257 | 258 | authorityAttributes = ["ONE", "TWO", "THREE", "FOUR"] 259 | authority1 = "authority1" 260 | 261 | dac.setupAuthority(GPP, authority1, authorityAttributes, authorities) 262 | 263 | alice = { 'id': 'alice', 'authoritySecretKeys': {}, 'keys': None } 264 | alice['keys'], users[alice['id']] = dac.registerUser(GPP) 265 | 266 | bob = { 'id': 'bob', 'authoritySecretKeys': {}, 'keys': None } 267 | bob['keys'], users[bob['id']] = dac.registerUser(GPP) 268 | 269 | for attr in authorityAttributes[0:-1]: 270 | dac.keygen(GPP, authorities[authority1], attr, users[alice['id']], alice['authoritySecretKeys']) 271 | dac.keygen(GPP, authorities[authority1], attr, users[bob['id']], bob['authoritySecretKeys']) 272 | 273 | k = groupObj.random(GT) 274 | 275 | policy_str = '((ONE or THREE) and (TWO or FOUR))' 276 | 277 | CT = dac.encrypt(GPP, policy_str, k, authorities[authority1]) 278 | 279 | TK1a = dac.generateTK(GPP, CT, alice['authoritySecretKeys'], alice['keys'][0]) 280 | PT1a = dac.decrypt(CT, TK1a, alice['keys'][1]) 281 | TK1b = dac.generateTK(GPP, CT, bob['authoritySecretKeys'], bob['keys'][0]) 282 | PT1b = dac.decrypt(CT, TK1b, bob['keys'][1]) 283 | 284 | assert k == PT1a, 'FAILED DECRYPTION (1a)!' 285 | assert k == PT1b, 'FAILED DECRYPTION (1b)!' 286 | # print('SUCCESSFUL DECRYPTION 1') 287 | 288 | # revoke bob on "ONE" 289 | attribute = "ONE" 290 | UK = dac.ukeygen(GPP, authorities[authority1], attribute, users[alice['id']]) 291 | dac.skupdate(alice['authoritySecretKeys'], attribute, UK['KUK']) 292 | dac.ctupdate(GPP, CT, attribute, UK['CUK']) 293 | 294 | TK2a = dac.generateTK(GPP, CT, alice['authoritySecretKeys'], alice['keys'][0]) 295 | PT2a = dac.decrypt(CT, TK2a, alice['keys'][1]) 296 | TK2b = dac.generateTK(GPP, CT, bob['authoritySecretKeys'], bob['keys'][0]) 297 | PT2b = dac.decrypt(CT, TK2b, bob['keys'][1]) 298 | 299 | assert k == PT2a, 'FAILED DECRYPTION (2a)!' 300 | assert k != PT2b, 'SUCCESSFUL DECRYPTION (2b)!' 301 | # print('SUCCESSFUL DECRYPTION 2') 302 | 303 | 304 | def test(): 305 | groupObj = PairingGroup('SS512') 306 | 307 | # k = groupObj.random() 308 | #print "k", k, ~k, k * ~k 309 | # g = groupObj.random(G1) 310 | # print "g", g, pair(g, g) 311 | # gt = groupObj.random(GT) 312 | # print "gt", gt 313 | 314 | def main(arg): 315 | 316 | l = basicTest() 317 | 318 | revokedTest() 319 | 320 | return l 321 | 322 | 323 | if __name__ == '__main__': 324 | 325 | a = main(0) 326 | # test() 327 | --------------------------------------------------------------------------------