def sym_key_gen(pairing_group=None, sym_key_size=None, debug=0): """ Generate a random symmetric key with given size. :param pairing_group: pairing group which the symmetric key is generated from :param sym_key_size: length in bytes of the symmetric key :param debug: if 1, prints will be shown during execution; default 0, no prints are shown :return: the randomly generated symmetric key """ # If sym_key_size is not defined, set a default value if sym_key_size is None: sym_key_size = SYM_KEY_DEFAULT_SIZE # Clamp the size between SYM_KEY_MIN_SIZE and the system maximum possible value size = clamp(sym_key_size, SYM_KEY_MIN_SIZE, sys.maxsize) # Check if an error occurred during clamping if size is None: logging.error('sym_key_gen clamp size exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_key_gen clamp size') raise Exception # Check if size is a power of 2 if not math.log2(size).is_integer(): logging.error('sym_key_gen size exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in sym_key_gen size') raise Exception # Generate and return a random symmetric key with the given size return random_string_gen(pairing_group, sym_key_size)
def iv_gen(iv_length=const.IV_DEFAULT_SIZE, debug=0): """ Generate an initialisation vector (IV) with the given length. :param iv_length: length in bytes of the IV :param debug: if 1, # prints will be shown during execution; default 0, no # prints are shown :return: the randomly generated IV """ # Clamp the size between IV_DEFAULT_SIZE and the system maximum possible value length = fu.clamp(iv_length, const.IV_DEFAULT_SIZE, const.IV_MAX_SIZE) # Check if an error occurred during clamping if length is None: logging.error('generate_iv clamp length exception') # if debug: # ONLY USE FOR DEBUG # print('EXCEPTION in generate_iv clamp length') raise Exception # Check if length is a power of 2 if not math.log2(length).is_integer(): logging.error('generate_iv length exception') # if debug: # ONLY USE FOR DEBUG # print('EXCEPTION in generate_iv length') raise Exception # Generate and return a random IV with the given length return fu.generate_random_bytes(iv_length, debug)
def key_gen(sym_key_size=const.SYM_KEY_DEFAULT_SIZE, debug=0): """ Generate a random symmetric key with given size. :param sym_key_size: length in bytes of the symmetric key :param debug: if 1, # prints will be shown during execution; default 0, no # prints are shown :return: the randomly generated symmetric key """ # Clamp the size between SYM_KEY_MIN_SIZE and the system maximum possible value size = fu.clamp(sym_key_size, const.SYM_KEY_MIN_SIZE, sys.maxsize) # Check if an error occurred during clamping if size is None: logging.error('sym_key_gen clamp size exception') # if debug: # ONLY USE FOR DEBUG # print('EXCEPTION in sym_key_gen clamp size') raise Exception # Check if size is a power of 2 if not math.log2(size).is_integer(): logging.error('sym_key_gen size exception') # if debug: # ONLY USE FOR DEBUG # print('EXCEPTION in sym_key_gen size') raise Exception # Generate and return a random symmetric key with the given size return fu.generate_random_bytes(size, debug)
def generate_iv(iv_length=None, debug=0): """ Generate an initialisation vector (IV) with the given length. :param iv_length: length in bytes of the IV :param debug: if 1, prints will be shown during execution; default 0, no prints are shown :return: the randomly generated IV """ # If iv_length is not defined, set a default value if iv_length is None: iv_length = IV_DEFAULT_SIZE # Clamp the size between IV_DEFAULT_SIZE and the system maximum possible value length = clamp(iv_length, IV_DEFAULT_SIZE, sys.maxsize) # Check if an error occurred during clamping if length is None: logging.error('generate_iv clamp length exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in generate_iv clamp length') raise Exception # Check if length is a power of 2 if not math.log2(length).is_integer(): logging.error('generate_iv length exception') if debug: # ONLY USE FOR DEBUG print('EXCEPTION in generate_iv length') raise Exception # Generate and return a random IV with the given length return generate_random_string(iv_length, debug)
def update_re_enc_infos(metafile, re_enc_length, pk, policy, debug=0): """ Update re-encryption infos contained in the metadata file adding parameters related to the latest re-encryption operation. :param metafile: metadata file where re-encryption parameters will be saved :param re_enc_length: number of bytes to re-encrypt :param pk: public key to encrypt re-encryption parameters :param policy: policy to apply to the encryption :param debug: if 1, prints will be shown during execution; default 0, no prints are shown :return: re-encryption parameters """ # Read metadata and update with new re-encryption infos with open(metafile, 'r+') as f: metadata = json.load(f) # Retrieve re-encryption parameters chunk_size = metadata[const.CHUNK_SIZE] # Generate re-encryption parameters seed = None seed_pg_elem = None if re_enc_length < chunk_size: seed, seed_pg_elem = pg.random_string_gen(pairing_group, const.SEED_LENGTH) key, key_pg_elem = pg.sym_key_gen(pairing_group, const.SYM_KEY_DEFAULT_SIZE, debug) iv = sym.iv_gen(const.IV_DEFAULT_SIZE, debug) # Clamp the number of bytes to re-encrypt between RE_ENC_MIN_LENGTH and the chunk size re_enc_length = fu.clamp(re_enc_length, const.RE_ENC_MIN_LENGTH, chunk_size, debug) if debug: # ONLY USE FOR DEBUG print('\nCHUNK SIZE = %d' % chunk_size) if seed: print('SEED = (%d) %s' % (len(seed), seed)) print('SEED PG ELEM = (%s) %s' % (type(seed_pg_elem), seed_pg_elem)) else: print('SEED =', seed) print('SEED PG ELEM =', seed_pg_elem) print('KEY = (%d) %s' % (len(key), key)) print('KEY PG ELEM = (%s) %s' % (type(key_pg_elem), key_pg_elem)) print('IV = (%d) %s' % (len(iv), iv)) print('RE-ENC LEN =', re_enc_length) # Prepare re-encryption parameters to write on the metadata file enc_seed = objectToBytes( abe.encrypt(seed_pg_elem, pairing_group, bytesToObject(pk, pairing_group), policy, debug), pairing_group) if seed is not None else seed enc_key = objectToBytes( abe.encrypt(key_pg_elem, pairing_group, bytesToObject(pk, pairing_group), policy, debug), pairing_group) if debug: # ONLY USE FOR DEBUG if enc_seed: print('ENC SEED = (%d) %s' % (len(enc_seed), enc_seed)) else: print('ENC SEED =', enc_seed) print('ENC KEY = (%d) %s' % (len(enc_key), enc_key)) # Add re-encryption informations to metadata file metadata['re_encs'].append({ 'pk': hashlib.sha256(pk).hexdigest(), # SHA256 of public key as hex 'policy': policy, 'enc_seed': hexlify(enc_seed).decode() if enc_seed is not None else enc_seed, 'enc_key': hexlify(enc_key).decode(), 'iv': hexlify(iv).decode(), 're_enc_length': re_enc_length }) if debug: # ONLY USE FOR DEBUG print('METADATA =', metadata) # Overwrite metadata file f.seek(0) json.dump(metadata, f) return seed, key, iv, chunk_size, re_enc_length
def update_re_enc_info(metafile, re_enc_params, debug=0): """ Update re-encryption info contained in the metadata file adding parameters related to the latest re-encryption operation. :param metafile: metadata file where re-encryption parameters will be saved :param re_enc_params: re-encryption parameters :param debug: if 1, prints will be shown during execution; default 0, no prints are shown :return: re-encryption parameters """ # Read metadata and update with new re-encryption info with open(metafile, 'r+') as f: metadata = json.load(f) # Retrieve re-encryption parameters chunk_size = metadata[const.CHUNK_SIZE] pairing_group = re_enc_params['pairing_group'] pk = re_enc_params['pk'] policy = re_enc_params['policy'] re_enc_length = re_enc_params['re_enc_length'] seed = re_enc_params['seed'] key = re_enc_params['key'] root_iv = re_enc_params['iv'] re_encs_num = re_enc_params['re_encs_num'] # Clamp the number of bytes to re-encrypt between RE_ENC_MIN_LENGTH and the chunk size re_enc_length = fu.clamp(re_enc_length, const.RE_ENC_MIN_LENGTH, chunk_size, debug) iv = fu.hash_chain(root_iv, re_encs_num) if debug: # ONLY USE FOR DEBUG print('CHUNK SIZE = %d' % chunk_size) print('SEED = (%s) %s' % (type(seed), seed)) print('KEY = (%s) %s' % (type(key), key)) print('ROOT_IV = (%d) %s' % (len(root_iv), root_iv)) print('IV = (%d) %s' % (len(iv), iv)) print('RE-ENC LEN =', re_enc_length) print('RE-ENC NUM =', re_encs_num) # Prepare re-encryption parameters to write on the metadata file enc_seed = objectToBytes( abe.encrypt(seed, pairing_group, bytesToObject(pk, pairing_group), policy, debug), pairing_group) enc_key = objectToBytes( abe.encrypt(key, pairing_group, bytesToObject(pk, pairing_group), policy, debug), pairing_group) if debug: # ONLY USE FOR DEBUG print('ENC SEED = (%d) %s' % (len(enc_seed), enc_seed)) print('ENC KEY = (%d) %s' % (len(enc_key), enc_key)) # Create re-encryption information re_enc_info = { 'pk': hashlib.sha256(pk).hexdigest(), # SHA256 of public key as hex 'policy': policy, 'enc_seed': hexlify(enc_seed).decode(), 'enc_key': hexlify(enc_key).decode(), 'iv': hexlify(root_iv).decode(), 're_enc_length': re_enc_length, 're_encs_num': re_encs_num + 1 } # Add re-encryption informations to metadata file if len(metadata['re_encs']) > 0: metadata['re_encs'][0] = re_enc_info else: metadata['re_encs'].append(re_enc_info) if debug: # ONLY USE FOR DEBUG print('METADATA =', metadata) # Overwrite metadata file f.seek(0) json.dump(metadata, f) f.truncate() return objectToBytes(seed, pairing_group)[: const.SEED_LENGTH], \ objectToBytes(key, pairing_group)[: const.SYM_KEY_DEFAULT_SIZE], iv, chunk_size, re_enc_length