Ejemplo n.º 1
0
def test_cheating_ursula_replays_old_reencryption(N, M):
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key)
    sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key)

    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    cfrags, metadata = [], []
    for i, kfrag in enumerate(kfrags):

        # Example of potential metadata to describe the re-encryption request
        metadata_i = "This is an example of metadata for re-encryption request #{}"
        metadata_i = metadata_i.format(i).encode()

        if i == 0:
            # Let's put the re-encryption of a different Alice ciphertext
            cfrag = pre.reencrypt(kfrag, capsule_alice2, metadata=metadata_i)
        else:
            cfrag = pre.reencrypt(kfrag, capsule_alice1, metadata=metadata_i)

        capsule_alice1.attach_cfrag(cfrag)

        cfrags.append(cfrag)

    # Let's activate the capsule
    capsule_alice1._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob)

    with pytest.raises(pre.GenericUmbralError):
        sym_key = pre._decapsulate_reencrypted(pub_key_bob.point_key,
                                               priv_key_bob.bn_key,
                                               pub_key_alice.point_key,
                                               capsule_alice1)

    assert not cfrags[0].verify_correctness(
        capsule_alice1,
        pub_key_alice,
        pub_key_bob,
    )

    # The response of cheating Ursula is in cfrags[0],
    # so the rest of CFrags should be correct:
    for cfrag_i, metadata_i in zip(cfrags[1:], metadata[1:]):
        assert cfrag_i.verify_correctness(
            capsule_alice1,
            pub_key_alice,
            pub_key_bob,
        )

    # Alternatively, we can try to open the capsule directly.
    # We should get an exception with an attached list of incorrect cfrags
    with pytest.raises(pre.UmbralCorrectnessError) as exception_info:
        _ = pre._open_capsule(capsule_alice1, priv_key_bob, pub_key_alice)
    correctness_error = exception_info.value
    assert cfrags[0] in correctness_error.offending_cfrags
    assert len(correctness_error.offending_cfrags) == 1
Ejemplo n.º 2
0
def test_cheating_ursula_replays_old_reencryption(N, M):
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key)
    sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key)

    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    cfrags, challenges = [], []
    for index, kfrag in enumerate(kfrags):
        if index == 0:
            # Let's put the re-encryption of a different Alice ciphertext
            cfrag = pre.reencrypt(kfrag, capsule_alice2)
        else:
            cfrag = pre.reencrypt(kfrag, capsule_alice1)

        metadata = ("Challenge metadata: index {}".format(index)).encode()

        challenge = pre._challenge(kfrag, capsule_alice1, cfrag, metadata)
        capsule_alice1.attach_cfrag(cfrag)

        challenges.append(challenge)
        cfrags.append(cfrag)

    # Let's activate the capsule
    capsule_alice1._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob)    

    with pytest.raises(pre.GenericUmbralError):
        sym_key = pre._decapsulate_reencrypted(pub_key_bob.point_key,
                                              priv_key_bob.bn_key,
                                              pub_key_alice.point_key,
                                              capsule_alice1)

    metadata = b"Challenge metadata: index 0"

    assert not pre._check_challenge(capsule_alice1,
                                   cfrags[0],
                                   challenges[0],
                                   pub_key_alice.point_key,
                                   pub_key_bob.point_key,
                                   metadata
                                   )

    # The response of cheating Ursula is in capsules[0],
    # so the rest of challenges chould be correct:
    for i, challenge in enumerate(challenges[1:], 1):
        cfrag = cfrags[i]
        metadata = ("Challenge metadata: index {}".format(i)).encode()
        assert pre._check_challenge(capsule_alice1,
                                   cfrag,
                                   challenge,
                                   pub_key_alice.point_key,
                                   pub_key_bob.point_key,
                                   metadata
                                   )
Ejemplo n.º 3
0
def test_cheating_ursula_replays_old_reencryption(N, M):
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key)
    sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key)

    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    cfrags, challenges, metadata = [], [], []
    for i, kfrag in enumerate(kfrags):
        if i == 0:
            # Let's put the re-encryption of a different Alice ciphertext
            cfrag = pre.reencrypt(kfrag, capsule_alice2)
        else:
            cfrag = pre.reencrypt(kfrag, capsule_alice1)

        # Example of potential metadata to describe the challenge request
        metadata_i = {
            'ursula_id': i,
            'timestamp': time.time(),
            'capsule': bytes(capsule_alice1),
            'cfrag': bytes(cfrag)
        }

        metadata.append(str(metadata_i).encode())

        challenge = pre._challenge(kfrag, capsule_alice1, cfrag, metadata[i])
        capsule_alice1.attach_cfrag(cfrag)

        challenges.append(challenge)
        cfrags.append(cfrag)

    # Let's activate the capsule
    capsule_alice1._reconstruct_shamirs_secret(pub_key_alice, priv_key_bob)

    with pytest.raises(pre.GenericUmbralError):
        sym_key = pre._decapsulate_reencrypted(pub_key_bob.point_key,
                                               priv_key_bob.bn_key,
                                               pub_key_alice.point_key,
                                               capsule_alice1)

    assert not pre._check_challenge(capsule_alice1, cfrags[0], challenges[0],
                                    pub_key_alice.point_key,
                                    pub_key_bob.point_key, metadata[0])

    # The response of cheating Ursula is in capsules[0],
    # so the rest of challenges should be correct:
    for i, challenge in enumerate(challenges[1:], 1):
        cfrag = cfrags[i]

        assert pre._check_challenge(capsule_alice1, cfrag, challenge,
                                    pub_key_alice.point_key,
                                    pub_key_bob.point_key, metadata[i])
Ejemplo n.º 4
0
def test_cheating_ursula_replays_old_reencryption(N, M):
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    sym_key_alice1, capsule_alice1 = pre._encapsulate(pub_key_alice.point_key)
    sym_key_alice2, capsule_alice2 = pre._encapsulate(pub_key_alice.point_key)

    k_frags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    c_frags, challenges = [], []
    for index, k_frag in enumerate(k_frags):
        if index == 0:
            # Let's put the re-encryption of a different Alice ciphertext
            c_frag = pre.reencrypt(k_frag, capsule_alice2)
        else:
            c_frag = pre.reencrypt(k_frag, capsule_alice1)

        challenge = pre.challenge(k_frag, capsule_alice1, c_frag)
        capsule_alice1.attach_cfrag(c_frag)

        challenges.append(challenge)
        c_frags.append(c_frag)

    capsule_alice1._reconstruct_shamirs_secret()  # activate capsule

    with pytest.raises(pre.GenericUmbralError):
        sym_key = pre.decapsulate_reencrypted(pub_key_bob.point_key,
                                              priv_key_bob.bn_key,
                                              pub_key_alice.point_key,
                                              capsule_alice1)
        assert not sym_key == sym_key_alice1

        assert not pre.check_challenge(
            capsule_alice1,
            c_frags[0],
            challenges[0],
            pub_key_alice.point_key,
            pub_key_bob.point_key,
        )

        # The response of cheating Ursula is in capsules[0],
        # so the rest of challenges chould be correct:
        for (c_frag, ch) in zip(c_frags[1:], challenges[1:]):
            assert pre.check_challenge(
                capsule_alice1,
                c_frag,
                ch,
                pub_key_alice.point_key,
                pub_key_bob.point_key,
            )
Ejemplo n.º 5
0
def test_cfrag_serialization_with_proof_but_no_metadata(alices_keys):
    priv_key_alice, pub_key_alice = alices_keys

    _unused_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_alice, 1, 2)

    cfrag = pre.reencrypt(kfrags[0], capsule, provide_proof=True)
    cfrag_bytes = cfrag.to_bytes()

    proof = cfrag.proof
    assert proof is not None
    assert proof.metadata is None

    # A CFrag can be represented as the 131 total bytes of three Points (33 each) and a CurveBN (32).
    # TODO: Figure out final size for CFrags with proofs
    #assert len(cfrag_bytes) == 33 + 33 + 33 + 32 == 131

    new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
    assert new_cfrag._point_e1 == cfrag._point_e1
    assert new_cfrag._point_v1 == cfrag._point_v1
    assert new_cfrag._bn_kfrag_id == cfrag._bn_kfrag_id
    assert new_cfrag._point_noninteractive == cfrag._point_noninteractive

    new_proof = new_cfrag.proof
    assert new_proof is not None
    assert new_proof._point_e2 == proof._point_e2
    assert new_proof._point_v2 == proof._point_v2
    assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
    assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
    assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1
    assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2
    assert new_proof._bn_sig == proof._bn_sig
    assert new_proof.metadata is None
Ejemplo n.º 6
0
def test_correctness_proof_serialization(alices_keys):
    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()
    signer = Signer(signing_privkey)

    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    params = delegating_privkey.params

    _unused_key, capsule = pre._encapsulate(delegating_pubkey)
    kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, 1, 2)

    # Example of potential metadata to describe the re-encryption request
    metadata = b"This is an example of metadata for re-encryption request"

    cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)
    proof = cfrag.proof
    proof_bytes = proof.to_bytes()

    # A CorrectnessProof can be represented as
    # the 228 total bytes of four Points (33 each) and three BigNums (32 each).
    # TODO: Figure out final size for CorrectnessProofs
    # assert len(proof_bytes) == (33 * 4) + (32 * 3) == 228

    new_proof = CorrectnessProof.from_bytes(proof_bytes)
    assert new_proof._point_e2 == proof._point_e2
    assert new_proof._point_v2 == proof._point_v2
    assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
    assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
    assert new_proof.bn_sig == proof.bn_sig
    assert new_proof.kfrag_signature == proof.kfrag_signature
    assert new_proof.metadata == proof.metadata
Ejemplo n.º 7
0
def test_challenge_response_serialization():
    priv_key = pre.gen_priv()
    pub_key = pre.priv2pub(priv_key)

    _unused_key, capsule = pre._encapsulate(pub_key)
    kfrags = pre.split_rekey(priv_key, pub_key, 1, 2)

    cfrag = pre.reencrypt(kfrags[0], capsule)

    capsule.attach_cfrag(cfrag)
    ch_resp = pre.challenge(kfrags[0], capsule, cfrag)

    ch_resp_bytes = ch_resp.to_bytes()

    # A ChallengeResponse can be represented as
    # the 228 total bytes of four Points (33 each) and three BigNums (32 each).
    assert len(ch_resp_bytes) == (33 * 4) + (32 * 3) == 228

    new_ch_resp = pre.ChallengeResponse.from_bytes(ch_resp_bytes)
    assert new_ch_resp.point_eph_e2 == ch_resp.point_eph_e2
    assert new_ch_resp.point_eph_v2 == ch_resp.point_eph_v2
    assert new_ch_resp.point_kfrag_commitment == ch_resp.point_kfrag_commitment
    assert new_ch_resp.point_kfrag_pok == ch_resp.point_kfrag_pok
    assert new_ch_resp.bn_kfrag_sig1 == ch_resp.bn_kfrag_sig1
    assert new_ch_resp.bn_kfrag_sig2 == ch_resp.bn_kfrag_sig2
    assert new_ch_resp.bn_sig == ch_resp.bn_sig
Ejemplo n.º 8
0
def test_capsule_serialization(alices_keys):
    priv_key_alice, pub_key_alice = alices_keys

    _symmetric_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    capsule_bytes = capsule.to_bytes()
    capsule_bytes_casted = bytes(capsule)
    assert capsule_bytes == capsule_bytes_casted

    # A Capsule can be represented as the 98 total bytes of two Points (33 each) and a BigNum (32).
    assert len(capsule_bytes) == 33 + 33 + 32 == 98

    new_capsule = pre.Capsule.from_bytes(capsule_bytes)

    # Three ways to think about equality.
    # First, the public approach for the Capsule.  Simply:
    assert new_capsule == capsule

    # Second, we show that the original components (which is all we have here since we haven't activated) are the same:
    assert new_capsule.original_components() == capsule.original_components()

    # Third, we can directly compare the private original component attributes
    # (though this is not a supported approach):
    assert new_capsule._point_eph_e == capsule._point_eph_e
    assert new_capsule._point_eph_v == capsule._point_eph_v
    assert new_capsule._bn_sig == capsule._bn_sig
Ejemplo n.º 9
0
def test_correctness_proof_serialization():
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    _unused_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, 1, 2)

    # Example of potential metadata to describe the re-encryption request
    metadata = b"This is an example of metadata for re-encryption request"

    cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)

    capsule.attach_cfrag(cfrag)

    proof = cfrag.proof
    proof_bytes = proof.to_bytes()

    # A CorrectnessProof can be represented as
    # the 228 total bytes of four Points (33 each) and three BigNums (32 each).
    # TODO: Figure out final size for CorrectnessProofs
    # assert len(proof_bytes) == (33 * 4) + (32 * 3) == 228

    new_proof = CorrectnessProof.from_bytes(proof_bytes)
    assert new_proof._point_e2 == proof._point_e2
    assert new_proof._point_v2 == proof._point_v2
    assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
    assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
    assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1
    assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2
    assert new_proof._bn_sig == proof._bn_sig
    assert new_proof.metadata == proof.metadata
Ejemplo n.º 10
0
def test_cheating_ursula_sends_garbage(N, M):
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    # Bob
    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    sym_key, capsule_alice = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    cfrags, metadata = [], []
    for i, kfrag in enumerate(kfrags[:M]):

        # Example of potential metadata to describe the re-encryption request
        metadata_i = "This is an example of metadata for re-encryption request #{}"
        metadata_i = metadata_i.format(i).encode()

        cfrag = pre.reencrypt(kfrag, capsule_alice, metadata=metadata_i)

        capsule_alice.attach_cfrag(cfrag)
        cfrags.append(cfrag)

    # Let's put random garbage in one of the cfrags
    cfrags[0]._point_e1 = Point.gen_rand()
    cfrags[0]._point_v1 = Point.gen_rand()

    capsule_alice._reconstruct_shamirs_secret(pub_key_alice,
                                              priv_key_bob)  # activate capsule

    with pytest.raises(pre.GenericUmbralError):
        _unused_key = pre._decapsulate_reencrypted(pub_key_bob.point_key,
                                                   priv_key_bob.bn_key,
                                                   pub_key_alice.point_key,
                                                   capsule_alice)

    assert not pre._verify_correctness(
        capsule_alice,
        cfrags[0],
        pub_key_alice.point_key,
        pub_key_bob.point_key,
    )

    # The response of cheating Ursula is in cfrags[0],
    # so the rest of CFrags chould be correct:
    for cfrag_i, metadata_i in zip(cfrags[1:], metadata[1:]):
        assert pre._verify_correctness(
            capsule_alice,
            cfrag_i,
            pub_key_alice.point_key,
            pub_key_bob.point_key,
        )

    # Alternatively, we can try to open the capsule directly.
    # We should get an exception with an attached list of incorrect cfrags
    with pytest.raises(pre.UmbralCorrectnessError) as exception_info:
        _ = pre._open_capsule(capsule_alice, priv_key_bob, pub_key_alice)
    correctness_error = exception_info.value
    assert cfrags[0] in correctness_error.offending_cfrags
    assert len(correctness_error.offending_cfrags) == 1
Ejemplo n.º 11
0
def test_cheating_ursula_sends_garbage(N, M):
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    # Bob
    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    sym_key, capsule_alice = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    cfrags, challenges, metadata = [], [], []
    for i, kfrag in enumerate(kfrags[:M]):
        cfrag = pre.reencrypt(kfrag, capsule_alice)

        # Example of potential metadata to describe the challenge request
        metadata_i = {
            'ursula_id': i,
            'timestamp': time.time(),
            'capsule': bytes(capsule_alice),
            'cfrag': bytes(cfrag)
        }

        metadata_i = str(metadata_i).encode()
        metadata.append(metadata_i)

        challenge = pre._challenge(kfrag, capsule_alice, cfrag, metadata_i)
        capsule_alice.attach_cfrag(cfrag)

        assert pre._check_challenge(capsule_alice, cfrag, challenge,
                                    pub_key_alice.point_key,
                                    pub_key_bob.point_key, metadata_i)

        cfrags.append(cfrag)
        challenges.append(challenge)

    # Let's put random garbage in one of the cfrags
    cfrags[0].point_eph_e1 = Point.gen_rand()
    cfrags[0].point_eph_v1 = Point.gen_rand()

    capsule_alice._reconstruct_shamirs_secret(pub_key_alice,
                                              priv_key_bob)  # activate capsule

    with pytest.raises(pre.GenericUmbralError):
        sym_key2 = pre._decapsulate_reencrypted(pub_key_bob.point_key,
                                                priv_key_bob.bn_key,
                                                pub_key_alice.point_key,
                                                capsule_alice)

    assert not pre._check_challenge(capsule_alice, cfrags[0], challenges[0],
                                    pub_key_alice.point_key,
                                    pub_key_bob.point_key, metadata[0])

    # The response of cheating Ursula is in capsules[0],
    # so the rest of challenges chould be correct:
    for i, challenge in enumerate(challenges[1:], 1):
        cfrag = cfrags[i]
        assert pre._check_challenge(capsule_alice, cfrag, challenge,
                                    pub_key_alice.point_key,
                                    pub_key_bob.point_key, metadata[i])
Ejemplo n.º 12
0
def test_capsule_serialization(alices_keys):
    delegating_privkey, _signing_privkey = alices_keys
    params = delegating_privkey.params

    _symmetric_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey())
    capsule_bytes = capsule.to_bytes()
    capsule_bytes_casted = bytes(capsule)
    assert capsule_bytes == capsule_bytes_casted

    # A Capsule can be represented as the 98 total bytes of two Points (33 each) and a CurveBN (32).
    assert len(capsule_bytes) == pre.Capsule.expected_bytes_length()

    new_capsule = pre.Capsule.from_bytes(capsule_bytes, params)

    # Three ways to think about equality.
    # First, the public approach for the Capsule.  Simply:
    assert new_capsule == capsule

    # Second, we show that the original components (which is all we have here since we haven't activated) are the same:
    assert new_capsule.original_components() == capsule.original_components()

    # Third, we can directly compare the private original component attributes
    # (though this is not a supported approach):
    assert new_capsule._point_e == capsule._point_e
    assert new_capsule._point_v == capsule._point_v
    assert new_capsule._bn_sig == capsule._bn_sig
Ejemplo n.º 13
0
def test_m_of_n(N, M, alices_keys, bobs_keys):
    priv_key_alice, pub_key_alice = alices_keys
    priv_key_bob, pub_key_bob = bobs_keys

    sym_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    for kfrag in kfrags:
        assert kfrag.verify(pub_key_alice.point_key, pub_key_bob.point_key)

    for kfrag in kfrags[:M]:
        cfrag = pre.reencrypt(kfrag, capsule)
        capsule.attach_cfrag(cfrag)
        ch = pre.challenge(kfrag, capsule, cfrag)
        assert pre.check_challenge(capsule, cfrag, ch, pub_key_alice.point_key,
                                   pub_key_bob.point_key)

    # assert capsule.is_openable_by_bob()  # TODO: Is it possible to check here if >= m cFrags have been attached?
    # capsule.open(pub_bob, priv_bob, pub_alice)

    capsule._reconstruct_shamirs_secret()
    sym_key_from_capsule = pre.decapsulate_reencrypted(pub_key_bob.point_key,
                                                       priv_key_bob.bn_key,
                                                       pub_key_alice.point_key,
                                                       capsule)
    assert sym_key == sym_key_from_capsule
Ejemplo n.º 14
0
def test_activated_capsule_serialization():
    priv_key = pre.gen_priv()
    pub_key = pre.priv2pub(priv_key)

    _unused_key, capsule = pre._encapsulate(pub_key)
    kfrags = pre.split_rekey(priv_key, pub_key, 1, 2)

    cfrag = pre.reencrypt(kfrags[0], capsule)

    capsule.attach_cfrag(cfrag)

    capsule._reconstruct_shamirs_secret()
    rec_capsule_bytes = capsule.to_bytes()

    # An activated Capsule is:
    # three points, representable as 33 bytes each (the original), and
    # two points and a bignum (32 bytes) (the activated components), for 197 total.
    assert len(rec_capsule_bytes) == (33 * 3) + (33 + 33 + 32)

    new_rec_capsule = pre.Capsule.from_bytes(rec_capsule_bytes)

    # Again, the same three perspectives on equality.
    assert new_rec_capsule == capsule

    assert new_rec_capsule.activated_components(
    ) == capsule.activated_components()

    assert new_rec_capsule._point_eph_e_prime == capsule._point_eph_e_prime
    assert new_rec_capsule._point_eph_v_prime == capsule._point_eph_v_prime
    assert new_rec_capsule._point_noninteractive == capsule._point_noninteractive
Ejemplo n.º 15
0
def test_m_of_n(N, M, alices_keys, bobs_keys):
    priv_key_alice, pub_key_alice = alices_keys
    priv_key_bob, pub_key_bob = bobs_keys

    sym_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    for kfrag in kfrags:
        assert kfrag.verify(pub_key_alice.point_key, pub_key_bob.point_key)

    for i, kfrag in enumerate(kfrags[:M]):

        # Example of potential metadata to describe the re-encryption request
        metadata = "This is an example of metadata for re-encryption request #{}"
        metadata = metadata.format(i).encode()

        cfrag = pre.reencrypt(kfrag, capsule, metadata=metadata)
        capsule.attach_cfrag(cfrag)

        assert pre._verify_correctness(
            capsule,
            cfrag,
            pub_key_alice.point_key,
            pub_key_bob.point_key,
        )

    # assert capsule.is_openable_by_bob()  # TODO: Is it possible to check here if >= m cFrags have been attached?

    sym_key_from_capsule = pre._open_capsule(capsule, priv_key_bob,
                                             pub_key_alice)
    assert sym_key == sym_key_from_capsule
Ejemplo n.º 16
0
def test_m_of_n(N, M, alices_keys, bobs_keys):
    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()
    signer = Signer(signing_privkey)

    priv_key_bob, pub_key_bob = bobs_keys

    params = delegating_privkey.params

    sym_key, capsule = pre._encapsulate(delegating_pubkey)

    capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
                                 receiving=pub_key_bob,
                                 verifying=signing_privkey.get_pubkey())

    kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, M, N)

    for kfrag in kfrags:
        assert kfrag.verify(signing_privkey.get_pubkey(), delegating_privkey.get_pubkey(), pub_key_bob)

    for i, kfrag in enumerate(kfrags[:M]):
        # Example of potential metadata to describe the re-encryption request
        metadata = "This is an example of metadata for re-encryption request #{}"
        metadata = metadata.format(i).encode()

        cfrag = pre.reencrypt(kfrag, capsule, metadata=metadata)
        capsule.attach_cfrag(cfrag)

        assert cfrag.verify_correctness(capsule)

    sym_key_from_capsule = pre._open_capsule(capsule, priv_key_bob)
    assert sym_key == sym_key_from_capsule
Ejemplo n.º 17
0
def test_cfrag_serialization_no_proof_no_metadata(alices_keys, bobs_keys):
    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()

    _receiving_privkey, receiving_pubkey = bobs_keys
    signer_alice = Signer(signing_privkey)

    _unused_key, capsule = pre._encapsulate(delegating_pubkey.point_key)
    kfrags = pre.split_rekey(delegating_privkey, signer_alice,
                             receiving_pubkey, 1, 2)

    cfrag = pre.reencrypt(kfrags[0], capsule, provide_proof=False)
    cfrag_bytes = cfrag.to_bytes()

    proof = cfrag.proof
    assert proof is None

    curve = default_curve()
    assert len(cfrag_bytes) == CapsuleFrag.expected_bytes_length(curve)

    new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
    assert new_cfrag._point_e1 == cfrag._point_e1
    assert new_cfrag._point_v1 == cfrag._point_v1
    assert new_cfrag._kfrag_id == cfrag._kfrag_id
    assert new_cfrag._point_noninteractive == cfrag._point_noninteractive

    new_proof = new_cfrag.proof
    assert new_proof is None
Ejemplo n.º 18
0
def test_decapsulation_by_alice(alices_keys):
    alice_priv, alice_pub = alices_keys

    sym_key, capsule = pre._encapsulate(alice_pub.point_key)
    assert len(sym_key) == 32

    # The symmetric key sym_key is perhaps used for block cipher here in a real-world scenario.
    sym_key_2 = pre._decapsulate_original(alice_priv.bn_key, capsule)
    assert sym_key_2 == sym_key
Ejemplo n.º 19
0
def prepared_capsule(alices_keys, bobs_keys):
    delegating_privkey, signing_privkey = alices_keys
    _receiving_privkey, receiving_pubkey = bobs_keys

    _sym_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey())
    capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
                                 receiving=receiving_pubkey,
                                 verifying=signing_privkey.get_pubkey())
    return capsule    
Ejemplo n.º 20
0
def test_decapsulation_by_alice(alices_keys):
    delegating_privkey, _signing_privkey = alices_keys

    sym_key, capsule = pre._encapsulate(
        delegating_privkey.get_pubkey().point_key)
    assert len(sym_key) == 32

    # The symmetric key sym_key is perhaps used for block cipher here in a real-world scenario.
    sym_key_2 = pre._decapsulate_original(delegating_privkey.bn_key, capsule)
    assert sym_key_2 == sym_key
Ejemplo n.º 21
0
def test_cheating_ursula_sends_garbage(N, M):
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    # Bob
    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    sym_key, capsule_alice = pre._encapsulate(pub_key_alice.point_key)
    k_frags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N)

    c_frags, challenges = [], []
    for k_frag in k_frags[0:M]:
        c_frag = pre.reencrypt(k_frag, capsule_alice)
        challenge = pre.challenge(k_frag, capsule_alice, c_frag)
        capsule_alice.attach_cfrag(c_frag)

        assert pre.check_challenge(
            capsule_alice,
            c_frag,
            challenge,
            pub_key_alice.point_key,
            pub_key_bob.point_key,
        )

        c_frags.append(c_frag)
        challenges.append(challenge)

    # Let's put random garbage in one of the c_frags
    c_frags[0].point_eph_e1 = Point.gen_rand()
    c_frags[0].point_eph_v1 = Point.gen_rand()

    capsule_alice._reconstruct_shamirs_secret()  # activate capsule

    with pytest.raises(pre.GenericUmbralError):
        sym_key2 = pre.decapsulate_reencrypted(pub_key_bob.point_key,
                                               priv_key_bob.bn_key,
                                               pub_key_alice.point_key,
                                               capsule_alice)
        assert sym_key2 != sym_key
        assert not pre.check_challenge(capsule_alice, c_frags[0],
                                       challenges[0], pub_key_alice.point_key,
                                       pub_key_bob.point_key)

        # The response of cheating Ursula is in capsules[0],
        # so the rest of challenges chould be correct:
        for (c_frag, ch) in zip(c_frags[1:], challenges[1:]):
            assert pre.check_challenge(capsule_alice, c_frag, ch,
                                       pub_key_alice.point_key,
                                       pub_key_bob.point_key)
Ejemplo n.º 22
0
def test_cheating_ursula_replays_old_reencryption(alices_keys, bobs_keys,
                                                  kfrags, prepared_capsule):
    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()

    receiving_privkey, receiving_pubkey = bobs_keys

    capsule_alice1 = prepared_capsule

    _unused_key2, capsule_alice2 = pre._encapsulate(delegating_pubkey)

    capsule_alice2.set_correctness_keys(delegating=delegating_pubkey,
                                        receiving=receiving_pubkey,
                                        verifying=signing_privkey.get_pubkey())

    cfrags = []
    for i, kfrag in enumerate(kfrags):

        # Example of potential metadata to describe the re-encryption request
        metadata_i = "This is an example of metadata for re-encryption request #{}"
        metadata_i = metadata_i.format(i).encode()

        if i == 0:
            # Let's put the re-encryption of a different Alice ciphertext
            cfrag = pre.reencrypt(kfrag, capsule_alice2, metadata=metadata_i)
        else:
            cfrag = pre.reencrypt(kfrag, capsule_alice1, metadata=metadata_i)

        cfrags.append(cfrag)

    #  CFrag 0 is not valid ...
    assert not cfrags[0].verify_correctness(capsule_alice1)

    # ... and trying to attach it raises an error.
    with pytest.raises(pre.UmbralCorrectnessError) as exception_info:
        capsule_alice1.attach_cfrag(cfrags[0])

    correctness_error = exception_info.value
    assert cfrags[0] in correctness_error.offending_cfrags
    assert len(correctness_error.offending_cfrags) == 1

    # The rest of CFrags should be correct:
    correct_cases = 0
    for cfrag_i in cfrags[1:]:
        assert cfrag_i.verify_correctness(capsule_alice1)
        capsule_alice1.attach_cfrag(cfrag_i)
        correct_cases += 1

    assert correct_cases == len(cfrags[1:])
Ejemplo n.º 23
0
def fragments(metadata):
    delegating_privkey = UmbralPrivateKey.gen_key()
    _symmetric_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey())
    signing_privkey = UmbralPrivateKey.gen_key()
    signer = Signer(signing_privkey)
    priv_key_bob = UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()
    kfrags = pre.generate_kfrags(delegating_privkey=delegating_privkey,
                                 signer=signer,
                                 receiving_pubkey=pub_key_bob,
                                 threshold=2,
                                 N=4,
                                 sign_delegating_key=False,
                                 sign_receiving_key=False)
    capsule.set_correctness_keys(delegating_privkey.get_pubkey(), pub_key_bob, signing_privkey.get_pubkey())
    cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)
    return capsule, cfrag
Ejemplo n.º 24
0
def test_cfrag_serialization(alices_keys):
    priv_key_alice, pub_key_alice = alices_keys

    _unused_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    k_frags = pre.split_rekey(priv_key_alice, pub_key_alice, 1, 2)

    c_frag = pre.reencrypt(k_frags[0], capsule)
    c_frag_bytes = c_frag.to_bytes()

    # A CFrag can be represented as the 131 total bytes of three Points (33 each) and a BigNum (32).
    assert len(c_frag_bytes) == 33 + 33 + 33 + 32 == 131

    new_cfrag = pre.CapsuleFrag.from_bytes(c_frag_bytes)
    assert new_cfrag.point_eph_e1 == c_frag.point_eph_e1
    assert new_cfrag.point_eph_v1 == c_frag.point_eph_v1
    assert new_cfrag.bn_kfrag_id == c_frag.bn_kfrag_id
    assert new_cfrag.point_eph_ni == c_frag.point_eph_ni
Ejemplo n.º 25
0
def _mock_ursula_reencrypts(ursula, corrupt_cfrag: bool = False):
    delegating_privkey = UmbralPrivateKey.gen_key()
    _symmetric_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey())
    signing_privkey = UmbralPrivateKey.gen_key()
    signing_pubkey = signing_privkey.get_pubkey()
    signer = Signer(signing_privkey)
    priv_key_bob = UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()
    kfrags = pre.generate_kfrags(delegating_privkey=delegating_privkey,
                                 signer=signer,
                                 receiving_pubkey=pub_key_bob,
                                 threshold=2,
                                 N=4,
                                 sign_delegating_key=False,
                                 sign_receiving_key=False)
    capsule.set_correctness_keys(delegating_privkey.get_pubkey(), pub_key_bob,
                                 signing_pubkey)

    ursula_pubkey = ursula.stamp.as_umbral_pubkey()

    alice_address = canonical_address_from_umbral_key(signing_pubkey)
    blockhash = bytes(32)

    specification = b''.join((bytes(capsule), bytes(ursula_pubkey),
                              bytes(ursula.decentralized_identity_evidence),
                              alice_address, blockhash))

    bobs_signer = Signer(priv_key_bob)
    task_signature = bytes(bobs_signer(specification))

    metadata = bytes(ursula.stamp(task_signature))

    cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)

    if corrupt_cfrag:
        cfrag.proof.bn_sig = CurveBN.gen_rand(capsule.params.curve)

    cfrag_signature = bytes(ursula.stamp(bytes(cfrag)))

    bob = Bob.from_public_keys(verifying_key=pub_key_bob)
    task = WorkOrder.Task(capsule, task_signature, cfrag, cfrag_signature)
    work_order = WorkOrder(bob, None, alice_address, [task], None, ursula,
                           blockhash)

    evidence = IndisputableEvidence(task, work_order)
    return evidence
Ejemplo n.º 26
0
def test_cfrag_serialization_with_proof_and_metadata(alices_keys):
    priv_key_alice, pub_key_alice = alices_keys

    _unused_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_alice, 1, 2)

    # Example of potential metadata to describe the re-encryption request
    metadata = {
        'ursula_id': 42,
        'timestamp': time.time(),
        'capsule': bytes(capsule),
    }
    metadata = str(metadata).encode()

    cfrag = pre.reencrypt(kfrags[0],
                          capsule,
                          provide_proof=True,
                          metadata=metadata)
    cfrag_bytes = cfrag.to_bytes()

    proof = cfrag.proof
    assert proof is not None
    assert proof.metadata is not None

    # A CFrag can be represented as the 131 total bytes of three Points (33 each) and a CurveBN (32).
    # TODO: Figure out final size for CFrags with proofs
    #assert len(cfrag_bytes) == 33 + 33 + 33 + 32 == 131

    new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
    assert new_cfrag._point_e1 == cfrag._point_e1
    assert new_cfrag._point_v1 == cfrag._point_v1
    assert new_cfrag._bn_kfrag_id == cfrag._bn_kfrag_id
    assert new_cfrag._point_noninteractive == cfrag._point_noninteractive

    new_proof = new_cfrag.proof
    assert new_proof is not None
    assert new_proof._point_e2 == proof._point_e2
    assert new_proof._point_v2 == proof._point_v2
    assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
    assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
    assert new_proof._bn_kfrag_sig1 == proof._bn_kfrag_sig1
    assert new_proof._bn_kfrag_sig2 == proof._bn_kfrag_sig2
    assert new_proof._bn_sig == proof._bn_sig
    assert new_proof.metadata == metadata
    assert new_proof.metadata == proof.metadata
Ejemplo n.º 27
0
def test_capsule_length(alices_keys, bobs_keys):
    delegating_privkey, signing_privkey = alices_keys
    signer = Signer(signing_privkey)

    priv_key_bob, pub_key_bob = bobs_keys

    sym_key, capsule = pre._encapsulate(delegating_privkey.get_pubkey())

    kfrags = pre.split_rekey(delegating_privkey, signer, pub_key_bob, 10, 15)

    capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
                                 receiving=pub_key_bob,
                                 verifying=signing_privkey.get_pubkey())

    for counter, kfrag in enumerate(kfrags):
        assert len(capsule) == counter
        cfrag = pre.reencrypt(kfrag, capsule)
        capsule.attach_cfrag(cfrag)
Ejemplo n.º 28
0
def test_challenge_response_serialization():
    priv_key_alice = keys.UmbralPrivateKey.gen_key()
    pub_key_alice = priv_key_alice.get_pubkey()

    priv_key_bob = keys.UmbralPrivateKey.gen_key()
    pub_key_bob = priv_key_bob.get_pubkey()

    _unused_key, capsule = pre._encapsulate(pub_key_alice.point_key)
    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, 1, 2)

    cfrag = pre.reencrypt(kfrags[0], capsule)

    capsule.attach_cfrag(cfrag)

    # Example of potential metadata to describe the challenge request
    challenge_metadata = {
        'ursula_id': 0,
        'timestamp': time.time(),
        'capsule': bytes(capsule),
        'cfrag': bytes(cfrag)
    }

    challenge_metadata = str(challenge_metadata).encode()

    ch_resp = pre._challenge(kfrags[0], capsule, cfrag, challenge_metadata)

    ch_resp_bytes = ch_resp.to_bytes()

    # A ChallengeResponse can be represented as
    # the 228 total bytes of four Points (33 each) and three BigNums (32 each).
    assert len(ch_resp_bytes) == (33 * 4) + (32 * 3) == 228

    new_ch_resp = pre.ChallengeResponse.from_bytes(ch_resp_bytes)
    assert new_ch_resp.point_eph_e2 == ch_resp.point_eph_e2
    assert new_ch_resp.point_eph_v2 == ch_resp.point_eph_v2
    assert new_ch_resp.point_kfrag_commitment == ch_resp.point_kfrag_commitment
    assert new_ch_resp.point_kfrag_pok == ch_resp.point_kfrag_pok
    assert new_ch_resp.bn_kfrag_sig1 == ch_resp.bn_kfrag_sig1
    assert new_ch_resp.bn_kfrag_sig2 == ch_resp.bn_kfrag_sig2
    assert new_ch_resp.bn_sig == ch_resp.bn_sig
Ejemplo n.º 29
0
def test_activated_capsule_serialization(alices_keys, bobs_keys):
    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()
    signer_alice = Signer(signing_privkey)

    params = delegating_privkey.params

    receiving_privkey, receiving_pubkey = bobs_keys

    _unused_key, capsule = pre._encapsulate(delegating_pubkey)

    kfrags = pre.split_rekey(delegating_privkey, signer_alice,
                             receiving_pubkey, 1, 2)

    cfrag = pre.reencrypt(kfrags[0], capsule)

    capsule.set_correctness_keys(delegating=delegating_pubkey,
                                 receiving=receiving_pubkey,
                                 verifying=signing_privkey.get_pubkey())

    capsule.attach_cfrag(cfrag)

    capsule._reconstruct_shamirs_secret(receiving_privkey)
    rec_capsule_bytes = capsule.to_bytes()

    assert len(rec_capsule_bytes) == pre.Capsule.expected_bytes_length(
        activated=True)

    new_rec_capsule = pre.Capsule.from_bytes(rec_capsule_bytes, params)

    # Again, the same three perspectives on equality.
    assert new_rec_capsule == capsule

    assert new_rec_capsule.activated_components(
    ) == capsule.activated_components()

    assert new_rec_capsule._point_e_prime == capsule._point_e_prime
    assert new_rec_capsule._point_v_prime == capsule._point_v_prime
    assert new_rec_capsule._point_noninteractive == capsule._point_noninteractive
Ejemplo n.º 30
0
def test_cfrag_serialization_with_proof_and_metadata(alices_keys, bobs_keys):
    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()
    signer_alice = Signer(signing_privkey)
    _receiving_privkey, receiving_pubkey = bobs_keys

    _unused_key, capsule = pre._encapsulate(delegating_pubkey.point_key)
    kfrags = pre.split_rekey(delegating_privkey, signer_alice,
                             receiving_pubkey, 1, 2)

    # Example of potential metadata to describe the re-encryption request
    metadata = b'This is an example of metadata for re-encryption request'

    cfrag = pre.reencrypt(kfrags[0],
                          capsule,
                          provide_proof=True,
                          metadata=metadata)
    cfrag_bytes = cfrag.to_bytes()

    proof = cfrag.proof
    assert proof is not None
    assert proof.metadata is not None

    new_cfrag = pre.CapsuleFrag.from_bytes(cfrag_bytes)
    assert new_cfrag._point_e1 == cfrag._point_e1
    assert new_cfrag._point_v1 == cfrag._point_v1
    assert new_cfrag._kfrag_id == cfrag._kfrag_id
    assert new_cfrag._point_noninteractive == cfrag._point_noninteractive

    new_proof = new_cfrag.proof
    assert new_proof is not None
    assert new_proof._point_e2 == proof._point_e2
    assert new_proof._point_v2 == proof._point_v2
    assert new_proof._point_kfrag_commitment == proof._point_kfrag_commitment
    assert new_proof._point_kfrag_pok == proof._point_kfrag_pok
    assert new_proof.bn_sig == proof.bn_sig
    assert new_proof.metadata == metadata
    assert new_proof.metadata == proof.metadata