def delete2(self, item): """ Delete an item from the filter. To delete an item safely, it must have been previously inserted. Otherwise, deleting a non-inserted item might unintentionally remove a real, different item that happens to share the same fingerprint. :param item: Item to delete from the filter. :return: True, if item is found and deleted; False, otherwise. """ fingerprint = hashutils.fingerprint(item, size=self.fingerprint_size) i = self._get_index(item) j = self._get_alternate1_index(i, fingerprint) x = self._get_alternate2_index(i, fingerprint) y = self._get_alternate3_index(i, fingerprint) if self.buckets[i].delete(fingerprint): return True elif self.buckets[y].delete(fingerprint): return True elif self.buckets[j].delete(fingerprint): return True elif self.buckets[x].delete(fingerprint): return True else: return False
def insert1(self, item): """ Insert an item into the filter. :param item: Item to be inserted. :return: True if insert is successful; CuckooFilterFullException if filter is full. """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) i = self._get_index(item) j = self._get_alternate3_index(i, fingerprint) if self.buckets[i].insert(fingerprint) \ or self.buckets[j].insert(fingerprint): self.size += 1 return True eviction_index = random.choice([i, j]) for _ in range(self.max_displacements): f = self.buckets[eviction_index].swap(fingerprint) eviction_index = self._get_alternate3_index(eviction_index, f) if self.buckets[eviction_index].insert(f): self.size += 1 return True fingerprint = f # 我自己感觉fingerprint没有改变,有问题,然后我加上了这行代码 # Filter is full return self.size
def acf_prune(self, cloud_ctxt, attr_list, c_for_acf): """ this part is set to prune the attr_list with the rho """ acf_prune_list = {} # initialize the acf_prune_list cflist = cloud_ctxt['ACF'] # get the cuckoofilter from the cloud ctxt for attr in attr_list: attr = str(attr) fingerprint = hashutils.fingerprint(attr, self.fingerprint_size) if cuckoofilter.new_antiCollisionFind(cflist, fingerprint): _value = cuckoofilter.new_antigetHiddenItem(cflist, fingerprint) _value = _value.value attr_str = '' row_str = '' for i in range(len(c_for_acf)): bit = int(list(c_for_acf)[i]) ^ int(list(_value)[i]) if i <= 31: attr_str += str(bit) if i >= 32: row_str += str(bit) attr_str = str(int(attr_str, 2)) # convert binary string attr_str to string row_str = int(row_str, 2) # convert binary string row_str to int acf_prune_list[attr_str] = row_str # recover the part related to attr_list in rho return acf_prune_list
def contains3(self, item, threshold1, threshold2): """ Check if the filter contains the item. :param item: Item to check its presence in the filter. :return: True, if item is in the filter; False, otherwise. """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) if fingerprint >= threshold1 and fingerprint <= threshold2: i = self._get_index(item) j = self._get_alternate1_index(i, fingerprint) x = self._get_alternate2_index(i, fingerprint) y = self._get_alternate3_index(i, fingerprint) if fingerprint in self.buckets[i]: return True elif fingerprint in self.buckets[y]: return True elif fingerprint in self.buckets[j]: return True elif fingerprint in self.buckets[x]: return True else: return False else: i = self._get_index(item) j = self._get_alternate3_index(i, fingerprint) return fingerprint in self.buckets[ i] or fingerprint in self.buckets[j]
def insert(self, item): """ Insert an item into the filter. :param item: Item to be inserted. :return: True if insert is successful; CuckooFilterFullException if filter is full. """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) i = self._get_index(item) j = self._get_alternate_index(i, fingerprint) if self.buckets[i].insert(fingerprint) \ or self.buckets[j].insert(fingerprint): self.size += 1 return True eviction_index = random.choice([i, j]) for _ in range(self.max_displacements): f = self.buckets[eviction_index].swap(fingerprint) eviction_index = self._get_alternate_index(eviction_index, f) if self.buckets[eviction_index].insert(f): self.size += 1 return True # Filter is full raise exceptions.CuckooFilterFullException('Insert operation failed. ' 'Filter is full.')
def contains1(self, item): """ Check if the filter contains the item. :param item: Item to check its presence in the filter. :return: True, if item is in the filter; False, otherwise. """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) i = self._get_index(item) j = self._get_alternate3_index(i, fingerprint) return fingerprint in self.buckets[i] or fingerprint in self.buckets[j]
def acf_decrypt(self, cloud_ctxt, key): """ this part is set to decrypt the C_FOR_ACF """ C3 = cloud_ctxt['C3'] C4 = cloud_ctxt['C4'] K3 = key['KEY_ACF']['K3'] K4 = key['KEY_ACF']['K4'] c_for_acf = pair(C3, K3) / pair(C4, K4) # before using the m_for_acf, we will perform some translation just like we did in encrypt c_for_acf = str(c_for_acf) c_for_acf = hashutils.fingerprint(c_for_acf, 64) c_for_acf = '{:064b}'.format(c_for_acf) return c_for_acf
def getHiddenItem(self, item): """ get HiddenItem object according to item :param item: Item to check its presence in the filter. :return: HiddenItem object. """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) i = self._get_index(item) j = self._get_alternate_index(i, fingerprint) for ele in self.buckets[i].bucket + self.buckets[j].bucket: if fingerprint in ele: return ele return None
def modified_insert(self, item): """ Insert an item into the filter. :param item: Item to be inserted. :return: 1 if without relocating process or 0 if with relocating process """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) i = self._get_index(item) j = self._get_alternate_index(i, fingerprint) if self.buckets[i].insert(fingerprint) \ or self.buckets[j].insert(fingerprint): self.size += 1 return 1 # Necessary for inserting the fingerprint into the next cuckoo filter return 0
def modified_contains(self, item): """ Check if the filter contains the item. :param item: Item to check its presence in the filter. :return: True, if item is in the filter; False, otherwise. """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) i = self._get_index(item) j = self._get_alternate_index(i, fingerprint) for ele in self.buckets[i].bucket + self.buckets[j].bucket: if fingerprint in ele: return True return False
def acf_create(self, rho, c_for_acf): """ this part is set to generate the cuckoofilter which is used for save the encrypted mapping relation """ cfList = [cuckoofilter.CuckooFilter(self.capacity, self.bucketSize, self.fingerprint_size) for i in range(self.maxCFNumber)] # initialize the cuckoofilter # this part is used for inserting the mapping relation into the cuckoofilter for attr, row in rho.items(): # translate the attr and row to the int, because the next step:'{:032b}'.format(x) request a int input attr_str = int(attr) row_str = int(row) attr_str = '{:032b}'.format(attr_str) # set the attr_str'length as 32 row_str = '{:032b}'.format(row_str) # set the row_str'length as 32 attr_row_str = attr_str + row_str # splice attr_str and row_str together value_for_xor = "" # initialize the value_for_xor which is used for saving the result # xor the m_for_xor with the attr_row_str for i in range(len(c_for_acf)): bit = int(list(c_for_acf)[i]) ^ int(list(attr_row_str)[i]) value_for_xor += str(bit) # after xor wo put the result which is value_for_xor into the cuckoofilter fingerprint = hashutils.fingerprint(attr, self.fingerprint_size) cuckoofilter.new_antiCollisionInsert(cfList=cfList, fingerprint=fingerprint, value=value_for_xor) return cfList
def insert3(self, item, threshold1, threshold2): """ Insert an item into the filter. :param item: Item to be inserted. :return: True if insert is successful; CuckooFilterFullException if filter is full. """ # 处于阈值区间则采用4个候选桶进行存储,注意:threshold1不能小于255,threshold2不能大于65280 fingerprint = hashutils.fingerprint(item, self.fingerprint_size) if fingerprint >= threshold1 and fingerprint <= threshold2: i = self._get_index(item) j = self._get_alternate1_index(i, fingerprint) x = self._get_alternate2_index(i, fingerprint) y = self._get_alternate3_index(i, fingerprint) if self.buckets[i].insert(fingerprint): self.size += 1 return True elif self.buckets[y].insert(fingerprint): self.size += 1 return True elif self.buckets[j].insert(fingerprint): self.size += 1 return True elif self.buckets[x].insert(fingerprint): self.size += 1 return True eviction_index = random.choice([i, j, x, y]) for _ in range(self.max_displacements): f = self.buckets[eviction_index].swap(fingerprint) # 若交换得到的指纹值位于阈值区间,则4个桶 if f >= threshold1 and f <= threshold2: eviction_index1 = self._get_alternate1_index( eviction_index, f) eviction_index2 = self._get_alternate2_index( eviction_index, f) eviction_index3 = self._get_alternate3_index( eviction_index, f) if self.buckets[eviction_index3].insert(f): self.size += 1 return True elif self.buckets[eviction_index1].insert(f): self.size += 1 return True elif self.buckets[eviction_index2].insert(f): self.size += 1 return True eviction_index = random.choice( [eviction_index1, eviction_index2, eviction_index3]) fingerprint = f else: eviction_index = self._get_alternate3_index( eviction_index, f) if self.buckets[eviction_index].insert(f): self.size += 1 return True fingerprint = f # Filter is full return self.size # raise exceptions.CuckooFilterFullException('Insert operation failed. ' # 'Filter is full.') # 否则采用2个候选桶存储 else: i = self._get_index(item) j = self._get_alternate3_index(i, fingerprint) if self.buckets[i].insert(fingerprint) \ or self.buckets[j].insert(fingerprint): self.size += 1 return True eviction_index = random.choice([i, j]) for _ in range(self.max_displacements): f = self.buckets[eviction_index].swap(fingerprint) # 如果交换的指纹值位于阈值区间,则扩展到4个桶 if f >= threshold1 and f <= threshold2: eviction_index1 = self._get_alternate1_index( eviction_index, f) eviction_index2 = self._get_alternate2_index( eviction_index, f) eviction_index3 = self._get_alternate3_index( eviction_index, f) if self.buckets[eviction_index3].insert(f): self.size += 1 return True elif self.buckets[eviction_index1].insert(f): self.size += 1 return True elif self.buckets[eviction_index2].insert(f): self.size += 1 return True eviction_index = random.choice( [eviction_index1, eviction_index2, eviction_index3]) fingerprint = f # 否则,还是两个桶 else: eviction_index = self._get_alternate3_index( eviction_index, f) if self.buckets[eviction_index].insert(f): self.size += 1 return True fingerprint = f # Filter is full return self.size
def insert2(self, item): """ Insert an item into the filter. :param item: Item to be inserted. :return: True if insert is successful; CuckooFilterFullException if filter is full. """ fingerprint = hashutils.fingerprint(item, self.fingerprint_size) i = self._get_index(item) j = self._get_alternate1_index(i, fingerprint) x = self._get_alternate2_index(i, fingerprint) y = self._get_alternate3_index(i, fingerprint) if i == j or x: # 候选桶扩展失败 if self.buckets[i].insert(fingerprint) \ or self.buckets[y].insert(fingerprint): self.size += 1 return True if i != j or x: # 候选桶扩展成功 if self.buckets[i].insert(fingerprint): self.size += 1 return True elif self.buckets[y].insert(fingerprint): self.size += 1 return True elif self.buckets[j].insert(fingerprint): self.size += 1 return True elif self.buckets[x].insert(fingerprint): self.size += 1 return True eviction_index = random.choice([i, j, x, y]) for _ in range(self.max_displacements): f = self.buckets[eviction_index].swap(fingerprint) eviction_index1 = self._get_alternate1_index(eviction_index, f) eviction_index2 = self._get_alternate2_index(eviction_index, f) eviction_index3 = self._get_alternate3_index(eviction_index, f) if eviction_index == eviction_index2 or eviction_index1: # 扩展候选桶失败 if self.buckets[eviction_index3].insert(f): self.size += 1 return True eviction_index = eviction_index3 if eviction_index != eviction_index2 or eviction_index1: # 扩展候选桶成功 if self.buckets[eviction_index3].insert(f): self.size += 1 return True elif self.buckets[eviction_index1].insert(f): self.size += 1 return True elif self.buckets[eviction_index2].insert(f): self.size += 1 return True eviction_index = random.choice( [eviction_index1, eviction_index2, eviction_index3]) fingerprint = f # 源码有问题,这一条代码还是得加上,不然导致重复插入初始的fingerprint,查询时会有问题 # Filter is full return self.size
def cipher_update_local(self, public_key, policy_str_new, cipher_for_local): """ this part is set to update the cipher in local """ # get the public_key pk_for_update = public_key # get the old access structure from the cipher_for_local mono_span_prog_old = cipher_for_local['MSP'] rho = cipher_for_local['RHO'] num_cols = cipher_for_local['NUM_COLS'] dic_for_secret = cipher_for_local['DIC_FOR_SECRET'] u = cipher_for_local['U'] # initialize the update components uc_for_cipher = {} uc_for_access_structure = {} # generate the new access structure policy_new = self.util.createPolicy(policy_str_new) mono_span_prog_new = self.util.convert_policy_to_msp(policy_new) num_cols_new = self.util.len_longest_row # compute the interpolation between the num_cols and num_cols_new interpolation = num_cols_new - num_cols # update the list u[] by insert the new_rand at the last of u[] if interpolation > 0: for i in range(interpolation): new_rand = self.group.random(ZR) u.append(new_rand) i_for_row = 0 # using for adding the row number for key_new, value_new in mono_span_prog_new.items(): # generate the cipher component which is type 'alter' if key_new in mono_span_prog_old.keys(): if value_new != mono_span_prog_old[key_new]: len_new = len(value_new) sum_new = 0 for i in range(len_new): sum_new += value_new[i] * u[i] d = sum_new - dic_for_secret[key_new] # component for cipher uc_for_cipher[rho[key_new]] = 'alter', pk_for_update['g1_a'] ** d # component for access structure uc_for_access_structure[rho[key_new]] = 'alter', value_new # generate the cipher component which is type 'insert' if key_new not in mono_span_prog_old.keys(): i_for_row += 1 row = len(rho) + i_for_row # update the row # xor the m_for_acf and attr_row_str attr_row_str = ('{:032b}'.format(int(key_new))) + ('{:032b}'.format(int(row))) c_for_acf = cipher_for_local['C_FOR_ACF'] value_for_xor = '' for i in range(len(c_for_acf)): bit = int(list(c_for_acf)[i]) ^ int(list(attr_row_str)[i]) value_for_xor += str(bit) # compute the value of sum for the new attributes len_new = len(value_new) sum_new = 0 for i in range(len_new): sum_new += value_new[i] * u[i] # perform the encryption algorithm for the attribute which is going to be inserted attr_stripped = self.util.strip_index(key_new) r_attr = self.group.random(ZR) c_attr = (pk_for_update['g1_a'] ** sum_new) / (pk_for_update['h'][int(attr_stripped)] ** r_attr) d_attr = pk_for_update['g2'] ** r_attr # component for cipher uc_for_cipher[row] = 'insert', c_attr, d_attr # component for access structure fingerprint = hashutils.fingerprint(key_new, self.fingerprint_size) uc_for_access_structure[row] = 'insert', value_new, fingerprint, value_for_xor # update the dic_for_secret[] dic_for_secret[key_new] = sum # generate the cipher component which is type 'delete' for key_old, value_old in mono_span_prog_old.items(): if key_old not in mono_span_prog_new.keys(): fingerprint = hashutils.fingerprint(key_old, self.fingerprint_size) # component for cipher uc_for_cipher[rho[key_old]] = 'delete', None # component for access structure uc_for_access_structure[rho[key_old]] = 'delete', fingerprint return {'UC_FOR_CIPHER': uc_for_cipher, 'UC_FOR_ACCESS_STRUCTURE': uc_for_access_structure}
def encrypt(self, pk, msg, policy_str): """ this part is set to encrypt the plaintext and generate the ciphertext """ # the list u[] is used for saving n random numbers, the first ele of u[] is the secret s which we use in LSSS # n is the length of access_matrix's row u = [] if debug: print('Encryption algorithm:\n') # the m_for_acf_encrypt will be used in acf_encrypt as the m_for_acf # m_for_acf_encrypt = self.group.random(GT) # encrypt the m_for_acf by acf_encrypt cipher_for_acf = self.acf_encrypt(pk) C3 = cipher_for_acf['C3'] C4 = cipher_for_acf['C4'] C_FOR_ACF = cipher_for_acf['C_FOR_ACF'] policy = self.util.createPolicy(policy_str) mono_span_prog = self.util.convert_policy_to_msp(policy) num_cols = self.util.len_longest_row # num_cols represent the length of access_matrix's row # generate access structure(access_matrix, rho) access_structure = self.access_structure_create(mono_span_prog) # before xor the m_for_acf and the attr_row_str, translate the m_for_acf_encrypt into string by hash function c_for_acf = str(C_FOR_ACF) c_for_acf = hashutils.fingerprint(c_for_acf, 64) c_for_acf = '{:064b}'.format(c_for_acf) # generate cuckoo_filter by acf_create cflist = self.acf_create(access_structure['rho'], c_for_acf) # pick randomness for i in range(num_cols): rand = self.group.random(ZR) u.append(rand) s = u[0] # the secret s which is going to be shared c0 = pk['g2'] ** s dic_for_secret = {} # encrypt the message by cp-abe scheme C = {} C_FOR_UPLOAD = {} D = {} D_FOR_UPLOAD = {} 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 # this step is hidden the attributes in C[] and D[], change them into the C_FOR_UPLOAD and D_FOR_UPLOAD if attr in access_structure['rho'].keys(): row_in_rho = access_structure['rho'][attr] C_FOR_UPLOAD[row_in_rho] = C[attr] D_FOR_UPLOAD[row_in_rho] = D[attr] # dic_as is used for saving the current secret share value dic_for_secret[attr] = sum c_m = (pk['e_gg_alpha'] ** s) * msg # cipher_for_upload will be uploaded to the cloud cipher_for_upload = {'c0': c0, 'C_FOR_UPLOAD': C_FOR_UPLOAD, 'D_FOR_UPLOAD': D_FOR_UPLOAD, 'c_m': c_m, 'C3': C3, 'C4': C4, 'access_matrix': access_structure['access_matrix'], 'ACF': cflist} # cipher_for_local will be saved in local for policy update cipher_for_local = {'MSP': mono_span_prog, 'RHO': access_structure['rho'], 'NUM_COLS': num_cols, 'DIC_FOR_SECRET': dic_for_secret, 'U': u, 'C_FOR_ACF': c_for_acf} return {'C_U': cipher_for_upload, 'C_L': cipher_for_local}