Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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
Example #6
0
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