├── 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 |
--------------------------------------------------------------------------------