Beispiel #1
0
 def __init__(self, group_obj, assump_size, k, verbose=False):
     ABEnc.__init__(self)
     self.group = group_obj
     self.assump_size = assump_size  # size of linear assumption, at least 2
     self.util = MSP(self.group, verbose)
     self.k = k
     self.index = k
     self.i = 5
     self.j = 5  # we assume i = j, equals to identity-based encryption.
     self.msk = {}
     self.mpk = {}
     self.pk = None
     self.sk = None
     self.sk_delta = None
     self.ID_i = None
     self.ID_j = None
     self.I = []
     for i in range(self.k):
         self.I.append(self.group.random(ZR))
Beispiel #2
0
 def __init__(self, group_obj, verbose=False):
     ABEnc.__init__(self)
     self.group = group_obj
     self.util = MSP(self.group, verbose)
Beispiel #3
0
class AGGABE(ABEnc):

    def __init__(self, group_obj, verbose=False):
        ABEnc.__init__(self)
        self.group = group_obj
        self.util = MSP(self.group, verbose)

    def agg_setup(self, n):

        g = self.group.random(G1)
        beta_2 = self.group.random(ZR)
        alpha = self.group.random(ZR)
        a = self.group.random(ZR)
        b = self.group.random(ZR)
        c = self.group.random(ZR)
        v = g ** beta_2
        g_a = g ** a
        g_b = g ** b
        g_c = g ** c

        dic_g_i = {}
        for i in range(1, 2*n + 1):
            g_i = g ** (alpha ** i)
            dic_g_i[i] = g_i
            # print(i, dic_g_i[i])

        pk = {'g': g, 'v': v, 'n': n, 'g_i': dic_g_i, 'g_a': g_a, 'g_b': g_b, 'g_c': g_c}
        msk = {'a': a, 'b': b, 'c': c, 'beta_2': beta_2}
        return pk, msk

    def agg_keygen(self, pk, msk, attr_list, S):
        g = pk['g']
        # generate key for cs
        beta_1 = self.group.random(ZR)
        u = g ** beta_1
        # key_cs = {'pk_cs': u, 'sk_cs': beta_1}

        # generate key for dta owners
        dic_g_i = pk['g_i']
        # print(len(dic_g_i))
        n = pk['n']
        h_i_1 = {}  # n * n
        h_i_2 = {}  # n * 2n
        sk_i = {}
        for i in range(1, n+1):
            gama_i_1 = self.group.random(ZR)
            gama_i_2 = self.group.random(ZR)

            # print(i, dic_g_i[i])
            # h_i_1[i] = dic_g_i[i] ** gama_i_1
            # print('h_i_1', h_i_1)
            dic_h_1 = {}
            for j in range(1, n+1):
                temp_1 = dic_g_i[j] ** gama_i_1
                dic_h_1[j] = temp_1
            h_i_1[i] = dic_h_1

            ek_i_1 = u ** gama_i_1
            ek_i_2 = pk['v'] ** gama_i_1
            sk_i[i] = (ek_i_1, ek_i_2)
            # print('sk_i', sk_i)

            # h_i_2 = list_g_i[i] ** gama_i_2
            # iteration with 2n
            dic_h_2 = {}
            for j in range(1, 2*n + 1):
                # print(j)
                temp_2 = dic_g_i[j] ** gama_i_2
                # h_i_2[i][j] = h_j_2
                dic_h_2[j] = temp_2
            h_i_2[i] = dic_h_2
            # print('h_i_2', h_i_2)
            # pk_i[i] = (h_i_1, h_i_2)

        # generate key for users
        r = self.group.random(ZR)
        g_r = g ** r
        a = msk['a']
        b = msk['b']
        b_inverse = 1 / b
        c = msk['c']
        A_d = (a * c - r) * b_inverse
        A = g ** A_d

        A_B = {}
        for attr_j in attr_list:
            r_j = self.group.random(ZR)
            A_j = g_r * (self.group.hash(str(attr_j), G1) ** r_j)
            B_j = g ** r_j
            A_B[attr_j] = (A_j, B_j)

        # authorize user with DOs
        beta_2 = msk['beta_2']
        k_agg = 1
        for k in S:
            k_agg *= (dic_g_i[n + 1 - k] ** beta_2)
            # print('k_agg', k_agg)
        return {'attr_list': attr_list, 'pk_cs': u, 'sk_cs': beta_1, 'h_i_1': h_i_1, 'h_i_2': h_i_2, 'sk_i': sk_i, 'A': A, 'A_B': A_B, 'k_agg': k_agg}

    def agg_index(self, pk, key_gen, w_l, policy_list):
        n = pk['n']
        g = pk['g']
        v = pk['v']
        # pk_i = key['pk_i']
        # h_i_1 = key_gen['h_i_1']
        h_i_2 = key_gen['h_i_2']
        sk_i = key_gen['sk_i']

        # for each DO
        C_agg = {}
        W_all = {}
        W_agg = {}

        policy = {}
        for i in range(1, n + 1):
            r_i_l = self.group.random(ZR)
            # (h_i_1, h_i_2) = pk_i[i]
            # print(i, sk_i[i])
            (ek_i_1, ek_i_2) = sk_i[i]
            c_i_l_1 = ek_i_1 ** r_i_l
            c_i_l_2 = ek_i_2 ** r_i_l
            c_i_l_3 = (v * h_i_2[i][i]) ** r_i_l
            C_agg[i] = (c_i_l_1, c_i_l_2, c_i_l_3)

            # perform attribute based encryption
            policy[i] = self.util.createPolicy(policy_list[i])
            mono_span_prog = self.util.convert_policy_to_msp(policy[i])
            num_cols = self.util.len_longest_row

            u_bsw = []
            for j in range(num_cols):
                rand = self.group.random(ZR)
                u_bsw.append(rand)

            r_i_1 = self.group.random(ZR)
            r_i_2 = u_bsw[0]  # shared secret
            g_a = pk['g_a']
            g_b = pk['g_b']
            g_c = pk['g_c']
            W = g_c ** r_i_1
            W_0 = (g_a ** (r_i_1 + r_i_2)) * ((g_b ** (self.group.hash(str(w_l), ZR))) ** r_i_1)
            W_bar = g_b ** r_i_2
            W_all[i] = (W, W_0, W_bar)

            W_agg_i = {}
            for attr, row in mono_span_prog.items():
                cols = len(row)
                sum = 0
                for l in range(cols):
                    sum += row[l] * u_bsw[l]
                attr_stripped = self.util.strip_index(attr)
                W_f = g ** sum
                D_f = self.group.hash(str(attr_stripped), G1) ** sum
                W_agg_i[attr] = (W_f, D_f)
                W_agg[i] = W_agg_i
        return {'policy': policy, 'C_agg': C_agg, 'W_all': W_all, 'W_agg': W_agg}

    def agg_trap(self, pk, key_gen, w_l):
        x = self.group.random(ZR)
        s = self.group.random(ZR)

        Tr_1 = key_gen['k_agg'] * (pk['v'] ** x)
        Tr_2 = key_gen['pk_cs'] ** x
        tok_1 = (pk['g_a'] * (pk['g_b'] ** (self.group.hash(str(w_l), ZR)))) ** s
        tok_2 = pk['g_c'] ** s
        tok_3 = key_gen['A'] ** s

        A_B_bar = {}
        for attr_j in key_gen['attr_list']:
            (A_j, B_j) = key_gen['A_B'][attr_j]
            A_j_bar = A_j ** s
            B_j_bar = B_j ** s
            A_B_bar[attr_j] = (A_j_bar, B_j_bar)
        return {'Tr_1': Tr_1, 'Tr_2': Tr_2, 'tok_1': tok_1, 'tok_2': tok_2, 'tok_3': tok_3, 'A_B_bar': A_B_bar}

    def agg_search(self, pk, key_gen, S, I, Trap):
        h_i_2 = key_gen['h_i_2']  # dic
        # print(type(h_i_2))
        # print('n', pk['n'])
        flag1 = {}
        flag2 = {}
        for i in range(1, pk['n'] + 1):
            print('i', i)
            prod_pub = 1
            prod_k = 1
            dic_h_i_2 = h_i_2[i]  # dic
            # print(type(dic_h_i_2))
            for k in S:
                # (pub_1, pub_2) = key_gen['pk_i'][pk['n'] + 1 - k]
                # prod_pub *= pub_1
                h_i_1_k = key_gen['h_i_1'][i][pk['n'] + 1 - k]
                prod_pub *= h_i_1_k

                if k != i:
                    # (pk_1, pk_2) = key_gen['pk_i'][pk['n'] + 1 - k + i]
                    # prod_k *= pk_2
                    # h_i_2_k = h_i_2[[pk['n'] - 1 - k + i]][[pk['n'] - 1 - k + i]]
                    h_i_2_k = dic_h_i_2[pk['n'] + 1 - k + i]
                    prod_k *= h_i_2_k

            Tr_i_1 = Trap['Tr_1'] * prod_k

            # verify the eq.1
            (c_i_l_1, c_i_l_2, c_i_l_3) = I['C_agg'][i]
            # (h_1, h_2) = key_gen['pk_i'][pk['n'] + 1]
            h_2 = dic_h_i_2[pk['n'] + 1]
            left_1 = ((pair(prod_pub, c_i_l_3) ** key_gen['sk_cs']) * pair(c_i_l_2, Trap['Tr_2'])) / pair(Tr_i_1, c_i_l_1)
            right_1 = pair(h_2, c_i_l_1)

            if left_1 == right_1:
                flag1[i] = True
                print("The first layer satisfied.")

                nodes = self.util.prune(I['policy'][i], key_gen['attr_list'])
                if not nodes:
                    print("Policy not satisfied.")
                    # return None

                E_root = 1
                for node in nodes:
                    attr = node.getAttributeAndIndex()
                    attr_stripped = self.util.strip_index(attr)  # satisfied attributes
                    (A_j_bar, B_j_bar) = Trap['A_B_bar'][attr_stripped]
                    (W_f, D_f) = I['W_agg'][i][attr]
                    E_f = pair(A_j_bar, W_f) / pair(B_j_bar, D_f)
                    E_root *= E_f

                (W, W_0, W_bar) = I['W_all'][i]
                left_2 = pair(W_0, Trap['tok_2'])
                right_2 = pair(W, Trap['tok_1']) * E_root * pair(Trap['tok_3'], W_bar)

                if left_2 == right_2:
                    # return True
                    flag2[i] = True
                    print("The second layer satisfied.")
                else:
                    flag2[i] = False
                    print("The second layer not satisfied.")
                    # return False
            else:
                flag1[i] = False
                print("The first layer not satisfied.")
                # return False
        return {'flag1': flag1, 'flag2': flag2}
Beispiel #4
0
 def __init__(self, group_obj, uni_size, verbose=False):
     ABEnc.__init__(self)
     self.group = group_obj
     self.uni_size = uni_size  # bound on the size of the universe of attributes
     self.util = MSP(self.group, verbose)
Beispiel #5
0
class Waters11(ABEnc):
    def __init__(self, group_obj, uni_size, verbose=False):
        ABEnc.__init__(self)
        self.group = group_obj
        self.uni_size = uni_size  # bound on the size of the universe of attributes
        self.util = MSP(self.group, verbose)

    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 and pair them
        g1 = self.group.random(G1)
        g2 = self.group.random(G2)
        alpha = self.group.random(ZR)
        g1_alpha = g1**alpha
        e_gg_alpha = pair(g1_alpha, g2)

        a = self.group.random(ZR)
        g1_a = g1**a

        h = [0]
        for i in range(self.uni_size):
            h.append(self.group.random(G1))

        pk = {
            'g1': g1,
            'g2': g2,
            'g1_a': g1_a,
            'h': h,
            'e_gg_alpha': e_gg_alpha
        }
        msk = {'g1_alpha': g1_alpha}
        return pk, msk

    def keygen(self, pk, msk, attr_list):
        """
        Generate a key for a set of attributes.
        """

        if debug:
            print('Key generation algorithm:\n')

        t = self.group.random(ZR)
        k0 = msk['g1_alpha'] * (pk['g1_a']**t)
        L = pk['g2']**t

        K = {}
        for attr in attr_list:
            K[attr] = pk['h'][int(attr)]**t

        return {'attr_list': attr_list, 'k0': k0, 'L': L, 'K': K}

    def encrypt(self, pk, msg, policy_str):
        """
         Encrypt a message M under a monotone span program.
        """

        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['g2']**s

        C = {}
        D = {}
        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)
            r_attr = self.group.random(ZR)
            c_attr = (pk['g1_a']**sum) / (pk['h'][int(attr_stripped)]**r_attr)
            d_attr = pk['g2']**r_attr
            C[attr] = c_attr
            D[attr] = d_attr

        c_m = (pk['e_gg_alpha']**s) * msg

        return {'policy': policy, 'c0': c0, 'C': C, 'D': D, 'c_m': c_m}

    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

        prodG = 1
        prodGT = 1

        for node in nodes:
            attr = node.getAttributeAndIndex()
            attr_stripped = self.util.strip_index(attr)
            prodG *= ctxt['C'][attr]
            prodGT *= pair(key['K'][attr_stripped], ctxt['D'][attr])

        return (ctxt['c_m'] * pair(prodG, key['L']) * prodGT) / (pair(
            key['k0'], ctxt['c0']))
def send_waypoint(protocol, params):
    protocol.provide(MSP_SET_WP, params)
    protocol.read_ack(MSP_SET_WP)


if __name__ == '__main__':
    filename = 'waypoints.txt'
    if len(sys.argv) > 1:
        filename = sys.argv[1]

    print('Using {0}'.format(filename))
    with open(filename) as f:
        transport = Serial(port='/dev/ttyACM0', baudrate=115200, timeout=5)
        print(transport)
        protocol = MSP(transport, initialization_delay=15)
        for i in range(0, MAX_WAYPOINTS):
            wp_no = i + 1

            line = f.readline().strip()
            if not line:
                break
            waypoint = line.split(' ')
            if waypoint[0].startswith(COMMENT_START_CHAR):
                continue

            print(waypoint)
            send_waypoint(
                protocol, {
                    'wp_no': wp_no,
                    'action': MSP_WAYPOINT_ACTIONS[waypoint[IDX_ACTION]],
Beispiel #7
0
 def __init__(self, group_obj, assump_size, verbose=False):
     ABEnc.__init__(self)
     self.group = group_obj
     self.assump_size = assump_size  # size of linear assumption, at least 2
     self.util = MSP(self.group, verbose)
Beispiel #8
0
class AC17CPABE(ABEnc):
    def __init__(self, group_obj, assump_size, verbose=False):
        ABEnc.__init__(self)
        self.group = group_obj
        self.assump_size = assump_size  # size of linear assumption, at least 2
        self.util = MSP(self.group, verbose)

    def setup(self):
        """
        Generates public key and master secret key.
        """

        if debug:
            print('\nSetup algorithm:\n')

        # generate two instances of the k-linear assumption
        A = []
        B = []
        for i in range(self.assump_size):
            A.append(self.group.random(ZR))
            B.append(self.group.random(ZR))  # note that A, B are vectors here

        # vector
        k = []
        for i in range(self.assump_size + 1):
            k.append(self.group.random(ZR))

        # pick a random element from the two source groups and pair them
        g = self.group.random(G1)
        h = self.group.random(G2)
        e_gh = pair(g, h)

        # now compute various parts of the public parameters

        # compute the [A]_2 term
        h_A = []
        for i in range(self.assump_size):
            h_A.append(h**A[i])
        h_A.append(h)

        # compute the e([k]_1, [A]_2) term
        g_k = []
        for i in range(self.assump_size + 1):
            g_k.append(g**k[i])

        e_gh_kA = []
        for i in range(self.assump_size):
            e_gh_kA.append(e_gh**(k[i] * A[i] + k[self.assump_size]))

        # the public key
        pk = {'h_A': h_A, 'e_gh_kA': e_gh_kA}

        # the master secret key
        msk = {'g': g, 'h': h, 'g_k': g_k, 'A': A, 'B': B}

        return pk, msk

    def keygen(self, pk, msk, attr_list):
        """
        Generate a key for a list of attributes.
        """

        if debug:
            print('\nKey generation algorithm:\n')

        # pick randomness
        r = []
        sum = 0
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            r.append(rand)
            sum += rand

        # compute the [Br]_2 term

        # first compute just Br as it will be used later too
        Br = []
        for i in range(self.assump_size):
            Br.append(msk['B'][i] * r[i])
        Br.append(sum)

        # now compute [Br]_2
        K_0 = []
        for i in range(self.assump_size + 1):
            K_0.append(msk['h']**Br[i])

        # compute [W_1 Br]_1, ...
        K = {}
        A = msk['A']
        g = msk['g']
        for attr in attr_list:
            key = []
            sigma_attr = self.group.random(ZR)
            for t in range(self.assump_size):
                prod = 1
                a_t = A[t]
                for l in range(self.assump_size + 1):
                    input_for_hash = attr + str(l) + str(t)
                    prod *= (self.group.hash(input_for_hash,
                                             G1)**(Br[l] / a_t))
                prod *= (g**(sigma_attr / a_t))
                key.append(prod)
            key.append(g**(-sigma_attr))
            K[attr] = key

        # compute [k + VBr]_1
        Kp = []
        g_k = msk['g_k']
        sigma = self.group.random(ZR)
        for t in range(self.assump_size):
            prod = g_k[t]
            a_t = A[t]
            for l in range(self.assump_size + 1):
                input_for_hash = '01' + str(l) + str(t)
                prod *= (self.group.hash(input_for_hash, G1)**(Br[l] / a_t))
            prod *= (g**(sigma / a_t))
            Kp.append(prod)
        Kp.append(g_k[self.assump_size] * (g**(-sigma)))

        return {'attr_list': attr_list, 'K_0': K_0, 'K': K, 'Kp': Kp}

    def encrypt(self, pk, msg, policy_str):
        """
        Encrypt a message msg under a policy string.
        """

        if debug:
            print('\nEncryption 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
        s = []
        sum = 0
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            s.append(rand)
            sum += rand

        # compute the [As]_2 term
        C_0 = []
        h_A = pk['h_A']
        for i in range(self.assump_size):
            C_0.append(h_A[i]**s[i])
        C_0.append(h_A[self.assump_size]**sum)

        # compute the [(V^T As||U^T_2 As||...) M^T_i + W^T_i As]_1 terms

        # pre-compute hashes
        hash_table = []
        for j in range(num_cols):
            x = []
            input_for_hash1 = '0' + str(j + 1)
            for l in range(self.assump_size + 1):
                y = []
                input_for_hash2 = input_for_hash1 + str(l)
                for t in range(self.assump_size):
                    input_for_hash3 = input_for_hash2 + str(t)
                    hashed_value = self.group.hash(input_for_hash3, G1)
                    y.append(hashed_value)
                    # if debug: print ('Hash of', i+2, ',', j2, ',', j1, 'is', hashed_value)
                x.append(y)
            hash_table.append(x)

        C = {}
        for attr, row in mono_span_prog.items():
            ct = []
            attr_stripped = self.util.strip_index(
                attr)  # no need, re-use not allowed
            for l in range(self.assump_size + 1):
                prod = 1
                cols = len(row)
                for t in range(self.assump_size):
                    input_for_hash = attr_stripped + str(l) + str(t)
                    prod1 = self.group.hash(input_for_hash, G1)
                    for j in range(cols):
                        # input_for_hash = '0' + str(j+1) + str(l) + str(t)
                        prod1 *= (hash_table[j][l][t]**row[j])
                    prod *= (prod1**s[t])
                ct.append(prod)
            C[attr] = ct

        # compute the e(g, h)^(k^T As) . m term
        Cp = 1
        for i in range(self.assump_size):
            Cp = Cp * (pk['e_gh_kA'][i]**s[i])
        Cp = Cp * msg

        return {'policy': policy, 'C_0': C_0, 'C': C, 'Cp': Cp}

    def decrypt(self, pk, ctxt, key):
        """
        Decrypt ciphertext ctxt with key key.
        """

        if debug:
            print('\nDecryption algorithm:\n')

        nodes = self.util.prune(ctxt['policy'], key['attr_list'])
        if not nodes:
            print("Policy not satisfied.")
            return None

        prod1_GT = 1
        prod2_GT = 1
        for i in range(self.assump_size + 1):
            prod_H = 1
            prod_G = 1
            for node in nodes:
                attr = node.getAttributeAndIndex()
                attr_stripped = self.util.strip_index(
                    attr)  # no need, re-use not allowed
                # prod_H *= key['K'][attr_stripped][i] ** coeff[attr]
                # prod_G *= ctxt['C'][attr][i] ** coeff[attr]
                prod_H *= key['K'][attr_stripped][i]
                prod_G *= ctxt['C'][attr][i]
            prod1_GT *= pair(key['Kp'][i] * prod_H, ctxt['C_0'][i])
            prod2_GT *= pair(prod_G, key['K_0'][i])

        return ctxt['Cp'] * prod2_GT / prod1_GT
Beispiel #9
0
class BSW07(ABEnc):
    def __init__(self, group_obj, verbose=False):
        ABEnc.__init__(self)
        self.group = group_obj
        self.util = MSP(self.group, verbose)

    def hash(self, args, type=ZR):
        return H(self.Pairing, args, type)

    def hash_0(self, msg, nH0):
        m = hashlib.sha256(msg.encode()).hexdigest()
        res = "{0:08b}".format(int(m, 16))
        return res

    def hash_1(self, msg):
        m = hashlib.sha256(msg.encode()).hexdigest()
        res = "{0:08b}".format(int(m, 16))
        return res

    def hash_2(self, msg, nH1):
        m = hashlib.sha256(msg.encode()).hexdigest()
        res = "{0:08b}".format(int(m, 16))
        return res

    def setup(self, attr_list1):
        """
        Generates public key and master secret key.
        """

        if debug:
            print('Setup algorithm:\n')
        strt_time = time.time()

        # pick a random element each from two source groups
        g = self.group.random(G1)
        # print(type(g**2))

        #Randomly selects the variables required
        alpha = self.group.random(ZR)
        beta_1 = self.group.random(ZR)
        beta_2 = self.group.random(ZR)
        beta_bar = self.group.random(ZR)
        # print("alpha", alpha)
        #parameter evaluation
        p = self.group.order()
        # print("p ::::::: ", p)

        beta = int(beta_1 + beta_2) % p
        # print(type(beta))

        T0 = g**alpha
        T1 = g**beta_bar
        Y = pair(g, g)**beta

        V = {}
        Apk = {}
        for i in range(0, len(attr_list1)):
            V[attr_list1[i]] = self.group.random(ZR)
            Apk[attr_list1[i]] = g**V[attr_list1[i]]

        #setting PK and MSK
        pk = {
            'G1': G1,
            'GT': GT,
            'p': p,
            'e': G1,
            'g': g,
            'H': hash,
            'H0': self.hash_0,
            'H1': self.hash_1,
            'H2': self.hash_2,
            'Y': Y,
            'T0': T0,
            'T1': T1,
            'APK': Apk
        }
        msk = {
            'beta': beta,
            'beta_1': beta_1,
            'beta_2': beta_2,
            'alpha': alpha,
            'beta_bar': beta_bar,
            'V_mu': V
        }
        # print(pk)
        # print(msk)
        # print ("%s", time.time()-strt_time)
        return pk, msk

    def FKeyGen(self, pk, msk, shrd, user_attr):
        k_s1 = pk['g']**(msk['beta_2'] / shrd['m'])
        k_s2 = pk['g']**(shrd['l'] / shrd['m'])
        F_ak = shrd['ak']

        k_mu = {}
        for i in range(0, len(user_attr)):
            temp1 = shrd['l'] / (msk['V_mu'][user_attr[i]])
            temp = pk['H'](int(user_attr[i])) / shrd['m']
            temp = pk['g']**(temp * temp1)
            k_mu[user_attr[i]] = temp

        FSK = {'k_s1': k_s1, 'k_s2': k_s2, 'k_mu': k_mu, 'F_ak': F_ak}

        return FSK

    def UKeyGen(self, pk, msk, shrd, user_attr):
        k_u1 = (pk['g']**msk['beta_1']) * (pk['g']**(msk['alpha'] * shrd['l']))
        k_u2 = shrd['m']
        E_ak = shrd['ak']
        k_prime = pk['g']**(msk['alpha'] * msk['beta_bar'])

        USK = {'k_u1': k_u1, 'k_u2': k_u2, 'k_prime': k_prime, 'E_ak': E_ak}
        return USK

    def keygen(self, pk, msk, user_attr):
        """
        Generate a key for a set of attributes.
        """

        if debug:
            print('Key generation algorithm:\n')

        ak = self.group.random(ZR)
        l = self.group.random(ZR)
        m = self.group.random(ZR)

        shrd = {'ak': ak, 'l': l, 'm': m}

        FSK = self.FKeyGen(pk, msk, shrd, user_attr)
        USK = self.UKeyGen(pk, msk, shrd, user_attr)
        # print("USK = " , USK)
        # print("FSK =" , FSK)
        return USK, FSK

    def rhoMap(self, mono_span_prog, index):
        i = 0
        for key in mono_span_prog:
            if i == index:
                return key
            else:
                i = i + 1
        return -1

    def getRowOfA(self, mono_span_prog, index):
        i = 0
        for key in mono_span_prog:
            if i == index:
                return mono_span_prog[key]
            else:
                i = i + 1
        return -1

    #
    # def randomString(self, length):
    #     letters = string.ascii_lowercase
    #     result = ''.join((random.choice(letters)) for x in range(length))
    #     return  result
    #

    def encrypt(self, pk, msk, msg, policy_str, univ):
        """
         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

        # print(mono_span_prog)
        c_i_prime = []
        d_i_prime = {}
        for i in range(len(mono_span_prog.keys())):
            r_i = self.group.random(ZR)
            c_i_prime.append(
                pk['g']**(r_i * pk['H'](int(self.rhoMap(mono_span_prog, i)))))
            d_i_prime[self.rhoMap(
                mono_span_prog,
                i)] = (pk['g']**(r_i *
                                 msk['V_mu'][self.rhoMap(mono_span_prog, i)]))

        CT_prime = {'c_i_prime': c_i_prime, 'd_i_prime': d_i_prime}

        R = random.randint(1000, 1000000)
        # print("R :",R)
        r_dash = []
        lambda_i = []

        for i in range(len(mono_span_prog.keys())):
            r_dash.append(self.group.random(ZR))

        # print(mo/no_span_prog)
        for k in range(len(mono_span_prog.keys())):
            sum = 0
            temp = self.getRowOfA(mono_span_prog, k)
            for j in range(len(temp)):
                sum += temp[j] * r_dash[j]
            lambda_i.append(sum)

        s = r_dash[0]
        temp = msk['beta']
        c0 = R * (pk['Y']**int(s))
        c1 = pk['g']**int(s)

        c_i = []
        for i in range(len(lambda_i)):
            c_i.append((pk['T0']**lambda_i[i]) * (c_i_prime[i]))

        D_i = d_i_prime

        CT_ABE = {
            "c0": c0,
            "c1": c1,
            "ci": c_i,
            "di": D_i,
            "msp": mono_span_prog
        }

        return CT_ABE

    def IndexGen(self, pk, msk, inverted_index):
        dict = list(inverted_index.keys())
        pi = self.group.random(ZR)
        psi = []
        i1 = []
        i2 = []
        i3 = []
        for i in range(len(dict)):
            psi.append(self.group.random(ZR))
            i1.append(pk['g']**(int(psi[i]) * int(msk['beta_bar'])))
            temp = (pk['T0']**(int(psi[i]))) * (pk['T0']**(pi))
            temp2 = (pk['g']**(int(psi[i]) * int(pk['H'](dict[i]))))
            i2.append(temp * temp2)
            i3.append(pk['T0']**pi)

        Index_ = {"i1": i1, "i2": i2, "i3": i3}
        return Index_

    def TrapGen(self, kw, USK, pk, msk):
        varphi = self.group.random(ZR)
        t_1 = (pk['T0']**(int(varphi))) * (pk['g']
                                           **(int(varphi) * int(pk['H'](kw))))
        t_2 = pk['g']**(int(varphi) * int(msk['beta_bar']))
        # t_3 = pk['T1']**varphi
        Eak = USK['E_ak']
        TD_ = {'t_1': t_1, 't_2': t_2, 'E_ak': Eak}
        return TD_

    def search(self, Index_, TD_, ii):
        for i in range(len(Index_['i1'])):
            ptr = pair(Index_['i1'][i], TD_['t_1'])
            ptr1 = pair(Index_['i2'][i], TD_['t_2'])
            ptr2 = pair(Index_['i3'][i], TD_['t_2'])
            if ptr * ptr2 == ptr1:
                print("file found at the server")
                temp = ii[i]
                return temp
        print("file not found at the server")
        return -1

    def decrypt(self, pk, msk, ctxt, FSK, USK):
        """
         Decrypt ciphertext ctxt with key key.
        """
        s = 0
        wi = []
        temp = 1
        temp2 = 1
        for i in range(len(ctxt['ci'])):
            wi.append(self.group.random(ZR))
            temp = temp * (pair(ctxt['ci'][i], FSK['k_s2'])**wi[i])
            temp2 = temp2 * (pair(ctxt['di'][self.rhoMap(ctxt['msp'], i)],
                                  FSK['k_mu'][self.rhoMap(ctxt['msp'], i)])**
                             wi[i])
            temp2 = temp2 * pair(ctxt['c1'], FSK['k_s1'])
            E = temp / temp2

        ptr = ctxt['c0'] * (E**USK['k_u2'])
        ptr1 = pair(ctxt['c1'], USK['k_u1'])
        R = ptr / ptr1

        return R

    def attrRevocation(self, pk, msk, FSK, mu, ctxt):

        vmu_prime = self.group.random(ZR)

        while msk['V_mu'][mu] == vmu_prime:
            vmu_prime = self.group.random(ZR)

        msk['V_mu'][mu] = vmu_prime / msk['V_mu'][mu]
        pk['APK'][mu] = pk['APK'][mu]**msk['V_mu'][mu]

        #updated userkey generation
        temp = pk['H'](int(mu)) / msk['V_mu'][mu]
        test = FSK['k_s2']**(temp)

        #updated ciphertext generation
        for i in range(len(ctxt['di'])):
            if (self.rhoMap(ctxt['msp'], i) == mu):
                r_i = self.group.random(ZR)
                ctxt['di'][self.rhoMap(
                    ctxt['msp'],
                    i)] = pk['g']**(r_i *
                                    msk['V_mu'][self.rhoMap(ctxt['msp'], i)])

        return FSK, ctxt
Beispiel #10
0
 def __init__(self, groupObj, assump_size, uni_size, verbose=False):
     ABEnc.__init__(self)
     self.group = groupObj
     self.assump_size = assump_size  # size of the linear assumption
     self.uni_size = uni_size  # bound on the size of the universe of attributes
     self.util = MSP(self.group, verbose)  
Beispiel #11
0
class CGW15CPABE(ABEnc):
    def __init__(self, groupObj, assump_size, uni_size, verbose=False):
        ABEnc.__init__(self)
        self.group = groupObj
        self.assump_size = assump_size  # size of the linear assumption
        self.uni_size = uni_size  # bound on the size of the universe of attributes
        self.util = MSP(self.group, verbose)  

    def setup(self):
        """
        Generates public key and master secret key.
        """

        if debug:
            print('Setup algorithm:\n')

        # generate two instances of the k-linear assumption
        A = []
        B = []
        for i in range(self.assump_size):
            A.append(self.group.random(ZR))
            B.append(self.group.random(ZR))  # note that A, B are vectors here

        # pick matrices that help to randomize basis
        W = {}
        for i in range(self.uni_size):
            x = []
            for j1 in range(self.assump_size + 1):
                y = []
                for j2 in range(self.assump_size + 1):
                    y.append(self.group.random(ZR))
                x.append(y)
            W[i + 1] = x

        V = []
        for j1 in range(self.assump_size + 1):
            y = []
            for j2 in range(self.assump_size + 1):
                y.append(self.group.random(ZR))
            V.append(y)

        # vector
        k = []
        for i in range(self.assump_size + 1):
            k.append(self.group.random(ZR))

        # pick a random element from the two source groups and pair them
        g = self.group.random(G1)
        h = self.group.random(G2)
        e_gh = pair(g, h)

        # now compute various parts of the public parameters

        # compute the [A]_1 term
        g_A = []
        for i in range(self.assump_size):
            g_A.append(g ** A[i])
        g_A.append(g)

        # compute the [W_1^T A]_1, [W_2^T A]_1, ...  terms
        g_WA = {}
        for i in range(self.uni_size):
            x = []
            for j1 in range(self.assump_size + 1):
                y = []
                for j2 in range(self.assump_size):
                    prod = (A[j2] * W[i + 1][j2][j1]) + W[i + 1][self.assump_size][j1]
                    y.append(g ** prod)
                x.append(y)
            g_WA[i + 1] = x

        g_VA = []
        for j1 in range(self.assump_size + 1):
            y = []
            for j2 in range(self.assump_size):
                prod = (A[j2] * V[j2][j1]) + V[self.assump_size][j1]
                y.append(g ** prod)
            g_VA.append(y)

        # compute the e([A]_1, [k]_2) term
        h_k = []
        for i in range(self.assump_size + 1):
            h_k.append(h ** k[i])

        e_gh_kA = []
        for i in range(self.assump_size):
            e_gh_kA.append(e_gh ** (k[i] * A[i] + k[self.assump_size]))

        # the public key
        pk = {'g_A': g_A, 'g_WA': g_WA, 'g_VA': g_VA, 'e_gh_kA': e_gh_kA}

        # the master secret key
        msk = {'h': h, 'k': k, 'B': B, 'W': W, 'V': V}

        return pk, msk

    def keygen(self, pk, msk, attr_list):
        """
        Generate a key for a set of attributes.
        """

        if debug:
            print('Key generation algorithm:\n')

        # pick randomness
        r = []
        sum = 0
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            r.append(rand)
            sum += rand

        # compute the [Br]_2 term
        K_0 = []
        Br = []
        h = msk['h']
        for i in range(self.assump_size):
            prod = msk['B'][i] * r[i]
            Br.append(prod)
            K_0.append(h ** prod)
        Br.append(sum)
        K_0.append(h ** sum)

        # compute the [W_i^T Br]_2 terms
        K = {}
        for attr in attr_list:
            key = []
            W_attr = msk['W'][int(attr)]
            for j1 in range(self.assump_size + 1):
                sum = 0
                for j2 in range(self.assump_size + 1):
                    sum += W_attr[j1][j2] * Br[j2]
                key.append(h ** sum)
            K[attr] = key

        # compute the [k + VBr]_2 term
        Kp = []
        V = msk['V']
        k = msk['k']
        for j1 in range(self.assump_size + 1):
            sum = 0
            for j2 in range(self.assump_size + 1):
                sum += V[j1][j2] * Br[j2]
            Kp.append(h ** (k[j1] + sum))

        return {'attr_list': attr_list, 'K_0': K_0, 'K': K, 'Kp': Kp}

    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
        s = []
        sum = 0
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            s.append(rand)
            sum += rand
        s.append(sum)

        # compute the [As]_1 term
        g_As = []
        g_A = pk['g_A']
        for i in range(self.assump_size + 1):
            g_As.append(g_A[i] ** s[i])

        # compute U^T_2 As, U^T_3 As by picking random matrices U_2, U_3 ...
        UAs = {}
        for i in range(num_cols - 1):
            x = []
            for j1 in range(self.assump_size + 1):
                prod = 1
                for j2 in range(self.assump_size + 1):
                    prod *= g_As[j2] ** (self.group.random(ZR))
                x.append(prod)
            UAs[i+1] = x

        # compute V^T As using VA from public key
        VAs = []
        g_VA = pk['g_VA']
        for j1 in range(self.assump_size + 1):
            prod = 1
            for j2 in range(self.assump_size):
                prod *= g_VA[j1][j2] ** s[j2]
            VAs.append(prod)

        # compute the [(V^T As||U^T_2 As||...||U^T_cols As) M^T_i + W^T_i As]_1 terms
        C = {}
        g_WA = pk['g_WA']
        for attr, row in mono_span_prog.items():
            attr_stripped = self.util.strip_index(attr)  # no need, re-use not allowed
            ct = []
            for j1 in range(self.assump_size + 1):
                cols = len(row)
                prod1 = VAs[j1] ** row[0]
                for j2 in range(1, cols):
                    prod1 *= UAs[j2][j1] ** row[j2]
                prod2 = 1
                for j2 in range(self.assump_size):
                    prod2 *= g_WA[int(attr_stripped)][j1][j2] ** s[j2]
                ct.append(prod1 * prod2)
            C[attr] = ct

        # compute the e(g, h)^(k^T As) . m term
        Cx = 1
        for i in range(self.assump_size):
            Cx = Cx * (pk['e_gh_kA'][i] ** s[i])
        Cx = Cx * msg

        return {'policy': policy, 'C_0': g_As, 'C': C, 'Cx': Cx}

    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

        prod1_GT = 1
        prod2_GT = 1
        for i in range(self.assump_size + 1):
            prod_H = 1
            prod_G = 1
            for node in nodes:
                attr = node.getAttributeAndIndex()
                attr_stripped = self.util.strip_index(attr)  # no need, re-use not allowed
                # prod_H *= D['K'][attr_stripped][i] ** coeff[attr]
                # prod_G *= E['C'][attr][i] ** coeff[attr]
                prod_H *= key['K'][attr_stripped][i]
                prod_G *= ctxt['C'][attr][i]
            prod1_GT *= pair(ctxt['C_0'][i], key['Kp'][i] * prod_H)
            prod2_GT *= pair(prod_G, key['K_0'][i])

        return ctxt['Cx'] * prod2_GT / prod1_GT
Beispiel #12
0
class BSW07(ABEnc):
    def __init__(self, group_obj, verbose=False):
        ABEnc.__init__(self)
        self.group = group_obj
        self.util = MSP(self.group, verbose)

    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

    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}

    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}

    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']))
Beispiel #13
0
 def run(self):
     print '\n#### COM ####'
     ann, knn, msp, svm = ANN(), KNN(), MSP(), SVM()
     self.gotta.emit({'ann': ann, 'knn': knn, 'msp': msp, 'svm': svm})
     print '#### COM ####\n'
Beispiel #14
0
class PCHBA(ABEnc):
    def __init__(self, group_obj, assump_size, k, verbose=False):
        ABEnc.__init__(self)
        self.group = group_obj
        self.assump_size = assump_size  # size of linear assumption, at least 2
        self.util = MSP(self.group, verbose)
        self.k = k
        self.index = k
        self.i = 5
        self.j = 5  # we assume i = j, equals to identity-based encryption.
        self.msk = {}
        self.mpk = {}
        self.pk = None
        self.sk = None
        self.sk_delta = None
        self.ID_i = None
        self.ID_j = None
        self.I = []
        for i in range(self.k):
            self.I.append(self.group.random(ZR))

    def setup(self):
        """
        Generates public key and master secret key.
        """

        if debug:
            print('\nSetup algorithm:\n')

# (sk, pk)
        h = self.group.random(G2)
        self.sk = self.group.random(ZR)
        self.pk = h**self.sk

        # (msk, mpk)
        g = self.group.random(G1)
        a0 = self.group.random(ZR)
        a1 = self.group.random(ZR)
        b0 = self.group.random(ZR)
        b1 = self.group.random(ZR)
        alpha = self.group.random(ZR)
        beta = self.group.random(ZR)
        d0 = self.group.random(ZR)
        d1 = self.group.random(ZR)
        d2 = self.group.random(ZR)
        g_d1 = g**d0
        g_d2 = g**d1
        g_d3 = g**d2
        Z = []  # {z1,...,zk}
        G = []  # {g1,...,gk}
        H = []  # {h1,...,hk}
        GZ = []  # {g_z1,...,g_zk}
        HZ = []  # {h_z1,...,h_zk}
        for i in range(self.k):
            Z.append(self.group.random(ZR))
            G.append(self.group.random(G1))
            H.append(self.group.random(G2))
            GZ.append(g**Z[i])
            HZ.append(h**Z[i])

        e_gh = pair(g, h)
        H1 = h**a0
        H2 = h**a1
        T1 = e_gh**(d0 * a0 + d2 / alpha)
        T2 = e_gh**(d1 * a1 + d2 / alpha)
        g_alpha = g**alpha
        d = d0 + d1 + d2
        h_d_alpha = h**(d / alpha)
        h_1_alpha = h**(1 / alpha)
        h_beta_alpha = h**(beta / alpha)

        self.ID_i = 1
        for i in range(self.i):
            g_k = GZ[self.k - i - 1]
            self.ID_i *= g_k**self.I[i]
        self.ID_i *= g
        self.ID_j = 1
        for j in range(self.j):
            h_k = HZ[self.k - j - 1]
            self.ID_j *= h_k**self.I[j]
        self.ID_j *= h

        self.msk = {
            'a0': a0,
            'a1': a1,
            'b0': b0,
            'b1': b1,
            'alpha': alpha,
            'beta': beta,
            'd0': d0,
            'd1': d1,
            'd2': d2,
            'g_d1': g_d1,
            'g_d2': g_d2,
            'g_d3': g_d3,
            'Z': Z
        }
        self.mpk = {
            'g': g,
            'h': h,
            'H1': H1,
            'H2': H2,
            'T1': T1,
            'T2': T2,
            'GZ': GZ,
            'HZ': HZ,
            'g_alpha': g_alpha,
            'h_d_alpha': h_d_alpha,
            'h_1_alpha': h_1_alpha,
            'h_beta_alpha': h_beta_alpha
        }

        return self.sk, self.pk, self.msk, self.mpk

    def keygen(self, sk, pk, msk, mpk, attr_list):
        """
        Generate a key for a list of attributes.
        """

        if debug:
            print('\nKey generation algorithm:\n')

        msk = self.msk
        mpk = self.mpk
        sk = self.sk
        pk = self.pk
        g = mpk['g']
        h = mpk['h']
        alpha = msk['alpha']
        x = sk
        d = msk['d0'] + msk['d1'] + msk['d2']
        R = self.group.random(ZR)
        r1 = self.group.random(ZR)
        r2 = self.group.random(ZR)
        r = r1 + r2
        h_b1_r1 = h**(msk['b0'] * r1)
        h_b2_r2 = h**(msk['b1'] * r2)
        h_r1_r2_alpha = h**((r1 + r2) / alpha)
        g_1_alpha = g**(1 / alpha)
        g_r_alpha = g**(r / alpha)
        g_R = g**R
        sk0 = {
            'h_b1_r1': h_b1_r1,
            'h_b2_r2': h_b2_r2,
            'h_r1_r2_alpha': h_r1_r2_alpha,
            'g_1_alpha': g_1_alpha,
            'g_r_alpha': g_r_alpha,
            'g_R': g_R
        }
        SK = {}  # SK = {[sk_y_1, sk_y_2]} sk_y_t
        sk_prime = []

        for attr in attr_list:
            sigma_y = self.group.random(ZR)
            key = []
            for t in range(self.assump_size):
                input_for_hash1 = attr + str(0) + str(t)
                input_for_hash2 = attr + str(1) + str(t)
                input_for_hash3 = attr + str(2) + str(t)
                a_t = 'a' + str(t)
                sk_y_t = self.group.hash(input_for_hash1, G1)**(
                    msk['b0'] * r1 / msk[a_t]) * self.group.hash(
                        input_for_hash2,
                        G1)**(msk['b1'] * r2 / msk[a_t]) * self.group.hash(
                            input_for_hash3, G1)**(
                                (r1 + r2) /
                                (alpha * msk[a_t])) * g**(sigma_y /
                                                          (alpha * msk[a_t]))
                key.append(sk_y_t)
            key.append(g**(-sigma_y))
            SK[attr] = key

        sigma_prime = self.group.random(ZR)
        for t in range(self.assump_size):
            input_for_hash1 = "010" + str(t)
            input_for_hash2 = "011" + str(t)
            input_for_hash3 = "012" + str(t)
            a_t = 'a' + str(t)
            d_t = 'd' + str(t)
            sk_t = g**msk[d_t] * self.group.hash(input_for_hash1, G1)**(
                msk['b0'] * r1 / msk[a_t]) * self.group.hash(
                    input_for_hash2,
                    G1)**(msk['b1'] * r2 / msk[a_t]) * self.group.hash(
                        input_for_hash3, G1)**(
                            (r1 + r2) /
                            (alpha * msk[a_t])) * g**(sigma_prime /
                                                      (alpha * msk[a_t]))
            sk_prime.append(sk_t)
        sk_prime.append(g**msk['d2'] * g**(-sigma_prime))

        sk1 = g**d * self.ID_i**(alpha * r) * g**(msk['beta'] * R)

        sk2 = [None] * ((self.i - 1) * 2)
        for i in range(self.i - 1):
            g_k = mpk['GZ'][self.i - 1 - i]
            sk2[i] = g_k**(alpha * r)
            sk2[self.i + i - 1] = g_k**alpha

        ssk = {
            'sk0': sk0,
            'sk_y_t': SK,
            'sk_prime': sk_prime,
            'sk1': sk1,
            'sk2': sk2
        }
        self.sk_delta = {'x': x, 'ssk': ssk, 'attr_list': attr_list}

        return self.sk_delta

    def hash(self, m, policy_str):
        msk = self.msk
        mpk = self.mpk
        pk = self.pk
        h = mpk['h']
        g = mpk['g']
        policy = self.util.createPolicy(policy_str)
        mono_span_prog = self.util.convert_policy_to_msp(policy)
        num_cols = self.util.len_longest_row

        # step 1
        r = self.group.random(ZR)
        p = pk**r

        # step 2
        R = self.group.random(ZR)
        sha256 = hashlib.new('sha256')
        sha256.update(self.group.serialize(R))
        hd = sha256.hexdigest()
        seed = str(hd)
        e = self.group.hash(seed, ZR)
        h_prime = h**e

        # step 3
        m = self.group.random(ZR)
        b = p * h_prime**m

        # step 4
        s = []
        sum = 0  # sum = s1 + s2
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            s.append(rand)
            sum += rand
        _sk = sum
        _vk = self.ID_j**(msk['alpha'] * sum)

        # step 5
        ct0 = []
        H1 = mpk['H1']
        H2 = mpk['H2']
        ct0.append(H1**s[0])
        ct0.append(H2**s[1])
        ct0.append(h**(sum / msk['alpha']))
        ct0.append(mpk['h_beta_alpha']**sum)

        # pre-compute hashes
        hash_table = []
        for j in range(num_cols):
            x = []
            input_for_hash1 = '0' + str(j + 1)
            for l in range(self.assump_size + 1):
                y = []
                input_for_hash2 = input_for_hash1 + str(l)
                for t in range(self.assump_size):
                    input_for_hash3 = input_for_hash2 + str(t)
                    hashed_value = self.group.hash(input_for_hash3, G1)
                    y.append(hashed_value)
                x.append(y)
            hash_table.append(x)

        # compute C = ct_u_l
        C = {}
        for attr, row in mono_span_prog.items():
            ct = []
            attr_stripped = self.util.strip_index(
                attr)  # no need, re-use not allowed
            for l in range(self.assump_size + 1):
                prod = 1
                cols = len(row)
                for t in range(self.assump_size):
                    input_for_hash = attr_stripped + str(l) + str(t)
                    prod1 = self.group.hash(input_for_hash, G1)
                    for j in range(cols):
                        prod1 *= (hash_table[j][l][t]**row[j])
                    prod *= (prod1**s[t])
                ct.append(prod)
            C[attr] = ct

        sha256 = hashlib.new('sha256')
        msg = mpk['T1']**s[0] * mpk['T2']**s[1]
        sha256.update(self.group.serialize(msg))
        hd = sha256.hexdigest()
        seed = str(hd)
        _ct = r * self.group.hash(seed, ZR)
        d = msk['d0'] + msk['d1'] + msk['d2']

        cpp = pair(g, h**(d / msk['alpha']))**_sk
        seed = str(cpp)
        _ctp = R * self.group.hash(seed, ZR)
        _ct2p = _vk
        _ct3p = self.ID_j**(sum)
        _ct4p = _vk**(sum)
        _C = [ct0, C, _ct, _ctp, _ct2p, _ct3p, policy, _ct4p]

        # step 6
        c = h**(_sk + R)
        esk = self.group.random(ZR)
        epk = pair(g, _vk)**esk
        sigma = esk + _sk * self.group.hash(str(epk) + str(c))

        # step 7
        return m, p, h_prime, b, _C, c, epk, sigma

    def verify(self, m, p, h_prime, b, C, c, epk, sigma):
        vk = C[4]  # get vk
        vk_s = C[7]  # get vk_s
        b_prime = p * h_prime**m
        base = pair(self.mpk['g'], vk)
        base_sigma_prime = epk * pair(
            self.mpk['g'], vk_s)**self.group.hash(str(epk) + str(c))

        if (b == b_prime and base**sigma == base_sigma_prime):
            return 0
        else:
            return 1

    def adapt(self, sk_delta, m, m_prime, p, h_prime, b, C, c, epk, sigma,
              ID_i, policy_str):
        m_prime = self.group.random(ZR)
        _m = self.group.random(ZR)
        g = self.mpk['g']
        h = self.mpk['h']
        d = self.msk['d0'] + self.msk['d1'] + self.msk['d2']
        alpha = self.msk['alpha']
        mpk = self.mpk
        msk = self.msk
        sk_delta = self.sk_delta
        sk_prime = self.sk_delta['ssk']['sk_prime']
        ID_i = self.ID_i

        policy = self.util.createPolicy(policy_str)
        mono_span_prog = self.util.convert_policy_to_msp(policy)
        num_cols = self.util.len_longest_row

        # step 2.(b)
        ctp = C[3]
        pair1 = pair(sk_delta['ssk']['sk1'], C[0][2])  # C[0][2] = ct0,3
        pair2 = pair(sk_delta['ssk']['sk0']['g_r_alpha'], C[4])  # C[4] = ct2p
        pair3 = pair(sk_delta['ssk']['sk0']['g_R'],
                     C[0][3])  # C[0][3] = mpk['h_beta_alpha'] ** sum
        cpp = pair1 / (pair2 * pair3)
        seed = str(cpp)
        R = ctp / self.group.hash(seed, ZR)

        # step 3
        nodes = self.util.prune(
            C[6], self.sk_delta['attr_list']
        )  # C[6] = ctxt['policy'] get ciphertext policy
        if not nodes:
            print("Policy is not satisfied.")
            return None

        sk0_tmp = []
        sk0_tmp.append(sk_delta['ssk']['sk0']['h_b1_r1'])
        sk0_tmp.append(sk_delta['ssk']['sk0']['h_b2_r2'])
        sk0_tmp.append(sk_delta['ssk']['sk0']['h_r1_r2_alpha'])

        prod1_GT = 1
        prod2_GT = 1
        for i in range(self.assump_size + 1):
            prod_H = 1
            prod_G = 1
            for node in nodes:
                attr = node.getAttributeAndIndex()
                attr_stripped = self.util.strip_index(
                    attr)  # no need, re-use not allowed
                prod_H *= sk_delta['ssk']['sk_y_t'][attr_stripped][i]
                prod_G *= C[1][attr][i]  # C[1] = _C
            prod1_GT *= pair(sk_prime[i] * prod_H, C[0][i])
            prod2_GT *= pair(prod_G, sk0_tmp[i])
        Cp = -(prod2_GT / prod1_GT)

        sha256 = hashlib.new('sha256')
        sha256.update(self.group.serialize(Cp))
        x = sha256.hexdigest()
        seed = str(x)
        r_tmp = C[2] / self.group.hash(seed, ZR)  # C[2] = _ct

        # step 4
        s_prime = []
        sum_prime = 0  # sum = s1 + s2
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            s_prime.append(rand)
            sum_prime += rand

        _sk_prime = sum_prime
        _vk_prime = self.ID_j**(msk['alpha'] * sum_prime
                                )  # TODO add comment for ID_j

        # step 5
        sha256 = hashlib.new('sha256')
        sha256.update(self.group.serialize(R))
        hd = sha256.hexdigest()
        seed = str(hd)
        e = self.group.hash(seed, ZR)
        r_prime = r_tmp + (m - m_prime) * e / self.sk
        p_prime = self.pk**r_prime

        # step 6
        ct0 = []
        H1 = mpk['H1']
        H2 = mpk['H2']
        ct0.append(H1**s_prime[0])
        ct0.append(H2**s_prime[1])
        ct0.append(h**(sum_prime / msk['alpha']))
        ct0.append(mpk['h_beta_alpha']**sum_prime)

        # pre-compute hashes
        hash_table = []
        for j in range(num_cols):
            x = []
            input_for_hash1 = '0' + str(j + 1)
            for l in range(self.assump_size + 1):
                y = []
                input_for_hash2 = input_for_hash1 + str(l)
                for t in range(self.assump_size):
                    input_for_hash3 = input_for_hash2 + str(t)
                    hashed_value = self.group.hash(input_for_hash3, G1)
                    y.append(hashed_value)
                x.append(y)
            hash_table.append(x)

        # compute C = ct_u_l
        C = {}
        for attr, row in mono_span_prog.items():
            ct = []
            attr_stripped = self.util.strip_index(
                attr)  # no need, re-use not allowed
            for l in range(self.assump_size + 1):
                prod = 1
                cols = len(row)
                for t in range(self.assump_size):
                    input_for_hash = attr_stripped + str(l) + str(t)
                    prod1 = self.group.hash(input_for_hash, G1)
                    for j in range(cols):
                        prod1 *= (hash_table[j][l][t]**row[j])
                    prod *= (prod1**s_prime[t])
                ct.append(prod)
            C[attr] = ct

        # step 7
        sha256 = hashlib.new('sha256')
        msg = mpk['T1']**s_prime[0] * mpk['T2']**s_prime[1]
        sha256.update(self.group.serialize(msg))
        hd = sha256.hexdigest()
        seed = str(hd)
        _ct = r_prime * self.group.hash(seed, ZR)
        d = msk['d0'] + msk['d1'] + msk['d2']

        cpp = pair(g, h**(d / msk['alpha']))**_sk_prime
        seed = str(cpp)
        _ctp = R * self.group.hash(seed, ZR)
        _ct2p = _vk_prime
        _ct3p = self.ID_j**(sum_prime)
        _ct4p = _vk_prime**(sum_prime)
        _C = [ct0, C, _ct, _ctp, _ct2p, _ct3p, policy, _ct4p]
        C_prime = _C

        c_prime = h**(_sk_prime + R)
        esk_prime = self.group.random(ZR)
        epk_prime = pair(g, _vk_prime)**esk_prime
        sigma_prime = esk_prime + _sk_prime * self.group.hash(
            str(epk_prime) + str(c_prime))

        return m_prime, p_prime, h_prime, b, C_prime, c_prime, epk_prime, sigma_prime

    def judge(self, m, p, h_prime, b, C, c, epk, sigma, m_prime, p_prime,
              C_prime, c_prime, epk_prime, sigma_prime):
        rs = 0
        alpha = self.msk['alpha']
        h = self.mpk['h']
        g = self.mpk['g']
        vk = C[4]
        vk_prime = C_prime[4]

        # step 1
        b0 = p * h_prime**m
        b1 = p_prime * h_prime**m_prime

        if (b == b0 and b == b1):
            rs = 0
        else:
            rs = 1

        # step 2
        vk_s = C[7]
        vk_s_prime = C_prime[7]
        base = pair(g, vk)
        base_prime = pair(g, vk_prime)
        base_sigma0 = epk * pair(g, vk_s)**self.group.hash(str(epk) + str(c))
        base_sigma1 = epk_prime * pair(
            g, vk_s_prime)**self.group.hash(str(epk_prime) + str(c_prime))
        if (base**sigma == base_sigma0
                and base_prime**sigma_prime == base_sigma1):
            rs = 0
        else:
            rs = 1

        # step 3
        delta_sk = c_prime / c
        ct_0_3 = C[0][2]
        ct_0_3_prime = C_prime[0][2]
        if (ct_0_3_prime == ct_0_3 * delta_sk):
            rs = 0
        else:
            rs = 1

        # step 4
        pair1 = pair(g, vk**(1 / (alpha * alpha)))
        pair2 = pair(self.ID_i, C[0][2])  # C[0][2] = ct_(0,3)
        if (pair1 == pair2):
            rs = 0
        else:
            rs = 1

        return rs

    def TestExp(self):
        self.mpk['g']**self.msk['a0']
class ABE(ABEnc):
    def __init__(self, group_obj, assump_size, verbose=False, htype='sha256'):
        ABEnc.__init__(self)
        self.group = group_obj
        self.assump_size = assump_size  # size of linear assumption, at least 2
        self.util = MSP(self.group, verbose)
	self.hash_type = htype

    def setup(self):
        """
        Generates master public key and master secret key.
        """

        # generate two instances of the k-linear assumption
        A = []
        B = []
        for i in range(self.assump_size):
            A.append(self.group.random(ZR))
            B.append(self.group.random(ZR))  # note that A, B are vectors here

        # vector includes d_1, d_2, d_3
        k = []
        for i in range(self.assump_size + 1):
            k.append(self.group.random(ZR))

        # pick a random element from the two source groups and pair them
        g = self.group.random(G1)
        h = self.group.random(G2)
        e_gh = pair(g, h)


        # compute the [A]_2 term includes h^{a_1}, h^{a_2}, h
        h_A = []
        for i in range(self.assump_size):
            h_A.append(h ** A[i])
        h_A.append(h)

        # compute the e([k]_1, [A]_2) term, g_k includes g^{d_1}, g^{d_2}, g^{d_3}
        g_k = []
        for i in range(self.assump_size + 1):
            g_k.append(g ** k[i])

        e_gh_kA = []
        for i in range(self.assump_size):
            e_gh_kA.append(e_gh ** (k[i] * A[i] + k[self.assump_size]))

        # the public key
        mpk = {'h_A': h_A, 'e_gh_kA': e_gh_kA}

        # the master secret key
        msk = {'g': g, 'h': h, 'g_k': g_k, 'A': A, 'B': B}

        return mpk, msk

    def keygen(self, mpk, msk, policy_str):
        """
        Generate a key under a policy string.
        """

        policy = self.util.createPolicy(policy_str)
        mono_span_prog = self.util.convert_policy_to_msp(policy)
        num_cols = self.util.len_longest_row # max col = 3 in this example

        # pick randomness
        r = []
        sum = 0
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            r.append(rand)
            sum += rand

        # first compute Br, which includes b_1 * r_1, b_2 * r_2, r_1 + r_2
        Br = []
        for i in range(self.assump_size):
            Br.append(msk['B'][i] * r[i])
        Br.append(sum)

        # compute the [Br]_2 term, which includes h^{b_1 * r_1], h^{b_2 * r_2}, h^{r_1 + r_2}
        K_0 = []
        for i in range(self.assump_size + 1):
            K_0.append(msk['h'] ** Br[i])

	# compute keys
        K = {}
        A = msk['A']
        g = msk['g']
    	g_k = msk['g_k']
 	
	# len(sigma_col) = 2
        sigma_col = [] 
        for j in range(num_cols-1):
            rand = self.group.random(ZR)
    	    sigma_col.append(rand)
	
        # The we compute the [ attribute y in S ]_1 terms	
	for attr, row in mono_span_prog.items():
            k = []
	    sigma_attr = self.group.random(ZR)
            cols = len(row)
            attr_stripped = self.util.strip_index(attr)  # no need, re-use not allowed

	    #sk_i_1/2
	    for t in range(self.assump_size):
		a_t = A[t]
		prod1 = 1
		for j in range(1, cols): # j = [1, 2]
		    prodt1 = 1	
	
		    for l in range(self.assump_size + 1):
			input_for_hash_1 = '0' + str(j+1) + str(l) + str(t) # l = [0, 1, 2], t = [0, 1]		
			prodt2 = self.group.hash(input_for_hash_1, G1)
			prodt2 = prodt2 ** (Br[l] / a_t)
			prodt1 *= prodt2
		    # g^(sig_p_j/a_t)
		    prodt2 = g ** (sigma_col[j-1] / a_t )
		    prodt1 *= prodt2
		    prodt1 = prodt1 ** (row[j])		
		    #print(prodt1)    
		    prod1 *= prodt1
 
		for l in range(self.assump_size + 1):
		    input_for_hash_2 = attr_stripped + str(l) + str(t)  # l = [0, 1, 2], t = [0, 1]	
		    prodt1 = self.group.hash(input_for_hash_2, G1) ** (Br[l] / a_t)
		    prod1 *= prodt1

		prodt1 = g ** (sigma_attr/a_t)
		prod1 *= prodt1
		prodt1 = (g_k[t]) ** (row[0])
		prod1 *= prodt1
		k.append(prod1) # sk_i1, sk_i2

	    prod1 = 1	    
	    for j in range(1, cols):	# j = [1, 2]
		prod1 *= (g ** (-sigma_col[j-1]) ) ** (row[j])
	    prod1 *= g ** (-sigma_attr)
	    prod1 *= (g_k[self.assump_size]) ** (row[0]) #sk_i3
	    k.append(prod1)
            K[attr] = k

        return {'policy': policy, 'K_0': K_0, 'K': K}

    def encrypt(self, mpk, msg, attr_list):
        """
        Encrypt a message msg for a list of attributes.
        """

        # pick randomness
        s = []
        sum = 0
        for i in range(self.assump_size):
            rand = self.group.random(ZR)
            s.append(rand)
            sum += rand

        # compute the [As]_2 term, h^{a_1 * s_1}, h^{a_2 * s_2}, h^{s_1 * s_2}
        C_0 = []
        h_A = mpk['h_A'] 
        for i in range(self.assump_size):
            C_0.append(h_A[i] ** s[i]) 
        C_0.append(h_A[self.assump_size] ** sum) 

        # compute the [Ws]_1 terms

        C = {}
        for attr in attr_list:
            ct = []
            for l in range(self.assump_size + 1):
                prod = 1
                for t in range(self.assump_size):
                    input_for_hash = attr + str(l) + str(t) # l = [0,1,2], t= [0,1]
                    prod *= (self.group.hash(input_for_hash, G1) ** s[t])
                ct.append(prod)
            C[attr] = ct

        # compute the e(g, h)^(k^T As) . msg term
        Cp = 1
        for i in range(self.assump_size):
            Cp = Cp * (mpk['e_gh_kA'][i] ** s[i])	 
	
	sha256 = hashlib.new(self.hash_type)
	sha256.update(self.group.serialize(Cp))
	x = sha256.hexdigest() 
	Cp = msg^(int(x,16))

        return {'attr_list': attr_list, 'C_0': C_0, 'C': C, 'Cp': Cp}

    def decrypt(self, mpk, key, ctxt):
        """
        Decrypt ciphertext ctxt with decryption key.
        """

        nodes = self.util.prune(key['policy'], ctxt['attr_list'])
        if not nodes:
            print ("Policy is not satisfied.")
            return None

        prod1_GT = 1
        prod2_GT = 1
        for i in range(self.assump_size + 1):
            prod_H = 1
            prod_G = 1
            for node in nodes:
                attr = node.getAttributeAndIndex()
                attr_stripped = self.util.strip_index(attr)  # no need, re-use not allowed
		prod_H *= key['K'][attr][i]
		prod_G *= ctxt['C'][attr_stripped][i]
	    prod1_GT *= pair(prod_H, ctxt['C_0'][i])
            prod2_GT *= pair(prod_G, key['K_0'][i])
	    #Cp = prod2_GT / prod1_GT
	    Cp = prod1_GT / prod2_GT

	sha256 = hashlib.new(self.hash_type)
	sha256.update(self.group.serialize(Cp))
	x = sha256.hexdigest()

        return ctxt['Cp']^(int(x,16))