Beispiel #1
0
def test_keypair_with_umbral_keys():
    umbral_privkey = UmbralPrivateKey.gen_key()
    umbral_pubkey = umbral_privkey.get_pubkey()

    new_keypair_from_priv = keypairs.Keypair(umbral_privkey)
    assert new_keypair_from_priv._privkey.bn_key.to_bytes(
    ) == umbral_privkey.bn_key.to_bytes()
    assert new_keypair_from_priv.pubkey.to_bytes() == umbral_pubkey.to_bytes()

    new_keypair_from_pub = keypairs.Keypair(public_key=umbral_pubkey)
    assert new_keypair_from_pub.pubkey.to_bytes() == umbral_pubkey.to_bytes()
    assert new_keypair_from_pub._privkey == PUBLIC_ONLY
def test_address(testerchain, signature_verifier):
    # Generate Umbral key and extract "address" from the public key
    umbral_privkey = UmbralPrivateKey.gen_key()
    umbral_pubkey = umbral_privkey.get_pubkey()
    umbral_pubkey_bytes = umbral_pubkey.to_bytes(is_compressed=False)[1:]
    signer_address = keccak_digest(umbral_pubkey_bytes)
    signer_address = to_normalized_address(signer_address[12:])

    # Check extracting address in library
    result_address = signature_verifier.functions.toAddress(
        umbral_pubkey_bytes).call()
    assert signer_address == to_normalized_address(result_address)
Beispiel #3
0
def test_umbral_key_to_cryptography_keys():
    umbral_priv_key = UmbralPrivateKey.gen_key()
    umbral_pub_key = umbral_priv_key.get_pubkey()

    crypto_privkey = umbral_priv_key.to_cryptography_privkey()
    assert int(umbral_priv_key.bn_key) == crypto_privkey.private_numbers(
    ).private_value

    crypto_pubkey = umbral_pub_key.to_cryptography_pubkey()
    umbral_affine = umbral_pub_key.point_key.to_affine()
    x, y = crypto_pubkey.public_numbers().x, crypto_pubkey.public_numbers().y
    assert umbral_affine == (x, y)
Beispiel #4
0
def test_cannot_set_different_keys():
    """
    Once a key is set on a Capsule, it can't be changed to a different key.
    """
    params = default_params()

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

    capsule.set_correctness_keys(
        delegating=UmbralPrivateKey.gen_key().get_pubkey(),
        receiving=UmbralPrivateKey.gen_key().get_pubkey(),
        verifying=UmbralPrivateKey.gen_key().get_pubkey())

    with pytest.raises(ValueError):
        capsule.set_correctness_keys(
            delegating=UmbralPrivateKey.gen_key().get_pubkey())

    with pytest.raises(ValueError):
        capsule.set_correctness_keys(
            receiving=UmbralPrivateKey.gen_key().get_pubkey())

    with pytest.raises(ValueError):
        capsule.set_correctness_keys(
            verifying=UmbralPrivateKey.gen_key().get_pubkey())
Beispiel #5
0
def test_recover(testerchain, signature_verifier):
    message = os.urandom(100)

    # Prepare message hash
    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(message)
    message_hash = hash_ctx.finalize()

    # Generate Umbral key and extract "address" from the public key
    umbral_privkey = UmbralPrivateKey.gen_key()
    umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
    signer_address = bytearray(testerchain.interface.w3.solidityKeccak(['bytes32'], [umbral_pubkey_bytes[1:]]))
    signer_address = to_normalized_address(signer_address[12:])

    # Sign message using SHA-256 hash (because only 32 bytes hash can be used in the `ecrecover` method)
    cryptography_priv_key = umbral_privkey.to_cryptography_privkey()
    signature_der_bytes = cryptography_priv_key.sign(message, ec.ECDSA(hashes.SHA256()))
    signature = Signature.from_bytes(signature_der_bytes, der_encoded=True)

    # Get recovery id (v) before using contract
    # If we don't have recovery id while signing than we should try to recover public key with different v
    # Only the correct v will match the correct public key
    # First try v = 0
    recoverable_signature = bytes(signature) + bytes([0])
    pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)\
        .format(compressed=False)
    if pubkey_bytes != umbral_pubkey_bytes:
        # Extracted public key is not ours, that means v = 1
        recoverable_signature = bytes(signature) + bytes([1])
        pubkey_bytes = coincurve.PublicKey.from_signature_and_message(recoverable_signature, message_hash, hasher=None)\
            .format(compressed=False)

    # Check that recovery was ok
    assert umbral_pubkey_bytes == pubkey_bytes
    # Check recovery method in the contract
    assert signer_address == to_normalized_address(
        signature_verifier.functions.recover(message_hash, recoverable_signature).call())

    # Also numbers 27 and 28 can be used for v
    recoverable_signature = recoverable_signature[0:-1] + bytes([recoverable_signature[-1] + 27])
    assert signer_address == to_normalized_address(
        signature_verifier.functions.recover(message_hash, recoverable_signature).call())

    # Only number 0,1,27,28 are supported for v
    recoverable_signature = bytes(signature) + bytes([2])
    with pytest.raises((TransactionFailed, ValueError)):
        signature_verifier.functions.recover(message_hash, recoverable_signature).call()

    # Signature must include r, s and v
    recoverable_signature = bytes(signature)
    with pytest.raises((TransactionFailed, ValueError)):
        signature_verifier.functions.recover(message_hash, recoverable_signature).call()
Beispiel #6
0
def generate_doctor_keys(username):
    enc_privkey = UmbralPrivateKey.gen_key()
    sig_privkey = UmbralPrivateKey.gen_key()

    keys = {}
    keys['enc'] = enc_privkey.to_bytes().hex()
    keys['sig'] = sig_privkey.to_bytes().hex()

    enc_pubkey = enc_privkey.get_pubkey()
    sig_pubkey = sig_privkey.get_pubkey()

    doctor_pubkeys = {
        'enc': enc_pubkey.to_bytes().hex(),
        'sig': sig_pubkey.to_bytes().hex()
    }

    BOB_PUBLIC_KEYS = os.path.join(os.getcwd(), 'bob/' + username + '.json')

    with open(BOB_PUBLIC_KEYS, 'w') as f:
        json.dump(doctor_pubkeys, f)

    return json.dumps(keys)
Beispiel #7
0
def test_enrico_encrypt(click_runner):
    policy_encrypting_key = UmbralPrivateKey.gen_key().get_pubkey().to_bytes(
    ).hex()
    encrypt_args = ('enrico', 'encrypt', '--message', 'to be or not to be',
                    '--policy-encrypting-key', policy_encrypting_key)
    result = click_runner.invoke(nucypher_cli,
                                 encrypt_args,
                                 catch_exceptions=False)

    assert result.exit_code == 0
    assert policy_encrypting_key in result.output
    assert "message_kit" in result.output
    assert "signature" in result.output
Beispiel #8
0
def test_keypair_with_umbral_keys():
    umbral_privkey = UmbralPrivateKey.gen_key()
    umbral_pubkey = umbral_privkey.get_pubkey()

    new_keypair_from_priv = keypairs.Keypair(umbral_privkey)
    assert new_keypair_from_priv._privkey.bn_key.to_bytes(
    ) == umbral_privkey.bn_key.to_bytes()
    assert new_keypair_from_priv.pubkey.to_bytes() == umbral_pubkey.to_bytes()

    new_keypair_from_pub = keypairs.Keypair(umbral_pubkey)
    assert new_keypair_from_pub.pubkey.to_bytes() == umbral_pubkey.to_bytes()
    with pytest.raises(AttributeError):
        new_keypair_from_pub._privkey
def test_signature_rs_serialization():
    privkey = UmbralPrivateKey.gen_key()
    message = b"peace at dawn"
    der_sig_bytes = ecdsa_sign(message, privkey)

    signature_from_der = Signature.from_bytes(der_sig_bytes, der_encoded=True)
    rs_sig_bytes = bytes(signature_from_der)
    assert len(rs_sig_bytes) == 64

    signature_from_rs = Signature.from_bytes(rs_sig_bytes, der_encoded=False)

    assert signature_from_rs == signature_from_der
    assert signature_from_rs == der_sig_bytes
    assert signature_from_rs.verify(message, privkey.get_pubkey())
Beispiel #10
0
def test_generate_alice_keyring(tmpdir):
    password = '******' * 16

    keyring = NucypherKeyring.generate(password=password,
                                       encrypting=True,
                                       wallet=False,
                                       rest=False,
                                       keyring_root=tmpdir)

    enc_pubkey = keyring.encrypting_public_key
    assert enc_pubkey is not None

    with pytest.raises(NucypherKeyring.KeyringLocked):
        _dec_keypair = keyring.derive_crypto_power(DecryptingPower).keypair

    keyring.unlock(password)
    dec_keypair = keyring.derive_crypto_power(DecryptingPower).keypair

    assert enc_pubkey == dec_keypair.pubkey

    label = b'test'

    delegating_power = keyring.derive_crypto_power(DelegatingPower)
    delegating_pubkey = delegating_power.get_pubkey_from_label(label)

    bob_pubkey = UmbralPrivateKey.gen_key().get_pubkey()
    signer = Signer(UmbralPrivateKey.gen_key())
    delegating_pubkey_again, _kfrags = delegating_power.generate_kfrags(
        bob_pubkey, signer, label, m=2, n=3)

    assert delegating_pubkey == delegating_pubkey_again

    another_delegating_power = keyring.derive_crypto_power(DelegatingPower)
    another_delegating_pubkey = another_delegating_power.get_pubkey_from_label(
        label)

    assert delegating_pubkey == another_delegating_pubkey
Beispiel #11
0
def test_recover(testerchain, signature_verifier):
    message = os.urandom(100)

    # Prepare message hash
    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(message)
    message_hash = hash_ctx.finalize()

    # Generate Umbral key and extract "address" from the public key
    umbral_privkey = UmbralPrivateKey.gen_key()
    umbral_pubkey = umbral_privkey.get_pubkey()
    umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(
        is_compressed=False)
    signer_address = keccak_digest(umbral_pubkey_bytes[1:])
    signer_address = to_normalized_address(signer_address[12:])

    # Sign message
    signer = Signer(umbral_privkey)
    signature = signer(message)

    # Get recovery id (v) before using contract
    # If we don't have recovery id while signing then we should try to recover public key with different v
    # Only the correct v will match the correct public key
    v = get_signature_recovery_value(message, signature, umbral_pubkey)
    recoverable_signature = bytes(signature) + v

    # Check recovery method in the contract
    assert signer_address == to_normalized_address(
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call())

    # Also numbers 27 and 28 can be used for v
    recoverable_signature = recoverable_signature[:-1] + bytes(
        [recoverable_signature[-1] + 27])
    assert signer_address == to_normalized_address(
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call())

    # Only number 0,1,27,28 are supported for v
    recoverable_signature = bytes(signature) + bytes([2])
    with pytest.raises((TransactionFailed, ValueError)):
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call()

    # Signature must include r, s and v
    recoverable_signature = bytes(signature)
    with pytest.raises((TransactionFailed, ValueError)):
        signature_verifier.functions.recover(message_hash,
                                             recoverable_signature).call()
Beispiel #12
0
def test_prehashed_message(execution_number):
    privkey = UmbralPrivateKey.gen_key()
    pubkey = privkey.get_pubkey()
    signer = Signer(private_key=privkey)

    message = b"peace at dawn"
    hash_function = hashes.Hash(DEFAULT_HASH_ALGORITHM(), backend=backend)
    hash_function.update(message)
    prehashed_message = hash_function.finalize()

    signature = signer(message=prehashed_message, is_prehashed=True)

    assert signature.verify(message=prehashed_message,
                            verifying_key=pubkey,
                            is_prehashed=True)
def test_coordinates_as_bytes():
    pubkey = UmbralPrivateKey.gen_key().pubkey
    point = pubkey.point_key
    stamp = SignatureStamp(verifying_key=pubkey)

    x, y = point.to_affine()
    x = x.to_bytes(32, 'big')
    y = y.to_bytes(32, 'big')

    for p in (point, pubkey, stamp):
        assert get_coordinates_as_bytes(p) == x + y
        assert get_coordinates_as_bytes(p, x_coord=False) == y
        assert get_coordinates_as_bytes(p, y_coord=False) == x
        with pytest.raises(ValueError):
            _ = get_coordinates_as_bytes(p, x_coord=False, y_coord=False)
Beispiel #14
0
def test_generate_alice_keyring(tmpdir):

    keyring = NucypherKeyring.generate(checksum_address=FEDERATED_ADDRESS,
                                       password=INSECURE_DEVELOPMENT_PASSWORD,
                                       encrypting=True,
                                       rest=False,
                                       keyring_root=tmpdir)

    enc_pubkey = keyring.encrypting_public_key
    assert enc_pubkey is not None

    with pytest.raises(NucypherKeyring.KeyringLocked):
        _dec_keypair = keyring.derive_crypto_power(DecryptingPower).keypair

    keyring.unlock(password=INSECURE_DEVELOPMENT_PASSWORD)
    dec_keypair = keyring.derive_crypto_power(DecryptingPower).keypair

    assert enc_pubkey == dec_keypair.pubkey

    label = b'test'

    delegating_power = keyring.derive_crypto_power(DelegatingPower)
    delegating_pubkey = delegating_power.get_pubkey_from_label(label)

    bob_pubkey = UmbralPrivateKey.gen_key().get_pubkey()
    signer = Signer(UmbralPrivateKey.gen_key())
    delegating_pubkey_again, _kfrags = delegating_power.generate_kfrags(
        bob_pubkey, signer, label, m=2, n=3)

    assert delegating_pubkey == delegating_pubkey_again

    another_delegating_power = keyring.derive_crypto_power(DelegatingPower)
    another_delegating_pubkey = another_delegating_power.get_pubkey_from_label(
        label)

    assert delegating_pubkey == another_delegating_pubkey
Beispiel #15
0
def test_set_invalid_correctness_keys(alices_keys, capsule, kfrags):
    """
    If the three keys do appear together, along with the capsule,
    we can attach them all at once.
    """

    delegating_privkey, signing_privkey = alices_keys
    unrelated_receiving_pubkey = UmbralPrivateKey.gen_key().get_pubkey()

    capsule.set_correctness_keys(delegating_privkey.get_pubkey(),
                                 unrelated_receiving_pubkey,
                                 signing_privkey.get_pubkey())

    for kfrag in kfrags:
        with pytest.raises(KFrag.NotValid):
            cfrag = pre.reencrypt(kfrag, capsule)
Beispiel #16
0
def generate_accounts(w3: Web3, quantity: int) -> List[str]:
    """
    Generate additional unlocked accounts transferring wei_balance to each account on creation.
    """

    addresses = list()
    insecure_passphrase = 'this-is-not-a-secure-password'
    for _ in range(quantity):
        umbral_priv_key = UmbralPrivateKey.gen_key()

        address = w3.personal.importRawKey(private_key=umbral_priv_key.to_bytes(),
                                           passphrase=insecure_passphrase)

        w3.personal.unlockAccount(address, passphrase=insecure_passphrase)
        addresses.append(addresses)
    return addresses
Beispiel #17
0
def test_compute_proof_challenge_scalar(testerchain, reencryption_validator,
                                        mock_ursula_reencrypts):
    ursula_privkey = UmbralPrivateKey.gen_key()
    ursula_stamp = SignatureStamp(verifying_key=ursula_privkey.pubkey,
                                  signer=Signer(ursula_privkey))
    ursula = Mock(stamp=ursula_stamp)

    # Bob prepares supporting Evidence
    evidence = mock_ursula_reencrypts(ursula)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    capsule_bytes = capsule.to_bytes()
    cfrag_bytes = cfrag.to_bytes()
    proof_challenge_scalar = int(evidence.get_proof_challenge_scalar())
    computeProofChallengeScalar = reencryption_validator.functions.computeProofChallengeScalar
    assert proof_challenge_scalar == computeProofChallengeScalar(
        capsule_bytes, cfrag_bytes).call()
def test_ecdsa_signature_recovery(execution_number):
    privkey = UmbralPrivateKey.gen_key()
    pubkey = privkey.get_pubkey()
    signer = Signer(private_key=privkey)
    message = b"peace at dawn"
    signature = signer(message=message)

    assert signature.verify(message, pubkey)

    v_value = 27
    pubkey_bytes = recover_pubkey_from_signature(message=message,
                                                 signature=signature,
                                                 v_value_to_try=v_value)
    if not pubkey_bytes == pubkey.to_bytes():
        v_value = 28
        pubkey_bytes = recover_pubkey_from_signature(message=message,
                                                     signature=signature,
                                                     v_value_to_try=v_value)

    assert pubkey_bytes == pubkey.to_bytes()
    assert bytes([v_value - 27
                  ]) == get_signature_recovery_value(message, signature,
                                                     pubkey)

    hash_function = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_function.update(message)
    prehashed_message = hash_function.finalize()

    v_value = 27
    pubkey_bytes = recover_pubkey_from_signature(message=prehashed_message,
                                                 signature=signature,
                                                 v_value_to_try=v_value,
                                                 is_prehashed=True)
    if not pubkey_bytes == pubkey.to_bytes():
        v_value = 28
        pubkey_bytes = recover_pubkey_from_signature(message=prehashed_message,
                                                     signature=signature,
                                                     v_value_to_try=v_value,
                                                     is_prehashed=True)
    assert pubkey_bytes == pubkey.to_bytes()
    assert bytes([v_value - 27
                  ]) == get_signature_recovery_value(prehashed_message,
                                                     signature,
                                                     pubkey,
                                                     is_prehashed=True)
Beispiel #19
0
    def __generate_insecure_unlocked_accounts(self, quantity: int) -> List[str]:
        """
        Generate additional unlocked accounts transferring a balance to each account on creation.
        """
        addresses = list()
        insecure_password = INSECURE_DEVELOPMENT_PASSWORD
        for _ in range(quantity):

            umbral_priv_key = UmbralPrivateKey.gen_key()
            address = self.interface.w3.personal.importRawKey(private_key=umbral_priv_key.to_bytes(),
                                                              passphrase=insecure_password)

            assert self.interface.unlock_account(address, password=insecure_password, duration=None), 'Failed to unlock {}'.format(address)
            addresses.append(address)
            self._test_account_cache.append(address)
            self.log.info('Generated new insecure account {}'.format(address))

        return addresses
Beispiel #20
0
 def __init__(self,
              pubkey: UmbralPublicKey = None,
              keypair: keypairs.Keypair = None,
              generate_keys_if_needed=True) -> None:
     if keypair and pubkey:
         raise ValueError(
             "Pass keypair or pubkey_bytes (or neither), but not both.")
     elif keypair:
         self.keypair = keypair
     else:
         # They didn't pass a keypair; we'll make one with the bytes (if any)
         # they provided.
         if pubkey:
             key_to_pass_to_keypair = pubkey
         else:
             # They didn't even pass pubkey_bytes.  We'll generate a keypair.
             key_to_pass_to_keypair = UmbralPrivateKey.gen_key()
         self.keypair = self._keypair_class(
             umbral_key=key_to_pass_to_keypair)
Beispiel #21
0
    def __init__(self,
                umbral_key: Union[UmbralPrivateKey, UmbralPublicKey]=None,
                generate_keys_if_needed=True):
        """
        Initalizes a Keypair object with an Umbral key object.

        :param umbral_key: An UmbralPrivateKey or UmbralPublicKey
        :param generate_keys_if_needed: Generate keys or not?
        """
        try:
            self.pubkey = umbral_key.get_pubkey()
            self._privkey = umbral_key
        except NotImplementedError:
            self.pubkey = umbral_key
        except AttributeError:
            # They didn't pass anything we recognize as a valid key.
            if generate_keys_if_needed:
                self._privkey = UmbralPrivateKey.gen_key()
                self.pubkey = self._privkey.get_pubkey()
            else:
                raise ValueError("Either pass a valid key as umbral_key or, if you want to generate keys, set generate_keys_if_needed to True.")
 def new_keypair_bytes():
     privkey = UmbralPrivateKey.gen_key(params=params)
     return privkey.to_bytes(), privkey.get_pubkey().to_bytes()
def test_evaluate_cfrag(testerchain, escrow, adjudicator_contract):
    creator, miner, wrong_miner, investigator, *everyone_else = testerchain.interface.w3.eth.accounts
    evaluation_log = adjudicator_contract.events.CFragEvaluated.createFilter(
        fromBlock='latest')

    worker_stake = 1000
    worker_penalty_history = 0
    investigator_balance = 0
    number_of_evaluations = 0

    # Prepare one miner
    tx = escrow.functions.setMinerInfo(miner, worker_stake).transact()
    testerchain.wait_for_receipt(tx)

    # Generate miner's Umbral key
    miner_umbral_private_key = UmbralPrivateKey.gen_key()
    miner_umbral_public_key_bytes = miner_umbral_private_key.get_pubkey(
    ).to_bytes(is_compressed=False)

    # Sign Umbral public key using eth-key
    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(miner_umbral_public_key_bytes)
    miner_umbral_public_key_hash = hash_ctx.finalize()
    provider = testerchain.interface.provider
    address = to_canonical_address(miner)
    sig_key = provider.ethereum_tester.backend._key_lookup[address]
    signed_miner_umbral_public_key = bytes(
        sig_key.sign_msg_hash(miner_umbral_public_key_hash))

    # Prepare hash of the data
    metadata = os.urandom(33)
    capsule, cfrag = fragments(metadata)

    assert cfrag.verify_correctness(capsule)

    capsule_bytes = capsule.to_bytes()
    cfrag_bytes = cfrag.to_bytes()

    # Bob prepares supporting Evidence
    evidence = IndisputableEvidence(capsule, cfrag, ursula=None)

    evidence_data = evidence.precompute_values()
    assert len(evidence_data) == 20 * 32 + 32 + 20 + 1

    # This check is a workaround in order to test the signature validation is correct.
    # In reality, this check should be part of the isCapsuleFragCorrect logic,
    # but we're facing with "Stack too deep" errors at the moment.
    # address = adjudicator_contract.functions.aliceAddress(cfrag_bytes, evidence_data).call()
    # assert address == to_checksum_address(evidence_data[-21:-1].hex())

    proof_challenge_scalar = int(evidence.get_proof_challenge_scalar())
    # computeProofChallengeScalar = adjudicator_contract.functions.computeProofChallengeScalar
    # assert proof_challenge_scalar == computeProofChallengeScalar(capsule_bytes, cfrag_bytes).call()

    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(capsule_bytes + cfrag_bytes)
    data_hash = hash_ctx.finalize()
    # This capsule and cFrag are not yet evaluated
    assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call()

    # Generate requester's Umbral key
    requester_umbral_private_key = UmbralPrivateKey.gen_key()
    requester_umbral_public_key_bytes = requester_umbral_private_key.get_pubkey(
    ).to_bytes(is_compressed=False)

    # Sign capsule and cFrag
    capsule_signature_by_requester = sign_data(capsule_bytes,
                                               requester_umbral_private_key)
    capsule_signature_by_requester_and_miner = sign_data(
        capsule_signature_by_requester, miner_umbral_private_key)
    cfrag_signature_by_miner = sign_data(cfrag_bytes, miner_umbral_private_key)

    # Challenge using good data
    args = (capsule_bytes, capsule_signature_by_requester,
            capsule_signature_by_requester_and_miner, cfrag_bytes,
            cfrag_signature_by_miner, requester_umbral_public_key_bytes,
            miner_umbral_public_key_bytes, signed_miner_umbral_public_key,
            evidence_data)

    assert worker_stake == escrow.functions.minerInfo(miner).call()[0]

    tx = adjudicator_contract.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1
    # Hash of the data is saved and miner was not slashed
    assert adjudicator_contract.functions.evaluatedCFrags(data_hash).call()
    assert worker_stake == escrow.functions.minerInfo(miner).call()[0]
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert miner == event_args['miner']
    assert investigator == event_args['investigator']
    assert event_args['correctness']

    # Test: Don't evaluate miner with data that already was checked
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(*args).transact()
        testerchain.wait_for_receipt(tx)

    # Test: Ursula produces incorrect proof:
    metadata = os.urandom(34)
    capsule, cfrag = fragments(metadata)
    capsule_bytes = capsule.to_bytes()
    # Corrupt proof
    cfrag.proof.bn_sig = CurveBN.gen_rand(capsule.params.curve)
    cfrag_bytes = cfrag.to_bytes()
    assert not cfrag.verify_correctness(capsule)

    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(capsule_bytes + cfrag_bytes)
    data_hash = hash_ctx.finalize()
    capsule_signature_by_requester = sign_data(capsule_bytes,
                                               requester_umbral_private_key)
    capsule_signature_by_requester_and_miner = sign_data(
        capsule_signature_by_requester, miner_umbral_private_key)
    cfrag_signature_by_miner = sign_data(cfrag_bytes, miner_umbral_private_key)
    evidence = IndisputableEvidence(capsule, cfrag, ursula=None)
    evidence_data = evidence.precompute_values()
    args = (capsule_bytes, capsule_signature_by_requester,
            capsule_signature_by_requester_and_miner, cfrag_bytes,
            cfrag_signature_by_miner, requester_umbral_public_key_bytes,
            miner_umbral_public_key_bytes, signed_miner_umbral_public_key,
            evidence_data)

    assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call()
    tx = adjudicator_contract.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1

    # Hash of the data is saved and miner was slashed
    assert adjudicator_contract.functions.evaluatedCFrags(data_hash).call()

    penalty, reward = compute_penalty_and_reward(worker_stake,
                                                 worker_penalty_history)
    worker_stake -= penalty
    investigator_balance += reward
    worker_penalty_history += 1

    assert worker_stake == escrow.functions.minerInfo(miner).call()[0]
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert miner == event_args['miner']
    assert investigator == event_args['investigator']
    assert not event_args['correctness']

    ###############################
    # Test: Bob produces wrong precomputed data
    ###############################

    metadata = os.urandom(34)
    capsule, cfrag = fragments(metadata)
    capsule_bytes = capsule.to_bytes()
    cfrag_bytes = cfrag.to_bytes()
    assert cfrag.verify_correctness(capsule)

    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(capsule_bytes + cfrag_bytes)
    data_hash = hash_ctx.finalize()
    capsule_signature_by_requester = sign_data(capsule_bytes,
                                               requester_umbral_private_key)
    capsule_signature_by_requester_and_miner = sign_data(
        capsule_signature_by_requester, miner_umbral_private_key)
    cfrag_signature_by_miner = sign_data(cfrag_bytes, miner_umbral_private_key)
    evidence = IndisputableEvidence(capsule, cfrag, ursula=None)
    evidence_data = evidence.precompute_values()

    # Bob produces a random point and gets the bytes of coords x and y
    random_point_bytes = Point.gen_rand().to_bytes(is_compressed=False)[1:]
    # He uses this garbage instead of correct precomputation of z*E
    evidence_data = bytearray(evidence_data)
    evidence_data[32:32 + 64] = random_point_bytes
    evidence_data = bytes(evidence_data)

    args = (capsule_bytes, capsule_signature_by_requester,
            capsule_signature_by_requester_and_miner, cfrag_bytes,
            cfrag_signature_by_miner, requester_umbral_public_key_bytes,
            miner_umbral_public_key_bytes, signed_miner_umbral_public_key,
            evidence_data)

    assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call()

    # Evaluation must fail since Bob precomputed wrong values
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(*args).transact(
            {'from': investigator})
        testerchain.wait_for_receipt(tx)

    ###############################
    # Test: Signatures and Metadata mismatch
    ###############################

    # TODO

    ###############################
    # Test: Second violation. Penalty is increased
    ###############################

    # Prepare hash of the data
    metadata = os.urandom(34)
    capsule, cfrag = fragments(metadata)
    capsule_bytes = capsule.to_bytes()
    # Corrupt proof
    cfrag.proof.bn_sig = CurveBN.gen_rand(capsule.params.curve)
    cfrag_bytes = cfrag.to_bytes()
    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(capsule_bytes + cfrag_bytes)
    data_hash = hash_ctx.finalize()
    capsule_signature_by_requester = sign_data(capsule_bytes,
                                               requester_umbral_private_key)
    capsule_signature_by_requester_and_miner = sign_data(
        capsule_signature_by_requester, miner_umbral_private_key)
    cfrag_signature_by_miner = sign_data(cfrag_bytes, miner_umbral_private_key)
    evidence = IndisputableEvidence(capsule, cfrag, ursula=None)
    evidence_data = evidence.precompute_values()
    args = [
        capsule_bytes, capsule_signature_by_requester,
        capsule_signature_by_requester_and_miner, cfrag_bytes,
        cfrag_signature_by_miner, requester_umbral_public_key_bytes,
        miner_umbral_public_key_bytes, signed_miner_umbral_public_key,
        evidence_data
    ]
    assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call()

    worker_stake = escrow.functions.minerInfo(miner).call()[0]
    investigator_balance = escrow.functions.rewardInfo(investigator).call()
    assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call()
    tx = adjudicator_contract.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1

    assert adjudicator_contract.functions.evaluatedCFrags(data_hash).call()

    previous_penalty = penalty
    penalty, reward = compute_penalty_and_reward(worker_stake,
                                                 worker_penalty_history)
    # Penalty was increased because it's the second violation
    assert penalty == previous_penalty + PENALTY_HISTORY_COEFFICIENT
    worker_stake -= penalty
    investigator_balance += reward
    worker_penalty_history += 1

    assert worker_stake == escrow.functions.minerInfo(miner).call()[0]
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert miner == event_args['miner']
    assert investigator == event_args['investigator']
    assert not event_args['correctness']

    ###############################
    # Test: Third violation. Penalty reaches the maximum allowed
    ###############################

    # Prepare corrupted data again
    capsule, cfrag = fragments(metadata)
    capsule_bytes = capsule.to_bytes()
    # Corrupt proof
    cfrag.proof.bn_sig = CurveBN.gen_rand(capsule.params.curve)
    cfrag_bytes = cfrag.to_bytes()
    hash_ctx = hashes.Hash(hashes.SHA256(), backend=backend)
    hash_ctx.update(capsule_bytes + cfrag_bytes)
    data_hash = hash_ctx.finalize()
    capsule_signature_by_requester = sign_data(capsule_bytes,
                                               requester_umbral_private_key)
    capsule_signature_by_requester_and_miner = sign_data(
        capsule_signature_by_requester, miner_umbral_private_key)
    cfrag_signature_by_miner = sign_data(cfrag_bytes, miner_umbral_private_key)
    evidence = IndisputableEvidence(capsule, cfrag, ursula=None)
    evidence_data = evidence.precompute_values()
    args = [
        capsule_bytes, capsule_signature_by_requester,
        capsule_signature_by_requester_and_miner, cfrag_bytes,
        cfrag_signature_by_miner, requester_umbral_public_key_bytes,
        miner_umbral_public_key_bytes, signed_miner_umbral_public_key,
        evidence_data
    ]

    worker_stake = escrow.functions.minerInfo(miner).call()[0]
    investigator_balance = escrow.functions.rewardInfo(investigator).call()
    assert not adjudicator_contract.functions.evaluatedCFrags(data_hash).call()
    tx = adjudicator_contract.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1

    assert adjudicator_contract.functions.evaluatedCFrags(data_hash).call()

    penalty, reward = compute_penalty_and_reward(worker_stake,
                                                 worker_penalty_history)
    # Penalty has reached maximum available percentage of value
    assert penalty == worker_stake // PERCENTAGE_PENALTY_COEFFICIENT
    worker_stake -= penalty
    investigator_balance += reward
    worker_penalty_history += 1

    assert worker_stake == escrow.functions.minerInfo(miner).call()[0]
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert miner == event_args['miner']
    assert investigator == event_args['investigator']
    assert not event_args['correctness']

    #################
    # Test: Invalid evaluations
    ##############

    # Can't evaluate miner using broken signatures
    wrong_args = args[:]
    wrong_args[1] = capsule_signature_by_requester[1:]
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)
    wrong_args = args[:]
    wrong_args[2] = capsule_signature_by_requester_and_miner[1:]
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)
    wrong_args = args[:]
    wrong_args[4] = cfrag_signature_by_miner[1:]
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)
    wrong_args = args[:]
    wrong_args[7] = signed_miner_umbral_public_key[1:]
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # Can't evaluate miner using wrong keys
    wrong_args = args[:]
    wrong_args[5] = UmbralPrivateKey.gen_key().get_pubkey().to_bytes(
        is_compressed=False)
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)
    wrong_args = args[:]
    wrong_args[6] = UmbralPrivateKey.gen_key().get_pubkey().to_bytes(
        is_compressed=False)
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # Can't use signature for another data
    wrong_args = args[:]
    wrong_args[0] = bytes(args[0][0] + 1) + args[0][1:]
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)
    wrong_args = args[:]
    wrong_args[3] = bytes(args[3][0] + 1) + args[3][1:]
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # Can't evaluate nonexistent miner
    address = to_canonical_address(wrong_miner)
    sig_key = provider.ethereum_tester.backend._key_lookup[address]
    signed_wrong_miner_umbral_public_key = bytes(
        sig_key.sign_msg_hash(miner_umbral_public_key_hash))
    wrong_args = args[:]
    wrong_args[7] = signed_wrong_miner_umbral_public_key
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator_contract.functions.evaluateCFrag(
            *wrong_args).transact()
        testerchain.wait_for_receipt(tx)
Beispiel #24
0
def test_validate_cfrag(testerchain, reencryption_validator,
                        mock_ursula_reencrypts):
    ursula_privkey = UmbralPrivateKey.gen_key()
    ursula_stamp = SignatureStamp(verifying_key=ursula_privkey.pubkey,
                                  signer=Signer(ursula_privkey))
    ursula = Mock(stamp=ursula_stamp)

    ###############################
    # Test: Ursula produces correct proof:
    ###############################

    # Bob prepares supporting Evidence
    evidence = mock_ursula_reencrypts(ursula)
    evidence_data = evidence.precompute_values()
    assert len(evidence_data) == 20 * 32 + 32 + 20 + 5

    # Challenge using good data
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    capsule_bytes = capsule.to_bytes()
    cfrag_bytes = cfrag.to_bytes()
    args = (capsule_bytes, cfrag_bytes, evidence_data)
    assert reencryption_validator.functions.validateCFrag(*args).call()

    ###############################
    # Test: Ursula produces incorrect proof:
    ###############################
    evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    capsule_bytes = capsule.to_bytes()
    cfrag_bytes = cfrag.to_bytes()
    assert not cfrag.verify_correctness(capsule)

    evidence_data = evidence.precompute_values()
    args = (capsule_bytes, cfrag_bytes, evidence_data)
    assert not reencryption_validator.functions.validateCFrag(*args).call()

    ###############################
    # Test: Bob produces wrong precomputed data
    ###############################
    evidence = mock_ursula_reencrypts(ursula)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    capsule_bytes = capsule.to_bytes()
    cfrag_bytes = cfrag.to_bytes()
    assert cfrag.verify_correctness(capsule)

    evidence_data = evidence.precompute_values()

    # Bob produces a random point and gets the bytes of coords x and y
    random_point_bytes = Point.gen_rand().to_bytes(is_compressed=False)[1:]
    # He uses this garbage instead of correct precomputation of z*E
    evidence_data = bytearray(evidence_data)
    evidence_data[32:32 + 64] = random_point_bytes
    evidence_data = bytes(evidence_data)

    args = (capsule_bytes, cfrag_bytes, evidence_data)

    # Evaluation must fail since Bob precomputed wrong values
    with pytest.raises(TransactionFailed):
        _ = reencryption_validator.functions.validateCFrag(*args).call()
Beispiel #25
0
def test_evaluate_cfrag(testerchain, escrow, adjudicator, token_economics,
                        blockchain_ursulas, mock_ursula_reencrypts):
    ursula = list(blockchain_ursulas)[0]

    creator, non_staker, investigator, *everyone_else = testerchain.client.accounts
    evaluation_log = adjudicator.events.CFragEvaluated.createFilter(
        fromBlock='latest')
    verdict_log = adjudicator.events.IncorrectCFragVerdict.createFilter(
        fromBlock='latest')

    worker_stake = 1000
    worker_penalty_history = 0
    investigator_balance = 0
    number_of_evaluations = 0

    def compute_penalty_and_reward(stake: int,
                                   penalty_history: int) -> Tuple[int, int]:
        penalty_ = token_economics.base_penalty
        penalty_ += token_economics.penalty_history_coefficient * penalty_history
        penalty_ = min(penalty_,
                       stake // token_economics.percentage_penalty_coefficient)
        reward_ = penalty_ // token_economics.reward_coefficient
        return penalty_, reward_

    # Prepare one staker
    staker = ursula.checksum_address
    tx = escrow.functions.setStakerInfo(staker, worker_stake,
                                        ursula.worker_address).transact()
    testerchain.wait_for_receipt(tx)

    assert ursula._stamp_has_valid_signature_by_worker()

    # Prepare evaluation data
    evidence = mock_ursula_reencrypts(ursula)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    assert cfrag.verify_correctness(capsule)

    evidence_data = evidence.precompute_values()
    assert len(evidence_data) == 20 * 32 + 32 + 20 + 5

    data_hash = sha256_digest(capsule, cfrag)
    # This capsule and cFrag are not yet evaluated
    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()

    args = list(evidence.evaluation_arguments())

    # Challenge using good data
    assert worker_stake == escrow.functions.getAllTokens(staker).call()

    tx = adjudicator.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1
    # Hash of the data is saved and staker was not slashed
    assert adjudicator.functions.evaluatedCFrags(data_hash).call()
    assert worker_stake == escrow.functions.getAllTokens(staker).call()
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert investigator == event_args['investigator']
    assert event_args['correctness']
    assert 0 == len(verdict_log.get_all_entries())

    ###############################
    # Test: Don't evaluate staker with data that already was checked
    ###############################
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*args).transact()
        testerchain.wait_for_receipt(tx)

    ###############################
    # Test: Ursula produces incorrect proof:
    ###############################
    evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    assert not cfrag.verify_correctness(capsule)

    args = list(evidence.evaluation_arguments())

    data_hash = sha256_digest(capsule, cfrag)
    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()

    tx = adjudicator.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1

    # Hash of the data is saved and staker was slashed
    assert adjudicator.functions.evaluatedCFrags(data_hash).call()

    penalty, reward = compute_penalty_and_reward(worker_stake,
                                                 worker_penalty_history)
    worker_stake -= penalty
    investigator_balance += reward
    worker_penalty_history += 1

    assert worker_stake == escrow.functions.getAllTokens(staker).call()
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert investigator == event_args['investigator']
    assert not event_args['correctness']
    events = verdict_log.get_all_entries()
    assert number_of_evaluations - 1 == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert ursula.worker_address == event_args['worker']
    assert staker == event_args['staker']

    ###############################
    # Test: Bob produces wrong precomputed data
    ###############################

    evidence = mock_ursula_reencrypts(ursula)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    assert cfrag.verify_correctness(capsule)

    # Bob produces a random point and gets the bytes of coords x and y
    random_point_bytes = Point.gen_rand().to_bytes(is_compressed=False)[1:]
    # He uses this garbage instead of correct precomputation of z*E
    evidence_data = bytearray(evidence_data)
    evidence_data[32:32 + 64] = random_point_bytes
    evidence_data = bytes(evidence_data)

    args = list(evidence.evaluation_arguments())
    args[-1] = evidence_data

    data_hash = sha256_digest(capsule, cfrag)
    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()

    # Evaluation must fail since Bob precomputed wrong values
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*args).transact(
            {'from': investigator})
        testerchain.wait_for_receipt(tx)

    ###############################
    # Test: Second violation. Penalty is increased
    ###############################

    evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    assert not cfrag.verify_correctness(capsule)

    args = list(evidence.evaluation_arguments())

    data_hash = sha256_digest(capsule, cfrag)
    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()

    worker_stake = escrow.functions.getAllTokens(staker).call()
    investigator_balance = escrow.functions.rewardInfo(investigator).call()

    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()
    tx = adjudicator.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1

    assert adjudicator.functions.evaluatedCFrags(data_hash).call()

    previous_penalty = penalty
    penalty, reward = compute_penalty_and_reward(worker_stake,
                                                 worker_penalty_history)
    # Penalty was increased because it's the second violation
    assert penalty == previous_penalty + token_economics.penalty_history_coefficient
    worker_stake -= penalty
    investigator_balance += reward
    worker_penalty_history += 1

    assert worker_stake == escrow.functions.getAllTokens(staker).call()
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert investigator == event_args['investigator']
    assert not event_args['correctness']
    events = verdict_log.get_all_entries()
    assert number_of_evaluations - 1 == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert ursula.worker_address == event_args['worker']
    assert staker == event_args['staker']

    ###############################
    # Test: Third violation. Penalty reaches the maximum allowed
    ###############################

    evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    assert not cfrag.verify_correctness(capsule)

    args = list(evidence.evaluation_arguments())

    data_hash = sha256_digest(capsule, cfrag)
    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()

    worker_stake = escrow.functions.getAllTokens(staker).call()
    investigator_balance = escrow.functions.rewardInfo(investigator).call()

    tx = adjudicator.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1

    assert adjudicator.functions.evaluatedCFrags(data_hash).call()

    penalty, reward = compute_penalty_and_reward(worker_stake,
                                                 worker_penalty_history)
    # Penalty has reached maximum available percentage of value
    assert penalty == worker_stake // token_economics.percentage_penalty_coefficient
    worker_stake -= penalty
    investigator_balance += reward
    worker_penalty_history += 1

    assert worker_stake == escrow.functions.getAllTokens(staker).call()
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert investigator == event_args['investigator']
    assert not event_args['correctness']
    events = verdict_log.get_all_entries()
    assert number_of_evaluations - 1 == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert ursula.worker_address == event_args['worker']
    assert staker == event_args['staker']

    #################
    # Test: Invalid evaluations
    ##############

    evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    assert not cfrag.verify_correctness(capsule)

    args = list(evidence.evaluation_arguments())

    data_hash = sha256_digest(capsule, cfrag)
    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()

    # Can't evaluate staker using broken signatures
    wrong_args = list(args)
    wrong_args[2] = evidence.task.cfrag_signature[1:]
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    wrong_args = list(args)
    wrong_args[3] = evidence.task.signature[1:]
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    wrong_args = list(args)
    wrong_args[7] = wrong_args[7][1:]
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # Can't evaluate staker using wrong keys
    wrong_args = list(args)
    wrong_args[5] = UmbralPrivateKey.gen_key().get_pubkey().to_bytes(
        is_compressed=False)[1:]
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    wrong_args = list(args)
    wrong_args[6] = UmbralPrivateKey.gen_key().get_pubkey().to_bytes(
        is_compressed=False)[1:]
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # Can't use signature for another data
    wrong_args = list(args)
    wrong_args[1] = os.urandom(len(bytes(cfrag)))
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # Can't evaluate nonexistent staker
    signed_stamp = testerchain.client.sign_message(account=non_staker,
                                                   message=bytes(ursula.stamp))

    wrong_args = list(args)
    wrong_args[7] = signed_stamp
    with pytest.raises(TransactionFailed):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # Can't evaluate staker without tokens
    tx = escrow.functions.setStakerInfo(non_staker, 0,
                                        ursula.worker_address).transact()
    testerchain.wait_for_receipt(tx)
    with pytest.raises((TransactionFailed, ValueError)):
        tx = adjudicator.functions.evaluateCFrag(*wrong_args).transact()
        testerchain.wait_for_receipt(tx)

    # If the non-staker starts to stake, then she can be slashed
    new_staker = non_staker
    tx = escrow.functions.setStakerInfo(new_staker, worker_stake,
                                        ursula.worker_address).transact()
    testerchain.wait_for_receipt(tx)

    evidence = mock_ursula_reencrypts(ursula, corrupt_cfrag=True)
    capsule = evidence.task.capsule
    cfrag = evidence.task.cfrag
    assert not cfrag.verify_correctness(capsule)

    args = list(evidence.evaluation_arguments())
    data_hash = sha256_digest(capsule, cfrag)
    assert not adjudicator.functions.evaluatedCFrags(data_hash).call()

    tx = adjudicator.functions.evaluateCFrag(*args).transact(
        {'from': investigator})
    testerchain.wait_for_receipt(tx)
    number_of_evaluations += 1

    assert adjudicator.functions.evaluatedCFrags(data_hash).call()

    penalty, reward = compute_penalty_and_reward(worker_stake,
                                                 worker_penalty_history)
    worker_stake -= penalty
    investigator_balance += reward
    worker_penalty_history += 1

    assert worker_stake == escrow.functions.getAllTokens(new_staker).call()
    assert investigator_balance == escrow.functions.rewardInfo(
        investigator).call()

    events = evaluation_log.get_all_entries()
    assert number_of_evaluations == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert investigator == event_args['investigator']
    assert not event_args['correctness']
    events = verdict_log.get_all_entries()
    assert number_of_evaluations - 1 == len(events)
    event_args = events[-1]['args']
    assert data_hash == event_args['evaluationHash']
    assert ursula.worker_address == event_args['worker']
    assert new_staker == event_args['staker']
Beispiel #26
0
def _generate_signing_keys() -> Tuple[UmbralPrivateKey, UmbralPublicKey]:
    """
    """
    privkey = UmbralPrivateKey.gen_key()
    pubkey = privkey.get_pubkey()
    return privkey, pubkey
Beispiel #27
0
alice_config = AliceConfiguration(
   config_root=os.path.join(TEMP_ALICE_DIR),
   domains={TEMPORARY_DOMAIN},
   known_nodes={ursula},
   start_learning_now=False,
   federated_only=True,
   learn_on_same_thread=True,
)
alice_config.initialize(password=passphrase)
alice_config.keyring.unlock(password=passphrase)
alicia = alice_config.produce()
# We will save Alicia’s config to a file for later use
alice_config_file = alice_config.to_configuration_file()
# Let’s get to learn about the NuCypher network
alicia.start_learning_loop(now=True)
enc_privkey = UmbralPrivateKey.gen_key()
sig_privkey = UmbralPrivateKey.gen_key()


print(enc_privkey.to_bytes().hex())
print(enc_privkey.get_pubkey().to_bytes().hex())
verifying_key = UmbralPublicKey.from_hex(enc_privkey.get_pubkey().to_bytes().hex()),
encrypting_key = UmbralPublicKey.from_hex(sig_privkey.get_pubkey().to_bytes().hex())

label = "QmVahkTzLmU88CayjyZrRvqX78BmjjqH4iW26tNPvYQ18M"
label = label.encode()

policy_pubkey = alicia.get_policy_encrypting_key_from_label(label)
print("The policy public key for "
      "label '{}' is {}".format(label.decode("utf-8"), policy_pubkey.to_bytes().hex()))
Beispiel #28
0
def _generate_encryption_keys() -> Tuple[UmbralPrivateKey, UmbralPublicKey]:
    """Use pyUmbral keys to generate a new encrypting key pair"""
    privkey = UmbralPrivateKey.gen_key()
    pubkey = privkey.get_pubkey()
    return privkey, pubkey
    except FileExistsError:
        pass


# If True, this will overwrite existing test vector files with new randomly generated instances
generate_again = False

#########
# SETUP #
#########
set_default_curve()
params = default_params()
curve = params.curve

# We create also some Umbral objects for later
delegating_privkey = UmbralPrivateKey.gen_key(params=params)
receiving_privkey = UmbralPrivateKey.gen_key(params=params)
signing_privkey = UmbralPrivateKey.gen_key(params=params)

verifying_key = signing_privkey.get_pubkey()
delegating_key = delegating_privkey.get_pubkey()
receiving_key = receiving_privkey.get_pubkey()

signer = Signer(signing_privkey)

kfrags = pre.generate_kfrags(delegating_privkey=delegating_privkey,
                             receiving_pubkey=receiving_key,
                             threshold=6,
                             N=10,
                             signer=signer,
                             )
Beispiel #30
0
def test_signature_can_verify():
    privkey = UmbralPrivateKey.gen_key()
    message = b"attack at dawn"
    der_sig_bytes = ecdsa_sign(message, privkey)
    signature = Signature.from_bytes(der_sig_bytes, der_encoded=True)
    assert signature.verify(message, privkey.get_pubkey())