Skip to content

Commit

Permalink
fix: do not require indy or bbs to be installed
Browse files Browse the repository at this point in the history
Signed-off-by: Timo Glastra <[email protected]>
  • Loading branch information
TimoGlastra committed Apr 30, 2021
1 parent cd4e4b0 commit 8259840
Show file tree
Hide file tree
Showing 14 changed files with 152 additions and 58 deletions.
16 changes: 10 additions & 6 deletions aries_cloudagent/config/default_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
from ..resolver.did_resolver import DIDResolver
from ..resolver.did_resolver_registry import DIDResolverRegistry
from ..tails.base import BaseTailsServer
from ..ledger.indy import IndySdkLedgerPool, IndySdkLedgerPoolProvider

from ..protocols.actionmenu.v1_0.base_service import BaseMenuService
from ..protocols.actionmenu.v1_0.driver_service import DriverMenuService
Expand All @@ -22,6 +21,7 @@
from ..protocols.introduction.v0_1.demo_service import DemoIntroductionService
from ..transport.wire_format import BaseWireFormat
from ..utils.stats import Collector
from ..utils.dependencies import is_indy_sdk_module_installed


class DefaultContextBuilder(ContextBuilder):
Expand Down Expand Up @@ -64,12 +64,16 @@ async def build_context(self) -> InjectionContext:
async def bind_providers(self, context: InjectionContext):
"""Bind various class providers."""

# MTODO: move to IndySdkProfileManager if possible
# Bind global indy pool provider to be able to share pools between wallets
context.injector.bind_provider(
IndySdkLedgerPool,
CachedProvider(IndySdkLedgerPoolProvider(), ("ledger.pool_name",)),
)
# It is important the ledger pool provider is available in the base context
# so it can be shared by all wallet instances. If we set it in the indy sdk
# profile provider it could mean other wallets won't have access to the provider
if is_indy_sdk_module_installed():
from ..ledger.indy import IndySdkLedgerPool, IndySdkLedgerPoolProvider
context.injector.bind_provider(
IndySdkLedgerPool,
CachedProvider(IndySdkLedgerPoolProvider(), ("ledger.pool_name",)),
)

context.injector.bind_provider(ProfileManager, ProfileManagerProvider())

Expand Down
3 changes: 1 addition & 2 deletions aries_cloudagent/ledger/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from .base import BaseLedger, Role as LedgerRole
from .endpoint_type import EndpointType
from .error import BadLedgerRequestError, LedgerError, LedgerTransactionError
from .indy import Role


class LedgerModulesResultSchema(OpenAPISchema):
Expand Down Expand Up @@ -93,7 +92,7 @@ class RegisterLedgerNymQueryStringSchema(OpenAPISchema):
description="Role",
required=False,
validate=validate.OneOf(
[r.name for r in Role if isinstance(r.value[0], int)] + ["reset"]
[r.name for r in LedgerRole if isinstance(r.value[0], int)] + ["reset"]
),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@
CredentialIssuancePurpose.term,
AuthenticationProofPurpose.term,
}
SUPPORTED_ISSUANCE_SUITES = {Ed25519Signature2018}
SIGNATURE_SUITE_KEY_TYPE_MAPPING = {Ed25519Signature2018: KeyType.ED25519}

SUPPORTED_ISSUANCE_SUITES = {Ed25519Signature2018, BbsBlsSignature2020}

SIGNATURE_SUITE_KEY_TYPE_MAPPING = {
Ed25519Signature2018: KeyType.ED25519,
BbsBlsSignature2020: KeyType.BLS12381G2,
}
# We only want to add bbs suites to supported if the module is installed
if BbsBlsSignature2020.BBS_SUPPORTED:
SUPPORTED_ISSUANCE_SUITES.add(BbsBlsSignature2020)
SIGNATURE_SUITE_KEY_TYPE_MAPPING[BbsBlsSignature2020] = KeyType.BLS12381G2


PROOF_TYPE_SIGNATURE_SUITE_MAPPING = {
suite.signature_type: suite
Expand Down
4 changes: 2 additions & 2 deletions aries_cloudagent/protocols/present_proof/indy/pres_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from marshmallow import fields

from ....ledger.indy import IndySdkLedger
from ....ledger.base import BaseLedger
from ....messaging.models.base import BaseModel, BaseModelSchema
from ....messaging.util import canon
from ....messaging.valid import INDY_CRED_DEF_ID, INDY_PREDICATE
Expand Down Expand Up @@ -292,7 +292,7 @@ async def indy_proof_request(
name: str = None,
version: str = None,
nonce: str = None,
ledger: IndySdkLedger = None,
ledger: BaseLedger = None,
non_revoc_intervals: Mapping[str, NonRevocationInterval] = None,
) -> dict:
"""
Expand Down
51 changes: 51 additions & 0 deletions aries_cloudagent/utils/dependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""Dependency related util methods."""

import sys


def is_indy_sdk_module_installed():
"""Check whether indy (indy-sdk) module is installed.
Returns:
bool: Whether indy (indy-sdk) is installed.
"""
try:
# Check if already imported
if "indy" in sys.modules:
return True

# Try to import
import indy # noqa: F401

return True
except ModuleNotFoundError:
# Not installed if import went wrong
return False


def is_ursa_bbs_signatures_module_installed():
"""Check whether ursa_bbs_signatures module is installed.
Returns:
bool: Whether ursa_bbs_signatures is installed.
"""
try:
# Check if already imported
if "ursa_bbs_signatures" in sys.modules:
return True

# Try to import
import ursa_bbs_signatures # noqa: F401

return True
except ModuleNotFoundError:
# Not installed if import went wrong
return False


def assert_ursa_bbs_signatures_installed():
"""Assert ursa_bbs_signatures module is installed."""
if not is_ursa_bbs_signatures_module_installed():
raise Exception("ursa_bbs_signatures module not installed")
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
from typing import List

from ..error import LinkedDataProofException
from ....utils.dependencies import is_ursa_bbs_signatures_module_installed
from ..document_loader import DocumentLoaderMethod
from .LinkedDataProof import LinkedDataProof


class BbsBlsSignature2020Base(LinkedDataProof, metaclass=ABCMeta):
"""Base class for BbsBlsSignature suites."""

BBS_SUPPORTED = is_ursa_bbs_signatures_module_installed()

def _create_verify_proof_data(
self, *, proof: dict, document: dict, document_loader: DocumentLoaderMethod
) -> List[str]:
Expand Down
28 changes: 16 additions & 12 deletions aries_cloudagent/vc/ld_proofs/suites/BbsBlsSignatureProof2020.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,27 @@
from os import urandom
from pyld import jsonld
from typing import List
from .BbsBlsSignature2020Base import BbsBlsSignature2020Base

from ursa_bbs_signatures import (
create_proof as bls_create_proof,
verify_proof as bls_verify_proof,
CreateProofRequest,
VerifyProofRequest,
get_total_message_count,
ProofMessage,
BlsKeyPair,
ProofMessageType,
)

if BbsBlsSignature2020Base.BBS_SUPPORTED:
from ursa_bbs_signatures import (
create_proof as bls_create_proof,
verify_proof as bls_verify_proof,
CreateProofRequest,
VerifyProofRequest,
get_total_message_count,
ProofMessage,
BlsKeyPair,
ProofMessageType,
)

from ....utils.dependencies import assert_ursa_bbs_signatures_installed
from ....wallet.util import b64_to_bytes, bytes_to_b64
from ..crypto import KeyPair
from ..error import LinkedDataProofException
from ..validation_result import ProofResult
from ..document_loader import DocumentLoaderMethod
from ..purposes import ProofPurpose
from .BbsBlsSignature2020Base import BbsBlsSignature2020Base
from .BbsBlsSignature2020 import BbsBlsSignature2020
from .LinkedDataProof import DeriveProofResult

Expand Down Expand Up @@ -61,6 +63,7 @@ async def derive_proof(
nonce: bytes = None,
):
"""Derive proof for document, return dict with derived document and proof."""
assert_ursa_bbs_signatures_installed()

# Validate that the input proof document has a proof compatible with this suite
if proof.get("type") not in self.supported_derive_proof_types:
Expand Down Expand Up @@ -222,6 +225,7 @@ async def verify_proof(
document_loader: DocumentLoaderMethod,
) -> ProofResult:
"""Verify proof against document and proof purpose."""
assert_ursa_bbs_signatures_installed()
try:
proof["type"] = self.mapped_derived_proof_type

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from asynctest import TestCase, mock as async_mock
import pytest


from .....did.did_key import DIDKey
Expand All @@ -21,6 +22,7 @@
from ..BbsBlsSignature2020 import BbsBlsSignature2020


@pytest.mark.ursa_bbs_signatures
class TestBbsBlsSignature2020(TestCase):
test_seed = "testseed000000000000000000000001"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from asynctest import TestCase, mock as async_mock

import pytest

from .....did.did_key import DIDKey
from .....wallet.key_pair import KeyType
Expand Down Expand Up @@ -30,6 +30,7 @@
from ..BbsBlsSignatureProof2020 import BbsBlsSignatureProof2020


@pytest.mark.ursa_bbs_signatures
class TestBbsBlsSignatureProof2020(TestCase):
test_seed = "testseed000000000000000000000001"

Expand Down
30 changes: 20 additions & 10 deletions aries_cloudagent/wallet/bbs.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
"""BBS+ crypto."""

from typing import List, Tuple
from ursa_bbs_signatures import (
SignRequest,
VerifyRequest,
BlsKeyPair,
sign as bbs_sign,
verify as bbs_verify,
BbsException as NativeBbsException,
)
from ursa_bbs_signatures._ffi.FfiException import FfiException

from ..utils.dependencies import (
assert_ursa_bbs_signatures_installed,
is_ursa_bbs_signatures_module_installed,
)
from ..core.error import BaseError

from ..wallet.util import random_seed

if is_ursa_bbs_signatures_module_installed():
from ursa_bbs_signatures import (
SignRequest,
VerifyRequest,
BlsKeyPair,
sign as bbs_sign,
verify as bbs_verify,
BbsException as NativeBbsException,
)
from ursa_bbs_signatures._ffi.FfiException import FfiException


class BbsException(BaseError):
"""Base BBS exception."""
Expand All @@ -31,6 +36,7 @@ def sign_messages_bls12381g2(messages: List[bytes], secret: bytes):
bytes: The signature
"""
assert_ursa_bbs_signatures_installed()

messages = [message.decode("utf-8") for message in messages]
try:
Expand Down Expand Up @@ -59,6 +65,8 @@ def verify_signed_messages_bls12381g2(
True if verified, else False
"""
assert_ursa_bbs_signatures_installed()

key_pair = BlsKeyPair(public_key=public_key)
messages = [message.decode("utf-8") for message in messages]

Expand Down Expand Up @@ -86,6 +94,8 @@ def create_bls12381g2_keypair(seed: bytes = None) -> Tuple[bytes, bytes]:
A tuple of (public key, secret key)
"""
assert_ursa_bbs_signatures_installed()

if not seed:
seed = random_seed()

Expand Down
11 changes: 6 additions & 5 deletions aries_cloudagent/wallet/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
from .error import WalletError
from .util import bytes_to_b58, b64_to_bytes, b58_to_bytes, random_seed
from .key_type import KeyType
from .bbs import (
create_bls12381g2_keypair,
verify_signed_messages_bls12381g2,
BbsException,
sign_messages_bls12381g2,
)


def create_keypair(key_type: KeyType, seed: bytes = None) -> Tuple[bytes, bytes]:
Expand All @@ -34,7 +40,6 @@ def create_keypair(key_type: KeyType, seed: bytes = None) -> Tuple[bytes, bytes]
return create_ed25519_keypair(seed)
elif key_type == KeyType.BLS12381G2:
# This ensures python won't crash if bbs is not installed and not used
from .bbs import create_bls12381g2_keypair

return create_bls12381g2_keypair(seed)
else:
Expand Down Expand Up @@ -133,8 +138,6 @@ def sign_message(
secret=secret,
)
elif key_type == KeyType.BLS12381G2:
from .bbs import sign_messages_bls12381g2

return sign_messages_bls12381g2(messages=messages, secret=secret)
else:
raise WalletError(f"Unsupported key type: {key_type.key_type}")
Expand Down Expand Up @@ -186,8 +189,6 @@ def verify_signed_message(
message=messages[0], signature=signature, verkey=verkey
)
elif key_type == KeyType.BLS12381G2:
from .bbs import verify_signed_messages_bls12381g2, BbsException

try:
return verify_signed_messages_bls12381g2(
messages=messages, signature=signature, public_key=verkey
Expand Down
3 changes: 2 additions & 1 deletion aries_cloudagent/wallet/tests/test_bbs.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from unittest import TestCase

import pytest

from ..bbs import (
sign_messages_bls12381g2,
Expand All @@ -15,6 +15,7 @@
SEED = "seed000000000001"


@pytest.mark.ursa_bbs_signatures
class TestBBS(TestCase):
def test_create_keypair_seed(self):
(pk, sk) = create_bls12381g2_keypair(SEED)
Expand Down
Loading

0 comments on commit 8259840

Please sign in to comment.