Module mydata_did.v1_0.utils.did.mydata_did
DID MyData class and resolver methods.
Expand source code
"""DID MyData class and resolver methods."""
from ..wallet.crypto import ed25519_pk_to_curve25519
from ..wallet.key_type import KeyType
from ..wallet.util import b58_to_bytes, bytes_to_b58
from ..diddoc import DIDDoc
class DIDMyData:
"""DID MyData parser and resolver."""
_key_type: KeyType
_public_key: bytes
def __init__(self, public_key: bytes, key_type: KeyType) -> None:
"""Initialize new DIDMyData instance."""
self._public_key = public_key
self._key_type = key_type
@classmethod
def from_public_key(cls, public_key: bytes, key_type: KeyType) -> "DIDMyData":
"""Initialize new DIDMyData instance from public key and key type."""
return cls(public_key, key_type)
@classmethod
def from_public_key_b58(cls, public_key: str, key_type: KeyType) -> "DIDMyData":
"""Initialize new DIDMyData instance from base58 encoded public key and key type."""
public_key_bytes = b58_to_bytes(public_key)
return cls.from_public_key(public_key_bytes, key_type)
@classmethod
def from_fingerprint(cls, fingerprint: str) -> "DIDMyData":
"""Initialize new DIDMyData instance from multibase encoded fingerprint.
The fingerprint contains both the public key and key type.
"""
# Assert fingerprint is in multibase format
assert fingerprint[0] == "z"
# Get key bytes, remove multicodec prefix
key_bytes_with_prefix = b58_to_bytes(fingerprint[1:])
# Get associated key type with prefixed bytes
key_type = KeyType.from_prefixed_bytes(key_bytes_with_prefix)
if not key_type:
raise Exception(
f"No key type for prefixed public key '{key_bytes_with_prefix}' found."
)
# Remove the prefix bytes to get the public key
prefix_len = len(key_type.multicodec_prefix)
public_key_bytes = key_bytes_with_prefix[prefix_len:]
return cls(public_key_bytes, key_type)
@classmethod
def from_did(cls, did: str) -> "DIDMyData":
"""Initialize a new DIDMyData instance from a fully qualified did:mydata string.
Extracts the fingerprint from the did:mydata and uses that to constrcut the did:mydata.
"""
did_parts = did.split("#")
_, fingerprint = did_parts[0].split("did:mydata:")
return cls.from_fingerprint(fingerprint)
@property
def prefixed_public_key(self) -> bytes:
"""Getter for multicodec prefixed public key."""
return b"".join([self.key_type.multicodec_prefix, self.public_key])
@property
def fingerprint(self) -> str:
"""Getter for DID MyData fingerprint."""
return f"z{bytes_to_b58(self.prefixed_public_key)}"
@property
def did(self) -> str:
"""Getter for full did:mydata string."""
return f"did:mydata:{self.fingerprint}"
@property
def did_doc(self) -> dict:
"""Getter for did document associated with did:mydata."""
resolver = DID_KEY_RESOLVERS[self.key_type]
return resolver(self)
@property
def public_key(self) -> bytes:
"""Getter for public key."""
return self._public_key
@property
def public_key_b58(self) -> str:
"""Getter for base58 encoded public key."""
return bytes_to_b58(self.public_key)
@property
def key_type(self) -> KeyType:
"""Getter for key type."""
return self._key_type
@property
def key_id(self) -> str:
"""Getter for key id."""
return f"{self.did}#{self.fingerprint}"
def construct_did_key_ed25519(did_key: "DIDMyData") -> dict:
"""Construct Ed25519 did:mydata.
Args:
did_key (DIDMyData): DID MyData instance to parse ed25519 did:mydata document from
Returns:
dict: The ed25519 did:mydata did document
"""
curve25519 = ed25519_pk_to_curve25519(did_key.public_key)
x25519 = DIDMyData.from_public_key(curve25519, KeyType.X25519)
did_doc = construct_did_signature_key_base(
id=did_key.did,
key_id=did_key.key_id,
verification_method={
"id": did_key.key_id,
"type": "Ed25519VerificationKey2018",
"controller": did_key.did,
"publicKeyBase58": did_key.public_key_b58,
},
)
# Ed25519 has pair with X25519
did_doc["keyAgreement"].append(
{
"id": f"{did_key.did}#{x25519.fingerprint}",
"type": "X25519KeyAgreementKey2019",
"controller": did_key.did,
"publicKeyBase58": bytes_to_b58(curve25519),
}
)
return did_doc
def construct_did_signature_key_base(
*, id: str, key_id: str, verification_method: dict
):
"""Create base DID MyData structure to use for most signature keys.
May not be suitable for all DID MyData types
"""
return {
"@context": DIDDoc.CONTEXT,
"id": id,
"verificationMethod": [verification_method],
"authentication": [key_id],
"assertionMethod": [key_id],
"capabilityDelegation": [key_id],
"capabilityInvocation": [key_id],
"keyAgreement": [],
}
DID_KEY_RESOLVERS = {
KeyType.ED25519: construct_did_key_ed25519,
}
Functions
def construct_did_key_ed25519(did_key: DIDMyData) ‑> dict
-
Construct Ed25519 did:mydata.
Args
did_key
:DIDMyData
- DID MyData instance to parse ed25519 did:mydata document from
Returns
dict
- The ed25519 did:mydata did document
Expand source code
def construct_did_key_ed25519(did_key: "DIDMyData") -> dict: """Construct Ed25519 did:mydata. Args: did_key (DIDMyData): DID MyData instance to parse ed25519 did:mydata document from Returns: dict: The ed25519 did:mydata did document """ curve25519 = ed25519_pk_to_curve25519(did_key.public_key) x25519 = DIDMyData.from_public_key(curve25519, KeyType.X25519) did_doc = construct_did_signature_key_base( id=did_key.did, key_id=did_key.key_id, verification_method={ "id": did_key.key_id, "type": "Ed25519VerificationKey2018", "controller": did_key.did, "publicKeyBase58": did_key.public_key_b58, }, ) # Ed25519 has pair with X25519 did_doc["keyAgreement"].append( { "id": f"{did_key.did}#{x25519.fingerprint}", "type": "X25519KeyAgreementKey2019", "controller": did_key.did, "publicKeyBase58": bytes_to_b58(curve25519), } ) return did_doc
def construct_did_signature_key_base(*, id: str, key_id: str, verification_method: dict)
-
Create base DID MyData structure to use for most signature keys.
May not be suitable for all DID MyData types
Expand source code
def construct_did_signature_key_base( *, id: str, key_id: str, verification_method: dict ): """Create base DID MyData structure to use for most signature keys. May not be suitable for all DID MyData types """ return { "@context": DIDDoc.CONTEXT, "id": id, "verificationMethod": [verification_method], "authentication": [key_id], "assertionMethod": [key_id], "capabilityDelegation": [key_id], "capabilityInvocation": [key_id], "keyAgreement": [], }
Classes
class DIDMyData (public_key: bytes, key_type: KeyType)
-
DID MyData parser and resolver.
Initialize new DIDMyData instance.
Expand source code
class DIDMyData: """DID MyData parser and resolver.""" _key_type: KeyType _public_key: bytes def __init__(self, public_key: bytes, key_type: KeyType) -> None: """Initialize new DIDMyData instance.""" self._public_key = public_key self._key_type = key_type @classmethod def from_public_key(cls, public_key: bytes, key_type: KeyType) -> "DIDMyData": """Initialize new DIDMyData instance from public key and key type.""" return cls(public_key, key_type) @classmethod def from_public_key_b58(cls, public_key: str, key_type: KeyType) -> "DIDMyData": """Initialize new DIDMyData instance from base58 encoded public key and key type.""" public_key_bytes = b58_to_bytes(public_key) return cls.from_public_key(public_key_bytes, key_type) @classmethod def from_fingerprint(cls, fingerprint: str) -> "DIDMyData": """Initialize new DIDMyData instance from multibase encoded fingerprint. The fingerprint contains both the public key and key type. """ # Assert fingerprint is in multibase format assert fingerprint[0] == "z" # Get key bytes, remove multicodec prefix key_bytes_with_prefix = b58_to_bytes(fingerprint[1:]) # Get associated key type with prefixed bytes key_type = KeyType.from_prefixed_bytes(key_bytes_with_prefix) if not key_type: raise Exception( f"No key type for prefixed public key '{key_bytes_with_prefix}' found." ) # Remove the prefix bytes to get the public key prefix_len = len(key_type.multicodec_prefix) public_key_bytes = key_bytes_with_prefix[prefix_len:] return cls(public_key_bytes, key_type) @classmethod def from_did(cls, did: str) -> "DIDMyData": """Initialize a new DIDMyData instance from a fully qualified did:mydata string. Extracts the fingerprint from the did:mydata and uses that to constrcut the did:mydata. """ did_parts = did.split("#") _, fingerprint = did_parts[0].split("did:mydata:") return cls.from_fingerprint(fingerprint) @property def prefixed_public_key(self) -> bytes: """Getter for multicodec prefixed public key.""" return b"".join([self.key_type.multicodec_prefix, self.public_key]) @property def fingerprint(self) -> str: """Getter for DID MyData fingerprint.""" return f"z{bytes_to_b58(self.prefixed_public_key)}" @property def did(self) -> str: """Getter for full did:mydata string.""" return f"did:mydata:{self.fingerprint}" @property def did_doc(self) -> dict: """Getter for did document associated with did:mydata.""" resolver = DID_KEY_RESOLVERS[self.key_type] return resolver(self) @property def public_key(self) -> bytes: """Getter for public key.""" return self._public_key @property def public_key_b58(self) -> str: """Getter for base58 encoded public key.""" return bytes_to_b58(self.public_key) @property def key_type(self) -> KeyType: """Getter for key type.""" return self._key_type @property def key_id(self) -> str: """Getter for key id.""" return f"{self.did}#{self.fingerprint}"
Static methods
def from_did(did: str) ‑> DIDMyData
-
Initialize a new DIDMyData instance from a fully qualified did:mydata string.
Extracts the fingerprint from the did:mydata and uses that to constrcut the did:mydata.
Expand source code
@classmethod def from_did(cls, did: str) -> "DIDMyData": """Initialize a new DIDMyData instance from a fully qualified did:mydata string. Extracts the fingerprint from the did:mydata and uses that to constrcut the did:mydata. """ did_parts = did.split("#") _, fingerprint = did_parts[0].split("did:mydata:") return cls.from_fingerprint(fingerprint)
def from_fingerprint(fingerprint: str) ‑> DIDMyData
-
Initialize new DIDMyData instance from multibase encoded fingerprint.
The fingerprint contains both the public key and key type.
Expand source code
@classmethod def from_fingerprint(cls, fingerprint: str) -> "DIDMyData": """Initialize new DIDMyData instance from multibase encoded fingerprint. The fingerprint contains both the public key and key type. """ # Assert fingerprint is in multibase format assert fingerprint[0] == "z" # Get key bytes, remove multicodec prefix key_bytes_with_prefix = b58_to_bytes(fingerprint[1:]) # Get associated key type with prefixed bytes key_type = KeyType.from_prefixed_bytes(key_bytes_with_prefix) if not key_type: raise Exception( f"No key type for prefixed public key '{key_bytes_with_prefix}' found." ) # Remove the prefix bytes to get the public key prefix_len = len(key_type.multicodec_prefix) public_key_bytes = key_bytes_with_prefix[prefix_len:] return cls(public_key_bytes, key_type)
def from_public_key(public_key: bytes, key_type: KeyType) ‑> DIDMyData
-
Initialize new DIDMyData instance from public key and key type.
Expand source code
@classmethod def from_public_key(cls, public_key: bytes, key_type: KeyType) -> "DIDMyData": """Initialize new DIDMyData instance from public key and key type.""" return cls(public_key, key_type)
def from_public_key_b58(public_key: str, key_type: KeyType) ‑> DIDMyData
-
Initialize new DIDMyData instance from base58 encoded public key and key type.
Expand source code
@classmethod def from_public_key_b58(cls, public_key: str, key_type: KeyType) -> "DIDMyData": """Initialize new DIDMyData instance from base58 encoded public key and key type.""" public_key_bytes = b58_to_bytes(public_key) return cls.from_public_key(public_key_bytes, key_type)
Instance variables
var did : str
-
Getter for full did:mydata string.
Expand source code
@property def did(self) -> str: """Getter for full did:mydata string.""" return f"did:mydata:{self.fingerprint}"
var did_doc : dict
-
Getter for did document associated with did:mydata.
Expand source code
@property def did_doc(self) -> dict: """Getter for did document associated with did:mydata.""" resolver = DID_KEY_RESOLVERS[self.key_type] return resolver(self)
var fingerprint : str
-
Getter for DID MyData fingerprint.
Expand source code
@property def fingerprint(self) -> str: """Getter for DID MyData fingerprint.""" return f"z{bytes_to_b58(self.prefixed_public_key)}"
var key_id : str
-
Getter for key id.
Expand source code
@property def key_id(self) -> str: """Getter for key id.""" return f"{self.did}#{self.fingerprint}"
var key_type : KeyType
-
Getter for key type.
Expand source code
@property def key_type(self) -> KeyType: """Getter for key type.""" return self._key_type
var prefixed_public_key : bytes
-
Getter for multicodec prefixed public key.
Expand source code
@property def prefixed_public_key(self) -> bytes: """Getter for multicodec prefixed public key.""" return b"".join([self.key_type.multicodec_prefix, self.public_key])
var public_key : bytes
-
Getter for public key.
Expand source code
@property def public_key(self) -> bytes: """Getter for public key.""" return self._public_key
var public_key_b58 : str
-
Getter for base58 encoded public key.
Expand source code
@property def public_key_b58(self) -> str: """Getter for base58 encoded public key.""" return bytes_to_b58(self.public_key)