Source code for agora.keys

import os

import base58
from kin_base import utils as kin_utils
from nacl import signing

ED25519_PUB_KEY_SIZE = 32
ED25519_PRIV_KEY_SIZE = 64


[docs]class PublicKey: """PublicKey is a blockchain-agnostic representation of an ed25519 public key. :param public_key: The public key, in raw bytes. """ def __init__(self, public_key: bytes): # Passing in a bytearray for public_key passes the type annotation checker, but fails an isinstance check # inside verify key, so we cast to bytes just in case. self._verify_key = signing.VerifyKey(bytes(public_key)) def __eq__(self, other): if not isinstance(other, PublicKey): return False return self._verify_key == other._verify_key def __repr__(self): return f'{self.__class__.__name__}(' \ f'public_key={self.to_base58()})'
[docs] @classmethod def from_base58(cls, address: str) -> 'PublicKey': """Decodes the provided base58-encoded public address and returns a PublicKey object. :param address: the base58 encoded public address :return: a PublicKey object. """ return cls(base58.b58decode(address))
[docs] @classmethod def from_string(cls, address: str) -> 'PublicKey': """Parses the provided Stellar-encoded address and returns a PublicKey. :param address: A Stellar-encoded address :return: A PublicKey object. """ if len(address) != 56: raise ValueError("address format not supported") if address[0] != "G": raise ValueError("provided address is not a public key") return cls(kin_utils.is_valid_address(address))
@property def stellar_address(self) -> str: """Returns the Stellar-encoded address, as a string. :return: The Stellar-encoded string representation of the public key. """ return kin_utils.encode_check('account', bytes(self._verify_key)).decode() @property def raw(self) -> bytes: """Returns the raw bytes of the public key. :return: bytes """ return bytes(self._verify_key)
[docs] def to_base58(self) -> str: """Returns the base58-encoded form of this public key. :return: the string base58-encoded public key """ return base58.b58encode(self.raw).decode('utf-8')
[docs] def verify(self, data: bytes, signature: bytes): """Verify the provided data and signature match this keypair's public key. :param data: The data that was signed. :param signature: The signature. """ return self._verify_key.verify(data, signature)
[docs]class PrivateKey: """PrivateKey is a blockchain-agnostic representation of an ed25519 private key. :param private_key: The private key, in raw bytes. """ def __init__(self, private_key: bytes): self._signing_key = signing.SigningKey(private_key) def __eq__(self, other): if not isinstance(other, PrivateKey): return False return self._signing_key == other._signing_key def __repr__(self): return f'{self.__class__.__name__}(' \ f'private_key={self.to_base58()})'
[docs] @classmethod def random(cls): """Returns a Private Key derived from a randomly generated seed. :return: A PrivateKey object. """ return cls(os.urandom(32))
[docs] @classmethod def from_base58(cls, seed: str) -> 'PrivateKey': """Decodes the provided base58-encoded seed and returns a PrivateKey object. :param seed: the base58-encoded seed :return: a PrivateKey object. """ return cls(base58.b58decode(seed))
[docs] @classmethod def from_string(cls, seed: str) -> 'PrivateKey': """Parses the provided Stellar-encoded seed and returns a Private Key. :param seed: A Stellar-encoded seed :return: A PrivateKey object. """ if len(seed) != 56: raise ValueError("seed format not supported") if seed[0] != "S": raise ValueError("provided seed is not a private key") return cls(kin_utils.is_valid_secret_key(seed))
@property def stellar_seed(self) -> str: """Returns the Stellar-encoded seed, as a string. :return: The Stellar-encoded string representation of the private key. """ return kin_utils.encode_check('seed', bytes(self._signing_key)).decode() @property def raw(self) -> bytes: """Returns the raw bytes of the private key. :return: bytes """ return bytes(self._signing_key) @property def public_key(self) -> PublicKey: """Returns a :class:`PublicKey <PublicKey>` object corresponding to this private key. :return: a :class:`PublicKey <PublicKey>` """ return PublicKey(bytes(self._signing_key.verify_key))
[docs] def to_base58(self) -> str: """Returns the base58-encoded form of the seed. :return: the string base58-encoded seed. """ return base58.b58encode(self.raw).decode('utf-8')
[docs] def sign(self, data: bytes) -> bytes: """Sign the provided data. :param data: The data to sign. :return: The signature. """ return self._signing_key.sign(data).signature