Minimal fixes to make CI pass, using an adapter for Umbral

pull/2612/head
Bogdan Opanchuk 2021-03-23 21:45:51 -07:00
parent 71af0f062b
commit e6fcdbbff6
50 changed files with 153 additions and 297 deletions

View File

@ -24,7 +24,7 @@ import msgpack
import os
import shutil
import sys
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.characters.lawful import Bob, Enrico, Ursula
from nucypher.config.constants import TEMPORARY_DOMAIN

View File

@ -17,7 +17,7 @@
import json
import os
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, UmbralPublicKey
DOCTOR_PUBLIC_JSON = 'doctor.public.json'
DOCTOR_PRIVATE_JSON = 'doctor.private.json'

View File

@ -24,10 +24,3 @@ from nucypher.__about__ import (
__all__ = [
"__title__", "__summary__", "__version__", "__author__", "__license__", "__copyright__", "__email__", "__url__"
]
# Set Default Curve #
#####################
from umbral.config import set_default_curve
set_default_curve()

View File

@ -34,8 +34,7 @@ from cryptography.exceptions import InvalidSignature
from eth_keys import KeyAPI as EthKeyAPI
from eth_utils import to_canonical_address, to_checksum_address
from typing import ClassVar, Dict, List, Optional, Union
from umbral.keys import UmbralPublicKey
from umbral.signing import Signature
from nucypher.crypto.umbral_adapter import UmbralPublicKey, Signature
from nucypher.acumen.nicknames import Nickname
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
@ -56,8 +55,8 @@ from nucypher.crypto.powers import (
from nucypher.crypto.signing import (
SignatureStamp,
StrangerStamp,
signature_splitter
)
from nucypher.crypto.splitters import signature_splitter
from nucypher.network.middleware import RestMiddleware
from nucypher.network.nodes import Learner
@ -505,9 +504,7 @@ class Character(Learner):
def derive_federated_address(self):
if self.federated_only:
verifying_key = self.public_keys(SigningPower)
uncompressed_bytes = verifying_key.to_bytes(is_compressed=False)
without_prefix = uncompressed_bytes[1:]
verifying_key_as_eth_key = EthKeyAPI.PublicKey(without_prefix)
verifying_key_as_eth_key = EthKeyAPI.PublicKey.from_compressed_bytes(bytes(verifying_key))
federated_address = verifying_key_as_eth_key.to_checksum_address()
else:
raise RuntimeError('Federated address can only be derived for federated characters.')

View File

@ -18,7 +18,7 @@
import functools
import maya
from typing import Union
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.characters.control.specifications import alice, bob, enrico
from nucypher.crypto.kits import UmbralMessageKit

View File

@ -16,7 +16,7 @@
"""
from marshmallow import fields
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.characters.control.specifications.exceptions import InvalidInputData, InvalidNativeDataTypes
from nucypher.characters.control.specifications.fields.base import BaseField

View File

@ -18,7 +18,7 @@
from base64 import b64decode, b64encode
from marshmallow import fields
from umbral.signing import Signature
from nucypher.crypto.umbral_adapter import Signature
from nucypher.characters.control.specifications.exceptions import InvalidInputData, InvalidNativeDataTypes
from nucypher.characters.control.specifications.fields.base import BaseField

View File

@ -25,6 +25,7 @@ from nucypher.characters.control.specifications.fields.base import BaseField
from nucypher.crypto.constants import HRAC_LENGTH
from nucypher.crypto.kits import UmbralMessageKit
from nucypher.crypto.signing import Signature
from nucypher.crypto.splitters import signature_splitter
class TreasureMap(BaseField, fields.Field):
@ -40,7 +41,7 @@ class TreasureMap(BaseField, fields.Field):
def _validate(self, value):
splitter = BytestringSplitter(Signature,
splitter = BytestringSplitter(signature_splitter,
(bytes, HRAC_LENGTH), # hrac
(UmbralMessageKit, VariableLengthBytestring)
) # TODO: USe the one from TMap

View File

@ -56,10 +56,7 @@ from twisted.internet.defer import Deferred
from twisted.internet.task import LoopingCall
from twisted.logger import Logger
from typing import Dict, Iterable, List, NamedTuple, Tuple, Union, Optional, Sequence, Set, Any
from umbral import pre
from umbral.keys import UmbralPublicKey
from umbral.kfrags import KFrag
from umbral.signing import Signature
from nucypher.crypto.umbral_adapter import UmbralPublicKey, VerifiedKeyFrag, Signature, pre, VerificationError
import nucypher
from nucypher.acumen.nicknames import Nickname
@ -79,7 +76,7 @@ from nucypher.cli.processes import UrsulaCommandProtocol
from nucypher.config.constants import END_OF_POLICIES_PROBATIONARY_PERIOD
from nucypher.config.storages import ForgetfulNodeStorage, NodeStorage
from nucypher.crypto.api import encrypt_and_sign, keccak_digest
from nucypher.crypto.constants import HRAC_LENGTH, PUBLIC_KEY_LENGTH
from nucypher.crypto.constants import HRAC_LENGTH
from nucypher.crypto.keypairs import HostingKeypair
from nucypher.crypto.kits import UmbralMessageKit
from nucypher.crypto.powers import (
@ -90,6 +87,7 @@ from nucypher.crypto.powers import (
TransactingPower
)
from nucypher.crypto.signing import InvalidSignature
from nucypher.crypto.splitters import key_splitter, signature_splitter
from nucypher.datastore.datastore import DatastoreTransactionError, RecordNotFound
from nucypher.datastore.queries import find_expired_policies, find_expired_treasure_maps
from nucypher.network.exceptions import NodeSeemsToBeDown
@ -808,16 +806,22 @@ class Bob(Character):
self._completed_work_orders.save_work_order(work_order, as_replete=retain_cfrags)
the_airing_of_grievances = []
verified_cfrags = []
for capsule, pre_task in work_order.tasks.items():
if not pre_task.cfrag.verify_correctness(capsule):
try:
verified_cfrag = pre_task.cfrag.verify_correctness(capsule)
except VerificationError:
# TODO: WARNING - This block is untested.
# I got a lot of problems with you people ...
the_airing_of_grievances.append(work_order.ursula)
else:
verified_cfrags.append(verified_cfrag) # FIXME: this is unused
pre_task.cfrag = verified_cfrag # FIXME: massive yikes, needs to be done properly
if the_airing_of_grievances:
return False, the_airing_of_grievances
else:
return True, cfrags
return True, verified_cfrags
def retrieve(self,
@ -1568,13 +1572,13 @@ class Ursula(Teacher, Character, Worker):
public_address=ETH_ADDRESS_BYTE_LENGTH,
domain=VariableLengthBytestring,
timestamp=(int, 4, {'byteorder': 'big'}),
interface_signature=Signature,
interface_signature=signature_splitter,
# FIXME: Fixed length doesn't work with federated. It was LENGTH_ECDSA_SIGNATURE_WITH_RECOVERY,
decentralized_identity_evidence=VariableLengthBytestring,
verifying_key=(UmbralPublicKey, PUBLIC_KEY_LENGTH),
encrypting_key=(UmbralPublicKey, PUBLIC_KEY_LENGTH),
verifying_key=key_splitter,
encrypting_key=key_splitter,
certificate=(load_pem_x509_certificate, VariableLengthBytestring, {"backend": default_backend()}),
rest_interface=InterfaceInfo,
)
@ -1727,26 +1731,24 @@ class Ursula(Teacher, Character, Worker):
# Re-Encryption
#
def _reencrypt(self, kfrag: KFrag, work_order: 'WorkOrder', alice_verifying_key: UmbralPublicKey):
def _reencrypt(self, kfrag: VerifiedKeyFrag, work_order: 'WorkOrder', alice_verifying_key: UmbralPublicKey):
# Prepare a bytestring for concatenating re-encrypted
# capsule data for each work order task.
cfrag_byte_stream = bytes()
for capsule, task in work_order.tasks.items():
# Ursula signs on top of Bob's signature of each task.
# Now both are committed to the same task. See #259.
reencryption_metadata = bytes(self.stamp(bytes(task.signature)))
# See #259 for the discussion leading to the current protocol.
# Ursula sets Alice's verifying key for capsule correctness verification.
capsule.set_correctness_keys(verifying=alice_verifying_key)
# Then re-encrypts the fragment.
cfrag = pre.reencrypt(kfrag, capsule, metadata=reencryption_metadata) # <--- pyUmbral
cfrag = pre.reencrypt(kfrag, capsule) # <--- pyUmbral
self.log.info(f"Re-encrypted capsule {capsule} -> made {cfrag}.")
# Next, Ursula signs to commit to her results.
reencryption_signature = self.stamp(bytes(cfrag))
cfrag_byte_stream += VariableLengthBytestring(cfrag) + reencryption_signature
cfrag_byte_stream += bytes(cfrag) + bytes(reencryption_signature)
# ... and finally returns all the re-encrypted bytes
return cfrag_byte_stream

View File

@ -17,7 +17,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
import click
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.characters.control.interfaces import EnricoInterface
from nucypher.characters.lawful import Enrico

View File

@ -20,7 +20,7 @@ from cryptography.exceptions import InternalError
from decimal import Decimal, DecimalException
from eth_utils import to_checksum_address
from ipaddress import ip_address
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.blockchain.economics import StandardTokenEconomics
from nucypher.blockchain.eth.interfaces import BlockchainInterface

View File

@ -34,7 +34,6 @@ from constant_sorrow.constants import (
LIVE_CONFIGURATION
)
from eth_utils.address import is_checksum_address
from umbral.signing import Signature
from nucypher.blockchain.eth.interfaces import BlockchainInterfaceFactory
from nucypher.blockchain.eth.networks import NetworksInventory
@ -53,6 +52,7 @@ from nucypher.config.storages import (
NodeStorage
)
from nucypher.crypto.powers import CryptoPower, CryptoPowerUp
from nucypher.crypto.umbral_adapter import Signature
from nucypher.network.middleware import RestMiddleware
from nucypher.utilities.logging import Logger

View File

@ -33,20 +33,17 @@ from cryptography.hazmat.backends.openssl.ec import _EllipticCurvePrivateKey
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.asymmetric.ec import EllipticCurve
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives.serialization import Encoding, load_pem_private_key
from cryptography.x509 import Certificate
from eth_account import Account
from eth_keys import KeyAPI as EthKeyAPI
from eth_utils import to_checksum_address
from nacl.exceptions import CryptoError
from nacl.secret import SecretBox
from umbral.keys import UmbralKeyingMaterial, UmbralPrivateKey, UmbralPublicKey, derive_key_from_password
from nucypher.crypto.umbral_adapter import UmbralKeyingMaterial, UmbralPrivateKey, UmbralPublicKey, derive_key_from_password, AuthenticationFailed
from nucypher.config.constants import DEFAULT_CONFIG_ROOT
from nucypher.crypto.api import generate_teacher_certificate, _TLS_CURVE
from nucypher.crypto.constants import BLAKE2B
from nucypher.crypto.keypairs import HostingKeypair
from nucypher.crypto.passwords import derive_wrapping_key_from_key_material, SecretBox
from nucypher.crypto.powers import (DecryptingPower, DerivedKeyBasedPower, KeyPairBasedPower, SigningPower)
from nucypher.network.server import TLSHostingPower
from nucypher.utilities.logging import Logger
@ -411,11 +408,11 @@ class NucypherKeyring:
def __decrypt_keyfile(self, key_path: str) -> UmbralPrivateKey:
"""Returns plaintext version of decrypting key."""
key_data = _read_keyfile(key_path, deserializer=_deserialize_private_key)
wrap_key = _derive_wrapping_key_from_key_material(salt=key_data['wrap_salt'],
key_material=self.__derived_key_material)
wrap_key = derive_wrapping_key_from_key_material(salt=key_data['wrap_salt'],
key_material=self.__derived_key_material)
try:
plain_umbral_key = UmbralPrivateKey.from_bytes(key_bytes=key_data['key'], wrapping_key=wrap_key)
except CryptoError:
except AuthenticationFailed:
raise self.AuthenticationFailed('Invalid or incorrect nucypher keyring password.')
return plain_umbral_key
@ -440,14 +437,9 @@ class NucypherKeyring:
return self.is_unlocked
key_data = _read_keyfile(keypath=self.__root_keypath, deserializer=_deserialize_private_key)
self.log.info("Unlocking keyring.")
try:
derived_key = derive_key_from_password(password=password.encode(), salt=key_data['master_salt'])
except CryptoError:
self.log.info("Keyring unlock failed.")
raise self.AuthenticationFailed
else:
self.__derived_key_material = derived_key
self.log.info("Finished unlocking.")
derived_key = derive_key_from_password(password=password.encode(), salt=key_data['master_salt'])
self.__derived_key_material = derived_key
self.log.info("Finished unlocking.")
return self.is_unlocked
@unlock_required
@ -490,7 +482,7 @@ class NucypherKeyring:
# Derived
elif issubclass(power_class, DerivedKeyBasedPower):
key_data = _read_keyfile(self.__delegating_keypath, deserializer=_deserialize_private_key)
wrap_key = _derive_wrapping_key_from_key_material(salt=key_data['wrap_salt'], key_material=self.__derived_key_material)
wrap_key = derive_wrapping_key_from_key_material(salt=key_data['wrap_salt'], key_material=self.__derived_key_material)
keying_material = SecretBox(wrap_key).decrypt(key_data['key'])
new_cryptopower = power_class(keying_material=keying_material)
@ -551,9 +543,7 @@ class NucypherKeyring:
signing_private_key, signing_public_key = _generate_signing_keys()
if checksum_address is FEDERATED_ADDRESS:
uncompressed_bytes = signing_public_key.to_bytes(is_compressed=False)
without_prefix = uncompressed_bytes[1:]
verifying_key_as_eth_key = EthKeyAPI.PublicKey(without_prefix)
verifying_key_as_eth_key = EthKeyAPI.PublicKey.from_compressed_bytes(bytes(signing_public_key))
checksum_address = verifying_key_as_eth_key.to_checksum_address()
else:
@ -576,9 +566,9 @@ class NucypherKeyring:
cls.log.info("About to derive key from password.")
derived_key_material = derive_key_from_password(salt=password_salt, password=password.encode())
encrypting_wrap_key = _derive_wrapping_key_from_key_material(salt=encrypting_salt, key_material=derived_key_material)
signature_wrap_key = _derive_wrapping_key_from_key_material(salt=signing_salt, key_material=derived_key_material)
delegating_wrap_key = _derive_wrapping_key_from_key_material(salt=delegating_salt, key_material=derived_key_material)
encrypting_wrap_key = derive_wrapping_key_from_key_material(salt=encrypting_salt, key_material=derived_key_material)
signature_wrap_key = derive_wrapping_key_from_key_material(salt=signing_salt, key_material=derived_key_material)
delegating_wrap_key = derive_wrapping_key_from_key_material(salt=delegating_salt, key_material=derived_key_material)
# Encapsulate Private Keys
encrypting_key_data = encrypting_private_key.to_bytes(wrapping_key=encrypting_wrap_key)

View File

@ -35,9 +35,7 @@ from eth_utils import is_checksum_address, to_checksum_address
from ipaddress import IPv4Address
from random import SystemRandom
from typing import Tuple
from umbral import pre
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from umbral.signing import Signature
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, UmbralPublicKey, Signature, pre
from nucypher.crypto.constants import SHA256
from nucypher.crypto.kits import UmbralMessageKit
@ -245,7 +243,7 @@ def encrypt_and_sign(recipient_pubkey_enc: UmbralPublicKey,
# Sign first, encrypt second.
sig_header = constants.SIGNATURE_TO_FOLLOW
signature = signer(plaintext)
ciphertext, capsule = pre.encrypt(recipient_pubkey_enc, sig_header + signature + plaintext)
ciphertext, capsule = pre.encrypt(recipient_pubkey_enc, sig_header + bytes(signature) + plaintext)
else:
# Encrypt first, sign second.
sig_header = constants.SIGNATURE_IS_ON_CIPHERTEXT

View File

@ -27,7 +27,3 @@ BLAKE2B_DIGEST_LENGTH = 64
# Hashes
SHA256 = hashes.SHA256()
BLAKE2B = hashes.BLAKE2b(64)
# SECP256K1
CAPSULE_LENGTH = 98
PUBLIC_KEY_LENGTH = 33

View File

@ -24,9 +24,7 @@ from constant_sorrow import constants
from cryptography.hazmat.primitives.asymmetric import ec
from hendrix.deploy.tls import HendrixDeployTLS
from hendrix.facilities.services import ExistingKeyTLSContextFactory
from umbral import pre
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from umbral.signing import Signature, Signer
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, UmbralPublicKey, Signature, Signer, pre
from nucypher.config.constants import MAX_UPLOAD_CONTENT_LENGTH
from nucypher.crypto import api as API
@ -67,16 +65,14 @@ class Keypair(object):
raise ValueError(
"Either pass a valid key or, if you want to generate keys, set generate_keys_if_needed to True.")
def serialize_pubkey(self, as_b64=False) -> bytes:
def serialize_pubkey(self) -> bytes:
"""
Serializes the pubkey for storage/transport in either urlsafe base64
or as a bytestring.
:param as_b64: Return the pubkey as urlsafe base64 byte string
:return: The serialized pubkey in bytes
"""
encoder = base64.urlsafe_b64encode if as_b64 else None
return self.pubkey.to_bytes(encoder=encoder)
return self.pubkey.to_bytes()
def fingerprint(self):
"""

View File

@ -19,7 +19,7 @@ from typing import Optional
from bytestring_splitter import BytestringKwargifier, VariableLengthBytestring
from constant_sorrow.constants import NOT_SIGNED, UNKNOWN_SENDER
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.crypto.splitters import capsule_splitter, key_splitter

View File

@ -20,8 +20,7 @@ import inspect
from eth_typing.evm import ChecksumAddress
from hexbytes import HexBytes
from typing import List, Optional, Tuple
from umbral import pre
from umbral.keys import UmbralKeyingMaterial, UmbralPrivateKey, UmbralPublicKey
from nucypher.crypto.umbral_adapter import pre, UmbralKeyingMaterial, UmbralPrivateKey, UmbralPublicKey
from nucypher.blockchain.eth.decorators import validate_checksum_address
from nucypher.blockchain.eth.signers.base import Signer

View File

@ -17,12 +17,10 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
from bytestring_splitter import BytestringSplitter
from umbral.signing import Signature, Signer
from nucypher.crypto.umbral_adapter import Signature, Signer
from nucypher.crypto.api import keccak_digest
signature_splitter = BytestringSplitter(Signature)
class SignatureStamp(object):
"""

View File

@ -17,13 +17,9 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
from bytestring_splitter import BytestringSplitter, VariableLengthBytestring
from umbral.cfrags import CapsuleFrag
from umbral.config import default_params
from umbral.keys import UmbralPublicKey
from umbral.pre import Capsule
from nucypher.crypto.umbral_adapter import CapsuleFrag, UmbralPublicKey, Capsule, Signature
from nucypher.crypto.constants import CAPSULE_LENGTH, PUBLIC_KEY_LENGTH
key_splitter = BytestringSplitter((UmbralPublicKey, PUBLIC_KEY_LENGTH))
capsule_splitter = BytestringSplitter((Capsule, CAPSULE_LENGTH, {"params": default_params()}))
cfrag_splitter = BytestringSplitter((CapsuleFrag, VariableLengthBytestring))
key_splitter = BytestringSplitter((UmbralPublicKey, UmbralPublicKey.serialized_size()))
capsule_splitter = BytestringSplitter((Capsule, Capsule.serialized_size()))
cfrag_splitter = BytestringSplitter((CapsuleFrag, CapsuleFrag.serialized_size()))
signature_splitter = BytestringSplitter((Signature, Signature.serialized_size()))

View File

@ -239,12 +239,11 @@ class CapsuleFrag(umbral.CapsuleFrag):
def to_bytes(self):
return bytes(self)
def verify_correctness(self, capsule, metadata=None):
def verify_correctness(self, capsule):
keys = capsule.get_correctness_keys()
return self.verify(
capsule._capsule,
verifying_pk=keys['verifying'], delegating_pk=keys['delegating'], receiving_pk=keys['receiving'],
metadata=metadata)
verifying_pk=keys['verifying'], delegating_pk=keys['delegating'], receiving_pk=keys['receiving'])
# Adapter for standalone functions
@ -253,9 +252,9 @@ class PRE:
GenericUmbralError = umbral.GenericError
@staticmethod
def reencrypt(kfrag, capsule, metadata=None):
def reencrypt(kfrag, capsule):
assert isinstance(capsule, Capsule)
cf = umbral.reencrypt(capsule._capsule, kfrag, metadata=metadata)
cf = umbral.reencrypt(capsule._capsule, kfrag)
return cf
@staticmethod

View File

@ -18,7 +18,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
from coincurve import PublicKey
from eth_keys import KeyAPI as EthKeyAPI
from typing import Any, Union
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.crypto.api import keccak_digest
from nucypher.crypto.signing import SignatureStamp
@ -43,7 +43,7 @@ def construct_policy_id(label: bytes, stamp: bytes) -> bytes:
def canonical_address_from_umbral_key(public_key: Union[UmbralPublicKey, SignatureStamp]) -> bytes:
if isinstance(public_key, SignatureStamp):
public_key = public_key.as_umbral_pubkey()
pubkey_compressed_bytes = public_key.to_bytes(is_compressed=True)
pubkey_compressed_bytes = bytes(public_key)
eth_pubkey = EthKeyAPI.PublicKey.from_compressed_bytes(pubkey_compressed_bytes)
canonical_address = eth_pubkey.to_canonical_address()
return canonical_address

View File

@ -15,8 +15,7 @@ You should have received a copy of the GNU Affero General Public License
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from maya import MayaDT
from umbral.keys import UmbralPublicKey
from umbral.kfrags import KFrag
from nucypher.crypto.umbral_adapter import UmbralPublicKey, VerifiedKeyFrag
from nucypher.crypto.signing import Signature
from nucypher.datastore.base import DatastoreRecord, RecordField
@ -29,9 +28,9 @@ class PolicyArrangement(DatastoreRecord):
encode=lambda maya_date: maya_date.iso8601().encode(),
decode=lambda maya_bytes: MayaDT.from_iso8601(maya_bytes.decode()))
_kfrag = RecordField(
KFrag,
encode=lambda kfrag: kfrag.to_bytes(),
decode=KFrag.from_bytes)
VerifiedKeyFrag,
encode=bytes,
decode=VerifiedKeyFrag.from_verified_bytes)
_alice_verifying_key = RecordField(
UmbralPublicKey,
encode=bytes,

View File

@ -26,8 +26,7 @@ from cryptography import x509
from cryptography.hazmat.backends import default_backend
from nucypher.blockchain.eth.networks import NetworksInventory
from nucypher.crypto.signing import signature_splitter
from nucypher.crypto.splitters import cfrag_splitter
from nucypher.crypto.splitters import cfrag_splitter, signature_splitter
from nucypher.utilities.logging import Logger
EXEMPT_FROM_VERIFICATION.bool_value(False)

View File

@ -44,7 +44,6 @@ from eth_utils import to_checksum_address
from requests.exceptions import SSLError
from twisted.internet import reactor, task
from twisted.internet.defer import Deferred
from umbral.signing import Signature
from nucypher.acumen.nicknames import Nickname
from nucypher.acumen.perception import FleetSensor
@ -58,7 +57,8 @@ from nucypher.config.storages import ForgetfulNodeStorage
from nucypher.crypto.api import InvalidNodeCertificate, recover_address_eip_191, verify_eip_191
from nucypher.crypto.kits import UmbralMessageKit
from nucypher.crypto.powers import DecryptingPower, NoSigningPower, SigningPower
from nucypher.crypto.signing import signature_splitter
from nucypher.crypto.splitters import signature_splitter
from nucypher.crypto.umbral_adapter import Signature
from nucypher.network import LEARNING_LOOP_VERSION
from nucypher.network.exceptions import NodeSeemsToBeDown
from nucypher.network.middleware import RestMiddleware

View File

@ -34,7 +34,7 @@ from mako import exceptions as mako_exceptions
from mako.template import Template
from maya import MayaDT
from typing import Tuple
from umbral.kfrags import KFrag
from nucypher.crypto.umbral_adapter import KFrag
from web3.exceptions import TimeExhausted
import nucypher
@ -263,13 +263,15 @@ def _make_rest_app(datastore: Datastore, this_node, domain: str, log: Logger) ->
kfrag_bytes = cleartext
kfrag = KFrag.from_bytes(kfrag_bytes)
if not kfrag.verify(signing_pubkey=alices_verifying_key):
try:
verified_kfrag = kfrag.verify(signing_pubkey=alices_verifying_key)
except VerificationError:
return Response(f"Signature on {kfrag} is invalid", status=403)
with datastore.describe(PolicyArrangement, id_as_hex, writeable=True) as policy_arrangement:
if not policy_arrangement.alice_verifying_key == alice.stamp.as_umbral_pubkey():
return Response("Policy arrangement's signing key does not match sender's", status=403)
policy_arrangement.kfrag = kfrag
policy_arrangement.kfrag = verified_kfrag
# TODO: Sign the arrangement here. #495
return "" # TODO: Return A 200, with whatever policy metadata.

View File

@ -30,9 +30,7 @@ from cryptography.hazmat.backends.openssl import backend
from cryptography.hazmat.primitives import hashes
from eth_utils import to_canonical_address, to_checksum_address
from typing import Optional, Tuple
from umbral.config import default_params
from umbral.keys import UmbralPublicKey
from umbral.pre import Capsule
from nucypher.crypto.umbral_adapter import UmbralPublicKey, Capsule
from nucypher.blockchain.eth.constants import ETH_ADDRESS_BYTE_LENGTH, ETH_HASH_BYTE_LENGTH
from nucypher.characters.lawful import Bob, Character
@ -40,9 +38,8 @@ from nucypher.crypto.api import encrypt_and_sign, keccak_digest
from nucypher.crypto.api import verify_eip_191
from nucypher.crypto.constants import HRAC_LENGTH
from nucypher.crypto.kits import UmbralMessageKit
from nucypher.crypto.signing import InvalidSignature, Signature, signature_splitter, SignatureStamp
from nucypher.crypto.splitters import capsule_splitter, key_splitter
from nucypher.crypto.splitters import cfrag_splitter
from nucypher.crypto.signing import InvalidSignature, Signature, SignatureStamp
from nucypher.crypto.splitters import capsule_splitter, cfrag_splitter, key_splitter, signature_splitter
from nucypher.crypto.utils import (
canonical_address_from_umbral_key,
)
@ -101,7 +98,7 @@ class TreasureMap:
@classmethod
def splitter(cls):
return BytestringKwargifier(cls,
public_signature=Signature,
public_signature=signature_splitter,
hrac=(bytes, HRAC_LENGTH),
message_kit=(UmbralMessageKit, VariableLengthBytestring)
)
@ -254,7 +251,7 @@ class SignedTreasureMap(TreasureMap):
def splitter(cls):
return BytestringKwargifier(cls,
blockchain_signature=65,
public_signature=Signature,
public_signature=signature_splitter,
hrac=(bytes, HRAC_LENGTH),
message_kit=(UmbralMessageKit, VariableLengthBytestring)
)
@ -293,7 +290,6 @@ class WorkOrder:
blockhash = bytes(blockhash)
expected_lengths = (
(ursula_pubkey, 'ursula_pubkey', UmbralPublicKey.expected_bytes_length()),
(alice_address, 'alice_address', ETH_ADDRESS_BYTE_LENGTH),
(blockhash, 'blockhash', ETH_HASH_BYTE_LENGTH),
# TODO: Why does ursula_identity_evidence has a default value of b''? for federated, perhaps?
@ -313,7 +309,7 @@ class WorkOrder:
def __bytes__(self):
data = bytes(self.capsule) + bytes(self.signature)
if self.cfrag and self.cfrag_signature:
data += VariableLengthBytestring(self.cfrag) + bytes(self.cfrag_signature)
data += bytes(self.cfrag) + bytes(self.cfrag_signature)
return data
@classmethod
@ -394,7 +390,7 @@ class WorkOrder:
@classmethod
def from_rest_payload(cls, arrangement_id, rest_payload, ursula, alice_address):
payload_splitter = BytestringSplitter(Signature) + key_splitter + BytestringSplitter(ETH_HASH_BYTE_LENGTH)
payload_splitter = signature_splitter + key_splitter + BytestringSplitter(ETH_HASH_BYTE_LENGTH)
signature, bob_verifying_key, blockhash, remainder = payload_splitter(rest_payload, return_remainder=True)
tasks = {capsule: cls.PRETask(capsule, sig) for capsule, sig in cls.PRETask.input_splitter.repeat(remainder)}
@ -444,12 +440,6 @@ class WorkOrder:
ursula_verifying_key = self.ursula.stamp.as_umbral_pubkey()
for task, (cfrag, cfrag_signature) in zip(self.tasks.values(), cfrags_and_signatures):
# Validate re-encryption metadata
metadata_input = bytes(task.signature)
metadata_as_signature = Signature.from_bytes(cfrag.proof.metadata)
if not metadata_as_signature.verify(metadata_input, ursula_verifying_key):
raise InvalidSignature(f"Invalid metadata for {cfrag}.")
# TODO: Instead of raising, we should do something (#957)
# Validate re-encryption signatures
if cfrag_signature.verify(bytes(cfrag), ursula_verifying_key):
@ -525,7 +515,7 @@ class Revocation:
REVOKE-<arrangement id to revoke><signature of the previous string>
This is sent as a payload in a DELETE method to the /KFrag/ endpoint.
"""
revocation_splitter = BytestringSplitter((bytes, 7), (bytes, 32), Signature)
revocation_splitter = BytestringSplitter((bytes, 7), (bytes, 32), signature_splitter)
def __init__(self, arrangement_id: bytes,
signer: 'SignatureStamp' = None,

View File

@ -27,7 +27,7 @@ import os
from bytestring_splitter import VariableLengthBytestring, BytestringKwargifier
from constant_sorrow.constants import ALICE, BOB, NO_SIGNATURE
from hexbytes.main import HexBytes
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from nucypher.characters.base import Character
from nucypher.characters.lawful import Alice, Bob

View File

@ -34,16 +34,16 @@ from twisted._threads import AlreadyQuit
from twisted.internet import reactor
from twisted.internet.defer import ensureDeferred, Deferred
from twisted.python.threadpool import ThreadPool
from umbral.keys import UmbralPublicKey
from umbral.kfrags import KFrag
from nucypher.crypto.umbral_adapter import UmbralPublicKey, KFrag
from nucypher.blockchain.eth.actors import BlockchainPolicyAuthor
from nucypher.blockchain.eth.agents import PolicyManagerAgent, StakersReservoir, StakingEscrowAgent
from nucypher.characters.lawful import Alice, Ursula
from nucypher.crypto.api import keccak_digest, secure_random
from nucypher.crypto.constants import HRAC_LENGTH, PUBLIC_KEY_LENGTH
from nucypher.crypto.constants import HRAC_LENGTH
from nucypher.crypto.kits import RevocationKit
from nucypher.crypto.powers import DecryptingPower, SigningPower, TransactingPower
from nucypher.crypto.splitters import key_splitter
from nucypher.crypto.utils import construct_policy_id
from nucypher.network.exceptions import NodeSeemsToBeDown
from nucypher.network.middleware import RestMiddleware
@ -57,7 +57,7 @@ class Arrangement:
"""
ID_LENGTH = 32
splitter = BytestringSplitter((UmbralPublicKey, PUBLIC_KEY_LENGTH), # alive_verifying_key
splitter = BytestringSplitter(key_splitter, # alive_verifying_key
(bytes, ID_LENGTH), # arrangement_id
(bytes, VariableLengthBytestring)) # expiration

View File

@ -20,7 +20,7 @@ import os
import pytest
import tempfile
from pathlib import Path
from umbral.keys import UmbralPrivateKey
from nucypher.crypto.umbral_adapter import UmbralPrivateKey
from nucypher.cli.main import nucypher_cli
from nucypher.policy.identity import Card

View File

@ -15,7 +15,7 @@
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
from umbral.keys import UmbralPrivateKey
from nucypher.crypto.umbral_adapter import UmbralPrivateKey
from nucypher.cli.main import nucypher_cli

View File

@ -22,7 +22,7 @@ import pytest
import shutil
from pathlib import Path
from umbral.keys import UmbralPrivateKey
from nucypher.crypto.umbral_adapter import UmbralPrivateKey
from nucypher.blockchain.eth.actors import Worker
from nucypher.cli.main import nucypher_cli

View File

@ -19,8 +19,7 @@ import os
import pytest
from eth_tester.exceptions import TransactionFailed
from eth_utils import to_canonical_address, to_wei
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, Signer
from web3.contract import Contract
from nucypher.blockchain.economics import BaseEconomics

View File

@ -23,13 +23,13 @@ from cryptography.hazmat.backends.openssl import backend
from cryptography.hazmat.primitives import hashes
from eth_account.account import Account
from eth_account.messages import HexBytes, SignableMessage, encode_defunct
from eth_keys import KeyAPI as EthKeyAPI
from eth_tester.exceptions import TransactionFailed
from eth_utils import to_canonical_address, to_checksum_address, to_normalized_address
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from umbral.signing import Signer, Signature
from nucypher.crypto.api import keccak_digest, verify_eip_191
from nucypher.crypto.utils import canonical_address_from_umbral_key
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, UmbralPublicKey, Signer, Signature
ALGORITHM_KECCAK256 = 0
ALGORITHM_SHA256 = 1
@ -51,7 +51,7 @@ def get_signature_recovery_value(message: bytes,
"""
signature = bytes(signature)
ecdsa_signature_size = Signature.expected_bytes_length()
ecdsa_signature_size = 64 # two curve scalars
if len(signature) != ecdsa_signature_size:
raise ValueError(f"The signature size should be {ecdsa_signature_size} B.")
@ -66,6 +66,20 @@ def get_signature_recovery_value(message: bytes,
"Either the message, the signature or the public key is not correct")
def pubkey_as_address(umbral_pubkey):
"""
Returns the public key as b'0x' + keccak(uncompressed_bytes)[-20:]
"""
return to_normalized_address(canonical_address_from_umbral_key(umbral_pubkey).hex())
def pubkey_as_uncompressed_bytes(umbral_pubkey):
"""
Returns the public key as uncompressed bytes (without the prefix, so 64 bytes long)
"""
return EthKeyAPI.PublicKey.from_compressed_bytes(bytes(umbral_pubkey)).to_bytes()
@pytest.fixture()
def signature_verifier(testerchain, deploy_contract):
contract, _ = deploy_contract('SignatureVerifierMock')
@ -83,9 +97,7 @@ def test_recover(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_privkey.get_pubkey().to_bytes(is_compressed=False)
signer_address = keccak_digest(umbral_pubkey_bytes[1:])
signer_address = to_normalized_address(signer_address[12:])
signer_address = pubkey_as_address(umbral_pubkey)
# Sign message
signer = Signer(umbral_privkey)
@ -121,9 +133,8 @@ 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:])
signer_address = pubkey_as_address(umbral_pubkey)
umbral_pubkey_bytes = pubkey_as_uncompressed_bytes(umbral_pubkey)
# Check extracting address in library
result_address = signature_verifier.functions.toAddress(umbral_pubkey_bytes).call()
@ -148,7 +159,7 @@ def test_verify(testerchain, signature_verifier):
# Generate Umbral key
umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey = umbral_privkey.get_pubkey()
umbral_pubkey_bytes = umbral_pubkey.to_bytes(is_compressed=False)
umbral_pubkey_bytes = pubkey_as_uncompressed_bytes(umbral_pubkey)
# Sign message using SHA-256 hash
signer = Signer(umbral_privkey)
@ -161,15 +172,15 @@ def test_verify(testerchain, signature_verifier):
# Verify signature
assert signature_verifier.functions.verify(message,
recoverable_signature,
umbral_pubkey_bytes[1:],
umbral_pubkey_bytes,
ALGORITHM_SHA256).call()
# Verify signature using wrong key
umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey_bytes = umbral_privkey.get_pubkey().to_bytes(is_compressed=False)
umbral_pubkey_bytes = pubkey_as_uncompressed_bytes(umbral_privkey.get_pubkey())
assert not signature_verifier.functions.verify(message,
recoverable_signature,
umbral_pubkey_bytes[1:],
umbral_pubkey_bytes,
ALGORITHM_SHA256).call()
@ -179,7 +190,7 @@ def test_verify_eip191(testerchain, signature_verifier):
# Generate Umbral key
umbral_privkey = UmbralPrivateKey.gen_key()
umbral_pubkey = umbral_privkey.get_pubkey()
umbral_pubkey_bytes = umbral_pubkey.to_bytes(is_compressed=False)
umbral_pubkey_bytes = pubkey_as_uncompressed_bytes(umbral_pubkey)
#
# Check EIP191 signatures: Version E
@ -201,14 +212,14 @@ def test_verify_eip191(testerchain, signature_verifier):
version_E = b'E'
assert signature_verifier.functions.verifyEIP191(message,
signature,
umbral_pubkey_bytes[1:],
umbral_pubkey_bytes,
version_E).call()
# Of course, it'll fail if we try using version 0
version_0 = b'\x00'
assert not signature_verifier.functions.verifyEIP191(message,
signature,
umbral_pubkey_bytes[1:],
umbral_pubkey_bytes,
version_0).call()
# Check that the hash-based method also works independently
@ -240,13 +251,13 @@ def test_verify_eip191(testerchain, signature_verifier):
# On chain verify signature
assert signature_verifier.functions.verifyEIP191(message,
signature,
umbral_pubkey_bytes[1:],
umbral_pubkey_bytes,
version_0).call()
# Of course, now it fails if we try with version E
assert not signature_verifier.functions.verifyEIP191(message,
signature,
umbral_pubkey_bytes[1:],
umbral_pubkey_bytes,
version_E).call()
# Check that the hash-based method also works independently

View File

@ -19,8 +19,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
import os
import pytest
from eth_tester.exceptions import TransactionFailed
from umbral import keys, pre
from umbral.signing import Signer
from nucypher.crypto.umbral_adapter import pre, Signer, UmbralPrivateKey
@pytest.fixture()
@ -31,11 +30,11 @@ def deserializer(testerchain, deploy_contract):
@pytest.fixture(scope="module")
def fragments():
delegating_privkey = keys.UmbralPrivateKey.gen_key()
delegating_privkey = UmbralPrivateKey.gen_key()
delegating_pubkey = delegating_privkey.get_pubkey()
signing_privkey = keys.UmbralPrivateKey.gen_key()
signing_privkey = UmbralPrivateKey.gen_key()
signer = Signer(signing_privkey)
priv_key_bob = keys.UmbralPrivateKey.gen_key()
priv_key_bob = UmbralPrivateKey.gen_key()
pub_key_bob = priv_key_bob.get_pubkey()
kfrags = pre.generate_kfrags(delegating_privkey=delegating_privkey,
signer=signer,
@ -44,14 +43,12 @@ def fragments():
N=4,
sign_delegating_key=False,
sign_receiving_key=False)
# TODO: Use nucypher re-encryption metadata
metadata = b"This is an example of metadata for re-encryption request"
_symmetric_key, capsule = pre._encapsulate(delegating_pubkey)
capsule.set_correctness_keys(delegating=delegating_pubkey,
receiving=pub_key_bob,
verifying=signing_privkey.get_pubkey())
cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)
cfrag = pre.reencrypt(kfrags[0], capsule)
return capsule, cfrag
@ -71,40 +68,7 @@ def test_capsule(testerchain, deserializer, fragments):
capsule, _cfrag = fragments
capsule_bytes = capsule.to_bytes()
result = deserializer.functions.toCapsule(capsule_bytes).call()
assert bytes(capsule.point_e) == result[0] + result[1]
assert bytes(capsule.point_v) == result[2] + result[3]
assert capsule.bn_sig.to_bytes() == bytes(result[4])
def test_proof(testerchain, deserializer, fragments):
# Wrong number of bytes to deserialize proof
with pytest.raises((TransactionFailed, ValueError)):
deserializer.functions.toCorrectnessProof(os.urandom(227)).call()
# Check random proof bytes without metadata
proof_bytes = os.urandom(228)
result = deserializer.functions.toCorrectnessProof(proof_bytes).call()
assert proof_bytes == bytes().join(result)
# Check random proof bytes with metadata
proof_bytes = os.urandom(270)
result = deserializer.functions.toCorrectnessProof(proof_bytes).call()
assert proof_bytes == bytes().join(result)
# Get real cfrag and proof
_capsule, cfrag = fragments
proof = cfrag.proof
proof_bytes = proof.to_bytes()
# Check real proof
result = deserializer.functions.toCorrectnessProof(proof_bytes).call()
assert bytes(proof.point_e2) == result[0] + result[1]
assert bytes(proof.point_v2) == result[2] + result[3]
assert bytes(proof.point_kfrag_commitment) == result[4] + result[5]
assert bytes(proof.point_kfrag_pok) == result[6] + result[7]
assert proof.bn_sig.to_bytes() == result[8]
assert bytes(proof.kfrag_signature) == result[9]
assert bytes(proof.metadata) == result[10]
assert b''.join(result) == capsule_bytes
def test_cfrag(testerchain, deserializer, fragments):
@ -123,20 +87,10 @@ def test_cfrag(testerchain, deserializer, fragments):
# Check real cfrag
_capsule, cfrag = fragments
proof = cfrag.proof
cfrag_bytes = cfrag.to_bytes()
result = deserializer.functions.toCapsuleFrag(cfrag_bytes).call()
assert bytes(cfrag.point_e1) == result[0] + result[1]
assert bytes(cfrag.point_v1) == result[2] + result[3]
assert bytes(cfrag.kfrag_id) == result[4]
assert bytes(cfrag.point_precursor) == result[5] + result[6]
result = deserializer.functions.toCorrectnessProofFromCapsuleFrag(cfrag_bytes).call()
assert bytes(proof.point_e2) == result[0] + result[1]
assert bytes(proof.point_v2) == result[2] + result[3]
assert bytes(proof.point_kfrag_commitment) == result[4] + result[5]
assert bytes(proof.point_kfrag_pok) == result[6] + result[7]
assert proof.bn_sig.to_bytes() == result[8]
assert bytes(proof.kfrag_signature) == result[9]
assert bytes(proof.metadata) == result[10]
cfrag_bytes = bytes(cfrag)
result_frag = deserializer.functions.toCapsuleFrag(cfrag_bytes).call()
result_proof = deserializer.functions.toCorrectnessProofFromCapsuleFrag(cfrag_bytes).call()
assert cfrag_bytes == b''.join(result_frag) + b''.join(result_proof)
# TODO: Missing test for precomputed_data

View File

@ -18,9 +18,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
import pytest
import pytest_twisted
from twisted.internet import threads
from umbral import pre
from umbral.cfrags import CapsuleFrag
from umbral.kfrags import KFrag
from nucypher.crypto.umbral_adapter import pre, CapsuleFrag, KFrag
from nucypher.crypto.kits import PolicyMessageKit
from nucypher.crypto.powers import DecryptingPower
@ -200,13 +198,6 @@ def test_bob_can_issue_a_work_order_to_a_specific_ursula(enacted_federated_polic
with ursula.datastore.describe(PolicyArrangement, work_order.arrangement_id.hex()) as policy_arrangement:
the_kfrag = policy_arrangement.kfrag
the_correct_cfrag = pre.reencrypt(the_kfrag, capsule)
# The first CFRAG_LENGTH_WITHOUT_PROOF bytes (ie, the cfrag proper, not the proof material), are the same:
assert bytes(the_cfrag)[:CapsuleFrag.expected_bytes_length()] == bytes(
the_correct_cfrag)[:CapsuleFrag.expected_bytes_length()] # It's the correct cfrag!
assert the_correct_cfrag.verify_correctness(capsule)
# Now we'll show that Ursula saved the correct WorkOrder.
with ursula.datastore.query_by(Workorder, filter_field='bob_verifying_key',
@ -336,7 +327,6 @@ def test_bob_gathers_and_combines(enacted_federated_policy, federated_bob, feder
_success, cfrags = federated_bob._reencrypt(new_work_order)
cfrag = cfrags[0]
assert cfrag not in the_message_kit.capsule._attached_cfrags
the_message_kit.capsule.attach_cfrag(cfrags[0])

View File

@ -18,7 +18,7 @@ along with nucypher. If not, see <https://www.gnu.org/licenses/>.
import datetime
import maya
import pytest
from umbral.kfrags import KFrag
from nucypher.crypto.umbral_adapter import KFrag
from nucypher.characters.lawful import Enrico
from nucypher.crypto.api import keccak_digest

View File

@ -145,7 +145,8 @@ def test_key_validation(federated_bob):
with pytest.raises(SpecificationError) as e:
# lets just take a couple bytes off
BobKeyInputRequirer().load({'bobkey': "02f0cb3f3a33f16255d9b2586e6c56570aa07bbeb1157e169f1fb114ffb40037"})
assert "Unknown OpenSSL error." in str(e)
assert "Could not convert input for bobkey to an Umbral Key" in str(e)
assert "Expected 33 bytes, got 32" in str(e)
result = BobKeyInputRequirer().load(dict(bobkey=bytes(federated_bob.public_keys(DecryptingPower)).hex()))
assert isinstance(result['bobkey'], bytes)

View File

@ -21,7 +21,7 @@ from unittest.mock import Mock
import pytest
import tempfile
from constant_sorrow.constants import CERTIFICATE_NOT_SAVED, NO_KEYRING_ATTACHED
from umbral.keys import UmbralPrivateKey
from nucypher.crypto.umbral_adapter import UmbralPrivateKey
from tests.constants import MOCK_IP_ADDRESS
from nucypher.blockchain.eth.actors import StakeHolder

View File

@ -21,10 +21,9 @@ from unittest.mock import ANY
import pytest
from constant_sorrow.constants import FEDERATED_ADDRESS
from cryptography.hazmat.primitives.serialization.base import Encoding
from cryptography.hazmat.primitives.serialization import Encoding
from flask import Flask
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, Signer
from nucypher.characters.lawful import Alice, Bob, Ursula
from nucypher.config.constants import TEMPORARY_DOMAIN

View File

@ -19,7 +19,7 @@ import pytest
import time
from datetime import datetime
from flask import Response
from umbral.keys import UmbralPublicKey
from nucypher.crypto.umbral_adapter import UmbralPublicKey
from unittest.mock import patch
from nucypher.characters.lawful import Ursula

View File

@ -33,8 +33,8 @@ from web3.contract import Contract
from nucypher.blockchain.eth.registry import InMemoryContractRegistry
from nucypher.blockchain.eth.signers.software import Web3Signer
from nucypher.crypto.powers import TransactingPower
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, Signer
from unittest.mock import Mock
from zope.interface import provider

View File

@ -35,7 +35,7 @@ import shutil
import time
from eth_typing.evm import ChecksumAddress
from typing import Set, Optional, List, Tuple
from umbral.keys import UmbralPrivateKey
from nucypher.crypto.umbral_adapter import UmbralPrivateKey
from web3.main import Web3
from web3.types import Wei

View File

@ -21,9 +21,7 @@ from unittest.mock import patch
from nucypher.network.server import make_rest_app
from tests.mock.serials import good_serials
from umbral.config import default_params
from umbral.keys import UmbralPublicKey
from umbral.signing import Signature
from nucypher.crypto.umbral_adapter import UmbralPublicKey, Signature
mock_cert_storage = patch("nucypher.config.storages.ForgetfulNodeStorage.store_node_certificate",
new=lambda *args, **kwargs: "this_might_normally_be_a_filepath")
@ -95,18 +93,11 @@ class NotAPublicKey:
self.i_want_to_be_a_real_boy()
return self.to_cryptography_pubkey()
@property
def params(self):
# Holy heck, metamock hacking.
self.i_want_to_be_a_real_boy()
return self.params
def __eq__(self, other):
return bytes(self) == bytes(other)
class NotAPrivateKey:
params = default_params()
fake_signature = Signature.from_bytes(
b'@\xbfS&\x97\xb3\x9e\x9e\xd3\\j\x9f\x0e\x8fY\x0c\xbeS\x08d\x0b%s\xf6\x17\xe2\xb6\xcd\x95u\xaapON\xd9E\xb3\x10M\xe1\xf4u\x0bL\x99q\xd6\r\x8e_\xe5I\x1e\xe5\xa2\xcf\xe5\x8be_\x077Gz'

View File

@ -63,7 +63,7 @@ def test_actor_with_signing_power_can_sign():
# ...or to get the signer's public key for verification purposes.
# (note: we use the private _der_encoded_bytes here to test directly against the API, instead of Character)
verification = api.verify_ecdsa(message, signature._der_encoded_bytes(),
verification = api.verify_ecdsa(message, bytes(signature),
stamp_of_the_signer.as_umbral_pubkey())
assert verification is True

View File

@ -19,7 +19,7 @@ from pathlib import Path
import pytest
from constant_sorrow.constants import FEDERATED_ADDRESS
from cryptography.hazmat.primitives.serialization.base import Encoding
from cryptography.hazmat.primitives.serialization import Encoding
from nucypher.config.keyring import (
_assemble_key_data,

View File

@ -18,7 +18,7 @@ import base64
import sha3
from constant_sorrow.constants import PUBLIC_ONLY
from umbral.keys import UmbralPrivateKey
from nucypher.crypto.umbral_adapter import UmbralPrivateKey
from nucypher.crypto import keypairs
@ -40,7 +40,7 @@ def test_keypair_with_umbral_keys():
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._privkey == umbral_privkey
assert new_keypair_from_priv.pubkey.to_bytes() == umbral_pubkey.to_bytes()
new_keypair_from_pub = keypairs.Keypair(public_key=umbral_pubkey)
@ -55,9 +55,6 @@ def test_keypair_serialization():
pubkey_bytes = new_keypair.serialize_pubkey()
assert pubkey_bytes == bytes(umbral_pubkey)
pubkey_b64 = new_keypair.serialize_pubkey(as_b64=True)
assert pubkey_b64 == base64.urlsafe_b64encode(umbral_pubkey.to_bytes())
def test_keypair_fingerprint():
umbral_pubkey = UmbralPrivateKey.gen_key().get_pubkey()

View File

@ -21,38 +21,7 @@ from nucypher.characters.lawful import Enrico
from nucypher.crypto.api import secure_random
from nucypher.crypto.kits import UmbralMessageKit
from nucypher.crypto.signing import Signature
def test_split_two_signatures():
"""
We make two random Signatures and concat them. Then split them and show that we got the proper result.
"""
sig1 = Signature.from_bytes(secure_random(64))
sig2 = Signature.from_bytes(secure_random(64))
sigs_concatted = sig1 + sig2
two_signature_splitter = BytestringSplitter(Signature, Signature)
rebuilt_sig1, rebuilt_sig2 = two_signature_splitter(sigs_concatted)
assert (sig1, sig2) == (rebuilt_sig1, rebuilt_sig2)
def test_split_signature_from_arbitrary_bytes():
how_many_bytes = 10
signature = Signature.from_bytes(secure_random(64))
some_bytes = secure_random(how_many_bytes)
splitter = BytestringSplitter(Signature, (bytes, how_many_bytes))
rebuilt_signature, rebuilt_bytes = splitter(signature + some_bytes)
def test_trying_to_extract_too_many_bytes_raises_typeerror():
how_many_bytes = 10
too_many_bytes = 11
signature = Signature.from_bytes(secure_random(64))
some_bytes = secure_random(how_many_bytes)
splitter = BytestringSplitter(Signature, (bytes, too_many_bytes))
with pytest.raises(BytestringSplittingError):
rebuilt_signature, rebuilt_bytes = splitter(signature + some_bytes, return_remainder=True)
from nucypher.crypto.splitters import signature_splitter
def test_message_kit_serialization_via_enrico(enacted_federated_policy, federated_alice):

View File

@ -19,8 +19,7 @@ import os
import pytest
from bytestring_splitter import VariableLengthBytestring
from eth_utils import to_canonical_address
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
from nucypher.crypto.umbral_adapter import UmbralPrivateKey, Signer
from nucypher.blockchain.eth.constants import ETH_HASH_BYTE_LENGTH, LENGTH_ECDSA_SIGNATURE_WITH_RECOVERY
from nucypher.crypto.signing import SignatureStamp, InvalidSignature
@ -62,7 +61,7 @@ def test_pre_task(mock_ursula_reencrypts, ursula, get_random_checksum_address):
assert signature == deserialized_task.signature
# Attaching cfrags to the task
cfrag_bytes = bytes(VariableLengthBytestring(cfrag.to_bytes()))
cfrag_bytes = bytes(cfrag)
cfrag_signature = ursula.stamp(cfrag_bytes)
task.attach_work_result(cfrag, cfrag_signature)
@ -169,11 +168,6 @@ def test_work_order_with_multiple_capsules(mock_ursula_reencrypts,
# Testing WorkOrder.complete()
# Trying to complete this work order fails because the current task signatures are different from the ones created
# when the re-encryption fixture ran. This is an expected effect of using that fixture, which makes the test simpler
with pytest.raises(InvalidSignature, match="Invalid metadata"):
work_order.complete(list(zip(cfrags, cfrag_signatures)))
# Let's use the original task signatures in our WorkOrder, instead
for capsule, task_signature in zip(capsules, signatures):
work_order.tasks[capsule].signature = task_signature

View File

@ -20,9 +20,7 @@ import contextlib
import socket
from cryptography.x509 import Certificate
from typing import Iterable, List, Optional, Set
from umbral import pre
from umbral.keys import UmbralPrivateKey
from umbral.signing import Signer
from nucypher.crypto.umbral_adapter import pre, UmbralPrivateKey, Signer
from nucypher.blockchain.eth.actors import Staker
from nucypher.blockchain.eth.interfaces import BlockchainInterface
@ -195,9 +193,7 @@ def _mock_ursula_reencrypts(ursula):
bobs_signer = Signer(priv_key_bob)
task_signature = bytes(bobs_signer(specification))
metadata = bytes(ursula.stamp(task_signature))
cfrag = pre.reencrypt(kfrags[0], capsule, metadata=metadata)
cfrag = pre.reencrypt(kfrags[0], capsule)
cfrag_signature = ursula.stamp(bytes(cfrag))
bob = Bob.from_public_keys(verifying_key=pub_key_bob)