Source code for bsw07
'''
John Bethencourt, Amit Sahai, Brent Waters
| From: "Ciphertext-Policy Attribute-Based Encryption"
| Published in: 2007
| Available from: https://doi.org/10.1109/SP.2007.11
| Notes: Implemented an asymmetric version of the scheme in Section 4.2
| Security Assumption: Generic group model
|
| type: ciphertext-policy attribute-based encryption
| setting: Pairing
:Authors: Shashank Agrawal
:Date: 05/2016
'''
from charm.toolbox.pairinggroup import PairingGroup, ZR, G1, G2, GT, pair
from charm.toolbox.ABEnc import ABEnc
from charm.toolbox.msp import MSP
debug = False
[docs]class BSW07(ABEnc):
def __init__(self, group_obj, verbose=False):
ABEnc.__init__(self)
self.group = group_obj
self.util = MSP(self.group, verbose)
[docs] def setup(self):
"""
Generates public key and master secret key.
"""
if debug:
print('Setup algorithm:\n')
# pick a random element each from two source groups
g1 = self.group.random(G1)
g2 = self.group.random(G2)
beta = self.group.random(ZR)
h = g2 ** beta
f = g2 ** (1/beta)
alpha = self.group.random(ZR)
g1_alpha = g1 ** alpha
e_gg_alpha = pair (g1_alpha, g2)
pk = {'g1': g1, 'g2': g2, 'h': h, 'f': f, 'e_gg_alpha': e_gg_alpha}
msk = {'beta': beta, 'g1_alpha': g1_alpha}
return pk, msk
[docs] def keygen(self, pk, msk, attr_list):
"""
Generate a key for a set of attributes.
"""
if debug:
print('Key generation algorithm:\n')
r = self.group.random(ZR)
g1_r = pk['g1'] ** r
beta_inverse = 1 / msk['beta']
k0 = (msk['g1_alpha'] * g1_r) ** beta_inverse
K = {}
for attr in attr_list:
r_attr = self.group.random(ZR)
k_attr1 = g1_r * (self.group.hash(str(attr), G1) ** r_attr)
k_attr2 = pk['g2'] ** r_attr
K[attr] = (k_attr1, k_attr2)
return {'attr_list': attr_list, 'k0': k0, 'K': K}
[docs] def encrypt(self, pk, msg, policy_str):
"""
Encrypt a message M under a policy string.
"""
if debug:
print('Encryption algorithm:\n')
policy = self.util.createPolicy(policy_str)
mono_span_prog = self.util.convert_policy_to_msp(policy)
num_cols = self.util.len_longest_row
# pick randomness
u = []
for i in range(num_cols):
rand = self.group.random(ZR)
u.append(rand)
s = u[0] # shared secret
c0 = pk['h'] ** s
C = {}
for attr, row in mono_span_prog.items():
cols = len(row)
sum = 0
for i in range(cols):
sum += row[i] * u[i]
attr_stripped = self.util.strip_index(attr)
c_i1 = pk['g2'] ** sum
c_i2 = self.group.hash(str(attr_stripped), G1) ** sum
C[attr] = (c_i1, c_i2)
c_m = (pk['e_gg_alpha'] ** s) * msg
return {'policy': policy, 'c0': c0, 'C': C, 'c_m': c_m}
[docs] def decrypt(self, pk, ctxt, key):
"""
Decrypt ciphertext ctxt with key key.
"""
if debug:
print('Decryption algorithm:\n')
nodes = self.util.prune(ctxt['policy'], key['attr_list'])
if not nodes:
print ("Policy not satisfied.")
return None
prod = 1
for node in nodes:
attr = node.getAttributeAndIndex()
attr_stripped = self.util.strip_index(attr)
(c_attr1, c_attr2) = ctxt['C'][attr]
(k_attr1, k_attr2) = key['K'][attr_stripped]
prod *= (pair(k_attr1, c_attr1) / pair(c_attr2, k_attr2))
return (ctxt['c_m'] * prod) / (pair(key['k0'], ctxt['c0']))