Esempio n. 1
0
def _decapsulate_reencrypted(receiving_privkey: UmbralPrivateKey,
                             capsule: Capsule,
                             key_length: int = DEM_KEYSIZE) -> bytes:
    """Derive the same symmetric encapsulated_key"""

    params = capsule.params

    pub_key = receiving_privkey.get_pubkey().point_key
    priv_key = receiving_privkey.bn_key

    precursor = capsule._attached_cfrags[0].point_precursor
    dh_point = priv_key * precursor

    # Combination of CFrags via Shamir's Secret Sharing reconstruction
    xs = list()
    for cfrag in capsule._attached_cfrags:
        x = hash_to_curvebn(precursor,
                            pub_key,
                            dh_point,
                            bytes(constants.X_COORDINATE),
                            cfrag.kfrag_id,
                            params=params)
        xs.append(x)

    e_summands, v_summands = list(), list()
    for cfrag, x in zip(capsule._attached_cfrags, xs):
        if precursor != cfrag.point_precursor:
            raise ValueError("Attached CFrags are not pairwise consistent")
        lambda_i = lambda_coeff(x, xs)
        e_summands.append(lambda_i * cfrag.point_e1)
        v_summands.append(lambda_i * cfrag.point_v1)

    e_prime = sum(e_summands[1:], e_summands[0])
    v_prime = sum(v_summands[1:], v_summands[0])

    # Secret value 'd' allows to make Umbral non-interactive
    d = hash_to_curvebn(precursor,
                        pub_key,
                        dh_point,
                        bytes(constants.NON_INTERACTIVE),
                        params=params)

    e, v, s = capsule.components()
    h = hash_to_curvebn(e, v, params=params)

    orig_pub_key = capsule.get_correctness_keys(
    )['delegating'].point_key  # type: ignore

    if not (s / d) * orig_pub_key == (h * e_prime) + v_prime:
        raise GenericUmbralError()

    shared_key = d * (e_prime + v_prime)
    encapsulated_key = kdf(shared_key, key_length)
    return encapsulated_key
Esempio n. 2
0
def _decapsulate_original(private_key: UmbralPrivateKey,
                          capsule: Capsule,
                          key_length: int = DEM_KEYSIZE) -> bytes:
    """Derive the same symmetric key"""

    if not capsule.verify():
        # Check correctness of original ciphertext
        raise capsule.NotValid("Capsule verification failed.")

    shared_key = private_key.bn_key * (capsule.point_e + capsule.point_v
                                       )  # type: Any
    key = kdf(shared_key, key_length)
    return key
Esempio n. 3
0
def test_point_operations():

    vector_file = os.path.join('vectors', 'vectors_point_operations.json')
    try:
        with open(vector_file) as f:
            vector_suite = json.load(f)
    except OSError:
        raise

    point1 = Point.from_bytes(
        bytes.fromhex(vector_suite['first Point operand']))
    point2 = Point.from_bytes(
        bytes.fromhex(vector_suite['second Point operand']))
    bn1 = CurveBN.from_bytes(bytes.fromhex(vector_suite['CurveBN operand']))

    expected = dict()
    for op_result in vector_suite['vectors']:
        expected[op_result['operation']] = bytes.fromhex(op_result['result'])

    test = [
        ('Addition', point1 + point2),
        ('Subtraction', point1 - point2),
        ('Multiplication', bn1 * point1),
        ('Inversion', -point1),
    ]

    for (operation, result) in test:
        assert result == Point.from_bytes(
            expected[operation]), 'Error in {}'.format(operation)

    test = [
        ('To_affine.X', point1.to_affine()[0]),
        ('To_affine.Y', point1.to_affine()[1]),
    ]

    for (operation, result) in test:
        assert result == int.from_bytes(expected[operation],
                                        'big'), 'Error in {}'.format(operation)

    assert kdf(point1, pre.DEM_KEYSIZE) == expected['kdf']
Esempio n. 4
0
def _encapsulate(alice_pubkey: UmbralPublicKey,
                 key_length: int = DEM_KEYSIZE) -> Tuple[bytes, Capsule]:
    """Generates a symmetric key and its associated KEM ciphertext"""

    params = alice_pubkey.params
    g = params.g

    priv_r = CurveBN.gen_rand(params.curve)
    pub_r = priv_r * g  # type: Any

    priv_u = CurveBN.gen_rand(params.curve)
    pub_u = priv_u * g  # type: Any

    h = hash_to_curvebn(pub_r, pub_u, params=params)
    s = priv_u + (priv_r * h)

    shared_key = (priv_r + priv_u) * alice_pubkey.point_key  # type: Any

    # Key to be used for symmetric encryption
    key = kdf(shared_key, key_length)

    return key, Capsule(point_e=pub_r, point_v=pub_u, bn_sig=s, params=params)
Esempio n. 5
0
##########
# Points #
##########

point1 = Point.gen_rand(curve)
point2 = Point.gen_rand(curve)

# Expected results for some Point operations
expected = [('Addition', point1 + point2),
            ('Subtraction', point1 - point2),
            ('Multiplication', bn1 * point1),
            ('Inversion', -point1),
            ('To_affine.X', point1.to_affine()[0]),
            ('To_affine.Y', point1.to_affine()[1]),
            ('kdf', kdf(point1, pre.DEM_KEYSIZE)),
            ]

expected = [{'operation': op, 'result': hexlify(result)} for (op, result) in expected]

# Definition of test vector
vector_suite = {
    'name': 'Test vectors for Point operations',
    'params': 'default',
    'first Point operand': hexlify(point1),
    'second Point operand': hexlify(point2),
    'CurveBN operand': hexlify(bn1),
    'vectors': expected
}

json_file = 'vectors_point_operations.json'