def test_capsule_as_dict_key(alices_keys):
    priv_key_alice, pub_key_alice = alices_keys
    plain_data = b'peace at dawn'
    ciphertext, capsule = pre.encrypt(pub_key_alice, plain_data)

    # We can use the capsule as a key, and successfully lookup using it.
    some_dict = {capsule: "Thing that Bob wants to try per-Capsule"}
    assert some_dict[capsule] == "Thing that Bob wants to try per-Capsule"

    kfrags = pre.split_rekey(alices_keys.priv, alices_keys.pub, 1, 2)
    cfrag = pre.reencrypt(kfrags[0], capsule)
    capsule.attach_cfrag(cfrag)

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

    # Even if we activate the capsule, it still serves as the same key.
    cleartext = pre.decrypt(ciphertext, capsule, alices_keys.priv,
                            alices_keys.pub)
    assert some_dict[capsule] == "Thing that Bob wants to try per-Capsule"
    assert cleartext == plain_data

    # And if we change the value for this key, all is still well.
    some_dict[capsule] = "Bob has changed his mind."
    assert some_dict[capsule] == "Bob has changed his mind."
    assert len(some_dict.keys()) == 1
示例#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, 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
示例#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 = [], []
    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
                                   )
示例#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)

    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])
示例#5
0
def test_bad_capsule_fails_reencryption(kfrags):
    params = default_params()

    bollocks_capsule = Capsule(params,
                               point_e=Point.gen_rand(),
                               point_v=Point.gen_rand(),
                               bn_sig=CurveBN.gen_rand())

    for kfrag in kfrags:
        with pytest.raises(Capsule.NotValid):
            pre.reencrypt(kfrag, bollocks_capsule)
def test_bad_capsule_fails_reencryption(alices_keys):
    priv_key_alice, pub_key_alice = alices_keys

    kfrags = pre.split_rekey(priv_key_alice, pub_key_alice, 1, 2)

    bollocks_capsule = Capsule(point_e=Point.gen_rand(),
                               point_v=Point.gen_rand(),
                               bn_sig=CurveBN.gen_rand())

    with pytest.raises(Capsule.NotValid):
        pre.reencrypt(kfrags[0], bollocks_capsule)
示例#7
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,
            )
示例#8
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:])
示例#9
0
def test_bad_capsule_fails_reencryption(alices_keys, bobs_keys):
    delegating_privkey, _signing_privkey = alices_keys
    signer_alice = Signer(_signing_privkey)

    _receiving_privkey, receiving_pubkey = bobs_keys

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

    bollocks_capsule = Capsule(point_e=Point.gen_rand(),
                               point_v=Point.gen_rand(),
                               bn_sig=CurveBN.gen_rand())

    with pytest.raises(Capsule.NotValid):
        pre.reencrypt(kfrags[0], bollocks_capsule)
示例#10
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
示例#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, 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
示例#12
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
示例#13
0
def test_cheating_ursula_sends_garbage(kfrags, prepared_capsule):
    capsule_alice = prepared_capsule

    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()

        cfrag = pre.reencrypt(kfrag, capsule_alice, metadata=metadata_i)
        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()

    #  Of course, this CFrag is not valid ...
    assert not cfrags[0].verify_correctness(capsule_alice)

    # ... and trying to attach it raises an error.
    with pytest.raises(pre.UmbralCorrectnessError) as exception_info:
        capsule_alice.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 response of cheating Ursula is in cfrags[0],
    # so the rest of CFrags should be correct:
    for cfrag_i in cfrags[1:]:
        assert cfrag_i.verify_correctness(capsule_alice)
        capsule_alice.attach_cfrag(cfrag_i)
示例#14
0
def test_simple_api(N, M, curve=default_curve()):
    """Manually injects umbralparameters for multi-curve testing."""

    params = UmbralParameters(curve=curve)

    priv_key_alice = keys.UmbralPrivateKey.gen_key(params=params)
    pub_key_alice = priv_key_alice.get_pubkey()

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

    plain_data = b'peace at dawn'
    ciphertext, capsule = pre.encrypt(pub_key_alice, plain_data, params=params)

    cleartext = pre.decrypt(ciphertext, capsule, priv_key_alice, params=params)
    assert cleartext == plain_data

    kfrags = pre.split_rekey(priv_key_alice, pub_key_bob, M, N, params=params)
    for kfrag in kfrags:
        cfrag = pre.reencrypt(kfrag, capsule, params=params)
        capsule.attach_cfrag(cfrag)

    reenc_cleartext = pre.decrypt(ciphertext,
                                  capsule,
                                  priv_key_bob,
                                  pub_key_alice,
                                  params=params)
    assert reenc_cleartext == plain_data
示例#15
0
    def reencrypt_via_rest(id_as_hex):
        from nucypher.policy.models import WorkOrder  # Avoid circular import
        arrangement_id = binascii.unhexlify(id_as_hex)
        work_order = WorkOrder.from_rest_payload(arrangement_id, request.data)
        log.info("Work Order from {}, signed {}".format(work_order.bob, work_order.receipt_signature))
        with ThreadedSession(db_engine) as session:
            policy_arrangement = datastore.get_policy_arrangement(arrangement_id=id_as_hex.encode(),
                                                                  session=session)

        kfrag_bytes = policy_arrangement.kfrag  # Careful!  :-)
        verifying_key_bytes = policy_arrangement.alice_pubkey_sig.key_data

        # TODO: Push this to a lower level.
        kfrag = KFrag.from_bytes(kfrag_bytes)
        alices_verifying_key = UmbralPublicKey.from_bytes(verifying_key_bytes)
        cfrag_byte_stream = b""

        for capsule, capsule_signature in zip(work_order.capsules, work_order.capsule_signatures):
            # This is the capsule signed by Bob
            capsule_signature = bytes(capsule_signature)
            # Ursula signs on top of it. Now both are committed to the same capsule.
            capsule_signed_by_both = bytes(stamp(capsule_signature))

            capsule.set_correctness_keys(verifying=alices_verifying_key)
            cfrag = pre.reencrypt(kfrag, capsule, metadata=capsule_signed_by_both)
            log.info("Re-encrypting for {}, made {}.".format(capsule, cfrag))
            signature = stamp(bytes(cfrag) + bytes(capsule))
            cfrag_byte_stream += VariableLengthBytestring(cfrag) + signature

        # TODO: Put this in Ursula's datastore
        work_order_tracker.append(work_order)

        headers = {'Content-Type': 'application/octet-stream'}

        return Response(response=cfrag_byte_stream, headers=headers)
示例#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
def test_cfrag_serialization_with_proof_but_no_metadata(
        prepared_capsule, kfrags):

    for kfrag in kfrags:
        cfrag = pre.reencrypt(kfrag, prepared_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 = 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_precursor == cfrag.point_precursor

        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 is None
示例#18
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
示例#19
0
def test_simple_api(N, M, curve=default_curve()):
    """Manually injects umbralparameters for multi-curve testing."""
    params = UmbralParameters(curve=curve)

    delegating_privkey = UmbralPrivateKey.gen_key(params=params)
    delegating_pubkey = delegating_privkey.get_pubkey()

    signing_privkey = UmbralPrivateKey.gen_key(params=params)
    signing_pubkey = signing_privkey.get_pubkey()
    signer = Signer(signing_privkey)

    receiving_privkey = UmbralPrivateKey.gen_key(params=params)
    receiving_pubkey = receiving_privkey.get_pubkey()

    plain_data = b'peace at dawn'
    ciphertext, capsule = pre.encrypt(delegating_pubkey, plain_data)

    cleartext = pre.decrypt(ciphertext, capsule, delegating_privkey)
    assert cleartext == plain_data

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

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

    for kfrag in kfrags:
        cfrag = pre.reencrypt(kfrag, capsule)
        capsule.attach_cfrag(cfrag)

    reenc_cleartext = pre.decrypt(ciphertext, capsule, receiving_privkey)
    assert reenc_cleartext == plain_data
示例#20
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
示例#21
0
    def reencrypt_via_rest(self, id_as_hex, request: http.Request):
        from nucypher.policy.models import WorkOrder  # Avoid circular import
        id = binascii.unhexlify(id_as_hex)
        work_order = WorkOrder.from_rest_payload(id, request.body)
        self.log.info("Work Order from {}, signed {}".format(
            work_order.bob, work_order.receipt_signature))
        with ThreadedSession(self.db_engine) as session:
            kfrag_bytes = self.datastore.get_policy_arrangement(
                id.hex().encode(), session=session).k_frag  # Careful!  :-)
        # TODO: Push this to a lower level.
        kfrag = KFrag.from_bytes(kfrag_bytes)
        cfrag_byte_stream = b""

        for capsule in work_order.capsules:
            # TODO: Sign the result of this.  See #141.
            cfrag = pre.reencrypt(kfrag, capsule)
            self.log.info(
                "Re-encrypting for Capsule {}, made CFrag {}.".format(
                    capsule, cfrag))
            cfrag_byte_stream += VariableLengthBytestring(cfrag)

        # TODO: Put this in Ursula's datastore
        self._work_orders.append(work_order)

        headers = {'Content-Type': 'application/octet-stream'}

        return Response(content=cfrag_byte_stream, headers=headers)
示例#22
0
def test_correctness_proof_serialization(prepared_capsule, kfrags):
    
    # Example of potential metadata to describe the re-encryption request
    metadata = b"This is an example of metadata for re-encryption request"

    for kfrag in kfrags:
        cfrag = pre.reencrypt(kfrag, prepared_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

        
示例#23
0
def test_capsule_length(prepared_capsule, kfrags):
    capsule = prepared_capsule

    for counter, kfrag in enumerate(kfrags):
        assert len(capsule) == counter
        cfrag = pre.reencrypt(kfrag, capsule)
        capsule.attach_cfrag(cfrag)
示例#24
0
    def reencrypt(self, policy_id: str, capsule: pre.Capsule,
                  M: int) -> List[fragments.CapsuleFrag]:
        """
        Re-encrypts the given capsule 'M' number of times and returns a list
        of CapsuleFrags (CFrags) to be attached to the original Capsule.

        :param policy_id: Policy ID to access re-encryption.
        :param capsule: The Umbral capsule to re-encrypt.
        :param M: The number of times to re-encrypt the capsule for the minimum
            number of CFrags needed.

        :return: List of CFrags (CapsuleFrags).
        """
        try:
            kfrags = self.db[policy_id]
        except KeyError:
            raise ValueError("No Policy found for {}".format(policy_id))

        if M > len(kfrags):
            raise ValueError(
                "Not enough KFrags to re-encrypt {} times!".format(M))

        cfrags = []

        # TODO: using web3py check if is dead?
        data = requests.get("http://172.16.21.223:3000/api/platform/isAlive/")
        res = json.loads(data.text)
        if bool(res["result"]) == True:
            m_kfrags = random.sample(kfrags, M)
            for kfrag in m_kfrags:
                cfrags.append(pre.reencrypt(kfrag, capsule))
            return cfrags
def test_cfrag_serialization_with_proof_and_metadata(prepared_capsule, kfrags):

    # Example of potential metadata to describe the re-encryption request
    metadata = b'This is an example of metadata for re-encryption request'
    for kfrag in kfrags:
        cfrag = pre.reencrypt(kfrag,
                              prepared_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 = 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_precursor == cfrag.point_precursor

        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
示例#26
0
    def reencrypt(self, policy_id: str, capsule: pre.Capsule,
                  M: int) -> List[fragments.CapsuleFrag]:
        """
        Re-encrypts the given capsule 'M' number of times and returns a list
        of CapsuleFrags (CFrags) to be attached to the original Capsule.

        :param policy_id: Policy ID to access re-encryption.
        :param capsule: The Umbral capsule to re-encrypt.
        :param M: The number of times to re-encrypt the capsule for the minimum
            number of CFrags needed.

        :return: List of CFrags (CapsuleFrags).
        """
        try:
            kfrags = self.db[policy_id]
        except KeyError:
            raise ValueError("No Policy found for {}".format(policy_id))

        if M > len(kfrags):
            raise ValueError(
                "Not enough KFrags to re-encrypt {} times!".format(M))

        cfrags = []
        m_kfrags = random.sample(kfrags, M)
        for kfrag in m_kfrags:
            cfrags.append(pre.reencrypt(kfrag, capsule))
        return cfrags
示例#27
0
def test_decryption_fails_when_it_expects_a_proof_and_there_isnt(N, M, alices_keys, bobs_keys):
    """Manually injects umbralparameters for multi-curve testing."""

    delegating_privkey, signing_privkey = alices_keys
    delegating_pubkey = delegating_privkey.get_pubkey()
    signer = Signer(signing_privkey)
    priv_key_bob, pub_key_bob = bobs_keys

    plain_data = b'peace at dawn'
    ciphertext, capsule = pre.encrypt(delegating_privkey.get_pubkey(), plain_data)

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

    capsule.set_correctness_keys(delegating=delegating_privkey.get_pubkey(),
                                 receiving=pub_key_bob,
                                 verifying=signing_privkey.get_pubkey())
    for kfrag in kfrags[:M]:
        cfrag = pre.reencrypt(kfrag, capsule)
        capsule.attach_cfrag(cfrag)

    # Even thought we can successfully attach a CFrag, if the proof is lost
    # (for example, it is chopped off a serialized CFrag or similar), then decrypt
    # will still fail.
    cfrag.proof = None

    with pytest.raises(cfrag.NoProofProvided):
        _cleartext = pre.decrypt(ciphertext, capsule, priv_key_bob)
示例#28
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
示例#29
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
示例#30
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