92 lines
2.6 KiB
Python
92 lines
2.6 KiB
Python
from abc import ABC, abstractmethod
|
|
from dataclasses import dataclass
|
|
from enum import Enum, unique
|
|
|
|
from .pb import crypto_pb2 as protobuf
|
|
|
|
|
|
@unique
|
|
class KeyType(Enum):
|
|
RSA = 0
|
|
Ed25519 = 1
|
|
Secp256k1 = 2
|
|
ECDSA = 3
|
|
ECC_P256 = 4
|
|
|
|
|
|
class Key(ABC):
|
|
"""A ``Key`` represents a cryptographic key."""
|
|
|
|
@abstractmethod
|
|
def to_bytes(self) -> bytes:
|
|
"""Returns the byte representation of this key."""
|
|
...
|
|
|
|
@abstractmethod
|
|
def get_type(self) -> KeyType:
|
|
"""Returns the ``KeyType`` for ``self``."""
|
|
...
|
|
|
|
def __eq__(self, other: object) -> bool:
|
|
if not isinstance(other, Key):
|
|
return NotImplemented
|
|
return self.to_bytes() == other.to_bytes()
|
|
|
|
|
|
class PublicKey(Key):
|
|
"""A ``PublicKey`` represents a cryptographic public key."""
|
|
|
|
@abstractmethod
|
|
def verify(self, data: bytes, signature: bytes) -> bool:
|
|
"""Verify that ``signature`` is the cryptographic signature of the hash
|
|
of ``data``."""
|
|
...
|
|
|
|
def _serialize_to_protobuf(self) -> protobuf.PublicKey:
|
|
"""Return the protobuf representation of this ``Key``."""
|
|
key_type = self.get_type().value
|
|
data = self.to_bytes()
|
|
protobuf_key = protobuf.PublicKey(key_type=key_type, data=data)
|
|
return protobuf_key
|
|
|
|
def serialize(self) -> bytes:
|
|
"""Return the canonical serialization of this ``Key``."""
|
|
return self._serialize_to_protobuf().SerializeToString()
|
|
|
|
@classmethod
|
|
def deserialize_from_protobuf(cls, protobuf_data: bytes) -> protobuf.PublicKey:
|
|
return protobuf.PublicKey.FromString(protobuf_data)
|
|
|
|
|
|
class PrivateKey(Key):
|
|
"""A ``PrivateKey`` represents a cryptographic private key."""
|
|
|
|
@abstractmethod
|
|
def sign(self, data: bytes) -> bytes:
|
|
...
|
|
|
|
@abstractmethod
|
|
def get_public_key(self) -> PublicKey:
|
|
...
|
|
|
|
def _serialize_to_protobuf(self) -> protobuf.PrivateKey:
|
|
"""Return the protobuf representation of this ``Key``."""
|
|
key_type = self.get_type().value
|
|
data = self.to_bytes()
|
|
protobuf_key = protobuf.PrivateKey(key_type=key_type, data=data)
|
|
return protobuf_key
|
|
|
|
def serialize(self) -> bytes:
|
|
"""Return the canonical serialization of this ``Key``."""
|
|
return self._serialize_to_protobuf().SerializeToString()
|
|
|
|
@classmethod
|
|
def deserialize_from_protobuf(cls, protobuf_data: bytes) -> protobuf.PrivateKey:
|
|
return protobuf.PrivateKey.FromString(protobuf_data)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class KeyPair:
|
|
private_key: PrivateKey
|
|
public_key: PublicKey
|