Source code for abenc_lsw08

'''
Allison Lewko, Amit Sahai and Brent Waters (Pairing-based)
 
| From: "Revocation Systems with Very Small Private Keys", Large Universe Construction
| Published in: IEEE S&P 2010
| Available from: http://eprint.iacr.org/2008/309.pdf
| Notes: 

* type:           key-policy attribute-based encryption (public key)
* setting:        Pairing

:Authors:    J Ayo Akinyele
:Date:            12/2010
'''

from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
from charm.toolbox.secretutil import SecretUtil
from charm.toolbox.ABEnc import ABEnc

debug = False
[docs]class KPabe(ABEnc): """ >>> from charm.toolbox.pairinggroup import PairingGroup,GT >>> group = PairingGroup('MNT224') >>> kpabe = KPabe(group) >>> (master_public_key, master_key) = kpabe.setup() >>> policy = '(ONE or THREE) and (THREE or TWO)' >>> attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ] >>> secret_key = kpabe.keygen(master_public_key, master_key, policy) >>> msg=group.random(GT) >>> cipher_text = kpabe.encrypt(master_public_key, msg, attributes) >>> decrypted_msg = kpabe.decrypt(cipher_text, secret_key) >>> decrypted_msg == msg True """ def __init__(self, groupObj, verbose=False): ABEnc.__init__(self) global group, util group = groupObj util = SecretUtil(group, verbose)
[docs] def setup(self): # pick random exponents alpha1, alpha2, b = group.random(ZR), group.random(ZR), group.random(ZR) alpha = alpha1 * alpha2 g_G1, g_G2 = group.random(G1), group.random(G2) # PK 1,2 h_G1, h_G2 = group.random(G1), group.random(G2) # PK 3 g1b = g_G1 ** b e_gg_alpha = pair(g_G1,g_G2) ** alpha #public parameters # 'g_G2^b':(g_G2 ** b), 'g_G2^b2':g_G2 ** (b * b), pk = { 'g_G1':g_G1, 'g_G2':g_G2, 'g_G1_b':g1b, 'g_G1_b2':g1b ** b, 'h_G1_b':h_G1 ** b, 'e(gg)_alpha':e_gg_alpha } #secret parameters mk = { 'alpha1':alpha1, 'alpha2':alpha2, 'b':b, 'h_G1':h_G1, 'h_G2':h_G2 } return (pk, mk)
[docs] def keygen(self, pk, mk, policy_str): policy = util.createPolicy(policy_str) attr_list = util.getAttributeList(policy) s = mk['alpha1']; secret = s shares = util.calculateSharesDict(secret, policy) D = { 'policy': policy_str } for x in attr_list: y = util.strip_index(x) d = []; r = group.random(ZR) if not self.negatedAttr(x): # meaning positive d.append((pk['g_G1'] ** (mk['alpha2'] * shares[x])) * (group.hash(y, G1) ** r)) # compute D1 for attribute x d.append((pk['g_G2'] ** r)) # compute D2 for attribute x #else: #d.append((pk['g2_G1'] ** shares[x]) * (pk['g_G1_b2'] ** r)) # compute D3 #d.append((pk['g_G1_b'] ** (r * group.hash(x))) * (pk['h_G1'] ** r)) # compute D4 #d.append(pk['g_G1'] ** -r) # compute D5 D[x] = d if debug: print("Access Policy for key: %s" % policy) if debug: print("Attribute list: %s" % attr_list) return D
[docs] def negatedAttr(self, attribute): if type(attribute) != str: attr = attribute.getAttribute() else: attr = attribute if attr[0] == '!': if debug: print("Checking... => %s" % attr[0]) return True return False
[docs] def encrypt(self, pk, M, attr_list): if debug: print('Encryption Algorithm...') # s will hold secret t = group.init(ZR, 0) s = group.random(); sx = [s] for i in range(len(attr_list)): sx.append(group.random(ZR)) sx[0] -= sx[i] E3 = {} #E4, E5 = {}, {} for i in range(len(attr_list)): attr = attr_list[i] E3[attr] = group.hash(attr, G1) ** s #E4[attr] = pk['g_G1_b'] ** sx[i] #E5[attr] = (pk['g_G1_b2'] ** (sx[i] * group.hash(attr))) * (pk['h_G1_b'] ** sx[i]) E1 = (pk['e(gg)_alpha'] ** s) * M E2 = pk['g_G2'] ** s return {'E1':E1, 'E2':E2, 'E3':E3, 'attributes':attr_list }
[docs] def decrypt(self, E, D): policy = util.createPolicy(D['policy']) attrs = util.prune(policy, E['attributes']) if attrs == False: return False coeff = util.getCoefficients(policy) Z = {}; prodT = 1 for i in range(len(attrs)): x = attrs[i].getAttribute() y = attrs[i].getAttributeAndIndex() if not self.negatedAttr(y): Z[y] = pair(D[y][0], E['E2']) / pair(E['E3'][x], D[y][1]) prodT *= Z[y] ** coeff[y] return E['E1'] / prodT
[docs]def main(): groupObj = PairingGroup('MNT224') kpabe = KPabe(groupObj) (pk, mk) = kpabe.setup() policy = '(ONE or THREE) and (THREE or TWO)' attributes = [ 'ONE', 'TWO', 'THREE', 'FOUR' ] msg = groupObj.random(GT) mykey = kpabe.keygen(pk, mk, policy) if debug: print("Encrypt under these attributes: ", attributes) ciphertext = kpabe.encrypt(pk, msg, attributes) if debug: print(ciphertext) rec_msg = kpabe.decrypt(ciphertext, mykey) assert msg == rec_msg if debug: print("Successful Decryption!")
if __name__ == "__main__": debug = True main()